优化
This commit is contained in:
@@ -63,6 +63,9 @@ const paymentForm = ref({ transactionDate: new Date().toISOString().slice(0, 10)
|
||||
const receiptOpen = ref(false)
|
||||
const receiptBusy = ref(false)
|
||||
const receiptFile = ref<File | null>(null)
|
||||
const receiptUploadKey = ref(0)
|
||||
const receiptValidationError = ref<string | null>(null)
|
||||
const receiptError = ref<ApiErrorDetails | null>(null)
|
||||
const receiptForm = ref({ receivedDate: new Date().toISOString().slice(0, 10), amount: 0, paymentMethod: 'BANK_TRANSFER' as 'BANK_TRANSFER' | 'CASH' | 'OTHER', remark: '' })
|
||||
const actionBusy = ref(false)
|
||||
|
||||
@@ -134,7 +137,7 @@ function displayDate(value?: string) { return value || '—' }
|
||||
function rowTotal(value: unknown) { return totalAmount(value as SettlementRow) }
|
||||
function rowPaid(value: unknown) { return paidAmount(value as SettlementRow) }
|
||||
function rowOutstanding(value: unknown) { return Number((value as SettlementRow).outstandingAmount || 0) }
|
||||
function customerName(customerId: string, snapshot?: string) { return snapshot || customers.value.find((item) => String(item.id) === String(customerId))?.tenantName || `客户 ${customerId}` }
|
||||
function customerName(customerId: string, snapshot?: string) { return snapshot || customers.value.find((item) => String(item.id) === String(customerId))?.tenantName || '—' }
|
||||
function totalAmount(row: SettlementRow) { return props.kind === 'receivable' ? (row as FinanceReceivableSettlement).receivableAmount : (row as FinancePayableSettlement).payableAmount }
|
||||
function paidAmount(row: SettlementRow) { return props.kind === 'receivable' ? (row as FinanceReceivableSettlement).receivedAmount : (row as FinancePayableSettlement).paidAmount }
|
||||
function selectedSupplierName() { return selectedRow.value && 'supplierName' in selectedRow.value ? selectedRow.value.supplierName || '—' : '—' }
|
||||
@@ -172,10 +175,9 @@ async function load(model: QueryModel = filters.value) {
|
||||
finally { loading.value = false }
|
||||
}
|
||||
|
||||
async function openDetail(row: unknown) {
|
||||
function openDetail(row: unknown) {
|
||||
selectedRow.value = row as SettlementRow
|
||||
emit('openDetail', selectedRow.value.id)
|
||||
await loadDetail(selectedRow.value.id)
|
||||
}
|
||||
|
||||
async function loadDetail(settlementId: string) {
|
||||
@@ -243,6 +245,8 @@ function selectPaymentFile(file: UploadFile) { paymentFile.value = file.raw ?? n
|
||||
async function openReceipt(row: unknown) {
|
||||
const settlement = row as FinanceReceivableSettlement
|
||||
selectedRow.value = settlement
|
||||
receiptError.value = null
|
||||
receiptValidationError.value = null
|
||||
receiptBusy.value = true
|
||||
try {
|
||||
const current = await getFinanceSettlement(settlement.id)
|
||||
@@ -251,7 +255,7 @@ async function openReceipt(row: unknown) {
|
||||
receiptFile.value = null
|
||||
receiptForm.value = { receivedDate: new Date().toISOString().slice(0, 10), amount: current.outstandingAmount, paymentMethod: 'BANK_TRANSFER', remark: '' }
|
||||
receiptOpen.value = true
|
||||
} catch (cause) { error.value = getApiErrorDetails(cause, '应收结算单加载失败,无法登记收款') }
|
||||
} catch (cause) { receiptError.value = getApiErrorDetails(cause, '应收结算单加载失败,无法登记收款') }
|
||||
finally { receiptBusy.value = false }
|
||||
}
|
||||
|
||||
@@ -260,11 +264,26 @@ async function openReceiptFromDetail() {
|
||||
await openReceipt({ id: detail.value.id, customerId: detail.value.customerId, settlementNo: detail.value.settlementNo, receivableAmount: detail.value.amount, receivedAmount: detail.value.paidAmount, outstandingAmount: detail.value.outstandingAmount, currency: 'CNY', status: detail.value.status, version: detail.value.version })
|
||||
}
|
||||
|
||||
function selectReceiptFile(file: UploadFile) { receiptFile.value = file.raw ?? null }
|
||||
function selectReceiptFile(file: UploadFile) {
|
||||
const raw = file.raw
|
||||
if (!raw || !raw.type.startsWith('image/')) {
|
||||
receiptFile.value = null
|
||||
receiptValidationError.value = '收款凭证仅支持图片文件'
|
||||
receiptUploadKey.value += 1
|
||||
return
|
||||
}
|
||||
receiptFile.value = raw
|
||||
receiptValidationError.value = null
|
||||
receiptError.value = null
|
||||
}
|
||||
|
||||
async function submitReceipt() {
|
||||
const current = detail.value
|
||||
if (!current?.reconciliationStatementId || !receiptFile.value || receiptForm.value.amount <= 0) return ElMessage.warning('请填写收款金额并选择收款凭证')
|
||||
if (!current?.reconciliationStatementId || !receiptFile.value || receiptForm.value.amount <= 0) {
|
||||
receiptValidationError.value = '请填写收款金额并选择收款凭证'
|
||||
return
|
||||
}
|
||||
receiptError.value = null
|
||||
receiptBusy.value = true
|
||||
try {
|
||||
const voucher = await uploadFinanceVoucher(current.customerId, receiptFile.value)
|
||||
@@ -273,7 +292,7 @@ async function submitReceipt() {
|
||||
ElMessage.success('收款已登记')
|
||||
if (detailMode.value) await loadDetail(current.id)
|
||||
else await load()
|
||||
} catch (cause) { error.value = getApiErrorDetails(cause, '收款登记失败') }
|
||||
} catch (cause) { receiptError.value = getApiErrorDetails(cause, '收款登记失败') }
|
||||
finally { receiptBusy.value = false }
|
||||
}
|
||||
|
||||
@@ -478,7 +497,10 @@ onMounted(() => {
|
||||
|
||||
<AppDialog v-model="receiptOpen" title="登记收款" width="min(560px, 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 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" /></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 :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" /></el-form-item></el-form>
|
||||
<el-alert v-if="receiptValidationError" type="error" :title="receiptValidationError" :closable="false" show-icon class="operation-error" />
|
||||
<el-alert v-if="receiptError" type="error" :title="receiptError.message" :closable="false" show-icon class="operation-error" />
|
||||
<ApiErrorMeta v-if="receiptError" :details="receiptError" class="operation-error-meta" />
|
||||
<el-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" /></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" /></el-form-item></el-form>
|
||||
<div v-if="detail" class="remaining-preview"><span>登记后剩余余额</span><strong>{{ remainingAfter(receiptForm.amount) }}</strong></div>
|
||||
</AppDialog>
|
||||
</AdminPage>
|
||||
@@ -510,6 +532,8 @@ onMounted(() => {
|
||||
.partial-summary strong.is-danger { color: #c2413a; }
|
||||
.remaining-preview { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 14px; 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; }
|
||||
:deep(.el-select), :deep(.el-date-editor) { width: 100%; }
|
||||
@media (max-width: 720px) {
|
||||
.settlement-summary, .settlement-detail-summary, .partial-summary { grid-template-columns: 1fr; }
|
||||
|
||||
Reference in New Issue
Block a user