新增财务仪表盘并统一金额到角
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
<script setup lang="ts">
|
||||
import { Refresh, Search } from '@element-plus/icons-vue'
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
|
||||
import {
|
||||
fetchFinanceDashboard,
|
||||
type FinanceDashboard,
|
||||
type FinanceDailyItem,
|
||||
} from '@/features/admin/api/adminFinance'
|
||||
import { formatMoneyWithSymbol } from '@/shared/utils/money'
|
||||
import { formatDateTime } from '@/utils/time'
|
||||
|
||||
const loading = ref(false)
|
||||
const dashboard = ref<FinanceDashboard | null>(null)
|
||||
const filters = reactive({
|
||||
start_date: defaultStartDate(),
|
||||
end_date: defaultEndDate(),
|
||||
})
|
||||
|
||||
const dailyItems = computed(() => dashboard.value?.daily_items ?? [])
|
||||
|
||||
onMounted(loadDashboard)
|
||||
|
||||
async function loadDashboard() {
|
||||
loading.value = true
|
||||
try {
|
||||
dashboard.value = await fetchFinanceDashboard(filters)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function moneyCent(value: number) {
|
||||
return formatMoneyWithSymbol(Number(value || 0) / 100)
|
||||
}
|
||||
|
||||
function money(value: number) {
|
||||
return formatMoneyWithSymbol(value)
|
||||
}
|
||||
|
||||
function defaultStartDate() {
|
||||
const date = new Date()
|
||||
date.setDate(date.getDate() - 6)
|
||||
return formatInputDate(date)
|
||||
}
|
||||
|
||||
function defaultEndDate() {
|
||||
return formatInputDate(new Date())
|
||||
}
|
||||
|
||||
function formatInputDate(date: Date) {
|
||||
return date.toISOString().slice(0, 10)
|
||||
}
|
||||
|
||||
function diffType(value: number) {
|
||||
return Math.abs(Number(value || 0)) >= 0.05 ? 'danger' : 'success'
|
||||
}
|
||||
|
||||
function rowDiffClass(row: FinanceDailyItem) {
|
||||
return Math.abs(Number(row.settlement_diff_amount || 0)) >= 0.05 ? 'amount-danger' : ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="page">
|
||||
<div class="page-header-row">
|
||||
<div class="page-header">
|
||||
<p class="eyebrow">Finance Dashboard</p>
|
||||
<h1>财务仪表盘</h1>
|
||||
<p>按天查看第三方收款退款、平台收入、号主入账和结算差异。</p>
|
||||
</div>
|
||||
<div class="toolbar-actions">
|
||||
<el-date-picker
|
||||
v-model="filters.start_date"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="开始日期"
|
||||
/>
|
||||
<el-date-picker
|
||||
v-model="filters.end_date"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="结束日期"
|
||||
/>
|
||||
<el-button type="primary" :icon="Search" :loading="loading" @click="loadDashboard">
|
||||
查询
|
||||
</el-button>
|
||||
<el-button :icon="Refresh" :loading="loading" @click="loadDashboard">刷新</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="dashboard" class="metric-grid">
|
||||
<div class="metric-card">
|
||||
<span>总流水</span>
|
||||
<strong>{{ moneyCent(dashboard.summary.total_flow_amount_cent) }}</strong>
|
||||
<small>{{ dashboard.summary.successful_pay_count }} 笔成功收款</small>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>总退款</span>
|
||||
<strong>{{ moneyCent(dashboard.summary.total_refund_amount_cent) }}</strong>
|
||||
<small>{{ dashboard.summary.successful_refund_count }} 笔成功退款</small>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>渠道净流入</span>
|
||||
<strong>{{ moneyCent(dashboard.summary.channel_net_amount_cent) }}</strong>
|
||||
<small>成功收款 - 成功退款</small>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>平台收入</span>
|
||||
<strong>{{ money(dashboard.summary.platform_income_amount) }}</strong>
|
||||
<small>{{ dashboard.summary.settled_order_count }} 个已结算订单</small>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>号主应得</span>
|
||||
<strong>{{ money(dashboard.summary.owner_should_income_amount) }}</strong>
|
||||
<small>结账单口径</small>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>号主实际入账</span>
|
||||
<strong>{{ money(dashboard.summary.owner_wallet_income_amount) }}</strong>
|
||||
<small>钱包流水口径</small>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>退款中</span>
|
||||
<strong>{{ moneyCent(dashboard.summary.pending_refund_amount_cent) }}</strong>
|
||||
<small>{{ dashboard.summary.pending_refund_count }} 笔待回执</small>
|
||||
</div>
|
||||
<div class="metric-card">
|
||||
<span>结算差异</span>
|
||||
<strong>
|
||||
<el-tag :type="diffType(dashboard.summary.settlement_diff_amount)">
|
||||
{{ money(dashboard.summary.settlement_diff_amount) }}
|
||||
</el-tag>
|
||||
</strong>
|
||||
<small>{{ dashboard.summary.financial_exception_count }} 个异常订单</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-table v-loading="loading" class="table-panel" :data="dailyItems">
|
||||
<el-table-column prop="date" label="日期" width="130" />
|
||||
<el-table-column label="总流水" width="130">
|
||||
<template #default="{ row }">{{ moneyCent(row.total_flow_amount_cent) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="总退款" width="130">
|
||||
<template #default="{ row }">{{ moneyCent(row.total_refund_amount_cent) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="渠道净流入" width="140">
|
||||
<template #default="{ row }">{{ moneyCent(row.channel_net_amount_cent) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="平台收入" width="130">
|
||||
<template #default="{ row }">{{ money(row.platform_income_amount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="号主应得" width="130">
|
||||
<template #default="{ row }">{{ money(row.owner_should_income_amount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="号主入账" width="130">
|
||||
<template #default="{ row }">{{ money(row.owner_wallet_income_amount) }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结算差异" width="130">
|
||||
<template #default="{ row }">
|
||||
<span :class="rowDiffClass(row)">{{ money(row.settlement_diff_amount) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收款/退款/结算" min-width="170">
|
||||
<template #default="{ row }">
|
||||
{{ row.successful_pay_count }} / {{ row.successful_refund_count }} /
|
||||
{{ row.settled_order_count }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<p v-if="dashboard" class="generated-at">
|
||||
数据生成时间:{{ formatDateTime(dashboard.generated_at) }}
|
||||
</p>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.amount-danger {
|
||||
color: #dc2626;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.generated-at {
|
||||
margin: 12px 0 0;
|
||||
color: #64748b;
|
||||
font-size: 13px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user