diff --git a/src/service/api/plugin.ts b/src/service/api/plugin.ts index e791726..a9b9d08 100644 --- a/src/service/api/plugin.ts +++ b/src/service/api/plugin.ts @@ -1,8 +1,23 @@ import { request } from '../request'; -/** 获取HAZOP节点列表 - * - */ +// 获取风险预分析详情 +export function riskPreDetailApi(change_id: number) { + return request({ + url: `/api/changes/${change_id}/risk-summary`, + method: 'get', + }); +} + +// 风险预分析保存 +export function riskPreSaveApi(change_id: number, data: any) { + return request({ + url: `/api/changes/${change_id}/risk-summary`, + method: 'put', + data, + }); +} + +// 获取HAZOP节点列表 export function hazopNodesApi(id: number) { return request({ url: `/api/changes/${id}/hazop/nodes`, @@ -18,6 +33,22 @@ export function hazopSaveApi(change_id: number, data: any) { }); } +// 获取FMEA节点列表 +export function fmeaNodesApi(change_id: number) { + return request({ + url: `/api/changes/${change_id}/fmea/nodes`, + method: 'get', + }); +} +// FMEA保存 +export function fmeaSaveApi(change_id: number, data: any) { + return request({ + url: `/api/changes/${change_id}/fmea`, + method: 'put', + data, + }); +} + // 获取JSA详情 export function jsaDetailApi(change_id: number) { return request({ @@ -34,23 +65,6 @@ export function jsaSaveApi(change_id: number, data: any) { }); } -// 获取风险预分析详情 -export function riskPreDetailApi(change_id: number) { - return request({ - url: `/api/changes/${change_id}/risk-summary`, - method: 'get', - }); -} - -// 风险预分析保存 -export function riskPreSaveApi(change_id: number, data: any) { - return request({ - url: `/api/changes/${change_id}/risk-summary`, - method: 'put', - data, - }); -} - // 获取风险检查表详情 export function riskCheckDetailApi(change_id: number) { return request({ diff --git a/src/views/my/initiateChange/modules/fmea.vue b/src/views/my/initiateChange/modules/fmea.vue index 6d629e4..885bb1e 100644 --- a/src/views/my/initiateChange/modules/fmea.vue +++ b/src/views/my/initiateChange/modules/fmea.vue @@ -4,7 +4,7 @@ import { Icon } from '@iconify/vue' import { useThemeStore } from '@/store/modules/theme'; import { useDialog, NInput, NPopconfirm, NButton } from 'naive-ui'; import { peopleListApi } from '@/service/api/system'; -import { hazopNodesApi, hazopSaveApi } from "@/service/api/plugin"; +import { fmeaNodesApi, fmeaSaveApi } from "@/service/api/plugin"; const themeStore = useThemeStore(); const dialog = useDialog(); @@ -45,6 +45,11 @@ const currentNodeListSource = ref([]) const currentNodeList = ref([]) const currentNodeIndex = ref(-1) +// 打开分析列表弹框 +const openList = () => { + node_description.value = currentNode.value?.description || '' + openListModal.value = true +} // 保存数据 const saveData = () => { currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) @@ -57,120 +62,65 @@ const handleSearch = () => { return } currentNodeList.value = currentNodeListSource.value.map((item:any) => { - const objMatched = item.obj_name?.includes(kw) - const matchedDeviations = (item.deviations || []).filter((d:any) => - d.deviation?.includes(kw) - ) - // obj_name 命中 → 保留全部 deviations;否则只保留命中的 deviations + const objMatched = item.deviation?.includes(kw) + // deviation 命中 → 保留全部 deviations;否则只保留命中的 deviations if (objMatched) { return { ...item } // 浅拷贝,结构不变 } - // 只有 deviation 命中 → 保留该对象,但 deviations 只留下命中的 - if (matchedDeviations.length) { - return { - ...item, // 保留 id / node_id / obj_name 等 - deviations: matchedDeviations // 命中项原样保留,rows 等都在 - } - } return null }).filter(Boolean) } -// 点击工序 +// 点击失效模式 const clickDev = (dev:any,nodeIndex:number) => { - currentNodeIndex.value = nodeIndex - currentNodeList.value = JSON.parse(JSON.stringify(nodes.value[nodeIndex]?.objects || [])) - currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) - currentDev.value = dev + currentNodeIndex.value = nodeIndex + currentNodeList.value = JSON.parse(JSON.stringify(nodes.value[nodeIndex]?.deviations || [])) + currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) + currentDev.value = dev } // 分析列表弹框添加 -const addListItem = (type: string,objIndex:number = -1) => { - // 分析对象 - if(type === 'obj'){ +const addListItem = () => { currentNodeList.value.push({ - id: 0, - obj_name: '', - node_id: nodes.value[currentNodeIndex.value]?.id, - deviations: [] + id: 0, + deviation: '', + rows: [] }) - } - // 工序 - if(type === 'dev'){ - currentNodeList.value[objIndex].deviations.push({ - id: 0, - object_id: currentNodeList.value[objIndex]?.id, - deviation: '', - rows: [] - }) - } - currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) + currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) } // 分析列表弹框删除 -const removeListItem = (type: string,objIndex:number = -1,devIndex:number = -1) => { - // 分析对象 - if(type === 'obj'){ - currentNodeList.value.splice(objIndex, 1) - } - // 工序 - if(type === 'dev'){ - currentNodeList.value[objIndex].deviations.splice(devIndex, 1) - } - currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) +const removeListItem = (devIndex:number = -1) => { + currentNodeList.value.splice(devIndex, 1) + currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) } // 分析列表弹框复制 -const copyListItem = (type: string,objIndex:number = -1,devIndex:number = -1) => { - // 分析对象 - if(type === 'obj'){ - let list = currentNodeList.value[objIndex]?.deviations?.map((item:any) => ({ +const copyListItem = (devIndex:number = -1) => { + let list = currentNodeList.value[devIndex]?.rows?.map((item:any) => ({ ...item, id: 0, - object_id: 0 })); currentNodeList.value.push({ id: 0, - obj_name: currentNodeList.value[objIndex]?.obj_name, - node_id: currentNodeList.value[objIndex]?.node_id, - deviations: list || [] - }) - } - // 工序 - if(type === 'dev'){ - let list = currentNodeList.value[objIndex]?.deviations[devIndex]?.rows?.map((item:any) => ({ - ...item, - id: 0, - deviation_id: 0 - })); - currentNodeList.value[objIndex].deviations.push({ - id: 0, - object_id: currentNodeList.value[objIndex]?.id, - deviation: currentNodeList.value[objIndex]?.deviations[devIndex]?.deviation, + deviation: currentNodeList.value[devIndex]?.deviation, rows: list || [] }) - } - currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) + currentNodeListSource.value = JSON.parse(JSON.stringify(currentNodeList.value)) } // 分析列表弹框保存 const listSave = () => { - const hasEmptyObjName = currentNodeList.value.some((item:any) => item.obj_name.trim() === '') + const hasEmptyObjName = currentNodeList.value.some((item:any) => item.deviation.trim() === '') if (hasEmptyObjName) { - window.$message?.warning('分析对象名称不能为空') + return window.$message?.warning('失效模式名称不能为空') } - const hasEmptyDeviation = currentNodeList.value.some((item:any) => - item.deviations?.some((d:any) => d.deviation.trim() === '') - ) - if (hasEmptyDeviation) { - window.$message?.warning('工序名称不能为空') - } - nodes.value[currentNodeIndex.value].objects = currentNodeList.value + nodes.value[currentNodeIndex.value].deviations = currentNodeList.value openListModal.value = false } const options = [ { - label: '分析当前工序', + label: '分析当前失效模式', key: 'current' }, { - label: '分析全部工序', + label: '分析全部失效模式', key: 'all' } ] @@ -186,14 +136,14 @@ const columns = ref([ } }, { - title: '过程名称', + title: '步骤名称', key: 'node_name', align: 'center', render: (row:any) => { return h(NInput,{ size:'small', type:'textarea', - placeholder:'过程名称', + placeholder:'步骤名称', class:'text-left', value:row.node_name, autosize: { minRows: 1 }, @@ -205,14 +155,14 @@ const columns = ref([ } }, { - title: '过程描述', + title: '步骤描述', key: 'description', align: 'center', render: (row:any) => { return h(NInput,{ size:'small', type:'textarea', - placeholder:'过程描述', + placeholder:'步骤描述', class:'text-left', value:row.description, autosize: { minRows: 1 }, @@ -264,18 +214,19 @@ const columns = ref([ }, ]) -// 弹框新增过程 -const addNode = () => { - nodeList.value.push({id:0,node_name:name.value,change_id:props.currentId,objects:[]}) +// 弹框新增步骤 +const addStep = () => { + nodeList.value.push({id:0,node_name:name.value,deviations:[]}) } -// 删除过程 +// 弹框删除步骤 const removeItem = (index:number) => { nodeList.value.splice(index, 1); } +// 弹框保存步骤 const setSave = async () => { const hasEmptyNodeName = nodeList.value.some((item:any) => item.node_name === ''); if(hasEmptyNodeName){ - return window.$message?.warning('请填写过程名称'); + return window.$message?.warning('请填写步骤名称'); } nodes.value = nodes.value.concat(nodeList.value); openSetModal.value = false; @@ -317,73 +268,56 @@ const contextMenuShow = ref(false) const contextMenuX = ref(0) const contextMenuY = ref(0) // 存储当前右键点击的目标数据 -const contextTarget = ref<{type: string, node: any, obj: any, dev: any, nodeIndex: number, objIndex: number, devIndex: number}>({ +const contextTarget = ref<{type: string, node: any, dev: any, nodeIndex: number, devIndex: number}>({ type: '', // 'node' | 'obj' | 'dev' node: null, - obj: null, dev: null, nodeIndex: -1, - objIndex: -1, devIndex: -1, }) -// 当前过程 +// 当前步骤 const currentNode = computed(() => { const targetId = currentDev.value?.id; if (!targetId) return null; for (const top of nodes.value) { - const matchedObj = top.objects?.find((obj:any) =>obj.deviations?.some((dev:any) => dev.id === targetId)); + const matchedObj = top.deviations?.some((dev:any) => dev.id === targetId); if (matchedObj) return top; } return null; }); -// 当前对象 -const currentObj = computed(() => { - const targetId = currentDev.value?.id; - if (!targetId) return null; - for (const top of nodes.value) { - const matchedObj = top.objects?.find((obj:any) =>obj.deviations?.some((dev:any) => dev.id === targetId)); - if (matchedObj) return matchedObj; - } - return null; -}); -// 当前工序 +// 当前失效模式 const currentDev = ref(null); // 展开收起 const collapsed = ref>({}) -// 过程列表 +// 列表 const nodes = ref([]); // 表格样式 const TH = "border bg-slate-100 px-2 py-1.5 text-[11px] font-medium text-slate-500"; const TD = "border px-1.5 py-1 align-top"; -// 工序总数 +// 失效模式总数 const devTotal = computed(() => { let total = 0; nodes.value.forEach((node:any) => { - node.objects.forEach((obj:any) => { - total += obj.deviations.length; - }); + total += node.deviations.length; }); return total; }); -// 已分析工序数 +// 已分析失效模式数 const devDone = computed(() => { let nonEmptyCount = 0; nodes.value.forEach((node:any) => { - node.objects.forEach((obj:any) => { - obj.deviations.forEach((dev:any) => { - if (dev.rows && dev.rows.length > 0) { - nonEmptyCount++; - } - }); + node.deviations.forEach((dev:any) => { + if (dev.rows && dev.rows.length > 0) { + nonEmptyCount++; + } }); }); return nonEmptyCount; }); // 已完成记录总数 const recTotal = computed(() => { - const totalRows = nodes.value.flatMap((node:any) => node.objects) - .flatMap((obj:any) => obj.deviations) - .filter((d:any) => d.rows && d.rows.length > 0) + const totalRows = nodes.value.flatMap((node:any) => node.deviations) + .filter((dev:any) => dev.rows && dev.rows.length > 0) .reduce((sum:number, d:any) => sum + d.rows.length, 0); return totalRows; }); @@ -414,7 +348,7 @@ const save = async (isClick: boolean = false) => { const { org_name, ...rest } = item; return rest; }); - const {error} = await hazopSaveApi(props.currentId, { + const {error} = await fmeaSaveApi(props.currentId, { nodes: nodes.value, users: workers, }); @@ -436,11 +370,10 @@ const findRowWithParents = (rowIndex: number = -1) => { ...row, scene: `${row.cause?row.cause+';':''}${currentDev.value?.deviation+';'}${row.consequence?'可能导致:'+row.consequence:''}`, source: 'HAZOP', - item: `${currentDev.value?.deviation}${currentNode.value?.node_name?`(${currentNode.value?.node_name}${currentObj.value?.obj_name?`-${currentObj.value?.obj_name}`:''})`:''}`, - inherent_level: row?.risk_value || '', + item: `${currentDev.value?.deviation}${currentNode.value?.node_name?`(${currentNode.value?.node_name})`:''}`, safeguards: row?.safeguards?.map((item:any) => item.name).join(';') || '', suggestions: row?.suggestions?.map((item:any) => item.name).join(';') || '', - residual_level: countRiskLevel(row)?.name || '', + residual_level: row?.residual_level || '', to_pssr: 0, safes: row?.safeguards || [], sugs: row?.suggestions || [], @@ -470,10 +403,9 @@ const enterToTable = (type: string, rowIndex: number = -1) => { scene: `${row.cause?row.cause+';':''}${deviation?deviation+';':''}${row.consequence?'可能导致:'+row.consequence:''}`, source: 'HAZOP', item: `${deviation}${node_ame?`(${node_ame}${obj_ame?`-${obj_ame}`:''})`:''}`, - inherent_level: row?.risk_value || '', safeguards: row?.safeguards?.map((item:any) => item.name).join(';') || '', suggestions: row?.suggestions?.map((item:any) => item.name).join(';') || '', - residual_level: countRiskLevel(row)?.name || '', + residual_level: row?.residual_level || '', to_pssr: 0, safes: row?.safeguards || [], sugs: row?.suggestions || [], @@ -492,18 +424,18 @@ const exportWord = () => { window.$message?.info('还差接口') } -// AI 自动分析工序 +// AI 自动分析失效模式 const runAi = async (type: string) => { if(currentDev.value.rows.length){ - return window.$message?.info("当前工序已有分析记录,可手动新增行补充"); + return window.$message?.info("当前失效模式已有分析记录,可手动新增行补充"); } - // 分析当前工序 + // 分析当前失效模式 if(type==='current'){ if(!currentDev.value){ - return window.$message?.warning("请先在左侧选择工序") + return window.$message?.warning("请先在左侧选择失效模式") } } - // 分析全部工序 + // 分析全部失效模式 if(type==='all'){ } @@ -582,18 +514,21 @@ const delSuggestion = (index: number, suggestionIndex: number) => { // 新增行 const addRow = async () => { - if(!currentDev.value){ - return window.$message?.warning("请先在左侧选择工序") - } - currentDev.value.rows.push({ - cause: "", - consequence: "", - l_value: l_options.value[0]?.key || 1, - s_value: s_options.value[0]?.key || 1, - risk_value: riskLevel(l_options.value[0]?.key || 1, s_options.value[0]?.key || 1)?.name || '', - safeguards: [], - suggestions: [], - }); + console.log(props.fmeaRiskMatrixConfig) + if(!currentDev.value){ + return window.$message?.warning("请先在左侧选择失效模式") + } + currentDev.value.rows.push({ + id: 0, + cause: "", + effect: "", + s_value: 0, + p_value: 0, + d_value: 0, + residual_level: '', + safeguards: '', + suggestions: '', + }); }; // 删除行 const delRow = async (index: number) => { @@ -625,61 +560,39 @@ const modalSave = async () => { if(name.value===''){ return window.$message?.warning("名称不能为空") } - // 新增过程 - if(currentModalType.value==='add' && currentModalObj.value==='node'){ - nodes.value.push({id:0,node_name:name.value,change_id:props.currentId,objects:[],description:node_description.value}); - window.$message?.success("新增过程成功") + // 新增步骤 + if(currentModalType.value==='add' && currentModalObj.value==='step'){ + nodes.value.push({id:0,node_name:name.value,deviations:[],description:node_description.value}); + window.$message?.success("新增步骤成功") editModal.value = false; } - // 编辑过程 - if(currentModalType.value==='edit' && currentModalObj.value==='node'){ + // 编辑步骤 + if(currentModalType.value==='edit' && currentModalObj.value==='step'){ nodes.value[contextTarget.value?.nodeIndex].node_name = name.value; nodes.value[contextTarget.value?.nodeIndex].description = node_description.value; - window.$message?.success("编辑过程成功") + window.$message?.success("编辑步骤成功") editModal.value = false; } - // 新增分析对象 - if(currentModalType.value==='add' && currentModalObj.value==='obj'){ - let obj = { - id: 0, - obj_name: name.value, - node_id: nodes.value[contextTarget.value?.nodeIndex]?.id, - deviations: [] - } - if(nodes.value[contextTarget.value?.nodeIndex].objects){ - nodes.value[contextTarget.value?.nodeIndex].objects.push(obj); - }else{ - nodes.value[contextTarget.value?.nodeIndex].objects = [obj]; - } - window.$message?.success("新增分析对象成功") - editModal.value = false; - } - // 编辑分析对象 - if(currentModalType.value==='edit' && currentModalObj.value==='obj'){ - nodes.value[contextTarget.value?.nodeIndex].objects[contextTarget.value?.objIndex].obj_name = name.value; - window.$message?.success("编辑分析对象成功") - editModal.value = false; - } - // 新增工序 + // 新增失效模式 if(currentModalType.value==='add' && currentModalObj.value==='dev'){ let dev = { id: 0, - object_id: nodes.value[contextTarget.value?.nodeIndex].objects[contextTarget.value?.objIndex].id, deviation: name.value, rows: [] } - if(nodes.value[contextTarget.value?.nodeIndex].objects[contextTarget.value?.objIndex].deviations){ - nodes.value[contextTarget.value?.nodeIndex].objects[contextTarget.value?.objIndex].deviations.push(dev); + console.log(contextTarget.value?.nodeIndex) + if(nodes.value[contextTarget.value?.nodeIndex].deviations){ + nodes.value[contextTarget.value?.nodeIndex].deviations.push(dev); }else { - nodes.value[contextTarget.value?.nodeIndex].objects[contextTarget.value?.objIndex].deviations = [dev]; + nodes.value[contextTarget.value?.nodeIndex].deviations = [dev]; } - window.$message?.success("新增工序成功") + window.$message?.success("新增失效模式成功") editModal.value = false; } - // 编辑工序 + // 编辑失效模式 if(currentModalType.value==='edit' && currentModalObj.value==='dev'){ - nodes.value[contextTarget.value?.nodeIndex].objects[contextTarget.value?.objIndex].deviations[contextTarget.value?.devIndex].deviation = name.value; - window.$message?.success("编辑工序成功") + nodes.value[contextTarget.value?.nodeIndex].deviations[contextTarget.value?.devIndex].deviation = name.value; + window.$message?.success("编辑失效模式成功") editModal.value = false; } } @@ -687,14 +600,11 @@ const modalSave = async () => { // 打开删除弹框 const openDelModal = (type: string) => { let txt = '' - if(type==='node'){ - txt = `确定删除过程「${contextTarget.value?.node?.node_name}」吗?` - } - if(type==='obj'){ - txt = `确定删除分析对象「${contextTarget.value?.obj?.obj_name}」吗?` + if(type==='step'){ + txt = `确定删除步骤「${contextTarget.value?.node?.node_name}」吗?` } if(type==='dev'){ - txt = `确定删除工序「${contextTarget.value?.dev?.deviation}」吗?` + txt = `确定删除失效模式「${contextTarget.value?.dev?.deviation}」吗?` } dialog.info({ title: '删除', @@ -702,20 +612,16 @@ const openDelModal = (type: string) => { positiveText: '确定', negativeText: '取消', onPositiveClick: () => { - // 删除过程 - if(type==='node'){ + // 删除步骤 + if(type==='step'){ nodes.value.splice(contextTarget.value?.nodeIndex, 1); - window.$message?.success("删除过程成功") + node_description.value = ''; + window.$message?.success("删除步骤成功") } - // 删除分析对象 - if(type==='obj'){ - nodes.value[contextTarget.value?.nodeIndex].objects.splice(contextTarget.value?.objIndex, 1); - window.$message?.success("删除分析对象成功") - } - // 删除工序 + // 删除失效模式 if(type==='dev'){ - nodes.value[contextTarget.value?.nodeIndex].objects[contextTarget.value?.objIndex].deviations.splice(contextTarget.value?.devIndex, 1); - window.$message?.success("删除工序成功") + nodes.value[contextTarget.value?.nodeIndex].deviations.splice(contextTarget.value?.devIndex, 1); + window.$message?.success("删除失效模式成功") } }, onNegativeClick: () => { @@ -727,22 +633,16 @@ const openDelModal = (type: string) => { // 菜单选项配置(根据不同层级返回不同菜单) const getMenuOptions = (type: string) => { const nodeOptions = [ - { label: '新增分析对象', key: 'addObj' }, - { label: '编辑过程', key: 'editNode' }, - { label: '删除过程', key: 'delNode' }, - ] - const objOptions = [ - { label: '新增工序', key: 'addDev' }, - { label: '编辑分析对象', key: 'editObj' }, - { label: '删除分析对象', key: 'delObj' }, + { label: '新增失效模式', key: 'addDev' }, + { label: '编辑步骤', key: 'editNode' }, + { label: '删除步骤', key: 'delNode' }, ] const devOptions = [ - { label: '编辑工序', key: 'editDev' }, - { label: '删除工序', key: 'delDev' }, + { label: '编辑失效模式', key: 'editDev' }, + { label: '删除失效模式', key: 'delDev' }, ] const map:any = { node: nodeOptions, - obj: objOptions, dev: devOptions, } return map[type] || [] @@ -758,11 +658,11 @@ const closeMenu = () => { } // 右键菜单事件处理 -const handleContextMenu = (event: MouseEvent, type: string, node: any, obj: any, dev: any, nodeIndex: number, objIndex: number, devIndex: number) => { +const handleContextMenu = (event: MouseEvent, type: string, node: any, dev: any, nodeIndex: number, devIndex: number) => { // 阻止浏览器默认右键菜单 event.preventDefault() // 记录目标数据 - contextTarget.value = { type, node, obj, dev, nodeIndex, objIndex, devIndex } + contextTarget.value = { type, node, dev, nodeIndex, devIndex } // 计算菜单位置 contextMenuX.value = Math.max(0, event.clientX) contextMenuY.value = Math.max(0, event.clientY) @@ -771,41 +671,28 @@ const handleContextMenu = (event: MouseEvent, type: string, node: any, obj: any, // 菜单选中回调 // ============================================================ const handleMenuSelect = (key: string) => { - const { type, node, obj, dev } = contextTarget.value + const { type, node, dev } = contextTarget.value switch (key) { // ---------- 过程操作 ---------- - case 'addObj': - // 新增分析对象 - openModal('add','obj','新增分析对象'); + case 'addDev': + // 新增失效模式 + openModal('add','dev','新增失效模式'); break case 'editNode': - // 编辑过程 - openModal('edit','node','编辑过程',node?.node_name,node?.description); + // 编辑步骤 + openModal('edit','step','编辑步骤',node?.node_name,node?.description); break case 'delNode': - // 删除过程 - openDelModal('node'); + // 删除步骤 + openDelModal('step'); break - // ---------- 对象操作 ---------- - case 'addDev': - // 新增工序 - openModal('add','dev','新增工序'); - break - case 'editObj': - // 编辑分析对象 - openModal('edit','obj','编辑分析对象',obj?.obj_name); - break - case 'delObj': - // 删除 - openDelModal('obj'); - break - // ---------- 工序操作 ---------- + // ---------- 失效模式操作 ---------- case 'editDev': - // 编辑工序 - openModal('edit','dev','编辑工序',dev?.deviation); + // 编辑失效模式 + openModal('edit','dev','编辑失效模式',dev?.deviation); break case 'delDev': - // 删除 + // 删除失效模式 openDelModal('dev'); break default: @@ -829,14 +716,15 @@ if (typeof window !== 'undefined') { }) } -// 获取FMEA过程列表 -const getHazopNodes = async () => { +// 获取FMEA列表 +const getFmeaNodes = async () => { loading.value = true; - const {data,error} = await hazopNodesApi(props.currentId); + const {data,error} = await fmeaNodesApi(props.currentId); if(!error){ + console.log(data) nodes.value = data.nodes; selectedWorkers.value = data.users; - clickDev(nodes.value[0]?.objects[0]?.deviations?.[0] || null,0) + clickDev(nodes.value[0]?.deviations[0] || null,0) } loading.value = false; } @@ -854,19 +742,16 @@ const getWorkers = async () => { } } -// ========== 拖拽状态记录(只记录设备卡片和工序项) ========== -const isDeviceDragging = ref(false) -const draggedDeviceInfo = reactive({ deviceIdx: -1 }) - +// ========== 拖拽状态记录(只记录设备卡片和失效模式项) ========== const isDevDragging = ref(false) -const draggedDevInfo = reactive({ deviceIdx: -1, devIdx: -1 }) +const draggedDevInfo = reactive({ deviceIdx: -1 }) -// ========== 分析对象拖拽逻辑 ========== +// ========== 分析拖拽逻辑 ========== const onDeviceDragStart = (e: DragEvent, dIdx: number) => { if (keyword.value) return // 搜索过滤态下索引与暂存数组不一致,禁用拖拽排序 - isDeviceDragging.value = true - draggedDeviceInfo.deviceIdx = dIdx + isDevDragging.value = true + draggedDevInfo.deviceIdx = dIdx if (e.dataTransfer) e.dataTransfer.effectAllowed = 'move' } @@ -874,9 +759,9 @@ const onDeviceDrop = (e: DragEvent, targetDeviceIdx: number) => { e.preventDefault() if (keyword.value) return - if (!isDeviceDragging.value) + if (!isDevDragging.value) return - const { deviceIdx: srcDeviceIdx } = draggedDeviceInfo + const { deviceIdx: srcDeviceIdx } = draggedDevInfo if (srcDeviceIdx === targetDeviceIdx) { resetDeviceDragState() return @@ -888,48 +773,12 @@ const onDeviceDrop = (e: DragEvent, targetDeviceIdx: number) => { resetDeviceDragState() } const resetDeviceDragState = () => { - isDeviceDragging.value = false - draggedDeviceInfo.deviceIdx = -1 -} - -// ========== 内部工序项拖拽逻辑(支持同对象排序与跨对象移动) ========== -const onDeviateDragStart = (e: DragEvent, dIdx: number, dvIdx: number) => { - if (keyword.value) - return // 同上,搜索过滤态禁用 - isDevDragging.value = true - draggedDevInfo.deviceIdx = dIdx - draggedDevInfo.devIdx = dvIdx - if (e.dataTransfer) - e.dataTransfer.effectAllowed = 'move' -} -const onDeviateDrop = (e: DragEvent, targetDeviceIdx: number, targetDevIdx: number) => { - e.preventDefault() - if (keyword.value) - return - if (!isDevDragging.value) - return - const { deviceIdx: srcDeviceIdx, devIdx: srcDevIdx } = draggedDevInfo - if (srcDeviceIdx === targetDeviceIdx && srcDevIdx === targetDevIdx) { - resetDevDragState() - return - } - const srcDevice = currentNodeList.value[srcDeviceIdx] - const tgtDevice = currentNodeList.value[targetDeviceIdx] - // 1. 移除源工序项 - const [devItem] = srcDevice.deviations.splice(srcDevIdx, 1) - // 2. 直接使用目标索引进行插入 - tgtDevice.deviations.splice(targetDevIdx, 0, devItem) - resetDevDragState() -} -const resetDevDragState = () => { isDevDragging.value = false draggedDevInfo.deviceIdx = -1 - draggedDevInfo.devIdx = -1 } - onMounted(() => { getWorkers(); - getHazopNodes(); + getFmeaNodes(); }) onBeforeUnmount(() => { document.removeEventListener('click', closeMenu) @@ -952,7 +801,7 @@ onBeforeUnmount(() => { 保存 FMEA 分析插件 插件 - {{ `分析进度 ${devDone}/${devTotal} 个工序 · ${recTotal} 条记录` }} + {{ `分析进度 ${devDone}/${devTotal} 个失效模式 · ${recTotal} 条记录` }}
分析组成员 · 已选 {{ selectedWorkers.length }} 人 @@ -1010,11 +859,11 @@ onBeforeUnmount(() => {
当前位置: - 过程:{{ currentNode?.node_name ?? '未选择' }} + + 工作步骤:{{ currentNode?.node_name ?? '未选择' }} - 分析对象:{{ currentObj?.obj_name ?? '未选择' }} - - 工序:{{ currentDev?.deviation ?? '未选择' }} + 失效模式:{{ currentDev?.deviation ?? '未选择' }}
{ >
- - 新增过程 + + 新增步骤
-

暂无过程数据

+

暂无数据

-

过程{{ Number(nodeIndex) + 1 }}:{{ node.node_name }}

+

步骤{{ Number(nodeIndex) + 1 }}:{{ node.node_name }}

@@ -1078,15 +914,15 @@ onBeforeUnmount(() => { 新增行 - + 分析列表 - AI 分析当前工序 + AI 分析当前失效模式 - 风险等级按风险矩阵L / S 取值实时重算;「入表」将本条选入风险分析记录表 + 风险等级按风险矩阵RPN = S × P × D 取值实时重算;「入表」将本条选入风险分析记录表
@@ -1107,7 +943,7 @@ onBeforeUnmount(() => { @@ -1132,48 +968,25 @@ onBeforeUnmount(() => { @@ -1258,7 +1048,7 @@ onBeforeUnmount(() => { >
- +
- + { {{ inferring - ? 'AI正在根据项目总体信息推演…' + ? 'AI正在根据工艺描述推演…' : inferred ? 'AI推演完成,已补全空缺内容,可手动修改后保存' - : '可点击右侧按钮,由AI根据项目总体信息自动推演' + : '可点击右侧按钮,由AI根据工艺描述自动推演' }} @@ -1296,21 +1086,21 @@ onBeforeUnmount(() => { -

项目总体信息

+

工艺描述

- - 新增过程 + + 新增步骤
{ > @@ -1348,11 +1138,11 @@ onBeforeUnmount(() => {

分析列表 - 编辑全部分析对象及对应工序,支持增删改与拖拽排序 + 编辑该步骤下全部失效模式,支持增删改与拖拽排序

- 分析对象 - AI设置工序 + 失效模式 + AI设置失效模式 {
-

本过程流程描述

- +

本步骤流程描述

+
-

本过程操作方式描述

- +

本步骤操作方式描述

+
-

本过程现有保护措施罗列

- +

本步骤现有保护措施罗列

+
- - - +
+
- 当前工序暂无分析记录,点击右上角「AI 分析当前工序」自动生成,或「新增行」手动填写 + 当前失效模式暂无分析记录,点击右上角「AI 分析当前失效模式」自动生成,或「新增行」手动填写
- + - + - + -
-
- -
- -
- - - 确定删除吗? - -
-
- - 增加 - +
- + - { }" > {{row.l_value * row.s_value}} - + --> - { }" > {{countRiskLevel(row)?.name}} - + --> -
-
- -
- -
- - - 确定删除吗? - -
-
- - 增加 - +