架构设计与数据库表结构 迭代2 - xiaochu-dev/online-shopping-group5 GitHub Wiki

在线购物系统 架构设计与数据库表结构(迭代2)

初稿:胡成溯。2026-10-22按iter2-java合并提交671ae63同步。商品中心T2-08~T2-12已合入,当前设计以Controller、Service、四份schema及商品中心契约为依据。Python基线保留在main,不覆盖基线成果或原始澄清记录。

1 技术与模块

Java17编译目标;Spring Boot3.3.5、MyBatis-Plus3.5.7、Thymeleaf、SQLite JDBC3.46.1.3,服务端渲染单体。新增Jsoup1.20.1过滤商品富文本。数据库、上传文件分别默认位于data/和uploads/。

负责人 模块与任务 当前职责
胡成溯 auth、buyer、admin,T2-01~T2-07 基座、卖家登录、客户账号与客户管理
黄程宇 product,T2-08~T2-12 分类、发布、库存、上下架、图集、富文本
周到 portal,T2-13~T2-18 浏览搜索、下单、订单、队列与交易确认
flowchart TB
    WEB[浏览器] --> MVC[Controller与Thymeleaf模板]
    MVC --> AUTH[auth / buyer / admin]
    MVC --> PRODUCT[product 分类、发布、库存、图片与描述]
    MVC --> PORTAL[portal 浏览、订单与交易]
    PRODUCT --> PDATA[product/domain 自有Entity与Mapper]
    PORTAL --> IDATA[portal/domain 意向Entity与Mapper]
    AUTH --> ADATA[auth / buyer 的Entity与Mapper]
    PDATA --> DB[(SQLite 六张表)]
    IDATA --> DB
    ADATA --> DB
    PRODUCT --> FILES[uploads 图片文件]

common保留公共返回体、配置、异常和工具等,Entity/Mapper位于各模块domain。商品新实现不写intent表;队列适配在portal内调用其Mapper。现有门户查询仍直接使用商品Entity/Mapper,是当前实现边界,不能宣称全部跨模块访问已解耦。

2 模块间调用

  • BuyerContext.current()提供买家身份;卖家上下文适配读取已登录Session。
  • CategoryQueryService实现CategoryPort,返回启用的两级分类树。
  • ProductDetailService实现ProductPort,提供图片、库存及freeze/release/deduct;ProductQueryService提供在售商品查询。
  • 库存归零时StockService调用IntentQueuePort;portal中的ProductQueueAdapter转调IntentMapper结束pending队列,并提供hasTrading。
  • IntentHistoryProvider实现admin侧IntentHistoryPort,供客户购买历史展示。商品临时探针SchemaCapability/PortalProbeMapper及无限库存降级已移除。

3 商品状态与成交

动作 库存变化 状态和队列
发布商品 指定非负整数 大于0为on_sale;0为off_shelf/auto
提交意向 不扣 要求登录、在售且有库存;进入pending
确认队首交易 不扣 意向trading,商品frozen
标记成功 原子扣1 意向success;库存归零则off_shelf/auto并将pending置failed,否则release恢复在售
标记失败 不扣 意向failed或重回pending队尾;商品通过release恢复,手动下架保持下架
手动下架 不扣 on_sale或frozen均可变为off_shelf/manual
调整库存 改为输入值 为0时off_shelf/auto并结束pending;有交易时禁止直接调为0
补货后重新上架 不扣 要求库存>0;无交易恢复on_sale,有交易恢复frozen

release()只处理frozen,不能覆盖已下架状态。delisted仅兼容历史商品,不是当前发布/下架入口写入的主状态。商品级traded_at/trade_result为兼容字段,本次交易结果与时间记录在intent。

