需求规格说明书 - H15058218452-rgb/Software-Engineering-Experimental-Group GitHub Wiki

《在线购物系统》需求规格说明书

一、 项目背景与目标

  • 项目背景:本项目为《软件工程实践》课程第一阶段(I)的挑战升级项目。课程以“大模型驱动开发”为背景,强调“定义问题”与“验收结果”。
  • 项目目标:构建一个单卖家、免注册、线下交易的极简在线购物系统(MVP),重点考察需求分析与商品状态流转控制能力。
  • 项目范围:仅开发 Web 网页端,包含卖家后台与买家前台。不包含 Android、iOS、微信小程序客户端。不提供线上支付、物流、商品评价、消息通知功能。

二、 用户角色定义

  1. 卖家:系统的唯一管理员(固定单账号)。使用“用户名+密码”登录后台,可修改密码。负责发布商品、处理交易、查看历史记录。
  2. 买家:免注册用户,无需账号。可匿名浏览商品,提交购买意向时仅需填写姓名和联系电话,凭系统生成的“口令码”管理自己的意向。

三、 子系统划分

根据软件工程模块化设计原则,本系统划分为四个子系统:

  1. 卖家管理子系统:负责卖家登录鉴权、密码修改、商品发布、手动冻结/解冻、交易结果标记、历史商品查看。
  2. 买家交易子系统:负责商品前台展示、买家意向提交、口令码生成与展示、买家意向管理(查询/修改/撤销)。
  3. 交易状态流转子系统(核心):负责商品状态机控制、排队队列管理(先到先得)、交易失败后的自动递补、并发状态校验。
  4. 数据与基础设施子系统:负责数据库表结构设计、图片上传与存储、API 联调、数据持久化。

四、 核心业务规则

1. 商品发布与修改规则

  • 单商品限制:同一时间,系统仅允许 一件 商品处于“在售”状态。要发布新品,必须先将当前商品“交易成功(下架)”或“手动下架”。
  • 不可修改:商品一经发布,名称、描述、图片、价格 均不可修改。如需调整,只能下架后重新发布。
  • 数据约束:
    • 名称:必填,长度无限制。
    • 描述:选填,可为空,长度无限制。
    • 图片:选填,最多上传 1 张主图,格式 JPG/PNG,单张不超过 5MB;不上传则展示占位图。
    • 价格:必填,人民币,保留 2 位小数;必须大于 0,不能为 0 或负数,无上限。

2. 商品状态定义

  • 在售:商品正常展示,可接收买家购买意向。
  • 已冻结(交易中):分为自动冻结与手动冻结,二者共用同一状态。冻结后商品详情仍可浏览,但不再接收新购买意向,买家页面统一提示“商品交易中”。
    • 自动冻结:队首意向进入交易流程时,系统自动触发冻结。
    • 手动冻结:卖家后台主动操作,临时停售商品。
    • 交易中的商品禁止手动解冻,手动解冻仅允许用于卖家手动冻结的商品。
  • 已下架:
    • 路径1:交易成功,商品从冻结直接转为下架,进入历史商品。
    • 路径2:卖家在售状态下手动下架商品,进入历史商品。

3. 排队与“先到先得”机制

  • 排队触发:买家提交购买意向时进入队列,并非“有人提交就冻结商品”。
  • 排序原则:严格按提交时间正序(先到先得)。卖家 无权 手动挑选交易对象。
  • 冻结时机:商品冻结发生在 卖家与队首买家“进入交易” 的那一刻。在此之前,商品仍处于“在售”状态,可继续接收新意向。
  • 队列封闭:一旦进入“已冻结(交易中)”状态,不再接收任何新意向。
  • 自动递补:当队首买家交易失败(或撤销),队列后面的买家 自动按顺序递补 进入交易,商品再次自动冻结,无需卖家手动操作。若队列已空,商品恢复“在售”状态等待新买家。

4. 进入交易的触发机制

  • 触发方:由卖家在后台手动触发。
  • 触发条件:
    1. 商品当前状态为“在售”;
    2. 排队队列中存在至少一位买家(即已提交购买意向);
    3. 队列中无正在进行的交易(上一次交易已结束)。
  • 触发动作:
    1. 卖家在后台的“意向购买人列表”中,点击“开始交易”按钮;
    2. 系统自动将队列中提交时间最早的买家状态变更为“已进入交易”;
    3. 商品状态从“在售”自动变更为“已冻结(交易中)”;
    4. 队列封闭,不再接收任何新的购买意向。
  • 备注:若队列中有多名买家,卖家只能与队首(最早提交)的买家开始交易,无权挑选其他买家。这保证了“先到先得”的公平性。

