Преглед на файлове

完善表格工具功能(下载没做)

fxs преди 9 месеца
родител
ревизия
1b295d5528
променени са 7 файла, в които са добавени 227 реда и са изтрити 25 реда
  1. 7 0
      components.d.ts
  2. 91 16
      src/components/Table.vue
  3. 27 0
      src/components/toolsBtn/FilterPopover.vue
  4. 22 0
      src/components/toolsBtn/RegreshBtn.vue
  5. 23 0
      src/types/table.ts
  6. 50 8
      src/views/Home/PlayerManageView.vue
  7. 7 1
      tsconfig.app.json

+ 7 - 0
components.d.ts

@@ -10,6 +10,7 @@ declare module 'vue' {
     ElAffix: typeof import('element-plus/es')['ElAffix']
     ElAvatar: typeof import('element-plus/es')['ElAvatar']
     ElButton: typeof import('element-plus/es')['ElButton']
+    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
     ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
     ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
     ElDialog: typeof import('element-plus/es')['ElDialog']
@@ -24,12 +25,18 @@ declare module 'vue' {
     ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
     ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
+    ElPopover: typeof import('element-plus/es')['ElPopover']
     ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
+    ElTag: typeof import('element-plus/es')['ElTag']
+    ElText: typeof import('element-plus/es')['ElText']
+    ElTooltip: typeof import('element-plus/es')['ElTooltip']
+    FilterPopover: typeof import('./src/components/toolsBtn/FilterPopover.vue')['default']
     IconEpHistogram: typeof import('~icons/ep/histogram')['default']
     IconEpPieChart: typeof import('~icons/ep/pie-chart')['default']
+    RegreshBtn: typeof import('./src/components/toolsBtn/RegreshBtn.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
     Table: typeof import('./src/components/Table.vue')['default']

+ 91 - 16
src/components/Table.vue

@@ -1,13 +1,21 @@
 <script setup lang="ts">
 import type { PropsParams, TablePaginationSetting, QueryInfo } from '@/types/table'
-import { FilterType } from '@/types/table'
+import { FilterType, FieldSpecialEffectType, ColorType } from '@/types/table'
 
 import { computed, onMounted, reactive, ref, watch } from 'vue'
 import { useTable } from '@/hooks/useTable'
 
+import FilterPopover from './toolsBtn/FilterPopover.vue'
+import RegreshBtn from './toolsBtn/RegreshBtn.vue'
+
+import type { FormInstance } from 'element-plus'
+
 // 表格工具图标大小
 const toolsIconSize = ref(25)
 
+// 查询表单
+const queryFormRef = ref<FormInstance>()
+
 // 传过来的配置
 const props = defineProps<PropsParams>()
 
@@ -96,6 +104,12 @@ const queryTableData = () => {
   getData()
 }
 
+// 重置查询的条件
+const resetQueryForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  formEl?.resetFields()
+}
+
 // 没有开启分页查询就关闭掉这个监听
 if (!props.openPageQuery) changePageLimit()
 
@@ -107,7 +121,6 @@ defineExpose({
 
 onMounted(() => {
   getData()
-  console.log(selectFieldsList)
 })
 </script>
 
@@ -119,8 +132,13 @@ onMounted(() => {
         <span>查询条件</span>
       </div>
       <div class="filterBody">
-        <!-- <slot name="filterBody"></slot> -->
-        <el-form :inline="true" :model="queryFormData" class="queryForm" :label-position="'left'">
+        <el-form
+          :inline="true"
+          ref="queryFormRef"
+          :model="queryFormData"
+          class="queryForm"
+          :label-position="'left'"
+        >
           <!-- 所有的input查询框 -->
           <el-form-item :label="item.label" v-for="item in inputFieldsList" class="filterItem">
             <el-input
@@ -156,7 +174,7 @@ onMounted(() => {
             <el-button class="queryBtn" color="#165dff" @click="queryTableData">
               <el-icon><Search /></el-icon>查询
             </el-button>
-            <el-button class="refreshBtn" color="#f2f3f5">
+            <el-button class="refreshBtn" color="#f2f3f5" @click="resetQueryForm(queryFormRef)">
               <el-icon><RefreshRight /></el-icon>重置
             </el-button>
           </div>
@@ -175,8 +193,15 @@ onMounted(() => {
         <el-button color="#f0f1f3" size="default" class="rightToolsItem">
           <el-icon><Download /></el-icon>下载
         </el-button>
-        <el-icon :size="toolsIconSize" class="rightToolsItem"><RefreshRight /></el-icon>
-        <el-icon :size="toolsIconSize" class="rightToolsItem"><Setting /></el-icon>
+
+        <RegreshBtn @refresh-table="getData" :icon-size="toolsIconSize"></RegreshBtn>
+        <!-- <el-icon :size="toolsIconSize" class="rightToolsItem"><RefreshRight /></el-icon> -->
+
+        <FilterPopover
+          :table-fields-info="tableFieldsInfo"
+          :icon-size="toolsIconSize"
+        ></FilterPopover>
+        <!-- <el-icon :size="toolsIconSize" class="rightToolsItem"><Setting /></el-icon> -->
       </div>
     </div>
 
@@ -187,15 +212,65 @@ onMounted(() => {
         class="tableBody"
       >
         <el-table-column align="center" label="#" type="index" :index="1" />
-        <el-table-column
-          v-for="item in tableFieldsInfo"
-          :prop="item.name"
-          :label="item.cnName"
-          width="auto"
-          align="center"
-          show-overflow-tooltip
-        >
-        </el-table-column>
+        <template v-for="item in tableFieldsInfo">
+          <el-table-column
+            :prop="item.name"
+            :label="item.cnName"
+            width="auto"
+            align="center"
+            show-overflow-tooltip
+            v-if="item.isShow"
+          >
+            <template v-slot="scope">
+              <!-- tag类 -->
+              <el-tag
+                v-if="item.specialEffect?.type === FieldSpecialEffectType.TAG"
+                :type="scope.row[item.name] ? 'danger' : 'success'"
+              >
+                {{
+                  scope.row[item.name]
+                    ? item.specialEffect.othnerInfo[0]
+                    : item.specialEffect.othnerInfo[1]
+                }}
+              </el-tag>
+
+              <!-- 头像类 -->
+              <el-image
+                v-else-if="item.specialEffect?.type === FieldSpecialEffectType.IMG"
+                :preview-teleported="true"
+                :src="scope.row[item.name]"
+                :preview-src-list="[scope.row[item.name]]"
+                style="width: 35px; height: 35px"
+                :fit="'fill'"
+                :hide-on-click-modal="true"
+              >
+                <template #error>
+                  <!--  -->
+                  <img style="width: 35px; height: 35px" src="../assets/default/defaultHead.png" />
+                </template>
+              </el-image>
+
+              <!-- 文字类 -->
+              <el-text
+                v-else-if="item.specialEffect?.type === FieldSpecialEffectType.TEXT"
+                :type="scope.row[item.name] ? 'danger' : 'success'"
+              >
+                {{ scope.row[item.name] }}
+              </el-text>
+
+              <!-- 翻译类 -->
+              <el-text v-else-if="item.specialEffect?.type === FieldSpecialEffectType.TRANSLATE">
+                {{ item.specialEffect.othnerInfo[scope.row[item.name]] }}
+              </el-text>
+
+              <el-text v-else>
+                <!-- 其他列按默认方式显示 -->
+                {{ scope.row[item.name] }}
+              </el-text>
+            </template>
+          </el-table-column>
+        </template>
+
         <slot name="tableOperation"></slot>
       </el-table>
       <div class="userTablePaginationBox">

+ 27 - 0
src/components/toolsBtn/FilterPopover.vue

@@ -0,0 +1,27 @@
+<script setup lang="ts">
+import type { TableFieldInfo } from '@/types/table'
+
+interface SettingInfo {
+  iconSize: number
+  tableFieldsInfo: Array<TableFieldInfo>
+}
+
+// 传过来的配置
+defineProps<SettingInfo>()
+</script>
+
+<template>
+  <el-tooltip effect="dark" placement="top" content="列设置">
+    <span>
+      <!-- 这个span必须要 -->
+      <el-popover placement="bottom-end" trigger="click">
+        <template #reference>
+          <el-icon :size="iconSize" class="rightToolsItem"><Setting /></el-icon>
+        </template>
+        <el-checkbox v-for="item in tableFieldsInfo" :label="item.cnName" v-model="item.isShow" />
+      </el-popover>
+    </span>
+  </el-tooltip>
+</template>
+
+<style scoped></style>

+ 22 - 0
src/components/toolsBtn/RegreshBtn.vue

@@ -0,0 +1,22 @@
+<script setup lang="ts">
+interface SettingInfo {
+  iconSize: number
+}
+
+const emits = defineEmits(['refreshTable'])
+
+// 传过来的配置
+defineProps<SettingInfo>()
+</script>
+
+<template>
+  <el-tooltip effect="dark" placement="top" content="刷新">
+    <span>
+      <el-icon @click="emits('refreshTable')" :size="iconSize" class="rightToolsItem"
+        ><RefreshRight
+      /></el-icon>
+    </span>
+  </el-tooltip>
+</template>
+
+<style scoped></style>

+ 23 - 0
src/types/table.ts

@@ -1,3 +1,13 @@
+// 颜色类型
+export enum ColorType {
+  DEFAULT = 'default',
+  PRIMARY = 'primary',
+  SUCCESS = 'success',
+  INFO = 'info',
+  WARNING = 'warning',
+  DANGER = 'danger'
+}
+
 export interface GameTableData {
   gameName: string //游戏名称
   gid: string //游戏ID
@@ -34,11 +44,24 @@ export interface QueryInfo {
   default?: any
 }
 
+// 字段特殊效果类型
+export enum FieldSpecialEffectType {
+  IMG = 'img',
+  TAG = 'tag',
+  TEXT = 'text',
+  TRANSLATE = 'translate'
+}
+
 // 表格字段信息格式
 export interface TableFieldInfo {
   name: string
   cnName: string
   isShow: boolean
+  specialEffect?: {
+    type: FieldSpecialEffectType
+    othnerInfo?: any
+    color?: Array<ColorType>
+  }
 }
 
 // props的参数格式

+ 50 - 8
src/views/Home/PlayerManageView.vue

@@ -4,7 +4,9 @@ import {
   type QueryInfo,
   FilterType,
   type SelectInfo,
-  type TableFieldInfo
+  type TableFieldInfo,
+  FieldSpecialEffectType,
+  ColorType
 } from '@/types/table'
 
 import Table from '@/components/Table.vue'
@@ -12,14 +14,14 @@ import CryptoJS from 'crypto-js'
 import axiosInstance from '@/utils/axios/axiosInstance'
 
 import { onMounted, reactive, ref, watch } from 'vue'
-
+import { ElMessageBox } from 'element-plus'
 import type { FormRules, FormInstance } from 'element-plus'
 
 import { useTableStore } from '@/stores/useTable'
 import { useRequest } from '@/hooks/useRequest'
 import { useDialog } from '@/hooks/useDialog'
 
-const { AllApi } = useRequest()
+const { AllApi, analysisResCode } = useRequest()
 const tableStore = useTableStore()
 const { dialogClose, submitDialog, handleEdit, addNeweItem } = useDialog()
 
@@ -111,12 +113,20 @@ const filedsInfo = reactive<Array<TableFieldInfo>>([
   {
     name: 'head',
     cnName: '头像',
-    isShow: true
+    isShow: true,
+    specialEffect: {
+      type: FieldSpecialEffectType.IMG
+    }
   },
   {
     name: 'inBlack',
     cnName: '是否在黑名单',
-    isShow: true
+    isShow: true,
+    specialEffect: {
+      type: FieldSpecialEffectType.TAG,
+      othnerInfo: ['是', '否'],
+      color: [ColorType.DANGER, ColorType.SUCCESS]
+    }
   },
   {
     name: 'nickName',
@@ -136,7 +146,15 @@ const filedsInfo = reactive<Array<TableFieldInfo>>([
   {
     name: 'pf',
     cnName: '平台',
-    isShow: true
+    isShow: true,
+    specialEffect: {
+      type: FieldSpecialEffectType.TRANSLATE,
+      othnerInfo: {
+        wx: '微信',
+        tt: '抖音',
+        web: 'Web'
+      }
+    }
   },
   {
     name: 'userId',
@@ -175,9 +193,32 @@ const optionFormData = reactive<PlayerDialogFormData>({
   userId: ''
 })
 
-// 进入用户页面
+// 封禁/解封用户
 const blockedPlayer = (row: any) => {
-  console.log(row)
+  let url = row.inBlack ? AllApi.deleteUserToBlack : AllApi.addUserToBlack
+  let message = row.inBlack ? '确认解封该用户嘛' : '确认封禁该用户嘛'
+  let playerInfo = {
+    gid: row.gid,
+    openId: row.openId,
+    pf: row.pf
+  }
+
+  ElMessageBox.confirm(message, '警告', {
+    confirmButtonText: '确认',
+    cancelButtonText: '取消',
+    type: 'warning'
+  }).then(() => {
+    axiosInstance.post(url, playerInfo).then((data) => {
+      analysisResCode(data)
+        .then((info) => {
+          console.log(info)
+          playerTableRef.value.getData()
+        })
+        .catch((err) => {
+          console.log(err)
+        })
+    })
+  })
 }
 
 // 游戏配置提交
@@ -193,6 +234,7 @@ const submiteOptionChange = (isEncrypt: boolean = false) => {
   )
 }
 
+// 拿到所有游戏的信息
 const getAllGameInfo = async () => {
   try {
     const response = await axiosInstance.post(AllApi.getGameTable, {

+ 7 - 1
tsconfig.app.json

@@ -1,6 +1,12 @@
 {
   "extends": "@vue/tsconfig/tsconfig.dom.json",
-  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
+  "include": [
+    "src/**/*.ts",
+    "src/**/*.d.ts",
+    "src/**/*.tsx",
+    "src/**/*.vue",
+    "src/components/toolsPopover/FilterPopover.vue"
+  ],
   "exclude": ["src/**/__tests__/*"],
   "compilerOptions": {
     "composite": true,