Skip to content

Commit

Permalink
feat(analytics): 1. 增加根据设备统计数据展示 2. 根据区域查询 增加根据城市查询
Browse files Browse the repository at this point in the history
  • Loading branch information
vaebe committed Jun 11, 2024
1 parent 7add6ee commit c700ab7
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 13 deletions.
25 changes: 22 additions & 3 deletions src/api/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Api from './base'
import type { ResultData } from './base'

export interface AnalyzeParams {
code: string
code?: string
dateType: '24h' | '7d' | '30d'
}

Expand All @@ -16,13 +16,32 @@ export function analyzeShortLinkAccessByTime(params: AnalyzeParams): Promise<Res
return Api.get('/analytics/clicksTime', { params })
}

export interface AnalyzeRegionParams extends AnalyzeParams {
type: 'countries' | 'cities'
}

export interface AnalyzeShortLinkAccessByRegionInfo {
clicks: number
countryCode: string
country: string
code: string
name: string
}

// 根据区域分析短链访问数据
export function analyzeShortLinkAccessByRegion(params: AnalyzeParams): Promise<ResultData<AnalyzeShortLinkAccessByRegionInfo[]>> {
export function analyzeShortLinkAccessByRegion(params: AnalyzeRegionParams): Promise<ResultData<AnalyzeShortLinkAccessByRegionInfo[]>> {
return Api.get('/analytics/clicksRegion', { params })
}

export interface AnalyzeDeviceParams extends AnalyzeParams {
type: 'devices' | 'browsers' | 'os'
}

export interface AnalyzeShortLinkAccessByDeviceInfo {
clicks: number
name: string
}

// 根据设备分析短链访问数据
export function analyzeShortLinkAccessByDevice(params: AnalyzeDeviceParams): Promise<ResultData<AnalyzeShortLinkAccessByDeviceInfo[]>> {
return Api.get('/analytics/clicksDevices', { params })
}
66 changes: 62 additions & 4 deletions src/views/analytics/components/VisitsDevice.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,70 @@
<script setup lang="ts">
import { computed, inject, onBeforeUnmount, ref, watch } from 'vue'
import type { AnalyzeDeviceParams, AnalyzeParams, AnalyzeShortLinkAccessByDeviceInfo } from '@/api/analytics.ts'
import { analyzeShortLinkAccessByDevice } from '@/api/analytics.ts'
const typeList = [{ label: 'Devices', value: 'devices' }, { label: 'Browsers', value: 'browsers' }, { label: 'OS', value: 'os' }]
const curType = ref<AnalyzeDeviceParams['type']>('devices')
const searchForm = inject<AnalyzeParams>('searchForm')
const list = ref<AnalyzeShortLinkAccessByDeviceInfo[]>([])
function getData() {
analyzeShortLinkAccessByDevice({ code: '', dateType: searchForm!.dateType, type: curType.value }).then((res) => {
if (res.code === 0)
list.value = res.data ?? []
})
}
const searchFormWatch = watch(() => searchForm, () => {
if (searchForm?.dateType)
getData()
}, { immediate: true, deep: true })
onBeforeUnmount(() => {
searchFormWatch()
})
const maxValue = computed(() => Math.max(...list.value.map(item => item.clicks)))
// 获取百分比
function getPercentage(item: AnalyzeShortLinkAccessByDeviceInfo) {
if (list.value?.length === 1) {
return 100
}
else {
const curValue = item.clicks ?? 0
return (curValue / maxValue.value) * 100
}
}
</script>

<template>
<div class="relative z-0 border border-gray-200 bg-white px-7 py-5 sm:rounded-lg sm:border-gray-100 sm:shadow-lg">
<p class="my-2">
<span>设备:</span>
</p>
<div class="relative z-0 border border-gray-200 bg-white px-7 py-5 sm:rounded-lg sm:border-gray-100 sm:shadow-lg">
<el-segmented v-model="curType" class="my-2" :options="typeList" block @change="getData" />

<el-scrollbar style="height: 40vh">
<div
v-for="item in list" :key="item.name"
class="group flex items-center justify-between mb-1 hover:bg-gray-50"
>
<div class="relative z-10 flex h-8 w-full max-w-[calc(100%-2rem)] items-center">
<div class="z-10 flex items-center space-x-2 px-2">
<div class="truncate text-sm text-gray-800 underline-offset-4 group-hover:underline">
{{ item.name }}
</div>
</div>
<div
class="absolute h-full origin-left rounded-sm bg-green-100"
:style="{ width: `${getPercentage(item)}%`, transform: 'scaleX(1)' }"
/>
</div>
<p class="z-10 px-2 text-sm text-gray-600">
{{ item.clicks }}
</p>
</div>
</el-scrollbar>
</div>
</template>

Expand Down
13 changes: 7 additions & 6 deletions src/views/analytics/components/VisitsRegion.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<script setup lang="ts">
import { computed, inject, onBeforeUnmount, ref, watch } from 'vue'
import type { AnalyzeParams, AnalyzeShortLinkAccessByRegionInfo } from '@/api/analytics.ts'
import type { AnalyzeParams, AnalyzeRegionParams, AnalyzeShortLinkAccessByRegionInfo } from '@/api/analytics.ts'
import { analyzeShortLinkAccessByRegion } from '@/api/analytics.ts'
const typeList = [{ label: 'Countries', value: 'countries' }, { label: 'Cities', value: 'cities' }]
const curType = ref<AnalyzeRegionParams['type']>('countries')
const searchForm = inject<AnalyzeParams>('searchForm')
const list = ref<AnalyzeShortLinkAccessByRegionInfo[]>([])
function getData() {
analyzeShortLinkAccessByRegion({ code: '', dateType: searchForm!.dateType }).then((res) => {
analyzeShortLinkAccessByRegion({ code: '', dateType: searchForm!.dateType, type: curType.value }).then((res) => {
if (res.code === 0)
list.value = res.data ?? []
})
Expand Down Expand Up @@ -42,9 +45,7 @@ function getIcon(code: string) {

<template>
<div class="relative z-0 border border-gray-200 bg-white px-7 py-5 sm:rounded-lg sm:border-gray-100 sm:shadow-lg">
<p class="my-2">
<span>国家</span>
</p>
<el-segmented v-model="curType" class="my-2" :options="typeList" block @change="getData" />

<el-scrollbar style="height: 40vh">
<div
Expand All @@ -55,7 +56,7 @@ function getIcon(code: string) {
<div class="z-10 flex items-center space-x-2 px-2">
<img :alt="item.countryCode" :src="getIcon(item.countryCode)" class="h-3 w-5">
<div class="truncate text-sm text-gray-800 underline-offset-4 group-hover:underline">
{{ item.country }}
{{ item.name }}
</div>
</div>
<div
Expand Down

0 comments on commit c700ab7

Please sign in to comment.