Sfoglia il codice sorgente

feat(game): 添加农场用户信息汇总功能

- 新增 FarmUserSummaryController 控制器,用于展示用户的农场信息汇总
- 在 User模型中添加 farmUser 关系,关联农场用户信息
- 创建新的数据库迁移,添加农场用户信息汇总菜单项
- 优化 DemoController,引入 RequestLandSow 类
notfff 7 mesi fa
parent
commit
4300c609f7

+ 3 - 1
app/Http/Controllers/DemoController.php

@@ -14,6 +14,8 @@ use Uraus\App\Common\RESPONSE_CODE;
 use Uraus\App\Request;
 use Uraus\App\Response;
 use Google\Protobuf\Internal\Message;
+use Uraus\Kku\Request\RequestLandSow;
+use Uraus\Kku\Request\RequestUserQueryData;
 
 class DemoController extends Controller
 {
@@ -25,7 +27,7 @@ class DemoController extends Controller
     public function login(HttpRequest $httpRequest)
     {
         $user_id = $httpRequest->input('user_id');
-
+        RequestLandSow::class;
 
     }
 

+ 576 - 0
app/Module/Game/AdminControllers/FarmUserSummaryController.php

@@ -0,0 +1,576 @@
+<?php
+
+namespace App\Module\Game\AdminControllers;
+
+use App\Module\Farm\Enums\GROWTH_STAGE;
+use App\Module\Farm\Models\FarmCrop;
+use App\Module\Farm\Models\FarmGodBuff;
+use App\Module\Farm\Models\FarmHouseConfig;
+use App\Module\Farm\Models\FarmLand;
+use App\Module\Farm\Models\FarmLandType;
+use App\Module\Farm\Models\FarmSeed;
+use App\Module\Farm\Models\FarmUser;
+use App\Module\Farm\Services\BuffService;
+use App\Module\Farm\Services\FarmService;
+use App\Module\Farm\Services\HouseService;
+use App\Module\Farm\Services\LandService;
+use App\Module\Fund\Models\FundModel;
+use App\Module\Fund\Services\AccountService;
+use App\Module\GameItems\Enums\ITEM_TYPE;
+use App\Module\GameItems\Models\Item;
+use App\Module\GameItems\Models\ItemUser;
+use App\Module\GameItems\Services\ItemService;
+use App\Module\User\Models\User;
+use Dcat\Admin\Grid;
+use Dcat\Admin\Layout\Content;
+use Dcat\Admin\Layout\Row;
+use Dcat\Admin\Widgets\Card;
+use Dcat\Admin\Widgets\Table;
+use Dcat\Admin\Widgets\Box;
+use Dcat\Admin\Widgets\Alert;
+use Illuminate\Support\Facades\DB;
+use Spatie\RouteAttributes\Attributes\Get;
+use Spatie\RouteAttributes\Attributes\Resource;
+use UCore\DcatAdmin\AdminController;
+
+/**
+ * 农场用户信息汇总控制器
+ *
+ * 用于展示用户的农场信息汇总,包括房屋、土地、作物、物品和代币信息
+ */
+#[Resource('farm-user-summary', names: 'dcat.admin.farm-user-summary')]
+class FarmUserSummaryController extends AdminController
+{
+
+    /**
+     * 页面标题
+     *
+     * @var string
+     */
+    protected $title = '农场用户信息汇总';
+
+    /**
+     * 用户列表页面
+     *
+     * @param Content $content
+     * @return Content
+     */
+    public function index(Content $content)
+    {
+        return $content
+            ->title($this->title)
+            ->description('查看用户的农场信息汇总')
+            ->body($this->grid());
+    }
+
+    /**
+     * 查看指定用户的农场信息汇总
+     *
+     * @param int $userId 用户ID
+     * @param Content $content
+     * @return Content
+     */
+    #[Get('farm-user-summary/{userId}', name: 'dcat.admin.farm-user-summary.show')]
+    public function show($userId, Content $content)
+    {
+        // 查找用户
+        $user = User::find($userId);
+        if (!$user) {
+            admin_error('错误', '用户不存在');
+
+            return redirect()->route('dcat.admin.farm-user-summary');
+        }
+
+        return $content
+            ->title($this->title)
+            ->description("用户 {$user->username}(ID: {$user->id})的农场信息汇总")
+            ->body(function (Row $row) use ($user) {
+                // 第一行:用户基本信息和房屋信息
+                $row->column(6, $this->userInfoCard($user));
+                $row->column(6, $this->houseInfoCard($user->id));
+
+                // 第二行:土地信息和作物信息
+                $row->column(12, $this->landInfoCard($user->id));
+
+                // 第三行:物品信息
+                $row->column(12, $this->itemInfoCard($user->id));
+
+                // 第四行:代币信息
+                $row->column(12, $this->fundInfoCard($user->id));
+
+                // 第五行:神像buff信息
+                $row->column(12, $this->buffInfoCard($user->id));
+            });
+    }
+
+    /**
+     * 用户基本信息卡片
+     *
+     * @param User $user 用户对象
+     * @return Card
+     */
+    protected function userInfoCard(User $user)
+    {
+        $userInfo = $user->info;
+        $avatar   = $userInfo ? $userInfo->avatar : '';
+        $nickname = $userInfo ? $userInfo->nickname : '';
+
+        $content = <<<HTML
+        <div class="row">
+            <div class="col-md-4">
+                <img src="{$avatar}" class="img-fluid rounded" style="max-width: 100px;" onerror="this.src='https://via.placeholder.com/100'">
+            </div>
+            <div class="col-md-8">
+                <p><strong>用户ID:</strong>{$user->id}</p>
+                <p><strong>用户名:</strong>{$user->username}</p>
+                <p><strong>昵称:</strong>{$nickname}</p>
+                <p><strong>注册时间:</strong>{$user->created_at}</p>
+            </div>
+        </div>
+        HTML;
+
+        return new Card('用户基本信息', $content);
+    }
+
+    /**
+     * 房屋信息卡片
+     *
+     * @param int $userId 用户ID
+     * @return Card
+     */
+    protected function houseInfoCard($userId)
+    {
+        // 获取用户的农场信息
+        $farmUser = FarmUser::where('user_id', $userId)->first();
+
+        if (!$farmUser) {
+            return new Card('房屋信息', new Alert('warning', '该用户没有农场信息'));
+        }
+
+        // 获取房屋配置信息
+        $houseConfig = FarmHouseConfig::where('level', $farmUser->house_level)->first();
+
+        $content = <<<HTML
+        <div class="row">
+            <div class="col-md-12">
+                <p><strong>房屋等级:</strong>{$farmUser->house_level}</p>
+                <p><strong>最后升级时间:</strong>{$farmUser->last_upgrade_time}</p>
+                <p><strong>产出加成:</strong>{$houseConfig->output_bonus}</p>
+                <p><strong>特殊土地上限:</strong>{$houseConfig->special_land_limit}</p>
+                <p><strong>可用土地数量:</strong>{$houseConfig->available_lands}</p>
+        HTML;
+
+        // 如果有降级天数,显示降级信息
+        if ($houseConfig->downgrade_days) {
+            $content .= "<p><strong>降级天数:</strong>{$houseConfig->downgrade_days}</p>";
+        }
+
+        $content .= <<<HTML
+            </div>
+        </div>
+        <div class="row mt-2">
+            <div class="col-md-12">
+                <a href="javascript:void(0);" class="btn btn-sm btn-primary" onclick="window.open('farm-house-configs', '_blank')">查看房屋配置</a>
+            </div>
+        </div>
+        HTML;
+
+        return new Card('房屋信息', $content);
+    }
+
+    /**
+     * 土地信息卡片
+     *
+     * @param int $userId 用户ID
+     * @return Card
+     */
+    protected function landInfoCard($userId)
+    {
+        // 获取用户的土地信息
+        /**
+         * @var FarmLand $land
+         */
+        $lands = FarmLand::with([ 'landType', 'crop.seed' ])
+            ->where('user_id', $userId)
+            ->get();
+
+        if ($lands->isEmpty()) {
+            return new Card('土地信息', new Alert('warning', '该用户没有土地信息'));
+        }
+
+        // 土地类型统计
+        $landTypeStats = $lands->groupBy('land_type')->map->count();
+
+        // 土地状态统计
+        $landStatusStats = $lands->groupBy('status')->map->count();
+
+        // 创建土地类型和状态的统计表格
+        $statsContent = '<div class="row">';
+
+        // 土地类型统计
+        $statsContent .= '<div class="col-md-6">';
+        $statsContent .= '<h5>土地类型统计</h5>';
+        $statsContent .= '<table class="table table-sm table-bordered">';
+        $statsContent .= '<thead><tr><th>土地类型</th><th>数量</th></tr></thead>';
+        $statsContent .= '<tbody>';
+
+        $landTypeNames = [
+            1 => '普通土地',
+            2 => '红土地',
+            3 => '黑土地',
+            4 => '金土地',
+            5 => '蓝土地',
+            6 => '紫土地',
+        ];
+
+        foreach ($landTypeStats as $typeId => $count) {
+            $typeName     = $landTypeNames[$typeId] ?? "类型{$typeId}";
+            $statsContent .= "<tr><td>{$typeName}</td><td>{$count}</td></tr>";
+        }
+
+        $statsContent .= '</tbody></table></div>';
+
+        // 土地状态统计
+        $statsContent .= '<div class="col-md-6">';
+        $statsContent .= '<h5>土地状态统计</h5>';
+        $statsContent .= '<table class="table table-sm table-bordered">';
+        $statsContent .= '<thead><tr><th>土地状态</th><th>数量</th></tr></thead>';
+        $statsContent .= '<tbody>';
+
+        $landStatusNames = [
+            0 => '空闲',
+            1 => '种植中',
+            2 => '灾害',
+            3 => '可收获',
+            4 => '枯萎',
+        ];
+
+        foreach ($landStatusStats as $statusId => $count) {
+            $statusName   = $landStatusNames[$statusId] ?? "状态{$statusId}";
+            $statsContent .= "<tr><td>{$statusName}</td><td>{$count}</td></tr>";
+        }
+
+        $statsContent .= '</tbody></table></div>';
+        $statsContent .= '</div>';
+
+        // 创建土地详情表格
+        $headers = [  'ID','位置', '土地类型', '状态', '种植作物', '种植时间', '生长阶段' ];
+        $rows    = [];
+
+        foreach ($lands as $land) {
+            $landType = $land->landType ? $land->landType->name : "类型{$land->land_type}";
+            $status   = $landStatusNames[$land->status] ?? "状态{$land->status}";
+
+            $crop        = $land->crop;
+            $cropInfo    = '无';
+            $plantTime   = '';
+            $growthStage = '';
+
+            if ($crop) {
+                $seedName    = $crop->seed ? $crop->seed->name : "种子{$crop->seed_id}";
+                $cropInfo    = $seedName;
+                $plantTime   = $crop->plant_time;
+                $growthStage = $this->getGrowthStageName($crop->growth_stage);
+            }
+
+            $rows[] = [
+                $land->id,
+                $land->position,
+                $landType,
+                $status,
+                $cropInfo,
+                $plantTime,
+                $growthStage,
+            ];
+        }
+
+        $table = new Table($headers, $rows);
+
+        $content = $statsContent . '<div class="mt-3">' . $table->render() . '</div>';
+
+        $content .= <<<HTML
+        <div class="row mt-2">
+            <div class="col-md-12">
+                <a href="javascript:void(0);" class="btn btn-sm btn-primary" onclick="window.open('farm-lands?user_id={$userId}', '_blank')">查看土地详情</a>
+            </div>
+        </div>
+        HTML;
+
+        return new Card('土地信息', $content);
+    }
+
+    /**
+     * 获取生长阶段名称
+     *
+     * @param int $stage 生长阶段值
+     * @return string 生长阶段名称
+     */
+    protected function getGrowthStageName(GROWTH_STAGE $stage)
+    {
+        $stageNames = GROWTH_STAGE::getValueDescription();
+
+        return $stageNames[$stage->valueInt()] ?? "阶段{$stage}";
+    }
+
+    /**
+     * 物品信息卡片
+     *
+     * @param int $userId 用户ID
+     * @return Card
+     */
+    protected function itemInfoCard($userId)
+    {
+        // 获取用户的物品信息
+        $items = ItemUser::with('item')
+            ->where('user_id', $userId)
+            ->orderBy('quantity', 'desc')
+            ->limit(20)
+            ->get();
+
+        if ($items->isEmpty()) {
+            return new Card('物品信息', new Alert('warning', '该用户没有物品信息'));
+        }
+
+        // 创建物品表格
+        $headers = [ '物品ID', '物品名称', '数量', '物品类型', '过期时间' ];
+        $rows    = [];
+
+        foreach ($items as $item) {
+            $itemName = $item->item ? $item->item->name : "物品{$item->item_id}";
+            $itemType = $item->item ? $this->getItemTypeName($item->item->type) : '';
+
+            $rows[] = [
+                $item->item_id,
+                $itemName,
+                $item->quantity,
+                $itemType,
+                $item->expire_at ?: '永久',
+            ];
+        }
+
+        $table = new Table($headers, $rows);
+
+        // 获取用户物品总数
+        $totalCount = ItemUser::where('user_id', $userId)->count();
+
+        $content = <<<HTML
+        <div class="alert alert-info">
+            用户共有 {$totalCount} 种物品,下表显示数量最多的前20种物品
+        </div>
+        {$table->render()}
+        <div class="row mt-2">
+            <div class="col-md-12">
+                <a href="javascript:void(0);" class="btn btn-sm btn-primary" onclick="window.open('game-items-users?user_id={$userId}', '_blank')">查看物品详情</a>
+            </div>
+        </div>
+        HTML;
+
+        return new Card('物品信息', $content);
+    }
+
+    /**
+     * 获取物品类型名称
+     *
+     * @param int $type 物品类型值
+     * @return string 物品类型名称
+     */
+    protected function getItemTypeName(ITEM_TYPE $type)
+    {
+        $typeNames = ITEM_TYPE::getValueDescription();
+
+        return $typeNames[$type->valueInt()] ?? "类型{$type}";
+    }
+
+    /**
+     * 代币信息卡片
+     *
+     * @param int $userId 用户ID
+     * @return Card
+     */
+    protected function fundInfoCard($userId)
+    {
+        // 获取用户的代币信息
+        $funds = FundModel::where('user_id', $userId)->get();
+
+        if ($funds->isEmpty()) {
+            return new Card('代币信息', new Alert('warning', '该用户没有代币信息'));
+        }
+
+        // 获取资金类型名称映射
+        $fundNames = AccountService::getFundsDesc();
+
+        // 创建代币表格
+        $headers = [ '账户ID', '账户名称', '余额', '更新时间' ];
+        $rows    = [];
+
+        foreach ($funds as $fund) {
+            $fundName = $fundNames[$fund->fund_id->value()] ?? "账户{$fund->fund_id->value()}";
+
+            $balance  = $fund->balance;
+
+            $rows[] = [
+                $fund->fund_id->value(),
+                $fundName,
+                $balance,
+                $fund->update_time ? date('Y-m-d H:i:s', $fund->update_time) : '',
+            ];
+        }
+
+        $table = new Table($headers, $rows);
+
+        $content = <<<HTML
+        {$table->render()}
+        <div class="row mt-2">
+            <div class="col-md-12">
+                <a href="javascript:void(0);" class="btn btn-sm btn-primary" onclick="window.open('fund-accounts?user_id={$userId}', '_blank')">查看账户详情</a>
+            </div>
+        </div>
+        HTML;
+
+        return new Card('代币信息', $content);
+    }
+
+    /**
+     * 神像buff信息卡片
+     *
+     * @param int $userId 用户ID
+     * @return Card
+     */
+    protected function buffInfoCard($userId)
+    {
+        // 获取用户的神像buff信息
+        $buffs = FarmGodBuff::where('user_id', $userId)
+            ->orderBy('expire_time', 'desc')
+            ->get();
+
+        if ($buffs->isEmpty()) {
+            return new Card('神像加持信息', new Alert('warning', '该用户没有神像加持信息'));
+        }
+
+        // 创建buff表格
+        $headers = [ '加持类型', '过期时间', '状态' ];
+        $rows    = [];
+
+        $buffTypeNames = [
+            1 => '丰收之神',
+            2 => '雨露之神',
+            3 => '屠草之神',
+            4 => '拭虫之神',
+        ];
+
+        foreach ($buffs as $buff) {
+            $buffType = $buffTypeNames[$buff->buff_type] ?? "类型{$buff->buff_type}";
+            $isActive = now()->lt($buff->expire_time);
+            $status   = $isActive ? '<span class="badge badge-success">生效中</span>' : '<span class="badge badge-secondary">已过期</span>';
+
+            $rows[] = [
+                $buffType,
+                $buff->expire_time,
+                $status,
+            ];
+        }
+
+        $table = new Table($headers, $rows);
+
+        $content = $table->render();
+
+        return new Card('神像加持信息', $content);
+    }
+
+    /**
+     * 用户列表网格
+     *
+     * @return Grid
+     */
+    protected function grid()
+    {
+        return Grid::make(User::with([ 'info', 'farmUser' ]), function (Grid $grid) {
+            $grid->column('id', 'ID')->sortable();
+
+            // 用户基本信息
+            $grid->column('username', '用户名');
+            $grid->column('info.nickname', '昵称');
+
+            // 农场信息
+            $grid->column('farmUser.house_level', '房屋等级')->sortable();
+
+            // 土地统计
+            $grid->column('id', '土地统计')->display(function ($userId) {
+                $lands = FarmLand::where('user_id', $userId)->get();
+                if ($lands->isEmpty()) {
+                    return '<span class="text-muted">无土地</span>';
+                }
+
+                $landTypeStats = $lands->groupBy('land_type')->map->count();
+                $totalLands    = $lands->count();
+
+                $html = "<div>总计: {$totalLands}块土地</div>";
+
+                $landTypeNames = [
+                    1 => '普通土地',
+                    2 => '红土地',
+                    3 => '黑土地',
+                    4 => '金土地',
+                    5 => '蓝土地',
+                    6 => '紫土地',
+                ];
+
+                foreach ($landTypeStats as $typeId => $count) {
+                    $typeName = $landTypeNames[$typeId] ?? "类型{$typeId}";
+                    $html     .= "<div>{$typeName}: {$count}块</div>";
+                }
+
+                return $html;
+            });
+
+            // 作物统计
+            $grid->column('id', '作物统计')->display(function ($userId) {
+                $crops = FarmCrop::where('user_id', $userId)->count();
+
+                return $crops > 0 ? "{$crops}种作物" : '<span class="text-muted">无作物</span>';
+            });
+
+            // 物品统计
+            $grid->column('id', '物品统计')->display(function ($userId) {
+                $itemCount = ItemUser::where('user_id', $userId)->count();
+
+                return $itemCount > 0 ? "{$itemCount}种物品" : '<span class="text-muted">无物品</span>';
+            });
+
+            // 代币统计
+            $grid->column('id', '代币统计')->display(function ($userId) {
+                $fundCount = FundModel::where('user_id', $userId)->count();
+
+                return $fundCount > 0 ? "{$fundCount}个账户" : '<span class="text-muted">无账户</span>';
+            });
+
+            $grid->column('created_at', '创建时间')->sortable();
+
+            // 添加查看详情操作
+            $grid->actions(function (Grid\Displayers\Actions $actions) {
+                // 禁用默认操作按钮
+                $actions->disableDelete();
+                $actions->disableEdit();
+                $actions->disableQuickEdit();
+
+                // 修改查看按钮,使其打开详情页
+                $actions->append('<a href="' . admin_url('farm-user-summary/' . $actions->getKey()) . '" class="btn btn-sm btn-primary">查看详情</a>');
+            });
+
+            // 禁用创建按钮
+            $grid->disableCreateButton();
+
+            // 禁用批量操作
+            $grid->disableBatchActions();
+
+            // 添加搜索
+            $grid->filter(function (Grid\Filter $filter) {
+                $filter->equal('id', '用户ID');
+                $filter->like('username', '用户名');
+                $filter->like('info.nickname', '昵称');
+                $filter->equal('farmUser.house_level', '房屋等级');
+            });
+        });
+    }
+
+}

+ 16 - 8
app/Module/User/Models/User.php

@@ -11,13 +11,13 @@ use UCore\ModelCore;
  *
  * 用户
  *
- * field start 
- * @property  int  $id  
- * @property  string  $username  
- * @property  string  $password  
- * @property  string  $remember_token  
- * @property  \Carbon\Carbon  $created_at  
- * @property  \Carbon\Carbon  $updated_at  
+ * field start
+ * @property  int  $id
+ * @property  string  $username
+ * @property  string  $password
+ * @property  string  $remember_token
+ * @property  \Carbon\Carbon  $created_at
+ * @property  \Carbon\Carbon  $updated_at
  * @property  int  $status2  状态
  * field end
  */
@@ -34,7 +34,7 @@ class User extends ModelCore
         'status2' => STATUS2::class,
     ];
 
