Bläddra i källkod

清理和更新文档:删除旧文档文件,更新README,添加Docs目录

Your Name 8 månader sedan
förälder
incheckning
164fa111f3

+ 0 - 0
app/Module/GameItems/GUILD.md → app/Module/GameItems/Docs/GUILD.md


+ 0 - 0
app/Module/GameItems/README.cline-gemini25.md → app/Module/GameItems/Docs/README.cline-gemini25.md


+ 2845 - 0
app/Module/GameItems/Docs/README.md

@@ -0,0 +1,2845 @@
+# GameItems模块
+
+> 游戏物品系统 - 综合管理游戏内所有物品的生命周期
+
+## 目录
+
+1. [模块概述](#1-模块概述)
+2. [数据结构设计](#2-数据结构设计)
+3. [核心功能](#3-核心功能)
+4. [物品过期机制](#4-物品过期机制)
+5. [宝箱系统](#5-宝箱系统)
+6. [物品获取与堆叠](#6-物品获取与堆叠)
+7. [物品产出限制](#7-物品产出限制)
+8. [日志记录系统](#8-日志记录系统)
+9. [物品合成系统](#9-物品合成系统)
+10. [物品分解系统](#10-物品分解系统)
+11. [物品绑定机制](#11-物品绑定机制)
+12. [系统交互](#12-系统交互)
+13. [最佳实践与注意事项](#13-最佳实践与注意事项)
+
+## 1. 模块概述
+
+### 1.1 功能与目的
+
+GameItems模块是游戏核心系统之一,负责管理游戏内所有物品的完整生命周期,包括创建、获取、使用、交易、过期和销毁。该模块为游戏内经济系统和玩家进度提供基础支持,是连接多个游戏子系统的核心组件。
+
+### 1.2 主要功能
+
+- **物品基础属性管理**:名称、描述、图标、类型等
+- **物品获取与消耗逻辑**:添加物品到用户背包、消耗物品
+- **物品库存管理**:堆叠、数量限制、过期处理
+- **物品交易系统**:玩家间交易、商店交易
+- **特殊物品效果**:使用效果、装备效果
+- **宝箱系统**:宝箱配置、开启机制、保底机制
+- **物品过期管理**:全局过期和用户特定过期
+- **物品合成系统**:配方、材料、成功率
+- **物品分解系统**:分解规则、结果计算
+- **物品绑定机制**:绑定类型、交易限制
+
+### 1.3 核心特点
+
+1. **多物品宝箱系统**:支持一个宝箱同时掉落多个物品,可配置数量范围和概率
+2. **灵活的过期机制**:支持全局过期时间和用户特定过期时间
+3. **完善的属性系统**:通过JSON格式存储物品属性,支持复杂物品效果
+4. **单独属性物品**:支持每个物品实例拥有独特属性(如装备)
+5. **物品绑定机制**:限制物品流通,保持游戏经济平衡
+6. **物品产出限制**:控制稀有物品的产出数量和频率
+7. **全面的日志系统**:记录所有物品相关操作,支持数据分析和问题排查
+
+## 2. 数据结构设计
+
+### 2.1 设计原则
+
+游戏物品模块采用关系型数据库设计,通过多个相互关联的数据表实现物品管理。数据结构设计遵循以下原则:
+
+1. **模块化**:各个表结构清晰,职责单一
+2. **扩展性**:支持通过属性表扩展物品特性,无需修改数据库结构
+3. **性能优化**:合理的索引设计和关联关系
+4. **数据完整性**:使用外键和事务确保数据一致性
+
+### 2.2 核心数据表
+
+#### 2.2.1 物品基础表
+
+| 表名 | 主要功能 | 关键字段 |
+|------|---------|---------|
+| item_categories | 物品分类管理 | id, name, code, parent_id |
+| item_items | 统一属性物品定义 | id, name, type, is_unique, attributes |
+| item_instances | 单独属性物品实例 | id, item_id, attributes, is_bound |
+| item_users | 用户物品关联 | user_id, item_id, instance_id, quantity |
+| item_groups | 物品组定义 | id, name, code |
+| item_group_items | 物品组内容 | group_id, item_id, weight |
+
+#### 2.2.2 宝箱系统表
+
+| 表名 | 主要功能 | 关键字段 |
+|------|---------|---------|
+| item_chest_contents | 宝箱内容配置 | chest_id, item_id/group_id, weight |
+| item_pity_times | 用户宝箱保底计数 | user_id, chest_id, chest_content_id, current_count |
+| item_chest_open_logs | 宝箱开启记录 | user_id, chest_id, result_items, pity_triggered |
+
+#### 2.2.3 物品限制与日志表
+
+| 表名 | 主要功能 | 关键字段 |
+|------|---------|---------|
+| item_output_limits | 物品产出限制 | item_id, limit_type, max_quantity |
+| item_user_output_counters | 用户产出限制计数 | user_id, limit_id, current_count |
+| item_transaction_logs | 物品交易记录 | user_id, item_id, quantity, transaction_type |
+
+#### 2.2.4 物品合成与分解表
+
+| 表名 | 主要功能 | 关键字段 |
+|------|---------|---------|
+| item_recipes | 合成配方定义 | id, result_item_id, success_rate |
+| item_recipe_materials | 配方材料需求 | recipe_id, item_id, quantity |
+| item_user_recipes | 用户配方解锁状态 | user_id, recipe_id, is_unlocked |
+| item_craft_logs | 物品合成记录 | user_id, recipe_id, is_success |
+| item_dismantle_rules | 物品分解规则 | item_id/category_id, priority |
+| item_dismantle_results | 分解结果配置 | rule_id, result_item_id, chance |
+| item_dismantle_logs | 物品分解记录 | user_id, item_id, results |
+
+### 2.3 详细表结构
+
+#### 2.3.1 item_categories 表(物品分类)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 分类ID,主键 |
+| name | varchar | 分类名称 |
+| code | varchar | 分类编码(唯一) |
+| icon | varchar | 分类图标 |
+| sort | int | 排序权重 |
+| parent_id | int | 父分类ID(可为空,用于实现分类层级) |
+| created_at | timestamp | 创建时间 |
+| updated_at | timestamp | 更新时间 |
+
+#### 2.3.2 item_items 表(统一属性物品)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 物品ID,主键 |
+| name | varchar | 物品名称 |
+| description | text | 物品描述 |
+| category_id | int | 物品分类ID,外键关联item_categories表 |
+| type | tinyint | 物品类型(1:可使用, 2:可装备, 3:可合成, 4:可交任务, 5:可开启...) |
+| is_unique | tinyint | 是否是单独属性物品(0:否,默认, 1:是) |
+| icon | varchar | 物品图标路径 |
+| max_stack | int | 最大堆叠数量 |
+| sell_price | int | 出售价格 |
+| tradable | tinyint | 是否可交易(0:不可交易, 1:可交易,默认) |
+| dismantlable | tinyint | 是否可分解(0:不可分解, 1:可分解,默认) |
+| default_expire_seconds | int | 玩家获取物品后的默认有效秒数(0表示永久有效) |
+| display_attributes | json | 展示属性,以JSON格式存储键值对,用于界面展示和描述的属性 |
+| numeric_attributes | json | 数值属性,以JSON格式存储键值对,用于计算和游戏逻辑的属性 |
+| global_expire_at | timestamp | 物品全局过期时间(可为空) |
+| created_at | timestamp | 创建时间 |
+| updated_at | timestamp | 更新时间 |
+
+#### 2.3.3 item_instances 表(单独属性物品)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 唯一物品ID,主键 |
+| item_id | int | 关联的基础物品ID,外键关联item_items表 |
+| name | varchar | 物品名称(可以与基础物品不同,如"锐利的钢刀") |
+| display_attributes | json | 展示属性,以JSON格式存储键值对,用于界面展示和描述的属性 |
+| numeric_attributes | json | 数值属性,以JSON格式存储键值对,用于计算和游戏逻辑的属性 |
+| tradable | tinyint | 是否可交易(0:不可交易, 1:可交易,默认) |
+| is_bound | tinyint | 是否已绑定(0:未绑定, 1:已绑定) |
+| bound_to | varchar | 绑定对象(账号ID或角色ID) |
+| bind_exp_time | timestamp | 绑定过期时间(为空表示永久绑定) |
+| expire_at | timestamp | 物品过期时间(可为空) |
+| created_at | timestamp | 创建时间 |
+| updated_at | timestamp | 更新时间 |
+
+#### 2.3.4 item_users 表(用户物品关联)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 记录ID,主键 |
+| user_id | int | 用户ID,外键 |
+| item_id | int | 统一属性物品ID,外键关联item_items表(始终有值) |
+| instance_id | int | 单独属性物品ID,外键关联item_instances表(可为空) |
+| quantity | int | 数量(对于单独属性物品,该值始终为1) |
+| expire_at | timestamp | 用户物品过期时间(可为空) |
+| created_at | timestamp | 获取时间 |
+| updated_at | timestamp | 更新时间 |
+
+### 2.4 数据库索引设计
+
+为确保系统高性能运行,对关键字段进行了索引设计:
+
+#### 2.4.1 物品基础表索引
+
+| 表名 | 索引字段 | 索引类型 | 说明 |
+| --- | --- | --- | --- |
+| item_items | id | 主键 | 物品ID主键索引 |
+| item_items | category_id | 普通索引 | 加速按物品分类查询 |
+| item_items | type | 普通索引 | 加速按物品类型查询 |
+| item_items | is_unique | 普通索引 | 加速查询单独属性物品 |
+| item_items | tradable | 普通索引 | 加速查询可交易/不可交易物品 |
+| item_items | dismantlable | 普通索引 | 加速查询可分解/不可分解物品 |
+| item_items | global_expire_at | 普通索引 | 加速过期物品查询 |
+| item_categories | id | 主键 | 分类ID主键索引 |
+| item_categories | parent_id | 普通索引 | 加速查询子分类 |
+| item_categories | code | 唯一索引 | 确保分类编码唯一性 |
+| item_instances | id | 主键 | 唯一物品ID主键索引 |
+| item_instances | item_id | 普通索引 | 加速根据基础物品查询唯一物品 |
+| item_instances | tradable | 普通索引 | 加速查询可交易/不可交易的单独属性物品 |
+| item_instances | is_bound | 普通索引 | 加速查询已绑定的单独属性物品 |
+| item_instances | bound_to | 普通索引 | 加速查询绑定到特定对象的单独属性物品 |
+| item_instances | bind_exp_time | 普通索引 | 加速查询需要解绑的单独属性物品 |
+| item_instances | expire_at | 普通索引 | 加速过期物品查询 |
+| item_users | user_id, item_id | 复合索引 | 加速用户统一属性物品查询 |
+| item_users | user_id, instance_id | 复合索引 | 加速用户单独属性物品查询 |
+| item_users | expire_at | 普通索引 | 加速过期物品查询 |
+
+#### 2.4.2 宝箱系统表索引
+
+| 表名 | 索引字段 | 索引类型 | 说明 |
+| --- | --- | --- | --- |
+| item_chest_contents | chest_id | 普通索引 | 加速宝箱内容查询 |
+| item_chest_contents | item_id | 普通索引 | 加速物品在宝箱中的查询 |
+| item_chest_contents | group_id | 普通索引 | 加速查询物品组在宝箱中的配置 |
+| item_chest_contents | pity_count | 普通索引 | 加速查询启用保底的宝箱内容 |
+| item_pity_times | user_id, chest_id, chest_content_id | 复合索引 | 加速查询用户对特定宝箱内容的保底计数 |
+| item_chest_open_logs | user_id, open_time | 复合索引 | 加速查询用户的宝箱开启历史 |
+| item_chest_open_logs | chest_id | 普通索引 | 加速查询特定宝箱的开启记录 |
+
+### 2.5 数据模型关联关系
+
+以下是主要数据模型之间的关联关系:
+
+1. **用户与物品关系**
+   - 用户可以拥有统一属性物品和单独属性物品,通过 item_users 表关联
+   - 对于统一属性物品,直接关联 item_items 表
+   - 对于单独属性物品,通过 item_instances 表间接关联 item_items 表
+
+2. **物品分类层级**
+   - item_categories 表通过 parent_id 字段实现自关联,形成分类层级结构
+   - item_items 表通过 category_id 字段关联到 item_categories 表
+
+3. **物品组与物品**
+   - item_groups 表定义物品组
+   - item_group_items 表建立物品组与物品的多对多关系
+
+4. **宝箱与内容关系**
+   - 宝箱是 item_items 表中 type=5 的特殊物品
+   - item_chest_contents 表定义宝箱可能掉落的内容
+   - 宝箱内容可以是具体物品(item_id)或物品组(group_id)
+
+5. **物品合成关系**
+   - item_recipes 表定义合成配方
+   - item_recipe_materials 表定义配方所需材料
+   - 用户通过 item_user_recipes 表记录已解锁的配方
+
+6. **物品分解关系**
+   - item_dismantle_rules 表定义分解规则
+   - item_dismantle_results 表定义分解可能的结果
+   - 分解规则可以针对特定物品或整个分类
+
+### 2.6 单独属性物品实现
+
+为支持"每个用户拥有的同类物品可以有不同属性"的需求(如不同的武器有不同的属性),系统采用了统一属性物品和单独属性物品两种设计:
+
+#### 2.6.1 实现方式
+
+1. **物品类型区分**
+   - item_items 表中的 is_unique 字段标记该物品是否为单独属性物品
+   - 单独属性物品(如装备)在 item_instances 表中创建独立记录
+   - 统一属性物品(如消耗品)直接使用 item_items 表的属性
+
+2. **属性存储方式**
+   - 基础属性存储在 item_items 表中
+   - 单独属性物品的特殊属性存储在 item_instances 表中
+   - 属性使用 JSON 格式存储,分为展示属性和数值属性
+
+3. **用户物品关联**
+   - item_users 表通过 item_id 和 instance_id 字段关联两种物品
+   - 对于统一属性物品,instance_id 为空,quantity 可以大于1
+   - 对于单独属性物品,instance_id 有值,quantity 始终为1
+
+## 3. 核心功能
+
+### 3.1 物品管理接口
+
+系统提供以下核心接口用于物品管理:
+
+#### 3.1.1 获取用户物品
+
+- **功能**:获取用户拥有的所有物品或特定类型的物品
+- **参数**:用户ID,物品类型(可选),分页参数
+- **返回**:物品列表,包含数量、属性等信息
+- **处理逻辑**:
+  1. 查询用户在 item_users 表中的记录
+  2. 关联 item_items 表获取物品基础信息
+  3. 对于单独属性物品,关联 item_instances 表获取特殊属性
+  4. 过滤掉已过期的物品(检查全局过期和用户物品过期)
+  5. 按类型、分类等条件筛选
+
+#### 3.1.2 添加物品到用户背包
+
+- **功能**:向用户背包添加指定物品
+- **参数**:用户ID、物品ID、数量、过期时间(可选)、属性参数(可选)
+- **返回**:添加结果、当前数量
+- **处理逻辑**:
+  1. 检查物品是否存在
+  2. 检查物品是否有全局过期时间
+  3. 对于统一属性物品:
+     - 检查用户是否已有该物品且过期时间相同
+     - 如果已有,增加数量(注意最大堆叠限制)
+     - 如果没有,创建新记录
+  4. 对于单独属性物品:
+     - 创建 item_instances 记录
+     - 关联到用户
+  5. 记录物品获取日志
+
+#### 3.1.3 使用物品
+
+- **功能**:消耗指定数量的物品并触发效果
+- **参数**:用户ID、物品ID/实例ID、数量、使用参数
+- **返回**:使用结果、剩余数量、触发效果
+- **处理逻辑**:
+  1. 检查用户是否拥有足够数量的物品
+  2. 检查物品是否已过期
+  3. 根据物品类型执行不同的使用逻辑
+  4. 扣除物品数量
+  5. 记录物品消耗日志
+  6. 返回使用效果
+
+#### 3.1.4 删除用户物品
+
+- **功能**:从用户背包中删除指定物品
+- **参数**:用户ID、物品ID/实例ID、数量、删除原因
+- **返回**:删除结果、剩余数量
+- **处理逻辑**:
+  1. 检查用户是否拥有足够数量的物品
+  2. 扣除物品数量
+  3. 如果数量为0,删除记录
+  4. 对于单独属性物品,可选择是否删除 item_instances 记录
+  5. 记录物品删除日志
+
+### 3.2 物品交易接口
+
+系统支持玩家间物品交易和与NPC的交易:
+
+#### 3.2.1 玩家间交易
+
+- **功能**:将物品从一个玩家转移到另一个玩家
+- **参数**:发送方ID、接收方ID、物品ID/实例ID、数量
+- **返回**:交易结果
+- **处理逻辑**:
+  1. 检查物品是否可交易(tradable=1)
+  2. 检查物品是否已绑定(is_bound=0)
+  3. 检查发送方是否拥有足够数量的物品
+  4. 从发送方扣除物品
+  5. 向接收方添加物品
+  6. 记录交易日志
+
+#### 3.2.2 商店购买
+
+- **功能**:玩家使用游戏货币购买物品
+- **参数**:用户ID、物品ID、数量
+- **返回**:购买结果、剩余货币
+- **处理逻辑**:
+  1. 检查物品价格和玩家货币是否足够
+  2. 扣除玩家货币
+  3. 添加物品到玩家背包
+  4. 记录购买日志
+
+#### 3.2.3 商店出售
+
+- **功能**:玩家将物品出售给商店获得货币
+- **参数**:用户ID、物品ID/实例ID、数量
+- **返回**:出售结果、获得货币
+- **处理逻辑**:
+  1. 检查玩家是否拥有足够数量的物品
+  2. 计算出售价格(可能受物品品质、耐久度等影响)
+  3. 从玩家背包中扣除物品
+  4. 增加玩家货币
+  5. 记录出售日志
+
+### 3.3 单独属性物品接口
+
+系统提供以下接口用于管理单独属性物品:
+
+#### 3.3.1 创建单独属性物品
+
+- **功能**:为用户创建具有独特属性的物品
+- **参数**:用户ID、基础物品ID、属性参数
+- **返回**:创建的单独属性物品信息
+- **处理逻辑**:
+  1. 检查基础物品是否存在且 is_unique=1
+  2. 生成物品属性(可能包含随机因素)
+  3. 创建 item_instances 记录
+  4. 关联到用户
+  5. 记录物品创建日志
+
+#### 3.3.2 修改单独属性物品
+
+- **功能**:修改单独属性物品的属性(如强化、附魔)
+- **参数**:用户ID、实例ID、属性变更
+- **返回**:修改后的物品信息
+- **处理逻辑**:
+  1. 检查用户是否拥有该物品
+  2. 验证属性变更的合法性
+  3. 更新 item_instances 记录
+  4. 记录物品修改日志
+
+#### 3.3.3 获取单独属性物品详情
+
+- **功能**:获取单独属性物品的详细信息
+- **参数**:实例ID
+- **返回**:物品详细信息,包括基础属性和特殊属性
+- **处理逻辑**:
+  1. 查询 item_instances 表获取物品实例
+  2. 关联 item_items 表获取基础信息
+  3. 合并基础属性和特殊属性
+  4. 返回完整的物品信息
+
+## 4. 物品过期机制
+
+物品模块支持两种过期时间机制,用于实现物品的时效性管理。
+
+### 4.1 全局过期时间
+
+全局过期时间定义在 `item_items` 表的 `global_expire_at` 字段中,表示该物品在所有用户中的绝对过期时间。当超过这个时间点后,所有用户的该物品均失效。
+
+#### 4.1.1 应用场景
+
+- **限时活动物品**:活动结束后自动失效
+- **赠送的体验物品**:在特定日期后全部失效
+- **版本更新物品**:新版本发布后旧版本物品自动失效
+
+#### 4.1.2 实现方式
+
+1. 在物品定义时设置 `global_expire_at` 字段
+2. 在获取用户物品时,检查物品的全局过期时间
+3. 定期运行任务,清理全局过期的物品
+
+### 4.2 用户物品过期时间
+
+用户物品过期时间定义在 `item_users` 表的 `expire_at` 字段中,表示特定用户的特定物品的过期时间。这允许每个用户的同一物品有不同的过期时间。
+
+#### 4.2.1 应用场景
+
+- **限时使用的装备或道具**:从获取开始计时
+- **会员特权物品**:与会员有效期绑定
+- **租借物品**:租借期结束后自动失效
+- **试用物品**:试用期结束后自动失效
+
+#### 4.2.2 实现方式
+
+1. 在添加物品到用户背包时,根据物品的 `default_expire_seconds` 计算过期时间
+2. 如果 `default_expire_seconds` 为0,则物品永久有效
+3. 在获取用户物品时,检查用户物品的过期时间
+4. 定期运行任务,清理用户过期物品
+
+### 4.3 过期处理机制
+
+系统定期运行任务检查并处理过期物品,确保游戏内物品的时效性。
+
+#### 4.3.1 全局过期物品处理
+
+1. **查询全局过期物品**
+   ```sql
+   SELECT id FROM item_items WHERE global_expire_at IS NOT NULL AND global_expire_at < NOW()
+   ```
+
+2. **删除用户物品记录**
+   ```sql
+   DELETE FROM item_users WHERE item_id IN (已过期物品ID列表)
+   ```
+
+3. **记录日志**
+   - 在 item_transaction_logs 表中记录物品过期删除日志
+   - 交易类型设置为 "过期失效"
+
+4. **可选操作**
+   - 发送通知给用户
+   - 提供过期物品的替代品
+
+#### 4.3.2 用户物品过期处理
+
+1. **查询用户过期物品**
+   ```sql
+   SELECT id, user_id, item_id, instance_id FROM item_users
+   WHERE expire_at IS NOT NULL AND expire_at < NOW()
+   ```
+
+2. **删除用户物品记录**
+   ```sql
+   DELETE FROM item_users WHERE id IN (已过期记录ID列表)
+   ```
+
+3. **处理单独属性物品**
+   - 对于单独属性物品,可以选择删除或保留 item_instances 记录
+   - 如果删除,需要确保没有其他用户关联到该实例
+
+4. **记录日志**
+   - 在 item_transaction_logs 表中记录物品过期删除日志
+   - 记录用户ID、物品ID、过期时间等信息
+
+### 4.4 过期时间的优先级
+
+当同时存在全局过期时间和用户物品过期时间时,系统采用以下优先级规则:
+
+1. **最早到期优先**:系统使用两个过期时间中较早的一个作为实际过期时间
+2. **全局过期强制执行**:即使用户物品过期时间晚于全局过期时间,全局过期时间到达后物品仍会失效
+3. **用户物品过期独立执行**:用户物品过期不影响其他用户的同类物品
+
+## 5. 宝箱系统
+
+宝箱系统是游戏物品系统的重要组成部分,允许玩家通过开启宝箱获得随机物品,增加游戏的随机性和乐趣。
+
+### 5.1 宝箱类型
+
+系统支持多种类型的宝箱,可以根据游戏需求进行配置:
+
+#### 5.1.1 按稀有度分类
+
+1. **普通宝箱**:包含基础消耗品和少量资源,开出稀有物品的概率较低
+2. **稀有宝箱**:有较高机会获得稀有装备和较多资源
+3. **史诗宝箱**:包含高价值物品,有较高概率获得史诗级物品
+4. **传说宝箱**:最高级别宝箱,有机会获得传说级物品
+
+#### 5.1.2 按获取方式分类
+
+1. **任务宝箱**:完成任务获得的宝箱,内容通常与任务相关
+2. **活动宝箱**:特定活动期间可获得的宝箱,包含活动限定物品
+3. **商店宝箱**:通过游戏货币或真实货币购买的宝箱
+4. **成就宝箱**:达成特定成就后获得的宝箱
+5. **副本宝箱**:在游戏副本中获得的宝箱,内容通常与副本主题相关
+
+### 5.2 宝箱配置
+
+宝箱的内容和概率通过 `item_chest_contents` 表进行配置:
+
+#### 5.2.1 基本配置
+
+1. **宝箱定义**:宝箱本身是 `item_items` 表中 `type=5` 的特殊物品
+2. **内容配置**:通过 `item_chest_contents` 表定义宝箱可能掉落的内容
+3. **物品组支持**:宝箱内容可以是具体物品(item_id)或物品组(group_id)
+4. **数量范围**:每个内容可以设置最小和最大掉落数量
+5. **概率控制**:通过 weight 字段控制每个内容的掉落概率
+
+#### 5.2.2 多物品掉落
+
+宝箱系统支持一个宝箱同时掉落多个物品:
+
+1. **掉落数量控制**:
+   - 宝箱物品在 `numeric_attributes` 字段中定义 `min_drop_count` 和 `max_drop_count` 属性
+   - 系统在开启宝箱时随机决定实际掉落的物品数量
+
+2. **重复控制**:
+   - 通过 `allow_duplicate` 字段控制物品是否可以在同一宝箱中重复掉落
+   - 当设置为0时,同一内容在一次开启中最多出现一次
+
+3. **物品组随机**:
+   - 当内容配置为物品组时,系统会根据物品组中的权重随机选择一个物品
+   - 物品组可以包含多个物品,增加宝箱内容的多样性
+
+### 5.3 概率机制
+
+宝箱内容的概率由 `item_chest_contents` 表中的 `weight` 字段决定:
+
+#### 5.3.1 基础概率计算
+
+1. **权重定义**:
+   - 每个宝箱内容的权重为三位小数
+   - 同一宝箱的所有内容权重总和为100
+   - 每个内容的概率直接等于其权重值(百分比)
+
+2. **概率计算公式**:
+   ```
+   内容获取概率 = 内容权重 / 宝箱内容权重总和 * 100%
+   ```
+
+3. **多物品抽取**:
+   - 当宝箱配置为掉落多个物品时,系统会进行多次抽取
+   - 每次抽取都会根据权重进行随机选择
+   - 如果不允许重复,已选中的内容会从后续抽取中排除
+
+### 5.4 保底机制
+
+为了确保玩家在多次开启宝箱后能获得稀有物品,系统实现了保底机制:
+
+#### 5.4.1 保底机制设计
+
+保底机制直接集成在宝箱内容配置中,具有以下特点:
+
+1. **内容级别保底**:
+   - 每个宝箱内容可以设置自己的保底次数(`pity_count`字段)
+   - 当玩家连续未获得该内容达到指定次数后,必定获得该内容
+
+2. **灵活的概率调整**:
+   - 通过 `pity_weight_factor` 字段控制递增概率的幅度
+   - 可以为不同内容设置不同的递增策略
+
+3. **保底计数记录**:
+   - 在 `item_pity_times` 表中记录用户对每个宝箱内容的尝试次数
+   - 当获得内容后,相应的计数会重置
+
+#### 5.4.2 保底实现方式
+
+系统支持两种保底实现方式:
+
+1. **确定保底**:
+   - 当玩家开启次数达到 `pity_count` 时,100%获得该内容
+   - 适用于重要的稀有物品
+
+2. **递增概率**:
+   - 每次未获得目标内容时,增加下次获得的概率
+   - 概率增加公式:
+     ```
+     调整后概率 = 基础概率 * (1 + (当前计数 / pity_count) * pity_weight_factor)
+     ```
+   - 当计数达到 `pity_count` 时,概率变为100%
+
+#### 5.4.3 保底机制实现流程
+
+1. **获取宝箱内容配置**
+   - 从 `item_chest_contents` 表查询宝箱的所有内容配置
+   - 过滤出 `pity_count > 0` 的内容,这些是启用了保底的内容
+
+2. **获取用户保底计数**
+   - 从 `item_pity_times` 表查询用户对各宝箱内容的当前计数
+   - 如果不存在,创建新记录并初始化计数
+
+3. **调整掉落概率**
+   - 根据保底计数调整各内容的掉落概率
+   - 如果有内容的计数达到保底次数,直接选择该内容
+
+4. **更新保底计数**
+   - 对于未获得的内容,增加保底计数
+   - 对于已获得的内容,重置保底计数
+
+### 5.5 宝箱开启接口
+
+系统提供以下接口用于宝箱开启:
+
+#### 5.5.1 开启宝箱
+
+- **功能**:消耗宝箱并获取随机物品
+- **参数**:用户ID、宝箱ID、数量
+- **返回**:获得的物品列表、剩余宝箱数量
+- **处理逻辑**:
+  1. 检查用户是否拥有足够数量的宝箱
+  2. 获取宝箱配置和用户保底计数
+  3. 计算实际掉落物品数量
+  4. 根据概率和保底机制选择掉落内容
+  5. 从用户背包中扣除宝箱
+  6. 向用户背包添加获得的物品
+  7. 更新保底计数
+  8. 记录宝箱开启日志
+
+#### 5.5.2 获取宝箱内容预览
+
+- **功能**:预览宝箱可能获得的物品及概率
+- **参数**:宝箱ID
+- **返回**:可能获得的物品列表及概率
+- **处理逻辑**:
+  1. 获取宝箱配置
+  2. 计算各内容的实际概率
+  3. 对于物品组,展开显示组内物品
+  4. 返回完整的可能获得物品列表及概率
+
+### 5.6 宝箱日志记录
+
+每次宝箱开启都会记录详细日志,用于数据分析和问题排查:
+
+#### 5.6.1 日志内容
+
+在 `item_chest_open_logs` 表中记录以下信息:
+
+1. **用户信息**:开启宝箱的用户ID
+2. **宝箱信息**:宝箱ID、开启数量
+3. **开启时间**:宝箱开启的时间戳
+4. **获得物品**:以JSON格式记录获得的所有物品ID和数量
+5. **保底触发**:是否触发保底机制,触发的内容ID
+6. **安全信息**:IP地址、设备信息等
+
+#### 5.6.2 日志用途
+
+1. **数据分析**:分析宝箱开启模式和物品掉落分布
+2. **概率验证**:验证实际掉落概率是否符合配置
+3. **用户支持**:解决用户关于宝箱开启的问题
+4. **异常检测**:发现可能的作弊或异常行为
+
+## 6. 物品获取与堆叠
+
+当玩家多次获得同一物品时,系统需要根据物品类型和过期时间进行不同的处理,以确保物品管理的合理性和高效性。
+
+### 6.1 统一属性物品的处理
+
+对于统一属性物品(如消耗品、材料等),系统采用以下处理策略:
+
+#### 6.1.1 基本堆叠规则
+
+1. **数量累加**:
+   - 当玩家获得已拥有的统一属性物品时,系统会增加物品数量
+   - 在 `item_users` 表中更新 `quantity` 字段
+
+2. **最大堆叠限制**:
+   - 每种物品都有最大堆叠数量限制,定义在 `item_items` 表的 `max_stack` 字段
+   - 当数量超过最大堆叠限制时,系统会创建新的堆叠
+
+3. **堆叠创建逻辑**:
+   ```php
+   // 伪代码示例
+   $currentQuantity = $userItem->quantity;
+   $maxStack = $item->max_stack;
+   $newQuantity = $currentQuantity + $addQuantity;
+
+   if ($newQuantity <= $maxStack) {
+       // 直接增加数量
+       $userItem->quantity = $newQuantity;
+       $userItem->save();
+   } else {
+       // 先填满当前堆叠
+       $userItem->quantity = $maxStack;
+       $userItem->save();
+
+       // 创建新堆叠
+       $remainingQuantity = $newQuantity - $maxStack;
+       $this->addNewStack($userId, $itemId, $remainingQuantity);
+   }
+   ```
+
+#### 6.1.2 过期时间分组策略
+
+对于有过期时间的统一属性物品,系统按照过期时间分组存储:
+
+1. **过期时间匹配**:
+   - 相同物品但过期时间不同,创建不同的记录
+   - 相同物品且过期时间相同,数量累加
+
+2. **过期时间查找逻辑**:
+   ```php
+   // 伪代码示例
+   $userItem = UserItem::where('user_id', $userId)
+       ->where('item_id', $itemId)
+       ->where('expire_at', $expireAt)
+       ->first();
+
+   if ($userItem) {
+       // 找到相同过期时间的记录,增加数量
+       $userItem->quantity += $quantity;
+       $userItem->save();
+   } else {
+       // 创建新记录
+       UserItem::create([
+           'user_id' => $userId,
+           'item_id' => $itemId,
+           'quantity' => $quantity,
+           'expire_at' => $expireAt
+       ]);
+   }
+   ```
+
+3. **使用优先级**:
+   - 在使用物品时,优先使用即将过期的物品
+   - 系统按过期时间升序排序,先使用最早过期的物品
+
+### 6.2 单独属性物品的处理
+
+对于单独属性物品(如装备、宠物等),每次获取都创建新记录,即使是相同物品:
+
+#### 6.2.1 单独属性物品创建
+
+1. **实例创建**:
+   - 每个单独属性物品都在 `item_instances` 表中创建一条记录
+   - 生成独特的属性(可能包含随机因素)
+
+2. **用户关联**:
+   - 在 `item_users` 表中创建记录,关联用户和物品实例
+   - `quantity` 字段始终为1
+
+3. **创建流程**:
+   ```php
+   // 伪代码示例
+   // 1. 创建物品实例
+   $instance = ItemInstance::create([
+       'item_id' => $itemId,
+       'name' => $generatedName,
+       'display_attributes' => $displayAttributes,
+       'numeric_attributes' => $numericAttributes,
+       'expire_at' => $expireAt
+   ]);
+
+   // 2. 关联到用户
+   UserItem::create([
+       'user_id' => $userId,
+       'item_id' => $itemId,
+       'instance_id' => $instance->id,
+       'quantity' => 1,
+       'expire_at' => $expireAt
+   ]);
+   ```
+
+#### 6.2.2 属性差异化
+
+单独属性物品可以通过多种方式实现属性差异化:
+
+1. **随机属性生成**:
+   - 在创建物品实例时生成随机属性
+   - 属性范围可以根据物品基础属性和品质定义
+
+2. **命名差异化**:
+   - 可以根据属性生成不同的物品名称
+   - 例如:"锐利的钢刀"、"坚固的钢刀"等
+
+3. **属性继承与变异**:
+   - 从基础物品继承部分属性
+   - 添加随机变异或特殊效果
+
+### 6.3 物品获取来源记录
+
+系统记录物品的获取来源,便于数据分析和问题排查:
+
+#### 6.3.1 来源类型
+
+在 `item_transaction_logs` 表中记录物品获取来源:
+
+1. **任务奖励**:完成任务获得的物品
+2. **商店购买**:通过游戏商店购买的物品
+3. **宝箱开启**:通过开启宝箱获得的物品
+4. **怪物掉落**:击败怪物获得的物品
+5. **玩家交易**:通过与其他玩家交易获得的物品
+6. **系统赠送**:系统活动或补偿赠送的物品
+7. **合成获得**:通过物品合成获得的物品
+8. **分解获得**:通过物品分解获得的物品
+
+#### 6.3.2 来源记录格式
+
+```json
+{
+  "source_type": "chest_open",
+  "source_id": 12345,
+  "details": {
+    "chest_id": 101,
+    "open_time": "2023-05-01 12:34:56",
+    "is_pity": false
+  }
+}
+```
+
+### 6.4 物品获取限制
+
+系统支持对物品获取进行限制,防止物品过度产出:
+
+#### 6.4.1 背包容量限制
+
+1. **背包容量检查**:
+   - 在添加物品前检查用户背包是否有足够空间
+   - 背包容量可以根据用户等级或VIP等级动态调整
+
+2. **超出处理策略**:
+   - 拒绝添加:当背包已满时拒绝添加新物品
+   - 邮件发送:将无法添加的物品通过邮件发送给用户
+   - 临时扩容:临时扩大背包容量,但用户需要尽快清理
+
+#### 6.4.2 物品数量限制
+
+1. **单个物品限制**:
+   - 某些特殊物品可以设置最大持有数量
+   - 当达到限制时,无法再获取该物品
+
+2. **物品组限制**:
+   - 可以对一组相关物品设置总数限制
+   - 例如,限制所有任务道具的总数量
+
+## 7. 物品产出限制
+
+为了防止某些物品产出超过预期,影响游戏平衡,系统实现了物品产出限制机制。
+
+### 7.1 限制类型
+
+系统支持多种限制类型,可以根据游戏需求灵活配置:
+
+#### 7.1.1 全局总量限制
+
+- **定义**:限制物品在整个游戏中的总产出数量
+- **应用场景**:限量版物品、稀有收藏品
+- **实现方式**:
+  - 在 `item_output_limits` 表中设置 `limit_type=1`
+  - 使用 `current_quantity` 字段记录当前已产出数量
+  - 每次产出前检查是否超过 `max_quantity`
+
+#### 7.1.2 单个用户限制
+
+- **定义**:限制每个用户可获得的物品总数量
+- **应用场景**:防止单个用户囤积稀有物品、控制关键物品分配
+- **实现方式**:
+  - 在 `item_output_limits` 表中设置 `limit_type=2`
+  - 在 `item_user_output_counters` 表中记录每个用户的获取数量
+  - 每次产出前检查用户是否超过限制
+
+#### 7.1.3 单日全局限制
+
+- **定义**:限制每天在整个游戏中的产出数量
+- **应用场景**:控制物品流通速度、防止市场泛滥
+- **实现方式**:
+  - 在 `item_output_limits` 表中设置 `limit_type=3`
+  - 使用 `current_quantity` 字段记录当日已产出数量
+  - 每天重置计数
+
+#### 7.1.4 单日用户限制
+
+- **定义**:限制每个用户每天可获得的物品数量
+- **应用场景**:日常活动物品、防止刷取行为
+- **实现方式**:
+  - 在 `item_output_limits` 表中设置 `limit_type=4`
+  - 在 `item_user_output_counters` 表中记录用户当日获取数量
+  - 每天重置计数
+
+### 7.2 重置机制
+
+不同类型的限制可以设置不同的重置周期,满足多样化的游戏需求:
+
+#### 7.2.1 重置类型
+
+1. **不重置**(`reset_type=0`):
+   - 永久限制,适用于限量物品
+   - 一旦达到限制,永远不会重置
+
+2. **每日重置**(`reset_type=1`):
+   - 每天重置限制计数
+   - 适用于日常活动物品
+   - 重置时间通常为凌晨0点
+
+3. **每周重置**(`reset_type=2`):
+   - 每周重置限制计数
+   - 适用于周常活动物品
+   - 重置时间通常为每周一凌晨0点
+
+4. **每月重置**(`reset_type=3`):
+   - 每月重置限制计数
+   - 适用于月度活动物品
+   - 重置时间通常为每月1日凌晨0点
+
+#### 7.2.2 重置实现
+
+系统通过定时任务实现自动重置:
+
+```php
+// 伪代码示例
+public function resetLimits()
+{
+    $now = new DateTime();
+
+    // 重置每日限制
+    $dailyLimits = OutputLimit::where('reset_type', 1)
+        ->where('last_reset_time', '<', $now->format('Y-m-d 00:00:00'))
+        ->get();
+
+    foreach ($dailyLimits as $limit) {
+        $limit->current_quantity = 0;
+        $limit->last_reset_time = $now;
+        $limit->save();
+
+        // 重置用户计数
+        UserOutputCounter::where('limit_id', $limit->id)
+            ->update(['current_count' => 0]);
+    }
+
+    // 类似地处理每周和每月重置
+    // ...
+}
+```
+
+### 7.3 关联物品限制
+
+系统支持将多个相关物品关联到同一个限制规则下,防止通过不同渠道绕过限制:
+
+#### 7.3.1 共享限制额度
+
+- **定义**:多个物品共享同一个限制额度
+- **应用场景**:不同渠道获取的相同物品、功能相似的物品
+- **实现方式**:
+  - 在 `item_output_limits` 表的 `related_items` 字段中存储关联物品ID列表
+  - 检查限制时,同时考虑所有关联物品的产出数量
+
+#### 7.3.2 关联物品配置
+
+```json
+// related_items字段示例
+{
+  "items": [1001, 1002, 1003],
+  "relation_type": "shared_limit"
+}
+```
+
+### 7.4 限制检查流程
+
+在物品产出前,系统会执行以下检查流程,确保不超过设定的限制:
+
+#### 7.4.1 检查步骤
+
+1. **查询物品限制**:
+   ```php
+   $limit = OutputLimit::where('item_id', $itemId)->first();
+   if (!$limit) {
+       // 没有限制,直接允许产出
+       return true;
+   }
+   ```
+
+2. **检查限制类型**:
+   ```php
+   switch ($limit->limit_type) {
+       case 1: // 全局总量限制
+           return $this->checkGlobalTotalLimit($limit, $quantity);
+       case 2: // 单个用户限制
+           return $this->checkUserTotalLimit($limit, $userId, $quantity);
+       case 3: // 单日全局限制
+           return $this->checkDailyGlobalLimit($limit, $quantity);
+       case 4: // 单日用户限制
+           return $this->checkDailyUserLimit($limit, $userId, $quantity);
+   }
+   ```
+
+3. **检查关联物品**:
+   ```php
+   if (!empty($limit->related_items)) {
+       $relatedItems = json_decode($limit->related_items, true);
+       foreach ($relatedItems['items'] as $relatedItemId) {
+           // 检查关联物品的产出记录
+           // ...
+       }
+   }
+   ```
+
+4. **更新计数**:
+   ```php
+   if ($isGlobalLimit) {
+       $limit->current_quantity += $quantity;
+       $limit->save();
+   } else {
+       $counter = UserOutputCounter::firstOrCreate([
+           'user_id' => $userId,
+           'limit_id' => $limit->id
+       ]);
+       $counter->current_count += $quantity;
+       $counter->save();
+   }
+   ```
+
+#### 7.4.2 超限处理
+
+当检测到物品产出将超过限制时,系统可以采取以下处理方式:
+
+1. **拒绝产出**:直接拒绝物品产出,返回错误信息
+2. **部分产出**:产出不超过限制的部分数量
+3. **替代产出**:提供替代物品作为补偿
+4. **等待队列**:将超出部分放入等待队列,等待下次重置后产出
+
+### 7.5 监控与预警
+
+系统提供监控和预警机制,帮助游戏运营团队及时了解物品产出情况:
+
+#### 7.5.1 接近限制预警
+
+当物品产出数量接近限制时(例如达到80%),系统可以发送预警通知:
+
+```php
+if ($currentQuantity >= $maxQuantity * 0.8 && $currentQuantity < $maxQuantity * 0.9) {
+    // 发送80%预警
+    $this->sendWarning($itemId, '80%');
+} elseif ($currentQuantity >= $maxQuantity * 0.9) {
+    // 发送90%预警
+    $this->sendWarning($itemId, '90%');
+}
+```
+
+#### 7.5.2 产出统计报告
+
+系统定期生成物品产出统计报告,包括:
+
+1. **总产出数量**:各物品的总产出数量
+2. **限制使用情况**:各限制规则的使用情况
+3. **用户获取分布**:物品在用户间的分布情况
+4. **时间分布**:物品产出的时间分布
+
+## 8. 日志记录系统
+
+物品系统的所有操作都会记录详细日志,用于数据分析、问题排查和安全审计。
+
+### 8.1 日志类型
+
+系统根据不同的操作类型记录多种日志:
+
+#### 8.1.1 物品交易日志
+
+在 `item_transaction_logs` 表中记录所有物品获取和消耗操作:
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 日志ID,主键 |
+| user_id | int | 用户ID |
+| item_id | int | 物品ID |
+| instance_id | int | 单独属性物品ID(可为空) |
+| quantity | int | 数量(正数表示获取,负数表示消耗) |
+| transaction_type | tinyint | 交易类型(1:获取, 2:使用, 3:交易, 4:出售, 5:过期, 6:删除...) |
+| source_type | varchar | 来源类型(任务、商店、宝箱等) |
+| source_id | int | 来源ID(任务ID、商店ID、宝箱ID等) |
+| details | json | 详细信息,以JSON格式存储 |
+| transaction_time | timestamp | 交易时间 |
+| ip_address | varchar | 操作的IP地址 |
+| device_info | varchar | 设备信息 |
+| created_at | timestamp | 创建时间 |
+
+#### 8.1.2 宝箱开启日志
+
+在 `item_chest_open_logs` 表中记录宝箱开启操作:
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 日志ID,主键 |
+| user_id | int | 用户ID |
+| chest_id | int | 宝箱ID |
+| quantity | int | 开启数量 |
+| results | json | 获得的物品,以JSON格式存储 |
+| pity_triggered | tinyint | 是否触发保底机制(0:否, 1:是) |
+| pity_content_id | int | 触发保底的内容ID(可为空) |
+| open_time | timestamp | 开启时间 |
+| ip_address | varchar | 操作的IP地址 |
+| device_info | varchar | 设备信息 |
+| created_at | timestamp | 创建时间 |
+
+#### 8.1.3 物品合成日志
+
+在 `item_craft_logs` 表中记录物品合成操作:
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 日志ID,主键 |
+| user_id | int | 用户ID |
+| recipe_id | int | 配方ID |
+| materials | json | 消耗的材料,以JSON格式存储 |
+| result_item_id | int | 获得的物品ID |
+| result_instance_id | int | 获得的单独属性物品ID(可为空) |
+| result_quantity | int | 获得的物品数量 |
+| is_success | tinyint | 是否成功(0:失败, 1:成功) |
+| craft_time | timestamp | 合成时间 |
+| ip_address | varchar | 操作的IP地址 |
+| device_info | varchar | 设备信息 |
+| created_at | timestamp | 创建时间 |
+
+#### 8.1.4 物品分解日志
+
+在 `item_dismantle_logs` 表中记录物品分解操作:
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 记录ID,主键 |
+| user_id | int | 用户ID |
+| item_id | int | 被分解的物品ID |
+| instance_id | int | 被分解的单独属性物品ID(可为空) |
+| quantity | int | 分解数量 |
+| rule_id | int | 使用的分解规则ID |
+| results | json | 分解结果,包含获得的物品ID、数量等信息 |
+| dismantle_time | timestamp | 分解时间 |
+| ip_address | varchar | 操作的IP地址 |
+| device_info | varchar | 设备信息 |
+| created_at | timestamp | 创建时间 |
+
+### 8.2 日志记录策略
+
+系统采用以下策略记录日志,确保数据完整性和系统性能:
+
+#### 8.2.1 事务内记录
+
+日志记录应在数据库事务内进行,确保操作和日志的一致性:
+
+```php
+DB::beginTransaction();
+try {
+    // 执行物品操作
+    $this->addItemToUser($userId, $itemId, $quantity);
+
+    // 记录日志
+    $this->logTransaction($userId, $itemId, $quantity, 1, $sourceType, $sourceId);
+
+    DB::commit();
+} catch (\Exception $e) {
+    DB::rollBack();
+    throw $e;
+}
+```
+
+#### 8.2.2 异步日志记录
+
+对于高频操作,可以使用队列实现异步日志记录,减轻数据库压力:
+
+```php
+// 将日志记录任务推送到队列
+Queue::push(new RecordItemTransactionLog($userId, $itemId, $quantity, $transactionType, $sourceType, $sourceId));
+```
+
+#### 8.2.3 批量日志记录
+
+对于批量操作,可以使用批量插入优化性能:
+
+```php
+$logs = [];
+foreach ($items as $item) {
+    $logs[] = [
+        'user_id' => $userId,
+        'item_id' => $item['id'],
+        'quantity' => $item['quantity'],
+        'transaction_type' => $transactionType,
+        'transaction_time' => now(),
+        // 其他字段...
+    ];
+}
+
+// 批量插入日志
+DB::table('item_transaction_logs')->insert($logs);
+```
+
+### 8.3 日志查询接口
+
+系统提供以下接口用于查询日志:
+
+#### 8.3.1 查询用户物品历史
+
+- **功能**:查询用户的物品获取和消耗历史
+- **参数**:用户ID、物品ID(可选)、交易类型(可选)、时间范围(可选)、分页参数
+- **返回**:物品交易记录列表
+- **查询示例**:
+  ```php
+  $logs = TransactionLog::where('user_id', $userId)
+      ->when($itemId, function ($query) use ($itemId) {
+          return $query->where('item_id', $itemId);
+      })
+      ->when($transactionType, function ($query) use ($transactionType) {
+          return $query->where('transaction_type', $transactionType);
+      })
+      ->when($startTime && $endTime, function ($query) use ($startTime, $endTime) {
+          return $query->whereBetween('transaction_time', [$startTime, $endTime]);
+      })
+      ->orderBy('transaction_time', 'desc')
+      ->paginate($perPage);
+  ```
+
+#### 8.3.2 查询宝箱开启历史
+
+- **功能**:查询用户的宝箱开启历史
+- **参数**:用户ID、宝箱ID(可选)、时间范围(可选)、分页参数
+- **返回**:宝箱开启记录列表
+- **查询示例**:
+  ```php
+  $logs = ChestOpenLog::where('user_id', $userId)
+      ->when($chestId, function ($query) use ($chestId) {
+          return $query->where('chest_id', $chestId);
+      })
+      ->when($startTime && $endTime, function ($query) use ($startTime, $endTime) {
+          return $query->whereBetween('open_time', [$startTime, $endTime]);
+      })
+      ->orderBy('open_time', 'desc')
+      ->paginate($perPage);
+  ```
+
+### 8.4 日志分析与应用
+
+系统日志可用于多种分析和应用场景:
+
+#### 8.4.1 数据分析
+
+1. **物品流通分析**:
+   - 分析物品的获取和消耗渠道
+   - 识别最受欢迎的物品和获取方式
+   - 监控物品经济平衡
+
+2. **用户行为分析**:
+   - 分析用户的物品使用模式
+   - 识别高价值用户和活跃用户
+   - 发现潜在的游戏优化点
+
+#### 8.4.2 问题排查
+
+1. **物品丢失排查**:
+   - 通过日志追踪物品的完整生命周期
+   - 确认物品是否正常获取和消耗
+   - 识别可能的系统错误或漏洞
+
+2. **异常行为检测**:
+   - 识别可能的作弊或滥用行为
+   - 监控异常的物品获取模式
+   - 发现潜在的系统漏洞
+
+#### 8.4.3 用户支持
+
+1. **物品恢复**:
+   - 在系统错误导致物品丢失时,通过日志确认物品状态
+   - 提供准确的物品恢复服务
+
+2. **用户查询**:
+   - 回答用户关于物品获取和消耗的问题
+   - 提供物品历史记录查询服务
+
+### 8.5 日志清理与归档
+
+为了管理日志数据量,系统实现了日志清理和归档机制:
+
+#### 8.5.1 日志保留策略
+
+1. **实时日志**:
+   - 保留最近30天的日志在主数据库中
+   - 用于实时查询和问题排查
+
+2. **归档日志**:
+   - 30天以上的日志移动到归档数据库
+   - 用于长期数据分析和审计
+
+3. **统计汇总**:
+   - 对超过180天的日志进行统计汇总
+   - 保留关键统计数据,删除详细记录
+
+#### 8.5.2 归档实现
+
+```php
+// 伪代码示例
+public function archiveLogs()
+{
+    $cutoffDate = now()->subDays(30);
+
+    // 查找需要归档的日志
+    $logsToArchive = TransactionLog::where('transaction_time', '<', $cutoffDate)
+        ->limit(1000)
+        ->get();
+
+    if ($logsToArchive->isEmpty()) {
+        return;
+    }
+
+    // 插入到归档表
+    DB::connection('archive')->table('archived_transaction_logs')->insert(
+        $logsToArchive->toArray()
+    );
+
+    // 删除已归档的日志
+    $ids = $logsToArchive->pluck('id')->toArray();
+    TransactionLog::whereIn('id', $ids)->delete();
+}
+
+## 9. 物品合成系统
+
+物品合成系统允许玩家使用已有物品合成新物品,增加游戏深度和物品获取途径。
+
+### 9.1 合成系统概述
+
+物品合成系统具有以下特点:
+
+#### 9.1.1 系统特点
+
+1. **多材料合成**:支持使用多种不同物品作为材料
+2. **概率成功**:合成可以设置成功率,增加游戏随机性
+3. **等级限制**:可以设置合成的等级或条件限制
+4. **配方解锁**:玩家需要先解锁配方才能进行合成
+5. **多币种成本**:支持消耗多种货币作为合成成本
+
+#### 9.1.2 合成流程
+
+1. **选择配方**:玩家从已解锁的配方中选择要合成的物品
+2. **检查材料**:系统检查玩家是否拥有足够的材料
+3. **支付成本**:扣除合成所需的货币成本
+4. **消耗材料**:从玩家背包中扣除材料
+5. **概率判定**:根据配方的成功率判定是否合成成功
+6. **发放物品**:合成成功时,向玩家发放合成物品
+7. **记录日志**:记录合成操作的详细信息
+
+### 9.2 数据库设计
+
+合成系统涉及三个主要数据表:配方表、配方材料表和用户配方表。
+
+#### 9.2.1 item_recipes 表(合成配方)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 配方ID,主键 |
+| name | varchar | 配方名称 |
+| result_item_id | int | 产出物品ID,外键关联item_items表 |
+| result_min_quantity | int | 最小产出数量 |
+| result_max_quantity | int | 最大产出数量 |
+| success_rate | decimal(5,2) | 成功率(百分比,最大100) |
+| coin_cost | json | 货币成本,以JSON格式存储多种货币类型和数量 |
+| level_required | int | 所需等级 |
+| is_default_unlocked | tinyint | 是否默认解锁(0:否, 1:是) |
+| unlock_condition | json | 解锁条件,以JSON格式存储 |
+| cooldown_seconds | int | 冷却时间(秒) |
+| category_id | int | 配方分类ID |
+| sort_order | int | 排序权重 |
+| is_active | tinyint | 是否激活(0:否, 1:是) |
+| created_at | timestamp | 创建时间 |
+| updated_at | timestamp | 更新时间 |
+
+#### 9.2.2 item_recipe_materials 表(配方材料)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 记录ID,主键 |
+| recipe_id | int | 配方ID,外键关联item_recipes表 |
+| item_id | int | 材料物品ID,外键关联item_items表 |
+| quantity | int | 所需数量 |
+| is_consumed | tinyint | 是否消耗(0:不消耗, 1:消耗) |
+| created_at | timestamp | 创建时间 |
+| updated_at | timestamp | 更新时间 |
+
+#### 9.2.3 item_user_recipes 表(用户配方)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 记录ID,主键 |
+| user_id | int | 用户ID |
+| recipe_id | int | 配方ID,外键关联item_recipes表 |
+| is_unlocked | tinyint | 是否已解锁(0:否, 1:是) |
+| unlock_time | timestamp | 解锁时间 |
+| last_craft_time | timestamp | 最后合成时间 |
+| craft_count | int | 合成次数 |
+| created_at | timestamp | 创建时间 |
+| updated_at | timestamp | 更新时间 |
+
+### 9.3 多币种成本设计
+
+系统支持使用多种货币作为合成成本,增加游戏经济的深度:
+
+#### 9.3.1 币种类型
+
+1. **游戏金币**:基础游戏货币
+2. **钻石**:高级游戏货币,通常与真实货币关联
+3. **声望**:特定阵营或活动的声望货币
+4. **活动代币**:限时活动专用货币
+
+#### 9.3.2 成本存储格式
+
+在 `item_recipes` 表的 `coin_cost` 字段中,使用JSON格式存储多币种成本:
+
+```json
+{
+  "gold": 1000,
+  "diamond": 5,
+  "reputation": {
+    "faction_id": 2,
+    "amount": 100
+  },
+  "event_token": {
+    "token_id": 101,
+    "amount": 20
+  }
+}
+```
+
+#### 9.3.3 成本检查逻辑
+
+```php
+// 伪代码示例
+public function checkCraftCost($userId, $recipeId)
+{
+    $recipe = Recipe::find($recipeId);
+    $coinCost = json_decode($recipe->coin_cost, true);
+
+    // 检查各种货币是否足够
+    foreach ($coinCost as $coinType => $amount) {
+        if (is_array($amount)) {
+            // 处理特殊货币(声望、活动代币等)
+            $specialCoinId = $amount['faction_id'] ?? $amount['token_id'];
+            $specialCoinAmount = $amount['amount'];
+
+            if (!$this->hasEnoughSpecialCoin($userId, $coinType, $specialCoinId, $specialCoinAmount)) {
+                return false;
+            }
+        } else {
+            // 处理基础货币(金币、钻石)
+            if (!$this->hasEnoughCoin($userId, $coinType, $amount)) {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+```
+
+### 9.4 合成成功率机制
+
+系统支持概率性合成,增加游戏的随机性和挑战性:
+
+#### 9.4.1 基础成功率
+
+每个配方都有一个基础成功率,定义在 `item_recipes` 表的 `success_rate` 字段中:
+
+- 成功率范围:0-100(百分比)
+- 成功率为100表示必定成功
+- 成功率为0表示无法通过常规方式成功
+
+#### 9.4.2 成功率调整因素
+
+基础成功率可以受多种因素影响:
+
+1. **玩家等级**:等级越高,成功率可能越高
+2. **技能加成**:特定技能可以提高成功率
+3. **道具加成**:使用特殊道具可以提高成功率
+4. **设备加成**:使用特殊设备进行合成可以提高成功率
+
+#### 9.4.3 成功率计算
+
+```php
+// 伪代码示例
+public function calculateSuccessRate($userId, $recipeId)
+{
+    $recipe = Recipe::find($recipeId);
+    $baseRate = $recipe->success_rate;
+
+    // 获取玩家等级加成
+    $user = User::find($userId);
+    $levelBonus = $this->getLevelSuccessBonus($user->level);
+
+    // 获取技能加成
+    $skillBonus = $this->getSkillSuccessBonus($userId);
+
+    // 获取道具加成
+    $itemBonus = $this->getItemSuccessBonus($userId);
+
+    // 计算最终成功率
+    $finalRate = $baseRate + $levelBonus + $skillBonus + $itemBonus;
+
+    // 确保成功率在0-100范围内
+    return max(0, min(100, $finalRate));
+}
+```
+
+### 9.5 合成接口
+
+系统提供以下接口用于物品合成:
+
+#### 9.5.1 获取可用配方
+
+- **功能**:获取用户可用的合成配方列表
+- **参数**:用户ID、分类ID(可选)
+- **返回**:配方列表,包含名称、材料、成功率等信息
+- **处理逻辑**:
+  1. 查询用户已解锁的配方
+  2. 检查配方是否激活
+  3. 关联配方材料信息
+  4. 检查用户是否拥有足够材料
+  5. 返回配方列表,标记可合成状态
+
+#### 9.5.2 执行合成
+
+- **功能**:执行物品合成操作
+- **参数**:用户ID、配方ID
+- **返回**:合成结果、获得的物品
+- **处理逻辑**:
+  1. 检查配方是否存在且已解锁
+  2. 检查冷却时间是否已过
+  3. 检查用户是否拥有足够材料和货币
+  4. 扣除材料和货币
+  5. 根据成功率判定是否成功
+  6. 发放合成物品或返回失败信息
+  7. 更新用户配方使用记录
+  8. 记录合成日志
+
+#### 9.5.3 解锁配方
+
+- **功能**:解锁新的合成配方
+- **参数**:用户ID、配方ID
+- **返回**:解锁结果
+- **处理逻辑**:
+  1. 检查配方是否存在
+  2. 检查用户是否已解锁该配方
+  3. 检查解锁条件是否满足
+  4. 解锁配方并记录解锁时间
+  5. 返回解锁结果
+
+### 9.6 配方解锁机制
+
+系统支持多种配方解锁机制,增加游戏的探索性和进度感:
+
+#### 9.6.1 解锁方式
+
+1. **默认解锁**:
+   - 在 `item_recipes` 表中设置 `is_default_unlocked=1`
+   - 玩家创建角色时自动解锁
+
+2. **等级解锁**:
+   - 在 `unlock_condition` 中设置所需等级
+   - 玩家达到指定等级时自动解锁
+
+3. **任务解锁**:
+   - 在 `unlock_condition` 中设置关联任务
+   - 完成指定任务后解锁
+
+4. **成就解锁**:
+   - 在 `unlock_condition` 中设置关联成就
+   - 达成指定成就后解锁
+
+5. **物品解锁**:
+   - 使用特定物品(如配方书)解锁
+   - 系统检测物品使用事件并解锁对应配方
+
+#### 9.6.2 解锁条件格式
+
+在 `item_recipes` 表的 `unlock_condition` 字段中,使用JSON格式存储解锁条件:
+
+```json
+{
+  "type": "level",
+  "value": 20
+}
+```
+
+或者更复杂的条件:
+
+```json
+{
+  "type": "multi",
+  "conditions": [
+    {
+      "type": "level",
+      "value": 15
+    },
+    {
+      "type": "quest",
+      "quest_id": 1024,
+      "status": "completed"
+    },
+    {
+      "type": "item",
+      "item_id": 5001,
+      "quantity": 1
+    }
+  ],
+  "logic": "and"
+}
+```
+
+### 9.7 合成结果计算
+
+系统支持多种合成结果计算方式,增加游戏的多样性:
+
+#### 9.7.1 固定结果
+
+最简单的合成方式,成功后获得固定数量的物品:
+
+```php
+// 伪代码示例
+if ($this->isSuccess($userId, $recipeId)) {
+    $recipe = Recipe::find($recipeId);
+    $resultItemId = $recipe->result_item_id;
+    $quantity = $recipe->result_min_quantity; // 固定数量
+
+    $this->addItemToUser($userId, $resultItemId, $quantity);
+    return ['success' => true, 'item_id' => $resultItemId, 'quantity' => $quantity];
+} else {
+    return ['success' => false];
+}
+```
+
+#### 9.7.2 随机数量
+
+成功后获得的物品数量在一个范围内随机:
+
+```php
+// 伪代码示例
+if ($this->isSuccess($userId, $recipeId)) {
+    $recipe = Recipe::find($recipeId);
+    $resultItemId = $recipe->result_item_id;
+    $minQuantity = $recipe->result_min_quantity;
+    $maxQuantity = $recipe->result_max_quantity;
+
+    // 随机数量
+    $quantity = rand($minQuantity, $maxQuantity);
+
+    $this->addItemToUser($userId, $resultItemId, $quantity);
+    return ['success' => true, 'item_id' => $resultItemId, 'quantity' => $quantity];
+} else {
+    return ['success' => false];
+}
+```
+
+#### 9.7.3 品质变化
+
+对于单独属性物品,合成可能影响物品的品质:
+
+```php
+// 伪代码示例
+if ($this->isSuccess($userId, $recipeId)) {
+    $recipe = Recipe::find($recipeId);
+    $resultItemId = $recipe->result_item_id;
+
+    // 计算品质
+    $baseQuality = 100;
+    $qualityVariation = rand(-10, 20); // 品质随机变化
+    $finalQuality = $baseQuality + $qualityVariation;
+
+    // 创建单独属性物品
+    $attributes = [
+        'quality' => $finalQuality,
+        // 其他属性...
+    ];
+
+    $instanceId = $this->createItemInstance($resultItemId, $attributes);
+    $this->addItemInstanceToUser($userId, $resultItemId, $instanceId);
+
+    return [
+        'success' => true,
+        'item_id' => $resultItemId,
+        'instance_id' => $instanceId,
+        'quality' => $finalQuality
+    ];
+} else {
+    return ['success' => false];
+}
+```
+
+## 10. 物品分解系统
+
+物品分解系统允许玩家将不需要的物品分解为基础材料或其他资源,增加物品循环利用的途径,丰富游戏经济系统。
+
+### 10.1 分解系统概述
+
+#### 10.1.1 系统特点
+
+1. **资源回收**:将不需要的物品转化为有用的材料或资源
+2. **经济平衡**:为过剩物品提供消耗渠道,维持游戏经济平衡
+3. **多样化奖励**:分解可以获得多种类型的材料和资源
+4. **随机性**:分解结果可以包含随机因素,增加游戏乐趣
+5. **品质影响**:物品品质影响分解获得的材料数量和种类
+
+#### 10.1.2 分解系统流程
+
+1. **物品选择**:玩家选择要分解的物品和数量
+2. **分解预览**:系统显示可能获得的材料及概率
+3. **确认分解**:玩家确认分解操作
+4. **规则匹配**:系统根据物品特性匹配适用的分解规则
+5. **结果计算**:根据规则计算分解结果
+6. **物品扣除**:从玩家背包中扣除被分解的物品
+7. **材料发放**:向玩家发放分解获得的材料
+8. **日志记录**:记录分解操作的详细信息
+
+### 10.2 数据库设计
+
+分解系统涉及三个主要数据表:分解规则表、分解结果配置表和分解日志表。
+
+#### 10.2.1 item_dismantle_rules 表(物品分解规则)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 规则ID,主键 |
+| item_id | int | 物品ID,外键关联item_items表 |
+| category_id | int | 分类ID,外键关联item_categories表(与item_id二选一,用于对整个分类设置规则) |
+| min_rarity | tinyint | 最小适用稀有度 |
+| max_rarity | tinyint | 最大适用稀有度 |
+| priority | int | 规则优先级,当多个规则适用时,使用优先级最高的规则 |
+| is_active | tinyint | 是否激活(0:否, 1:是) |
+| created_at | timestamp | 创建时间 |
+| updated_at | timestamp | 更新时间 |
+
+#### 10.2.2 item_dismantle_results 表(分解结果配置)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 记录ID,主键 |
+| rule_id | int | 分解规则ID,外键关联item_dismantle_rules表 |
+| result_item_id | int | 结果物品ID,外键关联item_items表 |
+| min_quantity | int | 最小数量 |
+| max_quantity | int | 最大数量 |
+| base_chance | decimal(5,2) | 基础获取概率(百分比,最大100) |
+| rarity_factor | decimal(5,2) | 稀有度影响因子,物品稀有度对数量的影响系数 |
+| quality_factor | decimal(5,2) | 品质影响因子,物品品质对数量的影响系数 |
+| created_at | timestamp | 创建时间 |
+| updated_at | timestamp | 更新时间 |
+
+#### 10.2.3 item_dismantle_logs 表(分解记录)
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| id | int | 记录ID,主键 |
+| user_id | int | 用户ID |
+| item_id | int | 被分解的物品ID |
+| instance_id | int | 被分解的单独属性物品ID(可为空) |
+| quantity | int | 分解数量 |
+| rule_id | int | 使用的分解规则ID |
+| results | json | 分解结果,包含获得的物品ID、数量等信息 |
+| dismantle_time | timestamp | 分解时间 |
+| ip_address | varchar | 操作的IP地址 |
+| device_info | varchar | 设备信息 |
+| created_at | timestamp | 创建时间 |
+
+### 10.3 分解规则和机制
+
+物品分解系统支持多种规则和机制,确保分解结果的合理性和游戏平衡。
+
+#### 10.3.1 规则匹配逻辑
+
+系统按照以下优先级顺序匹配分解规则:
+
+1. **精确匹配**:根据物品ID精确匹配分解规则
+2. **分类匹配**:当没有精确匹配规则时,根据物品分类匹配规则
+3. **稀有度范围**:规则可以设置适用的稀有度范围
+4. **优先级**:当多个规则都适用时,使用优先级最高的规则
+
+```php
+// 伪代码示例
+public function findDismantleRule($itemId, $rarity)
+{
+    // 1. 尝试精确匹配
+    $rule = DismantleRule::where('item_id', $itemId)
+        ->where('is_active', 1)
+        ->where('min_rarity', '<=', $rarity)
+        ->where('max_rarity', '>=', $rarity)
+        ->orderBy('priority', 'desc')
+        ->first();
+
+    if ($rule) {
+        return $rule;
+    }
+
+    // 2. 尝试分类匹配
+    $item = Item::find($itemId);
+    $rule = DismantleRule::where('category_id', $item->category_id)
+        ->where('item_id', null)
+        ->where('is_active', 1)
+        ->where('min_rarity', '<=', $rarity)
+        ->where('max_rarity', '>=', $rarity)
+        ->orderBy('priority', 'desc')
+        ->first();
+
+    return $rule;
+}
+```
+
+#### 10.3.2 特殊物品处理
+
+不同类型的物品在分解时有特殊处理逻辑:
+
+1. **绑定物品**:绑定物品分解后,获得的材料也会继承绑定状态
+2. **不可分解物品**:通过item_items表中的dismantlable字段标记物品是否可分解
+3. **单独属性物品**:分解单独属性物品时,可以根据其特殊属性调整分解结果
+
+```php
+// 伪代码示例
+public function canDismantle($itemId, $instanceId = null)
+{
+    $item = Item::find($itemId);
+
+    // 检查物品是否可分解
+    if ($item->dismantlable == 0) {
+        return false;
+    }
+
+    // 检查单独属性物品
+    if ($instanceId) {
+        $instance = ItemInstance::find($instanceId);
+        // 可以添加特殊条件,如不允许分解特定品质以上的装备
+        if ($instance->numeric_attributes->quality > 90) {
+            return false;
+        }
+    }
+
+    return true;
+}
+```
+
+#### 10.3.3 批量分解功能
+
+系统支持多种批量分解方式,提高用户体验:
+
+1. **同类物品批量分解**:一次分解多个相同物品
+2. **多类物品批量分解**:一次分解多种不同物品
+3. **自动分解**:可以设置自动分解规则,如自动分解低品质物品
+
+```php
+// 伪代码示例
+public function batchDismantle($userId, $items)
+{
+    $results = [];
+    $totalResults = [];
+
+    DB::beginTransaction();
+    try {
+        foreach ($items as $item) {
+            $itemId = $item['item_id'];
+            $instanceId = $item['instance_id'] ?? null;
+            $quantity = $item['quantity'];
+
+            // 检查是否可分解
+            if (!$this->canDismantle($itemId, $instanceId)) {
+                continue;
+            }
+
+            // 执行分解
+            $dismantleResult = $this->dismantleItem($userId, $itemId, $instanceId, $quantity);
+            $results[] = $dismantleResult;
+
+            // 合并结果
+            foreach ($dismantleResult['materials'] as $material) {
+                if (isset($totalResults[$material['item_id']])) {
+                    $totalResults[$material['item_id']]['quantity'] += $material['quantity'];
+                } else {
+                    $totalResults[$material['item_id']] = $material;
+                }
+            }
+        }
+
+        DB::commit();
+        return [
+            'success' => true,
+            'detail_results' => $results,
+            'total_materials' => array_values($totalResults)
+        ];
+    } catch (\Exception $e) {
+        DB::rollBack();
+        return ['success' => false, 'message' => $e->getMessage()];
+    }
+}
+```
+
+### 10.4 分解结果计算
+
+分解结果的计算是一个多步骤的过程,考虑多种因素。
+
+#### 10.4.1 基础数量计算
+
+首先计算基础数量:
+
+```php
+// 伪代码示例
+$baseQuantity = rand($resultConfig->min_quantity, $resultConfig->max_quantity);
+```
+
+#### 10.4.2 稀有度和品质影响
+
+物品的稀有度和品质会影响最终获得的数量:
+
+```php
+// 伪代码示例
+$rarityBonus = ($item->rarity - 1) * $resultConfig->rarity_factor;
+
+// 对于单独属性物品,考虑品质
+$qualityBonus = 0;
+if ($instanceId) {
+    $instance = ItemInstance::find($instanceId);
+    $quality = $instance->numeric_attributes->quality ?? 0;
+    $qualityBonus = $quality * $resultConfig->quality_factor;
+}
+
+$finalQuantity = ceil($baseQuantity * (1 + $rarityBonus) * (1 + $qualityBonus));
+```
+
+#### 10.4.3 概率计算
+
+每个可能的分解结果都有一个获取概率,也受物品稀有度和品质影响:
+
+```php
+// 伪代码示例
+$baseChance = $resultConfig->base_chance;
+$rarityBonus = ($item->rarity - 1) * 5; // 每级稀有度增加5%概率
+
+// 对于单独属性物品,考虑品质
+$qualityBonus = 0;
+if ($instanceId) {
+    $instance = ItemInstance::find($instanceId);
+    $quality = $instance->numeric_attributes->quality ?? 0;
+    $qualityBonus = $quality * 0.1; // 每点品质增加0.1%概率
+}
+
+$finalChance = $baseChance + $rarityBonus + $qualityBonus;
+$finalChance = min(100, $finalChance); // 最大100%
+
+// 判断是否获得该结果
+$isObtained = (mt_rand(1, 100) <= $finalChance);
+```
+
+#### 10.4.4 特殊结果机制
+
+某些特殊情况下,分解可能有额外结果:
+
+1. **暴击分解**:有小概率获得双倍或三倍材料
+2. **稀有材料**:分解高品质物品有几率获得稀有材料
+3. **特殊道具**:某些物品分解可能获得特殊道具或货币
+
+```php
+// 伪代码示例
+// 检查是否触发暴击
+$criticalChance = 5; // 5%暴击概率
+$isCritical = (mt_rand(1, 100) <= $criticalChance);
+
+if ($isCritical) {
+    $criticalMultiplier = (mt_rand(1, 100) <= 30) ? 3 : 2; // 30%几率3倍,70%几率2倍
+    $finalQuantity *= $criticalMultiplier;
+    $results['is_critical'] = true;
+    $results['critical_multiplier'] = $criticalMultiplier;
+}
+
+// 检查是否获得稀有材料
+if ($item->rarity >= 3 && mt_rand(1, 100) <= 10) {
+    $rareMaterials = $this->getRareMaterials($item->category_id);
+    // 添加稀有材料到结果中
+}
+```
+
+### 10.5 分解系统接口
+
+系统提供以下接口用于物品分解:
+
+#### 10.5.1 获取物品分解预览
+
+- **功能**:预览物品分解可能获得的材料
+- **参数**:用户ID、物品ID、数量
+- **返回**:可能获得的材料列表及概率
+- **处理逻辑**:
+  1. 检查物品是否可分解
+  2. 获取适用的分解规则
+  3. 获取可能的分解结果及概率
+  4. 返回预览信息
+
+#### 10.5.2 执行物品分解
+
+- **功能**:分解指定物品并获得材料
+- **参数**:用户ID、物品ID、数量
+- **返回**:分解结果、获得的材料列表
+- **处理逻辑**:
+  1. 检查用户是否拥有足够数量的物品
+  2. 检查物品是否可分解
+  3. 获取适用的分解规则
+  4. 计算分解结果
+  5. 从用户背包中扣除物品
+  6. 向用户背包添加获得的材料
+  7. 记录分解日志
+
+#### 10.5.3 批量分解物品
+
+- **功能**:批量分解多个物品
+- **参数**:用户ID、物品ID列表及数量
+- **返回**:分解结果、获得的材料列表
+- **处理逻辑**:
+  1. 检查用户是否拥有所有指定物品
+  2. 对每个物品执行分解操作
+  3. 合并分解结果
+  4. 返回总体分解结果
+
+#### 10.5.4 获取分解历史
+
+- **功能**:查询用户的物品分解历史
+- **参数**:用户ID、时间范围(可选)
+- **返回**:分解历史记录列表
+- **处理逻辑**:
+  1. 查询用户的分解日志记录
+  2. 按时间排序
+  3. 返回分解历史列表
+
+### 10.6 分解日志记录
+
+系统记录所有分解操作,确保可追溯性和数据分析需求:
+
+#### 10.6.1 日志内容
+
+在 `item_dismantle_logs` 表中记录以下信息:
+
+1. **用户信息**:执行分解的用户ID
+2. **物品信息**:被分解的物品ID、数量
+3. **分解结果**:获得的材料列表及数量
+4. **时间信息**:分解操作的时间
+5. **规则信息**:应用的分解规则ID
+6. **安全信息**:IP地址、设备信息等
+
+#### 10.6.2 日志用途
+
+1. **数据分析**:分析玩家分解行为和偏好
+2. **问题排查**:解决玩家关于分解结果的疑问
+3. **系统监控**:监控分解系统的运行状态
+4. **平衡调整**:为游戏平衡调整提供数据支持
+
+### 10.7 与其他系统的交互
+
+分解系统与游戏中的多个系统有紧密的交互关系:
+
+#### 10.7.1 与背包系统交互
+
+- 分解操作会减少背包中的物品,并添加新的材料
+- 需要检查背包容量是否足够存放分解获得的材料
+
+#### 10.7.2 与任务和成就系统交互
+
+- 分解特定物品或获得特定材料可能触发任务进度
+- 累计分解次数或特定物品分解可能触发成就
+
+#### 10.7.3 与合成系统交互
+
+- 分解获得的材料可用于物品合成
+- 分解和合成形成物品循环利用的闭环
+
+#### 10.7.4 与商店系统交互
+
+- 分解获得的材料可以在商店出售或用于购买其他物品
+- 商店可以提供分解服务,收取一定费用
+
+## 11. 物品绑定机制
+
+物品绑定机制用于限制物品的流通和交易,保持游戏经济平衡,并增加游戏内容的专属性。
+
+### 11.1 绑定机制概述
+
+#### 11.1.1 绑定机制目的
+
+物品绑定机制主要用于以下目的:
+
+1. **限制物品交易**:防止高价值物品在玩家间无限制流通
+2. **增加成就感**:使某些物品具有专属性,提高获取难度和价值感
+3. **控制游戏经济**:防止物品市场泛滥和通货膨胀
+4. **区分物品来源**:通过不同的绑定状态区分物品的获取途径
+5. **增加游戏深度**:为不同物品设计不同的绑定规则,增加游戏策略性
+
+#### 11.1.2 绑定与不可交易的区别
+
+物品绑定和物品不可交易是两个不同的概念,虽然它们都会限制物品的流通,但在实现方式、应用场景和用户体验上有明显区别:
+
+1. **概念区别**:
+   - **物品绑定**:指物品与特定玩家或角色建立关联,限制物品只能被该玩家或角色使用
+   - **物品不可交易**:指物品本身的一种固有属性,决定该物品是否可以参与玩家间的交易
+
+2. **状态变化**:
+   - **物品绑定**:是一种状态变化,物品可以从未绑定变为已绑定
+   - **物品不可交易**:是物品的固有特性,通常在物品创建时就已确定
+
+3. **触发条件**:
+   - **物品绑定**:通常发生在特定触发条件下(获取、使用、装备等)
+   - **物品不可交易**:不依赖于物品的使用状态或归属,始终保持不变
+
+### 11.2 绑定类型
+
+系统支持多种绑定类型,可以根据游戏需求灵活配置:
+
+#### 11.2.1 按绑定时机分类
+
+1. **不绑定**:物品可以自由交易和转移
+2. **获取绑定**:物品一旦被玩家获取后绑定到该玩家账号
+3. **使用绑定**:物品在首次使用后绑定到玩家账号
+4. **装备绑定**:装备类物品在首次装备后绑定
+
+#### 11.2.2 按绑定对象分类
+
+1. **角色绑定**:物品绑定到特定角色,不可在同一账号的不同角色间转移
+2. **账号绑定**:物品绑定到账号,可在同一账号的不同角色间转移
+
+#### 11.2.3 按绑定时长分类
+
+1. **永久绑定**:一旦绑定,永远不会解除
+2. **时间绑定**:物品在特定时间段内绑定,之后可以解除绑定
+
+### 11.3 数据库设计
+
+物品绑定机制主要针对单独属性物品(item_instances),因为这些物品具有独特性和个体差异。
+
+#### 11.3.1 item_instances 表中的绑定相关字段
+
+| 字段名 | 类型 | 说明 |
+| --- | --- | --- |
+| is_bound | tinyint | 是否已绑定(0:未绑定, 1:已绑定) |
+| bound_to | varchar | 绑定对象(账号ID或角色ID) |
+| bind_exp_time | timestamp | 绑定过期时间(为空表示永久绑定) |
+
+这种设计的优势:
+
+1. **与物品实例直接关联**:绑定状态直接与物品实例关联,而不是与用户物品关系关联
+2. **简化数据查询**:不需要跨表查询即可获取物品的绑定状态
+3. **更好的语义表达**:绑定是物品实例的属性,而不是用户与物品关系的属性
+4. **支持物品转移**:当物品在用户间转移时,绑定状态随物品实例一起转移
+
+### 11.4 绑定状态处理逻辑
+
+物品绑定状态的处理逻辑主要针对单独属性物品(item_instances):
+
+#### 11.4.1 获取绑定处理
+
+```php
+// 伪代码示例
+public function handleAcquireBind($itemId, $instanceId, $userId)
+{
+    $item = Item::find($itemId);
+
+    // 检查物品是否需要获取绑定
+    if ($item->bind_type == 1) { // 获取绑定
+        $instance = ItemInstance::find($instanceId);
+        $instance->is_bound = 1;
+        $instance->bound_to = $userId;
+        $instance->bind_exp_time = null; // 永久绑定
+        $instance->save();
+
+        // 记录绑定日志
+        $this->logItemBind($instanceId, $userId, 'acquire');
+    }
+}
+```
+
+#### 11.4.2 使用绑定处理
+
+```php
+// 伪代码示例
+public function handleUseBind($itemId, $instanceId, $userId)
+{
+    $item = Item::find($itemId);
+
+    // 检查物品是否需要使用绑定
+    if ($item->bind_type == 2) { // 使用绑定
+        $instance = ItemInstance::find($instanceId);
+
+        // 只有未绑定的物品才需要处理
+        if ($instance->is_bound == 0) {
+            $instance->is_bound = 1;
+            $instance->bound_to = $userId;
+            $instance->bind_exp_time = null; // 永久绑定
+            $instance->save();
+
+            // 记录绑定日志
+            $this->logItemBind($instanceId, $userId, 'use');
+        }
+    }
+}
+```
+
+#### 11.4.3 装备绑定处理
+
+```php
+// 伪代码示例
+public function handleEquipBind($itemId, $instanceId, $userId)
+{
+    $item = Item::find($itemId);
+
+    // 检查物品是否需要装备绑定
+    if ($item->bind_type == 3) { // 装备绑定
+        $instance = ItemInstance::find($instanceId);
+
+        // 只有未绑定的物品才需要处理
+        if ($instance->is_bound == 0) {
+            $instance->is_bound = 1;
+            $instance->bound_to = $userId;
+            $instance->bind_exp_time = null; // 永久绑定
+            $instance->save();
+
+            // 记录绑定日志
+            $this->logItemBind($instanceId, $userId, 'equip');
+        }
+    }
+}
+```
+
+#### 11.4.4 临时绑定处理
+
+```php
+// 伪代码示例
+public function handleTimeBind($itemId, $instanceId, $userId, $bindDuration)
+{
+    $item = Item::find($itemId);
+
+    // 检查物品是否需要时间绑定
+    if ($item->bind_type == 6) { // 时间绑定
+        $instance = ItemInstance::find($instanceId);
+        $instance->is_bound = 1;
+        $instance->bound_to = $userId;
+
+        // 计算绑定过期时间
+        $expTime = now()->addSeconds($bindDuration);
+        $instance->bind_exp_time = $expTime;
+        $instance->save();
+
+        // 记录绑定日志
+        $this->logItemBind($instanceId, $userId, 'time', $expTime);
+    }
+}
+```
+
+### 11.5 绑定物品的交易限制
+
+单独属性物品的交易限制由两个因素决定:物品的可交易性(tradable)和绑定状态(is_bound):
+
+#### 11.5.1 交易检查流程
+
+```php
+// 伪代码示例
+public function canTrade($instanceId, $fromUserId, $toUserId)
+{
+    $instance = ItemInstance::find($instanceId);
+
+    // 检查物品是否可交易
+    if ($instance->tradable == 0) {
+        return [
+            'can_trade' => false,
+            'reason' => 'item_not_tradable'
+        ];
+    }
+
+    // 检查物品是否已绑定
+    if ($instance->is_bound == 1) {
+        // 检查绑定对象
+        if ($instance->bound_to != $fromUserId) {
+            return [
+                'can_trade' => false,
+                'reason' => 'item_bound_to_another_user'
+            ];
+        }
+
+        // 检查绑定类型(账号绑定可以在同一账号的角色间转移)
+        $fromUser = User::find($fromUserId);
+        $toUser = User::find($toUserId);
+
+        if ($fromUser->account_id != $toUser->account_id) {
+            return [
+                'can_trade' => false,
+                'reason' => 'item_bound_to_account'
+            ];
+        }
+    }
+
+    return [
+        'can_trade' => true
+    ];
+}
+```
+
+#### 11.5.2 商店出售限制
+
+```php
+// 伪代码示例
+public function canSellToShop($instanceId, $userId)
+{
+    $instance = ItemInstance::find($instanceId);
+
+    // 不可交易物品通常不能出售给NPC商店
+    if ($instance->tradable == 0) {
+        return [
+            'can_sell' => false,
+            'reason' => 'item_not_tradable'
+        ];
+    }
+
+    // 已绑定物品只能由绑定的玩家出售
+    if ($instance->is_bound == 1 && $instance->bound_to != $userId) {
+        return [
+            'can_sell' => false,
+            'reason' => 'item_bound_to_another_user'
+        ];
+    }
+
+    return [
+        'can_sell' => true,
+        // 已绑定物品可能有价格折扣
+        'price_modifier' => $instance->is_bound ? 0.5 : 1.0
+    ];
+}
+```
+
+#### 11.5.3 邮件发送限制
+
+```php
+// 伪代码示例
+public function canSendByMail($instanceId, $fromUserId, $toUserId)
+{
+    // 邮件发送限制与交易限制相同
+    return $this->canTrade($instanceId, $fromUserId, $toUserId);
+}
+```
+
+### 11.6 应用场景
+
+物品绑定机制适用于多种场景:
+
+#### 11.6.1 任务奖励
+
+重要任务奖励通常设置为获取绑定,确保玩家亲自完成任务:
+
+```php
+// 伪代码示例
+public function giveQuestReward($userId, $questId)
+{
+    $quest = Quest::find($questId);
+
+    foreach ($quest->rewards as $reward) {
+        $itemId = $reward['item_id'];
+        $quantity = $reward['quantity'];
+
+        // 创建物品实例并设置为获取绑定
+        $instanceId = $this->createItemInstance($itemId);
+        $this->handleAcquireBind($itemId, $instanceId, $userId);
+
+        // 添加到用户背包
+        $this->addItemInstanceToUser($userId, $itemId, $instanceId);
+    }
+}
+```
+
+#### 11.6.2 成就奖励
+
+成就奖励物品通常设置为账号绑定,表彰玩家的个人成就:
+
+```php
+// 伪代码示例
+public function giveAchievementReward($userId, $achievementId)
+{
+    $achievement = Achievement::find($achievementId);
+    $user = User::find($userId);
+
+    foreach ($achievement->rewards as $reward) {
+        $itemId = $reward['item_id'];
+        $quantity = $reward['quantity'];
+
+        // 创建物品实例并设置为账号绑定
+        $instanceId = $this->createItemInstance($itemId);
+        $instance = ItemInstance::find($instanceId);
+        $instance->is_bound = 1;
+        $instance->bound_to = $user->account_id; // 绑定到账号
+        $instance->save();
+
+        // 添加到用户背包
+        $this->addItemInstanceToUser($userId, $itemId, $instanceId);
+    }
+}
+```
+
+#### 11.6.3 活动物品
+
+活动限定物品通常设置为获取绑定,防止二次交易:
+
+```php
+// 伪代码示例
+public function giveEventItem($userId, $eventId, $itemId)
+{
+    $event = Event::find($eventId);
+
+    // 创建物品实例并设置为获取绑定
+    $instanceId = $this->createItemInstance($itemId);
+    $this->handleAcquireBind($itemId, $instanceId, $userId);
+
+    // 添加到用户背包
+    $this->addItemInstanceToUser($userId, $itemId, $instanceId);
+}
+```
+
+### 11.7 绑定状态的显示
+
+在游戏界面中,应清晰显示物品的绑定状态:
+
+#### 11.7.1 物品图标标记
+
+已绑定物品在图标上添加特殊标记,区分不同的绑定类型:
+
+```php
+// 伪代码示例
+public function getItemIconWithBindMark($itemId, $instanceId)
+{
+    $item = Item::find($itemId);
+    $iconPath = $item->icon;
+
+    if ($instanceId) {
+        $instance = ItemInstance::find($instanceId);
+
+        if ($instance->is_bound) {
+            // 根据绑定类型添加不同的标记
+            if ($instance->bind_exp_time) {
+                return $iconPath . '?mark=time_bound';
+            } else {
+                return $iconPath . '?mark=bound';
+            }
+        }
+    }
+
+    return $iconPath;
+}
+```
+
+#### 11.7.2 物品描述
+
+在物品描述中注明绑定类型和状态:
+
+```php
+// 伪代码示例
+public function getItemDescription($itemId, $instanceId)
+{
+    $item = Item::find($itemId);
+    $description = $item->description;
+
+    if ($instanceId) {
+        $instance = ItemInstance::find($instanceId);
+
+        if ($instance->is_bound) {
+            $description .= "\n已绑定到: " . $this->getBindTargetName($instance->bound_to);
+
+            if ($instance->bind_exp_time) {
+                $description .= "\n绑定解除时间: " . $instance->bind_exp_time;
+            } else {
+                $description .= "\n永久绑定";
+            }
+        }
+    }
+
+    return $description;
+}
+```
+
+#### 11.7.3 交易提示
+
+尝试交易绑定物品时,显示明确的错误提示:
+
+```php
+// 伪代码示例
+public function getTradeErrorMessage($result)
+{
+    switch ($result['reason']) {
+        case 'item_not_tradable':
+            return "该物品不可交易";
+        case 'item_bound_to_another_user':
+            return "该物品已绑定到其他玩家,无法交易";
+        case 'item_bound_to_account':
+            return "该物品已绑定到账号,只能在同一账号的角色间转移";
+        default:
+            return "无法交易该物品";
+    }
+}
+
+## 12. 系统交互
+
+GameItems模块作为游戏的核心系统之一,与其他多个系统有紧密的交互关系。
+
+### 12.1 与其他系统的交互
+
+#### 12.1.1 与用户系统交互
+
+物品系统需要与用户系统交互,确保物品正确关联到用户:
+
+```php
+// 伪代码示例
+public function checkUserExists($userId)
+{
+    $user = User::find($userId);
+    if (!$user) {
+        throw new UserNotFoundException("用户不存在: $userId");
+    }
+    return $user;
+}
+```
+
+#### 12.1.2 与任务系统交互
+
+物品系统与任务系统交互,支持任务相关的物品操作:
+
+```php
+// 伪代码示例
+public function checkQuestItemRequirement($userId, $questId)
+{
+    $quest = Quest::find($questId);
+    $requirements = $quest->item_requirements;
+
+    foreach ($requirements as $req) {
+        $itemId = $req['item_id'];
+        $quantity = $req['quantity'];
+
+        $userItem = UserItem::where('user_id', $userId)
+            ->where('item_id', $itemId)
+            ->first();
+
+        if (!$userItem || $userItem->quantity < $quantity) {
+            return false;
+        }
+    }
+
+    return true;
+}
+```
+
+#### 12.1.3 与商店系统交互
+
+物品系统与商店系统交互,支持物品的购买和出售:
+
+```php
+// 伪代码示例
+public function buyItemFromShop($userId, $shopItemId, $quantity)
+{
+    $shopItem = ShopItem::find($shopItemId);
+    $itemId = $shopItem->item_id;
+    $price = $shopItem->price * $quantity;
+
+    // 检查用户余额
+    $user = User::find($userId);
+    if ($user->balance < $price) {
+        return [
+            'success' => false,
+            'message' => '余额不足'
+        ];
+    }
+
+    // 扣除余额
+    $user->balance -= $price;
+    $user->save();
+
+    // 添加物品
+    $this->addItemToUser($userId, $itemId, $quantity);
+
+    return [
+        'success' => true,
+        'item_id' => $itemId,
+        'quantity' => $quantity,
+        'price' => $price
+    ];
+}
+```
+
+#### 12.1.4 与邮件系统交互
+
+物品系统与邮件系统交互,支持通过邮件发送物品:
+
+```php
+// 伪代码示例
+public function sendItemByMail($fromUserId, $toUserId, $itemId, $quantity, $message)
+{
+    // 检查物品是否可以发送
+    if (!$this->canSendItem($fromUserId, $itemId, $quantity)) {
+        return [
+            'success' => false,
+            'message' => '物品不可发送'
+        ];
+    }
+
+    // 从发送者背包中扣除物品
+    $this->removeItemFromUser($fromUserId, $itemId, $quantity);
+
+    // 创建邮件
+    $mail = Mail::create([
+        'from_user_id' => $fromUserId,
+        'to_user_id' => $toUserId,
+        'subject' => '物品发送',
+        'message' => $message,
+        'has_attachment' => 1
+    ]);
+
+    // 添加邮件附件
+    MailAttachment::create([
+        'mail_id' => $mail->id,
+        'item_id' => $itemId,
+        'quantity' => $quantity
+    ]);
+
+    return [
+        'success' => true,
+        'mail_id' => $mail->id
+    ];
+}
+```
+
+### 12.2 事件系统
+
+物品系统使用事件机制与其他系统进行松耦合交互:
+
+#### 12.2.1 物品相关事件
+
+系统定义了以下物品相关事件:
+
+1. **ItemAdded**:物品添加到用户背包时触发
+2. **ItemRemoved**:物品从用户背包移除时触发
+3. **ItemUsed**:物品被使用时触发
+4. **ItemTraded**:物品被交易时触发
+5. **ChestOpened**:宝箱被开启时触发
+6. **ItemCrafted**:物品被合成时触发
+7. **ItemDismantled**:物品被分解时触发
+8. **ItemBound**:物品被绑定时触发
+
+#### 12.2.2 事件监听
+
+其他系统可以监听这些事件并执行相应操作:
+
+```php
+// 伪代码示例
+// 在服务提供者中注册事件监听
+public function boot()
+{
+    Event::listen(ItemAdded::class, function ($event) {
+        // 更新任务进度
+        $this->questService->updateItemCollectionProgress(
+            $event->userId,
+            $event->itemId,
+            $event->quantity
+        );
+
+        // 更新成就进度
+        $this->achievementService->updateItemCollectionProgress(
+            $event->userId,
+            $event->itemId,
+            $event->quantity
+        );
+    });
+}
+```
+
+### 12.3 API接口
+
+物品系统提供以下API接口供其他系统调用:
+
+#### 12.3.1 物品查询接口
+
+```php
+// 伪代码示例
+public function getUserItems($userId, $filters = [])
+{
+    $query = UserItem::where('user_id', $userId);
+
+    // 应用过滤条件
+    if (isset($filters['item_id'])) {
+        $query->where('item_id', $filters['item_id']);
+    }
+
+    if (isset($filters['category_id'])) {
+        $query->whereHas('item', function ($q) use ($filters) {
+            $q->where('category_id', $filters['category_id']);
+        });
+    }
+
+    // 排除过期物品
+    $query->where(function ($q) {
+        $q->whereNull('expire_at')
+          ->orWhere('expire_at', '>', now());
+    });
+
+    return $query->get();
+}
+```
+
+#### 12.3.2 物品操作接口
+
+```php
+// 伪代码示例
+public function addItem($userId, $itemId, $quantity, $options = [])
+{
+    // 检查用户是否存在
+    $this->checkUserExists($userId);
+
+    // 检查物品是否存在
+    $item = Item::find($itemId);
+    if (!$item) {
+        throw new ItemNotFoundException("物品不存在: $itemId");
+    }
+
+    // 处理单独属性物品
+    if ($item->is_unique) {
+        return $this->addUniqueItem($userId, $itemId, $options);
+    }
+
+    // 处理统一属性物品
+    return $this->addNormalItem($userId, $itemId, $quantity, $options);
+}
+```
+
+## 13. 最佳实践与注意事项
+
+### 13.1 性能优化
+
+为确保物品系统的高性能运行,应遵循以下最佳实践:
+
+#### 13.1.1 数据库优化
+
+1. **合理使用索引**:
+   - 为频繁查询的字段创建索引
+   - 避免过多索引导致写入性能下降
+   - 定期分析查询性能,优化索引设计
+
+2. **批量操作**:
+   - 使用批量插入和更新减少数据库操作次数
+   - 对于大量物品操作,使用事务确保原子性
+
+3. **分表策略**:
+   - 对于高频访问的日志表,考虑按时间或用户ID分表
+   - 历史数据可以归档到单独的表中
+
+#### 13.1.2 缓存策略
+
+1. **用户物品缓存**:
+   - 缓存用户常用物品列表,减少数据库查询
+   - 使用Redis等内存数据库存储临时数据
+
+2. **物品定义缓存**:
+   - 缓存物品基础定义,避免重复查询
+   - 使用缓存标签管理相关缓存
+
+3. **缓存失效策略**:
+   - 在物品数据变更时主动清除相关缓存
+   - 设置合理的缓存过期时间
+
+#### 13.1.3 异步处理
+
+1. **队列处理**:
+   - 使用队列处理非即时性操作,如日志记录
+   - 批量物品操作可以放入队列异步处理
+
+2. **定时任务**:
+   - 使用定时任务处理物品过期、绑定解除等周期性操作
+   - 将资源密集型操作安排在服务器负载较低的时间执行
+
+### 13.2 安全考虑
+
+物品系统涉及游戏经济核心,需要特别注意安全性:
+
+#### 13.2.1 防作弊措施
+
+1. **操作验证**:
+   - 所有物品操作都需要进行权限和合法性验证
+   - 敏感操作(如删除物品)需要额外的验证步骤
+
+2. **异常监控**:
+   - 监控异常的物品获取和消耗模式
+   - 设置物品操作的频率限制和阈值警报
+
+3. **日志审计**:
+   - 记录所有物品操作的详细日志
+   - 定期审计物品流通情况,发现潜在问题
+
+#### 13.2.2 并发控制
+
+1. **乐观锁**:
+   - 使用版本号或时间戳实现乐观锁
+   - 在高并发场景下防止数据不一致
+
+2. **悲观锁**:
+   - 对于关键操作,使用数据库行锁或表锁
+   - 在事务中锁定相关记录,防止并发修改
+
+3. **分布式锁**:
+   - 在分布式环境中,使用Redis等实现分布式锁
+   - 确保跨服务器的操作原子性
+
+### 13.3 通用注意事项
+
+在实现和维护物品系统时,应注意以下事项:
+
+1. **物品使用逻辑**应根据物品类型进行不同处理
+2. **需要考虑物品数量上限和背包容量限制**
+3. **稀有物品获取应有日志记录**
+4. **物品交易需考虑并发安全问题,建议使用数据库事务**
+5. **敏感操作(如删除物品)需要有权限验证**
+6. **在获取用户物品时,始终检查过期时间,不展示已过期物品**
+7. **在添加物品到用户背包时,需要检查全局过期时间**
+8. **宝箱开启操作应使用事务确保原子性**
+9. **宝箱配置应由管理员仔细调整和测试,确保概率合理**
+10. **当物品数量超过最大堆叠数量时,应自动创建新的堆叠**
+11. **在物品产出前应检查产出限制,防止超过预期产出**
+12. **对于关联物品限制,需要同时检查所有相关物品的产出记录**
+13. **定期检查并重置限制计数,确保重置机制正常运行**
+14. **对于限量物品,应设置监控机制,在接近限制时发出警告**
+15. **所有物品获取和消耗操作应记录到交易日志表中**
+16. **宝箱开启操作应同时记录到宝箱开启日志和物品交易日志**
+17. **定期清理和归档旧日志,防止日志表过大影响系统性能**
+18. **对于高频率的日志写入操作,考虑使用队列或批量写入方式提高性能**
+19. **物品合成操作应使用事务确保原子性,防止材料扣除后合成失败导致数据不一致**
+20. **合成配方的成功率和奖励应由管理员仔细调整和测试,确保游戏平衡**
+21. **对于高价值物品的合成,应考虑添加额外的验证和确认机制**
+22. **合成系统应考虑与物品产出限制系统集成,防止通过合成绕过产出限制**
+23. **处理多币种成本时,应确保在事务中同时检查和扣除所有必要的代币,防止部分扣除导致的数据不一致**
+24. **绑定物品的状态变更应在事务中处理,确保数据一致性**
+25. **对于时间绑定物品,需要定期检查并更新绑定状态**
+26. **在物品交易前,必须检查物品的绑定状态,防止绑定物品被交易**
+27. **物品分解操作应使用事务确保原子性,防止物品被扣除但未获得分解结果**
+28. **分解绑定物品时,获得的材料应继承绑定状态**
+29. **分解单独属性物品时,应考虑物品的特殊属性对分解结果的影响**
+30. **批量分解时,应注意性能优化,避免大量物品同时分解导致系统负担**
+

+ 0 - 0
app/Module/GameItems/WORK.md → app/Module/GameItems/Docs/WORK.md


+ 704 - 2653
app/Module/GameItems/README.md

@@ -1,22 +1,17 @@
-# GameItems模块
+# GameItems 游戏物品模块
 
 
 > 游戏物品系统 - 综合管理游戏内所有物品的生命周期
 > 游戏物品系统 - 综合管理游戏内所有物品的生命周期
 
 
 ## 目录
 ## 目录
 
 
 1. [模块概述](#1-模块概述)
 1. [模块概述](#1-模块概述)
-2. [数据结构设计](#2-数据结构设计)
-3. [核心功能](#3-核心功能)
-4. [物品过期机制](#4-物品过期机制)
-5. [宝箱系统](#5-宝箱系统)
-6. [物品获取与堆叠](#6-物品获取与堆叠)
-7. [物品产出限制](#7-物品产出限制)
-8. [日志记录系统](#8-日志记录系统)
-9. [物品合成系统](#9-物品合成系统)
-10. [物品分解系统](#10-物品分解系统)
-11. [物品绑定机制](#11-物品绑定机制)
-12. [系统交互](#12-系统交互)
-13. [最佳实践与注意事项](#13-最佳实践与注意事项)
+2. [目录结构](#2-目录结构)
+3. [架构设计](#3-架构设计)
+4. [核心服务](#4-核心服务)
+5. [数据模型](#5-数据模型)
+6. [业务逻辑](#6-业务逻辑)
+7. [使用示例](#7-使用示例)
+8. [最佳实践](#8-最佳实践)
 
 
 ## 1. 模块概述
 ## 1. 模块概述
 
 
@@ -39,58 +34,128 @@ GameItems模块是游戏核心系统之一,负责管理游戏内所有物品
 
 
 ### 1.3 核心特点
 ### 1.3 核心特点
 
 
-1. **多物品宝箱系统**:支持一个宝箱同时掉落多个物品,可配置数量范围和概率
-2. **灵活的过期机制**:支持全局过期时间和用户特定过期时间
-3. **完善的属性系统**:通过JSON格式存储物品属性,支持复杂物品效果
-4. **单独属性物品**:支持每个物品实例拥有独特属性(如装备)
-5. **物品绑定机制**:限制物品流通,保持游戏经济平衡
-6. **物品产出限制**:控制稀有物品的产出数量和频率
-7. **全面的日志系统**:记录所有物品相关操作,支持数据分析和问题排查
-
-## 2. 数据结构设计
-
-### 2.1 设计原则
-
-游戏物品模块采用关系型数据库设计,通过多个相互关联的数据表实现物品管理。数据结构设计遵循以下原则:
-
-1. **模块化**:各个表结构清晰,职责单一
-2. **扩展性**:支持通过属性表扩展物品特性,无需修改数据库结构
-3. **性能优化**:合理的索引设计和关联关系
-4. **数据完整性**:使用外键和事务确保数据一致性
-
-### 2.2 核心数据表
-
-#### 2.2.1 物品基础表
+- **多物品宝箱系统**:支持一个宝箱同时掉落多种物品,可配置数量范围和概率
+- **保底机制**:支持在开启一定次数后必定获得指定物品
+- **灵活的过期机制**:支持全局过期和用户特定过期
+- **物品属性扩展**:支持通过JSON格式存储的键值对属性,实现复杂效果
+- **物品分类与组**:支持物品分类和物品组,便于管理和配置
+
+## 2. 目录结构
+
+```
+app/Module/GameItems/
+├── AdminControllers/        # 后台管理控制器
+│   ├── Helper/              # 控制器辅助类
+│   ├── Actions/             # 控制器动作类
+│   └── LazyRenderable/      # 懒加载渲染类
+├── Commands/                # 命令行工具
+├── Casts/                   # 自定义类型转换器
+├── Databases/               # 数据库相关文件
+│   └── create.sql           # 数据库创建脚本
+├── Enums/                   # 枚举类型定义
+├── Events/                  # 事件类
+├── Exceptions/              # 异常类
+├── Logics/                  # 业务逻辑类
+├── Models/                  # 数据模型
+├── Providers/               # 服务提供者
+├── Repositorys/             # 数据仓库
+├── Services/                # 服务类
+└── README.md                # 模块文档
+```
+
+### 2.1 主要目录说明
+
+- **AdminControllers/**: 包含所有后台管理界面的控制器,用于物品、宝箱、配方等的管理
+  - **Helper/**: 控制器辅助类,如表单、表格、筛选器等帮助类
+  - **Actions/**: 控制器动作类,如复制、导出等操作
+  - **LazyRenderable/**: 懒加载渲染类,用于异步加载数据
+- **Commands/**: 命令行工具,如数据导入导出、配置生成等
+- **Casts/**: 自定义类型转换器,用于处理JSON属性等特殊字段
+- **Enums/**: 定义模块中使用的所有枚举类型,如物品类型、交易类型等
+- **Events/**: 定义模块触发的事件,用于模块间的松耦合通信
+- **Exceptions/**: 自定义异常类,用于处理业务异常
+- **Logics/**: 业务逻辑类,处理具体的业务规则,内部使用
+- **Models/**: 数据模型,定义数据结构和关系
+- **Providers/**: 服务提供者,用于注册服务和事件
+- **Repositorys/**: 数据仓库,封装数据库操作
+- **Services/**: 服务类,对外提供功能接口
+
+## 3. 架构设计
+
+### 3.1 模块架构
+
+GameItems模块采用分层架构设计,遵循"服务是对外的,Logic是内部的"原则:
+
+- **Models层**:数据模型,定义数据结构和关系
+- **Logics层**:业务逻辑,处理具体的业务规则
+- **Services层**:服务接口,对外提供功能,调用Logics层处理业务
+- **Controllers层**:控制器,处理HTTP请求,调用Services层
+- **Repositories层**:数据访问层,封装数据库操作
+
+### 2.2 核心类关系
+
+```
+Services
+  ├── ItemService - 物品基础服务
+  ├── ChestService - 宝箱服务
+  ├── CraftService - 合成服务
+  └── DismantleService - 分解服务
+
+Logics
+  ├── Item - 物品逻辑
+  ├── ChestContent - 宝箱内容逻辑
+  ├── PityTime - 保底计数逻辑
+  ├── ItemInstance - 物品实例逻辑
+  ├── UserRecipe - 用户配方逻辑
+  ├── Recipe - 配方逻辑
+  ├── UserOutputCounter - 用户产出计数逻辑
+  └── Group - 物品组逻辑
+
+Models
+  ├── Item - 物品基础信息
+  ├── ItemCategory - 物品分类
+  ├── ItemInstance - 物品实例(单独属性物品)
+  ├── ItemUser - 用户物品关联
+  ├── ItemGroup - 物品组
+  ├── ItemGroupItem - 物品组内容
+  ├── ItemChestContent - 宝箱内容配置
+  ├── ItemPityTime - 宝箱保底计数
+  ├── ItemChestOpenLog - 宝箱开启记录
+  ├── ItemRecipe - 物品合成配方
+  ├── ItemRecipeMaterial - 合成配方材料
+  ├── ItemUserRecipe - 用户配方解锁状态
+  ├── ItemCraftLog - 物品合成记录
+  ├── ItemDismantleRule - 物品分解规则
+  ├── ItemDismantleResult - 分解结果配置
+  ├── ItemDismantleLog - 物品分解记录
+  ├── ItemOutputLimit - 物品产出限制
+  ├── ItemUserOutputCounter - 用户产出计数
+  └── ItemTransactionLog - 物品交易记录
+```
+
+### 2.3 设计原则
+
+1. **单一职责原则**:每个类只负责一个功能领域
+2. **关注点分离**:模型只负责数据结构,业务逻辑由Logic类处理
+3. **依赖注入**:通过构造函数注入依赖,提高可测试性
+4. **事务完整性**:所有涉及多个操作的功能都使用数据库事务确保原子性
+5. **日志记录**:关键操作都有详细的日志记录,便于追踪和分析
+
+## 3. 数据结构
+
+### 3.1 核心表结构
 
 
 | 表名 | 主要功能 | 关键字段 |
 | 表名 | 主要功能 | 关键字段 |
 |------|---------|---------|
 |------|---------|---------|
-| item_categories | 物品分类管理 | id, name, code, parent_id |
 | item_items | 统一属性物品定义 | id, name, type, is_unique, attributes |
 | item_items | 统一属性物品定义 | id, name, type, is_unique, attributes |
+| item_categories | 物品分类管理 | id, name, code, parent_id |
 | item_instances | 单独属性物品实例 | id, item_id, attributes, is_bound |
 | item_instances | 单独属性物品实例 | id, item_id, attributes, is_bound |
 | item_users | 用户物品关联 | user_id, item_id, instance_id, quantity |
 | item_users | 用户物品关联 | user_id, item_id, instance_id, quantity |
 | item_groups | 物品组定义 | id, name, code |
 | item_groups | 物品组定义 | id, name, code |
 | item_group_items | 物品组内容 | group_id, item_id, weight |
 | item_group_items | 物品组内容 | group_id, item_id, weight |
-
-#### 2.2.2 宝箱系统表
-
-| 表名 | 主要功能 | 关键字段 |
-|------|---------|---------|
 | item_chest_contents | 宝箱内容配置 | chest_id, item_id/group_id, weight |
 | item_chest_contents | 宝箱内容配置 | chest_id, item_id/group_id, weight |
 | item_pity_times | 用户宝箱保底计数 | user_id, chest_id, chest_content_id, current_count |
 | item_pity_times | 用户宝箱保底计数 | user_id, chest_id, chest_content_id, current_count |
 | item_chest_open_logs | 宝箱开启记录 | user_id, chest_id, result_items, pity_triggered |
 | item_chest_open_logs | 宝箱开启记录 | user_id, chest_id, result_items, pity_triggered |
-
-#### 2.2.3 物品限制与日志表
-
-| 表名 | 主要功能 | 关键字段 |
-|------|---------|---------|
-| item_output_limits | 物品产出限制 | item_id, limit_type, max_quantity |
-| item_user_output_counters | 用户产出限制计数 | user_id, limit_id, current_count |
-| item_transaction_logs | 物品交易记录 | user_id, item_id, quantity, transaction_type |
-
-#### 2.2.4 物品合成与分解表
-
-| 表名 | 主要功能 | 关键字段 |
-|------|---------|---------|
 | item_recipes | 合成配方定义 | id, result_item_id, success_rate |
 | item_recipes | 合成配方定义 | id, result_item_id, success_rate |
 | item_recipe_materials | 配方材料需求 | recipe_id, item_id, quantity |
 | item_recipe_materials | 配方材料需求 | recipe_id, item_id, quantity |
 | item_user_recipes | 用户配方解锁状态 | user_id, recipe_id, is_unlocked |
 | item_user_recipes | 用户配方解锁状态 | user_id, recipe_id, is_unlocked |
@@ -98,2748 +163,734 @@ GameItems模块是游戏核心系统之一,负责管理游戏内所有物品
 | item_dismantle_rules | 物品分解规则 | item_id/category_id, priority |
 | item_dismantle_rules | 物品分解规则 | item_id/category_id, priority |
 | item_dismantle_results | 分解结果配置 | rule_id, result_item_id, chance |
 | item_dismantle_results | 分解结果配置 | rule_id, result_item_id, chance |
 | item_dismantle_logs | 物品分解记录 | user_id, item_id, results |
 | item_dismantle_logs | 物品分解记录 | user_id, item_id, results |
+| item_output_limits | 物品产出限制 | item_id, limit_type, max_quantity |
+| item_user_output_counters | 用户产出计数 | user_id, limit_id, current_count |
+| item_transaction_logs | 物品交易记录 | user_id, item_id, quantity, transaction_type |
 
 
-### 2.3 详细表结构
-
-#### 2.3.1 item_categories 表(物品分类)
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 分类ID,主键 |
-| name | varchar | 分类名称 |
-| code | varchar | 分类编码(唯一) |
-| icon | varchar | 分类图标 |
-| sort | int | 排序权重 |
-| parent_id | int | 父分类ID(可为空,用于实现分类层级) |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-#### 2.3.2 item_items 表(统一属性物品)
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 物品ID,主键 |
-| name | varchar | 物品名称 |
-| description | text | 物品描述 |
-| category_id | int | 物品分类ID,外键关联item_categories表 |
-| type | tinyint | 物品类型(1:可使用, 2:可装备, 3:可合成, 4:可交任务, 5:可开启...) |
-| is_unique | tinyint | 是否是单独属性物品(0:否,默认, 1:是) |
-| icon | varchar | 物品图标路径 |
-| max_stack | int | 最大堆叠数量 |
-| sell_price | int | 出售价格 |
-| tradable | tinyint | 是否可交易(0:不可交易, 1:可交易,默认) |
-| dismantlable | tinyint | 是否可分解(0:不可分解, 1:可分解,默认) |
-| default_expire_seconds | int | 玩家获取物品后的默认有效秒数(0表示永久有效) |
-| display_attributes | json | 展示属性,以JSON格式存储键值对,用于界面展示和描述的属性 |
-| numeric_attributes | json | 数值属性,以JSON格式存储键值对,用于计算和游戏逻辑的属性 |
-| global_expire_at | timestamp | 物品全局过期时间(可为空) |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-#### 2.3.3 item_instances 表(单独属性物品)
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 唯一物品ID,主键 |
-| item_id | int | 关联的基础物品ID,外键关联item_items表 |
-| name | varchar | 物品名称(可以与基础物品不同,如"锐利的钢刀") |
-| display_attributes | json | 展示属性,以JSON格式存储键值对,用于界面展示和描述的属性 |
-| numeric_attributes | json | 数值属性,以JSON格式存储键值对,用于计算和游戏逻辑的属性 |
-| tradable | tinyint | 是否可交易(0:不可交易, 1:可交易,默认) |
-| is_bound | tinyint | 是否已绑定(0:未绑定, 1:已绑定) |
-| bound_to | varchar | 绑定对象(账号ID或角色ID) |
-| bind_exp_time | timestamp | 绑定过期时间(为空表示永久绑定) |
-| expire_at | timestamp | 物品过期时间(可为空) |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-#### 2.3.4 item_users 表(用户物品关联)
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 记录ID,主键 |
-| user_id | int | 用户ID,外键 |
-| item_id | int | 统一属性物品ID,外键关联item_items表(始终有值) |
-| instance_id | int | 单独属性物品ID,外键关联item_instances表(可为空) |
-| quantity | int | 数量(对于单独属性物品,该值始终为1) |
-| expire_at | timestamp | 用户物品过期时间(可为空) |
-| created_at | timestamp | 获取时间 |
-| updated_at | timestamp | 更新时间 |
-
-### 2.4 数据库索引设计
-
-为确保系统高性能运行,对关键字段进行了索引设计:
-
-#### 2.4.1 物品基础表索引
-
-| 表名 | 索引字段 | 索引类型 | 说明 |
-| --- | --- | --- | --- |
-| item_items | id | 主键 | 物品ID主键索引 |
-| item_items | category_id | 普通索引 | 加速按物品分类查询 |
-| item_items | type | 普通索引 | 加速按物品类型查询 |
-| item_items | is_unique | 普通索引 | 加速查询单独属性物品 |
-| item_items | tradable | 普通索引 | 加速查询可交易/不可交易物品 |
-| item_items | dismantlable | 普通索引 | 加速查询可分解/不可分解物品 |
-| item_items | global_expire_at | 普通索引 | 加速过期物品查询 |
-| item_categories | id | 主键 | 分类ID主键索引 |
-| item_categories | parent_id | 普通索引 | 加速查询子分类 |
-| item_categories | code | 唯一索引 | 确保分类编码唯一性 |
-| item_instances | id | 主键 | 唯一物品ID主键索引 |
-| item_instances | item_id | 普通索引 | 加速根据基础物品查询唯一物品 |
-| item_instances | tradable | 普通索引 | 加速查询可交易/不可交易的单独属性物品 |
-| item_instances | is_bound | 普通索引 | 加速查询已绑定的单独属性物品 |
-| item_instances | bound_to | 普通索引 | 加速查询绑定到特定对象的单独属性物品 |
-| item_instances | bind_exp_time | 普通索引 | 加速查询需要解绑的单独属性物品 |
-| item_instances | expire_at | 普通索引 | 加速过期物品查询 |
-| item_users | user_id, item_id | 复合索引 | 加速用户统一属性物品查询 |
-| item_users | user_id, instance_id | 复合索引 | 加速用户单独属性物品查询 |
-| item_users | expire_at | 普通索引 | 加速过期物品查询 |
-
-#### 2.4.2 宝箱系统表索引
-
-| 表名 | 索引字段 | 索引类型 | 说明 |
-| --- | --- | --- | --- |
-| item_chest_contents | chest_id | 普通索引 | 加速宝箱内容查询 |
-| item_chest_contents | item_id | 普通索引 | 加速物品在宝箱中的查询 |
-| item_chest_contents | group_id | 普通索引 | 加速查询物品组在宝箱中的配置 |
-| item_chest_contents | pity_count | 普通索引 | 加速查询启用保底的宝箱内容 |
-| item_pity_times | user_id, chest_id, chest_content_id | 复合索引 | 加速查询用户对特定宝箱内容的保底计数 |
-| item_chest_open_logs | user_id, open_time | 复合索引 | 加速查询用户的宝箱开启历史 |
-| item_chest_open_logs | chest_id | 普通索引 | 加速查询特定宝箱的开启记录 |
-
-### 2.5 数据模型关联关系
-
-以下是主要数据模型之间的关联关系:
-
-1. **用户与物品关系**
-   - 用户可以拥有统一属性物品和单独属性物品,通过 item_users 表关联
-   - 对于统一属性物品,直接关联 item_items 表
-   - 对于单独属性物品,通过 item_instances 表间接关联 item_items 表
-
-2. **物品分类层级**
-   - item_categories 表通过 parent_id 字段实现自关联,形成分类层级结构
-   - item_items 表通过 category_id 字段关联到 item_categories 表
-
-3. **物品组与物品**
-   - item_groups 表定义物品组
-   - item_group_items 表建立物品组与物品的多对多关系
-
-4. **宝箱与内容关系**
-   - 宝箱是 item_items 表中 type=5 的特殊物品
-   - item_chest_contents 表定义宝箱可能掉落的内容
-   - 宝箱内容可以是具体物品(item_id)或物品组(group_id)
-
-5. **物品合成关系**
-   - item_recipes 表定义合成配方
-   - item_recipe_materials 表定义配方所需材料
-   - 用户通过 item_user_recipes 表记录已解锁的配方
-
-6. **物品分解关系**
-   - item_dismantle_rules 表定义分解规则
-   - item_dismantle_results 表定义分解可能的结果
-   - 分解规则可以针对特定物品或整个分类
-
-### 2.6 单独属性物品实现
-
-为支持"每个用户拥有的同类物品可以有不同属性"的需求(如不同的武器有不同的属性),系统采用了统一属性物品和单独属性物品两种设计:
-
-#### 2.6.1 实现方式
-
-1. **物品类型区分**
-   - item_items 表中的 is_unique 字段标记该物品是否为单独属性物品
-   - 单独属性物品(如装备)在 item_instances 表中创建独立记录
-   - 统一属性物品(如消耗品)直接使用 item_items 表的属性
-
-2. **属性存储方式**
-   - 基础属性存储在 item_items 表中
-   - 单独属性物品的特殊属性存储在 item_instances 表中
-   - 属性使用 JSON 格式存储,分为展示属性和数值属性
-
-3. **用户物品关联**
-   - item_users 表通过 item_id 和 instance_id 字段关联两种物品
-   - 对于统一属性物品,instance_id 为空,quantity 可以大于1
-   - 对于单独属性物品,instance_id 有值,quantity 始终为1
-
-## 3. 核心功能
-
-### 3.1 物品管理接口
-
-系统提供以下核心接口用于物品管理:
-
-#### 3.1.1 获取用户物品
-
-- **功能**:获取用户拥有的所有物品或特定类型的物品
-- **参数**:用户ID,物品类型(可选),分页参数
-- **返回**:物品列表,包含数量、属性等信息
-- **处理逻辑**:
-  1. 查询用户在 item_users 表中的记录
-  2. 关联 item_items 表获取物品基础信息
-  3. 对于单独属性物品,关联 item_instances 表获取特殊属性
-  4. 过滤掉已过期的物品(检查全局过期和用户物品过期)
-  5. 按类型、分类等条件筛选
-
-#### 3.1.2 添加物品到用户背包
-
-- **功能**:向用户背包添加指定物品
-- **参数**:用户ID、物品ID、数量、过期时间(可选)、属性参数(可选)
-- **返回**:添加结果、当前数量
-- **处理逻辑**:
-  1. 检查物品是否存在
-  2. 检查物品是否有全局过期时间
-  3. 对于统一属性物品:
-     - 检查用户是否已有该物品且过期时间相同
-     - 如果已有,增加数量(注意最大堆叠限制)
-     - 如果没有,创建新记录
-  4. 对于单独属性物品:
-     - 创建 item_instances 记录
-     - 关联到用户
-  5. 记录物品获取日志
-
-#### 3.1.3 使用物品
-
-- **功能**:消耗指定数量的物品并触发效果
-- **参数**:用户ID、物品ID/实例ID、数量、使用参数
-- **返回**:使用结果、剩余数量、触发效果
-- **处理逻辑**:
-  1. 检查用户是否拥有足够数量的物品
-  2. 检查物品是否已过期
-  3. 根据物品类型执行不同的使用逻辑
-  4. 扣除物品数量
-  5. 记录物品消耗日志
-  6. 返回使用效果
-
-#### 3.1.4 删除用户物品
-
-- **功能**:从用户背包中删除指定物品
-- **参数**:用户ID、物品ID/实例ID、数量、删除原因
-- **返回**:删除结果、剩余数量
-- **处理逻辑**:
-  1. 检查用户是否拥有足够数量的物品
-  2. 扣除物品数量
-  3. 如果数量为0,删除记录
-  4. 对于单独属性物品,可选择是否删除 item_instances 记录
-  5. 记录物品删除日志
-
-### 3.2 物品交易接口
-
-系统支持玩家间物品交易和与NPC的交易:
-
-#### 3.2.1 玩家间交易
-
-- **功能**:将物品从一个玩家转移到另一个玩家
-- **参数**:发送方ID、接收方ID、物品ID/实例ID、数量
-- **返回**:交易结果
-- **处理逻辑**:
-  1. 检查物品是否可交易(tradable=1)
-  2. 检查物品是否已绑定(is_bound=0)
-  3. 检查发送方是否拥有足够数量的物品
-  4. 从发送方扣除物品
-  5. 向接收方添加物品
-  6. 记录交易日志
-
-#### 3.2.2 商店购买
-
-- **功能**:玩家使用游戏货币购买物品
-- **参数**:用户ID、物品ID、数量
-- **返回**:购买结果、剩余货币
-- **处理逻辑**:
-  1. 检查物品价格和玩家货币是否足够
-  2. 扣除玩家货币
-  3. 添加物品到玩家背包
-  4. 记录购买日志
-
-#### 3.2.3 商店出售
-
-- **功能**:玩家将物品出售给商店获得货币
-- **参数**:用户ID、物品ID/实例ID、数量
-- **返回**:出售结果、获得货币
-- **处理逻辑**:
-  1. 检查玩家是否拥有足够数量的物品
-  2. 计算出售价格(可能受物品品质、耐久度等影响)
-  3. 从玩家背包中扣除物品
-  4. 增加玩家货币
-  5. 记录出售日志
-
-### 3.3 单独属性物品接口
-
-系统提供以下接口用于管理单独属性物品:
-
-#### 3.3.1 创建单独属性物品
-
-- **功能**:为用户创建具有独特属性的物品
-- **参数**:用户ID、基础物品ID、属性参数
-- **返回**:创建的单独属性物品信息
-- **处理逻辑**:
-  1. 检查基础物品是否存在且 is_unique=1
-  2. 生成物品属性(可能包含随机因素)
-  3. 创建 item_instances 记录
-  4. 关联到用户
-  5. 记录物品创建日志
-
-#### 3.3.2 修改单独属性物品
-
-- **功能**:修改单独属性物品的属性(如强化、附魔)
-- **参数**:用户ID、实例ID、属性变更
-- **返回**:修改后的物品信息
-- **处理逻辑**:
-  1. 检查用户是否拥有该物品
-  2. 验证属性变更的合法性
-  3. 更新 item_instances 记录
-  4. 记录物品修改日志
-
-#### 3.3.3 获取单独属性物品详情
-
-- **功能**:获取单独属性物品的详细信息
-- **参数**:实例ID
-- **返回**:物品详细信息,包括基础属性和特殊属性
-- **处理逻辑**:
-  1. 查询 item_instances 表获取物品实例
-  2. 关联 item_items 表获取基础信息
-  3. 合并基础属性和特殊属性
-  4. 返回完整的物品信息
-
-## 4. 物品过期机制
-
-物品模块支持两种过期时间机制,用于实现物品的时效性管理。
-
-### 4.1 全局过期时间
-
-全局过期时间定义在 `item_items` 表的 `global_expire_at` 字段中,表示该物品在所有用户中的绝对过期时间。当超过这个时间点后,所有用户的该物品均失效。
-
-#### 4.1.1 应用场景
-
-- **限时活动物品**:活动结束后自动失效
-- **赠送的体验物品**:在特定日期后全部失效
-- **版本更新物品**:新版本发布后旧版本物品自动失效
-
-#### 4.1.2 实现方式
-
-1. 在物品定义时设置 `global_expire_at` 字段
-2. 在获取用户物品时,检查物品的全局过期时间
-3. 定期运行任务,清理全局过期的物品
-
-### 4.2 用户物品过期时间
-
-用户物品过期时间定义在 `item_users` 表的 `expire_at` 字段中,表示特定用户的特定物品的过期时间。这允许每个用户的同一物品有不同的过期时间。
-
-#### 4.2.1 应用场景
-
-- **限时使用的装备或道具**:从获取开始计时
-- **会员特权物品**:与会员有效期绑定
-- **租借物品**:租借期结束后自动失效
-- **试用物品**:试用期结束后自动失效
-
-#### 4.2.2 实现方式
-
-1. 在添加物品到用户背包时,根据物品的 `default_expire_seconds` 计算过期时间
-2. 如果 `default_expire_seconds` 为0,则物品永久有效
-3. 在获取用户物品时,检查用户物品的过期时间
-4. 定期运行任务,清理用户过期物品
-
-### 4.3 过期处理机制
-
-系统定期运行任务检查并处理过期物品,确保游戏内物品的时效性。
-
-#### 4.3.1 全局过期物品处理
-
-1. **查询全局过期物品**
-   ```sql
-   SELECT id FROM item_items WHERE global_expire_at IS NOT NULL AND global_expire_at < NOW()
-   ```
-
-2. **删除用户物品记录**
-   ```sql
-   DELETE FROM item_users WHERE item_id IN (已过期物品ID列表)
-   ```
-
-3. **记录日志**
-   - 在 item_transaction_logs 表中记录物品过期删除日志
-   - 交易类型设置为 "过期失效"
-
-4. **可选操作**
-   - 发送通知给用户
-   - 提供过期物品的替代品
-
-#### 4.3.2 用户物品过期处理
-
-1. **查询用户过期物品**
-   ```sql
-   SELECT id, user_id, item_id, instance_id FROM item_users
-   WHERE expire_at IS NOT NULL AND expire_at < NOW()
-   ```
-
-2. **删除用户物品记录**
-   ```sql
-   DELETE FROM item_users WHERE id IN (已过期记录ID列表)
-   ```
-
-3. **处理单独属性物品**
-   - 对于单独属性物品,可以选择删除或保留 item_instances 记录
-   - 如果删除,需要确保没有其他用户关联到该实例
-
-4. **记录日志**
-   - 在 item_transaction_logs 表中记录物品过期删除日志
-   - 记录用户ID、物品ID、过期时间等信息
-
-### 4.4 过期时间的优先级
-
-当同时存在全局过期时间和用户物品过期时间时,系统采用以下优先级规则:
-
-1. **最早到期优先**:系统使用两个过期时间中较早的一个作为实际过期时间
-2. **全局过期强制执行**:即使用户物品过期时间晚于全局过期时间,全局过期时间到达后物品仍会失效
-3. **用户物品过期独立执行**:用户物品过期不影响其他用户的同类物品
-
-## 5. 宝箱系统
-
-宝箱系统是游戏物品系统的重要组成部分,允许玩家通过开启宝箱获得随机物品,增加游戏的随机性和乐趣。
-
-### 5.1 宝箱类型
-
-系统支持多种类型的宝箱,可以根据游戏需求进行配置:
-
-#### 5.1.1 按稀有度分类
-
-1. **普通宝箱**:包含基础消耗品和少量资源,开出稀有物品的概率较低
-2. **稀有宝箱**:有较高机会获得稀有装备和较多资源
-3. **史诗宝箱**:包含高价值物品,有较高概率获得史诗级物品
-4. **传说宝箱**:最高级别宝箱,有机会获得传说级物品
-
-#### 5.1.2 按获取方式分类
-
-1. **任务宝箱**:完成任务获得的宝箱,内容通常与任务相关
-2. **活动宝箱**:特定活动期间可获得的宝箱,包含活动限定物品
-3. **商店宝箱**:通过游戏货币或真实货币购买的宝箱
-4. **成就宝箱**:达成特定成就后获得的宝箱
-5. **副本宝箱**:在游戏副本中获得的宝箱,内容通常与副本主题相关
-
-### 5.2 宝箱配置
-
-宝箱的内容和概率通过 `item_chest_contents` 表进行配置:
-
-#### 5.2.1 基本配置
-
-1. **宝箱定义**:宝箱本身是 `item_items` 表中 `type=5` 的特殊物品
-2. **内容配置**:通过 `item_chest_contents` 表定义宝箱可能掉落的内容
-3. **物品组支持**:宝箱内容可以是具体物品(item_id)或物品组(group_id)
-4. **数量范围**:每个内容可以设置最小和最大掉落数量
-5. **概率控制**:通过 weight 字段控制每个内容的掉落概率
-
-#### 5.2.2 多物品掉落
-
-宝箱系统支持一个宝箱同时掉落多个物品:
-
-1. **掉落数量控制**:
-   - 宝箱物品在 `numeric_attributes` 字段中定义 `min_drop_count` 和 `max_drop_count` 属性
-   - 系统在开启宝箱时随机决定实际掉落的物品数量
-
-2. **重复控制**:
-   - 通过 `allow_duplicate` 字段控制物品是否可以在同一宝箱中重复掉落
-   - 当设置为0时,同一内容在一次开启中最多出现一次
-
-3. **物品组随机**:
-   - 当内容配置为物品组时,系统会根据物品组中的权重随机选择一个物品
-   - 物品组可以包含多个物品,增加宝箱内容的多样性
-
-### 5.3 概率机制
-
-宝箱内容的概率由 `item_chest_contents` 表中的 `weight` 字段决定:
-
-#### 5.3.1 基础概率计算
-
-1. **权重定义**:
-   - 每个宝箱内容的权重为三位小数
-   - 同一宝箱的所有内容权重总和为100
-   - 每个内容的概率直接等于其权重值(百分比)
-
-2. **概率计算公式**:
-   ```
-   内容获取概率 = 内容权重 / 宝箱内容权重总和 * 100%
-   ```
-
-3. **多物品抽取**:
-   - 当宝箱配置为掉落多个物品时,系统会进行多次抽取
-   - 每次抽取都会根据权重进行随机选择
-   - 如果不允许重复,已选中的内容会从后续抽取中排除
-
-### 5.4 保底机制
-
-为了确保玩家在多次开启宝箱后能获得稀有物品,系统实现了保底机制:
-
-#### 5.4.1 保底机制设计
-
-保底机制直接集成在宝箱内容配置中,具有以下特点:
-
-1. **内容级别保底**:
-   - 每个宝箱内容可以设置自己的保底次数(`pity_count`字段)
-   - 当玩家连续未获得该内容达到指定次数后,必定获得该内容
-
-2. **灵活的概率调整**:
-   - 通过 `pity_weight_factor` 字段控制递增概率的幅度
-   - 可以为不同内容设置不同的递增策略
-
-3. **保底计数记录**:
-   - 在 `item_pity_times` 表中记录用户对每个宝箱内容的尝试次数
-   - 当获得内容后,相应的计数会重置
-
-#### 5.4.2 保底实现方式
-
-系统支持两种保底实现方式:
-
-1. **确定保底**:
-   - 当玩家开启次数达到 `pity_count` 时,100%获得该内容
-   - 适用于重要的稀有物品
-
-2. **递增概率**:
-   - 每次未获得目标内容时,增加下次获得的概率
-   - 概率增加公式:
-     ```
-     调整后概率 = 基础概率 * (1 + (当前计数 / pity_count) * pity_weight_factor)
-     ```
-   - 当计数达到 `pity_count` 时,概率变为100%
-
-#### 5.4.3 保底机制实现流程
-
-1. **获取宝箱内容配置**
-   - 从 `item_chest_contents` 表查询宝箱的所有内容配置
-   - 过滤出 `pity_count > 0` 的内容,这些是启用了保底的内容
-
-2. **获取用户保底计数**
-   - 从 `item_pity_times` 表查询用户对各宝箱内容的当前计数
-   - 如果不存在,创建新记录并初始化计数
-
-3. **调整掉落概率**
-   - 根据保底计数调整各内容的掉落概率
-   - 如果有内容的计数达到保底次数,直接选择该内容
-
-4. **更新保底计数**
-   - 对于未获得的内容,增加保底计数
-   - 对于已获得的内容,重置保底计数
+### 3.2 关键字段说明
 
 
-### 5.5 宝箱开启接口
+#### 3.2.1 物品类型 (item_items.type)
 
 
-系统提供以下接口用于宝箱开启
+物品类型决定了物品的基本行为和使用方式:
 
 
-#### 5.5.1 开启宝箱
+- 1: 可使用物品 - 直接消耗获得效果
+- 2: 可装备物品 - 装备后提供属性加成
+- 3: 可合成物品 - 可用于合成其他物品
+- 4: 任务物品 - 用于完成任务
+- 5: 宝箱物品 - 可开启获得其他物品
+- 6: 货币物品 - 用于交易和购买
 
 
-- **功能**:消耗宝箱并获取随机物品
-- **参数**:用户ID、宝箱ID、数量
-- **返回**:获得的物品列表、剩余宝箱数量
-- **处理逻辑**:
-  1. 检查用户是否拥有足够数量的宝箱
-  2. 获取宝箱配置和用户保底计数
-  3. 计算实际掉落物品数量
-  4. 根据概率和保底机制选择掉落内容
-  5. 从用户背包中扣除宝箱
-  6. 向用户背包添加获得的物品
-  7. 更新保底计数
-  8. 记录宝箱开启日志
+#### 3.2.2 物品属性 (display_attributes, numeric_attributes)
 
 
-#### 5.5.2 获取宝箱内容预览
+物品属性以JSON格式存储,分为两类:
 
 
-- **功能**:预览宝箱可能获得的物品及概率
-- **参数**:宝箱ID
-- **返回**:可能获得的物品列表及概率
-- **处理逻辑**:
-  1. 获取宝箱配置
-  2. 计算各内容的实际概率
-  3. 对于物品组,展开显示组内物品
-  4. 返回完整的可能获得物品列表及概率
+- **display_attributes**: 用于界面展示的属性,如图标、描述、外观等
+- **numeric_attributes**: 用于游戏逻辑计算的属性,如攻击力、防御力、使用效果等
 
 
-### 5.6 宝箱日志记录
+#### 3.2.3 交易类型 (item_transaction_logs.transaction_type)
 
 
-每次宝箱开启都会记录详细日志,用于数据分析和问题排查
+记录物品流转的类型:
 
 
-#### 5.6.1 日志内容
+- 1: 获取 - 玩家获得物品
+- 2: 消耗 - 玩家消耗物品
+- 3: 交易获得 - 通过交易获得物品
+- 4: 交易失去 - 通过交易失去物品
+- 5: 过期失效 - 物品过期被移除
 
 
-在 `item_chest_open_logs` 表中记录以下信息:
+## 4. 核心功能
 
 
-1. **用户信息**:开启宝箱的用户ID
-2. **宝箱信息**:宝箱ID、开启数量
-3. **开启时间**:宝箱开启的时间戳
-4. **获得物品**:以JSON格式记录获得的所有物品ID和数量
-5. **保底触发**:是否触发保底机制,触发的内容ID
-6. **安全信息**:IP地址、设备信息等
+### 4.1 物品管理
 
 
-#### 5.6.2 日志用途
+#### 4.1.1 添加物品到用户背包
 
 
-1. **数据分析**:分析宝箱开启模式和物品掉落分布
-2. **概率验证**:验证实际掉落概率是否符合配置
-3. **用户支持**:解决用户关于宝箱开启的问题
-4. **异常检测**:发现可能的作弊或异常行为
-
-## 6. 物品获取与堆叠
-
-当玩家多次获得同一物品时,系统需要根据物品类型和过期时间进行不同的处理,以确保物品管理的合理性和高效性。
-
-### 6.1 统一属性物品的处理
-
-对于统一属性物品(如消耗品、材料等),系统采用以下处理策略:
-
-#### 6.1.1 基本堆叠规则
-
-1. **数量累加**:
-   - 当玩家获得已拥有的统一属性物品时,系统会增加物品数量
-   - 在 `item_users` 表中更新 `quantity` 字段
-
-2. **最大堆叠限制**:
-   - 每种物品都有最大堆叠数量限制,定义在 `item_items` 表的 `max_stack` 字段
-   - 当数量超过最大堆叠限制时,系统会创建新的堆叠
-
-3. **堆叠创建逻辑**:
-   ```php
-   // 伪代码示例
-   $currentQuantity = $userItem->quantity;
-   $maxStack = $item->max_stack;
-   $newQuantity = $currentQuantity + $addQuantity;
-
-   if ($newQuantity <= $maxStack) {
-       // 直接增加数量
-       $userItem->quantity = $newQuantity;
-       $userItem->save();
-   } else {
-       // 先填满当前堆叠
-       $userItem->quantity = $maxStack;
-       $userItem->save();
-
-       // 创建新堆叠
-       $remainingQuantity = $newQuantity - $maxStack;
-       $this->addNewStack($userId, $itemId, $remainingQuantity);
-   }
-   ```
-
-#### 6.1.2 过期时间分组策略
-
-对于有过期时间的统一属性物品,系统按照过期时间分组存储:
-
-1. **过期时间匹配**:
-   - 相同物品但过期时间不同,创建不同的记录
-   - 相同物品且过期时间相同,数量累加
-
-2. **过期时间查找逻辑**:
-   ```php
-   // 伪代码示例
-   $userItem = UserItem::where('user_id', $userId)
-       ->where('item_id', $itemId)
-       ->where('expire_at', $expireAt)
-       ->first();
-
-   if ($userItem) {
-       // 找到相同过期时间的记录,增加数量
-       $userItem->quantity += $quantity;
-       $userItem->save();
-   } else {
-       // 创建新记录
-       UserItem::create([
-           'user_id' => $userId,
-           'item_id' => $itemId,
-           'quantity' => $quantity,
-           'expire_at' => $expireAt
-       ]);
-   }
-   ```
-
-3. **使用优先级**:
-   - 在使用物品时,优先使用即将过期的物品
-   - 系统按过期时间升序排序,先使用最早过期的物品
-
-### 6.2 单独属性物品的处理
+```php
+// 添加统一属性物品
+$result = $itemService->addItem($userId, $itemId, $quantity, [
+    'source_type' => 'quest_reward',
+    'source_id' => $questId,
+]);
 
 
-对于单独属性物品(如装备、宠物等),每次获取都创建新记录,即使是相同物品:
-
-#### 6.2.1 单独属性物品创建
-
-1. **实例创建**:
-   - 每个单独属性物品都在 `item_instances` 表中创建一条记录
-   - 生成独特的属性(可能包含随机因素)
-
-2. **用户关联**:
-   - 在 `item_users` 表中创建记录,关联用户和物品实例
-   - `quantity` 字段始终为1
-
-3. **创建流程**:
-   ```php
-   // 伪代码示例
-   // 1. 创建物品实例
-   $instance = ItemInstance::create([
-       'item_id' => $itemId,
-       'name' => $generatedName,
-       'display_attributes' => $displayAttributes,
-       'numeric_attributes' => $numericAttributes,
-       'expire_at' => $expireAt
-   ]);
-
-   // 2. 关联到用户
-   UserItem::create([
-       'user_id' => $userId,
-       'item_id' => $itemId,
-       'instance_id' => $instance->id,
-       'quantity' => 1,
-       'expire_at' => $expireAt
-   ]);
-   ```
-
-#### 6.2.2 属性差异化
-
-单独属性物品可以通过多种方式实现属性差异化:
-
-1. **随机属性生成**:
-   - 在创建物品实例时生成随机属性
-   - 属性范围可以根据物品基础属性和品质定义
-
-2. **命名差异化**:
-   - 可以根据属性生成不同的物品名称
-   - 例如:"锐利的钢刀"、"坚固的钢刀"等
-
-3. **属性继承与变异**:
-   - 从基础物品继承部分属性
-   - 添加随机变异或特殊效果
-
-### 6.3 物品获取来源记录
-
-系统记录物品的获取来源,便于数据分析和问题排查:
-
-#### 6.3.1 来源类型
-
-在 `item_transaction_logs` 表中记录物品获取来源:
-
-1. **任务奖励**:完成任务获得的物品
-2. **商店购买**:通过游戏商店购买的物品
-3. **宝箱开启**:通过开启宝箱获得的物品
-4. **怪物掉落**:击败怪物获得的物品
-5. **玩家交易**:通过与其他玩家交易获得的物品
-6. **系统赠送**:系统活动或补偿赠送的物品
-7. **合成获得**:通过物品合成获得的物品
-8. **分解获得**:通过物品分解获得的物品
-
-#### 6.3.2 来源记录格式
-
-```json
-{
-  "source_type": "chest_open",
-  "source_id": 12345,
-  "details": {
-    "chest_id": 101,
-    "open_time": "2023-05-01 12:34:56",
-    "is_pity": false
-  }
-}
+// 添加单独属性物品
+$result = $itemService->addItem($userId, $itemId, 1, [
+    'source_type' => 'chest_open',
+    'source_id' => $chestId,
+    'display_attributes' => ['color' => 'red', 'size' => 'large'],
+    'numeric_attributes' => ['attack' => 100, 'defense' => 50],
+]);
 ```
 ```
 
 
-### 6.4 物品获取限制
-
-系统支持对物品获取进行限制,防止物品过度产出:
-
-#### 6.4.1 背包容量限制
-
-1. **背包容量检查**:
-   - 在添加物品前检查用户背包是否有足够空间
-   - 背包容量可以根据用户等级或VIP等级动态调整
-
-2. **超出处理策略**:
-   - 拒绝添加:当背包已满时拒绝添加新物品
-   - 邮件发送:将无法添加的物品通过邮件发送给用户
-   - 临时扩容:临时扩大背包容量,但用户需要尽快清理
-
-#### 6.4.2 物品数量限制
-
-1. **单个物品限制**:
-   - 某些特殊物品可以设置最大持有数量
-   - 当达到限制时,无法再获取该物品
-
-2. **物品组限制**:
-   - 可以对一组相关物品设置总数限制
-   - 例如,限制所有任务道具的总数量
-
-## 7. 物品产出限制
-
-为了防止某些物品产出超过预期,影响游戏平衡,系统实现了物品产出限制机制。
-
-### 7.1 限制类型
-
-系统支持多种限制类型,可以根据游戏需求灵活配置:
-
-#### 7.1.1 全局总量限制
-
-- **定义**:限制物品在整个游戏中的总产出数量
-- **应用场景**:限量版物品、稀有收藏品
-- **实现方式**:
-  - 在 `item_output_limits` 表中设置 `limit_type=1`
-  - 使用 `current_quantity` 字段记录当前已产出数量
-  - 每次产出前检查是否超过 `max_quantity`
-
-#### 7.1.2 单个用户限制
-
-- **定义**:限制每个用户可获得的物品总数量
-- **应用场景**:防止单个用户囤积稀有物品、控制关键物品分配
-- **实现方式**:
-  - 在 `item_output_limits` 表中设置 `limit_type=2`
-  - 在 `item_user_output_counters` 表中记录每个用户的获取数量
-  - 每次产出前检查用户是否超过限制
-
-#### 7.1.3 单日全局限制
-
-- **定义**:限制每天在整个游戏中的产出数量
-- **应用场景**:控制物品流通速度、防止市场泛滥
-- **实现方式**:
-  - 在 `item_output_limits` 表中设置 `limit_type=3`
-  - 使用 `current_quantity` 字段记录当日已产出数量
-  - 每天重置计数
-
-#### 7.1.4 单日用户限制
-
-- **定义**:限制每个用户每天可获得的物品数量
-- **应用场景**:日常活动物品、防止刷取行为
-- **实现方式**:
-  - 在 `item_output_limits` 表中设置 `limit_type=4`
-  - 在 `item_user_output_counters` 表中记录用户当日获取数量
-  - 每天重置计数
-
-### 7.2 重置机制
-
-不同类型的限制可以设置不同的重置周期,满足多样化的游戏需求:
-
-#### 7.2.1 重置类型
-
-1. **不重置**(`reset_type=0`):
-   - 永久限制,适用于限量物品
-   - 一旦达到限制,永远不会重置
-
-2. **每日重置**(`reset_type=1`):
-   - 每天重置限制计数
-   - 适用于日常活动物品
-   - 重置时间通常为凌晨0点
-
-3. **每周重置**(`reset_type=2`):
-   - 每周重置限制计数
-   - 适用于周常活动物品
-   - 重置时间通常为每周一凌晨0点
-
-4. **每月重置**(`reset_type=3`):
-   - 每月重置限制计数
-   - 适用于月度活动物品
-   - 重置时间通常为每月1日凌晨0点
-
-#### 7.2.2 重置实现
-
-系统通过定时任务实现自动重置:
+#### 4.1.2 消耗用户物品
 
 
 ```php
 ```php
-// 伪代码示例
-public function resetLimits()
-{
-    $now = new DateTime();
+// 消耗统一属性物品
+$result = $itemService->consumeItem($userId, $itemId, null, $quantity, [
+    'source_type' => 'item_use',
+    'details' => ['effect_id' => 123],
+]);
 
 
-    // 重置每日限制
-    $dailyLimits = OutputLimit::where('reset_type', 1)
-        ->where('last_reset_time', '<', $now->format('Y-m-d 00:00:00'))
-        ->get();
+// 消耗单独属性物品
+$result = $itemService->consumeItem($userId, $itemId, $instanceId, 1, [
+    'source_type' => 'equipment_upgrade',
+    'details' => ['upgrade_id' => 456],
+]);
+```
 
 
-    foreach ($dailyLimits as $limit) {
-        $limit->current_quantity = 0;
-        $limit->last_reset_time = $now;
-        $limit->save();
+#### 4.1.3 获取用户物品列表
 
 
-        // 重置用户计数
-        UserOutputCounter::where('limit_id', $limit->id)
-            ->update(['current_count' => 0]);
-    }
+```php
+// 获取所有物品
+$items = $itemService->getUserItems($userId);
 
 
-    // 类似地处理每周和每月重置
-    // ...
-}
+// 获取特定类型的物品
+$items = $itemService->getUserItems($userId, [
+    'type' => 2, // 装备类物品
+    'category_id' => 5, // 特定分类
+]);
 ```
 ```
 
 
-### 7.3 关联物品限制
-
-系统支持将多个相关物品关联到同一个限制规则下,防止通过不同渠道绕过限制:
+### 4.2 宝箱系统
 
 
-#### 7.3.1 共享限制额度
+#### 4.2.1 开启宝箱
 
 
-- **定义**:多个物品共享同一个限制额度
-- **应用场景**:不同渠道获取的相同物品、功能相似的物品
-- **实现方式**:
-  - 在 `item_output_limits` 表的 `related_items` 字段中存储关联物品ID列表
-  - 检查限制时,同时考虑所有关联物品的产出数量
-
-#### 7.3.2 关联物品配置
+```php
+// 开启宝箱
+$result = $chestService->openChest($userId, $chestId, $quantity, [
+    'ip_address' => $request->ip(),
+    'device_info' => $request->userAgent(),
+]);
 
 
-```json
-// related_items字段示例
-{
-  "items": [1001, 1002, 1003],
-  "relation_type": "shared_limit"
-}
+// 结果示例
+[
+    'success' => true,
+    'chest_id' => 123,
+    'quantity' => 1,
+    'results' => [
+        [
+            [
+                'item_id' => 456,
+                'quantity' => 2,
+                'is_pity' => false,
+            ],
+            [
+                'item_id' => 789,
+                'quantity' => 1,
+                'is_pity' => true,
+            ]
+        ]
+    ],
+    'pity_triggered' => true,
+    'log_id' => 10001,
+]
 ```
 ```
 
 
-### 7.4 限制检查流程
-
-在物品产出前,系统会执行以下检查流程,确保不超过设定的限制:
-
-#### 7.4.1 检查步骤
-
-1. **查询物品限制**:
-   ```php
-   $limit = OutputLimit::where('item_id', $itemId)->first();
-   if (!$limit) {
-       // 没有限制,直接允许产出
-       return true;
-   }
-   ```
-
-2. **检查限制类型**:
-   ```php
-   switch ($limit->limit_type) {
-       case 1: // 全局总量限制
-           return $this->checkGlobalTotalLimit($limit, $quantity);
-       case 2: // 单个用户限制
-           return $this->checkUserTotalLimit($limit, $userId, $quantity);
-       case 3: // 单日全局限制
-           return $this->checkDailyGlobalLimit($limit, $quantity);
-       case 4: // 单日用户限制
-           return $this->checkDailyUserLimit($limit, $userId, $quantity);
-   }
-   ```
-
-3. **检查关联物品**:
-   ```php
-   if (!empty($limit->related_items)) {
-       $relatedItems = json_decode($limit->related_items, true);
-       foreach ($relatedItems['items'] as $relatedItemId) {
-           // 检查关联物品的产出记录
-           // ...
-       }
-   }
-   ```
-
-4. **更新计数**:
-   ```php
-   if ($isGlobalLimit) {
-       $limit->current_quantity += $quantity;
-       $limit->save();
-   } else {
-       $counter = UserOutputCounter::firstOrCreate([
-           'user_id' => $userId,
-           'limit_id' => $limit->id
-       ]);
-       $counter->current_count += $quantity;
-       $counter->save();
-   }
-   ```
-
-#### 7.4.2 超限处理
-
-当检测到物品产出将超过限制时,系统可以采取以下处理方式:
-
-1. **拒绝产出**:直接拒绝物品产出,返回错误信息
-2. **部分产出**:产出不超过限制的部分数量
-3. **替代产出**:提供替代物品作为补偿
-4. **等待队列**:将超出部分放入等待队列,等待下次重置后产出
-
-### 7.5 监控与预警
-
-系统提供监控和预警机制,帮助游戏运营团队及时了解物品产出情况:
-
-#### 7.5.1 接近限制预警
-
-当物品产出数量接近限制时(例如达到80%),系统可以发送预警通知:
+#### 4.2.2 获取宝箱内容预览
 
 
 ```php
 ```php
-if ($currentQuantity >= $maxQuantity * 0.8 && $currentQuantity < $maxQuantity * 0.9) {
-    // 发送80%预警
-    $this->sendWarning($itemId, '80%');
-} elseif ($currentQuantity >= $maxQuantity * 0.9) {
-    // 发送90%预警
-    $this->sendWarning($itemId, '90%');
-}
+// 获取宝箱内容预览
+$preview = $chestService->getChestContentPreview($chestId);
 ```
 ```
 
 
-#### 7.5.2 产出统计报告
-
-系统定期生成物品产出统计报告,包括:
-
-1. **总产出数量**:各物品的总产出数量
-2. **限制使用情况**:各限制规则的使用情况
-3. **用户获取分布**:物品在用户间的分布情况
-4. **时间分布**:物品产出的时间分布
-
-## 8. 日志记录系统
-
-物品系统的所有操作都会记录详细日志,用于数据分析、问题排查和安全审计。
-
-### 8.1 日志类型
-
-系统根据不同的操作类型记录多种日志:
-
-#### 8.1.1 物品交易日志
-
-在 `item_transaction_logs` 表中记录所有物品获取和消耗操作:
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 日志ID,主键 |
-| user_id | int | 用户ID |
-| item_id | int | 物品ID |
-| instance_id | int | 单独属性物品ID(可为空) |
-| quantity | int | 数量(正数表示获取,负数表示消耗) |
-| transaction_type | tinyint | 交易类型(1:获取, 2:使用, 3:交易, 4:出售, 5:过期, 6:删除...) |
-| source_type | varchar | 来源类型(任务、商店、宝箱等) |
-| source_id | int | 来源ID(任务ID、商店ID、宝箱ID等) |
-| details | json | 详细信息,以JSON格式存储 |
-| transaction_time | timestamp | 交易时间 |
-| ip_address | varchar | 操作的IP地址 |
-| device_info | varchar | 设备信息 |
-| created_at | timestamp | 创建时间 |
-
-#### 8.1.2 宝箱开启日志
-
-在 `item_chest_open_logs` 表中记录宝箱开启操作:
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 日志ID,主键 |
-| user_id | int | 用户ID |
-| chest_id | int | 宝箱ID |
-| quantity | int | 开启数量 |
-| results | json | 获得的物品,以JSON格式存储 |
-| pity_triggered | tinyint | 是否触发保底机制(0:否, 1:是) |
-| pity_content_id | int | 触发保底的内容ID(可为空) |
-| open_time | timestamp | 开启时间 |
-| ip_address | varchar | 操作的IP地址 |
-| device_info | varchar | 设备信息 |
-| created_at | timestamp | 创建时间 |
-
-#### 8.1.3 物品合成日志
-
-在 `item_craft_logs` 表中记录物品合成操作:
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 日志ID,主键 |
-| user_id | int | 用户ID |
-| recipe_id | int | 配方ID |
-| materials | json | 消耗的材料,以JSON格式存储 |
-| result_item_id | int | 获得的物品ID |
-| result_instance_id | int | 获得的单独属性物品ID(可为空) |
-| result_quantity | int | 获得的物品数量 |
-| is_success | tinyint | 是否成功(0:失败, 1:成功) |
-| craft_time | timestamp | 合成时间 |
-| ip_address | varchar | 操作的IP地址 |
-| device_info | varchar | 设备信息 |
-| created_at | timestamp | 创建时间 |
-
-#### 8.1.4 物品分解日志
-
-在 `item_dismantle_logs` 表中记录物品分解操作:
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 记录ID,主键 |
-| user_id | int | 用户ID |
-| item_id | int | 被分解的物品ID |
-| instance_id | int | 被分解的单独属性物品ID(可为空) |
-| quantity | int | 分解数量 |
-| rule_id | int | 使用的分解规则ID |
-| results | json | 分解结果,包含获得的物品ID、数量等信息 |
-| dismantle_time | timestamp | 分解时间 |
-| ip_address | varchar | 操作的IP地址 |
-| device_info | varchar | 设备信息 |
-| created_at | timestamp | 创建时间 |
-
-### 8.2 日志记录策略
-
-系统采用以下策略记录日志,确保数据完整性和系统性能:
-
-#### 8.2.1 事务内记录
-
-日志记录应在数据库事务内进行,确保操作和日志的一致性:
+### 4.3 物品合成系统
+
+#### 4.3.1 合成物品
 
 
 ```php
 ```php
-DB::beginTransaction();
-try {
-    // 执行物品操作
-    $this->addItemToUser($userId, $itemId, $quantity);
-
-    // 记录日志
-    $this->logTransaction($userId, $itemId, $quantity, 1, $sourceType, $sourceId);
-
-    DB::commit();
-} catch (\Exception $e) {
-    DB::rollBack();
-    throw $e;
-}
+// 合成物品
+$result = $craftService->craftItem($userId, $recipeId, [
+    'ip_address' => $request->ip(),
+    'device_info' => $request->userAgent(),
+]);
 ```
 ```
 
 
-#### 8.2.2 异步日志记录
-
-对于高频操作,可以使用队列实现异步日志记录,减轻数据库压力:
+#### 4.3.2 获取用户可合成配方列表
 
 
 ```php
 ```php
-// 将日志记录任务推送到队列
-Queue::push(new RecordItemTransactionLog($userId, $itemId, $quantity, $transactionType, $sourceType, $sourceId));
+// 获取用户可合成配方列表
+$recipes = $craftService->getUserAvailableRecipes($userId);
 ```
 ```
 
 
-#### 8.2.3 批量日志记录
+### 4.4 物品分解系统
 
 
-对于批量操作,可以使用批量插入优化性能:
+#### 4.4.1 分解物品
 
 
 ```php
 ```php
-$logs = [];
-foreach ($items as $item) {
-    $logs[] = [
-        'user_id' => $userId,
-        'item_id' => $item['id'],
-        'quantity' => $item['quantity'],
-        'transaction_type' => $transactionType,
-        'transaction_time' => now(),
-        // 其他字段...
-    ];
-}
-
-// 批量插入日志
-DB::table('item_transaction_logs')->insert($logs);
+// 分解物品
+$result = $dismantleService->dismantleItem($userId, $itemId, $instanceId, $quantity, [
+    'ip_address' => $request->ip(),
+    'device_info' => $request->userAgent(),
+]);
 ```
 ```
 
 
-### 8.3 日志查询接口
-
-系统提供以下接口用于查询日志:
-
-#### 8.3.1 查询用户物品历史
-
-- **功能**:查询用户的物品获取和消耗历史
-- **参数**:用户ID、物品ID(可选)、交易类型(可选)、时间范围(可选)、分页参数
-- **返回**:物品交易记录列表
-- **查询示例**:
-  ```php
-  $logs = TransactionLog::where('user_id', $userId)
-      ->when($itemId, function ($query) use ($itemId) {
-          return $query->where('item_id', $itemId);
-      })
-      ->when($transactionType, function ($query) use ($transactionType) {
-          return $query->where('transaction_type', $transactionType);
-      })
-      ->when($startTime && $endTime, function ($query) use ($startTime, $endTime) {
-          return $query->whereBetween('transaction_time', [$startTime, $endTime]);
-      })
-      ->orderBy('transaction_time', 'desc')
-      ->paginate($perPage);
-  ```
-
-#### 8.3.2 查询宝箱开启历史
-
-- **功能**:查询用户的宝箱开启历史
-- **参数**:用户ID、宝箱ID(可选)、时间范围(可选)、分页参数
-- **返回**:宝箱开启记录列表
-- **查询示例**:
-  ```php
-  $logs = ChestOpenLog::where('user_id', $userId)
-      ->when($chestId, function ($query) use ($chestId) {
-          return $query->where('chest_id', $chestId);
-      })
-      ->when($startTime && $endTime, function ($query) use ($startTime, $endTime) {
-          return $query->whereBetween('open_time', [$startTime, $endTime]);
-      })
-      ->orderBy('open_time', 'desc')
-      ->paginate($perPage);
-  ```
-
-### 8.4 日志分析与应用
-
-系统日志可用于多种分析和应用场景:
-
-#### 8.4.1 数据分析
-
-1. **物品流通分析**:
-   - 分析物品的获取和消耗渠道
-   - 识别最受欢迎的物品和获取方式
-   - 监控物品经济平衡
-
-2. **用户行为分析**:
-   - 分析用户的物品使用模式
-   - 识别高价值用户和活跃用户
-   - 发现潜在的游戏优化点
-
-#### 8.4.2 问题排查
-
-1. **物品丢失排查**:
-   - 通过日志追踪物品的完整生命周期
-   - 确认物品是否正常获取和消耗
-   - 识别可能的系统错误或漏洞
-
-2. **异常行为检测**:
-   - 识别可能的作弊或滥用行为
-   - 监控异常的物品获取模式
-   - 发现潜在的系统漏洞
-
-#### 8.4.3 用户支持
-
-1. **物品恢复**:
-   - 在系统错误导致物品丢失时,通过日志确认物品状态
-   - 提供准确的物品恢复服务
-
-2. **用户查询**:
-   - 回答用户关于物品获取和消耗的问题
-   - 提供物品历史记录查询服务
-
-### 8.5 日志清理与归档
-
-为了管理日志数据量,系统实现了日志清理和归档机制:
-
-#### 8.5.1 日志保留策略
-
-1. **实时日志**:
-   - 保留最近30天的日志在主数据库中
-   - 用于实时查询和问题排查
-
-2. **归档日志**:
-   - 30天以上的日志移动到归档数据库
-   - 用于长期数据分析和审计
-
-3. **统计汇总**:
-   - 对超过180天的日志进行统计汇总
-   - 保留关键统计数据,删除详细记录
-
-#### 8.5.2 归档实现
+#### 4.4.2 获取物品分解预览
 
 
 ```php
 ```php
-// 伪代码示例
-public function archiveLogs()
-{
-    $cutoffDate = now()->subDays(30);
-
-    // 查找需要归档的日志
-    $logsToArchive = TransactionLog::where('transaction_time', '<', $cutoffDate)
-        ->limit(1000)
-        ->get();
-
-    if ($logsToArchive->isEmpty()) {
-        return;
-    }
-
-    // 插入到归档表
-    DB::connection('archive')->table('archived_transaction_logs')->insert(
-        $logsToArchive->toArray()
-    );
-
-    // 删除已归档的日志
-    $ids = $logsToArchive->pluck('id')->toArray();
-    TransactionLog::whereIn('id', $ids)->delete();
-}
-
-## 9. 物品合成系统
-
-物品合成系统允许玩家使用已有物品合成新物品,增加游戏深度和物品获取途径。
-
-### 9.1 合成系统概述
-
-物品合成系统具有以下特点:
-
-#### 9.1.1 系统特点
-
-1. **多材料合成**:支持使用多种不同物品作为材料
-2. **概率成功**:合成可以设置成功率,增加游戏随机性
-3. **等级限制**:可以设置合成的等级或条件限制
-4. **配方解锁**:玩家需要先解锁配方才能进行合成
-5. **多币种成本**:支持消耗多种货币作为合成成本
-
-#### 9.1.2 合成流程
-
-1. **选择配方**:玩家从已解锁的配方中选择要合成的物品
-2. **检查材料**:系统检查玩家是否拥有足够的材料
-3. **支付成本**:扣除合成所需的货币成本
-4. **消耗材料**:从玩家背包中扣除材料
-5. **概率判定**:根据配方的成功率判定是否合成成功
-6. **发放物品**:合成成功时,向玩家发放合成物品
-7. **记录日志**:记录合成操作的详细信息
-
-### 9.2 数据库设计
+// 获取物品分解预览
+$preview = $dismantleService->getDismantlePreview($userId, $itemId, $instanceId);
+```
 
 
-合成系统涉及三个主要数据表:配方表、配方材料表和用户配方表。
+## 4. 核心服务
 
 
-#### 9.2.1 item_recipes 表(合成配方)
+### 4.1 ItemService
 
 
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 配方ID,主键 |
-| name | varchar | 配方名称 |
-| result_item_id | int | 产出物品ID,外键关联item_items表 |
-| result_min_quantity | int | 最小产出数量 |
-| result_max_quantity | int | 最大产出数量 |
-| success_rate | decimal(5,2) | 成功率(百分比,最大100) |
-| coin_cost | json | 货币成本,以JSON格式存储多种货币类型和数量 |
-| level_required | int | 所需等级 |
-| is_default_unlocked | tinyint | 是否默认解锁(0:否, 1:是) |
-| unlock_condition | json | 解锁条件,以JSON格式存储 |
-| cooldown_seconds | int | 冷却时间(秒) |
-| category_id | int | 配方分类ID |
-| sort_order | int | 排序权重 |
-| is_active | tinyint | 是否激活(0:否, 1:是) |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
+物品基础服务,负责物品的基本操作。
 
 
-#### 9.2.2 item_recipe_materials 表(配方材料)
+#### 主要方法
 
 
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 记录ID,主键 |
-| recipe_id | int | 配方ID,外键关联item_recipes表 |
-| item_id | int | 材料物品ID,外键关联item_items表 |
-| quantity | int | 所需数量 |
-| is_consumed | tinyint | 是否消耗(0:不消耗, 1:消耗) |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
+```php
+/**
+ * 获取用户物品列表
+ *
+ * @param int $userId 用户ID
+ * @param array $filters 过滤条件
+ * @param bool $includeExpired 是否包含已过期物品
+ * @return Collection
+ */
+public function getUserItems(int $userId, array $filters = [], bool $includeExpired = false): Collection;
 
 
-#### 9.2.3 item_user_recipes 表(用户配方)
+/**
+ * 添加物品到用户背包
+ *
+ * @param int $userId 用户ID
+ * @param int $itemId 物品ID
+ * @param int $quantity 数量
+ * @param array $options 选项
+ * @return array 添加结果
+ */
+public function addItem(int $userId, int $itemId, int $quantity, array $options = []): array;
 
 
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 记录ID,主键 |
-| user_id | int | 用户ID |
-| recipe_id | int | 配方ID,外键关联item_recipes表 |
-| is_unlocked | tinyint | 是否已解锁(0:否, 1:是) |
-| unlock_time | timestamp | 解锁时间 |
-| last_craft_time | timestamp | 最后合成时间 |
-| craft_count | int | 合成次数 |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
+/**
+ * 消耗用户物品
+ *
+ * @param int $userId 用户ID
+ * @param int $itemId 物品ID
+ * @param int|null $instanceId 物品实例ID(单独属性物品)
+ * @param int $quantity 数量
+ * @param array $options 选项
+ * @return array 消耗结果
+ */
+public function consumeItem(int $userId, int $itemId, ?int $instanceId, int $quantity, array $options = []): array;
 
 
-### 9.3 多币种成本设计
+/**
+ * 检查用户物品数量
+ *
+ * @param int $userId 用户ID
+ * @param int $itemId 物品ID
+ * @param int|null $instanceId 物品实例ID(单独属性物品)
+ * @return int 物品数量
+ */
+public function getItemQuantity(int $userId, int $itemId, ?int $instanceId = null): int;
 
 
-系统支持使用多种货币作为合成成本,增加游戏经济的深度:
+/**
+ * 检查物品是否过期
+ *
+ * @param int $itemId 物品ID
+ * @param int|null $instanceId 物品实例ID
+ * @return bool 是否过期
+ */
+public function isItemExpired(int $itemId, ?int $instanceId = null): bool;
+```
 
 
-#### 9.3.1 币种类型
+### 4.2 ChestService
 
 
-1. **游戏金币**:基础游戏货币
-2. **钻石**:高级游戏货币,通常与真实货币关联
-3. **声望**:特定阵营或活动的声望货币
-4. **活动代币**:限时活动专用货币
+宝箱服务,负责宝箱开启和内容管理。
 
 
-#### 9.3.2 成本存储格式
+#### 主要方法
 
 
-在 `item_recipes` 表的 `coin_cost` 字段中,使用JSON格式存储多币种成本:
+```php
+/**
+ * 开启宝箱
+ *
+ * @param int $userId 用户ID
+ * @param int $chestId 宝箱ID
+ * @param int $quantity 开启数量
+ * @param array $options 选项
+ * @return array 开启结果
+ */
+public function openChest(int $userId, int $chestId, int $quantity = 1, array $options = []): array;
+
+/**
+ * 获取宝箱内容预览
+ *
+ * @param int $chestId 宝箱ID
+ * @return array 宝箱内容预览
+ */
+public function getChestContentPreview(int $chestId): array;
+```
+
+### 4.3 CraftService
+
+合成服务,负责物品合成和配方管理。
+
+#### 主要方法
+
+```php
+/**
+ * 合成物品
+ *
+ * @param int $userId 用户ID
+ * @param int $recipeId 配方ID
+ * @param array $options 选项
+ * @return array 合成结果
+ */
+public function craftItem(int $userId, int $recipeId, array $options = []): array;
+
+/**
+ * 获取用户可合成配方列表
+ *
+ * @param int $userId 用户ID
+ * @param array $filters 过滤条件
+ * @return Collection 配方列表
+ */
+public function getUserAvailableRecipes(int $userId, array $filters = []): Collection;
+
+/**
+ * 解锁用户配方
+ *
+ * @param int $userId 用户ID
+ * @param int $recipeId 配方ID
+ * @return bool 是否成功
+ */
+public function unlockRecipe(int $userId, int $recipeId): bool;
+```
+
+### 4.4 DismantleService
+
+分解服务,负责物品分解和规则管理。
+
+#### 主要方法
+
+```php
+/**
+ * 分解物品
+ *
+ * @param int $userId 用户ID
+ * @param int $itemId 物品ID
+ * @param int|null $instanceId 物品实例ID
+ * @param int $quantity 数量
+ * @param array $options 选项
+ * @return array 分解结果
+ */
+public function dismantleItem(int $userId, int $itemId, ?int $instanceId, int $quantity, array $options = []): array;
+
+/**
+ * 获取物品分解预览
+ *
+ * @param int $userId 用户ID
+ * @param int $itemId 物品ID
+ * @param int|null $instanceId 物品实例ID
+ * @return array 分解预览
+ */
+public function getDismantlePreview(int $userId, int $itemId, ?int $instanceId): array;
+```
+
+## 5. 数据模型
+
+### 5.1 核心模型
+
+#### 5.1.1 Item
 
 
-```json
+物品基础信息模型,定义物品的基本属性。
+
+```php
+/**
+ * 物品基础信息
+ *
+ * field start
+ * @property   int  $id  物品ID,主键
+ * @property   string  $name  物品名称
+ * @property   string  $description  物品描述
+ * @property   int  $category_id  物品分类ID,外键关联kku_item_categories表
+ * @property   int  $type  物品类型(1:可使用, 2:可装备, 3:可合成, 4:可交任务, 5:可开启...)
+ * @property   int  $is_unique  是否是单独属性物品(0:否,默认, 1:是)
+ * @property   int  $max_stack  最大堆叠数量
+ * @property   int  $sell_price  出售价格
+ * @property   int  $tradable  是否可交易(0:不可交易, 1:可交易,默认)
+ * @property   int  $dismantlable  是否可分解(0:不可分解, 1:可分解,默认)
+ * @property   int  $default_expire_seconds  玩家获取物品后的默认有效秒数(0表示永久有效)
+ * @property   object|array  $display_attributes  展示属性,以JSON格式存储键值对,用于界面展示和描述的属性
+ * @property   object|array  $numeric_attributes  数值属性,以JSON格式存储键值对,用于计算和游戏逻辑的属性
+ * @property   string  $global_expire_at  物品全局过期时间(可为空)
+ * @property   \Carbon\Carbon  $created_at  创建时间
+ * @property   \Carbon\Carbon  $updated_at  更新时间
+ * field end
+ */
+class Item extends ModelCore
+{
+    // 模型实现...
+}
+```
+
+#### 5.1.2 ItemChestContent
+
+宝箱内容配置模型,定义宝箱可能掉落的物品。
+
+```php
+/**
+ * 宝箱内容配置
+ *
+ * field start
+ * @property   int  $id  记录ID,主键
+ * @property   int  $chest_id  宝箱物品ID,外键关联kku_item_items表
+ * @property   int  $item_id  可能获得的物品ID,外键关联kku_item_items表(与group_id二选一)
+ * @property   int  $group_id  物品组ID,外键关联kku_item_groups表(与item_id二选一)
+ * @property   int  $min_quantity  最小数量
+ * @property   int  $max_quantity  最大数量
+ * @property   float  $weight  权重,决定获取概率
+ * @property   int  $allow_duplicate  是否允许在同一宝箱中重复掉落(0:不允许, 1:允许)
+ * @property   int  $pity_count  保底次数,当玩家连续未获得该内容达到次数后必定获得(0表示不启用保底)
+ * @property   float  $pity_weight_factor  保底权重因子,用于递增概率计算(默认1.0)
+ * @property   \Carbon\Carbon  $created_at  创建时间
+ * @property   \Carbon\Carbon  $updated_at  更新时间
+ * field end
+ */
+class ItemChestContent extends ModelCore
 {
 {
-  "gold": 1000,
-  "diamond": 5,
-  "reputation": {
-    "faction_id": 2,
-    "amount": 100
-  },
-  "event_token": {
-    "token_id": 101,
-    "amount": 20
-  }
+    // 模型实现...
 }
 }
 ```
 ```
 
 
-#### 9.3.3 成本检查逻辑
+#### 5.1.3 ItemUser
+
+用户物品关联模型,记录用户拥有的物品。
 
 
 ```php
 ```php
-// 伪代码示例
-public function checkCraftCost($userId, $recipeId)
+/**
+ * 用户物品关联
+ *
+ * field start
+ * @property   int  $id  记录ID,主键
+ * @property   int  $user_id  用户ID
+ * @property   int  $item_id  统一属性物品ID,外键关联kku_item_items表
+ * @property   int  $instance_id  单独属性物品ID,外键关联kku_item_instances表(可为空)
+ * @property   int  $quantity  数量(对于单独属性物品,该值始终为1)
+ * @property   string  $expire_at  用户物品过期时间(可为空)
+ * @property   \Carbon\Carbon  $created_at  获取时间
+ * @property   \Carbon\Carbon  $updated_at  更新时间
+ * field end
+ */
+class ItemUser extends ModelCore
 {
 {
-    $recipe = Recipe::find($recipeId);
-    $coinCost = json_decode($recipe->coin_cost, true);
-
-    // 检查各种货币是否足够
-    foreach ($coinCost as $coinType => $amount) {
-        if (is_array($amount)) {
-            // 处理特殊货币(声望、活动代币等)
-            $specialCoinId = $amount['faction_id'] ?? $amount['token_id'];
-            $specialCoinAmount = $amount['amount'];
-
-            if (!$this->hasEnoughSpecialCoin($userId, $coinType, $specialCoinId, $specialCoinAmount)) {
-                return false;
-            }
-        } else {
-            // 处理基础货币(金币、钻石)
-            if (!$this->hasEnoughCoin($userId, $coinType, $amount)) {
-                return false;
-            }
-        }
-    }
-
-    return true;
+    // 模型实现...
 }
 }
 ```
 ```
 
 
-### 9.4 合成成功率机制
+### 5.2 模型关系
 
 
-系统支持概率性合成,增加游戏的随机性和挑战性:
+模型之间的关系定义如下:
 
 
-#### 9.4.1 基础成功率
+- **Item** 与 **ItemCategory** 是多对一关系
+- **Item** 与 **ItemInstance** 是一对多关系
+- **Item** 与 **ItemUser** 是一对多关系
+- **ItemInstance** 与 **ItemUser** 是一对多关系
+- **Item** 与 **ItemChestContent** 是一对多关系(作为宝箱)
+- **Item** 与 **ItemChestContent** 是一对多关系(作为内容)
+- **ItemGroup** 与 **ItemGroupItem** 是一对多关系
+- **ItemGroup** 与 **ItemChestContent** 是一对多关系
+- **ItemRecipe** 与 **ItemRecipeMaterial** 是一对多关系
+- **ItemRecipe** 与 **ItemUserRecipe** 是一对多关系
 
 
-每个配方都有一个基础成功率,定义在 `item_recipes` 表的 `success_rate` 字段中:
+## 6. 业务逻辑
 
 
-- 成功率范围:0-100(百分比)
-- 成功率为100表示必定成功
-- 成功率为0表示无法通过常规方式成功
+### 6.1 Logics层
 
 
-#### 9.4.2 成功率调整因素
+Logics层包含所有业务逻辑处理类,负责具体的业务规则实现。这些类不直接对外提供服务,而是由Services层调用。
 
 
-基础成功率可以受多种因素影响:
+#### 6.1.1 Item
 
 
-1. **玩家等级**:等级越高,成功率可能越高
-2. **技能加成**:特定技能可以提高成功率
-3. **道具加成**:使用特殊道具可以提高成功率
-4. **设备加成**:使用特殊设备进行合成可以提高成功率
-
-#### 9.4.3 成功率计算
+物品逻辑类,处理物品相关的业务逻辑。
 
 
 ```php
 ```php
-// 伪代码示例
-public function calculateSuccessRate($userId, $recipeId)
+/**
+ * 物品逻辑类
+ */
+class Item
 {
 {
-    $recipe = Recipe::find($recipeId);
-    $baseRate = $recipe->success_rate;
-
-    // 获取玩家等级加成
-    $user = User::find($userId);
-    $levelBonus = $this->getLevelSuccessBonus($user->level);
-
-    // 获取技能加成
-    $skillBonus = $this->getSkillSuccessBonus($userId);
-
-    // 获取道具加成
-    $itemBonus = $this->getItemSuccessBonus($userId);
+    /**
+     * 判断物品是否为宝箱
+     *
+     * @param ItemModel $item 物品模型
+     * @return bool
+     */
+    public function isChest(ItemModel $item): bool;
 
 
-    // 计算最终成功率
-    $finalRate = $baseRate + $levelBonus + $skillBonus + $itemBonus;
-
-    // 确保成功率在0-100范围内
-    return max(0, min(100, $finalRate));
+    /**
+     * 检查物品是否已过期(全局过期)
+     *
+     * @param ItemModel $item 物品模型
+     * @return bool
+     */
+    public function isExpired(ItemModel $item): bool;
 }
 }
 ```
 ```
 
 
-### 9.5 合成接口
-
-系统提供以下接口用于物品合成:
-
-#### 9.5.1 获取可用配方
-
-- **功能**:获取用户可用的合成配方列表
-- **参数**:用户ID、分类ID(可选)
-- **返回**:配方列表,包含名称、材料、成功率等信息
-- **处理逻辑**:
-  1. 查询用户已解锁的配方
-  2. 检查配方是否激活
-  3. 关联配方材料信息
-  4. 检查用户是否拥有足够材料
-  5. 返回配方列表,标记可合成状态
-
-#### 9.5.2 执行合成
-
-- **功能**:执行物品合成操作
-- **参数**:用户ID、配方ID
-- **返回**:合成结果、获得的物品
-- **处理逻辑**:
-  1. 检查配方是否存在且已解锁
-  2. 检查冷却时间是否已过
-  3. 检查用户是否拥有足够材料和货币
-  4. 扣除材料和货币
-  5. 根据成功率判定是否成功
-  6. 发放合成物品或返回失败信息
-  7. 更新用户配方使用记录
-  8. 记录合成日志
-
-#### 9.5.3 解锁配方
-
-- **功能**:解锁新的合成配方
-- **参数**:用户ID、配方ID
-- **返回**:解锁结果
-- **处理逻辑**:
-  1. 检查配方是否存在
-  2. 检查用户是否已解锁该配方
-  3. 检查解锁条件是否满足
-  4. 解锁配方并记录解锁时间
-  5. 返回解锁结果
-
-### 9.6 配方解锁机制
-
-系统支持多种配方解锁机制,增加游戏的探索性和进度感:
-
-#### 9.6.1 解锁方式
-
-1. **默认解锁**:
-   - 在 `item_recipes` 表中设置 `is_default_unlocked=1`
-   - 玩家创建角色时自动解锁
-
-2. **等级解锁**:
-   - 在 `unlock_condition` 中设置所需等级
-   - 玩家达到指定等级时自动解锁
-
-3. **任务解锁**:
-   - 在 `unlock_condition` 中设置关联任务
-   - 完成指定任务后解锁
-
-4. **成就解锁**:
-   - 在 `unlock_condition` 中设置关联成就
-   - 达成指定成就后解锁
-
-5. **物品解锁**:
-   - 使用特定物品(如配方书)解锁
-   - 系统检测物品使用事件并解锁对应配方
+#### 6.1.2 ChestContent
 
 
-#### 9.6.2 解锁条件格式
+宝箱内容逻辑类,处理宝箱内容相关的业务逻辑。
 
 
-在 `item_recipes` 表的 `unlock_condition` 字段中,使用JSON格式存储解锁条件:
-
-```json
+```php
+/**
+ * 宝箱内容逻辑类
+ */
+class ChestContent
 {
 {
-  "type": "level",
-  "value": 20
-}
-```
+    /**
+     * 判断是否为物品组内容
+     *
+     * @param ItemChestContent $content 宝箱内容
+     * @return bool
+     */
+    public function isGroupContent(ItemChestContent $content): bool;
 
 
-或者更复杂的条件:
+    /**
+     * 获取随机数量
+     *
+     * @param ItemChestContent $content 宝箱内容
+     * @return int
+     */
+    public function getRandomQuantity(ItemChestContent $content): int;
 
 
-```json
-{
-  "type": "multi",
-  "conditions": [
-    {
-      "type": "level",
-      "value": 15
-    },
-    {
-      "type": "quest",
-      "quest_id": 1024,
-      "status": "completed"
-    },
-    {
-      "type": "item",
-      "item_id": 5001,
-      "quantity": 1
-    }
-  ],
-  "logic": "and"
+    /**
+     * 计算调整后的权重(考虑保底机制)
+     *
+     * @param ItemChestContent $content 宝箱内容
+     * @param int $currentPityCount 当前保底计数
+     * @return float
+     */
+    public function getAdjustedWeight(ItemChestContent $content, int $currentPityCount = 0): float;
 }
 }
 ```
 ```
 
 
-### 9.7 合成结果计算
-
-系统支持多种合成结果计算方式,增加游戏的多样性:
-
-#### 9.7.1 固定结果
+#### 6.1.3 PityTime
 
 
-最简单的合成方式,成功后获得固定数量的物品:
+保底计数逻辑类,处理宝箱保底机制相关的业务逻辑。
 
 
 ```php
 ```php
-// 伪代码示例
-if ($this->isSuccess($userId, $recipeId)) {
-    $recipe = Recipe::find($recipeId);
-    $resultItemId = $recipe->result_item_id;
-    $quantity = $recipe->result_min_quantity; // 固定数量
-
-    $this->addItemToUser($userId, $resultItemId, $quantity);
-    return ['success' => true, 'item_id' => $resultItemId, 'quantity' => $quantity];
-} else {
-    return ['success' => false];
+/**
+ * 宝箱保底计数逻辑类
+ */
+class PityTime
+{
+    /**
+     * 增加保底计数
+     *
+     * @param ItemPityTime $pityTime 保底计数模型
+     * @param int $count 增加的数量,默认为1
+     * @return bool
+     */
+    public function incrementCount(ItemPityTime $pityTime, int $count = 1): bool;
+
+    /**
+     * 重置保底计数
+     *
+     * @param ItemPityTime $pityTime 保底计数模型
+     * @return bool
+     */
+    public function resetCount(ItemPityTime $pityTime): bool;
 }
 }
 ```
 ```
 
 
-#### 9.7.2 随机数量
+### 6.2 业务流程
 
 
-成功后获得的物品数量在一个范围内随机:
+#### 6.2.1 宝箱开启流程
 
 
-```php
-// 伪代码示例
-if ($this->isSuccess($userId, $recipeId)) {
-    $recipe = Recipe::find($recipeId);
-    $resultItemId = $recipe->result_item_id;
-    $minQuantity = $recipe->result_min_quantity;
-    $maxQuantity = $recipe->result_max_quantity;
-
-    // 随机数量
-    $quantity = rand($minQuantity, $maxQuantity);
-
-    $this->addItemToUser($userId, $resultItemId, $quantity);
-    return ['success' => true, 'item_id' => $resultItemId, 'quantity' => $quantity];
-} else {
-    return ['success' => false];
-}
-```
+1. 用户请求开启宝箱
+2. 验证用户是否拥有足够数量的宝箱
+3. 获取宝箱内容配置
+4. 获取用户保底计数
+5. 计算每个内容的调整后权重
+6. 检查是否有达到保底次数的内容
+7. 随机选择掉落内容
+8. 消耗宝箱物品
+9. 添加获得的物品到用户背包
+10. 更新保底计数
+11. 记录宝箱开启日志
+12. 返回开启结果
+
+#### 6.2.2 物品合成流程
+
+1. 用户请求合成物品
+2. 验证用户是否已解锁该配方
+3. 检查用户是否在冷却时间内
+4. 获取配方所需材料
+5. 检查用户是否拥有足够的材料
+6. 消耗材料
+7. 计算合成成功率
+8. 随机决定是否成功
+9. 如果成功,添加产物到用户背包
+10. 更新用户配方使用记录
+11. 记录合成日志
+12. 返回合成结果
 
 
-#### 9.7.3 品质变化
+## 7. 使用示例
 
 
-对于单独属性物品,合成可能影响物品的品质:
+### 7.1 在其他模块中使用物品服务
 
 
-```php
-// 伪代码示例
-if ($this->isSuccess($userId, $recipeId)) {
-    $recipe = Recipe::find($recipeId);
-    $resultItemId = $recipe->result_item_id;
-
-    // 计算品质
-    $baseQuality = 100;
-    $qualityVariation = rand(-10, 20); // 品质随机变化
-    $finalQuality = $baseQuality + $qualityVariation;
-
-    // 创建单独属性物品
-    $attributes = [
-        'quality' => $finalQuality,
-        // 其他属性...
-    ];
-
-    $instanceId = $this->createItemInstance($resultItemId, $attributes);
-    $this->addItemInstanceToUser($userId, $resultItemId, $instanceId);
-
-    return [
-        'success' => true,
-        'item_id' => $resultItemId,
-        'instance_id' => $instanceId,
-        'quality' => $finalQuality
-    ];
-} else {
-    return ['success' => false];
-}
-```
+```php
+// 在任务完成后添加奖励物品
+public function completeQuest(int $userId, int $questId)
+{
+    // 获取任务信息
+    $quest = $this->questRepository->find($questId);
+
+    // 验证任务是否可完成
+    if (!$this->questService->canComplete($userId, $questId)) {
+        throw new QuestCannotCompleteException("任务无法完成");
+    }
 
 
-## 10. 物品分解系统
-
-物品分解系统允许玩家将不需要的物品分解为基础材料或其他资源,增加物品循环利用的途径,丰富游戏经济系统。
-
-### 10.1 分解系统概述
-
-#### 10.1.1 系统特点
-
-1. **资源回收**:将不需要的物品转化为有用的材料或资源
-2. **经济平衡**:为过剩物品提供消耗渠道,维持游戏经济平衡
-3. **多样化奖励**:分解可以获得多种类型的材料和资源
-4. **随机性**:分解结果可以包含随机因素,增加游戏乐趣
-5. **品质影响**:物品品质影响分解获得的材料数量和种类
-
-#### 10.1.2 分解系统流程
-
-1. **物品选择**:玩家选择要分解的物品和数量
-2. **分解预览**:系统显示可能获得的材料及概率
-3. **确认分解**:玩家确认分解操作
-4. **规则匹配**:系统根据物品特性匹配适用的分解规则
-5. **结果计算**:根据规则计算分解结果
-6. **物品扣除**:从玩家背包中扣除被分解的物品
-7. **材料发放**:向玩家发放分解获得的材料
-8. **日志记录**:记录分解操作的详细信息
-
-### 10.2 数据库设计
-
-分解系统涉及三个主要数据表:分解规则表、分解结果配置表和分解日志表。
-
-#### 10.2.1 item_dismantle_rules 表(物品分解规则)
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 规则ID,主键 |
-| item_id | int | 物品ID,外键关联item_items表 |
-| category_id | int | 分类ID,外键关联item_categories表(与item_id二选一,用于对整个分类设置规则) |
-| min_rarity | tinyint | 最小适用稀有度 |
-| max_rarity | tinyint | 最大适用稀有度 |
-| priority | int | 规则优先级,当多个规则适用时,使用优先级最高的规则 |
-| is_active | tinyint | 是否激活(0:否, 1:是) |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-#### 10.2.2 item_dismantle_results 表(分解结果配置)
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 记录ID,主键 |
-| rule_id | int | 分解规则ID,外键关联item_dismantle_rules表 |
-| result_item_id | int | 结果物品ID,外键关联item_items表 |
-| min_quantity | int | 最小数量 |
-| max_quantity | int | 最大数量 |
-| base_chance | decimal(5,2) | 基础获取概率(百分比,最大100) |
-| rarity_factor | decimal(5,2) | 稀有度影响因子,物品稀有度对数量的影响系数 |
-| quality_factor | decimal(5,2) | 品质影响因子,物品品质对数量的影响系数 |
-| created_at | timestamp | 创建时间 |
-| updated_at | timestamp | 更新时间 |
-
-#### 10.2.3 item_dismantle_logs 表(分解记录)
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| id | int | 记录ID,主键 |
-| user_id | int | 用户ID |
-| item_id | int | 被分解的物品ID |
-| instance_id | int | 被分解的单独属性物品ID(可为空) |
-| quantity | int | 分解数量 |
-| rule_id | int | 使用的分解规则ID |
-| results | json | 分解结果,包含获得的物品ID、数量等信息 |
-| dismantle_time | timestamp | 分解时间 |
-| ip_address | varchar | 操作的IP地址 |
-| device_info | varchar | 设备信息 |
-| created_at | timestamp | 创建时间 |
-
-### 10.3 分解规则和机制
-
-物品分解系统支持多种规则和机制,确保分解结果的合理性和游戏平衡。
-
-#### 10.3.1 规则匹配逻辑
-
-系统按照以下优先级顺序匹配分解规则:
-
-1. **精确匹配**:根据物品ID精确匹配分解规则
-2. **分类匹配**:当没有精确匹配规则时,根据物品分类匹配规则
-3. **稀有度范围**:规则可以设置适用的稀有度范围
-4. **优先级**:当多个规则都适用时,使用优先级最高的规则
+    // 开始事务
+    DB::beginTransaction();
+    try {
+        // 标记任务完成
+        $this->questService->markAsCompleted($userId, $questId);
+
+        // 添加奖励物品
+        foreach ($quest->rewards as $reward) {
+            $this->itemService->addItem(
+                $userId,
+                $reward['item_id'],
+                $reward['quantity'],
+                [
+                    'source_type' => 'quest_reward',
+                    'source_id' => $questId,
+                    'details' => ['quest_name' => $quest->name],
+                ]
+            );
+        }
 
 
-```php
-// 伪代码示例
-public function findDismantleRule($itemId, $rarity)
-{
-    // 1. 尝试精确匹配
-    $rule = DismantleRule::where('item_id', $itemId)
-        ->where('is_active', 1)
-        ->where('min_rarity', '<=', $rarity)
-        ->where('max_rarity', '>=', $rarity)
-        ->orderBy('priority', 'desc')
-        ->first();
-
-    if ($rule) {
-        return $rule;
+        DB::commit();
+        return ['success' => true, 'message' => '任务完成,奖励已发放'];
+    } catch (Exception $e) {
+        DB::rollBack();
+        throw $e;
     }
     }
-
-    // 2. 尝试分类匹配
-    $item = Item::find($itemId);
-    $rule = DismantleRule::where('category_id', $item->category_id)
-        ->where('item_id', null)
-        ->where('is_active', 1)
-        ->where('min_rarity', '<=', $rarity)
-        ->where('max_rarity', '>=', $rarity)
-        ->orderBy('priority', 'desc')
-        ->first();
-
-    return $rule;
 }
 }
 ```
 ```
 
 
-#### 10.3.2 特殊物品处理
-
-不同类型的物品在分解时有特殊处理逻辑:
-
-1. **绑定物品**:绑定物品分解后,获得的材料也会继承绑定状态
-2. **不可分解物品**:通过item_items表中的dismantlable字段标记物品是否可分解
-3. **单独属性物品**:分解单独属性物品时,可以根据其特殊属性调整分解结果
+### 6.2 实现宝箱开启功能
 
 
 ```php
 ```php
-// 伪代码示例
-public function canDismantle($itemId, $instanceId = null)
+// 在控制器中实现宝箱开启功能
+public function openChest(Request $request, int $chestId)
 {
 {
-    $item = Item::find($itemId);
+    // 验证请求
+    $validated = $request->validate([
+        'quantity' => 'required|integer|min:1|max:10',
+    ]);
 
 
-    // 检查物品是否可分解
-    if ($item->dismantlable == 0) {
-        return false;
-    }
+    try {
+        // 获取当前用户ID
+        $userId = Auth::id();
+
+        // 开启宝箱
+        $result = $this->chestService->openChest(
+            $userId,
+            $chestId,
+            $validated['quantity'],
+            [
+                'ip_address' => $request->ip(),
+                'device_info' => $request->userAgent(),
+            ]
+        );
 
 
-    // 检查单独属性物品
-    if ($instanceId) {
-        $instance = ItemInstance::find($instanceId);
-        // 可以添加特殊条件,如不允许分解特定品质以上的装备
-        if ($instance->numeric_attributes->quality > 90) {
-            return false;
-        }
+        return response()->json([
+            'success' => true,
+            'data' => $result,
+        ]);
+    } catch (Exception $e) {
+        return response()->json([
+            'success' => false,
+            'message' => $e->getMessage(),
+        ], 400);
     }
     }
-
-    return true;
 }
 }
 ```
 ```
 
 
-#### 10.3.3 批量分解功能
-
-系统支持多种批量分解方式,提高用户体验:
-
-1. **同类物品批量分解**:一次分解多个相同物品
-2. **多类物品批量分解**:一次分解多种不同物品
-3. **自动分解**:可以设置自动分解规则,如自动分解低品质物品
+### 6.3 实现物品合成功能
 
 
 ```php
 ```php
-// 伪代码示例
-public function batchDismantle($userId, $items)
+// 在控制器中实现物品合成功能
+public function craftItem(Request $request, int $recipeId)
 {
 {
-    $results = [];
-    $totalResults = [];
-
-    DB::beginTransaction();
     try {
     try {
-        foreach ($items as $item) {
-            $itemId = $item['item_id'];
-            $instanceId = $item['instance_id'] ?? null;
-            $quantity = $item['quantity'];
-
-            // 检查是否可分解
-            if (!$this->canDismantle($itemId, $instanceId)) {
-                continue;
-            }
-
-            // 执行分解
-            $dismantleResult = $this->dismantleItem($userId, $itemId, $instanceId, $quantity);
-            $results[] = $dismantleResult;
-
-            // 合并结果
-            foreach ($dismantleResult['materials'] as $material) {
-                if (isset($totalResults[$material['item_id']])) {
-                    $totalResults[$material['item_id']]['quantity'] += $material['quantity'];
-                } else {
-                    $totalResults[$material['item_id']] = $material;
-                }
-            }
-        }
+        // 获取当前用户ID
+        $userId = Auth::id();
+
+        // 合成物品
+        $result = $this->craftService->craftItem(
+            $userId,
+            $recipeId,
+            [
+                'ip_address' => $request->ip(),
+                'device_info' => $request->userAgent(),
+            ]
+        );
 
 
-        DB::commit();
-        return [
+        return response()->json([
             'success' => true,
             'success' => true,
-            'detail_results' => $results,
-            'total_materials' => array_values($totalResults)
-        ];
-    } catch (\Exception $e) {
-        DB::rollBack();
-        return ['success' => false, 'message' => $e->getMessage()];
+            'data' => $result,
+        ]);
+    } catch (Exception $e) {
+        return response()->json([
+            'success' => false,
+            'message' => $e->getMessage(),
+        ], 400);
     }
     }
 }
 }
 ```
 ```
 
 
-### 10.4 分解结果计算
-
-分解结果的计算是一个多步骤的过程,考虑多种因素。
-
-#### 10.4.1 基础数量计算
-
-首先计算基础数量:
-
-```php
-// 伪代码示例
-$baseQuantity = rand($resultConfig->min_quantity, $resultConfig->max_quantity);
-```
-
-#### 10.4.2 稀有度和品质影响
-
-物品的稀有度和品质会影响最终获得的数量:
-
-```php
-// 伪代码示例
-$rarityBonus = ($item->rarity - 1) * $resultConfig->rarity_factor;
-
-// 对于单独属性物品,考虑品质
-$qualityBonus = 0;
-if ($instanceId) {
-    $instance = ItemInstance::find($instanceId);
-    $quality = $instance->numeric_attributes->quality ?? 0;
-    $qualityBonus = $quality * $resultConfig->quality_factor;
-}
-
-$finalQuantity = ceil($baseQuantity * (1 + $rarityBonus) * (1 + $qualityBonus));
-```
-
-#### 10.4.3 概率计算
-
-每个可能的分解结果都有一个获取概率,也受物品稀有度和品质影响:
-
-```php
-// 伪代码示例
-$baseChance = $resultConfig->base_chance;
-$rarityBonus = ($item->rarity - 1) * 5; // 每级稀有度增加5%概率
-
-// 对于单独属性物品,考虑品质
-$qualityBonus = 0;
-if ($instanceId) {
-    $instance = ItemInstance::find($instanceId);
-    $quality = $instance->numeric_attributes->quality ?? 0;
-    $qualityBonus = $quality * 0.1; // 每点品质增加0.1%概率
-}
-
-$finalChance = $baseChance + $rarityBonus + $qualityBonus;
-$finalChance = min(100, $finalChance); // 最大100%
-
-// 判断是否获得该结果
-$isObtained = (mt_rand(1, 100) <= $finalChance);
-```
-
-#### 10.4.4 特殊结果机制
-
-某些特殊情况下,分解可能有额外结果:
-
-1. **暴击分解**:有小概率获得双倍或三倍材料
-2. **稀有材料**:分解高品质物品有几率获得稀有材料
-3. **特殊道具**:某些物品分解可能获得特殊道具或货币
-
-```php
-// 伪代码示例
-// 检查是否触发暴击
-$criticalChance = 5; // 5%暴击概率
-$isCritical = (mt_rand(1, 100) <= $criticalChance);
-
-if ($isCritical) {
-    $criticalMultiplier = (mt_rand(1, 100) <= 30) ? 3 : 2; // 30%几率3倍,70%几率2倍
-    $finalQuantity *= $criticalMultiplier;
-    $results['is_critical'] = true;
-    $results['critical_multiplier'] = $criticalMultiplier;
-}
-
-// 检查是否获得稀有材料
-if ($item->rarity >= 3 && mt_rand(1, 100) <= 10) {
-    $rareMaterials = $this->getRareMaterials($item->category_id);
-    // 添加稀有材料到结果中
-}
-```
-
-### 10.5 分解系统接口
-
-系统提供以下接口用于物品分解:
-
-#### 10.5.1 获取物品分解预览
-
-- **功能**:预览物品分解可能获得的材料
-- **参数**:用户ID、物品ID、数量
-- **返回**:可能获得的材料列表及概率
-- **处理逻辑**:
-  1. 检查物品是否可分解
-  2. 获取适用的分解规则
-  3. 获取可能的分解结果及概率
-  4. 返回预览信息
-
-#### 10.5.2 执行物品分解
-
-- **功能**:分解指定物品并获得材料
-- **参数**:用户ID、物品ID、数量
-- **返回**:分解结果、获得的材料列表
-- **处理逻辑**:
-  1. 检查用户是否拥有足够数量的物品
-  2. 检查物品是否可分解
-  3. 获取适用的分解规则
-  4. 计算分解结果
-  5. 从用户背包中扣除物品
-  6. 向用户背包添加获得的材料
-  7. 记录分解日志
-
-#### 10.5.3 批量分解物品
-
-- **功能**:批量分解多个物品
-- **参数**:用户ID、物品ID列表及数量
-- **返回**:分解结果、获得的材料列表
-- **处理逻辑**:
-  1. 检查用户是否拥有所有指定物品
-  2. 对每个物品执行分解操作
-  3. 合并分解结果
-  4. 返回总体分解结果
-
-#### 10.5.4 获取分解历史
-
-- **功能**:查询用户的物品分解历史
-- **参数**:用户ID、时间范围(可选)
-- **返回**:分解历史记录列表
-- **处理逻辑**:
-  1. 查询用户的分解日志记录
-  2. 按时间排序
-  3. 返回分解历史列表
-
-### 10.6 分解日志记录
-
-系统记录所有分解操作,确保可追溯性和数据分析需求:
-
-#### 10.6.1 日志内容
-
-在 `item_dismantle_logs` 表中记录以下信息:
-
-1. **用户信息**:执行分解的用户ID
-2. **物品信息**:被分解的物品ID、数量
-3. **分解结果**:获得的材料列表及数量
-4. **时间信息**:分解操作的时间
-5. **规则信息**:应用的分解规则ID
-6. **安全信息**:IP地址、设备信息等
-
-#### 10.6.2 日志用途
-
-1. **数据分析**:分析玩家分解行为和偏好
-2. **问题排查**:解决玩家关于分解结果的疑问
-3. **系统监控**:监控分解系统的运行状态
-4. **平衡调整**:为游戏平衡调整提供数据支持
-
-### 10.7 与其他系统的交互
-
-分解系统与游戏中的多个系统有紧密的交互关系:
-
-#### 10.7.1 与背包系统交互
-
-- 分解操作会减少背包中的物品,并添加新的材料
-- 需要检查背包容量是否足够存放分解获得的材料
-
-#### 10.7.2 与任务和成就系统交互
-
-- 分解特定物品或获得特定材料可能触发任务进度
-- 累计分解次数或特定物品分解可能触发成就
-
-#### 10.7.3 与合成系统交互
-
-- 分解获得的材料可用于物品合成
-- 分解和合成形成物品循环利用的闭环
-
-#### 10.7.4 与商店系统交互
-
-- 分解获得的材料可以在商店出售或用于购买其他物品
-- 商店可以提供分解服务,收取一定费用
-
-## 11. 物品绑定机制
-
-物品绑定机制用于限制物品的流通和交易,保持游戏经济平衡,并增加游戏内容的专属性。
-
-### 11.1 绑定机制概述
-
-#### 11.1.1 绑定机制目的
-
-物品绑定机制主要用于以下目的:
-
-1. **限制物品交易**:防止高价值物品在玩家间无限制流通
-2. **增加成就感**:使某些物品具有专属性,提高获取难度和价值感
-3. **控制游戏经济**:防止物品市场泛滥和通货膨胀
-4. **区分物品来源**:通过不同的绑定状态区分物品的获取途径
-5. **增加游戏深度**:为不同物品设计不同的绑定规则,增加游戏策略性
-
-#### 11.1.2 绑定与不可交易的区别
-
-物品绑定和物品不可交易是两个不同的概念,虽然它们都会限制物品的流通,但在实现方式、应用场景和用户体验上有明显区别:
-
-1. **概念区别**:
-   - **物品绑定**:指物品与特定玩家或角色建立关联,限制物品只能被该玩家或角色使用
-   - **物品不可交易**:指物品本身的一种固有属性,决定该物品是否可以参与玩家间的交易
-
-2. **状态变化**:
-   - **物品绑定**:是一种状态变化,物品可以从未绑定变为已绑定
-   - **物品不可交易**:是物品的固有特性,通常在物品创建时就已确定
-
-3. **触发条件**:
-   - **物品绑定**:通常发生在特定触发条件下(获取、使用、装备等)
-   - **物品不可交易**:不依赖于物品的使用状态或归属,始终保持不变
-
-### 11.2 绑定类型
-
-系统支持多种绑定类型,可以根据游戏需求灵活配置:
-
-#### 11.2.1 按绑定时机分类
-
-1. **不绑定**:物品可以自由交易和转移
-2. **获取绑定**:物品一旦被玩家获取后绑定到该玩家账号
-3. **使用绑定**:物品在首次使用后绑定到玩家账号
-4. **装备绑定**:装备类物品在首次装备后绑定
-
-#### 11.2.2 按绑定对象分类
-
-1. **角色绑定**:物品绑定到特定角色,不可在同一账号的不同角色间转移
-2. **账号绑定**:物品绑定到账号,可在同一账号的不同角色间转移
-
-#### 11.2.3 按绑定时长分类
-
-1. **永久绑定**:一旦绑定,永远不会解除
-2. **时间绑定**:物品在特定时间段内绑定,之后可以解除绑定
-
-### 11.3 数据库设计
-
-物品绑定机制主要针对单独属性物品(item_instances),因为这些物品具有独特性和个体差异。
-
-#### 11.3.1 item_instances 表中的绑定相关字段
-
-| 字段名 | 类型 | 说明 |
-| --- | --- | --- |
-| is_bound | tinyint | 是否已绑定(0:未绑定, 1:已绑定) |
-| bound_to | varchar | 绑定对象(账号ID或角色ID) |
-| bind_exp_time | timestamp | 绑定过期时间(为空表示永久绑定) |
-
-这种设计的优势:
-
-1. **与物品实例直接关联**:绑定状态直接与物品实例关联,而不是与用户物品关系关联
-2. **简化数据查询**:不需要跨表查询即可获取物品的绑定状态
-3. **更好的语义表达**:绑定是物品实例的属性,而不是用户与物品关系的属性
-4. **支持物品转移**:当物品在用户间转移时,绑定状态随物品实例一起转移
-
-### 11.4 绑定状态处理逻辑
-
-物品绑定状态的处理逻辑主要针对单独属性物品(item_instances):
-
-#### 11.4.1 获取绑定处理
-
-```php
-// 伪代码示例
-public function handleAcquireBind($itemId, $instanceId, $userId)
-{
-    $item = Item::find($itemId);
-
-    // 检查物品是否需要获取绑定
-    if ($item->bind_type == 1) { // 获取绑定
-        $instance = ItemInstance::find($instanceId);
-        $instance->is_bound = 1;
-        $instance->bound_to = $userId;
-        $instance->bind_exp_time = null; // 永久绑定
-        $instance->save();
-
-        // 记录绑定日志
-        $this->logItemBind($instanceId, $userId, 'acquire');
-    }
-}
-```
-
-#### 11.4.2 使用绑定处理
-
-```php
-// 伪代码示例
-public function handleUseBind($itemId, $instanceId, $userId)
-{
-    $item = Item::find($itemId);
-
-    // 检查物品是否需要使用绑定
-    if ($item->bind_type == 2) { // 使用绑定
-        $instance = ItemInstance::find($instanceId);
-
-        // 只有未绑定的物品才需要处理
-        if ($instance->is_bound == 0) {
-            $instance->is_bound = 1;
-            $instance->bound_to = $userId;
-            $instance->bind_exp_time = null; // 永久绑定
-            $instance->save();
-
-            // 记录绑定日志
-            $this->logItemBind($instanceId, $userId, 'use');
-        }
-    }
-}
-```
-
-#### 11.4.3 装备绑定处理
-
-```php
-// 伪代码示例
-public function handleEquipBind($itemId, $instanceId, $userId)
-{
-    $item = Item::find($itemId);
-
-    // 检查物品是否需要装备绑定
-    if ($item->bind_type == 3) { // 装备绑定
-        $instance = ItemInstance::find($instanceId);
-
-        // 只有未绑定的物品才需要处理
-        if ($instance->is_bound == 0) {
-            $instance->is_bound = 1;
-            $instance->bound_to = $userId;
-            $instance->bind_exp_time = null; // 永久绑定
-            $instance->save();
-
-            // 记录绑定日志
-            $this->logItemBind($instanceId, $userId, 'equip');
-        }
-    }
-}
-```
-
-#### 11.4.4 临时绑定处理
-
-```php
-// 伪代码示例
-public function handleTimeBind($itemId, $instanceId, $userId, $bindDuration)
-{
-    $item = Item::find($itemId);
-
-    // 检查物品是否需要时间绑定
-    if ($item->bind_type == 6) { // 时间绑定
-        $instance = ItemInstance::find($instanceId);
-        $instance->is_bound = 1;
-        $instance->bound_to = $userId;
-
-        // 计算绑定过期时间
-        $expTime = now()->addSeconds($bindDuration);
-        $instance->bind_exp_time = $expTime;
-        $instance->save();
-
-        // 记录绑定日志
-        $this->logItemBind($instanceId, $userId, 'time', $expTime);
-    }
-}
-```
-
-### 11.5 绑定物品的交易限制
-
-单独属性物品的交易限制由两个因素决定:物品的可交易性(tradable)和绑定状态(is_bound):
-
-#### 11.5.1 交易检查流程
-
-```php
-// 伪代码示例
-public function canTrade($instanceId, $fromUserId, $toUserId)
-{
-    $instance = ItemInstance::find($instanceId);
-
-    // 检查物品是否可交易
-    if ($instance->tradable == 0) {
-        return [
-            'can_trade' => false,
-            'reason' => 'item_not_tradable'
-        ];
-    }
-
-    // 检查物品是否已绑定
-    if ($instance->is_bound == 1) {
-        // 检查绑定对象
-        if ($instance->bound_to != $fromUserId) {
-            return [
-                'can_trade' => false,
-                'reason' => 'item_bound_to_another_user'
-            ];
-        }
-
-        // 检查绑定类型(账号绑定可以在同一账号的角色间转移)
-        $fromUser = User::find($fromUserId);
-        $toUser = User::find($toUserId);
-
-        if ($fromUser->account_id != $toUser->account_id) {
-            return [
-                'can_trade' => false,
-                'reason' => 'item_bound_to_account'
-            ];
-        }
-    }
-
-    return [
-        'can_trade' => true
-    ];
-}
-```
-
-#### 11.5.2 商店出售限制
-
-```php
-// 伪代码示例
-public function canSellToShop($instanceId, $userId)
-{
-    $instance = ItemInstance::find($instanceId);
-
-    // 不可交易物品通常不能出售给NPC商店
-    if ($instance->tradable == 0) {
-        return [
-            'can_sell' => false,
-            'reason' => 'item_not_tradable'
-        ];
-    }
-
-    // 已绑定物品只能由绑定的玩家出售
-    if ($instance->is_bound == 1 && $instance->bound_to != $userId) {
-        return [
-            'can_sell' => false,
-            'reason' => 'item_bound_to_another_user'
-        ];
-    }
-
-    return [
-        'can_sell' => true,
-        // 已绑定物品可能有价格折扣
-        'price_modifier' => $instance->is_bound ? 0.5 : 1.0
-    ];
-}
-```
-
-#### 11.5.3 邮件发送限制
-
-```php
-// 伪代码示例
-public function canSendByMail($instanceId, $fromUserId, $toUserId)
-{
-    // 邮件发送限制与交易限制相同
-    return $this->canTrade($instanceId, $fromUserId, $toUserId);
-}
-```
-
-### 11.6 应用场景
-
-物品绑定机制适用于多种场景:
-
-#### 11.6.1 任务奖励
-
-重要任务奖励通常设置为获取绑定,确保玩家亲自完成任务:
-
-```php
-// 伪代码示例
-public function giveQuestReward($userId, $questId)
-{
-    $quest = Quest::find($questId);
-
-    foreach ($quest->rewards as $reward) {
-        $itemId = $reward['item_id'];
-        $quantity = $reward['quantity'];
-
-        // 创建物品实例并设置为获取绑定
-        $instanceId = $this->createItemInstance($itemId);
-        $this->handleAcquireBind($itemId, $instanceId, $userId);
-
-        // 添加到用户背包
-        $this->addItemInstanceToUser($userId, $itemId, $instanceId);
-    }
-}
-```
-
-#### 11.6.2 成就奖励
-
-成就奖励物品通常设置为账号绑定,表彰玩家的个人成就:
-
-```php
-// 伪代码示例
-public function giveAchievementReward($userId, $achievementId)
-{
-    $achievement = Achievement::find($achievementId);
-    $user = User::find($userId);
-
-    foreach ($achievement->rewards as $reward) {
-        $itemId = $reward['item_id'];
-        $quantity = $reward['quantity'];
-
-        // 创建物品实例并设置为账号绑定
-        $instanceId = $this->createItemInstance($itemId);
-        $instance = ItemInstance::find($instanceId);
-        $instance->is_bound = 1;
-        $instance->bound_to = $user->account_id; // 绑定到账号
-        $instance->save();
-
-        // 添加到用户背包
-        $this->addItemInstanceToUser($userId, $itemId, $instanceId);
-    }
-}
-```
-
-#### 11.6.3 活动物品
-
-活动限定物品通常设置为获取绑定,防止二次交易:
-
-```php
-// 伪代码示例
-public function giveEventItem($userId, $eventId, $itemId)
-{
-    $event = Event::find($eventId);
-
-    // 创建物品实例并设置为获取绑定
-    $instanceId = $this->createItemInstance($itemId);
-    $this->handleAcquireBind($itemId, $instanceId, $userId);
-
-    // 添加到用户背包
-    $this->addItemInstanceToUser($userId, $itemId, $instanceId);
-}
-```
-
-### 11.7 绑定状态的显示
-
-在游戏界面中,应清晰显示物品的绑定状态:
-
-#### 11.7.1 物品图标标记
-
-已绑定物品在图标上添加特殊标记,区分不同的绑定类型:
-
-```php
-// 伪代码示例
-public function getItemIconWithBindMark($itemId, $instanceId)
-{
-    $item = Item::find($itemId);
-    $iconPath = $item->icon;
-
-    if ($instanceId) {
-        $instance = ItemInstance::find($instanceId);
-
-        if ($instance->is_bound) {
-            // 根据绑定类型添加不同的标记
-            if ($instance->bind_exp_time) {
-                return $iconPath . '?mark=time_bound';
-            } else {
-                return $iconPath . '?mark=bound';
-            }
-        }
-    }
-
-    return $iconPath;
-}
-```
-
-#### 11.7.2 物品描述
-
-在物品描述中注明绑定类型和状态:
-
-```php
-// 伪代码示例
-public function getItemDescription($itemId, $instanceId)
-{
-    $item = Item::find($itemId);
-    $description = $item->description;
-
-    if ($instanceId) {
-        $instance = ItemInstance::find($instanceId);
-
-        if ($instance->is_bound) {
-            $description .= "\n已绑定到: " . $this->getBindTargetName($instance->bound_to);
-
-            if ($instance->bind_exp_time) {
-                $description .= "\n绑定解除时间: " . $instance->bind_exp_time;
-            } else {
-                $description .= "\n永久绑定";
-            }
-        }
-    }
-
-    return $description;
-}
-```
-
-#### 11.7.3 交易提示
-
-尝试交易绑定物品时,显示明确的错误提示:
-
-```php
-// 伪代码示例
-public function getTradeErrorMessage($result)
-{
-    switch ($result['reason']) {
-        case 'item_not_tradable':
-            return "该物品不可交易";
-        case 'item_bound_to_another_user':
-            return "该物品已绑定到其他玩家,无法交易";
-        case 'item_bound_to_account':
-            return "该物品已绑定到账号,只能在同一账号的角色间转移";
-        default:
-            return "无法交易该物品";
-    }
-}
-
-## 12. 系统交互
-
-GameItems模块作为游戏的核心系统之一,与其他多个系统有紧密的交互关系。
-
-### 12.1 与其他系统的交互
-
-#### 12.1.1 与用户系统交互
-
-物品系统需要与用户系统交互,确保物品正确关联到用户:
-
-```php
-// 伪代码示例
-public function checkUserExists($userId)
-{
-    $user = User::find($userId);
-    if (!$user) {
-        throw new UserNotFoundException("用户不存在: $userId");
-    }
-    return $user;
-}
-```
-
-#### 12.1.2 与任务系统交互
-
-物品系统与任务系统交互,支持任务相关的物品操作:
-
-```php
-// 伪代码示例
-public function checkQuestItemRequirement($userId, $questId)
-{
-    $quest = Quest::find($questId);
-    $requirements = $quest->item_requirements;
-
-    foreach ($requirements as $req) {
-        $itemId = $req['item_id'];
-        $quantity = $req['quantity'];
-
-        $userItem = UserItem::where('user_id', $userId)
-            ->where('item_id', $itemId)
-            ->first();
-
-        if (!$userItem || $userItem->quantity < $quantity) {
-            return false;
-        }
-    }
-
-    return true;
-}
-```
-
-#### 12.1.3 与商店系统交互
-
-物品系统与商店系统交互,支持物品的购买和出售:
-
-```php
-// 伪代码示例
-public function buyItemFromShop($userId, $shopItemId, $quantity)
-{
-    $shopItem = ShopItem::find($shopItemId);
-    $itemId = $shopItem->item_id;
-    $price = $shopItem->price * $quantity;
-
-    // 检查用户余额
-    $user = User::find($userId);
-    if ($user->balance < $price) {
-        return [
-            'success' => false,
-            'message' => '余额不足'
-        ];
-    }
-
-    // 扣除余额
-    $user->balance -= $price;
-    $user->save();
-
-    // 添加物品
-    $this->addItemToUser($userId, $itemId, $quantity);
-
-    return [
-        'success' => true,
-        'item_id' => $itemId,
-        'quantity' => $quantity,
-        'price' => $price
-    ];
-}
-```
-
-#### 12.1.4 与邮件系统交互
-
-物品系统与邮件系统交互,支持通过邮件发送物品:
-
-```php
-// 伪代码示例
-public function sendItemByMail($fromUserId, $toUserId, $itemId, $quantity, $message)
-{
-    // 检查物品是否可以发送
-    if (!$this->canSendItem($fromUserId, $itemId, $quantity)) {
-        return [
-            'success' => false,
-            'message' => '物品不可发送'
-        ];
-    }
-
-    // 从发送者背包中扣除物品
-    $this->removeItemFromUser($fromUserId, $itemId, $quantity);
-
-    // 创建邮件
-    $mail = Mail::create([
-        'from_user_id' => $fromUserId,
-        'to_user_id' => $toUserId,
-        'subject' => '物品发送',
-        'message' => $message,
-        'has_attachment' => 1
-    ]);
-
-    // 添加邮件附件
-    MailAttachment::create([
-        'mail_id' => $mail->id,
-        'item_id' => $itemId,
-        'quantity' => $quantity
-    ]);
-
-    return [
-        'success' => true,
-        'mail_id' => $mail->id
-    ];
-}
-```
-
-### 12.2 事件系统
-
-物品系统使用事件机制与其他系统进行松耦合交互:
-
-#### 12.2.1 物品相关事件
-
-系统定义了以下物品相关事件:
-
-1. **ItemAdded**:物品添加到用户背包时触发
-2. **ItemRemoved**:物品从用户背包移除时触发
-3. **ItemUsed**:物品被使用时触发
-4. **ItemTraded**:物品被交易时触发
-5. **ChestOpened**:宝箱被开启时触发
-6. **ItemCrafted**:物品被合成时触发
-7. **ItemDismantled**:物品被分解时触发
-8. **ItemBound**:物品被绑定时触发
-
-#### 12.2.2 事件监听
-
-其他系统可以监听这些事件并执行相应操作:
-
-```php
-// 伪代码示例
-// 在服务提供者中注册事件监听
-public function boot()
-{
-    Event::listen(ItemAdded::class, function ($event) {
-        // 更新任务进度
-        $this->questService->updateItemCollectionProgress(
-            $event->userId,
-            $event->itemId,
-            $event->quantity
-        );
-
-        // 更新成就进度
-        $this->achievementService->updateItemCollectionProgress(
-            $event->userId,
-            $event->itemId,
-            $event->quantity
-        );
-    });
-}
-```
-
-### 12.3 API接口
-
-物品系统提供以下API接口供其他系统调用:
-
-#### 12.3.1 物品查询接口
-
-```php
-// 伪代码示例
-public function getUserItems($userId, $filters = [])
-{
-    $query = UserItem::where('user_id', $userId);
-
-    // 应用过滤条件
-    if (isset($filters['item_id'])) {
-        $query->where('item_id', $filters['item_id']);
-    }
-
-    if (isset($filters['category_id'])) {
-        $query->whereHas('item', function ($q) use ($filters) {
-            $q->where('category_id', $filters['category_id']);
-        });
-    }
-
-    // 排除过期物品
-    $query->where(function ($q) {
-        $q->whereNull('expire_at')
-          ->orWhere('expire_at', '>', now());
-    });
-
-    return $query->get();
-}
-```
-
-#### 12.3.2 物品操作接口
-
-```php
-// 伪代码示例
-public function addItem($userId, $itemId, $quantity, $options = [])
-{
-    // 检查用户是否存在
-    $this->checkUserExists($userId);
-
-    // 检查物品是否存在
-    $item = Item::find($itemId);
-    if (!$item) {
-        throw new ItemNotFoundException("物品不存在: $itemId");
-    }
-
-    // 处理单独属性物品
-    if ($item->is_unique) {
-        return $this->addUniqueItem($userId, $itemId, $options);
-    }
-
-    // 处理统一属性物品
-    return $this->addNormalItem($userId, $itemId, $quantity, $options);
-}
-```
-
-## 13. 最佳实践与注意事项
-
-### 13.1 性能优化
-
-为确保物品系统的高性能运行,应遵循以下最佳实践:
-
-#### 13.1.1 数据库优化
-
-1. **合理使用索引**:
-   - 为频繁查询的字段创建索引
-   - 避免过多索引导致写入性能下降
-   - 定期分析查询性能,优化索引设计
-
-2. **批量操作**:
-   - 使用批量插入和更新减少数据库操作次数
-   - 对于大量物品操作,使用事务确保原子性
-
-3. **分表策略**:
-   - 对于高频访问的日志表,考虑按时间或用户ID分表
-   - 历史数据可以归档到单独的表中
-
-#### 13.1.2 缓存策略
-
-1. **用户物品缓存**:
-   - 缓存用户常用物品列表,减少数据库查询
-   - 使用Redis等内存数据库存储临时数据
-
-2. **物品定义缓存**:
-   - 缓存物品基础定义,避免重复查询
-   - 使用缓存标签管理相关缓存
-
-3. **缓存失效策略**:
-   - 在物品数据变更时主动清除相关缓存
-   - 设置合理的缓存过期时间
-
-#### 13.1.3 异步处理
-
-1. **队列处理**:
-   - 使用队列处理非即时性操作,如日志记录
-   - 批量物品操作可以放入队列异步处理
+## 8. 最佳实践
 
 
-2. **定时任务**:
-   - 使用定时任务处理物品过期、绑定解除等周期性操作
-   - 将资源密集型操作安排在服务器负载较低的时间执行
+### 8.1 开发规范
 
 
-### 13.2 安全考虑
+1. **模型中不包含业务逻辑**:所有业务逻辑都应放在Logics层中
+2. **服务类是对外的门面**:其他模块只能通过Services层访问GameItems模块功能
+3. **使用依赖注入**:通过构造函数注入依赖,提高可测试性
+4. **使用事务确保数据一致性**:所有涉及多个操作的功能都应使用数据库事务
+5. **记录关键操作日志**:所有物品获取和消耗操作都应记录日志
 
 
-物品系统涉及游戏经济核心,需要特别注意安全性:
+### 8.2 扩展指南
 
 
-#### 13.2.1 防作弊措施
+#### 8.2.1 添加新的物品类型
 
 
-1. **操作验证**:
-   - 所有物品操作都需要进行权限和合法性验证
-   - 敏感操作(如删除物品)需要额外的验证步骤
+1. 在 `Enums/ITEM_TYPE.php` 中添加新的类型常量
+2. 在 `Models/Item.php` 中添加相关的关联方法(如果需要)
+3. 在 `Logics/Item.php` 中添加处理新类型的逻辑方法
+4. 在 `Services/ItemService.php` 中添加对外提供的服务方法
 
 
-2. **异常监控**:
-   - 监控异常的物品获取和消耗模式
-   - 设置物品操作的频率限制和阈值警报
+#### 8.2.2 添加新的宝箱机制
 
 
-3. **日志审计**:
-   - 记录所有物品操作的详细日志
-   - 定期审计物品流通情况,发现潜在问题
+1. 在 `Models/ItemChestContent.php` 中添加新的字段(如果需要)
+2. 在 `Logics/ChestContent.php` 中添加新机制的逻辑方法
+3. 在 `Services/ChestService.php` 中修改 `openChest` 方法以支持新机制
 
 
-#### 13.2.2 并发控制
+### 8.3 性能优化建议
 
 
-1. **乐观锁**:
-   - 使用版本号或时间戳实现乐观锁
-   - 在高并发场景下防止数据不一致
+1. **使用批量操作**:对于大量物品操作,使用批量插入和更新
+2. **合理使用索引**:为频繁查询的字段创建索引
+3. **缓存热点数据**:缓存物品基础信息、配方等不常变化的数据
+4. **分页加载**:用户物品列表使用分页加载,避免一次加载过多数据
+5. **延迟加载**:使用延迟加载关联数据,避免N+1查询问题
 
 
-2. **悲观锁**:
-   - 对于关键操作,使用数据库行锁或表锁
-   - 在事务中锁定相关记录,防止并发修改
+### 7.2 安全考虑
 
 
-3. **分布式锁**:
-   - 在分布式环境中,使用Redis等实现分布式锁
-   - 确保跨服务器的操作原子性
+1. **事务完整性**:所有涉及多个操作的功能都使用数据库事务
+2. **日志记录**:记录所有物品获取和消耗操作,便于追踪和审计
+3. **输入验证**:严格验证所有输入参数,防止恶意请求
+4. **并发控制**:使用锁机制防止并发操作导致的数据不一致
+5. **权限检查**:确保用户只能操作自己的物品
 
 
-### 13.3 通用注意事项
+### 7.3 代码规范
 
 
-在实现和维护物品系统时,应注意以下事项:
+1. **遵循单一职责原则**:每个类只负责一个功能领域
+2. **使用依赖注入**:通过构造函数注入依赖,提高可测试性
+3. **编写单元测试**:为核心功能编写单元测试,确保代码质量
+4. **使用类型提示**:使用PHP类型提示增强代码可读性和安全性
+5. **编写详细注释**:为公共方法编写详细的PHPDoc注释
 
 
-1. **物品使用逻辑**应根据物品类型进行不同处理
-2. **需要考虑物品数量上限和背包容量限制**
-3. **稀有物品获取应有日志记录**
-4. **物品交易需考虑并发安全问题,建议使用数据库事务**
-5. **敏感操作(如删除物品)需要有权限验证**
-6. **在获取用户物品时,始终检查过期时间,不展示已过期物品**
-7. **在添加物品到用户背包时,需要检查全局过期时间**
-8. **宝箱开启操作应使用事务确保原子性**
-9. **宝箱配置应由管理员仔细调整和测试,确保概率合理**
-10. **当物品数量超过最大堆叠数量时,应自动创建新的堆叠**
-11. **在物品产出前应检查产出限制,防止超过预期产出**
-12. **对于关联物品限制,需要同时检查所有相关物品的产出记录**
-13. **定期检查并重置限制计数,确保重置机制正常运行**
-14. **对于限量物品,应设置监控机制,在接近限制时发出警告**
-15. **所有物品获取和消耗操作应记录到交易日志表中**
-16. **宝箱开启操作应同时记录到宝箱开启日志和物品交易日志**
-17. **定期清理和归档旧日志,防止日志表过大影响系统性能**
-18. **对于高频率的日志写入操作,考虑使用队列或批量写入方式提高性能**
-19. **物品合成操作应使用事务确保原子性,防止材料扣除后合成失败导致数据不一致**
-20. **合成配方的成功率和奖励应由管理员仔细调整和测试,确保游戏平衡**
-21. **对于高价值物品的合成,应考虑添加额外的验证和确认机制**
-22. **合成系统应考虑与物品产出限制系统集成,防止通过合成绕过产出限制**
-23. **处理多币种成本时,应确保在事务中同时检查和扣除所有必要的代币,防止部分扣除导致的数据不一致**
-24. **绑定物品的状态变更应在事务中处理,确保数据一致性**
-25. **对于时间绑定物品,需要定期检查并更新绑定状态**
-26. **在物品交易前,必须检查物品的绑定状态,防止绑定物品被交易**
-27. **物品分解操作应使用事务确保原子性,防止物品被扣除但未获得分解结果**
-28. **分解绑定物品时,获得的材料应继承绑定状态**
-29. **分解单独属性物品时,应考虑物品的特殊属性对分解结果的影响**
-30. **批量分解时,应注意性能优化,避免大量物品同时分解导致系统负担**
+### 7.4 常见问题解决
 
 
+1. **物品数量不足**:在消耗物品前先检查数量是否足够
+2. **宝箱概率问题**:使用权重系统而非直接概率,确保总和为100%
+3. **保底机制实现**:使用计数器记录未获得次数,达到阈值时强制获得
+4. **过期物品处理**:定期清理过期物品,避免数据库膨胀
+5. **并发操作冲突**:使用悲观锁或乐观锁解决并发操作问题

+ 4 - 0
noai.md

@@ -53,3 +53,7 @@ Show::make 正确的使用方式`Show::make($id, new FundRepository(), function
 apply_diff
 apply_diff
 
 
 阅读@/app/Module/readme.ignore.md  ,制定宠物模块开发文档到 @/app/Module/Pet/README.md
 阅读@/app/Module/readme.ignore.md  ,制定宠物模块开发文档到 @/app/Module/Pet/README.md
+
+
+改进 GenerateModelAnnotation ,在 模块 的 `Databases/createsql` 目录下生成每一个表的创建sql,一个表一个文件
+