feat embed wallets and add withdrawal records

This commit is contained in:
david
2026-07-29 15:29:49 +08:00
parent 0c94c8033a
commit a7d318a013
7 changed files with 102 additions and 32 deletions

View File

@@ -45,6 +45,14 @@
</a-tag>
</template>
</a-table-column>
<a-table-column v-if="definition.walletOwnerType" title="钱包" :width="150">
<template #cell="{ record }">
<span v-if="walletByOwner[String(record.identity)]">
¥{{ (Number(walletByOwner[String(record.identity)].balance ?? 0) / 100).toFixed(2) }}
</span>
<span v-else class="muted-text">未开通</span>
</template>
</a-table-column>
<a-table-column title="操作" :width="definition.accountManagement ? 350 : 280" fixed="right">
<template #cell="{ record }">
<a-space>
@@ -161,6 +169,7 @@ const pageSize = 20;
const total = ref(0);
const list = ref<Row[]>([]);
const accountCounts = ref<Record<string, number>>({});
const walletByOwner = ref<Record<string, Row>>({});
const filters = reactive({
keyword: typeof route.query.keyword === 'string' ? route.query.keyword : '',
});
@@ -236,15 +245,25 @@ const displayFields = computed(() =>
.filter((field) => field.key !== 'password')
.slice(0, 6),
);
const detailEntries = computed(() =>
Object.entries(detail.value).filter(
const detailEntries = computed(() => {
const entries = Object.entries(detail.value).filter(
([key, value]) =>
key !== 'id' &&
!key.endsWith('_id') &&
!Array.isArray(value) &&
!(value && typeof value === 'object' && key !== 'order' && key !== 'contract'),
),
);
);
if (props.definition.walletOwnerType) {
const wallet = walletByOwner.value[String(detail.value.identity ?? '')];
entries.push(['wallet', wallet ? {
identity: wallet.identity,
balance: `¥${(Number(wallet.balance ?? 0) / 100).toFixed(2)}`,
withdrawal_balance: `¥${(Number(wallet.withdrawal_balance ?? 0) / 100).toFixed(2)}`,
status: wallet.status,
} : '未开通']);
}
return entries;
});
const detailCollections = computed(() =>
Object.entries(detail.value)
.filter(([, value]) => Array.isArray(value) && value.length > 0)
@@ -323,6 +342,7 @@ async function load() {
total.value = result.total;
}
await loadAccountCounts();
await loadWallets();
} catch (error) {
Message.error((error as Error).message);
} finally {
@@ -330,6 +350,21 @@ async function load() {
}
}
async function loadWallets() {
const ownerType = props.definition.walletOwnerType;
if (!ownerType) {
walletByOwner.value = {};
return;
}
const wallets = await loadAllRows('/wallet_basic');
walletByOwner.value = wallets.reduce<Record<string, Row>>((result, wallet) => {
if (wallet.owner_type === ownerType) {
result[String(wallet.owner_identity ?? '')] = wallet;
}
return result;
}, {});
}
async function loadAllRows(resource: string) {
const rows: Row[] = [];
for (let currentPage = 1; currentPage <= 100; currentPage += 1) {
@@ -621,6 +656,7 @@ function fieldLabel(key: string) {
products: '合同气瓶',
order: '订单',
contract: '合同',
wallet: '钱包',
};
const normalizedKey = key.endsWith('_masked')
? key.slice(0, -'_masked'.length)
@@ -641,6 +677,10 @@ function relationLabel(field: ResourceField, identity: string) {
function displayFieldValue(field: ResourceField, row: Row) {
const value = row[field.key] ?? row[`${field.key}_masked`];
if (field.options) {
const option = field.options.find((item) => item.value === value);
if (option) return option.label;
}
if (
(field.type === 'identity' || field.type === 'identity-list') &&
typeof value === 'string'
@@ -754,6 +794,9 @@ function optionLabel(option: Row) {
padding: 12px;
background: var(--color-fill-1);
}
.muted-text {
color: var(--color-text-3);
}
.json-value {
max-height: 260px;
margin: 0;