1
0
mirror of https://github.com/ZeroCatDev/Classworks.git synced 2025-07-05 11:09:29 +00:00
This commit is contained in:
孙悟元 2024-11-24 16:52:47 +08:00
parent 7abd0f0a15
commit 1137f44c44
2 changed files with 109 additions and 38 deletions

View File

@ -1,59 +1,101 @@
<template> <template>
<v-card title="选择服务器"> <v-card border>
<v-card-text> <v-card>
<v-form @submit.prevent="saveServerUrl"> <v-card-title>选择服务器</v-card-title>
<v-text-field v-model="serverUrl" label="后端地址" required /> <v-card-subtitle>没事别乱动</v-card-subtitle>
<v-btn type="submit" color="primary"> 保存 </v-btn> <v-card-text>
</v-form> <v-text-field v-model="serverUrl" label="后端地址" required />
</v-card-text> <v-btn type="submit" color="primary" @click="saveServerUrl"> 保存 </v-btn>
</v-card> </v-card-text>
</v-card>
<v-card>
<v-card-title>设置学生列表</v-card-title>
<v-card-subtitle>没事别乱动</v-card-subtitle>
<v-card-text>
<v-textarea v-model="students" label="学生列表" required />
<v-btn type="submit" color="primary" @click="saveStudents" border>
保存
</v-btn>
</v-card-text>
</v-card></v-card
>
<v-snackbar v-model="snackbar"> <v-snackbar v-model="snackbar">
{{ snackbarText }} {{ snackbarText }}
</v-snackbar> </v-snackbar>
</template> </template>
<script> <script>
import axios from "axios";
export default { export default {
data() { data() {
return { return {
serverUrl: "", serverUrl: "",
snackbar: false, snackbar: false,
snackbarText: "", snackbarText: "",
students: "",
studentsList: [],
}; };
}, },
mounted() { mounted() {
this.loadServerUrl(); this.loadServerUrl();
this.loadStudents();
}, },
methods: { methods: {
saveServerUrl() { saveServerUrl() {
try { try {
// URL/http://使new URL()
if (this.serverUrl == "") {
localStorage.removeItem("backendServerUrl");
this.snackbarText = "删除成功,请刷新页面。";
this.snackbar = true;
// URL/http://使new URL() return;
if (this.serverUrl == "") { }
localStorage.removeItem("backendServerUrl"); this.serverUrl =
this.snackbarText = "删除成功,请刷新页面。"; new URL(this.serverUrl).protocol +
"//" +
new URL(this.serverUrl).host;
localStorage.setItem("backendServerUrl", this.serverUrl);
this.snackbarText = "保存成功,请刷新页面。";
this.snackbar = true; this.snackbar = true;
} catch (error) {
return;
}
this.serverUrl =
new URL(this.serverUrl).protocol + "//" + new URL(this.serverUrl).host;
localStorage.setItem("backendServerUrl", this.serverUrl);
this.snackbarText = "保存成功,请刷新页面。";
this.snackbar = true;
}catch (error) {
console.log(error); console.log(error);
this.snackbarText = "保存失败,请检查后端地址。"; this.snackbarText = "保存失败,请检查后端地址。";
this.snackbar = true; this.snackbar = true;
} }
}, },
saveStudents() {
try {
this.studentsList = this.students.split("\n");
axios
.post(this.serverUrl + "/setstudentlist", {
studentList: this.studentsList,
id: 1,
})
.then((response) => {
console.log(response);
});
localStorage.setItem("studentList", this.students);
this.snackbarText = "保存成功,请刷新页面。";
this.snackbar = true;
} catch (error) {
console.log(error);
this.snackbarText = "保存失败,请检查学生列表。";
this.snackbar = true;
}
},
loadServerUrl() { loadServerUrl() {
const savedUrl = localStorage.getItem("backendServerUrl"); const savedUrl = localStorage.getItem("backendServerUrl");
if (savedUrl) { if (savedUrl) {
this.serverUrl = savedUrl; this.serverUrl = savedUrl;
} }
}, },
loadStudents() {
if (localStorage.getItem("studentList")) {
this.students = localStorage.getItem("studentList").replace(/,/g, "\n");
}
},
}, },
}; };
</script> </script>

View File

