巴青农资商城

订单管理技术方案.md 16KB

订单管理 — 技术方案

依据: 《订单管理功能需求.md》v1.0.1
关联: 《会员管理技术方案.md》v1.0、《商品管理技术方案.md》v1.2、《店铺管理技术方案.md》v1.2.1、《关联需求分析.md》v1.2
范围: 本文以 订单库表、平台履约接口、定时关单、跨模块 Facade 为主;C 端下单/支付/确认收货给出 共用表与接口占位;支付渠道、退款、拆单 非本期
原则: 整单发货;支付成功扣库存;O10 未完成订单;O11 完成后刷新会员消费。


1. 技术架构

选型
基础框架 RuoYi v3.9.2springboot2 分支)
数据库 MySQL 5.7.39
ORM / 权限 / 响应 MyBatis;@PreAuthorizeAjaxResult / TableDataInfo
订单号 Redis 或 DB 序列:O + yyyyMMdd + 6 位序号(应用保证唯一)
定时任务 RuoYi QuartzOrderPayTimeoutJob(O8)
配置 sys_configorder.pay.timeout.minutes,默认 1440
日志 发货/关闭/删除 @Log

1.1 模块落位

baqing-shop
├── com.ruoyi.web.controller.agri.OrderController       # 平台
└── com.ruoyi.web.controller.api.OrderAppController    # C 端占位
ruoyi-agri
├── domain.BizOrder / BizOrderItem / BizOrderLogisticsTrace
├── service.IOrderService
├── job.OrderPayTimeoutJob
└── facade.OrderFacadeImpl → IOrderFacade

1.2 业务链

C 端下单 → biz_order(待支付) + biz_order_item(快照)
    ↓ 支付成功
待发货 + IGoodsFacade.deductStock(按行)
    ↓ 平台发货
已发货 + biz_order_logistics_trace
    ↓ C 端确认收货
已完成 + IMemberFacade.refreshConsumption(memberId)
模块 关系
会员 member_idIMemberFacade.isMemberEnabled;完成后 refreshConsumption
店铺 shop_idIShopFacade.isShopOpenForOrder(C 端下单)
商品 IGoodsFacade.canPurchase / deductStock / restoreStock(关闭回滚)
商户/店铺删除 IOrderFacade.hasUnfinishedOrdersByShop/Merchant(O10)

1.3 跨模块 Facade

接口 提供方 调用方 方法
IOrderFacade 本模块 店铺、商户 hasUnfinishedOrdersByShop(Long shopId) — status∈{0,1,2}
hasUnfinishedOrdersByMerchant(Long merchantId) — 其下任一店存在未完成
pageOrdersByMember(Long memberId, OrderMemberQuery q)TableDataInfo
getOrderDetail(Long orderId, Long memberId)memberId=null 平台;非 null 校验归属
IMemberFacade 会员 本模块 isMemberEnabledgetMember(下单)
refreshConsumption(Long memberId)已完成 后重算 O11
IGoodsFacade 商品 本模块 canPurchase(goodsId, qty)deductStockrestoreStock(已支付关闭)
IShopFacade 店铺 本模块 isShopOpenForOrder(shopId)

未完成订单 SQL(O10):

SELECT 1 FROM biz_order
WHERE shop_id = #{shopId} AND order_status IN ('0','1','2') AND del_flag = '0'
LIMIT 1

1.4 状态联动

事件 订单 库存 会员消费
支付成功 0→1 扣减
待发货关闭 →4 回滚
超时未付 0→4
确认收货 2→3 refreshConsumption
已关闭删除 4→5

2. 数据库设计

2.1 本模块表

表名 说明
biz_order 订单主表
biz_order_item 商品明细(快照)
biz_order_logistics_trace 物流节点时间轴

2.2 订单状态与字典

order_status(char(1))

含义 页签
0 待支付 待支付
1 待发货 待发货
2 已发货 已发货
3 已完成 已完成
4 已关闭 已关闭
5 已删除 已删除

close_type(关闭时必填,order_status=4)

含义
1 未支付超时(O8)
2 买家取消
3 运营关闭
4 支付失败/退款(另册)

delivery_type(发货时写入)