5. 口令码机制(买家唯一凭证)

  • 生成与展示:买家提交意向后,系统 即时生成 唯一口令码,仅显示一次 在提交成功页面,提醒买家自行保存。不发送短信,无找回功能。
  • 生命周期:
    • 生效:提交意向成功即生效。
    • 失效条件:① 意向彻底终结(成功/作废/撤销);② 商品下架。失效后,买家无法再查询、修改或撤销。
    • 特殊说明:交易失败后若卖家选择“重新排队”,该意向并未终结,口令码继续有效,买家可凭原口令码查询新的排队位次。
  • 权限范围:买家凭口令码可做三件事——① 查询排队位次/状态;② 修改姓名和电话(不影响排队次序);③ 撤销意向(仅限排队阶段,一旦进入交易状态,买家无法自行撤销,只能由卖家标记交易结果)。

6. 交易结果与恢复机制

  • 判定方式:交易是否成功,由 卖家在后台手动标记(成功/失败),系统不自动判断。
  • 标记成功:商品直接下架,进入历史商品。操作不可撤销,一旦标记永久生效。
  • 标记失败:商品立即自动恢复为“在售”,中间无延迟。卖家处置当前意向(作废/重新排队),随后系统检查队列:若有剩余意向,自动递补队首进入交易,商品再次冻结;若无剩余意向,商品保持“在售”状态等待新买家。
  • 买家撤销与商品状态无关:买家撤销意向只是从队列中退出,后面位次前移。商品状态 不因买家撤销而改变,只由卖家标记交易结果决定。

五、 功能需求清单

1. 卖家端(后台管理)

模块 需求描述 备注
登录 卖家使用固定“用户名+密码”登录后台,不提供注册和退出登录功能。 密码加密存储。
修改密码 需验证原密码,新密码长度≥8位。
发布商品 填写名称、描述、图片、价格。同一时间只能有一件在售。 需校验图片格式/大小、价格精度。
手动冻结/解冻 对“在售”商品可手动冻结,对“已冻结(无交易中)”商品可手动解冻。 禁止在交易中手动解冻。
查看意向 查看当前有效意向列表,按提交时间排序,显示姓名、电话、提交时间、交易结果。 不可修改买家意向。
确认交易结果 在线下交易完成后,手动标记“交易成功”或“交易失败”。 标记成功即商品下架;标记失败即商品自动恢复在售并递补。
查看历史商品 查看所有已下架商品,每个商品下挂完整的意向购买人流水。 历史记录只读,持久化保存,重启不丢。

2. 买家端(前台展示)

模块 需求描述 备注
浏览商品 无需登录即可查看当前在售商品的名称、描述、图片、价格。 无商品时展示“暂无商品在售”占位图。
提交意向 点击“我要购买”,填写姓名和联系电话(必填),提交后进入排队队列。 提交成功后展示口令码。
管理意向 凭口令码查询排队位次、修改姓名/电话(不影响位次)、撤销意向。 撤销仅限排队阶段。
查看状态 商品冻结期间,买家仍可浏览详情,但购买按钮置灰,提示“商品交易中”。

3. 后端接口设计初稿(商品模块)

接口名称 请求方式 接口地址 接口说明
发布商品 POST /api/product/publish 卖家发布商品,商品进入“在售”状态。
手动冻结商品 POST /api/product/freeze 卖家手动冻结在售商品,用于临时停售。
手动解冻商品 POST /api/product/unfreeze 卖家手动解冻自己冻结的商品(禁止解冻交易中的商品)。
确认交易成功 POST /api/product/confirm-sold 卖家标记交易成功,商品直接下架,进入历史记录。
确认交易失败 POST /api/product/confirm-failed 卖家标记交易失败,商品自动恢复在售并递补下一位买家。

六、 状态机定义

1. 商品状态流转图

stateDiagram-v2
    [*] --> 在售: 卖家发布商品
    在售 --> 已冻结: 队首意向进入交易(自动冻结)/ 卖家手动冻结
    在售 --> 已下架: 卖家手动下架
    已冻结 --> 已下架: 卖家标记交易成功(商品永久撤下)
    已冻结 --> 在售: 卖家标记交易失败(商品自动恢复在售)
    已下架 --> [*]

