Bladeren bron

重构表格字段展示方式,新增TableFieldText组件来处理文字显示方式;修复表单查询的BUG;

fxs 6 maanden geleden
bovenliggende
commit
a58f5233cf

+ 2 - 0
components.d.ts

@@ -24,6 +24,7 @@ declare module 'vue' {
     ElIcon: typeof import('element-plus/es')['ElIcon']
     ElImage: typeof import('element-plus/es')['ElImage']
     ElInput: typeof import('element-plus/es')['ElInput']
+    ElLink: typeof import('element-plus/es')['ElLink']
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElOption: typeof import('element-plus/es')['ElOption']
@@ -58,6 +59,7 @@ declare module 'vue' {
     RouterView: typeof import('vue-router')['RouterView']
     StatisticText: typeof import('./src/components/dataAnalysis/StatisticText.vue')['default']
     Table: typeof import('./src/components/Table.vue')['default']
+    TableFieldText: typeof import('./src/components/table/TableFieldText.vue')['default']
     TemporalTrend: typeof import('./src/components/dataAnalysis/TemporalTrend.vue')['default']
     TimeLineChart: typeof import('./src/components/echarts/TimeLineChart.vue')['default']
     WithIconSelect: typeof import('./src/components/common/WithIconSelect.vue')['default']

+ 49 - 134
src/components/Table.vue

@@ -2,21 +2,20 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 18:16:18
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-11-06 17:55:04
- * @FilePath: \Quantity-Creation-Management-Systemc:\Users\NINGMEI\Desktop\Game-Backstage-Management-System\src\components\Table.vue
+ * @LastEditTime: 2024-11-14
+ * @FilePath: \Game-Backstage-Management-System\src\components\Table.vue
  * @Description: 
  * 
 -->
 <script setup lang="ts">
-import type { PropsParams, TablePaginationSetting } from '@/types/table'
+import type { PropsParams, TableFieldInfo, TablePaginationSetting } from '@/types/table'
 import type { ReqConfig } from '@/types/dataAnalysis'
-import type { TableFieldInfo } from '@/types/table'
 import type { FormInstance } from 'element-plus'
+import { FilterType } from '@/types/table'
+import { FieldSpecialEffectType } from '@/types/tableText'
 
-import { FilterType, FieldSpecialEffectType } from '@/types/table'
 import { initLoadResouce } from '@/utils/resource'
-import { fuzzySearch } from '@/utils/common'
-import { throttleFunc } from '@/utils/common'
+import { fuzzySearch, throttleFunc } from '@/utils/common'
 import { computed, onMounted, reactive, ref, toRaw, watch } from 'vue'
 import { useTable } from '@/hooks/useTable'
 import { useRequest } from '@/hooks/useRequest'
@@ -24,6 +23,7 @@ import { useRequest } from '@/hooks/useRequest'
 import FilterPopover from './toolsBtn/FilterPopover.vue'
 import RegreshBtn from './toolsBtn/RegreshBtn.vue'
 import axiosInstance from '@/utils/axios/axiosInstance'
+import TableFieldText from './table/TableFieldText.vue'
 
 const { analysisResCode } = useRequest()
 
@@ -127,21 +127,26 @@ const computedRowIndex = (index: number) => {
   return (paginationConfig.currentPage - 1) * paginationConfig.limit + index + 1
 }
 
-// 改变页码
+/**
+ * @description: 改变页码
+ * @param val
+ */
 const handleCurrentChange = (val: number) => {
   paginationConfig.currentPage = val
 }
 
-// 改变每页大小
+/**
+ * @description 改变每页大小
+ * @param val
+ */
 const handleSizeChange = (val: number) => {
   paginationConfig.limit = val
 }
 
 /**
- * @description: 加载表格数据
- * @return {*}
+ * @description 加载表格数据
  */
-const loadTableData = async () => {
+const loadTableData = async (): Promise<boolean> => {
   return new Promise(async (resolve, reject) => {
     loading.value = true
     if (props.dataList) {
@@ -181,7 +186,7 @@ const loadTableData = async () => {
 
 /**
  * @description: 获取数据,如果没有直接传入数据,则去请求数据,有则直接用
- * @return {*}
+ * @return Promise
  */
 const getData = () => {
   return new Promise(async (resolve, reject) => {
@@ -231,14 +236,13 @@ const resetTableData = () => {
 
 /**
  * @description: 按条件查询,如果开启了分页查询,那么会直接重新查询数据,否则,会根据现有数据进行查询
- * @return {*}
  */
 const queryTableData = () => {
   if (props.openRemoteinquiry && props.requestConfig) {
     reqconfig.otherOptions = { ...props.requestConfig.otherOptions, ...queryFormData }
     getData()
   } else {
-    let filteredTable = []
+    let filteredTable: any[]
     // 过滤出来所有符合formData数据的条件
     filteredTable = backupTableData.filter((item) => {
       let state = true
@@ -261,22 +265,20 @@ const throttleQueryTableData = throttleFunc(queryTableData, throttleTime)
 
 /**
  * @description: 重置整个查询表单,重置后,再请求一次全部表格
- * @param {*} formEl  表单对象
- * @return {*}
+ * @param needQuery 是否需要重新查询,默认为true,如果为false,则不重新查询
  */
-const resetQueryForm = (neewQuery: boolean = true) => {
+const resetQueryForm = (needQuery: boolean = true) => {
   // 使用函数返回保存的备份信息,这样可以正确的给queryformdata赋值
   // JSON.stringify()第二个参数可以用来处理undefined的情况,第一个参数设置为_可以避免ts检查
   function resetFormData() {
-    let data = JSON.parse(
+    return JSON.parse(
       JSON.stringify(backupQueryFormData, (_, v) => (typeof v === 'undefined' ? '' : v))
     )
-    return data
   }
   Object.assign(queryFormData, resetFormData())
   reqconfig.otherOptions = backupReqOtherOptions // 要把请求的参数也重置一次,不然切换平台等操作,会带着原来的查询参数请求
 
-  if (neewQuery) queryTableData()
+  if (needQuery) queryTableData()
 }
 
 // 把重置方法包装一下,节流
@@ -472,14 +474,13 @@ const tableSortChange = (data: { column: any; prop: string; order: any }) => {
 }
 
 /**
- * @description: 删除行
- * @param {*} url 请求地址
- * @param {*} row 行数据
- * @return {*}
+ * 删除行
+ * @param url 请求地址
+ * @param fieldsInfo 行数据
  */
-const deleteRow = (url: string, filedsInfo: any) => {
+const deleteRow = (url: string, fieldsInfo: any) => {
   axiosInstance
-    .post(url, { ...filedsInfo })
+    .post(url, { ...fieldsInfo })
     .then((data) => {
       analysisResCode(data).then(() => {
         resetQueryForm(false)
@@ -565,10 +566,14 @@ onMounted(() => {
             <el-form-item
               @keyup.enter.native="throttleQueryTableData"
               :label="item.label"
-              v-if="item.valueType === 'string' || item.valueType === 'float'"
+              v-if="item.valueType !== 'int'"
               class="filterItem"
             >
-              <el-input clearable v-model="queryFormData[item.name]" />
+              <el-input
+                :placeholder="item.placeholder"
+                clearable
+                v-model="queryFormData[item.name]"
+              />
             </el-form-item>
             <el-form-item
               @keyup.enter.native="throttleQueryTableData"
@@ -578,6 +583,7 @@ onMounted(() => {
             >
               <el-input
                 clearable
+                :placeholder="item.placeholder"
                 v-model="queryFormData[item.name]"
                 @input="numberInput(item.name)"
               />
@@ -687,25 +693,12 @@ onMounted(() => {
             align="center"
             show-overflow-tooltip
             v-if="item.isShow"
-            :sortable="item.needSort === true ? 'custorm' : false"
+            :sortable="item.needSort ? 'custorm' : false"
           >
             <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.text[0]
-                    : 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"
+                v-if="item.specialEffect?.type === FieldSpecialEffectType.IMG"
                 :preview-teleported="true"
                 :src="scope.row[item.name]"
                 :preview-src-list="[scope.row[item.name]]"
@@ -715,52 +708,20 @@ onMounted(() => {
               >
                 <template #error>
                   <!--  -->
-                  <img style="width: 35px; height: 35px" :src="blobUrlInfo.defaultHead" />
+                  <img
+                    alt="头像"
+                    style="width: 35px; height: 35px"
+                    :src="blobUrlInfo.defaultHead"
+                  />
                 </template>
               </el-image>
 
               <!-- 文字类 -->
-              <el-text
-                v-else-if="item.specialEffect?.type === FieldSpecialEffectType.TEXT"
-                :type="
-                  scope.row[item.name]
-                    ? item.specialEffect.othnerInfo.color[0]
-                    : item.specialEffect.othnerInfo.color[1]
-                "
-              >
-                {{ scope.row[item.name] }}
-              </el-text>
-
-              <!-- 翻译类 -->
-              <el-text v-else-if="item.specialEffect?.type === FieldSpecialEffectType.TRANSLATE">
-                <el-icon
-                  v-if="item.specialEffect.othnerInfo.icon"
-                  style="padding-right: 8px"
-                  :color="scope.row[item.name] ? '#409EFF' : '#F56C6C'"
-                  ><icon-tabler-point-filled></icon-tabler-point-filled
-                ></el-icon>
-                {{
-                  item.specialEffect.othnerInfo.translateText[scope.row[item.name]]
-                    ? item.specialEffect.othnerInfo.translateText[scope.row[item.name]]
-                    : '未知'
-                }}
-              </el-text>
-
-              <!-- 状态类 -->
-              <el-text v-else-if="item.specialEffect?.type === FieldSpecialEffectType.STATE">
-                <span>
-                  <el-icon
-                    style="padding-right: 8px"
-                    :color="scope.row[item.name] ? '#409EFF' : '#F56C6C'"
-                    ><icon-tabler-point-filled></icon-tabler-point-filled
-                  ></el-icon>
-                  {{
-                    scope.row[item.name]
-                      ? item.specialEffect.othnerInfo.text[0]
-                      : item.specialEffect.othnerInfo.text[1]
-                  }}</span
-                >
-              </el-text>
+              <!-- :value="tableTextFieldVal(item, scope)" -->
+              <span v-else-if="item.specialEffect?.type === FieldSpecialEffectType.TEXT">
+                <TableFieldText :special-effect="item.specialEffect" :value="scope.row[item.name]">
+                </TableFieldText>
+              </span>
 
               <!-- 开关类 -->
 
@@ -774,36 +735,6 @@ onMounted(() => {
               >
               </el-switch>
 
-              <!-- 下拉菜单类 -->
-              <el-dropdown
-                trigger="click"
-                v-else-if="item.specialEffect?.type === FieldSpecialEffectType.DROPDOWN"
-              >
-                <span
-                  class="el-dropdown-link"
-                  style="display: flex; align-items: center; cursor: pointer"
-                >
-                  <el-icon
-                    style="padding-right: 8px"
-                    :color="scope.row[item.name] ? '#409EFF' : '#F56C6C'"
-                    ><icon-tabler-point-filled></icon-tabler-point-filled
-                  ></el-icon>
-                  {{
-                    scope.row[item.name]
-                      ? item.specialEffect.othnerInfo.text[0]
-                      : item.specialEffect.othnerInfo.text[1]
-                  }}
-
-                  <el-icon class="el-icon--right"><arrow-down /></el-icon>
-                </span>
-                <template #dropdown>
-                  <el-dropdown-menu>
-                    <el-dropdown-item :command="{ value: true }">使用中</el-dropdown-item>
-                    <el-dropdown-item :command="{ value: false }">已弃用</el-dropdown-item>
-                  </el-dropdown-menu>
-                </template>
-              </el-dropdown>
-
               <el-text v-else>
                 <!-- 其他列按默认方式显示 -->
 
@@ -921,11 +852,6 @@ onMounted(() => {
   align-items: center;
 }
 
-.partition {
-  width: 98%;
-  margin: 0 auto;
-}
-
 .tableTools {
   width: 98%;
   margin: 0 auto;
@@ -958,7 +884,7 @@ onMounted(() => {
 }
 
 .tableBody {
-  box-shadow: 0 0 3px 0px rgba(0, 0, 0, 0.1);
+  box-shadow: 0 0 3px 0 rgba(0, 0, 0, 0.1);
   /* box-shadow:
     -4px -4px 8px 1px rgba(0, 0, 0, 0.02),
     -4px -4px 3px 1px rgba(0, 0, 0, 0.02); */
@@ -967,23 +893,12 @@ onMounted(() => {
 .userTablePaginationBox {
   box-sizing: border-box;
   width: 98%;
-  margin: 0% auto;
+  margin: 0 auto;
   padding: 1% 0;
   display: flex;
   justify-content: center;
 }
 
-.averageItem {
-  font-size: 14px;
-  color: #515b6f;
-}
-
-.normalItem {
-  font-size: 14px;
-  color: #515b6f;
-  font-weight: 400;
-}
-
 .leftToolBtn {
   margin-right: 5px;
 }

+ 231 - 0
src/components/table/TableFieldText.vue

@@ -0,0 +1,231 @@
+<script setup lang="ts">
+import type { SpecialEffectText } from '@/types/tableText'
+import { TagType, TextType } from '@/types/tableText'
+
+import { computed } from 'vue'
+
+const props = defineProps<{
+  specialEffect: SpecialEffectText
+  value: any
+}>()
+
+/**
+ * 格式化时间为YYYY-MM-DD
+ * @param dateInput 输入的日期
+ * @returns 格式化后的日期字符串
+ */
+function formatDateToYYYYMMDD(dateInput: string | Date): string {
+  // 将输入的字符串或 Date 对象解析为 Date 类型
+  const date = typeof dateInput === 'string' ? new Date(dateInput) : dateInput
+
+  // 检查是否为有效日期
+  if (isNaN(date.getTime())) {
+    throw new Error('Invalid date format')
+  }
+
+  // 格式化为 yyyy-mm-dd
+  const year = date.getFullYear()
+  const month = String(date.getMonth() + 1).padStart(2, '0') // 月份从0开始计数,需要加1
+  const day = String(date.getDate()).padStart(2, '0')
+
+  return `${year}-${month}-${day}`
+}
+/**
+ * 判断是否存在特殊效果信息。
+ *
+ * @returns {boolean} 如果 `specialEffect` 存在则返回 `true`,否则返回 `false`。
+ */
+const hasSpecialEffect = (): boolean => {
+  return props.specialEffect !== undefined
+}
+
+/**
+ * 判断是否具有翻译映射(translateMap)信息。
+ *
+ * @returns {boolean} 如果 `specialEffect` 存在且包含 `translateMap`,则返回 `true`,否则返回 `false`。
+ */
+const hasTranslateMap = (): boolean => {
+  return hasSpecialEffect() && props.specialEffect.otherInfo.translateMap !== undefined
+}
+
+/**
+ * 判断 `translateMap` 是否为数组类型。
+ *
+ * @returns {boolean} 如果 `translateMap` 存在且为数组类型,则返回 `true`,否则返回 `false`。
+ */
+const isArrTranslateMap = (): boolean => {
+  return hasTranslateMap() && Array.isArray(props.specialEffect.otherInfo.translateMap)
+}
+
+/**
+ * 判断是否具有颜色信息。
+ *
+ * @returns {boolean} 如果 `specialEffect` 存在且包含 `color` 属性,则返回 `true`,否则返回 `false`。
+ */
+const hasColor = (): boolean => {
+  return hasSpecialEffect() && props.specialEffect.otherInfo.color !== undefined
+}
+
+/**
+ * 判断 `color` 是否为数组类型。
+ *
+ * @returns {boolean} 如果 `color` 存在且为数组类型,则返回 `true`,否则返回 `false`。
+ */
+const isArrColor = (): boolean => {
+  return hasColor() && Array.isArray(props.specialEffect.otherInfo.color)
+}
+
+/**
+ * 判断是否具有标签类型(tagType)信息。
+ *
+ * @returns {boolean} 如果 `specialEffect` 存在且包含 `tagType` 属性,则返回 `true`,否则返回 `false`。
+ */
+const hasTag = (): boolean => {
+  return hasSpecialEffect() && props.specialEffect.otherInfo.tagType !== undefined
+}
+
+/**
+ * 获取到对应的文本
+ * 如果没有特殊效果,或者没有对应的翻译文本,则直接为原始版本
+ * 否则按照对象或者数组的方式,分别处理
+ * 数组直接按布尔值来确定,对象则根据传入值在翻译信息中的键来确定
+ * @returns 转译后的文本
+ */
+const getTableTextFieldVal = (): any => {
+  let val = props.value
+  // console.log(JSON.parse(JSON.stringify(val)))
+  if (hasSpecialEffect() && hasTranslateMap()) {
+    if (isArrTranslateMap()) {
+      let translateMap = props.specialEffect.otherInfo.translateMap!
+      val = Boolean(val) ? translateMap[0] : translateMap[1]
+    } else {
+      val = props.specialEffect.otherInfo.translateMap![val]
+    }
+  }
+
+  return val
+}
+
+/**
+ * 是否需要禁用文本颜色
+ * 不传disabelTextcolor字段或者传入false,都不禁用
+ * 当启用了前缀图标、没有传入特殊效果、设置为true的情况下都禁用
+ * @returns 是否禁用文本颜色
+ */
+const isdisabledTextColor = (): boolean => {
+  if (!hasSpecialEffect()) return true
+  if (props.specialEffect.otherInfo.needPreIcon) return true
+  let result = props.specialEffect.otherInfo.disabledTextColor
+  return Boolean(result)
+}
+
+/**
+ * 格式化文本
+ * @returns 格式化后的文本
+ */
+const formatterText = computed<string>(() => {
+  let result: string = getTableTextFieldVal()
+  switch (props.specialEffect.otherInfo.textType) {
+    case TextType.DATE:
+      {
+        result = formatDateToYYYYMMDD(result)
+      }
+      break
+    case TextType.FLoat:
+      {
+        result = String(parseFloat(result))
+      }
+      break
+    case TextType.INT:
+      {
+        result = String(parseInt(result))
+      }
+      break
+    case TextType.PERCENT:
+      {
+        result = String(result) + '%'
+      }
+      break
+    default: {
+      result = result
+    }
+  }
+
+  return result
+})
+
+/**
+ * 计算颜色
+ * 分别是数组、对象、单个字符串三种情况
+ * 其中数组则是只根据布尔类型来判断,真为数组第一个,假为数组第二个
+ * 对象则是直接根据传入的value值,对应color对象的键
+ * @returns 颜色
+ */
+const tableTextColor = computed<string>(() => {
+  let color = ''
+  let val = props.value
+  if (hasSpecialEffect() && hasColor()) {
+    if (isArrColor()) {
+      let colorList = props.specialEffect.otherInfo.color! as Array<string>
+      color = Boolean(val) ? colorList[0] : colorList[1]
+    } else if (typeof val === 'string') {
+      color = props.specialEffect.otherInfo.color as string
+    } else {
+      color = (
+        props.specialEffect.otherInfo.color as {
+          [key: string]: string
+        }
+      )[val as string]
+    }
+  }
+
+  return color
+})
+
+/**
+ * 计算出来的tag类型
+ * @returns tag类型
+ */
+const tableTag = computed<TagType>(() => {
+  let tagType = TagType.SUCCESS
+  let val = props.value
+  if (hasSpecialEffect() && hasTag()) {
+    let tagList = props.specialEffect.otherInfo.tagType!
+    tagType = Boolean(val) ? tagList[0] : tagList[1]
+  }
+  return tagType
+})
+</script>
+
+<template>
+  <div class="fieldTextItem">
+    <el-icon
+      v-if="props.specialEffect.otherInfo.needPreIcon"
+      style="padding-right: 8px"
+      :color="tableTextColor"
+      ><icon-tabler-point-filled></icon-tabler-point-filled
+    ></el-icon>
+    <span
+      :style="{ color: isdisabledTextColor() ? '' : tableTextColor }"
+      v-if="specialEffect.otherInfo.textType === TextType.TEXT"
+    >
+      {{ formatterText }}
+    </span>
+    <el-link
+      :style="{ color: isdisabledTextColor() ? '' : tableTextColor }"
+      v-if="specialEffect.otherInfo.textType === TextType.LINK"
+      >{{ formatterText }}</el-link
+    >
+    <el-tag :type="tableTag" v-if="specialEffect.otherInfo.textType === TextType.TAG">{{
+      formatterText
+    }}</el-tag>
+  </div>
+</template>
+
+<style scoped>
+.fieldTextItem {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+</style>

+ 5 - 17
src/types/table.ts

@@ -2,13 +2,15 @@
  * @Author: fxs bjnsfxs@163.com
  * @Date: 2024-08-20 17:56:13
  * @LastEditors: fxs bjnsfxs@163.com
- * @LastEditTime: 2024-11-06 17:44:35
- * @FilePath: \Quantity-Creation-Management-Systemc:\Users\NINGMEI\Desktop\Game-Backstage-Management-System\src\types\table.ts
+ * @LastEditTime: 2024-11-14
+ * @FilePath: \Game-Backstage-Management-System\src\types\table.ts
  * @Description:
  *
  */
 import type { ReqConfig } from './dataAnalysis'
 import type { ValueTypes } from './form'
+import type { SpecialEffect } from './tableText'
+
 // 颜色类型
 export enum ColorType {
   PRIMARY = 'primary',
@@ -53,27 +55,13 @@ export interface QueryInfo {
   default?: any
 }
 
-// 字段特殊效果类型
-export enum FieldSpecialEffectType {
-  IMG = 'img',
-  TAG = 'tag',
-  TEXT = 'text',
-  TRANSLATE = 'translate',
-  SWITCH = 'switch',
-  DROPDOWN = 'dropdown',
-  STATE = 'state'
-}
-
 // 表格字段信息格式
 export interface TableFieldInfo {
   name: string
   cnName: string
   isShow: boolean
   needSort: boolean
-  specialEffect?: {
-    type: FieldSpecialEffectType
-    othnerInfo?: any
-  }
+  specialEffect?: SpecialEffect
 }
 
 // props的参数格式

+ 82 - 0
src/types/tableText.ts

@@ -0,0 +1,82 @@
+// 字段特殊效果类型
+enum FieldSpecialEffectType {
+  TEXT = 'text',
+  SWITCH = 'switch',
+  DROPDOWN = 'dropdown',
+  IMG = 'img'
+}
+
+// 文本类型字段类型
+enum TextType {
+  TEXT = 'text', // 普通文字
+  LINK = 'link', // 链接
+  DATE = 'date', // 日期
+  INT = 'int', // 整数,
+  FLoat = 'float', // 浮点数
+  PERCENT = 'percent', // 百分比
+  TAG = 'tag' // 标签
+}
+
+// 标签类型
+enum TagType {
+  PRIMARY = 'primary',
+  SUCCESS = 'success',
+  INFO = 'info',
+  WARNING = 'warning',
+  DANGER = 'danger'
+}
+
+// 定义每种 specialEffect 结构
+interface SpecialEffectText {
+  type: FieldSpecialEffectType.TEXT
+  otherInfo: {
+    // 颜色
+    color?:
+      | string[]
+      | {
+          [key: string]: string
+        }
+      | string
+    // 翻译字典,即需要对应的值进行翻译,根据值不同展示不同文字
+    translateMap?:
+      | {
+          [key: string | number]: string
+        }
+      | Array<string>
+    disabledTextColor?: boolean // 是否禁用文字颜色,默认不禁用,当启用了前缀图标时默认禁用
+    needPreIcon?: boolean // 是否需要前缀图标
+    tagType?: TagType[] // 标签类型
+    textType: TextType // 文本类型
+  }
+}
+
+// 开关类型的特殊效果
+interface SpecialEffectSwitch {
+  type: FieldSpecialEffectType.SWITCH
+  otherInfo: {}
+}
+
+// 下拉框类型的特殊效果
+interface SpecialEffectDropdown {
+  type: FieldSpecialEffectType.DROPDOWN
+  otherInfo: {}
+}
+
+// 图片类型的特殊效果
+interface SpecialEffectImg {
+  type: FieldSpecialEffectType.IMG
+  otherInfo: {}
+}
+
+// 所有特殊效果类型
+type SpecialEffect =
+  | SpecialEffectText
+  | SpecialEffectSwitch
+  | SpecialEffectDropdown
+  | SpecialEffectImg
+
+export { FieldSpecialEffectType, TextType, TagType }
+
+export type { SpecialEffect }
+
+export type { SpecialEffectText, SpecialEffectSwitch, SpecialEffectDropdown, SpecialEffectImg }

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

@@ -7,7 +7,7 @@ import type { TablePaginationSetting, TableFieldInfo } from '@/types/table'
 
 import { FormFieldType } from '@/types/form'
 import { ElMessageBox } from 'element-plus'
-import { FieldSpecialEffectType } from '@/types/table'
+import { FieldSpecialEffectType, TextType } from '@/types/tableText'
 import { watch, onUnmounted, reactive, ref } from 'vue'
 import { useRoute } from 'vue-router'
 import { useRequest } from '@/hooks/useRequest'
@@ -173,9 +173,10 @@ const tableFieldConfig = reactive<Array<TableFieldInfo>>([
     isShow: true,
     needSort: false,
     specialEffect: {
-      type: FieldSpecialEffectType.TRANSLATE,
-      othnerInfo: {
-        translateText: {
+      type: FieldSpecialEffectType.TEXT,
+      otherInfo: {
+        textType: TextType.TEXT,
+        translateMap: {
           string: '字符串',
           int: '数字',
           array: '数组'
@@ -189,10 +190,11 @@ const tableFieldConfig = reactive<Array<TableFieldInfo>>([
     isShow: true,
     needSort: false,
     specialEffect: {
-      othnerInfo: {
-        text: ['启用', '禁用']
-      },
-      type: FieldSpecialEffectType.STATE
+      type: FieldSpecialEffectType.TEXT,
+      otherInfo: {
+        textType: TextType.TEXT,
+        translateMap: ['启用', '禁用']
+      }
     }
   },
   {

+ 8 - 5
src/views/AppManage/EventMangeTable.vue

@@ -7,7 +7,8 @@ import type { FormField } from '@/types/form'
 
 import { useRequest } from '@/hooks/useRequest'
 import { useCommonStore } from '@/stores/useCommon'
-import { FieldSpecialEffectType, FilterType } from '@/types/table'
+import { FilterType } from '@/types/table'
+import { FieldSpecialEffectType, TextType } from '@/types/tableText'
 import { FormFieldType } from '@/types/form'
 import { reactive, ref, watch } from 'vue'
 
@@ -66,9 +67,12 @@ const tableFieldsInfo = reactive<Array<TableFieldInfo>>([
     isShow: true,
     needSort: false,
     specialEffect: {
-      type: FieldSpecialEffectType.STATE,
-      othnerInfo: {
-        text: ['已使用', '已停用']
+      type: FieldSpecialEffectType.TEXT,
+      otherInfo: {
+        textType: TextType.TEXT,
+        translateMap: ['已启用', '已停用'],
+        color: ['#409eff', '#73767a'],
+        needPreIcon: true
       }
     }
   },
@@ -275,7 +279,6 @@ watch(
   (val: string) => {
     requestConfig.otherOptions.gid = val
     dialogReq.otherOptions.formData.gid = val // 把对话框的form表单的gid也改了
-    // requestConfig.otherOptions.formData.gid = val
   }
 )
 

+ 16 - 5
src/views/AppManage/UserConversionDetail.vue

@@ -40,7 +40,7 @@ const nowAd = ref<string>('')
 
 const formData = ref<FormData>({
   gid: selectInfo.gid, // 游戏Id
-  aid: null, // 广告ID
+  aid: 0, // 广告ID
   type: 'active', // 广告类型
   pid: 0, // 广告父ID
   start_num: 0, // 启动次数
@@ -125,14 +125,15 @@ const fieldsInfo: Array<FormField> = [
 
 const rules = reactive<FormRules<FormData>>({
   gid: [{ required: true, message: '游戏Id是必填项', trigger: 'blur' }],
-  aid: [
-    { required: true, message: '广告ID是必填项', trigger: 'blur' },
-    { type: 'number', message: '广告ID必须是数字', trigger: 'blur' }
-  ],
+
   pid: [
     { required: false, message: '广告父ID是可选项', trigger: 'blur' },
     { type: 'number', message: '广告父ID必须是数字', trigger: 'blur' }
   ],
+  aid: [
+    { required: false, message: '广告ID是必填项', trigger: 'blur' },
+    { type: 'number', message: '广告ID必须是数字', trigger: 'blur' }
+  ],
   type: [
     { required: true, message: '广告类型是必填项', trigger: 'trigger' },
 
@@ -292,6 +293,9 @@ onMounted(() => {})
         </template>
       </el-page-header>
     </div>
+    <div class="conditionTip">
+      <span>以下参数为0则代表<span style="font-weight: bold">通用</span></span>
+    </div>
     <div class="conditionBody">
       <el-form
         ref="formRef"
@@ -383,4 +387,11 @@ onMounted(() => {})
 .conditionHeader {
   padding: 0 24px;
 }
+
+.conditionTip {
+  padding: 0 24px;
+  margin-top: 24px;
+  font-size: 16px;
+  color: #606266;
+}
 </style>

+ 4 - 0
src/views/AppManage/UserConversionTable.vue

@@ -178,4 +178,8 @@ const goDetail = (data: any) => {
   padding: 10px 24px;
   background-color: white;
 }
+
+.operationBtn {
+  cursor: pointer;
+}
 </style>

+ 1 - 1
src/views/Home/Analysis/EventAnalysisTable.vue

@@ -101,7 +101,7 @@ const requestConfig = reactive<ReqConfig>({
 const eventTableFilterInfo: Array<QueryInfo> = [
   {
     name: 'actionName',
-    label: '',
+    label: '事件名',
     type: FilterType.INPUT,
     placeholder: '输入事件名查询'
   }

+ 15 - 18
src/views/Home/InfoManage/PlayerManageView.vue

@@ -4,7 +4,8 @@ import type { FormRules } from 'element-plus'
 import type { FormField } from '@/types/form'
 import type { DialogConfig } from '@/types/dialog'
 
-import { FilterType, FieldSpecialEffectType, ColorType } from '@/types/table'
+import { FilterType, ColorType } from '@/types/table'
+import { FieldSpecialEffectType, TagType, TextType } from '@/types/tableText'
 import { reactive, ref } from 'vue'
 import { ElMessageBox } from 'element-plus'
 import { FormFieldType } from '@/types/form'
@@ -99,7 +100,7 @@ const filedsInfo = reactive<Array<TableFieldInfo>>([
     needSort: false,
     specialEffect: {
       type: FieldSpecialEffectType.IMG,
-      othnerInfo: {}
+      otherInfo: {}
     }
   },
   {
@@ -108,10 +109,12 @@ const filedsInfo = reactive<Array<TableFieldInfo>>([
     isShow: true,
     needSort: false,
     specialEffect: {
-      type: FieldSpecialEffectType.TAG,
-      othnerInfo: {
-        text: ['是', '否'],
-        color: [ColorType.DANGER, ColorType.SUCCESS]
+      type: FieldSpecialEffectType.TEXT,
+      otherInfo: {
+        translateMap: ['是', '否'],
+
+        tagType: [TagType.DANGER, TagType.SUCCESS],
+        textType: TextType.TAG
       }
     }
   },
@@ -131,14 +134,7 @@ const filedsInfo = reactive<Array<TableFieldInfo>>([
     name: 'option',
     cnName: '权限',
     isShow: true,
-    needSort: false,
-    specialEffect: {
-      type: FieldSpecialEffectType.TEXT,
-      othnerInfo: {
-        text: ['是', '否'],
-        color: [ColorType.WARNING, ColorType.INFO]
-      }
-    }
+    needSort: false
   },
   {
     name: 'pf',
@@ -146,13 +142,14 @@ const filedsInfo = reactive<Array<TableFieldInfo>>([
     isShow: true,
     needSort: false,
     specialEffect: {
-      type: FieldSpecialEffectType.TRANSLATE,
-      othnerInfo: {
-        translateText: {
+      type: FieldSpecialEffectType.TEXT,
+      otherInfo: {
+        translateMap: {
           wx: '微信',
           tt: '抖音',
           web: 'Web'
-        }
+        },
+        textType: TextType.TEXT
       }
     }
   },

+ 6 - 8
src/views/Index.vue

@@ -203,8 +203,8 @@ let watchGameListChange: () => void = () => {}
  */
 const watchLoadingState = watch(
   () => loadingState,
-  (newval) => {
-    if (newval) {
+  (newVal) => {
+    if (newVal) {
       watchGameListChange = watch(
         () => allGameInfo,
         (newGameInfo: Array<any>) => {
@@ -407,7 +407,7 @@ onMounted(() => {
   margin-right: 40px;
 }
 
-.sideBarFold {  
+.sideBarFold {
   width: 5%;
   height: 3%;
   position: absolute;
@@ -446,8 +446,6 @@ onMounted(() => {
   display: flex;
   align-items: center;
   left: 5%;
-  display: flex;
-  align-items: center;
 }
 
 .gameIcon {
@@ -511,15 +509,15 @@ onMounted(() => {
   margin-top: 7vh;
   overflow: scroll;
   background-color: #f2f3f5;
-  right: 0vw;
-  top: 0vh;
+  right: 0;
+  top: 0;
 }
 </style>
 
 <!-- 为了让popper-class生效,需要的单独写一份 -->
 <style>
 .headPopper {
-  padding: 0px !important;
+  padding: 0 !important;
   border: 1px solid #e5e6eb;
 
   background-color: white;