Переглянути джерело

优化表格中的图片资源加载方式,现在会缓存为blob路径;修复了表格查询的重置功能会将下拉框置为无选中状态的bug;修复了趋势图组件在点击切换后,表格不展示数据的bug;更新了表格getdata函数的逻辑,现在会在数据请求完成之后再进行其他操作;修复了用户管理页无法展示数据的bug;更新了事件详情页对更换游戏操作的处理逻辑,现在切换游戏后,会直接替换url为tablemange;删除table中的无效emits事件loadsuccess;

fxs 8 місяців тому
батько
коміт
b604a67c28

+ 99 - 67
src/components/Table.vue

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 18:16:18
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-13 18:07:38
+ * @LastEditTime: 2024-09-18 12:00:45
  * @FilePath: \Game-Backstage-Management-System\src\components\Table.vue
  * @Description: 
  * 
@@ -23,7 +23,6 @@ import { useRequest } from '@/hooks/useRequest'
 
 import type { FormInstance } from 'element-plus'
 import axiosInstance from '@/utils/axios/axiosInstance'
-import { clearReactiveData } from '@/utils/common'
 
 const { analysisResCode } = useRequest()
 
@@ -46,7 +45,8 @@ const props = withDefaults(defineProps<PropsParams>(), {
 })
 
 // 父组件触发的方法
-const emits = defineEmits(['addNewItem', 'upload', 'downLoad', 'loadSuccess'])
+// 删除了一个事件触发,loadSuccess
+const emits = defineEmits(['addNewItem', 'upload', 'downLoad'])
 
 // 加载动画
 const loading = ref(false)
@@ -60,6 +60,8 @@ const backupTableData: Array<any> = []
 // 查询表单的数据
 const queryFormData = reactive<{ [key: string]: any }>({})
 
