144 lines
9.2 KiB
Markdown
144 lines
9.2 KiB
Markdown
# 第一次升级
|
||
|
||
## 1. 升级目标
|
||
- 不改 PostgreSQL 现有数据与表结构。
|
||
- 不改服务器文件存储路径(`UPLOAD_DIR` / `UPLOAD_FALLBACK_DIRS`)。
|
||
- 通过“代码 + 前端构建产物”发布完成升级。
|
||
- 修复现有高优先级缺陷并增强安全性与稳定性。
|
||
|
||
## 2. 约束与发布原则
|
||
- 不执行任何初始化/造数脚本(如 `init-db`、`seed`、`create_db`、`setup`)。
|
||
- 服务器 `.env` 保持原值(尤其数据库与上传目录相关配置)。
|
||
- 采用兼容式修改,避免破坏现网接口与数据。
|
||
|
||
## 3. 升级计划(逐项完成)
|
||
|
||
状态说明:
|
||
- `[ ]` 待处理
|
||
- `[-]` 处理中
|
||
- `[x]` 已完成
|
||
|
||
- [x] 01. 建立本升级文档与执行清单
|
||
- [x] 02. 修复成果编辑接口运行时错误与权限判断
|
||
- [x] 03. 前端移除 URL token 传递(导出/下载改为 Header 认证)
|
||
- [x] 04. 上传安全加固(文件大小/数量限制、通知附件类型限制)
|
||
- [x] 05. 上传失败时清理已落盘文件,避免孤儿文件
|
||
- [x] 06. 数据库配置兼容修复(`DB_DATABASE`/`DB_NAME`)
|
||
- [x] 07. 数据库连接池错误策略优化(避免进程直接退出)
|
||
- [x] 08. 整体回归检查与发布说明整理
|
||
|
||
## 4. 变更记录
|
||
- 2026-02-25:创建文档与首轮升级清单。
|
||
- 2026-02-25:修复 `GET /api/achievements/:id` 的运行时错误(移除未定义变量 `parsedContributors` 的错误逻辑)。
|
||
- 2026-02-25:修复 `PUT /api/achievements/:id` 事务提前返回未回滚问题(补充 `ROLLBACK`)。
|
||
- 2026-02-25:修复 `DELETE /api/achievements/:id` 事务提前返回未回滚问题(补充 `ROLLBACK`)。
|
||
- 2026-02-25:成果上传接口补充 JSON 解析失败时的落盘文件清理。
|
||
- 2026-02-25:通知发布接口补充附件限制与异常清理,`content` 改为净化后入库(不改表结构)。
|
||
- 2026-02-25:前端导出/下载去除 URL token,统一改为 `Authorization` Header + Blob 下载。
|
||
- 2026-02-25:数据库连接配置兼容 `DB_DATABASE` / `DB_NAME`,连接池 idle error 不再 `process.exit(-1)`。
|
||
- 2026-02-25:后端语法检查通过;前端 `npm run build` 编译通过。
|
||
- 2026-02-25:本次新增与更新内容全部按 UTF-8 编码保存。
|
||
- 2026-02-26:统计页新增“统计口径说明”和 AI 安全说明文案;新增“部门独立完成 / 合作项目统计表”。
|
||
- 2026-02-26:AI Prompt 优化为结构化管理汇报模板(执行摘要/关键发现/独立合作解读/风险/行动建议/一句话结论)。
|
||
- 2026-02-26:修复统计接口 500(`text <> varchar[]/text[]` 类型兼容问题),统一在 SQL 中显式转换为 `text[]`,并同步修复 AI 分析同口径查询。
|
||
- 2026-02-26:AI 分析结果前端改为 Markdown 渲染(支持标题/列表/表格等格式),提升可读性。
|
||
- 2026-02-26:AI 提示词精简;传给模型的数据改为语义化摘要(类型/状态中文化、TopN 与占比、近 24 个月趋势),降低上下文长度并提升分析速度。
|
||
- 2026-02-26:AI 分析新增流式输出(边生成边显示);前端新增“清空输出”按钮(生成中可中止并清空)。
|
||
- 2026-02-26:取消后端 `max_tokens` 人工上限(输出长度不再由项目侧硬限制,受模型侧能力约束)。
|
||
- 2026-02-26:AI 功能权限扩展至 `senior_user`(高级用户)与 `intermediate_user`(中级用户),前后端权限口径保持一致。
|
||
- 2026-02-26:成果列表/成果详情/导出接口的 `assigned_departments` 返回口径统一排除院领导部门(与统计页口径一致)。
|
||
- 2026-02-26:修正部门过滤边界:若某条成果过滤院领导部门后为空,则回退显示原始部门,避免“无归属部门”展示问题。
|
||
- 2026-02-26:成果归属部门计算改为“全体完成人手机号对应部门去重后统计”,并在写库时过滤院领导部门(不再仅按主要完成人计算)。
|
||
- 2026-02-26:归属部门规则再次调整为“单归属部门”:
|
||
- 优先按主要完成人顺序取部门;
|
||
- 若命中院领导部门则按顺序回退到下一个完成人,取第一个非院领导部门;
|
||
- 若全部均为院领导部门,则回退首个部门,保证每条成果只有 1 个归属部门。
|
||
- 2026-02-27:统计页下线“部门独立完成 / 合作项目统计表”(当前每个项目仅归属 1 个部门,该表不再提供有效增量信息)。
|
||
- 2026-02-27:成果相关全入口口径收敛为单归属部门(成果公示/全部成果/我的成果/详情权限/部门筛选/统计/AI 分析统一),并对历史多部门数据按“首个非院领导,否则首个部门”规则读取时归一。
|
||
- 2026-02-27:统计页新增“AI 年份筛选与图表年份联动”:在 AI 卡片选择年份后,下方部门分布/类型分布/部门种类统计三图同步切换;年份来源保持动态,无硬编码年份。
|
||
|
||
## 5. 服务器端操作(全部完成后填写)
|
||
- 1. 先备份服务器现有代码目录和前端静态目录(保留可回滚版本)。
|
||
- 2. 保持服务器 `.env` 不变,尤其是 `DB_*`、`UPLOAD_DIR`、`UPLOAD_FALLBACK_DIRS`。
|
||
- 3. 只上传本次变更的后端代码与前端构建产物(`client/build` 或你实际部署目录下的 dist)。
|
||
- 4. 不执行任何数据库初始化、迁移、造数脚本(`init-db`/`seed`/`create_db`/`setup`)。
|
||
- 5. 重启 Node 服务进程(`pm2 restart ...` 或 `systemctl restart ...`,按你现网方式)。
|
||
- 6. 发布后烟测:
|
||
- 成果详情页打开(`GET /api/achievements/:id`)。
|
||
- 成果修改/删除权限验证(普通用户、超管各测一次)。
|
||
- 成果附件下载、CSV 导出、ZIP 导出。
|
||
- 通知发布(带附件与异常附件各测一次)。
|
||
- 统计分析页:部门统计已排除院领导部门;每条成果仅计入一个归属部门。
|
||
- 统计分析页:不再显示“部门独立完成 / 合作项目统计表”。
|
||
- AI 分析:可在 `auto / qwen / deepseek` 切换,返回提供方与尝试顺序。
|
||
- 7. 若异常,先回滚代码与前端静态文件,不回滚数据库(本次未做数据库结构变更)。
|
||
|
||
## 6. 功能扩展:AI 分析(2026-02-25)
|
||
|
||
### 6.1 功能目标
|
||
- 在“统计分析”页面增加 AI 分析入口。
|
||
- 使用后端调用大模型 API 生成分析结论,前端仅展示结果。
|
||
- 保持数据库与文件存储路径不变,不做任何表结构变更。
|
||
|
||
### 6.2 安全策略(已实现)
|
||
- 不向大模型发送附件内容。
|
||
- 不向大模型发送附件路径与文件名。
|
||
- 不向大模型发送完成人手机号和姓名。
|
||
- 仅发送脱敏后的聚合统计数据(类型分布、状态分布、部门分布、月度趋势、质量计数)。
|
||
- 接口权限限制为管理员/超级管理员可用。
|
||
|
||
### 6.3 本次新增文件与改动
|
||
- 新增后端路由:`server/routes/aiAnalysis.js`
|
||
- 挂载后端路由:`server/index.js` -> `/api/ai-analysis`
|
||
- 新增 AI 配置示例:`server/.env.example`
|
||
- 前端入口与交互:`client/src/pages/Statistics.js`
|
||
- 新增提供方选择:自动 / 千问 / DeepSeek / custom
|
||
- 新增自动回退:按优先级依次尝试(可配置)
|
||
|
||
### 6.4 服务器端新增配置
|
||
在服务器 `.env` 新增(或确认)以下变量:
|
||
|
||
```env
|
||
AI_DEFAULT_PROVIDER=auto
|
||
AI_PROVIDER_PRIORITY=qwen,deepseek,custom
|
||
|
||
QWEN_API_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
|
||
QWEN_API_KEY=你的千问Key
|
||
QWEN_MODEL=qwen-plus
|
||
|
||
DEEPSEEK_API_BASE_URL=https://api.deepseek.com/v1
|
||
DEEPSEEK_API_KEY=你的DeepSeekKey
|
||
DEEPSEEK_MODEL=deepseek-chat
|
||
|
||
# 可选:自定义网关/代理
|
||
AI_API_BASE_URL=
|
||
AI_API_KEY=
|
||
AI_MODEL=
|
||
|
||
AI_TIMEOUT_MS=45000
|
||
AI_MAX_TOKENS=1600
|
||
```
|
||
|
||
说明:
|
||
- `AI_DEFAULT_PROVIDER=auto` 时,按 `AI_PROVIDER_PRIORITY` 顺序尝试。
|
||
- 前端可手动指定单一提供方,也可选“自动”。
|
||
- 私有网段网关可放在 `AI_API_BASE_URL`(custom)中使用(http/https 均支持)。
|
||
|
||
### 6.5 上线后测试点
|
||
- 1. 管理员/超管登录,进入“统计分析”页面,确认出现“AI 智能分析(脱敏)”卡片。
|
||
- 2. 选择筛选条件并输入问题,点击“生成 AI 分析”应返回文本结果。
|
||
- 3. 普通用户账号不应可用该功能(无入口或接口返回 403)。
|
||
- 4. 服务器日志确认无附件路径、文件名、手机号、姓名外发日志。
|
||
|
||
### 6.6 统计口径调整(院领导部门过滤)
|
||
- 部门相关统计(部门分布、部门类型交叉、部门趋势)统一排除 `dict_leader_departments` 中配置的院领导部门。
|
||
- 成果归属采用“单归属部门”写库规则(按主要完成人顺序回退到首个非院领导部门;若均为院领导则回退首个部门)。
|
||
- 统计页已下线“部门独立完成 / 合作项目统计表”。
|
||
- AI 分析入参与统计页保持同口径(排除院领导部门,不再传递独立/合作统计字段)。
|
||
|
||
### 6.7 文案与 Prompt 优化(2026-02-26)
|
||
- 前端统计页新增口径提示文案,明确“排除院领导部门 + 单归属部门计数”。
|
||
- AI 卡片新增安全提示文案,明确仅发送脱敏聚合数据,不发送附件信息和个人敏感信息。
|
||
- AI 系统提示词改为结构化输出,支持直接用于院级管理汇报。
|
||
- 输出要求强调“先结论、后证据、再建议”,并在数据不足时必须显式提示证据不足。
|