From 648274b69bcefc210a6b974a7051961f2b033796 Mon Sep 17 00:00:00 2001 From: Yangk Date: Thu, 25 Dec 2025 10:45:44 +0800 Subject: [PATCH] =?UTF-8?q?refactor(oa):=20=E7=A7=BB=E9=99=A4=E7=BC=96?= =?UTF-8?q?=E5=8F=B7=E7=94=9F=E6=88=90=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E8=A1=A8=E5=8D=95=E6=8F=90=E4=BA=A4=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除出差申请、售后申请和工时填报页面的编号生成按钮和相关逻辑 --- src/views/oa/crm/businessTripApply/edit.vue | 112 +++++----- src/views/oa/erp/afterSales/edit.vue | 158 +++++++------- src/views/oa/erp/timesheetInfo/edit.vue | 220 +++++++++----------- src/views/oa/erp/timesheetInfo/index.vue | 2 +- 4 files changed, 235 insertions(+), 257 deletions(-) diff --git a/src/views/oa/crm/businessTripApply/edit.vue b/src/views/oa/crm/businessTripApply/edit.vue index 8d1dcb0..f3bce39 100644 --- a/src/views/oa/crm/businessTripApply/edit.vue +++ b/src/views/oa/crm/businessTripApply/edit.vue @@ -30,11 +30,7 @@ - - - + @@ -286,8 +282,6 @@ const projectSelectRef = ref>(); const userList = ref([]); // 用户列表 -const isCodeGenerated = ref(false); - // 流程相关数据 const submitFormData = ref({ businessId: '', @@ -329,7 +323,7 @@ const data = reactive({ form: { ...initFormData }, rules: { tripType: [{ required: true, message: '出差类型不能为空', trigger: 'change' }], - applyCode: [{ required: true, message: '申请单号不能为空', trigger: 'blur' }], + // applyCode: [{ required: true, message: '申请单号不能为空', trigger: 'blur' }], tripLocation: [{ required: true, message: '出差地点不能为空', trigger: 'blur' }], startTime: [{ required: true, message: '开始时间不能为空', trigger: 'change' }], endTime: [{ required: true, message: '结束时间不能为空', trigger: 'change' }], @@ -393,30 +387,10 @@ onMounted(async () => { if (id && (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval')) { const res = await getBusinessTripApply(id); Object.assign(form.value, res.data); - if (form.value.applyCode) { - isCodeGenerated.value = true; - } } }); }); -// 生成申请编号 -const generateApplyCode = async () => { - if (isCodeGenerated.value) return; - try { - const params = { codeRuleCode: CodeRuleEnum.BUSINESS_TRIP } as any; - const res = await getRuleGenerateCode(params); - if (res.code === 200) { - form.value.applyCode = res.msg; - isCodeGenerated.value = true; - proxy?.$modal.msgSuccess('编号生成成功'); - } - } catch (e) { - console.error(e); - proxy?.$modal.msgError('编号生成失败'); - } -}; - // 计算时长 const calculateDuration = () => { if (form.value.startTime && form.value.endTime) { @@ -467,49 +441,57 @@ const handleApproverSelectChange = (val: any) => { // 提交表单 (包含暂存和提交审批) const submitForm = (status: string, mode: boolean) => { + if (status === 'draft') { + executeSubmit(status, mode); + return; + } businessTripApplyFormRef.value?.validate(async (valid) => { if (valid) { - buttonLoading.value = true; - try { - if (status !== 'draft') { - // 提交审批 - form.value.tripStatus = '2'; // 审批中 - form.value.flowStatus = 'waiting'; - form.value.variables = { - ...form.value.variables, - tripType: form.value.tripType - }; - form.value.bizExt = { - businessTitle: '出差申请', - businessCode: form.value.applyCode - }; - // 确保流程编码存在 - form.value.flowCode = FlowCodeEnum.BUSINESS_TRIP_CODE; - const res = await submitBusinessTripApplyAndFlowStart(form.value); - // 成功后处理 - proxy?.$modal.msgSuccess('提交成功'); - submitCallback(); - } else { - // 暂存 - form.value.tripStatus = '1'; - form.value.flowStatus = 'draft'; - if (form.value.tripId) { - await updateBusinessTripApply(form.value); - } else { - const res = await addBusinessTripApply(form.value); - } - proxy?.$modal.msgSuccess('暂存成功'); - submitCallback(); - } - } catch (e) { - console.error(e); - } finally { - buttonLoading.value = false; - } + executeSubmit(status, mode); } }); }; +const executeSubmit = async (status: string, mode: boolean) => { + buttonLoading.value = true; + try { + if (status !== 'draft') { + // 提交审批 + form.value.tripStatus = '2'; // 审批中 + form.value.flowStatus = 'waiting'; + form.value.variables = { + ...form.value.variables, + tripType: form.value.tripType + }; + form.value.bizExt = { + businessTitle: '出差申请', + businessCode: form.value.applyCode + }; + // 确保流程编码存在 + form.value.flowCode = FlowCodeEnum.BUSINESS_TRIP_CODE; + const res = await submitBusinessTripApplyAndFlowStart(form.value); + // 成功后处理 + proxy?.$modal.msgSuccess('提交成功'); + submitCallback(); + } else { + // 暂存 + form.value.tripStatus = '1'; + form.value.flowStatus = 'draft'; + if (form.value.tripId) { + await updateBusinessTripApply(form.value); + } else { + const res = await addBusinessTripApply(form.value); + } + proxy?.$modal.msgSuccess('暂存成功'); + submitCallback(); + } + } catch (e) { + console.error(e); + } finally { + buttonLoading.value = false; + } +}; + // 审批记录 const handleApprovalRecord = () => { approvalRecordRef.value?.init(form.value.tripId); diff --git a/src/views/oa/erp/afterSales/edit.vue b/src/views/oa/erp/afterSales/edit.vue index 99cb726..9505de4 100644 --- a/src/views/oa/erp/afterSales/edit.vue +++ b/src/views/oa/erp/afterSales/edit.vue @@ -35,17 +35,7 @@ - - - + @@ -425,7 +415,8 @@ import { getAfterSales, addAfterSales, updateAfterSales, submitAfterSalesAndFlow import { listProjectInfo } from '@/api/oa/erp/projectInfo'; import { listUser } from '@/api/system/user'; import { getErpProjectContractsList } from '@/api/oa/erp/projectContracts'; -import { listContractInfo } from '@/api/oa/erp/contractInfo'; +import { getContractInfo } from '@/api/oa/erp/contractInfo'; +import { getCustomerInfo } from '@/api/oa/crm/customerInfo'; import { listCustomerContact } from '@/api/oa/crm/customerContact'; import { listUnitInfo } from '@/api/oa/base/unitInfo'; import { getRuleGenerateCode } from '@/api/system/codeRule'; @@ -509,12 +500,12 @@ const data = reactive({ }, rules: { afterSalesSubject: [{ required: true, message: '售后主题不能为空', trigger: 'blur' }], - afterSalesCode: [{ required: true, message: '售后编号不能为空', trigger: 'blur' }], + // afterSalesCode: [{ required: true, message: '售后编号不能为空', trigger: 'blur' }], projectCode: [{ required: true, message: '请选择项目', trigger: 'change' }], projectName: [{ required: true, message: '请选择项目', trigger: 'change' }], afterSalesDate: [{ required: true, message: '请选择日期', trigger: 'change' }], afterSalesType: [{ required: true, message: '请选择售后类型', trigger: 'change' }], - stakeholderId: [{ required: true, message: '客户干系人不能为空', trigger: 'change' }], + // stakeholderId: [{ required: true, message: '客户干系人不能为空', trigger: 'change' }], handlerId: [{ required: true, message: '售后处理人不能为空', trigger: 'change' }] } }); @@ -698,23 +689,38 @@ function loadContractOptions(projectId: any) { } // 合同变更联动 -> 客户 -> 联系人 -function handleContractChange(val: any) { +async function handleContractChange(val: any) { form.value.customerName = undefined; form.value.customerId = undefined; contactOptions.value = []; if (!val) return; - listContractInfo({ contractId: val, pageNum: 1, pageSize: 10 } as any).then((res: any) => { - if (res.rows && res.rows.length > 0) { - const contract = res.rows[0]; + try { + // 1. 获取合同详情 + const resContract = await getContractInfo(val); + if (resContract.data) { + const contract = resContract.data; form.value.customerId = contract.oneCustomerId; - form.value.customerName = contract.oneCustomerName; - if (contract.oneCustomerId) { - loadContactOptions(contract.oneCustomerId); + + // 2. 如果合同详情中有客户名则直接用,否则单独查询客户详情 + if (contract.oneCustomerName) { + form.value.customerName = contract.oneCustomerName; + } else if (contract.oneCustomerId) { + const resCustomer = await getCustomerInfo(contract.oneCustomerId); + if (resCustomer.data) { + form.value.customerName = resCustomer.data.customerName; + } + } + + // 3. 加载联系人 + if (form.value.customerId) { + loadContactOptions(form.value.customerId); } } - }); + } catch (error) { + console.error('加载合同关联信息失败:', error); + } } // 加载客户联系人 @@ -900,62 +906,70 @@ const getMaterialSummaries = (param: any) => { /** 提交按钮 */ const submitForm = (status: string, mode: boolean) => { + if (status === 'draft') { + executeSubmit(status, mode); + return; + } afterSalesFormRef.value.validate(async (valid: boolean) => { if (valid) { - buttonLoading.value = true; - try { - const submitData: any = { ...form.value }; - - // 数据格式转换:数组 -> 字符串 - if (Array.isArray(submitData.handlerId)) submitData.handlerId = submitData.handlerId.join(','); - if (Array.isArray(submitData.stakeholderId)) submitData.stakeholderId = submitData.stakeholderId.join(','); - - if (status !== 'draft') { - // --- 提交审批 --- - submitData.flowCode = FlowCodeEnum.AFTER_SALES_KEY; - submitData.variables = { - afterSalesId: submitData.afterSalesId, - totalCost: submitData.totalCost || 0, - startUserId: useUserStore().userId - }; - submitData.bizExt = { - businessTitle: `售后申请:${submitData.afterSalesSubject}`, - businessCode: submitData.afterSalesCode - }; - submitData.afterSalesStatus = '1'; // 审批中 - submitData.flowStatus = 'waiting'; - - const res = await submitAfterSalesAndFlowStart(submitData); - if (res && res.data) { - form.value = res.data; - if (!form.value.laborCostsList) form.value.laborCostsList = []; - if (!form.value.materialCostsList) form.value.materialCostsList = []; - } - proxy.$modal.msgSuccess('提交成功,流程已发起'); - } else { - // --- 暂存草稿 --- - submitData.flowStatus = 'draft'; - submitData.afterSalesStatus = '0'; // 草稿 - if (submitData.afterSalesId) { - await updateAfterSales(submitData); - } else { - await addAfterSales(submitData); - } - proxy.$modal.msgSuccess('暂存成功'); - } - // 返回列表 - proxy.$tab.closePage(route); - router.go(-1); - } catch (error) { - console.error('提交发生错误:', error); - proxy.$modal.msgError('提交失败,请查看控制台错误详情'); - } finally { - buttonLoading.value = false; - } + executeSubmit(status, mode); } }); }; +const executeSubmit = async (status: string, mode: boolean) => { + buttonLoading.value = true; + try { + const submitData: any = { ...form.value }; + + // 数据格式转换:数组 -> 字符串 + if (Array.isArray(submitData.handlerId)) submitData.handlerId = submitData.handlerId.join(','); + if (Array.isArray(submitData.stakeholderId)) submitData.stakeholderId = submitData.stakeholderId.join(','); + + if (status !== 'draft') { + // --- 提交审批 --- + submitData.flowCode = FlowCodeEnum.AFTER_SALES_KEY; + submitData.variables = { + afterSalesId: submitData.afterSalesId, + totalCost: submitData.totalCost || 0, + startUserId: useUserStore().userId + }; + submitData.bizExt = { + businessTitle: `售后申请:${submitData.afterSalesSubject}`, + businessCode: submitData.afterSalesCode + }; + submitData.afterSalesStatus = '1'; // 审批中 + submitData.flowStatus = 'waiting'; + + const res = await submitAfterSalesAndFlowStart(submitData); + if (res && res.data) { + form.value = res.data; + if (!form.value.laborCostsList) form.value.laborCostsList = []; + if (!form.value.materialCostsList) form.value.materialCostsList = []; + } + proxy.$modal.msgSuccess('提交成功,流程已发起'); + } else { + // --- 暂存草稿 --- + submitData.flowStatus = 'draft'; + submitData.afterSalesStatus = '0'; // 草稿 + if (submitData.afterSalesId) { + await updateAfterSales(submitData); + } else { + await addAfterSales(submitData); + } + proxy.$modal.msgSuccess('暂存成功'); + } + // 返回列表 + proxy.$tab.closePage(route); + router.go(-1); + } catch (error) { + console.error('提交发生错误:', error); + proxy.$modal.msgError('提交失败,请查看控制台错误详情'); + } finally { + buttonLoading.value = false; + } +}; + // 审批记录初始化 const handleApprovalRecord = () => { if (form.value.afterSalesId) { diff --git a/src/views/oa/erp/timesheetInfo/edit.vue b/src/views/oa/erp/timesheetInfo/edit.vue index e3b9b51..8730758 100644 --- a/src/views/oa/erp/timesheetInfo/edit.vue +++ b/src/views/oa/erp/timesheetInfo/edit.vue @@ -30,17 +30,7 @@ - - - + @@ -271,7 +261,6 @@ const userStore = useUserStore(); const routeParams = ref({}); const buttonLoading = ref(false); const timesheetFormRef = ref(); -const isCodeGenerated = ref(false); const submitVerifyRef = ref>(); const approvalRecordRef = ref>(); @@ -304,7 +293,7 @@ const data = reactive({ timesheetProjectList: [] as any[] }, rules: { - timesheetCode: [{ required: true, message: '编号不能为空', trigger: 'blur' }], + // timesheetCode: [{ required: true, message: '编号不能为空', trigger: 'blur' }], startTime: [{ required: true, message: '请选择起始日期', trigger: 'change' }], endTime: [{ required: true, message: '请选择结束日期', trigger: 'change' }] } @@ -328,7 +317,6 @@ onMounted(async () => { form.value = res.data; if (!form.value.timesheetDeptList) form.value.timesheetDeptList = []; if (!form.value.timesheetProjectList) form.value.timesheetProjectList = []; - if (form.value.timesheetCode) isCodeGenerated.value = true; } else { setWeekDates(); form.value.timesheetDeptList = []; @@ -449,20 +437,6 @@ const getDeptName = (deptId: any) => { }; /** 生成编号 */ -const generateCode = async () => { - if (isCodeGenerated.value) return; - try { - const res = await getRuleGenerateCode({ codeRuleCode: CodeRuleEnum.TIMESHEET } as any); - if (res.code === 200) { - form.value.timesheetCode = res.msg; - isCodeGenerated.value = true; - proxy?.$modal.msgSuccess('生成成功'); - } - } catch (error) { - console.error(error); - } -}; - /** 自动计算工时 */ const calculateHours = () => { const deptList = form.value.timesheetDeptList || []; @@ -525,103 +499,111 @@ const getSummary = (param: any) => { /** 提交按钮 */ const submitForm = (status: string) => { + if (status === 'draft') { + executeSubmit(status); + return; + } timesheetFormRef.value?.validate(async (valid: boolean) => { if (valid) { - buttonLoading.value = true; - try { - const submitData: any = { ...form.value }; - - if (status !== 'draft') { - // 提交前校验 - if (submitData.timesheetDeptList && submitData.timesheetDeptList.length > 0) { - for (let i = 0; i < submitData.timesheetDeptList.length; i++) { - const row = submitData.timesheetDeptList[i]; - // 检查每一行是否选了审批人 - if (!row.approverId) { - proxy.$modal.msgError(`部门工作:第 ${i + 1} 行未选择审批人`); - buttonLoading.value = false; - return; // 阻止提交 - } - } - } - if (submitData.timesheetProjectList && submitData.timesheetProjectList.length > 0) { - for (let i = 0; i < submitData.timesheetProjectList.length; i++) { - const row = submitData.timesheetProjectList[i]; - if (!row.approverId) { - proxy.$modal.msgError(`项目工作:第 ${i + 1} 行未选择审批人`); - buttonLoading.value = false; - return; // 阻止提交 - } - } - } - if (submitData.timesheetDeptList.length === 0 && submitData.timesheetProjectList.length === 0) { - proxy.$modal.msgError('请至少填写一项部门工时或项目工时'); - buttonLoading.value = false; - return; - } - // 提交审批 - submitData.flowCode = FlowCodeEnum.TIMESHEET_KEY; - - // 提取部门工时审批人 (取 approverId) - const deptApproverSet = new Set(); - submitData.timesheetDeptList.forEach((item: any) => { - if (item.approverId) deptApproverSet.add(item.approverId); - }); - const deptApprovers = Array.from(deptApproverSet); - - // 提取项目工时审批人 (取 approverId) - const projectApproverSet = new Set(); - submitData.timesheetProjectList.forEach((item: any) => { - if (item.approverId) projectApproverSet.add(item.approverId); - }); - const projectApprovers = Array.from(projectApproverSet); - - // 必须选择审批人 - if (deptApprovers.length === 0 && projectApprovers.length === 0) { - proxy.$modal.msgError('请至少填写一项工时并指定审批人'); - buttonLoading.value = false; - return; - } - - // 放入流程变量 - submitData.variables = { - startUserId: userStore.userId, - totalHours: submitData.totalHours, - deptApprovers: deptApprovers, // 对应后端 variables.put("deptApprovers", ...) - projectApprovers: projectApprovers, // 对应后端 variables.put("projectApprovers", ...) - hasDeptWork: deptApprovers.length > 0, // 前端也可以传这个标记,双重保险 - hasProjectWork: projectApprovers.length > 0 // 前端也可以传这个标记 - }; - - submitData.bizExt = { - businessTitle: `工时填报:${userStore.nickname}`, - businessCode: submitData.timesheetCode - }; - submitData.timesheetStatus = '2'; // 已提交 - submitData.flowStatus = 'waiting'; - - const res = await submitTimesheetAndFlowStart(submitData); - if (res?.data) form.value = res.data; - proxy.$modal.msgSuccess('提交成功'); - } else { - // 暂存 - submitData.timesheetStatus = '1'; // 草稿 - submitData.flowStatus = 'draft'; - if (submitData.timesheetId) await updateTimesheetInfo(submitData); - else await addTimesheetInfo(submitData); - proxy.$modal.msgSuccess('暂存成功'); - } - proxy.$tab.closePage(route); - router.go(-1); - } catch (e) { - console.error(e); - } finally { - buttonLoading.value = false; - } + executeSubmit(status); } }); }; +const executeSubmit = async (status: string) => { + buttonLoading.value = true; + try { + const submitData: any = { ...form.value }; + + if (status !== 'draft') { + // 提交前校验 + if (submitData.timesheetDeptList && submitData.timesheetDeptList.length > 0) { + for (let i = 0; i < submitData.timesheetDeptList.length; i++) { + const row = submitData.timesheetDeptList[i]; + // 检查每一行是否选了审批人 + if (!row.approverId) { + proxy.$modal.msgError(`部门工作:第 ${i + 1} 行未选择审批人`); + buttonLoading.value = false; + return; // 阻止提交 + } + } + } + if (submitData.timesheetProjectList && submitData.timesheetProjectList.length > 0) { + for (let i = 0; i < submitData.timesheetProjectList.length; i++) { + const row = submitData.timesheetProjectList[i]; + if (!row.approverId) { + proxy.$modal.msgError(`项目工作:第 ${i + 1} 行未选择审批人`); + buttonLoading.value = false; + return; // 阻止提交 + } + } + } + if (submitData.timesheetDeptList.length === 0 && submitData.timesheetProjectList.length === 0) { + proxy.$modal.msgError('请至少填写一项部门工时或项目工时'); + buttonLoading.value = false; + return; + } + // 提交审批 + submitData.flowCode = FlowCodeEnum.TIMESHEET_KEY; + + // 提取部门工时审批人 (取 approverId) + const deptApproverSet = new Set(); + submitData.timesheetDeptList.forEach((item: any) => { + if (item.approverId) deptApproverSet.add(item.approverId); + }); + const deptApprovers = Array.from(deptApproverSet); + + // 提取项目工时审批人 (取 approverId) + const projectApproverSet = new Set(); + submitData.timesheetProjectList.forEach((item: any) => { + if (item.approverId) projectApproverSet.add(item.approverId); + }); + const projectApprovers = Array.from(projectApproverSet); + + // 必须选择审批人 + if (deptApprovers.length === 0 && projectApprovers.length === 0) { + proxy.$modal.msgError('请至少填写一项工时并指定审批人'); + buttonLoading.value = false; + return; + } + + // 放入流程变量 + submitData.variables = { + startUserId: userStore.userId, + totalHours: submitData.totalHours, + deptApprovers: deptApprovers, // 对应后端 variables.put("deptApprovers", ...) + projectApprovers: projectApprovers, // 对应后端 variables.put("projectApprovers", ...) + hasDeptWork: deptApprovers.length > 0, // 前端也可以传这个标记,双重保险 + hasProjectWork: projectApprovers.length > 0 // 前端也可以传这个标记 + }; + + submitData.bizExt = { + businessTitle: `工时填报:${userStore.nickname}`, + businessCode: submitData.timesheetCode + }; + submitData.timesheetStatus = '2'; // 已提交 + submitData.flowStatus = 'waiting'; + + const res = await submitTimesheetAndFlowStart(submitData); + if (res?.data) form.value = res.data; + proxy.$modal.msgSuccess('提交成功'); + } else { + // 暂存 + submitData.timesheetStatus = '1'; // 草稿 + submitData.flowStatus = 'draft'; + if (submitData.timesheetId) await updateTimesheetInfo(submitData); + else await addTimesheetInfo(submitData); + proxy.$modal.msgSuccess('暂存成功'); + } + proxy.$tab.closePage(route); + router.go(-1); + } catch (e) { + console.error(e); + } finally { + buttonLoading.value = false; + } +}; + const handleApprovalRecord = () => { if (form.value.timesheetId) approvalRecordRef.value?.init(form.value.timesheetId); }; diff --git a/src/views/oa/erp/timesheetInfo/index.vue b/src/views/oa/erp/timesheetInfo/index.vue index 0515a08..5853ad8 100644 --- a/src/views/oa/erp/timesheetInfo/index.vue +++ b/src/views/oa/erp/timesheetInfo/index.vue @@ -181,7 +181,7 @@ const data = reactive>({ }, rules: { timesheetId: [{ required: true, message: '工时填报ID不能为空', trigger: 'blur' }], - timesheetCode: [{ required: true, message: '工时填报编号不能为空', trigger: 'blur' }], + // timesheetCode: [{ required: true, message: '工时填报编号不能为空', trigger: 'blur' }], userId: [{ required: true, message: '人员ID不能为空', trigger: 'blur' }], startTime: [{ required: true, message: '起始时间不能为空', trigger: 'blur' }], endTime: [{ required: true, message: '结束时间不能为空', trigger: 'blur' }]