From a2b7d24de969d6036ce0fe68ec8b577e4715630f Mon Sep 17 00:00:00 2001 From: wsm <8454518+new-twice@user.noreply.gitee.com> Date: Mon, 3 Aug 2026 10:43:15 +0000 Subject: [PATCH] =?UTF-8?q?!132=20fix(fixcontact):=20=E5=8F=8D=E9=A6=88?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E5=AE=9E=E9=99=85=E5=AE=8C=E6=88=90=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=85=81=E8=AE=B8=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(fixcontact): 反馈弹窗实际完成时间允许编辑 * feat(fixcontact): 反馈列表展示反馈人与反馈部门名称 * feat(fixcontact): 流程表单支持部门并行子流程 --- .../bg/fixcontact/FixedContact20260730.api.ts | 16 ++ .../fixcontact/FixedContact20260730.data.ts | 4 +- .../FixedContact20260730BPMFeedbackModal.vue | 2 +- .../FixedContact20260730BPMForm.vue | 191 +++++++++++++++++- 4 files changed, 204 insertions(+), 9 deletions(-) diff --git a/src/views/bg/fixcontact/FixedContact20260730.api.ts b/src/views/bg/fixcontact/FixedContact20260730.api.ts index 0ca83a9..2f936e5 100644 --- a/src/views/bg/fixcontact/FixedContact20260730.api.ts +++ b/src/views/bg/fixcontact/FixedContact20260730.api.ts @@ -79,3 +79,19 @@ export const setBpmVariableLocal = (params) => { export const withDrawFixContact = (params) => { return defHttp.post({ url: '/bg/fixcontact/fixedContact20260730/withDrawFixContact', params }, { joinParamsToUrl: true, isTransformResponse: false }); }; + +export const saveSubApprove = (params) => { + return defHttp.post({ url: '/bg/fixcontact/fixedContact20260730/saveSubApprove', params }, { isTransformResponse: false }); +}; + +export const setProcessVariable = (params) => { + return defHttp.post({ url: '/act/process/setProcessVariable', params }, { isTransformResponse: false }); +}; + +/** + * 获取流程变量(支持局部变量查询),从task执行实例向上精准查找 + * @param params { taskId, key, isLocal } + */ +export const getProcessVariable = (params: { taskId: string; key: string; isLocal?: boolean }) => { + return defHttp.get({ url: '/act/process/extActProcessNode/getVariable', params }); +}; diff --git a/src/views/bg/fixcontact/FixedContact20260730.data.ts b/src/views/bg/fixcontact/FixedContact20260730.data.ts index 409d083..4445e23 100644 --- a/src/views/bg/fixcontact/FixedContact20260730.data.ts +++ b/src/views/bg/fixcontact/FixedContact20260730.data.ts @@ -130,13 +130,13 @@ export const fixedContactFeedbackColumns: BasicColumn[] = [ { title: '反馈人', align: 'center', - dataIndex: 'feedbackUser_dictText', + dataIndex: 'feedbackUserName', width: 110, }, { title: '反馈部门', align: 'center', - dataIndex: 'feedbackDept_dictText', + dataIndex: 'feedbackDeptName', width: 150, }, ]; diff --git a/src/views/bg/fixcontact/components/FixedContact20260730BPMFeedbackModal.vue b/src/views/bg/fixcontact/components/FixedContact20260730BPMFeedbackModal.vue index 57366b3..e409279 100644 --- a/src/views/bg/fixcontact/components/FixedContact20260730BPMFeedbackModal.vue +++ b/src/views/bg/fixcontact/components/FixedContact20260730BPMFeedbackModal.vue @@ -44,7 +44,7 @@ - + diff --git a/src/views/bg/fixcontact/components/FixedContact20260730BPMForm.vue b/src/views/bg/fixcontact/components/FixedContact20260730BPMForm.vue index 8aa975c..4d5b1ea 100644 --- a/src/views/bg/fixcontact/components/FixedContact20260730BPMForm.vue +++ b/src/views/bg/fixcontact/components/FixedContact20260730BPMForm.vue @@ -178,6 +178,23 @@
流程办理
+ + + + + + 否(分配部门经办人) + 是(办结) + + + + + + + + + + ([]); const feedbackAttachmentRefreshKey = ref(0); + const { usernames: subApproveUser, setDisplayNames, initFromData } = useSubApproveUserResolver(); + const isEnd = ref(0); const mainForm = reactive>({ id: '', @@ -257,8 +281,8 @@ } const feedbackBaseColumns = [ - { title: '反馈部门', dataIndex: 'feedbackDept_dictText', align: 'center', width: 160 }, - { title: '反馈人', dataIndex: 'feedbackUser_dictText', align: 'center', width: 120 }, + { title: '反馈部门', dataIndex: 'feedbackDeptName', align: 'center', width: 160 }, + { title: '反馈人', dataIndex: 'feedbackUserName', align: 'center', width: 120 }, { title: '计划完成时间', dataIndex: 'planFinishTime', align: 'center', width: 130, customRender: ({ text }) => (!text ? '' : String(text).slice(0, 10)) }, { title: '计划完成情况', dataIndex: 'planFinishStatus', align: 'left', width: 260, customRender: renderWrappedCell }, { title: '处理意见、承办情况', dataIndex: 'handleOpinion', align: 'left', width: 260, customRender: renderWrappedCell }, @@ -319,6 +343,10 @@ return !!hasProcess; }); const showSelnextUser = computed(() => String(props.formData?.extendUrlParams?.showSelnextUser ?? '') === '1'); + const showSubApproveUser = computed( + () => String(props.formData?.extendUrlParams?.showSubApproveUser ?? props.formData?.extendUrlParams?.selectuser ?? '') === '1' + ); + const showSubApproveUserSelector = computed(() => showSubApproveUser.value && String(isEnd.value) !== '1'); onMounted(() => { initFormData(); @@ -326,6 +354,21 @@ watch([() => props.formData?.dataId, () => processInfo.value.processInstanceId], () => initFormData()); + watch( + () => props.formData?.vars?.isEnd, + (value) => { + isEnd.value = String(value ?? '0') === '1' ? 1 : 0; + }, + { immediate: true } + ); + watch(isEnd, (val) => { + const vars = props.formData?.vars; + if (vars) { + vars.is_end = String(val); + vars.isEnd = String(val); + } + }); + async function initFormData() { const dataId = props.formData?.dataId; if (!dataId) { @@ -338,7 +381,7 @@ if (dataId !== props.formData?.dataId) { return; } - setMainForm(data || {}); + await setMainForm(data || {}); if (dataId !== props.formData?.dataId) { return; } @@ -348,10 +391,57 @@ } } - function setMainForm(record: Record) { + async function setMainForm(record: Record) { Object.keys(mainForm).forEach((key) => { mainForm[key] = record[key] ?? ''; }); + // 从 approveInfo JSON 初始化当前子流程部门的 isEnd 和部门经办人 + const approveInfo = record.approveInfo; + const deptId = await getCurrentProcessDeptId(); + if (approveInfo && deptId && approveInfo[deptId]) { + const detail = approveInfo[deptId]; + isEnd.value = detail.isEnd ?? 0; + // 多选经办人存于 implUserNameList,单选经办人存于 implWorker + const workerNames = Array.isArray(detail.implUserNameList) && detail.implUserNameList.length + ? detail.implUserNameList.join(',') + : detail.implWorker ?? ''; + await initFromData(workerNames); + } + } + + async function getCurrentProcessDeptId() { + const taskId = props.formData?.taskId; + if (taskId) { + try { + const res = await getProcessVariable({ taskId, key: 'impl_dept_id', isLocal: true }); + const value = res?.result?.value ?? res?.value; + if (value) { + const deptId = String(value).replace('[', '').replace(']', '').trim(); + if (deptId) { + return deptId; + } + } + } catch (e) { + // 局部变量读取失败,回退到当前用户部门 + } + } + return getCurrentUserDeptId(); + } + + function getCurrentUserDeptId() { + const userInfo = (userStore.getUserInfo || {}) as Record; + const loginInfo = (userStore.getLoginInfo || {}) as Record; + const departs = Array.isArray(loginInfo.departs) ? loginInfo.departs : []; + if (userInfo.orgCode) { + const dept = departs.find((item: any) => item.orgCode === userInfo.orgCode); + return dept?.id || ''; + } + return departs.length === 1 ? departs[0]?.id || '' : ''; + } + + function getCurrentAssignee() { + const userInfo = (userStore.getUserInfo || {}) as Record; + return userInfo.username || ''; } async function loadFeedbackList() { @@ -362,7 +452,7 @@ return; } const res = await fixedContactFeedbackList({ id: mainForm.id, bpmProcessId }); - feedbackList.value = res?.records || res?.result?.records || []; + feedbackList.value = Array.isArray(res) ? res : res?.records || []; feedbackAttachmentRefreshKey.value += 1; } @@ -410,9 +500,98 @@ return false; } } + if (showSubApproveUser.value) { + return saveSubApproveUserVariable({ showSuccessMessage: false }); + } return true; } + async function saveSubApproveUserVariable(options: { showSuccessMessage?: boolean } = {}) { + const { showSuccessMessage = true } = options; + const processInstanceId = processInfo.value.processInstanceId; + const isEndValue = String(isEnd.value); + const usernameValue = normalizeUsernameList(subApproveUser.value); + const deptId = await getCurrentProcessDeptId(); + if (!mainForm.id) { + createMessage.warning('主表ID不能为空'); + return false; + } + if (!processInstanceId) { + createMessage.warning('流程实例ID不能为空'); + return false; + } + if (!deptId) { + createMessage.warning('无法获取当前部门'); + return false; + } + if (isEndValue !== '1' && !usernameValue) { + createMessage.warning('请选择部门经办人'); + return false; + } + + savingSubApproveUser.value = true; + try { + // 写 is_end 子流程局部变量(多实例间互不覆盖),供 ${fixContactFlow.getIsEnd(execution)} 网关路由使用 + const isEndResult = await saveProcessVariableLocal('is_end', isEndValue); + if (!isEndResult?.success) { + createMessage.warning(isEndResult.message || '保存失败'); + return false; + } + // 未办结时写部门经办人子流程局部变量,供子流程内经办人并行会签多实例 collection 使用 + if (isEndValue !== '1') { + const subApproveUserResult = await saveProcessVariableLocal('sub_approve_user', usernameValue); + if (!subApproveUserResult?.success) { + createMessage.warning(subApproveUserResult.message || '保存失败'); + return false; + } + } + // 同步落库 approve_info JSON,用于按部门回显 + const params: Record = { + mainId: mainForm.id, + deptId, + isEnd: Number(isEndValue), + }; + if (isEndValue === '1') { + params.implWorker = getCurrentAssignee(); + } else { + params.implUserNameList = usernameValue.split(',').filter(Boolean); + } + const res = await saveSubApprove(params); + if (!res?.success) { + createMessage.warning(res?.message || '保存失败'); + return false; + } + if (showSuccessMessage) { + createMessage.success('保存成功'); + } + return true; + } catch (error) { + createMessage.warning('保存失败'); + return false; + } finally { + savingSubApproveUser.value = false; + } + } + + // 局部变量写入(默认向上追溯 2 层父级执行实例),与 FixContactDeptLeaderApproveListener 存储目标保持一致 + function saveProcessVariableLocal(varField: string, varVal: any) { + return setBpmVariableLocal({ + processInstanceId: processInfo.value.processInstanceId, + taskId: processInfo.value.taskId, + parentLevel: 2, + varField, + varVal, + }); + } + + function normalizeUsernameList(value: string) { + return String(value || '') + .split(',') + .map((item) => item.trim()) + .filter(Boolean) + .join(','); + } + function openFeedbackModal() { if (!mainForm.id) { createMessage.warning('主表数据不存在,无法新增反馈');