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('主表数据不存在,无法新增反馈');