@@ -1,688 +0,0 @@
// ===================== 数据模型与 Mock 数据 =====================
export type RoleId = "applicant" | "process" | "process2" | "safety" | "quality" | "dept" | "vp" | "admin" | "viewer" ;
export interface Role {
id : RoleId ;
name : string ;
person : string ;
org : string ;
desc : string ;
}
export const ROLES : Role [ ] = [
{ id : "applicant" , name : "申请人" , person : "张工艺" , org : "一车间 · 工艺组" , desc : "发起变更申请、AI 辅助判定、跟踪进度" } ,
{ id : "process" , name : "专业会签(仪表)" , person : "王仪表" , org : "技术部 · 仪表科" , desc : "专业会签、HAZOP 分析、确认连带变更" } ,
{ id : "process2" , name : "专业会签(设备)" , person : "周设备" , org : "设备管理部 · 设备科" , desc : "专业会签、设备完整性检查、行动项落实" } ,
{ id : "safety" , name : "安全工程师" , person : "王海燕" , org : "安全环保部" , desc : "安全审查、PSSR 检查表确认、风险分析组织" } ,
{ id : "dept" , name : "车间主任" , person : "李主任" , org : "一车间" , desc : "部门审核、现场验收、变更关闭确认" } ,
{ id : "vp" , name : "分管领导" , person : "刘副总" , org : "公司领导" , desc : "重要变更最终批准、移动端审批" } ,
{ id : "admin" , name : "系统管理员" , person : "刘敏" , org : "信息化部" , desc : "流程配置、字典维护、权限分配" } ,
{ id : "quality" , name : "质量工程师" , person : "陈质量" , org : "质量部" , desc : "质量会签、产品合格判定、检验方案确认" } ,
{ id : "viewer" , name : "非审批人员" , person : "吴新" , org : "相关部门" , desc : "以信息查看为主,不参与变更流程" } ,
] ;
export type ChangeType = "工艺" | "设备" | "管理" ;
export type ChangeLevel = "重要" | "一般" ;
export type ChangeStatus =
| "审批中"
| "已批准"
| "实施中"
| "待PSSR"
| "待验收"
| "待关闭"
| "已关闭" ;
export interface FlowNode {
name : string ;
kind : "审批" | "会签" | "最终批准" ;
roles : RoleId [ ] ;
members ? : { name : string ; done : boolean } [ ] ;
status : "done" | "current" | "todo" ;
locked? : boolean ;
}
export interface ChangeOrder {
id : string ;
title : string ;
type : ChangeType ;
level : ChangeLevel ;
duration : "永久" | "临时" ;
urgent : boolean ;
status : ChangeStatus ;
applicant : string ;
org : string ;
device : string ;
date : string ;
purpose : string ;
effect : string ;
before : string ;
after : string ;
related : string [ ] ;
materials : string [ ] ;
riskTools : string [ ] ;
flow : FlowNode [ ] ;
overdueDays? : number ;
}
export const FLOW_IMPORTANT : FlowNode [ ] = [
{ name : "部门审核" , kind : "审批" , roles : [ "dept" ] , status : "done" } ,
{
name : "专业会签" ,
kind : "会签" ,
roles : [ "process" , "process2" , "quality" ] ,
status : "current" ,
members : [
{ name : "王仪表(仪表)" , done : true } ,
{ name : "周设备(设备)" , done : false } ,
{ name : "陈质量(质量)" , done : false } ,
] ,
} ,
{ name : "安全审查" , kind : "审批" , roles : [ "safety" ] , status : "todo" , locked : true } ,
{ name : "分管领导最终批准" , kind : "最终批准" , roles : [ "vp" ] , status : "todo" , locked : true } ,
] ;
export const FLOW_SIMPLE : FlowNode [ ] = [
{ name : "部门审核" , kind : "审批" , roles : [ "dept" ] , status : "done" } ,
{ name : "专业审批" , kind : "审批" , roles : [ "process" ] , status : "current" } ,
{ name : "部门负责人批准" , kind : "最终批准" , roles : [ "dept" ] , status : "todo" , locked : true } ,
] ;
export const CHANGES : ChangeOrder [ ] = [
{
id : "MOC-2026-R01-0035" ,
title : "R-201 反应釜搅拌器电机更换(55kW→75kW 防爆电机)" ,
type : "设备" ,
level : "重要" ,
duration : "永久" ,
urgent : false ,
status : "审批中" ,
applicant : "张工艺" ,
org : "一车间 · 工艺组" ,
device : "R-201 反应釜 / M-201A 搅拌电机" ,
date : "2026-07-28" ,
purpose : "原 55kW 电机在高粘度工况下频繁过载跳闸,影响反应均匀性与产品质量,需更换为 75kW 防爆电机。" ,
effect : "消除过载跳闸(月均 3 次降至 0),搅拌电流裕量提升至 25%,产品批次合格率预计提升 1.5%。" ,
before : "M-201A 搅拌电机:55kW, ExdⅡBT4,额定电流 102A,原设计工况粘度 ≤3000cP。" ,
after : "更换为 75kW 防爆电机:ExdⅡCT4,额定电流 138A,适配粘度 ≤6000cP;电缆与开关容量同步校核升级。" ,
related : [ "更新 P&ID(图号 PID-R201-03) " , "修订电气图纸与电缆清册" , "校核联锁跳车电流设定" , "更新设备台账与备件清单" , "操作人员培训" ] ,
materials : [ "设备数据表" , "防爆合格证与材质证明" , "电气负荷校核计算书" , "更新后的 P&ID" , "制造商安装维护手册" ] ,
riskTools : [ "AI 分析" , "JSA" , "检查表法" ] ,
flow : FLOW_IMPORTANT ,
} ,
{
id : "MOC-2026-R01-0036" ,
title : "聚合反应温度控制上限调整(78℃→82℃)" ,
type : "工艺" ,
level : "重要" ,
duration : "永久" ,
urgent : false ,
status : "审批中" ,
applicant : "孙丽" ,
org : "一车间 · 工艺组" ,
device : "R-101 聚合釜 / TIC-101" ,
date : "2026-07-25" ,
purpose : "提高反应温度上限以缩短聚合时间、提升装置产能,满足新增订单需求。" ,
effect : "单釜反应周期缩短约 40 分钟,年产能预计提升 8%。" ,
before : "聚合反应温度控制范围 65– 78℃,TIC-101 高报 78℃、联锁 80℃。" ,
after : "控制范围调整为 65– 82℃,TIC-101 高报 82℃、联锁值维持 85℃ 安全边界不变。" ,
related : [ "修订工艺卡片与操作规程" , "DCS 参数与报警值修改" , "更新 HAZOP 分析报告" , "岗位人员再培训" ] ,
materials : [ "工艺计算书" , "热平衡与飞温风险分析" , "HAZOP 分析报告" , "更新后的工艺卡片" ] ,
riskTools : [ "AI 分析" , "HAZOP" ] ,
flow : [
{ name : "部门审核" , kind : "审批" , roles : [ "dept" ] , status : "done" } ,
{
name : "专业会签" ,
kind : "会签" ,
roles : [ "process" , "quality" ] ,
status : "done" ,
members : [
{ name : "王仪表(仪表)" , done : true } ,
{ name : "陈质量(质量)" , done : true } ,
] ,
} ,
{ name : "安全审查" , kind : "审批" , roles : [ "safety" ] , status : "current" , locked : true } ,
{ name : "分管领导最终批准" , kind : "最终批准" , roles : [ "vp" ] , status : "todo" , locked : true } ,
] ,
} ,
{
id : "MOC-2026-R02-0038" ,
title : "DCS 罐区液位报警值 LIA-301 调整" ,
type : "工艺" ,
level : "一般" ,
duration : "永久" ,
urgent : false ,
status : "待PSSR" ,
applicant : "吴强" ,
org : "一车间 · 罐区" ,
device : "V-301 储罐 / LIA-301" ,
date : "2026-07-20" ,
purpose : "原高报值偏保守,频繁误报导致操作疲劳,按最新容积表校准报警值。" ,
effect : "误报次数由每周 5 次降至 0,报警响应有效性提升。" ,
before : "LIA-301 高报 80%(对应 7.2m)。" ,
after : "高报调整为 85%(对应 7.65m),联锁值 90% 不变。" ,
related : [ "DCS 组态修改" , "更新报警台账" , "岗位告知培训" ] ,
materials : [ "储罐容积表" , "DCS 组态修改记录" , "报警台账" ] ,
riskTools : [ "AI 分析" , "检查表法" ] ,
flow : FLOW_SIMPLE.map ( ( n ) = > ( { . . . n , status : "done" as const } ) ) ,
} ,
{
id : "MOC-2026-R01-0039" ,
title : "紧急变更:V-102 安全阀起跳压力临时调整(补办手续)" ,
type : "设备" ,
level : "一般" ,
duration : "临时" ,
urgent : true ,
status : "待关闭" ,
applicant : "张工艺" ,
org : "一车间 · 工艺组" ,
device : "V-102 缓冲罐 / PSV-102" ,
date : "2026-07-15" ,
purpose : "上游工况波动导致安全阀频繁起跳,经紧急批准临时调整起跳压力并限期恢复原设定。" ,
effect : "装置维持连续运行,临时期限内风险受控。" ,
before : "PSV-102 起跳压力 0.8MPa。" ,
after : "临时调整为 0.88MPa(不超过设计压力 1.0MPa 的 90%),期限 30 天,到期恢复 0.8MPa。" ,
related : [ "恢复性检查" , "更新安全阀台账" , "事后风险分析补办" ] ,
materials : [ "安全阀校验报告" , "紧急变更审批单" , "事后 JSA 分析" ] ,
riskTools : [ "AI 分析" , "JSA" ] ,
flow : FLOW_SIMPLE.map ( ( n ) = > ( { . . . n , status : "done" as const } ) ) ,
overdueDays : 4 ,
} ,
{
id : "MOC-2026-R03-0040" ,
title : "原料环己烷供应商变更(新增 B 供应商)" ,
type : "管理" ,
level : "重要" ,
duration : "永久" ,
urgent : false ,
status : "实施中" ,
applicant : "刘芳" ,
org : "供应部" ,
device : "原料罐区 / TK-201" ,
date : "2026-07-18" ,
purpose : "引入第二供应商保障原料供应安全,降低单一来源断供风险。" ,
effect : "供应保障能力提升,采购成本预计下降 3%。" ,
before : "环己烷单一供应商 A,纯度 ≥99.5%。" ,
after : "新增供应商 B(纯度 ≥99.8%,已提供 MSDS 与质检报告),双源供应。" ,
related : [ "更新合格供应商名录" , "修订进厂检验规程" , "更新 MSDS 档案" , "卸料操作培训" ] ,
materials : [ "新供应商资质文件" , "产品质检报告与 MSDS" , "进厂检验规程" ] ,
riskTools : [ "AI 分析" , "检查表法" ] ,
flow : FLOW_IMPORTANT.map ( ( n ) = > ( { . . . n , status : "done" as const } ) ) ,
} ,
{
id : "MOC-2026-R01-0029" ,
title : "操作规程修订(夏季工况)" ,
type : "管理" ,
level : "一般" ,
duration : "临时" ,
urgent : false ,
status : "审批中" ,
applicant : "张工艺" ,
org : "一车间 · 工艺组" ,
device : "全装置" ,
date : "2026-06-20" ,
purpose : "夏季高温工况下循环水温度升高,原操作规程冷却参数不适用,需修订夏季操作参数与巡检频次。" ,
effect : "夏季工况下装置运行参数受控,避免超温降负荷,预计减少非计划降量 2 次/年。" ,
before : "操作规程(2025 版)未区分冬夏季工况,冷却参数单一。" ,
after : "增加夏季工况章节:循环水温度 >28℃ 时启用备用冷却塔,巡检频次由 4h 调整为 2h。" ,
related : [ "操作规程升版发布" , "岗位人员培训" ] ,
materials : [ "修订后操作规程" , "参数核算表" ] ,
riskTools : [ "AI 分析" , "检查表法" ] ,
flow : [
{ name : "部门审核" , kind : "审批" , roles : [ "dept" ] , status : "current" } ,
{ name : "专业审批" , kind : "审批" , roles : [ "process" ] , status : "todo" , locked : true } ,
{ name : "部门负责人批准" , kind : "最终批准" , roles : [ "dept" ] , status : "todo" , locked : true } ,
] ,
overdueDays : 3 ,
} ,
{
id : "MOC-2026-R02-0041" ,
title : "公用工程氮气减压阀组改造" ,
type : "设备" ,
level : "一般" ,
duration : "永久" ,
urgent : false ,
status : "审批中" ,
applicant : "周涛" ,
org : "公用工程车间" ,
device : "氮气总管 / PV-208 减压阀组" ,
date : "2026-07-29" ,
purpose : "氮气减压阀组单路运行,检修时需停氮气,影响装置密封气供应,需改造为双路并联。" ,
effect : "减压阀组可在线切换检修,氮气供应连续性提升至 100%。" ,
before : "PV-208 单路减压,无备用回路。" ,
after : "新增并联减压回路 PV-208B,双路一用一备,可在线切换。" ,
related : [ "更新 P&ID" , "修订氮气系统操作规程" , "更新设备台账" ] ,
materials : [ "阀门数据表" , "管道单线图" , "施工方案" ] ,
riskTools : [ "AI 分析" , "JSA" ] ,
flow : [
{ name : "部门审核" , kind : "审批" , roles : [ "dept" ] , status : "done" } ,
{ name : "专业审批" , kind : "审批" , roles : [ "process" ] , status : "current" } ,
{ name : "部门负责人批准" , kind : "最终批准" , roles : [ "dept" ] , status : "todo" , locked : true } ,
] ,
overdueDays : 3 ,
} ,
{
id : "MOC-2026-R03-0042" ,
title : "三车间自动化和安全隐患整改项目变更" ,
type : "管理" ,
level : "重要" ,
duration : "永久" ,
urgent : false ,
status : "审批中" ,
applicant : "刘芳" ,
org : "三车间" ,
device : "三车间装置区" ,
date : "2026-07-31" ,
purpose : "落实安全隐患整改要求,对三车间自动化控制系统升级改造,消除加料互串与超温隐患。" ,
effect : "隐患整改闭环率 100%,自动化水平提升,误操作风险显著降低。" ,
before : "加料系统手动控制,存在互串与超温隐患(隐患编号 YH-2026-017)。" ,
after : "改为 DCS 自动控制 + 加料顺序联锁,增设独立超温切断。" ,
related : [ "修订操作规程" , "DCS 组态修改" , "更新 HAZOP 分析" , "岗位再培训" ] ,
materials : [ "隐患整改方案" , "HAZOP 分析报告" , "联锁因果表" ] ,
riskTools : [ "AI 分析" , "HAZOP" ] ,
flow : [
{ name : "部门审核" , kind : "审批" , roles : [ "dept" ] , status : "done" } ,
{
name : "专业会签" ,
kind : "会签" ,
roles : [ "process" , "process2" , "quality" ] ,
status : "done" ,
members : [
{ name : "王仪表(仪表)" , done : true } ,
{ name : "周设备(设备)" , done : true } ,
{ name : "陈质量(质量)" , done : true } ,
] ,
} ,
{ name : "安全审查" , kind : "审批" , roles : [ "safety" ] , status : "done" } ,
{ name : "分管领导最终批准" , kind : "最终批准" , roles : [ "vp" ] , status : "current" } ,
] ,
} ,
] ;
// ===================== PSSR / 验收 =====================
export interface PssrItem {
id : number ;
category : string ;
content : string ;
owner : string ;
status : "待确认" | "已确认" | "不适用" | "整改中" ;
photo? : boolean ;
/** 完成时点:投用前(未完成禁止投用)/ 关闭前(未完成禁止关闭) */
phase ? : "投用前" | "关闭前" ;
}
export const PSSR_ITEMS : PssrItem [ ] = [
{ id : 1 , category : "设备完整性" , content : "搅拌电机安装就位,联轴器对中合格,地脚螺栓紧固" , owner : "周设备" , status : "已确认" , photo : true , phase : "投用前" } ,
{ id : 2 , category : "设备完整性" , content : "电机空载/负载试车合格,轴承温度、振动值在正常范围" , owner : "周设备" , status : "已确认" , photo : true , phase : "投用前" } ,
{ id : 3 , category : "仪表联锁" , content : "电机过载保护定值按 75kW 重新整定并传动试验合格" , owner : "王仪表" , status : "待确认" , phase : "投用前" } ,
{ id : 4 , category : "图纸规程" , content : "P&ID( PID-R201-03)与电气图纸已更新发布" , owner : "王仪表" , status : "已确认" , phase : "关闭前" } ,
{ id : 5 , category : "人员培训" , content : "相关岗位 12 人完成新设备操作培训并考核合格" , owner : "李主任" , status : "待确认" , phase : "投用前" } ,
{ id : 6 , category : "应急消防" , content : "现场消防器材完好,应急通道畅通" , owner : "王海燕" , status : "待确认" , phase : "投用前" } ,
{ id : 7 , category : "施工确认" , content : "施工遗留物清理完毕,临时用电已拆除" , owner : "周设备" , status : "整改中" , phase : "投用前" } ,
] ;
export const ACCEPT_ITEMS : PssrItem [ ] = [
{ id : 1 , category : "一致性" , content : "实施结果与批准的变更内容一致(电机型号、参数符合批准方案)" , owner : "李主任" , status : "待确认" } ,
{ id : 2 , category : "连带变更" , content : "5 项连带变更全部完成(图纸、台账、联锁、备件、培训)" , owner : "李主任" , status : "待确认" } ,
{ id : 3 , category : "资料更新" , content : "P&ID、电气图纸、设备台账已归档最新版本" , owner : "王仪表" , status : "待确认" } ,
{ id : 4 , category : "运行验证" , content : "连续运行 72 小时无异常,搅拌电流稳定在 118A±5%" , owner : "张工艺" , status : "待确认" } ,
] ;
// ===================== 关闭校验 =====================
export interface ClosureCheck {
item : string ;
done : boolean ;
note? : string ;
}
export const CLOSURE_CHECKS : ClosureCheck [ ] = [
{ item : "变更验收完成(结论:基本达到 · 遗留项 2 项已登记跟踪)" , done : true } ,
{ item : "资料上传齐全(验收报告、运行记录、恢复确认记录)" , done : false , note : "缺:更新后的安全阀台账" } ,
{ item : "行动项全部关闭(4/4,含「关闭前完成」标记项)" , done : true } ,
{ item : "受控文件已更新至生效版(P&ID Rev.4、操作规程)" , done : false , note : "安全阀台账待更新发布" } ,
{ item : "培训考核完成(12/12 人),签到与成绩已归档" , done : true } ,
] ;
// ===================== 风险分析 =====================
export const HAZOP_ROWS = [
{ node : "R-101 聚合釜" , guide : "过高(温度)" , dev : "反应温度超过 82℃" , cause : "冷却水中断;TIC-101 故障;进料配比失调" , cons : "飞温、冲料、超压破裂" , l : 2 , s : 5 , measures : "增设独立高温联锁;冷却水低流量报警;HAZOP 建议 2 项已落实" } ,
{ node : "R-101 聚合釜" , guide : "过低(温度)" , dev : "温度低于 65℃" , cause : "引发剂不足;夹套加热故障" , cons : "反应中止、物料积压,恢复时剧烈反应" , l : 3 , s : 3 , measures : "低温度报警;恢复升温操作程序" } ,
{ node : "进料系统" , guide : "无(流量)" , dev : "单体进料中断" , cause : "进料泵故障;过滤器堵塞" , cons : "釜内配比失衡,产品质量事故" , l : 2 , s : 3 , measures : "泵一用一备;压差报警" } ,
{ node : "进料系统" , guide : "反向" , dev : "物料反向流动" , cause : "停泵时止回阀失效" , cons : "串料污染、计量错误" , l : 2 , s : 2 , measures : "止回阀定期校验(检查表项)" } ,
] ;
export const JSA_ROWS = [
{ step : "1. 停机断电隔离" , hazard : "残余电能、机械能意外释放" , measure : "执行上锁挂牌(LOTO),验电确认" , owner : "周设备" } ,
{ step : "2. 拆卸旧电机" , hazard : "吊装伤害、挤压" , measure : "持证起重工指挥,吊具检查,警戒区隔离" , owner : "吊装班" } ,
{ step : "3. 新电机安装对中" , hazard : "对中误差导致振动超标" , measure : "激光对中仪,偏差 ≤0.05mm" , owner : "周设备" } ,
{ step : "4. 接线与送电" , hazard : "触电、相序错误反转" , measure : "双人复核相序,点动确认转向" , owner : "电气班" } ,
{ step : "5. 试车" , hazard : "机械伤害、异常振动" , measure : "空载→负载分级试车,振动在线监测" , owner : "周设备" } ,
] ;
export const SCL_ROWS = [
{ item : "新电机防爆等级不低于区域要求(ExdⅡCT4)" , std : "GB 50058" , result : "符合" } ,
{ item : "电缆载流量与开关容量匹配 75kW 负荷" , std : "GB 50217" , result : "符合" } ,
{ item : "电机接地电阻 ≤4Ω" , std : "GB 50169" , result : "符合" } ,
{ item : "防护罩、联轴器护罩安装齐全" , std : "企业设备规程" , result : "整改后符合" } ,
{ item : "润滑油牌号与加注量符合制造商要求" , std : "制造商手册" , result : "符合" } ,
] ;
// ===================== 资料库 =====================
export 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" } ,
] ;
// ===================== 报表数据 =====================
export const MONTHLY_COUNTS = [
{ m : "2月" , count : 4 } , { m : "3月" , count : 6 } , { m : "4月" , count : 5 } ,
{ m : "5月" , count : 8 } , { m : "6月" , count : 7 } , { m : "7月" , count : 9 } ,
] ;
export const TYPE_DIST = [
{ name : "工艺" , value : 16 } , { name : "设备" , value : 14 } , { name : "管理" , value : 9 } ,
] ;
export const CYCLE_TREND = [
{ m : "2月" , days : 12.5 } , { m : "3月" , days : 11.2 } , { m : "4月" , days : 10.8 } ,
{ m : "5月" , days : 9.6 } , { m : "6月" , days : 8.9 } , { m : "7月" , days : 8.2 } ,
] ;
export const OVERDUE_LIST = [
{ id : "MOC-2026-R01-0039" , title : "V-102 安全阀起跳压力临时调整" , stage : "待关闭" , days : 4 } ,
{ id : "MOC-2026-R02-0031" , title : "冷冻盐水泵 P-103 叶轮材质变更" , stage : "待验收" , days : 7 } ,
{ id : "MOC-2026-R01-0029" , title : "操作规程修订(夏季工况)" , stage : "审批中" , days : 3 } ,
] ;
// 状态色阶梯:全站状态标签唯一来源(工作台 / 台账 / 我的任务 / 审批中心共用),
// 色相全部取自品牌色板——amber=进行中提醒,品牌蓝=审批通过/执行,violet=投用前检查,emerald=验收/完成(浅→深递进),品牌红=待关闭关闸提醒
export const STATUS_COLOR : Record < ChangeStatus , string > = {
审 批 中 : "bg-amber-100 text-amber-700 border-amber-200" ,
已 批 准 : "bg-[#DFE9F6] text-[#17407F] border-[#ACC6E5]" ,
实 施 中 : "bg-[#1D4E9C]/10 text-[#1D4E9C] border-[#1D4E9C]/30" ,
待 PSSR : "bg-violet-100 text-violet-700 border-violet-200" ,
待 验 收 : "bg-emerald-50 text-emerald-600 border-emerald-200" ,
待 关 闭 : "bg-[#E15555]/10 text-[#E15555] border-[#E15555]/30" ,
已 关 闭 : "bg-emerald-100 text-emerald-700 border-emerald-200" ,
} ;
export const LEVEL_COLOR : Record < ChangeLevel , string > = {
重 要 : "bg-red-100 text-red-700 border-red-200" ,
一 般 : "bg-slate-100 text-slate-600 border-slate-200" ,
} ;
// ===================== 变更台账 =====================
export interface LedgerRow {
id : string ;
changeId? : string ; // 关联 CHANGES,可打开完整详情
title : string ;
type : ChangeType ;
level : ChangeLevel ;
duration : "永久" | "临时" ;
urgent? : boolean ;
applyTime : string ; // 申请时间
dept : string ; // 申请部门
applicant : string ; // 申请人
planUse : string ; // 计划投用时间
status : ChangeStatus ;
statusDetail : string ; // 当前环节说明
statusTime : string ; // 状态更新时间
overdueDays? : number ;
approveTime? : string ; // 审批通过时间
useTime? : string ; // 实际投用时间
handlers : { name : string ; done : boolean } [ ] ; // 接班人(当前待办/已办)
}
export const LEDGER_ROWS : LedgerRow [ ] = [
{ id : "MOC-2026-R01-0035" , changeId : "MOC-2026-R01-0035" , title : "R-201 反应釜搅拌器电机更换(55kW→75kW 防爆电机)" , type : "设备" , level : "重要" , duration : "永久" , applyTime : "2026-07-28 09:12" , dept : "一车间" , applicant : "张工艺" , planUse : "2026-08-10" , status : "审批中" , statusDetail : "专业会签中(周设备、王仪表待签)" , statusTime : "2026-07-30 14:20" , handlers : [ { name : "王仪表" , done : true } , { name : "周设备" , done : false } , { name : "王仪表" , done : false } ] } ,
{ id : "MOC-2026-R01-0036" , changeId : "MOC-2026-R01-0036" , title : "聚合反应温度控制上限调整(78℃→82℃)" , type : "工艺" , level : "重要" , duration : "永久" , applyTime : "2026-07-25 10:05" , dept : "一车间" , applicant : "孙丽" , planUse : "2026-08-05" , status : "审批中" , statusDetail : "安全审查(王海燕)" , statusTime : "2026-07-29 16:40" , handlers : [ { name : "王海燕" , done : false } ] } ,
{ id : "MOC-2026-R02-0038" , changeId : "MOC-2026-R02-0038" , title : "DCS 罐区液位报警值 LIA-301 调整" , type : "工艺" , level : "一般" , duration : "永久" , applyTime : "2026-07-20 08:30" , dept : "一车间" , applicant : "吴强" , planUse : "2026-07-31" , status : "待PSSR" , statusDetail : "培训 / PSSR 资料已传 · 待确认投用" , statusTime : "2026-07-27 11:15" , approveTime : "2026-07-26 16:40" , handlers : [ { name : "吴强" , done : false } ] } ,
{ id : "MOC-2026-R01-0039" , changeId : "MOC-2026-R01-0039" , title : "V-102 安全阀起跳压力临时调整(紧急补办)" , type : "设备" , level : "一般" , duration : "临时" , urgent : true , applyTime : "2026-07-15 19:40" , dept : "一车间" , applicant : "张工艺" , planUse : "2026-07-16(已投用)" , status : "待关闭" , statusDetail : "待关闭确认(资料更新核查中)" , statusTime : "2026-07-27 09:02" , approveTime : "2026-07-15 21:05" , useTime : "2026-07-16 06:30" , overdueDays : 4 , handlers : [ { name : "李主任" , done : false } ] } ,
{ id : "MOC-2026-R03-0040" , changeId : "MOC-2026-R03-0040" , title : "原料环己烷供应商变更(新增 B 供应商)" , type : "管理" , level : "重要" , duration : "永久" , applyTime : "2026-07-18 14:22" , dept : "供应部" , applicant : "刘芳" , planUse : "2026-08-01" , status : "实施中" , statusDetail : "实施准备中 · 培训 / PSSR 资料待上传" , statusTime : "2026-07-26 10:30" , handlers : [ { name : "刘芳" , done : false } ] } ,
{ id : "MOC-2026-R02-0031" , title : "冷冻盐水泵 P-103 叶轮材质变更" , type : "设备" , level : "一般" , duration : "永久" , applyTime : "2026-06-28 09:50" , dept : "二车间" , applicant : "周涛" , planUse : "2026-07-15" , status : "待验收" , statusDetail : "变更验收(72h 运行验证)" , statusTime : "2026-07-24 15:44" , overdueDays : 7 , handlers : [ { name : "李主任" , done : false } ] } ,
{ id : "MOC-2026-R01-0029" , title : "操作规程修订(夏季工况)" , type : "管理" , level : "一般" , duration : "临时" , applyTime : "2026-06-20 11:26" , dept : "一车间" , applicant : "张工艺" , planUse : "2026-07-01" , status : "审批中" , statusDetail : "部门审核(李主任)" , statusTime : "2026-06-21 08:40" , handlers : [ { name : "李主任" , done : false } ] } ,
{ id : "MOC-2026-R02-0033" , title : "包装线贴标机控制程序升级" , type : "设备" , level : "一般" , duration : "永久" , applyTime : "2026-07-08 13:35" , dept : "二车间" , applicant : "吴强" , planUse : "2026-08-02" , status : "已批准" , statusDetail : "待实施(计划 8 月 2 日投用)" , statusTime : "2026-07-22 09:12" , handlers : [ { name : "周设备" , done : false } ] } ,
{ id : "MOC-2026-R03-0027" , title : "化验室通风橱整体更换" , type : "设备" , level : "一般" , duration : "永久" , applyTime : "2026-06-12 15:10" , dept : "质量部" , applicant : "陈静" , planUse : "2026-06-25" , status : "已关闭" , statusDetail : "关闭确认完成,已归档" , statusTime : "2026-07-02 10:18" , handlers : [ { name : "钱峰" , done : true } ] } ,
{ id : "MOC-2026-R01-0024" , title : "氮气管网压力分级调整" , type : "工艺" , level : "重要" , duration : "永久" , applyTime : "2026-05-30 09:00" , dept : "一车间" , applicant : "孙丽" , planUse : "2026-06-20" , status : "已关闭" , statusDetail : "关闭确认完成,已归档" , statusTime : "2026-06-28 16:30" , handlers : [ { name : "李主任" , done : true } , { name : "刘副总" , done : true } ] } ,
] ;
// 演示数据:执行阶段变更的培训签到表 / PSSR 签字版上传状态(上传即视为完成确认并随单归档,系统不做内容识别)
export const PSSR_UPLOADS : Record < string , { train ? : string ; pssr ? : string } > = {
"MOC-2026-R02-0038" : { train : "培训签到表-照片.jpg" , pssr : "PSSR 检查确认表-签字版.pdf" } ,
"MOC-2026-R02-0031" : { train : "培训签到表-照片.jpg" , pssr : "PSSR 检查确认表-签字版.pdf" } ,
"MOC-2026-R03-0027" : { train : "培训签到表-归档.pdf" , pssr : "PSSR 检查确认表-归档版.pdf" } ,
"MOC-2026-R01-0024" : { train : "培训签到表-归档.pdf" , pssr : "PSSR 检查确认表-归档版.pdf" } ,
} ;
// ===================== 演示用轻量全局状态(提交 / 审批真实推进,全站联动) =====================
type DemoListener = ( ) = > void ;
const demoListeners = new Set < DemoListener > ( ) ;
export function subscribeDemo ( fn : DemoListener ) {
demoListeners . add ( fn ) ;
return ( ) = > { demoListeners . delete ( fn ) ; } ;
}
function emitDemo() { demoListeners . forEach ( ( f ) = > f ( ) ) ; }
// ===================== 催办记录(车间主任催办 → 申请人操作台实时提示,全站同源) =====================
export interface UrgeRecord { id : string ; changeId : string ; title : string ; applicant : string ; by : string ; time : string ; }
export const URGE_RECORDS : UrgeRecord [ ] = [ ] ;
let urgeSeq = 1 ;
/** 车间主任催办:写入同源记录并广播,申请人操作台即时出现催办提示 */
export function urgeChange ( changeId : string , byRole : RoleId ) {
const row = LEDGER_ROWS . find ( ( r ) = > r . id === changeId || r . changeId === changeId ) ;
const c = CHANGES . find ( ( x ) = > x . id === changeId ) ;
const by = ROLES . find ( ( r ) = > r . id === byRole ) ? . person ? ? byRole ;
URGE_RECORDS . unshift ( {
id : ` URGE- ${ urgeSeq ++ } ` ,
changeId ,
title : row?.title ? ? c ? . title ? ? changeId ,
applicant : row?.applicant ? ? c ? . applicant ? ? "" ,
by ,
time : nowStr ( ) ,
} ) ;
emitDemo ( ) ;
}
let demoSeq = 43 ;
export function nextChangeId() {
return ` MOC-2026-R01- ${ String ( demoSeq ++ ) . padStart ( 4 , "0" ) } ` ;
}
function nowStr() {
const d = new Date ( ) ;
const p = ( n : number ) = > String ( n ) . padStart ( 2 , "0" ) ;
return ` ${ d . getFullYear ( ) } - ${ p ( d . getMonth ( ) + 1 ) } - ${ p ( d . getDate ( ) ) } ${ p ( d . getHours ( ) ) } : ${ p ( d . getMinutes ( ) ) } ` ;
}
/** 申请页提交:生成真实变更单,台账 / 审批中心 / 我的任务 / 角标联动 */
export function submitChange ( c : ChangeOrder ) {
CHANGES . unshift ( c ) ;
const cur = c . flow . find ( ( n ) = > n . status === "current" ) ;
LEDGER_ROWS . unshift ( {
id : c.id ,
changeId : c.id ,
title : c.title ,
type : c . type ,
level : c.level ,
duration : c.duration ,
urgent : c.urgent || undefined ,
applyTime : nowStr ( ) ,
dept : c.org.split ( "·" ) [ 0 ] . trim ( ) ,
applicant : c.applicant ,
planUse : c.date || "待定" ,
status : c.status ,
statusDetail : cur ? ` ${ cur . name } (待处理) ` : "审批中" ,
statusTime : nowStr ( ) ,
handlers : ( cur ? . roles ? ? [ ] ) . map ( ( rid ) = > ( { name : ROLES.find ( ( r ) = > r . id === rid ) ? . person ? ? rid , done : false } ) ) ,
} ) ;
emitDemo ( ) ;
}
/** 详情页同意:真实推进流程节点(会签按人标记,全签通过才流转;末节点后进入待PSSR) */
export function advanceFlow ( id : string , role : RoleId ) {
const c = CHANGES . find ( ( x ) = > x . id === id ) ;
if ( ! c ) return ;
const idx = c . flow . findIndex ( ( n ) = > n . status === "current" ) ;
if ( idx < 0 ) return ;
const node = c . flow [ idx ] ;
if ( node . kind === "会签" && node . members ) {
const person = ROLES . find ( ( r ) = > r . id === role ) ? . person ;
const m = node . members . find ( ( x ) = > x . name . startsWith ( person ? ? "" ) ) ;
if ( m ) m . done = true ;
if ( ! node . members . every ( ( x ) = > x . done ) ) { emitDemo ( ) ; return ; }
}
node . status = "done" ;
const next = c . flow [ idx + 1 ] ;
if ( next ) {
next . status = "current" ;
next . locked = false ;
} else {
c . status = "待PSSR" ;
}
const row = LEDGER_ROWS . find ( ( r ) = > r . changeId === id || r . id === id ) ;
if ( row ) {
const cur = c . flow . find ( ( n ) = > n . status === "current" ) ;
row . status = c . status ;
row . statusTime = nowStr ( ) ;
row . statusDetail = cur ? ` ${ cur . name } (待处理) ` : "审批完成,进入投用前确认" ;
row . handlers = cur
? cur . roles . map ( ( rid ) = > ( { name : ROLES.find ( ( r ) = > r . id === rid ) ? . person ? ? rid , done : false } ) )
: [ { name : c.applicant , done : false } ] ;
}
emitDemo ( ) ;
}
// ===================== 延期 / 转永久子单(申请人提交 → 属地 / 安全 / 公司领导审批 → 回写原单,全站联动) =====================
export interface SubOrder {
id : string ; // 子单号:原单号-Y1(延期)/ -Z1(转永久)
parentId : string ; // 原变更单号
parentTitle : string ;
kind : "extend" | "permanent" ;
applicant : string ;
reason : string ;
newDeadline? : string ; // 延期子单:申请延期至
status : "审批中" | "已通过" | "已驳回" ;
submitTime : string ;
steps : { role : RoleId ; name : string ; done : boolean } [ ] ; // 会签:全员同意即通过
rejectNote? : string ;
}
export const SUB_ORDERS : SubOrder [ ] = [ ] ;
/** 申请人提交延期 / 转永久子单:延期走简化审批(属地负责人 + 变更主管部门);转永久按永久变更审批链(属地 → 安全 → 公司领导) */
export function submitSubOrder ( o : { parentId : string ; parentTitle : string ; kind : "extend" | "permanent" ; applicant : string ; reason : string ; newDeadline? : string } ) {
const steps : SubOrder [ "steps" ] = o . kind === "extend"
? [ { role : "dept" , name : "李主任" , done : false } , { role : "safety" , name : "王海燕" , done : false } ]
: [ { role : "dept" , name : "李主任" , done : false } , { role : "safety" , name : "王海燕" , done : false } , { role : "vp" , name : "刘副总" , done : false } ] ;
SUB_ORDERS . unshift ( {
id : ` ${ o . parentId } - ${ o . kind === "extend" ? "Y1" : "Z1" } ` ,
. . . o ,
status : "审批中" ,
submitTime : nowStr ( ) ,
steps ,
} ) ;
emitDemo ( ) ;
return SUB_ORDERS [ 0 ] ;
}
/** 子单审批(同意 / 驳回):全员同意 → 已通过并回写原单;任一驳回 → 已驳回,申请人可修改后重新提交 */
export function decideSubOrder ( id : string , role : RoleId , approve : boolean , note? : string ) {
const s = SUB_ORDERS . find ( ( x ) = > x . id === id ) ;
if ( ! s || s . status !== "审批中" ) return ;
const st = s . steps . find ( ( x ) = > x . role === role ) ;
if ( ! st || st . done ) return ;
st . done = true ;
if ( ! approve ) {
s . status = "已驳回" ;
s . rejectNote = note || "" ;
} else if ( s . steps . every ( ( x ) = > x . done ) ) {
s . status = "已通过" ;
}
emitDemo ( ) ;
}
// ===================== 工作台 / 个人统计共享数据源(唯一口径,避免双写漂移) =====================
/** 临时变更到期监视(申请人工作台「临时变更到期提醒情况」与个人统计报表共用同一来源) */
export const TEMP_WATCH = [
{ label : "正常(到期 > 7 天)" , n : 1 , c : "#7CC242" , note : "循环水加药泵冲程临时调整 · 剩 17 天" } ,
{ label : "临期(到期 ≤ 7 天)" , n : 1 , c : "#F5A623" , note : "循环水旁滤器临时绕流运行 · 剩 6 天,已触发提醒" } ,
{ label : "已超期" , n : 1 , c : "#E15555" , note : "V-102 安全阀起跳压力临时调整 · 超期 4 天(已延期 1 次)" } ,
] ;
/** 培训确认待办(工作台「待确认培训」卡片与「我的任务 · 培训确认」同源) */
export const TRAIN_TODO = [
{ id : "MOC-2026-R01-0035" , title : "搅拌电机更换操作培训" , target : "R-201 岗位操作人员(4 人)、维修班(2 人)" } ,
] ;
/** 资料归档待办(工作台「待上传资料」卡片与「待我处理 · 资料关闭」同源:验收 / 归档材料补交) */
export const DOC_TODO = [
{ id : "MOC-2026-R02-0038" , title : "DCS 罐区液位报警值 LIA-301 调整" , missing : "验收报告与运行数据" } ,
{ id : "MOC-2026-R01-0039" , title : "紧急变更:V-102 安全阀起跳压力临时调整(补办手续)" , missing : "更新后的 P&ID / 操作规程(受控最新版)、设备 / 联锁台账更新记录" } ,
] ;
/** 尚未关闭变更状态分布:四段口径固定,数量从 CHANGES 实时推导(0 项也保留展示,保证口径稳定)
* 对应三大流转阶段:① 申请提交后 / 会签中 / 审批中;② 审批通过后 → 变更关闭前(含投用、验收);③ 变更关闭 */
export const OPEN_STAGES : { name : string ; match : ChangeStatus [ ] ; c : string } [ ] = [
{ name : "审批中(含会签)" , match : [ "审批中" ] , c : "#F5A623" } ,
{ name : "已批准待投用" , match : [ "已批准" , "待PSSR" , "实施中" ] , c : "#1D4E9C" } ,
{ name : "待验收" , match : [ "待验收" ] , c : "#7CC242" } ,
{ name : "待关闭" , match : [ "待关闭" ] , c : "#E15555" } ,
] ;
export function countOpenStatus ( list : { status : ChangeStatus } [ ] ) {
return OPEN_STAGES . map ( ( s ) = > ( { name : s.name , c : s.c , n : list.filter ( ( x ) = > s . match . includes ( x . status ) ) . length } ) ) ;
}
// ===================== 统一待办推导(全站同源:工作台卡片 / 侧边栏角标 / 我的任务 / 审批中心) =====================
/** 判断变更是否停在当前角色的待办节点。
* 会签节点按成员粒度判定:已签署的成员(按角色对应人员姓名匹配)不再计入其待办。 */
export function isPendingFor ( c : ChangeOrder , role : RoleId ) : boolean {
if ( c . status !== "审批中" ) return false ;
const node = c . flow . find ( ( n ) = > n . status === "current" ) ;
if ( ! node ) return false ;
if ( node . kind === "会签" && node . members && node . members . length > 0 ) {
const person = ROLES . find ( ( r ) = > r . id === role ) ? . person ;
const me = person ? node . members . find ( ( m ) = > m . name . startsWith ( person ) ) : undefined ;
if ( me ) return ! me . done ;
}
return node . roles . includes ( role ) ;
}
/** 当前角色的实时待审批变更列表(唯一数据源) */
export function pendingApprovals ( role : RoleId ) : ChangeOrder [ ] {
return CHANGES . filter ( ( c ) = > isPendingFor ( c , role ) ) ;
}
/** 执行阶段(审批通过后 → 关闭前)的变更:投用准备与验收跟踪 */
export function executionStage ( list : ChangeOrder [ ] = CHANGES ) : ChangeOrder [ ] {
return list . filter ( ( c ) = > c . status === "待PSSR" || c . status === "待验收" ) ;
}
/** 超期未关闭变更(待关闭且已超期) */
export function overdueClosing ( list : ChangeOrder [ ] = CHANGES ) : ChangeOrder [ ] {
return list . filter ( ( c ) = > c . status === "待关闭" && ( c . overdueDays ? ? 0 ) > 0 ) ;
}
/** 专业人员「技术把关工作记录」:从 CHANGES 实时推导(与台账 / 待办同源,演示数据范围内统计)
* - signed:已完成的会签 / 审批签署次数(会签按成员粒度、审批节点按角色判定)
* - involved:涉及本专业的在办变更数(未关闭且流程中含本角色节点)
* - 驳回次数暂无结构化记录字段,演示版不展示;参与风险分析次数来自分析组成员(选择式)记录 */
export function profWorkStats ( role : RoleId ) {
const person = ROLES . find ( ( r ) = > r . id === role ) ? . person ? ? "" ;
let signed = 0 ;
for ( const c of CHANGES ) {
for ( const n of c . flow ) {
if ( n . kind === "会签" && n . members ? . length ) {
const me = n . members . find ( ( m ) = > m . name . startsWith ( person ) ) ;
if ( me ? . done ) signed += 1 ;
} else if ( n . status === "done" && n . roles . includes ( role ) ) {
signed += 1 ;
}
}
}
const involved = CHANGES . filter (
( c ) = > c . status !== "已关闭" && c . flow . some ( ( n ) = > n . roles . includes ( role ) )
) . length ;
return { signed , involved } ;
}