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-15 21:09:08 +08:00
parent 6ab280e484
commit efd622f819
No known key found for this signature in database
GPG Key ID: A6A54CF66F56BB64
5 changed files with 244 additions and 16 deletions

View File

@ -2,9 +2,7 @@
<v-navigation-drawer v-model="drawer" location="right" temporary width="400"> <v-navigation-drawer v-model="drawer" location="right" temporary width="400">
<v-toolbar color="primary"> <v-toolbar color="primary">
<v-toolbar-title>消息记录</v-toolbar-title> <v-toolbar-title>消息记录</v-toolbar-title>
<template #append>
<v-btn icon="mdi-delete" variant="text" @click="clearMessages" />
</template>
</v-toolbar> </v-toolbar>
<v-list> <v-list>
@ -21,14 +19,7 @@
{{ new Date(msg.timestamp).toLocaleTimeString() }} {{ new Date(msg.timestamp).toLocaleTimeString() }}
</span> </span>
<template #append>
<v-btn
icon="mdi-delete"
variant="text"
size="small"
@click="deleteMessage(msg.id)"
/>
</template>
</v-list-item> </v-list-item>
<v-list-item v-if="!messages.length"> <v-list-item v-if="!messages.length">

View File

@ -0,0 +1,215 @@
<template>
<settings-card
title="数据源设置"
icon="mdi-database-cog"
>
<v-list>
<!-- 服务器模式设置 -->
<template v-if="currentProvider === 'server'">
<v-list-item>
<template #prepend>
<v-icon icon="mdi-lan-connect" class="mr-3" />
</template>
<v-list-item-title>检查服务器连接</v-list-item-title>
<template #append>
<v-btn
:loading="loading"
variant="tonal"
size="small"
@click="checkServerConnection"
>
测试连接
</v-btn>
</template>
</v-list-item>
</template>
<!-- IndexedDB设置 -->
<template v-if="currentProvider === 'indexedDB'">
<v-list-item>
<template #prepend>
<v-icon icon="mdi-database" class="mr-3" />
</template>
<v-list-item-title>清除数据库缓存</v-list-item-title>
<v-list-item-subtitle>这将清除所有IndexedDB中的数据</v-list-item-subtitle>
<template #append>
<v-btn
color="error"
variant="tonal"
size="small"
@click="confirmClearIndexedDB"
>
清除
</v-btn>
</template>
</v-list-item>
<v-list-item>
<template #prepend>
<v-icon icon="mdi-database-export" class="mr-3" />
</template>
<v-list-item-title>导出数据库</v-list-item-title>
<template #append>
<v-btn
variant="tonal"
size="small"
@click="exportData"
>
导出
</v-btn>
</template>
</v-list-item>
</template>
</v-list>
<!-- 确认对话框 -->
<v-dialog v-model="confirmDialog" max-width="400">
<v-card>
<v-card-title>{{ confirmTitle }}</v-card-title>
<v-card-text>{{ confirmMessage }}</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="grey" variant="text" @click="confirmDialog = false">取消</v-btn>
<v-btn color="error" variant="tonal" @click="handleConfirm">确认</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</settings-card>
</template>
<script>
import SettingsCard from '@/components/SettingsCard.vue';
import { getSetting } from '@/utils/settings';
export default {
name: 'DataProviderSettingsCard',
components: { SettingsCard },
data() {
return {
loading: false,
confirmDialog: false,
confirmTitle: '',
confirmMessage: '',
confirmAction: null
};
},
computed: {
currentProvider() {
return getSetting('server.provider');
}
},
methods: {
async checkServerConnection() {
this.loading = true;
try {
const domain = getSetting('server.domain');
const response = await fetch(`${domain}`, {
method: 'GET',
headers: { 'Accept': 'application/json' }
});
if (response.ok) {
this.$message.success('连接成功', '服务器连接正常');
} else {
throw new Error('服务器响应异常');
}
} catch (error) {
this.$message.error('连接失败', error.message || '无法连接到服务器');
} finally {
this.loading = false;
}
},
confirmClearLocalStorage() {
this.confirmTitle = '确认清除';
this.confirmMessage = '此操作将清除所有本地存储的数据,确定要继续吗?';
this.confirmAction = this.clearLocalStorage;
this.confirmDialog = true;
},
clearLocalStorage() {
try {
localStorage.clear();
this.$message.success('清除成功', '本地存储数据已清除');
this.confirmDialog = false;
} catch (error) {
this.$message.error('清除失败', error.message);
}
},
confirmClearIndexedDB() {
this.confirmTitle = '确认清除';
this.confirmMessage = '此操作将清除所有IndexedDB中的数据确定要继续吗';
this.confirmAction = this.clearIndexedDB;
this.confirmDialog = true;
},
async clearIndexedDB() {
try {
const DBName = 'HomeworkDB';
//
await window.indexedDB.deleteDatabase(DBName);
this.$message.success('清除成功', '数据库缓存已清除');
this.confirmDialog = false;
} catch (error) {
this.$message.error('清除失败', error.message);
}
},
async exportData() {
try {
const DBName = 'HomeworkDB';
const data = { indexedDB: {} };
//
const db = await new Promise((resolve, reject) => {
const request = window.indexedDB.open(DBName);
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
//
const stores = Array.from(db.objectStoreNames);
//
for (const storeName of stores) {
const transaction = db.transaction(storeName, 'readonly');
const store = transaction.objectStore(storeName);
//
const storeData = await new Promise((resolve, reject) => {
const request = store.getAll();
request.onerror = () => reject(request.error);
request.onsuccess = () => resolve(request.result);
});
data.indexedDB[storeName] = storeData;
}
//
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
const timestamp = new Date().toISOString().split('T')[0];
a.href = url;
a.download = `homework-indexeddb-${timestamp}.json`;
a.click();
URL.revokeObjectURL(url);
this.$message.success('导出成功', 'IndexedDB数据已导出');
} catch (error) {
console.error('导出失败:', error);
this.$message.error('导出失败', error.message || '无法导出数据库数据');
}
},
handleConfirm() {
if (this.confirmAction) {
this.confirmAction();
}
}
}
};
</script>

0
src/pages/guide.vue Normal file
View File

View File

@ -627,6 +627,7 @@ export default {
if (response.error.code === "NOT_FOUND") { if (response.error.code === "NOT_FOUND") {
this.state.showNoDataMessage = true; this.state.showNoDataMessage = true;
this.state.noDataMessage = response.error.message; this.state.noDataMessage = response.error.message;
//
this.state.boardData = { this.state.boardData = {
homework: {}, homework: {},
attendance: { absent: [], late: [], exclude: [] }, attendance: { absent: [], late: [], exclude: [] },
@ -635,12 +636,25 @@ export default {
throw new Error(response.error.message); throw new Error(response.error.message);
} }
} else { } else {
this.state.boardData = response.data; //
this.state.boardData = {
homework: response.data.homework || {},
attendance: {
absent: response.data.attendance?.absent || [],
late: response.data.attendance?.late || [],
exclude: response.data.attendance?.exclude || [],
},
};
this.state.synced = true; this.state.synced = true;
this.state.showNoDataMessage = false; this.state.showNoDataMessage = false;
this.$message.success("下载成功", "数据已更新"); this.$message.success("下载成功", "数据已更新");
} }
} catch (error) { } catch (error) {
//
this.state.boardData = {
homework: {},
attendance: { absent: [], late: [], exclude: [] },
};
this.$message.error("下载失败", error.message); this.$message.error("下载失败", error.message);
} finally { } finally {
this.loading.download = false; this.loading.download = false;

View File

@ -15,26 +15,32 @@
<v-row> <v-row>
<v-col cols="12" md="6"> <v-col cols="12" md="6">
<server-settings-card <server-settings-card
border
:loading="loading.server" :loading="loading.server"
@saved="onSettingsSaved" @saved="onSettingsSaved"
/> />
</v-col> </v-col>
<v-col cols="12" md="6"> <v-col cols="12" md="6">
<edit-settings-card @saved="onSettingsSaved" /> <data-provider-settings-card border />
</v-col> </v-col>
<v-col cols="12" md="6"> <v-col cols="12" md="6">
<refresh-settings-card @saved="onSettingsSaved" /> <edit-settings-card @saved="onSettingsSaved" border/>
</v-col> </v-col>
<v-col cols="12" md="6"> <v-col cols="12" md="6">
<display-settings-card @saved="onSettingsSaved" /> <refresh-settings-card @saved="onSettingsSaved" border/>
</v-col>
<v-col cols="12" md="6">
<display-settings-card @saved="onSettingsSaved" border/>
</v-col> </v-col>
<!-- 开发者选项卡片 --> <!-- 开发者选项卡片 -->
<v-col :cols="12" :md="settings.developer.enabled ? 12 : 6"> <v-col :cols="12" :md="settings.developer.enabled ? 12 : 6">
<settings-card <settings-card
border
title="开发者选项" title="开发者选项"
icon="mdi-developer-board" icon="mdi-developer-board"
> >
@ -139,6 +145,7 @@ import ServerSettingsCard from '@/components/settings/cards/ServerSettingsCard.v
import EditSettingsCard from '@/components/settings/cards/EditSettingsCard.vue'; import EditSettingsCard from '@/components/settings/cards/EditSettingsCard.vue';
import RefreshSettingsCard from '@/components/settings/cards/RefreshSettingsCard.vue'; import RefreshSettingsCard from '@/components/settings/cards/RefreshSettingsCard.vue';
import DisplaySettingsCard from '@/components/settings/cards/DisplaySettingsCard.vue'; import DisplaySettingsCard from '@/components/settings/cards/DisplaySettingsCard.vue';
import DataProviderSettingsCard from '@/components/settings/cards/DataProviderSettingsCard.vue';
import { import {
getSetting, getSetting,
setSetting, setSetting,
@ -162,7 +169,8 @@ export default {
MessageLog, MessageLog,
SettingsCard, SettingsCard,
StudentListCard, StudentListCard,
AboutCard AboutCard,
DataProviderSettingsCard
}, },
setup() { setup() {
const { mobile } = useDisplay(); const { mobile } = useDisplay();