Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -79,3 +79,19 @@ export const setBpmVariableLocal = (params) => {
|
|||||||
export const withDrawFixContact = (params) => {
|
export const withDrawFixContact = (params) => {
|
||||||
return defHttp.post({ url: '/bg/fixcontact/fixedContact20260730/withDrawFixContact', params }, { joinParamsToUrl: true, isTransformResponse: false });
|
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';
|
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[] = [
|
export const columns: BasicColumn[] = [
|
||||||
{
|
{
|
||||||
title: '序号',
|
title: '序号',
|
||||||
@@ -86,21 +91,24 @@ export const fixedContactFeedbackColumns: BasicColumn[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '计划完成情况',
|
title: '计划完成情况',
|
||||||
align: 'center',
|
align: 'left',
|
||||||
dataIndex: 'planFinishStatus',
|
dataIndex: 'planFinishStatus',
|
||||||
width: 160,
|
width: 160,
|
||||||
|
customRender: renderWrappedText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '处理意见、承办情况',
|
title: '处理意见、承办情况',
|
||||||
align: 'center',
|
align: 'left',
|
||||||
dataIndex: 'handleOpinion',
|
dataIndex: 'handleOpinion',
|
||||||
width: 200,
|
width: 200,
|
||||||
|
customRender: renderWrappedText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '办结情况',
|
title: '办结情况',
|
||||||
align: 'center',
|
align: 'left',
|
||||||
dataIndex: 'finishStatus',
|
dataIndex: 'finishStatus',
|
||||||
width: 160,
|
width: 160,
|
||||||
|
customRender: renderWrappedText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '实际完成时间',
|
title: '实际完成时间',
|
||||||
@@ -114,20 +122,21 @@ export const fixedContactFeedbackColumns: BasicColumn[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '实际完成情况',
|
title: '实际完成情况',
|
||||||
align: 'center',
|
align: 'left',
|
||||||
dataIndex: 'actualFinishStatus',
|
dataIndex: 'actualFinishStatus',
|
||||||
width: 160,
|
width: 160,
|
||||||
|
customRender: renderWrappedText,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '反馈人',
|
title: '反馈人',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
dataIndex: 'feedbackUser_dictText',
|
dataIndex: 'feedbackUserName',
|
||||||
width: 110,
|
width: 110,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '反馈部门',
|
title: '反馈部门',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
dataIndex: 'feedbackDept_dictText',
|
dataIndex: 'feedbackDeptName',
|
||||||
width: 150,
|
width: 150,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -28,23 +28,23 @@
|
|||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-tooltip :title="isEdit ? '' : '该信息后续不可编辑,请谨慎填写'">
|
<a-tooltip :title="isEdit ? '' : '该信息后续不可编辑,请谨慎填写'">
|
||||||
<a-form-item label="计划完成情况" name="planFinishStatus" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
|
<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-form-item>
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="处理意见、承办情况" name="handleOpinion" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
|
<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-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="办结情况" name="finishStatus" :labelCol="wideLabelCol" :wrapperCol="wideWrapperCol">
|
<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-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="实际完成时间" name="actualFinishTime">
|
<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-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
@@ -87,10 +87,11 @@
|
|||||||
const formRef = ref();
|
const formRef = ref();
|
||||||
const uploadFileRef = ref<InstanceType<typeof SUploadFile> | null>(null);
|
const uploadFileRef = ref<InstanceType<typeof SUploadFile> | null>(null);
|
||||||
const uploadKey = ref(0);
|
const uploadKey = ref(0);
|
||||||
|
const subProcessDeptId = ref('');
|
||||||
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
|
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
|
||||||
const wrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
|
const wrapperCol = { xs: { span: 24 }, sm: { span: 17 } };
|
||||||
const wideLabelCol = { xs: { span: 24 }, sm: { span: 3 } };
|
const wideLabelCol = { xs: { span: 24 }, sm: { span: 5 } };
|
||||||
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 21 } };
|
const wideWrapperCol = { xs: { span: 24 }, sm: { span: 19 } };
|
||||||
|
|
||||||
const feedbackSaveUrl = '/bg/fixcontact/fixedContact20260730/addFixedContactFeedback20260730';
|
const feedbackSaveUrl = '/bg/fixcontact/fixedContact20260730/addFixedContactFeedback20260730';
|
||||||
const feedbackEditUrl = '/bg/fixcontact/fixedContact20260730/editFixedContactFeedback20260730';
|
const feedbackEditUrl = '/bg/fixcontact/fixedContact20260730/editFixedContactFeedback20260730';
|
||||||
@@ -110,21 +111,23 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
const formRules = {
|
const formRules = {
|
||||||
|
planFinishTime: [{ required: true, message: '请选择计划完成时间' }],
|
||||||
planFinishStatus: [{ required: true, message: '请输入计划完成情况' }],
|
planFinishStatus: [{ required: true, message: '请输入计划完成情况' }],
|
||||||
};
|
};
|
||||||
|
|
||||||
function resetForm(mainId = '', bpmProcessId = '') {
|
function resetForm(mainId = '', bpmProcessId = '', deptId = '') {
|
||||||
Object.keys(formData).forEach((key) => {
|
Object.keys(formData).forEach((key) => {
|
||||||
formData[key] = '';
|
formData[key] = '';
|
||||||
});
|
});
|
||||||
formData.fixedContact20260730Id = mainId;
|
formData.fixedContact20260730Id = mainId;
|
||||||
formData.bpmProcessId = bpmProcessId;
|
formData.bpmProcessId = bpmProcessId;
|
||||||
|
subProcessDeptId.value = deptId;
|
||||||
uploadKey.value += 1;
|
uploadKey.value += 1;
|
||||||
nextTick(() => formRef.value?.clearValidate?.());
|
nextTick(() => formRef.value?.clearValidate?.());
|
||||||
}
|
}
|
||||||
|
|
||||||
function open(mainId: string, bpmProcessId = '', record?: Record<string, any>) {
|
function open(mainId: string, bpmProcessId = '', deptId = '', record?: Record<string, any>) {
|
||||||
resetForm(mainId, bpmProcessId);
|
resetForm(mainId, bpmProcessId, deptId);
|
||||||
if (record?.id) {
|
if (record?.id) {
|
||||||
isEdit.value = true;
|
isEdit.value = true;
|
||||||
modalTitle.value = '编辑反馈';
|
modalTitle.value = '编辑反馈';
|
||||||
@@ -157,9 +160,8 @@
|
|||||||
const userInfo = (userStore.getUserInfo || {}) as Record<string, any>;
|
const userInfo = (userStore.getUserInfo || {}) as Record<string, any>;
|
||||||
formData.feedbackUser = userInfo.id || userInfo.userId || '';
|
formData.feedbackUser = userInfo.id || userInfo.userId || '';
|
||||||
const loginDepart = getCurrentLoginDepart();
|
const loginDepart = getCurrentLoginDepart();
|
||||||
if (loginDepart) {
|
// 反馈部门存当前子流程范围(impl_dept_id),供子流程内按范围过滤;非子流程节点回退到登录人部门
|
||||||
formData.feedbackDept = loginDepart.id || '';
|
formData.feedbackDept = subProcessDeptId.value || loginDepart?.id || '';
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCancel() {
|
function handleCancel() {
|
||||||
@@ -206,5 +208,9 @@
|
|||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.bpm-feedback-modal-form {
|
.bpm-feedback-modal-form {
|
||||||
padding: 12px 8px 0;
|
padding: 12px 8px 0;
|
||||||
|
|
||||||
|
:deep(textarea.ant-input) {
|
||||||
|
min-height: 88px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
|
|
||||||
<a-divider />
|
<a-divider />
|
||||||
|
|
||||||
<div class="feedback-header section-toolbar">
|
<div class="feedback-header section-toolbar" v-if="showFeedbackInfo">
|
||||||
<div class="section-title">办理情况</div>
|
<div class="section-title">办理情况</div>
|
||||||
<a-space class="section-actions">
|
<a-space class="section-actions">
|
||||||
<a-tooltip v-if="showAddFeedback" title="可以多次新增反馈">
|
<a-tooltip v-if="showAddFeedback" title="可以多次新增反馈">
|
||||||
@@ -139,7 +139,7 @@
|
|||||||
</a-space>
|
</a-space>
|
||||||
</div>
|
</div>
|
||||||
<a-table
|
<a-table
|
||||||
v-if="showFeedbackDetail"
|
v-if="showFeedbackInfo && showFeedbackDetail"
|
||||||
rowKey="id"
|
rowKey="id"
|
||||||
size="small"
|
size="small"
|
||||||
bordered
|
bordered
|
||||||
@@ -178,9 +178,44 @@
|
|||||||
<div class="process-header section-toolbar">
|
<div class="process-header section-toolbar">
|
||||||
<div class="section-title">流程办理</div>
|
<div class="section-title">流程办理</div>
|
||||||
</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
|
<TaskHandleInnerContent
|
||||||
:form-data="formData"
|
:form-data="formData"
|
||||||
:claim="claim"
|
:claim="claim"
|
||||||
|
:showSelnextUser="showSelnextUser"
|
||||||
:beforeHandle="saveMainFormBeforeProcessHandle"
|
:beforeHandle="saveMainFormBeforeProcessHandle"
|
||||||
@success="handleProcessSuccess"
|
@success="handleProcessSuccess"
|
||||||
@claimSuccess="handleClaimSuccess"
|
@claimSuccess="handleClaimSuccess"
|
||||||
@@ -191,18 +226,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<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 { defHttp } from '/@/utils/http/axios';
|
||||||
import { useMessage } from '/@/hooks/web/useMessage';
|
import { useMessage } from '/@/hooks/web/useMessage';
|
||||||
import { usePermission } from '/@/hooks/web/usePermission';
|
import { usePermission } from '/@/hooks/web/usePermission';
|
||||||
|
import { useUserStore } from '/@/store/modules/user';
|
||||||
import Icon from '/@/components/Icon/index';
|
import Icon from '/@/components/Icon/index';
|
||||||
import SzSelectDept from '/@/components/Form/src/jeecg/components/SzSelectDept.vue';
|
import SzSelectDept from '/@/components/Form/src/jeecg/components/SzSelectDept.vue';
|
||||||
import SzSelectUser from '/@/components/semri/userComponent/SzUserSelect.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 DeptRoleUserSelectDropDown from '/@/components/semri/userComponent/DeptRoleUserSelectDropDown.vue';
|
||||||
import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
|
import SUploadFile from '/@/components/semri/fileComponent/SUploadFile.vue';
|
||||||
import TaskHandleInnerContent from '/@/views/super/bpm/process/personalOffice/myHandleTask/content/TaskHandleInnerContent.vue';
|
import TaskHandleInnerContent from '/@/views/super/bpm/process/personalOffice/myHandleTask/content/TaskHandleInnerContent.vue';
|
||||||
import FixedContact20260730BPMFeedbackModal from './FixedContact20260730BPMFeedbackModal.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';
|
import { PARTY_COMMITTEE_DEPT_ID, CHARGE_LEADER_ROLE_ID } from '/@/constant/supervision';
|
||||||
|
|
||||||
const { initBpmFormData } = usePermission();
|
const { initBpmFormData } = usePermission();
|
||||||
@@ -218,6 +256,7 @@
|
|||||||
|
|
||||||
const emit = defineEmits(['ok', 'success', 'claimSuccess']);
|
const emit = defineEmits(['ok', 'success', 'claimSuccess']);
|
||||||
const { createMessage } = useMessage();
|
const { createMessage } = useMessage();
|
||||||
|
const userStore = useUserStore();
|
||||||
const queryByIdUrl = '/bg/fixcontact/fixedContact20260730/queryById';
|
const queryByIdUrl = '/bg/fixcontact/fixedContact20260730/queryById';
|
||||||
|
|
||||||
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
|
const labelCol = { xs: { span: 24 }, sm: { span: 7 } };
|
||||||
@@ -228,10 +267,16 @@
|
|||||||
const feedbackModalRef = ref();
|
const feedbackModalRef = ref();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const savingMain = ref(false);
|
const savingMain = ref(false);
|
||||||
|
const savingSubApproveUser = ref(false);
|
||||||
const showBaseInfoDetail = ref(false);
|
const showBaseInfoDetail = ref(false);
|
||||||
const showFeedbackDetail = ref(true);
|
const showFeedbackDetail = ref(true);
|
||||||
const feedbackList = ref<any[]>([]);
|
const feedbackList = ref<any[]>([]);
|
||||||
const feedbackAttachmentRefreshKey = ref(0);
|
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>>({
|
const mainForm = reactive<Record<string, any>>({
|
||||||
id: '',
|
id: '',
|
||||||
@@ -251,15 +296,19 @@
|
|||||||
superviseCount: '',
|
superviseCount: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function renderWrappedCell({ text }: Recordable) {
|
||||||
|
return h('div', { style: 'white-space: pre-wrap; word-break: break-word;' }, text ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
const feedbackBaseColumns = [
|
const feedbackBaseColumns = [
|
||||||
{ title: '反馈部门', dataIndex: 'feedbackDept_dictText', align: 'center', width: 160 },
|
{ title: '反馈部门', dataIndex: 'feedbackDeptName', align: 'center', width: 160 },
|
||||||
{ title: '反馈人', dataIndex: 'feedbackUser_dictText', align: 'center', width: 120 },
|
{ title: '反馈人', dataIndex: 'feedbackUserName', align: 'center', width: 120 },
|
||||||
{ title: '计划完成时间', dataIndex: 'planFinishTime', align: 'center', width: 130, customRender: ({ text }) => (!text ? '' : String(text).slice(0, 10)) },
|
{ title: '计划完成时间', dataIndex: 'planFinishTime', align: 'center', width: 130, customRender: ({ text }) => (!text ? '' : String(text).slice(0, 10)) },
|
||||||
{ title: '计划完成情况', dataIndex: 'planFinishStatus', align: 'center', width: 260 },
|
{ title: '计划完成情况', dataIndex: 'planFinishStatus', align: 'left', width: 260, customRender: renderWrappedCell },
|
||||||
{ title: '处理意见、承办情况', dataIndex: 'handleOpinion', align: 'center', width: 260 },
|
{ title: '处理意见、承办情况', dataIndex: 'handleOpinion', align: 'left', width: 260, customRender: renderWrappedCell },
|
||||||
{ title: '办结情况', dataIndex: 'finishStatus', align: 'center', width: 200 },
|
{ 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: '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 },
|
{ title: '附件', dataIndex: 'id', key: 'attachments', align: 'left', width: 340 },
|
||||||
];
|
];
|
||||||
const feedbackActionColumn = { title: '操作', dataIndex: 'action', key: 'action', align: 'center', width: 120, fixed: 'right' };
|
const feedbackActionColumn = { title: '操作', dataIndex: 'action', key: 'action', align: 'center', width: 120, fixed: 'right' };
|
||||||
@@ -276,9 +325,22 @@
|
|||||||
}
|
}
|
||||||
return props.formDisabled;
|
return props.formDisabled;
|
||||||
});
|
});
|
||||||
const showProcessHandle = computed(() => props.formBpm && props.formData?.PROCESS_TAB_TYPE === 'run' && !!props.formData?.taskId);
|
const showProcessHandle = computed(() => {
|
||||||
const canManageFeedback = computed(() => props.formBpm && props.formData?.PROCESS_TAB_TYPE === 'run' && !!props.formData?.taskId);
|
const explicit = props.formData?.extendUrlParams?.showProcessHandle;
|
||||||
const showAddFeedback = computed(() => String(props.formData?.extendUrlParams?.addfeedback ?? '') === '1');
|
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(() => ({
|
const processInfo = computed(() => ({
|
||||||
taskId: props.formData?.taskId,
|
taskId: props.formData?.taskId,
|
||||||
@@ -294,12 +356,60 @@
|
|||||||
processDataId: props.formData?.processDataId,
|
processDataId: props.formData?.processDataId,
|
||||||
processTableName: props.formData?.processTableName,
|
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(() => {
|
onMounted(() => {
|
||||||
initFormData();
|
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() {
|
async function initFormData() {
|
||||||
const dataId = props.formData?.dataId;
|
const dataId = props.formData?.dataId;
|
||||||
@@ -313,7 +423,7 @@
|
|||||||
if (dataId !== props.formData?.dataId) {
|
if (dataId !== props.formData?.dataId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setMainForm(data || {});
|
await setMainForm(data || {});
|
||||||
if (dataId !== props.formData?.dataId) {
|
if (dataId !== props.formData?.dataId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -323,10 +433,68 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMainForm(record: Record<string, any>) {
|
async function setMainForm(record: Record<string, any>) {
|
||||||
Object.keys(mainForm).forEach((key) => {
|
Object.keys(mainForm).forEach((key) => {
|
||||||
mainForm[key] = record[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_id(impl_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() {
|
async function loadFeedbackList() {
|
||||||
@@ -337,7 +505,21 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const res = await fixedContactFeedbackList({ id: mainForm.id, bpmProcessId });
|
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;
|
feedbackAttachmentRefreshKey.value += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,10 +567,158 @@
|
|||||||
return false;
|
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;
|
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) {
|
if (!mainForm.id) {
|
||||||
createMessage.warning('主表数据不存在,无法新增反馈');
|
createMessage.warning('主表数据不存在,无法新增反馈');
|
||||||
return;
|
return;
|
||||||
@@ -398,7 +728,8 @@
|
|||||||
createMessage.warning('流程实例ID不能为空,无法新增反馈');
|
createMessage.warning('流程实例ID不能为空,无法新增反馈');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
feedbackModalRef.value?.open(mainForm.id, processInstanceId);
|
const deptId = await getCurrentProcessDeptId();
|
||||||
|
feedbackModalRef.value?.open(mainForm.id, processInstanceId, deptId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function openFeedbackEditModal(record: Recordable) {
|
function openFeedbackEditModal(record: Recordable) {
|
||||||
@@ -410,7 +741,7 @@
|
|||||||
createMessage.warning('反馈记录不存在,无法编辑');
|
createMessage.warning('反馈记录不存在,无法编辑');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
feedbackModalRef.value?.open(mainForm.id, processInfo.value.processInstanceId, record);
|
feedbackModalRef.value?.open(mainForm.id, processInfo.value.processInstanceId, '', record);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleFeedbackDelete(record: Recordable) {
|
async function handleFeedbackDelete(record: Recordable) {
|
||||||
|
|||||||
Reference in New Issue
Block a user