feat(frontend): 合入 RuoYi 3.9.2 前端升级

- 升级 vue-router 4.3 → 4.6.4 (router4 新写法)
- 升级 echarts 5.4 → 5.6.0
- 修复 permission.js router4 过期 next() 写法
- 新增 isPathMatch 通配符白名单匹配
- 新增 TreePanel 树分割组件 (左树右表)
- 新增 ExcelImportDialog 导入组件
- 新增锁屏功能 (lock.js + lock.vue)
- 新增密码规则校验 (passwordRule.js)
- 新增 HeaderNotice 顶部通知组件
- 新增 TopBar 顶部工具栏组件
- 新增 Copyright 版权组件
- 增强 TagsView 持久化标签页
- 添加升级计划文档 (UPGRADE_PLAN_v2.0.md)
This commit is contained in:
2026-06-04 10:17:27 +08:00
parent 1438b0e569
commit f144dd7e2c
22 changed files with 2809 additions and 162 deletions

View File

@@ -0,0 +1,275 @@
# 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`(新增)<br>`src/views/lock.vue`(新增)<br>`src/permission.js`(加锁屏拦截)<br>`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 依赖冲突 | 锁版本,避免自动升级无关依赖 |

64
docs/UPGRADE_LOG.md Normal file
View File

@@ -0,0 +1,64 @@
# OpenHIS 组件升级日志
> 每次升级后在此记录,方便跨 session 追踪进度。
---
## RuoYi 3.9.2 前端合入进度
### Phase A: 基础设施修复
- [x] A.1 permission.js router4 过期写法修复 ✅ 2026-06-04
- [x] A.2 validate.js 通配符匹配 isPathMatch ✅ 2026-06-04
### Phase B: 核心组件合入
- [x] B.1 TreePanel 树分割组件 ✅ 2026-06-04
- [x] B.2 ExcelImportDialog 导入组件 ✅ 2026-06-04
- [x] B.3 锁屏功能 (lock.js + lock.vue) ✅ 2026-06-04
- [x] B.4 密码规则校验 (passwordRule.js) ✅ 2026-06-04
### Phase C: Layout 增强
- [x] C.1 HeaderNotice 顶部通知 ✅ 2026-06-04
- [x] C.2 TopBar 顶部工具栏 ✅ 2026-06-04
- [x] C.3 Copyright 版权组件 ✅ 2026-06-04
### Phase D: 持久化标签页
- [x] D.1 TagsView 持久化增强 ✅ 2026-06-04
### Phase E: 后端小版本升级
- [ ] E.1 Druid 1.2.27 → 1.2.28
- [ ] E.1 Fastjson2 2.0.58 → 2.0.61
- [ ] E.1 OSHI 6.6.5 → 6.10.0
- [ ] E.1 Commons IO 2.13.0 → 2.21.0
- [ ] E.1 BouncyCastle 1.69 → 1.80
### Phase F: 前端依赖升级
- [x] F.1 vue-router ^4.3.0 → 4.6.4 ✅ 2026-06-04
- [x] F.1 echarts ^5.4.3 → 5.6.0 ✅ 2026-06-04
---
## 升级记录
### 2026-06-04 RuoYi 3.9.2 前端合入
**变更文件:**
- `src/permission.js` — router4 新写法 + 锁屏检查 + 通配符白名单
- `src/utils/validate.js` — 新增 isPathMatch + isEmpty
- `src/utils/passwordRule.js` — 新增密码规则校验
- `src/store/modules/lock.js` — 新增锁屏 store
- `src/store/modules/tagsView.js` — RuoYi 3.9.2 增强版
- `src/views/lock.vue` — 新增锁屏页面
- `src/router/index.js` — 新增 /lock 路由
- `src/api/login.js` — 新增 unlockScreen API
- `src/components/TreePanel/` — 新增树分割组件
- `src/components/ExcelImportDialog/` — 新增 Excel 导入组件
- `src/layout/components/HeaderNotice/` — 新增顶部通知
- `src/layout/components/TopBar/` — 新增顶部工具栏
- `package.json` — vue-router 4.6.4 + echarts 5.6.0
**验证结果:**
- ✅ npm run build:dev 编译成功 (1m 41s)
- ✅ 前端 HTTP 200
- ✅ API 代理 HTTP 200
- ✅ 1825 文件107M

