优化
This commit is contained in:
@@ -1,13 +1,16 @@
|
||||
<script setup lang="ts">
|
||||
import '@/styles/adminDensity.css'
|
||||
import '../financeDensity.css'
|
||||
import { computed, onMounted, ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage, ElMessageBox, type UploadFile } from 'element-plus'
|
||||
import { ArrowLeft, CreditCard, Download, Eye, HandCoins, Plus, RotateCcw, XCircle } from '@lucide/vue'
|
||||
import { ArrowLeft, CreditCard, Download, HandCoins, Plus, RotateCcw, XCircle } from '@lucide/vue'
|
||||
import { useAccessPreviewStore } from '@/core/access/accessPreview'
|
||||
import { createPlatformExportTask } from '@/modules/downloads'
|
||||
import { listPlatformTenants, type PlatformTenantResource } from '@/modules/iam'
|
||||
import { categoryLabels, listSuppliers, type Supplier } from '@/modules/suppliers'
|
||||
import { getApiErrorDetails, getApiErrorMessage, type ApiErrorDetails } from '@/shared/api/http'
|
||||
import StatusBadge from '@/shared/components/StatusBadge.vue'
|
||||
import AdminPage from '@/shared/components/AdminPage.vue'
|
||||
import ApiErrorMeta from '@/shared/components/ApiErrorMeta.vue'
|
||||
import OperationErrorToast from '@/shared/components/OperationErrorToast.vue'
|
||||
@@ -437,6 +440,7 @@ async function submitPayment() {
|
||||
|
||||
async function performAction(row: SettlementRow, action: 'VOID' | 'REOPEN') {
|
||||
const reason = await ElMessageBox.prompt('请输入操作原因', action === 'VOID' ? `作废${title.value}` : `重开${title.value}`, {
|
||||
customClass: 'admin-density-confirm',
|
||||
inputType: 'textarea', inputPattern: /\S+/, inputErrorMessage: '操作原因不能为空', confirmButtonText: '确认', cancelButtonText: '取消',
|
||||
}).then((result) => result.value.trim()).catch(() => null)
|
||||
if (reason === null) return
|
||||
@@ -481,7 +485,7 @@ async function createSettlementExport(detailId?: string) {
|
||||
taskName,
|
||||
parameters,
|
||||
})
|
||||
const openDownloadCenter = await showExportTaskCreatedDialog({ taskName: task.taskName, taskNo: task.taskNo })
|
||||
const openDownloadCenter = await showExportTaskCreatedDialog({ taskName: task.taskName, taskNo: task.taskNo, dense: true })
|
||||
if (openDownloadCenter) await router.push({ name: 'download-center' })
|
||||
} catch (cause) {
|
||||
ElMessage.error(getApiErrorMessage(cause, `${taskName}导出任务创建失败`))
|
||||
@@ -502,38 +506,31 @@ onMounted(() => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AdminPage as="div" class="finance-settlement-page" spacing="normal">
|
||||
<AdminPage as="div" class="finance-settlement-page admin-density" spacing="normal">
|
||||
<OperationErrorToast :message="receiptValidationError" />
|
||||
<OperationErrorToast :details="receiptError" />
|
||||
<el-result v-if="!canView" icon="warning" :title="`无权访问${title}`" sub-title="请联系管理员开通结算单查看权限" />
|
||||
<DetailPageLayout v-else-if="detailMode" class="settlement-detail-page surface-panel" :aria-label="`${title}详情`">
|
||||
<template #header><header class="settlement-detail-header">
|
||||
<div class="settlement-detail-heading">
|
||||
<el-button aria-label="返回列表" title="返回列表" @click="backToList"><ArrowLeft :size="17" /></el-button>
|
||||
<div><div class="settlement-detail-breadcrumb">财务管理 / {{ title }} / {{ detail?.settlementNo || settlementId }}</div><h1>{{ title }}详情</h1></div>
|
||||
<el-tag v-if="detail" :type="financeStatusTone(detail.status)">{{ financeStatusLabel(detail.status) }}</el-tag>
|
||||
</div>
|
||||
<div class="settlement-detail-actions">
|
||||
<DetailPageLayout v-else-if="detailMode" class="settlement-detail-page surface-panel finance-density-detail" :aria-label="`${title}详情`">
|
||||
<template #header><div class="density-detail-header"><div class="density-detail-heading"><el-button link class="density-back" aria-label="返回列表" @click="backToList"><ArrowLeft :size="16" />返回列表</el-button><h1 class="density-detail-title">{{ detail?.settlementNo || '—' }}</h1><StatusBadge v-if="detail" :status="financeStatusLabel(detail.status)" /></div><div class="finance-detail-actions">
|
||||
<el-button v-if="detail && canExport" :loading="exportSubmitting" :disabled="exportSubmitting" @click="exportDetail"><Download :size="15" />导出</el-button>
|
||||
<el-button v-if="detail && canReceive && ['ISSUED','PARTIALLY_PAID'].includes(detail.status)" type="primary" :loading="receiptBusy" @click="openReceiptFromDetail"><HandCoins :size="15" />部分收款</el-button>
|
||||
<el-button v-if="detail && canPay && ['ISSUED','PARTIALLY_PAID'].includes(detail.status)" type="primary" @click="openPaymentFromDetail"><CreditCard :size="15" />部分付款</el-button>
|
||||
<el-button v-if="detail && canVoid && detail.status === 'ISSUED'" type="danger" :loading="actionBusy" @click="performAction(detailActionRow(), 'VOID')"><XCircle :size="15" />作废</el-button>
|
||||
<el-button v-if="detail && canVoid && detail.status === 'VOIDED'" :loading="actionBusy" @click="performAction(detailActionRow(), 'REOPEN')"><RotateCcw :size="15" />重开</el-button>
|
||||
</div>
|
||||
</header></template>
|
||||
</div></div></template>
|
||||
<template v-if="detail" #summary>
|
||||
<section class="settlement-detail-summary" aria-label="结算金额汇总">
|
||||
<div class="summary-item"><span>{{ kind === 'receivable' ? '应收金额' : '应付金额' }}</span><strong>{{ money(detail.amount) }}</strong></div>
|
||||
<div class="summary-item"><span>{{ kind === 'receivable' ? '已收金额' : '已付金额' }}</span><strong class="is-success">{{ money(detail.paidAmount) }}</strong></div>
|
||||
<div class="summary-item"><span>未结余额</span><strong class="is-danger">{{ money(detail.outstandingAmount) }}</strong></div>
|
||||
<div class="summary-item"><span>到期日</span><strong class="is-date">{{ displayDate(detail.dueDate) }}</strong></div>
|
||||
</section>
|
||||
<dl class="density-detail-overview settlement-detail-summary" aria-label="结算金额汇总">
|
||||
<div class="summary-item"><dt>{{ kind === 'receivable' ? '应收金额' : '应付金额' }}</dt><dd>{{ money(detail.amount) }}</dd></div>
|
||||
<div class="summary-item"><dt>{{ kind === 'receivable' ? '已收金额' : '已付金额' }}</dt><dd class="is-success">{{ money(detail.paidAmount) }}</dd></div>
|
||||
<div class="summary-item"><dt>未结余额</dt><dd class="is-danger">{{ money(detail.outstandingAmount) }}</dd></div>
|
||||
<div class="summary-item"><dt>到期日</dt><dd class="is-date">{{ displayDate(detail.dueDate) }}</dd></div>
|
||||
</dl>
|
||||
</template>
|
||||
<LoadErrorState v-if="detailError" class="settlement-detail-state" :title="`${title}详情加载失败`" :message="detailError.message" :loading="detailLoading" @retry="loadDetail(String(settlementId || ''))"><template #details><ApiErrorMeta :details="detailError" /></template></LoadErrorState>
|
||||
<el-skeleton v-else-if="detailLoading" class="settlement-detail-state" :rows="10" animated />
|
||||
<section v-else-if="detail" class="settlement-detail-content">
|
||||
<FormSection title="基本信息">
|
||||
<el-descriptions :column="4" class="settlement-detail-info">
|
||||
<FormSection class="density-form-section" title="基本信息">
|
||||
<el-descriptions border :column="4" class="settlement-detail-info density-descriptions">
|
||||
<el-descriptions-item label="结算单号">{{ detail.settlementNo }}</el-descriptions-item>
|
||||
<el-descriptions-item :label="kind === 'receivable' ? '客户' : '供应商'">{{ detailPartyName() }}</el-descriptions-item>
|
||||
<el-descriptions-item v-if="kind === 'payable'" label="客户">{{ customerName(detail.customerId, detail.customerName) }}</el-descriptions-item>
|
||||
@@ -550,7 +547,7 @@ onMounted(() => {
|
||||
<el-descriptions-item :label="kind === 'receivable' ? '最后收款时间' : '最后付款时间'">{{ displayDateTime(detail.lastPaymentAt) }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</FormSection>
|
||||
<FormSection title="费用明细">
|
||||
<FormSection class="density-form-section" title="费用明细">
|
||||
<div class="detail-table-scroll">
|
||||
<el-table :data="detail.lines" size="small" border stripe empty-text="暂无费用明细">
|
||||
<el-table-column prop="feeItemName" label="费用类型" min-width="150" />
|
||||
@@ -563,7 +560,7 @@ onMounted(() => {
|
||||
</el-table>
|
||||
</div>
|
||||
</FormSection>
|
||||
<FormSection :title="kind === 'receivable' ? '收款记录' : '付款记录'">
|
||||
<FormSection class="density-form-section" :title="kind === 'receivable' ? '收款记录' : '付款记录'">
|
||||
<div class="detail-table-scroll">
|
||||
<el-table :data="detail.transactions" size="small" border stripe :empty-text="kind === 'receivable' ? '暂无收款记录' : '暂无付款记录'">
|
||||
<el-table-column prop="transactionDate" :label="kind === 'receivable' ? '收款日期' : '付款日期'" width="130" />
|
||||
@@ -577,7 +574,7 @@ onMounted(() => {
|
||||
</el-table>
|
||||
</div>
|
||||
</FormSection>
|
||||
<FormSection title="修订记录" :bordered="false">
|
||||
<FormSection class="density-form-section" title="修订记录" :bordered="false">
|
||||
<div class="detail-table-scroll">
|
||||
<el-table :data="detail.revisions" size="small" border stripe empty-text="暂无调整记录">
|
||||
<el-table-column prop="action" label="动作" min-width="120"><template #default="scope">{{ settlementRevisionActionLabel(scope.row.action) || financeOperationActionLabel(scope.row.action) }}</template></el-table-column>
|
||||
@@ -602,11 +599,11 @@ onMounted(() => {
|
||||
<section class="surface-panel table-panel">
|
||||
<DataTable v-model:page="page" v-model:page-size="pageSize" :data="paginatedRows" :columns="columns" :loading="loading" :total="filteredRows.length" :aria-label="`${title}列表`" row-key="id" empty-text="暂无符合条件的结算单">
|
||||
<template #toolbar-start>
|
||||
<div class="settlement-summary" aria-label="结算汇总">
|
||||
<div class="summary-item"><span>{{ kind === 'receivable' ? '应收总额' : '应付总额' }}</span><strong>{{ money(totals.amount) }}</strong></div>
|
||||
<div class="summary-item"><span>{{ kind === 'receivable' ? '已收' : '已付' }}</span><strong class="is-success">{{ money(totals.paid) }}</strong></div>
|
||||
<div class="summary-item"><span>{{ kind === 'receivable' ? '待收' : '待付' }}</span><strong class="is-danger">{{ money(totals.outstanding) }}</strong></div>
|
||||
</div>
|
||||
<dl class="density-detail-overview settlement-summary" aria-label="结算汇总">
|
||||
<div class="summary-item"><dt>{{ kind === 'receivable' ? '应收总额' : '应付总额' }}</dt><dd>{{ money(totals.amount) }}</dd></div>
|
||||
<div class="summary-item"><dt>{{ kind === 'receivable' ? '已收' : '已付' }}</dt><dd class="is-success">{{ money(totals.paid) }}</dd></div>
|
||||
<div class="summary-item"><dt>{{ kind === 'receivable' ? '待收' : '待付' }}</dt><dd class="is-danger">{{ money(totals.outstanding) }}</dd></div>
|
||||
</dl>
|
||||
</template>
|
||||
<template #toolbar-actions>
|
||||
<div class="settlement-list-actions">
|
||||
@@ -615,12 +612,12 @@ onMounted(() => {
|
||||
</div>
|
||||
</template>
|
||||
<template #actions="{ row }">
|
||||
<div class="settlement-row-actions">
|
||||
<el-button size="small" plain type="primary" @click="openDetail(row)"><Eye :size="15" />详情</el-button>
|
||||
<el-button v-if="canReceive && ['ISSUED','PARTIALLY_PAID'].includes(String(row.status))" size="small" type="primary" :loading="receiptBusy" @click="openReceipt(row)"><HandCoins :size="15" />收款</el-button>
|
||||
<el-button v-if="canPay && ['ISSUED','PARTIALLY_PAID'].includes(String(row.status))" size="small" type="primary" @click="openPayment(row)"><CreditCard :size="15" />付款</el-button>
|
||||
<el-button v-if="canVoid && row.status === 'ISSUED'" size="small" plain type="danger" :loading="actionBusy" @click="performAction(row as SettlementRow, 'VOID')"><XCircle :size="15" />作废</el-button>
|
||||
<el-button v-if="canVoid && row.status === 'VOIDED'" size="small" plain type="primary" :loading="actionBusy" @click="performAction(row as SettlementRow, 'REOPEN')"><RotateCcw :size="15" />重开</el-button>
|
||||
<div class="settlement-row-actions density-actions">
|
||||
<el-button data-tone="neutral" class="density-action" size="small" @click="openDetail(row)">详情</el-button>
|
||||
<el-button data-tone="neutral" class="density-action" v-if="canReceive && ['ISSUED','PARTIALLY_PAID'].includes(String(row.status))" size="small" :loading="receiptBusy" @click="openReceipt(row)">收款</el-button>
|
||||
<el-button data-tone="neutral" class="density-action" v-if="canPay && ['ISSUED','PARTIALLY_PAID'].includes(String(row.status))" size="small" @click="openPayment(row)">付款</el-button>
|
||||
<el-button data-tone="danger" class="density-action" v-if="canVoid && row.status === 'ISSUED'" size="small" :loading="actionBusy" @click="performAction(row as SettlementRow, 'VOID')">作废</el-button>
|
||||
<el-button data-tone="neutral" class="density-action" v-if="canVoid && row.status === 'VOIDED'" size="small" :loading="actionBusy" @click="performAction(row as SettlementRow, 'REOPEN')">重开</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template #customer="{ row }">{{ customerName(String(row.customerId), row.customerName) }}</template>
|
||||
@@ -644,23 +641,23 @@ onMounted(() => {
|
||||
</template>
|
||||
</ListPageLayout>
|
||||
|
||||
<AppDialog v-model="createOpen" :title="`生成${title}`" width="min(600px, 94vw)" :confirm-loading="createBusy" @confirm="submitCreate">
|
||||
<el-form label-position="top">
|
||||
<AppDialog class="admin-density-dialog" v-model="createOpen" :title="`生成${title}`" width="min(600px, 94vw)" :confirm-loading="createBusy" @confirm="submitCreate">
|
||||
<el-form class="density-form" label-position="top">
|
||||
<el-form-item label="客户"><el-select v-model="createForm.customerId" filterable placeholder="请选择客户"><el-option v-for="item in activeCustomers" :key="String(item.id)" :label="item.tenantName" :value="String(item.id)" /></el-select></el-form-item>
|
||||
<el-form-item v-if="kind === 'receivable'" label="已出账对账单"><el-select v-model="createForm.reconciliationStatementId" filterable><el-option v-for="item in statementOptions" :key="item.id" :label="`${item.billNo} · ${item.outstandingAmount} CNY`" :value="item.id" /></el-select></el-form-item>
|
||||
<template v-else><el-form-item label="供应商"><el-select v-model="createForm.supplierId" filterable placeholder="请选择供应商"><el-option v-for="item in supplierOptions" :key="String(item.id)" :label="`${item.name} · ${categoryLabels[item.category]}`" :value="String(item.id)" /></el-select></el-form-item><el-form-item label="到期日"><el-date-picker v-model="createForm.dueDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="应付费用来源"><el-select v-model="createForm.feeSourceIds" multiple filterable><el-option v-for="item in feeOptions" :key="item.feeSourceId!" :label="`${item.feeItemName} · ${item.amount} CNY`" :value="item.feeSourceId!" /></el-select></el-form-item></template>
|
||||
</el-form>
|
||||
</AppDialog>
|
||||
|
||||
<AppDialog v-model="paymentOpen" title="登记付款" width="min(760px, 94vw)" :confirm-loading="paymentBusy" @confirm="submitPayment">
|
||||
<div v-if="detail" class="partial-summary"><div><span>结算单号</span><strong>{{ detail.settlementNo }}</strong></div><div><span>供应商</span><strong>{{ detailPartyName() }}</strong></div><div><span>应付金额</span><strong>{{ money(detail.amount) }}</strong></div><div><span>已付金额</span><strong class="is-success">{{ money(detail.paidAmount) }}</strong></div><div><span>当前余额</span><strong class="is-danger">{{ money(detail.outstandingAmount) }}</strong></div></div>
|
||||
<el-form class="settlement-operation-form" label-position="top"><el-form-item label="付款日期"><el-date-picker v-model="paymentForm.transactionDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="本次付款金额(CNY)"><el-input-number v-model="paymentForm.amount" :min="0.01" :max="detail?.outstandingAmount || 0.01" :precision="2" placeholder="请输入付款金额" /></el-form-item><el-form-item label="付款方式"><el-select v-model="paymentForm.method"><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item><el-form-item label="银行流水号/凭证号"><el-input v-model="paymentForm.referenceNo" placeholder="请输入付款流水号" /></el-form-item><el-form-item label="付款凭证"><el-upload :auto-upload="false" :limit="1" accept="image/*" :on-change="selectPaymentFile"><el-button>选择图片</el-button></el-upload></el-form-item><el-form-item label="备注"><el-input v-model="paymentForm.remark" type="textarea" placeholder="请输入付款备注(选填)" /></el-form-item></el-form>
|
||||
<AppDialog class="admin-density-dialog" v-model="paymentOpen" title="登记付款" width="min(760px, 94vw)" :confirm-loading="paymentBusy" @confirm="submitPayment">
|
||||
<dl v-if="detail" class="density-detail-overview partial-summary"><div><dt>结算单号</dt><dd>{{ detail.settlementNo }}</dd></div><div><dt>供应商</dt><dd>{{ detailPartyName() }}</dd></div><div><dt>应付金额</dt><dd>{{ money(detail.amount) }}</dd></div><div><dt>已付金额</dt><dd class="is-success">{{ money(detail.paidAmount) }}</dd></div><div><dt>当前余额</dt><dd class="is-danger">{{ money(detail.outstandingAmount) }}</dd></div></dl>
|
||||
<el-form class="settlement-operation-form density-form" label-position="top"><el-form-item label="付款日期"><el-date-picker v-model="paymentForm.transactionDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="本次付款金额(CNY)"><el-input-number v-model="paymentForm.amount" :min="0.01" :max="detail?.outstandingAmount || 0.01" :precision="2" placeholder="请输入付款金额" /></el-form-item><el-form-item label="付款方式"><el-select v-model="paymentForm.method"><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item><el-form-item label="银行流水号/凭证号"><el-input v-model="paymentForm.referenceNo" placeholder="请输入付款流水号" /></el-form-item><el-form-item label="付款凭证"><el-upload :auto-upload="false" :limit="1" accept="image/*" :on-change="selectPaymentFile"><el-button>选择图片</el-button></el-upload></el-form-item><el-form-item label="备注"><el-input v-model="paymentForm.remark" type="textarea" placeholder="请输入付款备注(选填)" /></el-form-item></el-form>
|
||||
<div v-if="detail" class="remaining-preview"><span>登记后剩余余额</span><strong>{{ remainingAfter(paymentForm.amount) }}</strong></div>
|
||||
</AppDialog>
|
||||
|
||||
<AppDialog v-model="receiptOpen" title="登记收款" width="min(760px, 94vw)" :confirm-loading="receiptBusy" @confirm="submitReceipt">
|
||||
<div v-if="detail" class="partial-summary"><div><span>结算单号</span><strong>{{ detail.settlementNo }}</strong></div><div><span>客户公司</span><strong>{{ detailPartyName() }}</strong></div><div><span>应收金额</span><strong>{{ money(detail.amount) }}</strong></div><div><span>已收金额</span><strong class="is-success">{{ money(detail.paidAmount) }}</strong></div><div><span>当前余额</span><strong class="is-danger">{{ money(detail.outstandingAmount) }}</strong></div></div>
|
||||
<el-form class="settlement-operation-form" label-position="top"><el-form-item label="收款日期"><el-date-picker v-model="receiptForm.receivedDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="本次收款金额(CNY)"><el-input-number v-model="receiptForm.amount" :min="0.01" :max="detail?.outstandingAmount || 0.01" :precision="2" placeholder="请输入收款金额" /></el-form-item><el-form-item label="收款方式"><el-select v-model="receiptForm.paymentMethod"><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item><el-form-item label="收款凭证"><el-upload :key="receiptUploadKey" :auto-upload="false" :limit="1" accept="image/*" :on-change="selectReceiptFile"><el-button>选择图片</el-button></el-upload></el-form-item><el-form-item label="备注"><el-input v-model="receiptForm.remark" type="textarea" placeholder="请输入收款备注(选填)" /></el-form-item></el-form>
|
||||
<AppDialog class="admin-density-dialog" v-model="receiptOpen" title="登记收款" width="min(760px, 94vw)" :confirm-loading="receiptBusy" @confirm="submitReceipt">
|
||||
<dl v-if="detail" class="density-detail-overview partial-summary"><div><dt>结算单号</dt><dd>{{ detail.settlementNo }}</dd></div><div><dt>客户公司</dt><dd>{{ detailPartyName() }}</dd></div><div><dt>应收金额</dt><dd>{{ money(detail.amount) }}</dd></div><div><dt>已收金额</dt><dd class="is-success">{{ money(detail.paidAmount) }}</dd></div><div><dt>当前余额</dt><dd class="is-danger">{{ money(detail.outstandingAmount) }}</dd></div></dl>
|
||||
<el-form class="settlement-operation-form density-form" label-position="top"><el-form-item label="收款日期"><el-date-picker v-model="receiptForm.receivedDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="本次收款金额(CNY)"><el-input-number v-model="receiptForm.amount" :min="0.01" :max="detail?.outstandingAmount || 0.01" :precision="2" placeholder="请输入收款金额" /></el-form-item><el-form-item label="收款方式"><el-select v-model="receiptForm.paymentMethod"><el-option label="银行转账" value="BANK_TRANSFER" /><el-option label="现金" value="CASH" /><el-option label="其他" value="OTHER" /></el-select></el-form-item><el-form-item label="收款凭证"><el-upload :key="receiptUploadKey" :auto-upload="false" :limit="1" accept="image/*" :on-change="selectReceiptFile"><el-button>选择图片</el-button></el-upload></el-form-item><el-form-item label="备注"><el-input v-model="receiptForm.remark" type="textarea" placeholder="请输入收款备注(选填)" /></el-form-item></el-form>
|
||||
<div v-if="detail" class="remaining-preview"><span>登记后剩余余额</span><strong>{{ remainingAfter(receiptForm.amount) }}</strong></div>
|
||||
</AppDialog>
|
||||
</AdminPage>
|
||||
@@ -669,115 +666,50 @@ onMounted(() => {
|
||||
<style scoped>
|
||||
.finance-settlement-page { min-width: 0; }
|
||||
.settlement-summary, .settlement-list-actions { display: flex; min-width: 0; align-items: center; flex-wrap: wrap; }
|
||||
.settlement-summary { gap: 6px 0; }
|
||||
.settlement-list-actions { flex: 0 0 auto; justify-content: flex-end; gap: 8px; }
|
||||
.settlement-summary { gap: var(--admin-space-2) 0; }
|
||||
.settlement-list-actions { flex: 0 0 auto; justify-content: flex-end; gap: var(--admin-space-3); }
|
||||
.settlement-list-actions :deep(.el-button + .el-button) { margin-left: 0; }
|
||||
.settlement-row-actions { display: flex; align-items: center; flex-wrap: nowrap; gap: 6px; white-space: nowrap; }
|
||||
.settlement-row-actions :deep(.el-button + .el-button) { margin-left: 0; }
|
||||
.summary-item { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
|
||||
.settlement-summary .summary-item + .summary-item { margin-left: 18px; padding-left: 18px; border-left: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.summary-item span { color: var(--cc-text-secondary, #64748b); font-size: 13px; }
|
||||
.summary-item strong { color: var(--cc-text-primary, #1f2937); font-size: 18px; line-height: 1.2; }
|
||||
.summary-item strong.is-success { color: #16803c; }
|
||||
.summary-item strong.is-danger { color: #c2413a; }
|
||||
.settlement-detail-page { display: flex; width: min(100%, 1920px); margin: 0 auto; min-width: 0; gap: 0; overflow: hidden; padding: 0; }
|
||||
.settlement-detail-header { display: flex; min-height: 68px; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 16px; border-bottom: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.settlement-detail-heading, .settlement-detail-actions { display: flex; align-items: center; gap: 10px; min-width: 0; flex-wrap: wrap; }
|
||||
.settlement-detail-heading h1 { margin: 0; font-size: 20px; line-height: 1.35; letter-spacing: 0; }
|
||||
.settlement-detail-breadcrumb { color: var(--cc-text-secondary, #64748b); font-size: 12px; }
|
||||
.settlement-detail-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); padding: 10px 16px; border-bottom: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.settlement-detail-summary .summary-item { align-items: flex-start; flex-direction: column; gap: 4px; padding: 0 12px; border-left: 1px solid var(--cc-border, #e3e8ef); }
|
||||
.settlement-detail-summary .summary-item:first-child { padding-left: 0; border-left: 0; }
|
||||
.summary-item strong.is-date { font-size: 20px; }
|
||||
.settlement-detail-state { margin: 14px 16px; }
|
||||
.settlement-detail-content { min-width: 0; padding: 0 16px 12px; overflow: hidden; }
|
||||
.settlement-detail-actions { display: flex; align-items: center; gap: var(--admin-space-4); min-width: 0; flex-wrap: wrap; }
|
||||
.settlement-detail-state { margin: var(--admin-space-5) var(--admin-space-6); }
|
||||
.settlement-detail-content { min-width: 0; padding: 0 var(--admin-space-6) var(--admin-space-5); overflow: hidden; }
|
||||
.settlement-detail-info { min-width: 0; }
|
||||
.detail-table-scroll { min-width: 0; overflow-x: auto; }
|
||||
:deep(.settlement-detail-info .el-descriptions__table) { table-layout: fixed; }
|
||||
:deep(.settlement-detail-info .el-descriptions__content) { min-width: 0; overflow-wrap: anywhere; }
|
||||
:deep(.detail-table-scroll .el-table) { min-width: 920px; }
|
||||
.partial-summary { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); margin-bottom: 12px; padding: 10px 0; border: 1px solid var(--el-color-primary-light-7); border-radius: 6px; background: var(--el-color-primary-light-9); }
|
||||
.partial-summary div { min-width: 0; padding: 0 10px; border-left: 1px solid var(--el-color-primary-light-7); }
|
||||
.partial-summary div:first-child { border-left: 0; }
|
||||
.partial-summary span, .partial-summary strong { display: block; overflow-wrap: anywhere; }
|
||||
.partial-summary span { color: var(--cc-text-secondary, #64748b); font-size: 12px; }
|
||||
.partial-summary strong { margin-top: 4px; color: var(--cc-text-primary, #1f2937); font-size: 15px; }
|
||||
.partial-summary strong.is-success { color: #16803c; }
|
||||
.partial-summary strong.is-danger { color: #c2413a; }
|
||||
.settlement-operation-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 14px; row-gap: 0; }
|
||||
.settlement-operation-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--admin-space-5); row-gap: 0; }
|
||||
.settlement-operation-form :deep(.el-form-item:last-child) { grid-column: 1 / -1; }
|
||||
.settlement-operation-form :deep(.el-input-number) { width: 100%; }
|
||||
.remaining-preview { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 8px 12px; border-radius: 8px; color: var(--cc-text-secondary, #64748b); background: var(--el-fill-color-light); }
|
||||
.remaining-preview strong { color: #b45309; font-size: 16px; }
|
||||
.operation-error { margin-bottom: 12px; }
|
||||
.operation-error-meta { margin: -6px 0 12px; }
|
||||
.remaining-preview { display: flex; align-items: center; justify-content: space-between; gap: var(--admin-space-4); padding: var(--admin-space-3) var(--admin-space-5); border-radius: var(--admin-radius); color: var(--cc-text-secondary, #64748b); background: var(--el-fill-color-light); }
|
||||
.remaining-preview strong { color: #b45309; font-size: var(--admin-font-section); }
|
||||
.operation-error { margin-bottom: var(--admin-space-5); }
|
||||
.operation-error-meta { margin: -var(--admin-space-2) 0 var(--admin-space-5); }
|
||||
:deep(.el-select), :deep(.el-date-editor) { width: 100%; }
|
||||
|
||||
@media (min-width: 1920px) {
|
||||
.finance-settlement-page {
|
||||
row-gap: 8px;
|
||||
}
|
||||
|
||||
.settlement-summary .summary-item {
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.settlement-summary .summary-item + .summary-item {
|
||||
margin-left: 12px;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.summary-item strong {
|
||||
font-size: 17px;
|
||||
row-gap: var(--admin-space-3);
|
||||
}
|
||||
|
||||
.settlement-detail-page {
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.settlement-detail-header {
|
||||
min-height: 56px;
|
||||
padding: 10px 14px;
|
||||
}
|
||||
|
||||
.settlement-detail-summary {
|
||||
padding: 8px 14px;
|
||||
}
|
||||
|
||||
.settlement-detail-summary .summary-item {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.settlement-detail-summary .summary-item strong {
|
||||
margin-top: 2px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.settlement-detail-state {
|
||||
margin: 10px 14px;
|
||||
margin: var(--admin-space-4) var(--admin-space-5);
|
||||
}
|
||||
|
||||
.settlement-detail-content {
|
||||
padding: 0 14px 10px;
|
||||
padding: 0 var(--admin-space-5) var(--admin-space-4);
|
||||
}
|
||||
|
||||
.detail-table-scroll {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.partial-summary {
|
||||
grid-template-columns: repeat(5, minmax(0, 1fr));
|
||||
gap: 0;
|
||||
margin-bottom: 8px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.partial-summary div {
|
||||
padding: 0 8px;
|
||||
margin-bottom: var(--admin-space-3);
|
||||
}
|
||||
|
||||
.settlement-operation-form {
|
||||
column-gap: 12px;
|
||||
column-gap: var(--admin-space-5);
|
||||
}
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
|
||||
Reference in New Issue
Block a user