feat(wms): 新增员工报餐日历页面

添加员工报餐日历功能页面,包含月份切换、餐型和部门筛选功能,展示每日报餐人数统计
This commit is contained in:
砂糖
2026-03-06 17:22:18 +08:00
parent 3afac814c4
commit 4fdddac389

View 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-60=周日)
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>