@@ -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_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 ( ) {
@@ -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 ) {