Arch Day 69: 订单系统设计
Arch Day 69: 订单系统设计
日期: 2026-06-07 (Day 69) 阶段: 第三阶段 - 零售域深度 标签: #电商 #订单系统 #状态机 #DDD #拆单
核心概念
一句话定义
订单系统是电商的"中枢神经"——它连接用户、商品、库存、支付、物流、售后等所有核心域,承载着从"用户下单意图"到"交易完成"的全部业务逻辑。
为什么关注
2025年全球电商交易额达6.42万亿美元,预计2026年将达6.88万亿美元(Shopify Global Report)。每一笔交易的背后,都是一次完整的订单生命周期管理。订单系统的设计质量,直接决定了:
- 用户体验:下单流程是否顺畅、退款是否及时
- 运营效率:拆单逻辑是否合理、履约是否高效
- 财务准确性:金额计算、优惠分摊、对账是否一致
- 系统可靠性:高并发下单、异常恢复、幂等保障
误区与反模式
| 误区 | 现实 |
|---|---|
| "订单就是一张表" | 订单是一个聚合根,包含订单项、支付、物流、优惠等多个实体 |
| "状态就是一个字段" | 复杂业务需要多维状态机(主订单+子订单+物流+支付+售后) |
| "先设计数据库再写业务" | 应先建立领域模型,再映射到存储 |
| "逆向流程是附加功能" | 退款/退货复杂度往往超过正向流程 |
| "订单号用自增ID就行" | 自增ID暴露业务量、不支持分库分表、无法分布式生成 |
知识点详解
一、订单状态机设计
状态机是订单系统的"骨骼",可以拆为三个要素:现态(State)、动作(Action)、次态(Next State)。
1.1 正向流程状态机
┌──────────┐ 用户提交 ┌──────────┐ 支付成功 ┌──────────┐
│ 待支付 │ ─────────→ │ 已支付 │ ─────────→ │ 待发货 │
│ PENDING │ │ PAID │ │ TO_SHIP │
└──────────┘ └──────────┘ └──────────┘
│
│ 商家发货
▼
┌──────────┐ 确认收货 ┌──────────┐ 物流签收 ┌──────────┐
│ 已完成 │ ←───────── │ 已签收 │ ←───────── │ 已发货 │
│ COMPLETED│ │ RECEIVED │ │ SHIPPED │
└──────────┘ └──────────┘ └──────────┘
1.2 逆向流程状态机
任意可退状态
│
│ 用户申请退款/退货
▼
┌──────────┐ 商家审核 ┌──────────┐ 退货寄回 ┌──────────┐
│ 退款申请 │ ─────────→ │ 退款审核中 │ ─────────→ │ 退货中 │
│ REFUND_ │ 通过 │ REFUND_ │ │ RETURNING│
│ APPLIED │ │ APPROVED │ │ │
└──────────┘ └──────────┘ └──────────┘
│ │
│ 仅退款 │ 商家确认收货
▼ ▼
┌──────────┐ ┌──────────┐
│ 退款中 │ │ 退款中 │
│ REFUNDING│ │ REFUNDING│
└──────────┘ └──────────┘
│ │
│ 退款到账 │ 退款到账
▼ ▼
┌──────────┐ ┌──────────┐
│ 退款完成 │ │ 退款完成 │
│ REFUNDED │ │ REFUNDED │
└──────────┘ └──────────┘
1.3 异常状态处理
| 异常场景 | 处理策略 | 状态流转 |
|---|---|---|
| 支付超时 | 定时任务扫描,自动关单 | PENDING → CANCELLED |
| 支付回调延迟 | 主动查询支付结果,补偿机制 | PENDING → PAID(补偿) |
| 部分发货 | 子订单独立状态机 | 父订单PARTIAL_SHIPPED |
| 物流异常 | 物流状态独立,不影响主流程 | 标记LOGISTICS_EXCEPTION |
| 退款失败 | 重试+人工介入 | REFUNDING → REFUND_FAILED |
| 并发修改冲突 | 乐观锁+版本号 | 拒绝非法跳转 |
1.4 状态机代码实现(Spring StateMachine 风格)
@Configuration
public class OrderStateMachineConfig {
// 定义状态枚举
public enum OrderState {
PENDING, PAID, TO_SHIP, SHIPPED, RECEIVED,
COMPLETED, CANCELLED, REFUND_APPLIED,
REFUND_APPROVED, RETURNING, REFUNDING, REFUNDED
}
// 定义事件枚举
public enum OrderEvent {
PAY, SHIP, SIGN, CONFIRM, CANCEL,
APPLY_REFUND, APPROVE_REFUND, REJECT_REFUND,
RETURN_GOODS, CONFIRM_RETURN, REFUND_SUCCESS, REFUND_FAIL
}
// 状态转换规则
@Bean
public StateMachine<OrderState, OrderEvent> orderStateMachine() {
StateMachineBuilder.Builder<OrderState, OrderEvent> builder =
StateMachineBuilder.builder();
// 正向流程
builder.configureTransitions()
.withExternal().source(PENDING).target(PAID).event(PAY)
.withExternal().source(PAID).target(TO_SHIP).event(PAY) // 自动
.withExternal().source(TO_SHIP).target(SHIPPED).event(SHIP)
.withExternal().source(SHIPPED).target(RECEIVED).event(SIGN)
.withExternal().source(RECEIVED).target(COMPLETED).event(CONFIRM)
// 超时自动关单
.withExternal().source(PENDING).target(CANCELLED).event(CANCEL)
// 逆向流程
.withExternal().source(PAID).target(REFUND_APPLIED).event(APPLY_REFUND)
.withExternal().source(TO_SHIP).target(REFUND_APPLIED).event(APPLY_REFUND)
.withExternal().source(SHIPPED).target(REFUND_APPLIED).event(APPLY_REFUND)
.withExternal().source(RECEIVED).target(REFUND_APPLIED).event(APPLY_REFUND);
return builder.build();
}
}
二、拆单逻辑设计
拆单是将用户的一个逻辑订单拆分为多个可独立履约的子订单。
2.1 拆单触发维度
| 拆单维度 | 场景 | 示例 |
|---|---|---|
| 按商家拆 | 平台型电商,不同商家独立发货 | 淘宝/京东第三方商家 |
| 按仓库拆 | 同商家不同仓库分别发货 | 华南仓+华北仓 |
| 按配送方式拆 | 普通快递/冷链/大件物流分开 | 生鲜冷链+日用快递 |
| 按促销活动拆 | 赠品单独发货、预售与现货分开 | 预售商品+现货商品 |
| 按品类拆 | 特殊品类(危险品/液体)单独包装 | 酒类+普通商品 |
| 按物流限制拆 | 超出物流重量/体积限制 | 单包裹超30kg |
2.2 拆单引擎架构
用户订单(MainOrder)
│
▼
┌─────────────┐
│ 拆单规则引擎 │
│ SplitEngine │
└──────┬──────┘
│
┌────┼────┬────┬────┐
▼ ▼ ▼ ▼ ▼
商家 仓库 配送 促销 品类
规则 规则 规则 规则 规则
│ │ │ │ │
└────┼────┴────┴────┘
│
▼
┌─────────────┐
│ 合并优化器 │ ← 避免过度拆分(同仓同配送可合并)
│ MergeOptim │
└──────┬──────┘
│
▼
子订单列表(SubOrders)
2.3 拆单规则引擎伪代码
class OrderSplitEngine:
def __init__(self):
self.rules = [
MerchantSplitRule(), # 按商家拆
WarehouseSplitRule(), # 按仓库拆
DeliverySplitRule(), # 按配送方式拆
PromotionSplitRule(), # 按促销活动拆
CategorySplitRule(), # 按品类拆
]
self.merge_optimizer = MergeOptimizer()
def split(self, main_order: MainOrder) -> List[SubOrder]:
# 初始:整个订单作为一组
groups = [main_order.items]
# 链式拆分:每条规则都可以进一步拆分已有的组
for rule in self.rules:
new_groups = []
for group in groups:
split_result = rule.apply(group)
new_groups.extend(split_result)
groups = new_groups
# 合并优化:避免过度拆分
groups = self.merge_optimizer.optimize(groups)
# 生成子订单
sub_orders = []
for i, group in enumerate(groups):
sub_order = SubOrder(
sub_order_no=f"{main_order.order_no}-{i+1:02d}",
items=group,
warehouse=group[0].warehouse,
delivery_type=group[0].delivery_type,
)
sub_orders.append(sub_order)
return sub_orders
三、合单逻辑
合单与拆单相反,是将多个逻辑订单合并处理以提高效率。
| 合单场景 | 条件 | 收益 |
|---|---|---|
| 合并支付 | 同用户同时下多笔订单 | 减少支付次数,提升转化 |
| 合并发货 | 同仓库同收货地址 | 节省物流成本 |
| 合并包裹 | 同物流商同时间窗发货 | 降低包装和人工成本 |
四、订单号设计
4.1 设计要求
| 要求 | 说明 |
|---|---|
| 全局唯一 | 分布式环境下不重复 |
| 有序递增 | 便于数据库索引,避免页分裂 |
| 可读性 | 便于客服查询、用户识别 |
| 含业务信息 | 可从订单号推断渠道、时间等 |
| 不可猜测 | 不能通过订单号推算业务量 |
| 高性能 | 每秒可生成百万级ID |
4.2 主流方案对比
| 方案 | 结构 | 优点 | 缺点 |
|---|---|---|---|
| UUID | 128位随机 | 简单,无中心 | 无序,索引差,可读性差 |
| 数据库自增 | AUTO_INCREMENT | 有序,简单 | 单点瓶颈,暴露信息 |
| Snowflake | 时间+机器+序列 | 有序,分布式,高性能 | 时钟回拨问题 |
| Leaf-Segment | 数据库号段 | 有序,高性能 | 依赖DB,号段浪费 |
| Leaf-Snowflake | 改进Snowflake | 解决时钟问题 | 引入ZooKeeper |
| 业务编码 | 渠道+时间+序列+校验 | 可读,含业务信息 | 设计复杂 |
4.3 推荐方案:业务编码 + Snowflake混合
订单号格式(20位):
CC YYMMDD HH NNNNNNNNNN KK
│ │ │ │ │
│ │ │ │ └── 校验位(2位)
│ │ │ └── Snowflake序列(10位)
│ │ └── 小时(2位)
│ └── 日期(6位)
└── 渠道码(2位):10=APP, 20=PC, 30=小程序, 40=H5
示例:10 260607 14 0038291047 35
含义:APP渠道 | 2026-06-07 | 14时 | 序列号 | 校验位
五、订单领域模型(DDD)
5.1 核心聚合
┌─────────────────────────────────────────────────────┐
│ 订单聚合(Order Aggregate) │
│ │
│ Order (聚合根) │
│ ├── orderId: OrderId (值对象) │
│ ├── orderNo: String │
│ ├── buyerId: UserId │
│ ├── status: OrderStatus (值对象) │
│ ├── orderItems: List<OrderItem> (实体) │
│ │ ├── skuId, skuName, quantity, unitPrice │
│ │ ├── promotionDiscount │
│ │ └── actualAmount │
│ ├── shippingAddress: Address (值对象) │
│ ├── payment: PaymentInfo (值对象) │
│ │ ├── paymentMethod, paymentAmount │
│ │ └── paymentStatus, paymentTime │
│ ├── shipment: ShipmentInfo (值对象) │
│ │ ├── logisticsCompany, trackingNo │
│ │ └── shipTime, receiveTime │
│ ├── promotion: PromotionInfo (值对象) │
│ │ ├── couponId, discountAmount │
│ │ └── promotionType │
│ └── timeline: List<OrderEvent> (值对象) │
│ ├── eventType, eventTime, operator │
│ └── remark │
└─────────────────────────────────────────────────────┘
5.2 领域事件
// 订单创建事件
public class OrderCreatedEvent extends DomainEvent {
private String orderId;
private String buyerId;
private BigDecimal totalAmount;
private List<OrderItemDTO> items;
}
// 订单已支付事件
public class OrderPaidEvent extends DomainEvent {
private String orderId;
private String paymentId;
private BigDecimal paidAmount;
private String paymentMethod;
}
// 订单已发货事件
public class OrderShippedEvent extends DomainEvent {
private String orderId;
private String logisticsCompany;
private String trackingNo;
}
// 退款申请事件
public class RefundAppliedEvent extends DomainEvent {
private String orderId;
private String refundId;
private BigDecimal refundAmount;
private String reason;
}
5.3 上下文映射
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 商品域 │ │ 订单域 │ │ 库存域 │
│ Product │────→│ Order │←────│ Inventory│
│ Context │ │ Context │ │ Context │
└──────────┘ └────┬─────┘ └──────────┘
│
┌───────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ 支付域 │ │ 物流域 │ │ 售后域 │
│ Payment │ │ Logistics│ │ AfterSale│
│ Context │ │ Context │ │ Context │
└──────────┘ └──────────┘ └──────────┘
六、逆向流程深度解析
逆向流程的复杂度通常是正向流程的2-3倍,因为需要处理:
6.1 退款类型矩阵
| 退款类型 | 触发时机 | 库存处理 | 物流处理 | 资金处理 |
|---|---|---|---|---|
| 仅退款(未发货) | 已支付/待发货 | 释放库存 | 无 | 原路退回 |
| 仅退款(已发货) | 已发货/已签收 | 不释放 | 无(商家承担) | 原路退回 |
| 退货退款 | 已签收 | 收货后释放 | 逆向物流 | 验货后退回 |
| 换货 | 已签收 | 收旧发新 | 双向物流 | 差价处理 |
| 部分退款 | 多商品订单 | 部分释放 | 可能部分退货 | 分摊计算 |
6.2 优惠分摊退款
当订单使用了优惠券时,部分退款需要重新计算优惠分摊:
def calculate_partial_refund(order, refund_items):
"""
优惠分摊退款计算
原则:按商品金额比例分摊优惠
"""
# 原始总金额(优惠前)
original_total = sum(item.price * item.qty for item in order.items)
# 退款商品原始金额
refund_original = sum(item.price * item.qty for item in refund_items)
# 优惠分摊比例
discount_ratio = refund_original / original_total
# 分摊的优惠金额
shared_discount = order.total_discount * discount_ratio
# 实际退款金额 = 退款商品原价 - 分摊的优惠
refund_amount = refund_original - shared_discount
# 边界处理:最后一件退款时,退剩余实付金额(避免分摊精度丢失)
remaining_items = [i for i in order.items if i not in refund_items]
if not remaining_items:
refund_amount = order.actual_paid - order.already_refunded
return round(refund_amount, 2)
对比分析
主流电商平台订单系统对比
| 维度 | 淘宝/天猫 | 京东 | 拼多多 | 美团 |
|---|---|---|---|---|
| 订单模型 | 主子订单模型 | 主子订单+包裹 | 扁平订单 | 主子订单 |
| 拆单粒度 | 商家+仓库+配送 | 仓库+配送+温区 | 简化拆单 | 商家+骑手 |
| 状态机复杂度 | 极高(20+状态) | 高(15+状态) | 中(10+状态) | 高(含配送状态) |
| 逆向流程 | 极复杂(含争议仲裁) | 复杂(含京东自营) | 相对简单 | 中等(即时退款) |
| 订单号位数 | 18-20位 | 12位数字 | 纯数字 | 含业务前缀 |
| 分库分表 | 按买家ID | 按订单ID | 按买家ID | 按城市+时间 |
| 日订单量级 | 亿级 | 亿级 | 亿级 | 千万级 |
架构设计实操
设计目标
设计一个"订单中心"系统,满足:
- 日订单量1000万+
- 支持多渠道(APP/PC/H5/小程序)
- 支持多商家入驻
- 完整正向+逆向流程
- 高可用(99.99%)
整体架构方案
┌──────────────────────────────────────────────────────┐
│ 接入层(Gateway) │
│ APP │ PC │ H5 │ 小程序 │ 开放平台 │
└──────────────────────┬───────────────────────────────┘
│
┌──────────────────────▼───────────────────────────────┐
│ 订单聚合服务(BFF) │
│ 下单编排 │ 查询聚合 │ 状态机调度 │ 逆向编排 │
└──────────────────────┬───────────────────────────────┘
│
┌──────────────────────▼───────────────────────────────┐
│ 核心领域服务层 │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │订单服务 │ │拆单服务 │ │状态机 │ │逆向服务 │ │
│ │Order │ │Split │ │Service │ │Reverse │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ │
│ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │超时服务 │ │快照服务 │ │查询服务 │ │归档服务 │ │
│ │Timeout │ │Snapshot│ │Query │ │Archive │ │
│ └────────┘ └────────┘ └────────┘ └────────┘ │
└──────────────────────┬───────────────────────────────┘
│
┌──────────────────────▼───────────────────────────────┐
│ 基础设施层 │
│ MySQL(分库分表) │ Redis │ MQ │ ES │ Hbase(归档) │
└──────────────────────────────────────────────────────┘
ADR: 订单分库分表策略
背景: 日订单量1000万+,单表超5000万行查询性能下降
决策: 采用按买家ID分库分表 + 异构索引(按订单号、商家ID)
理由:
- 80%查询是买家查自己的订单(C端)
- 按买家ID分片保证同用户订单在同一分片
- 商家维度查询通过异构索引(ES/独立表)支持
- 订单号查询通过订单号中嵌入分片键支持
权衡:
- 优势:C端查询高效、同用户事务简单
- 劣势:商家查询需跨库/依赖ES、数据迁移复杂
- 替代方案:按订单ID分片(查询简单但用户维度需聚合)
AI增强实践
1. AI智能客服与订单异常预判
class AIOrderAssistant:
"""AI驱动的订单智能助手"""
def predict_order_risk(self, order):
"""
预测订单风险(欺诈/退款概率)
输入:订单特征(金额、商品、地址、历史行为)
输出:风险评分 + 建议操作
"""
features = self.extract_features(order)
risk_score = self.risk_model.predict(features)
if risk_score > 0.8:
return {"action": "HOLD", "reason": "高风险订单,建议人工审核"}
elif risk_score > 0.5:
return {"action": "VERIFY", "reason": "中风险,建议二次验证"}
return {"action": "PASS", "reason": "正常订单"}
def auto_resolve_dispute(self, dispute):
"""
AI自动仲裁退款争议
基于历史案例 + 规则引擎 + LLM判断
"""
# RAG: 检索相似历史案例
similar_cases = self.rag_engine.search(dispute.description)
# LLM: 综合判断
prompt = f"""
争议描述: {dispute.description}
相似案例: {similar_cases}
平台规则: {self.platform_rules}
请给出仲裁建议。
"""
return self.llm.generate(prompt)
2. AI预测性订单运营
| AI能力 | 应用场景 | 技术方案 |
|---|---|---|
| 取消预测 | 预判用户可能取消的订单 | XGBoost + 用户行为序列 |
| 退货预测 | 发货前预判退货概率 | 多模态模型(商品图+评价+历史) |
| 物流异常预测 | 预测延迟/丢包 | 时序模型 + 天气/物流数据 |
| 智能催付 | 未支付订单个性化催付 | LLM生成催付文案 + A/B |
| 库存预分配 | 大促前智能预分仓 | 需求预测 + 仓储优化 |
与Web3/DeFi的关联
订单系统 × 区块链
| 场景 | Web2方案 | Web3增强 |
|---|---|---|
| 订单存证 | 数据库记录 | 关键节点上链(防篡改) |
| 跨境支付 | 银行清算(T+3) | 稳定币即时结算 |
| 供应链溯源 | 中心化数据库 | 链上全程追溯 |
| 争议仲裁 | 平台客服 | 智能合约自动仲裁(Escrow) |
| 跨平台订单 | 无法互通 | DID + 链上信用 |
智能合约 Escrow 模式
// 简化的订单托管合约
contract OrderEscrow {
enum OrderState { Created, Paid, Shipped, Completed, Disputed, Refunded }
struct Order {
address buyer;
address seller;
uint256 amount;
OrderState state;
uint256 deadline;
}
mapping(uint256 => Order) public orders;
function pay(uint256 orderId) external payable {
// 买家付款,资金锁定在合约中
orders[orderId] = Order(msg.sender, seller, msg.value, OrderState.Paid, block.timestamp + 7 days);
}
function confirmReceived(uint256 orderId) external {
// 买家确认收货,释放资金给卖家
require(msg.sender == orders[orderId].buyer);
orders[orderId].state = OrderState.Completed;
payable(orders[orderId].seller).transfer(orders[orderId].amount);
}
function dispute(uint256 orderId) external {
// 争议仲裁,引入DAO投票或预言机
orders[orderId].state = OrderState.Disputed;
}
}
今日思考
1. 订单系统如何支持"先用后付"(BNPL)模式?
先用后付改变了传统"先支付后履约"的流程。订单状态机需要增加"使用中(IN_USE)"和"待结算(TO_SETTLE)"状态。支付域需要与信用评估域协作,在下单时进行风控评估而非直接收款。结算可以是分期(如花呗三期)或到期一次性扣款。核心挑战在于:如何在用户未付款的情况下保证商家权益?答案是引入担保方(金融机构)和风控模型。
2. 订单分库分表后如何做全局统计分析?
直接跨分片查询性能极差。主流方案有三种:(1) 异构数据同步到OLAP(如ClickHouse/StarRocks)做实时分析;(2) 通过Canal/Flink将变更流同步到ES做查询索引;(3) T+1离线同步到数仓做报表。选哪种取决于时效性要求——实时大屏用方案1,模糊查询用方案2,经营报表用方案3。
3. 多租户(Multi-Tenant)电商平台的订单隔离如何设计?
SaaS电商平台服务多个商家,需要数据隔离。三种模式:(1) 独立数据库(隔离最强,成本高);(2) 共享数据库独立Schema(折中);(3) 共享表加租户ID(成本低,隔离弱)。推荐中小商家用方案3 + 行级安全策略(Row-Level Security),大商家用方案1。订单号中也应嵌入租户标识。
面试题准备
题目1:订单状态机如何处理异常状态?
30秒回答: 订单状态机通过"守卫条件+补偿机制"处理异常。每次状态转换前校验前置条件,转换失败时触发补偿(如定时重试、人工介入)。关键是将异常也纳入状态机设计,而非try-catch了事。
2分钟回答: 异常处理分三层:
- 预防层:乐观锁防并发冲突、幂等键防重复提交、守卫条件阻止非法跳转
- 检测层:定时任务扫描"卡住"的订单(如PENDING超30分钟)、监控告警
- 恢复层:自动补偿(查询支付结果补状态)、降级处理(超时自动关单)、人工介入(争议订单转客服)
实际案例:支付回调丢失是最常见的异常——用户已扣款但订单仍PENDING。解决方案是定时任务每5分钟主动查询支付网关,补偿订单状态。同时订单号要保证幂等,避免重复创建。
追问准备:
- Q: 并发修改同一个订单怎么办?→ 乐观锁(version字段) + 状态机限制合法跳转
- Q: 状态机太复杂怎么管理?→ 拆分为多个子状态机(订单/支付/物流/售后各一个)
题目2:拆单逻辑如何设计?
30秒回答: 拆单采用"规则链"模式——按商家→按仓库→按配送→按品类依次执行拆分规则,最后通过合并优化器避免过度拆分。核心原则是"拆单结果的每个子订单可以独立履约"。
2分钟回答: 拆单设计要点:
- 规则可配置:用规则引擎(如Drools)而非硬编码,运营可动态调整
- 链式执行:多条规则依次处理,每条规则在上一条结果上继续拆分
- 合并优化:拆完后检查是否可以合并(同仓同配送方式的子组合并)
- 优惠分摊:拆单后优惠按比例分摊到子订单(精度问题用"最后一单兜底"策略)
- 原子性:拆单是创建子订单前的计算过程,失败则整个订单创建失败
追问准备:
- Q: 拆单后退款怎么算?→ 子订单独立退款,优惠按分摊比例扣减
- Q: 拆单和合单的优先级?→ 先拆后合,拆单面向履约,合单面向体验
学习资源
- 订单系统:从0到1设计思路 - 人人都是产品经理
- 大型电商系统的订单设计 - CSDN
- 订单状态机设计 - CSDN
- Distributed Unique ID Generator Design - AlgoMaster
- Snowflake ID - Wikipedia
- Global Ecommerce Sales Growth Report 2026 - Shopify
明日预告
Day 70: 促销系统设计 —— 促销系统是电商的"增长引擎",也是"复杂度炸弹"。我们将深入优惠券、满减、折扣、秒杀、拼团等促销类型的叠加规则设计,以及价格计算引擎和优惠分摊算法。当AI遇上促销系统,动态定价和智能推荐将如何改变游戏规则?