From 90ae916b931ba225d81cc3e70d113d6461540a00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E7=BA=A2=E5=85=B5?= <374362909@qq.com> Date: Sun, 15 Mar 2026 10:53:43 +0800 Subject: [PATCH] =?UTF-8?q?feat(purchase):=20=E5=B1=A5=E7=BA=A6=E9=AA=8C?= =?UTF-8?q?=E6=94=B6=E8=87=AA=E5=8A=A8=E6=98=BE=E7=A4=BA=E5=90=88=E5=90=8C?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=92=8C=E4=BE=9B=E5=BA=94=E5=95=86=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 选择“是否签订合同”为“是”时,自动查询采购合同 - 合同流程已完成时,自动显示合同信息和供应商信息 - 合同不存在或流程未完成时,提示无法进行履约操作 - 移除合同下拉选择,改为只读显示 - 添加合同状态常量(运行中/已完成/已作废) --- .../accept/AcceptCommonForm.vue | 202 +++++++++++------- 1 file changed, 129 insertions(+), 73 deletions(-) diff --git a/src/views/purchase/purchasingrequisition/accept/AcceptCommonForm.vue b/src/views/purchase/purchasingrequisition/accept/AcceptCommonForm.vue index 1e9ccdb..cc3c4c3 100644 --- a/src/views/purchase/purchasingrequisition/accept/AcceptCommonForm.vue +++ b/src/views/purchase/purchasingrequisition/accept/AcceptCommonForm.vue @@ -13,30 +13,43 @@ - + 否 是 - - - - + + + + 正在查询合同... + + + + 合同名称: + {{ currentContract.contractName || currentContract.contractNo || '-' }} + + + 合同金额: + {{ currentContract.money ? `${currentContract.money}元` : '-' }} + + + + + 未找到关联合同,无法进行履约操作 + + + + + 合同正在流程审批中,无法进行履约操作 + + - + 否 是 @@ -44,12 +57,17 @@ - + - + @@ -64,6 +82,7 @@ :remote-method="searchAssetAdmin" :loading="assetAdminLoading" style="width: 100%" + :disabled="contractStatus === 'pending'" @change="onAssetAdminChange" > import { ref, reactive, watch, onMounted } from 'vue'; import type { FormInstance, FormRules } from 'element-plus'; +import { Loading } from '@element-plus/icons-vue'; import { getContracts, searchTeachers } from '/@/api/purchase/purchasingrequisition'; +import { useMessage } from '/@/hooks/message'; + +const CONTRACT_FLOW_STATUS = { + RUNNING: '0', + COMPLETED: '1', + CANCELLED: '2', +}; const props = defineProps<{ modelValue: Record; projectName?: string; deptName?: string; - /** 采购申请ID,用于拉取合同列表 */ purchaseId?: string | number; - /** 每次打开弹窗时变化,用于强制重置内部 form */ resetKey?: number; }>(); const emit = defineEmits(['update:modelValue']); const formRef = ref(); -const contractOptions = ref([]); const contractLoading = ref(false); -const contractLoaded = ref(false); +const currentContract = ref(null); +const contractStatus = ref<'none' | 'pending' | 'completed' | ''>(''); -// 采购人员相关 const purchaserOptions = ref([]); const purchaserLoading = ref(false); -// 资产管理员相关 const assetAdminOptions = ref([]); const assetAdminLoading = ref(false); @@ -157,13 +181,12 @@ const form = reactive({ purchaserName: '', assetAdminId: '', assetAdminName: '', - transactionAmount: null, + transactionAmount: null as number | null, ...props.modelValue, }); const syncFormFromModel = (val: Record | undefined) => { Object.assign(form, val || {}); - // 加载已选人员信息用于回显 if (form.purchaserId && form.purchaserName) { purchaserOptions.value = [{ teacherNo: form.purchaserId, realName: form.purchaserName, name: form.purchaserName }]; } @@ -172,33 +195,52 @@ const syncFormFromModel = (val: Record | undefined) => { } }; -const loadContractOptions = async () => { - if (contractLoaded.value || contractLoading.value) return; - if (form.hasContract !== '1') return; +const loadContractInfo = async () => { + if (!props.purchaseId) { + contractStatus.value = ''; + currentContract.value = null; + return; + } + contractLoading.value = true; + contractStatus.value = ''; + currentContract.value = null; + try { - const res = await getContracts(props.purchaseId ? { id: props.purchaseId } : {}); + const res = await getContracts({ id: props.purchaseId }); const list = res?.data; - contractOptions.value = Array.isArray(list) ? list : []; - contractLoaded.value = true; - // 回显时:列表中含当前合同,用其供应商名称填充(若尚未有值) - if (form.contractId) { - const c = contractOptions.value.find((it: any) => it.id === form.contractId); - if (c?.supplierName) form.supplierName = c.supplierName; + + if (Array.isArray(list) && list.length > 0) { + const contract = list[0]; + currentContract.value = contract; + form.contractId = contract.id; + + if (contract.flowStatus === CONTRACT_FLOW_STATUS.COMPLETED) { + contractStatus.value = 'completed'; + form.supplierName = contract.supplierName || ''; + } else if (contract.flowStatus === CONTRACT_FLOW_STATUS.RUNNING) { + contractStatus.value = 'pending'; + form.supplierName = ''; + } else { + contractStatus.value = 'pending'; + form.supplierName = ''; + } + } else { + contractStatus.value = 'none'; + currentContract.value = null; + form.contractId = ''; + form.supplierName = ''; } - } catch (_) { - contractOptions.value = []; + } catch (e: any) { + contractStatus.value = 'none'; + currentContract.value = null; + form.contractId = ''; + form.supplierName = ''; } finally { contractLoading.value = false; } }; -const onContractSelectVisibleChange = (visible: boolean) => { - if (visible && form.hasContract === '1' && contractOptions.value.length === 0) { - loadContractOptions(); - } -}; - const searchPurchaser = async (query: string) => { if (!query) { purchaserOptions.value = []; @@ -261,57 +303,38 @@ watch( () => props.modelValue, (val) => { syncFormFromModel(val); - // 回显:已有合同ID时主动加载合同列表,以便下拉显示合同名称(后端已排除"其他申请"的合同,当前申请合同会在列表中) - if (form.hasContract === '1' && form.contractId && props.purchaseId && !contractLoaded.value && !contractLoading.value) { - loadContractOptions(); - } }, { deep: true, immediate: true } ); -// resetKey 变化时强制用 modelValue 覆盖内部 form,并重置合同列表以便重新拉取 + watch( () => props.resetKey, () => { syncFormFromModel(props.modelValue); - contractLoaded.value = false; - contractOptions.value = []; + contractStatus.value = ''; + currentContract.value = null; } ); + watch(form, () => emit('update:modelValue', { ...form }), { deep: true }); watch( () => form.hasContract, (val) => { if (val === '1') { - contractLoaded.value = false; - loadContractOptions(); + loadContractInfo(); } else { - contractOptions.value = []; - contractLoaded.value = false; + contractStatus.value = ''; + currentContract.value = null; + form.contractId = ''; } - // hasContract 变化时触发 transactionAmount 校验 formRef.value?.validateField('transactionAmount'); } ); -// 选择合同后,自动带出合同供应商名称 -watch( - () => form.contractId, - (val) => { - if (!val) { - form.supplierName = ''; - return; - } - const c = contractOptions.value.find((it: any) => it.id === val); - if (c && c.supplierName) { - form.supplierName = c.supplierName; - } - } -); - onMounted(() => { if (form.hasContract === '1') { - loadContractOptions(); + loadContractInfo(); } }); @@ -322,7 +345,6 @@ const rules: FormRules = { transactionAmount: [ { validator: (rule: any, value: any, callback: any) => { - // 未签订合同时,成交金额为必填 if (form.hasContract === '0' && (value === null || value === undefined || value === '')) { callback(new Error('未签订合同时,成交金额为必填')); } else { @@ -334,7 +356,17 @@ const rules: FormRules = { ], }; -const validate = () => formRef.value?.validate(); +const validate = async () => { + if (form.hasContract === '1' && contractStatus.value === 'pending') { + useMessage().error('合同正在流程审批中,无法进行履约操作'); + return false; + } + if (form.hasContract === '1' && contractStatus.value === 'none') { + useMessage().error('未找到关联合同,无法进行履约操作'); + return false; + } + return formRef.value?.validate(); +}; defineExpose({ validate, form }); @@ -348,4 +380,28 @@ defineExpose({ validate, form }); color: #999; margin-top: 4px; } - +.contract-info-loading { + display: flex; + align-items: center; + gap: 8px; + color: #409eff; +} +.contract-info-display { + background: #f5f7fa; + border-radius: 4px; + padding: 12px; +} +.contract-item { + display: flex; + align-items: center; + line-height: 1.8; +} +.contract-item .label { + color: #606266; + min-width: 80px; +} +.contract-item .value { + color: #303133; + font-weight: 500; +} + \ No newline at end of file