周到 第2次个人汇报 - xiaochu-dev/online-shopping-group5 GitHub Wiki

周到:第2次个人汇报

  • 汇报人:周到(产品经理)
  • 报告期次:第2次
  • 报告日期:2026-10-22
  • 项目:第5组在线购物系统(迭代 2 · 挑战需求 A)
  • 我负责的任务:T2-13 ~ T2-18,共 6 项、15 个故事点
  • 演示录屏:下载 · 买家门户与交易(1920×1072,25fps,1.3 MB)

本迭代我负责的是「买家门户 + 交易推进」这一段:买家进站能看到哪些商品、怎么找到它、能不能下单、下完在哪看结果,以及卖家怎么把一笔意向推进成成交。三人的包是物理隔离的——buyer/、admin/ 归胡成溯,product/ 归黄程宇,portal/ 归我,我只改 portal/。

和迭代 1 相比,这一版的门户不是「加功能」,而是换了一套身份模型:迭代 1 靠 32 位口令码认领意向,A 口径定「下单必须注册登录」之后,口令码整条链路下线,买家身份从「一串码」变成「一个账号」。我这一层的所有查询都从 token_code 换成了 buyer_id。

一、我完成了什么

任务 我的具体工作 成果链接
T2-13 商品列表(分页 + 分类筛选) 只查 status = 'on_sale',按 published_at 倒序、id 兜底;分页非法入参(page=0、size=-5)归一化到默认值而不是抛错;分类下拉只列 enabled 分类,筛选走 category_id 索引 PortalController、PortalService
T2-14 关键词搜索 名称 + 描述双字段模糊匹配,用 LambdaQueryWrapper.like() 拼接而非手拼字符串;可与分类筛选叠加;两种空态文案分开(有筛选条件 → 「没有找到符合条件的商品」+ 一键清空;一件都没在售 → 「暂无商品在售」) PortalService、product-list.html
T2-15 商品详情页 状态分流:on_sale 可下单、frozen 展示「交易中」且表单整块替换为不可下单提示、delisted 走 404 错误页而不是 500;展示当前排队人数;富文本描述原样渲染(A 口径:不做白名单过滤) product-detail.html
T2-16 下单(强制登录) 未登录先跳 /buyer/login?redirect=/products/{id},登录后原地回到详情页继续下单;姓名与电话取注册资料快照写入单据;交易地点默认带出注册时的默认地点、可当次改写;提交时不扣库存;同一买家对同一商品最多 1 条未结束意向;不再生成口令码;老库启动时自动升级(IntentSchemaMigrator,迭代 1 的库不用删库重建) PortalService、03-intent.sql、IntentSchemaMigrator
T2-17 我的订单 只查已有结果的单(trade_result in (success, failed)),排队中/交易中的不出现;按 finished_at 倒序分页;字段含商品名、下单时间、交易结果、交易时间、失败原因、交易地点;WHERE buyer_id = ? 保证换号不串数据 MyOrdersController、OrderHistoryService、my-orders.html
T2-18 卖家交易确认 按商品看待处理意向数 → 点进队列看位次 → 只能从队首确认(跳过队首被服务端拒绝);确认后商品 frozen;标成功扣 1 件库存并把商品解冻回 on_sale;标失败库存不动、商品回 on_sale,该买家二选一(作废 / 塞回队尾);全程没有独立的「取消」状态——取消就是交易失败 SellerIntentController、SellerIntentService、seller-intents.html

另外单独写了买家侧的公共片段 portal/fragments.html,没有动 fragments/layout.html——那条顶栏是卖家视角(后台首页 / 基座自检 / 退出登录),放进一个免登录的买家页面讲不通。

二、验收方式

三条链路写成了 3 个用例类、26 个用例,mvn test 全项目 83 项全绿:

Tests run: 83, Failures: 0, Errors: 0, Skipped: 0
  PortalFlowTest        14 项   列表 / 搜索 / 分类 / 分页 / 详情 / 未登录下单 / 快照落库 / 重复提交被拒 / 地址必填
  MyOrdersFlowTest       3 项   未登录拦截 / 只显示已结果单并按交易时间倒序 / 换号不串数据
  SellerTradeFlowTest    9 项   未登录拦截 / 待处理计数 / 跳过队首被拒 / 确认后冻结 / 冻结期不能再开第二笔 /
                                成功扣库存并解冻 / 失败作废库存不动 / 失败塞回队尾 / 队列只展示未结束意向

三、界面与入口

运行环境:iter2-java 分支,mvnw.cmd spring-boot:run,端口 8080。演示数据:3 个买家(zhangming / liting / wangfang)+ 6 件商品(1 件已下架、1 件交易中)+ 5 条意向。

1. 商品列表(免登录可浏览)

商品列表:4 件在售,已下架与交易中的商品不出现在列表中

6 件商品里只出 4 件:下架的「罗技 M330」不出现,冻结中的「软件工程教材」也不出现。价格统一显示为 ¥ 299.00——库里存「分」,展示时除以 100,测试里专门断言过。

2. 关键词搜索(命中名称与描述)

搜「键盘」只命中机械键盘,出现「清空条件」按钮

搜「键盘」命中商品名;搜「实验指导」这类词则命中描述里的字。有筛选条件时才出现「清空条件」,无筛选时不出现。

