浏览代码

feat: Add analysis api

陈凯龙 3 年之前
父节点
当前提交
83327ea763

+ 63 - 0
mock/analysis/index.ts

@@ -22,5 +22,68 @@ export default [
         }
       }
     }
+  },
+  // 用户来源
+  {
+    url: '/analysis/userAccessSource',
+    method: 'get',
+    timeout,
+    response: () => {
+      return {
+        code: result_code,
+        data: [
+          { value: 335, name: 'analysis.directAccess' },
+          { value: 310, name: 'analysis.mailMarketing' },
+          { value: 234, name: 'analysis.allianceAdvertising' },
+          { value: 135, name: 'analysis.videoAdvertising' },
+          { value: 1548, name: 'analysis.searchEngines' }
+        ]
+      }
+    }
+  },
+  // 每周用户活跃量
+  {
+    url: '/analysis/weeklyUserActivity',
+    method: 'get',
+    timeout,
+    response: () => {
+      return {
+        code: result_code,
+        data: [
+          { value: 13253, name: 'analysis.monday' },
+          { value: 34235, name: 'analysis.tuesday' },
+          { value: 26321, name: 'analysis.wednesday' },
+          { value: 12340, name: 'analysis.thursday' },
+          { value: 24643, name: 'analysis.friday' },
+          { value: 1322, name: 'analysis.saturday' },
+          { value: 1324, name: 'analysis.sunday' }
+        ]
+      }
+    }
+  },
+  // 每月销售额
+  {
+    url: '/analysis/monthlySales',
+    method: 'get',
+    timeout,
+    response: () => {
+      return {
+        code: result_code,
+        data: [
+          { estimate: 100, actual: 120, name: 'analysis.january' },
+          { estimate: 120, actual: 82, name: 'analysis.february' },
+          { estimate: 161, actual: 91, name: 'analysis.march' },
+          { estimate: 134, actual: 154, name: 'analysis.april' },
+          { estimate: 105, actual: 162, name: 'analysis.may' },
+          { estimate: 160, actual: 140, name: 'analysis.june' },
+          { estimate: 165, actual: 145, name: 'analysis.july' },
+          { estimate: 114, actual: 250, name: 'analysis.august' },
+          { estimate: 163, actual: 134, name: 'analysis.september' },
+          { estimate: 185, actual: 56, name: 'analysis.october' },
+          { estimate: 118, actual: 99, name: 'analysis.november' },
+          { estimate: 123, actual: 123, name: 'analysis.december' }
+        ]
+      }
+    }
   }
 ] as MockMethod[]

+ 19 - 1
src/api/dashboard/analysis/index.ts

@@ -1,7 +1,25 @@
 import { useAxios } from '@/hooks/web/useAxios'
+import type {
+  AnalysisTotalTypes,
+  UserAccessSource,
+  WeeklyUserActivity,
+  MonthlySales
+} from './types'
 
 const { request } = useAxios()
 
 export const getCountApi = () => {
-  return request({ url: '/analysis/total', method: 'get' })
+  return request<AnalysisTotalTypes>({ url: '/analysis/total', method: 'get' })
+}
+
+export const getUserAccessSourceApi = () => {
+  return request<UserAccessSource[]>({ url: '/analysis/userAccessSource', method: 'get' })
+}
+
+export const getWeeklyUserActivityApi = () => {
+  return request<WeeklyUserActivity[]>({ url: '/analysis/weeklyUserActivity', method: 'get' })
+}
+
+export const getMonthlySalesApi = () => {
+  return request<MonthlySales[]>({ url: '/analysis/monthlySales', method: 'get' })
 }

+ 16 - 0
src/api/dashboard/analysis/types.ts

@@ -4,3 +4,19 @@ export type AnalysisTotalTypes = {
   moneys: number
   shoppings: number
 }
+
+export type UserAccessSource = {
+  value: number
+  name: string
+}
+
+export type WeeklyUserActivity = {
+  value: number
+  name: string
+}
+
+export type MonthlySales = {
+  name: string
+  estimate: number
+  actual: number
+}

+ 1 - 1
src/components/Highlight/src/Highlight.vue

