hookehuyr

feat(teacher/taskHomePage): 改进日历组件功能并优化样式

- 添加月份切换时获取打卡日期的功能
- 优化日历日期格式化逻辑,支持显示已打卡状态
- 调整日历弹窗高度和确认按钮显示
- 新增日历选中日期样式和今日标记
- 修复附件类型显示换行问题
<!--
* @Date: 2025-11-19 21:00:00
* @LastEditors: hookehuyr hookehuyr@gmail.com
* @LastEditTime: 2025-12-12 18:11:45
* @LastEditTime: 2025-12-13 21:24:23
* @FilePath: /mlaj/src/views/teacher/taskHomePage.vue
* @Description: 教师端作业主页(头部介绍、统计、日历与学生完成情况;数据Mock)
-->
......@@ -29,7 +29,8 @@
<div class="detailItem">频次:{{ task_details.frequency }}</div>
<div v-if="task_details.begin_date" class="detailItem">开始时间:{{ task_details.begin_date }}</div>
<div v-if="task_details.end_date" class="detailItem">截止时间:{{ task_details.end_date }}</div>
<div v-if="task_details.attachment_type.length" class="detailItem">附件类型:{{ task_details.attachment_type }}</div>
<div v-if="task_details.attachment_type.length" class="detailItem">附件类型:{{ task_details.attachment_type
}}</div>
<div v-if="task_type === 'checkin'" class="detailItem">类型:打卡签到</div>
</div>
</div>
......@@ -88,20 +89,15 @@
<!-- <div class="mt-3 text-sm text-gray-600">当前选择:{{ current_date_text }}</div> -->
<!-- 日历弹窗:点击“某个日期”弹出 -->
<van-config-provider :theme-vars="themeVars">
<van-calendar v-model:show="show_calendar_popup" :default-date="calendar_default_date" color="#10b981"
:show-confirm="true" switch-mode="month" :formatter="formatter" @confirm="on_date_select" />
<van-calendar v-model:show="show_calendar_popup" :default-date="calendar_default_date" color="#4caf50"
:show-confirm="false" switch-mode="month" :formatter="formatter" @select="on_date_select" @panel-change="onPanelChange" />
</van-config-provider>
</div>
<!-- 小作业选择弹窗 -->
<van-popup v-model:show="show_subtask_picker" position="bottom" round>
<van-picker
:columns="subtask_columns"
@confirm="on_confirm_subtask"
@cancel="show_subtask_picker = false"
show-toolbar
title="选择作业"
/>
<van-picker :columns="subtask_columns" @confirm="on_confirm_subtask" @cancel="show_subtask_picker = false"
show-toolbar title="选择作业" />
</van-popup>
<!-- 学生完成情况(参考图片2样式) -->
......@@ -132,6 +128,7 @@ import { useRoute, useRouter } from 'vue-router'
import { useTitle } from '@vueuse/core'
import checkCorner from '@/assets/images/dui.png'
import { getTeacherTaskDetailAPI } from '@/api/teacher'
import { getCheckinTeacherCheckedDatesAPI } from '@/api/checkin'
import dayjs from 'dayjs'
const $route = useRoute()
......@@ -139,7 +136,7 @@ const $router = useRouter()
useTitle('作业主页')
const themeVars = {
calendarPopupHeight: '60%',
calendarPopupHeight: '55%',
}
// 弹窗显示状态:是否展示“某个日期”选择日历
......@@ -178,29 +175,49 @@ function select_yesterday() {
calendar_default_date.value = null
}
const currentMonth = ref(dayjs().format('YYYY-MM'));
const selectedDate = ref(dayjs().format('YYYY-MM-DD'));
/**
* 日历日期格式化函数
* @param {Object} day - 日历天对象
* @returns {Object} 处理后的日历天对象
*/
const formatter = (day) => {
const dateStr = format_date(day.date)
const today = new Date()
const todayStr = format_date(today)
const yesterday = new Date(today)
yesterday.setDate(today.getDate() - 1)
const yesterdayStr = format_date(yesterday)
const year = day.date.getFullYear();
const month = day.date.getMonth() + 1;
const date = day.date.getDate();
let checkin_days = myCheckinDates.value;
// 检查当前日期是否在签到日期列表中
if (checkin_days && checkin_days.length > 0) {
// 格式化当前日期为YYYY-MM-DD格式,与checkin_days中的格式匹配
const formattedDate = `${year}-${month.toString().padStart(2, '0')}-${date.toString().padStart(2, '0')}`;
// 检查是否已打卡
if (checkin_days.includes(formattedDate)) {
// 如果是当前选中的已打卡日期,使用特殊样式
if (selectedDate.value === formattedDate) {
day.className = 'calendar-selected';
day.type = 'selected';
day.bottomInfo = '已打卡';
} else {
day.className = 'calendar-checkin';
day.type = 'selected';
day.bottomInfo = '已打卡';
}
}
}
if (dateStr === todayStr) {
// 选中今天的日期
if (dayjs(day.date).isSame(new Date(), 'day')) {
day.className = 'calendar-today';
day.bottomInfo = '今日'
} else if (dateStr === yesterdayStr) {
day.className = 'calendar-yesterday';
day.bottomInfo = '昨日'
day.type = 'selected';
day.bottomInfo = '今日';
}
return day
return day;
}
/**
......@@ -263,6 +280,7 @@ const on_confirm_subtask = ({ selectedOptions }) => {
if (selectedOptions && selectedOptions[0]) {
selectedSubtaskId.value = selectedOptions[0].value
fetchData()
getCheckedDates(dayjs().format('YYYY-MM'));
}
show_subtask_picker.value = false
}
......@@ -339,8 +357,23 @@ watch(selected_date, () => {
fetchData()
})
const myCheckinDates = ref([]);
// 获取用户打卡日期的函数
const getCheckedDates = async (month) => {
const checkedDatesResult = await getCheckinTeacherCheckedDatesAPI({
id: task_id,
subtask_id: selectedSubtaskId.value,
month
});
if (checkedDatesResult.code) {
myCheckinDates.value = checkedDatesResult.data.my_checkin_dates;
}
}
onMounted(() => {
fetchData()
getCheckedDates(dayjs().format('YYYY-MM'));
})
/**
......@@ -391,6 +424,12 @@ function on_date_select(val) {
calendar_default_date.value = is_date_obj ? val : parse_date_text(text)
}
// 切换月份时触发
const onPanelChange = ({ date }) => {
currentMonth.value = dayjs(date).format('YYYY-MM');
getCheckedDates(currentMonth.value);
}
/**
* 计算某日期下学生完成情况列表
* @returns {{id:string,name:string,completed:boolean}[]} 学生状态列表
......@@ -438,7 +477,7 @@ function go_student_record(stu) {
}
</script>
<style lang="less" scoped>
<style lang="less">
.TaskHomePage {
min-height: 100vh;
background: linear-gradient(to bottom right, #f0fdf4, #f0fdfa, #eff6ff);
......@@ -507,4 +546,16 @@ function go_student_record(stu) {
}
}
}
.calendar-checkin {
.van-calendar__selected-day {
background: #a2d8a3 !important;
}
}
.calendar-today {
.van-calendar__selected-day {
background: #FAAB0C !important;
}
}
</style>
......