2.md 21 KB

农贸市场交易规则

1. 价格机制

  • 最低价(保底价)
    • 系统设定,公示给用户
    • 卖出价格必须≤最低价才能成交
  • 最高价
    • 系统设定,作为参考价
    • 买入价格必须≥最高价才有可能成交
    • 实际成交价可能高于公示的最高价
  • 价格精度
    • 挂单价格支持5位小数

2. 交易撮合规则

  • 执行方式
    • 用户买入物品撮合任务和用户卖出物品撮合任务分别执行(每5-10分钟)
    • 价格优先原则:用户买入物品出价高者优先成交
  • 成交逻辑
    • 交易对象
    • 用户卖出物品:用户将物品卖给系统仓库(非用户间交易)
    • 用户买入物品:用户从系统仓库购买物品
    • 执行方式
    • 所有订单(用户买入物品订单/用户卖出物品订单)都先创建挂单记录
    • 用户买入物品撮合任务处理用户买入物品订单的成交验证
    • 用户卖出物品撮合任务处理用户卖出物品订单的成交验证

3. 撮合队列规则

  • 查询筛选条件(用户买入物品订单):
    1. 状态为"等待"
    2. 价格 ≥ 最高价(价格符合条件)
    3. 数量 ≤ 保护阈值(不超量订单)
  • 排序优先级(MySQL查询时完成):
    1. 价格优先(用户买入物品价格高者优先)
    2. 时间优先(价格相同时,挂单时间早者优先)
  • 队列处理流程
    1. MySQL查询时完成筛选和排序
    2. 逐个处理排序后的订单
    3. 整单匹配库存(不拆单)
    4. 库存不足时结束本次撮合处理
    5. 记录成交订单并更新库存

4. 特殊情况处理

  • 整单成交原则:所有订单不拆单(要么全成交,要么不成交)
  • 库存不足处理
    1. 遇到库存不足的订单时,结束本次撮合处理
    2. 避免无效的循环处理,等待下次撮合或库存补充
  • 价格相同场景(用户买入物品订单):
    1. MySQL查询时已过滤超量订单
    2. 相同价格按挂单时间早者优先
  • 供不应求时:按价格和时间优先级处理,库存不足时结束撮合
  • 供过于求时:符合条件的用户买入物品订单按顺序全部整单成交

5. 订单保护机制

  • 数量保护阈值(仅适用于用户买入物品订单):
    • 后台设置(如300个)
    • 挂单规则:所有订单都可以正常挂单并冻结资金,不管是否超过保护阈值
    • 撮合规则:超量的用户买入物品订单不参与撮合成交(保留挂单状态)
  • 保护机制的作用
    • 防止大额用户买入物品订单操控市场
    • 避免市场流动性枯竭
    • 大单卡小单效应:超量订单会阻止后续小额订单参与撮合,这是有意设计的保护机制

6. 市场调控功能(管理员)

  • 物品注入(增加市场供应)
    • 操作方式:选择品种+方向(卖出)+设置数量→确认
    • 资金流转:调控账户(USER_ID: 16)资金转出到仓库账户(USER_ID: 15)
    • 物品流转:调控账户(USER_ID: 16)物品转入到仓库账户(USER_ID: 15)
    • 效果:增加市场供应,稳定价格下降趋势
  • 物品回收(减少市场库存)
    • 操作方式:选择品种+方向(买入)+设置数量→确认→销毁
    • 资金流转:仓库账户(USER_ID: 15)资金转出到调控账户(USER_ID: 16)
    • 物品流转:仓库账户(USER_ID: 15)物品转入到调控账户(USER_ID: 16)
    • 效果:减少市场库存,稳定价格上升趋势
  • 调控原则
    • 优先级:管理员操作>>用户订单
    • 总量守恒:所有调控操作确保系统总资金和物品总量不变
    • 透明度:调控操作不在交易大厅显示,但有详细日志记录
    • 权限控制:只有授权管理员可以执行调控操作

7. 信息展示规则(客户端)

  • 交易大厅显示
    • 仅展示已成交订单
    • 包含:用户昵称、商品、数量、成交价
    • 不显示未成交挂单
  • 用户界面
    • 个人可查看自己的未成交订单
    • 通过历史成交价推测合理报价

