Merge branch 'lx' of http://xny.yj-3d.com:3000/taoge_xiaodi/maintenance_system into tcy
This commit is contained in:
@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<div class="chart-container">
|
||||
<!-- 图表标题和时间范围选择器 -->
|
||||
<div class="chart-header">
|
||||
<h2>出勤趋势分析</h2>
|
||||
<div class="chart-actions">
|
||||
<button @click="timeRange = 'week'" :class="{ active: timeRange === 'week' }">每周</button>
|
||||
<button @click="timeRange = 'month'" :class="{ active: timeRange === 'month' }">每月</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图表内容区域 -->
|
||||
<div ref="chartRef" class="chart-content"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, computed, watch } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
// 接收从父组件传入的数据
|
||||
const props = defineProps({
|
||||
attendData: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
week: {
|
||||
xAxis: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
||||
actualCount: [40, 20, 30, 15, 22, 63, 58],
|
||||
expectedCount: [100, 556, 413, 115, 510, 115, 317]
|
||||
},
|
||||
month: {
|
||||
xAxis: ['第1周', '第2周', '第3周', '第4周'],
|
||||
actualData: [280, 360, 320, 400],
|
||||
theoreticalData: [300, 400, 350, 450]
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// 图表DOM引用
|
||||
const chartRef = ref(null);
|
||||
// 图表实例
|
||||
let chartInstance = null;
|
||||
|
||||
// 时间范围状态
|
||||
const timeRange = ref('week');
|
||||
|
||||
// 根据时间范围计算当前显示的数据
|
||||
const chartData = computed(() => {
|
||||
const dataForRange = props.attendData[timeRange.value] || props.attendData.week;
|
||||
|
||||
// 处理字段名称差异
|
||||
if (timeRange.value === 'week') {
|
||||
return {
|
||||
xAxis: dataForRange.xAxis || [],
|
||||
actualCount: dataForRange.actualCount || [],
|
||||
expectedCount: dataForRange.expectedCount || []
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
xAxis: dataForRange.xAxis || [],
|
||||
actualCount: dataForRange.actualData || [],
|
||||
expectedCount: dataForRange.theoreticalData || []
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// 定义颜色常量
|
||||
const ACTUAL_COUNT_COLOR = '#029CD4'; // 蓝色 - 实际人数
|
||||
const EXPECTED_COUNT_COLOR = '#0052D9'; // 蓝色 - 应出勤人数
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
if (chartRef.value && !chartInstance) {
|
||||
chartInstance = echarts.init(chartRef.value);
|
||||
}
|
||||
|
||||
// 使用计算后的数据
|
||||
const { xAxis, actualCount, expectedCount } = chartData.value;
|
||||
|
||||
|
||||
const option = {
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(255,255,255,1)',
|
||||
borderColor: '#ddd',
|
||||
borderWidth: 1,
|
||||
textStyle: {
|
||||
color: '#333',
|
||||
fontSize: 14
|
||||
},
|
||||
formatter: function(params) {
|
||||
const actualCount = params[0].value;
|
||||
const expectedCount = params[1].value;
|
||||
return `
|
||||
<div style="padding: 5px;">
|
||||
<div style="color: ${params[0].color};">实际人数: ${actualCount}</div>
|
||||
<div style="color: ${params[1].color};">应出勤人数: ${expectedCount}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
top: 30,
|
||||
left: 'center',
|
||||
itemWidth: 10,
|
||||
itemHeight: 10,
|
||||
itemGap: 25,
|
||||
data: ['实际人数', '应出勤人数'],
|
||||
textStyle: {
|
||||
color: '#666',
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
top: '30%',
|
||||
right: '10%',
|
||||
bottom: '10%',
|
||||
left: '6%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
data: xAxis,
|
||||
type: 'category',
|
||||
boundaryGap: true,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#666',
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#ddd'
|
||||
}
|
||||
}
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '人数',
|
||||
nameTextStyle: {
|
||||
color: '#666',
|
||||
fontSize: 12
|
||||
},
|
||||
interval: 100,
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#666',
|
||||
fontSize: 12
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#f0f0f0',
|
||||
type: 'dashed'
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '实际人数',
|
||||
type: 'bar',
|
||||
barWidth: '40%',
|
||||
itemStyle: {
|
||||
color: ACTUAL_COUNT_COLOR
|
||||
},
|
||||
data: actualCount
|
||||
},
|
||||
{
|
||||
name: '应出勤人数',
|
||||
type: 'line',
|
||||
showSymbol: false,
|
||||
symbol: 'circle',
|
||||
symbolSize: 6,
|
||||
emphasis: {
|
||||
showSymbol: true,
|
||||
symbolSize: 10
|
||||
},
|
||||
lineStyle: {
|
||||
width: 2,
|
||||
color: EXPECTED_COUNT_COLOR
|
||||
},
|
||||
itemStyle: {
|
||||
color: EXPECTED_COUNT_COLOR,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
data: expectedCount
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
chartInstance.setOption(option);
|
||||
};
|
||||
|
||||
// 响应窗口大小变化
|
||||
const handleResize = () => {
|
||||
if (chartInstance) {
|
||||
chartInstance.resize();
|
||||
}
|
||||
};
|
||||
|
||||
// 监听时间范围变化,更新图表
|
||||
watch(timeRange, () => {
|
||||
initChart();
|
||||
});
|
||||
|
||||
// 监听数据变化,更新图表
|
||||
watch(() => props.attendData, () => {
|
||||
initChart();
|
||||
}, { deep: true });
|
||||
|
||||
// 生命周期钩子
|
||||
onMounted(() => {
|
||||
initChart();
|
||||
window.addEventListener('resize', handleResize);
|
||||
|
||||
// 清理函数
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
if (chartInstance) {
|
||||
chartInstance.dispose();
|
||||
chartInstance = null;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.chart-container {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
height: 500px;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.chart-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 15px 20px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.chart-header h2 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.chart-actions button {
|
||||
background: none;
|
||||
border: 1px solid #e0e0e0;
|
||||
padding: 5px 12px;
|
||||
border-radius: 4px;
|
||||
margin-left: 8px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.chart-actions button.active {
|
||||
background-color: #1890ff;
|
||||
color: white;
|
||||
border-color: #1890ff;
|
||||
}
|
||||
|
||||
.chart-content {
|
||||
width: 100%;
|
||||
height: calc(100% - 54px);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.chart-container {
|
||||
height: 450px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.chart-container {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
.chart-header {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.chart-actions {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.chart-actions button {
|
||||
margin: 0;
|
||||
flex: 1;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.chart-actions button:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.model {
|
||||
padding: 20px;
|
||||
background-color: rgba(242, 248, 252, 1);
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="total">
|
||||
<div class="infoBox">
|
||||
<div class="date text-color">2025-08-26</div>
|
||||
<div class="temperature text-color">28℃</div>
|
||||
<div class="role text-color">中午好,管理员</div>
|
||||
<div class="cycle text-color">加入项目已经89天</div>
|
||||
</div>
|
||||
<img src="@/assets/demo/icTicket.png" alt="" class="imgbox">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.total {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.imgbox {
|
||||
position: absolute;
|
||||
top: 60px;
|
||||
left: 210px;
|
||||
}
|
||||
|
||||
.infoBox {
|
||||
|
||||
height: 217px;
|
||||
border-radius: 12px;
|
||||
padding: 30px;
|
||||
background: rgba(24, 109, 245, 1);
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.text-color {
|
||||
color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
|
||||
.date {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.temperature {
|
||||
font-weight: 600;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
.role {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.cycle {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,211 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="chart-header">
|
||||
<TitleComponent title="审批" :font-level="2" />
|
||||
<span>更多</span>
|
||||
</div>
|
||||
<div class="approval-content">
|
||||
<div
|
||||
v-for="(item, index) in approvalData"
|
||||
:key="index"
|
||||
class="approval-item"
|
||||
>
|
||||
<div class="approval-left">
|
||||
<div class="approval-icon">
|
||||
<img :src="item.iconPath" :alt="item.type">
|
||||
</div>
|
||||
<div class="approval-info">
|
||||
<div class="info">
|
||||
<div class="type">{{ item.type }}</div>
|
||||
<div class="day">{{ item.days }}天</div>
|
||||
</div>
|
||||
<div class="info1">
|
||||
<div class="time">
|
||||
<img src="@/assets/demo/time.png" alt="时间">
|
||||
<span>{{ item.timeRange }}</span>
|
||||
</div>
|
||||
<div class="people">
|
||||
<img src="@/assets/demo/people.png" alt="人员">
|
||||
<span>{{ item.people }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="approval-tag">
|
||||
<el-tag :type="item.statusType">{{ item.status }}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import TitleComponent from '@/components/TitleComponent/index.vue';
|
||||
|
||||
const approvalData = [
|
||||
{
|
||||
type: '事假',
|
||||
days: 1,
|
||||
timeRange: '09.14-09.15',
|
||||
people: '水泥班组-王五',
|
||||
status: '待审批',
|
||||
statusType: 'primary',
|
||||
iconPath: '/src/assets/demo/approval.png'
|
||||
},
|
||||
{
|
||||
type: '病假',
|
||||
days: 2,
|
||||
timeRange: '09.14-09.15',
|
||||
people: '水泥班组-王五',
|
||||
status: '待审批',
|
||||
statusType: 'primary',
|
||||
iconPath: '/src/assets/demo/approval.png'
|
||||
},
|
||||
{
|
||||
type: '调休',
|
||||
days: 1,
|
||||
timeRange: '09.14-09.15',
|
||||
people: '水泥班组-王五',
|
||||
status: '待审批',
|
||||
statusType: 'primary',
|
||||
iconPath: '/src/assets/demo/approval.png'
|
||||
},
|
||||
{
|
||||
type: '事假',
|
||||
days: 1,
|
||||
timeRange: '09.14-09.15',
|
||||
people: '水泥班组-王五',
|
||||
status: '待审批',
|
||||
statusType: 'primary',
|
||||
iconPath: '/src/assets/demo/approval.png'
|
||||
},
|
||||
{
|
||||
type: '事假',
|
||||
days: 1,
|
||||
timeRange: '09.14-09.15',
|
||||
people: '水泥班组-王五',
|
||||
status: '已通过',
|
||||
statusType: 'success',
|
||||
iconPath: '/src/assets/demo/approval.png'
|
||||
}
|
||||
];
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.chart-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.chart-header h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.chart-header span {
|
||||
color: #186DF5;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.approval-content {
|
||||
background-color: white;
|
||||
.approval-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 12px 16px;
|
||||
background: #F2F8FC;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 12px;
|
||||
border: 1px solid #F2F3F5;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.approval-item:hover {
|
||||
border-color: #E4E6EB;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.approval-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.approval-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 16px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: #186DF5;
|
||||
}
|
||||
|
||||
.approval-icon img {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.approval-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.info .type {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.info .day {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.info1 {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.info1 .time,
|
||||
.info1 .people {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
color: rgba(113, 128, 150, 1);
|
||||
}
|
||||
|
||||
.info1 img {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.approval-tag {
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.approval-tag .el-tag {
|
||||
padding: 4px 12px;
|
||||
font-size: 12px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="chart-header">
|
||||
<TitleComponent title="日历" :font-level="2" />
|
||||
</div>
|
||||
<div class="calendar-container">
|
||||
<div class="calendar-header">
|
||||
<el-button size="small" type="text" @click="prevMonth">
|
||||
<el-icon><ArrowLeft /></el-icon>
|
||||
</el-button>
|
||||
<span class="current-month">{{ currentYear }} {{ currentMonthName }}</span>
|
||||
<el-button size="small" type="text" @click="nextMonth">
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<div class="calendar-weekdays">
|
||||
<span v-for="day in weekdays" :key="day" class="weekday">{{ day }}</span>
|
||||
</div>
|
||||
|
||||
<div class="calendar-days">
|
||||
<!-- 上月剩余天数 -->
|
||||
<div v-for="(day, index) in prevMonthDays" :key="'prev-' + index" class="day prev-month-day">
|
||||
{{ day }}
|
||||
</div>
|
||||
|
||||
<!-- 当月天数 -->
|
||||
<div
|
||||
v-for="day in currentMonthDays"
|
||||
:key="day"
|
||||
class="day current-month-day"
|
||||
:class="{
|
||||
'current-day': isCurrentDay(day),
|
||||
'selected-day': isSelectedDay(day)
|
||||
}"
|
||||
@click="selectDay(day)"
|
||||
>
|
||||
{{ day }}
|
||||
<!-- 今天有红点标记 -->
|
||||
<span v-if="isToday(day)" class="today-marker"></span>
|
||||
<!-- 考勤状态标记 -->
|
||||
<span v-if="getAttendanceStatus(day)" class="attendance-marker" :class="getAttendanceStatus(day)"></span>
|
||||
</div>
|
||||
|
||||
<!-- 下月开始天数 -->
|
||||
<div v-for="(day, index) in nextMonthDays" :key="'next-' + index" class="day next-month-day">
|
||||
{{ day }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import TitleComponent from '@/components/TitleComponent/index.vue';
|
||||
import { ArrowLeft, ArrowRight } from '@element-plus/icons-vue';
|
||||
import { ref, computed } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
// 初始化当前日期
|
||||
const today = new Date();
|
||||
const currentDate = ref(new Date(2025, 8, 27)); // 2025年9月27日,截图中显示的日期
|
||||
const selectedDate = ref(new Date(2025, 8, 27));
|
||||
|
||||
// 模拟考勤数据
|
||||
const attendanceData = ref({
|
||||
2025: {
|
||||
9: {
|
||||
1: 'normal',
|
||||
4: 'late',
|
||||
8: 'absent',
|
||||
10: 'leave',
|
||||
15: 'normal',
|
||||
20: 'normal',
|
||||
25: 'late',
|
||||
27: 'normal'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 星期几的显示
|
||||
const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||
const monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
|
||||
// 计算属性
|
||||
const currentYear = computed(() => currentDate.value.getFullYear());
|
||||
const currentMonth = computed(() => currentDate.value.getMonth());
|
||||
const currentMonthName = computed(() => monthNames[currentMonth.value]);
|
||||
|
||||
// 获取当月的天数
|
||||
const currentMonthDays = computed(() => {
|
||||
return new Date(currentYear.value, currentMonth.value + 1, 0).getDate();
|
||||
});
|
||||
|
||||
// 获取当月第一天是星期几(0-6,0是星期日)
|
||||
const firstDayOfMonth = computed(() => {
|
||||
return new Date(currentYear.value, currentMonth.value, 1).getDay();
|
||||
});
|
||||
|
||||
// 获取上月剩余天数
|
||||
const prevMonthDays = computed(() => {
|
||||
const days = [];
|
||||
const prevMonth = new Date(currentYear.value, currentMonth.value, 0).getDate(); // 上月最后一天
|
||||
|
||||
for (let i = firstDayOfMonth.value - 1; i >= 0; i--) {
|
||||
days.push(prevMonth - i);
|
||||
}
|
||||
|
||||
return days;
|
||||
});
|
||||
|
||||
// 获取下月开始天数
|
||||
const nextMonthDays = computed(() => {
|
||||
const days = [];
|
||||
const totalDays = prevMonthDays.value.length + currentMonthDays.value;
|
||||
const nextDays = 35 - totalDays; // 显示5周,共35天
|
||||
|
||||
for (let i = 1; i <= nextDays; i++) {
|
||||
days.push(i);
|
||||
}
|
||||
|
||||
return days;
|
||||
});
|
||||
|
||||
// 方法
|
||||
const prevMonth = () => {
|
||||
currentDate.value = new Date(currentYear.value, currentMonth.value - 1, 1);
|
||||
};
|
||||
|
||||
const nextMonth = () => {
|
||||
currentDate.value = new Date(currentYear.value, currentMonth.value + 1, 1);
|
||||
};
|
||||
|
||||
const selectDay = (day) => {
|
||||
selectedDate.value = new Date(currentYear.value, currentMonth.value, day);
|
||||
|
||||
// 显示选择的日期和考勤状态
|
||||
let message = `Selected: ${currentMonthName.value} ${day}, ${currentYear.value}`;
|
||||
const status = getAttendanceStatus(day);
|
||||
if (status) {
|
||||
const statusMap = {
|
||||
normal: '正常',
|
||||
late: '迟到',
|
||||
absent: '缺勤',
|
||||
leave: '请假'
|
||||
};
|
||||
message += ` - 考勤状态: ${statusMap[status] || '未知'}`;
|
||||
}
|
||||
ElMessage.success(message);
|
||||
};
|
||||
|
||||
// 获取考勤状态
|
||||
const getAttendanceStatus = (day) => {
|
||||
if (attendanceData.value[currentYear.value] &&
|
||||
attendanceData.value[currentYear.value][currentMonth.value + 1] &&
|
||||
attendanceData.value[currentYear.value][currentMonth.value + 1][day]) {
|
||||
return attendanceData.value[currentYear.value][currentMonth.value + 1][day];
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const isToday = (day) => {
|
||||
return day === today.getDate() &&
|
||||
currentMonth.value === today.getMonth() &&
|
||||
currentYear.value === today.getFullYear();
|
||||
};
|
||||
|
||||
const isCurrentDay = (day) => {
|
||||
return day === today.getDate() &&
|
||||
currentMonth.value === today.getMonth() &&
|
||||
currentYear.value === today.getFullYear();
|
||||
};
|
||||
|
||||
const isSelectedDay = (day) => {
|
||||
return day === selectedDate.value.getDate() &&
|
||||
currentMonth.value === selectedDate.value.getMonth() &&
|
||||
currentYear.value === selectedDate.value.getFullYear();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.chart-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.chart-header h3 {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.chart-header span {
|
||||
color: #186DF5;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.calendar-container {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
// border: 1px solid #F2F3F5;
|
||||
}
|
||||
|
||||
.calendar-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.current-month {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.calendar-weekdays {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.weekday {
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.calendar-days {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, 1fr);
|
||||
gap: 8px;
|
||||
height: 350px;
|
||||
}
|
||||
|
||||
.day {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.prev-month-day,
|
||||
.next-month-day {
|
||||
color: #C0C4CC;
|
||||
}
|
||||
|
||||
.current-month-day {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.current-month-day:hover {
|
||||
background-color: #ECF5FF;
|
||||
color: #186DF5;
|
||||
}
|
||||
|
||||
.current-day {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.today-marker {
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background-color: #FF6B3B;
|
||||
}
|
||||
|
||||
.selected-day {
|
||||
background-color: #186DF5;
|
||||
color: white !important;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.selected-day:hover {
|
||||
background-color: #4096ff;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
// 考勤状态标记样式
|
||||
.attendance-marker {
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.attendance-marker.normal {
|
||||
background-color: #52c41a;
|
||||
}
|
||||
|
||||
.attendance-marker.late {
|
||||
background-color: #faad14;
|
||||
}
|
||||
|
||||
.attendance-marker.absent {
|
||||
background-color: #f5222d;
|
||||
}
|
||||
|
||||
.attendance-marker.leave {
|
||||
background-color: #1890ff;
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<TitleComponent title="今日出勤" :font-level="2" />
|
||||
<div class="todayAttend">
|
||||
<div class="todayAttendItem">
|
||||
<img src="@/assets/demo/qin.png" alt="" width="30px" height="30px">
|
||||
<div class="todayAttendItemInfo">
|
||||
<span class="todayAttendItemTitle">出勤</span>
|
||||
<span class="todayAttendItemNum">150人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="todayAttendItem">
|
||||
<img src="@/assets/demo/qin.png" alt="" width="30px" height="30px">
|
||||
<div class="todayAttendItemInfo">
|
||||
<span class="todayAttendItemTitle">迟到</span>
|
||||
<span class="todayAttendItemNum">150人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="todayAttendItem">
|
||||
<img src="@/assets/demo/qin.png" alt="" width="30px" height="30px">
|
||||
<div class="todayAttendItemInfo">
|
||||
<span class="todayAttendItemTitle">早退</span>
|
||||
<span class="todayAttendItemNum">150人</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="todayAttendItem">
|
||||
<img src="@/assets/demo/qin.png" alt="" width="30px" height="30px">
|
||||
<div class="todayAttendItemInfo">
|
||||
<span class="todayAttendItemTitle">缺勤</span>
|
||||
<span class="todayAttendItemNum">150人</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import TitleComponent from '@/components/TitleComponent/index.vue';
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.todayAttend {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.todayAttendItem {
|
||||
width: 110px;
|
||||
height: 100px;
|
||||
background: #E5F0FF;
|
||||
padding: 5px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
flex-direction: column;
|
||||
.todayAttendItemInfo{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
.todayAttendItemTitle {
|
||||
color: rgba(113, 128, 150, 1);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.todayAttendItemNum {
|
||||
font-size: 16px;
|
||||
color: rgba(0, 30, 59, 1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
320
src/views/integratedManage/attendManage/components/totalView.vue
Normal file
320
src/views/integratedManage/attendManage/components/totalView.vue
Normal file
@ -0,0 +1,320 @@
|
||||
<template>
|
||||
<div class="total-view-container">
|
||||
<div class="total-view-content">
|
||||
<!-- 总出勤人数 -->
|
||||
<div class="stats-card">
|
||||
<div class="stats-card-header">
|
||||
<span class="stats-title">总出勤人数</span>
|
||||
<span class="stats-change positive">↑ 8.2% 较昨日同期</span>
|
||||
</div>
|
||||
<div class="stats-card-body">
|
||||
<div class="stats-value">248</div>
|
||||
<div class="stats-chart">
|
||||
<div ref="attendanceChart" class="chart-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 调休 -->
|
||||
<div class="stats-card">
|
||||
<div class="stats-card-header">
|
||||
<span class="stats-title">调休</span>
|
||||
<span class="stats-change positive">↑ 8.2% 较上月同期</span>
|
||||
</div>
|
||||
<div class="stats-card-body">
|
||||
<div class="stats-value">8</div>
|
||||
<div class="stats-chart">
|
||||
<div ref="restChart" class="chart-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 本月请假 -->
|
||||
<div class="stats-card">
|
||||
<div class="stats-card-header">
|
||||
<span class="stats-title">本月请假</span>
|
||||
<span class="stats-change negative">↓ 10% 较昨日同期</span>
|
||||
</div>
|
||||
<div class="stats-card-body">
|
||||
<div class="stats-value">24</div>
|
||||
<div class="stats-chart">
|
||||
<div ref="leaveChart" class="chart-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 平均出勤率 -->
|
||||
<div class="stats-card">
|
||||
<div class="stats-card-header">
|
||||
<span class="stats-title">平均出勤率</span>
|
||||
<span class="stats-change positive">↑ 10% 较昨日同期</span>
|
||||
</div>
|
||||
<div class="stats-card-body">
|
||||
<div class="stats-value">96.8%</div>
|
||||
<div class="stats-chart">
|
||||
<div ref="rateChart" class="chart-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
// 图表引用
|
||||
const attendanceChart = ref(null);
|
||||
const restChart = ref(null);
|
||||
const leaveChart = ref(null);
|
||||
const rateChart = ref(null);
|
||||
|
||||
// 初始化图表
|
||||
const initCharts = () => {
|
||||
// 总出勤人数图表 - 条形图
|
||||
const attendanceChartInstance = echarts.init(attendanceChart.value);
|
||||
attendanceChartInstance.setOption({
|
||||
tooltip: { show: false },
|
||||
grid: { top: 0, bottom: 0, left: -70, right: 0, containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['', '', '', '', '', '', ''],
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: { show: false }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false
|
||||
},
|
||||
series: [{
|
||||
data: [150, 230, 224, 218, 135, 300, 220],
|
||||
type: 'bar',
|
||||
barWidth: 10,
|
||||
itemStyle: {
|
||||
color: '#FF7D00',
|
||||
borderRadius: [10, 10, 0, 0] // 柱状图圆角
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
// 调休图表 - 折线图
|
||||
const restChartInstance = echarts.init(restChart.value);
|
||||
restChartInstance.setOption({
|
||||
tooltip: { show: false },
|
||||
grid: { top:10, bottom: 0, left: -30, right: 0, containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['', '', '', '', '', '', '', '', '', ''],
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: { show: false }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false
|
||||
},
|
||||
series: [{
|
||||
data: [120, 200, 150, 80, 70, 110, 130, 150, 160, 180],
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 3, // 折线图线条加粗
|
||||
color: '#52C41A'
|
||||
},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(82, 196, 26, 0.2)'
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(82, 196, 26, 0.01)'
|
||||
}])
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
// 本月请假图表 - 折线图
|
||||
const leaveChartInstance = echarts.init(leaveChart.value);
|
||||
leaveChartInstance.setOption({
|
||||
tooltip: { show: false },
|
||||
grid: { top: 10, bottom: 0, left: -30, right: 0, containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['', '', '', '', '', '', '', '', '', ''],
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: { show: false }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false
|
||||
},
|
||||
series: [{
|
||||
data: [80, 150, 120, 200, 180, 130, 160, 190, 140, 100],
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 3, // 折线图线条加粗
|
||||
color: '#F5222D'
|
||||
},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(245, 34, 45, 0.2)'
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(245, 34, 45, 0.01)'
|
||||
}])
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
// 平均出勤率图表 - 折线图
|
||||
const rateChartInstance = echarts.init(rateChart.value);
|
||||
rateChartInstance.setOption({
|
||||
tooltip: { show: false },
|
||||
grid: { top: 0, bottom: 0, left: -30, right: 0, containLabel: true },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['', '', '', '', '', '', '', '', '', ''],
|
||||
axisLine: { show: false },
|
||||
axisTick: { show: false },
|
||||
axisLabel: { show: false }
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
show: false
|
||||
},
|
||||
series: [{
|
||||
data: [90, 92, 91, 93, 95, 94, 96, 95, 97, 98],
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
showSymbol: false,
|
||||
lineStyle: {
|
||||
width: 3, // 折线图线条加粗
|
||||
color: '#186DF5'
|
||||
},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
|
||||
offset: 0,
|
||||
color: 'rgba(24, 109, 245, 0.2)'
|
||||
}, {
|
||||
offset: 1,
|
||||
color: 'rgba(24, 109, 245, 0.01)'
|
||||
}])
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
// 响应窗口大小变化
|
||||
window.addEventListener('resize', () => {
|
||||
attendanceChartInstance.resize();
|
||||
restChartInstance.resize();
|
||||
leaveChartInstance.resize();
|
||||
rateChartInstance.resize();
|
||||
});
|
||||
};
|
||||
|
||||
// 组件挂载后初始化图表
|
||||
onMounted(() => {
|
||||
initCharts();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.total-view-container {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.total-view-content {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 0;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
flex: 1;
|
||||
padding: 16px;
|
||||
background-color: #fff;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
border-right: 1px dashed #E4E7ED;
|
||||
}
|
||||
|
||||
.stats-card:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.stats-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.stats-title {
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.stats-change {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.stats-change.positive {
|
||||
color: #52C41A;
|
||||
}
|
||||
|
||||
.stats-change.negative {
|
||||
color: #F5222D;
|
||||
}
|
||||
|
||||
.stats-card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.stats-value {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.stats-chart {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// 响应式布局
|
||||
@media screen and (max-width: 1200px) {
|
||||
.total-view-content {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.stats-card {
|
||||
width: calc(50% - 10px);
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.stats-card {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
158
src/views/integratedManage/attendManage/index.vue
Normal file
158
src/views/integratedManage/attendManage/index.vue
Normal file
@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<div class="model">
|
||||
<!-- 标题栏 -->
|
||||
<el-row :gutter="24">
|
||||
<el-col :span="12">
|
||||
<TitleComponent title="考勤管理" subtitle="项目出勤情况、人员排班及请假调休管理" />
|
||||
</el-col>
|
||||
<!-- 外层col:控制整体宽度并右对齐,同时作为flex容器 -->
|
||||
<el-col :span="12" style="display: flex; justify-content: flex-end; align-items: center;">
|
||||
<!-- 子col1:下拉 -->
|
||||
<el-col :span="4">
|
||||
<el-select placeholder="选择电站">
|
||||
<el-option label="所有电站" value="all"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<!-- 子col2:下拉框容器 -->
|
||||
<el-col :span="4">
|
||||
<el-select placeholder="日期范围">
|
||||
<el-option label="所有月份" value="all"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button type="primary">
|
||||
导出数据
|
||||
<el-icon class="el-icon--right">
|
||||
<UploadFilled />
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<!-- 左侧 -->
|
||||
<el-col :span="17">
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<totalView ></totalView>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<attendTrend :attendData="attendData"></attendTrend>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
|
||||
<!-- 右侧 -->
|
||||
<el-col :span="7">
|
||||
<!-- hello -->
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<infoBox></infoBox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<!-- 日历 -->
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-card>
|
||||
<calendar></calendar>
|
||||
<todayAttend></todayAttend>
|
||||
<approval></approval>
|
||||
</el-card>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import infoBox from '@/views/integratedManage/attendManage/components/infoBox.vue'
|
||||
import attendTrend from '@/views/integratedManage/attendManage/components/attendTrend.vue'
|
||||
import todayAttend from '@/views/integratedManage/attendManage/components/leftBox/todayAttend.vue'
|
||||
import approval from '@/views/integratedManage/attendManage/components/leftBox/approval.vue'
|
||||
import calendar from '@/views/integratedManage/attendManage/components/leftBox/calendar.vue'
|
||||
import totalView from '@/views/integratedManage/attendManage/components/totalView.vue'
|
||||
const attendData = ref(
|
||||
{
|
||||
week: {
|
||||
xAxis: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
|
||||
actualCount: [40, 20, 30, 15, 22, 63, 58, 43, 39, 36],
|
||||
expectedCount: [100, 556, 413, 115, 510, 115, 317, 118, 14, 7]
|
||||
},
|
||||
month: {
|
||||
xAxis: ['第1周', '第2周', '第3周', '第4周'],
|
||||
actualData: [280, 360, 320, 400],
|
||||
theoreticalData: [300, 400, 350, 450]
|
||||
},
|
||||
}
|
||||
)
|
||||
// 创建itembox数据数组,用于循环渲染
|
||||
const itemBoxData = ref([
|
||||
{
|
||||
title: '总发电量',
|
||||
value: '2,456.8',
|
||||
unit: 'KWh',
|
||||
growth: '2.5',
|
||||
growthLabel: '较昨日',
|
||||
color: '#186DF5',
|
||||
chartType: 'bar',
|
||||
power: '',
|
||||
iconSrc: '/src/assets/demo/shandian.png',
|
||||
type: 'up',
|
||||
chartData: [30, 50, 40, 60, 80, 70, 100, 90, 85, 75, 65, 55]
|
||||
},
|
||||
{
|
||||
title: '平均效率',
|
||||
value: '18.7',
|
||||
unit: '%',
|
||||
growth: '2.5',
|
||||
growthLabel: '较昨日',
|
||||
color: '#00B87A',
|
||||
chartType: 'line',
|
||||
power: '',
|
||||
iconSrc: '/src/assets/demo/huojian.png',
|
||||
type: 'up',
|
||||
chartData: [30, 50, 40, 60, 80, 70, 100, 90, 85, 75, 65, 55]
|
||||
},
|
||||
{
|
||||
title: '设备温度',
|
||||
value: '43.5',
|
||||
unit: '℃',
|
||||
growth: '2.5',
|
||||
growthLabel: '较昨日',
|
||||
color: '#FFC300',
|
||||
chartType: 'line',
|
||||
power: '',
|
||||
iconSrc: '/src/assets/demo/wendu.png',
|
||||
type: 'up',
|
||||
chartData: [30, 50, 40, 60, 80, 70, 100, 90, 85, 75, 65, 55]
|
||||
},
|
||||
{
|
||||
title: '系统可用性',
|
||||
value: '18.7',
|
||||
unit: '%',
|
||||
growth: '2.5',
|
||||
growthLabel: '较昨日',
|
||||
color: '#7948EA',
|
||||
chartType: 'line',
|
||||
power: '',
|
||||
iconSrc: '/src/assets/demo/use.png',
|
||||
type: 'up',
|
||||
chartData: [30, 50, 40, 60, 80, 70, 100, 90, 85, 75, 65, 55]
|
||||
}
|
||||
]);
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.model {
|
||||
padding: 20px 15px;
|
||||
background-color: rgba(242, 248, 252, 1);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user