Procházet zdrojové kódy

更新加载动画

fxs před 9 měsíci
rodič
revize
5eade74df2

+ 31 - 23
src/components/Table.vue

@@ -92,13 +92,12 @@ const handleSizeChange = (val: number) => {
  */
 const getData = () => {
   return new Promise((resolve, reject) => {
-    loading.value = true
     if (props.dataList) {
       tableData.splice(0, tableData.length, ...props.dataList)
-
       loading.value = false
       resolve(true)
     } else {
+      loading.value = true
       if (props.requestConfig) {
         if (props.openPageQuery) {
           // 如果开启了分页查询,那么要计算出需要展示的页码位置所对应的偏移量
@@ -121,27 +120,33 @@ const getData = () => {
             loading.value = false
           })
       } else {
+        loading.value = false
         throw new Error('no match requestConfig')
       }
     }
-    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
-          rowData[item.name] =
-            (
-              averageList.reduce((accumulator, currentValue) => accumulator + currentValue, 0) /
-              averageList.length
-            ).toFixed(2) + '%'
-      })
-      insertRow(0, rowData)
+
+    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
+            rowData[item.name] =
+              (
+                averageList.reduce((accumulator, currentValue) => accumulator + currentValue, 0) /
+                averageList.length
+              ).toFixed(2) + '%'
+        })
+        insertRow(0, rowData)
+      }
     }
   })
 }
@@ -247,7 +252,9 @@ const changeDataList = watch(
 )
 
 // 没传入datalist则取消该监听
-if (!props.dataList) changeDataList()
+if (!props.dataList) {
+  changeDataList()
+}
 
 // 没有开启分页查询就关闭掉这个监听
 if (!props.openPageQuery) changePageLimit()
