121239-GameItems模块物品冻结功能开发.md 8.4 KB

GameItems模块物品冻结功能开发

任务时间: 2025年06月12日 12:39
任务类型: 功能开发
模块: GameItems
状态: ✅ 已完成

任务概述

为GameItems模块实现完整的物品冻结功能,支持统一属性物品和单独属性物品的冻结/解冻操作,采用拆堆模式确保数据一致性,满足匹配交易系统的需求。

实现内容

1. 核心数据结构

1.1 新增枚举类型

  • FREEZE_ACTION_TYPE: 冻结操作类型枚举(冻结/解冻)
  • FREEZE_REASON_TYPE: 冻结原因类型枚举(交易订单、管理员冻结、系统冻结、拍卖、邮件附件、任务冻结、合成冻结)

1.2 新增数据模型

  • ItemFreezeLog: 冻结记录模型,记录所有冻结/解冻操作的详细信息
  • ItemUser: 扩展了冻结相关字段(is_frozen、frozen_log_id)和相关方法

1.3 数据库表结构变更

  • kku_item_freeze_logs: 新建冻结记录表,包含完整的操作审计信息
  • kku_item_users: 添加冻结状态字段和相关索引,优化查询性能

2. 核心业务逻辑

2.1 ItemFreeze逻辑类

实现了完整的冻结业务逻辑:

  • freezeNormalItem(): 统一属性物品冻结(拆堆模式)
  • freezeUniqueItem(): 单独属性物品冻结
  • unfreezeByLogId(): 通过冻结日志ID精确解冻
  • getAvailableQuantity(): 获取可用数量(排除冻结)
  • batchFreezeItems(): 批量冻结操作
  • getFrozenItems(): 获取冻结物品列表
  • getFreezeStatistics(): 获取冻结统计信息
  • handleExpiredFrozenItems(): 处理过期冻结物品

2.2 ItemService服务类扩展

为外部模块提供统一的服务接口:

  • freezeItem(): 冻结物品服务接口
  • unfreezeItem(): 解冻物品服务接口
  • getAvailableQuantity(): 获取可用数量服务接口
  • getFrozenItems(): 获取冻结物品服务接口
  • batchFreezeItems(): 批量冻结服务接口
  • getFreezeStatistics(): 获取冻结统计服务接口

3. 现有逻辑集成改进

3.1 物品消耗逻辑修改

  • 修改consumeNormalItem()方法,确保只消耗未冻结的物品
  • 修改consumeUniqueItem()方法,增加冻结状态验证
  • 优化查询条件,提高消耗操作的准确性

3.2 物品添加逻辑修改

  • 修改addNormalItem()方法,确保查找可堆叠物品时排除冻结的物品
  • 保证新添加的物品不会与冻结物品混合

4. 核心特性

4.1 拆堆模式冻结

  • 冻结时将原堆叠拆分为冻结部分和可用部分
  • 例如:1000个物品冻结200个 → 200个(冻结)+ 800个(可用)
  • 确保冻结操作的精确性和可追溯性

4.2 独立解冻机制

  • 解冻后不自动合并堆叠,保持独立状态
  • 通过frozen_log_id精确定位需要解冻的物品
  • 支持部分解冻和批量解冻操作

4.3 完整的日志追踪

  • 记录所有冻结/解冻操作的详细信息
  • 支持按原因、来源类型、操作员等维度查询
  • 提供完整的操作审计轨迹

4.4 多业务场景支持

  • 交易订单: 卖出订单时自动冻结物品
  • 管理员操作: 支持管理员手动冻结/解冻
  • 系统冻结: 支持系统自动冻结(如异常检测)
  • 拍卖系统: 支持拍卖物品冻结
  • 任务系统: 支持任务物品冻结
  • 合成系统: 支持合成材料冻结

技术实现细节

1. 数据库设计

1.1 冻结记录表

CREATE TABLE `kku_item_freeze_logs` (
  `id` int NOT NULL AUTO_INCREMENT,
  `user_id` int NOT NULL,
  `item_id` int NOT NULL,
  `instance_id` int DEFAULT NULL,
  `quantity` int NOT NULL,
  `action_type` tinyint NOT NULL,
  `reason` varchar(255) NOT NULL,
  `source_id` int DEFAULT NULL,
  `source_type` varchar(50) DEFAULT NULL,
  `operator_id` int DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  -- 索引优化查询性能
);

1.2 用户物品表扩展

ALTER TABLE `kku_item_users`
ADD COLUMN `is_frozen` tinyint(1) NOT NULL DEFAULT 0,
ADD COLUMN `frozen_log_id` int DEFAULT NULL,
-- 添加相关索引

2. 性能优化

