This commit is contained in:
zmj 2024-07-06 11:45:54 +08:00
parent 57fe95a96e
commit a3bb69ef63
8 changed files with 221 additions and 348 deletions

BIN
dist.rar Normal file

Binary file not shown.

View File

@ -90,92 +90,7 @@ const visitorOption: any = reactive({
// //
const colorList = ['#5DB1FF', '#4CD384', '#FFC46A', '#CAA5F1', '#FFC46A', '#4CD384', '#5DB1FF', '#CAA5F1'] const colorList = ['#5DB1FF', '#4CD384', '#FFC46A', '#CAA5F1', '#FFC46A', '#4CD384', '#5DB1FF', '#CAA5F1']
// , 访, , , , , , 退, 退, 访- // , 访, , , , , , 退, 退, 访-
const basicList = reactive([ const basicList = reactive([])
// {
// name: '访',
// type: 'people',
// icon: 'RectangleCopy',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'browse',
// icon: 'RectangleCopy49',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'newUser',
// icon: 'RectangleCopy53',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payPeople',
// icon: 'RectangleCopy5',
// num: 0,
// percent: 0
// },
// {
// name: '访-',
// type: 'payPercent',
// icon: 'RectangleCopy4',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payUser',
// icon: 'RectangleCopy7',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'rechargePeople',
// icon: 'RectangleCopy59',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payPrice',
// icon: 'RectangleCopy15',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativeUser',
// icon: 'RectangleCopy54',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativePayUser',
// icon: 'RectangleCopy7',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativeRechargePeople',
// icon: 'RectangleCopy6',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativePayPeople',
// icon: 'RectangleCopy9',
// num: 0,
// percent: 0
// }
])
@ -235,6 +150,7 @@ const getData2 = () => {
num: item.total_money, num: item.total_money,
} }
visitorOption.legend.data.push(item.title)
}) })
}) })
} }

View File

@ -253,6 +253,8 @@ const getData2 = () => {
num: item.total_money, num: item.total_money,
} }
visitorOption.legend.data.push(item.title)
}) })
}) })
} }

View File

@ -235,6 +235,8 @@ const getData2 = () => {
num: item.total_money, num: item.total_money,
} }
visitorOption.legend.data.push(item.title)
}) })
}) })
} }

View File

@ -258,6 +258,8 @@ const getData2 = () => {
num: item.total_money, num: item.total_money,
} }
visitorOption.legend.data.push(item.title)
}) })
}) })
} }

View File

@ -67,7 +67,7 @@ const visitorOption: any = reactive({
containLabel: true containLabel: true
}, },
legend: { legend: {
data: ['访问量'] data: []
}, },
itemStyle: { itemStyle: {
// //
@ -76,6 +76,8 @@ const visitorOption: any = reactive({
tooltip: { tooltip: {
trigger: 'axis' trigger: 'axis'
}, },
series: [ series: [
{ {
name: '访问量', name: '访问量',
@ -89,92 +91,7 @@ const visitorOption: any = reactive({
// //
const colorList = ['#5DB1FF', '#4CD384', '#FFC46A', '#CAA5F1', '#FFC46A', '#4CD384', '#5DB1FF', '#CAA5F1'] const colorList = ['#5DB1FF', '#4CD384', '#FFC46A', '#CAA5F1', '#FFC46A', '#4CD384', '#5DB1FF', '#CAA5F1']
// , 访, , , , , , 退, 退, 访- // , 访, , , , , , 退, 退, 访-
const basicList = reactive([ const basicList = reactive([])
// {
// name: '访',
// type: 'people',
// icon: 'RectangleCopy',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'browse',
// icon: 'RectangleCopy49',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'newUser',
// icon: 'RectangleCopy53',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payPeople',
// icon: 'RectangleCopy5',
// num: 0,
// percent: 0
// },
// {
// name: '访-',
// type: 'payPercent',
// icon: 'RectangleCopy4',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payUser',
// icon: 'RectangleCopy7',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'rechargePeople',
// icon: 'RectangleCopy59',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payPrice',
// icon: 'RectangleCopy15',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativeUser',
// icon: 'RectangleCopy54',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativePayUser',
// icon: 'RectangleCopy7',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativeRechargePeople',
// icon: 'RectangleCopy6',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativePayPeople',
// icon: 'RectangleCopy9',
// num: 0,
// percent: 0
// }
])
function getLastMonthRange() { function getLastMonthRange() {
// //
let today = new Date(); let today = new Date();
@ -230,6 +147,7 @@ const getData2 = () => {
num: item.total_money, num: item.total_money,
} }
visitorOption.legend.data.push(item.title)
}) })
}) })
} }

View File

@ -231,6 +231,7 @@ const getData2 = () => {
icon: 'RectangleCopy14', icon: 'RectangleCopy14',
num: item.total_money, num: item.total_money,
} }
visitorOption.legend.data.push(item.title)
}) })
}) })
} }

