完成初版考勤管理静态页面
This commit is contained in:
@ -0,0 +1,179 @@
|
||||
<template>
|
||||
<div class="schedule-table-container">
|
||||
<el-table
|
||||
:data="scheduleData"
|
||||
style="width: 100%"
|
||||
max-height="600"
|
||||
stripe
|
||||
border
|
||||
>
|
||||
<!-- 固定列 -->
|
||||
<el-table-column fixed prop="name" label="姓名" width="120" align="center" />
|
||||
<el-table-column fixed="left" prop="position" label="岗位" width="120" align="center" />
|
||||
<el-table-column fixed="left" prop="weeklyHours" label="周总计/小时" width="120" align="center" />
|
||||
|
||||
<!-- 日期列 - 纵向显示号数和星期几 -->
|
||||
<el-table-column
|
||||
v-for="(dateInfo, index) in currentMonthDates"
|
||||
:key="index"
|
||||
:prop="`day${index + 1}`"
|
||||
width="80"
|
||||
align="center"
|
||||
>
|
||||
<template #header>
|
||||
<div class="vertical-header">
|
||||
<div class="date-number">{{ dateInfo.date }}</div>
|
||||
<div class="week-day">{{ dateInfo.weekDay }}</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, computed, onMounted } from 'vue';
|
||||
|
||||
// 员工列表
|
||||
const employees = [
|
||||
{ name: '张三', position: '水泥工', weeklyHours: 142 },
|
||||
{ name: '李四', position: '电工', weeklyHours: 138 },
|
||||
{ name: '王五', position: '木工', weeklyHours: 145 },
|
||||
{ name: '赵六', position: '钢筋工', weeklyHours: 140 },
|
||||
{ name: '钱七', position: '油漆工', weeklyHours: 135 },
|
||||
{ name: '孙八', position: '瓦工', weeklyHours: 143 },
|
||||
{ name: '周九', position: '钳工', weeklyHours: 137 },
|
||||
{ name: '吴十', position: '管道工', weeklyHours: 139 },
|
||||
{ name: '郑十一', position: '焊工', weeklyHours: 141 },
|
||||
{ name: '王十二', position: '起重工', weeklyHours: 136 }
|
||||
];
|
||||
|
||||
// 排班类型
|
||||
const shifts = ['早班', '中班', '晚班', '休息'];
|
||||
|
||||
// 获取当前月的日期信息
|
||||
const currentMonthDates = ref<any[]>([]);
|
||||
|
||||
// 计算当前月份并生成日期信息
|
||||
const getCurrentMonthDates = () => {
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = today.getMonth(); // 0-11
|
||||
|
||||
// 获取当月第一天
|
||||
const firstDay = new Date(year, month, 1);
|
||||
// 获取当月最后一天
|
||||
const lastDay = new Date(year, month + 1, 0);
|
||||
// 当月总天数
|
||||
const daysInMonth = lastDay.getDate();
|
||||
|
||||
const weekdays = ['日', '一', '二', '三', '四', '五', '六'];
|
||||
const dates = [];
|
||||
|
||||
// 生成当月所有日期信息
|
||||
for (let i = 1; i <= daysInMonth; i++) {
|
||||
const date = new Date(year, month, i);
|
||||
const weekDayIndex = date.getDay(); // 0-6,0表示星期日
|
||||
dates.push({
|
||||
date: i,
|
||||
weekDay: weekdays[weekDayIndex],
|
||||
fullDate: `${year}-${String(month + 1).padStart(2, '0')}-${String(i).padStart(2, '0')}`
|
||||
});
|
||||
}
|
||||
|
||||
return dates;
|
||||
};
|
||||
|
||||
// 生成排班数据
|
||||
const scheduleData = computed(() => {
|
||||
return Array.from({ length: 20 }, (_, index) => {
|
||||
// 循环使用员工数据
|
||||
const employee = employees[index % employees.length];
|
||||
|
||||
// 为每行生成不同的排班组合
|
||||
const rowData = {
|
||||
name: employee.name,
|
||||
position: employee.position,
|
||||
weeklyHours: employee.weeklyHours
|
||||
};
|
||||
|
||||
// 为当月每一天生成排班数据
|
||||
currentMonthDates.value.forEach((_, dayIndex) => {
|
||||
// 使用不同的种子生成略有变化的排班模式
|
||||
const seed = (index * 3 + dayIndex + 1) % shifts.length;
|
||||
rowData[`day${dayIndex + 1}`] = shifts[seed];
|
||||
});
|
||||
|
||||
return rowData;
|
||||
});
|
||||
});
|
||||
|
||||
// 组件挂载时获取当前月数据
|
||||
onMounted(() => {
|
||||
currentMonthDates.value = getCurrentMonthDates();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.schedule-table-container {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/* 优化滚动条样式 */
|
||||
.schedule-table-container::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.schedule-table-container::-webkit-scrollbar-track {
|
||||
background: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.schedule-table-container::-webkit-scrollbar-thumb {
|
||||
background: #c0c4cc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.schedule-table-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #909399;
|
||||
}
|
||||
|
||||
/* 优化表格样式 */
|
||||
:deep(.el-table) {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
:deep(.el-table__header-wrapper th) {
|
||||
background-color: #fafafa;
|
||||
font-weight: 500;
|
||||
padding: 0 !important;
|
||||
height: auto !important;
|
||||
min-height: 60px;
|
||||
}
|
||||
|
||||
:deep(.el-table__body-wrapper) {
|
||||
overflow-x: visible;
|
||||
}
|
||||
|
||||
/* 纵向表头样式 */
|
||||
.vertical-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.date-number {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.week-day {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
@ -233,7 +233,7 @@ onMounted(() => {
|
||||
background-color: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-bottom: 20px;
|
||||
height: 217px;
|
||||
}
|
||||
|
||||
.total-view-content {
|
||||
|
||||
@ -29,46 +29,38 @@
|
||||
</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">
|
||||
<!-- 第一行:totalView 和 infoBox -->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="17">
|
||||
<totalView></totalView>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<infoBox></infoBox>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
</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-row :gutter="20">
|
||||
<el-col :span="17">
|
||||
<div class="analysis-content">
|
||||
<attendTrend :attendData="attendData"></attendTrend>
|
||||
<el-card>
|
||||
<calendar></calendar>
|
||||
<todayAttend></todayAttend>
|
||||
<TitleComponent title="人员排班" :fontLevel="2" />
|
||||
<renyuanpaiban></renyuanpaiban>
|
||||
</el-card>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 右侧日历卡片 -->
|
||||
<el-col :span="7">
|
||||
<div class="calendar-content">
|
||||
<el-card>
|
||||
<calendar></calendar>
|
||||
<todayAttend></todayAttend>
|
||||
<approval></approval>
|
||||
</el-card>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
@ -79,6 +71,7 @@ import todayAttend from '@/views/integratedManage/attendManage/components/leftBo
|
||||
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'
|
||||
import renyuanpaiban from '@/views/integratedManage/attendManage/components/renyuanpaiban.vue'
|
||||
const attendData = ref(
|
||||
{
|
||||
week: {
|
||||
@ -93,66 +86,100 @@ const attendData = ref(
|
||||
},
|
||||
}
|
||||
)
|
||||
// 创建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;
|
||||
padding: 24px 20px;
|
||||
background-color: rgba(242, 248, 252, 1);
|
||||
}
|
||||
|
||||
/* 标题栏与内容区域间距 */
|
||||
.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>
|
||||
Reference in New Issue
Block a user