diff --git a/src/typings/components.d.ts b/src/typings/components.d.ts index 5c282d6..a8e3710 100644 --- a/src/typings/components.d.ts +++ b/src/typings/components.d.ts @@ -65,6 +65,7 @@ declare module 'vue' { NMessageProvider: typeof import('naive-ui')['NMessageProvider'] NModal: typeof import('naive-ui')['NModal'] NNotificationProvider: typeof import('naive-ui')['NNotificationProvider'] + NPopconfirm: typeof import('naive-ui')['NPopconfirm'] NProgress: typeof import('naive-ui')['NProgress'] NRadio: typeof import('naive-ui')['NRadio'] NRadioGroup: typeof import('naive-ui')['NRadioGroup'] @@ -152,6 +153,7 @@ declare global { const NMessageProvider: typeof import('naive-ui')['NMessageProvider'] const NModal: typeof import('naive-ui')['NModal'] const NNotificationProvider: typeof import('naive-ui')['NNotificationProvider'] + const NPopconfirm: typeof import('naive-ui')['NPopconfirm'] const NProgress: typeof import('naive-ui')['NProgress'] const NRadio: typeof import('naive-ui')['NRadio'] const NRadioGroup: typeof import('naive-ui')['NRadioGroup'] diff --git a/src/views/systemManage/setting/index.vue b/src/views/systemManage/setting/index.vue index 520ceea..7cc706d 100644 --- a/src/views/systemManage/setting/index.vue +++ b/src/views/systemManage/setting/index.vue @@ -9,29 +9,158 @@ const appStore = useAppStore(); const themeStore = useThemeStore(); const gap = computed(() => (appStore.isMobile ? 0 : 16)); -const aiEnabled = ref(true); // 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"); 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: "采纳" }, + { scene: "AI-07 审批辅助", user: "李主任", change: "MOC-2026-R01-0039", time: "08-24 08:47", cost: "1.2s", adopted: "采纳" }, + { scene: "AI-06 PSSR 生成", user: "张工艺", change: "MOC-2026-R02-0052", time: "08-23 16:20", cost: "2.1s", adopted: "未采纳" }, + { scene: "AI-09 关闭辅助判定", user: "系统管理员", change: "MOC-2026-R01-0035", time: "08-23 15:02", cost: "1.5s", adopted: "采纳" }, +]; // 变更类型 +const typeRef = ref(null); +const typeModal = ref(false); +const typeLoading = ref(false); +const currentType = ref('add'); +const typeInfo = ref<{id:number, name:string, desc?:string}>({ + id:0, + name:'', + desc:'', +}) +const typeRules = { + name:{required:true, message:'请输入类型名称', trigger:'blur'}, +} const typeList = ref<{id:number, name:string, desc?:string}[]>([ {id:1,name:'工艺', desc:'工艺参数、配方、操作条件、操作规程等工艺技术类变更'}, {id:2,name:'设备', desc:'设备本体、附件、材质、规格、备件等硬件类变更'}, {id:3,name:'管理', desc:'制度、职责、程序、组织与人员等管理类变更'}, ]) +// 新增类型 +const addType = () => { + typeInfo.value = { + id:0, + name:'', + desc:'', + } + currentType.value = 'add'; + typeModal.value = true; +} +// 编辑类型 +const editType = (row:any) => { + typeInfo.value = { + id:row.id, + name:row.name, + desc:row.desc, + } + currentType.value = 'edit'; + typeModal.value = true; +} +// 删除类型 +const deleteType = (item:any) => { + typeList.value = typeList.value.filter((i:any) => i.id !== item.id); +} +// 保存类型 +const typeSave = async (e:MouseEvent) => { + e.preventDefault() + typeRef.value?.validate((errors:any) => { + if (!errors) { + typeLoading.value = true; + try { + // await addTypeApi(typeInfo.value); + window.$message?.success('操作成功') + typeLoading.value = false; + typeModal.value = false; + } finally { + typeLoading.value = false; + } + } + }) +} // 变更等级 +const levelRef = ref(null); +const levelModal = ref(false); +const levelLoading = ref(false); +const currentLevel = ref('add'); +const toolsOptions = ref<{label:string, value:number}[]>([ + {label:'AI预分析',value:1}, + {label:'检查表法',value:2}, + {label:'HAZOP',value:3}, + {label:'JSA',value:4}, + {label:'SCL',value:5}, +]) +const levelInfo = ref<{id:number, name:string, way:string,tools:number[]}>({ + id:0, + name:'', + way:'', + tools:[], +}) +const levelRules = { + name:{required:true, message:'请输入等级名称', trigger:'blur'}, + way:{required:true, message:'请输入等级判定方式', trigger:'blur'}, + tools:{type:'array', required:true, message:'请选择分析工具', trigger:['blur','change']}, +} const levelList = ref<{id:number, name:string, way:string,tools:{id:number, name:string}[]}[]>([ {id:1,name:'一般', way:'等级评分< 20 分',tools:[{id:1,name:'AI预分析'},{id:2,name:'检查表法'}]}, {id:2,name:'重要', way:'等级评分 > 20 分',tools:[{id:1,name:'AI预分析'},{id:2,name:'HAZOP'},{id:3,name:'JSA'},{id:4,name:'SCL'}]}, ]) +// 新增等级 +const addLevel = () => { + levelInfo.value = { + id:0, + name:'', + way:'', + tools:[], + } + currentLevel.value = 'add'; + levelModal.value = true; +} +// 编辑类型 +const editLevel = (row:any) => { + levelInfo.value = { + id:row.id, + name:row.name, + way:row.way, + tools:row.tools.map((item:any) => (item.id)), + } + currentLevel.value = 'edit'; + levelModal.value = true; +} +// 删除类型 +const deleteLevel = (item:any) => { + levelList.value = levelList.value.filter((i:any) => i.id !== item.id); +} +// 保存类型 +const levelSave = async (e:MouseEvent) => { + e.preventDefault() + levelRef.value?.validate((errors:any) => { + if (!errors) { + levelLoading.value = true; + try { + // await addLevelApi(levelInfo.value); + window.$message?.success('操作成功') + levelLoading.value = false; + levelModal.value = false; + } finally { + levelLoading.value = false; + } + } + }) +} + // 变更编号规则 const ruleInfo = ref<{prefix:string, year:null|string, code:number|null, digit:number|null, rule:number|null}>({ prefix:'MOC', @@ -50,14 +179,91 @@ const ruleOptions = ref<{label:string, value:number}[]>([ {label:'按年度+装置代码重置',value:1} ]) - - - - +// ---------- 风险矩阵设置(按分析方法) ---------- +const dimensionModal = ref(false); +const dimensionLoading = ref(false); +const dimForm = ref({ s: [], l: [] }); +const LV_CLS = [ + "border-emerald-300 bg-emerald-100 text-emerald-700", + "border-yellow-300 bg-yellow-100 text-yellow-700", + "border-orange-300 bg-orange-100 text-orange-700", + "border-red-300 bg-red-100 text-red-700", +]; +const matrices = ref([ + { + tool: "HAZOP", + sLabels: ["轻微", "一般", "较重", "严重", "灾难"], + lLabels: ["极少发生", "较少发生", "偶尔发生", "可能发生", "频繁发生"], + levels: [ + { name: "低", min: 1, max: 4, cls: LV_CLS[0] }, + { name: "一般", min: 5, max: 9, cls: LV_CLS[1] }, + { name: "较大", min: 10, max: 16, cls: LV_CLS[2] }, + { name: "重大", min: 17, max: 25, cls: LV_CLS[3] }, + ], + }, + { + tool: "JSA", + sLabels: ["轻微伤害", "轻伤", "重伤", "单人死亡", "多人死亡"], + lLabels: ["极不可能", "不太可能", "有可能", "较可能", "很可能"], + levels: [ + { name: "低", min: 1, max: 6, cls: LV_CLS[0] }, + { name: "一般", min: 7, max: 12, cls: LV_CLS[1] }, + { name: "较大", min: 13, max: 19, cls: LV_CLS[2] }, + { name: "重大", min: 20, max: 25, cls: LV_CLS[3] }, + ], + }, + { + tool: "SCL", + sLabels: ["轻微影响", "一般影响", "较大影响", "严重影响", "灾难性影响"], + lLabels: ["极少", "较少", "偶尔", "可能", "经常"], + levels: [ + { name: "低", min: 1, max: 2, cls: LV_CLS[0] }, + { name: "一般", min: 3, max: 6, cls: LV_CLS[1] }, + { name: "较大", min: 7, max: 12, cls: LV_CLS[2] }, + { name: "重大", min: 13, max: 25, cls: LV_CLS[3] }, + ], + }, +]); +const activeMatrix = ref(0); +const curMatrix = computed(() => matrices.value[activeMatrix.value]); +const cellScore = (s:number, l:number) => (s + 1) * (l + 1); +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(() => { + window.$message?.success("操作成功"); + dimensionLoading.value = false; + dimensionModal.value = false; + }, 1000); +} +const openDimEdit = () => { + dimForm.value = { s: [...curMatrix.value.sLabels], l: [...curMatrix.value.lLabels] }; + dimensionModal.value = true; +} + +// tabs 切换 +const handleTabChange = (v: number) => { + activeMatrix.value = v; +} @@ -96,6 +302,11 @@ const toggle = (v: boolean) => { 当前状态:{{ aiEnabled ? "已启用 —— 变更申请界面提供 AI 变更识别与申请表生成" : "已关闭 —— 变更申请界面为纯手动模式" }}
+
+ + AI 接口配置 + 连接正常 +

接口地址

@@ -121,9 +332,9 @@ const toggle = (v: boolean) => {
- 测试连接 - 保存配置 - + 测试连接 + 保存配置 + 调用记录查询 @@ -140,7 +351,7 @@ const toggle = (v: boolean) => { 变更类型设置(支持自定义)
- + 新增类型
@@ -153,12 +364,22 @@ const toggle = (v: boolean) => {

{{item.desc}}

- + 编辑 - - 删除 - + + + 确定删除吗? +
@@ -188,7 +409,7 @@ const toggle = (v: boolean) => { 变更等级设定(支持自定义) - + 新增等级 @@ -202,12 +423,22 @@ const toggle = (v: boolean) => {

判定方式:{{item.way}}

- + 编辑 - - 删除 - + + + 确定删除吗? +
@@ -302,7 +533,7 @@ const toggle = (v: boolean) => { 风险矩阵设置(按分析方法)
- + 维度分级定义 @@ -311,21 +542,294 @@ const toggle = (v: boolean) => {
- - - HAZOP分析矩阵 + + +
+
+ + + + + + + + + + + + + +
+ L{{ li + 1 }}
{{ lb }} +
S{{ 6 - row }} {{ curMatrix.sLabels[5 - row] }} +
+ {{ cellScore(5 - row, col - 1) }} +
+
+
+ 纵轴:后果严重性 S + 横轴:发生可能性 L +
+
+ + +
+
风险值 = 严重性 S × 可能性 L(5×5),按分值区间定级:
+
+
+ + + 分值 + + + + {{ lv.name }}风险 +
+
+

+ 各分析方法独立维护矩阵与维度分级;风险分析记录表按所选工具对应的矩阵自动定级。分值区间不得重叠、须落在 1–25 内;在途分析记录按原矩阵保留定级快照。 +

+
+
- - JSA分析矩阵 + +
+
+ + + + + + + + + + + + + +
+ L{{ li + 1 }}
{{ lb }} +
S{{ 6 - row }} {{ curMatrix.sLabels[5 - row] }} +
+ {{ cellScore(5 - row, col - 1) }} +
+
+
+ 纵轴:后果严重性 S + 横轴:发生可能性 L +
+
+ + +
+
风险值 = 严重性 S × 可能性 L(5×5),按分值区间定级:
+
+
+ + + 分值 + + + + {{ lv.name }}风险 +
+
+

+ 各分析方法独立维护矩阵与维度分级;风险分析记录表按所选工具对应的矩阵自动定级。分值区间不得重叠、须落在 1–25 内;在途分析记录按原矩阵保留定级快照。 +

+
+
- - SCL分析矩阵 + +
+
+ + + + + + + + + + + + + +
+ L{{ li + 1 }}
{{ lb }} +
S{{ 6 - row }} {{ curMatrix.sLabels[5 - row] }} +
+ {{ cellScore(5 - row, col - 1) }} +
+
+
+ 纵轴:后果严重性 S + 横轴:发生可能性 L +
+
+ + +
+
风险值 = 严重性 S × 可能性 L(5×5),按分值区间定级:
+
+
+ + + 分值 + + + + {{ lv.name }}风险 +
+
+

+ 各分析方法独立维护矩阵与维度分级;风险分析记录表按所选工具对应的矩阵自动定级。分值区间不得重叠、须落在 1–25 内;在途分析记录按原矩阵保留定级快照。 +

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
AI 场景调用人关联变更时间耗时采纳结果
{{ r.scene }}{{ r.user }}{{ r.change }}{{ r.time }}{{ r.cost }} + {{ r.adopted }} + {{ r.adopted }} + {{ r.adopted }} +
+

调用记录含输入摘要(脱敏)、模型与提示词版本、耗时与采纳结果,支持采纳率统计;完整输出存对象存储。

+
+
+ + +
+ + + + + + + + +
+ +
+ + +
+ + + + + + + + + + + +
+ +
+ + +
+
+
后果严重性 S(S1 → S5 递增)
+
+ +
+
+
+
发生可能性 L(L1 → L5 递增)
+
+ +
+
+
+ +
+