---
url: /blog/0fjzgo2g/index.md
---
# ShopXO 购买流程业务逻辑分析

> 本文档专注于 ShopXO 购买流程的业务逻辑分析，不涉及具体代码实现细节。
> 目标：为开发者和业务分析师提供清晰、结构化的购买流程参考。

***

## 目录

* [1. 概述](buy-process-business-analysis.md#1-概述)
* [2. 购买流程总览](buy-process-business-analysis.md#2-购买流程总览)
* [3. 购物车处理逻辑](buy-process-business-analysis.md#3-购物车处理逻辑)
* [4. 下单流程详解](buy-process-business-analysis.md#4-下单流程详解)
* [5. 库存校验与锁定](buy-process-business-analysis.md#5-库存校验与锁定)
* [6. 库存回滚机制](buy-process-business-analysis.md#6-库存回滚机制)
* [7. 订单拆分逻辑](buy-process-business-analysis.md#7-订单拆分逻辑)
* [8. 价格计算逻辑](buy-process-business-analysis.md#8-价格计算逻辑)
* [9. 订单状态流转](buy-process-business-analysis.md#9-订单状态流转)
* [10. 扩展机制](buy-process-business-analysis.md#10-扩展机制)
* [11. 业务规则汇总](buy-process-business-analysis.md#11-业务规则汇总)

***

## 1. 概述

### 1.1 研究目标

本文档深入分析 ShopXO 电商系统的购买流程核心业务逻辑，涵盖从商品选择到订单创建的完整链路。

**核心研究内容：**

* 购物车处理机制
* 订单创建流程
* 库存管理与锁定机制
* 订单拆分策略
* 价格计算逻辑

### 1.2 核心概念

| 概念 | 说明 |
|------|------|
| **购买类型** | 系统支持两种购买方式：`goods`(直接购买) 和 `cart`(购物车购买) |
| **订单模式** | 定义订单的配送方式，包括快递、同城、自提、虚拟等 |
| **站点类型** | 系统级别的配送模式配置，可组合支持多种配送方式 |
| **仓库模式** | 商品按仓库分组，不同仓库的商品可能拆分为多个订单 |
| **规格商品** | 同一商品可因规格（颜色、尺寸等）差异拥有不同价格和库存 |

### 1.3 订单模式类型

系统支持多种订单配送模式：

| 模式值 | 名称 | 说明 | 是否需要地址 |
|--------|------|------|--------------|
| `0` | 快递配送 | 传统快递发货 | ✅ 收货地址 |
| `1` | 同城配送 | 本地配送服务 | ✅ 收货地址 |
| `2` | 自提 | 用户到店自提 | ✅ 自提点地址 |
| `3` | 虚拟商品 | 虚拟商品或服务 | ❌ 无需地址 |
| `4` | 展示型 | 仅展示不可下单 | - |

**组合模式：**

* `5`: 快递 + 自提
* `6`: 同城 + 自提
* `7`: 快递 + 同城
* `8`: 快递 + 同城 + 自提

### 1.4 相关服务层

购买流程涉及多个服务层协同：

```
┌─────────────────────────────────────────────────────────────┐
│                        BuyService                           │
│                    (购买流程核心服务)                        │
└─────────────────────────────────────────────────────────────┘
                            │
          ┌─────────────────┼─────────────────┐
          │                 │                 │
          ▼                 ▼                 ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ GoodsCartService│ │ OrderSplitService│ │GoodsService     │
│   (购物车服务)   │ │  (订单拆分服务)  │ │  (商品服务)     │
└─────────────────┘ └─────────────────┘ └─────────────────┘
          │                 │                 │
          ▼                 ▼                 ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│  UserService    │ │ PaymentService  │ │WarehouseService │
│   (用户服务)    │ │   (支付服务)    │ │  (仓库服务)     │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```

***

## 2. 购买流程总览

### 2.1 购买入口

系统提供两种购买入口：

| 入口类型 | 触发场景 | 数据来源 | 典型使用场景 |
|----------|----------|----------|--------------|
| **直接购买 (goods)** | 用户在商品详情页直接点击购买 | 商品ID + 规格 + 数量 | 快速购买单个商品 |
| **购物车购买 (cart)** | 用户从购物车页面提交订单 | 购物车内选中的商品 | 批量购买多个商品 |

### 2.2 主流程图

```mermaid
flowchart TD
    Start([用户发起购买]) --> CheckType{购买类型?}

    CheckType -->|直接购买| BuyGoods[BuyGoods<br/>获取商品数据]
    CheckType -->|购物车购买| BuyCart[BuyCart<br/>获取购物车数据]

    BuyGoods --> ValidateGoods
    BuyCart --> ValidateGoods

    ValidateGoods[商品基础校验] --> CheckSiteType{站点模式判断}

    CheckSiteType --> SiteModel[确定订单模式<br/>快递/同城/自提/虚拟]

    SiteModel --> AddressHandle[地址处理]
    AddressHandle -->|快递/同城| UserAddress[获取用户收货地址]
    AddressHandle -->|自提| ExtractionAddress[获取自提点地址]
    AddressHandle -->|虚拟| NoAddress[无需地址]

    UserAddress --> OrderSplit
    ExtractionAddress --> OrderSplit
    NoAddress --> OrderSplit

    OrderSplit[订单拆分处理] --> CalculatePrice[价格计算]

    CalculatePrice --> DisplayConfirm[显示订单确认页]

    DisplayConfirm --> UserConfirm{用户确认提交?}

    UserConfirm -->|否| End1([流程结束])
    UserConfirm -->|是| OrderInsert[OrderInsert<br/>订单创建]

    OrderInsert --> ValidateUser[用户状态校验]
    ValidateUser --> ValidateGoods2[商品二次校验]
    ValidateGoods2 --> ValidatePayment[支付方式校验]

    ValidatePayment --> Transaction[开启数据库事务]

    Transaction --> GenerateOrderNo[生成订单号]
    GenerateOrderNo --> InsertOrder[插入订单主表]
    InsertOrder --> InsertOrderDetail[插入订单详情]
    InsertOrderDetail --> InsertAddress[插入订单地址<br/>如需]
    InsertAddress --> InventoryDeduct{需扣库存?}

    InventoryDeduct -->|是| DeductStock[扣除商品库存]
    InventoryDeduct -->|否| Commit
    DeductStock --> Commit[提交事务]

    Commit --> DeleteCart[删除购物车数据<br/>购物车购买模式]
    DeleteCart --> TriggerHook[触发订单成功钩子]
    TriggerHook --> ReturnResult[返回订单数据]

    ReturnResult --> PaymentJump{需立即支付?}
    PaymentJump -->|是| PaymentPage[跳转支付页面]
    PaymentJump -->|否| End2([下单成功])

    style Start fill:#e1f5e1
    style End1 fill:#ffe1e1
    style End2 fill:#e1f5e1
    style OrderInsert fill:#fff4e1
    style Transaction fill:#ffe1f5
    style Commit fill:#e1f5e1
    style DeductStock fill:#e1f0ff
```

### 2.3 关键决策点说明

| 决策点 | 说明 | 业务影响 |
|--------|------|----------|
| **站点模式判断** | 根据系统配置和商品类型确定订单配送模式 | 决定是否需要地址、是否拆单 |
| **订单拆分** | 多仓库或多配送模式触发订单拆分 | 生成多个子订单 |
| **库存扣除时机** | 可配置下单时/支付时/发货时扣库存 | 影响库存并发安全 |
| **订单状态** | 预约模式/正常支付/线下支付决定初始状态 | 影响后续流程走向 |

***

## 3. 购物车处理逻辑

### 3.1 购物车数据获取

**流程说明：**

```mermaid
flowchart LR
    Start([用户选择购物车商品]) --> GetCartIds[获取选中的购物车ID列表]
    GetCartIds --> QueryCart[查询购物车数据<br/>关联商品基础信息]
    QueryCart --> FilterGoods[过滤已下架<br/>已删除商品]
    FilterGoods --> HandleSpec[处理商品规格数据]
    HandleSpec --> CalculateItem[计算单项小计]
    CalculateItem --> ReturnCart[返回购物车商品列表]

    style Start fill:#e1f5e1
    style ReturnCart fill:#e1f5e1
```

**核心数据字段：**

| 字段 | 来源 | 说明 |
|------|------|------|
| `goods_id` | 购物车表 | 商品ID |
| `stock` | 购物车表 | 购买数量 |
| `spec` | 购物车表 | 商品规格（JSON） |
| `title` | 商品表 | 商品标题 |
| `images` | 商品表 | 商品图片 |
| `price` | 规格表 | 规格价格 |
| `inventory` | 规格表 | 规格库存 |
| `original_price` | 规格表 | 规格原价 |

### 3.2 购物车商品校验

购物车商品在提交订单前会进行以下校验：

| 校验项 | 校验内容 | 失败处理 |
|--------|----------|----------|
| **商品状态** | `is_shelves = 1` 且 `is_delete_time = 0` | 提示商品已下架或删除 |
| **起购数量** | 购买数量 ≥ 规则起购数/商品起购数 | 提示数量不足 |
| **限购数量** | 购买数量 ≤ 规则限购数/商品限购数 | 提示数量超限 |
| **库存充足** | 购买数量 ≤ 规格库存 | 提示库存不足 |
| **模式一致性** | 多商品时需配送模式一致 | 提示模式不一致 |

### 3.3 购物车删除时机

购物车数据删除的时机：

| 场景 | 是否删除 | 说明 |
|------|----------|------|
| **订单创建成功** | ✅ 删除 | 仅删除已下单的购物车项 |
| **订单创建失败** | ❌ 保留 | 用户可调整后重新提交 |
| **直接购买模式** | ❌ 不涉及 | 不经过购物车 |

***

## 4. 下单流程详解

### 4.1 流程时序图

```mermaid
sequenceDiagram
    actor U as 用户
    participant C as Controller
    participant BS as BuyService
    participant GS as GoodsService
    participant US as UserService
    participant PS as PaymentService
    participant DB as 数据库

    U->>C: 提交订单请求
    C->>BS: OrderInsert(params)

    BS->>US: 用户状态校验
    US-->>BS: 校验结果

    BS->>BS: 获取商品清单<br/>(BuyTypeGoodsList)
    BS->>GS: 查询商品信息
    GS-->>BS: 商品数据

    BS->>BS: 订单拆分处理<br/>(OrderSplitHandle)

    BS->>BS: 商品校验<br/>(BuyGoodsCheck)
    BS->>GS: 校验商品状态/库存
    GS-->>BS: 校验通过

    BS->>PS: 校验支付方式
    PS-->>BS: 支付方式有效

    BS->>DB: 开启事务
    BS->>DB: 生成订单号
    BS->>DB: 插入订单主表
    BS->>DB: 插入订单详情
    BS->>DB: 插入订单地址(如需)

    alt 需扣除库存
        BS->>GS: 扣除商品库存
        BS->>DB: 记录库存日志
    end

    BS->>DB: 提交事务

    alt 购物车购买
        BS->>DB: 删除购物车数据
    end

    BS->>BS: 触发成功钩子
    BS-->>C: 返回订单数据
    C-->>U: 跳转支付/完成页面
```

### 4.2 用户状态校验

下单前必须验证用户状态：

| 校验项 | 说明 | 异常处理 |
|--------|------|----------|
| **用户存在** | 用户ID有效 | 提示用户信息错误 |
| **用户状态** | 账号未被禁用 | 提示账号异常 |
| **会员状态** | 会员有效期内 | 根据业务需求处理 |

### 4.3 商品数据校验

下单时进行二次校验，确保数据准确性：

```mermaid
flowchart TD
    Start([商品数据校验]) --> CheckExist{商品存在?}
    CheckExist -->|否| ReturnError1[返回:商品不存在]
    CheckExist -->|是| CheckShelves{商品上架?}

    CheckShelves -->|否| ReturnError2[返回:商品已下架]
    CheckShelves -->|是| CheckMin{数量≥起购数?}

    CheckMin -->|否| ReturnError3[返回:数量不足]
    CheckMin -->|是| CheckMax{数量≤限购数?}

    CheckMax -->|否| ReturnError4[返回:数量超限]
    CheckMax -->|是| CheckStock{数量≤库存?}

    CheckStock -->|否| ReturnError5[返回:库存不足]
    CheckStock -->|是| CheckSiteType{配送模式一致?}

    CheckSiteType -->|否| ReturnError6[返回:模式不一致]
    CheckSiteType -->|是| ReturnSuccess[返回:校验通过]

    style Start fill:#e1f5e1
    style ReturnSuccess fill:#e1f5e1
    style ReturnError1 fill:#ffe1e1
    style ReturnError2 fill:#ffe1e1
    style ReturnError3 fill:#ffe1e1
    style ReturnError4 fill:#ffe1e1
    style ReturnError5 fill:#ffe1e1
    style ReturnError6 fill:#ffe1e1
```

### 4.4 地址处理

**快递/同城配送模式：**

* 用户必须选择收货地址
* 未选择时使用默认地址
* 地址信息包含：姓名、电话、省市区、详细地址、经纬度

**自提模式：**

* 用户选择自提点
* 可选填写联系人信息（取货人姓名、电话）
* 系统自动生成4位取货码

**虚拟商品模式：**

* 无需收货地址
* 商品虚拟值直接写入订单详情

### 4.5 支付方式处理

| 配置项 | 说明 |
|--------|------|
| **预约模式** | 开启后订单状态为待确认，无需支付 |
| **支付方式必选** | 订单金额>0时必须选择支付方式 |
| **线下支付** | 线下支付订单可直接设为已支付状态 |

**订单状态决策表：**

| 预约模式 | 支付方式 | 线下支付正常流程 | 订单状态 |
|----------|----------|------------------|----------|
| 开启 | - | - | `0` 待确认 |
| 关闭 | 已选择 | 否 | `1` 待支付 |
| 关闭 | 已选择 | 是 | `2` 已支付 |

### 4.6 订单数据结构

订单创建时生成的核心数据：

**订单主表字段：**

* `order_no` - 订单号（YmdHis + 6位随机数）
* `user_id` - 用户ID
* `warehouse_id` - 仓库ID
* `status` - 订单状态
* `price` - 商品总价
* `preferential_price` - 优惠金额
* `increase_price` - 增加金额
* `total_price` - 实际支付金额
* `payment_id` - 支付方式ID
* `order_model` - 订单配送模式

**订单详情字段：**

* `goods_id` - 商品ID
* `title` - 商品标题
* `images` - 商品图片
* `price` - 规格价格
* `original_price` - 规格原价
* `spec` - 商品规格（JSON）
* `buy_number` - 购买数量
* `total_price` - 小计金额

***

## 5. 库存校验与锁定

### 5.1 库存扣除规则

系统支持三种库存扣除时机，由配置 `common_deduction_inventory_rules` 控制：

| 规则值 | 名称 | 扣除时机 | 优缺点 |
|--------|------|----------|--------|
| `0` | 下单扣库存 | 订单确认成功时 | 优点：库存准确缺点：恶意下单占用库存 |
| `1` | 支付扣库存 | 订单支付成功时 | 优点：减少恶意占用缺点：超卖风险 |
| `2` | 发货扣库存 | 订单发货时 | 优点：灵活度高缺点：库存预警困难 |

**配置检查点：**

* `common_is_deduction_inventory` - 是否启用库存扣除功能

### 5.2 库存扣除流程图

```mermaid
flowchart TD
    Start([订单状态变更]) --> CheckConfig{启用库存扣除?}
    CheckConfig -->|否| EndSkip([跳过库存处理])
    CheckConfig -->|是| CheckRule{扣除规则}

    CheckRule -->|下单扣| CheckStatus1{status=1或2?}
    CheckRule -->|支付扣| CheckStatus2{status=2?}
    CheckRule -->|发货扣| CheckStatus3{status=3?}

    CheckStatus1 -->|否| EndSkip
    CheckStatus2 -->|否| EndSkip
    CheckStatus3 -->|否| EndSkip

    CheckStatus1 -->|是| GetOrderDetail
    CheckStatus2 -->|是| GetOrderDetail
    CheckStatus3 -->|是| GetOrderDetail

    GetOrderDetail[获取订单商品详情] --> CheckDeducted{已扣除过?}
    CheckDeducted -->|是| EndSkip
    CheckDeducted -->|否| CheckGoodsSetting{商品启用扣库存?}

    CheckGoodsSetting -->|否| NextGoods
    CheckGoodsSetting -->|是| CheckGoodsStock{商品库存充足?}

    CheckGoodsStock -->|否| ReturnError[返回库存不足]
    CheckGoodsStock -->|是| DeductGoods[扣除商品库存]

    DeductGoods --> CheckSpecStock{规格库存充足?}
    CheckSpecStock -->|否| RollbackGoods[回滚商品库存]
    RollbackGoods --> ReturnError
    CheckSpecStock -->|是| DeductSpec[扣除规格库存]

    DeductSpec --> WarehouseDeduct[仓库库存扣除]
    WarehouseDeduct --> InsertLog[插入库存日志]

    InsertLog --> NextGoods{还有商品?}
    NextGoods -->|是| GetOrderDetail
    NextGoods -->|否| ReturnSuccess[返回成功]

    style Start fill:#e1f5e1
    style ReturnSuccess fill:#e1f5e1
    style ReturnError fill:#ffe1e1
    style EndSkip fill:#f0f0f0
    style DeductGoods fill:#e1f0ff
    style DeductSpec fill:#e1f0ff
```

### 5.3 商品校验

库存扣除前进行商品校验：

| 校验项 | 校验内容 | 说明 |
|--------|----------|------|
| **商品库存** | `inventory >= buy_number` | 商品级库存充足 |
| **规格库存** | `spec.inventory >= buy_number` | 规格级库存充足 |
| **扣库存标志** | `is_deduction_inventory = 1` | 商品启用扣库存 |
| **重复扣除检查** | 查询库存日志 | 避免模式切换导致重复扣除 |

### 5.4 仓库库存联动

库存扣除涉及三层库存：

```mermaid
flowchart LR
    subgraph 三层库存
        A[商品库存<br/>sxo_goods.inventory]
        B[规格库存<br/>sxo_goods_spec_base.inventory]
        C[仓库库存<br/>sxo_warehouse_goods.inventory]
    end

    A -->|同步扣除| D[库存扣除操作]
    B -->|同步扣除| D
    C -->|同步扣除| D

    D --> E[记录库存日志<br/>sxo_order_goods_inventory_log]

    style D fill:#ff6b6b
    style E fill:#51cf66
```

***

## 6. 库存回滚机制

### 6.1 回滚触发条件

库存回滚仅在订单取消或关闭时触发：

| 订单状态 | 说明 | 是否回滚 |
|----------|------|----------|
| `5` | 已取消 | ✅ 回滚库存 |
| `6` | 已关闭 | ✅ 回滚库存 |
| 其他状态 | - | ❌ 不回滚 |

### 6.2 回滚流程图

```mermaid
flowchart TD
    Start([订单取消/关闭]) --> GetOrder[获取订单数据]
    GetOrder --> CheckStatus{状态=5或6?}
    CheckStatus -->|否| EndSkip([不回滚库存])
    CheckStatus -->|是| GetDetail[获取订单商品]

    GetDetail --> CheckLog{存在库存日志?}
    CheckLog -->|否| EndSkip
    CheckLog -->|是| LoopGoods[遍历订单商品]

    LoopGoods --> AddGoods[增加商品库存]
    AddGoods --> AddSpec[增加规格库存]
    AddSpec --> WarehouseRollback[仓库库存回滚]

    WarehouseRollback --> UpdateLog[更新库存回滚日志]
    UpdateLog --> NextItem{还有商品?}

    NextItem -->|是| LoopGoods
    NextItem -->|否| ReturnSuccess[回滚完成]

    style Start fill:#ffe1e1
    style ReturnSuccess fill:#e1f5e1
    style AddGoods fill:#e1f0ff
    style AddSpec fill:#e1f0ff
    style EndSkip fill:#f0f0f0
```

### 6.3 回滚日志

库存日志表 `sxo_order_goods_inventory_log` 记录完整操作历史：

| 字段 | 说明 |
|------|------|
| `order_id` | 订单ID |
| `order_detail_id` | 订单详情ID |
| `goods_id` | 商品ID |
| `order_status` | 扣除时的订单状态 |
| `original_inventory` | 原始库存量 |
| `new_inventory` | 扣除后库存量 |
| `is_rollback` | 是否已回滚 |
| `rollback_time` | 回滚时间 |
| `add_time` | 扣除时间 |

***

## 7. 订单拆分逻辑

### 7.1 拆分触发场景

订单拆分由以下场景触发：

| 场景 | 拆分原因 | 拆分规则 |
|------|----------|----------|
| **多仓库** | 商品位于不同仓库 | 每个仓库生成一个订单 |
| **混合配送模式** | 系统支持多种配送模式 | 按配送模式拆分 |
| **用户指定** | 用户选择不同配送方式 | 按用户选择拆分 |

### 7.2 拆分流程图

```mermaid
flowchart TD
    Start([商品列表]) --> Aggregate[商品仓库聚合]
    Aggregate --> CheckCount{仓库数量>1<br/>且非快递/同城?}

    CheckCount -->|是| ForceModel[强制设为快递模式]
    CheckCount -->|否| BaseHandle

    ForceModel --> BaseHandle[分组商品基础处理]
    BaseHandle --> CalcWeight[计算重量/体积]
    CalcWeight --> CalcPrice[计算分组价格]

    CalcPrice --> CheckExt{存在扩展数据?}
    CheckExt -->|否| TriggerHook
    CheckExt -->|是| CalcExtPrice[计算扩展金额]

    CalcExtPrice --> UpdatePrice[更新订单金额<br/>增加/减少]
    UpdatePrice --> TriggerHook[触发拆分钩子]

    TriggerHook --> CheckHook{钩子返回成功?}
    CheckHook -->|否| ReturnError
    CheckHook -->|是| ReturnSuccess[返回拆分结果]

    ReturnSuccess --> Display[显示:多个子订单]

    style Start fill:#e1f5e1
    style ReturnSuccess fill:#e1f5e1
    style ReturnError fill:#ffe1e1
    style Aggregate fill:#fff4e1
```

### 7.3 金额计算

每个拆分订单独立计算金额：

| 字段 | 计算方式 | 说明 |
|------|----------|------|
| `total_price` | Σ(商品价格 × 数量) | 商品总价 |
| `actual_price` | total\_price - preferential + increase | 实际支付金额 |
| `preferential_price` | 扩展数据中type=0的总和 | 优惠金额 |
| `increase_price` | 扩展数据中type=1的总和 | 增加金额 |

**示例：**

```
订单A: 快递模式
  - 商品1: 价格100 × 2 = 200
  - 商品2: 价格50 × 1 = 50
  - total_price = 250
  - 运费(增加): +10
  - 优惠券(优惠): -20
  - actual_price = 250 + 10 - 20 = 240

订单B: 自提模式
  - 商品3: 价格80 × 1 = 80
  - total_price = 80
  - 自提优惠: -5
  - actual_price = 80 - 5 = 75

总计: actual_price = 240 + 75 = 315
```

***

## 8. 价格计算逻辑

### 8.1 价格字段说明

| 字段 | 含义 | 计算来源 |
|------|------|----------|
| `original_price` | 商品原价 | 规格原价 |
| `price` | 售价 | 规格价格（可应用VIP价） |
| `total_price` | 商品总价 | Σ(price × buy\_number) |
| `preferential_price` | 优惠金额 | 优惠券、满减等 |
| `increase_price` | 增加金额 | 运费、服务费等 |
| `actual_price` | 实际支付 | total\_price - preferential + increase |

### 8.2 计算流程

```mermaid
flowchart LR
    Start([开始计算]) --> GetBasePrice[获取基础价格]
    GetBasePrice --> ApplyVIP{用户是VIP?}
    ApplyVIP -->|是| VIPPrice[应用VIP折扣]
    ApplyVIP -->|否| UseOriginal
    VIPPrice --> CalcTotal
    UseOriginal[使用原价] --> CalcTotal[计算总价<br/>Σprice×quantity]

    CalcTotal --> CalcExt{存在扩展费用?}
    CalcExt -->|否| ReturnPrice
    CalcExt -->|是| CalcIncrease[计算增加金额<br/>type=1]

    CalcIncrease --> CalcPrefer[计算优惠金额<br/>type=0]
    CalcPrefer --> CalcActual[计算实际支付]

    CalcActual --> CheckNegative{实际金额<0?}
    CheckNegative -->|是| SetZero[设为0]
    CheckNegative -->|否| ReturnPrice
    SetZero --> ReturnPrice[返回价格数据]

    style Start fill:#e1f5e1
    style ReturnPrice fill:#e1f5e1
    style CalcActual fill:#fff4e1
```

### 8.3 VIP 价格应用

VIP 用户享受特殊价格：

| 条件 | 处理方式 |
|------|----------|
| 用户是VIP | 覆盖原价，使用VIP价格 |
| 用户非VIP | 使用规格原价 |
| 未设置VIP价 | 使用规格原价 |

**价格优先级：**

```
VIP价格 > 规格价格 > 商品基础价格
```

***

## 9. 订单状态流转

### 9.1 状态说明

| 状态值 | 名称 | 说明 | 可操作 |
|--------|------|------|--------|
| `0` | 待确认 | 预约模式或待审核 | 确认、取消 |
| `1` | 待支付 | 已确认待付款 | 支付、取消 |
| `2` | 已支付 | 已付款待发货 | 发货、退款 |
| `3` | 已发货 | 商品已发出 | 确认收货 |
| `4` | 已完成 | 交易完成 | 评价、售后 |
| `5` | 已取消 | 订单取消 | - |
| `6` | 已关闭 | 订单关闭 | - |

### 9.2 状态流转图

```mermaid
stateDiagram-v2
    [*] --> 待确认: 预约模式下单
    [*] --> 待支付: 正常下单

    待确认 --> 已取消: 取消订单
    待确认 --> 待支付: 确认订单
    待确认 --> 已支付: 线下支付

    待支付 --> 已取消: 取消/超时
    待支付 --> 已支付: 支付成功

    已支付 --> 待发货: 备货中
    待支付 --> 已取消: 申请退款

    待发货 --> 已发货: 发货操作

    已发货 --> 已完成: 确认收货
    已发货 --> 已关闭: 售后关闭

    已完成 --> [*]: 交易结束
    已取消 --> [*]: 流程结束
    已关闭 --> [*]: 流程结束

    note right of 待确认
        预约模式专属状态
        需人工确认
    end note

    note right of 待支付
        最常见状态
        支付扣库存时机
    end note

    note right of 已发货
        发货扣库存时机
        取消需回滚库存
    end note
```

***

## 10. 扩展机制

### 10.1 钩子系统

购买流程通过钩子系统提供扩展点，允许插件介入业务流程：

**钩子触发位置：**

* 订单创建前
* 订单创建后
* 库存扣除前
* 价格计算时
* 订单拆分时

### 10.2 主要扩展点

| 钩子名称 | 触发时机 | 用途 |
|----------|----------|------|
| `plugins_service_buy_oredr_site_type_model` | 确定订单模式 | 修改配送模式 |
| `plugins_service_buy_handle` | 订单数据处理 | 修改订单数据 |
| `plugins_service_buy_order_insert_begin` | 订单插入前 | 添加额外字段 |
| `plugins_service_buy_order_insert_end` | 订单插入后 | 关联数据处理 |
| `plugins_service_buy_order_submit_success` | 订单提交成功 | 发送通知等 |

***

## 11. 业务规则汇总

### 11.1 校验规则

| 规则 | 触发时机 | 校验内容 | 失败提示 |
|------|----------|----------|----------|
| **商品上架校验** | 下单前 | `is_shelves = 1` | 商品已下架 |
| **起购数量校验** | 下单前 | `stock ≥ min_number` | 数量不足 |
| **限购数量校验** | 下单前 | `stock ≤ max_number` | 数量超限 |
| **库存校验** | 下单前/支付前 | `stock ≤ inventory` | 库存不足 |
| **模式一致性校验** | 购物车下单 | 所有商品模式一致 | 模式不一致 |
| **地址必填校验** | 下单前 | 快递/同城需地址 | 请选择地址 |
| **支付方式校验** | 下单前 | 金额>0需选支付 | 请选择支付方式 |

### 11.2 库存规则

| 规则 | 配置项 | 说明 |
|------|--------|------|
| **启用库存扣除** | `common_is_deduction_inventory` | 全局开关 |
| **扣除时机** | `common_deduction_inventory_rules` | 0:下单 1:支付 2:发货 |
| **扣库存标志** | `goods.is_deduction_inventory` | 商品级控制 |
| **重复扣除防护** | 日志表查询 | 避免模式切换重复扣 |
| **回滚条件** | 订单状态=5或6 | 取消/关闭时回滚 |

### 11.3 价格规则

| 规则 | 说明 |
|------|------|
| **价格来源** | 优先级: VIP价 > 规格价 > 商品价 |
| **扩展金额** | type=0减少, type=1增加 |
| **负数防护** | actual\_price < 0 时设为 0 |
| **金额精度** | 使用 `PriceNumberFormat` 格式化 |

***

## 附录

### A. 数据表关系

```
sxo_order (订单主表)
├── sxo_order_detail (订单详情)
│   └── sxo_order_fictitious_value (虚拟商品值)
├── sxo_order_address (订单地址)
├── sxo_order_extraction_code (自提码)
├── sxo_order_currency (订单货币)
└── sxo_order_goods_inventory_log (库存日志)

sxo_cart (购物车)
├── sxo_goods (商品)
│   └── sxo_goods_spec_base (规格)
└── sxo_user (用户)
```

### B. 关键方法映射

| 业务功能 | 对应方法 |
|----------|----------|
| 购买入口 | `BuyTypeGoodsList()` |
| 购物车购买 | `BuyCart()` |
| 直接购买 | `BuyGoods()` |
| 订单创建 | `OrderInsert()` |
| 订单拆分 | `OrderSplitHandle()` |
| 库存扣除 | `OrderInventoryDeduct()` |
| 库存回滚 | `OrderInventoryRollback()` |
| 商品校验 | `BuyGoodsCheck()` |

### C. 配置项索引

| 配置键 | 默认值 | 说明 |
|--------|--------|------|
| `common_order_is_booking` | 0 | 预约模式 |
| `common_is_deduction_inventory` | 0 | 启用库存扣除 |
| `common_deduction_inventory_rules` | 1 | 库存扣除规则 |
| `common_fictitious_order_direct_pay` | 0 | 虚拟商品直接下单 |
| `common_is_under_line_order_normal` | 0 | 线下订单正常流程 |

***

**文档版本**: v1.0
**更新日期**: 2025-01-31
**适用版本**: ShopXO v6.7.0+

***
