✨ 结算单业务模式运输方式与编辑体验优化

预结算/收付款结算支持业务模式与运输方式展示导出;完善结算调整、对账导入与变更记录;组织合同初始流水号未填不再显示-1。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-21 16:42:02 +08:00
parent 6a21b4ac8d
commit e7c76c803f
11 changed files with 310 additions and 93 deletions
@@ -8,6 +8,8 @@ export const formalSettlementFormFields = [
{ label: '收款方', prop: 'payeeName', readonly: true }, { label: '收款方', prop: 'payeeName', readonly: true },
{ label: '结算类型', prop: 'settlementTypeName', readonly: true }, { label: '结算类型', prop: 'settlementTypeName', readonly: true },
{ label: '结算金额', prop: 'settlementAmount', readonly: true, money: true }, { label: '结算金额', prop: 'settlementAmount', readonly: true, money: true },
{ label: '业务模式', prop: 'businessModel', type: 'select', optionsKey: 'businessModelOptions' },
{ label: '运输方式', prop: 'transportType', type: 'select', optionsKey: 'transportTypeOptions' },
{ label: '汇率日期', prop: 'exchangeRateDate', type: 'date', required: true }, { label: '汇率日期', prop: 'exchangeRateDate', type: 'date', required: true },
{ label: '结算汇率', prop: 'exchangeRate', type: 'number', required: true }, { label: '结算汇率', prop: 'exchangeRate', type: 'number', required: true },
{ label: '本位币合计', prop: 'localSettlementAmount', readonly: true, money: true }, { label: '本位币合计', prop: 'localSettlementAmount', readonly: true, money: true },
@@ -25,6 +27,8 @@ export const createFormalSettlementForm = () => ({
settlementType: '', settlementType: '',
sourcePreSettlementIds: [], sourcePreSettlementIds: [],
sourceDetailIds: [], sourceDetailIds: [],
businessModel: '',
transportType: '',
exchangeRateDate: '', exchangeRateDate: '',
exchangeRate: 1, exchangeRate: 1,
createUserName: '', createUserName: '',
@@ -8,6 +8,8 @@ export const formalSettlementTableColumns = [
{ label: '合同编号', prop: 'contractNo', minWidth: 150 }, { label: '合同编号', prop: 'contractNo', minWidth: 150 },
{ label: '合同名称', prop: 'contractName', minWidth: 170 }, { label: '合同名称', prop: 'contractName', minWidth: 170 },
{ label: '原币结算金额', prop: 'settlementAmount', minWidth: 145, money: true }, { label: '原币结算金额', prop: 'settlementAmount', minWidth: 145, money: true },
{ label: '业务模式', prop: 'businessModelName', minWidth: 120 },
{ label: '运输方式', prop: 'transportTypeName', minWidth: 120 },
{ label: '本位币结算金额', prop: 'localSettlementAmount', minWidth: 155, money: true }, { label: '本位币结算金额', prop: 'localSettlementAmount', minWidth: 155, money: true },
{ label: '结算汇率', prop: 'exchangeRate', minWidth: 110 }, { label: '结算汇率', prop: 'exchangeRate', minWidth: 110 },
{ label: '申请付款金额(含预付)', prop: 'appliedPaymentAmount', minWidth: 185, money: true }, { label: '申请付款金额(含预付)', prop: 'appliedPaymentAmount', minWidth: 185, money: true },
@@ -12,6 +12,8 @@ export const preSettlementFormFields = [
{ label: '付款方', prop: 'payerName', readonly: true }, { label: '付款方', prop: 'payerName', readonly: true },
{ label: '结算类型', prop: 'settlementType', readonly: true }, { label: '结算类型', prop: 'settlementType', readonly: true },
{ label: '结算金额', prop: 'settlementAmount', readonly: true, money: true }, { label: '结算金额', prop: 'settlementAmount', readonly: true, money: true },
{ label: '业务模式', prop: 'businessModel', type: 'select', optionsKey: 'businessModelOptions' },
{ label: '运输方式', prop: 'transportType', type: 'select', optionsKey: 'transportTypeOptions' },
{ label: '汇率日期', prop: 'exchangeRateDate', type: 'date' }, { label: '汇率日期', prop: 'exchangeRateDate', type: 'date' },
{ label: '结算汇率', prop: 'exchangeRate', type: 'number', class: 'exchange-rate-input' }, { label: '结算汇率', prop: 'exchangeRate', type: 'number', class: 'exchange-rate-input' },
{ label: '本位币合计', prop: 'localSettlementAmount', readonly: true, money: true }, { label: '本位币合计', prop: 'localSettlementAmount', readonly: true, money: true },
@@ -64,6 +66,8 @@ export const emptyPreSettlementForm = () => ({
settlementType: 'payable', settlementType: 'payable',
currency: 'RMB', currency: 'RMB',
settlementAmount: 0, settlementAmount: 0,
businessModel: '',
transportType: '',
localCurrency: 'RMB', localCurrency: 'RMB',
localSettlementAmount: 0, localSettlementAmount: 0,
exchangeRateDate: '', exchangeRateDate: '',
@@ -8,6 +8,8 @@ export const preSettlementTableColumns = [
{ label: '合同编号', prop: 'contractNo', minWidth: 140 }, { label: '合同编号', prop: 'contractNo', minWidth: 140 },
{ label: '合同名称', prop: 'contractName', minWidth: 160 }, { label: '合同名称', prop: 'contractName', minWidth: 160 },
{ label: '原币结算金额', prop: 'settlementAmount', minWidth: 140, money: true, precision: 2 }, { label: '原币结算金额', prop: 'settlementAmount', minWidth: 140, money: true, precision: 2 },
{ label: '业务模式', prop: 'businessModelName', minWidth: 120 },
{ label: '运输方式', prop: 'transportTypeName', minWidth: 120 },
{ label: '本位币结算金额', prop: 'localSettlementAmount', minWidth: 150, money: true, precision: 2 }, { label: '本位币结算金额', prop: 'localSettlementAmount', minWidth: 150, money: true, precision: 2 },
{ label: '结算汇率', prop: 'exchangeRate', minWidth: 110, precision: 2 }, { label: '结算汇率', prop: 'exchangeRate', minWidth: 110, precision: 2 },
{ {
+4 -4
View File
@@ -7,7 +7,7 @@ import 'nprogress/nprogress.css';
const excelPattern = /\.(xls|xlsx)$/; const excelPattern = /\.(xls|xlsx)$/;
/** 是否为浏览器 Blob(含跨 realm 的 Blob-like) */ /** 是否为浏览器 Blob(含跨 realm 的 Blob-like) */
const isBlobLike = value => export const isBlobLike = value =>
value != null && value != null &&
typeof value === 'object' && typeof value === 'object' &&
typeof value.size === 'number' && typeof value.size === 'number' &&
@@ -15,14 +15,14 @@ const isBlobLike = value =>
(typeof value.text === 'function' || typeof value.arrayBuffer === 'function'); (typeof value.text === 'function' || typeof value.arrayBuffer === 'function');
/** axios 拦截器已把 JSON Blob 解析成的业务对象 */ /** axios 拦截器已把 JSON Blob 解析成的业务对象 */
const isBusinessJson = value => export const isBusinessJson = value =>
value != null && value != null &&
typeof value === 'object' && typeof value === 'object' &&
!isBlobLike(value) && !isBlobLike(value) &&
!(value instanceof ArrayBuffer) && !(value instanceof ArrayBuffer) &&
('code' in value || 'success' in value || 'msg' in value); ('code' in value || 'success' in value || 'msg' in value);
const isExcelResponse = res => { export const isExcelResponse = res => {
// 已是业务 JSON(导入成功/失败提示)时,绝不能当失败明细 Excel 处理 // 已是业务 JSON(导入成功/失败提示)时,绝不能当失败明细 Excel 处理
if (isBusinessJson(res?.data)) { if (isBusinessJson(res?.data)) {
return false; return false;
@@ -54,7 +54,7 @@ const isExcelResponse = res => {
* 提前解析成普通对象;此处需同时兼容 Blob / 字符串 / 已解析对象,避免再调 * 提前解析成普通对象;此处需同时兼容 Blob / 字符串 / 已解析对象,避免再调
* `blob.text()` 时出现「blob.text is not a function」。 * `blob.text()` 时出现「blob.text is not a function」。
*/ */
const parseBlobJson = async data => { export const parseBlobJson = async data => {
if (data == null) { if (data == null) {
return {}; return {};
} }
+18 -1
View File
@@ -3,10 +3,27 @@ export function isFreightFeeName(name) {
return text.includes('运费') || text.includes('运输费'); return text.includes('运费') || text.includes('运输费');
} }
function parseBillingRules(row = {}) {
const rule = row.billingRule || {};
const nested = Array.isArray(rule.rules) ? rule.rules : [];
if (nested.length) return nested;
const raw = row.billingRulesJson ?? row.billingRules;
if (Array.isArray(raw)) return raw.filter(item => item && typeof item === 'object');
if (typeof raw === 'string' && raw.trim()) {
try {
const parsed = JSON.parse(raw);
return Array.isArray(parsed) ? parsed.filter(item => item && typeof item === 'object') : [];
} catch (error) {
return [];
}
}
return [];
}
/** 运输单价对应的运费计费类型。 */ /** 运输单价对应的运费计费类型。 */
export function freightBillingType(row = {}) { export function freightBillingType(row = {}) {
const rule = row.billingRule || {}; const rule = row.billingRule || {};
const rules = Array.isArray(rule.rules) ? rule.rules : []; const rules = parseBillingRules(row);
const freightRule = rules.find( const freightRule = rules.find(
item => isFreightFeeName(item?.feeItem) || isFreightFeeName(item?.feeType) item => isFreightFeeName(item?.feeItem) || isFreightFeeName(item?.feeType)
); );
+6
View File
@@ -0,0 +1,6 @@
/** 审批通过、驳回等审批流转类变更内容,不在结算单变更记录中展示。 */
export function isApprovalSettlementChange(content) {
const text = String(content || '').trim();
if (!text) return false;
return text.includes('审批通过') || text.includes('审批驳回') || text === '已驳回';
}
@@ -64,6 +64,20 @@
:precision="2" :precision="2"
:controls="false" :controls="false"
/> />
<el-select
v-else-if="field.type === 'select' && editable"
v-model="form[field.prop]"
filterable
clearable
placeholder="请选择"
>
<el-option
v-for="item in formSelectOptions(field)"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey"
/>
</el-select>
<span <span
v-else-if="field.prop === 'formalSettlementNo'" v-else-if="field.prop === 'formalSettlementNo'"
:class="{ 'form-readonly--code': form.formalSettlementNo }" :class="{ 'form-readonly--code': form.formalSettlementNo }"
@@ -71,6 +85,9 @@
{{ form.formalSettlementNo || (form.id ? '-' : '系统自动生成') }} {{ form.formalSettlementNo || (form.id ? '-' : '系统自动生成') }}
</span> </span>
<span v-else-if="field.money">{{ formatMoney(form[field.prop]) }}</span> <span v-else-if="field.money">{{ formatMoney(form[field.prop]) }}</span>
<span v-else-if="field.type === 'select'">{{
formSelectLabel(field, form[field.prop])
}}</span>
<span v-else-if="field.type === 'contract'">{{ <span v-else-if="field.type === 'contract'">{{
displayValue(form.contractName) displayValue(form.contractName)
}}</span> }}</span>
@@ -424,26 +441,7 @@
<section-card title="发票信息"> <section-card title="发票信息">
<div class="formal-editor__invoice-claim"> <div class="formal-editor__invoice-claim">
<el-form inline label-position="right" label-width="auto" @submit.prevent> <el-button type="primary" @click="openInvoiceClaimDialog">认领查询</el-button>
<el-form-item label="发票号码">
<el-input
v-model="invoiceClaimNo"
clearable
maxlength="32"
placeholder="请输入发票号码"
@keyup.enter="openInvoiceClaimDialog"
/>
</el-form-item>
<el-form-item>
<el-button
type="primary"
:loading="invoiceClaimLoading"
@click="openInvoiceClaimDialog"
>
认领查询
</el-button>
</el-form-item>
</el-form>
</div> </div>
<el-table :data="invoices" border> <el-table :data="invoices" border>
<el-table-column type="index" label="序号" width="64" align="center" /> <el-table-column type="index" label="序号" width="64" align="center" />
@@ -544,7 +542,6 @@
title="查询可认领发票" title="查询可认领发票"
confirm-text="确认认领" confirm-text="确认认领"
multiple multiple
:initial-invoice-no="String(invoiceClaimNo || '').trim()"
:query-api="invoicePoolQueryApi" :query-api="invoicePoolQueryApi"
@confirm="handleInvoiceClaimConfirm" @confirm="handleInvoiceClaimConfirm"
/> />
@@ -697,9 +694,19 @@
<el-table-column prop="changeTime" label="变更时间" min-width="170" align="center"> <el-table-column prop="changeTime" label="变更时间" min-width="170" align="center">
<template #default="{ row }">{{ displayValue(row.changeTime) }}</template> <template #default="{ row }">{{ displayValue(row.changeTime) }}</template>
</el-table-column> </el-table-column>
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="{ row }">
<el-link type="primary" @click="openChangeRecordDetail(row)">详情</el-link>
</template>
</el-table-column>
</el-table> </el-table>
</section-card> </section-card>
</div> </div>
<change-record-detail-dialog
v-model="changeRecordDetailVisible"
:rows="changeRecordDetailRows"
/>
<template v-if="!pageMode" #footer> <template v-if="!pageMode" #footer>
<el-button v-if="editable" @click="handleSyncPlaceholder">同步</el-button> <el-button v-if="editable" @click="handleSyncPlaceholder">同步</el-button>
<el-button @click="visible = false">取消</el-button> <el-button @click="visible = false">取消</el-button>
@@ -1071,6 +1078,7 @@ import { getDictionary } from '@/api/system/dictbiz';
import { h } from 'vue'; import { h } from 'vue';
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import { isTierUnitPrice, isUnitPriceAdjustable } from '@/utils/settlement-adjust-rule'; import { isTierUnitPrice, isUnitPriceAdjustable } from '@/utils/settlement-adjust-rule';
import { isApprovalSettlementChange } from '@/utils/settlement-change-record';
import { normalizeCurrencyCode } from '@/utils/currency'; import { normalizeCurrencyCode } from '@/utils/currency';
import { import {
settlementRecordTypeName, settlementRecordTypeName,
@@ -1083,6 +1091,7 @@ import {
viewKingdeeInvoiceFile, viewKingdeeInvoiceFile,
} from '@/utils/kingdee-attachment'; } from '@/utils/kingdee-attachment';
import KingdeeInvoicePoolDialog from '@/components/kingdee-invoice-pool-dialog/main.vue'; import KingdeeInvoicePoolDialog from '@/components/kingdee-invoice-pool-dialog/main.vue';
import ChangeRecordDetailDialog from '@/components/change-record-detail-dialog/main.vue';
import ProjectAdvanceWriteOff from './project-advance-write-off.vue'; import ProjectAdvanceWriteOff from './project-advance-write-off.vue';
import * as XLSX from 'xlsx'; import * as XLSX from 'xlsx';
import { isAdministrator } from '@/utils/auth'; import { isAdministrator } from '@/utils/auth';
@@ -1093,7 +1102,12 @@ const LOCAL_CURRENCY_HIDDEN_FIELDS = ['exchangeRateDate', 'exchangeRate', 'local
export default { export default {
name: 'FormalSettlementEditor', name: 'FormalSettlementEditor',
components: { InfoFilled, KingdeeInvoicePoolDialog, ProjectAdvanceWriteOff }, components: {
InfoFilled,
KingdeeInvoicePoolDialog,
ChangeRecordDetailDialog,
ProjectAdvanceWriteOff,
},
props: { props: {
modelValue: Boolean, modelValue: Boolean,
recordId: [String, Number], recordId: [String, Number],
@@ -1123,14 +1137,14 @@ export default {
receiptClaims: [], receiptClaims: [],
adjustments: [], adjustments: [],
changeRecords: [], changeRecords: [],
changeRecordDetailVisible: false,
changeRecordDetailRows: [],
projectAdvanceWriteOffs: [], projectAdvanceWriteOffs: [],
attachments: [], attachments: [],
selectedAttachmentRows: [], selectedAttachmentRows: [],
invoices: [], invoices: [],
// 开票申请经金蝶回写的发票结果(只读展示,含板式文件/数电PDF下载地址) // 开票申请经金蝶回写的发票结果(只读展示,含板式文件/数电PDF下载地址)
issuedInvoices: [], issuedInvoices: [],
invoiceClaimNo: '',
invoiceClaimLoading: false,
// 金蝶侧发票附件查看/下载进行中(行组级 loading 守卫) // 金蝶侧发票附件查看/下载进行中(行组级 loading 守卫)
kingdeeAttachmentBusy: false, kingdeeAttachmentBusy: false,
invoiceClaimDialog: { invoiceClaimDialog: {
@@ -1162,6 +1176,7 @@ export default {
projects: [], projects: [],
feeOptions: [], feeOptions: [],
feeCategoryOptions: [], feeCategoryOptions: [],
businessModelOptions: [],
transportTypeOptions: [], transportTypeOptions: [],
fields: formalSettlementFormFields, fields: formalSettlementFormFields,
sourceTableColumns: sourceColumns, sourceTableColumns: sourceColumns,
@@ -1438,7 +1453,9 @@ export default {
this.receiptClaims = this.unwrapData(await getReceiptClaims(id)) || []; this.receiptClaims = this.unwrapData(await getReceiptClaims(id)) || [];
} }
this.adjustments = data.adjustments || []; this.adjustments = data.adjustments || [];
this.changeRecords = data.changeRecords || []; this.changeRecords = (data.changeRecords || []).filter(
row => !isApprovalSettlementChange(row.changeContent)
);
this.projectAdvanceWriteOffs = (data.projectAdvanceWriteOffs || []).map(row => ({ this.projectAdvanceWriteOffs = (data.projectAdvanceWriteOffs || []).map(row => ({
...row, ...row,
writeOffAmount: Number(row.writeOffAmount || 0), writeOffAmount: Number(row.writeOffAmount || 0),
@@ -1476,13 +1493,14 @@ export default {
this.receiptClaims = []; this.receiptClaims = [];
this.adjustments = []; this.adjustments = [];
this.changeRecords = []; this.changeRecords = [];
this.changeRecordDetailVisible = false;
this.changeRecordDetailRows = [];
this.projectAdvanceWriteOffs = []; this.projectAdvanceWriteOffs = [];
this.advancePayments = []; this.advancePayments = [];
this.attachments = []; this.attachments = [];
this.selectedAttachmentRows = []; this.selectedAttachmentRows = [];
this.invoices = []; this.invoices = [];
this.issuedInvoices = []; this.issuedInvoices = [];
this.invoiceClaimNo = '';
this.invoiceClaimDialog.visible = false; this.invoiceClaimDialog.visible = false;
this.invoiceClaimDialog.selected = []; this.invoiceClaimDialog.selected = [];
this.attachmentUploadFiles = []; this.attachmentUploadFiles = [];
@@ -1499,6 +1517,7 @@ export default {
this.loadFeeOptions(), this.loadFeeOptions(),
this.loadFeeCategoryOptions(), this.loadFeeCategoryOptions(),
this.loadAttachmentTypeOptions(), this.loadAttachmentTypeOptions(),
this.loadBusinessModelOptions(),
this.loadTransportTypeOptions(), this.loadTransportTypeOptions(),
]); ]);
} }
@@ -2424,6 +2443,7 @@ export default {
row.settlementAmountTax = Number(data.afterAmount || 0); row.settlementAmountTax = Number(data.afterAmount || 0);
} catch (error) { } catch (error) {
row.calculateError = error.message || '费用试算失败'; row.calculateError = error.message || '费用试算失败';
this.$message.warning(row.calculateError);
} finally { } finally {
if (version === row.adjustCalculateVersion) row.calculating = false; if (version === row.adjustCalculateVersion) row.calculating = false;
} }
@@ -2796,6 +2816,8 @@ export default {
sourceDetailId: row.sourcePreSettlementId ? undefined : row.sourceDetailId || row.id, sourceDetailId: row.sourcePreSettlementId ? undefined : row.sourceDetailId || row.id,
adjustAmount: Number(row.adjustAmount || 0), adjustAmount: Number(row.adjustAmount || 0),
})), })),
businessModel: this.form.businessModel || undefined,
transportType: this.form.transportType || undefined,
exchangeRateDate: this.form.exchangeRateDate, exchangeRateDate: this.form.exchangeRateDate,
exchangeRate: this.form.exchangeRate, exchangeRate: this.form.exchangeRate,
summaryFees: this.summaryFees summaryFees: this.summaryFees
@@ -2886,6 +2908,55 @@ export default {
const lineNo = row?.lineNo; const lineNo = row?.lineNo;
return lineNo === -1 || String(lineNo) === '-1' ? '' : this.displayValue(lineNo); return lineNo === -1 || String(lineNo) === '-1' ? '' : this.displayValue(lineNo);
}, },
parseChangeRecordData(value) {
if (!value) return {};
if (typeof value === 'object') return value;
try {
const parsed = JSON.parse(value);
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
} catch (error) {
return {};
}
},
formatChangeRecordValue(value) {
if (value === undefined || value === null || value === '') return '空';
if (Array.isArray(value)) {
if (!value.length) return '空';
return value
.map(item => {
if (!item || typeof item !== 'object') return String(item);
return Object.entries(item)
.map(([key, itemValue]) => `${key}:${this.formatChangeRecordValue(itemValue)}`)
.join(',');
})
.join('\n');
}
if (typeof value === 'object') return JSON.stringify(value);
return String(value);
},
buildChangeRecordDetailRows(row = {}) {
const before = this.parseChangeRecordData(row.beforeData);
const after = this.parseChangeRecordData(row.afterData);
const fields = [...new Set([...Object.keys(before), ...Object.keys(after)])];
const rows = fields
.filter(field => JSON.stringify(before[field]) !== JSON.stringify(after[field]))
.map(field => ({
field,
before: this.formatChangeRecordValue(before[field]),
after: this.formatChangeRecordValue(after[field]),
}));
if (row.changeContent) {
rows.unshift({ field: '变更内容', before: '空', after: row.changeContent });
}
if (row.changeReason) {
rows.push({ field: '变更原因', before: '空', after: row.changeReason });
}
return rows;
},
openChangeRecordDetail(row) {
this.changeRecordDetailRows = this.buildChangeRecordDetailRows(row);
this.changeRecordDetailVisible = true;
},
paymentMethodName(value) { paymentMethodName(value) {
const labels = { const labels = {
bank_transfer: '银行转账', bank_transfer: '银行转账',
@@ -2915,9 +2986,36 @@ export default {
formatDetailMileage(value) { formatDetailMileage(value) {
return this.readonly && Number(value) === -1 ? '-' : this.displayValue(value); return this.readonly && Number(value) === -1 ? '-' : this.displayValue(value);
}, },
async loadBusinessModelOptions() {
const { data } = await getDictionary({ code: 'business_model' });
const records = Array.isArray(data?.data) ? data.data : data?.data?.records || [];
this.businessModelOptions = records.map(item => ({
dictKey: item.dictKey ?? item.value,
dictValue: item.dictValue ?? item.label ?? item.name,
}));
},
async loadTransportTypeOptions() { async loadTransportTypeOptions() {
const { data } = await getDictionary({ code: 'transport_type' }); const { data } = await getDictionary({ code: 'transport_type' });
this.transportTypeOptions = data?.data || []; const records = Array.isArray(data?.data) ? data.data : data?.data?.records || [];
this.transportTypeOptions = records.map(item => ({
dictKey: item.dictKey ?? item.value,
dictValue: item.dictValue ?? item.label ?? item.name,
}));
},
formSelectOptions(field) {
const key = field?.optionsKey;
const options = key ? this[key] : [];
return Array.isArray(options) ? options : [];
},
formSelectLabel(field, value) {
if (value === undefined || value === null || value === '') return '-';
const normalized = String(value).trim();
const option = this.formSelectOptions(field).find(
item =>
String(item.dictKey ?? '').trim() === normalized ||
String(item.dictValue ?? '').trim() === normalized
);
return option?.dictValue || normalized;
}, },
transportTypeName(value) { transportTypeName(value) {
if (value === undefined || value === null || value === '') return ''; if (value === undefined || value === null || value === '') return '';
@@ -3253,21 +3351,9 @@ export default {
} }
.formal-editor__invoice-claim { .formal-editor__invoice-claim {
display: flex; display: flex;
flex-direction: column; justify-content: flex-end;
align-items: flex-end;
gap: 8px;
margin-bottom: 12px; margin-bottom: 12px;
} }
.formal-editor__invoice-claim-hint {
color: var(--el-color-danger);
font-size: 13px;
}
.formal-editor__invoice-claim :deep(.el-form-item) {
margin-bottom: 0;
}
.formal-editor__invoice-claim :deep(.el-input) {
width: 360px;
}
.formal-editor__issued-invoices { .formal-editor__issued-invoices {
margin-top: 16px; margin-top: 16px;
} }
@@ -20,7 +20,7 @@
<el-form-item :label="field.label" :prop="field.prop"> <el-form-item :label="field.label" :prop="field.prop">
<el-input <el-input
v-if="field.type === 'contract'" v-if="field.type === 'contract'"
:model-value="formatContractOptionLabel(form)" :model-value="form.contractName"
readonly readonly
:disabled="!editable || details.length > 0" :disabled="!editable || details.length > 0"
placeholder="请选择合同" placeholder="请选择合同"
@@ -53,6 +53,23 @@
:disabled="!editable" :disabled="!editable"
@change="recalculateLocalAmount" @change="recalculateLocalAmount"
/> />
<el-select
v-else-if="field.type === 'select' && editable"
v-model="form[field.prop]"
filterable
clearable
placeholder="请选择"
>
<el-option
v-for="item in formSelectOptions(field)"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey"
/>
</el-select>
<span v-else-if="field.type === 'select'" class="form-readonly">
{{ formSelectLabel(field, form[field.prop]) }}
</span>
<el-input <el-input
v-else-if="field.type === 'textarea'" v-else-if="field.type === 'textarea'"
v-model="form[field.prop]" v-model="form[field.prop]"
@@ -493,7 +510,7 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" width="100" align="center" fixed="right"> <el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="{ row }"> <template #default="{ row }">
<el-link type="primary" @click="openAdjustChangeRecord(row)">查看</el-link> <el-link type="primary" @click="openAdjustChangeRecord(row)">详情</el-link>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -999,8 +1016,8 @@ import {
settlementDetailColumns, settlementDetailColumns,
settlementSummaryColumns, settlementSummaryColumns,
} from '@/option/settlement/preSettlementTable'; } from '@/option/settlement/preSettlementTable';
import { formatContractOptionLabel } from '@/utils/contract';
import { isTierUnitPrice, isUnitPriceAdjustable } from '@/utils/settlement-adjust-rule'; import { isTierUnitPrice, isUnitPriceAdjustable } from '@/utils/settlement-adjust-rule';
import { isApprovalSettlementChange } from '@/utils/settlement-change-record';
import { normalizeCurrencyCode } from '@/utils/currency'; import { normalizeCurrencyCode } from '@/utils/currency';
import { settlementStatusName } from '@/utils/settlementStatus'; import { settlementStatusName } from '@/utils/settlementStatus';
import { downloadFileByUrl } from '@/utils/util'; import { downloadFileByUrl } from '@/utils/util';
@@ -1095,6 +1112,7 @@ export default {
}, },
feeOptions: [], feeOptions: [],
feeCategoryOptions: [], feeCategoryOptions: [],
businessModelOptions: [],
transportTypeOptions: [], transportTypeOptions: [],
summaryFees: [], summaryFees: [],
details: [], details: [],
@@ -1144,6 +1162,8 @@ export default {
readonly: false, readonly: false,
detailId: '', detailId: '',
sourceDetailId: '', sourceDetailId: '',
// 未保存明细(id 仍等于来源应收应付明细)时先暂存,保存预结算单后再生效
draftMode: false,
detailLineNo: '', detailLineNo: '',
reason: '', reason: '',
}, },
@@ -1330,7 +1350,6 @@ export default {
methods: { methods: {
isTierUnitPrice, isTierUnitPrice,
isUnitPriceAdjustable, isUnitPriceAdjustable,
formatContractOptionLabel,
hasPermission(code) { hasPermission(code) {
return this.isAdmin || this.validData(this.permission?.[code], false); return this.isAdmin || this.validData(this.permission?.[code], false);
}, },
@@ -1344,6 +1363,7 @@ export default {
if (!this.publicMode) { if (!this.publicMode) {
await this.loadFeeOptions(); await this.loadFeeOptions();
await this.loadFeeCategoryOptions(); await this.loadFeeCategoryOptions();
await this.loadBusinessModelOptions();
await this.loadTransportTypeOptions(); await this.loadTransportTypeOptions();
await this.loadAttachmentTypeOptions(); await this.loadAttachmentTypeOptions();
} }
@@ -1485,6 +1505,7 @@ export default {
this.detailFeeCache = {}; this.detailFeeCache = {};
this.adjustDialog.detailId = ''; this.adjustDialog.detailId = '';
this.adjustDialog.sourceDetailId = ''; this.adjustDialog.sourceDetailId = '';
this.adjustDialog.draftMode = false;
this.adjustDialog.detailLineNo = ''; this.adjustDialog.detailLineNo = '';
this.adjustChangeRecordVisible = false; this.adjustChangeRecordVisible = false;
this.adjustChangeRecord = null; this.adjustChangeRecord = null;
@@ -1523,7 +1544,7 @@ export default {
createTime: row.paymentCreateTime || row.createTime, createTime: row.paymentCreateTime || row.createTime,
})); }));
this.changeRecords = (detail.changeRecords || []).filter( this.changeRecords = (detail.changeRecords || []).filter(
row => row.changeContent !== '预结算审批通过' row => !isApprovalSettlementChange(row.changeContent)
); );
this.attachments = this.parseAttachments(detail.attachmentsJson); this.attachments = this.parseAttachments(detail.attachmentsJson);
this.sortAttachments(); this.sortAttachments();
@@ -1647,6 +1668,14 @@ export default {
const { data } = await getDictionary({ code: 'fee_category' }); const { data } = await getDictionary({ code: 'fee_category' });
this.feeCategoryOptions = data?.data || []; this.feeCategoryOptions = data?.data || [];
}, },
async loadBusinessModelOptions() {
const { data } = await getDictionary({ code: 'business_model' });
const records = Array.isArray(data?.data) ? data.data : data?.data?.records || [];
this.businessModelOptions = records.map(item => ({
dictKey: item.dictKey ?? item.value,
dictValue: item.dictValue ?? item.label ?? item.name,
}));
},
async loadTransportTypeOptions() { async loadTransportTypeOptions() {
const { data } = await getDictionary({ code: 'transport_type' }); const { data } = await getDictionary({ code: 'transport_type' });
const records = Array.isArray(data?.data) ? data.data : data?.data?.records || []; const records = Array.isArray(data?.data) ? data.data : data?.data?.records || [];
@@ -1655,6 +1684,21 @@ export default {
dictValue: item.dictValue ?? item.label ?? item.name, dictValue: item.dictValue ?? item.label ?? item.name,
})); }));
}, },
formSelectOptions(field) {
const key = field?.optionsKey;
const options = key ? this[key] : [];
return Array.isArray(options) ? options : [];
},
formSelectLabel(field, value) {
if (value === undefined || value === null || value === '') return '-';
const normalized = String(value).trim();
const option = this.formSelectOptions(field).find(
item =>
String(item.dictKey ?? '').trim() === normalized ||
String(item.dictValue ?? '').trim() === normalized
);
return option?.dictValue || normalized;
},
handleContractChange(id) { handleContractChange(id) {
const contract = this.contractOptions.find(item => String(item.id) === String(id)); const contract = this.contractOptions.find(item => String(item.id) === String(id));
if (!contract) { if (!contract) {
@@ -1741,6 +1785,8 @@ export default {
return { return {
id: this.form.id || undefined, id: this.form.id || undefined,
contractId: this.form.contractId, contractId: this.form.contractId,
businessModel: this.form.businessModel || undefined,
transportType: this.form.transportType || undefined,
exchangeRateDate: this.form.exchangeRateDate || undefined, exchangeRateDate: this.form.exchangeRateDate || undefined,
exchangeRate: this.form.exchangeRate, exchangeRate: this.form.exchangeRate,
attachmentsJson: JSON.stringify(this.attachments || []), attachmentsJson: JSON.stringify(this.attachments || []),
@@ -2251,17 +2297,21 @@ export default {
}, },
async openAdjustDialog(row, readonly) { async openAdjustDialog(row, readonly) {
const detailRow = row; const detailRow = row;
const sourceDetailId = detailRow.sourceDetailId || '';
// 未保存明细 id 仍等于来源应收应付明细 id,调整结果先暂存
const draftMode =
!this.form.id ||
!detailRow.id ||
String(detailRow.id) === String(detailRow.sourceDetailId);
this.adjustDialog.visible = true; this.adjustDialog.visible = true;
this.adjustDialog.loading = true; this.adjustDialog.loading = true;
this.adjustDialog.readonly = readonly; this.adjustDialog.readonly = readonly;
this.adjustDialog.draftMode = draftMode;
this.adjustDialog.detailId = detailRow.id; this.adjustDialog.detailId = detailRow.id;
this.adjustDialog.detailLineNo = detailRow.lineNo; this.adjustDialog.detailLineNo = detailRow.lineNo;
this.adjustDialog.sourceDetailId = this.adjustDialog.sourceDetailId = sourceDetailId;
detailRow.id && String(detailRow.id) === String(detailRow.sourceDetailId) const pendingKey = String(sourceDetailId || '');
? detailRow.sourceDetailId const pending = pendingKey ? this.pendingAdjustments[pendingKey] : null;
: '';
const sourceDetailId = String(this.adjustDialog.sourceDetailId || '');
const pending = sourceDetailId ? this.pendingAdjustments[sourceDetailId] : null;
// 底部备注回显结算明细备注;暂存过的调整优先取暂存备注 // 底部备注回显结算明细备注;暂存过的调整优先取暂存备注
this.adjustDialog.reason = this.adjustDialog.reason =
pending?.reason !== undefined && pending?.reason !== null pending?.reason !== undefined && pending?.reason !== null
@@ -2278,11 +2328,12 @@ export default {
this.adjustRows = cachedFees.map(item => this.normalizeAdjustRow(item)); this.adjustRows = cachedFees.map(item => this.normalizeAdjustRow(item));
return; return;
} }
if (sourceDetailId) { if (draftMode && sourceDetailId) {
if (!this.sourceFeeSnapshots[sourceDetailId]) { if (!this.sourceFeeSnapshots[String(sourceDetailId)]) {
this.sourceFeeSnapshots[sourceDetailId] = await this.loadSourceFeeRows(sourceDetailId); this.sourceFeeSnapshots[String(sourceDetailId)] =
await this.loadSourceFeeRows(sourceDetailId);
} }
this.adjustRows = this.cloneAdjustRows(this.sourceFeeSnapshots[sourceDetailId]); this.adjustRows = this.cloneAdjustRows(this.sourceFeeSnapshots[String(sourceDetailId)]);
return; return;
} }
const cachedFees = this.detailFeeCache[detailRow.id]; const cachedFees = this.detailFeeCache[detailRow.id];
@@ -2554,7 +2605,7 @@ export default {
if ( if (
['transportQuantity', 'mileage', 'unitPrice'].includes(changedField) && ['transportQuantity', 'mileage', 'unitPrice'].includes(changedField) &&
this.adjustDialog.sourceDetailId && this.adjustDialog.sourceDetailId &&
row.id && (row.sourceFeeId || row.id) &&
(changedField !== 'unitPrice' || isUnitPriceAdjustable(row)) (changedField !== 'unitPrice' || isUnitPriceAdjustable(row))
) { ) {
this.scheduleSourceAdjustCalculation(row, changedField); this.scheduleSourceAdjustCalculation(row, changedField);
@@ -2570,7 +2621,8 @@ export default {
try { try {
const response = await calculateAdjustedFee({ const response = await calculateAdjustedFee({
detailId: this.adjustDialog.sourceDetailId, detailId: this.adjustDialog.sourceDetailId,
feeId: row.id, // 已保存预结算费用行需用源应收应付费用ID试算
feeId: row.sourceFeeId || row.id,
transportQuantity: Number(row.transportQuantity || 0), transportQuantity: Number(row.transportQuantity || 0),
mileage: Number(row.mileage || 0), mileage: Number(row.mileage || 0),
unitPrice: row.unitPrice === null || row.unitPrice === '' ? null : Number(row.unitPrice), unitPrice: row.unitPrice === null || row.unitPrice === '' ? null : Number(row.unitPrice),
@@ -2596,6 +2648,7 @@ export default {
row.settlementAmountTax = Number(data.afterAmount || 0); row.settlementAmountTax = Number(data.afterAmount || 0);
} catch (error) { } catch (error) {
row.calculateError = error.message || '费用试算失败'; row.calculateError = error.message || '费用试算失败';
this.$message.warning(row.calculateError);
} finally { } finally {
if (version === row.adjustCalculateVersion) row.calculating = false; if (version === row.adjustCalculateVersion) row.calculating = false;
} }
@@ -2611,7 +2664,7 @@ export default {
} }
this.adjustDialog.saving = true; this.adjustDialog.saving = true;
try { try {
if (this.adjustDialog.sourceDetailId) { if (this.adjustDialog.draftMode && this.adjustDialog.sourceDetailId) {
this.pendingAdjustments[this.adjustDialog.sourceDetailId] = { this.pendingAdjustments[this.adjustDialog.sourceDetailId] = {
reason: this.adjustDialog.reason, reason: this.adjustDialog.reason,
rows: this.adjustRows.map(row => ({ ...row, feeItems: { ...row.feeItems } })), rows: this.adjustRows.map(row => ({ ...row, feeItems: { ...row.feeItems } })),
@@ -263,7 +263,7 @@
<template v-else-if="isExternalRowEditing(row) && isExternalEditableColumn(column.prop)"> <template v-else-if="isExternalRowEditing(row) && isExternalEditableColumn(column.prop)">
<el-input-number <el-input-number
v-if="column.feeItemName" v-if="column.feeItemName"
v-model="row.feeItems[column.feeItemName]" v-model="externalEditTarget(row).feeItems[column.feeItemName]"
:min="0" :min="0"
:precision="2" :precision="2"
:controls="false" :controls="false"
@@ -271,7 +271,7 @@
/> />
<el-date-picker <el-date-picker
v-else-if="isExternalDateColumn(column.prop)" v-else-if="isExternalDateColumn(column.prop)"
v-model="row[column.prop]" v-model="externalEditTarget(row)[column.prop]"
type="date" type="date"
value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
format="YYYY-MM-DD" format="YYYY-MM-DD"
@@ -280,7 +280,7 @@
/> />
<el-input-number <el-input-number
v-else-if="isExternalNumberColumn(column.prop)" v-else-if="isExternalNumberColumn(column.prop)"
v-model="row[column.prop]" v-model="externalEditTarget(row)[column.prop]"
:min="0" :min="0"
:precision="2" :precision="2"
:controls="false" :controls="false"
@@ -288,7 +288,7 @@
/> />
<el-select <el-select
v-else-if="column.prop === 'transportType'" v-else-if="column.prop === 'transportType'"
v-model="row[column.prop]" v-model="externalEditTarget(row)[column.prop]"
size="small" size="small"
clearable clearable
placeholder="请选择" placeholder="请选择"
@@ -300,7 +300,7 @@
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
<el-input v-else v-model="row[column.prop]" size="small" /> <el-input v-else v-model="externalEditTarget(row)[column.prop]" size="small" />
</template> </template>
<span v-else-if="column.prop === 'transportType'"> <span v-else-if="column.prop === 'transportType'">
{{ transportTypeLabel(row.transportType) }} {{ transportTypeLabel(row.transportType) }}
@@ -630,6 +630,7 @@ import { getDictionary } from '@/api/system/dictbiz';
import { Search } from '@element-plus/icons-vue'; import { Search } from '@element-plus/icons-vue';
import { h } from 'vue'; import { h } from 'vue';
import { downloadXls } from '@/utils/util'; import { downloadXls } from '@/utils/util';
import { isExcelResponse, parseBlobJson } from '@/utils/import-excel';
import { transportReconciliationFormFields } from '@/option/settlement/transportReconciliationForm'; import { transportReconciliationFormFields } from '@/option/settlement/transportReconciliationForm';
import { import {
internalColumns, internalColumns,
@@ -676,6 +677,8 @@ export default {
completionDialog: { visible: false, loading: false }, completionDialog: { visible: false, loading: false },
completionSummaryRowsData: null, completionSummaryRowsData: null,
externalEditing: {}, externalEditing: {},
// 调整中的草稿,输入只改草稿,点「完成」才写回列表
externalEditDrafts: {},
externalEditSnapshots: {}, externalEditSnapshots: {},
matchingStarted: false, matchingStarted: false,
rules: { rules: {
@@ -932,6 +935,7 @@ export default {
this.internalDetails = []; this.internalDetails = [];
this.externalDetails = []; this.externalDetails = [];
this.externalEditing = {}; this.externalEditing = {};
this.externalEditDrafts = {};
this.externalEditSnapshots = {}; this.externalEditSnapshots = {};
this.completionSummaryRowsData = null; this.completionSummaryRowsData = null;
this.matchingStarted = false; this.matchingStarted = false;
@@ -1503,16 +1507,16 @@ export default {
this.form.reconciliationMode === 'cargo' this.form.reconciliationMode === 'cargo'
? await api.importCargo(this.currentId, file) ? await api.importCargo(this.currentId, file)
: await api.importVehicle(this.currentId, file); : await api.importVehicle(this.currentId, file);
const contentType = response.headers?.['content-type'] || response.data?.type || ''; // 成功时 axios 拦截器可能已把 JSON Blob 解析成对象,不能再调 .text()
if (contentType.includes('spreadsheetml') || contentType.includes('ms-excel')) { if (isExcelResponse(response)) {
downloadXls( downloadXls(
response.data, response.data,
`运输对账导入失败明细${this.$dayjs().format('YYYY-MM-DD HH-mm-ss')}.xlsx` `运输对账导入失败明细${this.$dayjs().format('YYYY-MM-DD HH-mm-ss')}.xlsx`
); );
this.$message.warning('部分数据导入失败,已下载失败明细'); this.$message.warning('部分数据导入失败,已下载失败明细');
} else { } else {
const result = JSON.parse(await response.data.text()); const result = await parseBlobJson(response.data);
if (result.code !== 200) throw new Error(result.msg || '导入失败'); if (Number(result.code) !== 200) throw new Error(result.msg || '导入失败');
this.$message.success('外部账单导入成功'); this.$message.success('外部账单导入成功');
} }
this.matchingStarted = false; this.matchingStarted = false;
@@ -1661,6 +1665,28 @@ export default {
isExternalRowEditing(row) { isExternalRowEditing(row) {
return Boolean(this.externalEditing[this.externalRowKey(row)]); return Boolean(this.externalEditing[this.externalRowKey(row)]);
}, },
cloneExternalEditRow(row) {
return {
...row,
feeItems: { ...(row.feeItems || this.parseFeeItems(row.feeItemsJson)) },
};
},
/** 编辑态绑定草稿,避免输入时实时改写列表导致疑似重复 Tab 刷新 */
externalEditTarget(row) {
const key = this.externalRowKey(row);
return this.externalEditDrafts[key] || row;
},
clearExternalEditState(key) {
const editing = { ...this.externalEditing };
const drafts = { ...this.externalEditDrafts };
const snapshots = { ...this.externalEditSnapshots };
delete editing[key];
delete drafts[key];
delete snapshots[key];
this.externalEditing = editing;
this.externalEditDrafts = drafts;
this.externalEditSnapshots = snapshots;
},
isExternalEditableColumn(prop) { isExternalEditableColumn(prop) {
return !['externalLineNo', 'matchStatus'].includes(prop); return !['externalLineNo', 'matchStatus'].includes(prop);
}, },
@@ -1672,34 +1698,30 @@ export default {
}, },
openExternalAdjust(row) { openExternalAdjust(row) {
const key = this.externalRowKey(row); const key = this.externalRowKey(row);
const draft = this.cloneExternalEditRow(row);
this.externalEditSnapshots = { this.externalEditSnapshots = {
...this.externalEditSnapshots, ...this.externalEditSnapshots,
[key]: { ...row }, [key]: this.cloneExternalEditRow(row),
}; };
this.externalEditDrafts = { ...this.externalEditDrafts, [key]: draft };
this.externalEditing = { ...this.externalEditing, [key]: true }; this.externalEditing = { ...this.externalEditing, [key]: true };
}, },
cancelExternalAdjust(row) { cancelExternalAdjust(row) {
const key = this.externalRowKey(row); this.clearExternalEditState(this.externalRowKey(row));
const snapshot = this.externalEditSnapshots[key];
if (snapshot) Object.assign(row, snapshot);
const editing = { ...this.externalEditing };
const snapshots = { ...this.externalEditSnapshots };
delete editing[key];
delete snapshots[key];
this.externalEditing = editing;
this.externalEditSnapshots = snapshots;
}, },
async finishExternalAdjust(row) { async finishExternalAdjust(row) {
row.feeItemsJson = JSON.stringify(row.feeItems || {});
const key = this.externalRowKey(row); const key = this.externalRowKey(row);
const editing = { ...this.externalEditing }; const draft = this.externalEditDrafts[key];
const snapshots = { ...this.externalEditSnapshots }; if (draft) {
delete editing[key]; const feeItems = { ...(draft.feeItems || {}) };
delete snapshots[key]; Object.assign(row, draft, { feeItems });
this.externalEditing = editing; row.feeItemsJson = JSON.stringify(feeItems);
this.externalEditSnapshots = snapshots; } else {
row.feeItemsJson = JSON.stringify(row.feeItems || {});
}
this.clearExternalEditState(key);
this.refreshLocalStats(); this.refreshLocalStats();
this.$message.success('调整已暂存'); this.$message.success('调整已暂存,匹配或完成对账后生效');
}, },
normalizeExternalDateTime(value) { normalizeExternalDateTime(value) {
if (!value) return null; if (!value) return null;
@@ -1743,7 +1765,8 @@ export default {
differenceQuantity: Math.abs(internalQuantity - externalQuantity), differenceQuantity: Math.abs(internalQuantity - externalQuantity),
differenceAmount: Math.abs(internalAmount - externalAmount), differenceAmount: Math.abs(internalAmount - externalAmount),
matchedCount, matchedCount,
unmatchedCount: internalUnmatched + externalUnmatched, // 无法匹配按内部账单条数统计,不叠加外部未匹配数
unmatchedCount: internalUnmatched,
matchStatus: matchStatus:
this.internalDetails.length > 0 && this.internalDetails.length > 0 &&
this.internalDetails.length === this.externalDetails.length && this.internalDetails.length === this.externalDetails.length &&
+22 -2
View File
@@ -429,7 +429,13 @@ export default {
rules: [ rules: [
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
if (value === undefined || value === null || value === '') { // -1 为空占位,不填时按空处理
if (
value === undefined ||
value === null ||
value === '' ||
Number(value) === -1
) {
callback(); callback();
return; return;
} }
@@ -1188,7 +1194,13 @@ export default {
} }
}, },
normalizeContractInitialSerial(value) { normalizeContractInitialSerial(value) {
if (value === undefined || value === null || value === '') { // -1 为空占位,不填时不落库、不回显
if (
value === undefined ||
value === null ||
value === '' ||
Number(value) === -1
) {
return null; return null;
} }
const text = String(value).trim(); const text = String(value).trim();
@@ -1198,6 +1210,12 @@ export default {
const serial = Number(text); const serial = Number(text);
return Number.isInteger(serial) ? serial : value; return Number.isInteger(serial) ? serial : value;
}, },
clearEmptyContractInitialSerial(form = this.form) {
if (!form) return;
if (Number(form.contractInitialSerial) === -1) {
form.contractInitialSerial = '';
}
},
isRootDept(row) { isRootDept(row) {
return row && (row.parentId === 0 || String(row.parentId) === '0'); return row && (row.parentId === 0 || String(row.parentId) === '0');
}, },
@@ -1502,6 +1520,7 @@ export default {
if (this.form.isPlatformCompany === undefined || this.form.isPlatformCompany === null) { if (this.form.isPlatformCompany === undefined || this.form.isPlatformCompany === null) {
this.form.isPlatformCompany = 0; this.form.isPlatformCompany = 0;
} }
this.clearEmptyContractInitialSerial(this.form);
this.initData(this.form.tenantId); this.initData(this.form.tenantId);
this.loadParentDeptCode(this.form.parentId); this.loadParentDeptCode(this.form.parentId);
} }
@@ -1516,6 +1535,7 @@ export default {
if (this.form.parentId === '0') { if (this.form.parentId === '0') {
this.form.parentId = ''; this.form.parentId = '';
} }
this.clearEmptyContractInitialSerial(this.form);
this.loadParentDeptCode(this.form.parentId); this.loadParentDeptCode(this.form.parentId);
if (this.form.hasOwnProperty('leaderId')) { if (this.form.hasOwnProperty('leaderId')) {
const splitResult = func.split(this.form.leaderId); const splitResult = func.split(this.form.leaderId);