更新 ExamList.vue

This commit is contained in:
Jursin 2024-12-01 13:33:24 +08:00 committed by GitHub
parent df1679bc6c
commit 995dac31ed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -12,11 +12,17 @@
class="text-h5" class="text-h5"
> >
<template #item="{ item }"> <template #item="{ item }">
<tr :style="{ lineHeight: '2.0rem' }"> <tr :style="{ lineHeight: item.name.includes('/') ? '2.5rem' : '2.0rem' }">
<td v-if="item.showDate" class="text-h5 date-column" :rowspan="item.rowspan"> <td v-if="item.showDate" class="text-h5 date-column" :rowspan="item.rowspan">
{{ item.date }}<br>{{ item.period }} {{ item.date }}<br>{{ item.period }}
</td> </td>
<td class="text-h5 subject-column">{{ item.name }}</td> <td class="text-h5 subject-column">
<div v-if="item.name.includes('/')">
<div>{{ item.name.split('/')[0] }}</div>
<div>{{ item.name.split('/')[1] }}</div>
</div>
<div v-else>{{ item.name }}</div>
</td>
<td class="text-h5 time-column">{{ formatTime(item.start) }}</td> <td class="text-h5 time-column">{{ formatTime(item.start) }}</td>
<td class="text-h5 time-column">{{ formatTime(item.end) }}</td> <td class="text-h5 time-column">{{ formatTime(item.end) }}</td>
<td class="status-column"> <td class="status-column">
@ -27,19 +33,19 @@
</tr> </tr>
</template> </template>
<template #header.date> <template #header.date>
<span class="text-h5 font-weight-bold">日期</span> <span class="text-h5 font-weight-bold no-wrap">日期</span>
</template> </template>
<template #header.name> <template #header.name>
<span class="text-h5 font-weight-bold">科目</span> <span class="text-h5 font-weight-bold no-wrap">科目</span>
</template> </template>
<template #header.start> <template #header.start>
<span class="text-h5 font-weight-bold">开始</span> <span class="text-h5 font-weight-bold no-wrap">开始</span>
</template> </template>
<template #header.end> <template #header.end>
<span class="text-h5 font-weight-bold">结束</span> <span class="text-h5 font-weight-bold no-wrap">结束</span>
</template> </template>
<template #header.status> <template #header.status>
<span class="text-h5 font-weight-bold">状态</span> <span class="text-h5 font-weight-bold no-wrap">状态</span>
</template> </template>
</v-data-table> </v-data-table>
</v-col> </v-col>
@ -50,38 +56,44 @@
<script setup lang="ts"> <script setup lang="ts">
import { reactive, computed, onMounted, onUnmounted } from 'vue'; import { reactive, computed, onMounted, onUnmounted } from 'vue';
const props = defineProps({ const props = defineProps({
exam: { exam: {
type: Array as () => any[], type: Array as () => any[],
default: () => [] default: () => []
} }
}); });
const state = reactive({ const state = reactive({
exams: props.exam exams: props.exam
}); });
function formatPeriod(isoString: string): string { function formatPeriod(isoString: string): string {
const hour = new Date(isoString).getHours(); const hour = new Date(isoString).getHours();
if (hour < 12) return '上午'; if (hour < 12) return '上午';
else if (hour < 18) return '下午'; else if (hour < 18) return '下午';
else return '晚上'; else return '晚上';
} }
const groupedExams = computed(() => { const groupedExams = computed(() => {
const grouped = []; const grouped = [];
let currentDate = ''; let currentDate = '';
let currentPeriod = ''; let currentPeriod = '';
sortedExams.value.forEach((exam, index) => { sortedExams.value.forEach((exam, index) => {
const examDate = new Date(exam.start).toLocaleDateString('zh-CN', { const examDate = new Date(exam.start)
month: 'numeric', .toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' })
day: 'numeric' .replace('/', '月') + '日';
}).replace('/', '月') + '日';
const period = formatPeriod(exam.start); const period = formatPeriod(exam.start);
const showDate = examDate !== currentDate || period !== currentPeriod; const showDate = examDate !== currentDate || period !== currentPeriod;
if (showDate) { if (showDate) {
currentDate = examDate; currentDate = examDate;
currentPeriod = period; currentPeriod = period;
const rowspan = sortedExams.value.filter(e => const rowspan = sortedExams.value.filter(
new Date(e.start).toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' }).replace('/', '月') + '日' === currentDate && (e) =>
formatPeriod(e.start) === currentPeriod new Date(e.start)
.toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' })
.replace('/', '月') + '日' === currentDate &&
formatPeriod(e.start) === currentPeriod
).length; ).length;
grouped.push({ ...exam, date: examDate, period, showDate, rowspan }); grouped.push({ ...exam, date: examDate, period, showDate, rowspan });
} else { } else {
@ -90,6 +102,7 @@ const groupedExams = computed(() => {
}); });
return grouped; return grouped;
}); });
const headers = [ const headers = [
{ text: '日期', value: 'date', sortable: false, align: 'center' }, { text: '日期', value: 'date', sortable: false, align: 'center' },
{ text: '科目', value: 'name', align: 'center' }, { text: '科目', value: 'name', align: 'center' },
@ -97,10 +110,12 @@ const headers = [
{ text: '结束', value: 'end', sortable: false, align: 'center' }, { text: '结束', value: 'end', sortable: false, align: 'center' },
{ text: '状态', value: 'status', sortable: false, align: 'center' } { text: '状态', value: 'status', sortable: false, align: 'center' }
]; ];
const formatTime = (isoString: string) => { const formatTime = (isoString: string) => {
const date = new Date(isoString); const date = new Date(isoString);
return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
}; };
function getStatusColor(item: any): string { function getStatusColor(item: any): string {
const now = new Date(); const now = new Date();
const startTime = new Date(item.start); const startTime = new Date(item.start);
@ -109,6 +124,7 @@ function getStatusColor(item: any): string {
else if (now >= startTime && now <= endTime) return 'green'; else if (now >= startTime && now <= endTime) return 'green';
else return 'red'; else return 'red';
} }
function getStatusText(item: any): string { function getStatusText(item: any): string {
const now = new Date(); const now = new Date();
const startTime = new Date(item.start); const startTime = new Date(item.start);
@ -121,9 +137,11 @@ function getStatusText(item: any): string {
return '已结束'; return '已结束';
} }
} }
const sortedExams = computed(() => { const sortedExams = computed(() => {
return state.exams.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime()); return state.exams.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime());
}); });
onMounted(() => { onMounted(() => {
const interval = setInterval(() => { const interval = setInterval(() => {
state.exams = state.exams.map((exam) => ({ state.exams = state.exams.map((exam) => ({
@ -131,6 +149,7 @@ onMounted(() => {
status: getStatusText(exam) status: getStatusText(exam)
})); }));
}, 1000); }, 1000);
onUnmounted(() => { onUnmounted(() => {
clearInterval(interval); clearInterval(interval);
}); });
@ -152,6 +171,11 @@ onMounted(() => {
text-align: center; text-align: center;
} }
/* 强制标题行文字不换行 */
.no-wrap {
white-space: nowrap;
}
/* 列样式 */ /* 列样式 */
.date-column, .date-column,
.subject-column, .subject-column,