首页调整

This commit is contained in:
gaofy 2023-12-21 17:31:28 +08:00
parent b7d1036664
commit 69df0fbc66
7 changed files with 525 additions and 96 deletions

View File

@ -53,6 +53,25 @@ export function getFirstDayOfWeek(date: Date, i: number) {
const day = date.getDay() || 7; const day = date.getDay() || 7;
return new Date(date.getFullYear(), date.getMonth(), date.getDate() + i - day); return new Date(date.getFullYear(), date.getMonth(), date.getDate() + i - day);
} }
/**
*
* @returns
*/
const weekArray = ['周天', '周一', '周二', '周三', '周四', '周五', '周六'];
export function getCurrentDate(date: any) {
let myDate = new Date();
if (date) {
if (date instanceof Date) {
myDate = date;
} else {
date = date.replace(/-/g, '/');
myDate = new Date(date);
}
}
const days = myDate.getDay();
return weekArray[days];
}
/** /**
* *

View File

@ -3,7 +3,7 @@
<div class="background-box"> <div class="background-box">
<div class="left-content"> <div class="left-content">
<div class="header-box swing_skew_1"> <div class="header-box swing_skew_1">
<div class="header-item ="> <div class="header-item">
<span class="main-color f20" style="font-weight: 600;">{{ userInfo.name }}</span> <span class="main-color f20" style="font-weight: 600;">{{ userInfo.name }}</span>
<span class="text2-color f14">{{ userInfo.permissions }}</span> <span class="text2-color f14">{{ userInfo.permissions }}</span>
</div> </div>
@ -21,9 +21,15 @@
<div class="echart-item swing_skew_2"> <div class="echart-item swing_skew_2">
<NumberChart /> <NumberChart />
</div> </div>
<div class="echart-item swing_skew_2">
<NumberPieChart />
</div>
<div class="echart-item swing_skew_1"> <div class="echart-item swing_skew_1">
<TimeChart /> <TimeChart />
</div> </div>
<div class="echart-item swing_skew_1">
<TimeBarChart />
</div>
</div> </div>
</div> </div>
<div class="right-content"> <div class="right-content">
@ -49,7 +55,9 @@ import { onMounted, reactive, ref, toRefs, watch } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useLoginStore } from '@/stores/user-info-store' import { useLoginStore } from '@/stores/user-info-store'
import NumberChart from "./number-chart.vue"; import NumberChart from "./number-chart.vue";
import NumberPieChart from "./number-pie-chart.vue";
import TimeChart from "./time-chart.vue"; import TimeChart from "./time-chart.vue";
import TimeBarChart from "./time-bar-chart.vue";
import WeekCalendar from "./week-calendar.vue"; import WeekCalendar from "./week-calendar.vue";
import SystemLogs from "@/components/system-logs.vue"; import SystemLogs from "@/components/system-logs.vue";
@ -86,10 +94,11 @@ const total = ref(0) // 日历添加的记录提醒统计
justify-content: space-between; justify-content: space-between;
.header-item { .header-item {
width: calc(50% - 10px); width: calc(100% - 600px);
height: 100%; height: 100%;
border: 1px solid $border-color; border: 1px solid $border-color;
border-radius: 5px; border-radius: 5px;
box-shadow: 1px 1px 5px $border2-color;
padding: 0 90px; padding: 0 90px;
line-height: 1.5; line-height: 1.5;
display: flex; display: flex;
@ -97,6 +106,7 @@ const total = ref(0) // 日历添加的记录提醒统计
justify-content: center; justify-content: center;
&~.header-item { &~.header-item {
width: 580px;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
@ -108,11 +118,24 @@ const total = ref(0) // 日历添加的记录提醒统计
width: 100%; width: 100%;
height: calc(100% - 160px); height: calc(100% - 160px);
margin-top: 20px; margin-top: 20px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.echart-item { .echart-item {
width: 100%; width: calc(100% - 600px);
height: calc(50% - 20px); height: calc(50% - 10px);
margin-top: 20px; border: 1px solid $border-color;
border-radius: 5px;
padding: 20px;
box-shadow: 1px 1px 5px $border2-color;
&:nth-child(even) {
width: 580px;
}
&:nth-child(n + 3) {
margin-top: 20px;
}
} }
} }
} }

View File

@ -1,20 +1,14 @@
<template> <template>
<div class="chart-box"> <div class="chart-box">
<div class="date-btn text-color"> <div class="date-btn text-color">
<div :class="{'text2-color': calcTime(upMonth)}" @click="getData(upMonth)"> <div class="btn-box">
<p>{{ dateFormater('yyyy年MM月', upMonth) }}</p> <el-icon @click="getData(upMonth)"><ArrowLeft /></el-icon>
<el-icon><ArrowLeft /></el-icon> <el-date-picker v-model="currentMonth" format="YYYY年MM月" type="month" :editable="false" :clearable="false" @change="getData" />
</div> <el-icon @click="getData(downMonth)"><ArrowRight /></el-icon>
<div :class="{'text2-color': calcTime(downMonth)}" style="text-align: right;" @click="getData(downMonth)">
<p>{{ dateFormater('yyyy年MM月', downMonth) }}</p>
<el-icon><ArrowRight /></el-icon>
</div> </div>
</div> </div>
<div ref="chartDom" class="chart-dom"></div> <div ref="chartDom" class="chart-dom"></div>
<div class="total"> <div class="total-mini">本月共计{{ total }}台手术</div>
<span class="f18">总计<br>手术<br>数量:</span>
<span style="font-size: 24px;font-weight: 600;">{{ total }}</span>
</div>
</div> </div>
</template> </template>
@ -61,7 +55,7 @@ function initChart(chartData: any) {
show: true, show: true,
type: 'category', type: 'category',
boundaryGap: false, boundaryGap: false,
nameTextStyle: { color: '#303133' }, nameTextStyle: { color: '#909399' },
axisLine: { show: true, lineStyle: { color: '#006080', width: 2 } }, axisLine: { show: true, lineStyle: { color: '#006080', width: 2 } },
axisTick: { show: false }, axisTick: { show: false },
axisLabel: { show: true, interval: chartData.xData.length - 2 }, axisLabel: { show: true, interval: chartData.xData.length - 2 },
@ -69,11 +63,11 @@ function initChart(chartData: any) {
data: chartData.xData, data: chartData.xData,
}, },
yAxis: { yAxis: {
name: '手术数量/台', name: '数量',
show: true, show: true,
type: 'value', type: 'value',
min: 0, min: 0,
nameTextStyle: { color: '#303133', align: 'left', verticalAlign: 'top', padding: [0, 20] }, nameTextStyle: { color: '#909399', align: 'center', verticalAlign: 'top', padding: [0, 0] },
axisLine: { show: true, lineStyle: { color: '#006080', width: 2 } }, axisLine: { show: true, lineStyle: { color: '#006080', width: 2 } },
axisTick: { show: false }, axisTick: { show: false },
axisLabel: { show: false }, axisLabel: { show: false },
@ -145,33 +139,45 @@ const getData = (date: any) => {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
z-index: 1; z-index: 1;
&>div { .btn-box {
cursor: pointer; height: 30px;
p { display: flex;
margin-bottom: 10px; align-items: center;
font-weight: 600; 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 { .chart-dom {
width: calc(100% - 180px); width: 100%;
height: 100%; height: 100%;
} }
.total { .total-mini {
flex-shrink: 0; position: absolute;
width: 160px; top: 0;
height: 80%; right: 40px;
border: 2px solid $main-color;
border-radius: 5px;
background: rgba($main-color, .1);
color: $main-color; color: $main-color;
display: flex; border: 1px solid $main-color;
flex-direction: column; font-size: 14px;
justify-content: space-evenly; padding: 3px 8px;
align-items: center;
span {
text-align: center;
}
} }
} }
</style> </style>

View File

@ -0,0 +1,169 @@
<template>
<div class="chart-box">
<div class="date-btn text-color">
<div class="btn-box">
<el-icon @click="getData(upMonth)">
<ArrowLeft />
</el-icon>
<el-date-picker v-model="currentMonth" format="YYYY年MM月" type="month" :editable="false" :clearable="false" @change="getData" />
<el-icon @click="getData(downMonth)">
<ArrowRight />
</el-icon>
</div>
</div>
<div class="total-box">
<div class="total-item" v-for="item in pieData" :key="item.name">{{ item.name }}:{{ item.value }}</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, getMonthDays } from '@/utils/date-util';
const chartDom = ref()
const currentMonth = ref(new Date())
const upMonth = ref()
const downMonth = ref()
const pieData = ref([] as any)
onMounted(() => {
getData(new Date())
})
function initChart(chartData: any) {
const chart = echarts.init(chartDom.value as HTMLElement);
chart.clear();
const option = {
color: chartData.color,
tooltip: {
trigger: 'item',
formatter: (params: any) => {
return params.marker + params.name + '<br>数量:' + params.value + '<br>占比:' + params.percent + '%'
}
},
grid: {
left: 0,
right: 0,
bottom: 0,
top: 0,
containLabel: true,
},
series: [{
type: 'pie',
center: ['68%', '50%'],
radius: ['0%', '70%'],
clockwise: true,
label: {
show: true,
position: 'outter',
color: 'inherit',
overflow: 'break',
formatter: function (params: any) {
return params.name + params.percent + '%'
}
},
labelLine: {
show: false,
length: 3,
length2: 0,
smooth: true,
},
data: chartData.data
}],
};
chart.setOption(option);
chart.resize();
window.addEventListener('resize', () => {
chart.resize();
});
}
const getData = (date: any) => {
currentMonth.value = new Date(date)
upMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() - 1, 1)
downMonth.value = new Date(currentMonth.value.getFullYear(), currentMonth.value.getMonth() + 1, 1)
const types = ['心脏病手术', '骨科手术', '阑尾炎手术']
const color = ['#ffde69', '#f8b300', '#006080']
pieData.value = []
types.forEach((item: string, index: number) => {
pieData.value.push({value: Math.ceil(Math.random() * 10), name: item, itemStyle: {
color: color[index]
}})
})
initChart({ data: pieData.value, color })
}
</script>
<style lang='scss' scoped>
.chart-box {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.date-btn {
position: absolute;
height: 50px;
top: 0;
left: 20px;
right: 20px;
display: flex;
z-index: 1;
.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: 100%;
}
.total-box {
position: absolute;
width: 30%;
top: 30px;
left: 20px;
bottom: 0;
color: $text2-color;
font-size: 14px;
display: flex;
flex-direction: column;
justify-content: center;
.total-item {
padding: 5px 0;
}
}
}</style>

View File

@ -0,0 +1,200 @@
<template>
<div class="chart-box">
<div class="date-btn text-color">
<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 currentMonth = ref(new Date())
onMounted(() => {
getData(new Date())
})
// true
function calcTime(time: any) {
return Boolean(new Date().getTime() < new Date(time).getTime())
}
function initChart(chartData: any) {
const chart = echarts.init(chartDom.value as HTMLElement);
chart.clear();
const option = {
color: ['#006080', '#f8b300'],
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
}
},
legend: {
right: 50,
data: chartData.dataName
},
grid: {
left: 20,
right: 50,
bottom: 5,
top: 50,
containLabel: true,
},
xAxis: {
name: '日期',
show: true,
type: 'category',
nameTextStyle: { color: '#909399' },
axisLine: { show: true, lineStyle: { color: '#006080', width: 2 } },
axisTick: { show: false },
axisLabel: { show: true, color: '#909399', formatter: (value: any) => getCurrentDate(value) },
splitLine: { show: true, lineStyle: { color: 'rgba(212, 130, 1, .05)', width: 1, type: 'solid' } },
data: chartData.xData,
},
yAxis: {
name: '时间',
show: true,
type: 'value',
min: 0,
nameTextStyle: { color: '#909399', align: 'center', verticalAlign: 'top', padding: [0, 0] },
axisLine: { show: true, 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',
label: {
show: true,
rotate: -90,
align: 'left',
verticalAlign: 'center',
position: 'insideTop',
color: '#ffffff',
textBorderColor: '#006080',
textBorderWidth: 3,
formatter: (params: any) => params.value.toFixed(0) + 'h' + Number((params.value % 1).toFixed(1)) * 60 + 'm'
},
data: chartData.data[0]
},
{
name: chartData.dataName[1],
type: 'bar',
label: {
show: true,
rotate: -90,
align: 'left',
verticalAlign: 'center',
position: 'insideTop',
color: '#ffffff',
textBorderColor: '#f8b300',
textBorderWidth: 3,
formatter: (params: any) => params.value.toFixed(0) + 'h' + Number((params.value % 1).toFixed(1)) * 60 + 'm'
},
data: chartData.data[1]
}],
};
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[0].push(Number((Math.random() * 16 + 2).toFixed(1)))
data[1].push(Number((Math.random() * 16 + 2).toFixed(1)))
}
initChart({ dataName, xData, data })
}
</script>
<style lang='scss' scoped>
.chart-box {
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.date-btn {
position: absolute;
width: 150px;
height: 50px;
top: 0;
left: 20px;
display: flex;
z-index: 1;
.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: calc(100% - 180px);
width: 100%;
height: 100%;
}
}</style>

View File

@ -1,20 +1,18 @@
<template> <template>
<div class="chart-box"> <div class="chart-box">
<div class="date-btn text-color"> <div class="date-btn text-color">
<div :class="{'text2-color': calcTime(upMonth)}" @click="getData(upMonth)"> <div class="btn-box">
<p>{{ dateFormater('yyyy年MM月', upMonth) }}</p> <el-icon @click="getData(upMonth)">
<el-icon><ArrowLeft /></el-icon> <ArrowLeft />
</div> </el-icon>
<div :class="{'text2-color': calcTime(downMonth)}" style="text-align: right;" @click="getData(downMonth)"> <el-date-picker v-model="currentMonth" format="YYYY年MM月" type="month" :editable="false" :clearable="false" @change="getData" />
<p>{{ dateFormater('yyyy年MM月', downMonth) }}</p> <el-icon @click="getData(downMonth)">
<el-icon><ArrowRight /></el-icon> <ArrowRight />
</el-icon>
</div> </div>
</div> </div>
<div ref="chartDom" class="chart-dom"></div> <div ref="chartDom" class="chart-dom"></div>
<div class="total"> <div class="total-mini">本月共计{{ total.toFixed(0) }}小时{{ Number((total % 1).toFixed(1)) * 60 }}分钟</div>
<span class="f18">总计<br>手术<br>时长:</span>
<span style="font-size: 24px;font-weight: 600;">{{ total.toFixed(0) }}h<br>{{ Number((total % 1).toFixed(1)) * 60 }}min</span>
</div>
</div> </div>
</template> </template>
@ -34,10 +32,6 @@ onMounted(() => {
getData(new Date()) getData(new Date())
}) })
// true
function calcTime(time: any) {
return Boolean(new Date().getTime() < new Date(time).getTime())
}
function initChart(chartData: any) { function initChart(chartData: any) {
const chart = echarts.init(chartDom.value as HTMLElement); const chart = echarts.init(chartDom.value as HTMLElement);
chart.clear(); chart.clear();
@ -61,7 +55,7 @@ function initChart(chartData: any) {
show: true, show: true,
type: 'category', type: 'category',
boundaryGap: false, boundaryGap: false,
nameTextStyle: { color: '#303133' }, nameTextStyle: { color: '#909399' },
axisLine: { show: true, lineStyle: { color: '#D58301', width: 2 } }, axisLine: { show: true, lineStyle: { color: '#D58301', width: 2 } },
axisTick: { show: false }, axisTick: { show: false },
axisLabel: { show: true, interval: chartData.xData.length - 2 }, axisLabel: { show: true, interval: chartData.xData.length - 2 },
@ -69,11 +63,11 @@ function initChart(chartData: any) {
data: chartData.xData, data: chartData.xData,
}, },
yAxis: { yAxis: {
name: '手术时长/h', name: '时间',
show: true, show: true,
type: 'value', type: 'value',
min: 0, min: 0,
nameTextStyle: { color: '#303133', align: 'left', verticalAlign: 'top', padding: [0, 20] }, nameTextStyle: { color: '#909399', align: 'center', verticalAlign: 'top', padding: [0, 0] },
axisLine: { show: true, lineStyle: { color: '#D58301', width: 2 } }, axisLine: { show: true, lineStyle: { color: '#D58301', width: 2 } },
axisTick: { show: false }, axisTick: { show: false },
axisLabel: { show: false }, axisLabel: { show: false },
@ -120,7 +114,7 @@ const getData = (date: any) => {
let num = 0 let num = 0
for (let i = 0; i < days; i++) { for (let i = 0; i < days; i++) {
xData.push((i < 9 ? '0' : '') + (i + 1)) xData.push((i < 9 ? '0' : '') + (i + 1))
data.push( Number( (Math.random() * 16 + 2).toFixed(1) ) ) data.push(Number((Math.random() * 16 + 2).toFixed(1)))
num += data[i] num += data[i]
} }
total.value = Number(num.toFixed(1)) total.value = Number(num.toFixed(1))
@ -129,49 +123,66 @@ const getData = (date: any) => {
</script> </script>
<style lang='scss' scoped> <style lang='scss' scoped>
.chart-box { .chart-box {
position: relative; position: relative;
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.date-btn {
position: absolute;
height: 50px;
top: 0;
left: 20px;
right: 230px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; z-index: 1;
.date-btn {
position: absolute; .btn-box {
height: 50px; height: 30px;
top: 0;
left: 20px;
right: 230px;
display: flex; display: flex;
justify-content: space-between; align-items: center;
z-index: 1; color: $text2-color;
&>div {
cursor: pointer; &>:deep(.el-date-editor) {
p { font-size: 14px;
margin-bottom: 10px; .el-input__wrapper {
font-weight: 600; 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;
}
} }
} }
}
.chart-dom { .el-icon {
width: calc(100% - 180px); cursor: pointer;
height: 100%;
}
.total {
flex-shrink: 0;
width: 160px;
height: 80%;
border: 2px solid #D58301;
border-radius: 5px;
background: rgba(#D58301, .1);
color: #D58301;
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
span {
text-align: center;
} }
} }
} }
</style>
.chart-dom {
width: 100%;
height: 100%;
}
.total-mini {
position: absolute;
top: 0;
right: 40px;
color: #D58301;
border: 1px solid #D58301;
font-size: 14px;
padding: 3px 8px;
}
}</style>

View File

@ -118,6 +118,7 @@ function queryData(e: any) {
} }
obj.data.push(data) obj.data.push(data)
} }
obj.data.reverse()
tableData.value.push(obj) tableData.value.push(obj)
} }
} }