|
@@ -12,17 +12,18 @@
|
|
|
|
|
|
|
|
| # | 问题ID | 模块 | 严重度 | 状态 | 发现日期 | 根因确认日期 | 解决日期 |
|
|
| # | 问题ID | 模块 | 严重度 | 状态 | 发现日期 | 根因确认日期 | 解决日期 |
|
|
|
|---|--------|------|--------|------|----------|-------------|----------|
|
|
|---|--------|------|--------|------|----------|-------------|----------|
|
|
|
-| 1 | ISSUE-001 | 商品上下架 | 中 | 待解决 | 2026-06-29 | — | — |
|
|
|
|
|
|
|
+| 1 | ~~ISSUE-001~~ | ~~商品上下架~~ | ~~中~~ | ✅ 已解决 | 2026-06-29 | 2026-06-30 | 2026-06-30 |
|
|
|
| 2 | ~~ISSUE-002~~ | ~~文章发布~~ | ~~高~~ | ✅ 已解决 | 2026-06-29 | 2026-06-29 | 2026-06-29 |
|
|
| 2 | ~~ISSUE-002~~ | ~~文章发布~~ | ~~高~~ | ✅ 已解决 | 2026-06-29 | 2026-06-29 | 2026-06-29 |
|
|
|
-| 3 | ISSUE-003 | 创建用户 | 中 | ✅ 根因已确认 | 2026-06-29 | 2026-06-30 | — |
|
|
|
|
|
|
|
+| 3 | ~~ISSUE-003~~ | ~~创建用户~~ | ~~中~~ | ✅ 已解决 | 2026-06-29 | 2026-06-30 | 2026-06-30 |
|
|
|
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## ISSUE-001:供应商端商品上下架失败
|
|
## ISSUE-001:供应商端商品上下架失败
|
|
|
|
|
|
|
|
**严重度**: 中
|
|
**严重度**: 中
|
|
|
-**状态**: 待解决
|
|
|
|
|
|
|
+**状态**: ✅ 已解决(commit `d7a1c29`)
|
|
|
**发现日期**: 2026-06-29
|
|
**发现日期**: 2026-06-29
|
|
|
|
|
+**解决日期**: 2026-06-30
|
|
|
**模块**: 商品管理 / 供应商权限
|
|
**模块**: 商品管理 / 供应商权限
|
|
|
**测试用例**: `VENDOR-PRODUCT-SHELVE`
|
|
**测试用例**: `VENDOR-PRODUCT-SHELVE`
|
|
|
|
|
|
|
@@ -48,36 +49,40 @@
|
|
|
**文件**: `cfc-backend/src/main/java/com/etotem/cfc/service/ProductService.java`
|
|
**文件**: `cfc-backend/src/main/java/com/etotem/cfc/service/ProductService.java`
|
|
|
|
|
|
|
|
```java
|
|
```java
|
|
|
-// line 122-143
|
|
|
|
|
-public Result<String> shelve(Long productId, Long vendorId, String action) {
|
|
|
|
|
- Product product = productMapper.selectById(productId);
|
|
|
|
|
- // ...
|
|
|
|
|
- if (!"approved".equals(product.getStatus())) { // ← BUG
|
|
|
|
|
- return Result.error("商品未通过审核,无法上下架");
|
|
|
|
|
- }
|
|
|
|
|
- // ...
|
|
|
|
|
|
|
+// 修复前:统一检查 status=="approved"
|
|
|
|
|
+if (!"approved".equals(product.getStatus())) { // ← BUG
|
|
|
|
|
+ return Result.error("商品未通过审核,无法上下架");
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
供应商调用 `shelve` 时,商品状态已为 `on_shelf`(管理员已上架),而非 `approved`。
|
|
供应商调用 `shelve` 时,商品状态已为 `on_shelf`(管理员已上架),而非 `approved`。
|
|
|
-`ProductService.shelve()` 仅允许状态为 `approved` 时操作,但管理员上架后状态变为 `on_shelf`,导致供应商无法再次上下架。
|
|
|
|
|
-
|
|
|
|
|
-**正确逻辑**:供应商侧上下架应允许状态为 `approved`(待上架)或 `off_shelf`(已下架)。
|
|
|
|
|
|
|
+原代码仅允许状态为 `approved` 时操作,但管理员上架后状态变为 `on_shelf`,导致供应商无法再次上下架。
|
|
|
|
|
|
|
|
-### 影响范围
|
|
|
|
|
|
|
+### 修复方案
|
|
|
|
|
|
|
|
-- 供应商无法自主管理商品上下架状态
|
|
|
|
|
-- 管理员上架后,供应商只能等待管理员下架才能操作
|
|
|
|
|
-
|
|
|
|
|
-### 修复建议
|
|
|
|
|
|
|
+按动作区分状态检查:
|
|
|
|
|
+- **上架**(action=shelve):允许 `approved`(待上架)或 `off_shelf`(已下架)→ 变为 `on_shelf`
|
|
|
|
|
+- **下架**(action=unshelve):允许 `on_shelf`(已上架)→ 变为 `off_shelf`
|
|
|
|
|
|
|
|
```java
|
|
```java
|
|
|
-// ProductService.shelve() 中 line 130 修改为:
|
|
|
|
|
-if (!"approved".equals(product.getStatus()) && !"off_shelf".equals(product.getStatus())) {
|
|
|
|
|
- return Result.error("商品未通过审核,无法上下架");
|
|
|
|
|
|
|
+if ("shelve".equals(action)) {
|
|
|
|
|
+ if (!"approved".equals(product.getStatus()) && !"off_shelf".equals(product.getStatus())) {
|
|
|
|
|
+ return Result.error("商品未通过审核,无法上架");
|
|
|
|
|
+ }
|
|
|
|
|
+ product.setStatus("on_shelf");
|
|
|
|
|
+} else if ("unshelve".equals(action)) {
|
|
|
|
|
+ if (!"on_shelf".equals(product.getStatus())) {
|
|
|
|
|
+ return Result.error("商品未上架,无法下架");
|
|
|
|
|
+ }
|
|
|
|
|
+ product.setStatus("off_shelf");
|
|
|
}
|
|
}
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
|
|
+### 影响范围
|
|
|
|
|
+
|
|
|
|
|
+- 供应商无法自主管理商品上下架状态
|
|
|
|
|
+- 管理员上架后,供应商只能等待管理员下架才能操作
|
|
|
|
|
+
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## ISSUE-002:文章创建后发布失败
|
|
## ISSUE-002:文章创建后发布失败
|
|
@@ -139,8 +144,9 @@ if (!"approved".equals(product.getStatus()) && !"off_shelf".equals(product.getSt
|
|
|
## ISSUE-003:管理员创建用户500错误
|
|
## ISSUE-003:管理员创建用户500错误
|
|
|
|
|
|
|
|
**严重度**: 中
|
|
**严重度**: 中
|
|
|
-**状态**: 待解决
|
|
|
|
|
|
|
+**状态**: ✅ 已解决(commit `d7a1c29`)
|
|
|
**发现日期**: 2026-06-29
|
|
**发现日期**: 2026-06-29
|
|
|
|
|
+**解决日期**: 2026-06-30
|
|
|
**模块**: 用户管理
|
|
**模块**: 用户管理
|
|
|
**测试用例**: `ADMIN-CREATE-PARENT`
|
|
**测试用例**: `ADMIN-CREATE-PARENT`
|
|
|
|
|
|
|
@@ -162,31 +168,39 @@ if (!"approved".equals(product.getStatus()) && !"off_shelf".equals(product.getSt
|
|
|
|
|
|
|
|
### 根因分析
|
|
### 根因分析
|
|
|
|
|
|
|
|
-**分析**:`AdminController.createUser()` 逻辑清晰——检查手机号是否已存在 → 新建 User → `userMapper.insert(user)`。
|
|
|
|
|
|
|
+**根因确认**:`users` 表 DDL 中 `openid VARCHAR(64) NOT NULL` 和 `family_id BIGINT NOT NULL` 两个字段不可为空,但 `AdminController.createUser()` 未设置这两个字段的值,导致 MyBatis-Plus 插入时写入 `NULL` 触发 MySQL 字段约束异常,Spring Boot 返回默认 500 错误页面。
|
|
|
|
|
+
|
|
|
|
|
+**文件**: `cfc-backend/src/main/java/com/etotem/cfc/controller/admin/AdminController.java`
|
|
|
|
|
+
|
|
|
|
|
+```java
|
|
|
|
|
+// 修复前:未设置 openid 和 family_id
|
|
|
|
|
+User user = new User();
|
|
|
|
|
+user.setPhone(phone);
|
|
|
|
|
+// ... 缺少 openid 和 family_id 默认值
|
|
|
|
|
+userMapper.insert(user); // → MySQL 报错: Field 'openid'/'family_id' has no default value
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 修复方案
|
|
|
|
|
+
|
|
|
|
|
+在创建用户时补充 NOT NULL 字段的默认值:
|
|
|
|
|
|
|
|
-500 错误(Spring 默认错误页面,非 `Result.error`)表明是**数据库写入异常**,可能原因:
|
|
|
|
|
-1. **数据库字段约束**:phone 字段有唯一索引,但 check constraint 失败
|
|
|
|
|
-2. **外键约束**:`family_id`、`role` 等字段引用不存在的记录
|
|
|
|
|
-3. **字段 not null 但未设置默认值**:`password=""` 可能违反 DB 约束
|
|
|
|
|
-4. **MySQL 触发器异常**
|
|
|
|
|
-5. **数据库连接池耗尽或超时**
|
|
|
|
|
|
|
+```java
|
|
|
|
|
+user.setOpenid(""); // 非微信用户,默认空值
|
|
|
|
|
+user.setFamilyId(0L); // 尚未加入家庭,默认 0
|
|
|
|
|
+```
|
|
|
|
|
|
|
|
### 影响范围
|
|
### 影响范围
|
|
|
|
|
|
|
|
- 管理员无法通过管理后台创建新用户
|
|
- 管理员无法通过管理后台创建新用户
|
|
|
- 影响自动化测试中的用户创建流程
|
|
- 影响自动化测试中的用户创建流程
|
|
|
|
|
|
|
|
-### 修复建议
|
|
|
|
|
-
|
|
|
|
|
-1. 检查 `users` 表结构:`SHOW CREATE TABLE users;`
|
|
|
|
|
-2. 检查 `password` 字段约束(空字符串是否允许)
|
|
|
|
|
-3. 查看远程 MySQL 错误日志
|
|
|
|
|
-4. 考虑使用 `phone` 为空或 null 测试边界情况
|
|
|
|
|
-
|
|
|
|
|
---
|
|
---
|
|
|
|
|
|
|
|
## 更新记录
|
|
## 更新记录
|
|
|
|
|
|
|
|
| 日期 | 操作人 | 内容 |
|
|
| 日期 | 操作人 | 内容 |
|
|
|
|------|--------|------|
|
|
|------|--------|------|
|
|
|
-| 2026-06-29 | Sisyphus | 创建问题追踪文档,录入 ISSUE-001/002/003 |
|
|
|
|
|
|
|
+| 2026-06-29 | Sisyphus | 创建问题追踪文档,录入 ISSUE-001/002/003 |
|
|
|
|
|
+| 2026-06-30 | Sisyphus | ✅ 修复 ISSUE-001:ProductService.shelve() 状态检查按动作区分(上架允许 approved/off_shelf,下架允许 on_shelf) |
|
|
|
|
|
+| 2026-06-30 | Sisyphus | ✅ 修复 ISSUE-003:AdminController.createUser() 补充 openid="" / familyId=0L 默认值 |
|
|
|
|
|
+| 2026-06-30 | Sisyphus | 后端 jar 重新部署到 251(commit `d7a1c29`)|
|