Selaa lähdekoodia

feat(game): 添加神像奖励功能

- 新增神像奖励类型(农场buff)
- 实现神像奖励的发放逻辑
- 添加神像奖励的管理界面和工具链接
- 更新奖励类型枚举和文档说明
notfff 7 kuukautta sitten
vanhempi
commit
bde5c64622

+ 25 - 0
UCore/DcatAdmin/Form/Link.php

@@ -0,0 +1,25 @@
+<?php
+
+namespace UCore\DcatAdmin\Form;
+
+class Link extends \Dcat\Admin\Grid\Tools\AbstractTool
+{
+
+    protected $title = '链接';
+
+    protected $link = '';
+
+
+
+
+
+    public function html()
+    {
+        return <<<EOT
+<div class="btn-group pull-right" style="margin-right: 5px">
+    <a href="{$this->linkHref()}" class="btn btn-sm btn-primary "><i class="feather icon-list"></i><span class="d-none d-sm-inline">&nbsp;{$this->title()}</span></a>
+</div>
+EOT;
+    }
+
+}

+ 27 - 1
app/Module/Game/AdminControllers/GameRewardGroupController.php

@@ -125,7 +125,7 @@ class GameRewardGroupController extends AdminController
 
                 // 添加管理链接
                 $html .= '<div class="mt-3">';
-                $html .= '<a href="' . admin_url('game-reward-items?group_id=' . $id) . '" class="btn btn-sm btn-primary">';
+                $html .= '<a href="' . admin_url('game-reward-items?group_id=' . $id) . '" target="_blank" class="btn btn-sm btn-primary">';
                 $html .= '<i class="fa fa-list"></i> 管理奖励项';
                 $html .= '</a>';
                 $html .= '</div>';
@@ -227,6 +227,32 @@ class GameRewardGroupController extends AdminController
                 // 宠物体力奖励
                 return "宠物体力 (宠物ID: {$item->target_id})";
 
+            case REWARD_TYPE::FARM_SHRINE->value:
+                // 神像奖励(农场buff)
+                try {
+                    $shrineName = \App\Module\Farm\Enums\BUFF_TYPE::getName($item->target_id);
+                    $durationHours = $item->param2 > 0 ? $item->param2 : 24;
+                    $content = "<strong>{$shrineName}</strong> (类型: {$item->target_id})";
+                    $content .= "<br><small>持续时间: {$durationHours}小时</small>";
+
+                    // 添加参数说明
+                    $params = [];
+                    if ($item->param1 > 0) {
+                        $params[] = "神像类型: {$item->param1}";
+                    }
+                    if ($item->param2 > 0) {
+                        $params[] = "持续时间: {$item->param2}小时";
+                    }
+
+                    if (!empty($params)) {
+                        $content .= "<br><small>" . implode(', ', $params) . "</small>";
+                    }
+
+                    return $content;
+                } catch (\Exception $e) {
+                    return "神像 (类型: {$item->target_id})";
+                }
+
             case REWARD_TYPE::OTHER->value:
                 // 其他奖励
                 return "其他奖励 (ID: {$item->target_id})";

+ 29 - 6
app/Module/Game/AdminControllers/GameRewardItemController.php

@@ -4,6 +4,9 @@ namespace App\Module\Game\AdminControllers;
 
 use App\Module\Fund\Models\FundConfigModel;
 use App\Module\Fund\Models\FundCurrencyModel;
+use App\Module\Game\AdminControllers\Tools\ItemGroupList;
+use App\Module\Game\AdminControllers\Tools\RewareGroupInfo;
+use App\Module\Game\AdminControllers\Tools\RewareItemGroupInfoList;
 use App\Module\Game\Enums\REWARD_TYPE;
 use App\Module\Game\Models\GameRewardGroup;
 use App\Module\Game\Models\GameRewardItem;
@@ -141,6 +144,10 @@ class GameRewardItemController extends AdminController
                     case REWARD_TYPE::PET_ENERGY->value:
                         return "宠物体力 (宠物ID: {$targetId})";
 
+                    case REWARD_TYPE::FARM_SHRINE->value:
+                        $shrineName = \App\Module\Farm\Enums\BUFF_TYPE::getName($targetId);
+                        return "神像:{$shrineName} (类型: {$targetId})";
+
                     case REWARD_TYPE::OTHER->value:
                         return "其他奖励 (ID: {$targetId})";
 
@@ -199,6 +206,10 @@ class GameRewardItemController extends AdminController
                     case REWARD_TYPE::PET_ENERGY->value:
                         return "宠物体力 (宠物ID: {$targetId})";
 