注: 交易中的商品禁止卖家手动解冻;手动解冻仅适用于卖家自己手动冻结的商品。

2. 买家意向生命周期图

stateDiagram-v2
    [*] --> 排队中: 买家提交意向
    排队中 --> 已进入交易: 轮到该买家(队首进入交易)
    排队中 --> 已撤销: 买家凭口令码撤销
    已进入交易 --> 交易成功: 卖家标记成功(商品下架)
    已进入交易 --> 交易失败: 卖家标记失败(商品恢复在售)
    交易失败 --> 重新排队中: 卖家选择“重新排队”(排到队尾)
    交易失败 --> 已作废: 卖家选择“作废”
    重新排队中 --> 已进入交易: 再次轮到该买家
    重新排队中 --> 已撤销: 买家凭口令码撤销
    重新排队中 --> 已作废: 卖家选择“作废”
    交易成功 --> [*]
    已撤销 --> [*]
    已作废 --> [*]

注: 交易失败时,若卖家选择“作废”,该买家口令码失效;若选择“重新排队”,口令码继续有效(排到队尾)。

3. 系统主流程图

flowchart TD
    A[卖家登录] --> B[发布商品]
    B --> C[商品进入在售]
    C --> D[买家提交意向]
    D --> E[进入排队队列]
    E --> F[卖家与队列第一位进入交易]
    F --> G[商品自动冻结,队列封口]
    G --> H[线下交易]
    H --> I{卖家标记结果}
    
    I -->|交易成功| J[商品下架,口令码失效]
    J --> K[进入历史记录]
    
    I -->|交易失败| L[商品恢复在售]
    L --> M{队列是否有人}
    M -->|有人| N[系统自动让下一位递补]
    N --> F
    M -->|无人| C
    
    L --> O[卖家决定失败者:作废 或 重新排队]

注: 本图仅覆盖交易主流程。卖家后台的“手动冻结/解冻”功能独立于本流程,不影响自动冻结逻辑。

4. 意向终态(历史记录中)

  • 成功:买到商品(全系统最多一个)。
  • 撤销:买家主动撤销。
  • 失败:其余所有情况(含交易失败被作废、被挤掉没轮上、重新排队后仍未成功等)。
  • 注:不再单独列出“重新排队”作为终态,通过“失败次数”可反推。

七、 非功能性需求与边界规则

  1. 并发处理:严格同一时间的多个意向,采取“先到先得排入队列,后到者等待递补”策略,不报错。
  2. 数据持久化:历史记录持久化存储,系统重启不丢失。需求未规定“永久保留”或保留期限。
  3. 通知机制:系统 无主动推送,买家需自行凭口令码查询进度。
  4. 页面刷新:本版本无自动刷新商品状态功能。
  5. 二次确认:冻结、成交、失败恢复操作 无二次确认弹窗,点击即执行。
  6. 操作不可逆:标记“交易成功”后无法撤销,商品直接永久下架。
  7. 隐私与安全:卖家后台可查看买家电话,但前台不展示买家信息。卖家密码需加密存储。

八、 业务流程

1. 卖家流程

登录后台 → 发布商品(商品进入在售) → 等待买家提交意向形成排队队列 → 队首意向自动进入交易,商品自动冻结 → 线下交易 → 卖家后台标记交易结果。

  • 标记成功:商品下架,可发布新商品。
  • 标记失败:商品恢复在售;卖家处置该意向(作废/重排队尾),系统自动递补下一位意向进入交易,商品再次冻结。若队列已空,商品保持“在售”。

2. 买家流程

浏览在售商品 → 点击购买 → 填写姓名+电话提交意向 → 获取口令码,进入排队队列。

  1. 排队阶段:凭口令码查询位次、修改信息、撤销意向。
  2. 轮到队首:自动进入交易,商品冻结。
  3. 线下交易:等待卖家标记结果;交易结束或商品下架,口令码失效。

九、系统约束与假设条件