View File

@ -1,152 +1,61 @@
<template> <template>
<div class="workbench"> <div class="workbench">
<div class="lg:flex"> <el-card shadow="never" class=" !border-none">
<el-card class="!border-none mb-4 lg:mr-4 lg:w-[350px]" shadow="never">
<template #header>
<span class="card-title">版本信息</span>
</template>
<div>
<div class="flex leading-9">
<div class="w-20">当前版本</div>
<span> {{ workbenchData.version.version }}</span>
</div>
<div class="flex leading-9">
<div class="w-20">基于框架</div>
<span> {{ workbenchData.version.based }}</span>
</div>
<div class="flex leading-9">
<div class="w-20">获取渠道</div>
<div>
<a :href="workbenchData.version.channel.website" target="_blank">
<el-button type="success" size="small">官网</el-button>
</a>
<a class="ml-3" :href="workbenchData.version.channel.gitee" target="_blank">
<el-button type="danger" size="small">Gitee</el-button>
</a>
</div>
</div>
</div>
</el-card>
<el-card class="!border-none mb-4 flex-1" shadow="never">
<template #header>
<div>
<span class="card-title">今日数据</span>
<span class="text-tx-secondary text-xs ml-4">
更新时间{{ workbenchData.today.time }}
</span>
</div>
</template>
<div class="flex flex-wrap"> <div class="flex flex-wrap">
<div class="w-1/2 md:w-1/4"> <div class="w-1/5 flex mb-6" v-for="(item, index) in basicList" :key="index">
<div class="leading-10">访问量()</div> <div class="mr-2">
<div class="text-6xl">{{ workbenchData.today.today_visitor }}</div> <div class="rounded-full p-2" :style="{ 'background-color': colorList[index % 8] }">
<div class="text-tx-secondary text-xs"> <iconfont :iconName="item.icon" white className="text-6xl" />
总访问量{{ workbenchData.today.total_visitor }}
</div> </div>
</div> </div>
<div class="w-1/2 md:w-1/4">
<div class="leading-10">销售额()</div>
<div class="text-6xl">{{ workbenchData.today.today_sales }}</div>
<div class="text-tx-secondary text-xs">
总销售额{{ workbenchData.today.total_sales }}
</div>
</div>
<div class="w-1/2 md:w-1/4">
<div class="leading-10">订单量()</div>
<div class="text-6xl">{{ workbenchData.today.order_num }}</div>
<div class="text-tx-secondary text-xs">
总订单量{{ workbenchData.today.order_sum }}
</div>
</div>
<div class="w-1/2 md:w-1/4">
<div class="leading-10">新增用户</div>
<div class="text-6xl">{{ workbenchData.today.today_new_user }}</div>
<div class="text-tx-secondary text-xs">
总访用户{{ workbenchData.today.total_new_user }}
</div>
</div>
</div>
</el-card>
</div>
<div class="function mb-4">
<el-card class="flex-1 !border-none" shadow="never">
<template #header>
<span>常用功能</span>
</template>
<div class="flex flex-wrap">
<div v-for="item in workbenchData.menu" class="md:w-[12.5%] w-1/4 flex flex-col items-center"
:key="item">
<router-link :to="item.url" class="mb-3 flex flex-col items-center">
<image-contain width="40px" height="40px" :src="item?.image" />
<div class="mt-2">{{ item.name }}</div>
</router-link>
</div>
</div>
</el-card>
</div>
<div class="md:flex">
<el-card class="flex-1 !border-none md:mr-4 mb-4" shadow="never">
<template #header>
<span>访问量趋势图</span>
</template>
<div> <div>
<v-charts style="height: 350px" :option="workbenchData.visitorOption" :autoresize="true" /> <div class="text-info">{{ item.name }}</div>
<div class="text-6xl">{{ item.num }}</div>
<!-- <div class="text-info">环比增长: <span :class="item.percent > 0 ? 'text-success' : 'text-danger'">{{
item.percent }}%</span></div> -->
</div>
</div>
</div> </div>
</el-card> </el-card>
<el-card class="!border-none mb-4" shadow="never"> <el-card shadow="never" class="mt-4 !border-none">
<template #header>
<span>服务支持</span>
</template>
<div> <div>
<div v-for="(item, index) in workbenchData.support" :key="index"> <div class="mb-6 flex justify-between items-center">
<div class="flex items-center pb-10 pt-10" :class="{ <span class="text-2xl">趋势</span>
'border-b border-br': index == 0
}">
<image-contain :width="120" :height="120" class="flex-none" :src="item.image" />
<div class="ml-2">
<div>{{ item.title }}</div>
<div class="text-tx-regular text-xs mt-4">{{ item.desc }}</div>
</div>
</div>
</div> </div>
<v-charts style="height: 400px" :option="visitorOption" :autoresize="true" />
</div> </div>
</el-card> </el-card>
</div> </div>
</div>
</template> </template>
<script lang="ts" setup name="workbench"> <script lang="ts" setup name="statistics_user">
import { getWorkbench } from '@/api/app' import { getWorkbench } from '@/api/app'
import moment from 'moment'
import vCharts from 'vue-echarts' import vCharts from 'vue-echarts'
//
const workbenchData: any = reactive({
version: {
version: '', //
website: '', //
based: '',
channel: {
gitee: '',
website: ''
}
},
support: [],
today: {}, //
menu: [], //
visitor: [], // 访
article: [], //
visitorOption: { //
const visitorOption: any = reactive({
xAxis: { xAxis: {
type: 'category', type: 'category',
data: [0] data: [0],
axisLabel: {
rotate: 45,
color: '#333'
}
}, },
yAxis: { yAxis: {
type: 'value' type: 'value',
position: 'left',
axisLabel: {
formatter: '{value}'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
}, },
legend: { legend: {
data: ['访问量'] data: ['访问量']
@ -166,36 +75,159 @@ const workbenchData: any = reactive({
smooth: true smooth: true
} }
] ]
})
//
const colorList = ['#5DB1FF', '#4CD384', '#FFC46A', '#CAA5F1', '#FFC46A', '#4CD384', '#5DB1FF', '#CAA5F1']
// , 访, , , , , , 退, 退, 访-
const basicList = reactive([
// {
// name: '访',
// type: 'people',
// icon: 'RectangleCopy',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'browse',
// icon: 'RectangleCopy49',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'newUser',
// icon: 'RectangleCopy53',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payPeople',
// icon: 'RectangleCopy5',
// num: 0,
// percent: 0
// },
// {
// name: '访-',
// type: 'payPercent',
// icon: 'RectangleCopy4',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payUser',
// icon: 'RectangleCopy7',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'rechargePeople',
// icon: 'RectangleCopy59',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'payPrice',
// icon: 'RectangleCopy15',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativeUser',
// icon: 'RectangleCopy54',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativePayUser',
// icon: 'RectangleCopy7',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativeRechargePeople',
// icon: 'RectangleCopy6',
// num: 0,
// percent: 0
// },
// {
// name: '',
// type: 'cumulativePayPeople',
// icon: 'RectangleCopy9',
// num: 0,
// percent: 0
// }
])
function getLastMonthRange() {
//
let today = new Date();
//
let lastMonth = new Date(today.getFullYear(), today.getMonth() - 1, today.getDate());
// "--"
let formatDateString = (date) => {
let year = date.getFullYear();
let month = String(date.getMonth() + 1).padStart(2, '0'); // 0+10
let day = String(date.getDate()).padStart(2, '0'); // 0
return `${year}-${month}-${day}`;
};
//
let lastMonthFormatted = formatDateString(lastMonth);
let todayFormatted = formatDateString(today);
//
return [lastMonthFormatted, todayFormatted];
} }
})
//
const getData = () => {
getWorkbench()
.then((res: any) => {
workbenchData.version = res.version
workbenchData.today = res.today
workbenchData.menu = res.menu
workbenchData.visitor = res.visitor
workbenchData.support = res.support
const startEndTime = ref([new Date(), new Date()]);
const startEndTime2 = ref(getLastMonthRange());
const getData2 = () => {
let date = '';
if (startEndTime2.value[0] && startEndTime2.value[1]) date = moment(startEndTime2.value[0]).format('YYYY/MM/DD') + '-' + moment(startEndTime2.value[1]).format('YYYY/MM/DD');
getWorkbench({
date: date
}).then(res => {
// echarts // echarts
workbenchData.visitorOption.xAxis.data = [] visitorOption.xAxis.data = []
workbenchData.visitorOption.series[0].data = [] visitorOption.series = []
console.log(res)
visitorOption.xAxis.data = Object.keys(res[0].value)
// res.forEach((item, index) => {
res.visitor.date.reverse().forEach((item: any) => { visitorOption.series[index] = {
workbenchData.visitorOption.xAxis.data.push(item) type: 'line',
smooth: true,
data: Object.values(item.value),
name: item.title
}
basicList[index] = {
name: item.title,
type: 'payPrice',
icon: 'RectangleCopy14',
num: item.total_money,
}
visitorOption.legend.data.push(item.title)
}) })
res.visitor.list[0].data.forEach((item: any) => {
workbenchData.visitorOption.series[0].data.push(item)
})
})
.catch((err: any) => {
}) })
} }
onMounted(() => { onMounted(() => {
getData() getData2()
}) })
</script> </script>
<style lang="scss" scoped></style>