Files
td_official/src/views/ctr/update/index.vue
tcy 31963f69c3 feat(ctr): 优化合同提交流程并添加更新功能
- 修改合同提交成功后的步骤重置逻辑,根据合同类型跳转到不同页面
- 更新合同信息页面,添加批量导出功能
- 优化合同信息获取逻辑,提高页面加载速度
2025-08-22 22:24:10 +08:00

329 lines
13 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="container">
<el-steps style="max-width: 100%" :active="active" finish-status="success" align-center>
<el-step title="选择合同类型" />
<el-step title="修改合同内容" />
<el-step title="修改收款方式" />
</el-steps>
<div class="content">
<template v-if="active == 1">
<h1>修改收入合同</h1>
<el-form ref="incomeContractFormRef" :model="form" :rules="incomeContractFormRules" label-width="80px">
<!-- <el-form-item label="项目名称">
<el-input :model-value="project.name" disabled />
</el-form-item> -->
<el-form-item label="合同编号" prop="contractCode">
<el-input v-model="form.contractCode" placeholder="请输入合同编号" />
</el-form-item>
<el-form-item label="合同类型" prop="contractType">
<el-select v-model="form.contractType" placeholder="请选择合同类型">
<el-option v-for="item in income_contract_type" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="业主单位" prop="contractOwner">
<el-input v-model="form.contractOwner" placeholder="请输入业主单位" disabled />
</el-form-item>
<el-form-item label="承包内容" v-if="contract_type !== 'income'">
<editor v-model="form.contractedContent" :min-height="192" />
</el-form-item>
<el-form-item label="合同内容" v-else>
<editor v-model="form.contractedContent" :min-height="192" />
</el-form-item>
<el-form-item label="合同金额" prop="amount">
<el-input v-model="form.amount" placeholder="请输入合同金额"
oninput="value=value.replace(/[^0-9.]/g,'').replace(/\.{2,}/g,'.').replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="附件">
<FileUpload :multiple="true" :fileType="['pdf']" :onUploadSuccess="onUploadSuccess"
:ref="fileRef" :defaultFileList="tempFileList" />
</el-form-item>
</el-form>
<div>
<el-button type="primary" @click="next">下一步</el-button>
</div>
</template>
<template v-else-if="active == 2">
<h1>修改收入合同</h1>
<el-form :model="form" :rules="payMentRules" label-width="150" ref="payMentRef">
<el-form-item label="支付方式" placeholder="请选择支付方式" prop="payType">
<el-select v-model="form.payType">
<el-option :value="1" label="月结算">月结算</el-option>
<el-option :value="2" label="形象节点">形象节点</el-option>
</el-select>
</el-form-item>
<el-form-item label="预付款比例(%" prop="advancePayRatio">
<el-input-number v-model="form.advancePayRatio" :max="100" :min="0" />
</el-form-item>
<el-form-item label="尾款比例(%" prop="balancePayRatio">
<el-input-number v-model="form.balancePayRatio" :max="100" :min="0" />
</el-form-item>
<el-form-item label="质保金比例(%" prop="assuranceDepositRatio">
<el-input-number v-model="form.assuranceDepositRatio" :max="100" :min="0" />
</el-form-item>
<el-form-item label="付款比例(%" prop="payRatio">
<el-input-number v-model="payRatioComputed" disabled />
</el-form-item>
<el-form-item>
<div>
<el-button @click="back(false)">上一步</el-button>
<el-button type="success" @click="submitForm">提交</el-button>
</div>
</el-form-item>
</el-form>
</template>
</div>
</div>
</template>
<script setup>
import FileUpload from '@/components/FileUpload';
import { listExpensesContract, getExpensesContract, delExpensesContract, addExpensesContract, updateExpensesContract, getTenderPlan } from '@/api/ctr/expensesContract';
import { listIncomeContract, getIncomeContract, delIncomeContract, addIncomeContract, updateIncomeContract } from '@/api/ctr/incomeContract';
import { useUserStore } from '@/store/modules/user';
const active = ref(1);
const contract_type = ref("income")
const form = ref({ payType: 1 })
const fileList = ref([])
const tempFileList = ref([])
const { proxy } = getCurrentInstance();
const userStore = useUserStore();
const planList = ref([]);
const dialogVisible = ref(false);
const route = useRoute();
const router = useRouter();
const { expenses_contract_type, income_contract_type } = toRefs(
proxy?.useDict('income_contract_type', 'expenses_contract_type')
);
const fileRef = ref(null);
const incomeContractFormRef = ref(null);
const expensesContractFormRef = ref(null);
const payMentRef = ref(null);
const incomeContractFormRules = {
contractCode: [{ required: true, message: '请输入合同编号', trigger: 'blur' }],
contractType: [{ required: true, message: '请选择合同类型', trigger: 'change' }],
contractOwner: [{ required: true, message: '请输入业主单位', trigger: 'blur' }],
amount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }],
remark: [{ required: false, message: '请输入备注', trigger: 'blur' }],
};
const expensesContractFormRules = {
contractCode: [{ required: true, message: '请输入合同编号', trigger: 'blur' }],
contractType: [{ required: true, message: '请选择合同类型', trigger: 'change' }],
contractSupplier: [{ required: true, message: '请输入供应商', trigger: 'blur' }],
amount: [{ required: true, message: '请输入合同金额', trigger: 'blur' }],
tenderId: [{ required: true, message: '请选择招标计划', trigger: 'blur' }],
remark: [{ required: false, message: '请输入备注', trigger: 'blur' }],
};
const payMentRules = {
payType: [{ required: true, message: '请选择支付方式', trigger: 'change' }],
advancePayRatio: [{ required: true, message: '请输入预付款比例', trigger: 'blur' }],
balancePayRatio: [{ required: true, message: '请输入尾款比例', trigger: 'blur' }],
assuranceDepositRatio: [{ required: true, message: '请输入质保金比例', trigger: 'blur' }],
};
const project = computed(() => {
return JSON.parse(localStorage.getItem("selectedProject"))
});
const payRatioComputed = computed({
get: () => {
const { advancePayRatio = 0, balancePayRatio = 0, assuranceDepositRatio = 0 } = form.value;
const total = 100 - (advancePayRatio + balancePayRatio + assuranceDepositRatio);
// form.value.payRatio = total;
return total;
},
// 只读
set: () => { }
});
const onUploadSuccess = (data) => {
fileList.value = data
}
const next = async () => {
if (contract_type.value === 'income') {
await incomeContractFormRef.value.validate((valid) => {
if (valid) {
active.value++;
} else {
ElMessage.error('请填写完整的收入合同信息');
}
});
} else if (contract_type.value === 'expenses') {
await expensesContractFormRef.value.validate((valid) => {
if (valid) {
active.value++;
} else {
ElMessage.error('请填写完整的支出合同信息');
}
});
}
console.log(active.value);
form.value.step = active.value;
};
const submitForm = async () => {
await payMentRef.value.validate(async (valid) => {
if (valid) {
if (payRatioComputed.value < 0) {
ElMessage.error('四项付款比例之和必须等于100%');
return;
}
form.value.payRatio = payRatioComputed.value;
// 提交付款信息逻辑
console.log('提交付款信息', form.value, fileList.value);
// 这里可以调用API提交数据
form.value.projectId = project.value.id;
form.value.fileList = fileList.value.map((data) => {
return {
...data,
fileName: data.name,
fileUrl: data.url,
}
})
if (contract_type.value === 'income') {
await updateIncomeContract({ ...form.value });
}
ElMessage.success('合同修改成功');
} else {
ElMessage.error('请填写完整的付款信息');
}
});
}
const handleChoose = async () => {
if (!form.value.contractType) {
ElMessage.error('请先选择合同类型');
return;
}
const formData = {
projectId: userStore.selectedProject.id,
dictName: form.value.contractType,
status: 1,
}
const { data } = await getTenderPlan(formData)
if (data.length === 0) {
ElMessage.warning('当前没有招标计划,请先创建招标计划');
return;
}
planList.value = data
dialogVisible.value = true;
}
onMounted(async () => {
// const id = route.query.id;
// if (id) {
// const { data } = await getIncomeContract(id);
// form.value.id = data.id;
// form.value.contractOwner = data.contractOwner
// } else {
// router.push('/ctr/incomeContract');
// }
proxy?.download(
'/progress/progressCategory/export',
{
"ids": [
"1951552037761114114",
"1951552037811445761",
"1951552037811445762",
"1951552037811445763",
"1951552037811445764",
"1951552037811445765",
"1951552037811445766",
"1951552037811445767",
"1951552037865971713",
"1951552037865971714",
"1951552037865971715",
"1951552037865971716",
"1951552037865971717",
"1951552037865971718",
"1951552037865971719",
"1951552037865971720",
"1951552037865971721",
"1951552037865971722",
"1951552037865971723",
"1951552037865971724",
"1951552037865971725",
"1951552037924691969",
"1951552037924691970",
"1951552037924691971",
"1951552037924691972",
"1951552037924691973",
"1951552037924691974",
"1951552037924691975",
"1951552037924691976",
"1951552037924691977",
"1951552037962440706",
"1951552037962440707",
"1951552037962440708",
"1951552037962440709",
"1951552037962440710",
"1951552037962440711",
"1951552037962440712",
"1951552038004383745",
"1951552038004383746",
"1951552038004383747",
"1951552038004383748",
"1951552038004383749",
"1951552038004383750",
"1951552038004383751",
"1951552038004383752",
"1951552038004383753",
"1951552038004383754",
"1951552038058909698",
"1951552038058909699",
"1951552038058909700",
"1951552038058909701",
"1951552038058909702",
"1951552038058909703",
"1951552038058909704",
"1951552038096658434",
"1951552038096658435",
"1951552038096658436",
"1951552038096658437",
"1951552038096658438",
"1951552038096658439",
"1951552038096658440",
"1951552038096658441",
"1951552038096658442",
"1951552038096658443",
"1951552038096658444",
"1951552038146990081",
"1951552038146990082",
"1951552038146990083",
"1951552038146990084",
"1951552038146990085",
"1951552038188933122",
"1951552038188933123",
"1951552038188933124"
]
},
`1.xlsx`
);
})
</script>
<style scoped lang="scss">
.container {
padding: 20px;
.content {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 30px;
flex-direction: column;
}
}
</style>