8. 数据库表结构设计

  • 订单表(mex_orders)
    • 记录用户买卖订单信息
    • 包含:用户ID、商品ID、订单类型(买/卖)、数量、价格、状态、创建时间等
  • 系统仓库表(mex_warehouse)
    • 记录系统商品库存
    • 包含:商品ID、库存数量、更新时间等
  • 成交记录表(mex_transactions)
    • 记录所有成交信息
    • 包含:买方ID、卖方ID、商品ID、成交数量、成交价格、成交时间等
  • 价格配置表(mex_price_configs)
    • 存储商品的最低价和最高价配置
    • 包含:商品ID、最低价、最高价、保护阈值、状态等
  • 市场调控记录表(mex_admin_operations)
    • 记录管理员市场调控操作
    • 包含:操作类型、商品ID、数量、操作员ID、操作时间等

8.1 系统账户体系设计

  • 仓库账户(USER_ID: 15)
    • 系统核心账户,负责所有交易的资金和物品中转
    • 用户卖出:资金从仓库账户转出到用户账户,物品从用户转入仓库账户
    • 用户买入:资金从用户账户转入仓库账户,物品从仓库账户转出到用户账户
    • 确保系统总量平衡,所有交易通过此账户进行
  • 调控账户(USER_ID: 16)
    • 管理员市场调控专用账户
    • 物品注入:从调控账户转出物品到仓库账户,增加市场供应
    • 物品回收:从仓库账户转入物品到调控账户,减少市场库存
    • 资金调控:调节市场流动性和价格稳定
  • 账户安全机制
    • 仓库账户和调控账户为系统保留账户,不允许普通用户操作
    • 所有账户操作必须通过系统服务层进行,确保数据一致性
    • 账户余额和库存变化需要详细日志记录,便于审计和监控

9. 核心算法实现要点

  • 挂单阶段
    • 无价格验证:最低价和最高价仅作为参考价格展示
    • 资金/物品检查:验证用户是否有足够的资金或物品
    • 冻结机制:所有订单都要冻结资金或物品,不管是否超过保护阈值
    • 订单创建:所有订单先创建挂单记录,等待撮合
  • 撮合阶段价格验证算法
    • 用户卖出物品订单价格验证:price ≤ min_price(撮合时验证)
    • 用户买入物品订单价格验证:price ≥ max_price(撮合时验证)
  • 撮合查询算法(用户买入物品订单):
    • MySQL查询筛选:状态=等待 AND 价格≥最高价 AND 数量≤保护阈值
    • 二级排序:按价格从高到低(DESC),按创建时间从早到晚(ASC)
  • 数量保护算法
    • 挂单阶段:所有订单都可以挂单并冻结资金/物品,不受保护阈值限制
    • 撮合阶段:quantity > protection_threshold 的用户买入物品订单不参与撮合
    • 保护阈值对用户隐藏,防止恶意操控
  • 整单匹配算法
    • 库存充足:订单完全成交,继续处理下一个订单
    • 库存不足:结束本次撮合处理,避免无效循环处理

10. 安全机制与风控

  • 防刷单机制
    • 用户订单频率限制
    • 异常交易行为监控
  • 防操控机制
    • 大额订单保护阈值
    • 价格异常波动预警
  • 账户安全机制
    • 仓库账户(USER_ID: 15)和调控账户(USER_ID: 16)为系统保留账户
    • 禁止普通用户直接操作系统账户
    • 所有账户操作必须通过系统服务层进行
    • 账户余额变化实时监控和告警
  • 数据一致性保证
    • 数据库事务确保原子性
    • 库存扣减与订单状态同步更新
    • 资金和物品流转的双重验证
  • 异常处理机制
    • 撮合失败回滚机制
    • 系统异常时的订单状态恢复
    • 账户流转失败的完整回滚

11. 性能优化策略

  • 计划任务优化
    • 批量处理减少数据库连接
    • 分页处理大量订单避免内存溢出
  • 数据库索引优化
    • 订单表:(status, price, created_at) 复合索引
    • 成交表:(created_at) 时间索引用于展示
  • 缓存策略
    • 价格配置缓存(Redis)
    • 系统库存缓存(定期同步)

12. 监控与日志

  • 业务监控指标
    • 订单成交率统计
    • 平均撮合时间监控
    • 系统库存变化趋势
    • 仓库账户资金和物品余额监控
    • 调控账户操作频率和金额监控
  • 操作日志记录
    • 用户下单日志
    • 撮合执行日志
    • 管理员操作日志
    • 账户资金流转日志
    • 物品转移日志
  • 异常告警机制
    • 撮合任务执行失败告警
    • 价格异常波动告警
    • 系统库存异常告警
    • 账户余额异常告警
    • 账户操作权限异常告警

