dongasai пре 8 месеци
родитељ
комит
e597c0bb66
4 измењених фајлова са 269 додато и 49 уклоњено
  1. 49 13
      app/Module/GameItems/GUILD.md
  2. 208 35
      app/Module/GameItems/README.md
  3. 11 0
      app/Module/GameItems/WORK.md
  4. 1 1
      app/Module/README.md

+ 49 - 13
app/Module/GameItems/GUILD.md

@@ -1,20 +1,56 @@
 # GameItems模块
+> 游戏物品管理核心模块
 
+## 1. 核心功能
 
-
-## 物品
-
-- 物品基础属性管理(名称、TID、类型等)
+### 物品管理
+- 物品基础属性管理(名称、TID、类型、稀有度等)
 - 物品获取与消耗逻辑
-- 物品库存管理
-    * 库存变更事件
-## 宝箱类物品
+- 物品库存管理(包含库存变更事件)
+- 物品交易系统
+- 特殊物品效果实现(如BUFF效果、任务触发等)
+- 物品附加属性
+
+### 宝箱系统
 - 宝箱类物品管理与开启机制
-- 宝箱类物品的开启记录
-- 物品过期时间管理(全局过期和用户特定过期)
+- 宝箱内容配置与概率控制
+- 宝箱开启记录
+- 多物品掉落机制
+- 宝箱类型管理(普通、稀有、限定等)
+
+### 过期管理
+- 全局过期时间(所有用户统一过期)
+- 用户特定过期时间(每个用户独立过期)
+- 过期物品自动清理
+
+## 2. 模块交互
+
+### 与用户模块
+- 用户物品展示
+- 等级奖励发放
+
+### 与商店模块
+- 物品购买/出售
+- 物品信息展示
+
+### 与任务模块
+- 任务奖励发放
+- 任务进度检查
+
+### 与战斗模块
+- 消耗品使用
+- 战斗掉落发放
+
+## 3. 核心特点
+
+1. **多物品宝箱系统**:
+   - 支持多物品同时掉落
+   - 可配置数量范围和概率
 
-核心功能特点:
+2. **灵活的过期机制**:
+   - 支持全局和用户级过期
+   - 自动清理机制
 
-1. **多物品宝箱系统**:支持一个宝箱同时掉落多个物品,并可配置每个物品的数量范围和概率
-2. **灵活的过期机制**:支持全局过期时间和用户特定过期时间,适应不同的游戏需求
-3. **完善的属性系统**:通过键值对存储物品属性,支持复杂的物品效果实现
+3. **属性扩展系统**:
+   - 键值对属性存储
+   - 支持复杂效果实现

+ 208 - 35
app/Module/GameItems/README.md

@@ -31,7 +31,7 @@ GameItems模块主要负责游戏内所有物品的管理,包括但不限于
 
 ### 2.1 数据表设计
 
-#### items表(物品基础信息
+#### items 表(统一属性物品)
 
 | 字段名 | 类型 | 说明 |
 | --- | --- | --- |
@@ -43,40 +43,48 @@ GameItems模块主要负责游戏内所有物品的管理,包括但不限于
 | icon | varchar | 物品图标路径 |
 | max_stack | int | 最大堆叠数量 |
 | sell_price | int | 出售价格 |
+| display_attributes | json | 展示属性,以JSON格式存储键值对,用于界面展示和描述的属性 |
+| numeric_attributes | json | 数值属性,以JSON格式存储键值对,用于计算和游戏逻辑的属性 |
 | min_drop_count | int | 宝箱最小掉落物品数量(仅宝箱类型物品有效) |
 | max_drop_count | int | 宝箱最大掉落物品数量(仅宝箱类型物品有效) |
 | global_expire_at | timestamp | 物品全局过期时间(可为空) |
 | created_at | timestamp | 创建时间 |
 | updated_at | timestamp | 更新时间 |
 
-#### user_items表(用户物品关联
+#### unique_items 表(单独属性物品
 
 | 字段名 | 类型 | 说明 |
 | --- | --- | --- |
