Merge remote-tracking branch 'origin/master'

This commit is contained in:
ye1023
2026-08-04 10:46:09 +08:00
4 changed files with 400 additions and 38 deletions
@@ -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 });
};
@@ -1,5 +1,10 @@
import { h } from 'vue';
import { BasicColumn } from '/@/components/Table';
function renderWrappedText({ text }: any) {
return h('div', { style: 'white-space: pre-wrap; word-break: break-word;' }, text ?? '');
}
export const columns: BasicColumn[] = [
{
title: '序号',
@@ -86,21 +91,24 @@ export const fixedContactFeedbackColumns: BasicColumn[] = [
},
{
title: '计划完成情况',
align: 'center',
align: 'left',
dataIndex: 'planFinishStatus',
width: 160,
customRender: renderWrappedText,
},
{
title: '处理意见、承办情况',
align: 'center',
align: 'left',
dataIndex: 'handleOpinion',
width: 200,
customRender: renderWrappedText,
},
{
title: '办结情况',
align: 'center',
align: 'left',
dataIndex: 'finishStatus',
width: 160,
customRender: renderWrappedText,
},
{
title: '实际完成时间',
@@ -114,20 +122,21 @@ export const fixedContactFeedbackColumns: BasicColumn[] = [
},
{
title: '实际完成情况',
align: 'center',
align: 'left',
dataIndex: 'actualFinishStatus',
width: 160,
customRender: renderWrappedText,
},
{
title: '反馈人',
align: 'center',
dataIndex: 'feedbackUser_dictText',
dataIndex: 'feedbackUserName',
width: 110,
},
{
title: '反馈部门',
align: 'center',
dataIndex: 'feedbackDept_dictText',
dataIndex: 'feedbackDeptName',
width: 150,
},
];
@@ -28,23 +28,23 @@
<a-col :span="24">
<a-tooltip :title="isEdit ? '' : '该信息后续不可编辑,请谨慎填写'">
<a-form-item label="计划完成情况" name="planFinishStatus" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-textarea v-model:value="formData.planFinishStatus" :rows="3" :disabled="isEdit" allow-clear />
<a-textarea v-model:value="formData.planFinishStatus" :auto-size="{ minRows: 3 }" :disabled="isEdit" allow-clear />
</a-form-item>
</a-tooltip>
</a-col>
<a-col :span="24">
<a-form-item label="处理意见、承办情况" name="handleOpinion" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-textarea v-model:value="formData.handleOpinion" :rows="3" allow-clear />
<a-textarea v-model:value="formData.handleOpinion" :auto-size="{ minRows: 3 }" allow-clear />
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="办结情况" name="finishStatus" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-textarea v-model:value="formData.finishStatus" :rows="3" allow-clear />
<a-textarea v-model:value="formData.finishStatus" :auto-size="{ minRows: 3 }" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
<a-form-item label="实际完成时间" name="actualFinishTime">
<a-date-picker v-model:value="formData.actualFinishTime" value-format="YYYY-MM-DD" style="width: 100%" :disabled="isEdit" allow-clear />
<a-date-picker v-model:value="formData.actualFinishTime" value-format="YYYY-MM-DD" style="width: 100%" allow-clear />
</a-form-item>
</a-col>
<a-col :span="12">
@@ -87,10 +87,11 @@
const formRef = ref();
const uploadFileRef = ref<InstanceType<typeof SUploadFile> | null>(null);
const uploadKey = ref(0);
const subProcessDeptId = ref('');
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
const wrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
const wideLabelCol = { xs: { span: 24 }, sm: { span: 3 } };
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 21 } };
const wideLabelCol = { xs: { span: 24 }, sm: { span: 5 } };
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 19 } };
const feedbackSaveUrl = '/bg/fixcontact/fixedContact20260730/addFixedContactFeedback20260730';
const feedbackEditUrl = '/bg/fixcontact/fixedContact20260730/editFixedContactFeedback20260730';
@@ -110,21 +111,23 @@
});
const formRules = {
planFinishTime: [{ required: true, message: '请选择计划完成时间' }],
planFinishStatus: [{ required: true, message: '请输入计划完成情况' }],
};
function resetForm(mainId = '', bpmProcessId = '') {
function resetForm(mainId = '', bpmProcessId = '', deptId = '') {
Object.keys(formData).forEach((key) => {
formData[key] = '';
});
formData.fixedContact20260730Id = mainId;
formData.bpmProcessId = bpmProcessId;
subProcessDeptId.value = deptId;
uploadKey.value += 1;
nextTick(() => formRef.value?.clearValidate?.());
}
function open(mainId: string, bpmProcessId = '', record?: Record<string, any>) {
resetForm(mainId, bpmProcessId);
function open(mainId: string, bpmProcessId = '', deptId = '', record?: Record<string, any>) {
resetForm(mainId, bpmProcessId, deptId);
if (record?.id) {
isEdit.value = true;
modalTitle.value = '编辑反馈';
@@ -157,9 +160,8 @@
const userInfo = (userStore.getUserInfo || {}) as Record<string, any>;
formData.feedbackUser = userInfo.id || userInfo.userId || '';
const loginDepart = getCurrentLoginDepart();
if (loginDepart) {
formData.feedbackDept = loginDepart.id || '';
}
// 反馈部门存当前子流程范围(impl_dept_id),供子流程内按范围过滤;非子流程节点回退到登录人部门
formData.feedbackDept = subProcessDeptId.value || loginDepart?.id || '';
}
function handleCancel() {
@@ -206,5 +208,9 @@
<style lang="less" scoped>
.bpm-feedback-modal-form {
padding: 12px 8px 0;
:deep(textarea.ant-input) {
min-height: 88px;
}
}
</style>
@@ -118,7 +118,7 @@
<a-divider />
<div class="feedback-header section-toolbar">
<div class="feedback-header section-toolbar" v-if="showFeedbackInfo">
<div class="section-title">办理情况</div>
<a-space class="section-actions">
<a-tooltip v-if="showAddFeedback" title="可以多次新增反馈">
@@ -139,7 +139,7 @@
</a-space>
</div>
<a-table
v-if="showFeedbackDetail"
v-if="showFeedbackInfo && showFeedbackDetail"
rowKey="id"
size="small"
bordered
@@ -178,9 +178,44 @@
<div class="process-header section-toolbar">
<div class="section-title">流程办理</div>
</div>
<a-form v-if="showSubApproveUser" class="process-variable-form" labelAlign="left" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="是否办结" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-radio-group v-model:value="isEnd" :disabled="savingSubApproveUser">
<a-radio :value="0">分配部门经办人</a-radio>
<a-radio :value="1">办结</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
<a-col v-if="showSubApproveUserSelector" :span="12">
<a-form-item label="部门经办人" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<sz-dept-user-modal v-model:value="subApproveUser" :disabled="savingSubApproveUser" @confirm="setDisplayNames" />
</a-form-item>
</a-col>
</a-row>
</a-form>
<a-form v-if="showIsNeedLeaderApprove" class="process-variable-form" labelAlign="left" :labelCol="labelCol" :wrapperCol="wrapperCol">
<a-row :gutter="16">
<a-col :span="12">
<a-form-item label="是否需要所领导审批" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<a-radio-group v-model:value="isNeedLeaderApprove" :disabled="savingIsNeedLeaderApprove">
<a-radio :value="0">不需要</a-radio>
<a-radio :value="1">需要所领导审批</a-radio>
</a-radio-group>
</a-form-item>
</a-col>
<a-col v-if="showIsNeedLeaderApproveSelector" :span="12">
<a-form-item label="所领导审批人" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
<sz-dept-user-modal v-model:value="leaderApproveUser" :disabled="savingIsNeedLeaderApprove" />
</a-form-item>
</a-col>
</a-row>
</a-form>
<TaskHandleInnerContent
:form-data="formData"
:claim="claim"
:showSelnextUser="showSelnextUser"
:beforeHandle="saveMainFormBeforeProcessHandle"
@success="handleProcessSuccess"
@claimSuccess="handleClaimSuccess"
@@ -191,18 +226,21 @@
</template>
<script lang="ts" setup>
import { computed, onMounted, reactive, ref, watch } from 'vue';
import { computed, h, onMounted, reactive, ref, watch } from 'vue';
import { defHttp } from '/@/utils/http/axios';
import { useMessage } from '/@/hooks/web/useMessage';
import { usePermission } from '/@/hooks/web/usePermission';
import { useUserStore } from '/@/store/modules/user';
import Icon from '/@/components/Icon/index';
import SzSelectDept from '/@/components/Form/src/jeecg/components/SzSelectDept.vue';
import SzSelectUser from '/@/components/semri/userComponent/SzUserSelect.vue';
import SzDeptUserModal from '/@/components/semri/deptUserComponent/SzDeptUserModal.vue';
import DeptRoleUserSelectDropDown from '/@/components/semri/userComponent/DeptRoleUserSelectDropDown.vue';
import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
import TaskHandleInnerContent from '/@/views/super/bpm/process/personalOffice/myHandleTask/content/TaskHandleInnerContent.vue';
import FixedContact20260730BPMFeedbackModal from './FixedContact20260730BPMFeedbackModal.vue';
import { fixedContactFeedbackList, saveBpmForm, setBpmVariableLocal } from '../FixedContact20260730.api';
import { fixedContactFeedbackList, getProcessVariable, saveBpmForm, setBpmVariableLocal, saveSubApprove, setProcessVariable } from '../FixedContact20260730.api';
import { useSubApproveUserResolver } from '/@/composables/useSubApproveUserResolver';
import { PARTY_COMMITTEE_DEPT_ID, CHARGE_LEADER_ROLE_ID } from '/@/constant/supervision';
const { initBpmFormData } = usePermission();
@@ -218,6 +256,7 @@
const emit = defineEmits(['ok', 'success', 'claimSuccess']);
const { createMessage } = useMessage();
const userStore = useUserStore();
const queryByIdUrl = '/bg/fixcontact/fixedContact20260730/queryById';
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
@@ -228,10 +267,16 @@
const feedbackModalRef = ref();
const loading = ref(false);
const savingMain = ref(false);
const savingSubApproveUser = ref(false);
const showBaseInfoDetail = ref(false);
const showFeedbackDetail = ref(true);
const feedbackList = ref<any[]>([]);
const feedbackAttachmentRefreshKey = ref(0);
const { usernames: subApproveUser, setDisplayNames, initFromData } = useSubApproveUserResolver();
const isEnd = ref(0);
const isNeedLeaderApprove = ref(0);
const leaderApproveUser = ref('');
const savingIsNeedLeaderApprove = ref(false);
const mainForm = reactive<Record<string, any>>({
id: '',
@@ -251,15 +296,19 @@
superviseCount: '',
});
function renderWrappedCell({ text }: Recordable) {
return h('div', { style: 'white-space: pre-wrap; word-break: break-word;' }, text ?? '');
}
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: 'center', width: 260 },
{ title: '处理意见、承办情况', dataIndex: 'handleOpinion', align: 'center', width: 260 },
{ title: '办结情况', dataIndex: 'finishStatus', align: 'center', width: 200 },
{ title: '计划完成情况', dataIndex: 'planFinishStatus', align: 'left', width: 260, customRender: renderWrappedCell },
{ title: '处理意见、承办情况', dataIndex: 'handleOpinion', align: 'left', width: 260, customRender: renderWrappedCell },
{ title: '办结情况', dataIndex: 'finishStatus', align: 'left', width: 200, customRender: renderWrappedCell },
{ title: '实际完成时间', dataIndex: 'actualFinishTime', align: 'center', width: 130, customRender: ({ text }) => (!text ? '' : String(text).slice(0, 10)) },
{ title: '实际完成情况', dataIndex: 'actualFinishStatus', align: 'center', width: 200 },
{ title: '实际完成情况', dataIndex: 'actualFinishStatus', align: 'left', width: 200, customRender: renderWrappedCell },
{ title: '附件', dataIndex: 'id', key: 'attachments', align: 'left', width: 340 },
];
const feedbackActionColumn = { title: '操作', dataIndex: 'action', key: 'action', align: 'center', width: 120, fixed: 'right' };
@@ -276,9 +325,22 @@
}
return props.formDisabled;
});
const showProcessHandle = computed(() => props.formBpm && props.formData?.PROCESS_TAB_TYPE === 'run' && !!props.formData?.taskId);
const canManageFeedback = computed(() => props.formBpm && props.formData?.PROCESS_TAB_TYPE === 'run' && !!props.formData?.taskId);
const showAddFeedback = computed(() => String(props.formData?.extendUrlParams?.addfeedback ?? '') === '1');
const showProcessHandle = computed(() => {
const explicit = props.formData?.extendUrlParams?.showProcessHandle;
if (explicit === '0') return false;
if (explicit === '1') return true;
return props.formBpm && props.formData?.PROCESS_TAB_TYPE === 'run' && !!props.formData?.taskId;
});
const canManageFeedback = computed(() => {
const explicit = props.formData?.extendUrlParams?.showEditFeedback ?? props.formData?.extendUrlParams?.editfeedback;
if (explicit === '0') return false;
if (explicit === '1') return true;
return props.formBpm && props.formData?.PROCESS_TAB_TYPE === 'run' && !!props.formData?.taskId;
});
const showAddFeedback = computed(
() => String(props.formData?.extendUrlParams?.showAddFeedback ?? props.formData?.extendUrlParams?.addfeedback ?? '') === '1'
);
const filterByDept = computed(() => String(props.formData?.extendUrlParams?.filterByDept ?? '') === '1');
const processInfo = computed(() => ({
taskId: props.formData?.taskId,
@@ -294,12 +356,60 @@
processDataId: props.formData?.processDataId,
processTableName: props.formData?.processTableName,
}));
const showFeedbackInfo = computed(() => {
const explicit = props.formData?.extendUrlParams?.showFeedbackInfo;
if (explicit === '0') return false;
if (explicit === '1') return true;
const hasProcess = processInfo.value.taskId || processInfo.value.processInstanceId;
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');
const showIsNeedLeaderApprove = computed(() => String(props.formData?.extendUrlParams?.showIsNeedLeaderApprove ?? '') === '1');
const showIsNeedLeaderApproveSelector = computed(() => showIsNeedLeaderApprove.value && String(isNeedLeaderApprove.value) === '1');
onMounted(() => {
initFormData();
});
watch([() => props.formData?.dataId, () => processInfo.value.processInstanceId], () => initFormData());
// taskId 参与刷新:同实例多个子流程(督办经办人确认等)的 taskId 不同但 processInstanceId/dataId 相同,
// 切换子流程任务时若不刷新会沿用上一个子流程的部门过滤结果
watch(
[() => props.formData?.dataId, () => processInfo.value.processInstanceId, () => props.formData?.taskId],
() => 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);
}
});
watch(
() => props.formData?.vars?.isNeedLeaderApprove,
(value) => {
isNeedLeaderApprove.value = String(value ?? '0') === '1' ? 1 : 0;
},
{ immediate: true }
);
watch(isNeedLeaderApprove, (val) => {
const vars = props.formData?.vars;
if (vars) {
vars.is_need_leader_approve = String(val);
vars.isNeedLeaderApprove = String(val);
}
});
async function initFormData() {
const dataId = props.formData?.dataId;
@@ -313,7 +423,7 @@
if (dataId !== props.formData?.dataId) {
return;
}
setMainForm(data || {});
await setMainForm(data || {});
if (dataId !== props.formData?.dataId) {
return;
}
@@ -323,10 +433,68 @@
}
}
function setMainForm(record: Record<string, any>) {
async function setMainForm(record: Record<string, any>) {
Object.keys(mainForm).forEach((key) => {
mainForm[key] = record[key] ?? '';
});
// 所领导审批人默认取定点联系所领导 + 相关分管所领导,若流程变量已保存则沿用
const savedLeaderApproveUser = props.formData?.vars?.leader_approve_user ?? props.formData?.vars?.leaderApproveUser;
leaderApproveUser.value = String(savedLeaderApproveUser ?? '') || [mainForm.contactLeader, mainForm.relatedLeader].filter(Boolean).join(',');
// 从 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) {
// 子流程当前部门ID实际存于多实例元素变量 dept_idimpl_dept_id 从未写入),优先读取
for (const key of ['dept_id', 'impl_dept_id']) {
try {
const res = await getProcessVariable({ taskId, key, 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<string, any>;
const loginInfo = (userStore.getLoginInfo || {}) as Record<string, any>;
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<string, any>;
return userInfo.username || '';
}
async function getProcessVarDeptIds(): Promise<string[]> {
const deptId = await getCurrentProcessDeptId();
return deptId ? [deptId] : [];
}
async function loadFeedbackList() {
@@ -337,7 +505,21 @@
return;
}
const res = await fixedContactFeedbackList({ id: mainForm.id, bpmProcessId });
feedbackList.value = res?.records || res?.result?.records || [];
let list = Array.isArray(res) ? res : res?.records || [];
// 子流程过滤:filterByDept=1 时仅展示当前子流程内的反馈(反馈部门即保存时写入的子流程范围)
if (list.length && filterByDept.value) {
const deptIds = await getProcessVarDeptIds();
if (deptIds.length) {
list = list.filter((item) => {
const itemDeptIds = String(item.feedbackDept || '')
.split(',')
.map((s: string) => s.trim())
.filter(Boolean);
return itemDeptIds.some((id) => deptIds.includes(id));
});
}
}
feedbackList.value = list;
feedbackAttachmentRefreshKey.value += 1;
}
@@ -385,10 +567,158 @@
return false;
}
}
if (showSubApproveUser.value) {
const subSaved = await saveSubApproveUserVariable({ showSuccessMessage: false });
if (!subSaved) {
return false;
}
}
if (showIsNeedLeaderApprove.value) {
const leaderSaved = await saveIsNeedLeaderApproveVariable({ showSuccessMessage: false });
if (!leaderSaved) {
return false;
}
}
return true;
}
function openFeedbackModal() {
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<string, any> = {
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;
}
}
async function saveIsNeedLeaderApproveVariable(options: { showSuccessMessage?: boolean } = {}) {
const { showSuccessMessage = true } = options;
const processInstanceId = processInfo.value.processInstanceId;
const isNeedLeaderApproveValue = String(isNeedLeaderApprove.value);
const leaderUsernameValue = normalizeUsernameList(leaderApproveUser.value);
if (!processInstanceId) {
createMessage.warning('流程实例ID不能为空');
return false;
}
if (isNeedLeaderApproveValue === '1' && !leaderUsernameValue) {
createMessage.warning('请选择所领导审批人');
return false;
}
savingIsNeedLeaderApprove.value = true;
try {
const result = await saveGlobalProcessVariable('is_need_leader_approve', isNeedLeaderApproveValue);
if (!result?.success) {
createMessage.warning(result.message || '保存失败');
return false;
}
if (isNeedLeaderApproveValue === '1') {
const leaderResult = await saveGlobalProcessVariable('leader_approve_user', leaderUsernameValue);
if (!leaderResult?.success) {
createMessage.warning(leaderResult.message || '保存失败');
return false;
}
}
if (showSuccessMessage) {
createMessage.success('保存成功');
}
return true;
} catch (error) {
createMessage.warning('保存失败');
return false;
} finally {
savingIsNeedLeaderApprove.value = false;
}
}
// 所领导审批为顶层流程决策,写入全局流程变量供流程网关判断
function saveGlobalProcessVariable(varField: string, varVal: any) {
return setProcessVariable({
processInstanceId: processInfo.value.processInstanceId,
local: false,
varField,
varVal,
});
}
// 局部变量写入(默认向上追溯 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(',');
}
async function openFeedbackModal() {
if (!mainForm.id) {
createMessage.warning('主表数据不存在,无法新增反馈');
return;
@@ -398,7 +728,8 @@
createMessage.warning('流程实例ID不能为空,无法新增反馈');
return;
}
feedbackModalRef.value?.open(mainForm.id, processInstanceId);
const deptId = await getCurrentProcessDeptId();
feedbackModalRef.value?.open(mainForm.id, processInstanceId, deptId);
}
function openFeedbackEditModal(record: Recordable) {
@@ -410,7 +741,7 @@
createMessage.warning('反馈记录不存在,无法编辑');
return;
}
feedbackModalRef.value?.open(mainForm.id, processInfo.value.processInstanceId, record);
feedbackModalRef.value?.open(mainForm.id, processInfo.value.processInstanceId, '', record);
}
async function handleFeedbackDelete(record: Recordable) {