212146-修复Mex订单123物品转移失败问题.md 4.0 KB

修复Mex订单123物品转移失败问题

任务时间

  • 开始时间:2025-06-21 21:46:33
  • 完成时间:2025-06-21 21:52:00

问题描述

用户反馈:模块Mex 订单123 ,没有成交,这个订单是卖出单,失败原因是'物品转移失败',就很异常

问题分析

1. 订单123详细信息

SELECT * FROM kku_mex_orders WHERE id = 123;
  • 订单ID:123
  • 用户ID:39077
  • 物品ID:3(辣椒)
  • 订单类型:SELL(卖出)
  • 数量:100
  • 价格:0.00900
  • 状态:PENDING
  • 失败原因:用户卖出物品订单撮合失败:物品流转失败:物品转移异常:用户 39077 的物品 3 数量不足,需要 100,实际 74

2. 用户物品情况分析

用户39077的物品3情况:

  • 未冻结物品:74个
  • 冻结物品:2200个(分别来自订单113、117、122、123)
  • 总数量:2274个

3. 根本原因

物品消耗逻辑不支持冻结物品消耗

  1. ItemLogic::consumeNormalItem方法硬编码了->where('is_frozen', false)
  2. MexMatchLogic::transferFrozenItemsToWarehouse传递了'include_frozen' => true参数,但被忽略
  3. 撮合时只能消耗未冻结的74个物品,无法消耗已冻结的100个物品

修复方案

1. 修改ItemLogic::consumeNormalItem方法

// 检查是否包含冻结物品
$includeFrozen = $options['include_frozen'] ?? false;

// 构建查询条件
$query = ItemUser::where('user_id', $userId)
    ->where('item_id', $itemId)
    ->whereNull('instance_id')
    ->where('quantity', '>', 0);

// 根据include_frozen参数决定是否包含冻结物品
if (!$includeFrozen) {
    $query->where('is_frozen', false);
}

2. 修改ItemLogic::consumeUniqueItem方法

// 检查是否包含冻结物品
$includeFrozen = $options['include_frozen'] ?? false;

// 构建查询条件
$query = ItemUser::where('user_id', $userId)
    ->where('item_id', $itemId)
    ->where('instance_id', $instanceId);

// 根据include_frozen参数决定是否包含冻结物品
if (!$includeFrozen) {
    $query->where('is_frozen', false);
}

测试验证

1. 修复前状态

-- 订单123状态
SELECT id, status, last_match_failure_reason FROM kku_mex_orders WHERE id = 123;
-- 结果:PENDING,物品转移失败

-- 用户物品状态
SELECT id, quantity, is_frozen FROM kku_item_users WHERE user_id = 39077 AND item_id = 3;
-- 结果:74个未冻结,2200个冻结

2. 执行撮合测试

php artisan mex:user-sell-item-match --item=3

3. 修复后状态

-- 订单123状态
SELECT id, status, completed_quantity, last_match_failure_reason FROM kku_mex_orders WHERE id = 123;
-- 结果:COMPLETED,100,null

-- 成交记录
SELECT * FROM kku_mex_transactions WHERE sell_order_id = 123;
-- 结果:成功创建成交记录

4. 其他问题订单

同时修复了订单112(物品2,1000个)的相同问题。

影响范围

1. 向后兼容性

  • 默认行为不变(include_frozen默认为false)
  • 只有明确传递include_frozen=true时才包含冻结物品
  • 不影响现有业务逻辑

2. 受益模块

  • Mex模块:撮合时可以正确消耗冻结物品
  • 其他可能需要消耗冻结物品的业务场景

文件变更

1. 核心修改

  • app/Module/GameItems/Logics/Item.php
    • 修改consumeNormalItem方法支持include_frozen参数
    • 修改consumeUniqueItem方法支持include_frozen参数

2. 测试文件

  • tests/Unit/GameItems/ItemConsumeFrozenTest.php:单元测试
  • tests/manual_test_item_consume_frozen.php:手动测试脚本

总结

通过修复物品消耗逻辑中的冻结物品处理问题,成功解决了Mex模块订单撮合失败的问题。修复后:

  1. ✅ 订单123成功撮合并完成
  2. ✅ 订单112成功撮合并完成
  3. ✅ 所有待撮合订单的失败原因已清空
  4. ✅ 保持向后兼容性
  5. ✅ 提供了完整的测试验证

这个修复不仅解决了当前问题,还为未来可能需要消耗冻结物品的业务场景提供了支持。