feat(wms): 新增员工报餐日历页面
添加员工报餐日历功能页面,包含月份切换、餐型和部门筛选功能,展示每日报餐人数统计
This commit is contained in:
321
klp-ui/src/views/wms/hrm/calendar/meal.vue
Normal file
321
klp-ui/src/views/wms/hrm/calendar/meal.vue
Normal file
@@ -0,0 +1,321 @@
|
|||||||
|
<template>
|
||||||
|
<div class="meal-calendar-container">
|
||||||
|
<!-- 筛选和月份切换区域 -->
|
||||||
|
<div class="calendar-header">
|
||||||
|
<el-row align="middle" justify="space-between">
|
||||||
|
<el-col :span="16">
|
||||||
|
<el-form :inline="true" :model="queryParams" class="demo-form-inline">
|
||||||
|
<el-form-item label="餐型">
|
||||||
|
<el-select v-model="queryParams.mealType" placeholder="请选择餐型" clearable>
|
||||||
|
<el-option label="早餐" value="1"></el-option>
|
||||||
|
<el-option label="午餐" value="2"></el-option>
|
||||||
|
<el-option label="晚餐" value="3"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="部门">
|
||||||
|
<el-input v-model="queryParams.deptName" placeholder="请输入部门名称" clearable></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="getList()">查询</el-button>
|
||||||
|
<el-button @click="resetQuery()">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="8" class="month-control">
|
||||||
|
<el-button icon="el-icon-arrow-left" @click="prevMonth()">上个月</el-button>
|
||||||
|
<el-date-picker
|
||||||
|
v-model="currentMonth"
|
||||||
|
type="month"
|
||||||
|
placeholder="选择月份"
|
||||||
|
@change="handleMonthChange"
|
||||||
|
format="yyyy年MM月"
|
||||||
|
value-format="yyyy-MM"
|
||||||
|
></el-date-picker>
|
||||||
|
<el-button icon="el-icon-arrow-right" @click="nextMonth()">下个月</el-button>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 日历展示区域 -->
|
||||||
|
<div class="calendar-content" v-loading="loading">
|
||||||
|
<!-- 星期头部 -->
|
||||||
|
<div class="calendar-week-header">
|
||||||
|
<div class="week-item">周日</div>
|
||||||
|
<div class="week-item">周一</div>
|
||||||
|
<div class="week-item">周二</div>
|
||||||
|
<div class="week-item">周三</div>
|
||||||
|
<div class="week-item">周四</div>
|
||||||
|
<div class="week-item">周五</div>
|
||||||
|
<div class="week-item">周六</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 日历格子 -->
|
||||||
|
<div class="calendar-grid">
|
||||||
|
<!-- 上月占位 -->
|
||||||
|
<div class="calendar-cell prev-month" v-for="day in prevMonthDays" :key="'prev-' + day">
|
||||||
|
{{ day }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 当月日期 -->
|
||||||
|
<div
|
||||||
|
class="calendar-cell current-month"
|
||||||
|
v-for="day in currentMonthDays"
|
||||||
|
:key="'current-' + day"
|
||||||
|
>
|
||||||
|
<div class="date">{{ day }}</div>
|
||||||
|
<div class="meal-summary" v-if="summary[formatDate(currentMonth, day)]">
|
||||||
|
<div>总人数: {{ summary[formatDate(currentMonth, day)].totalPeople }}</div>
|
||||||
|
<div>堂食: {{ summary[formatDate(currentMonth, day)].dineInPeople }}</div>
|
||||||
|
<div>打包: {{ summary[formatDate(currentMonth, day)].takeoutPeople }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="meal-summary empty" v-else>
|
||||||
|
<div>暂无数据</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 下月占位 -->
|
||||||
|
<div class="calendar-cell next-month" v-for="day in nextMonthDays" :key="'next-' + day">
|
||||||
|
{{ day }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { listMealReport } from "@/api/wms/mealReport";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'MealCalendar',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 当前选中的月份,格式:YYYY-MM
|
||||||
|
currentMonth: dayjs().format('YYYY-MM'),
|
||||||
|
queryParams: {
|
||||||
|
mealType: '',
|
||||||
|
deptName: '',
|
||||||
|
deadlineTime: '',
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10000
|
||||||
|
},
|
||||||
|
list: [], // 原始数据列表
|
||||||
|
loading: false, // 加载状态
|
||||||
|
currentMonthDays: 0, // 当月总天数
|
||||||
|
prevMonthDays: 0, // 上月需要显示的天数
|
||||||
|
nextMonthDays: 0 // 下月需要显示的天数
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 当月开始时间(当月第一天 00:00:00)
|
||||||
|
startTime() {
|
||||||
|
return dayjs(this.currentMonth).startOf('month').format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
},
|
||||||
|
// 当月结束时间(下月第一天 00:00:00)
|
||||||
|
endTime() {
|
||||||
|
return dayjs(this.currentMonth).endOf('month').add(1, 'day').format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
},
|
||||||
|
// 按日期汇总的报餐数据
|
||||||
|
summary() {
|
||||||
|
const summaryObj = {};
|
||||||
|
this.list.forEach(item => {
|
||||||
|
// 格式化日期(统一为 YYYY-MM-DD)
|
||||||
|
const date = dayjs(item.reportDate).format('YYYY-MM-DD');
|
||||||
|
if (!summaryObj[date]) {
|
||||||
|
// 初始化当日数据
|
||||||
|
summaryObj[date] = {
|
||||||
|
totalPeople: 0,
|
||||||
|
dineInPeople: 0,
|
||||||
|
takeoutPeople: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// 累加当日数据
|
||||||
|
summaryObj[date].totalPeople += Number(item.totalPeople || 0);
|
||||||
|
summaryObj[date].dineInPeople += Number(item.dineInPeople || 0);
|
||||||
|
summaryObj[date].takeoutPeople += Number(item.takeoutPeople || 0);
|
||||||
|
});
|
||||||
|
return summaryObj;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 初始化当前月份
|
||||||
|
this.initCalendar();
|
||||||
|
// 获取初始数据
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 初始化日历参数(计算当月天数、上月/下月占位天数)
|
||||||
|
*/
|
||||||
|
initCalendar() {
|
||||||
|
const currentDate = dayjs(this.currentMonth);
|
||||||
|
// 当月总天数
|
||||||
|
this.currentMonthDays = currentDate.daysInMonth();
|
||||||
|
// 当月第一天是星期几(0-6,0=周日)
|
||||||
|
const firstDayWeek = currentDate.startOf('month').day();
|
||||||
|
// 上月需要显示的天数
|
||||||
|
this.prevMonthDays = firstDayWeek;
|
||||||
|
// 计算需要显示的总格子数(凑够7的倍数)
|
||||||
|
const totalCells = Math.ceil((this.prevMonthDays + this.currentMonthDays) / 7) * 7;
|
||||||
|
// 下月需要显示的天数
|
||||||
|
this.nextMonthDays = totalCells - this.prevMonthDays - this.currentMonthDays;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取报餐数据列表
|
||||||
|
*/
|
||||||
|
async getList() {
|
||||||
|
try {
|
||||||
|
// 组装请求参数(添加时间范围筛选)
|
||||||
|
const params = {
|
||||||
|
...this.queryParams,
|
||||||
|
startTime: this.startTime,
|
||||||
|
endTime: this.endTime
|
||||||
|
};
|
||||||
|
this.loading = true
|
||||||
|
const res = await listMealReport(params);
|
||||||
|
this.list = res.rows || [];
|
||||||
|
} catch (error) {
|
||||||
|
this.$message.error('获取报餐数据失败,请稍后重试');
|
||||||
|
console.error('获取数据失败:', error);
|
||||||
|
} finally {
|
||||||
|
this.loading = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换到上个月
|
||||||
|
*/
|
||||||
|
prevMonth() {
|
||||||
|
this.currentMonth = dayjs(this.currentMonth).subtract(1, 'month').format('YYYY-MM');
|
||||||
|
this.initCalendar();
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换到下个月
|
||||||
|
*/
|
||||||
|
nextMonth() {
|
||||||
|
this.currentMonth = dayjs(this.currentMonth).add(1, 'month').format('YYYY-MM');
|
||||||
|
this.initCalendar();
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期选择器切换月份
|
||||||
|
*/
|
||||||
|
handleMonthChange() {
|
||||||
|
this.initCalendar();
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置查询条件
|
||||||
|
*/
|
||||||
|
resetQuery() {
|
||||||
|
this.queryParams = {
|
||||||
|
mealType: '',
|
||||||
|
deptName: '',
|
||||||
|
deadlineTime: ''
|
||||||
|
};
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化日期(YYYY-MM + 日期 = YYYY-MM-DD)
|
||||||
|
* @param {String} month 月份(YYYY-MM)
|
||||||
|
* @param {Number} day 日期
|
||||||
|
*/
|
||||||
|
formatDate(month, day) {
|
||||||
|
return dayjs(`${month}-${day}`).format('YYYY-MM-DD');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.meal-calendar-container {
|
||||||
|
padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-header {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-control {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-control .el-button {
|
||||||
|
margin: 0 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 日历样式 */
|
||||||
|
.calendar-week-header {
|
||||||
|
display: flex;
|
||||||
|
background: #eef1f6;
|
||||||
|
border-radius: 4px 4px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-item {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 10px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
border-right: 1px solid #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.week-item:last-child {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-grid {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
border: 1px solid #e6e6e6;
|
||||||
|
border-top: none;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-cell {
|
||||||
|
width: calc(100% / 7);
|
||||||
|
height: 120px;
|
||||||
|
border-right: 1px solid #e6e6e6;
|
||||||
|
border-bottom: 1px solid #e6e6e6;
|
||||||
|
padding: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-cell:nth-child(7n) {
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.calendar-cell:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 上月/下月日期样式 */
|
||||||
|
.prev-month, .next-month {
|
||||||
|
color: #ccc;
|
||||||
|
background: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 当日日期样式 */
|
||||||
|
.current-month .date {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 报餐数据汇总样式 */
|
||||||
|
.meal-summary {
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meal-summary.empty {
|
||||||
|
color: #999;
|
||||||
|
line-height: 80px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user