diff --git a/src/service/api/system.ts b/src/service/api/system.ts
index e700e2a..7022ef8 100644
--- a/src/service/api/system.ts
+++ b/src/service/api/system.ts
@@ -30,3 +30,27 @@ export function deleteSystemConfigApi(id:number) {
method: 'delete',
});
}
+
+// 审批模板列表
+export function templateListApi() {
+ return request({
+ url: '/api/approval-templates',
+ method: 'get',
+ });
+}
+// 审批用户列表
+export function peopleListApi() {
+ return request({
+ url: '/api/approval-flow/users',
+ method: 'get',
+ });
+}
+
+// 批量修改ai配置项和变更编号规则
+export function updateConfigApi(data:{items:any[]}) {
+ return request({
+ url: '/api/system-config/batch',
+ method: 'put',
+ data,
+ });
+}
diff --git a/src/views/systemManage/role/index.vue b/src/views/systemManage/role/index.vue
index 7947910..7724c93 100644
--- a/src/views/systemManage/role/index.vue
+++ b/src/views/systemManage/role/index.vue
@@ -29,11 +29,6 @@ const rules = ref({
})
const roleModal = ref(false);
const permissionModal = ref(false);
-const pagination = ref<{ page: number, pageSize: number, pageCount: number }>({
- page: 1,
- pageSize: 20,
- pageCount: 0,
-})
const columns = ref([
{
title: '序号',
@@ -41,7 +36,7 @@ const columns = ref([
width: 5,
align: 'center',
render: (_row: any, index: number) => {
- return h('span', {}, { default: () => (pagination.value.page - 1) * pagination.value.pageSize + index + 1 })
+ return h('span', {}, { default: () => index + 1 })
}
},
{
@@ -230,7 +225,7 @@ onMounted(() => {
:single-line="false"
:columns="columns"
:data="list"
- :pagination="pagination"
+ :pagination="false"
max-height="calc(100vh - 290px)"
/>
diff --git a/src/views/systemManage/setting/index.vue b/src/views/systemManage/setting/index.vue
index a434366..98e73ac 100644
--- a/src/views/systemManage/setting/index.vue
+++ b/src/views/systemManage/setting/index.vue
@@ -4,26 +4,21 @@ import { useAppStore } from '@/store/modules/app';
import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme';
import { getColorWithOpacity, tagTextColor, tagBgColor, tagBorderColor } from '@/utils/common';
-import { systemConfigApi, addSystemConfigApi, editSystemConfigApi, deleteSystemConfigApi } from '@/service/api/system';
+import { systemConfigApi, addSystemConfigApi, editSystemConfigApi, deleteSystemConfigApi, updateConfigApi } from '@/service/api/system';
const appStore = useAppStore();
const themeStore = useThemeStore();
const gap = computed(() => (appStore.isMobile ? 0 : 16));
-// AI 辅助功能配置
-const aiEnabled = ref(true);
-const aiConfig = ref<{address:string, mode:number|null, key:string,timeout:null|number}>({
- address:'',
- mode:null,
- key:'',
- timeout:null,
-})
-const aiTested = ref("none");
+// *********************AI 辅助功能配置*********************//
+const aiConfig = ref([])
+const switchLoading = ref(false);
const modeOptions = ref<{label:string, value:number}[]>([
{label:'kimi-k2(企业私有化部署)',value:1}
])
const testing = ref(false);
const showLog = ref(false);
+
const AI_LOGS = [
{ scene: "AI-01 变更识别", user: "张工艺", change: "MOC-2026-R01-0041", time: "08-24 09:12", cost: "1.8s", adopted: "修改后采纳" },
{ scene: "AI-03 风险预分析", user: "张工艺", change: "MOC-2026-R01-0041", time: "08-24 09:15", cost: "2.4s", adopted: "采纳" },
@@ -32,6 +27,34 @@ const AI_LOGS = [
{ scene: "AI-09 关闭辅助判定", user: "系统管理员", change: "MOC-2026-R01-0035", time: "08-23 15:02", cost: "1.5s", adopted: "采纳" },
];
+// AI 辅助功能切换
+const toggle = async (v: boolean, item:any) => {
+ switchLoading.value = true;
+ const {error} = await updateConfigApi({items:[{
+ id:item.id,
+ label:item.label,
+ remark:item.remark,
+ value:v ? '1' : '0'
+ }]});
+ if(!error){
+ item.value = v ? '1' : '0';
+ window.$message?.success(v ? "AI 辅助功能已启用" : "AI 辅助功能已关闭");
+ }
+ switchLoading.value = false;
+}
+// 测试连接
+const testConn = () => {
+ testing.value = true;
+ setTimeout(() => {
+ testing.value = false;
+ window.$message?.success(`连接测试通过:${aiConfig.value.mode} 响应正常(耗时 0.8s)`);
+ }, 900);
+}
+// 保存ai配置
+const saveAiCfg = () => {
+ window.$message?.success("AI 接口配置已保存(配置变更留痕,立即生效)");
+}
+
// *********************变更类型*********************//
const typeRef = ref(null);
@@ -212,27 +235,24 @@ const levelSave = async (e:MouseEvent) => {
// *********************变更编号规则*********************//
+const ruleLoading = ref(false);
const previewNumber = computed(() => {
+ let prefix = ruleConfig.value.find((item:any) => item.item_key === 'prefix')?.value || '';
let year = '';
+ let code = ruleConfig.value.find((item:any) => item.item_key === 'unit_code')?.value || '';
let digit = '';
const currentYear = new Date().getFullYear();
- if (ruleInfo.value.year === 'yyyy') {
+ if (ruleConfig.value.find((item:any) => item.item_key === 'year_format')?.value === 'yyyy') {
year = currentYear.toString();
- } else if (ruleInfo.value.year === 'yy') {
+ } else if (ruleConfig.value.find((item:any) => item.item_key === 'year_format')?.value === 'yy') {
year = currentYear.toString().substring(2);
}
- if (ruleInfo.value.digit) {
- digit = '0'.repeat(ruleInfo.value.digit - 1) + '1';
+ if (ruleConfig.value.find((item:any) => item.item_key === 'seq_length')?.value) {
+ digit = '0'.repeat(ruleConfig.value.find((item:any) => item.item_key === 'seq_length')?.value - 1) + '1';
}
- return ruleInfo.value.prefix+'-' + year + '-' + ruleInfo.value.code + '-' + digit;
+ return prefix+'-' + year + '-' + code + '-' + digit;
});
-const ruleInfo = ref<{prefix:string, year:null|string, code:string|null, digit:number|null, rule:string|null}>({
- prefix:'',
- year:null,
- code: null,
- digit: null,
- rule: null,
-})
+const ruleConfig = ref([])
const yearOptions = ref<{label:string, value:string}[]>([
{label:'四位年份(yyyy)',value:'yyyy'},
{label:'两位年份(yy)',value:'yy'},
@@ -247,7 +267,21 @@ const ruleOptions = ref<{label:string, value:string}[]>([
{label:'连续不重置',value:'CONTINUE'},
])
-// ---------- 风险矩阵设置(按分析方法) ----------
+// 保存编号规则
+const saveRule = async () => {
+ if(ruleConfig.value.find((item:any) => item.item_key === 'prefix')?.value===''){
+ return window.$message?.warning(`请输入${ruleConfig.value.find((item:any) => item.item_key === 'prefix')?.label}`);
+ }
+ ruleLoading.value = true;
+ const {error} = await updateConfigApi({items:ruleConfig.value});
+ if(!error){
+ window.$message?.success("保存成功");
+ }
+ ruleLoading.value = false;
+}
+
+// *************** 风险矩阵设置(按分析方法) ***************//
+
const dimensionModal = ref(false);
const dimensionLoading = ref(false);
const dimForm = ref({ s: [], l: [] });
@@ -299,22 +333,6 @@ const cellLevel = (s:number, l:number) => {
const sc = cellScore(s, l);
return curMatrix.value.levels.find((lv:{min:number,max:number}) => sc >= lv.min && sc <= lv.max);
}
-// AI 辅助功能切换
-const toggle = (v: boolean) => {
- window.$message?.success(v ? "AI 辅助功能已启用" : "AI 辅助功能已关闭");
- aiEnabled.value = v;
-}
-const testConn = () => {
- testing.value = true;
- setTimeout(() => {
- testing.value = false;
- aiTested.value = "ok";
- window.$message?.success(`连接测试通过:${aiConfig.value.mode} 响应正常(耗时 0.8s)`);
- }, 900);
-}
-const saveAiCfg = () => {
- window.$message?.success("AI 接口配置已保存(配置变更留痕,立即生效)");
-}
const dimensionSave = () => {
dimensionLoading.value = true;
setTimeout(() => {
@@ -340,17 +358,11 @@ const getConfig = async () => {
// 解析 AI 辅助功能配置
const aiAssistGroup = data.find((group:{group_key:string}) => group.group_key === 'ai_assist');
if (aiAssistGroup) {
- const items = aiAssistGroup.items;
- items.forEach((item:any) => {
- switch (item.item_key) {
- case 'enabled': aiEnabled.value = item.value === '1'; break;
- case 'api_url': aiConfig.value.address = item.value; break;
- case 'model': aiConfig.value.mode = item.value; break;
- case 'api_key': aiConfig.value.key = item.value; break;
- case 'timeout_seconds': aiConfig.value.timeout = Number(item.value); break;
- default: break;
- }
- });
+ aiConfig.value = aiAssistGroup.items;
+ const target = aiConfig.value.find((item:any) => item.item_key === 'timeout_seconds');
+ if (target) {
+ target.value = Number(target.value);
+ }
}
// 解析 变更类型设置
const changeTypeGroup = data.find((group:{group_key:string}) => group.group_key === 'change_type');
@@ -365,17 +377,11 @@ const getConfig = async () => {
// 解析 变更编号规则
const changeCodeGroup = data.find((group:{group_key:string}) => group.group_key === 'change_no_rule');
if (changeCodeGroup) {
- const items = changeCodeGroup.items;
- items.forEach((item:any) => {
- switch (item.item_key) {
- case 'prefix': ruleInfo.value.prefix = item.value; break;
- case 'year_format': ruleInfo.value.year = item.value; break;
- case 'unit_code': ruleInfo.value.code = item.value; break;
- case 'seq_length': ruleInfo.value.digit = Number(item.value); break;
- case 'seq_reset': ruleInfo.value.rule = item.value; break;
- default: break;
- }
- });
+ ruleConfig.value = changeCodeGroup.items;
+ const target = ruleConfig.value.find((item:any) => item.item_key === 'seq_length');
+ if (target) {
+ target.value = Number(target.value);
+ }
}
}
}
@@ -405,59 +411,62 @@ onMounted(() => {
AI 辅助功能
-
-
-
启用 AI 辅助
-
+
+
+
+
{{item.label}}
+
toggle(v,item)" />
+
+
+ {{item.remark}}
+
-
- 开启后,变更申请界面显示「变更识别」按钮:AI 自动完成变更前后比较、生成变更申请表(均支持手动修改);关闭后全部内容手动填写。
+
+
+
+ 当前状态:{{ item.value==='1' ? "已启用 —— 变更申请界面提供 AI 变更识别与申请表生成" : "已关闭 —— 变更申请界面为纯手动模式" }}
-
-
-
-
- 当前状态:{{ aiEnabled ? "已启用 —— 变更申请界面提供 AI 变更识别与申请表生成" : "已关闭 —— 变更申请界面为纯手动模式" }}
-
+
AI 接口配置
- 连接正常
-
-
接口地址
-
-
-
模型
-
-
-
API Key
-
-
@@ -610,40 +619,42 @@ onMounted(() => {
-
-
编号前缀
-
-
-
年份格式
-
-
-
装置代码段
-
-
-
流水号位数
-
-
-
流水重置规则
-
+
编号示例预览:
{{previewNumber}}
- 保存规则
+ 保存规则
保存草稿即预占编号,提交后正式生效;规则修改不影响历史单据编号。
diff --git a/src/views/systemManage/template/index.vue b/src/views/systemManage/template/index.vue
index 30bf47d..9b2a39c 100644
--- a/src/views/systemManage/template/index.vue
+++ b/src/views/systemManage/template/index.vue
@@ -3,10 +3,10 @@ import { ref, computed, h, onMounted } from 'vue';
import { useAppStore } from '@/store/modules/app';
import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme';
-import { useRouter } from 'vue-router';
import { NButton, NPopconfirm, NTag } from 'naive-ui';
+import { tagTextColor, tagBgColor, tagBorderColor } from '@/utils/common';
+import { templateListApi, systemConfigApi, peopleListApi } from '@/service/api/system';
-const router = useRouter();
const appStore = useAppStore();
const themeStore = useThemeStore();
const gap = computed(() => (appStore.isMobile ? 0 : 16));
@@ -16,71 +16,47 @@ const btnLoading = ref
(false);
const currentType = ref('add');
const readonly = computed(() => currentType.value === "view");
const formRef = ref(null);
-const currentTemplate = ref<{ id: number, category: string | null, level: string | null, timeLimit: string | null, steps: any[] }>({
+const currentTemplate = ref<{ id: number, category: string | null, level: string | null, duration: number | null, steps: any[] }>({
id: 0,
category: null,
level: null,
- timeLimit: null,
+ duration: null,
steps: [],
});
const rules = ref({
category: { required: true, message: '变更类别不能为空', trigger: ['blur'] },
level: { required: true, message: '变更等级不能为空', trigger: ['blur'] },
- timeLimit: { required: true, message: '变更时效不能为空', trigger: ['blur'] },
+ duration: { required: true, message: '变更时效不能为空', trigger: ['blur'] },
step: { required: true, message: '审批步骤不能为空', trigger: ['blur'] }
})
const templateModal = ref(false);
-const categoryOptions = ref([
- {
- label: '工艺',
- value: '工艺'
- },
- {
- label: '设备',
- value: '设备'
- },
- {
- label: '管理',
- value: '管理'
+const categoryOptions = ref<{ label: string, value: string, color: string }[]>([])
+const levelOptions = ref<{ label: string, value: string, color: string }[]>([])
+const durationOptions = ref<{ label: string, value: number }[]>([
+ { label: '永久', value: 1 },
+ { label: '临时', value: 2 },
+])
+// 专业
+const SPECIALTIES = [
+ { label: '生产', value: '生产' },
+ { label: '技术', value: '技术' },
+ { label: '仪表', value: '仪表' },
+ { label: '电气', value: '电气' },
+ { label: '设备', value: '设备' },
+ { label: '安全', value: '安全' },
+ { label: '质量', value: '质量' }
+];
+// 审批用户列表
+const peopleList = ref<{label: string, value: number,children: any[]}[]>([]);
+
+// 根据value匹配label和color
+const getLabel = (type: string, value: number) => {
+ if(type=='level'){
+ return levelOptions.value.find((item: { label: string, value: string, color: string }) => item.value === value.toString()) || null;
}
-])
-
-const levelOptions = ref([
- {
- label: '一般',
- value: '一般'
- },
- {
- label: '重要',
- value: '重要'
- },
-])
-
-const timeLimitOptions = ref([
- {
- label: '永久',
- value: '永久'
- },
- {
- label: '临时',
- value: '临时'
- },
-])
-const SPECIALTIES = ref<{ label: string, value: string }[]>([
- { label: '工艺', value: 'process' },
- { label: '设备', value: 'equipment' },
- { label: '仪表', value: 'instrument' },
- { label: '电气', value: 'electrical' },
- { label: '安全', value: 'safety' },
- { label: '质量', value: 'quality' }
-]);
-
-const pagination = ref<{ page: number, pageSize: number, pageCount: number }>({
- page: 1,
- pageSize: 20,
- pageCount: 0,
-})
+ return categoryOptions.value.find((item: { label: string, value: string, color: string }) => item.value === value.toString()) || null;
+}
const columns = ref([
{
title: '序号',
@@ -88,7 +64,7 @@ const columns = ref([
width: 6,
align: 'center',
render: (row: any, index: number) => {
- return h('span', {}, { default: () => (pagination.value.page - 1) * pagination.value.pageSize + index + 1 })
+ return h('span', {}, { default: () => index + 1 })
}
},
{
@@ -96,11 +72,15 @@ const columns = ref([
key: 'category',
width: 8,
align: 'center',
- render: (row: any, index: number) => {
+ render: (row: any) => {
return h(NTag, {
size: 'small',
- type: 'default'
- }, { default: () => `${row.category}` })
+ color: {
+ 'color': tagBgColor(getLabel('category', row.category)?.color || ''),
+ 'textColor': tagTextColor(getLabel('category', row.category)?.color || ''),
+ 'borderColor': tagBorderColor(getLabel('category', row.category)?.color || ''),
+ },
+ }, { default: () => `${getLabel('category', row.category)?.label || ''}` })
}
},
{
@@ -108,23 +88,27 @@ const columns = ref([
key: 'level',
width: 8,
align: 'center',
- render: (row: any, index: number) => {
+ render: (row: any) => {
return h(NTag, {
size: 'small',
- type: `${row.level==='重要'?'error':'default'}`
- }, { default: () => `${row.level}` })
+ color: {
+ 'color': tagBgColor(getLabel('level', row.level)?.color || ''),
+ 'textColor': tagTextColor(getLabel('level', row.level)?.color || ''),
+ 'borderColor': tagBorderColor(getLabel('level', row.level)?.color || ''),
+ },
+ }, { default: () => `${getLabel('level', row.level)?.label || ''}` })
}
},
{
title: '变更时效',
- key: 'timeLimit',
+ key: 'duration',
width: 8,
align: 'center',
- render: (row: any, index: number) => {
+ render: (row: any) => {
return h(NTag, {
size: 'small',
- type: `${row.timeLimit==='临时'?'warning':'info'}`
- }, { default: () => `${row.timeLimit}` })
+ type: `${row.duration===2?'warning':'info'}`
+ }, { default: () => `${row.duration===2?'临时':'永久'}` })
}
},
{
@@ -194,46 +178,8 @@ const columns = ref([
}
},
])
-const list = ref<{ id: number, category: string, level: string, timeLimit: string, steps: any[] }[]>([])
+const list = ref<{ id: number, category: string, level: string, duration: number | null, steps: any[] }[]>([])
-// 获取列表
-const getList = async () => {
- loading.value = true;
- setTimeout(() => {
- loading.value = false;
- list.value = [
- {id:1,category:'工艺',level:'重要',timeLimit:'临时',steps: [
- {
- id:101,
- name:'部门审核',
- countersign: false,
- members: [{person:'测试人员01',specialty:'',countersign:false}]
- },
- {
- id:102,
- name:'专业审批',
- countersign: false,
- members: [{person:'测试人员02',specialty:'',countersign:false}]
- },
- {id: 103,
- name: "部门负责人批准",
- countersign: false,
- members: [ {person:'测试人员03',specialty:'',countersign:false}]
- }
- ]},
- {id:2,category:'设备',level:'一般',timeLimit:'临时',steps:[
-
- ]},
- {id:3,category:'管理',level:'重要',timeLimit:'永久',steps:[
-
- ]},
- {id:4,category:'工艺',level:'重要',timeLimit:'临时',steps:[
-
- ]},
-
- ]
- }, 1000)
-}
// 打开添加模板弹框
const addTemplate = () => {
@@ -242,7 +188,7 @@ const addTemplate = () => {
id: 0,
category: null,
level: null,
- timeLimit: null,
+ duration: null,
steps: [],
};
templateModal.value = true;
@@ -252,26 +198,26 @@ const handleView = (row: any) => {
currentType.value = 'view';
currentTemplate.value = {
id: row.id,
- category: row.category,
- level: row.level,
- timeLimit: row.timeLimit,
+ category: row.category.toString(),
+ level: row.level.toString(),
+ duration: row.duration,
steps: row.steps,
};
templateModal.value = true;
}
-// 编辑角色
+// 编辑模板
const handleEdit = (row: any) => {
currentType.value = 'edit';
currentTemplate.value = {
id: row.id,
- category: row.category,
- level: row.level,
- timeLimit: row.timeLimit,
+ category: row.category.toString(),
+ level: row.level.toString(),
+ duration: row.duration,
steps: row.steps,
};
templateModal.value = true;
}
-// 删除角色
+// 删除模板
const handleDelete = (row: any) => {
loading.value = true;
setTimeout(() => {
@@ -280,8 +226,8 @@ const handleDelete = (row: any) => {
window.$message?.success('删除成功')
}, 1000)
}
-// 保存角色
-const saveRole = async (e: MouseEvent) => {
+// 保存模板
+const saveTemplate = async (e: MouseEvent) => {
e.preventDefault()
formRef.value?.validate((errors: any) => {
if (!errors) {
@@ -293,7 +239,7 @@ const saveRole = async (e: MouseEvent) => {
id:list.value.length+1,
category:currentTemplate.value?.category as string,
level:currentTemplate.value?.level as string,
- timeLimit:currentTemplate.value?.timeLimit as string,
+ duration:currentTemplate.value?.duration as number,
steps:currentTemplate.value?.steps as any[]
})
}
@@ -303,7 +249,7 @@ const saveRole = async (e: MouseEvent) => {
if (target) {
target.category = currentTemplate.value?.category as string;
target.level = currentTemplate.value?.level as string;
- target.timeLimit = currentTemplate.value?.timeLimit as string;
+ target.duration = currentTemplate.value?.duration as number;
target.steps = currentTemplate.value?.steps as any[];
}
}
@@ -326,84 +272,114 @@ const setStepCountersign = (target: any, v: boolean) => {
const pickerStepId = ref(null);
const pick = ref(null);
const togglePicker = (s: any) => {
- pickerStepId.value = pickerStepId.value === s.id ? null : s.id;
+ pickerStepId.value = pickerStepId.value === s.unique_id ? null : s.unique_id;
pick.value = null;
}
+// 添加审批步骤人员
const addMember = (s: any, v: string | null) => {
- if (v && !s.members.some((m:any) => m.person === v)) s.members.push({ person: v, specialty: "", countersign: false });
- pick.value = null;
- pickerStepId.value = null;
+ console.log(s,v)
+ if (v && !s.members.some((m:any) => m.user_name === v)){
+ s.members.push({ user_name: v, specialty: "", countersign: false });
+ pick.value = null;
+ pickerStepId.value = null;
+ }
}
+// 删除审批步骤人员
const delMember = (s: any, p: string) => {
s.members = s.members.filter((m:any) => m.person !== p);
}
+// 删除审批步骤
const removeStep = (idx: number) => {
currentTemplate.value.steps.splice(idx, 1);
}
-let sid = 100;
-const mkStep = (name: string, extra: Partial = {}): any => ({ id: ++sid, name, countersign: false, members: [], ...extra });
-const addStepAfter = (idx: number) => {
- currentTemplate.value.steps.splice(idx + 1, 0, mkStep(""));
+// 添加审批步骤
+const addStep = (idx: number) => {
+ let step = {
+ unique_id: Date.now(),
+ step_order: currentTemplate.value.steps.length + 1,
+ name: "",
+ countersign: false,
+ members: [],
+ }
+ currentTemplate.value.steps.splice(idx + 1, 0, step);
}
-const ORG_TREE = [
- {
- id: "factory", name: "演示工厂", short: "YS", leaf: false, sort: 0,
- children: [
- {
- id: "scb", name: "生产部", short: "SCB", leaf: false, sort: 0,
- children: [
- { id: "cj1", name: "测试车间一", short: "CJ1", leaf: true, sort: 0 },
- { id: "cj2", name: "测试车间二", short: "CJ2", leaf: true, sort: 1 },
- { id: "cj3", name: "测试车间三", short: "CJ3", leaf: true, sort: 2 },
- ],
- },
- {
- id: "ahb", name: "安环部", short: "AHB", leaf: false, sort: 1,
- children: [
- { id: "aqk", name: "安全科", short: "AQK", leaf: true, sort: 0 },
- { id: "hbk", name: "环保科", short: "HBK", leaf: true, sort: 1 },
- ],
- },
- {
- id: "sbb", name: "设备部", short: "SBB", leaf: false, sort: 2,
- children: [
- { id: "sbk", name: "设备科", short: "SBK", leaf: true, sort: 0 },
- ],
- },
- {
- id: "zlb", name: "质量部", short: "ZLB", leaf: false, sort: 3,
- children: [
- { id: "zjk", name: "质检科", short: "ZJK", leaf: true, sort: 0 },
- ],
- },
- ],
- },
-];
-const LEVEL2_ORGS = ORG_TREE[0]?.children ?? [];
-const ORG_MEMBERS = [
- { id: 1, name: "测试人员01", dept: "测试车间一", gender: "男", phone: "13800000001", email: "test01@demo.com", account: "TEST001", role: "操作人员", scope: ["factory"], enabled: true },
- { id: 2, name: "测试人员02", dept: "测试车间二", gender: "女", phone: "13800000002", email: "test02@demo.com", account: "TEST002", role: "班长", scope: ["factory"], enabled: true },
- { id: 3, name: "测试人员03", dept: "测试车间三", gender: "男", phone: "13800000003", email: "test03@demo.com", account: "TEST003", role: "车间主任", scope: ["factory"], enabled: true },
- { id: 4, name: "测试人员04", dept: "安全科", gender: "女", phone: "13800000004", email: "test04@demo.com", account: "TEST004", role: "安全工程师", scope: ["factory"], enabled: true },
- { id: 5, name: "测试人员05", dept: "环保科", gender: "男", phone: "13800000005", email: "test05@demo.com", account: "TEST005", role: "环保专员", scope: ["factory"], enabled: true },
- { id: 6, name: "测试人员06", dept: "设备科", gender: "男", phone: "13800000006", email: "test06@demo.com", account: "TEST006", role: "设备工程师", scope: ["factory"], enabled: true },
- { id: 7, name: "测试人员07", dept: "质检科", gender: "女", phone: "13800000007", email: "test07@demo.com", account: "TEST007", role: "质量工程师", scope: ["factory"], enabled: true },
-];
-function orgSubtreeNames(n: any): string[] {
- return [n.name, ...(n.children ?? []).flatMap(orgSubtreeNames)];
+
+// 获取列表
+const getList = async () => {
+ loading.value = true;
+ const {data,error} = await templateListApi();
+ if(!error){
+ list.value = data || [];
+ }
+ loading.value = false;
}
-// 预设人员:级联选项(第二层组织 → 组织下可选成员,已选成员不再出现,空组织不展示)
-const peopleOpts = (s: any) =>
- LEVEL2_ORGS.map((o) => ({
- label: o.name,
- value: o.id,
- children: ORG_MEMBERS
- .filter((m) => m.enabled && orgSubtreeNames(o).includes(m.dept) && !s.members.some((x) => x.person === m.name))
- .map((m) => ({ label: m.name, value: m.name })),
- })).filter((o) => o.children.length > 0);
+
+// 获取配置
+const getConfig = async () => {
+ loading.value = true;
+ const {data,error} = await systemConfigApi();
+ if(!error){
+ // 变更类型
+ const changeTypeGroup = data.find((group:{group_key:string}) => group.group_key === 'change_type');
+ if (changeTypeGroup) {
+ categoryOptions.value = changeTypeGroup.items;
+ }
+ // 变更等级
+ const changeLevelGroup = data.find((group:{group_key:string}) => group.group_key === 'change_level');
+ if (changeLevelGroup) {
+ levelOptions.value = changeLevelGroup.items;
+ }
+ getList();
+ }
+ loading.value = false;
+}
+
+
+// 人员数据转换
+const groupUsersByOrg = (users:any) => {
+ const orgMap = new Map(); // key: org.id, value: { id, label, children }
+ users.forEach((user:any) => {
+ const { id: userId, realname, user_departments } = user;
+ if (!user_departments || user_departments.length === 0) return;
+
+ user_departments.forEach((dept:any) => {
+ const org = dept.org;
+ if (!org || !org.id) return;
+
+ if (!orgMap.has(org.id)) {
+ orgMap.set(org.id, {
+ value: org.id,
+ label: org.label,
+ children: []
+ });
+ }
+ const targetOrg = orgMap.get(org.id);
+ // 避免同一个用户重复加入同一个组织(理论上不会发生,但做去重保护)
+ if (!targetOrg.children.some((child:any) => child.id === userId)) {
+ targetOrg.children.push({
+ value: userId,
+ label: realname
+ });
+ }
+ });
+ });
+
+ return Array.from(orgMap.values());
+}
+// 获取审批用户列表
+const getPeopleList = async () => {
+ const {data,error} = await peopleListApi();
+ if(!error){
+ peopleList.value = groupUsersByOrg(data);
+ console.log(groupUsersByOrg(data))
+ }
+}
+
+
onMounted(() => {
- getList()
+ getPeopleList();
+ getConfig()
})
@@ -434,7 +410,7 @@ onMounted(() => {
:single-line="false"
:columns="columns"
:data="list"
- :pagination="pagination"
+ :pagination="false"
max-height="calc(100vh - 290px)"
:scroll-x="820"
/>
@@ -469,15 +445,15 @@ onMounted(() => {
-
+
{{ idx + 1 }}
@@ -496,42 +472,43 @@ onMounted(() => {
预设人员:
-
-
{{ m.person }}
+
+ {{ m.user_name }}
*专业:
m.specialty = v ?? ''"
+ @update:value="(v) => m.specialty = v ?? null"
/>
- m.countersign = v"
+ m.is_sign = v"
>
必须参与会签
-
+
必须参与会签:勾选的人员必须参与专业会签,未勾选的人员为可选会签(按需参加)
-
addMember(s, v == null ? null : String(v))" />
+ class="w-56" :on-update:value="(v) => addMember(s, v ? null : String(v))" />
+
未预设
-
添加审批步骤
+
添加审批步骤
取消
- 确定
+ 确定