Pārlūkot izejas kodu

优化表格头像的请求方式;优化代码结构,尽量降低圈复杂度

fxs 7 mēneši atpakaļ
vecāks
revīzija
db586d12ae

+ 90 - 94
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-10-14 11:06:43
+ * @LastEditTime: 2024-10-14 14:36:44
  * @FilePath: \Game-Backstage-Management-System\src\components\Table.vue
  * @Description: 
  * 
@@ -69,7 +69,7 @@ const queryFormData = reactive<{ [key: string]: any }>({})
 const backupQueryFormData = reactive<{ [key: string]: any }>({})
 
 // 分页数据
-const paginationConfig2 = reactive<TablePaginationSetting>({
+const paginationConfig = reactive<TablePaginationSetting>({
   currentPage: 1,
   limit: 0,
   total: 0,
@@ -91,12 +91,12 @@ const resourceInfo: Record<string, string> = {
 const blobUrlInfo = reactive<Record<string, string>>({})
 
 // 一些公用方法
-const { getTableData } = useTable(tableData, paginationConfig2)
+const { getTableData } = useTable(tableData, paginationConfig)
 
 // 没有开启分页查询的时候使用的数据
 const tableDataNoPaging = computed(() => {
-  let curPage = paginationConfig2.currentPage
-  let limit = paginationConfig2.limit
+  let curPage = paginationConfig.currentPage
+  let limit = paginationConfig.limit
   let begin = curPage * limit - limit
   //这里不减一是因为,slice方法裁切是左闭右开数组
   let end = curPage * limit
@@ -122,103 +122,102 @@ const dateFieldsList = computed(() => {
 
 // 计算行号
 const computedRowIndex = (index: number) => {
-  return (paginationConfig2.currentPage - 1) * paginationConfig2.limit + index + 1
+  return (paginationConfig.currentPage - 1) * paginationConfig.limit + index + 1
 }
 
 // 改变页码
 const handleCurrentChange = (val: number) => {
-  paginationConfig2.currentPage = val
+  paginationConfig.currentPage = val
 }
 
 // 改变每页大小
 const handleSizeChange = (val: number) => {
-  paginationConfig2.limit = val
+  paginationConfig.limit = val
 }
 
 /**
- * @description: 获取数据,如果没有直接传入数据,则去请求数据,有则直接用
+ * @description: 加载表格数据
  * @return {*}
  */
-const getData = () => {
-  console.trace()
-  return new Promise(async (resolve, reject) => {
-    try {
-      const loadTableData = async () => {
-        return new Promise((resolve, reject) => {
-          if (props.dataList) {
-            tableData.splice(0, tableData.length, ...props.dataList)
+const loadTableData = async () => {
+  return new Promise((resolve, reject) => {
+    if (props.dataList) {
+      tableData.splice(0, tableData.length, ...props.dataList)
+
+      paginationConfig.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 =
+            (paginationConfig.currentPage - 1) * paginationConfig.limit
+          reqconfig.otherOptions.limit = paginationConfig.limit
+        }
 
-            paginationConfig2.total = props.paginationConfig.total
-            loading.value = false
+        // 查询时要根据是否开启分页查询传入对应参数
+        getTableData(reqconfig.url, reqconfig.otherOptions, props.openPageQuery)
+          .then(() => {
             // emits('loadSuccess', tableData)
+            backupTableData.splice(0, backupTableData.length, ...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(() => {
-                  loading.value = false
-                })
-            } else {
-              loading.value = false
-
-              throw new Error('no match requestConfig')
-            }
-          }
-        })
+          })
+          .catch((err) => {
+            console.log(err)
+
+            reject(err)
+          })
+          .finally(() => {
+            loading.value = false
+          })
+      } else {
+        loading.value = false
+
+        throw new Error('no match requestConfig')
       }
+    }
+  })
+}
+import type { TableFieldInfo } from '@/types/table'
+
+/**
+ * @description: 获取数据,如果没有直接传入数据,则去请求数据,有则直接用
+ * @return {*}
+ */
+const getData = () => {
+  return new Promise(async (resolve, reject) => {
+    try {
       // 等待数据加载完成
       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)
+      if (props.needAverage) {
+        let rowData: any = {}
+        let oldList: Array<any> = JSON.parse(JSON.stringify(tableData))
+        Object.values(props.tableFieldsInfo).map((item: TableFieldInfo, index: number) => {
+          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)
-        })
-        .catch((err) => {
-          console.log(err)
-          reject(err)
         })
+        insertRow(0, rowData)
+      }
+      resolve(true)
     } catch (err) {
       console.log(err)
       reject(err)
@@ -246,6 +245,7 @@ const queryTableData = () => {
     reqconfig.otherOptions = { ...props.requestConfig.otherOptions, ...queryFormData }
     getData()
   } else {
+    console.log('执行')
     let filteredTable = []
     // 过滤出来所有符合formData数据的条件
     filteredTable = backupTableData.filter((item) => {
@@ -344,21 +344,17 @@ const tableCellStyle = (info: any) => {
  * @return {*}
  */
 const changePageLimit = watch(
-  () => [paginationConfig2.limit, paginationConfig2.currentPage],
+  () => [paginationConfig.limit, paginationConfig.currentPage],
   ([newLimit, newCurPage], [oldLimit, oldCruPage]) => {
     if (newLimit != oldLimit) {
       // 需要给分页按钮加上:current-page.sync="current_page" 配置,不然不生效
       // 当改变每页大小时把之前的缓存全部清除,重新开始
-      paginationConfig2.currentPage = 1
-      // resetTableData()
+      paginationConfig.currentPage = 1
     }
 
-    if (newCurPage != oldCruPage) paginationConfig2.currentPage = newCurPage
-
-    // if (newGid != oldGid) reqconfig.otherOptions.gid = newGid
-    // || newGid != oldGid
+    if (newCurPage != oldCruPage) paginationConfig.currentPage = newCurPage
 
-    if (newLimit != oldLimit || !tableData[paginationConfig2.currentPage]) {
+    if (newLimit != oldLimit || !tableData[paginationConfig.currentPage]) {
       getData()
     }
   },
@@ -444,7 +440,7 @@ if (!props.openPageQuery) {
  * @return {*}
  */
 const initpageConfig = () => {
-  Object.assign(paginationConfig2, props.paginationConfig)
+  Object.assign(paginationConfig, props.paginationConfig)
 }
 
 /**
@@ -670,7 +666,7 @@ onMounted(() => {
     <div class="tableBox">
       <!-- 没有分页的时候需要重新计算一下data -->
       <el-table
-        :data="openPageQuery ? tableData[paginationConfig2.currentPage] : tableDataNoPaging"
+        :data="openPageQuery ? tableData[paginationConfig.currentPage] : tableDataNoPaging"
         style="width: 100%"
         class="tableBody"
         :cell-style="tableCellStyle"
@@ -832,12 +828,12 @@ onMounted(() => {
         <el-pagination
           class="userTablePagination"
           background
-          :page-size="paginationConfig2.limit"
-          :page-sizes="paginationConfig2.pagesizeList"
+          :page-size="paginationConfig.limit"
+          :page-sizes="paginationConfig.pagesizeList"
           table-layout="fixed"
           layout="prev, pager, next ,jumper ,sizes,total,"
-          :total="paginationConfig2.total"
-          :current-page.sync="paginationConfig2.currentPage"
+          :total="paginationConfig.total"
+          :current-page.sync="paginationConfig.currentPage"
           @current-change="handleCurrentChange"
           @size-change="handleSizeChange"
         />

+ 10 - 7
src/components/common/Dialog.vue

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-09-04 11:21:05
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-10-12 18:06:12
+ * @LastEditTime: 2024-10-14 16:57:09
  * @FilePath: \Game-Backstage-Management-System\src\components\common\Dialog.vue
  * @Description: 
  * 
@@ -22,7 +22,7 @@ interface DialogProps {
 }
 
 // 临时用的close
-const { dialogClose2 } = useDialog()
+const { dialogClose } = useDialog()
 
 const emits = defineEmits(['formSubmit'])
 
@@ -51,15 +51,18 @@ const dialogConfig = reactive({
 
 // 游戏配置提交
 const submiteGameChange = () => {
-  dialogFormRef.value?.submitFormData().then(() => {
-    // console.log(dialogConfigInfo.reqConfig.otherOptions.formData.gid )
-    dialogConfig.dialogVisible = false
-  })
+  dialogFormRef.value
+    ?.submitFormData()
+    .then(() => {
+      // console.log(dialogConfigInfo.reqConfig.otherOptions.formData.gid )
+      dialogConfig.dialogVisible = false
+    })
+    .catch(() => {})
 }
 
 // 表单关闭
 const closeDialog = () => {
-  dialogClose2(dialogFormRef.value, dialogConfig)
+  dialogClose(dialogFormRef.value, dialogConfig)
 }
 
 // 表单添加

+ 0 - 23
src/components/common/WithIconSelect.vue

@@ -5,10 +5,6 @@ import type { IconDropdownItem } from '@/types/dataAnalysis'
 import { onMounted, ref, reactive, watch } from 'vue'
 import { initLoadResouce } from '@/utils/resource'
 import { useCommonStore } from '@/stores/useCommon'
-// import {
-//   getPfSelectTourShowState,
-//   setPfSelectTourShowState
-// } from '@/utils/localStorage/localStorage'
 
 const { selectInfo, tempMultipleChioce, saveSelectInfo, saveTempMultipleChioce } = useCommonStore()
 
@@ -25,9 +21,6 @@ const props = withDefaults(defineProps<DropdownInfo>(), {
 // 下拉框
 const dromDownMenu = ref()
 
-// 引导层显示状态
-// const tourOpen = ref(false)
-
 /**
  * @description:  初始化选择信息
  * @return {*}
@@ -44,9 +37,6 @@ const isConfimClose = ref<Boolean>(false)
 // emits
 const emits = defineEmits(['changePf'])
 
-// 引导层是否已经展示过
-// const isTourShowed = ref<boolean>(false)
-
 // 下拉框
 const dropDownRef = ref<DropdownInstance>()
 
@@ -104,22 +94,9 @@ const cancleSelect = () => {
  */
 const dropdownVis = (state: boolean) => {
   if (state) {
-    // if (!isTourShowed.value) {
-    //   nextTick(() => {
-    //     tourOpen.value = true
-    //   })
-    // }
-
     // 打开的时候,需要备份一下当前选择
     Object.assign(backupInfo, JSON.parse(JSON.stringify(selectBaseInfo)))
   } else {
-    // 关闭的时候,同时把引导框关闭,并且标记一下
-    // if (!isTourShowed.value) {
-    //   isTourShowed.value = true
-    //   tourOpen.value = false
-    //   setPfSelectTourShowState(true)
-    // }
-
     // 关闭的时候,如果一个都没有选中,那么就需要把备份的信息恢复回去
     // 这里只针对于多选情况,因为单选的逻辑中不存在一个都没有选中的情况,因为无法取消已经选中
     // 而多选的情况下,因为即使可以取消,也不会立即改变selectInfo中的信息,只有点击了确认按钮才会改变,所以这里只需要恢复props的selectinfo就行了

+ 9 - 4
src/components/dataAnalysis/DropDownSelection.vue

@@ -16,13 +16,18 @@ const emits = defineEmits(['changeSelect'])
 
 const selectVal = ref()
 
-onMounted(() => {
-  selectVal.value = props.defaultSelect
-})
-
+/**
+ * @description: 改变选择,通知父组件
+ * @param {*} val
+ * @return {*}
+ */
 const changeSelect = (val: any) => {
   emits('changeSelect', val)
 }
+
+onMounted(() => {
+  selectVal.value = props.defaultSelect
+})
 </script>
 
 <template>

+ 48 - 39
src/components/dataAnalysis/HeaderCard.vue

@@ -55,21 +55,6 @@ const shortcuts = [
 // 选择的日期
 const selectDate = ref<Array<Date>>(shortcuts[0].value())
 
-// 日期变化
-const dateChange = (val: any) => {
-  emits('changeDate', val)
-}
-
-// 控制日期范围
-/**
- * @description: 禁止选取今天之后的日期
- * @param {*} date
- * @return {*}
- */
-const disableDate = (time: Date) => {
-  return time.getTime() > Date.now()
-}
-
 // 面包屑列表
 const breadcrumbList = reactive<
   Array<{
@@ -78,10 +63,36 @@ const breadcrumbList = reactive<
   }>
 >([])
 
+// 下拉框的平台信息
+const pfSelectInfo = reactive<Array<IconDropdownItem>>([
+  {
+    value: 'web',
+    icon: '/img/platformIcon/web.svg',
+    label: '网页',
+    isSelected: false
+  },
+  {
+    value: 'wx',
+    icon: '/img/platformIcon/wx.svg',
+    label: '微信',
+    isSelected: true
+  },
+  {
+    value: 'tt',
+    icon: '/img/platformIcon/tt.svg',
+    label: '抖音',
+    isSelected: false
+  }
+])
+
 // 是否可点击
 const breadcrumbCanClick = computed(() => breadcrumbList.length > 1)
 
-// 返回总览
+/**
+ * @description: 返回总览,同时清除当前下标及之后的面包屑
+ * @param {*} index 当前面包屑的下标
+ * @return {*}
+ */
 const goBack = (index: number) => {
   if (breadcrumbCanClick) {
     router.push(breadcrumbList[index].pathName).then(() => {
@@ -91,6 +102,24 @@ const goBack = (index: number) => {
 }
 
 /**
+ * @description: 日期改变通知父组件
+ * @param {*} val 新日期
+ * @return {*}
+ */
+const dateChange = (val: any) => {
+  emits('changeDate', val)
+}
+
+/**
+ * @description: 禁止选取今天之后的日期
+ * @param {*} date
+ * @return {*}
+ */
+const disableDate = (time: Date) => {
+  return time.getTime() > Date.now()
+}
+
+/**
  * @description: 添加导航栏的信息
  * @param {*} title 标题
  * @param {*} pathName 对应的路由name
@@ -116,28 +145,6 @@ const clearBreadcrumb = () => {
   }
 }
 
-// 下拉框的平台信息
-const pfSelectInfo = reactive<Array<IconDropdownItem>>([
-  {
-    value: 'web',
-    icon: '/img/platformIcon/web.svg',
-    label: '网页',
-    isSelected: false
-  },
-  {
-    value: 'wx',
-    icon: '/img/platformIcon/wx.svg',
-    label: '微信',
-    isSelected: true
-  },
-  {
-    value: 'tt',
-    icon: '/img/platformIcon/tt.svg',
-    label: '抖音',
-    isSelected: false
-  }
-])
-
 /**
  * @description: 监控当前路由,每次路由改变都要去执行clearBreadcrumb,来判断是否需要清除当前面包屑
  * @param {*} watch
@@ -157,7 +164,9 @@ defineExpose({
   addPath,
   clearBreadcrumb
 })
-dateChange(selectDate.value)
+
+dateChange(selectDate.value) // 初始的时候触发一次,通知其他组件更新日期
+
 onMounted(() => {
   breadcrumbList.push({
     title: props.title,

+ 41 - 37
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-10-10 09:04:54
+ * @LastEditTime: 2024-10-14 17:46:27
  * @FilePath: \Game-Backstage-Management-System\src\components\dataAnalysis\StatisticText.vue
  * @Description: 用于展示统计数据,如总览页面上方的总览数据
  * 
@@ -13,54 +13,53 @@ import type { StaticDataInfo, StaticField } from '@/types/dataAnalysis'
 import { decimalToPercentage } from '@/utils/common'
 import { onMounted, reactive, ref, watch } from 'vue'
 import axiosInstance from '@/utils/axios/axiosInstance'
+import { useAnalysis } from '@/hooks/useAnalysis'
+
+const { updateReqConfig } = useAnalysis()
+
 const props = defineProps<StaticDataInfo>()
-const dataList = reactive<Array<StaticField>>([])
+let dataList = reactive<Array<StaticField>>([])
 const dataState = ref(false) // 数据是否加载成功
+
+/**
+ * @description: 创建dataList数组
+ * @param {*} fieldsInfo 字段信息
+ * @param {*} getValue 获取值的函数
+ * @return {*}
+ */
+const createDataList = (fieldsInfo: Array<StaticField>, getValue: (item: StaticField) => any) => {
+  return fieldsInfo.map((item) => ({
+    name: item.name,
+    cnName: item.cnName,
+    value: getValue(item)
+  }))
+}
+
 /**
  * @description: 用于获取数据
- * @tip  这里暂时只请求当日的数据,没有比较
  * @return {*}
  */
-const getData = () => {
+const getData = async () => {
   try {
+    let newDataList = []
     if (props.requestConfig) {
-      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
-        })
+      let info = await axiosInstance.post(props.requestConfig.url, props.requestConfig.otherOptions)
+
+      let data = info.data
+      newDataList = createDataList(props.fieldsInfo, (item) => data[item.name])
     } else {
       let hasNull = props.fieldsInfo.every((item) => item.value !== '')
 
-      if (hasNull) {
-        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
-      }
+      if (!hasNull) throw new Error('全为空')
+
+      newDataList = createDataList(props.fieldsInfo, (item) => item.value)
     }
+    dataList.splice(0, dataList.length, ...newDataList)
+
+    dataState.value = true // 标记成功
   } catch (err) {
     console.log(err)
+    dataState.value = false
     throw new Error('数据获取失败')
   }
 }
@@ -76,15 +75,20 @@ watch(
     props.fieldsInfo
   ],
   () => {
+    // 如果有请求配置,要去更新一下
+    if (props.requestConfig)
+      updateReqConfig(props.requestConfig, { gid: props.requestConfig?.otherOptions.gid })
+
     getData()
+  },
+  {
+    deep: true
   }
 )
 
 onMounted(() => {
   getData()
 })
-
-defineExpose({})
 </script>
 
 <template>

+ 7 - 8
src/components/dataAnalysis/TemporalTrend.vue

@@ -90,13 +90,13 @@ let chartInfo = reactive<OptionsProps>({
 
 /**
  * @description: 改变图表形式,当是表格的时候,去执行表格的获取数据方法,拿到最新的数据
- * @param {*} name 图表的展现形式,可以使table或者trend
+ * @param {*} type 图表的展现形式,可以使table或者trend,1为图,2为表
  * @return {*}
  */
-const changeSelectShape = (name: number) => {
-  if (selectShape.value === name) return
-  selectShape.value = name
-  if (name === 2) {
+const changeSelectShape = (type: number) => {
+  if (selectShape.value === type) return
+  selectShape.value = type
+  if (type === 2) {
     nextTick(() => {
       chartTable.value?.getData()
     })
@@ -289,7 +289,6 @@ const getData = async (type: number) => {
       if (activeTab.value) setCacheData() // 如果有tab的话再去缓存
     })
     .catch((err) => {
-      loadDataState.state = false
       console.log(err)
     })
     .finally(() => {
@@ -302,13 +301,13 @@ const getData = async (type: number) => {
  * @param {*} tabName 对应的tabName,去tabinfo中找到对应的url
  * @return {*}
  */
-const tabChange = (tabName: string) => {
+const tabChange = async (tabName: string) => {
   if (props.tabInfo) {
     if (cacheData[tabName]) {
       setCacheData(true)
     } else {
       let type = props.tabInfo.find((item) => item.name === tabName)?.type
-      if (type) getData(type)
+      if (type) await getData(type)
       else throw new Error('No match type')
     }
   }

+ 33 - 22
src/components/form/MyInput.vue

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-22 17:31:50
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-25 09:03:33
+ * @LastEditTime: 2024-10-14 17:04:09
  * @FilePath: \Game-Backstage-Management-System\src\components\form\MyInput.vue
  * @Description: 
  * 
@@ -35,25 +35,10 @@ let activeClass = ref(false) // 是否被选中
 let showTip = ref(false) // 是否展示提示框
 let errorMsg = ref('') // 提示的内容
 
-onMounted(() => {
-  // 点击输入框则聚焦,并给边框
-  document.addEventListener('click', (e) => {
-    // 如果点击的地方不在 div 内部,则移除 active-class
-    if (inputDivRef.value && !inputDivRef.value.contains(e.target)) {
-      activeClass.value = false
-    } else {
-      activeClass.value = true
-      // inputRef.value.focus()
-      // 这里有时会出现inputRef.value为空的情况
-      if (inputRef.value) {
-        inputRef.value.focus()
-      }
-    }
-  })
-  if (inputType.value === 'password') isPassword.value = true
-})
-
-// 改变密码框的可见性及可见按钮的切换
+/**
+ * @description: 改变密码框可见性
+ * @return {*}
+ */
 const changeVisible = () => {
   passwordVisiable.value = !passwordVisiable.value
   if (passwordVisiable.value) {
@@ -63,7 +48,11 @@ const changeVisible = () => {
   }
 }
 
-// 验证input框是否符合规则
+/**
+ * @description: 验证input框是否符合规则
+ * @param {*} let
+ * @return {*}
+ */
 const verifyIpt = () => {
   let rulesInfo = props.pinputRules
   if (rulesInfo) {
@@ -78,10 +67,32 @@ const verifyIpt = () => {
   }
 }
 
-// 当input框触发改变的时候,同步的更新v-model绑定的数据
+/**
+ * @description: 同步input框数据
+ * @param {*} val
+ * @return {*}
+ */
 const updateValue = (val: any) => {
   emits('update:modelValue', val.target.value)
 }
+
+onMounted(() => {
+  // 点击输入框则聚焦,并给边框
+  document.addEventListener('click', (e) => {
+    // 如果点击的地方不在 div 内部,则移除 active-class
+    if (inputDivRef.value && !inputDivRef.value.contains(e.target)) {
+      activeClass.value = false
+    } else {
+      activeClass.value = true
+      // inputRef.value.focus()
+      // 这里有时会出现inputRef.value为空的情况
+      if (inputRef.value) {
+        inputRef.value.focus()
+      }
+    }
+  })
+  if (inputType.value === 'password') isPassword.value = true
+})
 </script>
 
 <template>

+ 2 - 3
src/hooks/useAnalysis.ts

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 17:15:49
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-10-14 10:03:35
+ * @LastEditTime: 2024-10-14 14:39:48
  * @FilePath: \Game-Backstage-Management-System\src\hooks\useAnalysis.ts
  * @Description:
  *
@@ -11,11 +11,10 @@ import type { ReqConfig } from '@/types/dataAnalysis'
 
 export function useAnalysis() {
   /**
-   * @description: 更新统计组件的请求参数
+   * @description: 更新请求参数
    * @return {*}
    */
   const updateReqConfig = (config: ReqConfig, newVal: any) => {
-    console.log(config, newVal)
     Object.keys(newVal).map((k) => {
       config.otherOptions[k] = newVal[k]
     })

+ 17 - 81
src/hooks/useDialog.ts

@@ -2,33 +2,25 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-21 17:23:32
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-04 15:46:03
+ * @LastEditTime: 2024-10-14 17:00:57
  * @FilePath: \Game-Backstage-Management-System\src\hooks\useDialog.ts
  * @Description:
  *
  */
 import Form from '@/components/form/Form.vue'
 import type { DialogSetting } from '@/types/table'
-import type { FormInstance } from 'element-plus'
-import { useRequest } from './useRequest'
-import axiosInstance from '@/utils/axios/axiosInstance'
-import { ElMessage, ElMessageBox } from 'element-plus'
 import { nextTick } from 'vue'
 import 'element-plus/theme-chalk/el-message.css'
 import 'element-plus/theme-chalk/el-message-box.css'
 
-const { analysisResCode } = useRequest()
-
 export function useDialog() {
-  // 对话框关闭
-  const dialogClose = (formEl: FormInstance | undefined, dialogConfig: DialogSetting) => {
-    if (!formEl) return
-
-    dialogConfig.dialogVisible = false
-    formEl.resetFields()
-  }
-
-  const dialogClose2 = (
+  /**
+   * @description: 对话框关闭
+   * @param {InstanceType} formEl 表单对象
+   * @param {DialogSetting} dialogConfig 对话框配置
+   * @return {*}
+   */
+  const dialogClose = (
     formEl: InstanceType<typeof Form> | undefined,
     dialogConfig: DialogSetting
   ) => {
@@ -38,60 +30,13 @@ export function useDialog() {
     formEl.resetForm()
   }
 
-  // 对话框提交
-  const submitDialog = (
-    formEl: FormInstance | undefined,
-    dialogConfig: DialogSetting,
-    url: string,
-    formData: any
-  ) => {
-    return new Promise((reslove, reject) => {
-      ElMessageBox.confirm('确认提交吗?', '警告', {
-        confirmButtonText: '确认',
-        cancelButtonText: '取消',
-        type: 'warning'
-      })
-        .then(() => {
-          try {
-            if (!formEl) {
-              reject(new Error('no formEl'))
-              return
-            }
-            formEl.validate(async (valid, field) => {
-              if (valid) {
-                let result = await axiosInstance.post(url, formData)
-                let info = JSON.parse(JSON.stringify(result))
-
-                analysisResCode(info)
-                  .then(() => {
-                    dialogConfig.dialogVisible = false
-                    reslove(true)
-                  })
-                  .catch((err) => {
-                    reject(err)
-                    console.log(err)
-                  })
-              } else {
-                console.log(field)
-                console.log('表单校验不通过')
-              }
-            })
-          } catch (err) {
-            console.log(err)
-            ElMessage({
-              type: 'error',
-              message: '未知错误'
-            })
-            throw new Error('other err')
-          }
-        })
-        .catch(() => {
-          reject(false)
-        })
-    })
-  }
-
-  // 修改按钮
+  /**
+   * @description: 点击修改按钮,填充数据
+   * @param {any} row 行数据
+   * @param {any} formData 表单数据
+   * @param {DialogSetting} dialogConfig 对话框配置
+   * @return {*}
+   */
   const handleEdit = (row: any, formData: any, dialogConfig: DialogSetting) => {
     dialogConfig.type = 1
     dialogConfig.dialogVisible = true
@@ -107,20 +52,11 @@ export function useDialog() {
         }
       }
     })
-    console.log(dialogConfig)
-    // throw new Error('test')
-  }
-
-  const addNeweItem = (dialogConfig: DialogSetting) => {
-    dialogConfig.type = 0
-    dialogConfig.dialogVisible = true
   }
 
   return {
     dialogClose,
-    dialogClose2,
-    submitDialog,
-    handleEdit,
-    addNeweItem
+
+    handleEdit
   }
 }

+ 21 - 26
src/hooks/useForm.ts

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-09-04 15:07:56
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-09 12:10:43
+ * @LastEditTime: 2024-10-14 16:50:35
  * @FilePath: \Game-Backstage-Management-System\src\hooks\useForm.ts
  * @Description:
  *
@@ -15,6 +15,14 @@ import { useRequest } from './useRequest'
 
 const { analysisResCode } = useRequest()
 export function useForm() {
+  const vaildForm = async (formEl: FormInstance | undefined): Promise<boolean> => {
+    if (!formEl) {
+      console.log('找不到表单实例')
+      return false
+    }
+    return await formEl.validate()
+  }
+
   // 对话框提交
   const submitForm = (formEl: FormInstance | undefined, url: string, formData: any) => {
     return new Promise((reslove, reject) => {
@@ -24,40 +32,27 @@ export function useForm() {
         type: 'warning',
         appendTo: 'body'
       })
-        .then(() => {
+        .then(async () => {
           try {
-            if (!formEl) {
-              reject(new Error('no formEl'))
-              return
-            }
-            formEl.validate(async (valid, field) => {
-              if (valid) {
-                let result = await axiosInstance.post(url, formData)
-                let info = JSON.parse(JSON.stringify(result))
+            let vaild = await vaildForm(formEl)
+            if (!vaild) throw new Error('表单校验不通过')
 
-                analysisResCode(info)
-                  .then(() => {
-                    reslove(true)
-                  })
-                  .catch((err) => {
-                    reject(err)
-                    console.log(err)
-                  })
-              } else {
-                console.log(field)
-                console.log('表单校验不通过')
-              }
-            })
+            let result = await axiosInstance.post(url, formData)
+            let info = JSON.parse(JSON.stringify(result))
+
+            await analysisResCode(info)
+            reslove(true)
           } catch (err) {
             console.log(err)
             ElMessage({
               type: 'error',
-              message: '未知错误'
+              message: '表单验证不通过'
             })
-            throw new Error('other err')
+            reject(false)
           }
         })
         .catch(() => {
+          console.log('取消选择')
           reject(false)
         })
     })
@@ -78,5 +73,5 @@ export function useForm() {
     })
   }
 
-  return { submitForm, editForm }
+  return { submitForm, editForm, vaildForm }
 }

+ 47 - 50
src/hooks/useTable.ts

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 17:15:49
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-10-08 18:04:25
+ * @LastEditTime: 2024-10-14 17:26:28
  * @FilePath: \Game-Backstage-Management-System\src\hooks\useTable.ts
  * @Description:
  *
@@ -10,14 +10,46 @@
 import type { ResponseInfo } from '@/types/res'
 import axiosInstance from '../utils/axios/axiosInstance'
 
-import { loadResource } from '@/utils/resource'
+import { initLoadResouce } from '@/utils/resource'
 
-import type { TablePaginationSetting, DialogSetting } from '@/types/table'
-import { type FormInstance } from 'element-plus'
+import type { TablePaginationSetting } from '@/types/table'
+import { reactive } from 'vue'
+
+// 资源的加载路径
+const resourceInfo: Record<string, string> = {
+  defaultHead: `/img/default/defaultHead.png`
+}
+
+// 使用blob的资源路径信息
+const blobUrlInfo = reactive<Record<string, string>>({})
+
+// 初始化资源
+initLoadResouce(resourceInfo).then((data) => {
+  Object.assign(blobUrlInfo, data)
+})
 
 export function useTable(tableData: Array<any>, paginationSetting: TablePaginationSetting) {
-  // const { analysisResCode } = useRequest()
+  /**
+   * @description: 设置默认头像
+   * @param {Array} data 请求回来的数据表格
+   * @return {Array<any>} 返回处理后的数据
+   */
+  const setDefaultHead = (data: Array<any>): Array<any> => {
+    if (data) {
+      data.map(async (item: any) => {
+        if (!item.head) item.head = blobUrlInfo.defaultHead
+      })
+    }
+    return data
+  }
 
+  /**
+   * @description: 获取表格数据
+   * @param {string} url 请求地址
+   * @param {any} option 请求参数
+   * @param {boolean} isPagination 是否开启分页
+   * @return {*}
+   */
   const getTableData = (url: string, option: any, isPagination: boolean = false) => {
     return new Promise(async (reslove, reject) => {
       try {
@@ -25,45 +57,19 @@ export function useTable(tableData: Array<any>, paginationSetting: TablePaginati
           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 (data && data.length > 0) {
+          // 没有数据则直接置为空
+          if (!data) {
+            tableData.length = 0
+            paginationSetting.total = 0
+          } else {
+            paginationSetting.total = info.count ?? data.length
+            data = setDefaultHead(data)
+            // 如果开启了分页,那么默认这个tabledata是一个二维数组,每个位置对应当页的一个数据数组
+            // 没开启则是一个一维数组,直接赋值
             if (isPagination) tableData[paginationSetting.currentPage] = data
             else tableData.splice(0, tableData.length, ...data)
-          } else {
-            tableData.splice(0, tableData.length)
           }
 
-          // 如果有的接口没有返回count属性,就需要自己写
-          // 这个length,如果数组长为0,则需要自己赋值,不然会报错
-          if (info.count) paginationSetting.total = info.count
-          else if (info.data) {
-            paginationSetting.total = info.data.length
-          } else {
-            paginationSetting.total = 0
-          }
           reslove(true)
         })
       } catch (err) {
@@ -74,16 +80,7 @@ export function useTable(tableData: Array<any>, paginationSetting: TablePaginati
     })
   }
 
-  // 对话框关闭
-  const dialogClose = (formEl: FormInstance | undefined, dialogParam: DialogSetting) => {
-    if (!formEl) return
-
-    dialogParam.dialogVisible = false
-    formEl.resetFields()
-  }
-
   return {
-    getTableData,
-    dialogClose
+    getTableData
   }
 }

+ 16 - 0
src/main.ts

@@ -14,4 +14,20 @@ app.use(createPinia())
 
 app.use(router)
 
+/**
+ * @description:  全局异常捕获,此处只用于调试
+ * @param {*} err 错误对象
+ * @param {*} instance 触发该错误的组件实例
+ * @param {*} info 错误来源类型信息
+ * @return {*}
+ */
+app.config.errorHandler = (err, instance, info) => {
+  console.log('-----------------')
+  console.log('未被捕获的异常')
+  console.log(err)
+  console.log(instance)
+  console.log(info)
+  console.log('-----------------')
+}
+
 app.mount('#app')

+ 14 - 22
src/utils/resource/index.ts

@@ -2,11 +2,12 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-31 14:51:20
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-18 09:24:17
+ * @LastEditTime: 2024-10-14 16:11:04
  * @FilePath: \Game-Backstage-Management-System\src\utils\resource\index.ts
  * @Description:
  *
  */
+
 // 缓存对象
 const resourceCache: Record<string, string> = {}
 
@@ -17,33 +18,24 @@ const resourceCache: Record<string, string> = {}
  * @param url - 资源的加载路径
  * @returns 返回blob对象的url
  */
-export const loadResource = (url: string): Promise<string> => {
-  // console.log(resourceCache, url)
-
+export const loadResource = async (url: string): Promise<string> => {
   // 检查是否已经存储了这个资源,已经缓存了就直接返回
   if (resourceCache[url]) {
-    // alert(JSON.stringify(resourceCache[url]))
     return Promise.resolve(resourceCache[url])
   }
 
   // 如果没有缓存则去请求这个资源,并将他转为bolb对象,并且缓存blob对象的ulr
-  return fetch(url)
-    .then((response) => {
-      if (!response.ok) {
-        throw new Error(`资源加载失败: ${url}`)
-      }
-
-      return response.blob()
-    })
-    .then((blob) => {
-      const objectURL = URL.createObjectURL(blob)
-      resourceCache[url] = objectURL // Cache the resource
-      return objectURL
-    })
-    .catch((error) => {
-      console.error(`资源加载出错 ${url}:`, error)
-      throw error
-    })
+  try {
+    const resourceBlob = await fetch(url)
+    if (!resourceBlob.ok) throw new Error(`资源加载失败: ${url}`)
+    const blob = await resourceBlob.blob()
+    const objectURL = URL.createObjectURL(blob)
+    resourceCache[url] = objectURL
+    return objectURL
+  } catch (err) {
+    console.log(err)
+    throw new Error('资源加载失败')
+  }
 }
 
 /**

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

@@ -3,32 +3,46 @@ import { useRequest } from '@/hooks/useRequest'
 import axiosInstance from '../axios/axiosInstance'
 const { AllApi } = useRequest()
 
-// 拿到所有游戏的信息
+/**
+ * @description: 格式化游戏信息
+ * @param {Array} data 获取到的表格数据
+ * @param {number} code 状态码
+ * @return {*}
+ */
+const formatGameInfo = (data: Array<any>, code: number): Array<any> => {
+  const returnData: Array<any> = []
+
+  if (code === 0 && Array.isArray(data)) {
+    let gameInfoList = data.map((item) => {
+      return { gid: item.gid, gameName: item.gameName }
+    })
+    returnData.splice(0, returnData.length, ...gameInfoList)
+  } else {
+    console.log('获取游戏列表失败')
+  }
+  return returnData
+}
+
+/**
+ * @description: 获取所有游戏信息
+ * @return {*}
+ */
 export const getAllGameInfo = async () => {
   try {
     const tableStore = useTableStore() // 这一句不要直接写在函数外面,会导致在pinia挂载之前被调用
 
+    // 如果已经有了,那么直接用缓存
     if (tableStore.allGameInfo.length) return tableStore.allGameInfo
-    else {
-      const response = await axiosInstance.post(AllApi.getGameTable, {
-        appSecret: '6YJSuc50uJ18zj45'
-      })
-      const result = JSON.parse(JSON.stringify(response))
-      const data = result.data // 拿到返回的数据
 
-      if (result.code === 0) {
-        if (Array.isArray(data)) {
-          let gameInfoList = data.map((item) => {
-            return { gid: item.gid, gameName: item.gameName }
-          })
-          tableStore.setGameInfo(gameInfoList)
-          return gameInfoList
-        }
-      } else {
-        console.log('获取游戏列表失败')
-        return []
-      }
-    }
+    const response = await axiosInstance.post(AllApi.getGameTable, {
+      appSecret: '6YJSuc50uJ18zj45'
+    })
+    const result = JSON.parse(JSON.stringify(response))
+    const data = result.data
+    const returnData: Array<any> = formatGameInfo(data, result.code)
+    tableStore.setGameInfo(returnData) // 格式化后的数据放到tablestore中
+
+    return returnData
   } catch (err) {
     console.log(err)
     throw new Error('获取游戏列表失败')

+ 8 - 3
src/views/AppManage/EventDetailsView.vue

@@ -368,9 +368,14 @@ const cancelEdit = () => {
  * @return {*}
  */
 const saveEdit = () => {
-  eventFormRef.value.submitFormData().then(() => {
-    changeEditState(false)
-  })
+  eventFormRef.value
+    .submitFormData()
+    .then(() => {
+      changeEditState(false)
+    })
+    .catch((err: any) => {
+      console.log(err)
+    })
 }
 
 /**

+ 1 - 1
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-10-12 17:58:07
+ * @LastEditTime: 2024-10-14 18:35:26
  * @FilePath: \Game-Backstage-Management-System\src\views\AppManage\EventManageView.vue
  * @Description: 
  * 

+ 2 - 5
src/views/Home/Analysis/KeepView.vue

@@ -2,7 +2,7 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-27 17:11:23
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-09-28 12:02:07
+ * @LastEditTime: 2024-10-14 15:44:22
  * @FilePath: \Game-Backstage-Management-System\src\views\Home\Analysis\KeepView.vue
  * @Description: 
  * 
@@ -159,10 +159,7 @@ const getTableData = () => {
         .then(() => {
           let data = info.data
           let newList: Array<any> = []
-          for (const [key, val] of Object.entries(data)) {
-            // 为了编译通过,不做任何事
-            if (key) {
-            }
+          for (const [_key, val] of Object.entries(data)) {
             let nVal = val as Object
             newList.push({
               ...nVal

+ 13 - 24
src/views/Home/InfoManage/PlayerManageView.vue

@@ -14,7 +14,7 @@ import Table from '@/components/Table.vue'
 
 import axiosInstance from '@/utils/axios/axiosInstance'
 
-import { onMounted, reactive, ref } from 'vue'
+import { reactive, ref } from 'vue'
 import { ElMessageBox } from 'element-plus'
 
 import type { FormRules } from 'element-plus'
@@ -22,15 +22,13 @@ import type { FormField } from '@/types/form'
 import type { DialogConfig } from '@/types/dialog'
 import { FormFieldType } from '@/types/form'
 
-import { useTableStore } from '@/stores/useTable'
 import { useRequest } from '@/hooks/useRequest'
 import { useCommonStore } from '@/stores/useCommon'
-// import { useAnalysis } from '@/hooks/useAnalysis'
-// const { updateReqConfig } = useAnalysis()
+import { useAnalysis } from '@/hooks/useAnalysis'
+const { updateReqConfig } = useAnalysis()
 
 const { AllApi, analysisResCode } = useRequest()
 
-const tableStore = useTableStore()
 const { selectInfo } = useCommonStore()
 
 // 是否是单选pf
@@ -81,7 +79,7 @@ const allPf: Array<SelectInfo> = [
 ]
 
 // 所有游戏信息
-const allGameInfo = reactive<Array<SelectInfo>>([])
+// const allGameInfo = reactive<Array<SelectInfo>>([])
 
 // 查询字段设置
 const queryInfo = reactive<Array<QueryInfo>>([
@@ -248,6 +246,7 @@ const blockedPlayer = (row: any) => {
     })
     .catch(() => {
       // 在点击取消时他会抛出错误,这里需要去捕获一下,不然会在控制台出现
+      console.log('取消选择')
     })
 }
 
@@ -260,27 +259,16 @@ const encrypt = () => {
 }
 
 // 表格的查询应该和全局的平台选择独立开来
-// const updateSelect = (gid: any, pf: any) => {
-//   pf = isSinglePf ? pf[0] : pf
-//   updateReqConfig(requestConfig, { pf, gid })
-// }
-
-// const backupSelect = reactive([])
+const updateSelect = (gid: any) => {
+  updateReqConfig(requestConfig, { gid })
+}
 
-// import { usePage } from '@/hooks/usePage'
-// const { watchPageChange } = usePage()
+const backupSelect = reactive([])
 
-// watchPageChange(() => [selectInfo.gid, selectInfo.pf], backupSelect, updateSelect)
+import { usePage } from '@/hooks/usePage'
+const { watchPageChange } = usePage()
 
-onMounted(() => {
-  tableStore.allGameInfo.map((item) => {
-    allGameInfo.push({
-      name: item.gameName,
-      value: item.gid,
-      cnName: item.gameName
-    })
-  })
-})
+watchPageChange(() => [selectInfo.gid], backupSelect, updateSelect)
 </script>
 <template>
   <div class="gameMangeBox">
@@ -296,6 +284,7 @@ onMounted(() => {
       :query-info="queryInfo"
       :request-config="requestConfig"
       :pagination-config="paginationConfig"
+      :open-remoteinquiry="true"
     >
       <template #tableOperation>
         <el-table-column label="操作" align="center">

+ 2 - 1
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-10-11 09:06:56
+ * @LastEditTime: 2024-10-14 15:57:06
  * @FilePath: \Game-Backstage-Management-System\src\views\Index.vue
  * @Description: 
  * 
@@ -230,6 +230,7 @@ onMounted(() => {
   initLoadResouce(resourceInfo).then((data) => {
     Object.assign(blobUrlInfo, data)
   })
+  throw new Error('aaa')
 })
 </script>
 

+ 37 - 38
src/views/Login/LoginView.vue

@@ -25,44 +25,6 @@ const loginInfo = reactive<LoginInfoType>({
 // 判断目前是否在登陆
 const isLogining = ref(false)
 
-/**
- * @description: 用户登录
- * @return {*}
- */
-const userLogin = async () => {
-  if (isLogining.value) return
-  isLogining.value = true
-  let vaild = Object.keys(loginInfo).every((key) => {
-    return formFieldsRules[key].rules.every((item) => item.validator())
-  })
-  if (vaild) {
-    await axiosInstance
-      .post(AllApi.userLogin, loginInfo)
-      .then((data) => {
-        let result = JSON.parse(JSON.stringify(data))
-        analysisResCode(result, 'login')
-          .then(() => {
-            setToken(result.token)
-            setRefreshToken(result.refreshToken)
-            setLoginState(true)
-            axiosInstance.defaults.headers['Authorization'] = result.token // 需要在这里设置,不然又会触发拦截器
-            router.push('/')
-          })
-          .catch((err) => {
-            console.log(err)
-          })
-          .finally(() => {
-            isLogining.value = false
-          })
-      })
-      .catch((err) => {
-        console.log(err)
-      })
-  } else {
-    console.log('不通过')
-  }
-}
-
 const formFieldsRules = reactive<{
   [key: string]: RuleInfo
 }>({
@@ -112,6 +74,43 @@ const resourceInfo: Record<string, string> = {
 // 使用blob的资源路径数组
 const blobUrlInfo = reactive<Record<string, string>>({})
 
+/**
+ * @description: 验证登录信息是否符合表单规则
+ * @param {*} loginInfo 登录信息
+ * @return {*}
+ */
+const validLoginInfo = (loginInfo: LoginInfoType): boolean => {
+  return Object.keys(loginInfo).every((key) =>
+    formFieldsRules[key].rules.every((item) => item.validator())
+  )
+}
+
+/**
+ * @description: 用户登录
+ * @return {*}
+ */
+const userLogin = async () => {
+  if (isLogining.value) return
+  isLogining.value = true
+  let vaild = validLoginInfo(loginInfo)
+  if (vaild) {
+    try {
+      let data = await axiosInstance.post(AllApi.userLogin, loginInfo)
+      let result = JSON.parse(JSON.stringify(data))
+      await analysisResCode(result, 'login')
+      setToken(result.token)
+      setRefreshToken(result.refreshToken)
+      setLoginState(true)
+      axiosInstance.defaults.headers['Authorization'] = result.token // 需要在这里设置,不然又会触发拦截器
+      router.push('/')
+    } catch (err) {
+      console.log(err)
+    } finally {
+      isLogining.value = false
+    }
+  }
+}
+
 onMounted(() => {
   // 去加载所有需要的资源
   initLoadResouce(resourceInfo).then((data) => {