去掉应收登记收款功能逻辑2

This commit is contained in:
caojia
2026-09-16 17:57:48 +08:00
parent e52f52cb35
commit 6487146117
2 changed files with 0 additions and 130 deletions
-25
View File
@@ -1,25 +0,0 @@
import request from '@/utils/request'
export function listArReceipt(query) {
return request({ url: '/ar/receipt/list', method: 'get', params: query })
}
export function addArReceipt(data) {
return request({ url: '/ar/receipt', method: 'post', data })
}
export function cancelArReceipt(receiptId, data = {}) {
return request({ url: '/ar/receipt/' + receiptId + '/cancel', method: 'put', data })
}
export function listArWriteoffs(receiptId) {
return request({ url: '/ar/receipt/' + receiptId + '/writeoffs', method: 'get' })
}
export function writeoffArReceipt(data) {
return request({ url: '/ar/receipt/writeoff', method: 'post', data })
}
export function cancelArWriteoff(writeoffId, data = {}) {
return request({ url: '/ar/receipt/writeoff/' + writeoffId + '/cancel', method: 'put', data })
}
-105
View File
@@ -1,105 +0,0 @@
<template>
<div class="app-container ar-receipt-page">
<basic-table ref="tableRef" :columns="columns" :search-columns="searchColumns" :query="queryList" row-key="receiptId" :selection="false">
<template #search-customerId="{ model }">
<customer-select v-model="model.customerId" placeholder="请选择客户" class="receipt-customer-search" />
</template>
<template #toolbar><el-col :span="1.5"><el-button type="primary" plain icon="Plus" v-hasPermi="['ar:receipt:add']" @click="openRegister">登记收款</el-button></el-col></template>
<template #col-receiptAmount="{ row }"><span class="income">{{ row.currency }} {{ money(row.receiptAmount) }}</span></template>
<template #col-unallocatedAmount="{ row }"><span class="pending">{{ money(row.unallocatedAmount) }}</span></template>
<template #col-status="{ row }"><el-tag :type="receiptStatusType(row.status)">{{ receiptStatusText(row.status) }}</el-tag></template>
<template #col-action="{ row }">
<el-button v-if="row.status !== 'CANCELLED' && Number(row.unallocatedAmount) > 0" link type="primary" v-hasPermi="['ar:receipt:writeoff']" @click="openWriteoff(row)">核销</el-button>
<el-button v-if="row.status === 'REGISTERED'" link type="warning" v-hasPermi="['ar:receipt:cancel']" @click="cancelReceipt(row)">取消收款</el-button>
<el-button link type="primary" @click="openWriteoffHistory(row)">核销记录</el-button>
</template>
</basic-table>
<el-dialog v-model="registerOpen" title="登记应收收款" width="620px" append-to-body>
<el-form ref="registerFormRef" :model="registerForm" :rules="registerRules" label-width="110px">
<el-row :gutter="12">
<el-col :span="12"><el-form-item label="客户" prop="customerId"><customer-select v-model="registerForm.customerId" placeholder="请选择客户" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="到账日期" prop="receiptDate"><el-date-picker v-model="registerForm.receiptDate" type="date" value-format="YYYY-MM-DD" style="width: 100%;" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="到账金额" prop="receiptAmount"><el-input v-model="registerForm.receiptAmount" type="number" /></el-form-item></el-col>
<el-col :span="12"><el-form-item label="币种"><el-select v-model="registerForm.currency" style="width: 100%;"><el-option label="人民币 CNY" value="CNY" /><el-option label="美元 USD" value="USD" /></el-select></el-form-item></el-col>
<el-col :span="12"><el-form-item label="收款方式"><el-select v-model="registerForm.paymentMethod" style="width: 100%;"><el-option label="银行转账" value="BANK" /><el-option label="支付宝" value="ALIPAY" /><el-option label="微信" value="WECHAT" /><el-option label="现金" value="CASH" /></el-select></el-form-item></el-col>
<el-col :span="12"><el-form-item label="银行流水号"><el-input v-model="registerForm.bankReference" /></el-form-item></el-col>
<el-col :span="24"><el-form-item label="收款单号"><el-input v-model="registerForm.receiptNo" placeholder="不填则自动生成" /></el-form-item></el-col>
<el-col :span="24"><el-form-item label="备注"><el-input v-model="registerForm.remark" type="textarea" :rows="2" /></el-form-item></el-col>
</el-row>
</el-form>
<template #footer><el-button type="primary" :loading="registerLoading" @click="submitRegister">登记</el-button><el-button @click="registerOpen = false">取消</el-button></template>
</el-dialog>
<el-dialog v-model="writeoffOpen" title="批量核销收款" width="680px" append-to-body>
<el-descriptions :column="3" border size="small" class="writeoff-summary"><el-descriptions-item label="收款单号">{{ writeoffForm.receiptNo }}</el-descriptions-item><el-descriptions-item label="币种">{{ writeoffForm.currency }}</el-descriptions-item><el-descriptions-item label="可核销">{{ money(writeoffForm.unallocatedAmount) }}</el-descriptions-item></el-descriptions>
<el-form label-width="90px" class="allocation-form"><div v-for="(item, index) in writeoffForm.allocations" :key="index" class="allocation-row"><el-form-item label="账单"><el-select v-model="item.arBillId" filterable clearable :loading="billLoading" placeholder="请选择账单" class="bill-select"><el-option v-for="bill in billOptions" :key="bill.arBillId" :label="billOptionLabel(bill)" :value="bill.arBillId" /></el-select></el-form-item><el-form-item label="核销金额"><el-input v-model="item.amount" type="number" /></el-form-item><el-button v-if="writeoffForm.allocations.length > 1" link type="danger" icon="Delete" @click="removeAllocation(index)" /></div><div v-if="writeoffOpen && !billLoading && !billOptions.length" class="bill-empty">当前客户暂无可核销账单</div><el-button link type="primary" icon="Plus" @click="addAllocation">添加账单</el-button><el-form-item label="核销日期"><el-date-picker v-model="writeoffForm.writeoffDate" type="date" value-format="YYYY-MM-DD" /></el-form-item><el-form-item label="备注"><el-input v-model="writeoffForm.remark" /></el-form-item></el-form>
<template #footer><el-button type="primary" :loading="writeoffLoading" @click="submitWriteoff">确认核销</el-button><el-button @click="writeoffOpen = false">取消</el-button></template>
</el-dialog>
<el-dialog v-model="historyOpen" title="核销记录" width="820px" append-to-body>
<el-table :data="historyRows" border size="small" v-loading="historyLoading">
<el-table-column prop="writeoffNo" label="核销单号" min-width="180" />
<el-table-column prop="billNo" label="账单号" min-width="180" show-overflow-tooltip />
<el-table-column prop="writeoffAmount" label="核销金额" width="120" align="right"><template #default="{ row }">{{ money(row.writeoffAmount) }}</template></el-table-column>
<el-table-column prop="writeoffDate" label="核销日期" width="120" />
<el-table-column prop="status" label="状态" width="100"><template #default="{ row }"><el-tag :type="row.status === 'EFFECTIVE' ? 'success' : 'info'">{{ row.status === 'EFFECTIVE' ? '有效' : '已取消' }}</el-tag></template></el-table-column>
<el-table-column label="操作" width="90"><template #default="{ row }"><el-button v-if="row.status === 'EFFECTIVE'" link type="danger" v-hasPermi="['ar:receipt:cancel']" @click="cancelWriteoff(row)">取消</el-button></template></el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script setup name="ArReceipt">
import { listArReceipt, addArReceipt, cancelArReceipt, listArWriteoffs, writeoffArReceipt, cancelArWriteoff } from '@/api/ar/receipt'
import { listArBill } from '@/api/ar/bill'
const { proxy } = getCurrentInstance()
const tableRef = ref()
const registerOpen = ref(false), registerLoading = ref(false), registerFormRef = ref()
const writeoffOpen = ref(false), writeoffLoading = ref(false)
const billLoading = ref(false), billOptions = ref([])
const historyOpen = ref(false), historyLoading = ref(false), historyRows = ref([]), historyReceiptId = ref(null)
const today = () => proxy.parseTime(new Date(), '{y}-{m}-{d}')
const registerForm = reactive({ customerId: '', receiptDate: today(), receiptAmount: '', currency: 'CNY', paymentMethod: 'BANK', bankReference: '', receiptNo: '', remark: '' })
const registerRules = { customerId: [{ required: true, message: '请选择客户', trigger: 'change' }], receiptDate: [{ required: true, message: '到账日期不能为空', trigger: 'change' }], receiptAmount: [{ required: true, message: '到账金额不能为空', trigger: 'blur' }] }
const writeoffForm = reactive({ receiptId: null, receiptNo: '', currency: '', unallocatedAmount: 0, writeoffDate: today(), remark: '', allocations: [{ arBillId: '', amount: '' }] })
const columns = [
{ label: '收款单号', prop: 'receiptNo', minWidth: 190, showOverflowTooltip: true }, { label: '客户', prop: 'customerName', minWidth: 180, showOverflowTooltip: true, formatter: row => customerText(row) }, { label: '到账日期', prop: 'receiptDate', width: 120 },
{ label: '到账金额', prop: 'receiptAmount', width: 135, align: 'right', slot: 'receiptAmount' }, { label: '未分配', prop: 'unallocatedAmount', width: 120, align: 'right', slot: 'unallocatedAmount' },
{ label: '收款方式', prop: 'paymentMethod', width: 110, formatter: row => methodText(row.paymentMethod) }, { label: '流水号', prop: 'bankReference', minWidth: 160, showOverflowTooltip: true },
{ label: '状态', prop: 'status', width: 120, slot: 'status' }, { label: '登记人', prop: 'createBy', width: 100 }, { label: '操作', prop: 'action', width: 150, fixed: 'right', slot: 'action', showInToolbar: false }
]
const searchColumns = [
{ label: '客户', prop: 'customerId', component: 'input', width: '160px' }, { label: '收款单号', prop: 'receiptNo', component: 'input', width: '180px' },
{ label: '状态', prop: 'status', component: 'select', options: [{ label: '已登记', value: 'REGISTERED' }, { label: '部分核销', value: 'PARTIAL_WRITTEN_OFF' }, { label: '已核销', value: 'WRITTEN_OFF' }, { label: '已取消', value: 'CANCELLED' }], width: '140px' },
{ label: '到账日期', prop: 'dateRange', component: 'daterange', width: '280px' }
]
function queryList(params) { const query = { ...params }; if (query.dateRange?.length === 2) { query.receiptDateStart = query.dateRange[0]; query.receiptDateEnd = query.dateRange[1] }; delete query.dateRange; return listArReceipt(query) }
function openRegister() { Object.assign(registerForm, { customerId: '', receiptDate: today(), receiptAmount: '', currency: 'CNY', paymentMethod: 'BANK', bankReference: '', receiptNo: '', remark: '' }); registerOpen.value = true; nextTick(() => registerFormRef.value?.clearValidate()) }
function submitRegister() { registerFormRef.value.validate(valid => { if (!valid) return; registerLoading.value = true; const data = { ...registerForm, customerId: Number(registerForm.customerId), receiptAmount: String(registerForm.receiptAmount) }; addArReceipt(data).then(() => { proxy.$modal.msgSuccess('收款登记成功'); registerOpen.value = false; tableRef.value.refresh() }).finally(() => { registerLoading.value = false }) }) }
function cancelReceipt(row) { proxy.$modal.confirm(`确认取消收款「${row.receiptNo}」?`).then(() => cancelArReceipt(row.receiptId, { remark: '页面取消收款' })).then(() => { proxy.$modal.msgSuccess('收款已取消'); tableRef.value.refresh() }).catch(() => {}) }
function openWriteoff(row) { Object.assign(writeoffForm, { receiptId: row.receiptId, receiptNo: row.receiptNo, currency: row.currency, unallocatedAmount: row.unallocatedAmount, writeoffDate: today(), remark: '', allocations: [{ arBillId: '', amount: '' }] }); billOptions.value = []; writeoffOpen.value = true; loadBillOptions(row) }
function loadBillOptions(row) { billLoading.value = true; return listArBill({ pageNum: 1, pageSize: 1000, customerId: row.customerId, currency: row.currency }).then(res => { billOptions.value = (res.rows || []).filter(bill => ['CONFIRMED', 'PARTIAL_WRITTEN_OFF'].includes(bill.status) && Number(bill.unwrittenAmount) > 0) }).finally(() => { billLoading.value = false }) }
function billOptionLabel(bill) { return `${bill.billNo || '未命名账单'}(未核销:${money(bill.unwrittenAmount)})` }
function addAllocation() { writeoffForm.allocations.push({ arBillId: '', amount: '' }) }
function removeAllocation(index) { writeoffForm.allocations.splice(index, 1) }
function submitWriteoff() { const allocations = writeoffForm.allocations.filter(item => item.arBillId && item.amount).map(item => ({ arBillId: Number(item.arBillId), amount: String(item.amount) })); if (!allocations.length) { proxy.$modal.msgError('请至少填写一条账单核销金额'); return }; writeoffLoading.value = true; writeoffArReceipt({ receiptId: writeoffForm.receiptId, currency: writeoffForm.currency, writeoffDate: writeoffForm.writeoffDate, remark: writeoffForm.remark, allocations }).then(() => { proxy.$modal.msgSuccess('核销成功'); writeoffOpen.value = false; tableRef.value.refresh(); if (historyOpen.value) openWriteoffHistory({ receiptId: writeoffForm.receiptId }) }).finally(() => { writeoffLoading.value = false }) }
function openWriteoffHistory(row) { historyReceiptId.value = row.receiptId; historyOpen.value = true; historyLoading.value = true; listArWriteoffs(row.receiptId).then(res => { historyRows.value = res.data || [] }).finally(() => { historyLoading.value = false }) }
function cancelWriteoff(row) { proxy.$modal.confirm(`确认取消核销「${row.writeoffNo}」?`).then(() => cancelArWriteoff(row.writeoffId, { remark: '页面取消核销' })).then(() => { proxy.$modal.msgSuccess('核销已取消'); openWriteoffHistory({ receiptId: historyReceiptId.value }); tableRef.value.refresh() }).catch(() => {}) }
function money(value) { const num = Number(value); return Number.isNaN(num) ? '-' : num.toFixed(2) }
function customerText(row) { return row.customerName ? `${row.customerName}${row.customerCode ? `(${row.customerCode})` : ''}` : row.customerCode || '-' }
function methodText(value) { return { BANK: '银行转账', ALIPAY: '支付宝', WECHAT: '微信', CASH: '现金' }[value] || value || '-' }
function receiptStatusText(value) { return { REGISTERED: '已登记', PARTIAL_WRITTEN_OFF: '部分核销', WRITTEN_OFF: '已核销', CANCELLED: '已取消' }[value] || value || '-' }
function receiptStatusType(value) { return { REGISTERED: 'info', PARTIAL_WRITTEN_OFF: 'warning', WRITTEN_OFF: 'success', CANCELLED: 'danger' }[value] || 'info' }
</script>
<style scoped>
.ar-receipt-page .income { color: #67c23a; font-weight: 600; }
.ar-receipt-page .pending { color: #e6a23c; font-weight: 600; }
.writeoff-summary { margin-bottom: 18px; }
.allocation-row { display: flex; align-items: center; gap: 10px; }
.allocation-row .el-form-item { flex: 1; }
.bill-select { width: 100%; }
.bill-empty { margin: -4px 0 12px 90px; color: var(--el-text-color-secondary); font-size: 13px; }
</style>