1. 后台看礼物记录

This commit is contained in:
李琦
2026-08-03 15:15:12 +08:00
parent e1997bafa8
commit 98acccef52
4 changed files with 466 additions and 9 deletions

View File

@@ -197,7 +197,7 @@
<div class="text-sm text-[#2c2c2c]">礼物统计</div>
<div class="text-[11px] text-[#8A8680] mt-0.5">各礼物收到次数 · 合计 {{ giftStats.total }}</div>
</div>
<a-button size="small" :loading="giftStatsLoading" @click="loadGiftStats">
<a-button size="small" :loading="giftStatsLoading || giftListLoading" @click="() => Promise.all([loadGiftStats(), loadGiftList()])">
<i class="fa-solid fa-rotate-right mr-1"></i>刷新
</a-button>
</div>
@@ -234,6 +234,41 @@
/>
</div>
</div>
<div class="flex justify-between items-center mt-8 mb-3 gap-3 flex-wrap">
<div>
<div class="text-sm text-[#2c2c2c]">礼物明细</div>
<div class="text-[11px] text-[#8A8680] mt-0.5"> {{ giftList.length }} 条送礼记录</div>
</div>
<a-button size="small" :loading="giftListLoading" @click="loadGiftList">
<i class="fa-solid fa-rotate-right mr-1"></i>刷新列表
</a-button>
</div>
<a-table
class="admin-table"
:columns="giftListColumns"
:data-source="giftList"
:loading="giftListLoading"
row-key="id"
size="middle"
:pagination="{ pageSize: 10, hideOnSinglePage: true }"
:scroll="{ x: 720 }"
>
<template #bodyCell="{ column, record }">
<template v-if="column.key === 'gift_type'">
<span class="admin-pill admin-pill--rose">{{ giftTypeLabel(record.gift_type) }}</span>
</template>
<template v-else-if="column.key === 'cost'">
<span>{{ record.cost || 0 }} </span>
</template>
<template v-else-if="column.key === 'created_at'">
<span class="text-[12px] text-[#8A8680]">{{ formatTime(record.created_at) }}</span>
</template>
<template v-else-if="column.key === 'actions'">
<a-button size="small" danger type="text" @click="onDeleteGift(record)">删除</a-button>
</template>
</template>
</a-table>
</div>
</section>
@@ -1301,7 +1336,7 @@ import { CanvasRenderer } from 'echarts/renderers'
import {
getConfigSection, saveConfigSection, uploadImage, getRsvpList, deleteRsvp, getUploadConfig, saveUploadConfig,
getDanmakuList, updateDanmakuStatus, getVisitStats, getVisitList,
getPosterConfig, savePosterConfig, getGiftStats, saveGiftCosts,
getPosterConfig, savePosterConfig, getGiftStats, getGiftList, deleteGift, saveGiftCosts,
getCashGiftList, updateCashGift, deleteCashGift, submitCashGift,
getCashGiftNotes, saveCashGiftNotes,
getCashGiftViewPass, saveCashGiftViewPass,
@@ -1311,7 +1346,7 @@ import { useAdminStore } from '@/stores/admin'
import ImageField from '@/components/ImageField.vue'
import { BORDER_STYLES, borderClass } from '@/composables/borderStyles'
import { resolveDanmakuSwatch } from '@/utils/danmakuColors'
import { GIFT_TYPES, emptyGiftCosts, DEFAULT_GIFT_COSTS } from '@/utils/giftTypes'
import { GIFT_TYPES, GIFT_LABEL_MAP, emptyGiftCosts, DEFAULT_GIFT_COSTS } from '@/utils/giftTypes'
import { getSlotResizeSpecs, resizeSlotToFile, probeResizedMeta, metaHasFileSize } from '@/composables/resizeImage'
import {
defaultPosterBundle, normalizePosterBundle, normalizePosterConfig,
@@ -1451,8 +1486,10 @@ const danmakuFilter = ref('pending')
const visitStatsLoading = ref(false)
const visitListLoading = ref(false)
const giftStatsLoading = ref(false)
const giftListLoading = ref(false)
const giftCostsSaving = ref(false)
const giftTypeList = GIFT_TYPES
const giftList = ref([])
const giftStats = reactive({
total: 0,
counts: Object.fromEntries(GIFT_TYPES.map((g) => [g.key, 0])),
@@ -2261,6 +2298,39 @@ async function loadGiftStats() {
}
}
const giftListColumns = [
{ title: '姓名', dataIndex: 'name', key: 'name', width: 120 },
{ title: '礼物', dataIndex: 'gift_type', key: 'gift_type', width: 120 },
{ title: '消耗', dataIndex: 'cost', key: 'cost', width: 90 },
{ title: '时间', dataIndex: 'created_at', key: 'created_at', width: 170 },
{ title: '操作', key: 'actions', width: 90 },
]
const giftTypeLabel = (key) => GIFT_LABEL_MAP[key] || key || '—'
async function loadGiftList() {
giftListLoading.value = true
try {
const res = await getGiftList()
const data = res.data || {}
giftList.value = Array.isArray(data.list) ? data.list : (Array.isArray(data) ? data : [])
} catch (e) {
giftList.value = []
message.error(e?.message || '加载礼物明细失败')
} finally {
giftListLoading.value = false
}
}
async function onDeleteGift(record) {
try {
await deleteGift(record.id)
message.success('已删除')
await Promise.all([loadGiftList(), loadGiftStats()])
} catch (e) {
message.error(e?.message || '删除失败')
}
}
async function loadVisitStats() {
visitStatsLoading.value = true
try {
@@ -2330,7 +2400,7 @@ async function onTabActivate(tab) {
return
}
if (tab === 'gifts') {
await loadGiftStats()
await Promise.all([loadGiftStats(), loadGiftList()])
return
}
if (tab === 'visits') {