From 4d3b6cdaed9175caf48e3a2e375bd618bb042c93 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Fri, 16 Oct 2026 19:47:01 +0800
Subject: [PATCH 01/18] =?UTF-8?q?feat:=20=E7=BB=93=E7=AE=97=E8=B0=83?=
=?UTF-8?q?=E6=95=B4=E5=8D=95=E6=8E=A5=E5=85=A5=E9=87=91=E8=9D=B6=E5=88=97?=
=?UTF-8?q?=E8=A1=A8=E5=B1=95=E7=A4=BA=E4=B8=8E=E5=86=B2=E9=94=80=E9=A2=84?=
=?UTF-8?q?=E6=A3=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/api/settlement/settlementAdjustment.js | 4 ++
.../settlement/settlementAdjustmentTable.js | 2 +
.../settlement-adjustment-editor.vue | 15 +++++++
.../settlement/settlement-adjustment.vue | 42 +++++++++++++++----
4 files changed, 54 insertions(+), 9 deletions(-)
diff --git a/src/api/settlement/settlementAdjustment.js b/src/api/settlement/settlementAdjustment.js
index d809bf6..4c7b460 100644
--- a/src/api/settlement/settlementAdjustment.js
+++ b/src/api/settlement/settlementAdjustment.js
@@ -17,6 +17,10 @@ export const approve = id => request({ url: `${baseUrl}/approve`, method: 'post'
export const returnBill = (id, reason) =>
request({ url: `${baseUrl}/return`, method: 'post', data: { id, reason } });
export const repush = id => request({ url: `${baseUrl}/repush`, method: 'post', params: { id } });
+export const syncKingdee = id =>
+ request({ url: `${baseUrl}/sync-kingdee`, method: 'post', timeout: 30000, params: { id } });
+export const kingdeeWriteOffPrecheck = formalSettlementId =>
+ request({ url: `${baseUrl}/kingdee-writeoff-precheck`, method: 'get', params: { formalSettlementId } });
export const approvalStatusOptions = [
{ label: '草稿', value: 'draft' },
diff --git a/src/option/settlement/settlementAdjustmentTable.js b/src/option/settlement/settlementAdjustmentTable.js
index aaaa9fc..ad8b2fb 100644
--- a/src/option/settlement/settlementAdjustmentTable.js
+++ b/src/option/settlement/settlementAdjustmentTable.js
@@ -9,6 +9,8 @@ export const settlementAdjustmentTableColumns = [
{ label: '合同名称', prop: 'contractName', minWidth: 170 },
{ label: '调整金额', prop: 'adjustmentAmount', minWidth: 130, money: true },
{ label: '审核状态', prop: 'approvalStatusName', minWidth: 110, status: true },
+ { label: '金蝶单据状态', prop: 'kingdeeSyncStatus', minWidth: 130, kingdee: true },
+ { label: '金蝶单据号', prop: 'kingdeeBillNo', minWidth: 150 },
{ label: '当前节点', prop: 'currentNode', minWidth: 120 },
{ label: '当前处理人', prop: 'currentProcessor', minWidth: 130 },
{ label: '创建人', prop: 'createUserName', minWidth: 110 },
diff --git a/src/views/settlement/components/settlement-adjustment-editor.vue b/src/views/settlement/components/settlement-adjustment-editor.vue
index 0c646d3..0ee9530 100644
--- a/src/views/settlement/components/settlement-adjustment-editor.vue
+++ b/src/views/settlement/components/settlement-adjustment-editor.vue
@@ -414,6 +414,8 @@ export default {
});
this.details = [];
this.recalculate();
+ // 金蝶冲销预检:软提示,不阻断建单(金蝶不可用时静默降级)
+ this.precheckWriteOff(formalSettlementId);
this.loading = true;
try {
const { data } = await api.getFormalDetails(formalSettlementId);
@@ -431,6 +433,19 @@ export default {
this.loading = false;
}
},
+ async precheckWriteOff(formalSettlementId) {
+ try {
+ const { data } = await api.kingdeeWriteOffPrecheck(formalSettlementId);
+ if (String(this.form.formalSettlementId) !== String(formalSettlementId)) return;
+ const result = data?.data || data || {};
+ if (!result.message) return;
+ if (result.syncStatus === 'synced' && result.writtenOff === false)
+ this.$message.warning(result.message);
+ else this.$message.info(result.message);
+ } catch (error) {
+ // 预检软提示:金蝶查询失败静默降级,不阻断建单
+ }
+ },
addFeeRow() {
this.details.push({
formalSettlementDetailId: null,
diff --git a/src/views/settlement/settlement-adjustment.vue b/src/views/settlement/settlement-adjustment.vue
index c4bacd4..9a43c11 100644
--- a/src/views/settlement/settlement-adjustment.vue
+++ b/src/views/settlement/settlement-adjustment.vue
@@ -93,11 +93,16 @@
>{{
row[column.prop] || '-'
}}{{ kingdeeSyncName(row.kingdeeSyncStatus) }}{{ formatMoney(row[column.prop]) }}{{ displayValue(row[column.prop]) }}
-
驳回推送金蝶
{{ displayValue(row.createTime) }}
+
+
+ 重新推送
+ -
+
+
@@ -1048,6 +1064,7 @@ import KingdeeInvoicePoolDialog from '@/components/kingdee-invoice-pool-dialog/m
import ProjectAdvanceWriteOff from './project-advance-write-off.vue';
import * as XLSX from 'xlsx';
import { isAdministrator } from '@/utils/auth';
+import * as settlementAdjustmentApi from '@/api/settlement/settlementAdjustment';
// 结算币种为本位币(人民币)时汇率恒为1,汇率日期、结算汇率与按汇率换算的本位币合计都不展示
const LOCAL_CURRENCY_HIDDEN_FIELDS = ['exchangeRateDate', 'exchangeRate', 'localSettlementAmount'];
@@ -1316,6 +1333,17 @@ export default {
hasPermission(code) {
return this.isAdmin || this.validData(this.permission?.[code], false);
},
+ async handleAdjustmentRepush(row) {
+ await this.$confirm(
+ '请确认金蝶旧应付/应收单已由财务手工冲销,继续将生成全新财务应付/应收单。',
+ '高危操作确认',
+ { type: 'warning', confirmButtonText: '确认重新推送' }
+ );
+ const res = await settlementAdjustmentApi.repush(row.id);
+ this.$message.success(`已生成新金蝶单据:${res.data?.data || res.data || '-'}`);
+ await this.loadFormalDetail(this.recordId);
+ this.$emit('success');
+ },
async loadFormalDetail(id) {
const response = this.publicMode
? await getMkPublicDetail('formal-settlement', id)
diff --git a/src/views/settlement/components/formal-settlement-table-panel.vue b/src/views/settlement/components/formal-settlement-table-panel.vue
index 9108e5c..80ed458 100644
--- a/src/views/settlement/components/formal-settlement-table-panel.vue
+++ b/src/views/settlement/components/formal-settlement-table-panel.vue
@@ -92,6 +92,7 @@
{{
kingdeeSyncName(row.kingdeeSyncStatus)
}}
+ {{ adjustFlag(row) }}
{{ lockTag(row).label }}
@@ -275,6 +276,12 @@ export default {
kingdeeSyncName(value) {
return kingdeeSyncStatusOptions.find(item => item.value === value)?.label || value || '-';
},
+ adjustFlag(row) {
+ // 原单已调整 / 重推生成的新单(显示来源原单号)
+ if (row.adjustStatusName) return row.adjustStatusName;
+ if (row.originFormalSettlementNo) return '调整后单';
+ return '-';
+ },
lockTag(row) {
if (row.kingdeeLockStatus === 'locked') {
return { show: true, type: 'danger', label: '金蝶锁定中', tip: '该单据已被金蝶锁定,不可编辑/作废' };
From c1bc55e1335b494240c2377cc937bde05accde5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=88=98=E6=B3=89=E4=BD=B3?= <1107186916@qq.com>
Date: Fri, 16 Oct 2026 19:58:52 +0800
Subject: [PATCH 03/18] =?UTF-8?q?refactor:=20=E7=BB=93=E7=AE=97=E8=B0=83?=
=?UTF-8?q?=E6=95=B4=E5=8D=95=E6=8E=A8=E9=80=81=E9=87=91=E8=9D=B6=E4=B8=8E?=
=?UTF-8?q?=E9=87=8D=E6=96=B0=E6=8E=A8=E9=80=81=E5=90=88=E5=B9=B6=E4=B8=BA?=
=?UTF-8?q?=E5=8D=95=E4=B8=80=E6=8C=89=E9=92=AE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../settlement/settlement-adjustment.vue | 26 +++++++------------
1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/src/views/settlement/settlement-adjustment.vue b/src/views/settlement/settlement-adjustment.vue
index 9a43c11..60d321e 100644
--- a/src/views/settlement/settlement-adjustment.vue
+++ b/src/views/settlement/settlement-adjustment.vue
@@ -144,23 +144,10 @@
@click="handleReturn(row)"
>驳回推送金蝶重新推送(高危){{ row.kingdeeSyncStatus === 'synced' ? '重新推送(高危)' : '推送金蝶' }}
Date: Sat, 17 Oct 2026 00:56:04 +0800
Subject: [PATCH 04/18] =?UTF-8?q?style:=20=E4=BF=AE=E5=A4=8D=E7=9C=8B?=
=?UTF-8?q?=E6=9D=BF=E7=BB=84=E4=BB=B6=20sass=20@import=20=E5=BC=83?=
=?UTF-8?q?=E7=94=A8=E8=AD=A6=E5=91=8A=EF=BC=8C=E6=94=B9=E7=94=A8=20@use?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/views/wel/components/rank-panel.vue | 2 +-
src/views/wel/components/section-business.vue | 2 +-
src/views/wel/components/section-finance.vue | 2 +-
src/views/wel/components/section-fleet.vue | 2 +-
src/views/wel/components/section-kpi.vue | 2 +-
src/views/wel/components/section-project.vue | 2 +-
src/views/wel/components/section-structure.vue | 2 +-
src/views/wel/components/section-summary.vue | 2 +-
src/views/wel/components/section-vehicle.vue | 2 +-
src/views/wel/components/wel-filters.vue | 2 +-
10 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/views/wel/components/rank-panel.vue b/src/views/wel/components/rank-panel.vue
index 1ffaa6e..982968a 100644
--- a/src/views/wel/components/rank-panel.vue
+++ b/src/views/wel/components/rank-panel.vue
@@ -42,5 +42,5 @@ export default {
diff --git a/src/views/wel/components/section-business.vue b/src/views/wel/components/section-business.vue
index 9322f72..a0e3d8c 100644
--- a/src/views/wel/components/section-business.vue
+++ b/src/views/wel/components/section-business.vue
@@ -156,7 +156,7 @@ export default {
正式结算单
结算单号:${this.escapeHtml(
+ }
${this.escapeHtml(
+ settlementBillLabel(row.settlementType || this.activeSettlementType)
+ )}
结算单号:${this.escapeHtml(
row.formalSettlementNo
- )}
预结算单号:${this.escapeHtml(
+ )}
预付结算单号:${this.escapeHtml(
row.preSettlementNos
)}
项目:${this.escapeHtml(
row.projectName
@@ -582,12 +675,15 @@ export default {
const params = this.buildQueryParams();
if (this.selection.length) params.ids = this.selection.map(item => item.id).join(',');
const { data } = await api.exportList(params);
- downloadFile(data, `正式结算单${this.$dayjs().format('YYYY-MM-DD HH-mm-ss')}.xlsx`);
+ downloadFile(
+ data,
+ `${this.billLabel}${this.$dayjs().format('YYYY-MM-DD HH-mm-ss')}.xlsx`
+ );
},
buildQueryParams() {
// 所属组织级联返回 id 路径,转成组织名称传给后端(用副本,避免污染搜索框回显)
const params = this.normalizeOrganizationSearch({ ...this.query }, 'deptName');
- params.settlementType = this.activeSettlementType;
+ params.settlementType = this.lockedSettlementType || this.activeSettlementType;
const range = params.createDateRange || [];
delete params.createDateRange;
if (range.length === 2) {
diff --git a/src/views/settlement/payment-settlement.vue b/src/views/settlement/payment-settlement.vue
new file mode 100644
index 0000000..66ac565
--- /dev/null
+++ b/src/views/settlement/payment-settlement.vue
@@ -0,0 +1,12 @@
+
+
+
+
+
diff --git a/src/views/settlement/pre-settlement-form.vue b/src/views/settlement/pre-settlement-form.vue
index 9bd3549..18586de 100644
--- a/src/views/settlement/pre-settlement-form.vue
+++ b/src/views/settlement/pre-settlement-form.vue
@@ -1,7 +1,7 @@
{{ pageTitle }}
-
+
- 查看预结算
+ 查看预付结算单
item.preSettlementNo === preSettlementNo);
if (!row) {
- this.$message.warning('未找到对应的预结算单');
+ this.$message.warning('未找到对应的预付结算单');
return;
}
this.openView(row);
@@ -474,30 +474,30 @@ export default {
return ['draft', 'returned'].includes(row.approvalStatus);
},
async handleDelete(row) {
- await this.$confirm('确认删除该预结算草稿?', '提示', { type: 'warning' });
+ await this.$confirm('确认删除该预付结算单草稿?', '提示', { type: 'warning' });
await remove(row.id);
this.$message.success('删除成功');
this.loadTable();
},
selectedOne(operationName) {
if (this.selection.length !== 1) {
- this.$message.warning(`${operationName}需选择一条预结算单`);
+ this.$message.warning(`${operationName}需选择一条预付结算单`);
return null;
}
return this.selection[0];
},
handleAdvanceApplication() {
if (!this.selection.length) {
- this.$message.warning('请选择需要发起预付申请的预结算单');
+ this.$message.warning('请选择需要发起预付申请的预付结算单');
return;
}
if (this.selection.some(row => !row.contractId)) {
- this.$message.warning('所选预结算单缺少合同ID,无法发起预付申请');
+ this.$message.warning('所选预付结算单缺少合同ID,无法发起预付申请');
return;
}
const contractIds = new Set(this.selection.map(row => String(row.contractId)));
if (contractIds.size > 1) {
- this.$message.warning('预付申请只能选择同一合同下的预结算单');
+ this.$message.warning('预付申请只能选择同一合同下的预付结算单');
return;
}
if (
@@ -508,7 +508,7 @@ export default {
row.formalSettlementNo
)
) {
- this.$message.warning('仅审批通过、未转正式结算的应付预结算单可发起预付');
+ this.$message.warning('仅审批通过、未转付款结算的应付预付结算单可发起预付');
return;
}
const sourcePreSettlements = this.selection.map(row => ({
@@ -533,11 +533,11 @@ export default {
},
handleFormalSettlement() {
if (!this.selection.length) {
- this.$message.warning('请选择需要转正式结算的预结算单');
+ this.$message.warning('请选择需要转付款结算的预付结算单');
return;
}
if (this.selection.some(row => row.approvalStatus !== 'approved')) {
- this.$message.warning('仅审核通过的预结算单可转正式结算');
+ this.$message.warning('仅审核通过的预付结算单可转付款结算');
return;
}
const hasCompleteProjectIds = this.selection.every(
@@ -549,7 +549,7 @@ export default {
)
);
if (projectKeys.size > 1) {
- this.$message.warning('尾款结算只能选择同一项目下的预结算单');
+ this.$message.warning('尾款结算只能选择同一项目下的预付结算单');
return;
}
const transferToken = createSettlementTransfer({
@@ -560,14 +560,20 @@ export default {
});
this.$router.push({
path: '/settlement/formal-settlement/form',
- query: { mode: 'add', name: '新增正式结算', transferToken },
+ query: {
+ mode: 'add',
+ name: '新增付款结算单',
+ settlementType: 'payable',
+ listPath: '/settlement/payment-settlement',
+ transferToken,
+ },
});
},
async openPrintDialog() {
const row = this.selectedOne('打印结算单');
if (!row) return;
if (row.approvalStatus === 'voided') {
- this.$message.warning('已作废的预结算单不能打印');
+ this.$message.warning('已作废的预付结算单不能打印');
return;
}
this.printDialog.row = row;
@@ -622,8 +628,8 @@ export default {
)
.join('');
return `${this.escapeHtml(
- detail.preSettlementNo || '预结算单'
- )}预结算单