$this->testItemId, 'name' => '测试物品', 'description' => '用于测试冻结功能的物品', 'category_id' => 1, 'type' => 1, 'is_unique' => false, 'max_stack' => 100, 'sell_price' => 10, 'tradable' => true, 'dismantlable' => true, 'default_expire_seconds' => 0, ]); } /** * 测试冻结统一属性物品 */ public function testFreezeNormalItem() { Helper::begin_tr(); try { // 先给用户添加物品 ItemService::addItem($this->testUserId, $this->testItemId, 50); // 验证添加成功 $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId); $this->assertEquals(50, $availableQuantity); // 冻结部分物品 $result = ItemFreeze::freezeNormalItem( $this->testUserId, $this->testItemId, 20, FREEZE_REASON_TYPE::TRADE_ORDER, 123, 'order' ); // 验证冻结结果 $this->assertTrue($result['success']); $this->assertEquals(20, $result['frozen_quantity']); // 验证可用数量减少 $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId); $this->assertEquals(30, $availableQuantity); // 验证冻结记录 $freezeLog = ItemFreezeLog::where('user_id', $this->testUserId) ->where('item_id', $this->testItemId) ->where('action_type', FREEZE_ACTION_TYPE::FREEZE) ->first(); $this->assertNotNull($freezeLog); $this->assertEquals(20, $freezeLog->quantity); $this->assertEquals('交易订单', $freezeLog->reason); Helper::commit_tr(); } catch (\Exception $e) { Helper::rollback_tr(); throw $e; } } /** * 测试解冻物品 */ public function testUnfreezeItem() { Helper::begin_tr(); try { // 先添加物品并冻结 ItemService::addItem($this->testUserId, $this->testItemId, 50); $freezeResult = ItemFreeze::freezeNormalItem( $this->testUserId, $this->testItemId, 20, FREEZE_REASON_TYPE::TRADE_ORDER, 123, 'order' ); $freezeLogId = $freezeResult['frozen_items'][0]['freeze_log_id']; // 验证冻结状态 $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId); $this->assertEquals(30, $availableQuantity); // 解冻物品 $unfreezeResult = ItemFreeze::unfreezeByLogId($freezeLogId); // 验证解冻结果 $this->assertTrue($unfreezeResult['success']); $this->assertEquals(20, $unfreezeResult['unfrozen_quantity']); // 验证可用数量恢复 $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId); $this->assertEquals(50, $availableQuantity); // 验证解冻记录 $unfreezeLog = ItemFreezeLog::where('user_id', $this->testUserId) ->where('item_id', $this->testItemId) ->where('action_type', FREEZE_ACTION_TYPE::UNFREEZE) ->first(); $this->assertNotNull($unfreezeLog); $this->assertEquals(20, $unfreezeLog->quantity); Helper::commit_tr(); } catch (\Exception $e) { Helper::rollback_tr(); throw $e; } } /** * 测试消耗物品时排除冻结物品 */ public function testConsumeExcludesFrozenItems() { Helper::begin_tr(); try { // 添加物品 ItemService::addItem($this->testUserId, $this->testItemId, 50); // 冻结部分物品 ItemFreeze::freezeNormalItem( $this->testUserId, $this->testItemId, 20, FREEZE_REASON_TYPE::TRADE_ORDER, 123, 'order' ); // 尝试消耗物品,应该只能消耗未冻结的30个 $result = ItemService::consumeItem($this->testUserId, $this->testItemId, null, 25); // 验证消耗成功 $this->assertTrue($result['success']); $this->assertEquals(25, $result['quantity']); // 验证剩余可用数量 $availableQuantity = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId); $this->assertEquals(5, $availableQuantity); // 尝试消耗超过可用数量的物品,应该失败 $this->expectException(\Exception::class); ItemService::consumeItem($this->testUserId, $this->testItemId, null, 10); Helper::commit_tr(); } catch (\Exception $e) { Helper::rollback_tr(); throw $e; } } /** * 测试批量冻结物品 */ public function testBatchFreezeItems() { Helper::check_tr(); try { // 添加多种物品 ItemService::addItem($this->testUserId, $this->testItemId, 100); // 创建另一个测试物品 $testItemId2 = $this->testItemId + 1; Item::create([ 'id' => $testItemId2, 'name' => '测试物品2', 'description' => '用于测试批量冻结的物品', 'category_id' => 1, 'type' => 1, 'is_unique' => false, 'max_stack' => 100, 'sell_price' => 10, 'tradable' => true, 'dismantlable' => true, 'default_expire_seconds' => 0, ]); ItemService::addItem($this->testUserId, $testItemId2, 50); // 批量冻结 $items = [ ['item_id' => $this->testItemId, 'quantity' => 30], ['item_id' => $testItemId2, 'quantity' => 20], ]; $result = ItemFreeze::batchFreezeItems( $this->testUserId, $items, FREEZE_REASON_TYPE::SYSTEM_FREEZE, null, 'system' ); // 验证批量冻结结果 $this->assertTrue($result['success']); $this->assertEquals(2, $result['frozen_items_count']); // 验证各物品的可用数量 $availableQuantity1 = ItemFreeze::getAvailableQuantity($this->testUserId, $this->testItemId); $availableQuantity2 = ItemFreeze::getAvailableQuantity($this->testUserId, $testItemId2); $this->assertEquals(70, $availableQuantity1); $this->assertEquals(30, $availableQuantity2); Helper::commit_tr(); } catch (\Exception $e) { Helper::rollback_tr(); throw $e; } } /** * 测试获取冻结统计信息 */ public function testGetFreezeStatistics() { Helper::begin_tr(); try { // 添加物品并冻结 ItemService::addItem($this->testUserId, $this->testItemId, 100); ItemFreeze::freezeNormalItem( $this->testUserId, $this->testItemId, 30, FREEZE_REASON_TYPE::TRADE_ORDER, 123, 'order' ); ItemFreeze::freezeNormalItem( $this->testUserId, $this->testItemId, 20, FREEZE_REASON_TYPE::ADMIN_FREEZE, null, 'admin' ); // 获取统计信息 $statistics = ItemFreeze::getFreezeStatistics($this->testUserId); // 验证统计结果 $this->assertEquals(2, $statistics['total_frozen_items']); $this->assertEquals(50, $statistics['total_frozen_quantity']); $this->assertArrayHasKey('frozen_by_reason', $statistics); $this->assertArrayHasKey('frozen_by_source_type', $statistics); Helper::commit_tr(); } catch (\Exception $e) { Helper::rollback_tr(); throw $e; } } }