@@ -7,7 +7,7 @@ import { useChangeStore } from '@/store/modules/change';
import { useAiAnalysisApi } from '@/service/api/change' ;
const changeStore = useChangeStore ( ) ;
const { getStepsInfo , getFlowInfo } = storeToRefs ( changeStore ) ;
const { getStepsInfo } = storeToRefs ( changeStore ) ;
const props = defineProps ( [
'type' ,
@@ -45,12 +45,13 @@ const regenerateTypes = ref<Record<string, boolean>>({
// 存储每个步骤选中的审核人 user_id
const approvers = ref < Record < number , number [ ] > > ( { } )
const stepList = ref < any [ ] > ( [ ] ) ;
const flowList = ref < any [ ] > ( [ ] ) ;
// 审批链
const approvalFlowText = computed ( ( ) => {
if ( ! flowList . value || flowList . value . length === 0 ) return '暂无步骤'
if ( ! stepList . value || stepList . value . length === 0 ) return '暂无步骤'
// 按 step_order 排序
const sorted = [ ... flowList . value ] . sort ( ( a , b ) => a . step _order - b . step _order )
const sorted = [ ... stepList . value ] . sort ( ( a , b ) => a . step _order - b . step _order )
return sorted . map ( item => item . name ) . join ( ' → ' )
} )
@@ -66,27 +67,36 @@ const openApprovalDrawer = () => {
return window . $message ? . warning ( '请先选择变更类型、变更等级、变更时限' ) ;
}
}
flowList . value = getStepsInfo . value ;
stepList . value = getStepsInfo . value ;
if ( Object . keys ( approvers . value ) . length === 0 ) {
flowList . value . forEach ( ( item : any ) => {
if ( item . members && item . members . length > 0 ) {
// 优先选 is_sign=1 的成员 ,否则选第一个
const defaultMembers = item . members
. filter ( ( m : any ) => m ? . is _sign === 1 )
. map ( ( m : any ) => m . user _id ) ;
approvers . value [ item . id ] = defaultMembers . length > 0 ? defaultMembers : [ item . members [ 0 ] . user _id ] ;
}
} )
const result = Object . fromEntries (
stepList . value . map ( ( step : any ) => [ step . id , step . members . map ( ( m : any ) => m . user _id ) ] )
) ;
approvers . value = result ;
}
approvalDrawerShow . value = true ;
}
// 数据转换
const transformFlowInfo = ( steps : any [ ] ) => {
const sortedSteps = [ ... steps || [ ] ] . sort ( ( a , b ) => a . step _order - b . step _order )
const result = sortedSteps . map ( step => {
return {
stepId : step . id ,
name : step . name ,
countersign : step . countersign ,
selectedMember : step . members ,
} ;
} ) ;
return result ;
}
// 审批链
const approvalChain = computed ( ( ) => {
let template = getFlowInfo . value ;
console . log ( template ) ;
let template = getStepsInfo . value ;
if ( ! template || template . length === 0 ) return '暂无审批步骤'
const parts = template . map ( ( step : any ) => {
flowList . value = transformFlowInfo ( template ) ;
const parts = flowList . value . map ( ( step : any ) => {
// 根据 countersign 决定显示名称
const displayName = step . name
const members = step . selectedMember
@@ -158,23 +168,17 @@ function matchApprovers(steps: any[], mapping: Record<number, number[]>) {
for ( const [ stepId , usersId ] of Object . entries ( mapping ) ) {
const step = steps . find ( s => s . id === Number ( stepId ) ) ;
if ( step ) {
const members = props . members . filter ( ( m : any ) => usersId . includes ( m . user _id ) ) ;
if ( members . length > 0 ) {
result . push ( {
countersign : step . countersign ,
stepId : step . id ,
name : step . name ,
selectedMember : members
} ) ;
}
const members = props . members . filter ( ( m : any ) => usersId . includes ( m . user _id ) ) ;
step . members = members || [ ] ; // 更新 step 的 members 属性
result . push ( step ) ;
}
}
return result ;
}
// 完成设置
const finishApprover = async ( ) => {
const matched = matchApprovers ( flowList . value , approvers . value ) ;
changeStore . updateFlowInfo ( matched ) ;
const matched = matchApprovers ( stepList . value , approvers . value ) ;
changeStore . setStepsInfo ( matched ) ;
window . $message ? . success ( "审批流程设置完成" ) ;
approvalDrawerShow . value = false ;
}
@@ -185,9 +189,9 @@ defineExpose({clearApprovers, setRegenerateLoading})
< template >
< div >
< div class = "flex flex-wrap items-center justify-between gap-2 border-t p-4" >
< div class = "flex flex-wrap items-center justify-between gap-2 border-t py-3 px -4" >
< div class = "flex flex-wrap gap-2" >
< NButton v-if = "isAiOpen && type!=='risk'" ghost type="warning" :disabled="btnDisabled || regenerateLoading" @click="regenerate" >
< NButton v-if = "isAiOpen && type!=='risk'" size="small" ghost type="warning" :disabled="btnDisabled || regenerateLoading" @click="regenerate" >
< Icon icon = "tdesign:refresh" class = "size-14px mr-1" :class = "regenerateLoading?'animate-spin':''" / >
< template v-if = "regenerateLoading" >
< span > 生成中 ... < / span >
@@ -200,7 +204,7 @@ defineExpose({clearApprovers, setRegenerateLoading})
< span v-if = "type==='close'" > {{ regenerateTypes [ type ] ? ' 重新生成变更关闭确认表 ' : ' 生成变更关闭确认表 ' }} < / span >
< / template >
< / NButton >
< NButton ghost type = "success" : disabled = "btnDisabled || downloadLoading" @click ="download" >
< NButton size = "small" ghost type = "success" : disabled = "btnDisabled || downloadLoading" @click ="download" >
< Icon v-if = "downloadLoading" icon="tdesign:refresh" class="size-14px mr-1 animate-spin" / >
< Icon v-else icon = "material-symbols:download" class = "size-16px" / >
< span v-if = "type==='form'" > 下载变更申请表 < / span >
@@ -210,7 +214,7 @@ defineExpose({clearApprovers, setRegenerateLoading})
< span v-if = "type==='evaluation'" > 下载验收评价 < / span >
< span v-if = "type==='close'" > 下载变更关闭确认表 < / span >
< / NButton >
< NButton v-if = "isAiOpen" ghost :type="confirmed ? 'success' : 'primary'" :disabled="btnDisabled" @click="confirmTab" >
< NButton v-if = "isAiOpen" size="small" ghost :type="confirmed ? 'success' : 'primary'" :disabled="btnDisabled" @click="confirmTab" >
< Icon icon = "ix:success" class = "size-16px mr-1" / > { { confirmed ? '已确认完毕' : '本标签内容确认完毕' } }
< / NButton >
< / div >
@@ -219,7 +223,7 @@ defineExpose({clearApprovers, setRegenerateLoading})
< div class = "flex min-w-0 flex-1 flex-wrap items-center gap-x-2 gap-y-1 text-xs text-slate-500" >
< Icon icon = "lucide:users" class = "size-14px" / >
< span class = "min-w-0 truncate" >
部门 审核: { { approvalChain } }
审核 : { { approvalChain } }
< / span >
< NButton v-if = "getStepsInfo && getStepsInfo.length" ghost size="small" type="primary" :disabled="btnDisabled" @click="openApprovalDrawer" >
< Icon icon = "octicon:sliders-24" class = "size-14px" / >
@@ -242,14 +246,14 @@ defineExpose({clearApprovers, setRegenerateLoading})
< / template >
< div class = "h-full space-y-4 overflow-y-auto" >
< p class = "text-xs leading-relaxed text-slate-400" > 审批链 : { { approvalFlowText } } 。 专业会签人由申请表 「 涉及专业 」 勾选自动增减 , 可在此调整人选 ; 重要变更自动追加安全审查与分管领导终批 。 < / p >
< div class = "rounded-lg border p-3" v-for = "(item,index) in flow List" :key="item.id" >
< div class = "rounded-lg border p-3" v-for = "(item,index) in step List" :key="item.id" >
< div class = "mb-2 flex items-center gap-2 text-sm font-semibold text-slate-700" >
< NTag type = "info" size = "small" > { { Number ( index ) + 1 } } < / NTag > { { item . name } } { { item . countersign ? '(专业会签)' : '' } }
< / div >
< NSelect :value = "approvers[item.id]" multiple :options = "props.members" label -field = " full_name " value -field = " user_id "
@ update : value = "(v) => updateApprover(item.id, v)" / >
< / div >
< NButton v-if = "flow List.length" type="primary" class="w-full" @click="finishApprover" > 完成设置 < / NButton >
< NButton v-if = "step List.length" type="primary" class="w-full" @click="finishApprover" > 完成设置 < / NButton >
< / div >
< / NDrawerContent >
< / NDrawer >