feat: mp statistics init
							parent
							
								
									1b1424b79a
								
							
						
					
					
						commit
						7f7281355c
					
				|  | @ -14,4 +14,54 @@ export function formatToDate(date?: dayjs.ConfigType, format = DATE_FORMAT): str | |||
|   return dayjs(date).format(format) | ||||
| } | ||||
| 
 | ||||
| export function beginOfDay(date) { | ||||
|   return new Date(date.getFullYear(), date.getMonth(), date.getDate()) | ||||
| } | ||||
| 
 | ||||
| export function endOfDay(date) { | ||||
|   return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999) | ||||
| } | ||||
| 
 | ||||
| export function betweenDay(date1, date2) { | ||||
|   date1 = convertDate(date1) | ||||
|   date2 = convertDate(date2) | ||||
|   // 计算差值
 | ||||
|   return Math.floor((date2.getTime() - date1.getTime()) / (24 * 3600 * 1000)) | ||||
| } | ||||
| 
 | ||||
| export function formatDate(date, fmt) { | ||||
|   date = convertDate(date) | ||||
|   const o = { | ||||
|     'M+': date.getMonth() + 1, //月份
 | ||||
|     'd+': date.getDate(), //日
 | ||||
|     'H+': date.getHours(), //小时
 | ||||
|     'm+': date.getMinutes(), //分
 | ||||
|     's+': date.getSeconds(), //秒
 | ||||
|     'q+': Math.floor((date.getMonth() + 3) / 3), //季度
 | ||||
|     S: date.getMilliseconds() //毫秒
 | ||||
|   } | ||||
|   if (/(y+)/.test(fmt)) { | ||||
|     // 年份
 | ||||
|     fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)) | ||||
|   } | ||||
|   for (const k in o) { | ||||
|     if (new RegExp('(' + k + ')').test(fmt)) { | ||||
|       fmt = fmt.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)) | ||||
|     } | ||||
|   } | ||||
|   return fmt | ||||
| } | ||||
| 
 | ||||
| export function addTime(date, time) { | ||||
|   date = convertDate(date) | ||||
|   return new Date(date.getTime() + time) | ||||
| } | ||||
| 
 | ||||
| export function convertDate(date) { | ||||
|   if (typeof date === 'string') { | ||||
|     return new Date(date) | ||||
|   } | ||||
|   return date | ||||
| } | ||||
| 
 | ||||
| export const dateUtil = dayjs | ||||
|  |  | |||
|  | @ -0,0 +1,69 @@ | |||
| <!-- <template> | ||||
|   <Card title="接口分析数据" :loading="loading"> | ||||
|     <div ref="chartRef" :style="{ width, height }"></div> | ||||
|   </Card> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import { Ref, ref, watch } from 'vue' | ||||
| import { Card } from 'ant-design-vue' | ||||
| import { useECharts } from '@/hooks/web/useECharts' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   loading: Boolean, | ||||
|   newUser: propTypes.array, | ||||
|   cancelUser: propTypes.array, | ||||
|   width: propTypes.string.def('100%'), | ||||
|   height: propTypes.string.def('300px') | ||||
| }) | ||||
| 
 | ||||
| const chartRef = ref<HTMLDivElement | null>(null) | ||||
| const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>) | ||||
| 
 | ||||
| const newUserData = ref<any[]>(props.newUser) | ||||
| const cancelUserData = ref<any[]>(props.cancelUser) | ||||
| 
 | ||||
| watch( | ||||
|   () => props.loading, | ||||
|   () => { | ||||
|     if (props.loading) { | ||||
|       return | ||||
|     } | ||||
|     setOptions({ | ||||
|       color: ['#67C23A', '#e5323e', '#E6A23C', '#409EFF'], | ||||
|       legend: { | ||||
|         data: ['被动回复用户消息的次数', '失败次数', '最大耗时', '总耗时'] | ||||
|       }, | ||||
|       tooltip: {}, | ||||
|       xAxis: { | ||||
|         data: [] // X 轴的日期范围 | ||||
|       }, | ||||
|       yAxis: {}, | ||||
|       series: [ | ||||
|         { | ||||
|           name: '被动回复用户消息的次数', | ||||
|           type: 'bar', | ||||
|           barGap: 0, | ||||
|           data: [] // 被动回复用户消息的次数的数据 | ||||
|         }, | ||||
|         { | ||||
|           name: '失败次数', | ||||
|           type: 'bar', | ||||
|           data: [] // 失败次数的数据 | ||||
|         }, | ||||
|         { | ||||
|           name: '最大耗时', | ||||
|           type: 'bar', | ||||
|           data: [] // 最大耗时的数据 | ||||
|         }, | ||||
|         { | ||||
|           name: '总耗时', | ||||
|           type: 'bar', | ||||
|           data: [] // 总耗时的数据 | ||||
|         } | ||||
|       ] | ||||
|     }) | ||||
|   }, | ||||
|   { immediate: true } | ||||
| ) | ||||
| </script> --> | ||||
|  | @ -0,0 +1,62 @@ | |||
| <!-- <template> | ||||
|   <Card title="消息概况数据" :loading="loading"> | ||||
|     <div ref="chartRef" :style="{ width, height }"></div> | ||||
|   </Card> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import { Ref, ref, watch } from 'vue' | ||||
| import { Card } from 'ant-design-vue' | ||||
| import { useECharts } from '@/hooks/web/useECharts' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   loading: Boolean, | ||||
|   newUser: propTypes.array, | ||||
|   cancelUser: propTypes.array, | ||||
|   width: propTypes.string.def('100%'), | ||||
|   height: propTypes.string.def('300px') | ||||
| }) | ||||
| 
 | ||||
