Эх сурвалжийг харах

refactor(UseCommon): 重构allGameInfo

fxs 3 сар өмнө
parent
commit
1618edb3b5

+ 58 - 9
src/components/form/CustomForm.vue

@@ -8,12 +8,14 @@
 -->
 <script setup lang="ts">
 import { useForm } from '@/hooks/useForm'
+import type { BaseSelectOption, GroupSelect } from '@/types/dataAnalysis.ts'
 import { type FormConfig, type FormField, FormFieldType } from '@/types/form'
 
 // import CryptoJS from 'crypto-js'
 import { MD5 } from 'crypto-js'
 import type { FormInstance } from 'element-plus'
-import { onMounted, reactive, ref, watch } from 'vue'
+import { cloneDeep, debounce } from 'lodash'
+import { onMounted, reactive, ref, toRaw, watch } from 'vue'
 
 const { submitForm } = useForm()
 interface FormProp {
@@ -95,9 +97,7 @@ const resetForm = () => {
  * @param {*} row 传过来的数据
  */
 const fillForm = (row: any) => {
-  console.log(row)
   Object.assign(formData, row)
-  console.log(formData)
 }
 
 /**
@@ -172,8 +172,37 @@ const setDefaultValue = () => {
   })
 }
 
+const filteredOptions = ref<Record<string, (BaseSelectOption | GroupSelect)[]>>({})
+const backupOptions: Map<string, (BaseSelectOption | GroupSelect)[]> = new Map()
+
+const filterTT = debounce((query: string, fieldName: string) => {
+  const backup = backupOptions.get(fieldName)
+  if (!backup) return
+
+  const q = query.toLowerCase().trim()
+
+  filteredOptions.value[fieldName] = q
+    ? backup.filter((item) => {
+        if ('options' in item) {
+          return (
+            item.label.toLowerCase().includes(q) ||
+            item.options.some((opt) => opt.label.toLowerCase().includes(q))
+          )
+        }
+        return item.label.toLowerCase().includes(q)
+      })
+    : [...backup]
+}, 300)
+
 onMounted(() => {
   setDefaultValue()
+  props.config.fieldsInfo.forEach((item) => {
+    if (item.otherOptions && item.otherOptions.options) {
+      const options = cloneDeep(toRaw(item.otherOptions.options))
+      filteredOptions.value[item.name] = options
+      backupOptions.set(item.name, options)
+    }
+  })
 })
 
 defineExpose({
@@ -223,14 +252,34 @@ defineExpose({
             size="default"
             :id="item.name"
             :filterable="item.otherOptions.searchSelected"
+            :filter-method="(query: any) => filterTT(query, item.name)"
           >
-            <el-option
-              v-for="val in item.otherOptions.options"
-              :key="val.name"
-              :label="val.label"
-              :value="val.value"
-            />
+            <template v-if="item.otherOptions.needGroup">
+              <el-option-group
+                :key="group.value"
+                :label="group.label"
+                v-for="group in filteredOptions[item.name] as GroupSelect[]"
+              >
+                <el-option
+                  :key="option.value"
+                  :label="option.label"
+                  :value="option.value"
+                  v-for="option in group.options"
+                >
+                </el-option>
+              </el-option-group>
+            </template>
+
+            <template v-else>
+              <el-option
+                v-for="val in filteredOptions[item.name] as BaseSelectOption[]"
+                :key="val.name"
+                :label="val.label"
+                :value="val.value"
+              />
+            </template>
           </el-select>
+
           <el-input
             :id="item.name"
             v-if="item.type === FormFieldType.RICHTEXT"

+ 3 - 0
src/stores/useCommon.ts

@@ -10,6 +10,7 @@
 import { reactive } from 'vue'
 import { defineStore } from 'pinia'
 import { getLocalInfo, saveLocalInfo } from '@/utils/localStorage/localStorage'
+import type { PlatformInfo } from '@/types/dataAnalysis'
 
 interface SelectInfo {
   gid: string
@@ -96,8 +97,10 @@ export const useCommonStore = defineStore('commonStore', () => {
     localStorage.setItem('tempMultipleChoice', JSON.stringify(multipleChoice))
   }
 
+  const gameInfoList = reactive<Array<PlatformInfo>>([])
   const allGameInfo = reactive<Array<GameInfo>>([])
   return {
+    gameInfoList,
     selectInfo,
     allGameInfo,
     tempMultipleChoice: multipleChoice,

+ 13 - 0
src/types/dataAnalysis.ts

@@ -24,6 +24,19 @@ export interface DropDownInfo {
   optionsList: Array<DropDownItem>
 }
 
+export interface BaseSelectOption {
+  value: any
+  label: string
+  name: string
+}
+
+export interface GroupSelect {
+  name: string
+  value: any
+  label: string
+  options: Array<BaseSelectOption>
+}
+
 export interface GameItem {
   id: number
   pid: string

+ 3 - 2
src/types/form.ts

@@ -1,4 +1,4 @@
-import type { ReqConfig } from '@/types/dataAnalysis'
+import type { BaseSelectOption, GroupSelect, ReqConfig } from '@/types/dataAnalysis'
 import type { FormRules } from 'element-plus'
 import type { VNode } from 'vue'
 
@@ -20,8 +20,9 @@ export interface FormField {
   otherOptions?: {
     placeholder?: string
     tip?: string | (() => string | VNode)
+    needGroup?: boolean // 是否需要分组
     searchSelected?: boolean // 选择框是否可搜索,此选项只对select生效
-    options?: Array<{ name: string; label: string; value: any }>
+    options?: Array<BaseSelectOption> | Array<GroupSelect>
   }
 }
 

+ 22 - 20
src/utils/table/table.ts

@@ -1,4 +1,4 @@
-import { useTableStore } from '@/stores/useTable'
+import { useCommonStore } from '@/stores/useCommon.ts'
 import { useRequest } from '@/hooks/useRequest'
 
 import axiosInstance from '../axios/axiosInstance'
@@ -11,31 +11,32 @@ const { AllApi } = useRequest()
  * @param {Array} data 获取到的表格数据
  * @param {number} code 状态码
  */
-const formatGameInfo = (data: Array<any>, code: number): Array<any> => {
-  const returnData: Array<any> = []
-
-  if (code === 0 && Array.isArray(data)) {
-    const gameInfoList = data.map((item) => {
-      return { gid: item.gid, gameName: item.gameName }
-    })
-    returnData.splice(0, returnData.length, ...gameInfoList)
-  } else {
-    console.log('获取游戏列表失败')
-  }
-  return returnData
-}
+// const formatGameInfo = (data: Array<any>, code: number): Array<any> => {
+//   const returnData: Array<any> = []
+//
+//   if (code === 0 && Array.isArray(data)) {
+//     const gameInfoList = data.map((item) => {
+//       return { gid: item.gid, gameName: item.gameName }
+//     })
+//     returnData.splice(0, returnData.length, ...gameInfoList)
+//   } else {
+//     console.log('获取游戏列表失败')
+//   }
+//   return returnData
+// }
 
 /**
  * 获取所有游戏信息
  */
 export const getAllGameInfo = async () => {
   try {
-    const tableStore = useTableStore() // 这一句不要直接写在函数外面,会导致在pinia挂载之前被调用
+    // const tableStore = useTableStore() // 这一句不要直接写在函数外面,会导致在pinia挂载之前被调用
 
+    const { gameInfoList } = useCommonStore()
     // 如果已经有了,那么直接用缓存
-    if (tableStore.allGameInfo.length) return tableStore.allGameInfo
+    if (gameInfoList.length) return gameInfoList
 
-    const response = (await axiosInstance.post(AllApi.getGidList, {
+    const response = (await axiosInstance.post(AllApi.pidToGidList, {
       active: false
     })) as ResponseInfo
     if (!response || response.code !== 0) {
@@ -44,11 +45,12 @@ export const getAllGameInfo = async () => {
     }
 
     const result = JSON.parse(JSON.stringify(response))
+    gameInfoList.splice(0, gameInfoList.length, ...result.data)
     const data = result.data
-    const returnData: Array<any> = formatGameInfo(data, result.code)
-    tableStore.setGameInfo(returnData) // 格式化后的数据放到tableStore中
+    // const returnData: Array<any> = formatGameInfo(data, result.code)
+    // tableStore.setGameInfo(returnData) // 格式化后的数据放到tableStore中
 
-    return returnData
+    return data
   } catch (err) {
     console.log(err)
     return []

+ 5 - 5
src/views/AppManage/BaseInfoView.vue

@@ -9,7 +9,7 @@ import axiosInstance from '@/utils/axios/axiosInstance'
 import HeaderCard from '@/components/dataAnalysis/HeaderCard.vue'
 
 const { AllApi } = useRequest()
-const { selectInfo, allGameInfo } = useCommonStore()
+const { selectInfo } = useCommonStore()
 
 interface AppInfo {
   gameName: string
@@ -70,8 +70,8 @@ const copyGid = () => {
   })
 }
 
-const changeGameInfo = () => {
-  let nowGame = allGameInfo.find((item: any) => {
+const changeGameInfo = (gameTable: any[]) => {
+  let nowGame = gameTable.find((item: any) => {
     return item.gid === selectInfo.gid
   })
   Object.assign(appInfo, nowGame)
@@ -84,8 +84,8 @@ const getGameInfo = () => {
     })
     .then((data) => {
       let info = data.data
-      Object.assign(allGameInfo, info)
-      changeGameInfo()
+      // Object.assign(allGameInfo, info)
+      changeGameInfo(info)
     })
 }
 

+ 21 - 13
src/views/AppManage/EventManageView.vue

@@ -9,6 +9,7 @@
 -->
 <script setup lang="ts">
 import CustomDialog from '@/components/common/CustomDialog.vue'
+import type { GroupSelect } from '@/types/dataAnalysis.ts'
 import type { DialogConfig } from '@/types/dialog.ts'
 import { FormFieldType } from '@/types/form.ts'
 import type { ResponseInfo } from '@/types/res'
@@ -100,7 +101,7 @@ type GetTableReturn<T> = T extends 'all'
       ? { allOptionsInfo: { [key: string]: Array<DownLoadOption> } }
       : never
 
-const { selectInfo, allGameInfo } = useCommonStore()
+const { selectInfo, gameInfoList } = useCommonStore()
 
 const { AllApi } = useRequest()
 
@@ -154,15 +155,21 @@ const dialogRules = reactive<FormRules<typeof dialogRuleForm>>({
 
 const copyConfigDialogRef = ref<CustomDialogType>()
 
-const gameOptions = allGameInfo.map((item) => {
-  return {
-    name: item.gid,
-    value: item.gid,
-    label: item.gameName
-  }
+const gameOptions = computed<GroupSelect[]>(() => {
+  console.log('计算')
+  return gameInfoList.map((item) => ({
+    name: item.pidName,
+    label: item.pidName,
+    value: item.pid,
+    options: item.gidList.map((item) => ({
+      name: item.gameName,
+      label: item.gameName,
+      value: item.gid
+    }))
+  }))
 })
 
-const configCopyInfo = ref<DialogConfig>({
+const configCopyInfo = reactive<DialogConfig>({
   title: '复制事件',
   rules: dialogRules,
   reqConfig: {
@@ -174,10 +181,10 @@ const configCopyInfo = ref<DialogConfig>({
       name: 'gid',
       cnName: '原游戏',
       type: FormFieldType.SELECT,
-
       otherOptions: {
-        options: gameOptions,
-        searchSelected: true
+        options: gameOptions.value,
+        searchSelected: true,
+        needGroup: true
       }
     },
     {
@@ -186,8 +193,9 @@ const configCopyInfo = ref<DialogConfig>({
       type: FormFieldType.SELECT,
       defaultValue: selectInfo.gid,
       otherOptions: {
-        options: gameOptions,
-        searchSelected: true
+        options: gameOptions.value,
+        searchSelected: true,
+        needGroup: true
       }
     }
   ]

+ 13 - 13
src/views/AppManage/GameManageView.vue

@@ -46,7 +46,7 @@ interface ProjectInfo {
   pid: string
 }
 
-const { allGameInfo } = useCommonStore()
+// const { allGameInfo,gameInfoList } = useCommonStore()
 const { AllApi } = useRequest()
 
 const gameTableRef = ref<InstanceType<typeof Table>>()
@@ -340,7 +340,7 @@ const gameRules = reactive<FormRules<typeof gameFormRule>>({
 const dialogFormFields = computed<FormField[]>(() => [
   {
     name: 'pid',
-    cnName: '项目',
+    cnName: '项目',
     type: FormFieldType.SELECT,
     otherOptions: {
       options: projectList.value.map((item) => ({
@@ -419,17 +419,17 @@ const handleEdit = (row: any) => {
 }
 
 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
-    }
-  }
+  // 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()
 }

+ 32 - 25
src/views/IndexView.vue

@@ -9,7 +9,7 @@
 <script setup lang="ts">
 import { useRequest } from '@/hooks/useRequest.ts'
 import { useUser } from '@/stores/useUser.ts'
-import type { DropDownGroupInfo } from '@/types/dataAnalysis'
+import type { DropDownGroupInfo, PlatformInfo } from '@/types/dataAnalysis'
 import type { ResponseInfo } from '@/types/res.ts'
 import AxiosInstance from '@/utils/axios/axiosInstance.ts'
 
@@ -32,22 +32,22 @@ import router from '@/router'
 //   gameName: string
 // }
 
-interface GameItem {
-  id: number
-  pid: string
-  gid: string
-  gameName: string
-  pidName: string
-}
-
-interface PlatformInfo {
-  pidName: string
-  pid: string
-  gidList: GameItem[]
-}
+// interface GameItem {
+//   id: number
+//   pid: string
+//   gid: string
+//   gameName: string
+//   pidName: string
+// }
+//
+// interface PlatformInfo {
+//   pidName: string
+//   pid: string
+//   gidList: GameItem[]
+// }
 
 const route = useRoute()
-const { selectInfo, allGameInfo, saveSelectInfo } = useCommonStore()
+const { selectInfo, gameInfoList, saveSelectInfo } = useCommonStore()
 const { AllApi } = useRequest()
 const { updateUserInfo } = useUser()
 const userInfo = getUserInfo()
@@ -224,14 +224,14 @@ const updateGameInfo = () => {
   getAllGameInfo()
     .then((data) => {
       if (data) {
-        allGameInfo.splice(0, allGameInfo.length)
-
-        data.map((item) => {
-          allGameInfo.push({
-            gid: item.gid,
-            gameName: item.gameName
-          })
-        })
+        // allGameInfo.splice(0, allGameInfo.length)
+        //
+        // data.map((item) => {
+        //   allGameInfo.push({
+        //     gid: item.gid,
+        //     gameName: item.gameName
+        //   })
+        // })
 
         loadingState.value = true
       } else {
@@ -323,7 +323,6 @@ const updateNavbarGameSelect = async (query: string, force = false) => {
 }
 
 const filterSelect = (query: string) => {
-  console.log('执行')
   gameSelectInfo.optionsList = backupOptionsList.filter((item) => {
     return (
       item.pidName.includes(query) || item.gidList.find((item) => item.gameName.includes(query))
@@ -348,8 +347,16 @@ const watchLoadingState = watch(
   (newVal) => {
     if (newVal) {
       // 用来监听游戏列表的变化
+      // watchGameListChange = watch(
+      //   () => allGameInfo,
+      //   () => {
+      //     updateNavbarGameSelect('', true)
+      //   },
+      //   { deep: true }
+      // )
+
       watchGameListChange = watch(
-        () => allGameInfo,
+        () => gameInfoList,
         () => {
           updateNavbarGameSelect('', true)
         },

+ 39 - 16
src/views/MemberManage/MemberTable.vue

@@ -1,7 +1,7 @@
 <script setup lang="ts">
 import CustomTable from '@/components/table/CustomTable.vue'
 import { useRequest } from '@/hooks/useRequest.ts'
-import { useTableStore } from '@/stores/useTable.ts'
+import { useCommonStore } from '@/stores/useCommon.ts'
 
 import type { ReqConfig } from '@/types/dataAnalysis.ts'
 import type { ResponseInfo } from '@/types/res.ts'
@@ -37,11 +37,25 @@ interface TableConfig {
   tableToolsConfig: TableToolsConfig
 }
 
-type GameMap = Map<string, string>
-
 const { AllApi } = useRequest()
-const { allGameInfo } = useTableStore()
-const gameMap: GameMap = new Map(allGameInfo.map((item) => [item.gid, item.gameName]))
+const { gameInfoList } = useCommonStore()
+let gameInfo: Map<string, string> = new Map()
+
+const allGid: string[] = []
+
+const updateGameInfo = () => {
+  gameInfo = new Map<string, string>(
+    gameInfoList.flatMap((platform) =>
+      platform.gidList.map((item) => [item.gid, item.gameName] as [string, string])
+    )
+  )
+
+  allGid.splice(
+    0,
+    allGid.length,
+    ...gameInfoList.flatMap((item) => item.gidList).map((item) => item.gid)
+  )
+}
 
 const memberTableRef = ref<CustomTableType>()
 
@@ -70,7 +84,7 @@ const memberForm = ref<MemberInfo>({
 })
 
 const getGameName = (gid: string) => {
-  return gameMap.get(gid) || '未知游戏'
+  return gameInfo.get(gid) || '未知游戏'
 }
 
 // 表格配置
@@ -193,7 +207,7 @@ const editMember = (row: any) => {
   const permission: string[] = [...row.permission]
 
   if (isAdmin.value || row.permission[0] === 'all') {
-    const allGid = allGameInfo.map((item) => item.gid)
+    // const allGid = gameInfoList.map((item) => item.gid)
     permission.splice(0, permission.length, ...allGid)
     isCheckAllPermission.value = true
     console.log('执行')
@@ -230,7 +244,7 @@ const saveMember = async () => {
     }
 
     // 特殊处理一下全选的情况
-    if (params.permission.length === allGameInfo.length) {
+    if (params.permission.length === allGid.length) {
       params.permission = ['all']
     }
 
@@ -291,10 +305,8 @@ const closePasswordDialog = () => {
 
 const isCheckAllPermission = ref<boolean>(false)
 const handleCheckAll = (isAllCheck: CheckboxValueType) => {
-  console.log(isAllCheck)
-  console.log(memberForm.value)
   if (isAllCheck) {
-    memberForm.value.permission = allGameInfo.map((item) => item.gid)
+    memberForm.value.permission = [...allGid]
   } else {
     memberForm.value.permission = []
   }
@@ -303,9 +315,20 @@ const handleCheckAll = (isAllCheck: CheckboxValueType) => {
 watch(
   () => memberForm.value.permission,
   (val: string[]) => {
-    isCheckAllPermission.value = val.length === allGameInfo.length
+    isCheckAllPermission.value = val.length === allGid.length
+  },
+  {
+    deep: true
+  }
+)
+
+watch(
+  () => gameInfoList,
+  () => {
+    updateGameInfo()
   },
   {
+    immediate: true,
     deep: true
   }
 )
@@ -377,10 +400,10 @@ watch(
               </el-checkbox>
             </template>
             <el-option
-              v-for="item in allGameInfo"
-              :key="item.gid"
-              :label="item.gameName"
-              :value="item.gid"
+              v-for="[gid, gameName] of gameInfo"
+              :key="gid"
+              :label="gameName"
+              :value="gid"
             />
           </el-select>
         </el-form-item>