Files
admin-web/src/modules/finance/pages/FinanceCustomerAccountsView.vue
T
2026-08-17 17:49:10 +08:00

591 lines
26 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ArrowLeft, Download, Eye, Pencil, Save } from '@lucide/vue'
import { ElMessage } from 'element-plus'
import { useAccessPreviewStore } from '@/core/access/accessPreview'
import { createPlatformExportTask } from '@/modules/downloads'
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
import { getApiErrorDetails, getApiErrorMessage, type ApiErrorDetails } from '@/shared/api/http'
import AdminPage from '@/shared/components/AdminPage.vue'
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
import DataTable, { type DataTableColumn } from '@/shared/components/DataTable.vue'
import DetailPageLayout from '@/shared/components/DetailPageLayout.vue'
import FormSection from '@/shared/components/FormSection.vue'
import ListPageLayout from '@/shared/components/ListPageLayout.vue'
import LoadErrorState from '@/shared/components/LoadErrorState.vue'
import QueryToolbar, { type QueryField, type QueryModel } from '@/shared/components/QueryToolbar.vue'
import { showExportTaskCreatedDialog } from '@/shared/components/exportTaskCreatedDialog'
import { getFinanceCustomerTerms, listFinanceAccountLedger, listFinanceAccounts, updateFinanceCustomerTerms } from '../api/finance'
import { financeBusinessTypeLabel } from '../status'
import type { FinanceAccountSummary, FinanceCustomerTerms, FinanceLedgerEntry } from '../types'
const access = useAccessPreviewStore()
const route = useRoute()
const router = useRouter()
const filters = ref<QueryModel>({ customerId: '', status: '' })
const customers = ref<PlatformTenantResource[]>([])
const customersLoading = ref(false)
const customersError = ref<ApiErrorDetails | null>(null)
const rows = ref<FinanceAccountSummary[]>([])
const loading = ref(false)
const loadError = ref<ApiErrorDetails | null>(null)
const page = ref(1)
const pageSize = ref(20)
const total = ref(0)
const detailOpen = ref(false)
const editing = ref(false)
const saving = ref(false)
const selected = ref<FinanceAccountSummary | null>(null)
const ledger = ref<FinanceLedgerEntry[]>([])
const ledgerLoading = ref(false)
const ledgerError = ref<ApiErrorDetails | null>(null)
const selectedTerms = ref<FinanceCustomerTerms | null>(null)
const creditDays = ref(30)
const ledgerFilters = ref<QueryModel>({ businessType: '', occurredRange: [] })
const ledgerPage = ref(1)
const ledgerPageSize = ref(20)
const ledgerTotal = ref(0)
const accountExportBusy = ref(false)
const ledgerExportBusy = ref(false)
const canView = computed(() => access.can('platform:finance:customer-account:list'))
const canListCustomers = computed(() => canView.value || access.can('platform:customer:list'))
const canViewTerms = computed(() => access.can('platform:finance:customer-terms:view'))
const canUpdateTerms = computed(() => canViewTerms.value && access.can('platform:finance:customer-terms:update'))
const canExport = computed(() => access.can('platform:finance:customer-account:export') && access.can('platform:download:list'))
const stateError = computed(() => customersError.value || loadError.value)
const queryFields = computed<QueryField[]>(() => [
{ key: 'customerId', type: 'select', label: '客户名称', width: 260, placeholder: '全部客户', props: { 'aria-label': '客户名称', filterable: true, clearable: true, loading: customersLoading.value }, options: customers.value.filter((item) => item.status === 'ACTIVE').map((item) => ({ label: item.tenantName, value: String(item.id) })) },
{ key: 'status', type: 'select', label: '状态', width: 150, placeholder: '全部状态', options: [{ label: '正常', value: 'ACTIVE' }, { label: '停用', value: 'DISABLED' }] },
])
const columns: DataTableColumn[] = [
{ key: 'actions', label: '操作', width: 150, fixed: 'left', slotName: 'actions' },
{ key: 'customerName', label: '客户', minWidth: 180, slotName: 'customerName' },
{ key: 'outstandingReceivable', label: '待收(CNY)', width: 130 },
{ key: 'pendingBilling', label: '待开账(CNY)', width: 140 },
{ key: 'receivedInPeriod', label: '本期已收(CNY)', width: 140 },
{ key: 'outstandingPayable', label: '待付(CNY)', width: 130 },
{ key: 'status', label: '客户状态', width: 110, slotName: 'status' },
{ key: 'lastChangedAt', label: '最近变动', width: 170, slotName: 'lastChangedAt' },
]
const ledgerQueryFields: QueryField[] = [
{ key: 'businessType', type: 'select', label: '流水类型', width: 180, placeholder: '全部类型', options: [
{ label: '纳入结算', value: 'FEE_INCLUDED' }, { label: '排除结算', value: 'FEE_EXCLUDED' },
{ label: '生成对账单', value: 'RECONCILIATION_CREATED' }, { label: '结算单生效', value: 'SETTLEMENT_ISSUED' },
{ label: '收款', value: 'RECEIPT' }, { label: '付款', value: 'PAYMENT' },
{ label: '账务调整', value: 'ADJUSTMENT' }, { label: '作废', value: 'VOID' },
] },
{ key: 'occurredRange', type: 'daterange', label: '发生日期', width: 280 },
]
const ledgerColumns: DataTableColumn[] = [
{ key: 'ledgerId', label: '流水号', width: 180, slotName: 'ledgerId' }, { key: 'occurredAt', label: '发生时间', width: 170, slotName: 'occurredAt' }, { key: 'businessType', label: '业务类型', width: 140, slotName: 'businessType' },
{ key: 'documentNo', label: '关联单据', width: 220, slotName: 'documentNo' }, { key: 'receivableChange', label: '应收变动(CNY)', width: 145 }, { key: 'payableChange', label: '应付变动(CNY)', width: 145 },
{ key: 'outstandingReceivableAfter', label: '变动后未收(CNY)', width: 160 }, { key: 'operatorName', label: '操作人', width: 140, slotName: 'operatorName' }, { key: 'remark', label: '备注', minWidth: 180 },
]
const summary = computed(() => rows.value.reduce((result, row) => ({
receivable: result.receivable + row.outstandingReceivable,
pending: result.pending + row.pendingBilling,
received: result.received + row.receivedInPeriod,
payable: result.payable + row.outstandingPayable,
}), { receivable: 0, pending: 0, received: 0, payable: 0 }))
async function load(model: QueryModel = filters.value) {
Object.assign(filters.value, model)
if (!canView.value) return
loading.value = true
loadError.value = null
try {
const result = await listFinanceAccounts({ page: page.value, size: pageSize.value, customerId: String(filters.value.customerId || '').trim() || undefined, status: String(filters.value.status || '') })
rows.value = result.records
total.value = result.total
} catch (error) { loadError.value = getApiErrorDetails(error, '客户账户加载失败,请重试') }
finally { loading.value = false }
}
async function loadCustomers() {
customersLoading.value = true; customersError.value = null
try {
const records: PlatformTenantResource[] = []; let currentPage = 1; let pages = 1
do { const result = await listPlatformTenants({ page: currentPage, size: 200, status: 'ACTIVE' }); records.push(...result.records); pages = Math.max(1, result.pages); currentPage += 1 } while (currentPage <= pages)
customers.value = records
} catch (error) { customersError.value = getApiErrorDetails(error, '客户列表加载失败') }
finally { customersLoading.value = false }
}
function search(model: QueryModel) { page.value = 1; void load(model) }
async function openAccount(row: Record<string, unknown>, edit: boolean) {
selected.value = row as unknown as FinanceAccountSummary
editing.value = edit
if (!edit) {
await router.push({ name: 'finance-customer-account-detail', params: { customerId: selected.value.customerId } })
return
}
detailOpen.value = true
ledger.value = []
ledgerError.value = null
selectedTerms.value = null
if (edit) {
if (!canViewTerms.value) return
try { selectedTerms.value = await getFinanceCustomerTerms(selected.value.customerId); creditDays.value = selectedTerms.value.creditDays }
catch (error) { ledgerError.value = getApiErrorDetails(error, '客户账期加载失败,请重试') }
return
}
await loadLedger()
}
async function loadLedger(model: QueryModel = ledgerFilters.value) {
if (!selected.value) return
Object.assign(ledgerFilters.value, model)
ledgerLoading.value = true; ledgerError.value = null
const range = Array.isArray(ledgerFilters.value.occurredRange) ? ledgerFilters.value.occurredRange.map(String) : []
try {
const result = await listFinanceAccountLedger(selected.value.customerId, { page: ledgerPage.value, size: ledgerPageSize.value, businessType: String(ledgerFilters.value.businessType || ''), startDate: range[0], endDate: range[1] })
ledger.value = result.records
ledgerTotal.value = result.total
} catch (error) { ledgerError.value = getApiErrorDetails(error, '客户账户流水加载失败,请重试') }
finally { ledgerLoading.value = false }
}
async function retryDrawer() { if (selected.value) await openAccount(selected.value as unknown as Record<string, unknown>, editing.value) }
async function saveTerms() {
if (!selected.value || !Number.isInteger(creditDays.value) || creditDays.value < 0 || creditDays.value > 3650) { ElMessage.warning('账期必须是 0 到 3650 的整数天'); return }
saving.value = true
ledgerError.value = null
try { selectedTerms.value = await updateFinanceCustomerTerms(selected.value.customerId, { customerName: selected.value.customerName, creditDays: creditDays.value }); ElMessage.success('客户账期已保存') }
catch (error) { ledgerError.value = getApiErrorDetails(error, '客户账期保存失败,请重试'); ElMessage.error(ledgerError.value.message) }
finally { saving.value = false }
}
function money(value: unknown) { return Number(value || 0).toFixed(2) }
function customerName(customerId: string, snapshot?: string) {
const masterName = customers.value.find((item) => String(item.id) === String(customerId))?.tenantName?.trim()
const candidate = String(snapshot || '').trim()
const placeholder = [String(customerId), `客户 ${customerId}`, `客户${customerId}`].includes(candidate)
return masterName || (candidate && !placeholder ? candidate : '客户名称暂不可用')
}
function ledgerBusinessType(value: unknown) {
const code = String(value || '').trim().toUpperCase()
const known: Record<string, string> = { REC: '收款', RECONCILIATION: '对账单', FEE_SOURCE: '费用来源' }
return known[code] || financeBusinessTypeLabel(code)
}
function displayOperator(value: unknown) {
const operator = String(value || '').trim()
if (!operator) return '名称数据缺失'
return /^(?:operator-)?\d+$/i.test(operator) ? '名称数据缺失' : operator
}
function formatDateTime(value: unknown) {
const raw = String(value || '').trim()
if (!raw) return '时间数据缺失'
const date = new Date(raw)
return Number.isNaN(date.getTime()) ? '时间数据缺失' : date.toLocaleString('zh-CN', { hour12: false })
}
function formatLastChangedAt(value: unknown) { return String(value || '').trim() ? formatDateTime(value) : '暂无变动' }
function displayDocumentNo(value: unknown) { return String(value || '').trim() || '关联单据缺失' }
function displayLedgerId(value: unknown) { return String(value || '').trim() || '流水号缺失' }
async function finishExport(task: Awaited<ReturnType<typeof createPlatformExportTask>>) {
const openDownloadCenter = await showExportTaskCreatedDialog({ taskName: task.taskName, taskNo: task.taskNo })
if (openDownloadCenter) await router.push({ name: 'download-center' })
}
async function exportAccounts() {
const customerId = String(filters.value.customerId || '').trim()
const status = String(filters.value.status || '').trim()
accountExportBusy.value = true
try {
const task = await createPlatformExportTask({
exportType: 'FINANCE_CUSTOMER_ACCOUNT_LIST', format: 'XLSX', taskName: '客户账户',
parameters: {
...(customerId ? { customerId } : {}),
...(status ? { status } : {}),
},
})
await finishExport(task)
} catch (error) { ElMessage.error(getApiErrorMessage(error, '客户账户导出任务创建失败')) }
finally { accountExportBusy.value = false }
}
async function exportLedger() {
if (!selected.value) return
const range = Array.isArray(ledgerFilters.value.occurredRange) ? ledgerFilters.value.occurredRange.map(String) : []
const businessType = String(ledgerFilters.value.businessType || '').trim()
ledgerExportBusy.value = true
try {
const task = await createPlatformExportTask({
exportType: 'FINANCE_CUSTOMER_ACCOUNT_LEDGER', format: 'XLSX', taskName: '客户账户流水',
parameters: {
customerId: selected.value.customerId,
...(businessType ? { businessType } : {}),
...(range[0] ? { startDate: range[0] } : {}),
...(range[1] ? { endDate: range[1] } : {}),
},
})
await finishExport(task)
} catch (error) { ElMessage.error(getApiErrorMessage(error, '客户账户流水导出任务创建失败')) }
finally { ledgerExportBusy.value = false }
}
async function closeDetail() {
detailOpen.value = false; selected.value = null; editing.value = false; ledger.value = []
if (route.name === 'finance-customer-account-detail') await router.push({ name: 'finance-customer-accounts' })
}
async function restoreAccountDetail(customerId: string) {
detailOpen.value = true; editing.value = false; ledgerError.value = null
try {
let currentPage = 1; let pages = 1; selected.value = null
do {
const result = await listFinanceAccounts({ page: currentPage, size: 200 })
selected.value = result.records.find((row) => row.customerId === customerId) || null
pages = result.pages; currentPage += 1
} while (!selected.value && currentPage <= pages)
if (!selected.value) { ledgerError.value = { message: '未找到该客户账户,可能已停用或无权访问' }; return }
await loadLedger()
} catch (error) { ledgerError.value = getApiErrorDetails(error, '客户账户详情加载失败,请重试') }
}
onMounted(() => {
const customerId = String(route.params.customerId || '')
if (route.name === 'finance-customer-account-detail' && customerId) { if (canListCustomers.value) void loadCustomers(); void restoreAccountDetail(customerId) }
else { if (canListCustomers.value) void loadCustomers(); void load() }
})
watch(() => [route.name, String(route.params.customerId || '')], ([name, customerId], previous) => {
if (!previous) return
if (name === 'finance-customer-account-detail' && customerId) void restoreAccountDetail(String(customerId))
else { detailOpen.value = false; selected.value = null; ledger.value = []; void load() }
})
</script>
<template>
<AdminPage as="div" class="finance-account-page" spacing="normal">
<el-result v-if="!canView" icon="warning" title="无权访问客户账户" sub-title="请联系管理员开通客户账户查看权限" />
<ListPageLayout v-else-if="!detailOpen" aria-label="客户账户">
<template #toolbar><QueryToolbar v-model="filters" class="surface-panel" ariaLabel="客户账户筛选" :fields="queryFields" preference-key="finance-customer-accounts-query" @search="search" /></template>
<template v-if="stateError" #state><LoadErrorState title="客户账户加载失败" :message="stateError.message" :loading="loading || customersLoading" @retry="customersError ? loadCustomers() : load()"><template #details><ApiErrorMeta :details="stateError" /></template></LoadErrorState></template>
<section v-if="!stateError" class="surface-panel table-panel">
<DataTable v-model:page="page" v-model:page-size="pageSize" :data="rows" :columns="columns" :loading="loading" :total="total" preference-key="finance-customer-accounts-table" aria-label="客户账户列表" row-key="customerId" empty-text="暂无客户账户" @update:page="load()" @update:page-size="page = 1; load()">
<template #toolbar-actions><el-button v-if="canExport" :loading="accountExportBusy" :disabled="loading || accountExportBusy" @click="exportAccounts"><Download :size="16" />导出Excel</el-button></template>
<template #actions="{ row }"><div class="row-actions"><el-button link type="primary" @click="openAccount(row, false)"><Eye :size="15" />查看</el-button><el-button v-if="canUpdateTerms" link type="primary" @click="openAccount(row, true)"><Pencil :size="15" />账期</el-button></div></template>
<template #customerName="{ row }">{{ customerName(row.customerId, row.customerName) }}</template>
<template #lastChangedAt="{ row }">{{ formatLastChangedAt(row.lastChangedAt) }}</template>
<template #status="{ row }"><el-tag :type="row.status === 'ACTIVE' ? 'success' : 'info'">{{ row.status === 'ACTIVE' ? '正常' : '停用' }}</el-tag></template>
<template #pagination-left><span>汇总:未收 {{ money(summary.receivable) }} · 待出账 {{ money(summary.pending) }} · 本期已收 {{ money(summary.received) }} · 应付 {{ money(summary.payable) }} CNY</span></template>
</DataTable>
</section>
</ListPageLayout>
<AdminPage v-else as="div" class="finance-account-detail" spacing="normal">
<section class="surface-panel finance-account-detail__surface">
<DetailPageLayout class="finance-account-detail__layout" :aria-label="editing ? '维护客户账期' : '客户账户详情'">
<template #header><div class="detail-heading"><div class="detail-title"><h2>{{ editing ? '维护客户账期' : '客户账户详情' }}</h2><p v-if="selected">{{ customerName(selected.customerId, selected.customerName) }} · 客户财务往来总览</p></div><el-button class="detail-back" @click="closeDetail"><ArrowLeft :size="16" />返回客户账户</el-button></div></template>
<template v-if="selected && !ledgerError" #summary><section class="account-metrics" aria-label="客户账户汇总"><div class="account-metric is-receivable"><span>待收金额</span><strong>{{ money(selected.outstandingReceivable) }}</strong><small>CNY</small></div><div class="account-metric is-pending"><span>待开账金额</span><strong>{{ money(selected.pendingBilling) }}</strong><small>CNY</small></div><div class="account-metric is-received"><span>本期已收</span><strong>{{ money(selected.receivedInPeriod) }}</strong><small>CNY</small></div><div class="account-metric is-payable"><span>待付金额</span><strong>{{ money(selected.outstandingPayable) }}</strong><small>CNY</small></div></section></template>
<LoadErrorState v-if="ledgerError" :title="editing ? '客户账期加载失败' : '账户流水加载失败'" :message="ledgerError.message" :loading="ledgerLoading" @retry="retryDrawer"><template #details><ApiErrorMeta :details="ledgerError" /></template></LoadErrorState>
<template v-else-if="selected">
<FormSection v-if="!editing" class="ledger-section" title="账户流水" :bordered="false">
<QueryToolbar v-model="ledgerFilters" class="ledger-query" :fields="ledgerQueryFields" ariaLabel="账户流水筛选" preference-key="finance-account-ledger-query" @search="ledgerPage = 1; loadLedger" />
<div class="detail-table-scroll"><DataTable v-model:page="ledgerPage" v-model:page-size="ledgerPageSize" class="ledger-table" :data="ledger" :columns="ledgerColumns" :loading="ledgerLoading" :total="ledgerTotal" row-key="ledgerId" empty-text="暂无账户流水" @update:page="loadLedger()" @update:page-size="ledgerPage = 1; loadLedger()"><template #toolbar-actions><el-button v-if="canExport" :loading="ledgerExportBusy" :disabled="ledgerLoading || ledgerExportBusy" @click="exportLedger"><Download :size="16" />导出流水</el-button></template><template #pagination-left>共 {{ ledgerTotal }} 条</template><template #ledgerId="{ row }"><span class="ledger-identifier" :title="displayLedgerId(row.ledgerId)">{{ displayLedgerId(row.ledgerId) }}</span></template><template #occurredAt="{ row }">{{ formatDateTime(row.occurredAt) }}</template><template #businessType="{ row }">{{ ledgerBusinessType(row.businessType) }}</template><template #documentNo="{ row }"><span class="ledger-document" :title="displayDocumentNo(row.documentNo)">{{ displayDocumentNo(row.documentNo) }}</span></template><template #operatorName="{ row }">{{ displayOperator(row.operatorName) }}</template></DataTable></div>
</FormSection>
<FormSection v-else class="term-section" title="账期设置" :bordered="false"><div class="term-editor"><span class="term-label">账期天数</span><div class="term-control"><el-input-number v-model="creditDays" :min="0" :max="3650" :step="1" /><span class="term-unit">天</span></div></div></FormSection>
</template>
<template v-if="editing && selected && !ledgerError" #footer><div class="detail-footer"><el-button @click="closeDetail">关闭</el-button><el-button v-if="canUpdateTerms" type="primary" :loading="saving" @click="saveTerms"><Save :size="16" />保存账期</el-button></div></template>
</DetailPageLayout>
</section>
</AdminPage>
</AdminPage>
</template>
<style scoped>
.finance-account-page {
min-width: 0;
}
.finance-account-detail {
width: 100%;
min-width: 0;
}
.finance-account-detail__surface {
width: min(100%, 1920px);
margin: 0 auto;
overflow: hidden;
}
.finance-account-detail__layout {
width: 100%;
margin: 0 auto;
}
.finance-account-detail__layout :deep(.detail-page-layout) {
gap: 0;
}
.finance-account-detail__layout :deep(.detail-page-layout__header) {
min-height: 64px;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid var(--cc-border, #e3e8ef);
}
.finance-account-detail__layout :deep(.detail-page-layout__summary) {
padding: 10px 16px 0;
}
.finance-account-detail__layout :deep(.detail-page-layout__content) {
padding: 0 16px 12px;
}
.finance-account-detail__layout :deep(.detail-page-layout__footer) {
padding: 0 16px 12px;
}
.row-actions,
.detail-footer,
.detail-heading,
.term-control {
display: flex;
align-items: center;
gap: 8px;
}
.row-actions .el-button {
margin-left: 0;
}
.detail-heading {
width: 100%;
align-items: center;
}
.detail-title {
min-width: 0;
}
.detail-heading h2 {
margin: 0;
color: var(--cc-text);
font-size: 20px;
line-height: 1.4;
}
.detail-heading p {
margin: 3px 0 0;
color: var(--cc-muted);
font-size: 13px;
}
.detail-back {
margin-left: auto;
}
.account-metrics {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 0;
padding: 0 0 12px;
border-bottom: 1px solid var(--cc-border, #e3e8ef);
}
.account-metric {
min-width: 0;
padding: 0 12px;
}
.account-metric:first-child {
padding-left: 0;
}
.account-metric + .account-metric {
border-left: 1px solid var(--cc-border, #e3e8ef);
}
.account-metric::before {
display: none;
}
.account-metric span {
display: block;
color: var(--cc-muted);
font-size: 12px;
}
.account-metric strong {
display: inline-block;
margin-top: 6px;
color: var(--cc-text);
font-size: 20px;
line-height: 1;
font-variant-numeric: tabular-nums;
}
.account-metric small {
margin-left: 6px;
color: var(--cc-muted);
font-size: 11px;
}
.ledger-section {
padding: 10px 0 0;
}
.ledger-query {
margin-bottom: 8px;
}
:deep(.ledger-query.query-toolbar) {
padding: 0;
border: 0;
background: transparent;
}
.detail-table-scroll {
overflow-x: auto;
}
.ledger-table {
min-width: 0;
}
.ledger-identifier,
.ledger-document {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-variant-numeric: tabular-nums;
}
:deep(.ledger-table .data-table__toolbar.is-compact) {
min-height: 36px;
padding: 0 0 6px;
border-bottom: 0;
}
:deep(.ledger-table .data-table__pagination) {
min-height: 40px;
padding: 6px 10px;
}
.term-section {
width: 100%;
padding: 10px 0;
}
.term-editor {
display: grid;
grid-template-columns: 120px minmax(0, 220px);
justify-content: start;
align-items: center;
gap: 14px;
padding: 2px 0;
}
.term-label {
color: var(--cc-text);
font-size: 14px;
font-weight: 600;
}
.term-control :deep(.el-input-number) {
width: 220px;
}
.term-unit {
color: var(--cc-muted);
}
.detail-footer {
width: 100%;
justify-content: flex-end;
margin-top: 0;
padding-top: 8px;
border-top: 0;
}
@media (min-width: 1920px) {
.finance-account-detail__layout :deep(.detail-page-layout) {
gap: 8px;
}
.finance-account-detail__layout :deep(.detail-page-layout__header) {
min-height: 56px;
padding: 10px 14px;
}
.finance-account-detail__layout :deep(.detail-page-layout__summary) {
padding: 8px 14px 0;
}
.finance-account-detail__layout :deep(.detail-page-layout__content) {
padding: 0 14px 10px;
}
.finance-account-detail__layout :deep(.detail-page-layout__footer) {
padding: 0 14px 10px;
}
.finance-account-detail__layout :deep(.form-section) {
padding: 10px 0;
}
.finance-account-detail__layout :deep(.form-section__heading) {
margin-bottom: 8px;
}
.account-metrics {
gap: 8px;
}
.account-metric {
padding: 0 10px;
}
.detail-footer {
padding-top: 0;
}
}
@media (max-width: 1080px) {
.account-metrics {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.account-metric:nth-child(3) {
padding-left: 0;
border-left: 0;
}
.finance-account-detail__surface {
width: 100%;
}
}
@media (max-width: 720px) {
.detail-heading {
align-items: stretch;
flex-direction: column;
}
.detail-back {
margin-left: 0;
}
.detail-footer .el-button {
min-height: 44px;
}
.term-editor {
grid-template-columns: 1fr;
}
.account-metrics {
grid-template-columns: 1fr;
gap: 12px;
}
.account-metric,
.account-metric:first-child,
.account-metric:nth-child(3) {
padding-left: 0;
}
.account-metric + .account-metric {
border-left: 0;
}
}
@media (max-width: 480px) {
.detail-footer .el-button {
flex: 1 1 120px;
}
}
</style>