-| id | int | 记录ID,主键 |
-| user_id | int | 用户ID,外键 |
-| item_id | int | 物品ID,外键 |
-| quantity | int | 数量 |
-| expire_at | timestamp | 用户物品过期时间(可为空) |
-| created_at | timestamp | 获取时间 |
+| id | int | 唯一物品ID,主键 |
+| item_id | int | 关联的基础物品ID,外键关联items表 |
+| name | varchar | 物品名称(可以与基础物品不同,如“锐利的钢刀”) |
+| display_attributes | json | 展示属性,以JSON格式存储键值对,用于界面展示和描述的属性 |
+| numeric_attributes | json | 数值属性,以JSON格式存储键值对,用于计算和游戏逻辑的属性 |
+| expire_at | timestamp | 物品过期时间(可为空) |
+| created_at | timestamp | 创建时间 |
 | updated_at | timestamp | 更新时间 |
 
-#### item_attributes表(物品属性
+#### user_items 表(用户物品关联
 
 | 字段名 | 类型 | 说明 |
 | --- | --- | --- |
 | id | int | 记录ID,主键 |
-| item_id | int | 物品ID,外键 |
-| attribute_key | varchar | 属性键名 |
-| attribute_value | varchar | 属性值 |
+| user_id | int | 用户ID,外键 |
+| item_id | int | 统一属性物品ID,外键关联items表(当该字段有值时,unique_item_id应为空) |
+| unique_item_id | int | 单独属性物品ID,外键关联unique_items表(当该字段有值时,item_id应为空) |
+| quantity | int | 数量(对于单独属性物品,该值始终为1) |
+| expire_at | timestamp | 用户物品过期时间(可为空) |
+| created_at | timestamp | 获取时间 |
+| updated_at | timestamp | 更新时间 |
 
-#### chest_items表(宝箱内容配置)
+#### chest_items 表(宝箱内容配置)
 
 | 字段名 | 类型 | 说明 |
 | --- | --- | --- |
 | id | int | 记录ID,主键 |
 | chest_id | int | 宝箱物品ID,外键关联items表 |
 | item_id | int | 可能获得的物品ID |
+| is_unique | tinyint | 是否生成单独属性物品(0:否, 1:是) |
 | min_quantity | int | 最小数量 |
 | max_quantity | int | 最大数量 |
 | weight | int | 权重,决定获取概率 |
@@ -93,48 +101,213 @@ GameItems模块主要负责游戏内所有物品的管理,包括但不限于
 | items | id | 主键 | 物品ID主键索引 |
 | items | type | 普通索引 | 加速按物品类型查询 |
 | items | global_expire_at | 普通索引 | 加速过期物品查询 |
-| user_items | user_id, item_id | 复合索引 | 加速用户物品查询 |
+| unique_items | id | 主键 | 唯一物品ID主键索引 |
+| unique_items | item_id | 普通索引 | 加速根据基础物品查询唯一物品 |
+| unique_items | expire_at | 普通索引 | 加速过期物品查询 |
+| user_items | user_id, item_id | 复合索引 | 加速用户统一属性物品查询 |
+| user_items | user_id, unique_item_id | 复合索引 | 加速用户单独属性物品查询 |
 | user_items | expire_at | 普通索引 | 加速过期物品查询 |
-| item_attributes | item_id | 普通索引 | 加速物品属性查询 |
 | chest_items | chest_id | 普通索引 | 加速宝箱内容查询 |
 | chest_items | item_id | 普通索引 | 加速物品在宝箱中的查询 |
+| chest_items | is_unique | 普通索引 | 加速查询生成唯一物品的宝箱配置 |
+
+### 2.3 可视图的方式
+
+以下是数据模型之间的关联关系图:
+
+```mermaid
+graph TD
+    User["User"] --- UserItems{"user_items<br>M:N"}
+    UserItems --- Item["Item<br>统一属性物品"]
+    UserItems --- UniqueItem["unique_items<br>单独属性物品"]
+    UniqueItem -->|"N:1"| Item
+
+    subgraph "宝箱系统"
+        ChestItem["Item<br>(type=5)宝箱"] -->|"1:N"| ChestConfig["chest_items<br>宝箱配置"]
+        ChestConfig -->|"N:1"| ItemDrop["Item<br>掉落物品"]
+        ChestConfig -->|"is_unique=1"| UniqueItem
+    end
+
+    classDef entity fill:#f9f,stroke:#333,stroke-width:2px;
+    classDef junction fill:#bbf,stroke:#33f,stroke-width:2px;
+
+    class User,Item,UniqueItem,ChestItem,ItemDrop entity;
+    class UserItems,ChestConfig junction;
+```
 