-    // attrlist start 
+    // attrlist start
     protected $fillable = [
         'id',
         'username',
@@ -54,5 +54,13 @@ class User extends ModelCore
         return $this->hasOne(UserInfo::class, 'user_id', 'id');
     }
 
+    /**
+     * 用户农场信息
+     * @return \Illuminate\Database\Eloquent\Relations\HasOne
+     */
+    public function farmUser()
+    {
+        return $this->hasOne(\App\Module\Farm\Models\FarmUser::class, 'user_id', 'id');
+    }
 
 }

+ 109 - 0
database/migrations/2023_07_15_add_farm_user_summary_menu.php

@@ -0,0 +1,109 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Support\Facades\DB;
+
+class AddFarmUserSummaryMenu extends Migration
+{
+    /**
+     * 获取数据库连接
+     *
+     * @return string
+     */
+    public function getConnection()
+    {
+        return config('admin.database.connection') ?: config('database.default');
+    }
+
+    /**
+     * 获取菜单表名
+     *
+     * @return string
+     */
+    protected function getMenuTable()
+    {
+        return config('admin.database.menu_table');
+    }
+
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        $menuTable = $this->getMenuTable();
+        
+        // 查找Game模块的菜单ID
+        $gameMenuId = DB::table($menuTable)
+            ->where('title', 'like', '%游戏运营管理%')
+            ->value('id');
+            
+        if (!$gameMenuId) {
+            // 如果找不到游戏运营管理菜单,则创建它
+            $gameMenuId = DB::table($menuTable)->insertGetId([
+                'parent_id' => 0,
+                'order' => 8,
+                'title' => '游戏运营管理',
+                'icon' => 'fa-gamepad',
+                'uri' => null,
+                'created_at' => now(),
+                'updated_at' => now(),
+            ]);
+        }
+        
+        // 查找Farm模块的菜单ID
+        $farmMenuId = DB::table($menuTable)
+            ->where('parent_id', $gameMenuId)
+            ->where('title', 'like', '%农场管理%')
+            ->value('id');
+            
+        if (!$farmMenuId) {
+            // 如果找不到农场管理菜单,则创建它
+            $farmMenuId = DB::table($menuTable)->insertGetId([
+                'parent_id' => $gameMenuId,
+                'order' => 3,
+                'title' => '农场管理',
+                'icon' => 'fa-leaf',
+                'uri' => null,
+                'created_at' => now(),
+                'updated_at' => now(),
+            ]);
+        }
+        
+        // 检查菜单项是否已存在
+        $exists = DB::table($menuTable)
+            ->where('parent_id', $farmMenuId)
+            ->where('title', '农场用户信息汇总')
+            ->exists();
+            
+        if (!$exists) {
+            // 添加农场用户信息汇总菜单项
+            DB::table($menuTable)->insert([
+                'parent_id' => $farmMenuId,
+                'order' => 1, // 放在最前面
+                'title' => '农场用户信息汇总',
+                'icon' => 'fa-users',
+                'uri' => 'farm-user-summary',
+                'created_at' => now(),
+                'updated_at' => now(),
+            ]);
+        }
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        $menuTable = $this->getMenuTable();
+        
+        // 删除农场用户信息汇总菜单项
+        DB::table($menuTable)
+            ->where('uri', 'farm-user-summary')
+            ->where('title', '农场用户信息汇总')
+            ->delete();
+    }
+}