@@ -52,7 +52,7 @@ export default defineComponent({
       const regexp = /^[0-9]*$/
       const nodes = textArray.map((t) => {
         if (regexp.test(t)) {
-          return unref(keyNodes)[Math.floor(Number(t))] || t
+          return unref(keyNodes)[t] || t
         }
         return t
       })

+ 1 - 1
src/hooks/web/useAxios.ts

@@ -7,7 +7,7 @@ import { config } from '@/config/axios/config'
 const { default_headers } = config
 
 export const useAxios = () => {
-  const request = (option: AxiosConfig): AxiosPromise => {
+  const request = <T>(option: AxiosConfig): AxiosPromise<T> => {
     const { url, method, params, data, headersType, responseType } = option
     return service({
       url: url,

+ 1 - 1
src/locales/en.ts

@@ -130,7 +130,7 @@ export default {
     yield: 'Yield',
     dynamic: 'Dynamic',
     push: 'push',
-    pushCode: 'Archer push code to GitHub'
+    pushCode: 'Archer push code to Github'
   },
   formDemo: {
     input: 'Input',

+ 87 - 5
src/views/Dashboard/Analysis.vue

@@ -3,13 +3,95 @@ import PanelGroup from './components/PanelGroup.vue'
 import { ElRow, ElCol, ElCard, ElSkeleton } from 'element-plus'
 import { Echart } from '@/components/Echart'
 import { pieOptions, barOptions, lineOptions } from './echarts-data'
-import { ref } from 'vue'
+import { ref, reactive } from 'vue'
+import {
+  getUserAccessSourceApi,
+  getWeeklyUserActivityApi,
+  getMonthlySalesApi
+} from '@/api/dashboard/analysis'
+import { set } from 'lodash-es'
+import { EChartsOption } from 'echarts'
+import { useI18n } from '@/hooks/web/useI18n'
+
+const { t } = useI18n()
 
 const loading = ref(true)
 
-setTimeout(() => {
+const pieOptionsData = reactive<EChartsOption>(pieOptions)
+
+// 用户来源
+const getUserAccessSource = async () => {
+  const res = await getUserAccessSourceApi().catch(() => {})
+  if (res) {
+    set(
+      pieOptionsData,
+      'legend.data',
+      res.data.map((v) => t(v.name))
+    )
+    set(pieOptionsData, 'series.data', res.data)
+  }
+}
+
+const barOptionsData = reactive<EChartsOption>(barOptions) as EChartsOption
+
+// 周活跃量
+const getWeeklyUserActivity = async () => {
+  const res = await getWeeklyUserActivityApi().catch(() => {})
+  if (res) {
+    set(
+      barOptionsData,
+      'xAxis.data',
+      res.data.map((v) => t(v.name))
+    )
+    set(barOptionsData, 'series', [
+      {
+        name: t('analysis.activeQuantity'),
+        data: res.data.map((v) => v.value),
+        type: 'bar'
+      }
+    ])
+  }
+}
+
+const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
+
+// 每月销售总额
+const getMonthlySales = async () => {
+  const res = await getMonthlySalesApi().catch(() => {})
+  if (res) {
+    set(
+      lineOptionsData,
+      'xAxis.data',
+      res.data.map((v) => t(v.name))
+    )
+    set(lineOptionsData, 'series', [
+      {
+        name: t('analysis.estimate'),
+        smooth: true,
+        type: 'line',
+        data: res.data.map((v) => v.estimate),
+        animationDuration: 2800,
+        animationEasing: 'cubicInOut'
+      },
+      {
+        name: t('analysis.actual'),
+        smooth: true,
+        type: 'line',
+        itemStyle: {},
+        data: res.data.map((v) => v.actual),
+        animationDuration: 2800,
+        animationEasing: 'quadraticOut'
+      }
+    ])
+  }
+}
+
+const getAllApi = async () => {
+  await Promise.all([getUserAccessSource(), getWeeklyUserActivity(), getMonthlySales()])
   loading.value = false
-}, 1000)
+}
+
+getAllApi()
 </script>
 
 <template>
@@ -25,14 +107,14 @@ setTimeout(() => {
     <ElCol :xl="14" :lg="14" :md="24" :sm="24" :xs="24">
       <ElCard shadow="hover" class="mb-20px">
         <ElSkeleton :loading="loading" animated>
-          <Echart :options="barOptions" :height="300" />
+          <Echart :options="barOptionsData" :height="300" />
         </ElSkeleton>
       </ElCard>
     </ElCol>
     <ElCol :span="24">
       <ElCard shadow="hover" class="mb-20px">
         <ElSkeleton :loading="loading" animated :rows="4">
-          <Echart :options="lineOptions" :height="350" />
+          <Echart :options="lineOptionsData" :height="350" />
         </ElSkeleton>
       </ElCard>
     </ElCol>