mirror of
https://github.com/ZeroCatDev/Classworks.git
synced 2025-07-02 09:19:23 +00:00
1
This commit is contained in:
parent
e46f44bee2
commit
e6cbe1faea
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
},
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user