13. 业务流程详细说明

13.1 资金/物品流向详细说明

13.1.1 用户买入物品流程

挂单阶段
  • 资金流向:用户可用账户 → 用户冻结账户
  • 用户总资金:不变(仅状态改变)
  • 系统影响:无
  • 保护阈值:不影响挂单,所有订单都可以挂单并冻结资金

    graph LR
    A[用户可用账户] -->|资金冻结| B[用户冻结账户]
    C[用户总资金] -->|保持不变| C
    
取消挂单阶段
  • 资金流向:用户冻结账户 → 用户可用账户
  • 用户总资金:不变(恢复原状态)
  • 系统影响:无

    graph LR
    A[用户冻结账户] -->|解冻资金| B[用户可用账户]
    C[用户总资金] -->|保持不变| C
    
挂单成交阶段
  • 资金流向:用户冻结账户 → 仓库账户可用资金
  • 物品流向:仓库账户 → 用户可用物品
  • 用户总资金:减少
  • 用户物品总数:增加

    graph TB
    subgraph "用户账户"
        A[用户冻结账户]
        B[用户可用物品]
    end
    subgraph "仓库账户 USER_ID:15"
        C[仓库可用资金]
        D[仓库物品库存]
    end
    A -->|资金转出| C
    D -->|物品转出| B
    E[用户总资金] -->|减少| F[用户总资金-]
    G[用户物品总数] -->|增加| H[用户物品总数+]
    

13.1.2 用户卖出物品流程

挂单阶段
  • 物品流向:用户物品可用状态 → 用户物品冻结状态
  • 用户物品总数:不变(仅状态改变)
  • 系统影响:无
  • 保护阈值:不影响挂单,所有订单都可以挂单并冻结物品

    graph LR
    A[用户物品可用状态] -->|物品冻结| B[用户物品冻结状态]
    C[用户物品总数] -->|保持不变| C
    
取消挂单阶段
  • 物品流向:用户物品冻结状态 → 用户物品可用状态
  • 用户物品总数:不变(恢复原状态)
  • 系统影响:无

    graph LR
    A[用户物品冻结状态] -->|解冻物品| B[用户物品可用状态]
    C[用户物品总数] -->|保持不变| C
    
挂单成交阶段
  • 资金流向:仓库账户可用资金 → 用户可用账户
  • 物品流向:用户物品可用状态 → 仓库账户
  • 用户总资金:增加
  • 用户物品总数:减少

    graph TB
    subgraph "用户账户"
        A[用户可用账户]
        B[用户物品可用状态]
    end
    subgraph "仓库账户 USER_ID:15"
        C[仓库可用资金]
        D[仓库物品库存]
    end
    C -->|资金转出| A
    B -->|物品转出| D
    E[用户总资金] -->|增加| F[用户总资金+]
    G[用户物品总数] -->|减少| H[用户物品总数-]
    

13.2 完整交易流程图

13.2.1 用户买入物品交易完整流程

flowchart TD
    A[用户提交买入物品订单] --> B[资金检查]
    B -->|资金充足| C[资金冻结:所有订单都冻结资金]
    B -->|资金不足| Z[订单拒绝]
    C --> D[创建挂单记录:不管是否超过保护阈值]
    D --> E[进入撮合队列等待]
    E --> F[用户买入物品撮合任务]
    F --> G[MySQL查询筛选:状态=等待 AND 价格≥最高价 AND 数量≤保护阈值]
    G --> H[二级排序:价格DESC,时间ASC]
    H --> I[遍历符合条件的订单]
    I --> J{库存匹配}
    J -->|库存充足| K[执行成交]
    J -->|库存不足| L[结束本次撮合]
    K --> M[资金转移:用户冻结→仓库可用]
    M --> N[物品转移:仓库→用户可用]
    N --> O[更新库存和订单状态]
    O --> P[生成成交记录]
    P --> Q{是否还有订单}
    Q -->|有| I
    Q -->|无| R[撮合任务完成]
    L --> R

13.2.2 用户卖出物品交易完整流程