@ -1,7 +1,7 @@
<template> <template>
<v-app-bar> <v-app-bar>
<template #prepend> <template #prepend>
<v-app-bar-nav-icon icon="mdi-home"/> <v-app-bar-nav-icon icon="mdi-home" />
</template> </template>
<v-app-bar-title> <v-app-bar-title>
@ -28,7 +28,7 @@
style="padding: 2px !important" style="padding: 2px !important"
@click="openDialog(subject)" @click="openDialog(subject)"
> >
<v-card> <v-card border>
<v-card-title>{{ homeworkData[subject].name }}</v-card-title> <v-card-title>{{ homeworkData[subject].name }}</v-card-title>
<v-card-text :style="contentStyle"> <v-card-text :style="contentStyle">
<v-list> <v-list>
@ -47,6 +47,7 @@
<div /> <div />
</v-col> </v-col>
<v-col <v-col
v-if="studentList.length" v-if="studentList.length"
class="attendance-area" class="attendance-area"
@ -55,15 +56,21 @@
> >
<h1>出勤</h1> <h1>出勤</h1>
<h2>应到:{{ studentList.length }}</h2> <h2>应到:{{ studentList.length }}</h2>
<h2>实到:{{ studentList.length - selectedSet.size }}</h2> <h2>
<h2 style="margin-bottom: 5px">请假:{{ selectedSet.size }} </h2> 实到:{{ studentList.length - selectedSet.size - lateSet.size }}
<h3 v-for="(i, index) in selectedSet" :key="index"> </h2>
<h2>请假:{{ selectedSet.size }} </h2>
<h3 v-for="(i, index) in selectedSet" :key="'absent-' + index">
{{ `${index + 1}. ${studentList[i]}` }}
</h3>
<h2>迟到:{{ lateSet.size }} </h2>
<h3 v-for="(i, index) in lateSet" :key="'late-' + index">
{{ `${index + 1}. ${studentList[i]}` }} {{ `${index + 1}. ${studentList[i]}` }}
</h3> </h3>
</v-col> </v-col>
</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-plus" variant="text" @click="zoom('up')" />
<v-btn icon="mdi-minus" variant="text" @click="zoom('out')" /> <v-btn icon="mdi-minus" variant="text" @click="zoom('out')" />
@ -91,8 +98,9 @@
</v-btn> </v-btn>
</v-container> </v-container>
<v-dialog v-model="dialogVisible" width="500" @click:outside="handleClose"> <v-dialog v-model="dialogVisible" width="500" @click:outside="handleClose">
<v-card> <v-card border>
<v-card-title>{{ dialogTitle }}</v-card-title> <v-card-title>{{ dialogTitle }}</v-card-title>
<v-card-subtitle>写完后点击上传谢谢喵</v-card-subtitle>
<v-card-text> <v-card-text>
<v-textarea <v-textarea
ref="inputRef" ref="inputRef"
@ -107,8 +115,8 @@
<v-dialog v-model="attendDialogVisible" width="800"> <v-dialog v-model="attendDialogVisible" width="800">
<v-card> <v-card>
<v-card-title>设置未到学生列表</v-card-title> <v-card-title>设置学生出勤状态</v-card-title>
<v-card-text> <v-card-text><v-btn @click="cleanstudentslist">全勤</v-btn>
<v-container fluid> <v-container fluid>
<v-row> <v-row>
<v-col <v-col
@ -119,10 +127,16 @@
md="4" md="4"
> >
<v-card <v-card
:class="{ selected: selectedSet.has(i) }" border
variant="outlined" :class="{ selected: selectedSet.has(i) || lateSet.has(i) }"
:color="selectedSet.has(i) ? 'primary' : ''" :color="
@click="toggleStudent(i)" selectedSet.has(i)
? 'primary'
: lateSet.has(i)
? 'orange'
: ''
"
@click="toggleStudentStatus(i)"
> >
<v-card-text> <v-card-text>
{{ `${i + 1}. ${name}` }} {{ `${i + 1}. ${name}` }}
@ -134,6 +148,7 @@
</v-card-text> </v-card-text>
</v-card> </v-card>
</v-dialog> </v-dialog>
<v-dialog v-model="ServerSelectionDialog" width="500"> <v-dialog v-model="ServerSelectionDialog" width="500">
<ServerSelection /> <ServerSelection />
</v-dialog> </v-dialog>
@ -147,6 +162,7 @@
import axios from "axios"; import axios from "axios";
import { useDisplay } from "vuetify"; import { useDisplay } from "vuetify";
import ServerSelection from "../components/ServerSelection.vue"; import ServerSelection from "../components/ServerSelection.vue";
export default { export default {
name: "HomeworkBoard", name: "HomeworkBoard",
components: { ServerSelection }, components: { ServerSelection },
@ -155,7 +171,8 @@ export default {
backurl: localStorage.getItem("backendServerUrl") || "", backurl: localStorage.getItem("backendServerUrl") || "",
currentEditSubject: null, currentEditSubject: null,
studentList: ["加载中"], studentList: ["加载中"],
selectedSet: new Set(), selectedSet: new Set(), // Absent students
lateSet: new Set(), // Late students
dialogVisible: false, dialogVisible: false,
dialogTitle: "", dialogTitle: "",
textarea: "", textarea: "",
@ -194,6 +211,7 @@ export default {
async initializeData() { async initializeData() {
const res = await axios.get(this.backurl + "/config.json"); const res = await axios.get(this.backurl + "/config.json");
this.studentList = res.data.studentList; this.studentList = res.data.studentList;
localStorage.setItem("studentList", res.data.studentList);
this.homeworkArrange = res.data.homeworkArrange; this.homeworkArrange = res.data.homeworkArrange;
this.initializeHomeworkData(); this.initializeHomeworkData();
@ -261,15 +279,24 @@ export default {
this.attendDialogVisible = true; this.attendDialogVisible = true;
}, },
toggleStudent(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
} else if (this.lateSet.has(index)) {
this.lateSet.delete(index);
} else { } else {
this.selectedSet.add(index); this.selectedSet.add(index); // Toggle to late
} }
this.synced = false; this.synced = false;
}, },
cleanstudentslist()
{
this.selectedSet.clear();
this.lateSet.clear();
this.synced = false;
},
zoom(direction) { zoom(direction) {
const step = 2; const step = 2;
if (direction === "up" && this.fontSize < 100) { if (direction === "up" && this.fontSize < 100) {
@ -289,6 +316,7 @@ export default {
date: this.dateString, date: this.dateString,
data: this.homeworkData, data: this.homeworkData,
attendance: Array.from(this.selectedSet), attendance: Array.from(this.selectedSet),
late: Array.from(this.lateSet), // Upload late students as well
}); });
this.synced = true; this.synced = true;
this.showSyncMessage(); this.showSyncMessage();
@ -363,6 +391,7 @@ export default {
return acc; return acc;
}, {}); }, {});
this.selectedSet = new Set(res.data.attendance || []); this.selectedSet = new Set(res.data.attendance || []);
this.lateSet = new Set(res.data.late || []); // Initialize late set
this.synced = true; this.synced = true;
}, },