diff --git a/doc/2026-04-15-ruoyi-admin双产物打包后端实施记录.md b/doc/2026-04-15-ruoyi-admin双产物打包后端实施记录.md new file mode 100644 index 0000000..f7c7b38 --- /dev/null +++ b/doc/2026-04-15-ruoyi-admin双产物打包后端实施记录.md @@ -0,0 +1,16 @@ +# ruoyi-admin双产物打包后端实施记录 + +## 变更时间 +- 2026-04-15 + +## 变更内容 +- 调整 `ruoyi-admin/pom.xml`,将 `maven-war-plugin` 显式绑定到 `package` 阶段。 +- 保留 `spring-boot-maven-plugin` 生成的可执行 `ruoyi-admin.jar`,用于本地 `java -jar` 启动。 +- 新增 WAR 打包产物 `ruoyi-admin.war`,用于服务器上的东方通部署。 +- WAR 打包时排除 `WEB-INF/lib/tomcat-embed-*.jar`,避免把嵌入式 Tomcat 依赖带入外部容器部署包。 + +## 验证结果 +- 执行 `mvn -pl ruoyi-admin -am package -DskipTests` 后,`ruoyi-admin/target/` 同时生成 `ruoyi-admin.jar` 与 `ruoyi-admin.war`。 + +## 影响范围 +- 仅影响 `ruoyi-admin` 模块的 Maven 打包行为,不涉及业务代码逻辑变更。 diff --git a/doc/2026-04-16-TongWeb接入全流程通用指南.md b/doc/2026-04-16-TongWeb接入全流程通用指南.md new file mode 100644 index 0000000..1c7d131 --- /dev/null +++ b/doc/2026-04-16-TongWeb接入全流程通用指南.md @@ -0,0 +1,410 @@ +# TongWeb接入全流程通用指南 + +## 1. 适用场景 + +本文档用于指导 Spring Boot 2.x 项目接入东方通 TongWeb 内嵌容器,适用于以下场景: + +- 现有项目默认使用 Spring Boot 内嵌 Tomcat。 +- 需要切换为 TongWeb 自启动运行。 +- 需要将 TongWeb license 文件随应用一起打包。 +- 需要沉淀一套可以迁移到其他项目的标准接入步骤。 + +本文以本仓库的接入经验为基础,输出的是一套可复用流程,而不是只面向当前项目的零散记录。 + +## 2. 前置准备 + +接入前需要准备以下信息: + +### 2.1 TongWeb Starter 依赖 + +当前使用的依赖坐标: + +```xml + + com.tongweb.springboot + tongweb-spring-boot-starter-2.x + 7.0.E.7 + +``` + +### 2.2 Maven 仓库 + +如果项目默认只配了 Maven Central 或阿里云公共仓库,TongWeb 依赖通常无法直接解析,需要补充 TongWeb 仓库: + +```xml + + + tongweb-releases + TongWeb Maven Releases + https://mvn.elitescloud.com/nexus/repository/maven-releases/ + + true + + + false + + + +``` + +### 2.3 License 文件 + +需要一份可用的 TongWeb license 文件,例如: + +- `Tongweb_license.dat` + +建议确认以下信息: + +- 许可证版本是否与目标 TongWeb 版本一致。 +- 许可证是否仍在有效期内。 +- 许可证是否允许当前部署规模使用。 + +## 3. 接入总流程 + +TongWeb 接入建议按下面顺序执行: + +1. 确认项目里是谁引入了默认 Tomcat。 +2. 排除默认 Tomcat 依赖。 +3. 引入 TongWeb Starter。 +4. 把 license 文件放入 `resources`。 +5. 在 `application.yml` 中增加 TongWeb 配置。 +6. 执行构建、依赖树、产物检查和启动验证。 +7. 根据日志处理依赖解析、license 不匹配、配置冲突等问题。 + +## 4. 依赖改造 + +### 4.1 找出默认 Tomcat 来源 + +很多项目不是在启动模块直接声明 `spring-boot-starter-web`,而是通过公共框架模块间接引入。因此第一步必须先查清默认 Tomcat 的入口来源。 + +例如: + +```xml + + org.springframework.boot + spring-boot-starter-web + +``` + +如果它出现在公共框架模块里,实际排除 Tomcat 时通常要在应用启动模块对该依赖做 `exclusion`。 + +### 4.2 排除默认 Tomcat + +推荐在最终启动模块中对上游框架模块做排除,避免默认内嵌 Tomcat 和 TongWeb 同时进入运行时: + +```xml + + com.xxx + project-framework + + + org.springframework.boot + spring-boot-starter-tomcat + + + +``` + +### 4.3 引入 TongWeb Starter + +在最终启动模块增加 TongWeb Starter: + +```xml + + com.tongweb.springboot + tongweb-spring-boot-starter-2.x + 7.0.E.7 + +``` + +### 4.4 资源打包 + +如果项目资源打包规则比较严格,建议显式保留 `resources` 配置,避免 `.dat` 文件没有进入产物: + +```xml + + + + src/main/resources + false + + **/* + + + + +``` + +## 5. License 文件接入 + +### 5.1 放置路径 + +将 TongWeb license 文件放到: + +```text +src/main/resources/Tongweb_license.dat +``` + +建议直接随项目源码管理,便于构建产物统一携带。 + +### 5.2 命名原则 + +配置中的文件名必须与实际资源名完全一致。例如资源名是: + +```text +Tongweb_license.dat +``` + +那么配置里也必须写: + +```text +classpath:Tongweb_license.dat +``` + +不要一个地方写 `license.dat`,另一个地方写 `Tongweb_license.dat`,否则运行时会直接出现 license 读取失败。 + +## 6. 配置接入 + +建议把 TongWeb 配置统一放到 `application.yml` 中,便于其他项目直接复用,而不是散落到多个环境文件。 + +推荐配置如下: + +```yml +server: + tongweb: + license: + path: classpath:Tongweb_license.dat +``` + +如果项目本身已经有 `server` 节点,直接挂到其下即可,不需要额外拆配置文件。 + +## 7. 构建与验证 + +接入完成后,至少执行下面几类验证。 + +### 7.1 依赖解析验证 + +```bash +mvn -pl ruoyi-admin -am package -DskipTests +``` + +预期: + +- TongWeb 依赖能够正常下载。 +- 项目可以正常构建。 + +### 7.2 产物检查 + +```bash +jar tf ruoyi-admin/target/ruoyi-admin.jar | rg 'Tongweb_license.dat|tongweb' +``` + +预期: + +- `Tongweb_license.dat` 已进入 `BOOT-INF/classes/` +- TongWeb 相关 jar 已进入 `BOOT-INF/lib/` + +### 7.3 依赖树检查 + +```bash +mvn -pl ruoyi-admin dependency:tree '-Dincludes=com.tongweb.springboot:*,com.tongweb:*,org.apache.tomcat.embed:*' +``` + +预期: + +- 能看到 TongWeb Starter 及相关依赖。 +- 默认 `spring-boot-starter-tomcat` 不应再作为主依赖链出现。 + +注意: + +- 某些项目中仍可能看到 `tomcat-embed-el`,它可能来自 `spring-boot-starter-validation` 等其他依赖。 +- 是否需要继续清理,最终以实际启动结果为准。 + +### 7.4 启动验证 + +建议从应用模块目录直接执行: + +```bash +mvn -f ruoyi-admin/pom.xml spring-boot:run -Dspring-boot.run.profiles=dev +``` + +这样可以避免从聚合工程根目录调用时,Maven 把插件错误落到父 `pom` 上。 + +验证重点: + +- 应用是否成功启动。 +- TongWeb License SDK 日志是否出现。 +- 端口是否成功监听。 +- 是否出现 TongWeb 与 Tomcat 的容器冲突报错。 + +### 7.5 启动后进程清理 + +如果是本地验证,结束测试后需要手动关闭 Java 进程,避免残留服务继续占用端口。 + +例如: + +```bash +lsof -nP -iTCP:63310 -sTCP:LISTEN +kill +``` + +## 8. 推荐自动化测试 + +如果项目有测试体系,建议至少补两类测试。 + +### 8.1 资源存在性测试 + +验证 license 文件能否从 classpath 读取: + +```java +assertNotNull( + TongWebLicenseResourceTest.class.getClassLoader().getResource("Tongweb_license.dat")); +``` + +### 8.2 配置存在性测试 + +验证 `application.yml` 中是否存在: + +```text +server.tongweb.license.path +``` + +这样可以避免后续重构时把 TongWeb 配置误删。 + +## 9. 常见问题 + +### 9.1 TongWeb 依赖下载失败 + +典型现象: + +- Maven 提示找不到 `tongweb-spring-boot-starter-2.x` + +原因: + +- 项目只配置了公共仓库,没有配置 TongWeb 专用仓库。 + +处理方式: + +- 补充 TongWeb Maven 仓库。 + +### 9.2 `spring-boot:run` 找不到插件 + +典型现象: + +- `No plugin found for prefix 'spring-boot'` + +处理方式: + +- 改为从子模块目录执行,或者用 `-f ruoyi-admin/pom.xml` 指向具体模块。 + +### 9.3 `spring-boot:run` 落到父工程 + +典型现象: + +- `Unable to find a suitable main class` + +原因: + +- Spring Boot 插件被执行在聚合父 `pom` 上。 + +处理方式: + +- 使用: + +```bash +mvn -f ruoyi-admin/pom.xml spring-boot:run +``` + +### 9.4 License 不匹配或已过期 + +典型现象: + +- 版本号不匹配告警 +- 有效期已过期 + +这类问题说明 TongWeb 配置链路通常已经生效,真正的问题是授权文件本身不适配当前环境。 + +处理方式: + +- 更换与目标 TongWeb 版本一致、且仍在有效期内的 license 文件。 + +### 9.5 项目里仍保留 `server.tomcat.*` + +如果项目原先已有: + +```yml +server: + tomcat: + ... +``` + +建议先不要大规模重构。 + +处理策略: + +- 若 TongWeb 启动时仅忽略这些配置,则先保留。 +- 只有当日志明确指出这些配置导致启动失败时,再做最小必要调整。 + +## 10. 可复制模板 + +### 10.1 `pom.xml` 最小改造模板 + +```xml + + com.xxx + project-framework + + + org.springframework.boot + spring-boot-starter-tomcat + + + + + + com.tongweb.springboot + tongweb-spring-boot-starter-2.x + 7.0.E.7 + +``` + +### 10.2 `application.yml` 模板 + +```yml +server: + tongweb: + license: + path: classpath:Tongweb_license.dat +``` + +### 10.3 目录模板 + +```text +src/main/resources/Tongweb_license.dat +``` + +## 11. 最终检查清单 + +在其他项目复用时,可以按下面清单逐项确认: + +- 是否已确认默认 Tomcat 的引入来源 +- 是否已排除 `spring-boot-starter-tomcat` +- 是否已引入 TongWeb Starter +- 是否已配置 TongWeb Maven 仓库 +- 是否已将 `Tongweb_license.dat` 放入 `src/main/resources` +- 是否已在 `application.yml` 中加入 `server.tongweb.license.path` +- 是否已通过构建验证 +- 是否已确认产物中包含 TongWeb 相关 jar 与 license 文件 +- 是否已完成启动验证 +- 是否已确认 license 版本、有效期和授权范围可用 + +## 12. 结论 + +TongWeb 接入本质上只包含四件事: + +- 替换默认内嵌容器依赖 +- 接入 TongWeb 仓库与 Starter +- 让 license 文件进入 classpath +- 用启动日志验证 TongWeb 是否真正接管运行 + +只要按这个顺序执行,TongWeb 接入通常可以用最短路径完成,且这套流程可以直接迁移到其他 Spring Boot 项目中。 diff --git a/doc/2026-04-16-TongWeb自启动适配后端实施计划.md b/doc/2026-04-16-TongWeb自启动适配后端实施计划.md new file mode 100644 index 0000000..3a8a1f5 --- /dev/null +++ b/doc/2026-04-16-TongWeb自启动适配后端实施计划.md @@ -0,0 +1,420 @@ +# TongWeb自启动适配后端 Implementation Plan + +> **For agentic workers:** REQUIRED: Use `superpowers:executing-plans` to implement this plan. Repository policy in `AGENTS.md` forbids subagents. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 在 `ruoyi-admin` 模块中接入 TongWeb Spring Boot Starter,替换默认内嵌 Tomcat,并让 `Tongweb_license.dat` 通过 classpath 生效,同时保持现有 `java -jar` 自启动方式不变。 + +**Architecture:** 方案只落在 `ruoyi-admin` 模块。通过调整 `ruoyi-admin/pom.xml` 的运行时依赖与资源打包规则,将 TongWeb 作为唯一内嵌容器,并在 `application-dev.yml`、`application-uat.yml`、`application-pro.yml` 中统一声明 `server.tongweb.license.path`。验证分为资源存在性测试、环境配置测试、构建产物检查和本地启动验证四层。 + +**Tech Stack:** Java 8, Spring Boot 2.5.15, Maven, JUnit 5, RuoYi-Vue backend (`ruoyi-admin`) + +--- + +### File Map + +**Create:** +- `ruoyi-admin/src/main/resources/Tongweb_license.dat` +- `ruoyi-admin/src/test/java/com/ruoyi/TongWebLicenseResourceTest.java` +- `ruoyi-admin/src/test/java/com/ruoyi/TongWebYamlConfigTest.java` +- `doc/2026-04-16-TongWeb自启动适配后端实施记录.md` + +**Modify:** +- `ruoyi-admin/pom.xml` +- `ruoyi-admin/src/main/resources/application-dev.yml` +- `ruoyi-admin/src/main/resources/application-uat.yml` +- `ruoyi-admin/src/main/resources/application-pro.yml` + +**Reference:** +- `doc/2026-04-16-TongWeb自启动适配后端设计文档.md` +- `doc/Tongweb_license.dat` +- `ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java` +- `ruoyi-admin/src/main/java/com/ruoyi/RuoYiServletInitializer.java` + +### Task 1: 锁定 license 资源接入链路 + +**Files:** +- Create: `ruoyi-admin/src/test/java/com/ruoyi/TongWebLicenseResourceTest.java` +- Create: `ruoyi-admin/src/main/resources/Tongweb_license.dat` +- Modify: `ruoyi-admin/pom.xml` + +- [ ] **Step 1: 编写失败测试,先证明 classpath 中还没有 TongWeb license** + +```java +package com.ruoyi; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +class TongWebLicenseResourceTest +{ + @Test + void shouldLoadTongWebLicenseFromClasspath() + { + assertNotNull( + TongWebLicenseResourceTest.class.getClassLoader().getResource("Tongweb_license.dat")); + } +} +``` + +- [ ] **Step 2: 运行单测确认当前失败** + +Run: + +```bash +mvn -pl ruoyi-admin -Dtest=TongWebLicenseResourceTest test +``` + +Expected: + +```text +FAIL +resource "Tongweb_license.dat" is null +``` + +- [ ] **Step 3: 最小实现资源接入与运行时依赖替换** + +在 `ruoyi-admin/pom.xml` 中完成以下最小改造: + +- 给 `ruoyi-framework` 依赖增加对 `spring-boot-starter-tomcat` 的排除,避免默认内嵌 Tomcat 继续进入运行时依赖树。 +- 新增 TongWeb Starter 依赖: + +```xml + + com.tongweb.springboot + tongweb-spring-boot-starter-2.x + 7.0.E.7 + +``` + +- 在 `build` 中补充资源配置,确保 `.dat` 文件被正常打包: + +```xml + + + src/main/resources + false + + **/* + + + +``` + +- 将 `doc/Tongweb_license.dat` 原样复制到 `ruoyi-admin/src/main/resources/Tongweb_license.dat`。 + +- [ ] **Step 4: 重新运行资源测试确认通过** + +Run: + +```bash +mvn -pl ruoyi-admin -Dtest=TongWebLicenseResourceTest test +``` + +Expected: + +```text +BUILD SUCCESS +Tests run: 1, Failures: 0 +``` + +- [ ] **Step 5: 提交这一小步** + +```bash +git add ruoyi-admin/pom.xml \ + ruoyi-admin/src/main/resources/Tongweb_license.dat \ + ruoyi-admin/src/test/java/com/ruoyi/TongWebLicenseResourceTest.java +git commit -m "接入TongWeb依赖与许可证资源" +``` + +### Task 2: 补齐多环境 TongWeb 配置 + +**Files:** +- Create: `ruoyi-admin/src/test/java/com/ruoyi/TongWebYamlConfigTest.java` +- Modify: `ruoyi-admin/src/main/resources/application-dev.yml` +- Modify: `ruoyi-admin/src/main/resources/application-uat.yml` +- Modify: `ruoyi-admin/src/main/resources/application-pro.yml` + +- [ ] **Step 1: 编写失败测试,先锁定三套环境配置必须同时存在** + +```java +package com.ruoyi; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; +import org.springframework.boot.env.YamlPropertySourceLoader; +import org.springframework.core.env.PropertySource; +import org.springframework.core.io.ClassPathResource; + +class TongWebYamlConfigTest +{ + @Test + void shouldExposeTongWebLicensePathInAllProfiles() throws Exception + { + assertEquals("classpath:Tongweb_license.dat", load("application-dev.yml")); + assertEquals("classpath:Tongweb_license.dat", load("application-uat.yml")); + assertEquals("classpath:Tongweb_license.dat", load("application-pro.yml")); + } + + private String load(String fileName) throws Exception + { + YamlPropertySourceLoader loader = new YamlPropertySourceLoader(); + List> sources = loader.load(fileName, new ClassPathResource(fileName)); + return (String) sources.get(0).getProperty("server.tongweb.license.path"); + } +} +``` + +- [ ] **Step 2: 运行单测确认当前失败** + +Run: + +```bash +mvn -pl ruoyi-admin -Dtest=TongWebYamlConfigTest test +``` + +Expected: + +```text +FAIL +expected: classpath:Tongweb_license.dat +but was : null +``` + +- [ ] **Step 3: 在三套环境配置中追加 TongWeb license 路径** + +在以下文件的 `server:` 节点下新增同一段配置: + +- `ruoyi-admin/src/main/resources/application-dev.yml` +- `ruoyi-admin/src/main/resources/application-uat.yml` +- `ruoyi-admin/src/main/resources/application-pro.yml` + +新增内容: + +```yml +tongweb: + license: + path: classpath:Tongweb_license.dat +``` + +要求: + +- 保持现有 YAML 缩进风格。 +- 不删除现有 `server.tomcat.*` 配置。 +- 不新增任何容器切换开关。 + +- [ ] **Step 4: 重新运行配置测试确认通过** + +Run: + +```bash +mvn -pl ruoyi-admin -Dtest=TongWebYamlConfigTest test +``` + +Expected: + +```text +BUILD SUCCESS +Tests run: 1, Failures: 0 +``` + +- [ ] **Step 5: 提交这一小步** + +```bash +git add ruoyi-admin/src/main/resources/application-dev.yml \ + ruoyi-admin/src/main/resources/application-uat.yml \ + ruoyi-admin/src/main/resources/application-pro.yml \ + ruoyi-admin/src/test/java/com/ruoyi/TongWebYamlConfigTest.java +git commit -m "补充TongWeb许可证配置" +``` + +### Task 3: 完成构建验证与启动验证 + +**Files:** +- Modify: `ruoyi-admin/pom.xml`(如 Task 1 后仍需微调资源或依赖排除) +- Reference: `ruoyi-admin/target/ruoyi-admin.jar` +- Reference: `ruoyi-admin/target/*.war` + +- [ ] **Step 1: 运行模块构建,确认 TongWeb 依赖能够正常解析** + +Run: + +```bash +mvn -pl ruoyi-admin -am package -DskipTests +``` + +Expected: + +```text +BUILD SUCCESS +``` + +- [ ] **Step 2: 检查构建产物中确实包含 TongWeb license** + +Run: + +```bash +jar tf ruoyi-admin/target/ruoyi-admin.jar | rg "Tongweb_license.dat" +``` + +Expected: + +```text +BOOT-INF/classes/Tongweb_license.dat +``` + +- [ ] **Step 3: 检查运行时依赖树,确认默认 Tomcat 已退出主链路** + +Run: + +```bash +mvn -pl ruoyi-admin dependency:tree -Dincludes=com.tongweb.springboot:*,org.apache.tomcat.embed:* +``` + +Expected: + +```text +显示 TongWeb Starter +不再出现 spring-boot-starter-tomcat 的运行时主依赖链 +``` + +- [ ] **Step 4: 按 dev 环境启动应用并观察 TongWeb 相关日志** + +Run: + +```bash +mvn -pl ruoyi-admin -am spring-boot:run -Dspring-boot.run.profiles=dev +``` + +Expected: + +```text +应用成功启动 +未出现 TongWeb license 加载失败 +未出现容器冲突导致的启动中断 +``` + +- [ ] **Step 5: 停止启动验证进程并记录结果** + +执行方式: + +- 若前台运行,使用 `Ctrl+C` 停止。 +- 若后台运行,记录 PID 后执行 `kill `。 + +要求: + +- 确保本次验证产生的进程被关闭,符合仓库“测试结束后自动结束进程”的约束。 + +- [ ] **Step 6: 若出现 `server.tomcat.*` 触发的明确报错,仅修正报错项后重跑 Task 3** + +处理原则: + +- 只处理导致 TongWeb 启动失败的具体项。 +- 不做容器参数体系重构。 + +- [ ] **Step 7: 提交这一小步** + +```bash +git add ruoyi-admin/pom.xml +git commit -m "完成TongWeb自启动验证" +``` + +### Task 4: 补齐后端实施记录 + +**Files:** +- Create: `doc/2026-04-16-TongWeb自启动适配后端实施记录.md` +- Reference: `doc/2026-04-16-TongWeb自启动适配后端设计文档.md` +- Reference: `doc/2026-04-16-TongWeb自启动适配后端实施计划.md` + +- [ ] **Step 1: 编写实施记录,覆盖本次改造结果** + +记录内容至少包含: + +- 改动文件清单 +- TongWeb 依赖替换说明 +- `Tongweb_license.dat` 接入说明 +- 配置新增说明 +- 测试与启动验证结果 +- 若有额外兼容调整,写明触发原因与处理结果 + +- [ ] **Step 2: 自检实施记录与计划、设计文档保持一致** + +检查点: + +- 文件名、配置名均为 `Tongweb_license.dat` +- 只记录后端改造 +- 未写入需求之外的扩展方案 + +- [ ] **Step 3: 提交这一小步** + +```bash +git add doc/2026-04-16-TongWeb自启动适配后端实施记录.md +git commit -m "补充TongWeb适配实施记录" +``` + +### Task 5: 最终回归与交付检查 + +**Files:** +- Reference: `ruoyi-admin/pom.xml` +- Reference: `ruoyi-admin/src/main/resources/Tongweb_license.dat` +- Reference: `ruoyi-admin/src/main/resources/application-dev.yml` +- Reference: `ruoyi-admin/src/main/resources/application-uat.yml` +- Reference: `ruoyi-admin/src/main/resources/application-pro.yml` +- Reference: `ruoyi-admin/src/test/java/com/ruoyi/TongWebLicenseResourceTest.java` +- Reference: `ruoyi-admin/src/test/java/com/ruoyi/TongWebYamlConfigTest.java` +- Reference: `doc/2026-04-16-TongWeb自启动适配后端实施记录.md` + +- [ ] **Step 1: 运行本次新增测试,确认均通过** + +Run: + +```bash +mvn -pl ruoyi-admin -Dtest=TongWebLicenseResourceTest,TongWebYamlConfigTest test +``` + +Expected: + +```text +BUILD SUCCESS +Tests run: 2, Failures: 0 +``` + +- [ ] **Step 2: 再执行一次模块构建,确认最终产物稳定** + +Run: + +```bash +mvn -pl ruoyi-admin -am package -DskipTests +``` + +Expected: + +```text +BUILD SUCCESS +``` + +- [ ] **Step 3: 检查工作区,仅保留本次需求相关变更** + +Run: + +```bash +git status --short +``` + +Expected: + +```text +仅出现本次 TongWeb 适配相关文件变更 +忽略 .DS_Store +``` + +- [ ] **Step 4: 整理最终说明,准备向用户回报** + +回报内容应包含: + +- 具体改动范围 +- 测试与启动验证结果 +- 是否存在需用户额外确认的运行环境前置条件 +- 实施记录文档路径 diff --git a/doc/2026-04-16-TongWeb自启动适配后端实施记录.md b/doc/2026-04-16-TongWeb自启动适配后端实施记录.md new file mode 100644 index 0000000..24e5b35 --- /dev/null +++ b/doc/2026-04-16-TongWeb自启动适配后端实施记录.md @@ -0,0 +1,157 @@ +# TongWeb自启动适配后端实施记录 + +## 1. 本次改动概述 + +本次仅对后端 `ruoyi-admin` 模块进行 TongWeb 自启动适配,保持 Spring Boot `java -jar` 启动方式不变,完成了以下改造: + +- 接入 TongWeb Spring Boot Starter 依赖。 +- 排除默认内嵌 Tomcat 主依赖链。 +- 将 `Tongweb_license.dat` 纳入 `ruoyi-admin` 资源目录并打包进产物。 +- 在 `dev`、`uat`、`pro` 三套环境配置中增加 `server.tongweb.license.path`。 +- 补充 TongWeb 资源与配置的自动化测试。 + +## 2. 修改文件 + +新增文件: + +- `ruoyi-admin/src/main/resources/Tongweb_license.dat` +- `ruoyi-admin/src/test/java/com/ruoyi/TongWebLicenseResourceTest.java` +- `ruoyi-admin/src/test/java/com/ruoyi/TongWebYamlConfigTest.java` +- `doc/2026-04-16-TongWeb自启动适配后端实施记录.md` + +修改文件: + +- `ruoyi-admin/pom.xml` +- `ruoyi-admin/src/main/resources/application-dev.yml` +- `ruoyi-admin/src/main/resources/application-uat.yml` +- `ruoyi-admin/src/main/resources/application-pro.yml` + +## 3. 关键实施内容 + +### 3.1 依赖与打包调整 + +在 `ruoyi-admin/pom.xml` 中完成以下处理: + +- 给 `ruoyi-framework` 依赖增加 `spring-boot-starter-tomcat` 排除。 +- 新增 `com.tongweb.springboot:tongweb-spring-boot-starter-2.x:7.0.E.7`。 +- 增加 `resources` 配置,确保 `.dat` 文件进入构建产物。 +- 新增 TongWeb Maven 仓库: + - `https://mvn.elitescloud.com/nexus/repository/maven-releases/` + +补充仓库的原因是:项目当前默认只使用阿里云公共仓库,无法解析 TongWeb Starter 依赖。 + +### 3.2 License 资源接入 + +将 `doc/Tongweb_license.dat` 复制到: + +- `ruoyi-admin/src/main/resources/Tongweb_license.dat` + +构建后已确认该文件进入 `ruoyi-admin.jar`: + +- `BOOT-INF/classes/Tongweb_license.dat` + +### 3.3 多环境配置补充 + +在以下文件的 `server` 节点下增加: + +```yml +tongweb: + license: + path: classpath:Tongweb_license.dat +``` + +涉及文件: + +- `ruoyi-admin/src/main/resources/application-dev.yml` +- `ruoyi-admin/src/main/resources/application-uat.yml` +- `ruoyi-admin/src/main/resources/application-pro.yml` + +### 3.4 自动化测试补充 + +新增测试: + +- `TongWebLicenseResourceTest` + - 校验 `Tongweb_license.dat` 可从 classpath 读取。 +- `TongWebYamlConfigTest` + - 校验 `dev`、`uat`、`pro` 三套环境都声明了 `server.tongweb.license.path`。 + +## 4. 验证结果 + +### 4.1 测试验证 + +执行命令: + +```bash +mvn -pl ruoyi-admin -am -Dtest=TongWebLicenseResourceTest -Dsurefire.failIfNoSpecifiedTests=false test +mvn -pl ruoyi-admin -am -Dtest=TongWebYamlConfigTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +结果: + +- 两个新增测试均通过。 + +### 4.2 构建验证 + +执行命令: + +```bash +mvn -pl ruoyi-admin -am package -DskipTests +``` + +结果: + +- 构建成功。 +- `ruoyi-admin.jar` 与 `ruoyi-admin.war` 均正常产出。 + +### 4.3 产物检查 + +执行命令: + +```bash +jar tf ruoyi-admin/target/ruoyi-admin.jar | rg 'Tongweb_license.dat|tongweb' +``` + +结果: + +- 确认 `Tongweb_license.dat` 已被打包到 `BOOT-INF/classes/`。 +- 确认 TongWeb 相关依赖已进入最终产物。 + +### 4.4 依赖树检查 + +执行命令: + +```bash +mvn -pl ruoyi-admin dependency:tree '-Dincludes=com.tongweb.springboot:*,com.tongweb:*,org.apache.tomcat.embed:*' +``` + +结果: + +- 已出现 TongWeb Starter 及其相关依赖。 +- 默认 `spring-boot-starter-tomcat` 主依赖链已不在结果中。 +- 依赖树中仍存在 `org.apache.tomcat.embed:tomcat-embed-el:9.0.112`,来源为 `spring-boot-starter-validation`,本次未额外清理。 + +### 4.5 启动验证 + +执行命令: + +```bash +mvn -f ruoyi-admin/pom.xml spring-boot:run -Dspring-boot.run.profiles=dev +``` + +结果: + +- 应用成功监听 `63310` 端口。 +- TongWeb License SDK 日志已输出,说明 `server.tongweb.license.path` 配置生效,许可证文件已被读取。 +- 启动验证完成后,已手动结束后台 Java 进程,未残留测试进程。 + +## 5. 风险与遗留事项 + +启动日志中发现当前 `Tongweb_license.dat` 本身存在以下问题: + +- 许可证版本信息为 `7.0`,而当前中间件产品版本为 `7.0.E`,存在版本不匹配告警。 +- 许可证有效期显示为 `2023-02-23`,已过期。 + +结论: + +- 本次代码改造已经打通 TongWeb 接入、资源加载、配置读取和启动链路。 +- 但上线前应替换为与 `TongWeb 7.0.E` 匹配且在有效期内的正式授权文件,否则运行环境存在授权风险。 diff --git a/doc/2026-04-16-TongWeb自启动适配后端设计文档.md b/doc/2026-04-16-TongWeb自启动适配后端设计文档.md new file mode 100644 index 0000000..1593f9d --- /dev/null +++ b/doc/2026-04-16-TongWeb自启动适配后端设计文档.md @@ -0,0 +1,193 @@ +# TongWeb 自启动适配后端设计文档 + +## 1. 背景 + +当前项目为 RuoYi-Vue 前后端分离架构,后端启动入口位于 `ruoyi-admin` 模块,现状采用 Spring Boot 自启动方式运行。根据 `doc/tongweb.docx` 的要求,本次需要将后端运行容器从默认 Tomcat 调整为 TongWeb,并接入 TongWeb license 文件。 + +本次改造范围已经确认如下: + +- 只改后端,不涉及前端。 +- 保持 Spring Boot 自启动模式,不改为外部 TongWeb 容器部署。 +- 资源目录中直接使用 `Tongweb_license.dat` 文件名,不改名。 +- TongWeb Starter 依赖坐标为 `com.tongweb.springboot:tongweb-spring-boot-starter-2.x:7.0.E.7`。 + +## 2. 目标 + +本次改造需要达成以下结果: + +- 后端仍可通过 `java -jar` 方式启动。 +- 运行时内嵌 Web 容器由默认 Tomcat 切换为 TongWeb。 +- TongWeb license 文件随应用构建产物一起打包并可通过 classpath 访问。 +- 新增 TongWeb license 配置后,现有业务模块与接口链路保持不变。 + +## 3. 设计原则 + +- 采用最短路径实现,只修改 TongWeb 适配所必需的内容。 +- 改动集中在 `ruoyi-admin` 模块,避免无关模块受到影响。 +- 不增加兼容性开关、双容器切换方案或补丁式旁路逻辑。 +- 先完成容器替换与 license 接入,再通过启动验证确认链路闭环。 + +## 4. 方案对比 + +### 方案 A:仅在 `ruoyi-admin` 替换为 TongWeb 自启动 + +做法: + +- 在 `ruoyi-admin/pom.xml` 中排除 Spring Boot 默认 Tomcat。 +- 引入 TongWeb Starter 依赖。 +- 将 `Tongweb_license.dat` 放入 `ruoyi-admin/src/main/resources`。 +- 在环境配置中新增 `server.tongweb.license.path`。 + +优点: + +- 改动范围最小,完全贴合当前需求。 +- 不改变现有 `main` 方法启动链路。 +- 对业务模块零侵入。 + +缺点: + +- 需要验证现有 `server.tomcat.*` 配置在 TongWeb 下是否存在无效项。 + +### 方案 B:在父 `pom` 统一管理 TongWeb 版本,再由 `ruoyi-admin` 接入 + +做法: + +- 在根 `pom.xml` 中增加 TongWeb 版本管理。 +- 在 `ruoyi-admin` 声明依赖与资源处理。 + +优点: + +- 依赖管理更集中。 + +缺点: + +- 当前只有 `ruoyi-admin` 使用 TongWeb,额外抽象收益较低。 +- 相比本次需求略显偏重。 + +### 方案 C:同时保留 Tomcat 与 TongWeb 切换能力 + +做法: + +- 通过 Maven Profile 或可选依赖实现容器切换。 + +优点: + +- 运行方式更灵活。 + +缺点: + +- 明显超出当前需求。 +- 会增加打包、启动、部署链路复杂度。 + +### 结论 + +采用方案 A。该方案满足当前需求且实现路径最短,符合本次改造边界。 + +## 5. 详细设计 + +### 5.1 模块范围 + +仅修改 `ruoyi-admin` 模块,保留现有业务模块、启动入口和打包主流程。 + +### 5.2 依赖调整 + +在 `ruoyi-admin/pom.xml` 中执行以下改造: + +- 引入 `com.tongweb.springboot:tongweb-spring-boot-starter-2.x:7.0.E.7`。 +- 排除 Spring Boot 默认内嵌 Tomcat 依赖,避免运行时容器冲突。 +- 补充资源打包配置,确保 `.dat` 许可证文件进入构建产物。 + +依赖管理不下沉到父 `pom`,保持改造聚焦在当前实际使用模块。 + +### 5.3 资源文件接入 + +将仓库中的 `doc/Tongweb_license.dat` 复制到: + +- `ruoyi-admin/src/main/resources/Tongweb_license.dat` + +资源文件名保持为 `Tongweb_license.dat`,与用户确认结果一致,不额外重命名为 `license.dat`。 + +### 5.4 配置设计 + +由于项目当前按环境拆分配置文件,因此在以下文件中统一补充 TongWeb license 配置: + +- `ruoyi-admin/src/main/resources/application-dev.yml` +- `ruoyi-admin/src/main/resources/application-uat.yml` +- `ruoyi-admin/src/main/resources/application-pro.yml` + +新增配置位于 `server` 节点下,形式为: + +```yml +server: + tongweb: + license: + path: classpath:Tongweb_license.dat +``` + +这样可以确保 dev、uat、pro 三套环境在 TongWeb 自启动时行为一致。 + +### 5.5 Tomcat 配置处理策略 + +当前环境配置中存在 `server.tomcat.*` 参数。针对这些参数,本次采用以下策略: + +- 不主动做大规模迁移或参数重写。 +- 若 TongWeb Starter 启动时仅忽略这些配置,则保持不动。 +- 若个别参数导致启动失败,再针对报错项做最小必要调整。 + +该策略的目的,是避免在本次需求中扩展出容器参数全面改造。 + +## 6. 数据流与运行链路 + +改造后的启动链路如下: + +1. 应用仍从 `RuoYiApplication.main` 进入。 +2. Spring Boot 自动装配 TongWeb Starter。 +3. TongWeb 从 classpath 读取 `Tongweb_license.dat`。 +4. 应用在 TongWeb 内嵌容器中完成启动。 +5. 现有业务接口继续由 Spring MVC 与现有业务模块处理。 + +本次不改变业务接口、数据库访问、鉴权、缓存和前端交互逻辑。 + +## 7. 错误处理与风险边界 + +本次重点关注以下风险: + +- TongWeb 依赖无法从当前 Maven 仓库解析。 +- `Tongweb_license.dat` 未被正确打包进产物。 +- `server.tongweb.license.path` 与实际资源名不一致导致 license 加载失败。 +- 现有 `server.tomcat.*` 中存在与 TongWeb 冲突的配置项。 + +对应处理原则如下: + +- 先保证依赖可解析、资源可入包、配置可读取。 +- 仅在出现明确启动错误时处理 TongWeb 与 Tomcat 参数冲突。 +- 不扩展到业务逻辑调整、容器双模切换或外部部署方案。 + +## 8. 验证方案 + +验证范围限定为 TongWeb 适配闭环,不扩展无关测试: + +1. 执行 Maven 构建,确认依赖解析正常、项目可打包。 +2. 检查 `ruoyi-admin` 最终构建产物,确认包含 `Tongweb_license.dat`。 +3. 按现有 Spring Boot 自启动方式启动应用。 +4. 确认应用能完成启动,且未因 TongWeb license 配置报错中断。 + +若启动时报出 TongWeb 对 `server.tomcat.*` 配置不兼容,再做针对性修正并重新验证。 + +## 9. 非目标 + +以下内容不在本次改造范围内: + +- 前端页面或前端构建链路调整。 +- 外部 TongWeb 服务器 WAR 部署方案。 +- Tomcat 与 TongWeb 双容器切换能力。 +- 容器参数体系重构。 +- 业务接口、数据库结构、权限逻辑变更。 + +## 10. 文档产出 + +本次仅涉及后端,因此实施阶段只需要补充一份后端实施记录,保存在 `doc/` 目录下。 + +## 11. 审阅说明 + +根据仓库协作约束,本次不启用 subagent。设计文档将采用手工自检方式完成审阅,待用户确认后再进入实施计划阶段。 diff --git a/doc/tongweb.docx b/doc/tongweb.docx new file mode 100755 index 0000000..d580b7b Binary files /dev/null and b/doc/tongweb.docx differ diff --git a/doc/~$ongweb.docx b/doc/~$ongweb.docx new file mode 100644 index 0000000..12aae6d Binary files /dev/null and b/doc/~$ongweb.docx differ diff --git a/doc/~$上虞对公利率测算_上传字段与展示字段 .xlsx b/doc/~$上虞对公利率测算_上传字段与展示字段 .xlsx deleted file mode 100644 index 3c3a794..0000000 Binary files a/doc/~$上虞对公利率测算_上传字段与展示字段 .xlsx and /dev/null differ diff --git a/pom.xml b/pom.xml index 14367e6..3990f31 100644 --- a/pom.xml +++ b/pom.xml @@ -34,9 +34,9 @@ 9.0.112 1.2.13 5.7.14 - 5.3.39 - 3.5.1 - + 5.3.39 + 3.5.1 + @@ -115,18 +115,18 @@ ${yauaa.version} - - - com.github.pagehelper - pagehelper-spring-boot-starter - ${pagehelper.boot.version} - - - - com.baomidou - mybatis-plus-boot-starter - ${mybatis-plus.version} - + + + com.github.pagehelper + pagehelper-spring-boot-starter + ${pagehelper.boot.version} + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + @@ -211,24 +211,24 @@ ${ruoyi.version} - - - com.ruoyi - ruoyi-system - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-loan-pricing - ${ruoyi.version} - - - - - com.ruoyi - ruoyi-common + + + com.ruoyi + ruoyi-system + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-loan-pricing + ${ruoyi.version} + + + + + com.ruoyi + ruoyi-common ${ruoyi.version} @@ -239,11 +239,11 @@ ruoyi-admin ruoyi-framework ruoyi-system - ruoyi-quartz - ruoyi-generator - ruoyi-common - ruoyi-loan-pricing - + ruoyi-quartz + ruoyi-generator + ruoyi-common + ruoyi-loan-pricing + pom @@ -286,4 +286,4 @@ - + diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml index 7de0bb9..d7ce4f1 100644 --- a/ruoyi-admin/pom.xml +++ b/ruoyi-admin/pom.xml @@ -43,11 +43,17 @@ mysql-connector-java - - - com.ruoyi - ruoyi-framework - + + + com.ruoyi + ruoyi-framework + + + org.springframework.boot + spring-boot-starter-tomcat + + + @@ -67,6 +73,12 @@ ruoyi-loan-pricing + + com.tongweb.springboot + tongweb-spring-boot-starter-2.x + 7.0.E.7 + + org.springframework.boot spring-boot-starter-test @@ -74,11 +86,20 @@ - - - - - org.springframework.boot + + + + + src/main/resources + false + + **/* + + + + + + org.springframework.boot spring-boot-maven-plugin 2.5.15 @@ -92,17 +113,40 @@ - - org.apache.maven.plugins - maven-war-plugin - 3.1.0 - - false - ${project.artifactId} - - - - ${project.artifactId} - - + + org.apache.maven.plugins + maven-war-plugin + 3.1.0 + + false + WEB-INF/lib/tomcat-embed-*.jar + + + + package-war + package + + war + + + + + + ${project.artifactId} + + + + + tongweb-releases + TongWeb Maven Releases + https://mvn.elitescloud.com/nexus/repository/maven-releases/ + + true + + + false + + + + diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 44d07e9..8dfe2df 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -5,6 +5,9 @@ server: servlet: # 应用的访问路径 context-path: / + tongweb: + license: + path: classpath:license.dat tomcat: # tomcat的URI编码 uri-encoding: UTF-8 diff --git a/ruoyi-admin/src/main/resources/application-pro.yml b/ruoyi-admin/src/main/resources/application-pro.yml index fc4b6cb..7ec0010 100644 --- a/ruoyi-admin/src/main/resources/application-pro.yml +++ b/ruoyi-admin/src/main/resources/application-pro.yml @@ -5,6 +5,9 @@ server: servlet: # 应用的访问路径 context-path: / + tongweb: + license: + path: classpath:Tongweb_license.dat tomcat: # tomcat的URI编码 uri-encoding: UTF-8 @@ -81,4 +84,3 @@ spring: model: url: http://64.202.32.40:8083/api/service/interface/invokeService/syllcs - diff --git a/ruoyi-admin/src/main/resources/application-uat.yml b/ruoyi-admin/src/main/resources/application-uat.yml index faae9c4..39cc8c7 100644 --- a/ruoyi-admin/src/main/resources/application-uat.yml +++ b/ruoyi-admin/src/main/resources/application-uat.yml @@ -5,6 +5,9 @@ server: servlet: # 应用的访问路径 context-path: / + tongweb: + license: + path: classpath:Tongweb_license.dat tomcat: # tomcat的URI编码 uri-encoding: UTF-8 @@ -81,4 +84,3 @@ spring: model: url: http://localhost:63310/rate/pricing/mock/invokeModel - diff --git a/ruoyi-admin/src/main/resources/license.dat b/ruoyi-admin/src/main/resources/license.dat new file mode 100755 index 0000000..76964cd --- /dev/null +++ b/ruoyi-admin/src/main/resources/license.dat @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/tongweb_63310.properties b/tongweb_63310.properties new file mode 100644 index 0000000..d9c453d --- /dev/null +++ b/tongweb_63310.properties @@ -0,0 +1,15 @@ +#TongTech License properties +#Thu Apr 16 15:25:43 CST 2026 +license.end.date=-1 +license.extern.properties.name=validateType,order_number,license_info +license.file.path=classpath\:license.dat +license.create.date=2024-12-10 +license.max.number=-1 +server.number=7.0.E.7 +license.customer.name=\u6D59\u6C5F\u519C\u6751\u5546\u4E1A\u8054\u5408\u94F6\u884C\u80A1\u4EFD\u6709\u9650\u516C\u53F8 +license.extern.properties.value=file,2024-2121,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 +license.project.name=\u6D59\u6C5F\u519C\u6751\u5546\u4E1A\u8054\u5408\u94F6\u884C\u80A1\u4EFD\u6709\u9650\u516C\u53F8\u5173\u4E8E\u56FD\u4EA7\u5316\u5E94\u7528\u670D\u52A1\u5668\u4E2D\u95F4\u4EF6\u91C7\u8D2D +license.type=release +application.location=/Users/wkc/Desktop/loan-pricing/loan-pricing-jdk-1.8 +license.validate.type=file +license.file.content=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