This commit is contained in:
gaofy 2023-12-22 17:15:25 +08:00
parent d0b6259cbb
commit 022661b58b
5 changed files with 390 additions and 11 deletions

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,95 @@
<template>
<div ref="chartDom" class="map-chart" style="width: 100%;height: 100%;"></div>
</template>
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import * as echarts from 'echarts'
import chinaJson from '@/assets/map/china.json'
const chartDom = ref()
onMounted(() => {
const data: any = []
chinaJson.features.forEach((item: any) => {
data.push({
name: item.properties.name,
value: Math.ceil(Math.random() * 100)
})
})
initMap({data})
})
function initMap(chartData: any) {
const chart = echarts.init(chartDom.value as HTMLElement);
chart.clear();
echarts.registerMap('china', chinaJson as any);
const option = {
tooltip: {
triggerOn: "mousemove",
formatter: function (e: any) {
return e.name + "<br />" + e.value + '所'
}
},
visualMap: {
show: false,
min: 0,
max: 100,
left: 'left',
top: 'bottom',
orient: 'vertical',
text: ['多', '少'],
realtime: false,
calculable: false,
inRange: {
color: ['#006080', '#abd9ef']
}
},
geo: {
map: "china",
roam: false,
scaleLimit: {
min: 1,
max: 2
},
zoom: 1.6,
top: 150,
label: {
show: true,
fontSize: 12,
color: "#ffffff",
textBorderWidth: 1,
textBorderColor: '#006080',
emphasis: {
color: "#006080",
textBorderColor: '#ffffff',
}
},
itemStyle: {
borderColor: "rgba(255, 255, 255, .2)",
emphasis: {
areaColor: "#f8b300"
}
}
},
series: [{
name: "确诊病例",
type: "map",
mapType: 'china',
geoIndex: 0,
data: chartData.data
}]
}
chart.setOption(option)
chart.resize()
window.addEventListener('resize', () => {
chart.resize()
})
chart.on('click', (params: any) => {
console.log('--------', params)
})
}
</script>
<style lang='scss' scoped></style>

View File