含义
1 物流配送
2 商家配送

biz_order_logistics_trace.trace_type

含义
1 已发货
2 运输更新
3 已送达
4 确认收货

检索 shipStatus(Query):order_status 映射 — 0/1/2 直接等值;「运输中」= order_status=2

2.3 biz_order

字段 类型 说明
order_id bigint PK
order_no varchar(32) 唯一
member_id bigint 买家
shop_id bigint 店铺
merchant_id bigint 冗余,便于商户维度统计
order_status char(1) §2.2
close_type char(1) 关闭类型
close_reason varchar(500) 关闭说明
pay_type char(1) 支付方式字典
pay_status char(1) 0未付 1已付
trade_no varchar(64) 交易单号
goods_amount decimal(12,2) 商品合计
freight_amount decimal(12,2) 运费,默认 0
pay_amount decimal(12,2) 实付 = goods + freight(O11 统计字段)
consignee_name varchar(64) 收货快照
consignee_mobile varchar(20)
consignee_address varchar(512) 完整地址文本
delivery_type char(1) 发货后填写
logistics_company varchar(64) 物流
tracking_no varchar(64) 快递单号
vehicle_no varchar(32) 商家配送
courier_name varchar(64) 配送员
courier_mobile varchar(20)
ship_remark varchar(500) 发货备注
member_nick_name varchar(64) 下单时会员昵称快照
shop_name varchar(128) 店铺名快照
create_time datetime 下单时间
pay_time datetime 支付时间
ship_time datetime 发货时间
pay_expire_time datetime 支付截止时间
finish_time datetime 确认收货时间
del_flag char(1) 0 存在;已删除 用 status=5,del_flag 仍 0(审计)
update_by/time, remark

列表默认:order_status != '5';「已删除」页签 order_status='5'

2.4 biz_order_item

字段 类型 说明
item_id bigint PK
order_id bigint
goods_id bigint 原商品 ID
goods_name varchar(128) 快照
goods_spec varchar(64) 单规格文案
goods_image varchar(512) 主图 URL
unit_price decimal(12,2)
quantity int
line_amount decimal(12,2) unit_price * quantity
sort_no int

2.5 biz_order_logistics_trace

字段 类型 说明
trace_id bigint PK
order_id bigint
trace_type char(1) §2.2
trace_time datetime
content varchar(1000) 描述/摘要
create_by varchar(64) 操作人

2.6 索引

索引
biz_order uk_order_no;idx_member;idx_shop_status;idx_create_time;idx_pay_expire(status, pay_expire_time)
biz_order_item idx_order_id
biz_order_logistics_trace idx_order_id_time

2.7 DDL