-### 2.3 模型关系
+图表说明:
+- **User 与 Item/UniqueItem**:用户可以拥有统一属性物品和单独属性物品,通过 user_items 表关联
+- **UniqueItem 与 Item**:多对一关系,每个单独属性物品都关联到一个基础物品模板
+- **宝箱物品与掉落物品**:宝箱(Item type=5)与 chest_items 表是一对多关系
+- **chest_items 与物品**:可以配置生成统一属性物品或单独属性物品(通过is_unique字段控制)
 
-使用Laravel Eloquent ORM实现数据模型之间的关联关系:
+### 2.4 单独属性物品实现
+
+为了支持“每个用户拥有的同类物品可以有不同属性”的需求(如不同的刀有不同的属性),我们采用了两种物品类型的设计:
+
+#### 实现方式说明
+
+该设计允许我们实现以下功能:
+
+1. **物品类型分离**
+   - `items`表存储统一属性物品,属性以JSON格式存储
+   - `unique_items`表存储单独属性物品,属性以JSON格式存储
+   - 每个单独属性物品都关联到一个基础物品模板
+
+2. **用户物品关联的灵活性**
+   - 用户可以同时拥有统一属性物品和单独属性物品
+   - `user_items`表中的`item_id`和`unique_item_id`字段互斥,一个记录只能关联其中一种物品
+   - 对于单独属性物品,`quantity`始终为1
+
+3. **宝箱生成机制**
+   - 宝箱可以配置生成统一属性物品或单独属性物品
+   - 通过`chest_items`表中的`is_unique`字段控制生成类型
+
+#### 使用示例
 
 ```php
-// Item模型与User多对多关系
-Item::belongsToMany(User::class, 'user_items')
-    ->withPivot('quantity', 'expire_at')
-    ->withTimestamps();
+// 为用户创建一把具有单独属性的刀
+public function createUniqueWeapon($userId, $baseItemId)
+{
+    // 开始事务
+    DB::beginTransaction();
 
-// Item模型与ItemAttribute一对多关系
-Item::hasMany(ItemAttribute::class);
+    try {
+        // 1. 获取基础物品信息
+        $baseItem = Item::findOrFail($baseItemId);
+
+        // 2. 生成随机属性
+        // 继承基础物品的展示属性
+        $baseDisplayAttributes = json_decode($baseItem->display_attributes, true) ?? [];
+        $displayAttributes = $baseDisplayAttributes;
+
+        // 添加自定义展示属性
+        $customDisplayAttributes = [
+            'appearance' => '闪亮的刀身上刻有精美的纹理',
+            'material' => '特殊合金打造',
+            'description' => '这把刀经过精心锻造,锐利无比'
+        ];
 
-// 宝箱物品与其内容物品的关系
-Item::hasMany(ChestItem::class, 'chest_id')
-    ->where('type', 5); // 类型5为宝箱
+        // 合并展示属性,自定义属性会覆盖基础属性
+        $displayAttributes = array_merge($displayAttributes, $customDisplayAttributes);
+
+        // 继承基础物品的数值属性
+        $baseNumericAttributes = json_decode($baseItem->numeric_attributes, true) ?? [];
+        $numericAttributes = $baseNumericAttributes;
+
+        // 生成随机数值属性
+        $randomNumericAttributes = [
+            'attack' => mt_rand(10, 20),
+            'durability' => mt_rand(80, 100),
+            'sharpness' => mt_rand(1, 5),
+            'critical_chance' => mt_rand(5, 15) / 100 // 暴击几率
+        ];
 
-// ChestItem模型与宝箱物品的关系
-ChestItem::belongsTo(Item::class, 'chest_id');
+        // 合并数值属性,随机属性会覆盖基础属性
+        $numericAttributes = array_merge($numericAttributes, $randomNumericAttributes);
 
-// ChestItem模型与内容物品的关系
-ChestItem::belongsTo(Item::class, 'item_id');
+        // 3. 创建单独属性物品
+        $uniqueItem = new UniqueItem();
+        $uniqueItem->item_id = $baseItemId;
+        $uniqueItem->name = "锐利的" . $baseItem->name; // 可以自定义名称
+        $uniqueItem->display_attributes = json_encode($displayAttributes);
+        $uniqueItem->numeric_attributes = json_encode($numericAttributes);
+        $uniqueItem->save();
 
-// User模型与Item多对多关系
-User::belongsToMany(Item::class, 'user_items')
-    ->withPivot('quantity', 'expire_at')
-    ->withTimestamps();
+        // 4. 关联到用户
+        $userItem = new UserItem();
+        $userItem->user_id = $userId;
+        $userItem->unique_item_id = $uniqueItem->id; // 注意这里使用unique_item_id而非item_id
+        $userItem->quantity = 1; // 单独属性物品数量始终为1
+        $userItem->save();
+
+        DB::commit();
+        return [
+            'user_item' => $userItem,
+            'unique_item' => $uniqueItem
+        ];
+
+    } catch (\Exception $e) {
+        DB::rollBack();
+        throw $e;
+    }
+}
+
+// 获取用户的所有单独属性武器
+public function getUserUniqueWeapons($userId, $baseItemId = null)
+{
+    // 构建查询
+    $query = UserItem::where('user_id', $userId)
+        ->whereNotNull('unique_item_id'); // 只查询单独属性物品
+
+    // 如果指定了基础物品ID,则只查询该类型的武器
+    if ($baseItemId) {
+        $query->whereHas('uniqueItem', function($q) use ($baseItemId) {
+            $q->where('item_id', $baseItemId);
+        });
+    }
+
+    // 获取用户物品记录,并预加载单独属性物品信息
+    $userItems = $query->with('uniqueItem.baseItem')->get();
+
+    $result = [];
+
+    foreach ($userItems as $userItem) {
+        $uniqueItem = $userItem->uniqueItem;
+        $baseItem = $uniqueItem->baseItem;
+
+        $weaponData = [
+            'id' => $userItem->id,
+            'unique_item_id' => $uniqueItem->id,
+            'base_item_id' => $baseItem->id,
+            'name' => $uniqueItem->name,
+            'base_name' => $baseItem->name,
+            'display_attributes' => json_decode($uniqueItem->display_attributes, true),
+            'numeric_attributes' => json_decode($uniqueItem->numeric_attributes, true),
+            'obtained_at' => $userItem->created_at->format('Y-m-d H:i:s')
+        ];
+
+        $result[] = $weaponData;
+    }
+
+    return $result;
+}
+
+// 为用户添加统一属性物品
+public function addItemToUser($userId, $itemId, $quantity = 1)
+{
+    // 查找用户是否已有该物品
+    $userItem = UserItem::where('user_id', $userId)
+        ->where('item_id', $itemId)
+        ->whereNull('unique_item_id') // 确保是统一属性物品
+        ->first();
+
+    if ($userItem) {
+        // 如果已有,增加数量
+        $userItem->quantity += $quantity;
+        $userItem->save();
+    } else {
+        // 如果没有,创建新记录
+        $userItem = new UserItem();
+        $userItem->user_id = $userId;
+        $userItem->item_id = $itemId;
+        $userItem->quantity = $quantity;
+        $userItem->save();
+    }
+
+    return $userItem;
+}
 ```
 
