瀏覽代碼

feat:游戏管理功能

aiden 4 月之前
父節點
當前提交
ac850a35a1
共有 6 個文件被更改,包括 834 次插入10 次删除
  1. 447 0
      app/controller/Game.php
  2. 332 0
      app/model/GameModel.php
  3. 1 1
      app/model/PlayerModel.php
  4. 23 9
      config/menu.php
  5. 17 0
      config/permission.php
  6. 14 0
      route/app.php

+ 447 - 0
app/controller/Game.php

@@ -0,0 +1,447 @@
+<?php
+declare (strict_types = 1);
+
+namespace app\controller;
+
+use app\BaseController;
+use app\model\MerchantGameModel;
+use think\facade\Request;
+
+class Game extends BaseController
+{
+    /**
+     * 获取游戏列表
+     */
+    public function list()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'list')) {
+            return json_error([], '没有查看游戏列表的权限');
+        }
+        
+        // 获取查询参数
+        $page = Request::get('page', 1, 'intval');
+        $limit = Request::get('limit', 10, 'intval');
+        
+        // 过滤条件
+        $filters = [
+            'title' => Request::get('title', '', 'trim'),
+            'game_id' => Request::get('game_id', 0, 'intval'),
+            'game_platform' => Request::get('game_platform', ''),
+            'status' => Request::get('status', ''),
+            'rtp_type' => Request::get('rtp_type', ''),
+            'free_game_status' => Request::get('free_game_status', ''),
+            'terminal_spin' => Request::get('terminal_spin', ''),
+            'rtp_min' => Request::get('rtp_min', 0, 'floatval'),
+            'rtp_max' => Request::get('rtp_max', 0, 'floatval'),
+            'max_multiple_min' => Request::get('max_multiple_min', 0, 'intval'),
+            'max_multiple_max' => Request::get('max_multiple_max', 0, 'intval'),
+            'create_time_start' => Request::get('create_time_start', '', 'trim'),
+            'create_time_end' => Request::get('create_time_end', '', 'trim'),
+            'order' => Request::get('order', 'id', 'trim'),
+            'sort' => Request::get('sort', 'desc', 'trim'),
+        ];
+        
+        try {
+            // 获取游戏列表
+            $result = MerchantGameModel::getGameList($page, $limit, $filters);
+            
+            // 处理列表数据
+            foreach ($result['list'] as &$game) {
+                $game['platform_text'] = MerchantGameModel::getPlatformText($game['game_platform']);
+                $game['status_text'] = MerchantGameModel::getStatusText($game['status']);
+                $game['rtp_type_text'] = MerchantGameModel::getRtpTypeText($game['rtp_type']);
+                $game['free_game_status_text'] = $game['free_game_status'] ? '支持' : '不支持';
+                $game['terminal_spin_text'] = $game['terminal_spin'] ? '开启' : '关闭';
+                $game['create_time_text'] = date('Y-m-d H:i:s', $game['create_time']);
+                $game['update_time_text'] = date('Y-m-d H:i:s', $game['update_time']);
+                
+                // 处理押注配置显示
+                if (!empty($game['deposit_list'])) {
+                    $depositList = $game['deposit_list'];
+                    if (is_array($depositList)) {
+                        $game['deposit_list_text'] = implode(', ', $depositList);
+                    } else {
+                        $game['deposit_list_text'] = $depositList;
+                    }
+                } else {
+                    $game['deposit_list_text'] = '未设置';
+                }
+            }
+            
+            return json_success($result, '获取成功');
+        } catch (\Exception $e) {
+            return json_error([], '获取游戏列表失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 获取游戏详情
+     */
+    public function detail()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'detail')) {
+            return json_error([], '没有查看游戏详情的权限');
+        }
+        
+        $id = Request::get('id', 0, 'intval');
+        if (!$id) {
+            return json_error([], '游戏ID不能为空');
+        }
+        
+        try {
+            $game = MerchantGameModel::getGameDetail($id);
+            if (!$game) {
+                return json_error([], '游戏不存在');
+            }
+            
+            // 添加文本字段
+            $game['platform_text'] = MerchantGameModel::getPlatformText($game['game_platform']);
+            $game['status_text'] = MerchantGameModel::getStatusText($game['status']);
+            $game['rtp_type_text'] = MerchantGameModel::getRtpTypeText($game['rtp_type']);
+            $game['free_game_status_text'] = $game['free_game_status'] ? '支持' : '不支持';
+            $game['terminal_spin_text'] = $game['terminal_spin'] ? '开启' : '关闭';
+            $game['create_time_text'] = date('Y-m-d H:i:s', $game['create_time']);
+            $game['update_time_text'] = date('Y-m-d H:i:s', $game['update_time']);
+            
+            return json_success($game, '获取成功');
+        } catch (\Exception $e) {
+            return json_error([], '获取游戏详情失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 创建游戏
+     */
+    public function create()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'create')) {
+            return json_error([], '没有创建游戏的权限');
+        }
+        
+        $data = Request::only([
+            'game_platform', 'game_id', 'title', 'title_en', 'image', 'image_en',
+            'rtp', 'rtp_type', 'free_game_status', 'bet_line_count', 'bet_max_level',
+            'max_multiple_count', 'deposit_list', 'default_deposit', 'default_deposit_level',
+            'min_deposit', 'terminal_spin', 'status'
+        ]);
+        
+        // 验证必填字段
+        if (empty($data['game_platform'])) {
+            return json_error([], '游戏平台不能为空');
+        }
+        
+        if (empty($data['game_id'])) {
+            return json_error([], '游戏ID不能为空');
+        }
+        
+        if (empty($data['title'])) {
+            return json_error([], '游戏名称不能为空');
+        }
+        
+        // 检查游戏ID是否已存在
+        if (MerchantGameModel::checkGameIdExists($data['game_id'])) {
+            return json_error([], '游戏ID已存在');
+        }
+        
+        try {
+            $game = MerchantGameModel::createGame($data);
+            return json_success(['id' => $game->id], '创建游戏成功');
+        } catch (\Exception $e) {
+            return json_error([], '创建游戏失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 更新游戏
+     */
+    public function update()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'update')) {
+            return json_error([], '没有更新游戏的权限');
+        }
+        
+        $id = Request::post('id', 0, 'intval');
+        if (!$id) {
+            return json_error([], '游戏ID不能为空');
+        }
+        
+        $data = Request::only([
+            'game_platform', 'game_id', 'title', 'title_en', 'image', 'image_en',
+            'rtp', 'rtp_type', 'free_game_status', 'bet_line_count', 'bet_max_level',
+            'max_multiple_count', 'deposit_list', 'default_deposit', 'default_deposit_level',
+            'min_deposit', 'terminal_spin', 'status'
+        ]);
+        
+        // 验证必填字段
+        if (empty($data['title'])) {
+            return json_error([], '游戏名称不能为空');
+        }
+        
+        // 检查游戏是否存在
+        $game = MerchantGameModel::getGameDetail($id);
+        if (!$game) {
+            return json_error([], '游戏不存在');
+        }
+        
+        // 如果修改了游戏ID,检查是否与其他游戏冲突
+        if (isset($data['game_id']) && $data['game_id'] != $game['game_id']) {
+            if (MerchantGameModel::checkGameIdExists($data['game_id'], $id)) {
+                return json_error([], '游戏ID已存在');
+            }
+        }
+        
+        try {
+            MerchantGameModel::updateGame($id, $data);
+            return json_success([], '更新游戏成功');
+        } catch (\Exception $e) {
+            return json_error([], '更新游戏失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 更新游戏状态
+     */
+    public function updateStatus()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'updateStatus')) {
+            return json_error([], '没有更新游戏状态的权限');
+        }
+        
+        $id = Request::post('id', 0, 'intval');
+        $status = Request::post('status', 0, 'intval');
+        
+        if (!$id) {
+            return json_error([], '游戏ID不能为空');
+        }
+        
+        if (!in_array($status, [
+            MerchantGameModel::STATUS_NORMAL,
+            MerchantGameModel::STATUS_MAINTAIN,
+            MerchantGameModel::STATUS_DISABLED
+        ])) {
+            return json_error([], '状态值无效');
+        }
+        
+        try {
+            $result = MerchantGameModel::updateGameStatus($id, $status);
+            if ($result) {
+                return json_success([], '状态更新成功');
+            } else {
+                return json_error([], '状态更新失败');
+            }
+        } catch (\Exception $e) {
+            return json_error([], '更新游戏状态失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 批量更新游戏状态
+     */
+    public function batchUpdateStatus()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'batchUpdate')) {
+            return json_error([], '没有批量更新游戏状态的权限');
+        }
+        
+        $ids = Request::post('ids', []);
+        $status = Request::post('status', 0, 'intval');
+        
+        if (empty($ids) || !is_array($ids)) {
+            return json_error([], '请选择要更新的游戏');
+        }
+        
+        if (!in_array($status, [
+            MerchantGameModel::STATUS_NORMAL,
+            MerchantGameModel::STATUS_MAINTAIN,
+            MerchantGameModel::STATUS_DISABLED
+        ])) {
+            return json_error([], '状态值无效');
+        }
+        
+        try {
+            $result = MerchantGameModel::batchUpdateStatus($ids, $status);
+            if ($result > 0) {
+                return json_success(['updated' => $result], '批量更新成功');
+            } else {
+                return json_error([], '批量更新失败');
+            }
+        } catch (\Exception $e) {
+            return json_error([], '批量更新游戏状态失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 获取游戏统计信息
+     */
+    public function statistics()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'statistics')) {
+            return json_error([], '没有查看游戏统计的权限');
+        }
+        
+        try {
+            $statistics = MerchantGameModel::getGameStatistics();
+            return json_success($statistics, '获取成功');
+        } catch (\Exception $e) {
+            return json_error([], '获取游戏统计失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 获取游戏平台列表
+     */
+    public function getPlatforms()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        try {
+            $platforms = MerchantGameModel::getAllPlatforms();
+            return json_success($platforms, '获取成功');
+        } catch (\Exception $e) {
+            return json_error([], '获取游戏平台失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 删除游戏
+     */
+    public function delete()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'delete')) {
+            return json_error([], '没有删除游戏的权限');
+        }
+        
+        $id = Request::post('id', 0, 'intval');
+        if (!$id) {
+            return json_error([], '游戏ID不能为空');
+        }
+        
+        try {
+            // 检查游戏是否存在
+            $game = MerchantGameModel::getGameDetail($id);
+            if (!$game) {
+                return json_error([], '游戏不存在');
+            }
+            
+            // 删除游戏
+            MerchantGameModel::where('id', $id)->delete();
+            
+            return json_success([], '删除成功');
+        } catch (\Exception $e) {
+            return json_error([], '删除游戏失败:' . $e->getMessage());
+        }
+    }
+    
+    /**
+     * 导出游戏列表
+     */
+    public function export()
+    {
+        $loginInfo = checkUserLogin();
+        if (!$loginInfo) {
+            return json_error([], '请先登录');
+        }
+        
+        if (!checkPermission($loginInfo, 'Game', 'export')) {
+            return json_error([], '没有导出游戏列表的权限');
+        }
+        
+        // 获取所有过滤条件
+        $filters = [
+            'title' => Request::get('title', '', 'trim'),
+            'game_id' => Request::get('game_id', 0, 'intval'),
+            'game_platform' => Request::get('game_platform', ''),
+            'status' => Request::get('status', ''),
+            'rtp_type' => Request::get('rtp_type', ''),
+            'free_game_status' => Request::get('free_game_status', ''),
+            'terminal_spin' => Request::get('terminal_spin', ''),
+            'rtp_min' => Request::get('rtp_min', 0, 'floatval'),
+            'rtp_max' => Request::get('rtp_max', 0, 'floatval'),
+            'max_multiple_min' => Request::get('max_multiple_min', 0, 'intval'),
+            'max_multiple_max' => Request::get('max_multiple_max', 0, 'intval'),
+            'create_time_start' => Request::get('create_time_start', '', 'trim'),
+            'create_time_end' => Request::get('create_time_end', '', 'trim'),
+        ];
+        
+        try {
+            // 获取所有数据
+            $result = MerchantGameModel::getGameList(1, 100000, $filters);
+            
+            // 生成CSV数据
+            $csvData = "ID,游戏ID,游戏平台,中文名称,英文名称,RTP,RTP类型,免费游戏,下注线数,最高倍数,默认押注,最低押注,止损止赢,状态,创建时间\n";
+            
+            foreach ($result['list'] as $game) {
+                $csvData .= sprintf(
+                    "%d,%d,%s,%s,%s,%.2f,%s,%s,%d,%d,%.2f,%.2f,%s,%s,%s\n",
+                    $game['id'],
+                    $game['game_id'],
+                    MerchantGameModel::getPlatformText($game['game_platform']),
+                    $game['title'],
+                    $game['title_en'],
+                    $game['rtp'],
+                    MerchantGameModel::getRtpTypeText($game['rtp_type']),
+                    $game['free_game_status'] ? '支持' : '不支持',
+                    $game['bet_line_count'],
+                    $game['max_multiple_count'],
+                    $game['default_deposit'],
+                    $game['min_deposit'],
+                    $game['terminal_spin'] ? '开启' : '关闭',
+                    MerchantGameModel::getStatusText($game['status']),
+                    date('Y-m-d H:i:s', $game['create_time'])
+                );
+            }
+            
+            // 返回CSV数据
+            return response($csvData)
+                ->header('Content-Type', 'text/csv; charset=utf-8')
+                ->header('Content-Disposition', 'attachment; filename="games_' . date('YmdHis') . '.csv"')
+                ->header('Cache-Control', 'no-cache, must-revalidate');
+                
+        } catch (\Exception $e) {
+            return json_error([], '导出游戏列表失败:' . $e->getMessage());
+        }
+    }
+}

