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-02-23 14:35:39 +08:00
parent dfdb662e11
commit 4f2fd40f78
No known key found for this signature in database
GPG Key ID: A6A54CF66F56BB64
2 changed files with 196 additions and 61 deletions

View File

@ -11,11 +11,35 @@
<v-spacer /> <v-spacer />
<template #append> <template #append>
<v-btn
icon="mdi-format-font-size-decrease"
variant="text"
@click="zoom('out')"
/>
<v-btn
icon="mdi-format-font-size-increase"
variant="text"
@click="zoom('up')"
/>
<v-menu
v-model="datePickerDialog"
:close-on-content-click="false"
>
<template v-slot:activator="{ props }">
<v-btn <v-btn
icon="mdi-calendar" icon="mdi-calendar"
variant="text" variant="text"
@click="datePickerDialog = true" v-bind="props"
/> />
</template>
<v-date-picker
v-model="selectedDate"
color="primary"
@update:model-value="handleDateSelect"
/>
</v-menu>
<v-btn <v-btn
icon="mdi-refresh" icon="mdi-refresh"
variant="text" variant="text"
@ -100,25 +124,6 @@
</v-row> </v-row>
</v-container> </v-container>
<v-container fluid> <v-container fluid>
<v-btn
icon="mdi-plus"
variant="text"
@click="zoom('up')"
/>
<v-btn
icon="mdi-minus"
variant="text"
@click="zoom('out')"
/>
<v-btn
v-if="!synced"
color="primary"
size="large"
:loading="downloadLoading"
@click="downloadData"
>
下载
</v-btn>
<v-btn <v-btn
v-if="!synced" v-if="!synced"
color="error" color="error"
@ -200,33 +205,12 @@
</v-card> </v-card>
</v-dialog> </v-dialog>
<v-dialog
v-model="ServerSelectionDialog"
width="500"
>
<ServerSelection />
</v-dialog>
<v-snackbar <v-snackbar
v-model="snackbar" v-model="snackbar"
:timeout="2000" :timeout="2000"
> >
{{ snackbarText }} {{ snackbarText }}
</v-snackbar> </v-snackbar>
<v-dialog v-model="datePickerDialog" width="auto">
<v-card>
<v-card-title>选择日期</v-card-title>
<v-card-text>
<v-date-picker v-model="selectedDate" />
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn color="primary" @click="goToDate">确定</v-btn>
<v-btn @click="datePickerDialog = false">取消</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template> </template>
<script> <script>
@ -256,11 +240,12 @@ export default {
homeworkArrange: [[], []], homeworkArrange: [[], []],
snackbar: false, snackbar: false,
snackbarText: "", snackbarText: "",
fontSize: 28, fontSize: parseInt(localStorage.getItem('fontSize')) || 28,
ServerSelectionDialog: false,
datePickerDialog: false, datePickerDialog: false,
selectedDate: null, selectedDate: null,
refreshInterval: null, refreshInterval: null,
autoSave: false,
refreshBeforeEdit: false,
}; };
}, },
@ -269,12 +254,19 @@ export default {
return useDisplay().mobile.value; return useDisplay().mobile.value;
}, },
titleText() { titleText() {
const today = new Date().toISOString().split('T')[0]; const now = new Date();
const yesterday = new Date(Date.now() - 86400000).toISOString().split('T')[0]; const year = now.getFullYear();
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);
const yesterdayFormatted = `${yesterday.getFullYear()}-${String(yesterday.getMonth() + 1).padStart(2, '0')}-${String(yesterday.getDate()).padStart(2, '0')}`;
if (this.dateString === today) { if (this.dateString === today) {
return '今天的作业'; return '今天的作业';
} else if (this.dateString === yesterday) { } else if (this.dateString === yesterdayFormatted) {
return '昨天的作业'; return '昨天的作业';
} else { } else {
return `${this.dateString}的作业`; return `${this.dateString}的作业`;
@ -287,6 +279,8 @@ export default {
this.updateBackendUrl(); this.updateBackendUrl();
await this.initializeData(); await this.initializeData();
this.setupAutoRefresh(); this.setupAutoRefresh();
this.autoSave = localStorage.getItem('autoSave') === 'true';
this.refreshBeforeEdit = localStorage.getItem('refreshBeforeEdit') === 'true';
} catch (err) { } catch (err) {
console.error("初始化失败:", err); console.error("初始化失败:", err);
this.showError("初始化失败,请刷新页面重试"); this.showError("初始化失败,请刷新页面重试");
@ -318,21 +312,30 @@ export default {
setCurrentDate() { setCurrentDate() {
if (this.$route.query.date) { if (this.$route.query.date) {
//
try { try {
const date = new Date(this.$route.query.date); const date = new Date(this.$route.query.date);
if (isNaN(date.getTime())) { if (isNaN(date.getTime())) {
throw new Error('Invalid date'); throw new Error('Invalid date');
} }
this.dateString = date.toISOString().split('T')[0]; // 使
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
this.dateString = `${year}-${month}-${day}`;
} catch (e) { } catch (e) {
// 使 // 使
const today = new Date(); const today = new Date();
this.dateString = today.toISOString().split('T')[0]; const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
this.dateString = `${year}-${month}-${day}`;
} }
} else { } else {
const today = new Date(); const today = new Date();
this.dateString = today.toISOString().split('T')[0]; const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
this.dateString = `${year}-${month}-${day}`;
} }
}, },
@ -340,6 +343,11 @@ export default {
if (this.currentEditSubject) { if (this.currentEditSubject) {
this.homeworkData[this.currentEditSubject].content = this.textarea; this.homeworkData[this.currentEditSubject].content = this.textarea;
this.synced = false; this.synced = false;
//
if (this.autoSave) {
this.uploadData();
}
} }
this.dialogVisible = false; this.dialogVisible = false;
}, },
@ -354,7 +362,16 @@ export default {
this.snackbarText = message; this.snackbarText = message;
}, },
openDialog(subject) { async openDialog(subject) {
//
if (this.refreshBeforeEdit) {
try {
await this.downloadData();
} catch (err) {
this.showError("刷新数据失败,可能显示的不是最新数据");
}
}
this.currentEditSubject = subject; this.currentEditSubject = subject;
this.dialogTitle = this.homeworkData[subject].name; this.dialogTitle = this.homeworkData[subject].name;
this.textarea = this.homeworkData[subject].content; this.textarea = this.homeworkData[subject].content;
@ -379,13 +396,18 @@ export default {
toggleStudentStatus(index) { toggleStudentStatus(index) {
if (this.selectedSet.has(index)) { if (this.selectedSet.has(index)) {
this.selectedSet.delete(index); this.selectedSet.delete(index);
this.lateSet.add(index); // Toggle to late this.lateSet.add(index);
} else if (this.lateSet.has(index)) { } else if (this.lateSet.has(index)) {
this.lateSet.delete(index); this.lateSet.delete(index);
} else { } else {
this.selectedSet.add(index); // Toggle to late this.selectedSet.add(index);
} }
this.synced = false; this.synced = false;
//
if (this.autoSave) {
this.uploadData();
}
}, },
cleanstudentslist() cleanstudentslist()
{ {
@ -393,6 +415,10 @@ export default {
this.lateSet.clear(); this.lateSet.clear();
this.synced = false; this.synced = false;
//
if (this.autoSave) {
this.uploadData();
}
}, },
zoom(direction) { zoom(direction) {
const step = 2; const step = 2;
@ -404,9 +430,12 @@ export default {
this.contentStyle = { this.contentStyle = {
"font-size": `${this.fontSize}px`, "font-size": `${this.fontSize}px`,
}; };
localStorage.setItem('fontSize', this.fontSize.toString());
}, },
async uploadData() { async uploadData() {
if (this.uploadLoading) return; //
try { try {
this.uploadLoading = true; this.uploadLoading = true;
await axios.post(`${this.backurl}/homework`, { await axios.post(`${this.backurl}/homework`, {
@ -514,12 +543,17 @@ export default {
} }
}, },
goToDate() { handleDateSelect(newDate) {
if (this.selectedDate) { if (newDate) {
const formattedDate = new Date(this.selectedDate).toISOString().split('T')[0]; // 使
const date = new Date(newDate);
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}`;
this.dateString = formattedDate; this.dateString = formattedDate;
this.$router.push(`/?date=${formattedDate}`); this.$router.push(`/?date=${formattedDate}`);
this.datePickerDialog = false;
this.downloadData(); this.downloadData();
} }
}, },

View File

@ -32,7 +32,7 @@
<v-col cols="12"> <v-col cols="12">
<v-card> <v-card>
<v-card-title>学生列表设置</v-card-title> <v-card-title>云端学生列表设置</v-card-title>
<v-card-text> <v-card-text>
<v-textarea v-model="students" label="学生列表" required /> <v-textarea v-model="students" label="学生列表" required />
<v-btn color="primary" @click="saveStudents">保存</v-btn> <v-btn color="primary" @click="saveStudents">保存</v-btn>
@ -41,7 +41,7 @@
</v-col> </v-col>
<v-col cols="12"> <v-col cols="12">
<v-card> <v-card disabled>
<v-card-title>自动刷新设置</v-card-title> <v-card-title>自动刷新设置</v-card-title>
<v-card-text> <v-card-text>
<v-switch v-model="autoRefresh" label="启用自动刷新"/> <v-switch v-model="autoRefresh" label="启用自动刷新"/>
@ -55,6 +55,64 @@
</v-card-text> </v-card-text>
</v-card> </v-card>
</v-col> </v-col>
<v-col cols="12">
<v-card>
<v-card-title>字体设置</v-card-title>
<v-card-text>
<v-row align="center">
<v-col>
<v-text-field
v-model="fontSize"
type="number"
label="字体大小"
suffix="px"
:rules="[
v => v >= 16 || '字体大小不能小于16px',
v => v <= 100 || '字体大小不能大于100px'
]"
/>
</v-col>
<v-col cols="auto">
<v-btn color="primary" @click="saveFontSize">保存</v-btn>
</v-col>
<v-col cols="auto">
<v-btn color="error" @click="resetFontSize">重置</v-btn>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-col>
<v-col cols="12">
<v-card>
<v-card-title>编辑设置</v-card-title>
<v-card-text>
<v-row>
<v-col>
<v-switch
v-model="autoSave"
label="启用自动保存"
hint="编辑完成后自动上传到服务器"
persistent-hint
@change="saveEditSettings"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-switch
v-model="refreshBeforeEdit"
label="编辑前自动刷新"
hint="打开编辑框前自动从服务器获取最新数据"
persistent-hint
@change="saveEditSettings"
/>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-col>
</v-row> </v-row>
</v-container> </v-container>
@ -77,6 +135,9 @@ export default {
snackbarText: '', snackbarText: '',
autoRefresh: false, autoRefresh: false,
refreshInterval: 300, refreshInterval: 300,
fontSize: '28',
autoSave: false,
refreshBeforeEdit: false,
}; };
}, },
@ -102,6 +163,14 @@ export default {
this.autoRefresh = localStorage.getItem('autoRefresh') === 'true'; this.autoRefresh = localStorage.getItem('autoRefresh') === 'true';
this.refreshInterval = parseInt(localStorage.getItem('refreshInterval')) || 300; this.refreshInterval = parseInt(localStorage.getItem('refreshInterval')) || 300;
const savedFontSize = localStorage.getItem('fontSize');
if (savedFontSize) {
this.fontSize = savedFontSize;
}
this.autoSave = localStorage.getItem('autoSave') === 'true';
this.refreshBeforeEdit = localStorage.getItem('refreshBeforeEdit') === 'true';
}, },
saveServerSettings() { saveServerSettings() {
@ -151,6 +220,38 @@ export default {
this.showMessage('保存成功'); this.showMessage('保存成功');
}, },
saveFontSize() {
try {
const size = parseInt(this.fontSize);
if (size >= 16 && size <= 100) {
localStorage.setItem('fontSize', size.toString());
this.showMessage('字体大小保存成功');
} else {
throw new Error('Invalid font size');
}
} catch (error) {
this.showMessage('保存失败字体大小必须在16-100之间');
}
},
resetFontSize() {
localStorage.removeItem('fontSize');
this.fontSize = '28';
this.showMessage('字体大小已重置为默认值');
},
saveEditSettings() {
localStorage.setItem('autoSave', this.autoSave);
localStorage.setItem('refreshBeforeEdit', this.refreshBeforeEdit);
this.showMessage(
this.autoSave
? '已启用自动保存'
: this.refreshBeforeEdit
? '已启用编辑前刷新'
: '已更新编辑设置'
);
},
showMessage(text) { showMessage(text) {
this.snackbarText = text; this.snackbarText = text;
this.snackbar = true; this.snackbar = true;