-### 2.4 数据库事务
+### 2.5 数据库事务
 
 在涉及多表操作的关键业务逻辑中,使用数据库事务确保数据一致性:
 
 1. **宝箱开启操作**:包含宝箱扣除和物品添加的原子性操作
 2. **物品交易**:确保物品转移的原子性
 3. **批量物品操作**:如批量删除过期物品
+4. **单独属性物品创建**:包含创建 unique_items 记录和关联到用户的原子性操作
+5. **宝箱生成单独属性物品**:当宝箱配置为生成单独属性物品时,需要保证创建和关联的原子性
 
 ## 3. 与其他模块的交互
 

+ 11 - 0
app/Module/GameItems/WORK.md

@@ -0,0 +1,11 @@
+
+
+比如一个武器 - 刀 ,每个人的刀的属性都不一样,一个人可以拥有多把刀 ,如何实现;更新文档
+
+
+重新规划,两种物品:
+1. 统一属性物品 items 表
+    - 属性字段,json存属性
+2. 单独属性物品 unique_items 表
+    - 属性字段,json存属性
+用户物品 user_items 两个字段 item_id,unique_item_id一个物品要么统一属性,要么单独属性

+ 1 - 1
app/Module/README.md

@@ -1 +1 @@
-# 模块
+# 模块目录