删除演示页面

This commit is contained in:
2026-09-10 15:06:28 +08:00
parent c36a5bbc85
commit db8100130a
8 changed files with 1 additions and 432 deletions
-2
View File
@@ -232,8 +232,6 @@ const local: App.I18n.Schema = {
my_mytask: '我的任务',
my_mydraft: '我的草稿',
my_pending: '待我处理',
my_process: '流程演示',
my_processdetail: '流程演示详情',
my_pendingchange: '待投用变更',
my_effect: '变更投入和效果',
my_datachangecenter: '变更数据中心',
-2
View File
@@ -36,8 +36,6 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
my_mytask: () => import("@/views/my/myTask/index.vue"),
my_pending: () => import("@/views/my/pending/index.vue"),
my_pendingchange: () => import("@/views/my/pendingChange/index.vue"),
my_process: () => import("@/views/my/process/index.vue"),
my_processdetail: () => import("@/views/my/processDetail/index.vue"),
my_pssr: () => import("@/views/my/pssr/index.vue"),
report: () => import("@/views/report/index.vue"),
riskstatistics: () => import("@/views/riskStatistics/index.vue"),
-19
View File
@@ -248,25 +248,6 @@ export const generatedRoutes: GeneratedRoute[] = [
i18nKey: 'route.my_pendingchange'
}
},
{
name: 'my_process',
path: '/my/process',
component: 'view.my_process',
meta: {
title: '流程演示',
i18nKey: 'route.my_process'
}
},
{
name: 'my_processdetail',
path: '/my/processdetail',
component: 'view.my_processdetail',
meta: {
title: '流程演示详情',
hideInMenu: true,
i18nKey: 'route.my_processdetail'
}
},
{
name: 'my_pssr',
path: '/my/pssr',
-2
View File
@@ -187,8 +187,6 @@ const routeMap: RouteMap = {
"my_mytask": "/my/mytask",
"my_pending": "/my/pending",
"my_pendingchange": "/my/pendingchange",
"my_process": "/my/process",
"my_processdetail": "/my/processdetail",
"my_pssr": "/my/pssr",
"report": "/report",
"riskstatistics": "/riskstatistics",
-4
View File
@@ -41,8 +41,6 @@ declare module "@elegant-router/types" {
"my_mytask": "/my/mytask";
"my_pending": "/my/pending";
"my_pendingchange": "/my/pendingchange";
"my_process": "/my/process";
"my_processdetail": "/my/processdetail";
"my_pssr": "/my/pssr";
"report": "/report";
"riskstatistics": "/riskstatistics";
@@ -135,8 +133,6 @@ declare module "@elegant-router/types" {
| "my_mytask"
| "my_pending"
| "my_pendingchange"
| "my_process"
| "my_processdetail"
| "my_pssr"
| "report"
| "riskstatistics"
+1 -1
View File
@@ -159,7 +159,7 @@ const getAllFormData = () => {
risk_records:changeRiskForm,
train:{...changeTrainingForm},
pssr:{items:allItems},
accept_form:{items:evaluationForm,purposes:changeApplyForm?.purposes,effect:changeApplyForm?.effect},
accept_form:{items:evaluationForm},
};
}
-218
View File
@@ -1,218 +0,0 @@
<script setup lang="ts">
import { ref } from 'vue';
import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme';
import { useRouterPush } from '@/hooks/common/router';
const { routerPushByKey } = useRouterPush();
const themeStore = useThemeStore();
interface FlowStep {
stage: string;
actor: string;
role?: string;
title: string;
detail?: string;
system?: string;
time: string;
branch?: string;
}
interface Scenario {
id: string; no: string; title: string; changeName: string;
tags: { text: string; cls: string }[];
desc: string; stages: string[]; steps: FlowStep[];
}
const T = {
perm: "border-[#ACC6E5] bg-[#DFE9F6] text-[#1D4E9C]",
temp: "border-amber-200 bg-amber-50 text-amber-700",
general: "bg-slate-100 text-slate-600",
major: "border-red-200 bg-red-50 text-red-600",
urgent: "border-red-600 bg-red-600 text-white",
branch: "border-violet-200 bg-violet-50 text-violet-600",
};
const STAGE_MAIN = ["变更申请", "会签与审批", "投用前确认", "投用", "验收", "关闭"];
const STAGE_TEMP = ["变更申请", "会签与审批", "投用前确认", "投用", "临时运行与恢复", "验收", "关闭"];
const SCENARIOS: Scenario[] = [
{
id: "s1", no: "示例 1", title: "永久 · 一般变更 全流程",
changeName: "MOC-2026-R01-0041「缩合反应温度及时间优化」",
tags: [{ text: "永久", cls: T.perm }, { text: "一般", cls: T.general }],
desc: "覆盖:AI 识别 → 申请表 → 风险分析 → 培训/PSSR/验收/关闭表生成 → 部门审核 → 专业会签 → 最终批准 → 培训签到 → PSSR → 确认投用 → 验收 → 关闭归档。",
stages: STAGE_MAIN,
steps: [
{ stage: "变更申请", actor: "张工艺", role: "车间工程师", title: "录入变更描述,AI 完成变更识别", detail: "判定为「变更」(非同类替换):反应温度 80℃→90℃、保温 8h→4h、DCS 报警/联锁值上调等 4 项前后对比,输出所需材料清单;识别结果人工确认,可直接修改", system: "AI 识别完成,自动预填变更前后对比表", time: "08-01 09:12" },
{ stage: "变更申请", actor: "张工艺", title: "生成变更申请表", detail: "AI 自动总结名称「缩合反应温度及时间优化」(28 字内);类型判定:工艺;等级评分 12 分 → 一般变更;时限:永久;上传小试报告、杂质分析等附件", system: "附件版本受控,变更编号 MOC-2026-R01-0041 生成", time: "08-01 09:40" },
{ stage: "变更申请", actor: "张工艺", title: "AI 风险预分析,形成风险分析记录表", detail: "输出危害严重性 / 事件概率 / 保护层影响预分析;系统按规则推荐 HAZOP + 检查表法(支持手动重选),形成风险分析记录与管控措施", system: "预分析报告经人工确认后生效", time: "08-01 10:05" },
{ stage: "变更申请", actor: "张工艺", title: "生成培训 / PSSR / 验收评价 / 关闭确认表,提交审批", detail: "验收评价按预期效果量化:转化率 ≥98%、保温 4h±0.5h、杂质 ≤0.15% 等 5 项;选择审批人后提交", system: "进入一般变更审批流,企业微信 + 短信通知李主任", time: "08-01 10:20" },
{ stage: "会签与审批", actor: "李主任", role: "车间主任", title: "部门审核:同意", detail: "AI 审批辅助:强制合规提示(联锁测试投用前完成)、冲突提示(无冲突)、关键参数对比;意见:变更方案可行,同意", system: "审批留痕,流转专业会签", time: "08-01 14:32" },
{ stage: "会签与审批", actor: "王仪表", role: "专业会签 · 仪表", title: "专业会签:同意", detail: "核对 DCS 高报 85→95℃、联锁 90→100℃ 整定方案;采纳 AI 建议「联锁测试记录投用前完成」为行动项", system: "行动项自动写入 PSSR 清单,会签进度 1/2", time: "08-02 09:15" },
{ stage: "会签与审批", actor: "周设备", role: "专业会签 · 设备", title: "专业会签:同意(会签完成 2/2)", detail: "确认保温更换与紧固件方案满足要求", system: "全体会签通过,流转最终批准", time: "08-02 10:40" },
{ stage: "会签与审批", actor: "李主任", role: "部门负责人", title: "最终批准,变更下达实施", system: "自动生成培训任务与 PSSR 行动项并推送相关人员;状态 → 投用前确认;发布「审批通过」公告", time: "08-02 11:05" },
{ stage: "投用前确认", actor: "岗位人员(4 人)+ 维修班(2 人)", title: "培训签到与考核", detail: "扫码签到 + 现场提问考核合格;维修班拍照上传纸质签到表", system: "签到与考核记录自动归档至变更档案", time: "08-03 15:00" },
{ stage: "投用前确认", actor: "周设备 / 王仪表", title: "PSSR 逐项确认", detail: "联锁校核记录上传、送电前容量校核、保温验收;移动端现场拍照上传", system: "全部完成,自动推送属地负责人「具备投用条件」", time: "08-04 10:30" },
{ stage: "投用", actor: "李主任", role: "属地负责人", title: "确认投用", detail: "投用时间默认当前日期时间,手动确认为 08-05 08:30", system: "状态 → 实施中;发布「确定投用」公告", time: "08-05 08:30" },
{ stage: "验收", actor: "车间 + 各专业", title: "投用后验收评估", detail: "72h 运行验证 + 连续 3 批化验:转化率 98.6%(完全达到)、保温 4h(完全达到)、杂质 0.11%(完全达到)、温控联锁动作正确(完全达到)", system: "验收结论留痕:完全达到", time: "08-08 16:00" },
{ stage: "关闭", actor: "变更主管部门专人", title: "变更关闭确认", detail: "8 项资料全部归档、行动项全部关闭,系统推送专人;关闭确认表 AI 辅助判定逐项核对", system: "记录关闭时间,台账 → 已关闭;发布「变更关闭」公告", time: "08-09 09:20" },
],
},
{
id: "s2", no: "示例 2", title: "永久 · 重要变更 全流程",
changeName: "MOC-2026-R01-0035「R-201 反应釜搅拌器电机更换(55kW→75kW 防爆电机)」",
tags: [{ text: "永久", cls: T.perm }, { text: "重要", cls: T.major }],
desc: "重要变更差异:等级评分 ≥20 分,审批流增加安全审查与公司领导终批,PSSR 需安全部门审核,投用由公司领导确认。",
stages: STAGE_MAIN,
steps: [
{ stage: "变更申请", actor: "张工艺", role: "车间工程师", title: "AI 变更识别:判定为变更(排除同类替换)", detail: "功率 55→75kW、防爆等级 ExdⅡBT4→ExdⅡCT4、额定电流 102A→138A,超出同类替换范围;输出前后对比与所需材料清单", system: "AI 类型预判:设备类", time: "07-28 09:12" },
{ stage: "变更申请", actor: "张工艺", title: "生成变更申请表", detail: "类型:设备;等级评分 21 分 → 重要变更;时限:永久;上传变更方案、设备数据表、防爆合格证、电气负荷校核计算书", system: "编号 MOC-2026-R01-0035;按「重要变更」自动匹配审批流:部门审核 → 专业会签 → 安全审查 → 公司领导终批", time: "07-28 09:45" },
{ stage: "变更申请", actor: "张工艺", title: "风险分析:HAZOP + JSA + 检查表法", detail: "风险辨识会议(张工艺、王仪表、周设备、王海燕、李主任);4 项安全措施:联锁校核、送电前容量校核、培训考核、P&ID 与台账更新", system: "风险分析记录表随申请单一并提交", time: "07-29 13:32" },
{ stage: "会签与审批", actor: "李主任", role: "车间主任", title: "部门审核:同意", detail: "经综合评审,变更方案与风险管控措施可行", system: "审批留痕,流转专业会签", time: "07-29 08:31" },
{ stage: "会签与审批", actor: "王仪表 / 周设备 / 工艺专业", title: "专业会签:3/3 全部同意", detail: "王仪表核对联锁设定;周设备确认安装与校核方案;工艺专业确认运行窗口无变化", system: "会签全体通过,流转安全审查", time: "07-30 09:00" },
{ stage: "会签与审批", actor: "安全部", role: "安全审查", title: "安全审查:同意", detail: "强制合规项确认:联锁测试记录投用前完成并归档;防爆接合面检查纳入 PSSR", system: "审查留痕,流转公司领导终批", time: "07-30 15:20" },
{ stage: "会签与审批", actor: "刘副总", role: "公司领导", title: "最终批准", system: "变更下达实施;发布「审批通过」公告;培训与 PSSR 任务自动推送", time: "07-31 10:00" },
{ stage: "投用前确认", actor: "岗位人员", title: "培训签到与考核合格", system: "培训记录自动归档", time: "08-01 14:00" },
{ stage: "投用前确认", actor: "安全部", title: "PSSR 清单审核通过(重要变更)", detail: "审核现场检查项目与保护措施确认项", time: "08-02 09:00" },
{ stage: "投用前确认", actor: "周设备 / 王仪表", title: "现场 PSSR 逐项确认", detail: "联锁跳车试验记录、防爆接合面与格兰头检查、送电前校核;移动端拍照上传", system: "全部完成,推送属地负责人与公司领导", time: "08-03 11:00" },
{ stage: "投用", actor: "刘副总", role: "公司领导", title: "确认投用(重要变更由公司领导确认)", detail: "属地负责人确认条件具备后,公司领导确认投用 08-05 08:00", system: "状态 → 实施中;发布「确定投用」公告", time: "08-05 08:00" },
{ stage: "验收", actor: "车间 + 各专业", title: "验收评估", detail: "投用首周每班测温与振动记录:无过载跳闸(完全达到)、电流裕量 27%(完全达到)、批次合格率 +1.6%(完全达到)", system: "验收结论留痕", time: "08-12 17:00" },
{ stage: "关闭", actor: "变更主管部门专人", title: "关闭确认", detail: "资料归档齐全(含联锁测试记录、PSSR 现场照片、验收报告)", system: "记录关闭时间;发布「变更关闭」公告", time: "08-13 10:00" },
],
},
{
id: "s3", no: "示例 3", title: "临时 · 一般变更 全流程(3.1 到期恢复)",
changeName: "MOC-2026-R02-0052「夏季工况循环水旁路临时调整」",
tags: [{ text: "临时", cls: T.temp }, { text: "一般", cls: T.general }, { text: "3.1 到期恢复", cls: T.branch }],
desc: "临时变更差异:强制填写计划恢复时间,到期前 7 天系统提醒;本示例按「3.1 到期恢复原状」走通全流程。",
stages: STAGE_TEMP,
steps: [
{ stage: "变更申请", actor: "张工艺", role: "车间工程师", title: "AI 变更识别", detail: "循环水旁路阀开度由 30% 调整为 60%,应对夏季高温工况;判定为变更", time: "06-10 09:00" },
{ stage: "变更申请", actor: "张工艺", title: "生成变更申请表", detail: "类型:工艺;等级评分 10 分 → 一般;时限:临时(计划恢复时间 2026-09-15),非紧急", system: "临时变更强制填写计划恢复时间", time: "06-10 09:30" },
{ stage: "变更申请", actor: "张工艺", title: "风险分析并提交", detail: "AI 预分析 + 检查表法;验收评价:换热器出口温度 ≤42℃、无超温报警", system: "进入一般变更审批流", time: "06-10 10:00" },
{ stage: "会签与审批", actor: "李主任", role: "车间主任", title: "部门审核:同意", time: "06-10 14:00" },
{ stage: "会签与审批", actor: "王仪表 / 周设备", title: "专业会签:2/2 同意", time: "06-11 09:30" },
{ stage: "会签与审批", actor: "李主任", role: "部门负责人", title: "最终批准", system: "变更下达;发布「审批通过」公告", time: "06-11 10:20" },
{ stage: "投用前确认", actor: "岗位人员", title: "培训签到完成", system: "记录自动归档", time: "06-12 09:00" },
{ stage: "投用前确认", actor: "周设备", title: "PSSR 确认完成", detail: "旁路阀行程确认、温度仪表校验", system: "全部完成,推送属地负责人", time: "06-12 15:00" },
{ stage: "投用", actor: "李主任", role: "属地负责人", title: "确认投用 06-13 08:00", system: "台账标记「临时变更 · 计划恢复 09-15」;发布「确定投用」公告", time: "06-13 08:00" },
{ stage: "临时运行与恢复", actor: "系统", title: "到期前 7 天自动提醒", detail: "向申请人、属地负责人推送「临时变更将于 09-15 到期,请安排恢复原状」(企业微信 + 短信),每日复提", branch: "分支:到期恢复", time: "09-08 09:00" },
{ stage: "临时运行与恢复", actor: "张工艺", title: "现场恢复原状", detail: "旁路阀开度恢复至 30%,移动端拍照上传恢复确认", system: "恢复记录归档,推送属地确认", time: "09-10 10:00" },
{ stage: "临时运行与恢复", actor: "李主任", role: "属地负责人", title: "属地确认恢复完成", time: "09-10 15:00" },
{ stage: "验收", actor: "车间 + 各专业", title: "验收评估", detail: "临时运行期间换热器出口温度均值 39.8℃(完全达到)、无超温报警(完全达到)", time: "09-12 16:00" },
{ stage: "关闭", actor: "变更主管部门专人", title: "确认关闭(含恢复记录归档)", system: "记录关闭时间;发布「变更关闭」公告", time: "09-13 09:00" },
],
},
{
id: "s32", no: "示例 3.2", title: "临时 · 一般变更(延期一次,到期再恢复)",
changeName: "MOC-2026-R02-0052「夏季工况循环水旁路临时调整」(延续示例 3)",
tags: [{ text: "临时", cls: T.temp }, { text: "一般", cls: T.general }, { text: "3.2 延期后恢复", cls: T.branch }],
desc: "从到期提醒开始:延期申请 → 部门审批 → 到期时间更新(已延期 1 次)→ 新到期恢复 → 验收 → 关闭。",
stages: ["到期提醒", "延期申请与审批", "恢复", "验收", "关闭"],
steps: [
{ stage: "到期提醒", actor: "系统", title: "前置流程与示例 3 相同", detail: "申请 → 审批 → 培训 → PSSR → 投用(共 9 步)已于 06-13 完成,变更处于临时运行中", time: "06-13" },
{ stage: "到期提醒", actor: "系统", title: "到期前 7 天提醒", detail: "推送「将于 09-15 到期」;因高温天气持续,申请人决定办理延期", time: "09-08 09:00" },
{ stage: "延期申请与审批", actor: "张工艺", title: "发起延期申请", detail: "延期事项:计划恢复时间 09-15 → 10-15;理由:高温天气持续,装置仍需旁路运行;系统自动校验剩余延期次数(≤1 次)", branch: "分支:延期一次", time: "09-08 10:00" },
{ stage: "延期申请与审批", actor: "李主任", role: "部门负责人", title: "延期审批:同意", detail: "一般临时变更延期由部门负责人批准", system: "留痕并更新到期时间;台账标记「已延期 1 次」", time: "09-09 09:00" },
{ stage: "恢复", actor: "系统", title: "新到期日前 7 天再次提醒", time: "10-08 09:00" },
{ stage: "恢复", actor: "张工艺", title: "恢复原状 + 拍照上传", detail: "旁路阀开度恢复至 30%,移动端拍照上传", system: "恢复记录归档,推送属地确认", time: "10-10 10:00" },
{ stage: "恢复", actor: "李主任", role: "属地负责人", title: "属地确认恢复完成", time: "10-10 15:00" },
{ stage: "验收", actor: "车间 + 各专业", title: "验收评估:延期期间运行数据达标", detail: "出口温度均值 40.2℃(完全达到)、无超温报警(完全达到)", time: "10-12 16:00" },
{ stage: "关闭", actor: "变更主管部门专人", title: "确认关闭", system: "延期与恢复全程留痕可追溯;发布「变更关闭」公告", time: "10-13 09:00" },
],
},
{
id: "s33", no: "示例 3.3", title: "临时 · 一般变更(到期转化为永久)",
changeName: "MOC-2026-R02-0052「夏季工况循环水旁路临时调整」(延续示例 3)",
tags: [{ text: "临时", cls: T.temp }, { text: "一般", cls: T.general }, { text: "3.3 转为永久", cls: T.branch }],
desc: "从到期提醒开始:转永久申请 → AI 补充长期风险分析 → 按原等级审批 → 时限改判留痕、取消恢复期限 → 验收 → 关闭。",
stages: ["到期提醒", "转永久申请", "补充风险分析", "转永久审批", "验收", "关闭"],
steps: [
{ stage: "到期提醒", actor: "系统", title: "前置流程与示例 3 相同", detail: "已投用,变更处于临时运行中(计划恢复 09-15)", time: "06-13" },
{ stage: "到期提醒", actor: "系统", title: "到期前 7 天提醒", time: "09-08 09:00" },
{ stage: "转永久申请", actor: "张工艺", title: "发起「临时转永久」申请", detail: "理由:临时运行 3 个月效果稳定,夏季工况每年重现,建议转为永久;转永久后不再恢复原状", branch: "分支:转为永久", time: "09-08 10:30" },
{ stage: "补充风险分析", actor: "张工艺", title: "AI 重新分析长期运行风险", detail: "补充长期运行场景:旁路长期 60% 开度对换热器结垢的影响、冬季低负荷工况影响;更新管控措施", system: "风险分析记录版本 V2 留痕", time: "09-09 09:00" },
{ stage: "转永久审批", actor: "李主任", role: "车间主任", title: "部门审核:同意", time: "09-09 14:00" },
{ stage: "转永久审批", actor: "王仪表 / 周设备", title: "专业会签:同意", time: "09-10 09:00" },
{ stage: "转永久审批", actor: "李主任", role: "部门负责人", title: "批准转为永久变更", system: "变更时限「临时 → 永久」改判留痕;取消恢复期限与到期提醒", time: "09-10 10:00" },
{ stage: "验收", actor: "车间 + 各专业", title: "按永久变更标准验收", detail: "连续 30 天运行数据评估:温度、能耗指标全部达标(完全达到)", time: "10-10 16:00" },
{ stage: "关闭", actor: "变更主管部门专人", title: "确认关闭", system: "转永久审批记录并入变更档案;发布「变更关闭」公告", time: "10-12 09:00" },
],
},
{
id: "s4", no: "示例 4", title: "临时 · 重要变更 全流程",
changeName: "MOC-2026-R01-0039「V-102 安全阀起跳压力临时调整」",
tags: [{ text: "临时", cls: T.temp }, { text: "重要", cls: T.major }, { text: "紧急", cls: T.urgent }],
desc: "重要 + 临时 + 紧急:紧急标记各节点加急提醒当日办结,安全审查强制合规项,到期恢复起跳压力并重新校验。",
stages: STAGE_TEMP,
steps: [
{ stage: "变更申请", actor: "张工艺", role: "车间工程师", title: "AI 变更识别", detail: "V-102 安全阀起跳压力由 1.6MPa 临时调整为 1.45MPa(上游管网改造期间)", system: "紧急标记:安全生产需要,各节点加急提醒", time: "07-16 08:00" },
{ stage: "变更申请", actor: "张工艺", title: "生成变更申请表", detail: "类型:设备;等级评分 22 分 → 重要;时限:临时(计划恢复 08-30);紧急标记", system: "按「重要 + 紧急」匹配审批流并加急推送", time: "07-16 08:20" },
{ stage: "变更申请", actor: "张工艺", title: "风险分析:JSA + 检查表法 + AI 预分析", detail: "起跳压力下调后泄放能力复核、工艺波动场景评估", time: "07-16 09:00" },
{ stage: "会签与审批", actor: "李主任", role: "车间主任", title: "部门审核:同意(加急)", time: "07-16 10:00" },
{ stage: "会签与审批", actor: "王仪表 / 周设备 / 安全员", title: "专业会签:3/3 同意", detail: "安全阀校验报告复核、泄放量核算", time: "07-16 11:30" },
{ stage: "会签与审批", actor: "安全部", role: "安全审查", title: "安全审查:同意", detail: "强制合规:调整期间每班巡查记录、恢复后重新校验", time: "07-16 14:00" },
{ stage: "会签与审批", actor: "刘副总", role: "公司领导", title: "最终批准(加急)", system: "当日完成全部审批;发布「审批通过」公告", time: "07-16 15:30" },
{ stage: "投用前确认", actor: "岗位人员", title: "培训签到(新起跳压力与应急处置)", system: "记录自动归档", time: "07-17 09:00" },
{ stage: "投用前确认", actor: "安全部 / 周设备", title: "PSSR 确认", detail: "安全阀重新铅封、校验标签更新、巡查记录表就位", system: "全部完成,推送属地负责人与公司领导", time: "07-17 14:00" },
{ stage: "投用", actor: "刘副总", role: "公司领导", title: "确认投用(重要变更)", system: "状态 → 实施中;发布「确定投用」公告", time: "07-18 08:00" },
{ stage: "临时运行与恢复", actor: "系统", title: "到期前 7 天提醒(临时变更 08-30 到期)", branch: "分支:到期恢复", time: "08-23 09:00" },
{ stage: "临时运行与恢复", actor: "张工艺 / 周设备", title: "恢复起跳压力至 1.6MPa", detail: "安全阀重新校验、铅封,校验报告与现场照片上传", system: "恢复记录归档,推送属地确认", time: "08-25 10:00" },
{ stage: "验收", actor: "车间 + 各专业 + 安全部", title: "验收评估", detail: "调整期间无超压、无泄放事件;恢复后校验合格(完全达到)", time: "08-27 16:00" },
{ stage: "关闭", actor: "变更主管部门专人", title: "确认关闭", system: "记录关闭时间;发布「变更关闭」公告", time: "08-28 09:00" },
],
},
];
function open(item:any) {
routerPushByKey('home_processdetail', { query: { params: JSON.stringify(item) } })
}
</script>
<template>
<NSpace vertical :size="16">
<!-- 流程演示 -->
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
<div class="flex flex-wrap items-center gap-3 mb-3.5">
<span class="flex items-center gap-1.5 text-base font-bold text-slate-800">
<Icon icon="fluent:flow-dot-24-filled" class="size-22px" :style="{ color: themeStore.themeColor }" />全流程走通演示
</span>
<span class="text-xs text-slate-400">
6 个完整示例永久 / 临时 × 一般 / 重要含临时到期恢复延期转永久分支逐步推进查看每个环节的操作人与系统行为
</span>
</div>
<div class="space-y-2 scroll">
<div class="grid gap-3 grid-cols-2">
<div
v-for="s in SCENARIOS" :key="s.id"
class="flex flex-col border bg-white p-4 transition hover:border-[var(--hover-border-color)] hover:shadow-sm"
:style="{
borderRadius: themeStore.themeRadius + 'px',
'--hover-border-color': themeStore.themeColor,
}"
>
<div class="flex flex-wrap items-center gap-2">
<span class="text-sm font-bold" :style="{ color: themeStore.themeColor }">{{ s.no }}</span>
<span class="text-sm font-semibold text-slate-800">{{ s.title }}</span>
<NTag v-for="t in s.tags" :key="t.text" :class="t.cls" size="small">{{ t.text }}</NTag>
</div>
<div class="mt-1.5 text-xs text-slate-500">示例变更:{{ s.changeName }}</div>
<p class="mt-2 flex-1 text-xs leading-relaxed text-slate-400">{{ s.desc }}</p>
<div class="mt-3 flex items-center justify-between">
<span class="text-[11px] text-slate-400">{{ s.stages.length }} 个阶段 · {{ s.steps.length }} 个步骤</span>
<NButton type="primary" size="small" class="text-xs" @click="open(s)">
<Icon icon="griddy-icons:play" class="size-16px" /> 开始演示
</NButton>
</div>
</div>
</div>
</div>
</NCard>
</NSpace>
</template>
<style scoped>
</style>
<style scoped lang="scss">
.scroll {
height: calc(100vh - 185px);
overflow-y: auto;
}
</style>
-184
View File
@@ -1,184 +0,0 @@
<script setup lang="ts">
import { onMounted, ref, computed, watch } from 'vue';
import { Icon } from '@iconify/vue'
import { useThemeStore } from '@/store/modules/theme';
import { useRouterPush } from '@/hooks/common/router';
import { useRoute } from 'vue-router';
const route = useRoute();
const { routerPushByKey } = useRouterPush();
const themeStore = useThemeStore();
const sc = ref<any>(null);
const cur = ref<number>(0);
const playing = ref(false);
const curStageIdx = computed(() => (sc.value ? sc.value.stages.indexOf(sc.value.steps[cur.value].stage) : 0));
const finished = computed(() => (sc.value ? cur.value >= sc.value?.steps?.length - 1 : false));
const ROLES_NAME: Record<string, string> = {
applicant: "申请人(张工艺)", process: "专业会签(王仪表)", process2: "专业会签(周设备)",
safety: "安全工程师(王海燕)", dept: "车间主任(李主任)", vp: "分管领导(刘副总)", admin: "系统管理员",
quality: "质量工程师(陈质量)", viewer: "非审批人员(吴新)",
};
const VIEW_NAME: Record<string, string> = {
apply: "变更申请", tasks: "我的任务", approvals: "审批中心", execution: "PSSR / 验收", closure: "关闭管理",
};
let timer: ReturnType<typeof setTimeout> | undefined;
watch([playing, cur, sc], ([p, c, s]) => {
if (timer) { clearTimeout(timer); timer = undefined; }
if (!p || !s) return;
if (c >= s.steps.length - 1) { playing.value = false; return; }
timer = setTimeout(() => { cur.value = Math.min(cur.value + 1, (sc.value?.steps.length ?? 1) - 1); }, 2000);
});
function jumpFor(s: any): { role: string; view: string } | null {
const a = s.actor;
if (a === "系统") return null;
let role: string;
if (a.includes("张工艺")) role = "applicant";
else if (a.includes("李主任")) role = "dept";
else if (a.includes("王仪表")) role = "process";
else if (a.includes("周设备")) role = "process2";
else if (a.includes("刘副总")) role = "vp";
else if (a.includes("专人") || a.includes("安全")) role = "safety";
else if (a.includes("岗位") || a.includes("维修班")) role = "applicant";
else if (a.includes("车间")) role = "dept";
else return null;
let view: string;
if (role === "applicant") view = s.stage === "变更申请" ? "apply" : "tasks";
else if (s.stage.includes("审批")) view = "approvals";
else if (s.stage === "关闭") view = "closure";
else view = "execution";
return { role, view };
}
function prev() { playing.value = false; cur.value = Math.max(0, cur.value - 1); }
function next() { playing.value = false; if (sc.value) cur.value = Math.min(sc.value.steps.length - 1, cur.value + 1); }
function reset() { playing.value = false; cur.value = 0; }
function back() {
routerPushByKey("home_process");
}
function jumpTo() {
routerPushByKey("home_initiatechange");
}
onMounted(() => {
if(route.query && route.query.params){
sc.value = JSON.parse(route.query.params as string);
}
})
</script>
<template>
<NSpace vertical :size="16">
<!-- 流程演示详情 -->
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
<div class="space-y-3">
<div class="flex flex-wrap items-center gap-2">
<NButton ghost type="primary" class="text-sm font-medium" @click="back">
<Icon icon="ep:back" class="size-16px mr-1" /> 返回示例列表
</NButton>
<span class="text-base font-bold text-slate-800">{{ sc?.no }} {{ sc?.title }}</span>
<NTag size="small" v-for="t in sc?.tags" :key="t.text" :class="t.cls">{{ t.text }}</NTag>
<span class="text-xs text-slate-400">示例变更{{ sc?.changeName }}</span>
</div>
<!-- 阶段进度条 -->
<div class="flex items-center gap-1 overflow-x-auto rounded-lg border bg-white p-3">
<div v-for="(st, i) in sc?.stages" :key="st" class="flex shrink-0 items-center gap-1">
<span
class="flex items-center gap-1.5 rounded-full px-2.5 py-1 text-xs font-medium"
:class="i < curStageIdx ? 'bg-emerald-50 text-emerald-600' : i === curStageIdx ? 'bg-[var(--theme-color)] text-white' : 'bg-slate-100 text-slate-400'"
:style="{ '--theme-color': themeStore.themeColor }"
>
<Icon v-if="i < curStageIdx" icon="ix:success" class="size-14px" />
<span v-else class="flex h-3.5 w-3.5 items-center justify-center rounded-full border text-[10px]" :class="i === curStageIdx ? 'border-white' : 'border-slate-300'">{{ Number(i) + 1 }}</span>
{{ st }}
</span>
<Icon v-if="Number(i) < sc?.stages?.length - 1" icon="formkit:right" class="size-12px text-slate-300" />
</div>
</div>
<!-- 控制条 -->
<div class="flex flex-wrap items-center gap-2 rounded-lg border bg-white px-3 py-2">
<NButton ghost size="small" class="text-xs" :disabled="cur === 0" @click="prev">
<Icon icon="formkit:left" class="size-12px" /> 上一步
</NButton>
<NButton type="primary" size="small" class="text-xs text-white" :disabled="finished" @click="next">
下一步 <Icon icon="formkit:right" class="size-12px" />
</NButton>
<NButton ghost size="small" class="text-xs" :disabled="finished && !playing" @click="playing = !playing">
<template v-if="playing"><Icon icon="material-symbols:pause-outline-rounded" class="size-14px" /> 暂停</template>
<template v-else><Icon icon="griddy-icons:play" class="size-14px" /> 自动播放</template>
</NButton>
<NButton ghost size="small" class="text-xs" @click="reset">
<Icon icon="system-uicons:reset" class="size-12px" /> 重置
</NButton>
<span class="ml-auto text-xs text-slate-400"> {{ cur + 1 }} / {{ sc?.steps?.length }} {{ finished ? " · 流程已走通 ✓" : "" }}</span>
</div>
<!-- 完成横幅 -->
<div v-if="finished" class="flex flex-wrap items-center gap-2 rounded-lg border border-emerald-200 bg-emerald-50 px-4 py-2.5 text-sm text-emerald-700">
<Icon icon="ix:success" class="size-16px" />
<b>流程已走通</b> {{ sc.steps.length }} {{ sc.stages.length }} 个阶段全部闭环全程操作留痕资料归档公告发布完整可追溯
</div>
<!-- 步骤时间线 -->
<div class="space-y-2">
<div
v-for="(s, i) in sc?.steps" :key="i" @click="playing = false; cur = Number(i)"
class="flex w-full cursor-pointer items-start gap-3 rounded-lg border px-3 py-2.5 text-left transition"
:class="i === cur ? 'border-[var(--theme-color)] bg-[#EAF0F9]/50 shadow-sm' : Number(i) < cur ? 'border-emerald-100 bg-emerald-50/30' : 'bg-white hover:border-slate-300'"
:style="{ '--theme-color': themeStore.themeColor }"
>
<span
class="mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full text-[11px] font-bold"
:class="Number(i) < cur ? 'bg-emerald-500 text-white' : i === cur ? 'bg-[var(--theme-color)] text-white' : 'bg-slate-100 text-slate-400'"
:style="{ '--theme-color': themeStore.themeColor }"
>
<Icon v-if="Number(i) < cur" icon="ix:success" class="size-16px" />
<template v-else>{{ Number(i) + 1 }}</template>
</span>
<span class="min-w-0 flex-1">
<span class="flex flex-wrap items-center gap-x-2 gap-y-1">
<span class="flex items-center gap-1 text-xs text-slate-500">
<Icon icon="lucide:user-round" class="size-14px" />
{{ s.actor }}{{ s.role ? `${s.role}` : "" }}
</span>
<span class="rounded bg-slate-100 px-1.5 text-[10px] text-slate-400">{{ s.stage }}</span>
<span class="text-sm font-medium" :class="i === cur ? 'text-[#17407F]' : 'text-slate-700'">{{ s.title }}</span>
<NTag v-if="s.branch" class="border-violet-200 bg-violet-50 text-violet-600">{{ s.branch }}</NTag>
<span class="ml-auto shrink-0 font-mono text-[11px] text-slate-400">{{ s.time }}</span>
<NButton ghost type="primary" size="tiny" v-if="jumpFor(s) && s.actor !== '系统'"
class="text-[10px] font-medium"
:title="`切换到${ROLES_NAME[jumpFor(s)!.role]}的「${VIEW_NAME[jumpFor(s)!.view] ?? jumpFor(s)!.view}」界面`"
@click.stop="jumpTo"
>
进入界面
</NButton>
</span>
<span v-if="i === cur && (s.detail || s.system)" class="mt-2 block space-y-1.5 border-t border-[#ACC6E5]/40 pt-2">
<span v-if="s.detail" class="block text-xs leading-relaxed text-slate-600"><b class="text-slate-500">内容</b>{{ s.detail }}</span>
<span
v-if="s.system"
class="flex items-start gap-1.5 text-xs leading-relaxed"
:style="{ color: themeStore.themeColor }"
>
<Icon icon="lucide:sparkles" class="mt-0.8 size-12px" />{{ s.system }}
</span>
</span>
</span>
</div>
</div>
</div>
</NCard>
</NSpace>
</template>
<style scoped>
</style>
<style scoped lang="scss">
.scroll {
height: calc(100vh - 185px);
overflow-y: auto;
}
</style>