feat(payment): rebuild order details and asset records

This commit is contained in:
kate522 committed 2026-10-05 16:42:25 +08:00
1 parent 476e2f961d
commit 7b55cfb190
57 files changed
+2080 -1294

No files matched your search

+37 -44
View File
@@ -23,15 +23,13 @@
</n-form>
</n-card>
<n-card title="统一资产账本" class="aksrt-section-card">
<n-card title="用户近期资产记录" class="aksrt-section-card">
<n-space vertical :size="12">
<n-space wrap>
<n-select v-model:value="ledgerFilters.asset" :options="assetOptions" clearable placeholder="资产" style="width: 130px" />
<n-input v-model:value="ledgerFilters.transaction_id" placeholder="交易号" clearable style="width: 130px" />
<n-input v-model:value="ledgerFilters.operation_key" placeholder="幂等键" clearable style="width: 240px" />
<n-input v-model:value="ledgerFilters.ref_type" placeholder="引用类型" clearable style="width: 130px" />
<n-input v-model:value="ledgerFilters.ref_key" placeholder="引用键" clearable style="width: 180px" />
<n-input v-model:value="ledgerFilters.actor_user_id" placeholder="操作者 ID" clearable style="width: 130px" />
<n-input v-model:value="ledgerFilters.user_id" placeholder="用户 ID" clearable style="width: 130px" />
<n-select v-model:value="ledgerFilters.asset" :options="assetOptions" placeholder="资产" style="width: 130px" />
<n-input v-model:value="ledgerFilters.date_from" type="date" placeholder="开始日期" style="width: 160px" />
<n-input v-model:value="ledgerFilters.date_to" type="date" placeholder="结束日期" style="width: 160px" />
<n-button type="primary" :loading="ledgerLoading" @click="searchLedger">查询</n-button>
<n-button @click="resetLedger">重置</n-button>
</n-space>
@@ -40,13 +38,13 @@
:data="ledgerRows"
:loading="ledgerLoading"
:row-key="row => row.id"
:scroll-x="1600"
:scroll-x="1100"
size="small"
/>
<n-pagination
v-model:page="ledgerPage"
:page-count="ledgerPageCount"
:page-size="20"
:page-size="10"
@update:page="loadLedger"
/>
</n-space>
@@ -169,40 +167,41 @@ const ledgerRows = ref([])
const ledgerPage = ref(1)
const ledgerPageCount = ref(1)
const ledgerFilters = reactive({
asset: null,
transaction_id: '',
operation_key: '',
ref_type: '',
ref_key: '',
actor_user_id: '',
user_id: '',
asset: 'points',
date_from: '',
date_to: '',
})
const assetOptions = [
{ label: '积分', value: 'points' },
{ label: '余额', value: 'balance' },
]
const ledgerColumns = [
{ title: '交易号', key: 'transaction_label', width: 100, fixed: 'left' },
{ title: '幂等键', key: 'operation_key', width: 260, ellipsis: { tooltip: true } },
{ title: '资产', key: 'assets_label', width: 100 },
{ title: '原因', key: 'reason', width: 150, ellipsis: { tooltip: true } },
{ title: '业务引用', key: 'reference_label', width: 200, ellipsis: { tooltip: true } },
{ title: '操作者', key: 'actor_label', width: 100 },
{ title: '增减 / 手续费', key: 'delta_label', width: 180, ellipsis: { tooltip: true } },
{ title: '变动后余额', key: 'balance_label', width: 150, ellipsis: { tooltip: true } },
{ title: '备注', key: 'remark', width: 180, ellipsis: { tooltip: true } },
{ title: 'UTC 时间', key: 'created_at', width: 190 },
{ title: '类型', key: 'reason', width: 150 },
{ title: '订单号', key: 'ref_key', width: 200 },
{ title: '变动 / 变动后', key: 'delta_label', width: 190 },
{ title: '说明', key: 'remark', width: 240, ellipsis: { tooltip: true } },
{ title: '时间', key: 'created_at', width: 170 },
]
function formatAssetValue(asset, value) {
if (asset === 'balance') return typeof value === 'string' && /^[+-]?\d+\.\d{2}$/.test(value) ? value : '0.00'
const raw = String(value ?? '0')
return /^-?\d+$/.test(raw) ? raw : '0'
const raw = Number(value ?? 0)
if (!Number.isFinite(raw)) return asset === 'balance' ? '0.00' : '0'
if (asset !== 'balance') return String(raw)
const negative = raw < 0
const digits = String(Math.abs(Math.trunc(raw))).padStart(3, '0')
const whole = digits.slice(0, -2).replace(/^0+(?=\d)/, '')
return (negative ? '-' : '') + whole + '.' + digits.slice(-2)
}
async function loadLedger() {
ledgerLoading.value = true
try {
const params = { page: ledgerPage.value, per_page: 20 }
if (!/^\d+$/.test(String(ledgerFilters.user_id).trim())) {
message.warning('请输入用户 ID 后查询该用户近期记录')
return
}
const params = { page: ledgerPage.value, per_page: 10 }
Object.entries(ledgerFilters).forEach(([key, value]) => {
if (value !== null && String(value).trim() !== '') params[key] = value
})
@@ -210,23 +209,16 @@ async function loadLedger() {
const data = response?.data || response || {}
ledgerRows.value = (data.items || []).map((row) => {
const entries = Array.isArray(row.entries) ? row.entries : []
const entry = entries[0] || {}
return {
...row,
transaction_label: `#${row.id}`,
assets_label: (row.assets || []).join(' / '),
reference_label: [row.ref_type, row.ref_key].filter(Boolean).join(':') || '—',
actor_label: row.actor_user_id ? `#${row.actor_user_id}` : '系统',
delta_label: entries.map((entry) => {
const value = formatAssetValue(entry.asset, entry.delta)
const signed = entry.asset === 'points' && !value.startsWith('-') && value !== '0' ? `+${value}` : value
return `${entry.asset}:${signed}`
}).join(';'),
balance_label: entries.map((entry) => `${entry.asset}:${formatAssetValue(entry.asset, entry.balance_after)}`).join(';'),
delta_label: `${formatAssetValue(entry.asset, entry.delta)} / ${formatAssetValue(entry.asset, entry.balance_after)}`,
remark: row.remark || '—',
}
})
ledgerPageCount.value = Math.max(1, Math.ceil(Number(data.total || 0) / Number(data.per_page || 20)))
ledgerPageCount.value = Math.max(1, Math.ceil(Number(data.total || 0) / Number(data.per_page || 10)))
} catch (e) {
message.error(e.message || '加载账本失败')
message.error(e.message || '加载资产记录失败')
} finally {
ledgerLoading.value = false
}
@@ -238,8 +230,10 @@ function searchLedger() {
}
function resetLedger() {
Object.assign(ledgerFilters, { asset: null, transaction_id: '', operation_key: '', ref_type: '', ref_key: '', actor_user_id: '' })
searchLedger()
Object.assign(ledgerFilters, { user_id: '', asset: 'points', date_from: '', date_to: '' })
ledgerRows.value = []
ledgerPage.value = 1
ledgerPageCount.value = 1
}
async function loadCfg() {
@@ -270,6 +264,5 @@ async function saveCfg() {
onMounted(() => {
loadCfg()
loadLedger()
})
</script>
@@ -25,7 +25,6 @@ export const knowledgeSchema = {
payment_show_pay_time: true,
payment_order_status_pending: '待支付',
payment_order_status_paid: '已支付',
payment_order_status_refunding: '退款中',
payment_order_status_refunded: '已退款',
payment_order_status_closed: '已关闭',
pay_service: [],
@@ -136,7 +135,6 @@ export const knowledgeSchema = {
fields: [
{ key: 'payment_order_status_pending', label: '待支付状态文案', type: 'input', default: '待支付' },
{ key: 'payment_order_status_paid', label: '已支付状态文案', type: 'input', default: '已支付' },
{ key: 'payment_order_status_refunding', label: '退款中状态文案', type: 'input', default: '退款中' },
{ key: 'payment_order_status_refunded', label: '已退款状态文案', type: 'input', default: '已退款' },
{ key: 'payment_order_status_closed', label: '已关闭状态文案', type: 'input', default: '已关闭' },
],