make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); echo "=== 物品消耗并发安全性测试 ===\n\n"; try { DB::beginTransaction(); $userId = 1001; $itemId = 1; echo "1. 准备测试数据\n"; // 添加物品 $addResult = ItemService::addItem($userId, $itemId, 100); echo " 添加物品: " . json_encode($addResult, JSON_UNESCAPED_UNICODE) . "\n"; // 检查初始状态 echo "\n2. 检查初始物品状态\n"; $userItems = DB::table('item_users') ->where('user_id', $userId) ->where('item_id', $itemId) ->get(); foreach ($userItems as $item) { $frozenStatus = $item->is_frozen ? '冻结' : '可用'; echo " 物品堆ID: {$item->id}, 数量: {$item->quantity}, 状态: {$frozenStatus}\n"; } // 测试正常消耗 echo "\n3. 测试正常消耗(锁定机制)\n"; $consumeResult1 = ItemService::consumeItem( $userId, $itemId, null, 30, [ 'include_frozen' => false, 'source_type' => 'test_consume_1', 'source_id' => 1001 ] ); echo " 消耗30个成功: " . json_encode($consumeResult1, JSON_UNESCAPED_UNICODE) . "\n"; // 检查消耗后状态 echo "\n4. 检查消耗后的物品状态\n"; $userItemsAfter = DB::table('item_users') ->where('user_id', $userId) ->where('item_id', $itemId) ->get(); foreach ($userItemsAfter as $item) { $frozenStatus = $item->is_frozen ? '冻结' : '可用'; echo " 物品堆ID: {$item->id}, 数量: {$item->quantity}, 状态: {$frozenStatus}\n"; } // 测试边界情况:消耗全部剩余数量 echo "\n5. 测试边界情况:消耗全部剩余数量\n"; $consumeResult2 = ItemService::consumeItem( $userId, $itemId, null, 70, [ 'include_frozen' => false, 'source_type' => 'test_consume_2', 'source_id' => 1002 ] ); echo " 消耗70个成功: " . json_encode($consumeResult2, JSON_UNESCAPED_UNICODE) . "\n"; // 检查完全消耗后状态 echo "\n6. 检查完全消耗后的物品状态\n"; $userItemsFinal = DB::table('item_users') ->where('user_id', $userId) ->where('item_id', $itemId) ->get(); foreach ($userItemsFinal as $item) { $frozenStatus = $item->is_frozen ? '冻结' : '可用'; echo " 物品堆ID: {$item->id}, 数量: {$item->quantity}, 状态: {$frozenStatus}\n"; } // 测试数量不足的情况 echo "\n7. 测试数量不足的情况\n"; try { $consumeResult3 = ItemService::consumeItem( $userId, $itemId, null, 10, [ 'include_frozen' => false, 'source_type' => 'test_consume_3', 'source_id' => 1003 ] ); echo " 意外成功: " . json_encode($consumeResult3, JSON_UNESCAPED_UNICODE) . "\n"; } catch (Exception $e) { echo " 预期失败: " . $e->getMessage() . "\n"; } // 测试包含冻结物品的消耗 echo "\n8. 测试包含冻结物品的消耗\n"; // 先添加更多物品并冻结一部分 $addResult2 = ItemService::addItem($userId, $itemId, 50); echo " 添加50个物品\n"; $freezeResult = ItemService::freezeItem( $userId, $itemId, null, 20, FREEZE_REASON_TYPE::TRADE_ORDER->value, [ 'source_id' => 12345, 'source_type' => 'test_order', 'operator_id' => 1 ] ); echo " 冻结20个物品\n"; // 检查冻结后状态 echo " 冻结后物品状态:\n"; $userItemsWithFrozen = DB::table('item_users') ->where('user_id', $userId) ->where('item_id', $itemId) ->where('quantity', '>', 0) ->get(); foreach ($userItemsWithFrozen as $item) { $frozenStatus = $item->is_frozen ? '冻结' : '可用'; echo " 物品堆ID: {$item->id}, 数量: {$item->quantity}, 状态: {$frozenStatus}\n"; } // 消耗包含冻结物品 echo " 消耗包含冻结物品(优先消耗冻结物品):\n"; $consumeResult4 = ItemService::consumeItem( $userId, $itemId, null, 35, [ 'include_frozen' => true, 'source_type' => 'test_consume_4', 'source_id' => 1004 ] ); echo " 消耗35个成功: " . json_encode($consumeResult4, JSON_UNESCAPED_UNICODE) . "\n"; // 检查最终状态 echo "\n9. 检查最终物品状态\n"; $userItemsEnd = DB::table('item_users') ->where('user_id', $userId) ->where('item_id', $itemId) ->get(); foreach ($userItemsEnd as $item) { $frozenStatus = $item->is_frozen ? '冻结' : '可用'; echo " 物品堆ID: {$item->id}, 数量: {$item->quantity}, 状态: {$frozenStatus}\n"; } echo "\n=== 测试完成 ===\n"; DB::rollback(); echo "已回滚测试数据\n"; } catch (Exception $e) { DB::rollback(); echo "测试失败: " . $e->getMessage() . "\n"; echo "堆栈跟踪: " . $e->getTraceAsString() . "\n"; }