提交
This commit is contained in:
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);
|
||||
|
||||
Reference in new issue
Block a user