diff --git a/src/service/api/role.ts b/src/service/api/role.ts index 7613329..363edfa 100644 --- a/src/service/api/role.ts +++ b/src/service/api/role.ts @@ -1,24 +1,24 @@ -import { request } from '../request'; - -/** 获取角色列表 - * - */ -export function roleListApi() { - return request({ url: '/api/role' }); -} -/** - * 登录 - * - * @param username User name - * @param password Password - */ -export function fetchLogin(username: string, password: string) { - return request({ - url: '/api/auth/login', - method: 'post', - data: { - username, - password - } - }); -} +import { request } from '../request'; + +/** 获取角色列表 + * + */ +export function roleListApi() { + return request({ url: '/api/role' }); +} +/** + * 登录 + * + * @param username User name + * @param password Password + */ +export function fetchLogin(username: string, password: string) { + return request({ + url: '/api/auth/login', + method: 'post', + data: { + username, + password + } + }); +} diff --git a/src/typings/model.ts b/src/typings/model.ts index ac8f255..7d82305 100644 --- a/src/typings/model.ts +++ b/src/typings/model.ts @@ -1,688 +1,688 @@ -// ===================== 数据模型与 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 = { - 审批中: "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 = { - 重要: "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 = { - "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(); -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 }; -} +// ===================== 数据模型与 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 = { + 审批中: "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 = { + 重要: "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 = { + "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(); +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 }; +} diff --git a/src/views/changeLedger/myChanges/index.vue b/src/views/changeLedger/myChanges/index.vue index c7736ce..325a754 100644 --- a/src/views/changeLedger/myChanges/index.vue +++ b/src/views/changeLedger/myChanges/index.vue @@ -1,688 +1,688 @@ - - - - - - + + + + + + diff --git a/src/views/changeLedger/workshopChanges/index.vue b/src/views/changeLedger/workshopChanges/index.vue index c002bfe..44c512d 100644 --- a/src/views/changeLedger/workshopChanges/index.vue +++ b/src/views/changeLedger/workshopChanges/index.vue @@ -1,688 +1,688 @@ - - - - - - + + + + + + diff --git a/src/views/changeStatistics/index.vue b/src/views/changeStatistics/index.vue index 4f6bd64..fee9e2a 100644 --- a/src/views/changeStatistics/index.vue +++ b/src/views/changeStatistics/index.vue @@ -1,246 +1,246 @@ - - - - - + + + + + diff --git a/src/views/changeStatistics/modules/pieChart.vue b/src/views/changeStatistics/modules/pieChart.vue index 376a702..2078588 100644 --- a/src/views/changeStatistics/modules/pieChart.vue +++ b/src/views/changeStatistics/modules/pieChart.vue @@ -1,63 +1,63 @@ - - - - - + + + + + diff --git a/src/views/changeStatistics/modules/pieChart2.vue b/src/views/changeStatistics/modules/pieChart2.vue index 376a702..2078588 100644 --- a/src/views/changeStatistics/modules/pieChart2.vue +++ b/src/views/changeStatistics/modules/pieChart2.vue @@ -1,63 +1,63 @@ - - - - - + + + + + diff --git a/src/views/docs/archives/index.vue b/src/views/docs/archives/index.vue index 459b9a0..20b2cc0 100644 --- a/src/views/docs/archives/index.vue +++ b/src/views/docs/archives/index.vue @@ -1,236 +1,236 @@ - - - - - - + + + + + + diff --git a/src/views/docs/query/index.vue b/src/views/docs/query/index.vue index ba22a37..6219c38 100644 --- a/src/views/docs/query/index.vue +++ b/src/views/docs/query/index.vue @@ -1,332 +1,332 @@ - - - - - - + + + + + + diff --git a/src/views/factoryOverview/index.vue b/src/views/factoryOverview/index.vue index 691dc44..7d116cf 100644 --- a/src/views/factoryOverview/index.vue +++ b/src/views/factoryOverview/index.vue @@ -1,213 +1,213 @@ - - - - - + + + + + diff --git a/src/views/factoryOverview/modules/columnChart.vue b/src/views/factoryOverview/modules/columnChart.vue index b112e22..0e5f285 100644 --- a/src/views/factoryOverview/modules/columnChart.vue +++ b/src/views/factoryOverview/modules/columnChart.vue @@ -1,90 +1,90 @@ - - - - - + + + + + diff --git a/src/views/my/closeConfirm/index.vue b/src/views/my/closeConfirm/index.vue index 0e24336..c16fc46 100644 --- a/src/views/my/closeConfirm/index.vue +++ b/src/views/my/closeConfirm/index.vue @@ -1,213 +1,213 @@ - - -