9.1 业务约束

  1. 单活跃商品约束:同一时间,系统最多允许一件“未下架商品”存在。未下架商品包括:在售、手动冻结、交易中冻结。要发布新品,当前商品必须已下架。
  2. 买家身份约束:买家无账号体系,口令码是唯一凭证。口令码仅提交成功时显示一次,系统不发送短信、不提供找回。
  3. 先到先得约束:队列严格按 queued_at 正序排列,时间相同按意向 ID 正序。卖家无权挑选交易对象,只能操作队首。
  4. 开始交易约束:买家提交意向只进入队列,不冻结商品。只有卖家执行“开始交易”后,队首意向才进入交易,商品才进入“交易中冻结”。
  5. 撤销边界约束:买家撤销仅允许发生在“排队中”或“重新排队中”。撤销只使该意向退出队列,后续位次前移,不改变商品状态,不触发递补。
  6. 交易失败处置约束:卖家标记交易失败时,必须同时选择当前意向的处置方式:作废或重新排队。系统在同一事务内完成“处置当前意向 + 检查队列 + 自动递补或恢复在售”。
  7. 下架与队列约束:交易成功或卖家手动下架时,商品下架,所有未终态意向统一转为“最终失败”,对应口令码失效。

9.2 开发与运行假设

  1. 假设买家姓名、电话真实有效,系统仅做非空和格式校验,不做真伪核验。
  2. 假设同一手机号同一时间只能存在一条有效意向,不支持同一手机号多队列占位。
  3. 系统无主动推送,买家需凭口令码自行查询进度。
  4. 价格“无上限”指业务不人为封顶,实际存储受数据库精度约束。本版按 DECIMAL(10,2) 验收,有效范围为 0.01 ~ 99,999,999.99。
  5. 若前文接口清单未列“开始交易”“手动下架”接口,开发时应按本口径补充,否则第十二章验收无法落地。

9.3 状态与流程澄清

  1. 商品“已冻结”必须区分为“手动冻结”和“交易中冻结”。二者前端均可提示“商品交易中”,但后端权限不同。
  2. 手动冻结:卖家主动停售,可手动解冻,不可接收新意向。
  3. 交易中冻结:队首进入交易时触发,不可接收新意向,禁止手动解冻,禁止手动下架,只能由卖家标记交易成功或失败。
  4. 交易失败时,若队列还有下一位,商品不经过“在售”中间态,直接由下一位递补并保持“交易中冻结”。
  5. 若卖家选择“重新排队”,该意向排到队尾,更新排队时间,不参与本次递补;若队列无其他人,商品恢复“在售”,该意向仍为“重新排队中”,等待卖家下次开始交易。
  6. 买家在排队阶段撤销,不触发递补;只有交易失败才触发递补。
  7. 交易成功或手动下架后,队列中未轮到、重新排队中的意向全部转为“最终失败”。

十、数据字典简要说明

1. 商品状态字段

值 状态 说明
0 在售 可接收买家意向
1 手动冻结 卖家主动停售,可手动解冻
2 交易中冻结 队首进入交易,禁止解冻、禁止手动下架
3 已下架 终态,进入历史商品

商品表关键字段:

  • id:商品 ID
  • status:商品状态,取值 0~3
  • current_intent_id:当前交易中的意向 ID,非交易中为空
  • name、description、image_url、price
  • created_at、off_shelf_at

2. 意向状态字段

值 状态 说明
0 排队中 已提交,等待轮到
1 交易中 当前队首,商品已交易中冻结
2 交易成功 终态
3 已作废 卖家交易失败后选择作废,终态
4 已撤销 买家主动撤销,终态
5 重新排队中 交易失败后选择重新排队,非终态
6 最终失败 商品下架、交易成功关闭队列、被挤掉未轮上等,终态

说明:不再把“交易失败”作为独立长期状态。卖家标记失败时,该意向立即转为“已作废”或“重新排队中”。

意向表关键字段:

  • id:意向 ID
  • product_id:商品 ID
  • code:口令码
  • name、phone
  • status:意向状态,取值 0~6
  • queued_at:排队时间,重新排队时更新
  • fail_count:交易失败次数
  • created_at、updated_at

3. 价格字段

  • 类型:DECIMAL(10,2)
  • 规则:必须大于 0,强制保留两位小数
  • 有效范围:0.01 ~ 99,999,999.99
  • “无上限”解释为不设业务封顶,实际以数据库精度为准。

4. 口令码字段

  • 全局唯一
  • 提交意向成功即生成
  • 仅提交成功页面显示一次
  • 意向终态或商品下架后失效
  • 重新排队时继续有效