stateDiagram-v2
    direction LR
    state "在售 on_sale" as S
    state "交易中 frozen" as F
    state "已下架 off_shelf" as O
    [*] --> S: 发布且库存大于0
    [*] --> O: 发布库存为0,auto
    S --> F: 确认队首交易,库存不变
    F --> S: 交易结束且有库存,release
    F --> O: 成交扣至0,auto
    S --> O: 调整库存为0,auto
    S --> O: 手动下架,manual
    F --> O: 手动下架,manual
    O --> S: 补货后手动上架,无交易
    O --> F: 手动上架时仍有交易

只改库存和上下架,不编辑或删除已发布商品。商品整件冻结,同一时刻一笔交易;未结束交易时不允许把库存直接改为0,这是实现约束,团队联调时确认。

4 意向与身份

浏览公开,提交意向必须登录。新单不生成token_code,客户页面没有撤销入口,旧码撤销接口仅作兼容。买家签名BUYER_SESSION与卖家HttpSession的SHOP_SESSION独立;不要将设计中的SELLER_SESSION写成实际cookie名。

意向按created_at,id先到先得;卖家仅确认队首。失败可置failed或回pending队尾;下一位仍由卖家确认。成功扣1,只有库存归零才结束剩余pending。客户历史只显示success/failed,按finished_at倒序分页;商品级历史字段不替代订单字段。

5 数据结构

erDiagram
    seller ||--o{ product : owns
    category o|--o{ category : parent
    category ||--o{ product : classifies
    product ||--o{ product_image : images
    product ||--o{ intent : queues
    buyer ||..o{ intent : logical_buyer_id

实际六表及字段、外键、CHECK、唯一性、索引以数据库设计为准;初始化是schema/00-base.sql→01-buyer.sql→02-product.sql→03-intent.sql。intent.buyer_id为逻辑关联,不是当前DDL中的外键。

6 页面接口与上传

方法 路径 入参 响应/模型
GET /admin/products status选填 product/list;products、selectedStatus
GET /admin/products/new 无 product/publish;tree
GET /admin/products/publish 无 同发布页
POST /admin/products name、price、categoryId、stock、description、images、imageOrder、primaryIndex 成功回/admin/products;业务失败回/admin/products/new
POST /admin/products/{id}/stock stock 调整库存后回/admin/products
POST /admin/products/{id}/off-shelf 无 手动下架后回/admin/products
POST /admin/products/{id}/relist 无 重新上架后回/admin/products
GET /admin/categories 无 product/categories;categories
POST /admin/categories name、parentId选填、sortNo默认0 新增分类后回/admin/categories
POST /admin/categories/{id}/status enabled布尔值 启停后回/admin/categories
POST /admin/categories/{id}/delete 无 仅删除无子类、无商品引用的分类

后台继承卖家鉴权;商品操作校验所有权。GET成功200,表单redirect当前默认302,商品模块使用Flash提示。完整门户/账号路由见总API契约与账号契约。

每商品发布时最多9张图片,5MiB/张,JPG/JPEG/PNG,检查后缀、文件头与解码;封面与顺序发布后不可改。富文本先白名单过滤再渲染,允许图片和受信播放器iframe,不能继续写原样保存或只靠Thymeleaf默认转义。

7 初始化、迁移与验证

新库由四份SQL初始化。旧Java商品库先一致性备份后事务升级;商品编号和关联保留,失败回滚。订单迁移器对旧匿名意向的重建需另行核对,不能把商品迁移当作整库无损升级。具体见数据库设计。

已记录2026-10-21 23:19全量83项通过(新增16项),环境Windows/JDK25/Maven3.9.11、编译目标Java17。本机Byte Buddy需实验兼容开关;团队Java17运行、外站视频真实播放、录屏与教师验收仍待对应证据。本次文档维护没有更改业务代码、重跑测试或生成交付包。

8 版本说明

本次同步替换早期正文中的四表、可编辑商品、库存未实现、冻结留待迭代3、匿名新单与成交即清队列等过期描述。原署名和历史版本保留在Git历史及week06同步前副本;这次维护不改写PM原始澄清问答,任务表与其文本差异继续由团队确认。