Эх сурвалжийг харах

feat(数据总览、成员管理): 成员管理权限新增全选功能、广告数据总览新增展示类目

fxs 5 сар өмнө
parent
commit
a4f7c296f2

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

@@ -40,7 +40,10 @@ const props = withDefaults(defineProps<TemporalTrendProps>(), {
   selectExpressForm: 1,
   needTable: true,
   needCharts: true,
-  needDownload: false
+  needDownload: false,
+  chartOptions: () => {
+    return {}
+  }
 })
 const activeTab = ref<string>('') // 激活的Tab
 const iconSize = ref(20) // 图标的尺寸
@@ -86,10 +89,11 @@ let statisticFieldsInfo = reactive<Array<StaticField>>([])
 // 图表的展示形式,曲线图或者是表格
 const selectShape = ref(1)
 
-const initChartInfo = {
+const initChartInfo: OptionsProps = {
   legendData: [],
   xAxisData: [],
-  seriesData: []
+  seriesData: [],
+  yAxis: props.chartOptions.yAxis
 }
 
 // 图表的信息,包括图例,数据,以及x轴的刻度label
@@ -378,6 +382,7 @@ onMounted(() => {
             :legend-data="chartInfo.legendData"
             :series-data="chartInfo.seriesData"
             :x-axis-data="chartInfo.xAxisData"
+            :y-axis="chartInfo.yAxis"
             :loading-state="loadDataState.loading"
             class="chart"
           ></TimeLineChart>

+ 12 - 3
src/components/echarts/TimeLineChart.vue

@@ -43,7 +43,7 @@ const formatterTooltip = (params: Array<any>) => {
     let data = `${circle}${colorList[index]}"></span>
     <span >
     <span  style="display: inline-block;  box-sizing: border-box;
-  padding-right: 50px;">${item['seriesName']}</span><span>${item['value']}<span>`
+  padding-right: 50px;">${item['seriesName']}</span><span>${item['value'] === -1 ? 0 : item['value']}<span>`
     result += `<br/>${data}`
   })
   return result
@@ -72,7 +72,8 @@ const initOptions = () => {
     },
     yAxis: {
       type: 'value',
-      minInterval: 1
+      minInterval: 1,
+      min: 1
     },
     tooltip: {
       trigger: 'axis',
@@ -87,6 +88,7 @@ const initOptions = () => {
     grid: {
       left: '24px',
       right: '10px',
+
       containLabel: true
     },
     series: []
@@ -127,7 +129,12 @@ const initOptions = () => {
         return val.name === item
       })
 
-      seriesClone.data = Object.values(result.data)
+      // 对0做特殊处理,改为-1,在formatter里格式化,让他显示为0
+      seriesClone.data = Object.values(result.data).map((item) => {
+        if (item === 0) return -1
+        return item
+      })
+      console.log(seriesClone.data)
       seriesClone.itemStyle.borderColor = colorList[index]
       seriesClone.lineStyle.color = colorList[index]
 
@@ -138,6 +145,8 @@ const initOptions = () => {
     options.series = finalSeriesList
     options.legend.data = Object.values(props.legendData as any)
     options.xAxis.data = props.xAxisData as any
+    Object.assign(options.yAxis, props.yAxis)
+    // console.log(props.yAxis)
   } else {
     options = {
       title: {

+ 5 - 0
src/types/dataAnalysis.ts

@@ -9,6 +9,8 @@
  */
 
 // 下拉选项的信息
+import type { EChartsOption } from 'echarts/types/dist/shared'
+
 export interface DropDownItem {
   value: any
   label: string
@@ -68,6 +70,7 @@ export interface OptionsProps {
   xAxisData: Array<any> // x轴的刻度label
   legendData: Array<any> // 图例的信息
   seriesData: Array<any> // 数据
+  yAxis: any // Y轴配置
 }
 
 // 返回的数据中每个字段的分类信息
@@ -100,6 +103,7 @@ export interface TemporalTrendProps {
   resDataFieldsInfo: ResDataFieldInfo // 返回的数据中每个字段的分类信息
   requestConfig: ReqConfig // 请求参数配置,需要监听,一旦变化,需要重新获取数据
 
+  chartOptions?: EChartsOption // 图表配置
   staticFields?: { [key: string]: Array<StaticField> } // 图表中统计组件的字段信息
   // staticFields?: Array<StaticField> // 图表中统计组件的字段信息
   title: string // 上方显示的title
@@ -120,6 +124,7 @@ export interface TemporalTrendInfo {
   resDataField: ResDataFieldInfo // 返回数据中的字段信息
   tabList?: Array<TabInfo> //标签页数据
   trendTableFields: TrendTableField // 表格的字段,同时也作为legend的一部分
+  chartsOptions?: EChartsOption // 图表配置
   // chartsStaticField?: Array<StaticField> // 统计字段的信息
   chartsStaticField?: { [key: string]: Array<StaticField> } // 统计字段的信息
 }

+ 15 - 2
src/views/Home/AdvertisingData/AdvertisingOverview.vue

@@ -10,6 +10,7 @@
 import type { ReqConfig, StaticField, TemporalTrendInfo } from '@/types/dataAnalysis'
 import { useCommonStore } from '@/stores/useCommon'
 import { useRequest } from '@/hooks/useRequest'
+import type { EChartsOption } from 'echarts/types/dist/shared'
 import { reactive, toRaw } from 'vue'
 import { useAnalysis } from '@/hooks/useAnalysis'
 import { createDateRange, resetTimeToMidnight } from '@/utils/common'
@@ -40,6 +41,11 @@ const adOverviewFieldsInfo: Array<StaticField> = [
     name: 'avgUserAds7',
     cnName: '近七日活跃用户平均看广告次数',
     value: ''
+  },
+  {
+    name: 'todayCashCount',
+    cnName: '当日注册变现人数',
+    value: ''
   }
 ]
 
@@ -56,6 +62,11 @@ const adOverviewReqConfig = reactive<ReqConfig>({
 })
 
 const dailyInfo = reactive<TemporalTrendInfo>({
+  chartsOptions: {
+    yAxis: {
+      type: 'log'
+    }
+  },
   dataReqConfig: {
     url: AllApi.userAdsDaily,
     otherOptions: {
@@ -67,7 +78,7 @@ const dailyInfo = reactive<TemporalTrendInfo>({
   },
   resDataField: toRaw({
     xAxis: 'userAdsDaily', // x轴的刻度信息所在的字段
-    values: ['userAdsDaily'] // 值所在的字段
+    values: ['userAdsDaily', 'userAdsDailyToday'] // 值所在的字段
   }),
   tabList: toRaw([
     {
@@ -79,7 +90,8 @@ const dailyInfo = reactive<TemporalTrendInfo>({
   trendTableFields: toRaw({
     userAdsDaily: {
       index: '日期',
-      userAdsDaily: '用户广告数据'
+      userAdsDaily: '用户广告数据',
+      userAdsDailyToday: '每日广告数据'
     }
   })
 })
@@ -129,6 +141,7 @@ watchPageChange(() => [selectInfo.pf, selectInfo.gid], backupSelect, updateSelec
           :table-fields-info="dailyInfo.trendTableFields"
           :res-data-fields-info="dailyInfo.resDataField"
           :tab-info="dailyInfo.tabList"
+          :chart-options="dailyInfo.chartsOptions as EChartsOption"
           :need-table="false"
           :need-tab="false"
           :select-express-form="1"

+ 44 - 6
src/views/MemberManage/MemberTable.vue

@@ -15,8 +15,8 @@ import {
 import { FieldSpecialEffectType } from '@/types/tableText.ts'
 
 import axiosInstance from '@/utils/axios/axiosInstance.ts'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { ref } from 'vue'
+import { type CheckboxValueType, ElMessage, ElMessageBox } from 'element-plus'
+import { ref, watch } from 'vue'
 
 type CustomTableType = InstanceType<typeof CustomTable>
 
@@ -140,7 +140,7 @@ const tableConfig = ref<TableConfig>({
         otherInfo: {
           render: (val: string[]) => {
             // console.log(val)
-            if (!val || val.length === 0) return '超级管理员'
+            if (!val || val.length === 0 || val[0] === 'all') return '全部权限'
             console.log(val)
             return val.map((item) => getGameName(item)).join(',')
           }
@@ -187,16 +187,23 @@ const editMember = (row: any) => {
   isEdit.value = true
   dialogTitle.value = '修改成员'
 
-  console.log(allGameInfo)
+  console.log(row)
   isAdmin.value = !row.permission
 
-  console.log(isAdmin.value)
+  const permission: string[] = [...row.permission]
+
+  if (isAdmin.value || row.permission[0] === 'all') {
+    const allGid = allGameInfo.map((item) => item.gid)
+    permission.splice(0, permission.length, ...allGid)
+    isCheckAllPermission.value = true
+    console.log('执行')
+  }
   memberForm.value = {
     adminId: row.id, // 注意字段映射
     account: row.account,
     name: row.name,
     password: row.password, // 编辑时密码保留为空
-    permission: row.permission || allGameInfo.map((item) => item.gid)
+    permission
   }
   dialogVisible.value = true
 }
@@ -222,6 +229,11 @@ const saveMember = async () => {
       delete params.adminId // 确保新增时不发送adminId
     }
 
+    // 特殊处理一下全选的情况
+    if (params.permission.length === allGameInfo.length) {
+      params.permission = ['all']
+    }
+
     const res = (await axiosInstance.post(url, params)) as ResponseInfo
 
     if (res.code !== 0) {
@@ -276,6 +288,27 @@ const closePasswordDialog = () => {
   passwordDialogVisible.value = false
   newPassword.value = ''
 }
+
+const isCheckAllPermission = ref<boolean>(false)
+const handleCheckAll = (isAllCheck: CheckboxValueType) => {
+  console.log(isAllCheck)
+  console.log(memberForm.value)
+  if (isAllCheck) {
+    memberForm.value.permission = allGameInfo.map((item) => item.gid)
+  } else {
+    memberForm.value.permission = []
+  }
+}
+
+watch(
+  () => memberForm.value.permission,
+  (val: string[]) => {
+    isCheckAllPermission.value = val.length === allGameInfo.length
+  },
+  {
+    deep: true
+  }
+)
 </script>
 
 <template>
@@ -338,6 +371,11 @@ const closePasswordDialog = () => {
             clearable
             :disabled="isAdmin"
           >
+            <template #header>
+              <el-checkbox v-model="isCheckAllPermission" @change="handleCheckAll">
+                全选
+              </el-checkbox>
+            </template>
             <el-option
               v-for="item in allGameInfo"
               :key="item.gid"