flowchart TD
    A[用户提交卖出物品订单] --> B[物品检查]
    B -->|物品充足| C[物品冻结]
    B -->|物品不足| Z[订单拒绝]
    C --> D[创建挂单记录]
    D --> E[进入撮合队列等待]
    E --> F[用户卖出物品撮合任务]
    F --> G{价格验证}
    G -->|价格≤最低价| H[执行成交]
    G -->|价格>最低价| I[跳过此订单]
    H --> J[资金转移:仓库可用→用户可用]
    J --> K[物品转移:用户冻结→仓库]
    K --> L[更新库存和订单状态]
    L --> M[生成成交记录]
    M --> N[交易完成]
    I --> O[等待下次撮合]
    O --> F

13.3 系统账户流转关系图

graph TB
    subgraph "普通用户账户"
        UA[用户A可用资金]
        UF[用户A冻结资金]
        UI[用户A可用物品]
        UIF[用户A冻结物品]
    end

    subgraph "仓库账户 USER_ID:15"
        WF[仓库可用资金]
        WI[仓库物品库存]
    end

    subgraph "调控账户 USER_ID:16"
        CF[调控账户资金]
        CI[调控账户物品]
    end

    UA -.->|买入挂单| UF
    UF -->|买入成交| WF
    WI -->|买入成交| UI

    UI -.->|卖出挂单| UIF
    UIF -->|卖出成交| WI
    WF -->|卖出成交| UA

    CF <-->|市场调控| WF
    CI <-->|市场调控| WI

    style WF fill:#e1f5fe
    style WI fill:#e1f5fe
    style CF fill:#fff3e0
    style CI fill:#fff3e0

13.4 撮合执行流程(包含账户流转)

13.4.1 用户买入物品撮合任务执行步骤

  1. 任务启动:用户买入物品撮合任务定时启动(5-10分钟间隔)
  2. 订单获取:获取待撮合的用户买入物品订单(MySQL查询时完成筛选和排序)
    • 状态为"等待"
    • 价格 ≥ 最高价(价格符合条件)
    • 数量 ≤ 保护阈值(不超量订单)
    • 二级排序:价格DESC,时间ASC
    • 注意:所有订单在挂单时都已冻结资金,保护阈值只影响撮合成交
  3. 库存匹配:逐个匹配系统仓库库存
  4. 整单成交判断
    • 库存充足:执行成交
    • 库存不足:结束本次撮合处理(避免无效循环处理)
  5. 账户流转执行:用户冻结资金→仓库账户,仓库物品→用户账户
  6. 状态更新:更新订单状态和系统库存
  7. 记录生成:生成成交记录供交易大厅展示
  8. 异常处理:如果账户流转失败,回滚所有操作

13.4.2 用户卖出物品撮合任务执行步骤

  1. 任务启动:用户卖出物品撮合任务定时启动(5-10分钟间隔)
  2. 订单获取:获取所有状态为"等待"的用户卖出物品订单
  3. 价格验证:验证 用户卖出物品价格 ≤ 最低价
  4. 成交处理:符合条件的用户卖出物品订单执行成交
  5. 账户流转执行:用户冻结物品→仓库账户,仓库资金→用户账户
  6. 状态更新:更新订单状态和系统库存
  7. 记录生成:生成成交记录供交易大厅展示
  8. 异常处理:如果账户流转失败,回滚所有操作

13.4.3 用户买入物品撮合算法流程图

flowchart TD
    A[用户买入物品撮合任务启动] --> B[MySQL查询获取符合条件的订单]
    B --> C[筛选条件:状态=等待 AND 价格≥最高价 AND 数量≤保护阈值]
    C --> D[二级排序:价格DESC,时间ASC]
    D --> E[遍历排序后用户买入物品订单]
    E --> F{检查库存是否充足}
    F -->|充足| G[执行用户买入物品订单成交]
    F -->|不足| H[结束本次撮合处理]
    G --> I[资金流转:用户冻结→仓库可用]
    I --> J[物品流转:仓库→用户可用]
    J --> K[更新用户买入物品订单状态为已成交]
    K --> L[更新系统库存数量]
    L --> M[生成成交记录]
    M --> N{是否还有用户买入物品订单}
    N -->|有| E
    N -->|无| O[用户买入物品撮合任务完成]
    H --> O
    O --> P[任务正常结束]

13.4.4 用户卖出物品撮合算法流程图

