1. 礼物特效
This commit is contained in:
@@ -76,6 +76,22 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center mb-3 gap-3 flex-wrap">
|
||||
<div>
|
||||
<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">
|
||||
<i class="fa-solid fa-rotate-right mr-1"></i>刷新
|
||||
</a-button>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 sm:grid-cols-4 gap-3 mb-5">
|
||||
<div v-for="g in giftTypeList" :key="g.key" class="stat-card">
|
||||
<div class="stat-label calligraphy">{{ g.label }}</div>
|
||||
<div class="stat-value">{{ giftStats.counts[g.key] || 0 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-5">
|
||||
<div class="chart-card">
|
||||
<div class="text-[12px] text-[#7a6550] mb-2 tracking-wide">地区分布</div>
|
||||
@@ -967,12 +983,13 @@ import { CanvasRenderer } from 'echarts/renderers'
|
||||
import {
|
||||
getConfigSection, saveConfigSection, uploadImage, getRsvpList, getUploadConfig, saveUploadConfig,
|
||||
getDanmakuList, updateDanmakuStatus, getVisitStats, getVisitList,
|
||||
getPosterConfig, savePosterConfig,
|
||||
getPosterConfig, savePosterConfig, getGiftStats,
|
||||
} from '@/api/wedding'
|
||||
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 } from '@/utils/giftTypes'
|
||||
import { getSlotResizeSpecs, resizeSlotToFile, probeResizedMeta, metaHasFileSize } from '@/composables/resizeImage'
|
||||
import {
|
||||
defaultPosterBundle, normalizePosterBundle, normalizePosterConfig,
|
||||
@@ -1026,6 +1043,12 @@ const danmakuFilter = ref('pending')
|
||||
|
||||
const visitStatsLoading = ref(false)
|
||||
const visitListLoading = ref(false)
|
||||
const giftStatsLoading = ref(false)
|
||||
const giftTypeList = GIFT_TYPES
|
||||
const giftStats = reactive({
|
||||
total: 0,
|
||||
counts: Object.fromEntries(GIFT_TYPES.map((g) => [g.key, 0])),
|
||||
})
|
||||
const visitStats = reactive({ uv: 0, pv: 0, today_uv: 0, regions: [], devices: [] })
|
||||
const visitList = ref([])
|
||||
const visitPreviewList = ref([])
|
||||
@@ -1695,6 +1718,23 @@ function renderDeviceChart() {
|
||||
)
|
||||
}
|
||||
|
||||
async function loadGiftStats() {
|
||||
giftStatsLoading.value = true
|
||||
try {
|
||||
const res = await getGiftStats()
|
||||
const d = res.data || {}
|
||||
const counts = d.counts || {}
|
||||
for (const g of GIFT_TYPES) {
|
||||
giftStats.counts[g.key] = Number(counts[g.key]) || 0
|
||||
}
|
||||
giftStats.total = Number(d.total) || Object.values(giftStats.counts).reduce((a, b) => a + b, 0)
|
||||
} catch (e) {
|
||||
message.error(e?.message || '加载礼物统计失败')
|
||||
} finally {
|
||||
giftStatsLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function loadVisitStats() {
|
||||
visitStatsLoading.value = true
|
||||
try {
|
||||
@@ -1747,7 +1787,7 @@ async function loadVisitList() {
|
||||
}
|
||||
|
||||
async function loadOverview() {
|
||||
await Promise.all([loadVisitStats(), loadVisitPreview()])
|
||||
await Promise.all([loadVisitStats(), loadVisitPreview(), loadGiftStats()])
|
||||
}
|
||||
|
||||
function onVisitTableChange(pag) {
|
||||
|
||||
Reference in New Issue
Block a user