积分与余额账务系统硬切重构
This commit is contained in:
1 parent
ca12226b39
commit
5cae5b5c93
159 files changed
+7275
-4718
No files matched your search
@@ -49,7 +49,7 @@
|
||||
</div>
|
||||
<n-empty v-else size="small" description="暂无数据" />
|
||||
<div class="aksrt-revenue__chart-summary">
|
||||
<span>期间总计: <strong>{{ formatAmount(group.total, group.key) }}</strong></span>
|
||||
<span>期间总计: <strong>{{ formatAmount(group.total, group.key) }}</strong></span>
|
||||
<span>共 {{ group.count }} 笔</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,7 +91,7 @@
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<div class="aksrt-revenue__stat">
|
||||
<strong>{{ withdrawalStats.total_paid.toFixed(2) }}</strong>
|
||||
<strong>{{ formatAmount(withdrawalStats.total_paid, 'cash') }}</strong>
|
||||
<p>已提现 (元)</p>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
@@ -106,16 +106,21 @@ import { ref, computed, onMounted } from 'vue'
|
||||
import PaymentSectionPage from '@/pages/payment/PaymentSectionPage.vue'
|
||||
import api from '@/api'
|
||||
|
||||
const emptyCurrencyStats = () => ({ total: 0, pending: 0, settled: 0, count: 0 })
|
||||
const revenueStats = ref({ cash: emptyCurrencyStats(), points: emptyCurrencyStats() })
|
||||
const withdrawalStats = ref({ total: 0, pending: 0, processing: 0, completed: 0, rejected: 0, total_paid: 0 })
|
||||
const emptyCurrencyStats = (currency) => ({
|
||||
total: currency === 'cash' ? '0.00' : 0,
|
||||
pending: currency === 'cash' ? '0.00' : 0,
|
||||
settled: currency === 'cash' ? '0.00' : 0,
|
||||
count: 0,
|
||||
})
|
||||
const revenueStats = ref({ cash: emptyCurrencyStats('cash'), points: emptyCurrencyStats('points') })
|
||||
const withdrawalStats = ref({ total: 0, pending: 0, processing: 0, completed: 0, rejected: 0, total_paid: '0.00' })
|
||||
const timeSeries = ref({ cash: [], points: [] })
|
||||
const granularity = ref('day')
|
||||
|
||||
const revenueSummary = computed(() => [
|
||||
{ key: 'cash-total', value: `${revenueStats.value.cash.total.toFixed(2)} 元`, label: '现金总收益' },
|
||||
{ key: 'cash-pending', value: `${revenueStats.value.cash.pending.toFixed(2)} 元`, label: '现金待结算' },
|
||||
{ key: 'cash-settled', value: `${revenueStats.value.cash.settled.toFixed(2)} 元`, label: '现金已结算' },
|
||||
{ key: 'cash-total', value: `${formatAmount(revenueStats.value.cash.total, 'cash')} 元`, label: '现金总收益' },
|
||||
{ key: 'cash-pending', value: `${formatAmount(revenueStats.value.cash.pending, 'cash')} 元`, label: '现金待结算' },
|
||||
{ key: 'cash-settled', value: `${formatAmount(revenueStats.value.cash.settled, 'cash')} 元`, label: '现金已结算' },
|
||||
{ key: 'cash-count', value: revenueStats.value.cash.count, label: '现金收益笔数' },
|
||||
{ key: 'points-total', value: `${formatAmount(revenueStats.value.points.total, 'points')}`, label: '积分总收益' },
|
||||
{ key: 'points-pending', value: `${formatAmount(revenueStats.value.points.pending, 'points')}`, label: '积分待结算' },
|
||||
@@ -134,21 +139,44 @@ const timeSeriesGroups = computed(() => [
|
||||
label: '积分收益',
|
||||
items: Array.isArray(timeSeries.value.points) ? timeSeries.value.points : [],
|
||||
},
|
||||
].map((group) => ({
|
||||
...group,
|
||||
total: group.items.reduce((sum, item) => sum + Number(item.amount || 0), 0),
|
||||
count: group.items.reduce((sum, item) => sum + Number(item.count || 0), 0),
|
||||
})))
|
||||
].map((group) => {
|
||||
const totalMinor = group.items.reduce((sum, item) => sum + amountMinor(item.amount, group.key), 0n)
|
||||
return {
|
||||
...group,
|
||||
total: formatMinor(totalMinor, group.key),
|
||||
count: group.items.reduce((sum, item) => sum + Number(item.count || 0), 0),
|
||||
}
|
||||
}))
|
||||
|
||||
const hasTimeSeries = computed(() => timeSeriesGroups.value.some((group) => group.items.length > 0))
|
||||
|
||||
function formatAmount(amount, currency) {
|
||||
return currency === 'points' ? `${Number(amount || 0).toFixed(0)} 积分` : `¥${Number(amount || 0).toFixed(2)}`
|
||||
return currency === 'points'
|
||||
? `${formatMinor(amountMinor(amount, currency), currency)} 积分`
|
||||
: `¥${formatMinor(amountMinor(amount, currency), currency)}`
|
||||
}
|
||||
|
||||
function amountMinor(amount, currency) {
|
||||
const raw = String(amount ?? '').trim()
|
||||
if (currency === 'points') return /^\d+$/.test(raw) ? BigInt(raw) : 0n
|
||||
const match = /^(0|[1-9]\d*)(?:\.(\d{1,2}))?$/.exec(raw)
|
||||
return match ? (BigInt(match[1]) * 100n) + BigInt((match[2] || '').padEnd(2, '0') || '0') : 0n
|
||||
}
|
||||
|
||||
function formatMinor(minor, currency) {
|
||||
if (currency === 'points') return String(minor)
|
||||
return `${minor / 100n}.${String(minor % 100n).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
function getBarHeight(amount, items) {
|
||||
const maxAmount = Math.max(1, ...items.map((item) => Number(item.amount || 0)))
|
||||
return Math.max(2, (Number(amount || 0) / maxAmount) * 100)
|
||||
const currency = items === timeSeries.value.points ? 'points' : 'cash'
|
||||
const maxAmount = items.reduce((max, item) => {
|
||||
const current = amountMinor(item.amount, currency)
|
||||
return current > max ? current : max
|
||||
}, 0n)
|
||||
if (maxAmount <= 0n) return 2
|
||||
const scaled = Number((amountMinor(amount, currency) * 10000n) / maxAmount) / 100
|
||||
return Math.max(2, scaled)
|
||||
}
|
||||
|
||||
function formatLabel(date) {
|
||||
@@ -170,8 +198,8 @@ async function loadRevenue() {
|
||||
if (res?.data) {
|
||||
if (res.data.revenue) {
|
||||
revenueStats.value = {
|
||||
cash: { ...emptyCurrencyStats(), ...(res.data.revenue.cash || {}) },
|
||||
points: { ...emptyCurrencyStats(), ...(res.data.revenue.points || {}) },
|
||||
cash: { ...emptyCurrencyStats('cash'), ...(res.data.revenue.cash || {}) },
|
||||
points: { ...emptyCurrencyStats('points'), ...(res.data.revenue.points || {}) },
|
||||
}
|
||||
}
|
||||
if (res.data.withdrawal) {
|
||||
@@ -181,7 +209,7 @@ async function loadRevenue() {
|
||||
processing: Number(res.data.withdrawal.processing || 0),
|
||||
completed: Number(res.data.withdrawal.completed || 0),
|
||||
rejected: Number(res.data.withdrawal.rejected || 0),
|
||||
total_paid: Number(res.data.withdrawal.total_paid || 0),
|
||||
total_paid: String(res.data.withdrawal.total_paid || '0.00'),
|
||||
}
|
||||
}
|
||||
timeSeries.value = {
|
||||
|
||||
Reference in new issue
Block a user