第1组 · 林初俊 · 第1次评审详情 - sebestp/coursewise GitHub Wiki
- 报告期次:第1次 | 报告日期:2026-10-08 | 项目组号:第1组 | 项目名称:在线购物系统
- 已完成工作:实现 Java 买家端与交易流转模块(提交意向与 8 位唯一口令码、凭码查询位次、修改信息不改位次、撤销留痕、队首自动进入交易并冻结、标记成功清队进历史、标记失败自动递补、失败买家重排沿用原码排队尾,454 行 5 接口),并编写 JUnit 5 单元测试 16 组(457 行,mvn test 实测 16 通过 0 失败 0 跳过)
- 成果物:买家端模块实现(含交易流转与单元测试)
第 1 组 · 在线购物系统 | 完成人:林初俊 | 完成日期:2026-10-07 对应提交:
cac53ac| 代码位置:server/src/main/java/.../与server/src/test/java/.../
| 文件 | 行数 | 职责 |
|---|---|---|
service/IntentService.java |
213 | 提交意向、口令码查询、修改信息、撤销意向、当前商品查询 |
service/TradeService.java |
149 | 交易流转核心:进入交易、标记结果、处置失败意向 |
controller/BuyerController.java |
92 | 5 个买家端 REST 接口 |
test/.../BuyerApiTest.java |
252 | JUnit 5 + MockMvc,16 组用例中的第 1~11 组 |
test/.../TradeFlowTest.java |
205 | JUnit 5,第 12~16 组(直调 TradeService + MockMvc 验证对外行为) |
业务代码 454 行 + 测试 457 行。
| # | 接口 | 关键规则 |
|---|---|---|
| 1 | GET /api/product |
买家浏览当前在售商品 |
| 2 | POST /api/intents |
生成 8 位口令码(字符集剔除易混淆的 I/O/0/1),查库保证全库唯一,仅在提交响应中返回一次 |
| 3 | GET /api/intents/lookup/{code} |
返回位次与状态;进入交易时 position=null、inTransaction=true;无效或已终态码返回 404 |
| 4 | PUT /api/intents/lookup/{code} |
只更新姓名电话,submittedAt 不动 → 排队位次不变
|
| 5 | POST /api/intents/lookup/{code}/cancel |
交易中拒绝撤销;其余置 cancelled(终态留痕) |
规则逐条依据 需求规格说明书 第 4.1~4.3 节的状态机与排队规则实现,未作改动:
-
进入交易:取队列首位(
submittedAt正序、id 兜底,卖家不可挑人)置in_transaction;商品自动置冻结、frozenBy='auto';队列为空则拒绝。 - 标记成功:当前意向置成功且已处置;队列剩余全部转失败并已处置;商品下架进历史,全部口令码失效。
- 标记失败:当前意向转失败待处置;队列有人 → 下一位自动递补进入交易(商品保持冻结);队列无人 → 商品恢复在售。
-
处置失败意向:
void只作废;requeue新建排队记录、沿用原口令码、submittedAt刷新(排到队尾)、requeuedFrom指向原意向。
技术说明(TD-1):Intent.code 有数据库唯一约束,重排沿用原码时两行不能同码。处理为:已终态原记录改码为 原码#r{id} 占位(终态意向对外不返回口令码)、新记录沿用原码。本模块进一步修复了原临时实现中 Hibernate「INSERT 先于 UPDATE」会撞唯一约束的缺陷,改为 saveAndFlush 先落库。
组长本地复跑实测结果:
[INFO] Tests run: 11, Failures: 0, Errors: 0, Skipped: 0 -- in BuyerApiTest
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0 -- in TradeFlowTest
[INFO] Tests run: 16, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
| # | 用例 | # | 用例 |
|---|---|---|---|
| 1 | 错误密码登录返回 401 | 9 | 修改电话后位次不变 |
| 2 | 不带 X-Token 访问后台返回 401 | 10 | 撤销意向后该口令码查询返回 404 |
| 3 | 发布价格为 -1 的商品返回 400 | 11 | 商品冻结后提交意向返回 400 |
| 4 | 发布成功且价格保留两位小数 | 12 | 交易中手动解冻返回 400 |
| 5 | 已有在售商品时再次发布返回 400 | 13 | 标记失败后下一位自动递补进入交易 |
| 6 | 三个买家依次入队,位次 1、2、3 | 14 | 失败买家重排后原口令码仍有效且排到队尾 |
| 7 | 姓名或电话为空提交意向返回 400 | 15 | 标记成功后队列剩余意向全部转为失败 |
| 8 | 无效口令码查询返回 404 | 16 | 历史详情的意向流水中不包含 code 字段 |
测试设计:@SpringBootTest + @AutoConfigureMockMvc 走真实 Spring MVC 链路(含统一异常处理),每个用例前清空数据保证相互独立,断言 HTTP 状态码与错误文案。
| 技术债 | 处理 |
|---|---|
| TD-2 |
ProductService 注入 TradeService,删除三个带 TODO 的临时方法(enterDealTemp / markResultTemp / disposeFailedTemp),改为正式调用 |
| TD-3 | 从 SellerController 删除临时 GET /api/product,仅保留在 BuyerController,避免 Spring Boot 重复映射导致启动失败 |
(评审后填写)