Files
td_official/src/views/ctr/index.vue
tcy 9f45f2e3b5 refactor(ctr): 优化合同创建页面逻辑
- 添加 active.value 的日志输出,便于调试
- 调整 back 函数,增加日志输出并更新表单步骤
- 简化 resetForm 函数,移除不必要的逻辑
2025-08-21 16:43:00 +08:00

409 lines
19 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 == 0">
<div>
<el-button type="success" size="large" @click="checkContractType('income')">收入合同</el-button>
<el-button type="primary" size="large" @click="checkContractType('expenses')">支出合同</el-button>
</div>
</template>
<template v-else-if="active == 1">
<h1>{{ contract_type == "income" ? "收入合同" : "支出合同" }}</h1>
<template v-if="contract_type == 'income'">
<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="请输入业主单位" />
</el-form-item>
<el-form-item label="承包内容">
<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>
</template>
<template v-else-if="contract_type == 'expenses'">
<el-form ref="expensesContractFormRef" :model="form" :rules="expensesContractFormRules"
label-width="80px">
<!-- <el-form-item label="项目名称">
<el-input :model-value="projectName" placeholder="请输入项目ID" 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 expenses_contract_type" :key="item.value" :label="item.label"
:value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="招标计划" prop="tenderId">
<!-- <el-input v-model="form.tenderId" placeholder="请输入招标Id" /> -->
<el-input v-model="form.name" placeholder="请选择招标计划" disabled />
<el-button type="primary" @click="handleChoose">选择招标</el-button>
</el-form-item>
<el-form-item label="供应商" prop="contractSupplier">
<el-input v-model="form.contractSupplier" placeholder="请输入供应商" disabled />
</el-form-item>
<el-form-item label="分包内容">
<!-- <editor v-model="form.contractedContent" :min-height="192" disabled /> -->
<el-input v-model="form.contractedContent" style="width: 300px"
:autosize="{ minRows: 2, maxRows: 4 }" type="textarea" disabled />
</el-form-item>
<el-form-item label="合同金额" prop="amount">
<el-input
oninput="value=value.replace(/[^0-9.]/g,'').replace(/\.{2,}/g,'.').replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')"
v-model="form.amount" placeholder="请输入合同金额" disabled />
</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>
</template>
<div>
<el-button @click="back(true)">上一步</el-button>
<el-button type="primary" @click="next">下一步</el-button>
</div>
</template>
<template v-else-if="active == 2">
<h1>{{ contract_type == "income" ? "收入合同" : "支出合同" }}</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 v-model="form.advancePayRatio" 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="balancePayRatio">
<el-input v-model="form.balancePayRatio" 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="assuranceDepositRatio;">
<el-input v-model="form.assuranceDepositRatio" 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="payRatio">
<el-input v-model="form.payRatio" placeholder="请输入付款比例"
oninput="value=value.replace(/[^0-9.]/g,'').replace(/\.{2,}/g,'.').replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3')" />
</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>
<el-dialog v-model="dialogVisible" title="选择招标计划" width="45%">
<el-table :data="planList">
<el-table-column type="index" width="50" label="序号" />
<el-table-column label="名称" align="center" prop="name" />
<el-table-column label="合同额" align="center" prop="contractPrice" />
<el-table-column label="分包内容" align="center" prop="content" />
<el-table-column label="中标单位" align="center" prop="winningBidder" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button type="primary" @click="handleChooseData(scope.row)">选择</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="dialogVisible = false">
关闭
</el-button>
</div>
</template>
</el-dialog>
</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(0);
const contract_type = ref("")
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 { 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' }],
payRatio: [{ required: true, message: '请输入付款比例', trigger: 'blur' }],
};
const project = computed(() => {
console.log(111);
return JSON.parse(localStorage.getItem("selectedProject"))
});
const checkContractType = (type) => {
contract_type.value = type;
form.value.contract_type = type;
active.value = 1;
form.value.step = active.value;
};
const onUploadSuccess = (data) => {
fileList.value = data
}
const back = async (reset) => {
console.log(active.value);
if (reset) {
await ElMessageBox.confirm('返回上一步将清空目前填写的内容,确定返回?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
resetForm();
active.value--;
}).catch(() => {
return;
});
} else {
active.value--;
}
console.log(active.value);
form.value.step = active.value;
};
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 resetForm = () => {
form.value = {
payType: 1,
contractCode: '',
contractType: '',
contractOwner: '',
contractedContent: '',
amount: '',
remark: '',
advancePayRatio: '',
balancePayRatio: '',
assuranceDepositRatio: '',
payRatio: ''
};
fileList.value = [];
tempFileList.value = [];
contract_type.value = '';
setTimeout(() => {
localStorage.removeItem("tempContractForm");
}, 0);
};
const submitForm = async () => {
console.log(payMentRef.value);
await payMentRef.value.validate(async (valid) => {
if (valid) {
// 提交付款信息逻辑
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 addIncomeContract({ ...form.value });
} else if (contract_type.value === 'expenses') {
await addExpensesContract({ ...form.value });
}
resetForm();
ElMessage.success('合同提交成功');
} else {
ElMessage.error('请填写完整的付款信息');
}
});
// if (contract_type.value === 'income') {
// const incomeContractFormRef = ref(null);
// await incomeContractFormRef.value.validate(async (valid) => {
// if (valid) {
// // 提交收入合同逻辑
// console.log('提交收入合同', form.value, fileList.value);
// // 这里可以调用API提交数据
// resetForm();
// ElMessage.success('收入合同提交成功');
// } else {
// ElMessage.error('请填写完整的收入合同信息');
// }
// });
// } else if (contract_type.value === 'expenses') {
// const expensesContractFormRef = ref(null);
// await expensesContractFormRef.value.validate(async (valid) => {
// if (valid) {
// // 提交支出合同逻辑
// console.log('提交支出合同', form.value, fileList.value);
// // 这里可以调用API提交数据
// resetForm();
// 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;
}
const handleChooseData = (row) => {
form.value.tenderId = row.id;
form.value.name = row.name;
form.value.contractPrice = row.contractPrice;
form.value.content = row.content;
form.value.winningBidder = row.winningBidder;
dialogVisible.value = false;
};
watch(form, (val) => {
localStorage.setItem("tempContractForm", JSON.stringify({ ...val, fileList: fileList.value }));
}, { deep: true });
watch(fileList, (val) => {
localStorage.setItem("tempContractForm", JSON.stringify({ ...form.value, fileList: val }));
}, { deep: true });
onMounted(() => {
const tempForm = localStorage.getItem("tempContractForm");
if (tempForm) {
ElMessageBox.confirm('检测到有未完成的合同录入,是否继续?', '提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
const t = JSON.parse(tempForm);
const { fileList: files, ...rest } = JSON.parse(tempForm);
form.value = rest;
fileList.value = files || [];
tempFileList.value = files || [];
contract_type.value = form.value.contract_type;
active.value = form.value.step || 0;
}).catch(() => {
localStorage.removeItem("tempContractForm");
});
}
});
</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>