@ -0,0 +1,212 @@
<template>
<div class="chart-box">
<h3 class="title f20 main-color">新增用户统计</h3>
<div class="total-box">
<div class="total-item">
<p class="label">本日</p>
<p class="value">+ {{ total.day }}</p>
</div>
<div class="total-item">
<p class="label">本周</p>
<p class="value">+ {{ total.week }}</p>
</div>
<div class="total-item">
<p class="label">本月</p>
<p class="value">+ {{ total.month }}</p>
</div>
<div class="total-item">
<p class="label">本年</p>
<p class="value">+ {{ total.year }}</p>
</div>
</div>
<div class="date-btn text-color">
<span class="title">周新增用户</span>
<div class="btn-box">
<el-icon @click="setDate('up')">
<ArrowLeft />
</el-icon>
<el-date-picker v-model="currentMonth" format="第ww周" type="week" :editable="false" :clearable="false"
@change="getData" />
<el-icon @click="setDate('down')">
<ArrowRight />
</el-icon>
</div>
</div>
<div ref="chartDom" class="chart-dom"></div>
</div>
</template>
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import * as echarts from 'echarts'
import { dateFormater, getFirstDayOfWeek, getCurrentDate, getDays } from '@/utils/date-util';
const chartDom = ref()
const total = ref({
day: 2,
week: 8,
month: 32,
year: 103
})
const currentMonth = ref(new Date())
onMounted(() => {
getData(new Date())
})
function initChart(chartData: any) {
const chart = echarts.init(chartDom.value as HTMLElement);
chart.clear();
const option = {
color: ['#00aab7'],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
formatter: (params: any) => {
let str = dateFormater('yyyy-MM-dd', params[0].axisValue) + '<b style="padding: 0 10px;">' + getCurrentDate(params[0].axisValue) + '</b>'
params.forEach((item: any) => {
str += '<br>'
str += item.marker + item.seriesName + '' + item.value + '人'
})
return str
}
},
grid: {
left: 0,
right: 0,
bottom: 0,
top: 0,
containLabel: true,
},
xAxis: {
show: true,
type: 'category',
nameTextStyle: { color: '#909399' },
axisLine: { show: false, lineStyle: { color: '#006080', width: 2 } },
axisTick: { show: false },
axisLabel: { show: true, color: '#909399', formatter: (value: any) => getCurrentDate(value) },
splitLine: { show: false, lineStyle: { color: 'rgba(212, 130, 1, .05)', width: 1, type: 'solid' } },
data: chartData.xData,
},
yAxis: {
show: true,
type: 'value',
min: 0,
axisLine: { show: false, lineStyle: { color: '#006080', width: 2 } },
axisTick: { show: false },
axisLabel: { show: false },
splitLine: { show: false, lineStyle: { color: '#D4E8F0', width: 1, type: 'solid' } },
},
series: [{
name: chartData.dataName[0],
type: 'bar',
itemStyle: {
borderRadius: 10
},
data: chartData.data
}],
}
chart.setOption(option)
chart.resize()
window.addEventListener('resize', () => {
chart.resize()
})
}
const setDate = (type: string) => {
getData(getDays(currentMonth.value, type === 'up' ? -7 : 7))
}
const getData = (date: any) => {
currentMonth.value = new Date(date)
const dataName = ['新增用户']
const xData = []
const data = [] as any
for (let i = 1; i < 8; i++) {
xData.push(getFirstDayOfWeek(date, i))
data.push(Math.ceil(Math.random() * 16 + 2))
}
initChart({ dataName, xData, data })
}
</script>
<style lang='scss' scoped>
.chart-box {
position: relative;
width: 100%;
height: 100%;
padding: 20px 40px;
h3.title {
line-height: 30px;
}
.total-box {
width: 100%;
height: 120px;
display: flex;
justify-content: space-between;
align-items: center;
color: $text2-color;
font-size: 18px;
line-height: 2;
.total-item {
text-align: center;
.value {
font-size: 22px;
font-weight: 600;
color: #00aab7;
}
&:nth-child(odd) .value {
color: #f8b300;
}
}
}
.date-btn {
position: reactive;
width: 100%;
height: 50px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 1;
.title {
font-size: 18px;
}
.btn-box {
height: 30px;
display: flex;
align-items: center;
color: $text2-color;
&>:deep(.el-date-editor) {
font-size: 14px;
.el-input__wrapper {
box-shadow: none;
padding: 0;
.el-input__prefix,
.el-input__suffix {
display: none;
}
.el-input__inner {
cursor: pointer;
width: 100px;
color: $text2-color;
text-align: center;
}
}
}
.el-icon {
cursor: pointer;
}
}
}
.chart-dom {
width: 100%;
height: calc(100% - 200px);
}
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<div class="ststem-manage-page">
<div class="ststem-manage-page" :class="{'route-home': currentPage?.path === '/system-manage/system-home'}">
<div class="header-box">
<PageTabs ref="pageTabsRef" />
</div>
@ -12,26 +12,64 @@
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import type { MenuItem } from '@/utils/public-interface'
import { useRouter, useRoute } from 'vue-router'
import PageTabs from '@/components/page-tabs.vue'
const pageTabsRef = ref()
const router = useRouter()
const route = useRoute()
const pageTabsRef = ref()
const currentPage = ref<MenuItem>()
onMounted(() => {
//
pageTabsRef.value.setTab({
path: '/system-manage/system-home',
name: '后台首页',
})
//
if(route) {
currentPage.value = {name: (route.name || '') as string, path: route.path}
pageTabsRef.value.setTab(currentPage.value)
}
//
router.beforeEach((to, from, next) => {
currentPage.value = {name: (to.name || '') as string, path: to.path}
setTimeout(() => {
pageTabsRef.value && pageTabsRef.value.setTab(currentPage.value)
})
next()
})
})
// name
// path
</script>
<style lang='scss' scoped>
.ststem-manage-page {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.header-box {
width: 100%;
height: 50px;
margin-bottom: 10px;
}
.main-box {
flex-grow: 1;
width: 100%;
height: calc(100% - 60px);
margin-top: 10px;
background: white;
padding: 20px;
}
&.route-home {
padding-top: 10px;
.header-box {
display: none;
}
}
}
</style>

View File

@ -1,21 +1,23 @@
<template>
<div class="system-home-page">
<div class="left-box">
<div class="total-box block-border">
<div class="total-box block-border swing_skew_2" @click="router.push('/system-manage/user-list')">
<span class="label"><el-icon><UserFilled /></el-icon></span>
<span class="value">{{ total.user }}</span>
</div>
<div class="total-box block-border">
<div class="total-box block-border swing_skew_2" @click="router.push('/system-manage/hospitals')">
<span class="label"><el-icon><OfficeBuilding /></el-icon></span>
<span class="value">{{ total.hospitals }}</span>
</div>
<div class="chart-total-box">
<div class="chart-total-box swing_skew_2">
<div class="title">用户数据统计</div>
<div class="chart block-border"></div>
<div class="chart block-border">
<userChart />
</div>
</div>
</div>
<div class="right-box">
<div class="system-log-box block-border">
<div class="system-log-box block-border swing_skew_1">
<div class="title-box">
<span class="title"><el-icon><List /></el-icon></span>
<span class="more">更多</span>
@ -24,14 +26,21 @@
<SystemLogs />
</div>
</div>
<div class="map-box block-border"></div>
<div class="map-box block-border swing_skew_1">
<mapChart />
</div>
</div>
</div>
</template>
<script lang='ts' setup>
import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { useRouter } from 'vue-router'
import SystemLogs from "@/components/system-logs.vue"
import userChart from './chart/user-chart.vue'
import mapChart from './chart/map-chart.vue'
const router = useRouter()
const total = {
user: 300,
@ -52,12 +61,36 @@ const total = {
border-radius: 12px;
}
.left-box {
width: 670px;
width: 37%;
height: 100%;
.total-box {
cursor: pointer;
width: 100%;
height: 90px;
margin-bottom: 30px;
font-weight: 600;
color: $main-color;
padding: 0 30px;
display: flex;
justify-content: space-between;
align-items: center;
transition: all .6s;
&:hover {
background: rgba($main-color, .1);
transition: all .6s;
}
.label {
font-size: 22px;
display: flex;
align-items: center;
.el-icon {
font-size: 30px;
margin: 0 20px 0 10px;
}
}
.value {
font-size: 26px;
}
}
.chart-total-box {
width: 100%;
@ -77,7 +110,7 @@ const total = {
}
}
.right-box {
width: calc(100% - 700px);
width: calc(63% - 30px);
height: 100%;
.system-log-box {
width: 100%;