审批流程人员选择后切换tab标签保存问题
This commit is contained in:
@@ -4,39 +4,15 @@ import { SetupStoreId } from '@/enum';
|
|||||||
|
|
||||||
export const useChangeStore = defineStore(SetupStoreId.Change, () => {
|
export const useChangeStore = defineStore(SetupStoreId.Change, () => {
|
||||||
const stepsInfo = ref<Api.Change.StepInfo[]>([]);
|
const stepsInfo = ref<Api.Change.StepInfo[]>([]);
|
||||||
const flowInfo = ref<Api.Change.FlowInfo[]>([]);
|
|
||||||
// 获取选中模板信息
|
// 获取选中模板信息
|
||||||
const getStepsInfo = computed(() => stepsInfo.value);
|
const getStepsInfo = computed(() => stepsInfo.value);
|
||||||
// 获取审批链信息
|
|
||||||
const getFlowInfo = computed(() => flowInfo.value);
|
|
||||||
|
|
||||||
// 设置选中模板信息
|
// 设置选中模板信息
|
||||||
function setStepsInfo(data: Api.Change.StepInfo[]) {
|
function setStepsInfo(data: Api.Change.StepInfo[]) {
|
||||||
stepsInfo.value = data;
|
stepsInfo.value = data;
|
||||||
setFlowInfo(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置审批链信息
|
|
||||||
function setFlowInfo(data: Api.Change.StepInfo[]) {
|
|
||||||
const sortedSteps = [...data || []].sort((a, b) => a.step_order - b.step_order)
|
|
||||||
flowInfo.value = sortedSteps.map(step => {
|
|
||||||
return {
|
|
||||||
stepId: step.id,
|
|
||||||
name: step.name,
|
|
||||||
countersign: step.countersign,
|
|
||||||
selectedMember: step.members,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// 更新审批链信息
|
|
||||||
function updateFlowInfo(data: Api.Change.FlowInfo[]) {
|
|
||||||
flowInfo.value = data;
|
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
getStepsInfo,
|
getStepsInfo,
|
||||||
setStepsInfo,
|
setStepsInfo,
|
||||||
getFlowInfo,
|
|
||||||
updateFlowInfo,
|
|
||||||
flowInfo,
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -20,7 +20,7 @@ import Evaluation from "./modules/evaluation.vue";
|
|||||||
import CloseConfirm from "./modules/closeConfirm.vue";
|
import CloseConfirm from "./modules/closeConfirm.vue";
|
||||||
|
|
||||||
const changeStore = useChangeStore();
|
const changeStore = useChangeStore();
|
||||||
const { getFlowInfo } = storeToRefs(changeStore);
|
const { getStepsInfo } = storeToRefs(changeStore);
|
||||||
const themeStore = useThemeStore();
|
const themeStore = useThemeStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
@@ -150,8 +150,8 @@ const getAllFormData = () => {
|
|||||||
let pssrForm = pssrRef.value?.list;
|
let pssrForm = pssrRef.value?.list;
|
||||||
let allItems = pssrForm.flatMap((group:any) => group.items ?? []);
|
let allItems = pssrForm.flatMap((group:any) => group.items ?? []);
|
||||||
let evaluationForm = evaluationRef.value?.list;
|
let evaluationForm = evaluationRef.value?.list;
|
||||||
let flowList = getFlowInfo.value.map((item:any) => ({
|
let flowList = getStepsInfo.value.map((item:any) => ({
|
||||||
members: item.selectedMember.map((m:any) => ({
|
members: item.members.map((m:any) => ({
|
||||||
user_id: m.user_id,
|
user_id: m.user_id,
|
||||||
org_id: m.org_id,
|
org_id: m.org_id,
|
||||||
org_name: m.org_name,
|
org_name: m.org_name,
|
||||||
|
|||||||
@@ -820,7 +820,7 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
.scroll {
|
.scroll {
|
||||||
height: calc(100vh - 393px);
|
height: calc(100vh - 379px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -115,7 +115,7 @@ defineExpose({form, onRegenerate})
|
|||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.scroll {
|
.scroll {
|
||||||
height: calc(100vh - 393px);
|
height: calc(100vh - 379px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -302,7 +302,7 @@ defineExpose({list, onRegenerate})
|
|||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.scroll {
|
.scroll {
|
||||||
height: calc(100vh - 393px);
|
height: calc(100vh - 379px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -7,7 +7,7 @@ import { useChangeStore } from '@/store/modules/change';
|
|||||||
import { useAiAnalysisApi } from '@/service/api/change';
|
import { useAiAnalysisApi } from '@/service/api/change';
|
||||||
|
|
||||||
const changeStore = useChangeStore();
|
const changeStore = useChangeStore();
|
||||||
const { getStepsInfo, getFlowInfo } = storeToRefs(changeStore);
|
const { getStepsInfo } = storeToRefs(changeStore);
|
||||||
|
|
||||||
const props = defineProps([
|
const props = defineProps([
|
||||||
'type',
|
'type',
|
||||||
@@ -45,12 +45,13 @@ const regenerateTypes = ref<Record<string, boolean>>({
|
|||||||
|
|
||||||
// 存储每个步骤选中的审核人 user_id
|
// 存储每个步骤选中的审核人 user_id
|
||||||
const approvers = ref<Record<number, number[]>>({})
|
const approvers = ref<Record<number, number[]>>({})
|
||||||
|
const stepList = ref<any[]>([]);
|
||||||
const flowList = ref<any[]>([]);
|
const flowList = ref<any[]>([]);
|
||||||
// 审批链
|
// 审批链
|
||||||
const approvalFlowText = computed(() => {
|
const approvalFlowText = computed(() => {
|
||||||
if (!flowList.value || flowList.value.length === 0) return '暂无步骤'
|
if (!stepList.value || stepList.value.length === 0) return '暂无步骤'
|
||||||
// 按 step_order 排序
|
// 按 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(' → ')
|
return sorted.map(item => item.name).join(' → ')
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -66,27 +67,36 @@ const openApprovalDrawer = () => {
|
|||||||
return window.$message?.warning('请先选择变更类型、变更等级、变更时限');
|
return window.$message?.warning('请先选择变更类型、变更等级、变更时限');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flowList.value = getStepsInfo.value;
|
stepList.value = getStepsInfo.value;
|
||||||
if(Object.keys(approvers.value).length === 0){
|
if(Object.keys(approvers.value).length === 0){
|
||||||
flowList.value.forEach((item: any) => {
|
const result = Object.fromEntries(
|
||||||
if (item.members && item.members.length > 0) {
|
stepList.value.map((step: any) => [step.id, step.members.map((m: any) => m.user_id)])
|
||||||
// 优先选 is_sign=1 的成员 ,否则选第一个
|
);
|
||||||
const defaultMembers = item.members
|
approvers.value = result;
|
||||||
.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];
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
approvalDrawerShow.value = true;
|
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(() => {
|
const approvalChain = computed(() => {
|
||||||
let template = getFlowInfo.value;
|
let template = getStepsInfo.value;
|
||||||
console.log(template);
|
|
||||||
if (!template || template.length === 0) return '暂无审批步骤'
|
if (!template || template.length === 0) return '暂无审批步骤'
|
||||||
const parts = template.map((step: any) => {
|
flowList.value = transformFlowInfo(template);
|
||||||
|
const parts = flowList.value.map((step: any) => {
|
||||||
// 根据 countersign 决定显示名称
|
// 根据 countersign 决定显示名称
|
||||||
const displayName = step.name
|
const displayName = step.name
|
||||||
const members = step.selectedMember
|
const members = step.selectedMember
|
||||||
@@ -159,22 +169,16 @@ function matchApprovers(steps: any[], mapping: Record<number, number[]>) {
|
|||||||
const step = steps.find(s => s.id === Number(stepId));
|
const step = steps.find(s => s.id === Number(stepId));
|
||||||
if (step) {
|
if (step) {
|
||||||
const members = props.members.filter((m: any) => usersId.includes(m.user_id));
|
const members = props.members.filter((m: any) => usersId.includes(m.user_id));
|
||||||
if (members.length > 0) {
|
step.members = members || []; // 更新 step 的 members 属性
|
||||||
result.push({
|
result.push(step);
|
||||||
countersign: step.countersign,
|
|
||||||
stepId: step.id,
|
|
||||||
name: step.name,
|
|
||||||
selectedMember: members
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
// 完成设置
|
// 完成设置
|
||||||
const finishApprover = async () => {
|
const finishApprover = async () => {
|
||||||
const matched = matchApprovers(flowList.value, approvers.value);
|
const matched = matchApprovers(stepList.value, approvers.value);
|
||||||
changeStore.updateFlowInfo(matched);
|
changeStore.setStepsInfo(matched);
|
||||||
window.$message?.success("审批流程设置完成");
|
window.$message?.success("审批流程设置完成");
|
||||||
approvalDrawerShow.value = false;
|
approvalDrawerShow.value = false;
|
||||||
}
|
}
|
||||||
@@ -185,9 +189,9 @@ defineExpose({clearApprovers, setRegenerateLoading})
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<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">
|
<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':''" />
|
<Icon icon="tdesign:refresh" class="size-14px mr-1" :class="regenerateLoading?'animate-spin':''" />
|
||||||
<template v-if="regenerateLoading">
|
<template v-if="regenerateLoading">
|
||||||
<span>生成中...</span>
|
<span>生成中...</span>
|
||||||
@@ -200,7 +204,7 @@ defineExpose({clearApprovers, setRegenerateLoading})
|
|||||||
<span v-if="type==='close'">{{regenerateTypes[type]?'重新生成变更关闭确认表':'生成变更关闭确认表'}}</span>
|
<span v-if="type==='close'">{{regenerateTypes[type]?'重新生成变更关闭确认表':'生成变更关闭确认表'}}</span>
|
||||||
</template>
|
</template>
|
||||||
</NButton>
|
</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-if="downloadLoading" icon="tdesign:refresh" class="size-14px mr-1 animate-spin" />
|
||||||
<Icon v-else icon="material-symbols:download" class="size-16px" />
|
<Icon v-else icon="material-symbols:download" class="size-16px" />
|
||||||
<span v-if="type==='form'">下载变更申请表</span>
|
<span v-if="type==='form'">下载变更申请表</span>
|
||||||
@@ -210,7 +214,7 @@ defineExpose({clearApprovers, setRegenerateLoading})
|
|||||||
<span v-if="type==='evaluation'">下载验收评价</span>
|
<span v-if="type==='evaluation'">下载验收评价</span>
|
||||||
<span v-if="type==='close'">下载变更关闭确认表</span>
|
<span v-if="type==='close'">下载变更关闭确认表</span>
|
||||||
</NButton>
|
</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 ? '已确认完毕' : '本标签内容确认完毕' }}
|
<Icon icon="ix:success" class="size-16px mr-1" /> {{ confirmed ? '已确认完毕' : '本标签内容确认完毕' }}
|
||||||
</NButton>
|
</NButton>
|
||||||
</div>
|
</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">
|
<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" />
|
<Icon icon="lucide:users" class="size-14px" />
|
||||||
<span class="min-w-0 truncate">
|
<span class="min-w-0 truncate">
|
||||||
部门审核:{{ approvalChain }}
|
审核:{{ approvalChain }}
|
||||||
</span>
|
</span>
|
||||||
<NButton v-if="getStepsInfo && getStepsInfo.length" ghost size="small" type="primary" :disabled="btnDisabled" @click="openApprovalDrawer">
|
<NButton v-if="getStepsInfo && getStepsInfo.length" ghost size="small" type="primary" :disabled="btnDisabled" @click="openApprovalDrawer">
|
||||||
<Icon icon="octicon:sliders-24" class="size-14px" />
|
<Icon icon="octicon:sliders-24" class="size-14px" />
|
||||||
@@ -242,14 +246,14 @@ defineExpose({clearApprovers, setRegenerateLoading})
|
|||||||
</template>
|
</template>
|
||||||
<div class="h-full space-y-4 overflow-y-auto">
|
<div class="h-full space-y-4 overflow-y-auto">
|
||||||
<p class="text-xs leading-relaxed text-slate-400">审批链:{{ approvalFlowText }}。专业会签人由申请表「涉及专业」勾选自动增减,可在此调整人选;重要变更自动追加安全审查与分管领导终批。</p>
|
<p class="text-xs leading-relaxed text-slate-400">审批链:{{ approvalFlowText }}。专业会签人由申请表「涉及专业」勾选自动增减,可在此调整人选;重要变更自动追加安全审查与分管领导终批。</p>
|
||||||
<div class="rounded-lg border p-3" v-for="(item,index) in flowList" :key="item.id">
|
<div class="rounded-lg border p-3" v-for="(item,index) in stepList" :key="item.id">
|
||||||
<div class="mb-2 flex items-center gap-2 text-sm font-semibold text-slate-700">
|
<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 ? '(专业会签)' : ''}}
|
<NTag type="info" size="small">{{Number(index)+1}}</NTag> {{item.name}} {{item.countersign ? '(专业会签)' : ''}}
|
||||||
</div>
|
</div>
|
||||||
<NSelect :value="approvers[item.id]" multiple :options="props.members" label-field="full_name" value-field="user_id"
|
<NSelect :value="approvers[item.id]" multiple :options="props.members" label-field="full_name" value-field="user_id"
|
||||||
@update:value="(v) => updateApprover(item.id, v)" />
|
@update:value="(v) => updateApprover(item.id, v)" />
|
||||||
</div>
|
</div>
|
||||||
<NButton v-if="flowList.length" type="primary" class="w-full" @click="finishApprover">完成设置</NButton>
|
<NButton v-if="stepList.length" type="primary" class="w-full" @click="finishApprover">完成设置</NButton>
|
||||||
</div>
|
</div>
|
||||||
</NDrawerContent>
|
</NDrawerContent>
|
||||||
</NDrawer>
|
</NDrawer>
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ defineExpose({list, onRegenerate})
|
|||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.scroll {
|
.scroll {
|
||||||
height: calc(100vh - 393px);
|
height: calc(100vh - 379px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -479,7 +479,7 @@ onMounted(() => {
|
|||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.scroll {
|
.scroll {
|
||||||
height: calc(100vh - 393px);
|
height: calc(100vh - 379px);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user