+const backupQueryFormData = reactive<{ [key: string]: any }>({})
+
 // 分页数据
 const paginationConfig2 = reactive<TablePaginationSetting>({
   currentPage: 0,
@@ -132,79 +134,104 @@ const handleSizeChange = (val: number) => {
  * @return {*}
  */
 const getData = () => {
-  return new Promise((resolve, reject) => {
-    if (props.dataList) {
-      tableData.splice(0, tableData.length, ...props.dataList)
-      paginationConfig2.total = props.paginationConfig.total
-      loading.value = false
-      emits('loadSuccess', tableData)
-      resolve(true)
-    } else {
-      loading.value = true
-      if (props.requestConfig) {
-        if (props.openPageQuery) {
-          // 如果开启了分页查询,那么要计算出需要展示的页码位置所对应的偏移量
-          // 同时要将查询的条数改为对应的用户选择的展示条数
-          reqconfig.otherOptions.offset =
-            (paginationConfig2.currentPage - 1) * paginationConfig2.limit
-          reqconfig.otherOptions.limit = paginationConfig2.limit
-        }
-
-        // 查询时要根据是否开启分页查询传入对应参数
-        getTableData(reqconfig.url, reqconfig.otherOptions, props.openPageQuery)
-          .then(() => {
-            emits('loadSuccess', tableData)
-            backupTableData.splice(0, backupTableData.length, ...tableData)
-            resolve(true)
-          })
-          .catch((err) => {
-            console.log(err)
-
-            reject(err)
-          })
-          .finally(() => {
+  return new Promise(async (resolve, reject) => {
+    try {
+      Object.assign(queryFormData, JSON.parse(JSON.stringify(backupQueryFormData)))
+      const loadTableData = async () => {
+        return new Promise((resolve, reject) => {
+          if (props.dataList) {
+            tableData.splice(0, tableData.length, ...props.dataList)
+
+            paginationConfig2.total = props.paginationConfig.total
             loading.value = false
-          })
-      } else {
-        loading.value = false
+            // emits('loadSuccess', tableData)
 
-        throw new Error('no match requestConfig')
-      }
-    }
-
-    if (tableData.length) {
-      if (props.needAverage) {
-        let rowData: any = {}
-        let oldList: Array<any> = JSON.parse(JSON.stringify(tableData))
-        Object.values(props.tableFieldsInfo).map((item, index) => {
-          let sum = oldList
-            .map((item) => item.count)
-            .reduce((accumulator, currentValue) => accumulator + currentValue, 0)
-          let averageList = oldList
-            .map((val) => val[item.name])
-            .filter((item) => item !== undefined)
-          if (index === 0) rowData[item.name] = '均值'
-          else if (item.name === 'count') rowData[item.name] = sum
-          else {
-            let num =
-              averageList.reduce((accumulator, currentValue) => accumulator + currentValue, 0) /
-              averageList.length
-
-            rowData[item.name] = isNaN(num) ? 0 : num.toFixed(2)
+            resolve(true)
+          } else {
+            loading.value = true
+            if (props.requestConfig) {
+              if (props.openPageQuery) {
+                // 如果开启了分页查询,那么要计算出需要展示的页码位置所对应的偏移量
+                // 同时要将查询的条数改为对应的用户选择的展示条数
+                reqconfig.otherOptions.offset =
+                  (paginationConfig2.currentPage - 1) * paginationConfig2.limit
+                reqconfig.otherOptions.limit = paginationConfig2.limit
+              }
+
+              // 查询时要根据是否开启分页查询传入对应参数
+              getTableData(reqconfig.url, reqconfig.otherOptions, props.openPageQuery)
+                .then(() => {
+                  // emits('loadSuccess', tableData)
+                  backupTableData.splice(0, backupTableData.length, ...tableData)
+
+                  resolve(true)
+                })
+                .catch((err) => {
+                  console.log(err)
+
+                  reject(err)
+                })
+                .finally(() => {
+                  loading.value = false
+                })
+            } else {
+              loading.value = false
+
+              throw new Error('no match requestConfig')
+            }
           }
         })
-        insertRow(0, rowData)
       }
+      // 等待数据加载完成
+      await loadTableData()
+        .then(async () => {
+          if (props.needAverage) {
+            let rowData: any = {}
+            let oldList: Array<any> = JSON.parse(JSON.stringify(tableData))
+            Object.values(props.tableFieldsInfo).map((item, index) => {
+              let sum = oldList
+                .map((item) => item.count)
+                .reduce((accumulator, currentValue) => accumulator + currentValue, 0)
+              let averageList = oldList
+                .map((val) => val[item.name])
+                .filter((item) => item !== undefined)
+              if (index === 0) rowData[item.name] = '均值'
+              else if (item.name === 'count') rowData[item.name] = sum
+              else {
+                let num =
+                  averageList.reduce((accumulator, currentValue) => accumulator + currentValue, 0) /
+                  averageList.length
+
+                rowData[item.name] = isNaN(num) ? 0 : num.toFixed(2)
+              }
+            })
+            insertRow(0, rowData)
+          }
+          resolve(true)
+        })
+        .catch((err) => {
+          console.log(err)
+          reject(err)
+        })
+    } catch (err) {
+      console.log(err)
+      reject(err)
     }
   })
 }
 
-// 清空表格数据
+/**
+ * @description: 清空表格数据
+ * @return {*}
+ */
 const resetTableData = () => {
   tableData.splice(0, tableData.length)
 }
 
-// 按条件查询
+/**
+ * @description: 按条件查询,如果开启了分页查询,那么会直接重新查询数据,否则,会根据现有数据进行查询
+ * @return {*}
+ */
 const queryTableData = () => {
   if (props.requestConfig) {
     reqconfig.otherOptions = { ...props.requestConfig.otherOptions, ...queryFormData }
@@ -212,9 +239,11 @@ const queryTableData = () => {
   if (props.openPageQuery) getData()
   else {
     let filteredTable = []
+    // 过滤出来所有符合formData数据的条件
     filteredTable = backupTableData.filter((item) => {
       let state = true
       for (let [k, v] of Object.entries(queryFormData)) {
+        // 模糊查询,看值是否跟表格中的数据匹配
         if (!fuzzySearch(v, item[k])) {
           state = false
           break
@@ -234,7 +263,9 @@ const queryTableData = () => {
  */
 const resetQueryForm = (formEl: FormInstance | undefined) => {
   if (!formEl) return
-  clearReactiveData(queryFormData)
+  // clearReactiveData(queryFormData)
+  // queryFormData
+  Object.assign(queryFormData, JSON.parse(JSON.stringify(backupQueryFormData)))
   queryTableData()
 }
 
@@ -283,8 +314,6 @@ const tableCellStyle = (info: any) => {
   } else return {}
 }
 
-// 根据分页大小的切换来更新数据
-// 这里将他赋值,用于根据传入的配置来选择是否开启该监听
 /**
  * @description: 监听litmit,currentpage的变化,改变后去重新请求数据
  * 如果是limit的变化,则需要把当前页置为1
@@ -395,6 +424,8 @@ const initFormData = () => {
   props.queryInfo?.map((item: any) => {
     queryFormData[item.name] = item.default
   })
+  // backupQueryFormData = JSON.parse(JSON.stringify(queryFormData))
+  Object.assign(backupQueryFormData, JSON.parse(JSON.stringify(queryFormData)))
 }
 
 /**
@@ -613,7 +644,8 @@ onMounted(() => {
                     : item.specialEffect.othnerInfo.text[1]
                 }}
               </el-tag>
-
+              <!-- :src="loadResource(scope.row[item.name])" -->
+              <!-- :src="scope.row[item.name]" -->
               <!-- 头像类 -->
               <el-image
                 v-else-if="item.specialEffect?.type === FieldSpecialEffectType.IMG"

+ 10 - 3
src/components/dataAnalysis/TemporalTrend.vue

@@ -7,7 +7,7 @@
 -->
 
 <script setup lang="ts">
-import { onMounted, reactive, ref, watch } from 'vue'
+import { nextTick, onMounted, reactive, ref, watch } from 'vue'
 import type { TemporalTrendProps, OptionsProps, StaticField, ReqConfig } from '@/types/dataAnalysis'
 import type { TablePaginationSetting, TableFieldInfo } from '@/types/table'
 import Table from '../Table.vue'
@@ -34,6 +34,7 @@ const props = withDefaults(defineProps<TemporalTrendProps>(), {
 })
 const activeTab = ref<string>('') // 激活的Tab
 const iconSize = ref(20) // 图标的尺寸
+const chartTable = ref<InstanceType<typeof Table>>() // 图表的表格
 
 // 缓存数据
 const cacheData: Record<string, CacheData> = {}
@@ -88,12 +89,18 @@ let chartInfo = reactive<OptionsProps>({
 })
 
 /**
- * @description: 改变图表形式的时候
+ * @description: 改变图表形式,当是表格的时候,去执行表格的获取数据方法,拿到最新的数据
  * @param {*} name 图表的展现形式,可以使table或者trend
  * @return {*}
  */
 const changeSelectShape = (name: number) => {
+  if (selectShape.value === name) return
   selectShape.value = name
+  if (name === 2) {
+    nextTick(() => {
+      chartTable.value?.getData()
+    })
+  }
 }
 
 /**
@@ -149,6 +156,7 @@ const createTableData = (data: any) => {
     newList.push(newItem)
   }
   tableDataList.splice(0, tableDataList.length, ...newList)
+
   paginationConfig.total = xInfo.length
 }
 
@@ -244,7 +252,6 @@ const getData = async (type: number) => {
 
       // 判断返回的数据是否合法,不合法直接全置为空
       if (!isLegalData(data)) {
-        console.log('不合法')
         paginationConfig = reactive({ ...initPageConfig })
 
         chartInfo = reactive<OptionsProps>({ ...initChartInfo })

+ 1 - 1
src/hooks/useRequest.ts

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 17:24:06
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-13 16:48:09
+ * @LastEditTime: 2024-09-18 12:04:38
  * @FilePath: \Game-Backstage-Management-System\src\hooks\useRequest.ts
  * @Description:
  *

+ 26 - 3
src/hooks/useTable.ts

@@ -2,14 +2,15 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 17:15:49
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-13 17:09:30
+ * @LastEditTime: 2024-09-18 10:09:12
  * @FilePath: \Game-Backstage-Management-System\src\hooks\useTable.ts
  * @Description:
  *
  */
 import type { ResponseInfo } from '@/types/res'
 import axiosInstance from '../utils/axios/axiosInstance'
-// import { useRequest } from './useRequest'
+
+import { loadResource } from '@/utils/resource'
 
 import type { TablePaginationSetting, DialogSetting } from '@/types/table'
 import { type FormInstance } from 'element-plus'
@@ -20,10 +21,32 @@ export function useTable(tableData: Array<any>, paginationSetting: TablePaginati
   const getTableData = (url: string, option: any, isPagination: boolean = false) => {
     return new Promise(async (reslove, reject) => {
       try {
-        await axiosInstance.post(url, option).then((result) => {
+        await axiosInstance.post(url, option).then(async (result) => {
           let info = JSON.parse(JSON.stringify(result)) as ResponseInfo
           let data = info.data
 
+          // 加载图片资源
+          // 如果有头像字段,就去加载这个头像字段,缓存起来
+          const loadImg = async () => {
+            return new Promise((resolve) => {
+              let resList: Array<Promise<any>> = []
+              if (data && data.length > 0) {
+                data.slice(0, data.length).map(async (item: any) => {
+                  if (item.head) {
+                    const loadHead = loadResource(item.head).then((res) => {
+                      item.head = res
+                    })
+                    resList.push(loadHead)
+                  }
+                })
+              }
+              Promise.allSettled(resList).then(() => {
+                resolve(true)
+              })
+            })
+          }
+          await loadImg()
+
           // 如果开启了分页,那么默认这个tabledata是一个二维数组,每个位置对应当页的一个数据数组
           // 没开启则是一个一维数组,直接赋值
           if (isPagination) {

+ 2 - 2
src/utils/resource/index.ts

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-31 14:51:20
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-11 16:50:46
+ * @LastEditTime: 2024-09-18 09:24:17
  * @FilePath: \Game-Backstage-Management-System\src\utils\resource\index.ts
  * @Description:
  *
@@ -48,7 +48,7 @@ export const loadResource = (url: string): Promise<string> => {
 
 /**
  * @description: 初始化加载所有的资源
- * @param {Record} resourceObj  请求的url对象,键值都为string
+ * @param {Record} resourceObj  请求的url对象,键值都为string,key为资源的名称,值为资源的请求地址
  * @return {*} 返回一个包含了key和blobURL的对象,用来表示所有资源的请求情况
  */
 export const initLoadResouce = (

+ 15 - 1
src/views/AppManage/EventDetailsView.vue

@@ -14,11 +14,14 @@ import {
   FieldSpecialEffectType
 } from '@/types/table'
 import type { DialogConfig } from '@/types/dialog'
-import { reactive, ref } from 'vue'
+import { watch, onUnmounted, reactive, ref } from 'vue'
 import { useRoute } from 'vue-router'
 import { useRequest } from '@/hooks/useRequest'
+import { useCommonStore } from '@/stores/useCommon'
 import axiosInstance from '@/utils/axios/axiosInstance'
+import router from '@/router'
 
+const { selectInfo } = useCommonStore()
 const { AllApi, analysisResCode } = useRequest()
 
 const emits = defineEmits(['tableDataLoaded', 'upload'])
@@ -432,6 +435,17 @@ const initParams = () => {
 
 // 初始化参数
 initParams()
+
+const watchGid = watch(
+  () => selectInfo.gid,
+  () => {
+    router.replace({ name: 'EventManage' })
+  }
+)
+
+onUnmounted(() => {
+  watchGid()
+})
 </script>
 
 <template>

+ 2 - 4
src/views/AppManage/EventManageView.vue

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-09-02 17:57:15
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-13 12:02:28
+ * @LastEditTime: 2024-09-18 12:00:30
  * @FilePath: \Game-Backstage-Management-System\src\views\AppManage\EventManageView.vue
  * @Description: 
  * 
@@ -10,7 +10,7 @@
 <script setup lang="ts">
 import HeaderCard from '@/components/dataAnalysis/HeaderCard.vue'
 import { shouldListenToEvent } from '@/utils/table/table'
-import { onMounted, ref, reactive, computed } from 'vue'
+import { ref, reactive, computed } from 'vue'
 
 // import { ElMessage, ElNotification } from 'element-plus'
 
@@ -308,8 +308,6 @@ const uploadSuccess = async (data: any) => {
   uploadRef.value?.uploadCallback()
   eventTableRef.value?.updateData()
 }
-
-onMounted(() => {})
 </script>
 
 <template>

+ 1 - 3
src/views/AppManage/EventMangeTable.vue

@@ -12,7 +12,7 @@ import { type DialogConfig } from '@/types/dialog'
 import { FormFieldType } from '@/types/form'
 import type { FormField } from '@/types/form'
 
-import { reactive, onMounted, ref, watch } from 'vue'
+import { reactive, ref, watch } from 'vue'
 
 import router from '@/router'
 
@@ -281,8 +281,6 @@ watch(
 defineExpose({
   updateData
 })
-
-onMounted(() => {})
 </script>
 
 <template>

+ 6 - 2
src/views/Home/InfoManage/GameManageView.vue

@@ -8,7 +8,7 @@ import type { DialogConfig } from '@/types/dialog'
 import type { FormField } from '@/types/form'
 import { FormFieldType } from '@/types/form'
 
-import { reactive, ref } from 'vue'
+import { onMounted, reactive, ref } from 'vue'
 import { useRequest } from '@/hooks/useRequest'
 
 const { AllApi } = useRequest()
@@ -228,7 +228,11 @@ const formSub = () => {
   gameTableRef.value?.getData()
 }
 
-gameTableRef.value?.getData()
+onMounted(() => {
+  gameTableRef.value?.getData()
+})
+
+// gameTableRef.value?.getData()
 </script>
 <template>
   <div class="gameMangeBox">

+ 0 - 21
src/views/Home/Overview/OverView.vue

@@ -190,11 +190,6 @@ const monthInfo = reactive<TemporalTrendInfo>({
       name: 'deviceDuration',
       tabTitle: '单设备时长',
       type: 4
-    },
-    {
-      name: 'retentionRate',
-      tabTitle: '留存率',
-      type: 5
     }
   ]),
   chartsStaticField: toRaw({
@@ -245,18 +240,6 @@ const monthInfo = reactive<TemporalTrendInfo>({
         cnName: '总数',
         value: ''
       }
-    ],
-    retentionRate: [
-      {
-        name: 'avg',
-        cnName: '平均值',
-        value: ''
-      },
-      {
-        name: 'count',
-        cnName: '总数',
-        value: ''
-      }
     ]
   }),
   resDataField: toRaw({
@@ -279,10 +262,6 @@ const monthInfo = reactive<TemporalTrendInfo>({
     deviceDuration: {
       index: '日期',
       timeDistribution: '单设备时长'
-    },
-    retentionRate: {
-      index: '日期',
-      timeDistribution: '留存率'
     }
   })
 })

+ 1 - 2
src/views/Index.vue

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 14:06:49
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-13 16:39:27
+ * @LastEditTime: 2024-09-18 11:56:31
  * @FilePath: \Game-Backstage-Management-System\src\views\Index.vue
  * @Description: 
  * 
@@ -169,7 +169,6 @@ getAllGameInfo().then((data) => {
 })
 
 onMounted(() => {
-  console.log('okok')
   // 去加载所有需要的资源
   initLoadResouce(resourceInfo).then((data) => {
     Object.assign(blobUrlInfo, data)