3. 分类筛选

按「图书教材」筛选,只剩 1 件在售

「图书教材」下本来有 2 件,另一件正在交易中,所以只剩 1 件——这是状态过滤与分类过滤叠加后的正确结果。

4. 商品详情(在售 / 未登录)

详情页:未登录时按钮为「登录后购买」

未登录也能看详情(浏览不拦截),但下单区明确写「购买商品需要先注册并登录」,按钮变成「登录后购买」。

5. 未登录下单 → 跳登录页并带回跳地址

买家登录页,URL 带 redirect=/products/1

地址栏是 /buyer/login?redirect=%2Fproducts%2F1,登录成功后直接回到刚才那件商品,不用重新找。

6. 已登录的下单表单

已登录:只需选择交易地点,姓名电话取注册资料

表单只剩「交易地点」一个输入框(留空则用注册时填的默认地点)。姓名和电话不再让买家手填——它们从注册资料取快照写进单据,这样卖家在队列里看到的永远是下单当时的信息,买家事后改资料不会篡改历史单据。

7. 下单成功提示

下单成功:跳到详情页并提示等待卖家确认

下单成功后回到详情页,顶部提示「购买意向已提交,等待卖家确认」。注意这里没有口令码了——迭代 1 那个「只显示一次、丢了无法撤销」的页面已经整体下线。

8. 交易中的商品无法下单

商品处于交易中,下单区替换为红色提示

卖家确认交易后,商品进入 frozen,详情页仍可访问但整块下单表单被替换成「该商品正在交易中,暂时无法提交意向」。这就是「整件冻结」在买家侧的可视表现。

9. 我的订单(只显示已有结果)

我的订单:1 条交易失败(红)、1 条交易成功(绿)

同一个买家(zhangming)有两笔单:成功的那笔显示交易时间与交易地点,失败的那笔多一列失败原因。排队中和交易中的单不在这里——页面上明确写了这句话,避免买家以为自己的单丢了。

10. 卖家:交易与意向总览

卖家意向总览:按商品显示待处理意向数

按商品聚合:显示器 2 条待处理、软件工程教材 1 条(交易中),其余为 0 或「无」。

11. 卖家:意向队列与交易确认

意向队列:位次 1 可确认,位次 2 需等待

只有位次 1 有「确认交易」按钮,位次 2 显示「等待前面的人处理」;页面底部写清了「本系统没有单独的取消状态,取消等于交易失败,库存不动」。

四、演示录屏

录屏文件 演示录屏-买家门户与交易.mp4:下载。

时间 画面 对应任务
0:00–0:08 买家首页:共 3 件在售商品,搜索框 + 两级分类下拉 T2-13
0:08–0:16 搜「键盘」只命中 1 件并出现「清空条件」;再按「全部 · 数码电子」筛选 T2-14、T2-13
0:16–0:30 详情页:可售库存 1 件、当前 0 人排队;填交易地点后提交意向 T2-15、T2-16
0:30–0:40 卖家「交易与意向」总览:该商品 1 条待处理,点进队列只有位次 1 有「确认交易」 T2-18
0:40–0:48 点确认交易 → 「已标记交易成功,库存扣减 1 件」→ 商品自动下架、队列清零 T2-18(扣减与自动下架由商品中心的库存服务执行)
0:48–0:55 我的订单:该笔交易成功,带交易时间与交易地点 T2-17

五、协作分工与边界

三个人按代码包物理隔离:buyer/、admin/、auth/、common/ 归胡成溯,product/ 归黄程宇,portal/ 归我。

  • 我只改 portal/,需要别人东西的地方一律走契约接口(CategoryPort / ProductPort / SellerContext / IntentHistoryPort)。其中 IntentHistoryPort 是组长定义的接口、我来实现(IntentHistoryProvider),因为客户详情页要显示购买历史,数据在我的 intent 表里——跨模块读数据时,接口由消费方定义、由数据持有方实现,这个方向是对的。
  • 临时适配层是有期限的:portal/contract/adapter 这一层是给「别人的正式服务还没合入」用的——依赖没到位时保证门户照常启动,等对方的 Service 注册成 Bean,我的实现自动退让、门户代码零改动。CategoryQueryService / StockService 合入后整个包删除。我在类注释里写明了这条纪律,避免过渡方案变成永久架构。
  • 因为改了他的 BuyerAuthTest 一条断言(historyReady 从 false 改成 true,因为我实现了 IntentHistoryPort),已在代码注释里说明原因,避免他回看时以为是误改。

六、与基线需求的差异

# 差异 原因
1 口令码整条链路下线,仅保留 POST /intents/cancel 兜底接口 A 口径:「下单必须先注册登录」,身份由账号识别。兜底接口保留是为了迭代 1 的验收材料仍可复现,计划迭代 3 移除
2 客户不能自己取消意向,也看不到排队位次 A 口径:取消/重排由卖家在后台确认,位次不展示给买家(卖家侧仍按先到先得排队)
3 「同一时间在售仅一件」的基线约束作废 A.1 要求多商品并行在售

七、教师点评与后续改进

评审后按实际记录填写,并同步到第2次阶段性评审报告对应任务的「教师评审意见」列。

教师点评 对应任务或问题 后续改进行动 完成与验证记录
待评审后填写 — — —

返回项目 Wiki 首页