十一、风险与异常处理机制

11.1 业务异常处理

  1. 图片上传超限/格式错误:前端实时校验,拦截非法文件并提示。
  2. 交易中商品解冻异常:禁止操作,接口拦截,提示“交易中的商品不支持手动解冻”。
  3. 交易中商品手动下架异常:禁止操作,提示“交易中的商品不支持手动下架,请先标记交易结果”。
  4. 并发提交意向:使用数据库事务和行锁,按 queued_at、意向 ID 排序,保证先到先得,无插队、无乱序。
  5. 失效口令码查询:已终结或商品下架后的口令码,提示“口令码已失效,无对应意向信息”。
  6. 交易中买家撤销异常:拒绝撤销,提示“已进入交易,买家不能自行撤销,请联系卖家处理交易结果”。
  7. 交易失败递补事务:标记失败时,必须携带 productId、intentId、disposition。系统在同一事务内:
    • 校验商品为交易中冻结,且 current_intent_id = intentId;
    • 若 disposition = VOID,当前意向转为已作废;
    • 若 disposition = REQUEUE,当前意向转为重新排队中,更新 queued_at,排到队尾;
    • 查询剩余有效队列;
    • 有下一位:队首转为交易中,商品保持交易中冻结,更新 current_intent_id;
    • 无下一位:商品恢复在售,清空 current_intent_id。
  8. 重新排队且队列为空:商品恢复在售,该意向保持重新排队中,不立即进入交易,等待卖家下次开始交易。
  9. 交易成功处理:当前意向转为交易成功,商品下架;其他未终态意向全部转为最终失败,口令码失效。
  10. 手动下架处理:仅允许在售或手动冻结状态下架;交易中冻结禁止下架。下架后,所有未终态意向转为最终失败,口令码失效。
  11. 开始交易异常:非在售状态拒绝;队列为空拒绝;只能取队首意向,卖家不能指定其他意向。
  12. 接口参数要求:confirm-sold 必须携带 productId、intentId;confirm-failed 必须携带 productId、intentId、disposition。若前文接口初稿未写,以本处为准。

11.2 事务与并发一致性

  1. 商品发布、开始交易、标记成功、标记失败、手动下架均需在事务中完成。
  2. 单活跃商品约束通过数据库唯一索引或事务锁保证。
  3. 队列排序以 queued_at 和意向 ID 为准,重新排队时更新 queued_at。
  4. 交易失败递补过程中,商品不允许接收新意向,不出现可插队的中间在售状态。

十二、需求验收标准

  1. 卖家可正常登录、改密、发布单商品、手动冻结/解冻、手动下架。
  2. 商品发布后名称、描述、图片、价格不可修改,只能下架后重新发布。
  3. 买家可匿名浏览、提交意向、获取唯一口令码,并凭口令码查询、修改姓名电话、撤销排队意向。
  4. 排队严格先到先得;买家提交意向不冻结商品;只有卖家执行“开始交易”后,队首进入交易,商品转为交易中冻结,队列封闭。
  5. 排队阶段买家撤销只影响队列位次,不改变商品状态,不触发递补。
  6. 交易失败时,系统在同一事务内完成“当前意向作废或重新排队 + 自动递补或恢复在售”,不出现可被新买家插入的中间状态。
  7. 卖家选择“重新排队”时,该意向排到队尾,不立即再次进入交易;若队列无其他人,商品恢复在售,该意向仍可凭原口令码查询。
  8. 交易成功时,商品直接下架,当前意向成功,队列中其他未终态意向全部最终失败,相关口令码失效。
  9. 手动下架仅允许在售或手动冻结状态;交易中冻结禁止手动下架。下架后剩余未终态意向全部最终失败,口令码失效。
  10. 交易中商品禁止手动解冻,禁止手动下架,提示明确。
  11. 商品状态、意向状态流转完全匹配第十章数据字典和状态定义。
  12. 历史商品、意向流水持久化保存,重启不丢失,只读不可改。
  13. 所有异常场景均有拦截与提示,无逻辑漏洞、无状态错乱。
  14. 并发提交意向时,排队顺序绝对一致,无插队、无乱序。

十三、 需求变更说明

本文档为项目阶段性定稿需求规格说明书,在本课程迭代周期内,核心业务规则、状态流转、功能范围不做变更。所有开发严格依据本文档执行,无额外新增需求、无隐性需求。