test_safe_unfreeze_rewrite.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <?php
  2. /**
  3. * 手动测试脚本:验证重写的安全解冻方法
  4. *
  5. * 测试安全解冻的两个分支:无需补足和需要补足
  6. */
  7. require_once __DIR__ . '/../vendor/autoload.php';
  8. use App\Module\GameItems\Services\ItemService;
  9. use App\Module\GameItems\Enums\FREEZE_REASON_TYPE;
  10. use Illuminate\Support\Facades\DB;
  11. // 启动Laravel应用
  12. $app = require_once __DIR__ . '/../bootstrap/app.php';
  13. $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
  14. echo "=== 安全解冻方法重写验证测试 ===\n\n";
  15. try {
  16. DB::beginTransaction();
  17. $userId = 1001;
  18. $itemId = 1;
  19. echo "1. 准备测试数据\n";
  20. // 添加物品
  21. $addResult = ItemService::addItem($userId, $itemId, 150);
  22. echo " 添加150个物品成功\n";
  23. // 冻结第一批物品(用于测试无需补足)
  24. $freezeResult1 = ItemService::freezeItem(
  25. $userId,
  26. $itemId,
  27. null,
  28. 30,
  29. FREEZE_REASON_TYPE::TRADE_ORDER->value,
  30. [
  31. 'source_id' => 12345,
  32. 'source_type' => 'test_order_1',
  33. 'operator_id' => 1
  34. ]
  35. );
  36. $freezeLogId1 = $freezeResult1['frozen_items'][0]['freeze_log_id'];
  37. echo " 冻结30个物品成功,日志ID: {$freezeLogId1}\n";
  38. // 冻结第二批物品(用于测试需要补足)
  39. $freezeResult2 = ItemService::freezeItem(
  40. $userId,
  41. $itemId,
  42. null,
  43. 50,
  44. FREEZE_REASON_TYPE::TRADE_ORDER->value,
  45. [
  46. 'source_id' => 12346,
  47. 'source_type' => 'test_order_2',
  48. 'operator_id' => 1
  49. ]
  50. );
  51. $freezeLogId2 = $freezeResult2['frozen_items'][0]['freeze_log_id'];
  52. echo " 冻结50个物品成功,日志ID: {$freezeLogId2}\n";
  53. // 冻结第三批物品(用于作为补足来源)
  54. $freezeResult3 = ItemService::freezeItem(
  55. $userId,
  56. $itemId,
  57. null,
  58. 40,
  59. FREEZE_REASON_TYPE::TRADE_ORDER->value,
  60. [
  61. 'source_id' => 12347,
  62. 'source_type' => 'test_order_3',
  63. 'operator_id' => 1
  64. ]
  65. );
  66. $freezeLogId3 = $freezeResult3['frozen_items'][0]['freeze_log_id'];
  67. echo " 冻结40个物品成功,日志ID: {$freezeLogId3}\n";
  68. // 检查当前状态
  69. echo "\n2. 检查冻结后的物品状态\n";
  70. $userItems = DB::table('item_users')
  71. ->where('user_id', $userId)
  72. ->where('item_id', $itemId)
  73. ->get();
  74. foreach ($userItems as $item) {
  75. $frozenStatus = $item->is_frozen ? '冻结' : '可用';
  76. $freezeLogId = $item->frozen_log_id ?? 'N/A';
  77. echo " 物品堆ID: {$item->id}, 数量: {$item->quantity}, 状态: {$frozenStatus}, 冻结日志: {$freezeLogId}\n";
  78. }
  79. echo "\n3. 测试分支A:无需补足的安全解冻\n";
  80. // 第一个冻结堆没有被消耗,直接解冻
  81. try {
  82. $safeUnfreezeResult1 = ItemService::safeUnfreezeItem($freezeLogId1);
  83. echo " 安全解冻成功: " . json_encode($safeUnfreezeResult1, JSON_UNESCAPED_UNICODE) . "\n";
  84. echo " 补足差额: " . ($safeUnfreezeResult1['shortage_compensated'] ?? 0) . "\n";
  85. if ($safeUnfreezeResult1['shortage_compensated'] == 0) {
  86. echo " ✅ 分支A测试通过:无需补足\n";
  87. } else {
  88. echo " ❌ 分支A测试失败:不应该有补足\n";
  89. }
  90. } catch (Exception $e) {
  91. echo " ❌ 分支A测试失败: " . $e->getMessage() . "\n";
  92. }
  93. echo "\n4. 测试分支B:需要补足的安全解冻\n";
  94. // 部分消耗第二个冻结堆
  95. $consumeResult = ItemService::consumeItem(
  96. $userId,
  97. $itemId,
  98. null,
  99. 30,
  100. [
  101. 'include_frozen' => true,
  102. 'source_type' => 'test_consume',
  103. 'source_id' => 67890
  104. ]
  105. );
  106. echo " 消耗30个冻结物品成功\n";
  107. // 检查消耗后状态
  108. echo " 消耗后物品状态:\n";
  109. $userItemsAfter = DB::table('item_users')
  110. ->where('user_id', $userId)
  111. ->where('item_id', $itemId)
  112. ->get();
  113. foreach ($userItemsAfter as $item) {
  114. $frozenStatus = $item->is_frozen ? '冻结' : '可用';
  115. $freezeLogId = $item->frozen_log_id ?? 'N/A';
  116. echo " 物品堆ID: {$item->id}, 数量: {$item->quantity}, 状态: {$frozenStatus}, 冻结日志: {$freezeLogId}\n";
  117. }
  118. // 现在第二个冻结堆应该只有20个(50-30),需要从第三个冻结堆补足30个
  119. try {
  120. $safeUnfreezeResult2 = ItemService::safeUnfreezeItem($freezeLogId2);
  121. echo " 安全解冻成功: " . json_encode($safeUnfreezeResult2, JSON_UNESCAPED_UNICODE) . "\n";
  122. echo " 补足差额: " . ($safeUnfreezeResult2['shortage_compensated'] ?? 0) . "\n";
  123. if ($safeUnfreezeResult2['shortage_compensated'] == 30) {
  124. echo " ✅ 分支B测试通过:正确补足30个\n";
  125. } else {
  126. echo " ❌ 分支B测试失败:应该补足30个,实际补足 " . ($safeUnfreezeResult2['shortage_compensated'] ?? 0) . "\n";
  127. }
  128. if ($safeUnfreezeResult2['unfrozen_quantity'] == 50) {
  129. echo " ✅ 解冻数量正确:50个\n";
  130. } else {
  131. echo " ❌ 解冻数量错误:应该50个,实际 " . ($safeUnfreezeResult2['unfrozen_quantity'] ?? 0) . "\n";
  132. }
  133. } catch (Exception $e) {
  134. echo " ❌ 分支B测试失败: " . $e->getMessage() . "\n";
  135. }
  136. echo "\n5. 检查最终物品状态\n";
  137. $userItemsFinal = DB::table('item_users')
  138. ->where('user_id', $userId)
  139. ->where('item_id', $itemId)
  140. ->get();
  141. $totalAvailable = 0;
  142. $totalFrozen = 0;
  143. foreach ($userItemsFinal as $item) {
  144. $frozenStatus = $item->is_frozen ? '冻结' : '可用';
  145. $freezeLogId = $item->frozen_log_id ?? 'N/A';
  146. echo " 物品堆ID: {$item->id}, 数量: {$item->quantity}, 状态: {$frozenStatus}, 冻结日志: {$freezeLogId}\n";
  147. if ($item->is_frozen) {
  148. $totalFrozen += $item->quantity;
  149. } else {
  150. $totalAvailable += $item->quantity;
  151. }
  152. }
  153. echo " 总计:可用 {$totalAvailable},冻结 {$totalFrozen}\n";
  154. // 验证数量守恒
  155. $totalQuantity = $totalAvailable + $totalFrozen;
  156. if ($totalQuantity == 120) { // 150 - 30(消耗) = 120
  157. echo " ✅ 数量守恒正确:总数量120(150-30消耗)\n";
  158. } else {
  159. echo " ❌ 数量守恒错误:总数量应该120,实际 {$totalQuantity}\n";
  160. }
  161. echo "\n6. 测试完全消耗的情况\n";
  162. // 完全消耗第三个冻结堆
  163. $consumeResult2 = ItemService::consumeItem(
  164. $userId,
  165. $itemId,
  166. null,
  167. 10, // 第三个冻结堆现在应该只有10个(40-30补足)
  168. [
  169. 'include_frozen' => true,
  170. 'source_type' => 'test_consume_all',
  171. 'source_id' => 67891
  172. ]
  173. );
  174. echo " 完全消耗第三个冻结堆成功\n";
  175. // 尝试解冻第三个冻结堆(应该失败,因为没有其他冻结堆可以补足)
  176. try {
  177. $safeUnfreezeResult3 = ItemService::safeUnfreezeItem($freezeLogId3);
  178. echo " ❌ 意外成功: " . json_encode($safeUnfreezeResult3, JSON_UNESCAPED_UNICODE) . "\n";
  179. } catch (Exception $e) {
  180. echo " ✅ 预期失败: " . $e->getMessage() . "\n";
  181. }
  182. echo "\n=== 测试完成 ===\n";
  183. echo "安全解冻方法重写验证完成,两个分支逻辑正确\n";
  184. DB::rollback();
  185. echo "已回滚测试数据\n";
  186. } catch (Exception $e) {
  187. DB::rollback();
  188. echo "测试失败: " . $e->getMessage() . "\n";
  189. echo "堆栈跟踪: " . $e->getTraceAsString() . "\n";
  190. }