# 功能测试报告_部署包打包与独立启动_2026-09-13 ## 一、功能说明 用户需要把系统打包部署到另一台机器。本轮交付三件事: ### 1. 一键打包脚本 `package-deploy.py`(新增) 一条命令完成:前端构建 → 把 `dist` 内嵌进后端 jar(拷进 `src/main/resources/static`)→ `mvn clean package` → 清空 static(保持仓库干净)→ 组装部署目录 → 压缩 zip。 产物: - 目录 `deploy/traffic-audit-deploy-YYYYMMDD/` - 压缩包 `traffic-audit-deploy-YYYYMMDD.zip`(本次 69.9 MB / 246 个文件) 部署目录结构(沿用 8 月版包习惯): ``` backend/ jar(含内嵌前端)+ docs/ + application.yml + start-backend.cmd/.sh frontend/ dist/ + nginx.conf.example (仅 nginx 方案需要) db/ init.sql + sql_city_bus.sql + sql_city_taxi.sql + sql_wyc.sql README-部署说明.txt ``` ### 2. 修复 `JwtUtils`:`jwt.secret` 非法 Base64 导致登录 500(根因修复) - 现象(本次烟测实测):把外置 `application.yml` 的 `jwt.secret` 填成中文串后,登录接口返回 `500 {"code":500,"message":"20018"}`。 - 根因:jjwt 0.9.1 默认把 secret 当 **Base64** 解码,非法字符会在 `DatatypeConverter.guessLength` 抛 `ArrayIndexOutOfBoundsException`,被 `GlobalExceptionHandler` 兜成 500。部署同事第一次改配置很容易踩。 - 处置:`JwtUtils` 新增 `secretKeyBytes()`——能按 Base64 解码就用解码结果(与历史 token 兼容),否则按 UTF-8 字节处理并打 WARN。 ### 3. 更正《打包部署说明》(`docs/打包部署说明.md`) 旧版(2026-08-27)有三处与现状不符,本次一并改正: | 旧说明 | 实际情况 | 处理 | |--------|----------|------| | 「Redis 后端启动必需」 | pom 无 redis 依赖,代码也未使用 | 改为「不需要 Redis」,并去掉外置配置里的 redis 段 | | 「jar 已内置前端静态托管(file:./web/)」 | jar 内无任何静态文件,也没有 `static-locations` 配置;旧包实际靠 nginx | 改为「打包时把 dist 内嵌进 jar」,访问 8090 即可,无需 nginx | | 数据库只提 3 个脚本 | 现网还有 `wyc_total_monthly` / `wyc_order_monthly` 两张表 | 补 `db/sql_wyc.sql`,并补充 `summary.template-dir` 等配置与时序 | ## 二、测试环境 - 开发机:后端 8090(`start-dev.ps1`,重启后 PID 变化)、前端 8080、MySQL 127.0.0.1:3308。 - 部署包验证:把 `deploy/traffic-audit-deploy-20260913/backend` 拷到 `_deploytest/`,用 **8091** 端口独立启动 (数据库用命令行参数覆盖为 3308,模拟「外置 yml + 命令行覆盖」两种改配置方式)。 - 测试时间:2026-09-13;脚本:`package-deploy.py`、`_deploy_smoke.py`(结果 `_deploytest_result.txt`、`_deploytest_backend.log`)。 ## 三、用例表 ### 3.1 正向用例 | 编号 | 输入 | 预期 | 实际 | 结论 | | --- | --- | --- | --- | --- | | TC-1 | `python package-deploy.py --no-build` | 产出 zip,且无报错 | `traffic-audit-deploy-20260913.zip` 69.9 MB / 246 文件 | 通过 | | TC-2 | 检查 jar 内容 | 含内嵌前端 | jar 55.5 MB,`BOOT-INF/classes/static/` 下 42 个文件,`static/index.html` 存在 | 通过 | | TC-3 | 检查部署目录结构 | backend/frontend/db/README 齐全 | backend(jar + docs + application.yml + 2 个启动脚本)、frontend/dist、db 4 个 sql、README | 通过 | | TC-4 | 打包后源码目录 | `src/main/resources/static` 应被清空 | 打包结束自动清空(仓库无污染) | 通过 | | TC-5 | 从部署包独立启动(8091) | 启动成功 | 日志出现 `Started TrafficAuditApplication`、`Tomcat started on port(s): 8091` | 通过 | | TC-6 | `GET /` | 200 且返回页面 | 200,1828 字节,含 `
` | 通过 | | TC-7 | `GET /js/app.*.js` | 200(静态资源可访问) | 200,6253 字节 | 通过 | | TC-8 | `POST /api/auth/login`(admin/123456) | 200 且返回 token | 200,`{"code":200,"message":"success","data":{...,"token":"eyJ..."}}` | 通过 | | TC-9 | 带 token 导出《道路运输量汇总表》2026-08 | 200 且是合法 xlsx | 200,950,783 字节,头部 `PK`(与开发机导出件同尺寸) | 通过 | ### 3.2 负向用例 | 编号 | 输入 | 预期 | 实际 | 结论 | | --- | --- | --- | --- | --- | | TC-N1 | 修复前:`--jwt.secret=这是一个中文密钥` | 暴露问题 | 登录 500,日志 `ArrayIndexOutOfBoundsException: 20018 at JwtUtils.generateToken` | 已复现(问题成立) | | TC-N2 | 修复后:同样传中文 secret | 不因密钥格式崩,登录仍可用 | 登录 200 拿到 token;导出同样 200 / 950,783 字节;日志出现「jwt.secret 不是合法的 Base64 字符串…」WARN | 通过 | | TC-N3 | 外置 application.yml 保留占位密码,用命令行 `--spring.datasource.password` 覆盖 | 命令行覆盖生效 | 启动成功并正常查库(登录 200) | 通过 | | TC-N4 | 打包脚本重复执行(旧 staging 目录含只读文件) | 能清理并重建 | 首轮报 `PermissionError WinError 5`,加 `rmtree_force`(先清只读属性)后正常 | 已修复 | ### 3.3 回归用例 | 编号 | 输入 | 预期 | 实际 | 结论 | | --- | --- | --- | --- | --- | | TC-R1 | 开发机重启后端(载入 JwtUtils 改动) | 功能不回归 | 登录 200;导出 2026-08 → HTTP 200 / 950,783 字节(与部署包产物、9-13 归档件同尺寸) | 通过 | | TC-R2 | 前端生产构建 | 构建成功 | `npm run build` 成功,`dist/index.html` + css/js/fonts 齐全 | 通过 | ## 四、发现的问题与处置 1. **`jwt.secret` 非法 Base64 → 登录 500**(烟测抓到):已按根因修复(Base64 优先、否则 UTF-8 兜底 + WARN),并在打包配置里给出可直接使用的 32 位十六进制示例值、在说明文档里写明取值规则。 2. **打包脚本清理旧目录被只读文件挡住**:源 `docs` 里有只读 xlsx,`copy2` 会把只读属性带过去,导致 Windows 下 `rmtree` 报「拒绝访问」→ 新增 `rmtree_force()` 先 `chmod` 再删。 3. **旧《打包部署说明》三处不实**(Redis 必需 / jar 已内置前端 / 缺 sql_wyc.sql):已全部更正,并补上部署后验证清单与常见问题。 4. 说明:烟测脚本里「拿到 token」那一项打印为 False,是脚本把响应体截断到 120 字符后再判断字符串导致(截断后看不到 `"token"`),原始响应与后续带 token 的导出请求均成功(HTTP 200),程序本身无问题。 ## 五、结论 - 打包脚本一键可产出可直接部署的 zip;部署包在**脱离源码目录**、仅靠 jar + docs + 外置配置的前提下,独立启动、页面/静态资源/登录/导出全部通过,导出产物与开发机一致(950,783 字节)。 - `jwt.secret` 的部署陷阱已根因修复,部署同事即使填了不规范的值也不会再出现「登录 500」而无从下手。 - 部署说明已与当前代码对齐(不需要 Redis、不需要 nginx、4 个建表脚本、外置配置项齐全)。