# 调用日志列表增加用户字段实现计划 > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** 在管理后台调用日志列表中增加"调用用户"列,显示格式为 `昵称(ID)`,方便排查用户反馈问题。 **Architecture:** 后端 `AiCallLog` 实体新增 `userName` 字段,两处日志保存逻辑写入该字段;前端列表和详情弹窗统一展示 `昵称(ID)` 格式。 **Tech Stack:** Java (Spring Boot 2.7 + MyBatis-Plus), Vue 3 + TypeScript + Element Plus **Spec:** `docs/superpowers/specs/2026-05-25-call-log-add-user-design.md` --- ## 文件清单 | 操作 | 文件 | 说明 | |------|------|------| | Modify | `backend-single/src/main/java/com/emotion/entity/AiCallLog.java` | 实体新增 `userName` 字段 | | Create | `backend-single/src/main/resources/db/migration/V20260525__add_user_name_to_ai_call_log.sql` | 数据库迁移脚本 | | Modify | `backend-single/src/main/java/com/emotion/service/impl/AiRuntimeServiceImpl.java:68-73` | invokeStream 写入 userName | | Modify | `backend-single/src/main/java/com/emotion/service/impl/AiRuntimeServiceImpl.java:219-225` | invokeEndpointStream 写入 userName | | Modify | `web-admin/src/types/aiconfig.ts` | AiCallLog 接口新增 userName | | Modify | `web-admin/src/views/aiconfig/AiRoutingList.vue` | 列表新增"调用用户"列 + userDisplay 函数 | | Modify | `web-admin/src/views/aiconfig/components/AiCallLogDetailDialog.vue` | 详情弹窗"用户 ID"改为"调用用户" | --- ### Task 1: 后端实体 + 数据库迁移 **Files:** - Modify: `backend-single/src/main/java/com/emotion/entity/AiCallLog.java:29-31` - Create: `backend-single/src/main/resources/db/migration/V20260525__add_user_name_to_ai_call_log.sql` - Test: `backend-single/` 目录下执行编译验证 - [ ] **Step 1: 在 AiCallLog 实体中新增 userName 字段** 在 `userId` 字段(第 29-30 行)下方新增: ```java // AiCallLog.java — 在 @TableField("user_id") private String userId; 之后新增 @TableField("user_name") private String userName; ``` - [ ] **Step 2: 创建数据库迁移脚本** 创建 `backend-single/src/main/resources/db/migration/V20260525__add_user_name_to_ai_call_log.sql`: ```sql -- 调用日志表新增 user_name 字段 ALTER TABLE t_ai_call_log ADD COLUMN user_name VARCHAR(100) DEFAULT NULL COMMENT '用户昵称' AFTER user_id; ``` - [ ] **Step 3: 编译验证后端代码** ```bash cd backend-single mvn clean compile -DskipTests ``` 预期:BUILD SUCCESS - [ ] **Step 4: 提交** ```bash git add backend-single/src/main/java/com/emotion/entity/AiCallLog.java git add backend-single/src/main/resources/db/migration/V20260525__add_user_name_to_ai_call_log.sql git commit -m "feat: 调用日志实体新增 userName 字段及数据库迁移脚本" ``` --- ### Task 2: 后端日志保存逻辑写入 userName **Files:** - Modify: `backend-single/src/main/java/com/emotion/service/impl/AiRuntimeServiceImpl.java` - Test: `backend-single/src/test/java/com/emotion/service/AiRuntimeServiceImplTest.java` - [ ] **Step 1: 在 invokeStream 方法中写入 userName** 找到第 71 行 `callLog.setUserId(resolveUserId(request));` 之后,第 72 行 `callLog.setInputText(...)` 之前,新增: ```java // 在 callLog.setUserId(resolveUserId(request)); 之后新增 callLog.setUserName(request.getUserName()); ``` 修改后的上下文(第 68-74 行)变为: ```java AiCallLog callLog = new AiCallLog(); callLog.setRequestId(requestId); callLog.setSceneCode(request.getSceneCode()); callLog.setUserId(resolveUserId(request)); callLog.setUserName(request.getUserName()); callLog.setInputText(JSON.toJSONString(request.getInputs())); callLog.setStatus("running"); ``` - [ ] **Step 2: 在 invokeEndpointStream 方法中写入 userName** 找到第 223 行 `callLog.setUserId(request.getUserId());` 之后,第 224 行 `callLog.setInputText(...)` 之前,新增: ```java // 在 callLog.setUserId(request.getUserId()); 之后新增 callLog.setUserName(request.getUserName()); ``` 修改后的上下文(第 219-226 行)变为: ```java AiCallLog callLog = new AiCallLog(); callLog.setRequestId(requestId); callLog.setEndpointCode(endpoint.getEndpointCode()); callLog.setProviderCode(provider.getProviderCode()); callLog.setUserId(request.getUserId()); callLog.setUserName(request.getUserName()); callLog.setInputText(JSON.toJSONString(request.getInputs())); callLog.setStatus("running"); ``` - [ ] **Step 3: 更新单元测试,验证 userName 被正确写入** 修改 `backend-single/src/test/java/com/emotion/service/AiRuntimeServiceImplTest.java`,在 `invokeStreamRecoversWhenOutputExists` 测试中: 在已有的 `request.setRequestId("client-request-1");` 之后添加 `request.setUserName("测试用户");`,然后在断言部分新增 userName 的验证: ```java // 在 request.setRequestId("client-request-1"); 之后添加 request.setUserName("测试用户"); // 在已有的 assertEquals("完整输出", savedLog.getOutputText()); 之后添加 assertEquals("测试用户", savedLog.getUserName()); ``` - [ ] **Step 4: 运行测试验证** ```bash cd backend-single mvn test -Dtest=AiRuntimeServiceImplTest ``` 预期:Tests run: 1, Failures: 0, Errors: 0 - [ ] **Step 5: 编译验证 + 提交** ```bash cd backend-single mvn clean compile -DskipTests ``` ```bash git add backend-single/src/main/java/com/emotion/service/impl/AiRuntimeServiceImpl.java git add backend-single/src/test/java/com/emotion/service/AiRuntimeServiceImplTest.java git commit -m "feat: 日志保存时写入 userName 字段" ``` --- ### Task 3: 前端类型定义 + 列表新增列 **Files:** - Modify: `web-admin/src/types/aiconfig.ts:249-250` (AiCallLog 接口) - Modify: `web-admin/src/views/aiconfig/AiRoutingList.vue` (调用日志表格区域) - [ ] **Step 1: AiCallLog 接口新增 userName** 在 `web-admin/src/types/aiconfig.ts` 的 `AiCallLog` 接口中,找到 `userId?: string` 行(约第 249 行),在其下方新增: ```typescript // 在 userId?: string 之后新增 userName?: string ``` - [ ] **Step 2: AiRoutingList.vue 新增"调用用户"列** 在调用日志表格中,找到 `调用时间` 列(``)之后,`场景` 列之前,新增: ```vue ``` - [ ] **Step 3: AiRoutingList.vue 新增 userDisplay 辅助函数** 在 `