3 changed files with 303 additions and 0 deletions
|
After Width: | Height: | Size: 304 B |
@ -0,0 +1,292 @@ |
|||||
|
<script setup lang="ts"> |
||||
|
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' |
||||
|
import bagIcon from '@/assets/images/bag.svg' |
||||
|
|
||||
|
const router = useRouter() |
||||
|
const bagStore = useBagStore() |
||||
|
const characterStore = useCharacterStore() |
||||
|
|
||||
|
const bagName = computed(() => bagStore.characterBag?.bagName || '背包') |
||||
|
const bagCapacity = computed(() => bagStore.characterBag?.bagCapacity || 0) |
||||
|
const usedCapacity = computed(() => bagStore.usedCapacity) |
||||
|
|
||||
|
const itemTypeMap: Record<number, string> = { |
||||
|
1: '装备', |
||||
|
2: '丹药' |
||||
|
} |
||||
|
|
||||
|
const rarityMap: Record<number, string> = { |
||||
|
1: '普通', |
||||
|
2: '稀有', |
||||
|
3: '史诗', |
||||
|
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 handleBack = () => { |
||||
|
router.push('/game') |
||||
|
} |
||||
|
|
||||
|
onMounted(() => { |
||||
|
bagStore.loadBag() |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<template> |
||||
|
<div class="bag-page"> |
||||
|
<Particles :particle-count="30" :particle-colors="['#ffffff', '#cccccc']" class="particles-bg" /> |
||||
|
|
||||
|
<div class="bag-container"> |
||||
|
<StarBorder as="div" color="#8b5cf6" speed="5s" :thickness="2" class="back-btn" @click="handleBack"> |
||||
|
<div class="back-content"> |
||||
|
<el-icon><ArrowLeft /></el-icon> |
||||
|
<span>返回</span> |
||||
|
</div> |
||||
|
</StarBorder> |
||||
|
|
||||
|
<div class="bag-header"> |
||||
|
<div class="header-left"> |
||||
|
<img :src="bagIcon" class="header-icon" /> |
||||
|
<h2>{{ bagName }}</h2> |
||||
|
</div> |
||||
|
<span class="capacity">{{ usedCapacity }} / {{ bagCapacity }}</span> |
||||
|
</div> |
||||
|
|
||||
|
<div v-if="bagStore.loading" class="loading"> |
||||
|
加载中... |
||||
|
</div> |
||||
|
|
||||
|
<div v-else-if="bagStore.error" class="error"> |
||||
|
{{ bagStore.error }} |
||||
|
</div> |
||||
|
|
||||
|
<div v-else-if="bagStore.totalItems === 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"> |
||||
|
<div 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> |
||||
|
</el-tooltip> |
||||
|
</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> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<style scoped> |
||||
|
.bag-page { |
||||
|
min-height: 100vh; |
||||
|
background: #000000; |
||||
|
padding: 20px; |
||||
|
position: relative; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.particles-bg { |
||||
|
position: fixed !important; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
width: 100% !important; |
||||
|
height: 100% !important; |
||||
|
} |
||||
|
|
||||
|
.bag-container { |
||||
|
max-width: 480px; |
||||
|
margin: 0 auto; |
||||
|
position: relative; |
||||
|
z-index: 10; |
||||
|
} |
||||
|
|
||||
|
.back-btn { |
||||
|
margin-bottom: 20px; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
|
||||
|
.back-content { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 8px; |
||||
|
padding: 8px 16px; |
||||
|
cursor: pointer; |
||||
|
color: #cccccc; |
||||
|
background: rgba(255, 255, 255, 0.03); |
||||
|
border: 1px solid rgba(255, 255, 255, 0.08); |
||||
|
border-radius: 8px; |
||||
|
} |
||||
|
|
||||
|
.bag-header { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
margin-bottom: 24px; |
||||
|
padding: 16px 20px; |
||||
|
background: rgba(255, 255, 255, 0.03); |
||||
|
border: 1px solid rgba(255, 255, 255, 0.08); |
||||
|
border-radius: 12px; |
||||
|
} |
||||
|
|
||||
|
.header-left { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 12px; |
||||
|
} |
||||
|
|
||||
|
.header-icon { |
||||
|
width: 28px; |
||||
|
height: 28px; |
||||
|
object-fit: contain; |
||||
|
} |
||||
|
|
||||
|
.bag-header h2 { |
||||
|
margin: 0; |
||||
|
color: #ffffff; |
||||
|
font-size: 1.25rem; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.capacity { |
||||
|
color: #888888; |
||||
|
font-size: 0.9rem; |
||||
|
} |
||||
|
|
||||
|
.loading, .error, .empty { |
||||
|
text-align: center; |
||||
|
padding: 40px; |
||||
|
color: #888888; |
||||
|
} |
||||
|
|
||||
|
.error { |
||||
|
color: #ff4444; |
||||
|
} |
||||
|
|
||||
|
.items-grid { |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(4, 1fr); |
||||
|
gap: 12px; |
||||
|
margin-bottom: 24px; |
||||
|
} |
||||
|
|
||||
|
.item-cell { |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 16px 8px; |
||||
|
background: rgba(255, 255, 255, 0.03); |
||||
|
border: 1px solid rgba(255, 255, 255, 0.08); |
||||
|
border-radius: 12px; |
||||
|
cursor: pointer; |
||||
|
transition: all 0.2s ease; |
||||
|
} |
||||
|
|
||||
|
.item-cell:hover { |
||||
|
background: rgba(255, 255, 255, 0.06); |
||||
|
border-color: rgba(255, 255, 255, 0.15); |
||||
|
} |
||||
|
|
||||
|
.item-icon { |
||||
|
font-size: 2rem; |
||||
|
margin-bottom: 8px; |
||||
|
} |
||||
|
|
||||
|
.item-name { |
||||
|
color: #cccccc; |
||||
|
font-size: 0.75rem; |
||||
|
text-align: center; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.item-count { |
||||
|
position: absolute; |
||||
|
top: 4px; |
||||
|
right: 4px; |
||||
|
background: rgba(139, 92, 246, 0.8); |
||||
|
color: #ffffff; |
||||
|
font-size: 0.65rem; |
||||
|
padding: 2px 6px; |
||||
|
border-radius: 8px; |
||||
|
min-width: 18px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.rarity-1 { filter: grayscale(0.3); } |
||||
|
.rarity-2 { filter: hue-rotate(80deg) saturate(1.5); } |
||||
|
.rarity-3 { filter: hue-rotate(200deg) saturate(2); } |
||||
|
.rarity-4 { filter: hue-rotate(-30deg) saturate(2) brightness(1.2); } |
||||
|
|
||||
|
.pagination { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
gap: 16px; |
||||
|
} |
||||
|
|
||||
|
.page-btn { |
||||
|
padding: 10px 20px; |
||||
|
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; |
||||
|
} |
||||
|
|
||||
|
.page-btn:hover:not(:disabled) { |
||||
|
background: rgba(255, 255, 255, 0.1); |
||||
|
} |
||||
|
|
||||
|
.page-btn:disabled { |
||||
|
opacity: 0.4; |
||||
|
cursor: not-allowed; |
||||
|
} |
||||
|
|
||||
|
.page-info { |
||||
|
color: #888888; |
||||
|
font-size: 0.9rem; |
||||
|
} |
||||
|
</style> |
||||
Loading…
Reference in new issue