This commit is contained in:
zlwu committed 2026-05-24 23:04:33 +08:00
1 parent 13e4c9530a
commit 575e63e7e8
62 files changed
+28759 -9636

No files matched your search

File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -177,6 +177,80 @@
<el-empty v-else description="暂无邮寄地址" :image-size="48" />
</div>
<div id="view-section-account" class="section-card section-card--white">
<div class="section-title"><h3>账户信息</h3></div>
<div class="account-balance-card">
<div class="account-balance-card__label">账户余额</div>
<div class="account-balance-card__value">
¥ {{ accountLoading ? '—' : formatAmount(accountData?.balanceAmount) }}
</div>
</div>
<div class="account-quotas-head">
<h4 class="account-quotas-title">产品份数</h4>
</div>
<div v-if="quotasLoading" v-loading="true" style="min-height: 120px"></div>
<div v-else-if="productQuotas.length" class="list-body list-wrap account-quota-list-wrap">
<el-table
:data="productQuotas"
class="list-table account-quota-table"
stripe
row-key="id"
max-height="360"
>
<el-table-column
type="index"
label="序号"
min-width="68"
align="center"
header-align="center"
/>
<el-table-column
prop="projectName"
label="项目名称"
min-width="150"
align="center"
header-align="center"
/>
<el-table-column
prop="cellTypeName"
label="细胞类型"
min-width="120"
align="center"
header-align="center"
/>
<el-table-column
prop="specText"
label="规格"
min-width="150"
align="center"
header-align="center"
/>
<el-table-column
prop="totalQty"
label="总份数"
min-width="100"
align="center"
header-align="center"
/>
<el-table-column
prop="usedQty"
label="已用份数"
min-width="100"
align="center"
header-align="center"
/>
<el-table-column
prop="remainingQty"
label="剩余份数"
min-width="100"
align="center"
header-align="center"
/>
</el-table>
</div>
<el-empty v-else description="暂无产品份数数据" :image-size="48" />
</div>
<div id="view-section-agreement" class="section-card">
<div class="section-title"><h3>协议信息</h3></div>
<div v-if="agreementList.length" class="agreement-cards">
@@ -354,7 +428,9 @@
fetchChannelInvoices,
fetchChannelMailAddresses,
fetchChannelAgreements,
fetchChannelAgreementPrices
fetchChannelAgreementPrices,
fetchChannelAccount,
fetchChannelProductQuotas
} from '@/api/admin'
const props = defineProps<{
@@ -371,7 +447,8 @@
{ key: 'basic', label: '基础信息' },
{ key: 'invoice', label: '开票信息' },
{ key: 'mail', label: '邮寄地址' },
{ key: 'agreement', label: '协议信息' }
{ key: 'agreement', label: '协议信息' },
{ key: 'account', label: '账户信息' }
] as const
const loading = ref(false)
@@ -380,6 +457,11 @@
const mailList = ref<any[]>([])
const agreementList = ref<any[]>([])
const agreementPricesMap = ref<Record<string, any[]>>({})
const accountData = ref<{ balanceAmount: number } | null>(null)
const productQuotas = ref<any[]>([])
const accountLoading = ref(false)
const quotasLoading = ref(false)
const accountLoaded = ref(false)
const channel = computed(() => props.listRow || null)
@@ -460,6 +542,35 @@
downloadAttachmentFile(file, { fullFileUrl })
}
function formatAmount(val: unknown) {
if (val === null || val === undefined || val === '') return '0.00'
const num = Number(val)
if (isNaN(num)) return '0.00'
return num.toFixed(2)
}
async function loadAccountData() {
if (!props.channelId || accountLoaded.value) return
accountLoading.value = true
quotasLoading.value = true
try {
const [accRes, quotaRes] = await Promise.all([
fetchChannelAccount(props.channelId),
fetchChannelProductQuotas(props.channelId)
])
accountData.value = (accRes as any)?.data ?? accRes ?? null
const quotaRows = Array.isArray(quotaRes) ? quotaRes : (quotaRes as any)?.list || []
productQuotas.value = quotaRows
accountLoaded.value = true
} catch {
accountData.value = null
productQuotas.value = []
} finally {
accountLoading.value = false
quotasLoading.value = false
}
}
async function loadSubTables() {
if (!props.channelId) {
invoiceList.value = []
@@ -531,13 +642,19 @@
mailList.value = []
agreementList.value = []
agreementPricesMap.value = {}
accountData.value = null
productQuotas.value = []
accountLoaded.value = false
activeTab.value = 'basic'
}
watch(
() => [props.modelValue, props.channelId] as const,
([visible, id]) => {
if (visible && id) loadSubTables()
if (visible && id) {
loadSubTables()
loadAccountData()
}
}
)
</script>
@@ -915,6 +1032,86 @@
text-align: center;
}
/* 账户信息 */
.account-balance-card {
display: flex;
align-items: center;
gap: 16px;
padding: 18px 22px;
background: linear-gradient(135deg, #ecfdf5 0%, #f0fdf4 100%);
border: 1px solid #a7f3d0;
border-radius: 10px;
margin-bottom: 20px;
}
.account-balance-card__label {
font-size: 14px;
color: #64748b;
font-weight: 500;
}
.account-balance-card__value {
font-size: 26px;
font-weight: 700;
color: #059669;
letter-spacing: 0.02em;
}
.account-quotas-head {
margin-bottom: 10px;
}
.account-quotas-title {
margin: 0;
font-size: 14px;
font-weight: 600;
color: #1e293b;
line-height: 1.4;
&::before {
content: '';
display: inline-block;
width: 3px;
height: 14px;
background: #10b981;
border-radius: 2px;
margin-right: 8px;
vertical-align: -2px;
}
}
.account-quota-list-wrap {
margin-bottom: 0;
border-radius: 8px;
background: #fff;
}
.account-quota-table.list-table {
border: none !important;
box-shadow: none !important;
&::before,
&::after {
display: none !important;
}
:deep(.el-table__inner-wrapper) {
border: none !important;
&::before {
display: none !important;
}
}
:deep(.el-table__cell) {
border-right: none !important;
}
:deep(.el-table__body tr:last-child td.el-table__cell) {
border-bottom: none !important;
}
}
@media (max-width: 1200px) {
.kpi-strip {
grid-template-columns: repeat(2, 1fr);