@@ -1,12 +1,20 @@
|
||||
<template>
|
||||
<basic-container class="contract-change-page">
|
||||
<div class="archive-page-form__title">{{ pageTitle }}</div>
|
||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="right" label-width="auto" class="contract-change-form">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
:disabled="pageReadonly"
|
||||
label-position="right"
|
||||
label-width="auto"
|
||||
class="contract-change-form"
|
||||
>
|
||||
<section class="change-section contract-basic-section">
|
||||
<div class="dialog-section-title">基本信息</div>
|
||||
<div class="contract-basic-section__grid">
|
||||
<el-form-item label="变更类型" class="contract-basic-section__change-type">
|
||||
<el-radio-group v-model="form.changeType">
|
||||
<el-radio-group v-model="form.changeType" :disabled="pageReadonly">
|
||||
<el-radio label="合同信息变更" />
|
||||
<el-radio label="结算规则变更" />
|
||||
<el-radio label="终止合同" />
|
||||
@@ -280,7 +288,7 @@
|
||||
<div class="section-head">
|
||||
<div class="dialog-section-title">计费信息</div>
|
||||
<el-button
|
||||
v-if="feeGenerationMode !== 'manual'"
|
||||
v-if="!pageReadonly && feeGenerationMode !== 'manual'"
|
||||
type="primary"
|
||||
plain
|
||||
@click="addPlan"
|
||||
@@ -301,6 +309,7 @@
|
||||
row.defaultPlan ? '是' : '否'
|
||||
}}</template></el-table-column
|
||||
><el-table-column prop="remark" label="备注" min-width="260" /><el-table-column
|
||||
v-if="!pageReadonly"
|
||||
label="操作"
|
||||
width="180"
|
||||
><template #default="{ row, $index }"
|
||||
@@ -416,7 +425,7 @@
|
||||
:value="item.value"
|
||||
/></el-select></template
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="100"
|
||||
<el-table-column v-if="!pageReadonly" label="操作" width="100"
|
||||
><template #default="{ $index }"
|
||||
><el-link v-if="$index === 0" type="primary" @click="addCustomPeriodRow">添加</el-link
|
||||
><el-link v-else type="danger" @click="removeCustomPeriodRow($index)"
|
||||
@@ -425,7 +434,7 @@
|
||||
></el-table-column
|
||||
>
|
||||
<template #empty
|
||||
><el-link type="primary" @click="addCustomPeriodRow">添加</el-link></template
|
||||
><el-link v-if="!pageReadonly" type="primary" @click="addCustomPeriodRow">添加</el-link></template
|
||||
>
|
||||
</el-table>
|
||||
</section>
|
||||
@@ -461,7 +470,7 @@
|
||||
:disabled="isSettlementRuleChange"
|
||||
/></template
|
||||
></el-table-column>
|
||||
<el-table-column v-if="!isSettlementRuleChange" label="操作" width="100"
|
||||
<el-table-column v-if="!pageReadonly && !isSettlementRuleChange" label="操作" width="100"
|
||||
><template #default="{ $index }"
|
||||
><el-link type="danger" @click="paymentRatioRows.splice($index, 1)"
|
||||
>删除</el-link
|
||||
@@ -470,7 +479,7 @@
|
||||
>
|
||||
</el-table>
|
||||
<el-button
|
||||
v-if="!isSettlementRuleChange"
|
||||
v-if="!pageReadonly && !isSettlementRuleChange"
|
||||
type="primary"
|
||||
plain
|
||||
@click="addPaymentRatioRow"
|
||||
@@ -525,8 +534,9 @@
|
||||
@update:rows="changeMaterials = $event"
|
||||
@upload-to-location="handleAttachmentUploadToLocation"
|
||||
/>
|
||||
<div class="page-footer">
|
||||
<el-button @click="$router.back()">取消</el-button>
|
||||
<div v-if="!pageReadonly" class="page-footer">
|
||||
<el-button @click="goBack">取消</el-button>
|
||||
<el-button v-if="isContractChangeModule" @click="saveDraft">保存草稿</el-button>
|
||||
<el-button type="primary" @click="submit">提交</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
@@ -539,7 +549,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as api from '@/api/business/contract-manage';
|
||||
import * as contractApi from '@/api/business/contract-manage';
|
||||
import * as changeApi from '@/api/business/contract-change';
|
||||
import { getMkPublicDetail } from '@/api/mk-process';
|
||||
import { loadMkEnabled, submitMkApprovalFlow } from '@/utils/mk-approval';
|
||||
import BillingPlanEditor from './components/billing-plan-editor.vue';
|
||||
import ContractAttachmentSection, {
|
||||
@@ -577,6 +589,8 @@ const defaultContractFormatOptions = [
|
||||
{ label: '电子合同', value: '电子合同' },
|
||||
{ label: '纸质合同', value: '纸质合同' },
|
||||
];
|
||||
const contractChangeListRoute = '/business/contract-change';
|
||||
const contractChangeListRefreshKey = 'contract-change-list-refresh';
|
||||
const normalizeOptionalPositiveInteger = value => {
|
||||
if (value === undefined || value === null || value === '') return null;
|
||||
const number = Number(value);
|
||||
@@ -713,8 +727,21 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
pageTitle() {
|
||||
if (this.pageReadonly) return this.$route.query.name || '查看合同变更';
|
||||
return this.$route.query.name || '合同变更';
|
||||
},
|
||||
isContractChangeModule() {
|
||||
return (
|
||||
this.$route.path === '/business/contract-change/form' ||
|
||||
this.$route.path === '/business/contract-change/public-view'
|
||||
);
|
||||
},
|
||||
isPublicViewPage() {
|
||||
return this.$route.path === '/business/contract-change/public-view';
|
||||
},
|
||||
pageReadonly() {
|
||||
return this.isPublicViewPage || this.$route.query.mode === 'view';
|
||||
},
|
||||
// 高风险/黑名单客商提示:按合同推送合规留痕 hcs_risk_level/hcs_black_status 判定(与合同详情口径一致)
|
||||
riskTipText() {
|
||||
const riskLevel = String(this.form.hcsRiskLevel || '').trim();
|
||||
@@ -833,13 +860,25 @@ export default {
|
||||
async load() {
|
||||
const id = this.$route.query.id;
|
||||
if (!id) return;
|
||||
const res = await api.getDetail(id);
|
||||
const data = res.data?.data || res.data || {};
|
||||
let data = {};
|
||||
if (this.isPublicViewPage) {
|
||||
const res = await getMkPublicDetail('contract-change', id);
|
||||
data = res.data?.data || res.data || {};
|
||||
} else if (this.isContractChangeModule) {
|
||||
const res = await changeApi.getDetail(id);
|
||||
data = res.data?.data || res.data || {};
|
||||
} else {
|
||||
const res = await contractApi.getDetail(id);
|
||||
data = res.data?.data || res.data || {};
|
||||
}
|
||||
const isChangeRecord = this.isContractChangeModule || this.isPublicViewPage;
|
||||
this.form = {
|
||||
...data,
|
||||
changeContent: '',
|
||||
changeReason: '',
|
||||
changeAttachmentsJson: '',
|
||||
// 独立变更单保留 contractId;旧路由以合同 id 作为主键
|
||||
contractId: data.contractId || (isChangeRecord ? data.contractId : data.id),
|
||||
changeContent: isChangeRecord ? data.changeContent || '' : '',
|
||||
changeReason: isChangeRecord ? data.changeReason || '' : '',
|
||||
changeAttachmentsJson: data.changeAttachmentsJson || '',
|
||||
copyCount: normalizeOptionalPositiveInteger(data.copyCount),
|
||||
invoiceCycle: normalizeOptionalPositiveInteger(data.invoiceCycle),
|
||||
paymentDays: normalizeOptionalPositiveInteger(data.paymentDays),
|
||||
@@ -847,14 +886,14 @@ export default {
|
||||
templateFlag: data.templateFlag ?? 0,
|
||||
electronicSealFlag: data.electronicSealFlag ?? 0,
|
||||
archiveStatus: data.archiveStatus || '未归档',
|
||||
changeType: '合同信息变更',
|
||||
changeType: data.changeType || '合同信息变更',
|
||||
};
|
||||
this.changeMaterials = [];
|
||||
this.changeMaterials = this.parse(data.changeAttachmentsJson);
|
||||
this.period = data.startDate && data.endDate ? [data.startDate, data.endDate] : [];
|
||||
this.plans = this.parse(data.billingPlanJson);
|
||||
this.attachments = this.mergeChangeAttachments(
|
||||
this.parse(data.attachmentsJson),
|
||||
this.parse(data.changeAttachmentsJson)
|
||||
isChangeRecord ? [] : this.parse(data.changeAttachmentsJson)
|
||||
);
|
||||
this.contractFileRows = normalizeContractFileRows(this.parse(data.contractFileJson));
|
||||
const rules = this.parseObject(data.settlementRuleJson);
|
||||
@@ -896,6 +935,70 @@ export default {
|
||||
data.feeGenerationMode || (Number(data.billingEnabled) === 0 ? 'manual' : 'system');
|
||||
this.paymentRatioRows = this.parse(data.paymentRatioJson);
|
||||
},
|
||||
goBack() {
|
||||
if (this.isContractChangeModule) {
|
||||
this.$router.push(contractChangeListRoute);
|
||||
return;
|
||||
}
|
||||
this.$router.back();
|
||||
},
|
||||
buildChangePayload() {
|
||||
if (this.settlementConfigTab === 'pre') this.preSettlementConfig = { ...this.settlementRule };
|
||||
else this.formalSettlementConfig = { ...this.settlementRule };
|
||||
const settlementRule = {
|
||||
preSettlementConfig: this.preSettlementConfig,
|
||||
formalSettlementConfig: this.formalSettlementConfig,
|
||||
};
|
||||
if (this.isSettlementRuleChange) {
|
||||
return {
|
||||
id: this.form.id,
|
||||
contractId: this.form.contractId,
|
||||
changeType: this.form.changeType,
|
||||
changeContent: this.form.changeContent,
|
||||
changeReason: this.form.changeReason,
|
||||
feeGenerationMode: this.feeGenerationMode,
|
||||
billingEnabled: this.feeGenerationMode === 'system' ? 1 : 0,
|
||||
billingPlanJson: JSON.stringify(this.plans),
|
||||
settlementRuleJson: JSON.stringify(settlementRule),
|
||||
preSettlementConfigJson: JSON.stringify(this.preSettlementConfig),
|
||||
formalSettlementConfigJson: JSON.stringify(this.formalSettlementConfig),
|
||||
changeAttachmentsJson: JSON.stringify(this.changeMaterials),
|
||||
};
|
||||
}
|
||||
return {
|
||||
...this.form,
|
||||
contractId: this.form.contractId,
|
||||
changeType: this.form.changeType || '合同信息变更',
|
||||
settlementCurrency: String(this.form.settlementCurrency || '').trim() || 'RMB',
|
||||
copyCount: normalizeOptionalPositiveInteger(this.form.copyCount),
|
||||
invoiceCycle: normalizeOptionalPositiveInteger(this.form.invoiceCycle),
|
||||
paymentDays: normalizeOptionalPositiveInteger(this.form.paymentDays),
|
||||
contractAmount: normalizeOptionalAmount(this.form.contractAmount),
|
||||
startDate: this.period[0],
|
||||
endDate: this.period[1],
|
||||
feeGenerationMode: this.feeGenerationMode,
|
||||
billingEnabled: this.feeGenerationMode === 'system' ? 1 : 0,
|
||||
billingPlanJson: JSON.stringify(this.plans),
|
||||
settlementRuleJson: JSON.stringify(settlementRule),
|
||||
preSettlementConfigJson: JSON.stringify(this.preSettlementConfig),
|
||||
formalSettlementConfigJson: JSON.stringify(this.formalSettlementConfig),
|
||||
paymentRatioJson: JSON.stringify(this.paymentRatioRows),
|
||||
contractFileJson: JSON.stringify(this.contractFileRows),
|
||||
attachmentsJson: JSON.stringify(this.attachments),
|
||||
changeContent: this.form.changeContent,
|
||||
changeReason: this.form.changeReason,
|
||||
changeAttachmentsJson: JSON.stringify(this.changeMaterials),
|
||||
};
|
||||
},
|
||||
async saveDraft() {
|
||||
if (this.form.changeType === '终止合同') {
|
||||
this.$message.warning('终止合同无需保存草稿,请直接提交');
|
||||
return;
|
||||
}
|
||||
const payload = this.buildChangePayload();
|
||||
await changeApi.saveDraft(payload);
|
||||
this.$message.success('草稿已保存');
|
||||
},
|
||||
parse(value) {
|
||||
try {
|
||||
const result = JSON.parse(value || '[]');
|
||||
@@ -989,9 +1092,10 @@ export default {
|
||||
validateSettlementRule(rule, label) { if (Number(rule.autoGenerate) !== 1) return true; if (!rule.billStartDate || !rule.settlementType) { this.$message.warning(`${label}:请完整填写账单起始日和结算类型`); return false; } if (rule.settlementType === '月结' && !rule.billCycleType) { this.$message.warning(`${label}:请选择结算周期`); return false; } if (rule.settlementType === '月结' && rule.billCycleType === '固定截单日' && !rule.billCutoffDay) { this.$message.warning(`${label}:请选择账单截单日`); return false; } if (rule.settlementType === '月结' && rule.billCycleType === '自定义多周期') return this.validateCustomPeriods(rule.customPeriods, label); if (rule.settlementType === '固定天数周期结算' && !rule.cycleDays) { this.$message.warning(`${label}:请选择周期天数`); return false; } return true; },
|
||||
async submit() {
|
||||
if (this.form.changeType === '终止合同') {
|
||||
await api.terminate(this.form.id, this.form.changeReason);
|
||||
const contractId = this.form.contractId || this.form.id;
|
||||
await contractApi.terminate(contractId, this.form.changeReason);
|
||||
this.$message.success('合同已终止');
|
||||
this.$router.back();
|
||||
this.goBack();
|
||||
return;
|
||||
}
|
||||
await this.$refs.formRef.validate();
|
||||
@@ -1020,48 +1124,22 @@ export default {
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const settlementRule = {
|
||||
preSettlementConfig: this.preSettlementConfig,
|
||||
formalSettlementConfig: this.formalSettlementConfig,
|
||||
};
|
||||
const payload = this.isSettlementRuleChange
|
||||
? {
|
||||
id: this.form.id,
|
||||
changeType: this.form.changeType,
|
||||
changeContent: this.form.changeContent,
|
||||
changeReason: this.form.changeReason,
|
||||
feeGenerationMode: this.feeGenerationMode,
|
||||
billingEnabled: this.feeGenerationMode === 'system' ? 1 : 0,
|
||||
billingPlanJson: JSON.stringify(this.plans),
|
||||
settlementRuleJson: JSON.stringify(settlementRule),
|
||||
preSettlementConfigJson: JSON.stringify(this.preSettlementConfig),
|
||||
formalSettlementConfigJson: JSON.stringify(this.formalSettlementConfig),
|
||||
changeAttachmentsJson: JSON.stringify(this.changeMaterials),
|
||||
}
|
||||
: {
|
||||
...this.form,
|
||||
changeType: this.form.changeType || '合同信息变更',
|
||||
settlementCurrency: String(this.form.settlementCurrency || '').trim() || 'RMB',
|
||||
copyCount: normalizeOptionalPositiveInteger(this.form.copyCount),
|
||||
invoiceCycle: normalizeOptionalPositiveInteger(this.form.invoiceCycle),
|
||||
paymentDays: normalizeOptionalPositiveInteger(this.form.paymentDays),
|
||||
contractAmount: normalizeOptionalAmount(this.form.contractAmount),
|
||||
startDate: this.period[0],
|
||||
endDate: this.period[1],
|
||||
feeGenerationMode: this.feeGenerationMode,
|
||||
billingEnabled: this.feeGenerationMode === 'system' ? 1 : 0,
|
||||
billingPlanJson: JSON.stringify(this.plans),
|
||||
settlementRuleJson: JSON.stringify(settlementRule),
|
||||
preSettlementConfigJson: JSON.stringify(this.preSettlementConfig),
|
||||
formalSettlementConfigJson: JSON.stringify(this.formalSettlementConfig),
|
||||
paymentRatioJson: JSON.stringify(this.paymentRatioRows),
|
||||
contractFileJson: JSON.stringify(this.contractFileRows),
|
||||
attachmentsJson: JSON.stringify(this.attachments),
|
||||
changeContent: this.form.changeContent,
|
||||
changeReason: this.form.changeReason,
|
||||
changeAttachmentsJson: JSON.stringify(this.changeMaterials),
|
||||
};
|
||||
await api.submitChange(payload);
|
||||
const payload = this.buildChangePayload();
|
||||
if (this.isContractChangeModule) {
|
||||
await changeApi.submit(payload);
|
||||
await submitMkApprovalFlow({
|
||||
bizType: 'contract-change',
|
||||
bizId: this.form.id,
|
||||
subjectName: this.form.contractName || '',
|
||||
approvalStatus: this.form.approvalStatus || '',
|
||||
mkEnabled: await loadMkEnabled().catch(() => false),
|
||||
});
|
||||
sessionStorage.setItem(contractChangeListRefreshKey, '1');
|
||||
this.$message.success('变更已提交');
|
||||
this.$router.push(contractChangeListRoute);
|
||||
return;
|
||||
}
|
||||
await contractApi.submitChange(payload);
|
||||
await submitMkApprovalFlow({
|
||||
bizType: 'contract-manage',
|
||||
bizId: this.form.id,
|
||||
|
||||
Reference in New Issue
Block a user