CREATE TABLE `biz_order` (
  `order_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `order_no` varchar(32) NOT NULL COMMENT '订单编号',
  `member_id` bigint(20) NOT NULL,
  `shop_id` bigint(20) NOT NULL,
  `merchant_id` bigint(20) NOT NULL,
  `order_status` char(1) NOT NULL DEFAULT '0' COMMENT '0待支付1待发货2已发货3已完成4已关闭5已删除',
  `close_type` char(1) DEFAULT NULL,
  `close_reason` varchar(500) DEFAULT NULL,
  `pay_type` char(1) DEFAULT NULL,
  `pay_status` char(1) NOT NULL DEFAULT '0' COMMENT '0未付1已付',
  `trade_no` varchar(64) DEFAULT NULL,
  `goods_amount` decimal(12,2) NOT NULL DEFAULT '0.00',
  `freight_amount` decimal(12,2) NOT NULL DEFAULT '0.00',
  `pay_amount` decimal(12,2) NOT NULL DEFAULT '0.00',
  `consignee_name` varchar(64) NOT NULL,
  `consignee_mobile` varchar(20) NOT NULL,
  `consignee_address` varchar(512) NOT NULL,
  `delivery_type` char(1) DEFAULT NULL,
  `logistics_company` varchar(64) DEFAULT NULL,
  `tracking_no` varchar(64) DEFAULT NULL,
  `vehicle_no` varchar(32) DEFAULT NULL,
  `courier_name` varchar(64) DEFAULT NULL,
  `courier_mobile` varchar(20) DEFAULT NULL,
  `ship_remark` varchar(500) DEFAULT NULL,
  `member_nick_name` varchar(64) DEFAULT NULL,
  `shop_name` varchar(128) DEFAULT NULL,
  `create_time` datetime NOT NULL,
  `pay_time` datetime DEFAULT NULL,
  `ship_time` datetime DEFAULT NULL,
  `pay_expire_time` datetime NOT NULL,
  `finish_time` datetime DEFAULT NULL,
  `del_flag` char(1) NOT NULL DEFAULT '0',
  `create_by` varchar(64) DEFAULT '',
  `update_by` varchar(64) DEFAULT '',
  `update_time` datetime DEFAULT NULL,
  `remark` varchar(500) DEFAULT NULL,
  PRIMARY KEY (`order_id`),
  UNIQUE KEY `uk_order_no` (`order_no`),
  KEY `idx_member` (`member_id`,`create_time`),
  KEY `idx_shop_status` (`shop_id`,`order_status`),
  KEY `idx_create_time` (`create_time`),
  KEY `idx_pay_expire` (`order_status`,`pay_expire_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单';

CREATE TABLE `biz_order_item` (
  `item_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `order_id` bigint(20) NOT NULL,
  `goods_id` bigint(20) NOT NULL,
  `goods_name` varchar(128) NOT NULL,
  `goods_spec` varchar(64) DEFAULT '默认',
  `goods_image` varchar(512) DEFAULT NULL,
  `unit_price` decimal(12,2) NOT NULL,
  `quantity` int(11) NOT NULL,
  `line_amount` decimal(12,2) NOT NULL,
  `sort_no` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`item_id`),
  KEY `idx_order_id` (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单明细';

CREATE TABLE `biz_order_logistics_trace` (
  `trace_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `order_id` bigint(20) NOT NULL,
  `trace_type` char(1) NOT NULL,
  `trace_time` datetime NOT NULL,
  `content` varchar(1000) NOT NULL DEFAULT '',
  `create_by` varchar(64) DEFAULT '',
  `create_time` datetime DEFAULT NULL,
  PRIMARY KEY (`trace_id`),
  KEY `idx_order_id_time` (`order_id`,`trace_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流节点';

2.8 字典

dict_type 用途
biz_order_status order_status
biz_order_close_type close_type
biz_delivery_type delivery_type
biz_order_pay_type pay_type
biz_order_pay_status pay_status
biz_logistics_trace_type trace_type

3. 平台端接口设计

基路径: /agri/order
权限: agri:order:list|query|ship|edit|remove

3.1 接口一览

方法 路径 权限 说明
GET /list list 分页列表(含页签)
GET /{orderId} query 详情(明细+物流轴)
POST /{orderId}/ship ship 整单发货 → 已发货
POST /{orderId}/logistics ship 更新物流(已发货)
POST /{orderId}/delivered ship 登记送达
PUT /{orderId}/close edit 关闭(0/1/2)
DELETE /{orderId} remove 已关闭 → 已删除

3.2 列表 GET /list

Query 说明
pageNum, pageSize
orderStatus 页签:空=全部(排除5);0~5
orderNo 订单编号
goodsName 关联 item 模糊
shipStatus 同 orderStatus 履约态(0/1/2)
consigneeName, consigneeMobile, consigneeAddress
deliveryType 1/2(已发货后有值)
payType, payStatus
tradeNo
memberKeyword 会员昵称/手机号
shopName 店铺名模糊
logisticsCompany
beginTime, endTime create_time

排序: create_time DESC
默认过滤: 未传 orderStatusorder_status != '5'

rows(摘要):

字段 说明
orderId, orderNo, createTime
orderStatus, orderStatusLabel
payAmount, freightAmount
memberNickName, consigneeName, consigneeMobile 手机脱敏
consigneeAddress, deliveryTypeLabel
shopName
items 数组:goodsImage, goodsName, goodsSpec, quantity, unitPrice(首行+itemCount)

3.3 详情 GET /{orderId}

含 §需求 6.2 各分区:baseitemsconsigneelogistics(当前单号/配送员)、traceList(时间倒序)、closeInfo

3.4 发货 POST /{orderId}/ship

前置: order_status=1

{
  "shipTime": "2026-05-28 14:00:00",
  "deliveryType": "1",
  "logisticsCompany": "顺丰",
  "trackingNo": "SF123456",
  "vehicleNo": null,
  "courierName": null,
  "courierMobile": null,
  "shipRemark": ""
}
deliveryType 必填
1 logisticsCompany + trackingNo
2 vehicleNo + courierName + courierMobile

事务: order_status=2;写 ship 字段;插入 trace_type=1; 再扣库存。

3.5 更新物流 POST /{orderId}/logistics

{ "traceTime": "2026-05-28 18:00:00", "content": "到达拉萨中转站" }

前置: order_status=2;追加 trace_type=2。

3.6 登记送达 POST /{orderId}/delivered

{ "traceTime": "2026-05-29 10:00:00", "content": "已送达小区门口" }

追加 trace_type=3; 改 order_status(仍为 2,O7)。

3.7 关闭 PUT /{orderId}/close

{ "closeType": "3", "closeReason": "运营协商关闭" }
前置 status 副作用
0 无库存操作
1 IGoodsFacade.restoreStock 按 item 行
2 同上(若已发货关闭,本期仅记原因,退款另册)

order_status=4,写 close_type/reason。

3.8 删除 DELETE /{orderId}

前置: order_status=4order_status=5

3.9 业务错误 msg(示例)

场景 msg
状态不允许发货 当前状态不可发货
非已关闭删单 仅已关闭订单可删除
库存回滚失败 库存回滚失败,请稍后重试

4. C 端接口(占位)

基路径: /api/order(会员 Token)

方法 路径 说明
POST /create 校验 canPurchase + isMemberEnabled + isShopOpen;写 order/item;status=0;pay_expire_time=now+timeout
POST /{orderId}/pay 模拟/渠道回调:status→1,pay_status=1,deductStock,pay_time
POST /{orderId}/confirmReceive status→2 时:→3,trace_type=4,refreshConsumption
GET /list 当前会员订单
GET /{orderId} 详情(校验 member_id)
规则 说明
待支付关闭后 支付接口拒绝,msg 订单已关闭
拆单 不支持

5. 定时任务(O8)

OrderPayTimeoutJob(如每 5 分钟)
  SELECT order_id FROM biz_order
   WHERE order_status='0' AND pay_expire_time < NOW() AND del_flag='0'
  FOR EACH → close_type=1, order_status=4(批量 UPDATE)

pay_expire_time创建订单 时:create_time + ConfigService.getInt("order.pay.timeout.minutes", 1440) 分钟。


6. 会员模块协作(O11)

confirmReceive / 平台不代确认
  @Transactional
  → UPDATE biz_order SET order_status='3', finish_time=NOW()
  → INSERT trace_type=4
  → IMemberFacade.refreshConsumption(memberId)

refreshConsumption 实现见《会员管理技术方案》§5.2(按 member_id 重算已完成 SUM)。

pageOrdersByMember / getOrderDetail 与 §3.2、§3.3 共用 Service;memberId 强制 WHERE member_id=?


7. 菜单与权限

权限 说明
agri:order:list 列表
agri:order:query 详情
agri:order:ship 发货/物流/送达
agri:order:edit 关闭
agri:order:remove 删除

8. 非本期

说明
分批发货/拆单 需求 §17
支付渠道、退款 另册;pay 可先 Mock
商家端订单后台 平台代履约
Excel 批量发货/打印 需求 §17

9. 需求规则映射

规则 实现
O1~O3 biz_order + 字典
O4 pay 成功 deductStock
O5 ship 整单一次 → status=2
O6~O7 logistics trace;完成仅 C 端 confirm
O8 Job + pay_expire_time
O9 DELETE status 4→5
O10 Facade IN (0,1,2)
O11 refreshConsumption
O12 写接口仅 OrderController
O15 delivery_type 分支校验

文档版本:v1.0 · MySQL 5.7.39 · RuoYi v3.9.2-springboot2 · 关联《订单管理功能需求.md》v1.0.1、《订单管理测试用例.md》v1.0、《会员管理技术方案.md》v1.0、《关联需求分析.md》v1.2