Files
maintenance_system/src/views/integratedManage/attendManage/index.vue

325 lines
8.4 KiB
Vue
Raw Normal View History

<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>
2025-09-20 11:26:02 +08:00
<!-- 第一行totalView infoBox -->
<el-row :gutter="20">
<el-col :span="17">
2025-09-20 19:27:56 +08:00
<totalView :totalData="totalData"></totalView>
2025-09-20 11:26:02 +08:00
</el-col>
<el-col :span="7">
<infoBox></infoBox>
</el-col>
</el-row>
<!-- 第二行人员排班和出勤趋势分析 -->
<el-row :gutter="20">
<el-col :span="17">
<div class="analysis-content">
<attendTrend :attendData="attendData"></attendTrend>
<el-card>
<TitleComponent title="人员排班" :fontLevel="2" />
<renyuanpaiban></renyuanpaiban>
</el-card>
</div>
</el-col>
<!-- 右侧日历卡片 -->
<el-col :span="7">
<div class="calendar-content">
<el-card>
2025-09-20 19:27:56 +08:00
<calendar :calendarData="calendarData"></calendar>
<todayAttend :todayAttendData="todayAttendData"></todayAttend>
<approval :approvalData="approvalData"></approval>
</el-card>
2025-09-20 11:26:02 +08:00
</div>
</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'
2025-09-20 11:26:02 +08:00
import renyuanpaiban from '@/views/integratedManage/attendManage/components/renyuanpaiban.vue'
2025-09-20 19:27:56 +08:00
import { ref } from 'vue';
// 出勤数据 - 用于attendTrend组件
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]
},
}
)
2025-09-20 19:27:56 +08:00
// Mock数据 - 更新为循环生成所需的数据结构
const totalData = ref({
attendance: {
value: 248,
change: '+8.2%',
isPositive: true,
chartData: [150, 230, 224, 218, 135, 300, 220],
color: '#FF7D00',
title: '总出勤人数',
compareText: '较昨日同期',
chartType: 'bar'
},
rest: {
value: 8,
change: '+8.2%',
isPositive: true,
chartData: [10, 12, 15, 8, 7, 9, 10],
color: '#00C48C',
title: '调休',
compareText: '较上月同期',
chartType: 'line'
},
leave: {
value: 24,
change: '-10%',
isPositive: false,
chartData: [30, 25, 28, 22, 20, 26, 24],
color: '#FF5252',
title: '本月请假',
compareText: '较昨日同期',
chartType: 'line'
},
rate: {
value: '96.8%',
change: '+10%',
isPositive: true,
chartData: [90, 92, 94, 95, 97, 98, 96.8],
color: '#029CD4',
title: '平均出勤率',
compareText: '较昨日同期',
chartType: 'line'
}
});
// 审批数据 - 用于approval组件
const approvalData = ref([
{
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'
}
]);
// 今日出勤数据 - 用于todayAttend组件
const todayAttendData = ref({
attendance: {
count: 150,
icon: '/src/assets/demo/qin.png'
},
late: {
count: 5,
icon: '/src/assets/demo/chi.png'
},
earlyLeave: {
count: 2,
icon: '/src/assets/demo/tui.png'
},
absent: {
count: 8,
icon: '/src/assets/demo/que.png'
}
});
// 日历数据 - 用于calendar组件
const calendarData = ref({
// 初始化当前日期
today: new Date(),
currentDate: new Date(2025, 8, 27), // 2025年9月27日截图中显示的日期
selectedDate: new Date(2025, 8, 27),
// 模拟考勤数据
attendanceData: {
2025: {
9: {
1: 'normal',
4: 'late',
8: 'absent',
10: 'leave',
15: 'normal',
20: 'normal',
25: 'late',
27: 'normal'
}
}
}
});
</script>
<style scoped lang="scss">
.model {
2025-09-20 11:26:02 +08:00
padding: 24px 20px;
background-color: rgba(242, 248, 252, 1);
}
2025-09-20 11:26:02 +08:00
/* 标题栏与内容区域间距 */
.el-row+.el-row {
margin-top: 24px;
}
/* 分析内容区域 */
.analysis-content {
display: flex;
flex-direction: column;
gap: 45px;
// border: 1px solid red;
}
/* 日历内容区域 */
.calendar-content {
display: flex;
flex-direction: column;
}
/* 右侧日历卡片内组件间距 */
.calendar-content .el-card {
display: flex;
flex-direction: column;
height: 100%;
}
.calendar-content .el-card > * {
margin-bottom: 16px;
}
.calendar-content .el-card > *:last-child {
margin-bottom: 0;
flex: 1;
}
/* 卡片样式统一 */
.el-card {
border-radius: 8px !important;
border: none !important;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
overflow: hidden;
}
/* 下拉选择器和按钮样式调整 */
.el-select {
width: 100%;
margin-right: 12px;
}
.el-button {
margin-left: 8px;
}
/* 响应式布局优化 */
@media screen and (max-width: 1200px) {
.model {
padding: 16px;
}
.el-row+.el-row {
margin-top: 16px;
}
.analysis-content {
gap: 16px;
}
/* 日历卡片内组件间距 */
.calendar-content .el-card > * {
margin-bottom: 12px;
}
}
/* 更细粒度的响应式调整 */
@media screen and (max-width: 768px) {
.model {
padding: 12px;
}
.el-select {
margin-right: 8px;
}
.el-button {
margin-left: 4px;
padding: 8px 12px;
}
}
</style>