# 缩略图功能 · 内网验证部署手册 在内网服务器 **172.16.204.61** 上用 `docker-compose` 起一套自包含环境(crm-app + MySQL + Redis + MinIO),验证 [file-thumbnail](../.scratch/file-thumbnail/spec.md) 从「上传文件 → 生成缩略图 → 取缩略图」的端到端行为。 > ⚠️ **本手册及其配套的 `docker-compose.yml` / `application-verify.yml` / `DebugTokenController` 严禁用于生产。** verify profile 含一个「按 userId 直接签发 JWT」的后门接口(见 [ADR-0014](adr/0014-verify-profile-debug-token-endpoint.md))。 --- ## 0. 前置条件(已核实) | 项 | 要求 | 172.16.204.61 现状 | |---|---|---| | Docker + compose v2 | compose ≥ 2.x | ✅ 26.1.3 / compose 2.27 | | 出公网拉 Maven 依赖 | repo.maven.apache.org 可达 | ✅ HTTP 200 | | 出公网访问钉钉 | api.dingtalk.com 可达 | ✅ HTTP 200(钉钉首登可走通)| | 磁盘 | ≥ 6GB(LibreOffice 镜像 ~1.5GB)| ✅ 223GB 可用 | | 你的本机 | 能连 172.16.204.61(scp/ssh + 浏览器访问 :8080)| —— | --- ## 1. 把源码传到服务器 服务器构建目录:`/home/data/project/crm`(你已在此)。从本机传源码(`.dockerignore` 已排除 `target/`、`.git/` 等,无需手动清理): ```bash # 本机(Windows PowerShell / Git Bash)——任选其一 rsync -az --exclude target --exclude .git ./ root@172.16.204.61:/home/data/project/crm/ # 或 scp -r . root@172.16.204.61:/home/data/project/crm/ ``` > 若服务器能访问你的 Git 仓库,也可直接在服务器 `git clone`。 --- ## 2. 一键构建并启动 在服务器 `/home/data/project/crm` 下: ```bash docker compose up -d --build ``` 首次会:① 用 `Dockerfile` 在 `maven:3.9` 里 `mvn package`(含拉依赖,约几分钟)→ ② 运行镜像装 LibreOffice + 中文字体 → ③ 拉起 mysql/redis/minio → ④ `minio-init` 建 `crm` bucket → ⑤ crm-app 以 `verify` profile 启动。 **确认启动成功:** ```bash docker compose logs -f crm-app # 看到 verify 后门告警(说明 profile 生效)+ Tomcat started on port 8080 即可 # 调试 token 接口 /api/auth/debug/token 已启用(verify profile) ``` 空库首启会由 `ddl-auto: update` 自动建全部表(含缩略图新增的 `thumbnail_status` / `thumbnail_retry_count` 列)。 --- ## 3. 拿到一个可用的 JWT 受鉴权接口(`/api/file/upload` 等)需要 `Authorization: Bearer `。两条路,任选: ### 路径 A:钉钉首登(产生真实用户) 钉钉扫码换到 `authCode` 后(authCode 短时效,几分钟内用掉): ```bash curl -X POST 'http://172.16.204.61:8080/api/auth/login/dingtalk?authCode=<你的authCode>' # 返回 { "data": { "token": "xxx", "userInfo": {...} } } ``` 首次登录会**自动注册**该用户(无需手动插库)。记下返回的 `token`(有效期 7 天)。 ### 路径 B:调试 token 接口(环境重建后复用已有用户) DB 里已有用户后(例如已走过一次路径 A),直接按 userId 签发: ```bash # 先从库里挑一个 userId docker compose exec mysql mysql -uroot -pverify123 -e "SELECT id, username FROM crm.crm_auth_user LIMIT 5;" # 用该 id 换 token(此端点仅 verify profile 存在) curl -X POST 'http://172.16.204.61:8080/api/auth/debug/token?userId=<上面的id>' # 返回 { "data": "" } ``` 导出备用: ```bash export TOKEN='<上一步拿到的 jwt>' ``` --- ## 4. 上传文件,拿 fileId 分别上传四类文件覆盖三条渲染管线 + 占位图分支: ```bash # 图片(ImageIO) curl -X POST 'http://172.16.204.61:8080/api/file/upload' \ -H "Authorization: Bearer $TOKEN" \ -F 'file=@sample.jpg' -F 'bizDomain=verify' # PDF(PDFBox 渲染第一页) curl -X POST 'http://172.16.204.61:8080/api/file/upload' \ -H "Authorization: Bearer $TOKEN" \ -F 'file=@sample.pdf' -F 'bizDomain=verify' # Office(LibreOffice headless 渲染第一页;含中文可验证 CJK 字体) curl -X POST 'http://172.16.204.61:8080/api/file/upload' \ -H "Authorization: Bearer $TOKEN" \ -F 'file=@sample.docx' -F 'bizDomain=verify' # 非视觉类型(应标记 UNSUPPORTED,取缩略图返回占位图) curl -X POST 'http://172.16.204.61:8080/api/file/upload' \ -H "Authorization: Bearer $TOKEN" \ -F 'file=@sample.txt' -F 'bizDomain=verify' ``` 每次返回 `{ "data": { "fileId": "...", "thumbnailStatus": "PENDING|UNSUPPORTED", ... } }`,记下各自的 `fileId`。 --- ## 5. 取缩略图,验证行为 ```bash # 取缩略图(此端点已在 verify profile 放行,无需 token) curl -v 'http://172.16.204.61:8080/api/file/thumbnail?fileId=' -o thumb.jpg ``` **逐类断言:** | 上传文件 | 期望 | 检查点 | |---|---|---| | jpg/png | 真缩略图(宽 200 JPEG)| `thumb.jpg` 可打开;响应头 `Cache-Control: max-age=86400` | | pdf | 第一页真缩略图 | 同上 | | docx(含中文)| 第一页真缩略图,中文**不出方块** | 打开 `thumb.jpg` 看中文渲染;`max-age=86400` | | txt | 占位图(类型图标)| 响应头 `Cache-Control: no-cache` | **辅助观察:** ```bash # 缩略图对象是否落到 MinIO(thumbnails/{fileId}.jpg) # 浏览器开 http://172.16.204.61:9001 (minioadmin/minioadmin)看 crm/thumbnails/ 前缀 # 状态机流转 docker compose exec mysql mysql -uroot -pverify123 \ -e "SELECT id, file_name, thumbnail_status, thumbnail_retry_count FROM crm.crm_file_info;" ``` 首次取 PENDING 的缩略图会触发**同步兜底生成**(分布式锁保护),完成后状态转 `READY`;再次请求直接命中 MinIO。 --- ## 6. 清理 ```bash docker compose down -v # 删容器 + 数据卷,环境不留痕 ``` --- ## 附:常见问题 - **Office 缩略图空白 / 方块字**:镜像已装 `fonts-noto-cjk`;若仍异常,进容器 `docker compose exec crm-app soffice --version` 确认 LibreOffice 可用,查 `docker compose logs crm-app` 里 soffice 转换日志。 - **构建卡在拉依赖**:确认服务器出网正常(`curl -I https://repo.maven.apache.org/maven2/`)。 - **crm-app 起不来、连不上中间件**:`docker compose ps` 看三个中间件是否 `healthy`;compose 已配 `depends_on: condition: service_healthy`,正常会等它们就绪再启 app。 - **调试 token 接口 404**:说明 verify profile 没激活——检查 `docker compose logs crm-app` 是否有那条 WARN 告警。