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

feat(事件分析-注册页): 新增事件分析-注册维度

fxs 1 долоо хоног өмнө
parent
commit
91a3344b90

+ 4 - 0
src/hooks/useRequest.ts

@@ -73,6 +73,10 @@ export function useRequest() {
     userActionList: `/user/userActionList`, // 游戏事件统计列表
     userActionListExpand: `/user/userActionOptionList`, // 事件选项统计详情
 
+    // 事件分析-用户注册维度
+    userRegisterActionList: `/user/userActionRegister`, // 用户注册事件统计列表
+    userRegisterActionListExpand: `/user/actionOptionRegister`, // 用户注册活跃详情
+
     // 用户转化条件
     gameConditionList: `/user/gameConditionList`, // 广告列表
     setGameCondition: `/user/setGameCondition`, // 编辑游戏用户转化条件

+ 19 - 0
src/router/home.ts

@@ -121,6 +121,25 @@ export default [
             ]
           },
           {
+            path: 'registerEventAnalysisView',
+            name: 'RegisterEventAnalysisView',
+            cnName: '事件分析-注册',
+            showChild: false,
+            redirect: '/home/dataAnalysis/registerEventAnalysisView/registerEventAnalysisTable',
+            component: () => import('@/views/Home/Analysis/RegisterEventAnalysisView.vue'),
+            meta: {
+              activeMenu: 'registerEventAnalysisView',
+              needKeepAlive: true
+            },
+            children: [
+              {
+                path: 'registerEventAnalysisTable',
+                name: 'RegisterEventAnalysisTable',
+                component: () => import('@/views/Home/Analysis/RegisterEventAnalysisTable.vue')
+              }
+            ]
+          },
+          {
             path: 'userBehavior',
             name: 'UserBehavior',
             cnName: '用户行为',

+ 277 - 0
src/views/Home/Analysis/RegisterEventAnalysisTable.vue

@@ -0,0 +1,277 @@
+<!--
+ * @Author: fxs bjnsfxs@163.com
+ * @Date: 2024-09-18
+ * @LastEditors: fxs bjnsfxs@163.com
+ * @LastEditTime: 2024-12-03
+ * @Description:
+ *
+-->
+<script setup lang="ts">
+import type { ReqConfig } from '@/types/dataAnalysis'
+import type {
+  QueryInfo,
+  TableFieldInfo,
+  TablePaginationSetting,
+  TableToolsConfig
+} from '@/types/table'
+import { FilterType } from '@/types/table'
+import { reactive, ref } from 'vue'
+import { useRequest } from '@/hooks/useRequest'
+import { useCommonStore } from '@/stores/useCommon'
+import { resetTimeToMidnight } from '@/utils/common'
+import { useAnalysis } from '@/hooks/useAnalysis'
+import { usePage } from '@/hooks/usePage'
+
+import Table from '@/components/table/CustomTable.vue'
+
+const { updateReqConfig } = useAnalysis()
+
+const { watchPageChange } = usePage()
+
+const { AllApi } = useRequest()
+const { selectInfo, tempMultipleChoice } = useCommonStore()
+
+const eventTable = ref<InstanceType<typeof Table>>()
+
+// 是否是单选的pf
+const isSinglePf = false
+
+interface eventTableProps {
+  startTime: string
+  endTime: string
+}
+
+const props = withDefaults(defineProps<eventTableProps>(), {
+  startTime: resetTimeToMidnight(new Date()),
+  endTime: resetTimeToMidnight(new Date())
+})
+
+// 表格分页设置
+const pagingConfig = reactive<TablePaginationSetting>({
+  limit: 20,
+  currentPage: 1,
+  total: 0,
+  pageSizeList: [20, 30]
+})
+
+// 工具栏配置
+const tableToolsConfig: TableToolsConfig = {
+  add: false,
+  filterFields: true,
+  refresh: true,
+  download: true,
+  headerMap: {
+    actionId: '事件ID',
+    actionName: '事件名称',
+    actionCount: '操作次数',
+    actionUserCount: '操作用户数',
+    activeUserRate: '活跃设备发生率'
+  },
+  expandHeaderMap: {
+    actionId: '选项ID',
+    actionName: '选项名',
+    actionCount: '选项执行次数',
+    actionUserCount: '操作用户数',
+    activeUserRate: '活跃用户率'
+  }
+}
+
+// 表格字段信息
+const tableFieldsInfo = reactive<Array<TableFieldInfo>>([
+  {
+    name: 'actionId',
+    cnName: '事件ID',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'actionName',
+    cnName: '事件名称',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'actionCount',
+    cnName: '操作次数',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'actionUserCount',
+    cnName: '操作用户数',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'activeUserRate',
+    cnName: '活跃设备发生率',
+    isShow: true,
+    needSort: false
+  }
+])
+
+const tableExpandFieldsInfo = reactive<Array<TableFieldInfo>>([
+  {
+    name: 'id',
+    cnName: 'ID',
+    isShow: false,
+    needSort: false
+  },
+  {
+    name: 'actionId',
+    cnName: '选项ID',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'actionName',
+    cnName: '选项名',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'actionCount',
+    cnName: '选项执行次数',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'actionUserCount',
+    cnName: '操作用户数',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'activeUserRate',
+    cnName: '活跃用户率',
+    isShow: true,
+    needSort: false
+  },
+  {
+    name: 'lossUserRate',
+    cnName: '用户流失率',
+    isShow: true,
+    needSort: false
+  }
+])
+
+const expandRequestConfig = reactive<ReqConfig>({
+  url: AllApi.userRegisterActionListExpand,
+  otherOptions: {
+    actionId: '',
+    pf: tempMultipleChoice.pf,
+    gid: selectInfo.gid,
+    startTime: props.startTime,
+    endTime: props.endTime
+  }
+})
+
+// 表格请求配置
+const requestConfig = reactive<ReqConfig>({
+  url: AllApi.userRegisterActionList,
+  otherOptions: {
+    pf: tempMultipleChoice.pf,
+    gid: selectInfo.gid,
+    startTime: props.startTime,
+    endTime: props.endTime
+  }
+})
+
+// 事件表格的上方查询字段信息
+const eventTableFilterInfo: Array<QueryInfo> = [
+  {
+    name: 'actionName',
+    label: '事件名',
+    type: FilterType.INPUT,
+    placeholder: '输入事件名查询'
+  }
+]
+
+/**
+ * 下载展开数据
+ * @param row 行信息
+ */
+const downLoadExpand = (row: any) => {
+  eventTable.value?.downLoadExpandTable(row)
+}
+
+/**
+ *  更新时间
+ * @param {*} startTime 开始时间
+ * @param {*} endTime 结束时间
+ */
+const updateDate = (startTime: string, endTime: string) => {
+  requestConfig.otherOptions.startTime = startTime
+  requestConfig.otherOptions.endTime = endTime
+  expandRequestConfig.otherOptions.startTime = startTime
+  expandRequestConfig.otherOptions.endTime = endTime
+}
+
+/**
+ * 更新请求配置
+ * @param gid 游戏ID
+ * @param pf 平台
+ */
+const updateSelect = (gid: string, pf: any) => {
+  pf = isSinglePf ? pf[0] : pf
+  updateReqConfig(requestConfig, { pf, gid })
+  updateReqConfig(expandRequestConfig, { pf, gid })
+}
+
+const backupDate = reactive([])
+const backupSelect = reactive([])
+
+// 这里特殊一点,监听pf的时候去监听临时的pf,但是gid还是和其他一样
+watchPageChange(() => [selectInfo.gid, tempMultipleChoice.pf], backupSelect, updateSelect)
+
+watchPageChange(() => [props.startTime, props.endTime], backupDate, updateDate)
+</script>
+<template>
+  <div class="eventTable">
+    <div class="content">
+      <Table
+        ref="eventTable"
+        :request-config="requestConfig"
+        :open-page-query="true"
+        :open-remote-query="true"
+        :open-filter-query="true"
+        :query-info="eventTableFilterInfo"
+        :pagination-config="pagingConfig"
+        :table-fields-info="tableFieldsInfo"
+        :tools="tableToolsConfig"
+        :need-expand="true"
+        :expand-config="{
+          expandField: tableExpandFieldsInfo,
+          expandReqConfig: expandRequestConfig
+        }"
+      >
+        <template #tableOperation>
+          <el-table-column label="操作" align="center">
+            <template #default="scope">
+              <el-text class="operationBtn" type="success" @click="downLoadExpand(scope.row)"
+                >下载</el-text
+              >
+            </template>
+          </el-table-column>
+        </template>
+      </Table>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+.eventTable {
+  width: 100%;
+  box-sizing: border-box;
+  padding: 0 24px;
+  background-color: white;
+}
+
+.content {
+  width: 100%;
+}
+
+.operationBtn {
+  cursor: pointer;
+}
+</style>