+ 332 - 0
app/model/GameModel.php

@@ -0,0 +1,332 @@
+<?php
+declare (strict_types = 1);
+
+namespace app\model;
+
+use think\Model;
+
+/**
+ * 商户游戏模型
+ */
+class GameModel extends Model
+{
+    // 设置表名
+    protected $name = 'merchant_game_list';
+
+    // 设置主键
+    protected $pk = 'id';
+
+    // 设置自动时间戳
+    protected $autoWriteTimestamp = 'int';
+
+    // 设置字段类型
+    protected $type = [
+        'id' => 'int',
+        'game_platform' => 'int',
+        'game_id' => 'int',
+        'title' => 'string',
+        'title_en' => 'string',
+        'image' => 'string',
+        'image_en' => 'string',
+        'rtp' => 'float',
+        'rtp_type' => 'int',
+        'free_game_status' => 'int',
+        'bet_line_count' => 'int',
+        'bet_max_level' => 'int',
+        'max_multiple_count' => 'int',
+        'deposit_list' => 'string',
+        'default_deposit' => 'float',
+        'default_deposit_level' => 'int',
+        'min_deposit' => 'float',
+        'terminal_spin' => 'int',
+        'status' => 'int',
+        'create_time' => 'int',
+        'update_time' => 'int',
+    ];
+
+    // 游戏平台常量
+    const PLATFORM_PG = 1;      // PG平台
+    const PLATFORM_PP = 2;      // PP平台
+    const PLATFORM_CQ9 = 3;     // CQ9平台
+    const PLATFORM_JDB = 4;     // JDB平台
+    const PLATFORM_JILI = 5;    // JILI平台
+
+    // 状态常量
+    const STATUS_NORMAL = 0;    // 正常
+    const STATUS_MAINTAIN = 1;  // 维护
+    const STATUS_DISABLED = 2;  // 停用
+
+    // RTP类型常量
+    const RTP_TYPE_FIXED = 1;       // 固定RTP
+    const RTP_TYPE_DYNAMIC = 2;     // 动态RTP
+    const RTP_TYPE_CUSTOM = 3;      // 自定义RTP
+
+    // 免费游戏状态
+    const FREE_GAME_DISABLED = 0;   // 不支持购买免费游戏
+    const FREE_GAME_ENABLED = 1;    // 支持购买免费游戏
+
+    // 止损止赢功能
+    const TERMINAL_SPIN_DISABLED = 0;   // 关闭止损止赢
+    const TERMINAL_SPIN_ENABLED = 1;    // 开启止损止赢
+
+    /**
+     * 获取游戏平台文本
+     */
+    public static function getPlatformText($platform): string
+    {
+        $platformMap = [
+            self::PLATFORM_PG => 'PG',
+            self::PLATFORM_PP => 'PP',
+            self::PLATFORM_CQ9 => 'CQ9',
+            self::PLATFORM_JDB => 'JDB',
+            self::PLATFORM_JILI => 'JILI',
+        ];
+        return $platformMap[$platform] ?? '未知';
+    }
+
+    /**
+     * 获取状态文本
+     */
+    public static function getStatusText($status): string
+    {
+        $statusMap = [
+            self::STATUS_NORMAL => '正常',
+            self::STATUS_MAINTAIN => '维护',
+            self::STATUS_DISABLED => '停用',
+        ];
+        return $statusMap[$status] ?? '未知';
+    }
+
+    /**
+     * 获取RTP类型文本
+     */
+    public static function getRtpTypeText($rtpType): string
+    {
+        $rtpTypeMap = [
+            self::RTP_TYPE_FIXED => '固定',
+            self::RTP_TYPE_DYNAMIC => '动态',
+            self::RTP_TYPE_CUSTOM => '自定义',
+        ];
+        return $rtpTypeMap[$rtpType] ?? '未知';
+    }
+
+    /**
+     * 获取游戏列表
+     * 
+     * 注意:merchant_game_list表没有merchant_id字段,
+     * 如果需要按商户过滤,需要关联其他表或调整表结构
+     */
+    public static function getGameList($page = 1, $limit = 10, $filters = [])
+    {
+        $query = self::where('id', '>', 0); // 基础查询
+
+        // 应用过滤条件
+        if (!empty($filters['title'])) {
+            $query->where(function($q) use ($filters) {
+                $q->where('title', 'like', '%' . $filters['title'] . '%')
+                  ->whereOr('title_en', 'like', '%' . $filters['title'] . '%');
+            });
+        }
+
+        if (!empty($filters['game_id'])) {
+            $query->where('game_id', $filters['game_id']);
+        }
+
+        if (isset($filters['game_platform']) && $filters['game_platform'] !== '') {
+            $query->where('game_platform', $filters['game_platform']);
+        }
+
+        if (isset($filters['status']) && $filters['status'] !== '') {
+            $query->where('status', $filters['status']);
+        }
+
+        if (isset($filters['rtp_type']) && $filters['rtp_type'] !== '') {
+            $query->where('rtp_type', $filters['rtp_type']);
+        }
+
+        if (isset($filters['free_game_status']) && $filters['free_game_status'] !== '') {
+            $query->where('free_game_status', $filters['free_game_status']);
+        }
+
+        if (isset($filters['terminal_spin']) && $filters['terminal_spin'] !== '') {
+            $query->where('terminal_spin', $filters['terminal_spin']);
+        }
+
+        // RTP范围
+        if (!empty($filters['rtp_min'])) {
+            $query->where('rtp', '>=', $filters['rtp_min']);
+        }
+        if (!empty($filters['rtp_max'])) {
+            $query->where('rtp', '<=', $filters['rtp_max']);
+        }
+
+        // 最高倍数范围
+        if (!empty($filters['max_multiple_min'])) {
+            $query->where('max_multiple_count', '>=', $filters['max_multiple_min']);
+        }
+        if (!empty($filters['max_multiple_max'])) {
+            $query->where('max_multiple_count', '<=', $filters['max_multiple_max']);
+        }
+
+        // 创建时间范围
+        if (!empty($filters['create_time_start'])) {
+            $query->where('create_time', '>=', strtotime($filters['create_time_start']));
+        }
+        if (!empty($filters['create_time_end'])) {
+            $query->where('create_time', '<=', strtotime($filters['create_time_end']));
+        }
+
+        // 排序
+        $order = $filters['order'] ?? 'id';
+        $sort = $filters['sort'] ?? 'desc';
+        $query->order($order, $sort);
+
+        // 获取总数
+        $total = $query->count();
+
+        // 获取列表
+        $list = $query->page($page, $limit)->select();
+
+        return [
+            'list' => $list,
+            'total' => $total,
+            'page' => $page,
+            'limit' => $limit
+        ];
+    }
+
+    /**
+     * 获取游戏详情
+     */
+    public static function getGameDetail($id)
+    {
+        return self::where('id', $id)->find();
+    }
+
+    /**
+     * 创建游戏
+     */
+    public static function createGame($data)
+    {
+        // 处理押注配置
+        if (isset($data['deposit_list']) && is_array($data['deposit_list'])) {
+            $data['deposit_list'] = json_encode($data['deposit_list']);
+        }
+        
+        return self::create($data);
+    }
+
+    /**
+     * 更新游戏
+     */
+    public static function updateGame($id, $data)
+    {
+        // 处理押注配置
+        if (isset($data['deposit_list']) && is_array($data['deposit_list'])) {
+            $data['deposit_list'] = json_encode($data['deposit_list']);
+        }
+        
+        return self::where('id', $id)->update($data);
+    }
+
+    /**
+     * 更新游戏状态
+     */
+    public static function updateGameStatus($id, $status)
+    {
+        return self::where('id', $id)->update(['status' => $status]);
+    }
+
+    /**
+     * 批量更新游戏状态
+     */
+    public static function batchUpdateStatus($ids, $status)
+    {
+        return self::whereIn('id', $ids)->update(['status' => $status]);
+    }
+
+    /**
+     * 获取游戏统计信息
+     */
+    public static function getGameStatistics()
+    {
+        $totalGames = self::count();
+        $normalGames = self::where('status', self::STATUS_NORMAL)->count();
+        $maintainGames = self::where('status', self::STATUS_MAINTAIN)->count();
+        $disabledGames = self::where('status', self::STATUS_DISABLED)->count();
+        
+        // 按平台统计
+        $platformStats = [];
+        $platforms = [
+            self::PLATFORM_PG => 'PG',
+            self::PLATFORM_PP => 'PP',
+            self::PLATFORM_CQ9 => 'CQ9',
+            self::PLATFORM_JDB => 'JDB',
+            self::PLATFORM_JILI => 'JILI',
+        ];
+        
+        foreach ($platforms as $platform => $name) {
+            $platformStats[$name] = self::where('game_platform', $platform)->count();
+        }
+        
+        return [
+            'total_games' => $totalGames,
+            'normal_games' => $normalGames,
+            'maintain_games' => $maintainGames,
+            'disabled_games' => $disabledGames,
+            'platform_stats' => $platformStats,
+            'avg_rtp' => self::avg('rtp'),
+            'free_game_enabled' => self::where('free_game_status', self::FREE_GAME_ENABLED)->count(),
+            'terminal_spin_enabled' => self::where('terminal_spin', self::TERMINAL_SPIN_ENABLED)->count(),
+        ];
+    }
+
+    /**
+     * 获取所有游戏平台
+     */
+    public static function getAllPlatforms(): array
+    {
+        return [
+            ['value' => self::PLATFORM_PG, 'text' => 'PG'],
+            ['value' => self::PLATFORM_PP, 'text' => 'PP'],
+            ['value' => self::PLATFORM_CQ9, 'text' => 'CQ9'],
+            ['value' => self::PLATFORM_JDB, 'text' => 'JDB'],
+            ['value' => self::PLATFORM_JILI, 'text' => 'JILI'],
+        ];
+    }
+
+    /**
+     * 解析押注配置
+     */
+    public function getDepositListAttr($value)
+    {
+        if (empty($value)) {
+            return [];
+        }
+        
+        // 如果是JSON字符串,解析它
+        $decoded = json_decode($value, true);
+        if (json_last_error() === JSON_ERROR_NONE) {
+            return $decoded;
+        }
+        
+        // 如果是逗号分隔的字符串,转换为数组
+        if (strpos($value, ',') !== false) {
+            return array_map('floatval', explode(',', $value));
+        }
+        
+        return [];
+    }
+
+    /**
+     * 检查游戏ID是否已存在
+     */
+    public static function checkGameIdExists($gameId, $excludeId = null): bool
+    {
+        $query = self::where('game_id', $gameId);
+        if ($excludeId) {
+            $query->where('id', '<>', $excludeId);
+        }
+        return $query->count() > 0;
+    }
+}

