发起变更,底部封装通用组件

This commit is contained in:
2026-09-04 11:24:27 +08:00
parent cb918ea562
commit 7d05236399
18 changed files with 2260 additions and 1608 deletions
@@ -0,0 +1,77 @@
<!-- 审批流程设置 -->
<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue';
import { setApproverApi } from '@/service/api/system';
const props = defineProps(['currentId','currentTemplate'])
const emit = defineEmits(['finish'])
const loading = ref<boolean>(false);
// 存储每个步骤选中的审核人 user_id
const approvers = reactive<Record<number, number>>({})
// 审批链
const approvalFlowText = computed(() => {
if (!list.value || list.value.length === 0) return '暂无步骤'
// 按 step_order 排序
const sorted = [...list.value].sort((a, b) => a.step_order - b.step_order)
return sorted.map(item => item.name).join(' → ')
})
const list = ref<any[]>(props.currentTemplate?.steps || []);
// 更新选中值
const updateApprover = (stepId: number, userId: number) => {
approvers[stepId] = userId
}
// 匹配审批人
function matchApprovers(steps: any[], mapping: Record<number, number>) {
const result = [];
for (const [stepId, userId] of Object.entries(mapping)) {
const step = steps.find(s => s.id === Number(stepId));
if (step) {
const member = step.members.filter((m: any) => m.user_id === userId);
if (member.length > 0) {
result.push({
step_id: step.id,
member: member
});
}
}
}
return result;
}
// 完成设置
const finishApprover = async () => {
const matched = matchApprovers(list.value, approvers);
loading.value = true;
const {error} = await setApproverApi(props.currentId,{steps: matched})
if(!error){
window.$message?.success("审批流程设置已保存");
emit('finish', matched, false)
}
loading.value = false;
}
onMounted(() => {
list.value.forEach((item: any) => {
if (item.members && item.members.length > 0) {
// 优先选 is_sign=1 的成员 ,否则选第一个
const defaultMember = item.members.find((m: any) => m.is_sign === 1) || item.members[0]
approvers[item.id] = defaultMember.user_id
}
})
})
</script>
<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 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]" :options="item.members" label-field="user_name" value-field="user_id"
@update:value="(v) => updateApprover(item.id, v)" />
</div>
<NButton type="primary" class="w-full" :loading="loading" @click="finishApprover">完成设置</NButton>
</div>
</template>