| const chartRef = ref<HTMLDivElement | null>(null) | ||||
| const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>) | ||||
| 
 | ||||
| const newUserData = ref<any[]>(props.newUser) | ||||
| const cancelUserData = ref<any[]>(props.cancelUser) | ||||
| 
 | ||||
| watch( | ||||
|   () => props.loading, | ||||
|   () => { | ||||
|     if (props.loading) { | ||||
|       return | ||||
|     } | ||||
|     setOptions({ | ||||
|       color: ['#67C23A', '#e5323e'], | ||||
|       legend: { | ||||
|         data: ['用户发送人数', '用户发送条数'] | ||||
|       }, | ||||
|       tooltip: {}, | ||||
|       xAxis: { | ||||
|         data: [] // X 轴的日期范围 | ||||
|       }, | ||||
|       yAxis: { | ||||
|         minInterval: 1 | ||||
|       }, | ||||
|       series: [ | ||||
|         { | ||||
|           name: '用户发送人数', | ||||
|           type: 'line', | ||||
|           smooth: true, | ||||
|           data: newUserData.value // 用户发送人数的数据 | ||||
|         }, | ||||
|         { | ||||
|           name: '用户发送条数', | ||||
|           type: 'line', | ||||
|           smooth: true, | ||||
|           data: cancelUserData.value // 用户发送条数的数据 | ||||
|         } | ||||
|       ] | ||||
|     }) | ||||
|   }, | ||||
|   { immediate: true } | ||||
| ) | ||||
| </script> --> | ||||
|  | @ -0,0 +1,73 @@ | |||
| <!-- <template> | ||||
|   <Card title="累计用户数据" :loading="loading"> | ||||
|     <div ref="chartRef" :style="{ width, height }"></div> | ||||
|   </Card> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import { Ref, onMounted, ref, watch } from 'vue' | ||||
| import { Card } from 'ant-design-vue' | ||||
| import { useECharts } from '@/hooks/web/useECharts' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { getUserCumulate } from '@/api/mp/statistics' | ||||
| import { beginOfDay, endOfDay, formatToDateTime } from '@/utils/dateUtil' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   loading: Boolean, | ||||
|   accountId: propTypes.number, | ||||
|   dataTime: { | ||||
|     type: Array as PropType<Date[]>, | ||||
|     default: () => [ | ||||
|       beginOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24 * 7)), // -7 天 | ||||
|       endOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24)) | ||||
|     ] | ||||
|   }, | ||||
|   width: propTypes.string.def('100%'), | ||||
|   height: propTypes.string.def('300px') | ||||
| }) | ||||
| 
 | ||||
| const chartRef = ref<HTMLDivElement | null>(null) | ||||
| const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>) | ||||
| 
 | ||||
| const optionsData = ref() | ||||
| 
 | ||||
| async function initData() { | ||||
|   const res = await getUserCumulate({ | ||||
|     accountId: props.accountId, | ||||
|     date: [formatToDateTime(props.dataTime[0]), formatToDateTime(props.dataTime[1])] | ||||
|   }) | ||||
|   optionsData.value = res.cumulateUser | ||||
| } | ||||
| watch( | ||||
|   () => props.loading, | ||||
|   () => { | ||||
|     if (props.loading) { | ||||
|       return | ||||
|     } | ||||
|     setOptions({ | ||||
|       legend: { | ||||
|         data: ['累计用户量'] | ||||
|       }, | ||||
|       xAxis: { | ||||
|         type: 'category', | ||||
|         data: optionsData.value | ||||
|       }, | ||||
|       yAxis: { | ||||
|         minInterval: 1 | ||||
|       }, | ||||
|       series: [ | ||||
|         { | ||||
|           name: '累计用户量', | ||||
|           data: [], // 累计用户量的数据 | ||||
|           type: 'line', | ||||
|           smooth: true | ||||
|         } | ||||
|       ] | ||||
|     }) | ||||
|   }, | ||||
|   { immediate: true } | ||||
| ) | ||||
| 
 | ||||
