瀏覽代碼

refactor(游戏管理页): 现在支持分页查询

fxs 14 小時之前
父節點
當前提交
d51e6625f6
共有 1 個文件被更改,包括 83 次插入122 次删除
  1. 83 122
      src/views/AppManage/GameManageView.vue

+ 83 - 122
src/views/AppManage/GameManageView.vue

@@ -7,6 +7,14 @@
  * 
 -->
 <script setup lang="ts">
+import Dialog from '@/components/common/CustomDialog.vue'
+import Table from '@/components/table/CustomTable.vue'
+import { useRequest } from '@/hooks/useRequest.ts'
+import type { ReqConfig } from '@/types/dataAnalysis.ts'
+import type { DialogConfig } from '@/types/dialog.ts'
+import type { FormField } from '@/types/form.ts'
+import { FormFieldType } from '@/types/form.ts'
+import type { ResponseInfo } from '@/types/res.ts'
 import type {
   QueryInfo,
   TableFieldInfo,
@@ -14,20 +22,11 @@ import type {
   TableToolsConfig
 } from '@/types/table.ts'
 import { FilterType } from '@/types/table.ts'
-import AxiosInstance from '@/utils/axios/axiosInstance.ts'
-import type { FormRules } from 'element-plus'
-import type { DialogConfig } from '@/types/dialog.ts'
-import type { FormField } from '@/types/form.ts'
-import { FormFieldType } from '@/types/form.ts'
-import type { ResponseInfo } from '@/types/res.ts'
 
 import { FieldSpecialEffectType } from '@/types/tableText.ts'
-import { computed, onMounted, reactive, ref } from 'vue'
-import { useRequest } from '@/hooks/useRequest.ts'
-
-import Dialog from '@/components/common/CustomDialog.vue'
-import Table from '@/components/table/CustomTable.vue'
 import axiosInstance from '@/utils/axios/axiosInstance.ts'
+import type { FormRules } from 'element-plus'
+import { computed, onMounted, reactive, ref } from 'vue'
 
 interface GameInfo {
   gameName: string
@@ -52,11 +51,11 @@ const gameTableRef = ref<InstanceType<typeof Table>>()
 const gameDialogRef = ref()
 
 // 配置请求参数
-const requestConfig = reactive({
+const requestConfig = reactive<ReqConfig>({
   url: AllApi.getGameTable,
   // url: 'http://192.168.1.139:8000/user/getGidConfig',
   otherOptions: {
-    appSecret: '6YJSuc50uJ18zj45'
+    search: ''
   }
 })
 
@@ -158,16 +157,10 @@ const fieldsInfo = reactive<Array<TableFieldInfo>>([
 // 查询字段设置
 const queryInfo: Array<QueryInfo> = [
   {
-    name: 'gameName',
+    name: 'search',
     label: '游戏名',
     type: FilterType.INPUT,
-    placeholder: '请输入游戏名进行搜索'
-  },
-  {
-    name: 'pid',
-    label: '项目ID',
-    type: FilterType.INPUT,
-    placeholder: '请输入Pid进行搜索'
+    placeholder: '请输入游戏名 / GID / PID 进行搜索'
   }
 ]
 
@@ -188,58 +181,30 @@ const isAddDialog = ref(false)
 
 const projectList = ref<ProjectInfo[]>([])
 
-/**
- * 校验GID有没有重复
- *
- * @param _rule 规则,可忽略
- * @param value 值
- * @param callback 回调函数
- */
-const checkGid = (_rule: any, value: any, callback: any) => {
-  if (!value) {
-    return callback(new Error('请输入游戏ID'))
-  }
-  if (!isAddDialog.value) {
-    callback()
-    return
-  }
-  setTimeout(() => {
-    for (let i = 0; i < tableData.length; i++) {
-      if (tableData[i].gid === value) {
-        callback(new Error('游戏ID已存在'))
-        break
-      }
+const checkGid = (_rule: unknown, value: string, callback: (err?: Error) => void) => {
+  if (!value) return callback(new Error('请输入游戏ID'))
+  // 编辑时不检查重复
+  if (!isAddDialog.value) return callback()
+
+  for (let i = 0; i < tableData.length; i++) {
+    if (tableData[i].gid === value) {
+      return callback(new Error('游戏ID已存在'))
     }
-    callback()
-  }, 10)
+  }
+  return callback()
 }
 
-/**
- * 校验游戏名
- *
- * 主要对已经存在的游戏名进行校验
- *
- * @param _rule 规则,可忽略
- * @param value 值
- * @param callback 回调函数
- */
-const checkGameName = (_rule: any, value: any, callback: any) => {
-  if (!value) {
-    return callback(new Error('请输入游戏名'))
-  }
-  if (!isAddDialog.value) {
-    callback()
-    return
-  }
-  setTimeout(() => {
-    for (let i = 0; i < tableData.length; i++) {
-      if (tableData[i].gameName === value) {
-        callback(new Error('游戏名已存在'))
-        break
-      }
+const checkGameName = (_rule: unknown, value: string, callback: (err?: Error) => void) => {
+  if (!value) return callback(new Error('请输入游戏名'))
+  // 编辑时不检查重复
+  if (!isAddDialog.value) return callback()
+
+  for (let i = 0; i < tableData.length; i++) {
+    if (tableData[i].gameName === value) {
+      return callback(new Error('游戏名已存在'))
     }
-    callback()
-  }, 10)
+  }
+  return callback()
 }
 
 // 表单规则
@@ -417,76 +382,72 @@ const handleEdit = (row: any) => {
   gameDialogRef.value.editForm(row)
 }
 
-const formSub = (formData: any, type: number) => {
-  // if (type === 0) {
-  //   allGameInfo.push({
-  //     gid: formData.gid,
-  //     gameName: formData.gameName
-  //   })
-  // } else {
-  //   let game = allGameInfo.find((item) => item.gid === formData.gid)
-  //   if (game) {
-  //     game.gameName = formData.gameName
-  //   }
-  // }
-  getTableData()
-  updateProjectList()
+const formSub = () => {
+  gameTableRef.value?.updateTableData()
 }
 
-const getTableData = async () => {
-  const res = (await axiosInstance.post(
-    requestConfig.url,
-    requestConfig.otherOptions
-  )) as ResponseInfo
-  const dataList = res.data as Array<any>
-  tableData.splice(0, tableData.length, ...dataList)
+async function postWithRetry<T>(fn: () => Promise<T>, maxRetries = 2) {
+  let lastErr: unknown
+  for (let attempt = 0; attempt <= maxRetries; attempt++) {
+    try {
+      return await fn()
+    } catch (e) {
+      lastErr = e
+      if (attempt === maxRetries) throw e
+    }
+  }
+  throw lastErr
 }
 
-const updateProjectList = async () => {
-  const allProjects: ProjectInfo[] = []
-  const limit = 10000 // 每次请求最大数量,建议与后端保持一致
+async function* fetchProjectsByPage(limit: number) {
   let offset = 0
-
   let total: number | null = null
+  let fetched = 0
 
-  while (true) {
-    try {
-      const res = (await AxiosInstance.post(AllApi.getProjectList, {
+  while (total === null || fetched < total) {
+    const res = await postWithRetry(async () => {
+      return (await axiosInstance.post(AllApi.getProjectList, {
         offset,
         limit
       })) as ResponseInfo
+    }, 2)
 
-      let { count, data } = res
-      if (count === undefined) {
-        ElMessage.error('获取Pid列表错误')
-        count = 10000
-      }
+    if (typeof res.count !== 'number') {
+      throw new Error('后端未返回count')
+    }
 
-      // 第一次请求时获取总数
-      if (total === null) {
-        total = count
-      }
+    total ??= res.count
+    const page = (res.data ?? []) as ProjectInfo[]
 
-      // 将当前页数据追加到总列表
-      allProjects.push(...data)
+    yield page
 
-      // 判断是否已全部获取:已获取数量 >= 总数
-      if (allProjects.length >= total) {
-        break
-      }
+    fetched += page.length
+    offset += limit
 
-      // 继续下一页
-      offset += limit
-    } catch (error) {
-      ElMessage.error('获取Pid列表错误失败')
-      console.error(`分页请求失败,偏移量: ${offset}`)
+    // 保险:如果后端返回空数组但 total 还没到,避免死循环
+    if (page.length === 0) break
+  }
+}
+
+const updateProjectList = async () => {
+  try {
+    const limit = 10000
+    const all: ProjectInfo[] = []
+
+    for await (const page of fetchProjectsByPage(limit)) {
+      all.push(...page)
     }
+
+    projectList.value = all
+  } catch (e) {
+    ElMessage.error('获取Pid列表失败')
+    console.error(e)
+    projectList.value = []
   }
-  projectList.value = [...allProjects]
 }
 
 onMounted(() => {
-  getTableData()
+  // getTableData()
   updateProjectList()
 })
 </script>
@@ -495,13 +456,13 @@ onMounted(() => {
     <div class="gameTableContainer">
       <Table
         ref="gameTableRef"
+        :request-config="requestConfig"
         :tools="tableToolsConfig"
         :open-filter-query="true"
         :open-page-query="true"
-        :open-remote-req-data="false"
-        :open-remote-query="false"
+        :open-remote-req-data="true"
+        :open-remote-query="true"
         :query-info="queryInfo"
-        :data-list="tableData"
         :table-fields-info="fieldsInfo"
         :pagination-config="paginationConfig"
         @addNewItem="addNewItem"