1
0
mirror of https://github.com/ZeroCatDev/Classworks.git synced 2025-07-03 01:39:22 +00:00
This commit is contained in:
SunWuyuan 2025-03-16 09:41:48 +08:00
parent d52be573ef
commit 69c67a7e52
No known key found for this signature in database
GPG Key ID: A6A54CF66F56BB64
5 changed files with 92 additions and 57 deletions

View File

@ -5,7 +5,7 @@
</template> </template>
<v-app-bar-title> <v-app-bar-title>
{{ state.classNumber }} - {{ titleText }} {{ state.classNumber }} - {{ titleText }}
</v-app-bar-title> </v-app-bar-title>
<v-spacer /> <v-spacer />
@ -25,14 +25,13 @@
<template #activator="{ props }"> <template #activator="{ props }">
<v-btn icon="mdi-calendar" variant="text" v-bind="props" /> <v-btn icon="mdi-calendar" variant="text" v-bind="props" />
</template> </template>
<v-card border>
<v-date-picker <v-date-picker
v-model="state.selectedDate" v-model="state.selectedDateObj"
:model-value="state.selectedDate" :model-value="state.selectedDateObj"
color="primary" color="primary"
width="300"
@update:model-value="handleDateSelect" @update:model-value="handleDateSelect"
/> /></v-card>
</v-menu> </v-menu>
<v-btn <v-btn
icon="mdi-refresh" icon="mdi-refresh"
@ -372,7 +371,8 @@ export default {
snackbarText: "", snackbarText: "",
fontSize: getSetting("font.size"), fontSize: getSetting("font.size"),
datePickerDialog: false, datePickerDialog: false,
selectedDate: new Date().toISOString().split("T")[0], // selectedDate: new Date().toISOString().split("T")[0],
selectedDateObj: new Date(this.selectedDate),
refreshInterval: null, refreshInterval: null,
subjectOrder: [ subjectOrder: [
"语文", "语文",
@ -427,24 +427,20 @@ export default {
return useDisplay().mobile.value; return useDisplay().mobile.value;
}, },
titleText() { titleText() {
const now = new Date(); const today = this.getToday();
const year = now.getFullYear(); const yesterday = new Date(today);
const month = String(now.getMonth() + 1).padStart(2, "0");
const day = String(now.getDate()).padStart(2, "0");
const today = `${year}-${month}-${day}`;
const yesterday = new Date(now);
yesterday.setDate(yesterday.getDate() - 1); yesterday.setDate(yesterday.getDate() - 1);
const yesterdayFormatted = `${yesterday.getFullYear()}-${String(
yesterday.getMonth() + 1
).padStart(2, "0")}-${String(yesterday.getDate()).padStart(2, "0")}`;
if (this.state.dateString === today) { const currentDateStr = this.state.dateString;
const todayStr = this.formatDate(today);
const yesterdayStr = this.formatDate(yesterday);
if (currentDateStr === todayStr) {
return "今天的作业"; return "今天的作业";
} else if (this.state.dateString === yesterdayFormatted) { } else if (currentDateStr === yesterdayStr) {
return "昨天的作业"; return "昨天的作业";
} else { } else {
return `${this.state.dateString}的作业`; return `${currentDateStr}的作业`;
} }
}, },
sortedItems() { sortedItems() {
@ -459,7 +455,9 @@ export default {
.filter(([, value]) => value.content?.trim()) .filter(([, value]) => value.content?.trim())
.map(([key, value]) => ({ .map(([key, value]) => ({
key, key,
name: this.state.availableSubjects.find((s) => s.key === key)?.name || key, name:
this.state.availableSubjects.find((s) => s.key === key)?.name ||
key,
content: value.content, content: value.content,
order: this.state.subjectOrder.indexOf(key), order: this.state.subjectOrder.indexOf(key),
rowSpan: Math.ceil( rowSpan: Math.ceil(
@ -593,6 +591,32 @@ export default {
}, },
methods: { methods: {
//
ensureDate(dateInput) {
if (dateInput instanceof Date) {
return dateInput;
}
if (typeof dateInput === "string") {
const date = new Date(dateInput);
if (!isNaN(date.getTime())) {
return date;
}
}
return new Date(); //
},
formatDate(dateInput) {
const date = this.ensureDate(dateInput);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
},
getToday() {
return new Date();
},
async initializeData() { async initializeData() {
this.provider = getSetting("server.provider"); this.provider = getSetting("server.provider");
const domain = getSetting("server.domain"); const domain = getSetting("server.domain");
@ -605,12 +629,14 @@ export default {
// URL 使 // URL 使
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const dateFromUrl = urlParams.get("date"); const dateFromUrl = urlParams.get("date");
const today = new Date().toISOString().split("T")[0]; const today = this.getToday();
// //
this.state.dateString = dateFromUrl || today; const currentDate = dateFromUrl ? new Date(dateFromUrl) : today;
this.state.selectedDate = this.state.dateString; // this.state.dateString = this.formatDate(currentDate);
this.state.isToday = this.state.dateString === today; this.state.selectedDate = this.state.dateString;
this.state.isToday =
this.formatDate(currentDate) === this.formatDate(today);
await Promise.all([this.downloadData(), this.loadConfig()]); await Promise.all([this.downloadData(), this.loadConfig()]);
}, },
@ -700,7 +726,8 @@ export default {
if (!this.currentEditSubject) return; if (!this.currentEditSubject) return;
const content = this.state.textarea.trim(); const content = this.state.textarea.trim();
const originalContent = this.state.boardData.homework[this.currentEditSubject]?.content || ''; const originalContent =
this.state.boardData.homework[this.currentEditSubject]?.content || "";
// () // ()
if (content !== originalContent.trim()) { if (content !== originalContent.trim()) {
@ -785,9 +812,9 @@ export default {
content: "", content: "",
}; };
} }
this.state.dialogTitle = this.state.availableSubjects.find( this.state.dialogTitle =
(s) => s.key === subject this.state.availableSubjects.find((s) => s.key === subject)?.name ||
)?.name || subject; subject;
this.state.textarea = this.state.boardData.homework[subject].content; this.state.textarea = this.state.boardData.homework[subject].content;
this.state.dialogVisible = true; this.state.dialogVisible = true;
this.$nextTick(() => { this.$nextTick(() => {
@ -890,22 +917,16 @@ export default {
if (!newDate) return; if (!newDate) return;
try { try {
// const selectedDate = this.ensureDate(newDate);
const date = typeof newDate === 'string' ? new Date(newDate) : newDate; const formattedDate = this.formatDate(selectedDate);
if (!(date instanceof Date) || isNaN(date.getTime())) {
console.error('Invalid date:', newDate);
return;
}
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
const formattedDate = `${year}-${month}-${day}`;
// //
if (this.state.dateString !== formattedDate) { if (this.state.dateString !== formattedDate) {
this.state.dateString = formattedDate; this.state.dateString = formattedDate;
this.state.selectedDate = formattedDate; this.state.selectedDate = formattedDate;
this.state.isToday =
formattedDate === this.formatDate(this.getToday());
// 使 replace push // 使 replace push
this.$router this.$router
.replace({ .replace({
@ -915,8 +936,8 @@ export default {
this.downloadData(); this.downloadData();
} }
} catch (error) { } catch (error) {
console.error('Date processing error:', error); console.error("Date processing error:", error);
this.$message.error('日期处理错误', '请重新选择日期'); this.$message.error("日期处理错误", "请重新选择日期");
} }
}, },

View File

@ -136,6 +136,7 @@ $standard-accelerate: cubic-bezier(0.3, 0.0, 1.0, 1.0);
transform 150ms $emphasized-decelerate; transform 150ms $emphasized-decelerate;
touch-action: manipulation; touch-action: manipulation;
min-height: 40px; // 确保触摸目标足够大 min-height: 40px; // 确保触摸目标足够大
min-width: 40px;
&:active { &:active {
transform: scale(0.98); transform: scale(0.98);

View File

@ -0,0 +1,16 @@
export const defaultConfig = {
studentList: [
"Classworks可以管理学生列表",
'你可以点击设置,在其中找到"学生列表"',
"在添加学生处输入学生姓名,点击添加",
"或者点击高级编辑从Excel表格中复制数据并粘贴进来",
],
};
export const defaultHomework = {
homework: {},
attendance: {
absent: [],
late: [],
},
};

View File

@ -1,5 +1,6 @@
import { openDB } from 'idb'; import { openDB } from 'idb';
import { formatResponse, formatError } from '../dataProvider'; import { formatResponse, formatError } from '../dataProvider';
import { defaultConfig, defaultHomework } from '../defaults/defaultData';
const DB_NAME = "HomeworkDB"; const DB_NAME = "HomeworkDB";
const DB_VERSION = 1; const DB_VERSION = 1;
@ -32,10 +33,7 @@ export const indexedDBProvider = {
if (!data) { if (!data) {
const today = new Date().toISOString().split("T")[0]; const today = new Date().toISOString().split("T")[0];
if (date === today) { if (date === today) {
return formatResponse({ return formatResponse(defaultHomework);
homework: {},
attendance: { absent: [], late: [] },
});
} }
return formatError("数据不存在", "NOT_FOUND"); return formatError("数据不存在", "NOT_FOUND");
} }
@ -74,10 +72,7 @@ export const indexedDBProvider = {
const config = await db.get("config", storageKey); const config = await db.get("config", storageKey);
if (!config) { if (!config) {
return formatResponse({ return formatResponse(defaultConfig);
studentList: [],
displayOptions: {},
});
} }
return formatResponse(JSON.parse(config)); return formatResponse(JSON.parse(config));

View File

@ -61,7 +61,7 @@ window.addEventListener("load", initializeStorage);
*/ */
// 存储所有设置的localStorage键名 // 存储所有设置的localStorage键名
const SETTINGS_STORAGE_KEY = "classworks_settings"; const SETTINGS_STORAGE_KEY = "Classworks_settings";
/** /**
* 所有配置项的定义 * 所有配置项的定义
@ -107,9 +107,11 @@ const settingsDefinitions = {
}, },
"server.classNumber": { "server.classNumber": {
type: "string", type: "string",
default: "", default: "高三八班",
validate: (value) => /^[A-Za-z0-9]*$/.test(value), //validate: (value) => /^[A-Za-z0-9]*$/.test(value),
description: "班级编号(无论使用哪种存储方式都需要设置)", validate: (value) => /.*/.test(value),
description: "班级编号",
}, },
"server.provider": { "server.provider": {
type: "string", type: "string",