flowchart TD
    A[用户卖出物品撮合任务启动] --> B[获取待撮合用户卖出物品订单]
    B --> C[遍历用户卖出物品订单]
    C --> D{用户卖出物品订单价格验证}
    D -->|价格≤最低价| E[执行用户卖出物品订单成交]
    D -->|价格>最低价| F[跳过订单,继续下一个]
    E --> G[资金流转:仓库可用→用户可用]
    G --> H[物品流转:用户冻结→仓库]
    H --> I[更新用户卖出物品订单状态为已成交]
    I --> J[更新系统库存数量]
    J --> K[生成成交记录]
    K --> L{是否还有用户卖出物品订单}
    F --> L
    L -->|有| C
    L -->|无| M[用户卖出物品撮合任务完成]
    M --> N[任务正常结束]

13.5 资金和物品流转汇总表

13.5.1 用户买入物品流转汇总

阶段 资金流向 物品流向 用户总资金变化 用户物品总数变化 系统影响
挂单 用户可用→用户冻结 不变 不变
取消挂单 用户冻结→用户可用 不变 不变
挂单成交 用户冻结→仓库可用 仓库→用户可用 减少 增加 库存减少

13.5.2 用户卖出物品流转汇总

阶段 资金流向 物品流向 用户总资金变化 用户物品总数变化 系统影响
挂单 用户可用→用户冻结 不变 不变
取消挂单 用户冻结→用户可用 不变 不变
挂单成交 仓库可用→用户可用 用户可用→仓库 增加 减少 库存增加

14. 技术实现架构

14.1 模块结构

app/Module/Mex/
├── Models/              # 数据模型
│   ├── MexOrder.php     # 订单模型
│   ├── MexWarehouse.php # 仓库模型
│   ├── MexTransaction.php # 成交记录模型
│   └── MexPriceConfig.php # 价格配置模型
├── Services/            # 服务层
│   ├── MexOrderService.php # 订单服务
│   ├── MexMatchService.php # 撮合服务
│   └── MexWarehouseService.php # 仓库服务
├── Logic/               # 逻辑层
│   ├── MexOrderLogic.php # 订单逻辑
│   └── MexMatchLogic.php # 撮合逻辑
├── Commands/            # 计划任务
│   ├── MexUserBuyItemMatchCommand.php  # 用户买入物品撮合任务
│   └── MexUserSellItemMatchCommand.php # 用户卖出物品撮合任务
├── Controllers/         # 控制器
│   └── Admin/           # 后台管理
└── Databases/           # 数据库文件
    └── GenerateSql/     # SQL文件

14.2 模块定位说明

  • 逻辑模块:Mex模块为纯逻辑模块,不提供API接口
  • 服务提供:仅为其他模块提供服务层接口
  • 内部调用:通过Service层方法供其他模块调用
  • 数据访问:通过Repository层提供后台管理数据访问

15. 部署与运维

15.1 计划任务配置

# 添加到 crontab
# 用户买入物品撮合任务
*/5 * * * * php artisan mex:user-buy-item-match >> /var/log/mex-user-buy-item-match.log 2>&1
# 用户卖出物品撮合任务
*/5 * * * * php artisan mex:user-sell-item-match >> /var/log/mex-user-sell-item-match.log 2>&1

15.2 监控指标

  • 撮合任务执行时间
  • 订单积压数量
  • 成交成功率
  • 系统库存水位

15.3 运维注意事项

  • 定期清理历史成交记录
  • 监控系统库存异常变化
  • 关注价格配置的合理性调整
  • 保护阈值的动态调整

文档版本:v2.8 最后更新:2025年06月12日 15:30 文档状态:已移除系统总量守恒验证 更新内容

  • 移除系统总量守恒验证:因为交易期间会产生新的物品/资金,总量守恒验证不可用
  • 移除所有流程图中的总量验证步骤
  • 移除总量守恒验证章节和相关流程图
  • 简化异常处理机制,移除总量异常相关的处理
  • 修正挂单机制:所有订单都要冻结资金或物品,不管是否超过保护阈值
  • 明确保护阈值作用:只影响撮合成交,不影响挂单创建
  • 优化用户买入物品撮合算法:MySQL查询时完成筛选和排序
  • 简化为二级排序:价格DESC + 时间ASC(移除数量排序)
  • 明确关键词:'买入' → '用户买入物品','卖出' → '用户卖出物品'
  • 分离用户买入物品和用户卖出物品为两个独立的撮合任务