+ 87 - 0
src/views/Home/Analysis/RegisterEventAnalysisView.vue

@@ -0,0 +1,87 @@
+<script setup lang="ts">
+import type { HeaderCardProps } from '@/types/dataAnalysis'
+
+import { resetTimeToMidnight } from '@/utils/common'
+import { shouldListenToEvent } from '@/utils/table/table'
+import { reactive, ref } from 'vue'
+
+import HeaderCard from '@/components/dataAnalysis/HeaderCard.vue'
+
+// 顶部ref
+const headerCard = ref()
+
+// 头部组件需要的 props
+const headerProps = reactive<HeaderCardProps>({
+  title: '事件分析',
+  openDateSelect: true
+})
+
+// 开始时间
+const startTime = ref()
+// 结束时间
+const endTime = ref()
+
+/**
+ * 增加面包屑导航
+ * @param {*} info 传入的信息
+ */
+const headerAddPath = (info: any) => {
+  const { name, pathName } = info
+
+  headerCard.value?.addPath(name, pathName)
+}
+
+/**
+ * 更新日期
+ * @param {*} newDate 新的日期
+ */
+const dateChange = (newDate: Array<Date>) => {
+  startTime.value = resetTimeToMidnight(newDate[0])
+  endTime.value = resetTimeToMidnight(newDate[1])
+}
+</script>
+<template>
+  <div class="eventAnalysis">
+    <div class="header">
+      <HeaderCard
+        ref="headerCard"
+        :title="headerProps.title"
+        :open-date-select="headerProps.openDateSelect"
+        :need-breadcrumb="true"
+        :need-pf-select="true"
+        :is-radio="false"
+        @change-date="dateChange"
+      ></HeaderCard>
+    </div>
+
+    <!-- 等时间改变后再去请求,不然会请求两次 -->
+    <div class="content" v-if="startTime && endTime">
+      <!-- 监听表格的跳转事件 -->
+      <router-view v-slot="{ Component, route }" :startTime="startTime" :endTime="endTime">
+        <!-- 是eventTable组件就去监听enterDetail事件 -->
+        <!-- 这个keepalive不要去掉,因为里面的table的监听事件是放在onActive中 -->
+        <keep-alive>
+          <component
+            :is="Component"
+            v-if="shouldListenToEvent(route.name, 'RegisterEventAnalysisTable')"
+            @enterAnalysisDetail="headerAddPath"
+          />
+        </keep-alive>
+        <!-- 如果不是正常渲染其他组件 -->
+        <component v-if="route.name === 'RegisterEventAnalysisDetail'" :is="Component" />
+        <!-- <component v-else :is="Component" /> -->
+      </router-view>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+.eventAnalysis {
+  width: 98%;
+  margin: 1% auto;
+  box-sizing: border-box;
+
+  background-color: white;
+  /* border: 1px solid #e5e6eb; */
+}
+</style>