fix(web): 知识库图谱预览与保存修复(CSP 放行 S3 图片源 + imageUrl 表单注册)

- server.cjs: img-src 放行 http://100.83.103.1:7480,修复编辑页预览图被 CSP 拦截
- Knowledge.tsx: 新增隐藏 Form.Item name=imageUrl,修复 validateFields 提交时丢弃图片 URL
- 部署至 100.83.103.1:5174(备份 /home/pan/backups/web-20260812-1605)
- 补绑白僵病 image_url(UPDATE 1),更新故障排查/开发交接/变更记录
This commit is contained in:
weijuesen
2026-08-12 16:16:28 +08:00
parent 4f66a71c6c
commit fa01b1cb97
5 changed files with 111 additions and 1 deletions
+55
View File
@@ -1023,3 +1023,58 @@ APP 使用 `react-native-vector-icons` 的 `MaterialCommunityIcons` 字体渲染
- `ScrollView` 的 `style` 设置容器样式(如 flex、背景色),`contentContainerStyle` 设置内容样式(如 padding)
- 仅修改 JS/TS 代码,Metro reload 即可生效,无需重新构建 APK
---
## 三十二、Web 知识库症状图谱预览打不开且保存不生效
**现象**:Web「知识库 → 蚕病百科」编辑病种时上传新的症状图谱:编辑弹窗里的预览图打不开;点击提交提示"保存成功",但重新打开/刷新后图谱仍未绑定(`image_url` 为空)。
**原因(两个独立问题,均为前端问题,后端与存储正常)**:
1. **预览图打不开:CSP 拦截跨源图片**
`web/server.cjs` 的 `Content-Security-Policy` 为 `img-src 'self' data: blob:`,只允许同源图片。上传成功后返回的图片 URL 是 `http://100.83.103.1:7480/silk-images/...`Ceph RGW,端口 7480 与页面 5174 不同源),浏览器直接拦截,图片本身可匿名访问(200 image/jpeg)。
2. **保存不生效:`imageUrl` 未注册到表单,提交时被丢弃**
`web/src/pages/Knowledge.tsx` 上传成功后执行 `form.setFieldValue('imageUrl', res.url)`,但「症状图谱图片」的 `Form.Item` 只有 label、没有 `name="imageUrl"`。antd 的 `form.validateFields()` 只返回已注册(有 `Form.Item name`)的字段,`imageUrl` 不在其中,因此 `PATCH /knowledge/diseases/:id` 的请求体里根本没有 `imageUrl`,后端收到 200 但 `image_url` 列不更新(`updated_at` 会变)。
**排查证据(开发服务器 100.83.103.1**
- `web/web.log``POST /api/v1/knowledge/images` → `PATCH /api/v1/knowledge/diseases/17b1cae4-21cc-4996-9db3-96f785aef800` → `GET /api/v1/knowledge/diseases`
- `server-go/server-go.log`(实际生效日志,非 `/home/pan/silk/server-go.log`):15:57:54 `POST images` 20015:58:03 `PATCH` 200
- Ceph `silk-images` 桶:存在 `knowledge/20260812/36a2bc56e466fb41.jpeg`286608 字节,image/jpeg),匿名 GET 200
- PostgreSQL:白僵病 `image_url` 为 NULL;全表无任何病种有 `image_url`
- 部署产物校验:服务器 `server.cjs` md5 与仓库一致(CSP 生效);新 bundle 中已含修复代码
**处理**
1. 前端修复(`web/src/pages/Knowledge.tsx`、`web/server.cjs`):
- 「症状图谱图片」后新增隐藏字段,使 `imageUrl` 注册进表单并被 `validateFields()` 返回:
```tsx
<Form.Item name="imageUrl" hidden>
<Input />
</Form.Item>
```
- CSP `img-src` 放行开发环境 S3 源:`img-src 'self' data: blob: http://100.83.103.1:7480`
2. 构建与部署(本地 `npm run lint`、`npm run build` 均通过):
- 备份旧产物:`/home/pan/backups/web-20260812-1605/`dist、server.cjs、web.log
- 上传新 `dist` 与 `server.cjs`,重启 node(旧 pid 3764542 → 新 pid 3803472
- 验证:`http://localhost:5174/` 200CSP 头含 `http://100.83.103.1:7480`;新 bundle `index-CSVEb7gG.js` 200`/api/v1/health` 200
3. 数据补绑(用户确认直接改库):
```sql
UPDATE diseases
SET image_url = 'http://100.83.103.1:7480/silk-images/knowledge/20260812/36a2bc56e466fb41.jpeg',
updated_at = now()
WHERE id = '17b1cae4-21cc-4996-9db3-96f785aef800';
```
结果:`UPDATE 1`,查询确认 `image_url` 已写入;图片匿名 GET 200。
**验证结果**:DB 行已绑定图谱 URL;CSP 已放行;部署产物包含隐藏字段注册;lint/build 通过(详见上文)。
**回滚点**
- 前端回滚:恢复 `/home/pan/backups/web-20260812-1605/` 下的旧 `dist`/`server.cjs` 并重启 node
- 数据回滚:`UPDATE diseases SET image_url = NULL, updated_at = now() WHERE id = '17b1cae4-21cc-4996-9db3-96f785aef800';` 或 `pg_restore` 恢复 `/home/pan/backups/diseases-20260812-1605.dump`
**注意事项**
- `/home/pan/silk` 不是 git 仓库,无法打 tag 回滚,只能依赖文件备份(本次已备份)
- 部署指南中的 `admin/admin123` 已无法登录(401 用户名或密码错误),本次 API 冒烟改用 DB 直接验证;如需 API 级冒烟请先确认当前 admin 密码
- 已知边界:编辑页若点「移除」图片再保存,`imageUrl` 会以 `undefined` 提交(键被省略),不会清空库里已有图片;如需「移除即清空」后续应显式传 `null`
- CSP 当前放行的是开发服务器 IP;生产切云 OSS/COS 时需把 OSS/CDN 域名加入 `img-src`,或改为同源代理