# RuoYi 3.9.2 前端合入清单 > **编制日期**: 2026-06-04 > **基线**: RuoYi-Vue3 v3.9.2 (2026-03-26) > **目标**: 从 RuoYi 3.9.2 合入高价值前端组件,不破坏现有业务 --- ## 执行原则 1. **渐进式合入** — 每次只合一个组件,验证通过再合下一个 2. **保留业务代码** — `com.openhis.*` 目录不动,只改脚手架层 3. **兼容优先** — 优先合入无侵入的独立组件 4. **验证必做** — 每步完成后跑 `npm run dev` + 核心页面冒烟 --- ## Phase A: 基础设施修复(0.5 天) ### A.1 修复 router4 过期写法 `next()` | 项 | 内容 | |---|---| | **文件** | `src/permission.js` | | **变更** | `next()` → `return { path: '/' }` / `return true` / `return false` | | **参考** | RuoYi 3.9.2 `src/permission.js` 第 1-76 行 | | **风险** | 🟡 中 — 所有路由跳转都经过这里 | | **验证** | 登录→首页→各菜单跳转→返回→刷新→404页→白名单 | **具体变更点:** ``` // 旧写法 (我们当前) router.beforeEach((to, from, next) => { if (getToken()) { if (to.path === '/login') { next({ path: '/' }) } else { if (useUserStore().roles.length === 0) { // ... next({ ...to, replace: true }) } else { next() } } } else { next(`/login?redirect=${to.fullPath}`) } }) // 新写法 (RuoYi 3.9.2) router.beforeEach(async (to, from) => { if (getToken()) { if (to.path === '/login') { return { path: '/' } } if (useUserStore().roles.length === 0) { // ... return { ...to, replace: true } } return true } else { return `/login?redirect=${to.fullPath}` } }) ``` --- ### A.2 引入通配符白名单匹配 | 项 | 内容 | |---|---| | **文件** | `src/utils/validate.js` | | **变更** | 新增 `isPathMatch(pattern, path)` 函数 | | **参考** | RuoYi 3.9.2 `src/utils/validate.js` | | **风险** | 🟢 低 — 纯新增函数 | | **验证** | 白名单路径 `/login`、`/register` 仍正常 | --- ## Phase B: 核心组件合入(2-3 天) ### B.1 TreePanel 树分割组件 | 项 | 内容 | |---|---| | **来源** | RuoYi 3.9.2 `src/components/TreePanel/` | | **目标** | 我们的 `src/components/TreePanel/`(新建) | | **依赖** | Element Plus Tree + Table | | **风险** | 🟢 低 — 独立组件,不影响现有代码 | | **验证** | 新建一个测试页面引入 TreePanel,确认左右分栏正常 | **HIS 适用场景:** - 基础管理 → 组织机构(左树右表) - 基础管理 → 药品目录(左分类右列表) - 数据字典 → 分类管理 - 病区管理 → 病区/床位 --- ### B.2 ExcelImportDialog 导入组件 | 项 | 内容 | |---|---| | **来源** | RuoYi 3.9.2 `src/components/ExcelImportDialog/` | | **目标** | 我们的 `src/components/ExcelImportDialog/`(新建) | | **依赖** | Element Plus Dialog + Upload | | **风险** | 🟢 低 — 独立组件 | | **验证** | 上传 Excel → 预览 → 确认导入 | **HIS 适用场景:** - 基础管理 → 药品批量导入 - 基础管理 → 诊断目录导入 - 基础管理 → 医保目录同步 - 患者管理 → 批量建档 --- ### B.3 锁屏功能 | 项 | 内容 | |---|---| | **来源** | RuoYi 3.9.2 | | **涉及文件** | `src/store/modules/lock.js`(新增)
`src/views/lock.vue`(新增)
`src/permission.js`(加锁屏拦截)
`src/store/modules/user.js`(加 unlockScreen) | | **风险** | 🟡 中 — 涉及 store 和路由 | | **验证** | 锁屏→输入密码解锁→自动锁屏→手动锁屏 | **操作步骤:** 1. 复制 `lock.js` 到 `src/store/modules/` 2. 复制 `lock.vue` 到 `src/views/` 3. 修改 `permission.js` 添加锁屏路由检查 4. 修改 `user.js` 登录成功后调用 `unlockScreen()` 5. 在 Navbar 添加锁屏按钮 --- ### B.4 密码规则校验 | 项 | 内容 | |---|---| | **来源** | RuoYi 3.9.2 `src/utils/passwordRule.js` | | **目标** | 我们的 `src/utils/passwordRule.js`(新增) | | **风险** | 🟢 低 — 独立工具函数 | | **验证** | 修改密码页测试密码强度校验 | --- ## Phase C: Layout 增强(1-2 天) ### C.1 HeaderNotice 顶部通知 | 项 | 内容 | |---|---| | **来源** | RuoYi 3.9.2 `src/layout/components/HeaderNotice/` | | **目标** | 我们的 `src/layout/components/HeaderNotice/`(新增) | | **依赖** | 我们已有的通知公告接口 | | **风险** | 🟢 低 — 新增组件 | | **验证** | 顶部显示通知铃铛 → 点击展开通知列表 | --- ### C.2 TopBar 顶部工具栏 | 项 | 内容 | |---|---| | **来源** | RuoYi 3.9.2 `src/layout/components/TopBar/` | | **目标** | 我们的 `src/layout/components/TopBar/`(新增) | | **风险** | 🟡 中 — 需要修改 `layout/index.vue` 引入 | | **验证** | 顶部工具栏显示搜索、全屏、通知等 | --- ### C.3 Copyright 版权组件 | 项 | 内容 | |---|---| | **来源** | RuoYi 3.9.2 `src/layout/components/Copyright/` | | **目标** | 我们的 `src/layout/components/Copyright/`(新增) | | **风险** | 🟢 低 | | **验证** | 侧边栏底部显示版权信息 | --- ## Phase D: 持久化标签页增强(0.5 天) ### D.1 TagsView 持久化 | 项 | 内容 | |---|---| | **文件** | `src/store/modules/tagsView.js` | | **变更** | 从 RuoYi 3.9.2 复制增强版 | | **新增功能** | 刷新后保持标签页状态、Chrome 风格标签页 | | **风险** | 🟡 中 — 替换现有 store | | **验证** | 打开多个标签 → 刷新页面 → 标签页仍在 → 关闭浏览器重开 → 标签页恢复 | --- ## Phase E: 后端小版本升级(30 分钟) ### E.1 依赖版本升级 | 组件 | 当前 | 升级到 | 文件 | |---|---|---|---| | Druid | 1.2.27 | 1.2.28 | `pom.xml` | | Fastjson2 | 2.0.58 | 2.0.61 | `pom.xml` | | OSHI | 6.6.5 | 6.10.0 | `pom.xml` | | Commons IO | 2.13.0 | 2.21.0 | `pom.xml` | | BouncyCastle | bcprov-jdk15on 1.69 | bcprov-jdk18on 1.80 | `pom.xml` | **操作:** ```bash cd openhis-server-new mvn clean package -DskipTests # 验证启动正常 ``` --- ## Phase F: 前端依赖升级(30 分钟) ### F.1 版本号更新 | 组件 | 当前 | 升级到 | 风险 | |---|---|---|---| | vue-router | ^4.3.0 | ^4.6.4 | 🟢 低 | | echarts | ^5.4.3 | ^5.6.0 | 🟢 低 | | element-plus | ^2.14.1 | 保持 | ✅ 我们更新 | | @vueuse/core | ^14.3.0 | 保持 | ✅ 我们更新 | **操作:** ```bash cd openhis-ui-vue3 npm install vue-router@^4.6.4 echarts@^5.6.0 npm run dev # 验证无报错 ``` --- ## 执行顺序 ``` Day 1 上午: A.1 (permission.js router4 修复) + A.2 (validate.js) Day 1 下午: E.1 (后端小版本升级) + F.1 (前端依赖升级) Day 2 上午: B.1 (TreePanel) + B.2 (ExcelImportDialog) Day 2 下午: B.3 (锁屏功能) + B.4 (密码规则) Day 3 上午: C.1 (HeaderNotice) + C.2 (TopBar) + C.3 (Copyright) Day 3 下午: D.1 (TagsView 持久化) + 全量验证 ``` --- ## 验证清单 每步完成后逐项检查: - [ ] `npm run dev` 无报错 - [ ] 登录页正常 - [ ] 首页加载正常 - [ ] 菜单导航正常 - [ ] 各业务模块页面正常(至少抽查 5 个) - [ ] 表格渲染正常(VXE Table) - [ ] 打印功能正常(vue-plugin-hiprint) - [ ] 权限控制正常(hasPermi 指令) --- ## 风险控制 | 风险 | 缓解 | |---|---| | permission.js 改坏导致无法登录 | 备份当前文件,改完立即测试登录流程 | | store 变更导致状态丢失 | 测试登录→刷新→各页面切换 | | 新组件与现有样式冲突 | 先在独立页面测试,确认无冲突再引入 layout | | npm 依赖冲突 | 锁版本,避免自动升级无关依赖 |