+                    case REWARD_TYPE::FARM_SHRINE->value:
+                        $shrineName = \App\Module\Farm\Enums\BUFF_TYPE::getName($targetId);
+                        return "神像:{$shrineName} (类型: {$targetId})";
+
                     case REWARD_TYPE::OTHER->value:
                         return "其他奖励 (ID: {$targetId})";
 
@@ -240,10 +251,19 @@ class GameRewardItemController extends AdminController
     {
         return Form::make(new GameRewardItemRepository(), function (Form $form) {
             $form->display('id', 'ID');
-
             // 获取请求中的奖励组ID
             $groupId = request()->get('group_id');
 
+            $form->tools(function ( Form\Tools $tools) {
+                $tools->append(new RewareItemGroupInfoList());
+                $tools->append(new RewareGroupInfo());
+
+//                $tools->disableDelete();
+            });
+
+
+            $rewardType = $form->model()->reward_type ?? request()->get('reward_type');
+
             // 如果有奖励组ID,则设置默认值
             if ($groupId && $form->isCreating()) {
                 $form->hidden('group_id')->default($groupId);
@@ -266,14 +286,14 @@ class GameRewardItemController extends AdminController
                     ->required();
             }else{
                 $form->select('reward_type', '奖励类型')
-                    ->options(REWARD_TYPE::getAll());
+                    ->options(REWARD_TYPE::getAll())
+                    ->default($rewardType);
             }
 
 
             $form->select('target_id', '目标ID')
-                ->options(function () use ($form) {
+                ->options(function () use ($form,$rewardType) {
                     // 获取当前奖励类型
-                    $rewardType = $form->model()->reward_type ?? request()->get('reward_type');
 
                     // 根据奖励类型返回不同的选项
                     if ($rewardType == REWARD_TYPE::ITEM->value) {
@@ -285,6 +305,9 @@ class GameRewardItemController extends AdminController
                     } elseif ($rewardType == REWARD_TYPE::FUND_CONFIG->value) {
                         // 代币账户类型,返回代币账户列表
                         return FundConfigModel::pluck('name', 'id')->toArray();
+                    } elseif ($rewardType == REWARD_TYPE::FARM_SHRINE->value) {
+                        // 神像类型,返回神像类型列表
+                        return \App\Module\Farm\Enums\BUFF_TYPE::getAll();
                     }
 
                     // 默认返回空选项
@@ -295,11 +318,11 @@ class GameRewardItemController extends AdminController
 
             $form->number('param1', '参数1')
                 ->default(0)
-                ->help('根据奖励类型不同含义,如物品的品质、货币的来源等');
+                ->help('根据奖励类型不同含义:物品-品质,货币-来源,神像-神像类型(与目标ID相同)');
 
             $form->number('param2', '参数2')
                 ->default(0)
-                ->help('根据奖励类型不同含义,如物品的绑定状态、货币的类型等');
+                ->help('根据奖励类型不同含义:物品-绑定状态,货币-类型,神像-持续时间(小时,默认24)');
 
             $form->number('quantity', '数量')
                 ->default(1)

+ 30 - 0
app/Module/Game/AdminControllers/Tools/ItemGroupList.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Module\Game\AdminControllers\Tools;
+
+use UCore\DcatAdmin\Form\Link;
+
+class ItemGroupList extends Link
+{
+
+    protected $title = '分组列表';
+
+    public function allowed()
+    {
+        $groupId = request()->get('group_id');
+
+        return $groupId > 0;
+
+    }
+
+    public function linkHref()
+    {
+        $groupId = request()->get('group_id');
+
+        return admin_url('game-reward-groups/' . $groupId . '/edit');
+    }
+
+
+
+
+}

+ 30 - 0
app/Module/Game/AdminControllers/Tools/RewareGroupInfo.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Module\Game\AdminControllers\Tools;
+
+use UCore\DcatAdmin\Form\Link;
+
+class RewareGroupInfo extends Link
+{
+
+    protected $title = '奖励组信息';
+
+    public function allowed()
+    {
+        $groupId = request()->get('group_id');
+
+        return $groupId > 0;
+
+    }
+
+    public function linkHref()
+    {
+        $groupId = request()->get('group_id');
+
+        return admin_url('game-reward-groups/' . $groupId );
+    }
+
+
+
+
+}

+ 30 - 0
app/Module/Game/AdminControllers/Tools/RewareItemGroupInfoList.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace App\Module\Game\AdminControllers\Tools;
+
+use UCore\DcatAdmin\Form\Link;
+
+class RewareItemGroupInfoList extends Link
+{
+
+    protected $title = '奖励项目列表(本组)';
+
+    public function allowed()
+    {
+        $groupId = request()->get('group_id');
+
+        return $groupId > 0;
+
+    }
+
+    public function linkHref()
+    {
+        $groupId = request()->get('group_id');
+
+        return admin_url('game-reward-items/?group_id=' . $groupId );
+    }
+
+
+
+
+}

+ 52 - 1
app/Module/Game/Docs/奖励类型实现说明.md

@@ -119,7 +119,46 @@ $method->setAccessible(true);
 $actualGained = $method->invoke($petLogic, $item->targetId, $item->quantity);
 ```
 
-### 6. 其他奖励 (REWARD_TYPE::OTHER = 99)
+### 6. 神像奖励(农场buff) (REWARD_TYPE::FARM_SHRINE = 6)
+
+**功能**: 发放神像加持时间,直接激活用户的农场buff
+
+**参数说明**:
+- `target_id`: 神像类型(1=丰收之神,2=雨露之神,3=屠草之神,4=拭虫之神)
+- `param1`: 神像类型(与target_id相同,用于兼容)
+- `param2`: 持续时间(小时,默认24小时)
+- `quantity`: 激活次数(通常为1,表示激活次数)
+
+**实现方式**:
+```php
+// 获取神像类型和持续时间
+$shrineType = $item->targetId; // 神像类型
+$durationHours = $item->param2 > 0 ? $item->param2 : 24; // 持续时间(小时)
+$activationCount = $item->quantity > 0 ? $item->quantity : 1; // 激活次数
+
+// 验证神像类型是否有效
+if (!in_array($shrineType, [1, 2, 3, 4])) {
+    throw new Exception("无效的神像类型: {$shrineType}");
+}
+
+// 循环激活神像(支持多次激活)
+for ($i = 0; $i < $activationCount; $i++) {
+    // 使用BuffService激活神像
+    $buff = \App\Module\Farm\Services\BuffService::activateBuff($userId, $shrineType, $durationHours);
+
+    if (!$buff) {
+        throw new Exception("神像激活失败");
+    }
+}
+```
+
+**神像类型说明**:
+- `1`: 丰收之神 - 确保收获时获得最高产量
+- `2`: 雨露之神 - 防止干旱灾害
+- `3`: 屠草之神 - 防止杂草灾害
+- `4`: 拭虫之神 - 防止虫害灾害
+
+### 7. 其他奖励 (REWARD_TYPE::OTHER = 99)
 
 **功能**: 处理其他类型的奖励(如称号、成就等)
 
@@ -194,6 +233,18 @@ GameRewardItem::create([
     'weight' => 1.0,
     'is_guaranteed' => true
 ]);
+
+// 添加神像奖励
+GameRewardItem::create([
+    'group_id' => $group->id,
+    'reward_type' => REWARD_TYPE::FARM_SHRINE->value,
+    'target_id' => 1, // 丰收之神
+    'param1' => 1, // 神像类型(与target_id相同)
+    'param2' => 48, // 持续时间48小时
+    'quantity' => 1, // 激活1次
+    'weight' => 1.0,
+    'is_guaranteed' => true
+]);
 ```
 
 ## 测试

+ 11 - 0
app/Module/Game/Enums/REWARD_TYPE.php

@@ -44,6 +44,16 @@ enum REWARD_TYPE: int
      */
     case CURRENCY = 5;
 
+    /**
+     * 神像奖励(农场buff)
+     * 奖励用户神像加持时间
+     * target_id: 神像类型(1=丰收之神,2=雨露之神,3=屠草之神,4=拭虫之神)
+     * param1: 神像类型(与target_id相同,用于兼容)
+     * param2: 持续时间(小时)
+     * quantity: 数量(通常为1,表示激活次数)
+     */
+    case FARM_SHRINE = 6;
+
     /**
      * 其他奖励
      */
@@ -62,6 +72,7 @@ enum REWARD_TYPE: int
             self::PET_EXP->value => '宠物经验',
             self::PET_ENERGY->value => '宠物体力',
             self::CURRENCY->value => '币种',
+            self::FARM_SHRINE->value => '神像(农场buff)',
             self::OTHER->value => '其他',
         ];
     }

+ 78 - 0
app/Module/Game/Logics/RewardLogic.php

@@ -222,6 +222,10 @@ class RewardLogic
                 $this->processPetEnergyReward($userId, $item, $sourceType, $sourceId);
                 break;
 
+            case REWARD_TYPE::FARM_SHRINE->valueInt():
+                $this->processFarmShrineReward($userId, $item, $sourceType, $sourceId);
+                break;
+
             case REWARD_TYPE::OTHER->valueInt():
                 $this->processOtherReward($userId, $item, $sourceType, $sourceId);
                 break;
@@ -524,6 +528,80 @@ class RewardLogic
         }
     }
 
+    /**
+     * 处理神像奖励(农场buff)
+     *
+     * @param int $userId 用户ID
+     * @param RewardItemDto $item 奖励项
+     * @param string $sourceType 来源类型
+     * @param int $sourceId 来源ID
+     * @return void
+     * @throws Exception
+     */
+    private function processFarmShrineReward(int $userId, RewardItemDto $item, string $sourceType, int $sourceId): void
+    {
+        try {
+            // 获取神像类型和持续时间
+            $shrineType = $item->targetId; // 神像类型(1=丰收之神,2=雨露之神,3=屠草之神,4=拭虫之神)
+            $durationHours = $item->param2 > 0 ? $item->param2 : 24; // 持续时间(小时),默认24小时
+            $activationCount = $item->quantity > 0 ? $item->quantity : 1; // 激活次数,默认1次
+
+            // 验证神像类型是否有效
+            if (!in_array($shrineType, [1, 2, 3, 4])) {
+                throw new Exception("无效的神像类型: {$shrineType}");
+            }
+
+            // 验证用户是否存在
+            $farmUser = \App\Module\Farm\Models\FarmUser::where('user_id', $userId)->first();
+            if (!$farmUser) {
+                throw new Exception("用户农场数据不存在,用户ID: {$userId}");
+            }
+
+            // 循环激活神像(支持多次激活)
+            for ($i = 0; $i < $activationCount; $i++) {
+                // 使用BuffService激活神像
+                $buff = \App\Module\Farm\Services\BuffService::activateBuff($userId, $shrineType, $durationHours);
+
+                if (!$buff) {
+                    throw new Exception("神像激活失败,神像类型: {$shrineType},用户ID: {$userId}");
+                }
+
+                Log::info("神像奖励激活成功", [
+                    'userId' => $userId,
+                    'shrineType' => $shrineType,
+                    'shrineName' => \App\Module\Farm\Enums\BUFF_TYPE::getName($shrineType),
+                    'durationHours' => $durationHours,
+                    'activationIndex' => $i + 1,
+                    'totalActivations' => $activationCount,
+                    'expireTime' => $buff->expire_time ? $buff->expire_time->toDateTimeString() : null,
+                    'sourceType' => $sourceType,
+                    'sourceId' => $sourceId
+                ]);
+            }
+
+            Log::info("神像奖励发放完成", [
+                'userId' => $userId,
+                'shrineType' => $shrineType,
+                'shrineName' => \App\Module\Farm\Enums\BUFF_TYPE::getName($shrineType),
+                'durationHours' => $durationHours,
+                'totalActivations' => $activationCount,
+                'sourceType' => $sourceType,
+                'sourceId' => $sourceId
+            ]);
+        } catch (Exception $e) {
+            Log::error("神像奖励发放失败", [
+                'userId' => $userId,
+                'shrineType' => $item->targetId,
+                'durationHours' => $item->param2,
+                'quantity' => $item->quantity,
+                'sourceType' => $sourceType,
+                'sourceId' => $sourceId,
+                'error' => $e->getMessage()
+            ]);
+            throw new Exception("神像奖励发放失败: " . $e->getMessage());
+        }
+    }
+
     /**
      * 处理其他类型奖励
      *

+ 11 - 2
app/Module/Game/Models/GameRewardGroup.php

@@ -8,7 +8,7 @@ use UCore\ModelCore;
 /**
  * 奖励组
  *
- * field start 
+ * field start
  * @property  int  $id  主键
  * @property  string  $name  奖励组名称
  * @property  string  $code  奖励组编码(唯一)
@@ -28,7 +28,7 @@ class GameRewardGroup extends ModelCore
      */
     protected $table = 'game_reward_groups';
 
-    // attrlist start 
+    // attrlist start
     protected $fillable = [
         'id',
         'name',
@@ -142,6 +142,15 @@ class GameRewardGroup extends ModelCore
             case \App\Module\Game\Enums\REWARD_TYPE::PET_ENERGY->value:
                 return "宠物体力 (宠物ID: {$item->target_id})";
 
+            case \App\Module\Game\Enums\REWARD_TYPE::FARM_SHRINE->value:
+                try {
+                    $shrineName = \App\Module\Farm\Enums\BUFF_TYPE::getName($item->target_id);
+                    $durationHours = $item->param2 > 0 ? $item->param2 : 24;
+                    return "{$shrineName} ({$durationHours}小时)";
+                } catch (\Exception $e) {
+                    return "神像 (类型: {$item->target_id})";
+                }
+
             case \App\Module\Game\Enums\REWARD_TYPE::OTHER->value:
                 return "其他奖励 (ID: {$item->target_id})";