2.1 索引设计

  • 复合索引:(user_id, is_frozen) 优化可用数量查询
  • 复合索引:(user_id, item_id, is_frozen) 优化物品状态查询
  • 单独索引:frozen_log_id 优化解冻操作

2.2 查询优化

  • 使用聚合函数计算可用数量,避免大量数据传输
  • 合理使用事务确保数据一致性
  • 批量操作减少数据库交互次数

3. 安全性考虑

3.1 数据一致性

  • 所有冻结/解冻操作都在事务中执行
  • 冻结前验证可用数量是否足够
  • 解冻时验证冻结记录的有效性

3.2 操作审计

  • 记录操作员信息和操作来源
  • 完整的操作时间戳
  • 支持操作回溯和问题排查

使用示例

1. 基础冻结操作

// 冻结统一属性物品
$result = ItemService::freezeItem(
    $userId,
    $itemId,
    null,
    20,
    '交易订单冻结',
    [
        'reason_type' => FREEZE_REASON_TYPE::TRADE_ORDER->value,
        'source_id' => $orderId,
        'source_type' => 'order'
    ]
);

// 解冻物品
$result = ItemService::unfreezeItem($freezeLogId);

2. 批量操作

// 批量冻结多种物品
$items = [
    ['item_id' => 1001, 'quantity' => 10],
    ['item_id' => 1002, 'quantity' => 5],
];

$result = ItemService::batchFreezeItems(
    $userId,
    $items,
    '系统批量冻结',
    ['reason_type' => FREEZE_REASON_TYPE::SYSTEM_FREEZE->value]
);

3. 查询操作

// 获取可用数量
$availableQuantity = ItemService::getAvailableQuantity($userId, $itemId);

// 获取冻结统计
$statistics = ItemService::getFreezeStatistics($userId);

测试验证

1. 单元测试

创建了完整的测试用例覆盖:

  • 统一属性物品冻结/解冻
  • 单独属性物品冻结/解冻
  • 消耗物品时排除冻结物品
  • 批量冻结操作
  • 冻结统计信息查询

2. 手动测试脚本

提供了手动测试脚本用于功能验证:

  • 完整的功能流程测试
  • 异常情况处理验证
  • 数据一致性检查

文件变更清单

新增文件

  1. app/Module/GameItems/Enums/FREEZE_ACTION_TYPE.php - 冻结操作类型枚举
  2. app/Module/GameItems/Enums/FREEZE_REASON_TYPE.php - 冻结原因类型枚举
  3. app/Module/GameItems/Models/ItemFreezeLog.php - 冻结记录模型
  4. app/Module/GameItems/Logics/ItemFreeze.php - 冻结逻辑类
  5. app/Module/GameItems/Tests/ItemFreezeTest.php - 单元测试
  6. app/Module/GameItems/Tests/freeze_test_manual.php - 手动测试脚本
  7. app/Module/GameItems/Databases/GenerateSql/item_freeze_logs.sql - 冻结记录表SQL
  8. app/Module/GameItems/Databases/GenerateSql/alter_item_users_add_freeze_fields.sql - 用户物品表修改SQL
  9. app/Module/GameItems/Docs/冻结功能实现完成.md - 功能实现文档

修改文件

  1. app/Module/GameItems/Models/ItemUser.php - 添加冻结相关字段和方法
  2. app/Module/GameItems/Services/ItemService.php - 扩展冻结相关服务方法
  3. app/Module/GameItems/Logics/Item.php - 修改消耗和添加逻辑排除冻结物品

后续扩展建议

1. 功能扩展

  • 自动解冻机制:根据业务需求添加定时解冻
  • 冻结过期:为冻结操作添加过期时间
  • 冻结通知:添加冻结/解冻的事件通知机制

2. 管理界面

  • 后台管理系统中添加冻结管理界面
  • 支持管理员查看和操作用户冻结物品
  • 提供冻结统计报表和分析功能

3. 性能优化

  • 大数据量下的查询优化
  • 缓存机制优化频繁查询
  • 分库分表支持海量数据

总结

本次任务成功实现了GameItems模块的完整物品冻结功能,包括:

核心功能完整: 支持统一属性和单独属性物品的冻结/解冻
数据一致性: 采用拆堆模式和事务保护确保数据准确性
性能优化: 合理的索引设计和查询优化
扩展性强: 支持多种业务场景和批量操作
可维护性: 完整的日志记录和测试覆盖
文档完善: 详细的实现文档和使用示例

该功能为匹配交易系统提供了可靠的物品冻结支持,同时为其他业务模块提供了通用的物品冻结能力。代码已提交并推送到远程仓库,可以投入使用。


提交信息: 实现GameItems模块物品冻结功能
提交哈希: 38e94454
分支: master