pxb 5 часов назад
Родитель
Сommit
11ff737b95

+ 53 - 0
src/api/data.js

@@ -889,6 +889,59 @@ export function getThirdPartyDepositDetail(params) {
   })
 }
 
+// egame:筛选项
+export function getEgameOptions() {
+  return request({
+    url: 'egame/options',
+    method: 'get'
+  })
+}
+
+// egame:列表(大类/平台/游戏)
+export function getEgameItems(params) {
+  return request({
+    url: 'egame/items',
+    method: 'get',
+    params: params
+  })
+}
+
+// egame:新增/修改
+export function updateEgame(data) {
+  return request({
+    url: 'egame/update',
+    method: 'post',
+    data: data
+  })
+}
+
+// egame:启用/停用
+export function setEgameStatus(data) {
+  return request({
+    url: 'egame/setStatus',
+    method: 'post',
+    data: data
+  })
+}
+
+// 三方游戏订单列表
+export function getThirdGameOrders(params) {
+  return request({
+    url: 'thirdGame/orders',
+    method: 'get',
+    params: params
+  })
+}
+
+// 三方游戏订单同步
+export function syncThirdGameOrders(data) {
+  return request({
+    url: 'thirdGame/orders/sync',
+    method: 'post',
+    data: data
+  })
+}
+
 /**
  * 彩票配置
  * @description GET请求

+ 2 - 1
src/layout/components/Sidebar/index.vue

@@ -40,7 +40,8 @@ export default {
       return variables
     },
     isCollapse() {
-      return !this.sidebar.opened
+      // 无论 sidebar 状态如何,菜单始终保持展开
+      return false
     }
   },
   mounted() {

+ 4 - 3
src/layout/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div :class="classObj" class="app-wrapper">
-    <div v-if="device !== 'mobile' && sidebar.opened" class="theTitle">后台管理</div>
+    <div v-if="device !== 'mobile'" class="theTitle">后台管理</div>
     <div v-if="device === 'mobile' && sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
     <sidebar class="sidebar-container" />
     <div class="main-container">
@@ -42,8 +42,9 @@ export default {
     },
     classObj() {
       return {
-        hideSidebar: !this.sidebar.opened,
-        openSidebar: this.sidebar.opened,
+        // 侧边栏始终展开,不因 toggle 收起
+        hideSidebar: false,
+        openSidebar: true,
         withoutAnimation: this.sidebar.withoutAnimation,
         mobile: this.device === 'mobile'
       }

+ 291 - 189
src/views/thirdGame/list/index.vue

@@ -4,39 +4,35 @@
       <div class="filter-panel">
         <el-form inline :model="query" class="filter-form">
           <el-form-item label="游戏分类">
-            <el-select v-model="query.category" clearable placeholder="请选择" style="width: 130px">
+            <el-select v-model="query.game_type" clearable placeholder="请选择" style="width: 130px">
               <el-option label="全部" value="" />
-              <el-option v-for="c in categoryOptions" :key="c" :label="c" :value="c" />
+              <el-option v-for="c in categoryOptions" :key="c.value" :label="c.label" :value="c.value" />
             </el-select>
           </el-form-item>
           <el-form-item label="平台类型">
-            <el-select v-model="query.platform" clearable placeholder="请选择" style="width: 130px">
+            <el-select v-model="query.plat_type" clearable placeholder="请选择" style="width: 130px">
               <el-option label="全部" value="" />
-              <el-option v-for="p in platformOptions" :key="p" :label="p" :value="p" />
+              <el-option v-for="p in platformOptions" :key="p.value" :label="p.label" :value="p.value" />
             </el-select>
           </el-form-item>
           <el-form-item label="显示名称">
-            <el-input v-model="query.display_name" clearable placeholder="请输入" style="width: 150px" />
+            <el-input v-model="query.name" clearable placeholder="请输入" style="width: 150px" />
           </el-form-item>
           <el-form-item label="平台状态">
             <el-select v-model="query.status" clearable placeholder="请选择" style="width: 120px">
               <el-option label="全部" value="" />
-              <el-option label="正常" value="正常" />
-              <el-option label="停用" value="停用" />
+              <el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value" />
             </el-select>
           </el-form-item>
           <el-form-item label="支持终端类型">
-            <el-select v-model="query.terminal" clearable placeholder="请选择" style="width: 150px">
+            <el-select v-model="query.ingress" clearable placeholder="请选择" style="width: 150px">
               <el-option label="全部" value="" />
-              <el-option label="电脑网页" value="电脑网页" />
-              <el-option label="手机网页" value="手机网页" />
-              <el-option label="电脑/手机网页" value="电脑/手机网页" />
+              <el-option v-for="t in ingressOptions" :key="t.value" :label="t.label" :value="t.value" />
             </el-select>
           </el-form-item>
           <el-form-item label="支持网络">
             <el-select v-model="query.network" clearable placeholder="请选择" style="width: 120px">
-              <el-option label="全部" value="" />
-              <el-option v-for="n in networkOptions" :key="n" :label="n" :value="n" />
+              <el-option v-for="n in networkOptions" :key="n.value" :label="n.label" :value="n.value" />
             </el-select>
           </el-form-item>
           <el-form-item class="filter-actions">
@@ -51,36 +47,35 @@
           height="calc(100vh - 330px)" style="width: 100%; border-radius: 12px; overflow: hidden;"
           empty-text="暂无数据">
           <el-table-column type="index" label="序号" width="70" align="center" />
-          <el-table-column prop="platform_id" label="平台ID" width="100" align="center" />
+          <el-table-column prop="id" label="平台ID" width="100" align="center" />
           <el-table-column prop="category" label="游戏分类" width="140" align="center" />
-          <el-table-column prop="platform" label="平台类型" width="130" align="center" />
+          <el-table-column prop="plat_type" label="平台类型" width="130" align="center" />
           <el-table-column prop="display_name" label="显示名称" width="200" align="center" />
           <el-table-column prop="terminal" label="支持终端类型" width="180" align="center" />
           <el-table-column prop="network" label="支持网络" width="140" align="center" />
           <el-table-column label="平台状态" width="120" align="center">
             <template slot-scope="{ row }">
-              <el-switch v-model="row.platform_status"
-                :active-value="'正常'" :inactive-value="'停用'" active-color="#13ce66" inactive-color="#f56c6c"
+              <el-switch v-model="row.status" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#f56c6c"
                 @change="handlePlatformStatusChange(row)" />
             </template>
           </el-table-column>
           <el-table-column prop="sort" label="排序" width="140" align="center">
             <template slot-scope="{ row }">
-              <el-input-number v-model="row.sort" :min="1" size="mini" controls-position="right" style="width: 100px"
+              <el-input-number v-model="row.sort" size="mini" controls-position="right" style="width: 100px"
                 @change="handleSortChange(row)" />
             </template>
           </el-table-column>
           <el-table-column label="PC游戏图片" width="130" align="center">
             <template slot-scope="{ row }">
-              <el-image v-if="row.pc_image" :src="row.pc_image" style="width: 40px; height: 40px;" fit="cover"
-                :preview-src-list="[row.pc_image]" />
+              <el-image v-if="row.logo" :src="row.logo" style="width: 40px; height: 40px;" fit="cover"
+                :preview-src-list="[row.logo]" />
               <span v-else>--</span>
             </template>
           </el-table-column>
           <el-table-column label="H5/APP游戏图片" width="140" align="center">
             <template slot-scope="{ row }">
-              <el-image v-if="row.h5_image" :src="row.h5_image" style="width: 40px; height: 40px;" fit="cover"
-                :preview-src-list="[row.h5_image]" />
+              <el-image v-if="row.logo_h5" :src="row.logo_h5" style="width: 40px; height: 40px;" fit="cover"
+                :preview-src-list="[row.logo_h5]" />
               <span v-else>--</span>
             </template>
           </el-table-column>
@@ -89,15 +84,14 @@
               <el-button type="text" size="small" class="ym-view-btn" @click="handleEditImage(row)">修改</el-button>
               <el-button v-if="row.has_manager" type="text" size="small" class="ym-view-btn"
                 @click="handleGameManage(row)">游戏管理</el-button>
-              <span v-else>--</span>
             </template>
           </el-table-column>
         </el-table>
-        <el-pagination v-if="tableData.length" background
+        <el-pagination v-if="total" background
           layout="total, prev, pager, next, jumper" :page-size="pageSize"
           :page-sizes="[15, 30, 45, 60]" :current-page="page"
-          :total="tableData.length"
-          @current-change="page = $event" @size-change="handleSizeChange" />
+          :total="total"
+          @current-change="page = $event; fetchList()" @size-change="handleSizeChange" />
       </div>
     </div>
 
@@ -106,41 +100,38 @@
       width: 'auto',
       title: manageTitle,
       confirmButtom: false,
-    }" close-on-click-modal="false" top="5vh" custom-class="game-manage-dialog">
+    }" :close-on-click-modal="false" top="5vh" custom-class="game-manage-dialog">
       <template slot="content">
         <div class="manage-dialog-content">
           <!-- 内部分页列表 -->
           <div class="inner-filter">
             <el-form inline :model="innerQuery" class="inner-form">
               <el-form-item label="游戏ID">
-                <el-input v-model="innerQuery.game_id" clearable placeholder="请输入" style="width: 120px" />
+                <el-input v-model="innerQuery.game_code" clearable placeholder="请输入" style="width: 120px" />
               </el-form-item>
               <el-form-item label="游戏名称">
-                <el-input v-model="innerQuery.game_name" clearable placeholder="请输入" style="width: 150px" />
+                <el-input v-model="innerQuery.name" clearable placeholder="请输入" style="width: 150px" />
               </el-form-item>
               <el-form-item label="状态">
-                <el-select v-model="innerQuery.enabled" clearable placeholder="请选择" style="width: 110px">
+                <el-select v-model="innerQuery.status" clearable placeholder="请选择" style="width: 110px">
                   <el-option label="全部" value="" />
-                  <el-option label="启用" :value="true" />
-                  <el-option label="停用" :value="false" />
+                  <el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value" />
                 </el-select>
               </el-form-item>
               <el-form-item label="支持终端类型">
-                <el-select v-model="innerQuery.terminal" clearable placeholder="请选择" style="width: 150px">
+                <el-select v-model="innerQuery.ingress" clearable placeholder="请选择" style="width: 150px">
                   <el-option label="全部" value="" />
-                  <el-option label="电脑网页" value="电脑网页" />
-                  <el-option label="手机网页" value="手机网页" />
-                  <el-option label="电脑/手机网页" value="电脑/手机网页" />
+                  <el-option v-for="t in ingressOptions" :key="t.value" :label="t.label" :value="t.value" />
                 </el-select>
               </el-form-item>
               <el-form-item label="支持网络">
                 <el-select v-model="innerQuery.network" clearable placeholder="请选择" style="width: 120px">
-                  <el-option label="全部" value="" />
-                  <el-option v-for="n in networkOptions" :key="n" :label="n" :value="n" />
+                  <el-option v-for="n in networkOptions" :key="n.value" :label="n.label" :value="n.value" />
                 </el-select>
               </el-form-item>
               <el-form-item>
                 <el-button type="primary" size="small" @click="handleInnerSearch">查询</el-button>
+                <el-button size="small" @click="handleInnerReset">重置</el-button>
               </el-form-item>
             </el-form>
           </div>
@@ -148,31 +139,31 @@
           <el-table v-loading="innerLoading" :data="innerPagedData" height="420px"
             style="width: 100%; border-radius: 8px; overflow: hidden;" empty-text="暂无数据">
             <el-table-column type="index" label="序号" width="70" align="center" />
-            <el-table-column prop="game_id" label="游戏ID" width="90" align="center" />
+            <el-table-column prop="game_code" label="游戏ID" width="90" align="center" />
             <el-table-column prop="game_name" label="游戏名称" width="180" align="center" />
             <el-table-column label="PC游戏图片" width="130" align="center">
               <template slot-scope="{ row }">
-                <el-image v-if="row.pc_image" :src="row.pc_image" style="width: 40px; height: 40px;" fit="cover"
-                  :preview-src-list="[row.pc_image]" />
+                <el-image v-if="row.logo" :src="row.logo" style="width: 40px; height: 40px;" fit="cover"
+                  :preview-src-list="[row.logo]" />
                 <span v-else>--</span>
               </template>
             </el-table-column>
             <el-table-column label="H5/APP游戏图片" width="140" align="center">
               <template slot-scope="{ row }">
-                <el-image v-if="row.h5_image" :src="row.h5_image" style="width: 40px; height: 40px;" fit="cover"
-                  :preview-src-list="[row.h5_image]" />
+                <el-image v-if="row.logo_h5" :src="row.logo_h5" style="width: 40px; height: 40px;" fit="cover"
+                  :preview-src-list="[row.logo_h5]" />
                 <span v-else>--</span>
               </template>
             </el-table-column>
             <el-table-column label="排序" width="140" align="center">
               <template slot-scope="{ row }">
-                <el-input-number v-model="row.sort" :min="1" size="mini" controls-position="right" style="width: 100px"
+                <el-input-number v-model="row.sort" size="mini" controls-position="right" style="width: 100px"
                   @change="handleInnerSortChange(row)" />
               </template>
             </el-table-column>
             <el-table-column label="状态" width="120" align="center">
               <template slot-scope="{ row }">
-                <el-switch v-model="row.enabled" active-color="#13ce66" inactive-color="#f56c6c"
+                <el-switch v-model="row.status" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#f56c6c"
                   @change="handleInnerEnabledChange(row)" />
               </template>
             </el-table-column>
@@ -188,7 +179,7 @@
             layout="total, prev, pager, next, jumper" :page-size="innerPageSize"
             :page-sizes="[15, 30, 45, 60]" :current-page="innerPage"
             :total="innerTotal"
-            @current-change="innerPage = $event" @size-change="handleInnerSizeChange" />
+            @current-change="innerPage = $event; fetchInnerList()" @size-change="handleInnerSizeChange" />
         </div>
       </template>
     </Dialog>
@@ -203,26 +194,16 @@
           <el-form-item label="游戏名称">
             <el-input v-model="innerEditForm.game_name" placeholder="请输入" style="width: 250px" />
           </el-form-item>
-          <el-form-item label="游戏分类">
-            <el-select v-model="innerEditForm.category" style="width: 250px">
-              <el-option v-for="c in categoryOptions" :key="c" :label="c" :value="c" />
-            </el-select>
-          </el-form-item>
-          <el-form-item label="平台类型">
-            <el-select v-model="innerEditForm.platform" style="width: 250px">
-              <el-option v-for="p in platformOptions" :key="p" :label="p" :value="p" />
-            </el-select>
-          </el-form-item>
           <el-form-item label="PC游戏图片">
-            <UploadOneImage v-model="innerEditForm.pc_image" />
+            <UploadOneImage v-model="innerEditForm.logo" />
           </el-form-item>
           <el-form-item label="H5/APP游戏图片">
-            <UploadOneImage v-model="innerEditForm.h5_image" />
+            <UploadOneImage v-model="innerEditForm.logo_h5" />
           </el-form-item>
           <el-form-item label="是否启用">
-            <el-radio-group v-model="innerEditForm.enabled">
-              <el-radio :label="true">启用</el-radio>
-              <el-radio :label="false">停用</el-radio>
+            <el-radio-group v-model="innerEditForm.status">
+              <el-radio :label="1">启用</el-radio>
+              <el-radio :label="0">停用</el-radio>
             </el-radio-group>
           </el-form-item>
         </el-form>
@@ -240,10 +221,10 @@
             <el-input v-model="imageEditForm.display_name" placeholder="请输入" style="width: 250px" />
           </el-form-item>
           <el-form-item label="PC游戏图片">
-            <UploadOneImage v-model="imageEditForm.pc_image" />
+            <UploadOneImage v-model="imageEditForm.logo" />
           </el-form-item>
           <el-form-item label="H5/APP游戏图片">
-            <UploadOneImage v-model="imageEditForm.h5_image" />
+            <UploadOneImage v-model="imageEditForm.logo_h5" />
           </el-form-item>
         </el-form>
       </template>
@@ -254,42 +235,7 @@
 <script>
 import Dialog from '@/components/Dialog/index.vue'
 import UploadOneImage from '@/components/UploadOneImage/index.vue'
-
-// 假数据
-const MOCK_DATA = [
-  // 电子
-  { id: 1, platform_id: 'FL01', game_id: 'G001', category: '电子', platform: 'jdb', display_name: 'JDB电子', terminal: '电脑/手机网页', network: '大陆', platform_status: '正常', sort: 1, pc_image: '', h5_image: '', has_manager: true },
-  { id: 2, platform_id: 'FL02', game_id: 'G002', category: '电子', platform: 'mg', display_name: 'MG电子', terminal: '电脑/手机网页', network: '香港', platform_status: '停用', sort: 2, pc_image: '', h5_image: '', has_manager: false },
-  // 捕鱼
-  { id: 3, platform_id: 'FL03', game_id: 'G003', category: '捕鱼', platform: 'pt', display_name: 'PT捕鱼', terminal: '手机网页', network: '韩国', platform_status: '正常', sort: 3, pc_image: '', h5_image: '', has_manager: false },
-  { id: 4, platform_id: 'FL04', game_id: 'G004', category: '捕鱼', platform: 'fg', display_name: 'FG捕鱼', terminal: '电脑/手机网页', network: '日本', platform_status: '正常', sort: 4, pc_image: '', h5_image: '', has_manager: true },
-  // 棋牌
-  { id: 5, platform_id: 'FL05', game_id: 'G005', category: '棋牌', platform: 'ky', display_name: '开元棋牌', terminal: '电脑/手机网页', network: '大陆', platform_status: '正常', sort: 5, pc_image: '', h5_image: '', has_manager: true },
-  { id: 6, platform_id: 'FL06', game_id: 'G006', category: '棋牌', platform: 'db7', display_name: 'DB棋牌', terminal: '电脑网页', network: '香港', platform_status: '停用', sort: 6, pc_image: '', h5_image: '', has_manager: false },
-  // 视讯
-  { id: 7, platform_id: 'FL07', game_id: 'G007', category: '视讯', platform: 'ag', display_name: 'PA真人', terminal: '电脑/手机网页', network: '大陆', platform_status: '正常', sort: 7, pc_image: '', h5_image: '', has_manager: true },
-  { id: 8, platform_id: 'FL08', game_id: 'G008', category: '视讯', platform: 'evo', display_name: 'EVO真人', terminal: '手机网页', network: '香港', platform_status: '停用', sort: 8, pc_image: '', h5_image: '', has_manager: true },
-  { id: 9, platform_id: 'FL09', game_id: 'G009', category: '视讯', platform: 'bbin', display_name: 'BBIN真人', terminal: '电脑/手机网页', network: '韩国', platform_status: '正常', sort: 9, pc_image: '', h5_image: '', has_manager: false }
-]
-
-// 各平台对应的游戏名(点击游戏管理时按平台生成)
-const PLATFORM_GAMES = {
-  jdb: ['JDB夺宝', 'JDB招财进宝', 'JDB三国'],
-  mg: ['MG大丰收', 'MG糖果派对', 'MG龙虎斗'],
-  pt: ['PT深海捕鱼', 'PT龙王捕鱼', 'PT美人鱼'],
-  fg: ['FG捕鱼达人', 'FG捕鱼大师', 'FG深海狂鲨'],
-  ky: ['开元斗地主', '开元麻将', '开元百人牛牛'],
-  db7: ['DB德州扑克', 'DB斗牛', 'DB炸金花'],
-  ag: ['PA龙虎斗', 'PA骰宝', 'PA百家乐'],
-  evo: ['EVO百家乐', 'EVO龙虎', 'EVO三公'],
-  bbin: ['BBIN轮盘', 'BBIN德州', 'BBIN骰宝']
-}
-
-// 默认内层游戏假数据(兜底)
-const INNER_MOCK = [
-  { id: 1, game_id: 'G001', game_name: '游戏1', sort: 1, enabled: true, terminal: '电脑/手机网页', network: '大陆', category: '电子', platform: 'jdb', pc_image: '', h5_image: '' },
-  { id: 2, game_id: 'G002', game_name: '游戏2', sort: 2, enabled: true, terminal: '电脑网页', network: '香港', category: '电子', platform: 'jdb', pc_image: '', h5_image: '' }
-]
+import { getEgameItems, getEgameOptions, updateEgame, setEgameStatus } from '@/api/data'
 
 export default {
   name: 'ThirdGameList',
@@ -302,17 +248,32 @@ export default {
       loading: false,
       page: 1,
       pageSize: 15,
-      tableData: [...MOCK_DATA],
-      filteredData: [...MOCK_DATA],
-      categoryOptions: ['视讯', '电子', '捕鱼', '体育', '棋牌'],
-      platformOptions: ['ag', 'pg', 'bg', 'dg', 'db5'],
-      networkOptions: ['大陆', '香港', '韩国', '日本'],
+      total: 0,
+      tableData: [],
+      categoryOptions: [],
+      platformOptions: [],
+      statusOptions: [
+        { value: 1, label: '启用' },
+        { value: 0, label: '停用' }
+      ],
+      ingressOptions: [
+        { value: '1', label: '电脑网页' },
+        { value: '2', label: '手机网页' },
+        { value: '3', label: '电脑/手机网页' }
+      ],
+      networkOptions: [
+        { value: '', label: '不限制' },
+        { value: 'mainland', label: '大陆' },
+        { value: 'hk', label: '香港' },
+        { value: 'kr', label: '韩国' },
+        { value: 'jp', label: '日本' }
+      ],
       query: {
-        category: '',
-        platform: '',
-        display_name: '',
+        game_type: '',
+        plat_type: '',
+        name: '',
         status: '',
-        terminal: '',
+        ingress: '',
         network: ''
       },
       // 内层游戏管理
@@ -320,148 +281,289 @@ export default {
       innerPage: 1,
       innerPageSize: 15,
       innerTotal: 0,
-      innerTableData: [...INNER_MOCK],
-      innerFiltered: [...INNER_MOCK],
+      innerTableData: [],
+      innerFiltered: [],
       innerQuery: {
-        game_id: '',
-        game_name: '',
-        enabled: '',
-        terminal: '',
+        game_code: '',
+        name: '',
+        status: '',
+        ingress: '',
         network: ''
       },
+      innerPlatType: '',
       innerEditForm: {},
       imageEditForm: {},
       manageTitle: '游戏管理'
     }
   },
   computed: {
+    // 后端已按 page/limit 分页,直接返回当前页数据
     pagedData() {
-      const start = (this.page - 1) * this.pageSize
-      return this.filteredData.slice(start, start + this.pageSize)
+      return this.tableData
     },
     innerPagedData() {
-      const start = (this.innerPage - 1) * this.innerPageSize
-      return this.innerFiltered.slice(start, start + this.innerPageSize)
+      return this.innerFiltered
     }
   },
+  created() {
+    this.fetchOptions()
+    this.fetchList()
+  },
   methods: {
-    handlePlatformStatusChange(row) {
-      this.$message.success(`平台状态已改为${row.platform_status}`)
+    fetchOptions() {
+      getEgameOptions().then(res => {
+        if (res.code === 0 || res.code === 99) {
+          const data = res.data || {}
+          this.categoryOptions = (data.categories || []).map(c => ({ value: c.game_type, label: c.name }))
+          this.platformOptions = (data.platforms || []).map(p => ({ value: p.plat_type, label: p.name }))
+          if (Array.isArray(data.statuses) && data.statuses.length) this.statusOptions = data.statuses
+          if (Array.isArray(data.ingress) && data.ingress.length) this.ingressOptions = data.ingress
+          if (Array.isArray(data.networks) && data.networks.length) this.networkOptions = data.networks
+        }
+      }).catch(() => {})
     },
-    handleSortChange(row) {
-      if (row.sort < 1) row.sort = 1
-      this.$message.success(`排序已修改为 ${row.sort}`)
+    fetchList() {
+      this.loading = true
+      const params = {
+        item_type: 'platform',
+        platform_scope: 'category',
+        page: this.page,
+        limit: this.pageSize,
+        game_type: this.query.game_type || '',
+        plat_type: this.query.plat_type || '',
+        name: this.query.name || '',
+        // status 可能是 0(禁用),不能用 || 兜底,避免丢失 0
+        status: this.query.status === '' || this.query.status === null || this.query.status === undefined ? '' : this.query.status,
+        ingress: this.query.ingress || '',
+        network: this.query.network || ''
+      }
+      getEgameItems(params).then(res => {
+        if (res.code === 0 || res.code === 99) {
+          const data = res.data || {}
+          this.total = Number(data.total) || 0
+          this.tableData = (data.data || []).map(row => this.mapPlatform(row))
+        } else {
+          this.$message.error(res.msg || '获取列表失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      }).finally(() => {
+        this.loading = false
+      })
     },
-    handleInnerSortChange(row) {
-      if (row.sort < 1) row.sort = 1
-      this.$message.success(`游戏 ${row.game_name} 排序已修改为 ${row.sort}`)
+    // 平台行字段映射
+    mapPlatform(row) {
+      return {
+        id: row.id,
+        plat_type: row.plat_type,
+        category: row.game_type_name || '',
+        category_code: row.game_type,
+        display_name: row.name,
+        terminal: row.ingress_name || '',
+        ingress: row.ingress,
+        network: row.network_name || '',
+        network_code: row.network,
+        status: Number(row.status) === 1 ? 1 : 0,
+        sort: row.sort,
+        logo: row.logo || row.logo_pc || '',
+        logo_h5: row.logo_h5 || '',
+        has_manager: !!row.has_game_manage
+      }
     },
     handleSizeChange(val) {
       this.pageSize = val
       this.page = 1
+      this.fetchList()
     },
     handleSearch() {
       this.page = 1
-      let filtered = [...this.tableData]
-      if (this.query.category) filtered = filtered.filter(r => r.category === this.query.category)
-      if (this.query.platform) filtered = filtered.filter(r => r.platform === this.query.platform)
-      if (this.query.display_name) filtered = filtered.filter(r => r.display_name.includes(this.query.display_name))
-      if (this.query.status) filtered = filtered.filter(r => r.platform_status === this.query.status)
-      if (this.query.terminal) filtered = filtered.filter(r => r.terminal === this.query.terminal)
-      if (this.query.network) filtered = filtered.filter(r => r.network === this.query.network)
-      this.filteredData = filtered
+      this.fetchList()
     },
-    // 重置筛选条件到初始状态
     handleReset() {
       this.query = {
-        category: '',
-        platform: '',
-        display_name: '',
+        game_type: '',
+        plat_type: '',
+        name: '',
         status: '',
-        terminal: '',
+        ingress: '',
         network: ''
       }
-      this.filteredData = [...this.tableData]
       this.page = 1
+      this.fetchList()
+    },
+    // 平台状态切换
+    handlePlatformStatusChange(row) {
+      setEgameStatus({ id: row.id, status: row.status }).then(res => {
+        if (res.code === 0) {
+          this.$message.success(`平台已${row.status === 1 ? '启用' : '停用'}`)
+        } else {
+          this.$message.error(res.msg || '状态修改失败')
+          row.status = row.status === 1 ? 0 : 1
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+        row.status = row.status === 1 ? 0 : 1
+      })
+    },
+    // 平台排序
+    handleSortChange(row) {
+      updateEgame({ id: row.id, sort: row.sort }).then(res => {
+        if (res.code === 0) {
+          this.$message.success(`排序已修改为 ${row.sort}`)
+        } else {
+          this.$message.error(res.msg || '排序修改失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      })
     },
     // 游戏管理弹窗
     handleGameManage(row) {
-      // 弹窗标题用显示名称,如「JDB电子游戏管理」
       this.manageTitle = `${row.display_name || ''}游戏管理`
-      // 根据当前行平台生成对应游戏列表
-      const games = PLATFORM_GAMES[row.platform] || ['游戏1', '游戏2']
-      const terminalOptions = ['电脑网页', '手机网页', '电脑/手机网页']
-      const networkOptions = ['大陆', '香港', '韩国', '日本']
-      const list = games.map((name, idx) => ({
-        id: idx + 1,
-        game_id: `${String(row.platform).toUpperCase()}${String(idx + 1).padStart(3, '0')}`,
-        game_name: name,
-        sort: idx + 1,
-        enabled: Math.random() > 0.3, // 随机启用/停用
-        terminal: terminalOptions[Math.floor(Math.random() * terminalOptions.length)],
-        network: networkOptions[Math.floor(Math.random() * networkOptions.length)],
-        category: row.category,
-        platform: row.platform,
-        pc_image: '',
-        h5_image: ''
-      }))
-      this.innerTableData = list
-      this.innerFiltered = [...list]
-      this.innerTotal = list.length
+      this.innerPlatType = row.plat_type
       this.innerPage = 1
       this.$refs.manageDialog.open()
+      this.fetchInnerList()
+    },
+    fetchInnerList() {
+      this.innerLoading = true
+      const params = {
+        item_type: 'game',
+        plat_type: this.innerPlatType,
+        page: this.innerPage,
+        limit: this.innerPageSize,
+        game_code: this.innerQuery.game_code || '',
+        name: this.innerQuery.name || '',
+        // status 可能是 0(禁用),不能用 || 兜底,避免丢失 0
+        status: this.innerQuery.status === '' || this.innerQuery.status === null || this.innerQuery.status === undefined ? '' : this.innerQuery.status,
+        ingress: this.innerQuery.ingress || '',
+        network: this.innerQuery.network || ''
+      }
+      getEgameItems(params).then(res => {
+        if (res.code === 0 || res.code === 99) {
+          const data = res.data || {}
+          this.innerTotal = Number(data.total) || 0
+          this.innerTableData = (data.data || []).map(row => this.mapGame(row))
+          this.innerFiltered = [...this.innerTableData]
+        } else {
+          this.$message.error(res.msg || '获取游戏列表失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      }).finally(() => {
+        this.innerLoading = false
+      })
+    },
+    // 游戏行字段映射
+    mapGame(row) {
+      return {
+        id: row.id,
+        game_code: row.game_code,
+        game_name: row.name,
+        terminal: row.ingress_name || '',
+        ingress: row.ingress,
+        network: row.network_name || '',
+        network_code: row.network,
+        status: Number(row.status) === 1 ? 1 : 0,
+        sort: row.sort,
+        logo: row.logo || row.logo_pc || '',
+        logo_h5: row.logo_h5 || '',
+        plat_type: row.plat_type
+      }
     },
     handleInnerSizeChange(val) {
       this.innerPageSize = val
       this.innerPage = 1
+      this.fetchInnerList()
     },
     handleInnerSearch() {
       this.innerPage = 1
-      let filtered = [...this.innerTableData]
-      if (this.innerQuery.game_id) filtered = filtered.filter(r => r.game_id.includes(this.innerQuery.game_id))
-      if (this.innerQuery.game_name) filtered = filtered.filter(r => r.game_name.includes(this.innerQuery.game_name))
-      // enabled 可能是布尔值(0 不是),需区分空串和值
-      if (this.innerQuery.enabled !== '' && this.innerQuery.enabled !== null && this.innerQuery.enabled !== undefined) {
-        filtered = filtered.filter(r => r.enabled === this.innerQuery.enabled)
+      this.fetchInnerList()
+    },
+    // 重置内层筛选条件到初始状态
+    handleInnerReset() {
+      this.innerQuery = {
+        game_code: '',
+        name: '',
+        status: '',
+        ingress: '',
+        network: ''
       }
-      if (this.innerQuery.terminal) filtered = filtered.filter(r => r.terminal === this.innerQuery.terminal)
-      if (this.innerQuery.network) filtered = filtered.filter(r => r.network === this.innerQuery.network)
-      this.innerFiltered = filtered
-      this.innerTotal = filtered.length
+      this.innerPage = 1
+      this.fetchInnerList()
+    },
+    handleInnerSortChange(row) {
+      updateEgame({ id: row.id, sort: row.sort }).then(res => {
+        if (res.code === 0) {
+          this.$message.success(`游戏 ${row.game_name} 排序已修改为 ${row.sort}`)
+        } else {
+          this.$message.error(res.msg || '排序修改失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      })
     },
     handleInnerEnabledChange(row) {
-      this.$message.success(`游戏 ${row.game_name} 已${row.enabled ? '启用' : '停用'}`)
+      setEgameStatus({ id: row.id, status: row.status }).then(res => {
+        if (res.code === 0) {
+          this.$message.success(`游戏 ${row.game_name} 已${row.status === 1 ? '启用' : '停用'}`)
+        } else {
+          this.$message.error(res.msg || '状态修改失败')
+          row.status = row.status === 1 ? 0 : 1
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+        row.status = row.status === 1 ? 0 : 1
+      })
     },
     handleInnerEdit(row) {
       this.innerEditForm = { ...row }
       this.$refs.innerEditDialog.open()
     },
     handleInnerConfirm() {
-      const idx = this.innerTableData.findIndex(item => item.id === this.innerEditForm.id)
-      if (idx > -1) {
-        this.innerTableData[idx] = { ...this.innerEditForm }
-        this.innerFiltered = [...this.innerTableData]
-        this.innerTotal = this.innerFiltered.length
+      const params = {
+        id: this.innerEditForm.id,
+        name: this.innerEditForm.game_name,
+        logo_pc: this.innerEditForm.logo,
+        logo_h5: this.innerEditForm.logo_h5,
+        status: this.innerEditForm.status
       }
-      this.$message.success('修改成功')
-      this.$refs.innerEditDialog.close()
+      updateEgame(params).then(res => {
+        if (res.code === 0) {
+          this.$message.success('修改成功')
+          this.$refs.innerEditDialog.close()
+          this.fetchInnerList()
+        } else {
+          this.$message.error(res.msg || '修改失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      })
     },
-    // 打开修改图片弹窗
+    // 打开修改弹窗
     handleEditImage(row) {
       this.imageEditForm = { ...row }
       this.$refs.imageEditDialog.open()
     },
-    // 保存修改图片到列表
+    // 保存平台修改
     handleImageConfirm() {
-      const idx = this.tableData.findIndex(item => item.id === this.imageEditForm.id)
-      if (idx > -1) {
-        this.tableData[idx].display_name = this.imageEditForm.display_name
-        this.tableData[idx].pc_image = this.imageEditForm.pc_image
-        this.tableData[idx].h5_image = this.imageEditForm.h5_image
-        this.filteredData = [...this.tableData]
+      const params = {
+        id: this.imageEditForm.id,
+        name: this.imageEditForm.display_name,
+        logo_pc: this.imageEditForm.logo,
+        logo_h5: this.imageEditForm.logo_h5
       }
-      this.$message.success('修改成功')
-      this.$refs.imageEditDialog.close()
+      updateEgame(params).then(res => {
+        if (res.code === 0) {
+          this.$message.success('修改成功')
+          this.$refs.imageEditDialog.close()
+          this.fetchList()
+        } else {
+          this.$message.error(res.msg || '修改失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      })
     }
   }
 }

+ 106 - 81
src/views/thirdGame/order/index.vue

@@ -3,15 +3,6 @@
     <div class="content-panel">
       <div class="filter-panel">
         <el-form inline :model="query" class="filter-form">
-          <el-form-item label="注册来源">
-            <el-select v-model="query.from" clearable placeholder="请选择" style="width: 130px">
-              <el-option label="全部" value="" />
-              <el-option label="tg用户" value="-1" />
-              <el-option label="后台客服账号" value="0" />
-              <el-option label="真实用户" value="1" />
-              <el-option label="虚拟用户" value="2" />
-            </el-select>
-          </el-form-item>
           <el-form-item label="会员ID">
             <el-input v-model="query.member_id" clearable placeholder="请输入" style="width: 130px" />
           </el-form-item>
@@ -24,20 +15,13 @@
           <el-form-item label="游戏分类">
             <el-select v-model="query.category" clearable placeholder="请选择" style="width: 130px">
               <el-option label="全部" value="" />
-              <el-option v-for="c in categoryOptions" :key="c" :label="c" :value="c" />
+              <el-option v-for="c in categoryOptions" :key="c.value" :label="c.label" :value="c.value" />
             </el-select>
           </el-form-item>
-          <el-form-item label="平台类型">
-            <el-select v-model="query.platform" clearable placeholder="请选择" style="width: 130px">
+          <el-form-item label="状态">
+            <el-select v-model="query.status" clearable placeholder="请选择" style="width: 130px">
               <el-option label="全部" value="" />
-              <el-option v-for="p in platformOptions" :key="p" :label="p" :value="p" />
-            </el-select>
-          </el-form-item>
-          <el-form-item label="结算状态">
-            <el-select v-model="query.settle_status" clearable placeholder="请选择" style="width: 130px">
-              <el-option label="全部" value="" />
-              <el-option label="未结算" value="未结算" />
-              <el-option label="已结算" value="已结算" />
+              <el-option v-for="s in statusOptions" :key="s.value" :label="s.label" :value="s.value" />
             </el-select>
           </el-form-item>
           <el-form-item label="投注时间">
@@ -59,6 +43,7 @@
           </el-form-item>
           <el-form-item class="filter-actions">
             <el-button type="primary" size="small" :loading="loading" @click="handleSearch">查询</el-button>
+            <el-button size="small" @click="handleReset">重置</el-button>
           </el-form-item>
         </el-form>
       </div>
@@ -70,20 +55,6 @@
           <el-table-column type="index" label="序号" width="80" align="center" />
           <el-table-column prop="member_id" label="会员ID" width="110" align="center" />
           <el-table-column prop="member_name" label="会员昵称" width="130" align="center" />
-          <el-table-column prop="from" label="注册来源" width="110" align="center">
-            <template slot-scope="{ row }">
-              <span :style="{
-                color: Number(row.from) === 1 ? '#05A58F' : Number(row.from) === 2 ? '#F3061F' : '#606266'
-              }">
-                {{
-                  Number(row.from) === 1 ? '真实用户' :
-                    Number(row.from) === 2 ? '虚拟用户' :
-                      Number(row.from) === -1 ? 'tg用户' :
-                        Number(row.from) === 0 ? '后台客服账号' : '--'
-                }}
-              </span>
-            </template>
-          </el-table-column>
           <el-table-column prop="order_no" label="订单号" width="180" align="center" />
           <el-table-column prop="game_type" label="游戏类型" width="110" align="center" />
           <el-table-column prop="platform" label="平台类型" width="100" align="center" />
@@ -108,7 +79,7 @@
           </el-table-column>
           <el-table-column prop="settle_status" label="结算状态" width="100" align="center">
             <template slot-scope="{ row }">
-              <span :style="{ color: row.settle_status === '已结算' ? '#18C80A' : '#909399' }">{{ row.settle_status }}</span>
+              <span :style="{ color: row.settle_status === '已完成' ? '#18C80A' : row.settle_status === '未完成' ? '#909399' : '#F56C6C' }">{{ row.settle_status }}</span>
             </template>
           </el-table-column>
           <el-table-column label="操作" width="90" align="center" fixed="right">
@@ -117,11 +88,11 @@
             </template>
           </el-table-column>
         </el-table>
-        <el-pagination v-if="tableData.length" background
+        <el-pagination v-if="total" background
           layout="total, prev, pager, next, jumper" :page-size="pageSize"
           :page-sizes="[15, 30, 45, 60]" :current-page="page"
-          :total="tableData.length"
-          @current-change="page = $event" @size-change="handleSizeChange" />
+          :total="total"
+          @current-change="page = $event; fetchList()" @size-change="handleSizeChange" />
       </div>
     </div>
 
@@ -146,17 +117,9 @@
 
 <script>
 import Dialog from '@/components/Dialog/index.vue'
+import { getThirdGameOrders } from '@/api/data'
 import { buildDatePickerOptions } from '@/utils/index'
 
-// 假数据
-const MOCK_DATA = [
-  { id: 1, member_id: 10001, member_name: 'test01', from: '1', order_no: 'TG202608130001', game_type: '电子', platform: 'pg', game_name: '麻将胡了', amount: 100, currency: 'CNY', valid_amount: 100, win_loss: 50, settle_status: '已结算', bet_time: '2026-08-13 10:20:30' },
-  { id: 2, member_id: 10002, member_name: 'test02', from: '2', order_no: 'TG202608130002', game_type: '捕鱼', platform: 'ag', game_name: '冰川时代', amount: 200, currency: 'CNY', valid_amount: 180, win_loss: -60, settle_status: '已结算', bet_time: '2026-08-13 11:00:00' },
-  { id: 3, member_id: 10003, member_name: 'test03', from: '1', order_no: 'TG202608130003', game_type: '棋牌', platform: 'bg', game_name: '捕鱼达人', amount: 500, currency: 'CNY', valid_amount: 500, win_loss: 120, settle_status: '未结算', bet_time: '2026-08-13 14:30:00' },
-  { id: 4, member_id: 10004, member_name: 'test04', from: '0', order_no: 'TG202608130004', game_type: '体育', platform: 'dg', game_name: '功夫熊猫', amount: 1000, currency: 'CNY', valid_amount: 1000, win_loss: -300, settle_status: '已结算', bet_time: '2026-08-13 16:40:00' },
-  { id: 5, member_id: 10005, member_name: 'test05', from: '1', order_no: 'TG202608130005', game_type: '视讯', platform: 'db5', game_name: '捕鱼3D', amount: 300, currency: 'CNY', valid_amount: 300, win_loss: 0, settle_status: '未结算', bet_time: '2026-08-13 18:00:00' }
-]
-
 export default {
   name: 'ThirdGameOrder',
   components: {
@@ -167,19 +130,30 @@ export default {
       loading: false,
       page: 1,
       pageSize: 15,
-      tableData: [...MOCK_DATA],
-      filteredData: [...MOCK_DATA],
+      total: 0,
+      tableData: [],
       viewRow: null,
-      categoryOptions: ['视讯', '电子', '捕鱼', '体育', '棋牌'],
-      platformOptions: ['ag', 'pg', 'bg', 'dg', 'db5'],
+      categoryOptions: [
+        { value: 1, label: '视讯' },
+        { value: 2, label: '老虎机' },
+        { value: 3, label: '彩票' },
+        { value: 4, label: '体育' },
+        { value: 5, label: '电竞' },
+        { value: 6, label: '捕猎' },
+        { value: 7, label: '棋牌' }
+      ],
+      statusOptions: [
+        { value: 0, label: '未完成' },
+        { value: 1, label: '已完成' },
+        { value: 2, label: '已取消' },
+        { value: 3, label: '已撤单' }
+      ],
       query: {
-        from: '',
         member_id: '',
         first_name: '',
         order_no: '',
         category: '',
-        platform: '',
-        settle_status: '',
+        status: '',
         dateRange: []
       },
       pickerOptions: buildDatePickerOptions({
@@ -222,22 +196,20 @@ export default {
     }
   },
   computed: {
+    // 后端已分页,直接返回
     pagedData() {
-      const start = (this.page - 1) * this.pageSize
-      return this.filteredData.slice(start, start + this.pageSize)
+      return this.tableData
     },
     viewFields() {
       if (!this.viewRow) return []
       const row = this.viewRow
-      const fromMap = { '-1': 'tg用户', 0: '后台客服账号', 1: '真实用户', 2: '虚拟用户' }
-      const fromText = fromMap[row.from] || '--'
-      const fromColor = Number(row.from) === 1 ? '#05A58F' : Number(row.from) === 2 ? '#F3061F' : '#606266'
       const winLossColor = Number(row.win_loss) > 0 ? '#18C80A' : Number(row.win_loss) < 0 ? '#F56C6C' : '#606266'
+      const statusColor = row.settle_status === '已完成' ? '#18C80A' : row.settle_status === '未完成' ? '#909399' : '#F56C6C'
       return [
         { label: '序号', prop: 'id', value: row.id },
         { label: '会员ID', prop: 'member_id', value: row.member_id },
         { label: '会员昵称', prop: 'member_name', value: row.member_name || '--' },
-        { label: '注册来源', prop: 'from_text', value: fromText, color: fromColor },
+        { label: '三方玩家ID', prop: 'player_id', value: row.player_id || '--' },
         { label: '订单号', prop: 'order_no', value: row.order_no || '--' },
         { label: '游戏类型', prop: 'game_type', value: row.game_type || '--' },
         { label: '平台类型', prop: 'platform', value: row.platform || '--' },
@@ -246,41 +218,94 @@ export default {
         { label: '游戏货币', prop: 'currency', value: row.currency || '--' },
         { label: '有效投注', prop: 'valid_amount', value: row.valid_amount != null ? Number(row.valid_amount).toFixed(2) : '--', color: '#1677FF' },
         { label: '输赢金额', prop: 'win_loss', value: row.win_loss != null ? Number(row.win_loss).toFixed(2) : '--', color: winLossColor },
-        { label: '结算状态', prop: 'settle_status', value: row.settle_status || '--', color: row.settle_status === '已结算' ? '#18C80A' : '#909399' },
-        { label: '投注时间', prop: 'bet_time', value: row.bet_time || '--' }
+        { label: '结算状态', prop: 'settle_status', value: row.settle_status || '--', color: statusColor },
+        { label: '投注内容', prop: 'bet_content', value: row.bet_content || '--' },
+        { label: '投注时间', prop: 'bet_time', value: row.bet_time || '--' },
+        { label: '更新时间', prop: 'last_update_time', value: row.last_update_time || '--' }
       ]
     }
   },
+  created() {
+    this.fetchList()
+  },
   methods: {
     handleSizeChange(val) {
       this.pageSize = val
       this.page = 1
+      this.fetchList()
     },
     handleSearch() {
       this.page = 1
-      let filtered = [...this.tableData]
-      if (this.query.from) {
-        filtered = filtered.filter(r => String(r.from) === this.query.from)
-      }
-      if (this.query.member_id) {
-        filtered = filtered.filter(r => String(r.member_id).includes(this.query.member_id))
-      }
-      if (this.query.first_name) {
-        filtered = filtered.filter(r => r.member_name.includes(this.query.first_name))
-      }
-      if (this.query.order_no) {
-        filtered = filtered.filter(r => r.order_no.includes(this.query.order_no))
+      this.fetchList()
+    },
+    // 重置所有筛选条件到初始状态
+    handleReset() {
+      this.query = {
+        member_id: '',
+        first_name: '',
+        order_no: '',
+        category: '',
+        status: '',
+        dateRange: []
       }
-      if (this.query.category) {
-        filtered = filtered.filter(r => r.game_type === this.query.category)
+      this.page = 1
+      this.fetchList()
+    },
+    fetchList() {
+      this.loading = true
+      const [start, end] = this.query.dateRange || []
+      const params = {
+        page: this.page,
+        limit: this.pageSize,
+        member_id: this.query.member_id || '',
+        first_name: this.query.first_name || '',
+        game_order_id: this.query.order_no || '',
+        game_type: this.query.category || '',
+        status: this.query.status
       }
-      if (this.query.platform) {
-        filtered = filtered.filter(r => r.platform === this.query.platform)
+      // 时间范围必须同时传
+      if (start && end) {
+        params.start_time = start
+        params.end_time = end
       }
-      if (this.query.settle_status) {
-        filtered = filtered.filter(r => r.settle_status === this.query.settle_status)
+      getThirdGameOrders(params).then(res => {
+        if (res.code === 0 || res.code === 99) {
+          const data = res.data || {}
+          this.total = Number(data.total) || 0
+          this.tableData = (data.list || []).map(row => this.mapRow(row))
+          const opts = data.options || {}
+          if (Array.isArray(opts.game_types) && opts.game_types.length) this.categoryOptions = opts.game_types
+          if (Array.isArray(opts.statuses) && opts.statuses.length) this.statusOptions = opts.statuses
+        } else {
+          this.$message.error(res.msg || '获取列表失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      }).finally(() => {
+        this.loading = false
+      })
+    },
+    // 订单字段映射
+    mapRow(row) {
+      return {
+        id: row.id,
+        member_id: row.member_id,
+        member_name: row.first_name || row.username || '--',
+        player_id: row.player_id || '--',
+        order_no: row.game_order_id || '--',
+        game_type: row.game_type_text || row.game_type || '--',
+        platform: row.platform || '--',
+        game_name: row.game_name || '--',
+        amount: row.bet_amount,
+        currency: row.currency || '--',
+        valid_amount: row.valid_amount,
+        win_loss: row.settled_amount,
+        settle_status: row.status_text || (Number(row.status) === 1 ? '已完成' : Number(row.status) === 0 ? '未完成' : Number(row.status) === 2 ? '已取消' : '已撤单'),
+        status_code: row.status,
+        bet_content: row.bet_content || '--',
+        bet_time: row.bet_time || '--',
+        last_update_time: row.last_update_time || '--'
       }
-      this.filteredData = filtered
     },
     handleView(row) {
       this.viewRow = { ...row }

+ 83 - 29
src/views/thirdGame/setting/index.vue

@@ -5,32 +5,32 @@
         <el-table v-loading="loading" :data="tableData"
           height="calc(100vh - 200px)" style="width: 100%; border-radius: 12px; overflow: hidden;"
           empty-text="暂无数据">
-          <el-table-column prop="id" label="游戏大类ID" width="120" align="center" />
+          <el-table-column prop="game_type" label="游戏大类ID" width="120" align="center" />
           <el-table-column prop="name" label="游戏大类名称" width="140" align="center" />
           <el-table-column label="PC Logo" width="120" align="center">
             <template slot-scope="{ row }">
-              <el-image v-if="row.pc_image" :src="row.pc_image" style="width: 50px; height: 50px;" fit="cover"
-                :preview-src-list="[row.pc_image]" />
+              <el-image v-if="row.logo" :src="row.logo" style="width: 50px; height: 50px;" fit="cover"
+                :preview-src-list="[row.logo]" />
               <span v-else>--</span>
             </template>
           </el-table-column>
           <el-table-column label="H5/APP Logo" width="130" align="center">
             <template slot-scope="{ row }">
-              <el-image v-if="row.h5_image" :src="row.h5_image" style="width: 50px; height: 50px;" fit="cover"
-                :preview-src-list="[row.h5_image]" />
+              <el-image v-if="row.logo_h5" :src="row.logo_h5" style="width: 50px; height: 50px;" fit="cover"
+                :preview-src-list="[row.logo_h5]" />
               <span v-else>--</span>
             </template>
           </el-table-column>
           <el-table-column prop="description" label="游戏说明" min-width="180" align="center" show-overflow-tooltip />
           <el-table-column prop="sort" label="排序" width="180" align="center">
             <template slot-scope="{ row }">
-              <el-input-number v-model="row.sort" :min="1" size="small" controls-position="right" style="width: 120px"
+              <el-input-number v-model="row.sort" size="small" controls-position="right" style="width: 120px"
                 @change="handleSortChange(row)" />
             </template>
           </el-table-column>
           <el-table-column label="启用状态" width="110" align="center">
             <template slot-scope="{ row }">
-              <el-switch v-model="row.enabled" active-color="#13ce66" inactive-color="#f56c6c"
+              <el-switch v-model="row.status" :active-value="1" :inactive-value="0" active-color="#13ce66" inactive-color="#f56c6c"
                 @change="handleEnabledChange(row)" />
             </template>
           </el-table-column>
@@ -54,10 +54,10 @@
             <span>{{ editForm.name }}</span>
           </el-form-item>
           <el-form-item label="PC Logo">
-            <UploadOneImage v-model="editForm.pc_image" />
+            <UploadOneImage v-model="editForm.logo" />
           </el-form-item>
           <el-form-item label="H5/APP Logo">
-            <UploadOneImage v-model="editForm.h5_image" />
+            <UploadOneImage v-model="editForm.logo_h5" />
           </el-form-item>
           <el-form-item label="游戏说明">
             <el-input v-model="editForm.description" type="textarea" :rows="4" placeholder="请输入游戏说明" style="width: 400px" />
@@ -71,15 +71,7 @@
 <script>
 import Dialog from '@/components/Dialog/index.vue'
 import UploadOneImage from '@/components/UploadOneImage/index.vue'
-
-// 假数据
-const MOCK_DATA = [
-  { id: 1, name: '视讯', pc_image: '', h5_image: '', sort: 1, description: '真人视讯游戏', enabled: true },
-  { id: 2, name: '电子', pc_image: '', h5_image: '', sort: 2, description: '电子老虎机游戏', enabled: true },
-  { id: 3, name: '捕鱼', pc_image: '', h5_image: '', sort: 3, description: '捕鱼游戏', enabled: true },
-  { id: 4, name: '体育', pc_image: '', h5_image: '', sort: 4, description: '体育赛事游戏', enabled: false },
-  { id: 5, name: '棋牌', pc_image: '', h5_image: '', sort: 5, description: '棋牌游戏', enabled: true }
-]
+import { getEgameItems, updateEgame, setEgameStatus } from '@/api/data'
 
 export default {
   name: 'ThirdGameCategory',
@@ -91,31 +83,93 @@ export default {
     return {
       loading: false,
       saving: false,
-      tableData: [...MOCK_DATA],
+      tableData: [],
       editForm: {}
     }
   },
+  created() {
+    this.fetchList()
+  },
   methods: {
+    fetchList() {
+      this.loading = true
+      getEgameItems({ item_type: 'category', page: 1, limit: 200 }).then(res => {
+        if (res.code === 0 || res.code === 99) {
+          const data = res.data || {}
+          this.tableData = (data.data || []).map(row => this.mapRow(row))
+        } else {
+          this.$message.error(res.msg || '获取列表失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      }).finally(() => {
+        this.loading = false
+      })
+    },
+    // 接口字段映射
+    mapRow(row) {
+      return {
+        id: row.id,
+        game_type: row.game_type,
+        name: row.name,
+        description: row.description || '',
+        logo: row.logo || row.logo_pc || '',
+        logo_h5: row.logo_h5 || '',
+        sort: row.sort != null ? row.sort : 0,
+        status: Number(row.status) === 1 ? 1 : 0
+      }
+    },
     handleSortChange(row) {
-      // 排序修改(可直接输入或上下调整),最低 1
-      if (row.sort < 1) row.sort = 1
-      this.$message.success(`游戏大类 ${row.name} 排序已修改为 ${row.sort}`)
+      // 排序修改(可直接输入或上下调整),数字越大越靠前
+      updateEgame({ id: row.id, sort: row.sort }).then(res => {
+        if (res.code === 0) {
+          this.$message.success(`游戏大类 ${row.name} 排序已修改为 ${row.sort}`)
+        } else {
+          this.$message.error(res.msg || '排序修改失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      })
     },
     handleEnabledChange(row) {
-      this.$message.success(`游戏大类 ${row.name} 已${row.enabled ? '开启' : '关闭'}`)
+      setEgameStatus({ id: row.id, status: row.status }).then(res => {
+        if (res.code === 0) {
+          this.$message.success(`游戏大类 ${row.name} 已${row.status === 1 ? '启用' : '停用'}`)
+        } else {
+          this.$message.error(res.msg || '状态修改失败')
+          row.status = row.status === 1 ? 0 : 1 // 回滚
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+        row.status = row.status === 1 ? 0 : 1
+      })
     },
     handleEdit(row) {
       this.editForm = { ...row }
       this.$refs.editDialog.open()
     },
     handleConfirm() {
-      // 保存修改到列表
-      const idx = this.tableData.findIndex(item => item.id === this.editForm.id)
-      if (idx > -1) {
-        this.tableData[idx] = { ...this.editForm }
+      this.saving = true
+      const params = {
+        id: this.editForm.id,
+        name: this.editForm.name,
+        description: this.editForm.description,
+        logo_pc: this.editForm.logo,
+        logo_h5: this.editForm.logo_h5
       }
-      this.$message.success('修改成功')
-      this.$refs.editDialog.close()
+      updateEgame(params).then(res => {
+        if (res.code === 0) {
+          this.$message.success('修改成功')
+          this.$refs.editDialog.close()
+          this.fetchList()
+        } else {
+          this.$message.error(res.msg || '修改失败')
+        }
+      }).catch(() => {
+        this.$message.error('请求异常')
+      }).finally(() => {
+        this.saving = false
+      })
     }
   }
 }