From a7315b44916d5aa59229ffbad9db1222e25876fb Mon Sep 17 00:00:00 2001 From: b2894lxlx <517289602@qq.com> Date: Mon, 7 Sep 2026 19:37:27 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E7=BB=93=E7=AE=97=E6=A8=A1?= =?UTF-8?q?=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/settlement/transportReconciliation.js | 2 - .../settlement/transportReconciliationForm.js | 4 +- .../transportReconciliationSearch.js | 4 +- .../transportReconciliationTable.js | 9 +- src/router/views/index.js | 27 + src/views/base/fee-item.vue | 26 +- src/views/base/region.vue | 51 +- .../components/billing-plan-editor.vue | 23 +- .../components/waybill-import-dialog.vue | 274 +++++++-- src/views/business/contract-manage.vue | 59 +- src/views/business/waybill-import-form.vue | 38 ++ .../payment/payment-application-form.vue | 64 +- .../components/formal-settlement-editor.vue | 422 ++++++++++--- .../components/pre-settlement-editor.vue | 557 ++++++++++++++---- .../transport-reconciliation-editor.vue | 557 ++++++++++++++---- .../transport-reconciliation-table-panel.vue | 2 - .../settlement/formal-settlement-form.vue | 1 + src/views/settlement/pre-settlement-form.vue | 2 +- .../transport-reconciliation-form.vue | 107 ++++ .../settlement/transport-reconciliation.vue | 23 +- src/views/vehicle/customer-archive.vue | 259 ++++---- 21 files changed, 1876 insertions(+), 635 deletions(-) create mode 100644 src/views/business/waybill-import-form.vue create mode 100644 src/views/settlement/transport-reconciliation-form.vue diff --git a/src/api/settlement/transportReconciliation.js b/src/api/settlement/transportReconciliation.js index 104b970..d8c3cf5 100644 --- a/src/api/settlement/transportReconciliation.js +++ b/src/api/settlement/transportReconciliation.js @@ -16,8 +16,6 @@ export const getFormalOptions = (current, size, params) => export const save = data => request({ url: `${baseUrl}/save`, method: 'post', data }); export const remove = id => request({ url: `${baseUrl}/remove`, method: 'post', params: { id } }); export const match = id => request({ url: `${baseUrl}/match`, method: 'post', params: { id } }); -export const manualMatch = data => - request({ url: `${baseUrl}/manual-match`, method: 'post', data }); export const unmatch = internalId => request({ url: `${baseUrl}/unmatch`, method: 'post', params: { internalId } }); export const adjust = data => request({ url: `${baseUrl}/adjust`, method: 'post', data }); diff --git a/src/option/settlement/transportReconciliationForm.js b/src/option/settlement/transportReconciliationForm.js index 69f249c..8735ab4 100644 --- a/src/option/settlement/transportReconciliationForm.js +++ b/src/option/settlement/transportReconciliationForm.js @@ -2,10 +2,8 @@ export const transportReconciliationFormFields = [ { prop: 'reconciliationNo', label: '对账单号', readonly: true }, { prop: 'reconciliationMode', label: '对账模式', type: 'mode' }, { prop: 'formalSettlementNo', label: '正式结算单', type: 'formal' }, - { prop: 'payerName', label: '付款方', readonly: true }, - { prop: 'payeeName', label: '收款方', readonly: true }, + { prop: 'customerName', label: '客户/承运商', readonly: true }, { prop: 'projectName', label: '项目', readonly: true }, - { prop: 'deptName', label: '所属组织', readonly: true }, { prop: 'contractName', label: '合同名称', readonly: true }, { prop: 'paidAmount', label: '已付合计', money: true, readonly: true }, { prop: 'reconcilerName', label: '对账人', readonly: true }, diff --git a/src/option/settlement/transportReconciliationSearch.js b/src/option/settlement/transportReconciliationSearch.js index 5577db4..0f1ca83 100644 --- a/src/option/settlement/transportReconciliationSearch.js +++ b/src/option/settlement/transportReconciliationSearch.js @@ -1,12 +1,12 @@ export const reconciliationMatchStatusOptions = [ - { label: '全部', value: '' }, + { label: '全部', value: 'all' }, { label: '未匹配', value: 'unmatched' }, { label: '部分匹配', value: 'partial' }, { label: '已匹配', value: 'matched' }, ]; export const reconciliationStatusOptions = [ - { label: '全部', value: '' }, + { label: '全部', value: 'all' }, { label: '未完成', value: 'unfinished' }, { label: '已完成', value: 'completed' }, ]; diff --git a/src/option/settlement/transportReconciliationTable.js b/src/option/settlement/transportReconciliationTable.js index 8bcc65a..aadac13 100644 --- a/src/option/settlement/transportReconciliationTable.js +++ b/src/option/settlement/transportReconciliationTable.js @@ -27,13 +27,10 @@ export const internalColumns = [ { prop: 'transportType', label: '运输类型', minWidth: 120 }, { prop: 'cargoName', label: '货物名称', minWidth: 120 }, { prop: 'cargoType', label: '货物类型', minWidth: 120 }, - { prop: 'specification', label: '规格', minWidth: 100 }, - { prop: 'model', label: '型号', minWidth: 100 }, { prop: 'transportQuantity', label: '运输总量', minWidth: 100, number: true }, - { prop: 'mileage', label: '里程(KM)', minWidth: 100, number: true }, + { prop: 'mileage', label: '里程(KM)', minWidth: 120, number: true }, { prop: 'batchNo', label: '批次号', minWidth: 100 }, { prop: 'unitPrice', label: '运输单价', minWidth: 110, money: true }, - { prop: 'freightAmount', label: '运输费', minWidth: 110, money: true }, { prop: 'settlementAmount', label: '结算金额', minWidth: 120, money: true }, { prop: 'matchResult', label: '匹配结果', minWidth: 100 }, { prop: 'updateResult', label: '账单更新结果', minWidth: 130 }, @@ -50,7 +47,7 @@ export const externalVehicleColumns = [ { prop: 'cargoName', label: '货物名称', minWidth: 120 }, { prop: 'cargoType', label: '货物类型', minWidth: 120 }, { prop: 'transportQuantity', label: '运输总量', minWidth: 100, number: true }, - { prop: 'mileage', label: '里程(KM)', minWidth: 100, number: true }, + { prop: 'mileage', label: '里程(KM)', minWidth: 120, number: true }, { prop: 'batchNo', label: '批次号', minWidth: 100 }, { prop: 'unitPrice', label: '运输单价', minWidth: 110, money: true }, { prop: 'freightAmount', label: '运费', minWidth: 110, money: true }, @@ -71,7 +68,7 @@ export const externalCargoColumns = [ { prop: 'model', label: '型号', minWidth: 100 }, { prop: 'transportQuantity', label: '运输量', minWidth: 100, number: true }, { prop: 'unitPrice', label: '运输单价', minWidth: 110, money: true }, - { prop: 'mileage', label: '里程(KM)', minWidth: 100, number: true }, + { prop: 'mileage', label: '里程(KM)', minWidth: 120, number: true }, { prop: 'freightAmount', label: '运输费', minWidth: 110, money: true }, { prop: 'settlementAmount', label: '结算金额', minWidth: 120, money: true }, ]; diff --git a/src/router/views/index.js b/src/router/views/index.js index 7248d7a..451ab81 100644 --- a/src/router/views/index.js +++ b/src/router/views/index.js @@ -116,6 +116,21 @@ export default [ }, ], }, + { + path: '/settlement/transport-reconciliation/form', + component: Layout, + children: [ + { + path: '', + name: '新增编辑运输对账单', + meta: { + keepAlive: false, + activeMenu: '/settlement/transport-reconciliation', + }, + component: () => import('@/views/settlement/transport-reconciliation-form.vue'), + }, + ], + }, { path: '/business/contract-manage/form', component: Layout, @@ -164,6 +179,18 @@ export default [ }, ], }, + { + path: '/business/waybill-import/form', + component: Layout, + children: [ + { + path: '', + name: '新建导入运单', + meta: { keepAlive: false, activeMenu: '/business/waybill-import' }, + component: () => import('@/views/business/waybill-import-form.vue'), + }, + ], + }, { path: '/business/loading-manage/form', component: Layout, diff --git a/src/views/base/fee-item.vue b/src/views/base/fee-item.vue index 0054421..9d5eed0 100644 --- a/src/views/base/fee-item.vue +++ b/src/views/base/fee-item.vue @@ -54,8 +54,8 @@ {{ formatCell(row, column) }} - + + @@ -1133,5 +1247,41 @@ const confirmImport = async () => { :deep(.el-table .el-date-editor) { width: 100%; } + + &__footer { + position: fixed; + z-index: 20; + right: 0; + bottom: 0; + left: 230px; + display: flex; + align-items: center; + justify-content: flex-end; + min-height: 64px; + box-sizing: border-box; + padding: 12px 24px; + background: #fff; + border-top: 1px solid #eff1f7; + box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06); + + // 统一 12px 间距,与全站底部操作栏(去 gap,由相邻按钮 margin 提供)一致 + .el-button + .el-button { + margin-left: 12px; + } + } + + &--page { + min-height: calc(100vh - 120px); + padding: 12px 24px 96px; + background: #fff; + } +} + +:global(.avue--collapse .waybill-import-create__footer) { + left: 60px; +} + +:global(.avue-layout--horizontal .waybill-import-create__footer) { + left: 0; } diff --git a/src/views/business/contract-manage.vue b/src/views/business/contract-manage.vue index 750472b..75f5c71 100644 --- a/src/views/business/contract-manage.vue +++ b/src/views/business/contract-manage.vue @@ -907,6 +907,27 @@ const defaultForm = () => ({ feeGenerationMode: 'system', remark: '', }); +// 复制新增:仅保留可编辑字段与明细,剔除主键、编号、审批与流程信息 +const createCopiedDetail = (detail = {}) => { + const form = defaultForm(); + Object.keys(form).forEach(prop => { + if (Object.prototype.hasOwnProperty.call(detail, prop)) form[prop] = detail[prop]; + }); + return { + ...form, + contractNo: '', + feeGenerationMode: detail.feeGenerationMode || '', + billingEnabled: detail.billingEnabled, + contractFileJson: detail.contractFileJson || '', + attachmentsJson: detail.attachmentsJson || '', + billingPlanJson: detail.billingPlanJson || '', + paymentRatioJson: detail.paymentRatioJson || '', + settlementRuleJson: detail.settlementRuleJson || '', + preSettlementConfigJson: detail.preSettlementConfigJson || '', + formalSettlementConfigJson: detail.formalSettlementConfigJson || '', + changeRecordJson: '', + }; +}; const parseArray = value => { if (Array.isArray(value)) return value; if (!value) return []; @@ -1458,11 +1479,7 @@ export default { ); }, canCopy(row) { - return ( - this.hasPermission(`${this.config.permission}_copy`) && - !row.readonly && - typeof this.api.copy === 'function' - ); + return this.hasPermission(`${this.config.permission}_copy`) && !row.readonly; }, editLabel(row) { return this.config.editLabelStatusMap?.[row.approvalStatus] || '编辑'; @@ -1559,6 +1576,11 @@ export default { initFormPage() { this.resetFormState(); if (this.formMode === 'add') { + const copyId = this.$route.query.copyId; + if (copyId) { + this.api.getDetail(copyId).then(res => this.applyCopyDetail(res.data?.data || {})); + return; + } this.loadContractPartyOptions(); return; } @@ -1624,6 +1646,12 @@ export default { this.syncCurrentOrganizationOption(); this.loadContractPartyOptions(); }, + applyCopyDetail(detail) { + this.applyDetail(createCopiedDetail(detail)); + this.form.handlerUserName = + this.userInfo?.realName || this.userInfo?.userName || this.userInfo?.account || ''; + this.$nextTick(() => this.$refs.contractForm?.clearValidate()); + }, closeForm() { this.$router.$avueRouter?.closeTag?.(); this.$router.push('/business/contract-manage'); @@ -1796,10 +1824,15 @@ export default { if (this.contractPartyLoading) return; const requestId = ++this.contractPartyRequestId; this.contractPartyLoading = true; - getCustomerArchiveList(1, 9999, { status: 1, approvalStatus: 'approved' }) - .then(res => { + const queryParams = { status: 1, approvalStatus: 'approved' }; + Promise.all([ + getCustomerArchiveList(1, 9999, queryParams), + getCustomerArchiveList(1, 9999, { ...queryParams, accessType: 'temporary' }), + ]) + .then(responses => { if (requestId !== this.contractPartyRequestId) return; - const names = extractRecords(res) + const names = responses + .flatMap(extractRecords) .map(item => item.fullName || item.shortName || item.customerName || item.customerCode) .map(name => String(name || '').trim()) .filter(Boolean); @@ -2336,12 +2369,10 @@ export default { }); }, handleCopy(row) { - this.$confirm('确定复制该合同?', '提示', { type: 'warning' }) - .then(() => this.api.copy(row.id)) - .then(() => { - this.$message.success('复制成功'); - this.onLoad(this.page, this.query); - }); + this.$router.push({ + path: '/business/contract-manage/form', + query: { mode: 'add', copyId: row.id, name: '新增合同管理' }, + }); }, openFlow(row, loaded = false) { const processInstanceId = row.processInstanceId || row.processInstanceID || row.procInstId; diff --git a/src/views/business/waybill-import-form.vue b/src/views/business/waybill-import-form.vue new file mode 100644 index 0000000..e2c978d --- /dev/null +++ b/src/views/business/waybill-import-form.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/src/views/payment/payment-application-form.vue b/src/views/payment/payment-application-form.vue index d924b07..13cee87 100644 --- a/src/views/payment/payment-application-form.vue +++ b/src/views/payment/payment-application-form.vue @@ -447,9 +447,6 @@ -
- 确定 -
-
- 确定 -
+ > + + - + + diff --git a/src/views/settlement/transport-reconciliation.vue b/src/views/settlement/transport-reconciliation.vue index 2698b4e..4b24afc 100644 --- a/src/views/settlement/transport-reconciliation.vue +++ b/src/views/settlement/transport-reconciliation.vue @@ -109,8 +109,8 @@ const emptyQuery = () => ({ contractNo: '', payerName: '', payeeName: '', - matchStatus: '', - reconciliationStatus: '', + matchStatus: 'all', + reconciliationStatus: 'all', }); export default { @@ -153,7 +153,7 @@ export default { try { const response = await api.getList(this.page.current, this.page.size, { // 所属组织级联返回 id 路径,转成组织名称传给后端(用副本,避免污染搜索框回显) - ...this.normalizeOrganizationSearch({ ...this.query }, 'deptName'), + ...this.buildSearchParams(), settlementType: this.settlementType, }); const data = response?.data?.data || response?.data || response || {}; @@ -183,10 +183,15 @@ export default { this.page.size = size; this.loadTable(); }, + buildSearchParams() { + const params = this.normalizeOrganizationSearch({ ...this.query }, 'deptName'); + if (params.matchStatus === 'all') params.matchStatus = ''; + if (params.reconciliationStatus === 'all') params.reconciliationStatus = ''; + return params; + }, handleAction({ type, row }) { const map = { view: this.openView, - edit: this.openEdit, delete: this.handleDelete, complete: this.handleComplete, }; @@ -194,10 +199,10 @@ export default { if (fn) fn(row); }, openCreate() { - this.editor = { visible: true, id: null, readonly: false }; - }, - openEdit(row) { - this.editor = { visible: true, id: row.id, readonly: false }; + this.$router.push({ + path: '/settlement/transport-reconciliation/form', + query: { mode: 'add', settlementType: this.settlementType, name: '新增运输对账单' }, + }); }, openView(row) { this.editor = { visible: true, id: row.id, readonly: true }; @@ -218,7 +223,7 @@ export default { }, async handleExport() { const params = { - ...this.normalizeOrganizationSearch({ ...this.query }, 'deptName'), + ...this.buildSearchParams(), settlementType: this.settlementType, }; if (this.selection.length) params.ids = this.selection.map(item => item.id).join(','); diff --git a/src/views/vehicle/customer-archive.vue b/src/views/vehicle/customer-archive.vue index 3299260..1ef7073 100644 --- a/src/views/vehicle/customer-archive.vue +++ b/src/views/vehicle/customer-archive.vue @@ -476,7 +476,7 @@ {{ row.reviewStatus }} - + - +