|
|
|
@ -2,7 +2,6 @@ |
|
|
|
import { onMounted, computed } from 'vue' |
|
|
|
import { useRouter } from 'vue-router' |
|
|
|
import { useBagStore } from '@/stores/bag' |
|
|
|
import { useCharacterStore } from '@/stores/character' |
|
|
|
import StarBorder from '@/components/StarBorder/StarBorder.vue' |
|
|
|
import Particles from '@/components/Particles/Particles.vue' |
|
|
|
import { ArrowLeft } from '@element-plus/icons-vue' |
|
|
|
@ -11,7 +10,6 @@ import itemDefaultIcon from '@/assets/images/item-default.svg' |
|
|
|
|
|
|
|
const router = useRouter() |
|
|
|
const bagStore = useBagStore() |
|
|
|
const characterStore = useCharacterStore() |
|
|
|
|
|
|
|
const bagName = computed(() => bagStore.characterBag?.bagName || '背包') |
|
|
|
const bagCapacity = computed(() => bagStore.characterBag?.bagCapacity || 0) |
|
|
|
@ -19,7 +17,8 @@ const usedCapacity = computed(() => bagStore.usedCapacity) |
|
|
|
|
|
|
|
const itemTypeMap: Record<number, string> = { |
|
|
|
1: '装备', |
|
|
|
2: '丹药' |
|
|
|
2: '丹药', |
|
|
|
3: '垃圾' |
|
|
|
} |
|
|
|
|
|
|
|
const rarityMap: Record<number, string> = { |
|
|
|
@ -29,10 +28,20 @@ const rarityMap: Record<number, string> = { |
|
|
|
4: '传说' |
|
|
|
} |
|
|
|
|
|
|
|
const getItemTooltip = (item: { itemType: number; itemId: number; quantity: number; itemName: string | null; itemRarity: number | null }) => { |
|
|
|
const type = itemTypeMap[item.itemType] || '未知' |
|
|
|
const rarity = item.itemRarity ? rarityMap[item.itemRarity] || '' : '' |
|
|
|
return `${item.itemName}\n类型: ${type}${rarity ? ` | 稀有度: ${rarity}` : ''}\n数量: ${item.quantity}` |
|
|
|
const scrapLevelMap: Record<number, string> = { |
|
|
|
1: '普通', |
|
|
|
2: '优秀', |
|
|
|
3: '精良', |
|
|
|
4: '史诗', |
|
|
|
5: '传说' |
|
|
|
} |
|
|
|
|
|
|
|
const scrapLevelColorMap: Record<number, string> = { |
|
|
|
1: '#FFFFFF', |
|
|
|
2: '#00FF00', |
|
|
|
3: '#0077FF', |
|
|
|
4: '#9932CC', |
|
|
|
5: '#FF8C00' |
|
|
|
} |
|
|
|
|
|
|
|
const getItemIcon = (item: { icon: string | null }) => { |
|
|
|
@ -42,6 +51,25 @@ const getItemIcon = (item: { icon: string | null }) => { |
|
|
|
return itemDefaultIcon |
|
|
|
} |
|
|
|
|
|
|
|
const getEquipmentTooltip = (item: { itemName: string | null; itemRarity: number | null; quantity: number }) => { |
|
|
|
const rarity = item.itemRarity ? rarityMap[item.itemRarity] || '' : '' |
|
|
|
return `${item.itemName}\n类型: 装备${rarity ? ` | 稀有度: ${rarity}` : ''}\n数量: ${item.quantity}` |
|
|
|
} |
|
|
|
|
|
|
|
const getPillTooltip = (item: { itemName: string | null; quantity: number }) => { |
|
|
|
return `${item.itemName}\n类型: 丹药\n数量: ${item.quantity}` |
|
|
|
} |
|
|
|
|
|
|
|
const getScrapTooltip = (item: any) => { |
|
|
|
const level = item.scrapLevel ? scrapLevelMap[item.scrapLevel] || '' : '' |
|
|
|
let stats = '' |
|
|
|
if (item.attackBonus) stats += `\n攻击+${item.attackBonus}` |
|
|
|
if (item.defenseBonus) stats += `\n防御+${item.defenseBonus}` |
|
|
|
if (item.hpBonus) stats += `\n生命+${item.hpBonus}` |
|
|
|
if (item.magicBonus) stats += `\n魔力+${item.magicBonus}` |
|
|
|
return `${item.itemName}\n类型: 垃圾 | 稀有度: ${level}\n数量: ${item.quantity}${stats}` |
|
|
|
} |
|
|
|
|
|
|
|
const handleBack = () => { |
|
|
|
router.push('/game') |
|
|
|
} |
|
|
|
@ -79,45 +107,133 @@ onMounted(() => { |
|
|
|
{{ bagStore.error }} |
|
|
|
</div> |
|
|
|
|
|
|
|
<div v-else-if="bagStore.totalItems === 0" class="empty"> |
|
|
|
<div v-else-if="bagStore.bagItems.length === 0" class="empty"> |
|
|
|
背包空空如也,快去获取一些物品吧! |
|
|
|
</div> |
|
|
|
|
|
|
|
<div v-else class="items-grid"> |
|
|
|
<el-tooltip |
|
|
|
v-for="item in bagStore.paginatedItems" |
|
|
|
:key="item.id" |
|
|
|
:content="getItemTooltip(item)" |
|
|
|
placement="top" |
|
|
|
:show-after="300" |
|
|
|
> |
|
|
|
<div class="item-cell"> |
|
|
|
<img v-if="item.icon" :src="getItemIcon(item)" class="item-icon-img" :class="'rarity-' + (item.itemRarity || 1)" /> |
|
|
|
<div v-else class="item-icon" :class="'rarity-' + (item.itemRarity || 1)"> |
|
|
|
{{ item.itemType === 1 ? '⚔️' : '💊' }} |
|
|
|
</div> |
|
|
|
<span class="item-name">{{ item.itemName }}</span> |
|
|
|
<span v-if="item.quantity > 1" class="item-count">{{ item.quantity }}</span> |
|
|
|
<div v-else class="bag-sections"> |
|
|
|
<!-- 装备区域 --> |
|
|
|
<div class="section" v-if="bagStore.paginatedEquipment.length > 0 || bagStore.totalEquipmentPages > 0"> |
|
|
|
<div class="section-header"> |
|
|
|
<span class="section-title">装备</span> |
|
|
|
<span class="section-count">({{ bagStore.paginatedEquipment.length }} / {{ bagStore.equipmentItems.length }})</span> |
|
|
|
</div> |
|
|
|
</el-tooltip> |
|
|
|
</div> |
|
|
|
<div class="items-grid"> |
|
|
|
<el-tooltip |
|
|
|
v-for="item in bagStore.paginatedEquipment" |
|
|
|
:key="item.id" |
|
|
|
:content="getEquipmentTooltip(item)" |
|
|
|
placement="top" |
|
|
|
:show-after="300" |
|
|
|
> |
|
|
|
<div class="item-cell"> |
|
|
|
<img v-if="item.icon" :src="getItemIcon(item)" class="item-icon-img" :class="'rarity-' + (item.itemRarity || 1)" /> |
|
|
|
<div v-else class="item-icon">⚔️</div> |
|
|
|
<span class="item-name">{{ item.itemName }}</span> |
|
|
|
<span v-if="item.quantity > 1" class="item-count">{{ item.quantity }}</span> |
|
|
|
</div> |
|
|
|
</el-tooltip> |
|
|
|
</div> |
|
|
|
<div v-if="bagStore.totalEquipmentPages > 1" class="pagination"> |
|
|
|
<button |
|
|
|
class="page-btn" |
|
|
|
:disabled="bagStore.equipmentPage === 1" |
|
|
|
@click="bagStore.prevEquipmentPage()" |
|
|
|
> |
|
|
|
上一页 |
|
|
|
</button> |
|
|
|
<span class="page-info">{{ bagStore.equipmentPage }} / {{ bagStore.totalEquipmentPages }}</span> |
|
|
|
<button |
|
|
|
class="page-btn" |
|
|
|
:disabled="bagStore.equipmentPage >= bagStore.totalEquipmentPages" |
|
|
|
@click="bagStore.nextEquipmentPage()" |
|
|
|
> |
|
|
|
下一页 |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<!-- 丹药区域 --> |
|
|
|
<div class="section" v-if="bagStore.paginatedPills.length > 0 || bagStore.totalPillPages > 0"> |
|
|
|
<div class="section-header"> |
|
|
|
<span class="section-title">丹药</span> |
|
|
|
<span class="section-count">({{ bagStore.paginatedPills.length }} / {{ bagStore.pillItems.length }})</span> |
|
|
|
</div> |
|
|
|
<div class="items-grid"> |
|
|
|
<el-tooltip |
|
|
|
v-for="item in bagStore.paginatedPills" |
|
|
|
:key="item.id" |
|
|
|
:content="getPillTooltip(item)" |
|
|
|
placement="top" |
|
|
|
:show-after="300" |
|
|
|
> |
|
|
|
<div class="item-cell"> |
|
|
|
<img v-if="item.icon" :src="getItemIcon(item)" class="item-icon-img" /> |
|
|
|
<div v-else class="item-icon">💊</div> |
|
|
|
<span class="item-name">{{ item.itemName }}</span> |
|
|
|
<span v-if="item.quantity > 1" class="item-count">{{ item.quantity }}</span> |
|
|
|
</div> |
|
|
|
</el-tooltip> |
|
|
|
</div> |
|
|
|
<div v-if="bagStore.totalPillPages > 1" class="pagination"> |
|
|
|
<button |
|
|
|
class="page-btn" |
|
|
|
:disabled="bagStore.pillPage === 1" |
|
|
|
@click="bagStore.prevPillPage()" |
|
|
|
> |
|
|
|
上一页 |
|
|
|
</button> |
|
|
|
<span class="page-info">{{ bagStore.pillPage }} / {{ bagStore.totalPillPages }}</span> |
|
|
|
<button |
|
|
|
class="page-btn" |
|
|
|
:disabled="bagStore.pillPage >= bagStore.totalPillPages" |
|
|
|
@click="bagStore.nextPillPage()" |
|
|
|
> |
|
|
|
下一页 |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
|
|
|
|
<div v-if="bagStore.totalPages > 1" class="pagination"> |
|
|
|
<button |
|
|
|
class="page-btn" |
|
|
|
:disabled="bagStore.currentPage === 1" |
|
|
|
@click="bagStore.prevPage()" |
|
|
|
> |
|
|
|
上一页 |
|
|
|
</button> |
|
|
|
<span class="page-info">{{ bagStore.currentPage }} / {{ bagStore.totalPages }}</span> |
|
|
|
<button |
|
|
|
class="page-btn" |
|
|
|
:disabled="bagStore.currentPage >= bagStore.totalPages" |
|
|
|
@click="bagStore.nextPage()" |
|
|
|
> |
|
|
|
下一页 |
|
|
|
</button> |
|
|
|
<!-- 垃圾区域 --> |
|
|
|
<div class="section" v-if="bagStore.paginatedScraps.length > 0 || bagStore.totalScrapPages > 0"> |
|
|
|
<div class="section-header"> |
|
|
|
<span class="section-title">垃圾</span> |
|
|
|
<span class="section-count">({{ bagStore.paginatedScraps.length }} / {{ bagStore.scrapItems.length }})</span> |
|
|
|
</div> |
|
|
|
<div class="items-grid"> |
|
|
|
<el-tooltip |
|
|
|
v-for="item in bagStore.paginatedScraps" |
|
|
|
:key="item.id" |
|
|
|
:content="getScrapTooltip(item)" |
|
|
|
placement="top" |
|
|
|
:show-after="300" |
|
|
|
> |
|
|
|
<div class="item-cell scrap-cell"> |
|
|
|
<img v-if="item.icon" :src="getItemIcon(item)" class="item-icon-img" :style="{ borderColor: scrapLevelColorMap[item.scrapLevel || 1] }" /> |
|
|
|
<div v-else class="item-icon" :style="{ color: scrapLevelColorMap[item.scrapLevel || 1] }">📦</div> |
|
|
|
<span class="item-name">{{ item.itemName }}</span> |
|
|
|
<span v-if="item.quantity > 1" class="item-count">{{ item.quantity }}</span> |
|
|
|
</div> |
|
|
|
</el-tooltip> |
|
|
|
</div> |
|
|
|
<div v-if="bagStore.totalScrapPages > 1" class="pagination"> |
|
|
|
<button |
|
|
|
class="page-btn" |
|
|
|
:disabled="bagStore.scrapPage === 1" |
|
|
|
@click="bagStore.prevScrapPage()" |
|
|
|
> |
|
|
|
上一页 |
|
|
|
</button> |
|
|
|
<span class="page-info">{{ bagStore.scrapPage }} / {{ bagStore.totalScrapPages }}</span> |
|
|
|
<button |
|
|
|
class="page-btn" |
|
|
|
:disabled="bagStore.scrapPage >= bagStore.totalScrapPages" |
|
|
|
@click="bagStore.nextScrapPage()" |
|
|
|
> |
|
|
|
下一页 |
|
|
|
</button> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
@ -209,11 +325,44 @@ onMounted(() => { |
|
|
|
color: #ff4444; |
|
|
|
} |
|
|
|
|
|
|
|
.bag-sections { |
|
|
|
display: flex; |
|
|
|
flex-direction: column; |
|
|
|
gap: 24px; |
|
|
|
} |
|
|
|
|
|
|
|
.section { |
|
|
|
background: rgba(255, 255, 255, 0.02); |
|
|
|
border: 1px solid rgba(255, 255, 255, 0.06); |
|
|
|
border-radius: 16px; |
|
|
|
padding: 16px; |
|
|
|
} |
|
|
|
|
|
|
|
.section-header { |
|
|
|
display: flex; |
|
|
|
align-items: center; |
|
|
|
gap: 8px; |
|
|
|
margin-bottom: 16px; |
|
|
|
padding-bottom: 12px; |
|
|
|
border-bottom: 1px solid rgba(255, 255, 255, 0.06); |
|
|
|
} |
|
|
|
|
|
|
|
.section-title { |
|
|
|
color: #ffffff; |
|
|
|
font-size: 1rem; |
|
|
|
font-weight: 500; |
|
|
|
} |
|
|
|
|
|
|
|
.section-count { |
|
|
|
color: #666666; |
|
|
|
font-size: 0.8rem; |
|
|
|
} |
|
|
|
|
|
|
|
.items-grid { |
|
|
|
display: grid; |
|
|
|
grid-template-columns: repeat(4, 1fr); |
|
|
|
gap: 12px; |
|
|
|
margin-bottom: 24px; |
|
|
|
margin-bottom: 16px; |
|
|
|
} |
|
|
|
|
|
|
|
.item-cell { |
|
|
|
@ -235,6 +384,10 @@ onMounted(() => { |
|
|
|
border-color: rgba(255, 255, 255, 0.15); |
|
|
|
} |
|
|
|
|
|
|
|
.scrap-cell { |
|
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
|
} |
|
|
|
|
|
|
|
.item-icon { |
|
|
|
font-size: 2rem; |
|
|
|
margin-bottom: 8px; |
|
|
|
@ -245,6 +398,8 @@ onMounted(() => { |
|
|
|
height: 2.5rem; |
|
|
|
object-fit: contain; |
|
|
|
margin-bottom: 8px; |
|
|
|
border-radius: 4px; |
|
|
|
border: 2px solid transparent; |
|
|
|
} |
|
|
|
|
|
|
|
.item-name { |
|
|
|
@ -283,13 +438,14 @@ onMounted(() => { |
|
|
|
} |
|
|
|
|
|
|
|
.page-btn { |
|
|
|
padding: 10px 20px; |
|
|
|
padding: 8px 16px; |
|
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
|
border: 1px solid rgba(255, 255, 255, 0.1); |
|
|
|
border-radius: 8px; |
|
|
|
color: #cccccc; |
|
|
|
cursor: pointer; |
|
|
|
transition: all 0.2s ease; |
|
|
|
font-size: 0.85rem; |
|
|
|
} |
|
|
|
|
|
|
|
.page-btn:hover:not(:disabled) { |
|
|
|
@ -303,6 +459,6 @@ onMounted(() => { |
|
|
|
|
|
|
|
.page-info { |
|
|
|
color: #888888; |
|
|
|
font-size: 0.9rem; |
|
|
|
font-size: 0.85rem; |
|
|
|
} |
|
|
|
</style> |