任务时间: 2025年06月26日 18:02 任务类型: 功能修复 模块: GameItems, Game 状态: ✅ 已完成
用户反馈:Mex模块挂单时,物品冻结产生了拆堆,但同步物品状态只同步了一个物品堆的,应该是两个物品堆。
通过 debug:reproduce-error 命令重放请求 69010888,发现:
拆堆场景:当用户有10000个萝卜,挂单冻结100个时,会发生拆堆:
同步问题:在修复前,lastdata中只显示一个物品堆的信息,缺少另一个堆叠的状态
根本原因:ItemTemp::handleItemQuantityChanged 方法使用 item_id 作为键存储临时数据,导致同一物品的多个堆叠变更事件相互覆盖
文件: app/Module/Game/Logics/ItemTemp.php
// 修改前:使用物品ID作为键,导致同一物品的不同堆叠相互覆盖
$userItemsTemp[$event->itemId] = $itemData;
// 修改后:使用用户物品记录ID作为键,避免覆盖
$userItemsTemp[$event->userItemId] = $itemData;
文件: app/Module/Game/Logics/ItemTemp.php
getUserItemChanges() 方法返回所有物品堆的变更记录getUserItemChangeByUserItemId() 方法支持按用户物品记录ID查询getUserItemChange() 方法返回指定物品ID的所有堆叠变更确认 ItemFreeze::freezeNormalItem 方法在拆堆时正确触发两个事件:
change_type: quantity_decrease)change_type: frozen_item_create)使用 php artisan debug:reproduce-error 69010888 重放原问题请求:
修复前响应:
{
"lastData": {
"items": [
{
"itemId": "2",
"quantity": "100",
"isFrozen": true,
"iuId": "1047"
}
]
}
}
修复后响应:
{
"lastData": {
"items": [
{
"itemId": "2",
"quantity": "9600",
"iuId": "1042"
},
{
"itemId": "2",
"quantity": "100",
"isFrozen": true,
"iuId": "1055"
}
]
}
}
新增测试文件:
tests/Unit/GameItems/ItemFreezeSyncFixTest.phptests/Unit/GameItems/ItemFreezeSplitStackSyncTest.php测试覆盖场景:
所有测试通过,验证修复正确性。
当执行部分冻结时,ItemFreeze::freezeNormalItem 方法会:
判断是否拆堆:
is_frozen=true拆堆操作:
quantity = 原数量 - 冻结数量quantity = 冻结数量, is_frozen = true事件触发:
修复后的同步流程:
ItemQuantityChanged 事件ItemTemp 使用 user_item_id 作为键存储每个堆叠的变更AppGameProtobufResponseListener 获取所有变更记录lastData 包含所有变更的物品堆信息修复物品冻结拆堆时lastdata同步问题
问题描述:
- Mex模块挂单时,物品冻结产生拆堆,但只同步了一个物品堆的状态
- 原因是ItemTemp使用item_id作为键存储临时数据,导致同一物品的多个堆叠相互覆盖
修复内容:
1. 修改ItemTemp::handleItemQuantityChanged方法,使用user_item_id作为键而不是item_id
2. 调整getUserItemChanges方法返回所有物品堆的变更记录
3. 新增getUserItemChangeByUserItemId方法支持按用户物品记录ID查询
4. 添加测试用例验证拆堆场景下的双堆叠同步功能
测试验证:
- 通过debug:reproduce-error命令验证,拆堆时lastdata正确包含两个物品堆信息
- 新增单元测试覆盖拆堆和全部冻结两种场景
成功修复了物品冻结拆堆时的lastdata同步问题。通过改进临时数据存储机制,确保同一物品的多个堆叠变更都能正确同步到客户端,提升了系统的数据一致性和用户体验。