16 KiB
10:50 — AI 调用记录方案评估
话题: 记录 AI 调用(session_id, tokens, 返回结果),复用操作日志机制
评估结论:方案 A — 扩展 OperLog
sys_oper_log新增 5 字段:ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokensmodule复用为"AI识别"/"AI对话"区分业务- 复用现有 OperLog 全部基础设施(service/mapper/controller/分页/查询)
- 工作量最小,约 20min
- 方案已确认,待实现
10:50 — Git 约定提醒
提示 commit 时必须附带 commit message,让用户可直接复制运行。
11:08~11:18 — AI 调用记录实现 ✅
改动点:
scripts/postgresql/10-system.sql— DDL 新增ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokensscripts/postgresql/fix-ai-oper-log.sql— 迁移脚本(新增)OperLog.java— 实体添加 5 个对应字段AiServiceImpl.java— 注入OperLogService,在chatText()/chatWithImages()调用前后记录日志(含 sessionId, tokens, 耗时, 输入/输出摘要)AiChatResponseDTO— 新增sessionId字段DeepSeekChatRequestDTO— 新增sessionId字段(@JsonIgnore,仅用于日志传递)
执行迁移: 本地库(localhost:31983)跑 fix-ai-oper-log.sql
测试结果: ✅ Tests run: 2, Failures: 0, Errors: 0 — 日志成功写入 sys_oper_log(ai_model=qwen3.5-plus 等字段正确)
13:00~13:06 — 测试库执行 AI 迁移 ✅
- 本地 WSL Docker 可连接测试库(
docker exec -i tiny-erp-db psql -U postgres -d tinyerp) - 执行
fix-ai-oper-log.sql,5 个 AI 字段(ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokens)已添加 - 验证本地库(localhost:31983)和测试库(Docker db:5432)字段均存在 ✅
13:08~13:10 — 日志文件冲突问题 → 方案A
问题: IDEA 和 Docker 都在 WSL 同一机器运行,./logs/ 会互相覆盖
方案A: docker-compose 挂载路径改为 ./logs-docker:/app/logs
.gitignore添加logs-docker/Dockerfile保留 root 运行(无USER appuser)- 已实施 ✅
13:11~13:13 — deploy-test.sh 脚本
创建 deploy-test.sh 一键部署脚本:
mvn clean install -DskipTestsdocker compose stop/rm/build/up appcurl health自动验证(失败重试 15s)
13:14~13:22 — 测试目录规范化
问题: 大部分测试包路径缺少 module 层级,与源码不一致
- 移动所有测试到
com.witsoft.erp.module.*包下 - 统一先删旧包(git rm)、再建新包、再写入
- 运行全量测试通过 ✅
test.base.BaseControllerTest保留在com.witsoft.erp.test.base(基建归 test,不归 module)
13:38~14:11 — docs/ 目录全面清理
整理方向:
| 操作 | 说明 |
|---|---|
| ✅ 合并 API 规范到项目规范.md | 删除 docs/API/ |
✅ 删除 docs/数据库/ |
以 SQL 脚本为唯一来源 |
| ✅ 文档按模块移入对应子目录 | 06-AI单据识别需求.md → 需求/AI模块,物料信息填充公共服务总结.md → 设计/主数据模块 |
| ✅ 按模块独立编号 | 全局连续 → 每个模块 01- 起编 |
| ✅ 测试文件重排序 | 按 登录→首页→物料→字典→入库出库→库存盘点→操作日志 排列 |
| ✅ README.md 同步 | 目录结构、版本历史逐一同步,标注"(预留)"空目录 |
编号规则变更: 跨模块连续编号(旧)→ 按模块独立编号(新),新增文档只加模块内序号,不碰其他模块。
14:14 — UserContext 使用指南.md 文件缺失
文档中引用 设计/系统模块/UserContext 使用指南.md,但实际文件不存在(被 yangxuan/ → docs/ 重命名遗漏)。已补充。
10:50 — AI 调用记录方案评估
话题: 记录 AI 调用(session_id, tokens, 返回结果),复用操作日志机制
评估结论:方案 A — 扩展 OperLog
sys_oper_log新增 5 字段:ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokensmodule复用为"AI识别"/"AI对话"区分业务- 复用现有 OperLog 全部基础设施(service/mapper/controller/分页/查询)
- 工作量最小,约 20min
- 方案已确认,待实现
10:50 — Git 约定提醒
提示 commit 时必须附带 commit message,让用户可直接复制运行。
11:08~11:18 — AI 调用记录实现 ✅
改动点:
scripts/postgresql/10-system.sql— DDL 新增ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokensscripts/postgresql/fix-ai-oper-log.sql— 迁移脚本(新增)OperLog.java— 实体添加 5 个对应字段AiServiceImpl.java— 注入OperLogService,在chatText()/chatWithImages()调用前后记录日志(含 sessionId, tokens, 耗时, 输入/输出摘要)AiChatResponseDTO— 新增sessionId字段DeepSeekChatRequestDTO— 新增sessionId字段(@JsonIgnore,仅用于日志传递)
执行迁移: 本地库(localhost:31983)跑 fix-ai-oper-log.sql
测试结果: ✅ Tests run: 2, Failures: 0, Errors: 0 — 日志成功写入 sys_oper_log(ai_model=qwen3.5-plus 等字段正确)
13:00~13:06 — 测试库执行 AI 迁移 ✅
- 本地 WSL Docker 可连接测试库(
docker exec -i tiny-erp-db psql -U postgres -d tinyerp) - 执行
fix-ai-oper-log.sql,5 个 AI 字段(ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokens)已添加 - 验证本地库(localhost:31983)和测试库(Docker db:5432)字段均存在 ✅
13:08~13:10 — 日志文件冲突问题 → 方案A
问题: IDEA 和 Docker 都在 WSL 同一机器运行,./logs/ 会互相覆盖
方案A: docker-compose 挂载路径改为 ./logs-docker:/app/logs
.gitignore添加logs-docker/Dockerfile保留 root 运行(无USER appuser)- 已实施 ✅
13:11~13:13 — deploy-test.sh 脚本
创建 deploy-test.sh 一键部署脚本:
mvn clean install -DskipTestsdocker compose stop/rm/build/up appcurl health自动验证(失败重试 15s)
13:14~13:22 — 测试目录规范化
问题: 大部分测试包路径缺少 module 层级,与源码不一致
- 移动所有测试到
com.witsoft.erp.module.*包下 - 统一先删旧包(git rm)、再建新包、再写入
- 运行全量测试通过 ✅
test.base.BaseControllerTest保留在com.witsoft.erp.test.base(基建归 test,不归 module)
13:38~14:11 — docs/ 目录全面清理
整理方向:
| 操作 | 说明 |
|---|---|
| ✅ 合并 API 规范到项目规范.md | 删除 docs/API/ |
✅ 删除 docs/数据库/ |
以 SQL 脚本为唯一来源 |
| ✅ 文档按模块移入对应子目录 | 06-AI单据识别需求.md → 需求/AI模块,物料信息填充公共服务总结.md → 设计/主数据模块 |
| ✅ 按模块独立编号 | 全局连续 → 每个模块 01- 起编 |
| ✅ 测试文件重排序 | 按 登录→首页→物料→字典→入库出库→库存盘点→操作日志 排列 |
| ✅ README.md 同步 | 目录结构、版本历史逐一同步,标注"(预留)"空目录 |
编号规则变更: 跨模块连续编号(旧)→ 按模块独立编号(新),新增文档只加模块内序号,不碰其他模块。
14:14 — UserContext 使用指南.md 文件缺失
文档中引用 设计/系统模块/UserContext 使用指南.md,但实际文件不存在(被 yangxuan/ → docs/ 重命名遗漏)。已补充。
14:18 — docs/测试 HTTP 文件重排序 ✅
按执行依赖逻辑重新编号:
| 序号 | 文件 | 说明 |
|---|---|---|
| 00 | 登录登出 | 先拿 token |
| 01 | 首页 API 测试 | 仪表盘概览 |
| 02 | 物料分页 | 基础数据查询 |
| 03 | 数据字典与映射 | 字典+翻译 |
| 04 | 入库出库 | 核心业务流程 |
| 05 | 实时库存&盘点 | 库存状态 |
| 06 | 操作日志 | 审计兜底 |
同步更新了 docs/README.md。
14:24 — scripts/postgresql 目录组织讨论
话题: 杨轩问脚本目录是否可以按 ddl/dml/init 或按模块区分。
分析结果: 当前脚本目录的问题:
- 编号混乱(00/03/10/20/21/22...99,无一致规则)
- DDL/DML 混在一起(如 10-system.sql 既建表又插数据)
- fix- 前缀不统一(26-material-last-price.sql 也是 ALTER 但没用 fix- 前缀)
方案A(用户选中): 二级目录 ddl/、dml/、migration/、mock/,根目录保留一个 init.sql 通过 \i 引用子目录文件(因为 docker-entrypoint-initdb.d 只处理扁平 .sql 文件)。
待实现: [not yet started — compaction happened before implementation]
10:50 — AI 调用记录方案评估
话题: 记录 AI 调用(session_id, tokens, 返回结果),复用操作日志机制
评估结论:方案 A — 扩展 OperLog
sys_oper_log新增 5 字段:ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokensmodule复用为"AI识别"/"AI对话"区分业务- 复用现有 OperLog 全部基础设施(service/mapper/controller/分页/查询)
- 工作量最小,约 20min
- 方案已确认,待实现
10:50 — Git 约定提醒
提示 commit 时必须附带 commit message,让用户可直接复制运行。
11:08~11:18 — AI 调用记录实现 ✅
改动点:
scripts/postgresql/10-system.sql— DDL 新增ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokensscripts/postgresql/fix-ai-oper-log.sql— 迁移脚本(新增)OperLog.java— 实体添加 5 个对应字段AiServiceImpl.java— 注入OperLogService,在chatText()/chatWithImages()调用前后记录日志(含 sessionId, tokens, 耗时, 输入/输出摘要)AiChatResponseDTO— 新增sessionId字段DeepSeekChatRequestDTO— 新增sessionId字段(@JsonIgnore,仅用于日志传递)
执行迁移: 本地库(localhost:31983)跑 fix-ai-oper-log.sql
测试结果: ✅ Tests run: 2, Failures: 0, Errors: 0 — 日志成功写入 sys_oper_log(ai_model=qwen3.5-plus 等字段正确)
13:00~13:06 — 测试库执行 AI 迁移 ✅
- 本地 WSL Docker 可连接测试库(
docker exec -i tiny-erp-db psql -U postgres -d tinyerp) - 执行
fix-ai-oper-log.sql,5 个 AI 字段(ai_session_id,ai_model,prompt_tokens,completion_tokens,total_tokens)已添加 - 验证本地库(localhost:31983)和测试库(Docker db:5432)字段均存在 ✅
13:08~13:10 — 日志文件冲突问题 → 方案A
问题: IDEA 和 Docker 都在 WSL 同一机器运行,./logs/ 会互相覆盖
方案A: docker-compose 挂载路径改为 ./logs-docker:/app/logs
.gitignore添加logs-docker/Dockerfile保留 root 运行(无USER appuser)- 已实施 ✅
13:11~13:13 — deploy-test.sh 脚本
创建 deploy-test.sh 一键部署脚本:
mvn clean install -DskipTestsdocker compose stop/rm/build/up appcurl health自动验证(失败重试 15s)
13:14~13:22 — 测试目录规范化
问题: 大部分测试包路径缺少 module 层级,与源码不一致
- 移动所有测试到
com.witsoft.erp.module.*包下 - 统一先删旧包(git rm)、再建新包、再写入
- 运行全量测试通过 ✅
test.base.BaseControllerTest保留在com.witsoft.erp.test.base(基建归 test,不归 module)
13:38~14:11 — docs/ 目录全面清理
整理方向:
| 操作 | 说明 |
|---|---|
| ✅ 合并 API 规范到项目规范.md | 删除 docs/API/ |
✅ 删除 docs/数据库/ |
以 SQL 脚本为唯一来源 |
| ✅ 文档按模块移入对应子目录 | 06-AI单据识别需求.md → 需求/AI模块,物料信息填充公共服务总结.md → 设计/主数据模块 |
| ✅ 按模块独立编号 | 全局连续 → 每个模块 01- 起编 |
| ✅ 测试文件重排序 | 按 登录→首页→物料→字典→入库出库→库存盘点→操作日志 排列 |
| ✅ README.md 同步 | 目录结构、版本历史逐一同步,标注"(预留)"空目录 |
编号规则变更: 跨模块连续编号(旧)→ 按模块独立编号(新),新增文档只加模块内序号,不碰其他模块。
14:14 — UserContext 使用指南.md 文件缺失
文档中引用 设计/系统模块/UserContext 使用指南.md,但实际文件不存在(被 yangxuan/ → docs/ 重命名遗漏)。已补充。
14:18 — docs/测试 HTTP 文件重排序 ✅
按执行依赖逻辑重新编号:
| 序号 | 文件 | 说明 |
|---|---|---|
| 00 | 登录登出 | 先拿 token |
| 01 | 首页 API 测试 | 仪表盘概览 |
| 02 | 物料分页 | 基础数据查询 |
| 03 | 数据字典与映射 | 字典+翻译 |
| 04 | 入库出库 | 核心业务流程 |
| 05 | 实时库存&盘点 | 库存状态 |
| 06 | 操作日志 | 审计兜底 |
同步更新了 docs/README.md。
14:24 — scripts/postgresql 目录组织讨论
话题: 杨轩问脚本目录是否可以按 ddl/dml/init 或按模块区分。
分析结果: 当前脚本目录的问题:
- 编号混乱(00/03/10/20/21/22...99,无一致规则)
- DDL/DML 混在一起(如 10-system.sql 既建表又插数据)
- fix- 前缀不统一(26-material-last-price.sql 也是 ALTER 但没用 fix- 前缀)
方案A(用户选中): 二级目录 ddl/、dml/、migration/、mock/,根目录保留一个 init.sql 通过 \i 引用子目录文件(因为 docker-entrypoint-initdb.d 只处理扁平 .sql 文件)。
待实现: [not yet started — compaction happened before implementation]
14:47~15:30 — AI 接口文档 + 测试文件 ✅
AI 接口文档: docs/需求/AI模块/02-AI单据识别接口文档.md
AI 测试文件: docs/测试/07-AI单据识别.http
- 解释了 exactMatch=false 仍有 materialId 的语义:近似匹配自动选最佳,前端标黄提示
docs/README.md同步更新
提交策略: 用户自行处理敏感配置文件的版本管理(application.yml、application-local.yml、scripts/idea/http-client.env.json)
15:30~16:20 — 物料选择器 excludedMaterialIds 实现 ✅
需求: 出库/入库选择器支持排除已选物料
改动点:
MaterialSelectorReqDTO— 新增excludedMaterialIds(List<Long>)MaterialServiceImpl— 4 个分页/计数方法加excludedMaterialIds参数StockMapper.xml— 4 个 SQL 加<if test="excludedMaterialIds != null and excludedMaterialIds.size() > 0"> AND s.material_id NOT IN ...</if>MaterialSelectorServiceImpl— 新增filterExcludedIds()私有方法做内存过滤 + queryByIds 方法加上排除逻辑
MyBatis 行为验证:
null→ false,跳过 NOT IN[](空列表)→size() > 0为 false,跳过 NOT IN[1, 2]→ 进 NOT IN,WHERE 过滤
测试覆盖: 集成测试三类场景全部通过 ✅
testMaterialSelector_empty(传 null)✅testMaterialSelector_emptyExcludeList(传[])✅testMaterialSelector_withExcludedIds(传实际 ID,验证排除正确)✅
15:55 — 测试编号冲突修复
问题: 新增物料选择器测试插入 @Order(4)/@Order(5) 后,原有的 @Order(4)(新增出库单)和 @Order(5)(明细为空)未重编号,导致 @Order(4)/@Order(5)/@Order(7) 重复
修复: 将所有 @Order(n) 增加 2(n>=4 的改成 n+2),最后 2 个测试增加 2。涉及约 20 个测试方法。
16:05 — 测试 bug 修复
问题: 排除测试中 assertFalse(list.stream().anyMatch(s -> s.getId().equals(excludedId))) 失败
原因: StockPageDTO.getId() 返回库存记录 ID(s.id),而非物料 ID(s.material_id)。SQL NOT IN 排除的是 material_id,但测试用 getId() 取了库存记录 ID
修复: 改用 getMaterialId() 验证排除