1
0
mirror of https://github.com/ZeroCatDev/Classworks.git synced 2025-07-02 17:29:23 +00:00
This commit is contained in:
SunWuyuan 2025-03-15 13:42:13 +08:00
parent e46f44bee2
commit e6cbe1faea
No known key found for this signature in database
GPG Key ID: A6A54CF66F56BB64
2 changed files with 35 additions and 132 deletions

View File

@ -1,8 +1,8 @@
<template>
<v-card
border
:color="hasChanges ? 'warning-subtle' : undefined"
:class="{ 'unsaved-changes': hasChanges }"
:color="unsavedChanges ? 'warning-subtle' : undefined"
:class="{ 'unsaved-changes': unsavedChanges }"
>
<v-card-item>
<template #prepend>
@ -11,7 +11,7 @@
<v-card-title class="text-h6">学生列表</v-card-title>
<template #append>
<unsaved-warning
:show="hasChanges"
:show="unsavedChanges"
message="有未保存的更改"
/>
<v-btn
@ -190,8 +190,8 @@
prepend-icon="mdi-content-save"
size="large"
:loading="loading"
:disabled="loading || !hasChanges"
@click="handleSave"
:disabled="loading || !unsavedChanges"
@click="$emit('save')"
>
保存名单
</v-btn>
@ -201,7 +201,7 @@
prepend-icon="mdi-refresh"
size="large"
:loading="loading"
:disabled="loading || !hasChanges"
:disabled="loading || !unsavedChanges"
@click="$emit('reload')"
>
重载名单
@ -234,51 +234,16 @@ export default {
loading: Boolean,
error: String,
isMobile: Boolean,
originalList: {
type: Array,
default: () => []
}
unsavedChanges: Boolean
},
data() {
return {
newStudentName: '', //
newStudentName: '',
editState: {
index: -1,
name: ''
},
savedState: null // null
}
},
created() {
this.initializeSavedState()
},
mounted() {
this.$nextTick(() => {
this.initializeSavedState()
})
},
watch: {
originalList: {
handler(newList) {
//
if (this.modelValue.list.length === 0) {
const newState = {
list: [...newList],
text: newList.join('\n')
};
//
this.savedState = { ...newState };
this.updateModelValue({
...this.modelValue,
...newState
});
}
},
immediate: true
}
},
@ -292,29 +257,11 @@ export default {
set(value) {
this.handleTextInput(value);
}
},
hasChanges() {
return this.savedState && this.isStateChanged();
}
},
methods: {
//
initializeSavedState() {
const currentList = this.modelValue.list || []
this.savedState = {
list: [...currentList],
text: currentList.join('\n')
}
},
//
isListChanged(current, original) {
if (current.length !== original.length) return true;
return JSON.stringify(current) !== JSON.stringify(original);
},
//
// UI
toggleAdvanced() {
const advanced = !this.modelValue.advanced;
this.updateModelValue({
@ -324,7 +271,6 @@ export default {
});
},
//
updateModelValue(newData) {
this.$emit('update:modelValue', {
...this.modelValue,
@ -332,16 +278,7 @@ export default {
});
},
//
updateSavedState() {
const currentList = this.modelValue.list || []
this.savedState = {
list: [...currentList],
text: currentList.join('\n')
}
},
//
//
addStudent() {
const name = this.newStudentName.trim();
if (!name || this.modelValue.list.includes(name)) return;
@ -385,7 +322,7 @@ export default {
}
},
//
//
startEdit(index, name) {
this.editState = { index, name };
},
@ -405,23 +342,11 @@ export default {
},
handleClick(index, student) {
//
if (this.isMobile) {
this.startEdit(index, student);
}
},
//
async handleSave() {
try {
await this.$emit('save')
this.updateSavedState()
} catch (error) {
console.error('保存失败:', error);
throw error;
}
},
handleTextInput(value) {
const list = value
.split('\n')
@ -432,31 +357,6 @@ export default {
text: value,
list
});
},
//
isStateChanged() {
if (!this.savedState) return false
const currentList = this.modelValue.list || []
const savedList = this.savedState.list || []
//
if (currentList.length !== savedList.length) return true
//
for (let i = 0; i < currentList.length; i++) {
if (currentList[i] !== savedList[i]) return true
}
//
if (this.modelValue.advanced) {
const currentText = this.modelValue.text || ''
const savedText = this.savedState.text || ''
if (currentText !== savedText) return true
}
return false
}
}
}

