docs/´ò°ü²¿Êð˵Ã÷.md
@@ -17,7 +17,7 @@
| ç»„ä»¶ | ç‰ˆæœ¬ | è¯´æ˜Ž |
|------|------|------|
| JDK | 1.8 | éƒ¨ç½²æœºå¿…须;后端编译/运行 |
| MySQL | 5.7 / 8.0 | éƒ¨ç½²æœºå¿…须,库名 `traffic_audit` |
| MySQL | **8.0** | éƒ¨ç½²æœºå¿…须,库名 `traffic_audit`;现网/开发机为 8.0.29,表排序规则是 `utf8mb4_0900_ai_ci`,**目标机装 5.7 ä¼šå¯¼å…¥å¤±è´¥** |
| Maven 3.x / Node.js 14+ | â€” | **只有「在部署机上打包」才需要**;用一键脚本产出的包部署则不需要 |
| Redis | **不需要** | ä»£ç æœªä½¿ç”¨ Redis(旧说明中的 Redis é…ç½®æ˜¯é—留项,可忽略) |
| nginx / IIS | **不需要** | å‰ç«¯å·²å†…嵌进 jar,访问 8090 å³å¯ï¼›è¦å‰åŽç«¯åˆ†ç¦»æ—¶æ‰æ˜¯å¤‡é€‰ |
@@ -69,17 +69,69 @@
## äº”、目标机器部署步骤
### 5.1 åˆå§‹åŒ–数据库(4 ä¸ªè„šæœ¬éƒ½è¦æ‰§è¡Œï¼‰
### 5.1 å‡†å¤‡æ•°æ®åº“(两条路线二选一,**不要混着做**)
#### è·¯çº¿ A:全新空库(要跑 4 ä¸ªè„šæœ¬ï¼‰
`init.sql` è‡ªå¸¦ `CREATE DATABASE` ä¸Ž `USE traffic_audit`,可独立执行;另外 3 ä¸ªè„šæœ¬æ²¡æœ‰ `USE` è¯­å¥ï¼Œå¿…须用 `-D traffic_audit`(或 `mysql ... traffic_audit < æ–‡ä»¶`)指定库:
```bash
mysql --default-character-set=utf8mb4 -u root -p < db/init.sql
mysql --default-character-set=utf8mb4 -u root -p traffic_audit < db/sql_city_bus.sql
mysql --default-character-set=utf8mb4 -u root -p traffic_audit < db/sql_city_taxi.sql
mysql --default-character-set=utf8mb4 -u root -p traffic_audit < db/sql_wyc.sql
cd db
mysql --default-character-set=utf8mb4 -u root -p            < init.sql          # å»ºåº“ + 24 å¼ åŸºç¡€è¡¨ + é¢„置账号
mysql --default-character-set=utf8mb4 -u root -p -D traffic_audit < sql_city_bus.sql
mysql --default-character-set=utf8mb4 -u root -p -D traffic_audit < sql_city_taxi.sql
mysql --default-character-set=utf8mb4 -u root -p -D traffic_audit < sql_wyc.sql
```
- é¢„置账号:`admin / admin123`(登录后请立即改密码)。
- æƒ³è¿žæ•°æ®ä¸€èµ·æ¬ï¼šåœ¨æºæœºå™¨ `mysqldump -u root -p --databases traffic_audit > traffic_audit_full.sql`,在目标机器 `mysql -u root -p < traffic_audit_full.sql`(会覆盖预置账号)。
> âš ï¸ **`init.sql` æ˜¯ç ´åæ€§çš„**:里面的基础表都带 `DROP TABLE IF EXISTS`。**已有数据的库上千万不要再跑 init.sql**,否则表数据会被清空重建。
> 4 ä¸ªè„šæœ¬å…±è¦†ç›– 29 å¼ è¡¨ï¼ˆinit.sql 24 å¼  + åŸŽå¸‚客运 3 å¼  + ç½‘约车 2 å¼ ï¼‰ã€‚
#### è·¯çº¿ B:把现网/开发机的数据整套搬过去(推荐,不用跑脚本)
先确认两端 MySQL éƒ½æ˜¯ **8.0**(本库表排序规则为 `utf8mb4_0900_ai_ci`,5.7 ä¸è¯†åˆ«ä¼šå¯¼è‡´å¯¼å…¥å¤±è´¥ï¼‰ï¼Œå¹¶ä¸”**用与服务端同版本的 mysqldump**(不要用 5.7 çš„客户端去导 8.0 æœåŠ¡ç«¯ï¼‰ã€‚
在源机器(本机 MySQL ç«¯å£ç¤ºä¾‹ 3308,按实际改):
```bash
"C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqldump.exe" ^
  --host=127.0.0.1 --port=3308 --user=root --password=你的密码 ^
  --default-character-set=utf8mb4 --single-transaction --routines --triggers --events ^
  --databases traffic_audit > traffic_audit_full_YYYYMMDD.sql
```
在目标机器:
```bash
mysql --default-character-set=utf8mb4 -u root -p < traffic_audit_full_YYYYMMDD.sql
```
- `--databases` ä¼šæŠŠ `CREATE DATABASE` + `USE` ä¸€èµ·å†™è¿›å¤‡ä»½ï¼Œæ‰€ä»¥ç›®æ ‡æœºå™¨**不用先建库、也不用跑那 4 ä¸ªè„šæœ¬**。
- å¤‡ä»½é‡ŒåŒ…含 `sys_user`,账号密码与源机器完全一致(本机是 `admin / 123456`),不会被重置成 `admin/admin123`。
- âš ï¸ å¤‡ä»½é‡Œæ¯å¼ è¡¨éƒ½å¸¦ `DROP TABLE IF EXISTS`(共 29 å¼ ï¼‰ï¼š**目标库要是已有数据,会被直接覆盖**。请还原到空库,或先自己备份目标库。
- æœ¬æ¬¡å·²ç”Ÿæˆå¹¶**验证过**备份:`traffic_audit_full_20260913.sql`(45.5 MB,8.0.29 å®¢æˆ·ç«¯å¯¼å‡ºï¼‰ã€‚
  éªŒè¯æ–¹å¼ï¼šæŠŠå¤‡ä»½åº“名改成临时库导入,逐表比对 `SHOW CREATE TABLE`(表结构)与 `COUNT(*)`(行数)——**29 å¼ è¡¨ç»“构与行数均 0 å·®å¼‚**,抽查 `wyc_order_monthly` 2026-08 æ•°æ®ä¸€è‡´ï¼ŒéªŒè¯åŽå·²åˆ é™¤ä¸´æ—¶åº“。
#### è·¯çº¿ B2:用 Navicat çš„「备份 / è¿˜åŽŸå¤‡ä»½ã€ï¼ˆ.nb3,最贴近日常习惯)
`.nb3` æ˜¯ Navicat ç§æœ‰å¤‡ä»½æ ¼å¼ï¼ˆtar å®¹å™¨ï¼šæ¯å¼ è¡¨ä¸€ä»½ meta.json + gz åŽ‹ç¼©çš„æ•°æ®åˆ†ç‰‡ + SHA1 æ ¡éªŒ + æ€» meta.json),
只能由 Navicat è‡ªå·±ç”Ÿæˆã€ä¹Ÿåªèƒ½åœ¨ Navicat é‡Œç”¨ã€Œè¿˜åŽŸå¤‡ä»½ã€è¿˜åŽŸâ€”â€”**用 `.sql` ç‚¹ã€Œè¿˜åŽŸå¤‡ä»½ã€ä¸€å®šå¤±è´¥**(那个入口只认 .nb3)。
在源机器(30 ç§’):
1. Navicat â†’ è¿žæŽ¥ `mysql80` â†’ é€‰ä¸­ `traffic_audit` â†’ å³é”® â†’「备份…」→ èµ·ä¸ªåå­— â†’ ç¡®å®šï¼Œç­‰å®ƒè·‘完;
2. ç”Ÿæˆçš„备份文件在 Navicat çš„ profile ç›®å½•:`D:\文档\Navicat\MySQL\Servers\mysql80\traffic_audit\<时间戳>.nb3`
   ï¼ˆæœ¬æœº 8/27 é‚£ä»½å°±åœ¨è¿™é‡Œï¼Œä½†å®ƒ**已过期**:只有 27 å¼ è¡¨ã€ç¼ºç½‘约车两张表、数据是 8/27 çš„,不要用)。
在目标机器:
3. å…ˆåœ¨ Navicat é‡Œå»ºä¸€ä¸ªè¿žåˆ°æœ¬æœº MySQL 8.0 çš„连接(**连接名建议与源机器一致,比如 `mysql80`**),并新建空库 `traffic_audit`(字符集 utf8mb4);
4. æŠŠ `.nb3` æ”¾åˆ°ç›®æ ‡æœºå™¨çš„对应目录 `<Navicat profile>\MySQL\Servers\<连接名>\traffic_audit\`(没有就照着建目录);
5. å³é”®è¯¥åº“ â†’「还原备份」→ åœ¨é€‰æ‹©åˆ—表里勾选这份备份 â†’ å¼€å§‹ï¼ˆåˆ—表里看不到就重启一次 Navicat)。
> ä¸‰ç§æ–¹å¼ï¼ˆè·¯çº¿ A ç©ºåº“ 4 è„šæœ¬ / è·¯çº¿ B å‘½ä»¤è¡Œè¿˜åŽŸ .sql / è·¯çº¿ B2 Navicat .nb3)**任选其一**即可,
> ä½†**不要叠加**:还原完备份后再跑 `init.sql` ä¼šæŠŠæ•°æ®æ¸…空重建。
> æ³¨æ„ï¼š`docs/` ç›®å½•(报表模板、汇总大表母版)**与数据库无关,无论哪条路线都必须一并拷贝**。
### 5.2 æ”¹é…ç½® `backend/application.yml`
@@ -167,3 +219,75 @@
- **2026-09-13**:新增一键打包脚本 `package-deploy.py`;jar æ”¹ä¸ºå†…嵌前端(部署机不再需要 nginx);删除 Redis ç›¸å…³è¯´æ˜Žï¼ˆä»£ç æœªä½¿ç”¨ï¼‰ï¼›è¡¥ `sql_wyc.sql` ä¸Ž `summary.template-dir`;补 `jwt.secret` å–值规则;补部署后验证清单。
- 2026-08-27:首版(zip éƒ¨ç½²åŒ… + nginx æ–¹æ¡ˆï¼‰ã€‚
---
## å¯†é’¥ä¸Žé…ç½®ï¼ˆ2026-09-26 èµ·ï¼Œæ‰“包必读)
### åˆ†å±‚约定
| ä½ç½® | ç”¨é€” | æ˜¯å¦è¿› git | æ˜¯å¦è¿› jar |
| --- | --- | --- | --- |
| `traffic-audit-server/src/main/resources/application.yml` | è¿› jar çš„默认配置,**只有占位符**(`${TRAFFIC_DB_PASSWORD:}`、`${DEEPSEEK_API_KEY:}` ç­‰ï¼‰ | å¦ï¼ˆå·² gitignore,用 `application.yml.example` åšæ¨¡æ¿ï¼‰ | **是**(无真实值) |
| `traffic-audit-server/config/application.yml` | æœ¬æœºå¼€å‘真实值(库口令 / JWT / DeepSeek key) | å¦ï¼ˆå·² gitignore) | å¦ |
| jar åŒçº§çš„ `backend/application.yml` | éƒ¨ç½²æœºçœŸå®žå€¼ï¼ˆä¼˜å…ˆçº§é«˜äºŽ jar å†…置) | å¦ | å¦ï¼ˆåœ¨åŒ…外,现场填) |
| çŽ¯å¢ƒå˜é‡ `TRAFFIC_DB_PASSWORD` / `TRAFFIC_DB_USER` / `TRAFFIC_DB_URL` / `TRAFFIC_JWT_SECRET` / `DEEPSEEK_API_KEY` | è¦†ç›–以上任意一项 | å¦ | å¦ |
### æœ¬æœºå¼€å‘(值放环境变量,不落文件)
```powershell
setx TRAFFIC_DB_PASSWORD "本机 MySQL å£ä»¤"     # è®¾ä¸€æ¬¡å³å¯ï¼Œä¹‹åŽæ–°å¼€çš„终端自动带上
setx DEEPSEEK_API_KEY   "DeepSeek key"
# éœ€è¦æ—¶å†è¦†ç›–:setx TRAFFIC_DB_URL / TRAFFIC_DB_USER / TRAFFIC_JWT_SECRET
powershell -NoProfile -ExecutionPolicy Bypass -File start-dev.ps1   # ä¼šè‡ªåŠ¨ä»Žæ³¨å†Œè¡¨è¡¥é½å¹¶æ³¨å…¥åŽç«¯è¿›ç¨‹
```
- `traffic-audit-server/config/application.yml` åªç•™æ³¨é‡Šè¯´æ˜Žï¼ˆæ— æ˜Žæ–‡ï¼‰ï¼›åˆ æŽ‰å®ƒä¹Ÿä¸å½±å“ï¼ˆå€¼å…¨åœ¨çŽ¯å¢ƒå˜é‡é‡Œï¼‰ã€‚
- è‹¥ç”¨ IDE ç›´æŽ¥è·‘主类,请在**新开的**终端/IDE é‡Œå¯åŠ¨ï¼ˆè®©æ–°ç»ˆç«¯ç»§æ‰¿ç”¨æˆ·çŽ¯å¢ƒå˜é‡ï¼‰ï¼Œæˆ–æ‰‹åŠ¨ `setx` åŽé‡å¯ IDE。
### æ‰“包前自查(30 ç§’)
```powershell
# 1) ç¡®è®¤è¿› jar çš„配置没有真实密钥(应只看到 ${...})
Select-String -Path traffic-audit-server\src\main\resources\application.yml -Pattern "password:|api-key:|secret:"
# 2) æ‰“完包后再验证一次 jar å†…部
python -c "import zipfile;print(zipfile.ZipFile('traffic-audit-server/target/traffic-audit-server-1.0.0-SNAPSHOT.jar').read('BOOT-INF/classes/application.yml').decode('utf-8'))" | Select-String "password:|api-key:"
```
### ä¸€é”®æ‰“包(推荐,2026-09-27 èµ·ï¼‰
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File pack-deploy.ps1
# å¯é€‰å‚数: -OutRoot "E:\试验"   -SkipFrontend
```
脚本做四件事:
1. `mvn clean package -DskipTests` æž„建后端 jar;
2. **解压 jar è‡ªæ£€**:检查 `BOOT-INF/classes/application.yml` æ˜¯å¦å…¨ä¸ºå ä½ç¬¦â€”—一旦发现 `sk-` æˆ–明文口令**直接中止打包**;
3. `npm run build` é‡å»ºå‰ç«¯ `dist`;
4. æŒ‰ `deploy-templates/` ç»„装完整部署包(backend / frontend / db / README-部署说明.txt),输出到 `<OutRoot>\traffic-audit-deploy-<yyyyMMdd>`。
模板件统一放在 **`deploy-templates/`**(已入库):外部 `application.yml`、`start-backend.cmd/.sh`、`nginx.conf.example`、`db\{init.sql,sql_city_bus,sql_city_taxi,sql_wyc}.sql`、`README-部署说明.txt`。改模板即改打包产物。
### è½®æ¢å¯†é’¥åŽåŒæ­¥æœ¬æœº
```powershell
powershell -NoProfile -ExecutionPolicy Bypass -File set-secrets.ps1
```
交互式输入(回车跳过某一项),自动 `setx` åˆ°ç”¨æˆ·çŽ¯å¢ƒå˜é‡å¹¶æç¤ºé‡å¯åŽç«¯ï¼›å€¼ä¸ä¼šå†™å…¥ä»»ä½•æ–‡ä»¶ã€‚
### éƒ¨ç½²æœºä¸ŠåŠ /换 DeepSeek key
1. æ‰“包上传后,编辑 **jar åŒçº§**的 `backend/application.yml`:`deepseek.api-key: "你的新key"`(留空则页面 AI åˆ†æžä¸å¯ç”¨ï¼Œå…¶ä½™åŠŸèƒ½æ­£å¸¸ï¼‰ï¼›
2. é‡å¯åŽç«¯ï¼š`start-backend.cmd`(或 `java -jar traffic-audit-server-1.0.0-SNAPSHOT.jar`);
3. é¡µé¢é‡Œç‚¹ä¸€æ¬¡ AI åˆ†æžç¡®è®¤å¯ç”¨ï¼›
4. **不要**去改 jar å†…部的配置(改了下次发包就丢),也不要把 key æäº¤è¿›ä»»ä½•仓库文件。
### è½®æ¢ï¼ˆä½œåºŸï¼‰å·²æ³„露的 key
1. ç™»å½• DeepSeek æŽ§åˆ¶å° â†’ API Keys â†’ æ–°å»ºä¸€ä¸ª key;
2. åˆ é™¤/禁用旧 key(旧 key ç«‹åˆ»å¤±æ•ˆï¼Œæ­¤å‰æ‰“包带出去的 jar é‡Œé‚£ä»½å³ä½œåºŸï¼‰ï¼›
3. æŒ‰ä¸Šé¢ç¬¬ 1~3 æ­¥æŠŠæ–° key å¡«åˆ°éƒ¨ç½²æœºçš„外部配置并重启验证。