|
@@ -5,12 +5,34 @@
|
|
|
<div class="myTable" :style="{ width: '100%', marginTop: '20px' }">
|
|
<div class="myTable" :style="{ width: '100%', marginTop: '20px' }">
|
|
|
<ElTable :data="tableData" stripe show-summary>
|
|
<ElTable :data="tableData" stripe show-summary>
|
|
|
<ElTableColumn prop="channel" label="渠道" align="center" />
|
|
<ElTableColumn prop="channel" label="渠道" align="center" />
|
|
|
- z
|
|
|
|
|
<ElTableColumn label="取码量" align="center">
|
|
<ElTableColumn label="取码量" align="center">
|
|
|
<ElTableColumn prop="yesterdayData" label="昨日数据" align="center" sortable />
|
|
<ElTableColumn prop="yesterdayData" label="昨日数据" align="center" sortable />
|
|
|
<ElTableColumn prop="todayData" label="今日数据" align="center" sortable />
|
|
<ElTableColumn prop="todayData" label="今日数据" align="center" sortable />
|
|
|
</ElTableColumn>
|
|
</ElTableColumn>
|
|
|
- <ElTableColumn prop="balance" label="余额" align="center" />
|
|
|
|
|
|
|
+ <ElTableColumn prop="balance" label="余额" align="center">
|
|
|
|
|
+ <template #default="{ row }">
|
|
|
|
|
+ <div style="display: flex; align-items: center; justify-content: center; gap: 8px">
|
|
|
|
|
+ <ElSkeleton style="width: 100%" animated :loading="row.balanceLoading" :count="1">
|
|
|
|
|
+ <template #template>
|
|
|
|
|
+ <div style="display: flex; align-items: center; justify-content: center">
|
|
|
|
|
+ <ElSkeletonItem variant="text" style="width: 100px"/>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ <template #default>
|
|
|
|
|
+ <span>{{ row.balance }}</span>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ElSkeleton>
|
|
|
|
|
+ <ElButton
|
|
|
|
|
+ v-if="row.balance === '超时'"
|
|
|
|
|
+ :icon="Refresh"
|
|
|
|
|
+ circle
|
|
|
|
|
+ text
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ @click="refreshChannelBalance(row.channel)"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ElTableColumn>
|
|
|
</ElTable>
|
|
</ElTable>
|
|
|
</div>
|
|
</div>
|
|
|
<div style="margin-top: 10px">
|
|
<div style="margin-top: 10px">
|
|
@@ -55,49 +77,79 @@ const numData = ref([])
|
|
|
const sentHourData = ref([])
|
|
const sentHourData = ref([])
|
|
|
const backupData = ref([])
|
|
const backupData = ref([])
|
|
|
|
|
|
|
|
|
|
+// 支持的平台列表
|
|
|
|
|
+const supportedPlatforms = {
|
|
|
|
|
+ durian: 0,
|
|
|
|
|
+ durian02: 0,
|
|
|
|
|
+ xyz: 0,
|
|
|
|
|
+ usapanel: 0,
|
|
|
|
|
+ dashboard: 0,
|
|
|
|
|
+ smspva: 0,
|
|
|
|
|
+ smspva02: 0,
|
|
|
|
|
+ smstiger: 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
- codeStatistics()
|
|
|
|
|
- hourSentStatistics()
|
|
|
|
|
- numStatistics()
|
|
|
|
|
- backupStatistics()
|
|
|
|
|
|
|
+ refresh()
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
async function refresh() {
|
|
async function refresh() {
|
|
|
- codeStatistics()
|
|
|
|
|
- hourSentStatistics()
|
|
|
|
|
- numStatistics()
|
|
|
|
|
- backupStatistics()
|
|
|
|
|
|
|
+ await Promise.all([
|
|
|
|
|
+ codeStatistics(),
|
|
|
|
|
+ hourSentStatistics(),
|
|
|
|
|
+ numStatistics(),
|
|
|
|
|
+ backupStatistics()
|
|
|
|
|
+ ])
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async function codeStatistics() {
|
|
async function codeStatistics() {
|
|
|
tableData.value = []
|
|
tableData.value = []
|
|
|
const quantityResponse = await http.get('/task/codeStatistics')
|
|
const quantityResponse = await http.get('/task/codeStatistics')
|
|
|
- const balanceResponse = await http.get('/task/balanceStatistics')
|
|
|
|
|
-
|
|
|
|
|
- // 将余额数据转为 Map,方便后续快速查找
|
|
|
|
|
- const balanceMap = new Map(Object.entries(balanceResponse))
|
|
|
|
|
|
|
|
|
|
- // 遍历数量数据,将数量和余额合并
|
|
|
|
|
- quantityResponse.forEach((item) => {
|
|
|
|
|
- const balance = balanceMap.get(item.channel)
|
|
|
|
|
- tableData.value.push({
|
|
|
|
|
- channel: item.channel,
|
|
|
|
|
|
|
+ const dataMap = new Map(
|
|
|
|
|
+ quantityResponse.map(item => [item.channel, {
|
|
|
todayData: parseInt(item.todayData, 10) || 0,
|
|
todayData: parseInt(item.todayData, 10) || 0,
|
|
|
- yesterdayData: parseInt(item.yesterdayData, 10) || 0,
|
|
|
|
|
- balance: balance !== undefined ? parseInt(balance, 10) : '-'
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ yesterdayData: parseInt(item.yesterdayData, 10) || 0
|
|
|
|
|
+ }])
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
- balanceMap.delete(item.channel)
|
|
|
|
|
|
|
+ tableData.value = Object.keys(supportedPlatforms).map(channel => {
|
|
|
|
|
+ const data = dataMap.get(channel) || { todayData: 0, yesterdayData: 0 }
|
|
|
|
|
+ return {
|
|
|
|
|
+ channel,
|
|
|
|
|
+ todayData: data.todayData,
|
|
|
|
|
+ yesterdayData: data.yesterdayData,
|
|
|
|
|
+ balance: 0,
|
|
|
|
|
+ balanceLoading: false
|
|
|
|
|
+ }
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- for (const [channel, balance] of balanceMap) {
|
|
|
|
|
- tableData.value.push({
|
|
|
|
|
- channel,
|
|
|
|
|
- todayData: 0,
|
|
|
|
|
- yesterdayData: 0,
|
|
|
|
|
- balance: parseInt(balance, 10)
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const balancePromises = tableData.value.map(row => {
|
|
|
|
|
+ if (row.channel in supportedPlatforms) {
|
|
|
|
|
+ row.balanceLoading = true
|
|
|
|
|
+ return Promise.race([
|
|
|
|
|
+ http.get(`/task/balanceStatistics/${row.channel}`)
|
|
|
|
|
+ .then(response => {
|
|
|
|
|
+ const balance = response[row.channel]
|
|
|
|
|
+ row.balance = balance ? parseFloat(balance).toFixed(4) : 0
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(error => {
|
|
|
|
|
+ console.error(`获取${row.channel}余额失败:`, error)
|
|
|
|
|
+ row.balance = error.message === 'Timeout' ? '超时' : 0
|
|
|
|
|
+ })
|
|
|
|
|
+ .finally(() => {
|
|
|
|
|
+ row.balanceLoading = false
|
|
|
|
|
+ }),
|
|
|
|
|
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 15000))
|
|
|
|
|
+ ]).catch((error) => {
|
|
|
|
|
+ row.balance = error.message === 'Timeout' ? '超时' : 0
|
|
|
|
|
+ row.balanceLoading = false
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ return Promise.resolve()
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ await Promise.all(balancePromises)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async function hourSentStatistics() {
|
|
async function hourSentStatistics() {
|
|
@@ -114,4 +166,30 @@ async function backupStatistics() {
|
|
|
backupData.value = []
|
|
backupData.value = []
|
|
|
backupData.value = await http.get(`/task/backupStatistics`)
|
|
backupData.value = await http.get(`/task/backupStatistics`)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+async function refreshChannelBalance(channel) {
|
|
|
|
|
+ const row = tableData.value.find(item => item.channel === channel)
|
|
|
|
|
+ if (!row) return
|
|
|
|
|
+
|
|
|
|
|
+ row.balanceLoading = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const response = await Promise.race([
|
|
|
|
|
+ http.get(`/task/balanceStatistics/${channel}`),
|
|
|
|
|
+ new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 30000))
|
|
|
|
|
+ ])
|
|
|
|
|
+ const balance = response[channel]
|
|
|
|
|
+ row.balance = balance ? parseFloat(balance).toFixed(4) : 0
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error(`获取${channel}余额失败:`, error)
|
|
|
|
|
+ row.balance = error.message === 'Timeout' ? '超时' : 0
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ row.balanceLoading = false
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.el-skeleton {
|
|
|
|
|
+ --el-skeleton-text-width: 100%;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|