171
docs/UPGRADE_PLAN_v2.0.md Normal file
View File

@@ -0,0 +1,171 @@
# OpenHIS 二次开发版本 — 组件升级计划
> **编制日期**: 2026-06-03
> **对比基线**: Gitee `tntlinking-opensource/openhis-itai-pro` 2.0 分支
> **目标**: 在不破坏现有业务的前提下,逐步引入高价值组件升级
---
## 升级原则
1. **独立可验证** — 每个 Phase 完成后必须独立通过编译 + 冒烟测试
2. **不破坏业务** — 一次只升级一个组件,出问题可快速回滚
3. **先补丁后重构** — 小版本升级直接改版本号,大版本升级单独评估
4. **文档同步** — 每次升级后更新 `UPGRADE_LOG.md`
---
## Phase 0: 安全修复(预估 0.5 天)
> 🔴 **最高优先级** — 安全漏洞,必须立即处理
### 0.1 BouncyCastle 1.69 → 1.80
| 项目 | 详情 |
|---|---|
| **文件** | `openhis-server-new/pom.xml` |
| **变更** | `<bcprov-jdk15on.version>1.69</bcprov-jdk15on.version>` → 删除,改用 jdk18on |
| **新依赖** | `org.bouncycastle:bcprov-jdk18on:1.80` + `org.bouncycastle:bcpkix-jdk18on:1.80` |
| **原因** | 1.69 有已知安全漏洞1.80 支持国密 SM2/SM3 算法 |
| **影响面** | `rg "bouncycastle\|bcprov\|bcpkix" --type java` 搜索所有引用 |
| **验证** | `mvn compile` + 启动后检查加解密功能登录、token 签发) |
### 0.2 vue-router 4.3 → 4.5
| 项目 | 详情 |
|---|---|
| **文件** | `openhis-ui-vue3/package.json` |
| **变更** | `"vue-router": "^4.3.0"``"^4.5.1"` |
| **风险** | 低 — 4.x 小版本API 兼容 |
| **验证** | 前端 `npm run dev` → 测试所有页面路由跳转、返回、权限拦截 |
---
## Phase 1: 核心组件升级(预估 1-2 天)
> 🟡 **高价值** — 改动可控,收益明显
### 1.1 echarts 5.4 → 6.0
| 项目 | 详情 |
|---|---|
| **文件** | `openhis-ui-vue3/package.json` |
| **变更** | `"echarts": "^5.4.3"``"^6.0.0"` |
| **影响面** | `rg "echarts" --type vue --type js` 搜索所有图表组件 |
| **Breaking Changes** | ECharts 6 主要变更Tree-shaking 更彻底、部分 API 重命名 |
| **验证清单** | 首页统计图表、门诊量趋势、药品销售报表、住院床位占用图 |
| **回滚方案** | 改回 `"^5.4.3"` 即可 |
### 1.2 lodash-es → es-toolkit
| 项目 | 详情 |
|---|---|
| **文件** | `openhis-ui-vue3/package.json` + 所有引用文件 |
| **变更** | `"lodash-es": "^4.17.21"` → 删除,添加 `"es-toolkit": "^1.41.0"` |
| **迁移映射** | `_.cloneDeep``cloneDeep``_.debounce``debounce``_.isEqual``isEqual``_.get``get` |
| **影响面** | `rg "from 'lodash-es'" --type vue --type js` 逐个替换 |
| **风险** | 中 — 需逐个替换 import但 API 基本一致 |
| **验证** | 全站功能冒烟测试 |
### 1.3 引入 MapStruct后端
| 项目 | 详情 |
|---|---|
| **文件** | `openhis-server-new/pom.xml` (parent) + `openhis-application/pom.xml` |
| **新增依赖** | `org.mapstruct:mapstruct:1.5.5.Final` + `mapstruct-processor` + `lombok-mapstruct-binding` |
| **使用方式** | 新增 `@Mapper(componentModel = "spring")` 接口替代 `BeanUtils.copyProperties` |
| **策略** | **渐进式** — 不改造现有代码,仅新功能使用 MapStruct |
| **验证** | `mvn compile` 确认注解处理器工作 |
---
## Phase 2: 富文本 + 数据库迁移(预估 3-5 天)
> 🟢 **中等工作量** — 需要一定的改造
### 2.1 tiptap 富文本编辑器(替代 vue-quill
| 项目 | 详情 |
|---|---|
| **新增依赖** | `@tiptap/vue-3``@tiptap/starter-kit``@tiptap/extension-*` 系列 |
| **替换目标** | `@vueup/vue-quill`(当前用于病历编辑、处方备注等) |
| **影响面** | `rg "vue-quill\|Quill" --type vue` 搜索所有引用 |
| **新增能力** | 表格编辑、图片内嵌、协作编辑、自定义节点 |
| **策略** | 新页面用 tiptap旧页面逐步迁移 |
| **验证** | 病历编辑器、处方备注、各种富文本输入场景 |
### 2.2 引入 Flyway 数据库迁移
| 项目 | 详情 |
|---|---|
| **新增依赖** | `org.flywaydb:flyway-core` + `flyway-database-postgresql` |
| **配置** | `application-dev.yml` 添加 Flyway 配置 |
| **目录** | `src/main/resources/db/migration/` |
| **迁移文件命名** | `V1__init.sql``V2__add_xxx.sql` |
| **策略** | **不对现有表做迁移**,仅新功能的 DDL 用 Flyway 管理 |
| **风险** | 中 — 需确保现有数据库与 Flyway 基线一致 |
| **验证** | 启动时 Flyway 自动执行 → 检查 `flyway_schema_history` 表 |
---
## Phase 3: UI 框架评估(预估 5-10 天,可选)
> ⚪ **长期规划** — 工作量大,收益高但风险也高
### 3.1 Tailwind CSS 引入
| 项目 | 详情 |
|---|---|
| **新增依赖** | `tailwindcss``autoprefixer``postcss` |
| **策略** | **渐进式** — Tailwind 与现有 SCSS 共存,新页面用 Tailwind |
| **影响面** | 全局样式可能冲突,需仔细测试 |
| **建议** | 先在 `help-center` 或独立页面试水 |
### 3.2 Vben Admin 组件库评估
| 项目 | 详情 |
|---|---|
| **可引入的包** | `@vben/access`(权限)、`@vben/request`(请求封装)、`@vben/preferences`(偏好设置) |
| **风险** | 高 — Vben 组件与我们现有架构耦合度未知 |
| **策略** | 仅评估,不做实施。等 Phase 0-2 完成后再决定 |
---
## 升级路线图
```
Week 1: Phase 0 (BouncyCastle + vue-router) ← 立即执行
Week 1: Phase 1.1 (echarts 6) ← 紧随其后
Week 2: Phase 1.2 (es-toolkit) + 1.3 (MapStruct)
Week 3: Phase 2.1 (tiptap) ← 可并行
Week 3: Phase 2.2 (Flyway) ← 可并行
Week 4+: Phase 3 (Tailwind + Vben 评估) ← 按需
```
---
## 升级日志模板
```markdown
## [日期] 升级记录
### 组件: XXX Y.Y → Z.Z
- **Phase**: 0/1/2/3
- **变更文件**: list...
- **验证结果**: ✅ 编译通过 / ✅ 冒烟测试通过
- **回滚方案**: 改回旧版本号
- **备注**: ...
```
---
## 风险矩阵
| 风险 | 概率 | 影响 | 缓解措施 |
|---|---|---|---|
| echarts 6 API 不兼容 | 中 | 高 | 先在测试环境验证所有图表 |
| es-toolkit 行为差异 | 低 | 中 | 逐个替换,每个改完跑测试 |
| Flyway 与现有 SQL 冲突 | 中 | 高 | 设置 baseline不管理已有表 |
| tiptap 与现有编辑器冲突 | 低 | 低 | 新旧共存,逐步迁移 |
| Tailwind 样式覆盖 | 高 | 中 | 使用 CSS Module 隔离 |