mirror of
https://hub.gitmirror.com/https://github.com/ExamAware/ExamShowboard-Legacy.git
synced 2025-04-29 08:06:32 +00:00
更新 ExamList.vue
This commit is contained in:
parent
df1679bc6c
commit
995dac31ed
@ -12,11 +12,17 @@
|
||||
class="text-h5"
|
||||
>
|
||||
<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">
|
||||
{{ item.date }}<br>{{ item.period }}
|
||||
</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.end) }}</td>
|
||||
<td class="status-column">
|
||||
@ -27,19 +33,19 @@
|
||||
</tr>
|
||||
</template>
|
||||
<template #header.date>
|
||||
<span class="text-h5 font-weight-bold">日期</span>
|
||||
<span class="text-h5 font-weight-bold no-wrap">日期</span>
|
||||
</template>
|
||||
<template #header.name>
|
||||
<span class="text-h5 font-weight-bold">科目</span>
|
||||
<span class="text-h5 font-weight-bold no-wrap">科目</span>
|
||||
</template>
|
||||
<template #header.start>
|
||||
<span class="text-h5 font-weight-bold">开始</span>
|
||||
<span class="text-h5 font-weight-bold no-wrap">开始</span>
|
||||
</template>
|
||||
<template #header.end>
|
||||
<span class="text-h5 font-weight-bold">结束</span>
|
||||
<span class="text-h5 font-weight-bold no-wrap">结束</span>
|
||||
</template>
|
||||
<template #header.status>
|
||||
<span class="text-h5 font-weight-bold">状态</span>
|
||||
<span class="text-h5 font-weight-bold no-wrap">状态</span>
|
||||
</template>
|
||||
</v-data-table>
|
||||
</v-col>
|
||||
@ -50,38 +56,44 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { reactive, computed, onMounted, onUnmounted } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
exam: {
|
||||
type: Array as () => any[],
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const state = reactive({
|
||||
exams: props.exam
|
||||
});
|
||||
|
||||
function formatPeriod(isoString: string): string {
|
||||
const hour = new Date(isoString).getHours();
|
||||
if (hour < 12) return '上午';
|
||||
else if (hour < 18) return '下午';
|
||||
else return '晚上';
|
||||
}
|
||||
|
||||
const groupedExams = computed(() => {
|
||||
const grouped = [];
|
||||
let currentDate = '';
|
||||
let currentPeriod = '';
|
||||
sortedExams.value.forEach((exam, index) => {
|
||||
const examDate = new Date(exam.start).toLocaleDateString('zh-CN', {
|
||||
month: 'numeric',
|
||||
day: 'numeric'
|
||||
}).replace('/', '月') + '日';
|
||||
const examDate = new Date(exam.start)
|
||||
.toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' })
|
||||
.replace('/', '月') + '日';
|
||||
const period = formatPeriod(exam.start);
|
||||
const showDate = examDate !== currentDate || period !== currentPeriod;
|
||||
if (showDate) {
|
||||
currentDate = examDate;
|
||||
currentPeriod = period;
|
||||
const rowspan = sortedExams.value.filter(e =>
|
||||
new Date(e.start).toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' }).replace('/', '月') + '日' === currentDate &&
|
||||
formatPeriod(e.start) === currentPeriod
|
||||
const rowspan = sortedExams.value.filter(
|
||||
(e) =>
|
||||
new Date(e.start)
|
||||
.toLocaleDateString('zh-CN', { month: 'numeric', day: 'numeric' })
|
||||
.replace('/', '月') + '日' === currentDate &&
|
||||
formatPeriod(e.start) === currentPeriod
|
||||
).length;
|
||||
grouped.push({ ...exam, date: examDate, period, showDate, rowspan });
|
||||
} else {
|
||||
@ -90,6 +102,7 @@ const groupedExams = computed(() => {
|
||||
});
|
||||
return grouped;
|
||||
});
|
||||
|
||||
const headers = [
|
||||
{ text: '日期', value: 'date', sortable: false, align: 'center' },
|
||||
{ text: '科目', value: 'name', align: 'center' },
|
||||
@ -97,10 +110,12 @@ const headers = [
|
||||
{ text: '结束', value: 'end', sortable: false, align: 'center' },
|
||||
{ text: '状态', value: 'status', sortable: false, align: 'center' }
|
||||
];
|
||||
|
||||
const formatTime = (isoString: string) => {
|
||||
const date = new Date(isoString);
|
||||
return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
function getStatusColor(item: any): string {
|
||||
const now = new Date();
|
||||
const startTime = new Date(item.start);
|
||||
@ -109,6 +124,7 @@ function getStatusColor(item: any): string {
|
||||
else if (now >= startTime && now <= endTime) return 'green';
|
||||
else return 'red';
|
||||
}
|
||||
|
||||
function getStatusText(item: any): string {
|
||||
const now = new Date();
|
||||
const startTime = new Date(item.start);
|
||||
@ -121,9 +137,11 @@ function getStatusText(item: any): string {
|
||||
return '已结束';
|
||||
}
|
||||
}
|
||||
|
||||
const sortedExams = computed(() => {
|
||||
return state.exams.sort((a, b) => new Date(a.start).getTime() - new Date(b.start).getTime());
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
const interval = setInterval(() => {
|
||||
state.exams = state.exams.map((exam) => ({
|
||||
@ -131,6 +149,7 @@ onMounted(() => {
|
||||
status: getStatusText(exam)
|
||||
}));
|
||||
}, 1000);
|
||||
|
||||
onUnmounted(() => {
|
||||
clearInterval(interval);
|
||||
});
|
||||
@ -152,6 +171,11 @@ onMounted(() => {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* 强制标题行文字不换行 */
|
||||
.no-wrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 列样式 */
|
||||
.date-column,
|
||||
.subject-column,
|
||||
|
Loading…
x
Reference in New Issue
Block a user