+ 1 - 1
app/model/MerchantPlayerModel.php → app/model/PlayerModel.php

@@ -8,7 +8,7 @@ use think\Model;
 /**
  * 商户玩家模型
  */
-class MerchantPlayerModel extends Model
+class PlayerModel extends Model
 {
     // 设置表名
     protected $name = 'merchant_player';

+ 23 - 9
config/menu.php

@@ -37,10 +37,20 @@ return [
             'children' => [
                 [
                     'id' => 21,
-                    'title' => '游戏配置',
-                    'icon' => 'layui-icon-audit',
-                    'controller' => 'MerchantAudit',
-                    'url' => '/merchant/audit',
+                    'title' => '游戏列表',
+                    'icon' => 'layui-icon-app',
+                    'controller' => 'Game',
+                    'url' => '/view/game/list.html',
+                    'sort' => 1,
+                    'level' => 2,
+                    'parent_id' => 2,
+                ],
+                [
+                    'id' => 22,
+                    'title' => '游戏管理',
+                    'icon' => 'layui-icon-set',
+                    'controller' => 'Game',
+                    'url' => '',
                     'sort' => 2,
                     'level' => 2,
                     'parent_id' => 2,
@@ -49,18 +59,18 @@ return [
                             'id' => 221,
                             'title' => '游戏配置',
                             'icon' => '',
-                            'controller' => 'MerchantAudit',
-                            'url' => '/merchant/audit/pending',
+                            'controller' => 'Game',
+                            'url' => '/view/game/config.html',
                             'sort' => 1,
                             'level' => 3,
                             'parent_id' => 22,
                         ],
                         [
                             'id' => 222,
-                            'title' => '游戏批量维护',
+                            'title' => '批量维护',
                             'icon' => '',
-                            'controller' => 'MerchantAudit',
-                            'url' => '/merchant/audit/passed',
+                            'controller' => 'Game',
+                            'url' => '/view/game/batch.html',
                             'sort' => 2,
                             'level' => 3,
                             'parent_id' => 22,
@@ -113,6 +123,10 @@ return [
             'name' => '玩家管理',
             'actions' => ['list', 'detail', 'updateStatus', 'updateAdjustStatus', 'statistics', 'batchUpdate', 'export']
         ],
+        'Game' => [
+            'name' => '游戏管理',
+            'actions' => ['list', 'detail', 'create', 'update', 'updateStatus', 'batchUpdate', 'delete', 'statistics', 'export']
+        ],
         'UserRole' => [
             'name' => '角色管理',
             'actions' => ['list', 'create', 'update', 'delete', 'detail', 'permissions']

+ 17 - 0
config/permission.php

@@ -28,6 +28,20 @@ return [
                 'export' => '导出玩家数据'
             ]
         ],
+        'Game' => [
+            'name' => '游戏管理',
+            'actions' => [
+                'list' => '查看游戏列表',
+                'detail' => '查看游戏详情',
+                'create' => '创建游戏',
+                'update' => '更新游戏',
+                'updateStatus' => '更新游戏状态',
+                'batchUpdate' => '批量更新游戏',
+                'delete' => '删除游戏',
+                'statistics' => '查看游戏统计',
+                'export' => '导出游戏数据'
+            ]
+        ],
         'UserRole' => [
             'name' => '角色管理',
             'actions' => [
@@ -96,6 +110,7 @@ return [
             'permissions' => [
                 'User' => ['list', 'detail'],
                 'Player' => ['list', 'detail', 'statistics'],
+                'Game' => ['list', 'detail', 'statistics'],
                 'UserRole' => ['list', 'detail'],
                 'Merchant' => ['list', 'detail'],
                 'Statistics' => ['user', 'merchant', 'daily', 'monthly', 'yearly']
@@ -107,6 +122,7 @@ return [
             'permissions' => [
                 'User' => ['list', 'create', 'update', 'detail'],
                 'Player' => ['list', 'detail', 'updateStatus', 'statistics'],
+                'Game' => ['list', 'detail', 'updateStatus', 'statistics'],
                 'UserRole' => ['list', 'detail'],
                 'Merchant' => ['list', 'create', 'update', 'detail'],
                 'MerchantAudit' => ['pending', 'passed'],
@@ -119,6 +135,7 @@ return [
             'permissions' => [
                 'User' => ['list', 'create', 'update', 'delete', 'detail'],
                 'Player' => ['list', 'detail', 'updateStatus', 'updateAdjustStatus', 'statistics', 'batchUpdate', 'export'],
+                'Game' => ['list', 'detail', 'create', 'update', 'updateStatus', 'batchUpdate', 'delete', 'statistics', 'export'],
                 'UserRole' => ['list', 'create', 'update', 'delete', 'detail', 'permissions'],
                 'Permission' => ['list', 'assign'],
                 'Menu' => ['list', 'tree', 'breadcrumb', 'permissions'],

+ 14 - 0
route/app.php

@@ -69,3 +69,17 @@ Route::group('player', function () {
     Route::post('batchUpdateAdjustStatus', 'Player/batchUpdateAdjustStatus');
     Route::get('export', 'Player/export');
 });
+
+// 游戏相关路由
+Route::group('game', function () {
+    Route::get('list', 'Game/list');
+    Route::get('detail', 'Game/detail');
+    Route::post('create', 'Game/create');
+    Route::post('update', 'Game/update');
+    Route::post('updateStatus', 'Game/updateStatus');
+    Route::post('batchUpdateStatus', 'Game/batchUpdateStatus');
+    Route::get('statistics', 'Game/statistics');
+    Route::get('getPlatforms', 'Game/getPlatforms');
+    Route::post('delete', 'Game/delete');
+    Route::get('export', 'Game/export');
+});