View File

@ -313,8 +313,10 @@
:loading="loading.students"
:error="studentsError"
:is-mobile="isMobile"
:unsaved-changes="hasUnsavedChanges"
@save="saveStudents"
@reload="loadStudentList"
@update:modelValue="handleStudentDataChange"
/>
</v-col>
@ -420,12 +422,13 @@ export default {
loading: {
server: false,
students: false
}
},
hasUnsavedChanges: false,
lastSavedData: null
}
},
watch: {
//
'settings': {
handler(newSettings) {
this.handleSettingsChange(newSettings);
@ -434,10 +437,12 @@ export default {
},
'studentData': {
handler(newData) {
//
if (JSON.stringify(newData.list) !== JSON.stringify(this.studentData.list)) {
this.studentData.text = newData.list.join('\n');
//
if (this.lastSavedData) {
this.hasUnsavedChanges = JSON.stringify(newData.list) !== JSON.stringify(this.lastSavedData);
}
//
this.studentData.text = newData.list.join('\n');
},
deep: true
}
@ -531,6 +536,8 @@ export default {
if (res.data && Array.isArray(res.data.studentList)) {
this.studentData.list = res.data.studentList;
this.studentData.text = res.data.studentList.join('\n');
this.lastSavedData = [...res.data.studentList];
this.hasUnsavedChanges = false;
}
} catch (error) {
console.error('加载学生列表失败:', error);
@ -554,13 +561,15 @@ export default {
const key = provider === 'server' ? `${domain}/${classNum}` : classNum;
const res = await dataProvider.saveConfig(provider, key, {
studentList: this.studentData.list,
//
});
if (!res.success) {
throw new Error(res.error.message);
}
//
this.lastSavedData = [...this.studentData.list];
this.hasUnsavedChanges = false;
this.showMessage('保存成功', '学生列表已更新');
} catch (error) {
console.error('保存学生列表失败:', error);
@ -568,14 +577,19 @@ export default {
}
},
handleStudentDataChange(newData) {
//
if (JSON.stringify(newData.list) !== JSON.stringify(this.studentData.list)) {
this.studentData = { ...newData };
this.hasUnsavedChanges = true;
}
},
saveEdit() {
if (this.editingIndex !== -1) {
const newName = this.editingName.trim();
if (newName && newName !== this.studentData.list[this.editingIndex]) {
this.studentData.list[this.editingIndex] = newName;
if (this.settings.edit.autoSave) {
this.saveStudents();
}
}
this.editingIndex = -1;
this.editingName = '';
@ -599,9 +613,6 @@ export default {
const newIndex = direction === 'up' ? index - 1 : index + 1;
if (newIndex >= 0 && newIndex < this.studentData.list.length) {
[this.studentData.list[index], this.studentData.list[newIndex]] = [this.studentData.list[newIndex], this.studentData.list[index]];
if (this.settings.edit.autoSave) {
this.saveStudents();
}
}
},
@ -622,7 +633,6 @@ export default {
const student = this.studentData.list[this.studentToMove];
this.studentData.list.splice(this.studentToMove, 1);
this.studentData.list.splice(newPos, 0, student);
if (this.settings.edit.autoSave) this.saveStudents();
}
this.numberDialog = false;
this.studentToMove = null;
@ -634,9 +644,6 @@ export default {
const student = this.studentData.list[index];
this.studentData.list.splice(index, 1);
this.studentData.list.unshift(student);
if (this.settings.edit.autoSave) {
this.saveStudents();
}
}
},
@ -645,9 +652,6 @@ export default {
if (student && !this.studentData.list.includes(student)) {
this.studentData.list.push(student);
this.newStudent = '';
if (this.settings.edit.autoSave) {
this.saveStudents();
}
}
},
@ -656,7 +660,6 @@ export default {
this.studentData.list.splice(index, 1);
this.deleteDialog = false;
this.studentToDelete = null;
if (this.settings.edit.autoSave) this.saveStudents();
}
},