| onMounted(async () => { | ||||
|   await initData() | ||||
| }) | ||||
| </script> --> | ||||
|  | @ -0,0 +1,86 @@ | |||
| <!-- <template> | ||||
|   <Card title="用户增减数据" :loading="loading"> | ||||
|     <div ref="chartRef" :style="{ width, height }"></div> | ||||
|   </Card> | ||||
| </template> | ||||
| <script lang="ts" setup> | ||||
| import { Ref, onMounted, ref, watch } from 'vue' | ||||
| import { Card } from 'ant-design-vue' | ||||
| import { useECharts } from '@/hooks/web/useECharts' | ||||
| import { propTypes } from '@/utils/propTypes' | ||||
| import { getUserSummary } from '@/api/mp/statistics' | ||||
| import { addTime, beginOfDay, betweenDay, endOfDay, formatDate, formatToDateTime } from '@/utils/dateUtil' | ||||
| 
 | ||||
| const props = defineProps({ | ||||
|   loading: Boolean, | ||||
|   accountId: propTypes.number, | ||||
|   dataTime: { | ||||
|     type: Array as PropType<Date[]>, | ||||
|     default: () => [ | ||||
|       beginOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24 * 7)), // -7 天 | ||||
|       endOfDay(new Date(new Date().getTime() - 3600 * 1000 * 24)) | ||||
|     ] | ||||
|   }, | ||||
|   width: propTypes.string.def('100%'), | ||||
|   height: propTypes.string.def('300px') | ||||
| }) | ||||
| 
 | ||||
| const chartRef = ref<HTMLDivElement | null>(null) | ||||
| const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>) | ||||
| 
 | ||||
| const optionsData = ref() | ||||
| 
 | ||||
| const xAxisDate = ref() | ||||
| 
 | ||||
| async function initData() { | ||||
|   const res = await getUserSummary({ | ||||
|     accountId: props.accountId, | ||||
|     date: [formatToDateTime(props.dataTime[0]), formatToDateTime(props.dataTime[1])] | ||||
|   }) | ||||
|   optionsData.value = res | ||||
|   xAxisDate.value = [] | ||||
|   const days = betweenDay(props.dataTime[0], props.dataTime[1]) // 相差天数 | ||||
|   for (let i = 0; i <= days; i++) { | ||||
|     xAxisDate.value.push(formatDate(addTime(props.dataTime[0], 3600 * 1000 * 24 * i), 'yyyy-MM-dd')) | ||||
|   } | ||||
| } | ||||
| watch( | ||||
|   () => props.loading, | ||||
|   () => { | ||||
|     if (props.loading) { | ||||
|       return | ||||
|     } | ||||
|     setOptions({ | ||||
|       color: ['#67C23A', '#e5323e'], | ||||
|       legend: { | ||||
|         data: ['新增用户', '取消关注的用户'] | ||||
|       }, | ||||
|       tooltip: {}, | ||||
|       xAxis: { | ||||
|         data: xAxisDate.value // X 轴的日期范围 | ||||
|       }, | ||||
|       yAxis: { | ||||
|         minInterval: 1 | ||||
|       }, | ||||
|       series: [ | ||||
|         { | ||||
|           name: '新增用户', | ||||
|           type: 'bar', | ||||
|           barGap: 0, | ||||
|           data: optionsData.value.newUserData // 新增用户的数据 | ||||
|         }, | ||||
|         { | ||||
|           name: '取消关注的用户', | ||||
|           type: 'bar', | ||||
|           data: optionsData.value.cancelUserData // 取消关注的用户的数据 | ||||
|         } | ||||
|       ] | ||||
|     }) | ||||
|   }, | ||||
|   { immediate: true } | ||||
| ) | ||||
| 
 | ||||
| onMounted(async () => { | ||||
|   await initData() | ||||
| }) | ||||
| </script> --> | ||||
|  | @ -1,3 +1,20 @@ | |||
| <template> | ||||
|   <div>开发中</div> | ||||
| <!-- <template> | ||||
|   <div> | ||||
|     <UserSummaryChart class="md:w-1/2 w-full" :loading="loading" :accountId="accountId" /> | ||||
|     <UserCumulateChart class="md:w-1/2 w-full" :loading="loading" :accountId="accountId" /> | ||||
|     <UpstreamMessageChart class="md:w-1/2 w-full" :loading="loading" :accountId="accountId" /> | ||||
|     <InterfaceSummaryChart class="md:w-1/2 w-full" :loading="loading" :accountId="accountId" /> | ||||
|   </div> | ||||
| </template> | ||||
| <script lang="ts" setup name="Statistics"> | ||||
| import { ref } from 'vue' | ||||
| import UserSummaryChart from './components/UserSummaryChart.vue' | ||||
| import UserCumulateChart from './components/UserCumulateChart.vue' | ||||
| import UpstreamMessageChart from './components/UpstreamMessageChart.vue' | ||||
| import InterfaceSummaryChart from './components/InterfaceSummaryChart.vue' | ||||
| 
 | ||||
| const loading = ref(true) | ||||
| 
 | ||||
| const accountId = ref(1) | ||||
| </script> --> | ||||
| <template><div>开发中</div></template> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 xingyu
						xingyu