@@ -259,9 +266,10 @@ defineExpose({
 })
 
 onMounted(() => {
-  if (!props.dataList) {
-    getData()
+  if (props.dataLoading !== undefined) {
+    loading.value = props.dataLoading
   }
+  getData()
 })
 </script>
 

+ 31 - 17
src/components/dataAnalysis/StatisticText.vue

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-26 13:57:37
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-08-29 18:23:28
+ * @LastEditTime: 2024-08-30 11:40:29
  * @FilePath: \Game-Backstage-Management-System\src\components\dataAnalysis\StatisticText.vue
  * @Description: 用于展示统计数据,如总览页面上方的总览数据
  * 
@@ -11,11 +11,11 @@
 <script setup lang="ts">
 import type { StaticDataInfo, StaticField } from '@/types/dataAnalysis'
 import { decimalToPercentage } from '@/utils/common'
-import { onMounted, reactive, watchEffect } from 'vue'
+import { onMounted, reactive, watchEffect, ref } from 'vue'
 import axiosInstance from '@/utils/axios/axiosInstance'
 const props = defineProps<StaticDataInfo>()
 const dataList = reactive<Array<StaticField>>([])
-
+const dataState = ref(false) // 数据是否加载成功
 /**
  * @description: 用于获取数据
  * @tip  这里暂时只请求当日的数据,没有比较
@@ -23,26 +23,37 @@ const dataList = reactive<Array<StaticField>>([])
  */
 const getData = () => {
   if (props.requestConfig) {
-    axiosInstance.post(props.requestConfig.url, props.requestConfig.otherOptions).then((info) => {
+    axiosInstance
+      .post(props.requestConfig.url, props.requestConfig.otherOptions)
+      .then((info) => {
+        dataList.splice(0, dataList.length) // 清空一下
+        let data = info.data
+        props.fieldsInfo.map((item) => {
+          dataList.push({
+            name: item.name,
+            cnName: item.cnName,
+            value: data[item.name]
+          })
+        })
+        dataState.value = true
+      })
+      .catch(() => {
+        dataState.value = false
+      })
+  } else {
+    if (dataList.length) {
       dataList.splice(0, dataList.length) // 清空一下
-      let data = info.data
       props.fieldsInfo.map((item) => {
         dataList.push({
           name: item.name,
           cnName: item.cnName,
-          value: data[item.name]
+          value: item.value
         })
       })
-    })
-  } else {
-    dataList.splice(0, dataList.length) // 清空一下
-    props.fieldsInfo.map((item) => {
-      dataList.push({
-        name: item.name,
-        cnName: item.cnName,
-        value: item.value
-      })
-    })
+      dataState.value = true
+    } else {
+      dataState.value = false
+    }
   }
 }
 
@@ -61,7 +72,7 @@ defineExpose({
 
 <template>
   <div class="dataBox">
-    <div class="dataBody">
+    <div class="dataBody" v-if="dataState">
       <div class="dataItem" v-for="item in dataList">
         <div class="header">
           <span :class="titleClass ? titleClass : 'dataTitle'">{{ item.cnName }}</span>
@@ -82,6 +93,9 @@ defineExpose({
         </div>
       </div>
     </div>
+    <div v-else>
+      <span>加载失败</span>
+    </div>
   </div>
 </template>
 

+ 18 - 4
src/components/dataAnalysis/TemporalTrend.vue

@@ -23,13 +23,14 @@ const iconSize = ref(20) // 图标的尺寸
 // 表格数据
 const tableDataList = reactive<Array<any>>([])
 
+const loading = ref<Boolean>(true) // 是否在加载
+
 // 配置表格分页数据
 const paginationConfig = reactive<TablePaginationSetting>({
   limit: 6, // 每页展示个数
   currentPage: 1, // 当前页码
   total: 0, // 数据总数
   pagesizeList: [6], // 页数大小列表
-  loading: true, // 加载图标
   hasLodingData: 0 // 已经加载的数据
 })
 
@@ -43,7 +44,8 @@ const selectShape = ref(1)
 const chartInfo = reactive<OptionsProps>({
   legendData: [],
   xAxisData: [],
-  seriesData: []
+  seriesData: [],
+  loadingState: ref(loading) as unknown as boolean
 })
 
 /**
@@ -130,10 +132,13 @@ const createOptions = (data: any) => {
 }
 
 const getData = async (type: number) => {
+  // chartInfo.loadingState = true
+
   axiosInstance
     .post(props.requestConfig.url, { ...props.requestConfig.otherOptions, type })
     .then((info) => {
       let data = info.data
+
       // 生成表格字段
       createTableField()
       // 生成表格数据
@@ -153,6 +158,12 @@ const getData = async (type: number) => {
         createOptions(info.data)
       }
     })
+    .catch((err) => {
+      console.log(err)
+    })
+    .finally(() => {
+      loading.value = false
+    })
 }
 
 /**
@@ -182,9 +193,8 @@ watch(
     deep: true
   }
 )
-
+getData(1)
 onMounted(() => {
-  getData(1)
   if (props.tabInfo) activeTab.value = props.tabInfo[0].name
 })
 </script>
@@ -223,17 +233,21 @@ onMounted(() => {
             ></StatisticText>
           </div>
           <TimeLineChart
+            ref="timeLineChart"
             v-if="props.needCharts"
             :legend-data="chartInfo.legendData"
             :series-data="chartInfo.seriesData"
             :x-axis-data="chartInfo.xAxisData"
+            :loading-state="chartInfo.loadingState"
             class="chart"
           ></TimeLineChart>
         </div>
         <div class="tableContent" v-else>
           <Table
+            ref="chartTable"
             v-if="props.needTable"
             :data-list="tableDataList"
+            :data-loading="loading"
             :need-rowindex="true"
             :need-average="false"
             :need-right-tools="false"

+ 86 - 51
src/components/echarts/TimeLineChart.vue

@@ -41,36 +41,6 @@ const formatterTooltip = (params: Array<any>) => {
   return result
 }
 
-// 选项
-const options = {
-  xAxis: {
-    type: 'category',
-    data: [],
-    axisTick: {
-      alignWithLabel: true
-    }
-  },
-  yAxis: {
-    type: 'value'
-  },
-  tooltip: {
-    trigger: 'axis',
-    formatter: formatterTooltip
-  },
-  legend: {
-    orient: 'horizontal', //图例布局方式:水平 'horizontal' 、垂直 'vertical'
-    x: 'right', // 横向放置位置,选项:'center'、'left'、'right'、'number'(横向值 px)
-    y: 'top', // 纵向放置位置,选项:'top'、'bottom'、'center'、'number'(纵向值 px)
-    data: []
-  },
-  grid: {
-    left: '24px',
-    right: '10px',
-    containLabel: true
-  },
-  series: []
-}
-
 // 尺寸变化
 const changeSize = () => {
   nextTick(() => {
@@ -80,6 +50,36 @@ const changeSize = () => {
 
 // 初始化options
 const initOptions = () => {
+  // 选项
+  let options: any = {
+    xAxis: {
+      type: 'category',
+      data: [],
+      axisTick: {
+        alignWithLabel: true
+      }
+    },
+    yAxis: {
+      type: 'value'
+    },
+    tooltip: {
+      trigger: 'axis',
+      formatter: formatterTooltip
+    },
+    legend: {
+      orient: 'horizontal', //图例布局方式:水平 'horizontal' 、垂直 'vertical'
+      x: 'right', // 横向放置位置,选项:'center'、'left'、'right'、'number'(横向值 px)
+      y: 'top', // 纵向放置位置,选项:'top'、'bottom'、'center'、'number'(纵向值 px)
+      data: []
+    },
+    grid: {
+      left: '24px',
+      right: '10px',
+      containLabel: true
+    },
+    series: []
+  }
+
   // 基本的series数据配置
   let baseSeries = {
     symbol: 'circle',
@@ -101,28 +101,52 @@ const initOptions = () => {
     stack: 'x',
     smooth: true
   }
-  // 最终的siries数组
-  let finalSeriesList: any = []
-  // const finalSeriesList: Array<any> = []
-
-  props.legendData.map((item, index) => {
-    const seriesClone = JSON.parse(JSON.stringify(baseSeries))
-    // 设置克隆的属性
-    seriesClone.name = item
-    seriesClone.data = props.seriesData[index]
-    seriesClone.itemStyle.borderColor = colorList[index]
-    seriesClone.lineStyle.color = colorList[index]
-
-    // 将克隆后的对象添加到 finalSeriesList 中
-    finalSeriesList.push(seriesClone)
-  })
 
-  options.series = finalSeriesList
-  options.legend.data = props.legendData as any
-  options.xAxis.data = props.xAxisData as any
-  linechart.value.setOption(options)
+  linechart.value.clear()
+
+  if (props.seriesData.length) {
+    // 最终的siries数组
+    let finalSeriesList: any = []
+    // const finalSeriesList: Array<any> = []
+
+    props.legendData.map((item, index) => {
+      const seriesClone = JSON.parse(JSON.stringify(baseSeries))
+      // 设置克隆的属性
+      seriesClone.name = item
+      seriesClone.data = props.seriesData[index]
+      seriesClone.itemStyle.borderColor = colorList[index]
+      seriesClone.lineStyle.color = colorList[index]
+
+      // 将克隆后的对象添加到 finalSeriesList 中
+      finalSeriesList.push(seriesClone)
+    })
+
+    options.series = finalSeriesList
+    options.legend.data = props.legendData as any
+    options.xAxis.data = props.xAxisData as any
+  } else {
+    options = {
+      title: {
+        text: '暂无数据',
+        x: 'center',
+        y: 'center',
+        textStyle: {
+          fontSize: 16,
+          fontWeight: 'normal'
+        }
+      }
+    }
+  }
+  linechart.value.setOption(options, true)
+}
+
+// 改变加载状态
+const changeLoading = (state: boolean) => {
+  if (state) linechart.value.showLoading()
+  else linechart.value.hideLoading()
 }
 
+// 监听options信息的变化
 watch(
   () => [props.legendData, props.seriesData, props.xAxisData],
   () => {
@@ -130,11 +154,22 @@ watch(
   }
 )
 
+// 监听加载状态
+watch(
+  () => props.loadingState,
+  (val) => {
+    changeLoading(val)
+    if (!val) initOptions()
+  },
+  { deep: true }
+)
+
 onMounted(() => {
   nextTick(() => {
+    // 开始的时候,不要去直接初始化,先展示加载状态,等到数据加载完状态改变,再去设置
     linechart.value = echarts.init(chart.value)
-
-    initOptions()
+    changeLoading(props.loadingState)
+    if (!props.loadingState) initOptions()
 
     /**
      * @description: 只监听window会导致当侧边栏缩放时,dom大小变化但无法resize

+ 3 - 3
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-08-29 16:43:13
+ * @LastEditTime: 2024-08-30 11:35:44
  * @FilePath: \Game-Backstage-Management-System\src\hooks\useRequest.ts
  * @Description:
  *
@@ -16,8 +16,8 @@ import type { AxiosResponse } from 'axios'
 import type { ResponseInfo } from '@/types/res'
 
 export function useRequest() {
-  // const baseIp = 'http://server.ichunhao.cn'  // 线上
-  const baseIp = 'http://192.168.1.139:8000' // 本地
+  const baseIp = 'http://server.ichunhao.cn' // 线上
+  // const baseIp = 'http://192.168.1.139:8000' // 本地
 
   const AllApi = {
     mock: `http://127.0.0.1:8003/mock`,

+ 2 - 1
src/types/dataAnalysis.ts

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-23 14:58:29
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-08-29 16:23:15
+ * @LastEditTime: 2024-08-30 10:36:03
  * @FilePath: \Game-Backstage-Management-System\src\types\dataAnalysis.ts
  * @Description:用于dataAnalysis相关组件的type
  *
@@ -66,6 +66,7 @@ export interface OptionsProps {
   xAxisData: Array<any> // x轴的刻度lable
   legendData: Array<any> // 图例的信息
   seriesData: Array<any> // 数据
+  loadingState: boolean // 加载状态
 }
 
 // 返回的数据中每个字段的分类信息

+ 1 - 1
src/types/table.ts

@@ -24,7 +24,6 @@ export interface TablePaginationSetting {
   currentPage: number // 当前页码
   total: number // 数据总数
   pagesizeList: Array<number> // 页数大小列表
-  loading: boolean // 加载图标
   hasLodingData: number // 已经加载的数据
 }
 
@@ -67,6 +66,7 @@ export interface TableFieldInfo {
 
 // props的参数格式
 export interface PropsParams {
+  dataLoading?: boolean // 加载图表,这个配置是当数据直接由外部控制时触发
   needRowindex?: boolean // 是否需要行号
   needAverage?: boolean // 是否需要均值功能
   needLeftTools?: boolean // 是否需要左侧的工具栏

+ 8 - 3
src/views/Home/Analysis/KeepView.vue

@@ -2,13 +2,13 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-27 17:11:23
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-08-29 17:23:51
+ * @LastEditTime: 2024-08-30 10:45:10
  * @FilePath: \Game-Backstage-Management-System\src\views\Home\Analysis\KeepView.vue
  * @Description: 
  * 
 -->
 <script setup lang="ts">
-import { watch, reactive, onMounted } from 'vue'
+import { watch, reactive, onMounted, ref } from 'vue'
 import Table from '@/components/Table.vue'
 import HeaderCard from '@/components/dataAnalysis/HeaderCard.vue'
 import axiosInstance from '@/utils/axios/axiosInstance'
@@ -30,6 +30,8 @@ const keepViewSelect = reactive({
   pf: 'web'
 })
 
+const loading = ref(true) // 加载状态
+
 // 数据详情表格信息
 const keepDataTableInfo = reactive<{
   paginationConfig: TablePaginationSetting
@@ -41,7 +43,6 @@ const keepDataTableInfo = reactive<{
     currentPage: 1, // 当前页码
     total: 0, // 数据总数
     pagesizeList: [15, 30], // 页数大小列表
-    loading: true, // 加载图标
     hasLodingData: 0 // 已经加载的数据
   },
   requestConfig: {
@@ -154,6 +155,9 @@ const getTableData = () => {
       keepTableData.splice(0, keepTableData.length, ...newList)
       keepDataTableInfo.paginationConfig.total = newList.length
     })
+    .finally(() => {
+      loading.value = false
+    })
 }
 
 /**
@@ -195,6 +199,7 @@ onMounted(() => {})
     </div>
     <div class="tableBox">
       <Table
+        v-loading="loading"
         :need-average="true"
         :pagination-config="keepDataTableInfo.paginationConfig"
         :table-fields-info="keepDataTableInfo.tableFieldsInfo"

+ 0 - 1
src/views/Home/Analysis/UserTrendView.vue

@@ -141,7 +141,6 @@ const detailDataTableInfo = reactive<{
     currentPage: 1, // 当前页码
     total: 0, // 数据总数
     pagesizeList: [15, 30], // 页数大小列表
-    loading: true, // 加载图标
     hasLodingData: 0 // 已经加载的数据
   },
   requestConfig: {

+ 1 - 1
src/views/Home/InfoManage/GameManageView.vue

@@ -43,7 +43,7 @@ const paginationConfig = reactive<TablePaginationSetting>({
   currentPage: 1, // 当前页码
   total: 0, // 数据总数
   pagesizeList: [15, 20], // 页数大小列表
-  loading: true, // 加载图标
+
   hasLodingData: 0 // 已经加载的数据
 })
 

+ 1 - 1
src/views/Home/InfoManage/PlayerManageView.vue

@@ -46,7 +46,7 @@ const paginationConfig = reactive<TablePaginationSetting>({
   currentPage: 1, // 当前页码
   total: 0, // 数据总数
   pagesizeList: [15, 30], // 页数大小列表
-  loading: true, // 加载图标
+
   hasLodingData: 0 // 已经加载的数据
 })