变更预识别接口完成
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
<!-- 变更预识别 -->
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { AiError, aiRecognize } from "@/service/api/ai";
|
||||
import ChangeCompareTable from "./ChangeCompareTable.vue";
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
const emit = defineEmits(['updateBtn']);
|
||||
|
||||
const aiFail = (e: any) => {
|
||||
if (e instanceof AiError) window.$message?.warning(`AI 分析失败:${e.message},可手动填写`);
|
||||
else window.$message?.warning("AI 分析失败,可手动填写");
|
||||
};
|
||||
// 是否是ai生成
|
||||
const isAiGenerated = ref<boolean>(false);
|
||||
// 变更识别loading
|
||||
const preLoading = ref<boolean>(false);
|
||||
// 编辑风险预分析
|
||||
const preRiskEdit = ref<string>('');
|
||||
// 是否显示险预分析
|
||||
const preRiskShow = ref<boolean>(false);
|
||||
// 按钮禁用
|
||||
const btnDisabled = ref<boolean>(false);
|
||||
// 表单
|
||||
const form = ref<{
|
||||
description: string,
|
||||
compare_rows: {item: string, before_text: string, after_text: string}[],
|
||||
severity: string,
|
||||
probability: string,
|
||||
protection: string
|
||||
}>({
|
||||
description: '',
|
||||
compare_rows: [],
|
||||
severity: "",
|
||||
probability: "",
|
||||
protection: "",
|
||||
});
|
||||
// AI 变更识别
|
||||
const runIdentify = async () => {
|
||||
if (!form.value.description.trim()) {
|
||||
return window.$message?.warning("请先输入变更内容描述");
|
||||
}
|
||||
form.value.compare_rows = [];
|
||||
emit('updateBtn', true);
|
||||
preLoading.value = true;
|
||||
try {
|
||||
const res = await aiRecognize(form.value.description);
|
||||
form.value.compare_rows = (res?.rows ?? []).map((x, i) => ({ item: x.item, before_text: x.before_text, after_text: x.after_text }));
|
||||
window.$message?.success(`AI 变更识别完成,共 ${form.value.compare_rows.length} 项,请逐项人工确认(可直接修改)`);
|
||||
} catch (e: any) {
|
||||
form.value.compare_rows = [];
|
||||
aiFail(e);
|
||||
} finally {
|
||||
preLoading.value = false;
|
||||
emit('updateBtn', false);
|
||||
}
|
||||
};
|
||||
// 更新表单
|
||||
const updateForm = (res: any, isShow: boolean) => {
|
||||
form.value = {
|
||||
...form.value,
|
||||
severity: res?.severity ?? form.value.severity,
|
||||
probability: res?.probability ?? form.value.probability,
|
||||
protection: res?.protection ?? form.value.protection,
|
||||
};
|
||||
preRiskShow.value = isShow;
|
||||
}
|
||||
// 更新按钮禁用状态
|
||||
const updateBtnDisabled = (disabled: boolean) => {
|
||||
btnDisabled.value = disabled;
|
||||
}
|
||||
|
||||
defineExpose({form,updateForm,updateBtnDisabled})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 变更内容描述 -->
|
||||
<div class="border" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
|
||||
<div class="flex items-center justify-between px-4 py-2 border-b">
|
||||
<div class="flex items-center">
|
||||
<Icon icon="lucide:sparkles" class="size-16px text-violet-500" />
|
||||
<span class="font-semibold text-base ml-2">变更内容描述</span>
|
||||
</div>
|
||||
<NButton ghost type="primary" @click="runIdentify" :disabled="btnDisabled || preLoading">
|
||||
<Icon v-if="preLoading" icon="ri:loader-4-fill" class="size-16px animate-spin" />
|
||||
<Icon v-else icon="fluent:wand-24-regular" class="size-16px" />
|
||||
变更识别
|
||||
</NButton>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<NInput type="textarea" v-model:value="form.description" rows="4" placeholder="请输入变更内容描述,例如:将反应釜R-101的搅拌速度从120rpm提高至180rpm,同时将反应温度从80℃提高至95℃…" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 变更识别结果 -->
|
||||
<div class="border" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
|
||||
<div class="flex items-center justify-between px-4 py-2 border-b">
|
||||
<div class="flex items-center">
|
||||
<Icon icon="lucide:list-checks" class="size-16px text-emerald-500" />
|
||||
<span class="font-semibold text-base ml-2">{{form.compare_rows.length ? `变更识别结果(${form.compare_rows.length}项)` : '变更识别结果(空表 · 可手动录入,或由 AI 识别生成)'}}</span>
|
||||
</div>
|
||||
<span v-if="isAiGenerated" class="inline-flex items-center gap-1 rounded-full border border-violet-200 bg-violet-100 px-2 py-0.5 text-xs font-medium text-violet-700">
|
||||
✨ AI 生成 · 需人工确认
|
||||
</span>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<ChangeCompareTable
|
||||
:data="form.compare_rows"
|
||||
:editable="true"
|
||||
@update:data="(d) => form.compare_rows = d"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 风险预分析报告 -->
|
||||
<div v-if="preRiskShow" class="border" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
|
||||
<div class="flex items-center justify-between px-4 py-2 border-b">
|
||||
<div class="flex items-center">
|
||||
<Icon icon="lucide:list-checks" class="size-16px text-emerald-500" />
|
||||
<span class="font-semibold text-base ml-2">风险预分析报告</span>
|
||||
</div>
|
||||
<span class="inline-flex items-center gap-1 rounded-full border border-violet-200 bg-violet-100 px-2 py-0.5 text-xs font-medium text-violet-700">
|
||||
✨ AI 生成 · 需人工确认
|
||||
</span>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="space-y-4">
|
||||
<div v-for="s in ([{ key: 'severity', name: '危害严重性分析' }, { key: 'probability', name: '事件概率分析' }, { key: 'protection', name: '保护措施影响分析' }])" :key="s.key" class="rounded-lg border">
|
||||
<div class="flex items-center gap-2 border-b bg-slate-50/60 px-4 py-2">
|
||||
<span class="text-sm font-semibold text-slate-700">{{ s.name }}</span>
|
||||
<NButton text type="primary" class="ml-auto text-xs hover:underline" @click="preRiskEdit = preRiskEdit === s.key ? '' : s.key">
|
||||
{{ preRiskEdit === s.key ? "完成" : "编辑" }}
|
||||
</NButton>
|
||||
</div>
|
||||
<NInput v-if="preRiskEdit === s.key" type="textarea" :bordered="false" v-model:value="form[s.key]" autofocus rows="6" />
|
||||
<p v-else class="whitespace-pre-wrap px-3 py-1.5 text-sm leading-relaxed text-slate-700">{{ form[s.key] }}</p>
|
||||
</div>
|
||||
<div class="rounded-lg bg-amber-50 px-3 py-2 text-xs leading-5 text-amber-700">
|
||||
AI 风险预分析仅供参考,用于申请阶段的快速研判;正式风险识别请前往「风险分析记录表」标签页,使用 HAZOP / JSA / 检查表法开展并留存记录。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user