@@ -0,0 +1,236 @@
< script setup lang = "ts" >
import { ref , computed } from 'vue' ;
import { useAppStore } from '@/store/modules/app' ;
import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme' ;
const appStore = useAppStore ( ) ;
const themeStore = useThemeStore ( ) ;
const gap = computed ( ( ) => ( appStore . isMobile ? 0 : 16 ) ) ;
const keyword = ref < string > ( '' ) ;
const uploadFiles = ( ) => {
window . $message ? . success ( '演示:上传资料(限资料管理员 / 各专业专责维护;上传后进入受控评审,发布生效并生成新版本号,全程留痕)' )
}
const KNOWLEDGE _DOCS = [
{ name : "PID-R201-03 反应釜工艺流程图(Rev C) " , cat : "工艺技术资料" , device : "一车间" , ver : "Rev C" , date : "2026-07-29" } ,
{ name : "聚合岗位操作规程(2026 版)" , cat : "工艺技术资料" , device : "一车间" , ver : "V2026" , date : "2026-07-26" } ,
{ name : "M-201A 搅拌电机设备台账" , cat : "设备资料" , device : "一车间" , ver : "V3.2" , date : "2026-07-28" } ,
{ name : "环己烷 MSDS(供应商 B) " , cat : "化学品资料" , device : "原料罐区" , ver : "V1.0" , date : "2026-07-18" } ,
{ name : "AQ/T 3034 化工企业工艺安全管理实施导则" , cat : "法规标准库" , device : "全厂" , ver : "2013 版" , date : "2025-12-01" } ,
{ name : "PSSR 检查表模板(设备类)" , cat : "检查表模板库" , device : "全厂" , ver : "V2.1" , date : "2026-05-10" } ,
{ name : "2025 年度典型变更案例汇编" , cat : "历史变更案例库" , device : "全厂" , ver : "2025 版" , date : "2026-01-15" } ,
{ name : "HAZOP 分析报告(R-101 温度变更)" , cat : "历史变更案例库" , device : "一车间" , ver : "V1.0" , date : "2026-07-26" } ,
] ;
const libHits = computed ( ( ) => ( keyword . value ? KNOWLEDGE _DOCS . filter ( ( d : any ) => d . name . includes ( keyword . value ) || d . cat . includes ( keyword . value ) ) : [ ] ) ) ;
const preview = ( d : any ) => {
window . $message ? . info ( ` 演示:在线预览 ${ d . name } ` )
}
const download = ( d : any ) => {
window . $message ? . success ( ` 演示:下载 ${ d . name } ` )
}
const call = ( d : any ) => {
window . $message ? . success ( ` 演示:已将「 ${ d . name } 」调用为当前变更的 AI 知识来源(调用记录留痕) ` )
}
interface LibDoc { name : string ; ver : string ; date : string }
interface LibFolder { label : string ; docs : LibDoc [ ] }
interface LibGroup { cat : string ; folders : LibFolder [ ] }
const LIB _ORGS : { org : string ; groups : LibGroup [ ] } [ ] = [
{ org : "一车间" , groups : [
{ cat : "工艺" , folders : [
{ label : "操作规程" , docs : [
{ name : "聚合岗位操作规程(2026 版)" , ver : "V2026" , date : "2026-07-26" } ,
{ name : "干燥岗位操作规程(2026 版)" , ver : "V2026" , date : "2026-06-30" } ] } ,
{ label : "PID 图纸" , docs : [
{ name : "PID-R201-03 反应釜工艺流程图(Rev C) " , ver : "Rev C" , date : "2026-07-29" } ,
{ name : "PID-V102-01 罐区工艺流程图(Rev B) " , ver : "Rev B" , date : "2026-05-12" } ] } ,
{ label : "工艺卡片" , docs : [
{ name : "R-201 反应釜工艺卡片(夏季工况)" , ver : "V2.0" , date : "2026-07-01" } ] } ,
] } ,
{ cat : "设备" , folders : [
{ label : "设备台账" , docs : [
{ name : "M-201A 搅拌电机设备台账" , ver : "V3.2" , date : "2026-07-28" } ,
{ name : "P-204 输送泵设备台账" , ver : "V2.8" , date : "2026-06-15" } ] } ,
{ label : "安全阀台账" , docs : [
{ name : "一车间安全阀台账(PSV-101 ~ PSV-118) " , ver : "V5.1" , date : "2026-07-10" } ] } ,
] } ,
{ cat : "仪表" , folders : [
{ label : "报警台账" , docs : [
{ name : "一车间 DCS 报警台账(2026H1) " , ver : "V4.0" , date : "2026-07-20" } ] } ,
{ label : "联锁台账" , docs : [
{ name : "一车间联锁逻辑台账(SIS-01 ~ SIS-09) " , ver : "V3.6" , date : "2026-07-22" } ] } ,
] } ,
{ cat : "安全" , folders : [
{ label : "总图" , docs : [ { name : "一车间装置总平面布置图" , ver : "Rev D" , date : "2026-04-18" } ] } ,
{ label : "现场气体报警仪布置图" , docs : [ { name : "一车间可燃 / 有毒气体报警仪布置图" , ver : "Rev B" , date : "2026-05-28" } ] } ,
{ label : "防爆分区图" , docs : [ { name : "一车间爆炸危险区域划分图" , ver : "Rev C" , date : "2026-03-15" } ] } ,
] } ,
] } ,
{ org : "二车间" , groups : [
{ cat : "工艺" , folders : [
{ label : "操作规程" , docs : [ { name : "二车间精馏岗位操作规程(2026 版)" , ver : "V2026" , date : "2026-06-20" } ] } ,
{ label : "PID 图纸" , docs : [ { name : "PID-T301-02 精馏塔工艺流程图(Rev A) " , ver : "Rev A" , date : "2026-03-08" } ] } ,
] } ,
{ cat : "设备" , folders : [
{ label : "设备台账" , docs : [ { name : "P-103 冷冻盐水泵设备台账" , ver : "V2.2" , date : "2026-05-30" } ] } ,
{ label : "安全阀台账" , docs : [ { name : "二车间安全阀台账(PSV-201 ~ PSV-212) " , ver : "V4.3" , date : "2026-06-11" } ] } ,
] } ,
{ cat : "仪表" , folders : [
{ label : "报警台账" , docs : [ { name : "二车间 DCS 报警台账(2026H1) " , ver : "V3.5" , date : "2026-07-02" } ] } ,
{ label : "联锁台账" , docs : [ { name : "二车间联锁逻辑台账(SIS-11 ~ SIS-16) " , ver : "V2.9" , date : "2026-06-25" } ] } ,
] } ,
{ cat : "安全" , folders : [
{ label : "总图" , docs : [ { name : "二车间装置总平面布置图" , ver : "Rev B" , date : "2026-02-14" } ] } ,
{ label : "现场气体报警仪布置图" , docs : [ { name : "二车间可燃 / 有毒气体报警仪布置图" , ver : "Rev A" , date : "2026-04-02" } ] } ,
{ label : "防爆分区图" , docs : [ { name : "二车间爆炸危险区域划分图" , ver : "Rev B" , date : "2026-01-20" } ] } ,
] } ,
] } ,
{ org : "全厂共用" , groups : [
{ cat : "法规" , folders : [
{ label : "法规标准库" , docs : [ { name : "AQ/T 3034 化工企业工艺安全管理实施导则" , ver : "2013 版" , date : "2025-12-01" } ] } ,
] } ,
{ cat : "化学品" , folders : [
{ label : "MSDS" , docs : [ { name : "环己烷 MSDS(供应商 B) " , ver : "V1.0" , date : "2026-07-18" } ] } ,
] } ,
{ cat : "模板" , folders : [
{ label : "检查表模板" , docs : [ { name : "PSSR 检查表模板(设备类)" , ver : "V2.1" , date : "2026-05-10" } ] } ,
] } ,
{ cat : "案例" , folders : [
{ label : "历史变更案例" , docs : [
{ name : "2025 年度典型变更案例汇编" , ver : "2025 版" , date : "2026-01-15" } ,
{ name : "HAZOP 分析报告(R-101 温度变更)" , ver : "V1.0" , date : "2026-07-26" } ] } ,
] } ,
] } ,
] ;
const openOrgs = ref < Record < string , boolean > > ( { 一车间 : true } ) ;
const libSel = ref ( { org : "一车间" , cat : "工艺" , label : "操作规程" } ) ;
const libCur = computed ( ( ) => LIB _ORGS . find ( ( o ) => o . org === libSel . value . org ) ? . groups . find ( ( g ) => g . cat === libSel . value . cat ) ? . folders . find ( ( f ) => f . label === libSel . value . label ) ) ;
< / script >
< template >
< NSpace vertical :size = "16" >
<!-- 我的草稿箱 -- >
< NCard :bordered = "false" size = "small" : style = "{ borderRadius: themeStore.themeRadius + 'px' }" >
< NGrid :x-gap = "gap" :y-gap = "16" responsive = "screen" item -responsive class = "pb-[12px] border-b" >
< NGi span = "24 s:24 m:16" >
< div class = "h-100% flex items-center gap-2" >
< Icon icon = "mage:book" class = "size-20px" : style = "{ color: themeStore.themeColor }" / >
< p class = "text-base font-semibold" > 资料档案库 ( 按组织 / 专业类别建立文件夹 · AI 判定的知识来源 ) < / p >
< / div >
< / NGi >
< NGi span = "24 s:24 m:8" class = "flex items-center justify-end gap-12px" >
< div class = "flex items-center gap-2" >
< NInput v -model :value = "keyword" size = "small" type = "text" class = "w-40 text-xs" placeholder = "全文检索…" >
< template # suffix >
< Icon icon = "akar-icons:search" class = "size-14px text-slate-400 cursor-pointer" / >
< / template >
< / NInput >
< NButton size = "small" type = "primary" class = "text-xs" @click ="uploadFiles" >
< Icon icon = "material-symbols:upload" class = "size-16px" / > 上传资料
< / NButton >
< / div >
< / NGi >
< / NGrid >
< div class = "mt-4 mb-2 rounded-lg bg-slate-50 px-3 py-1.5 text-[11px] text-slate-400" >
按 「 组织 → 专业类别 → 资料文件夹 」 归档具体资料 ( 操作规程 / PID 图纸 / 工艺卡片 / 设备台账 / 安全阀台账 / 报警台账 / 联锁台账 / 总图 / 现场气体报警仪布置图 / 防爆分区图等 ) ; 资料由指定维护人 ( 资料管理员 / 各专业专责 ) 上传维护 , 版本受控 ; 「 调用 」 可将资料引用为当前变更的 AI 知识来源 , 调用记录留痕 。
< / div >
<!-- 全文检索 : 跨文件夹平铺结果 -- >
< div v-if = "keyword" >
< div class = "mb-1.5 text-xs text-slate-400" > 全文检索 「 { { keyword } } 」 : 跨全部文件夹命中 { { libHits . length } } 份 < / div >
< div class = "divide-y rounded-lg border bg-white" >
< div v-for = "d in libHits" :key="d.name" class="flex flex-wrap items-center gap-3 px-2 py-2.5" >
< FileText class = "h-4 w-4 shrink-0 text-slate-400" / >
< div class = "min-w-0 flex-1" >
< div class = "truncate text-sm" > { { d . name } } < / div >
< div class = "mt-0.5 flex flex-wrap items-center gap-x-2 text-xs text-slate-500" >
< span > { { d . cat } } · { { d . device } } < / span >
< span > 更新 { { d . date } } < / span >
< / div >
< / div >
< div class = "flex shrink-0 gap-3 text-xs" >
< button class = "text-[#1D4E9C] hover:underline" @click ="preview(d)" > 查看 < / button >
< button class = "text-[#1D4E9C] hover:underline" @click ="download(d)" > 下载 < / button >
< / div >
< / div >
< div v-if = "libHits.length === 0" class="py-6 text-center text-xs text-slate-400" > 未找到匹配 「 {{ keyword }} 」 的资料 < / div >
< / div >
< / div >
< ! - - 文件夹树 + 当前文件夹资料 - - >
< div v-else class = "flex gap-3" >
< div class = "shrink-0 space-y-2 w-56 scroll-left" >
< div v-for = "o in LIB_ORGS" :key="o.org" class="overflow-hidden rounded-lg border bg-white" >
< button class = "flex w-full items-center gap-1.5 px-2.5 py-2 text-xs font-semibold text-slate-700 hover:bg-slate-50 bg-transparent"
@click ="openOrgs[o.org] = !openOrgs[o.org]" >
< Icon icon = "formkit:right" class = "size-14px transition-transform" : class = "openOrgs[o.org] ? 'rotate-90' : ''" / >
< Icon v-if = "openOrgs[o.org]" icon="quill:folder-open" class="size-14px" :style="{ color: themeStore.themeColor }" / >
< Icon v-else icon = "material-symbols:folder-outline" class = "size-14px text-slate-400" / >
{ { o . org } }
< / button >
< template v-if = "openOrgs[o.org]" >
< div v-for = "g in o.groups" :key="g.cat" class="border-t px-2 py-1.5" >
< div class = "px-1 pb-0.5 text-[10px] font-medium tracking-wide text-slate-400" > { { g . cat } } 专业 < / div >
< button v-for = "f in g.folders" :key="f.label"
@click ="libSel = { org: o.org, cat: g.cat, label: f.label }"
class = "flex w-full items-center gap-1.5 rounded px-2 py-1 text-left text-xs transition"
: class = "libSel.org === o.org && libSel.cat === g.cat && libSel.label === f.label ? 'bg-[var(--theme-color)] font-medium text-white' : 'text-slate-600 hover:bg-slate-100 bg-transparent'"
: style = "{ '--theme-color': themeStore.themeColor }"
>
< Icon icon = "material-symbols:folder-outline" class = "size-14px text-slate-400" / >
< span class = "min-w-0 flex-1 truncate" > { { f . label } } < / span >
< span class = "text-[10px]" : class = "libSel.label === f.label && libSel.cat === g.cat && libSel.org === o.org ? 'text-white/70' : 'text-slate-300'" > { { f . docs . length } } < / span >
< / button >
< / div >
< / template >
< / div >
< / div >
< div class = "min-w-0 flex-1" >
< div class = "mb-1.5 flex flex-wrap items-center gap-1 text-xs text-slate-400" >
当前位置 : { { libSel . org } }
< Icon icon = "formkit:right" class = "size-12px" / >
{ { libSel . cat } } 专业
< Icon icon = "formkit:right" class = "size-12px" / >
< span class = "font-medium text-slate-600" > { { libSel . label } } < / span >
< span class = "ml-auto" > 共 { { libCur ? . docs . length ? ? 0 } } 份 · 版本受控 < / span >
< / div >
< div class = "scroll-right" >
< div class = "divide-y rounded-lg border bg-white" >
< div v-for = "d in libCur?.docs ?? []" :key="d.name" class="flex flex-wrap items-center gap-3 px-2 py-2.5" >
< Icon icon = "akar-icons:file" class = "size-16px" / >
< div class = "min-w-0 flex-1" >
< div class = "truncate text-sm" > { { d . name } } < / div >
< div class = "mt-0.5 flex flex-wrap items-center gap-x-2 text-xs text-slate-500" >
< NTag size = "small" type = "info" class = "text-[10px]" > 版本 { { d . ver } } < / NTag >
< span > 更新 { { d . date } } < / span >
< / div >
< / div >
< div class = "flex shrink-0 gap-3 text-xs" >
< NButton type = "primary" text class = "hover:underline text-xs" @click ="preview(d)" > 查看 < / NButton >
< NButton type = "primary" text class = "hover:underline text-xs" @click ="download(d)" > 下载 < / NButton >
< NButton type = "primary" text class = "hover:underline text-xs" @click ="call(d)" > 调用 < / NButton >
< / div >
< / div >
< / div >
< / div >
< / div >
< / div >
< / NCard >
< / NSpace >
< / template >
< style scoped >
< / style >
< style scoped lang = "scss" >
. scroll - left {
height : calc ( 100 vh - 260 px ) ;
overflow - y : auto ;
}
. scroll - right {
height : calc ( 100 vh - 280 px ) ;
overflow - y : auto ;
}
< / style >