<template> <div class="pro_scheduling"> <div class="pick"> <span>当前日期:{{ yue ? yue : dDate }}</span> <el-date-picker v-model="yue" value-format="yyyy-MM" format="yyyy 年 MM 月" type="month" placeholder="选择日期" @change="changeYue" > </el-date-picker> </div> <el-calendar v-model="yue"> <template #dateCell="{ date }"> <div> <div>{{ date.getDate() }}</div> <div v-if="isDateAvailable(date)"> <el-button type="primary" @click="bookDate(date)" :disabled="!isDateAvailable(date)" > 可预约 </el-button> <div class="yy">已约 {{ bookedCount(date) }}</div> <div class="yy">剩余 {{ availableCount(date) }}</div> </div> <div v-else> <el-button disabled>不可预约</el-button> <div class="test">已约 {{ bookedCount(date) }}</div> <div class="test">剩余 0</div> </div> </div> </template> </el-calendar> <el-dialog :visible.sync="dialogVisible" @open="onOpen" @close="onClose" title="编辑" > <el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px" > <el-form-item label="出行日期" prop="date"> <el-input v-model="formData.date" placeholder="请输入单行文本单行文本" :disabled="true" clearable :style="{ width: '100%' }" ></el-input> </el-form-item> <el-form-item label="可预约数量" prop="num"> <el-input v-model="formData.num" type="number" placeholder="请输入可预约数量" clearable :style="{ width: '100%' }" ></el-input> </el-form-item> </el-form> <div slot="footer"> <el-button @click="close">取消</el-button> <el-button type="primary" @click="handelConfirm">确定</el-button> </div> </el-dialog> </div> </template> <script> import { getProductSchedules, addProductSchedulesApi } from "@/api/admin"; export default { data() { return { dialogVisible: false, value: new Date(), appointments: {}, formData: { date: "", num: "", id: "", }, yue: "", dDate: "", rules: { num: [ { required: true, message: "请输入可预约数量", trigger: "blur", }, ], }, }; }, created() { this.formData.id = this.$route.query.id; this.getList(); }, methods: { async getList(val) { const date = this.value; // 使用当前展示的日期 const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, "0"); const formattedDate = `${year}-${month}`; this.dDate = formattedDate; const param = { id: this.formData.id, date: val ? val : formattedDate, }; const res = await getProductSchedules(param); if (res && res.error === 0) { this.appointments = {}; // 清空旧数据 res.data.forEach((item) => { this.$set(this.appointments, item.date, { books_num: item.books_num, left_num: item.left_num, }); }); } }, changeYue() { this.getList(this.yue); }, isDateAvailable(date) { const today = new Date(); today.setHours(0, 0, 0, 0); return date >= today; }, isDateAvailable(date) { const today = new Date(); today.setHours(0, 0, 0, 0); // 获取当前选择的月份和年份 const selectedYear = this.yue ? new Date(this.yue).getFullYear() : today.getFullYear(); const selectedMonth = this.yue ? new Date(this.yue).getMonth() : today.getMonth(); // 获取目标日期的年份和月份 const dateYear = date.getFullYear(); const dateMonth = date.getMonth(); // 如果目标日期是在当前选择的月份之后的月份 if ( dateYear > selectedYear || (dateYear === selectedYear && dateMonth > selectedMonth) ) { return true; } // 如果目标日期是在当前选择的月份,并且日期大于等于今天 if ( dateYear === selectedYear && dateMonth === selectedMonth && date >= today ) { return true; } // 其他情况下,日期不可用 return false; }, bookDate(date) { console.log(`预约日期: ${date.toLocaleDateString()}`); this.dialogVisible = true; this.formData.date = date.toLocaleDateString(); }, onOpen() {}, onClose() { this.$refs["elForm"].resetFields(); }, close() { this.dialogVisible = false; }, handelConfirm() { this.$refs["elForm"].validate(async (valid) => { if (!valid) return; const res = await addProductSchedulesApi(this.formData); if (res.error === 0) { this.$message.success("预约成功"); this.getList(); } this.close(); }); }, }, computed: { availableCount() { return (date) => { const dateString = date.toISOString().split("T")[0]; return this.appointments[dateString]?.left_num || 0; }; }, bookedCount() { return (date) => { const dateString = date.toISOString().split("T")[0]; return this.appointments[dateString]?.books_num || 0; }; }, }, }; </script> <style scoped lang="scss"> .pick { position: relative; top: 20px; left: 40px; display: flex; align-items: center; width: 100%; height: 50px; span { margin-right: 20px; } } .pro_scheduling { display: flex; flex-direction: column; align-items: center; position: relative; .el-calendar { margin: 20px 0; } } .pro_scheduling ::v-deep .el-calendar-table .el-calendar-day { height: 130px; } .test { color: #c6ccd2; font-size: 14px; margin-top: 10px; } .yy { color: #8a8c90; font-size: 14px; margin-top: 10px; } ::v-deep .el-calendar-table:not(.is-range) td.prev, ::v-deep .el-calendar-table:not(.is-range) td.next { cursor: not-allowed; pointer-events: none; // display: none; } // ::v-deep .el-calendar-table:not(.is-range) td.prev { // /*隐藏上个月的日期*/ // visibility: hidden; // } .prev > .el-calendar-day > .dateContent { display: none; } .next > .el-calendar-day > .dateContent { display: none; } // 隐藏月份后多一行 ::v-deep .el-calendar-table:not(.is-range) td.next { /*隐藏下个月的日期*/ visibility: hidden; } // 隐藏上个月 今天 下个月按钮 ::v-deep .el-calendar__button-group { display: none; } ::v-deep .el-calendar__title { display: none; } ::v-deep .el-calendar-table thead th { font-weight: bold; color: #202020; } </style>