Implement data migration tool and enhance KV storage support. Add automatic redirection for legacy data providers, improve user interface for migration settings, and update data handling for Classworks cloud storage. Refactor components for better integration with new storage options.

This commit is contained in:
SunWuyuan
2025-05-10 20:51:56 +08:00
parent c0e33dcbf9
commit a542e9b91f
11 changed files with 355 additions and 204 deletions
+15 -73
View File
@@ -1,5 +1,3 @@
import { serverProvider } from "./providers/server";
import { indexedDBProvider } from "./providers/indexedDB";
import { kvProvider } from "./providers/kvProvider";
import { getSetting } from "./settings";
@@ -14,84 +12,28 @@ export const formatError = (message, code = "UNKNOWN_ERROR") => ({
error: { code, message },
});
// Legacy providers
const legacyProviders = {
server: serverProvider,
indexedDB: indexedDBProvider,
};
// New KV provider
const newProviders = {
kv: kvProvider,
};
// Main data provider with support for both legacy and new API
// Main data provider with simplified API
export default {
// Provider API methods
loadData: (provider, key, date) => {
if (legacyProviders[provider]) {
return legacyProviders[provider]?.loadData(key, date);
}
loadData: async (key, date) => {
const provider = getSetting("server.provider");
const useServer = provider === "kv-server" || provider === "classworkscloud";
// If using new KV provider
if (provider === "kv-local") {
const classNumber = key.split("/").pop();
return newProviders.kv.local.loadData(classNumber, date);
} else if (provider === "kv-server") {
const classNumber = key.split("/").pop();
const serverUrl = getSetting("server.domain");
return newProviders.kv.server.loadData(serverUrl, classNumber, date);
if (useServer) {
return kvProvider.server.loadData(key, date);
} else {
return kvProvider.local.loadData(date);
}
},
saveData: (provider, key, data, date) => {
if (legacyProviders[provider]) {
return legacyProviders[provider]?.saveData(key, data, date);
}
saveData: async (key, data, date) => {
const provider = getSetting("server.provider");
const useServer = provider === "kv-server" || provider === "classworkscloud";
// If using new KV provider
if (provider === "kv-local") {
const classNumber = key.split("/").pop();
return newProviders.kv.local.saveData(classNumber, data, date);
} else if (provider === "kv-server") {
const classNumber = key.split("/").pop();
const serverUrl = getSetting("server.domain");
return newProviders.kv.server.saveData(
serverUrl,
classNumber,
data,
date
);
}
},
loadConfig: (provider, key) => {
if (legacyProviders[provider]) {
return legacyProviders[provider]?.loadConfig(key);
}
// If using new KV provider
if (provider === "kv-local") {
const classNumber = key.split("/").pop();
return newProviders.kv.local.loadConfig(classNumber);
} else if (provider === "kv-server") {
const serverUrl = getSetting("server.domain");
return newProviders.kv.server.loadConfig(serverUrl);
}
},
saveConfig: (provider, key, config) => {
if (legacyProviders[provider]) {
return legacyProviders[provider]?.saveConfig(key, config);
}
// If using new KV provider
if (provider === "kv-local") {
const classNumber = key.split("/").pop();
return newProviders.kv.local.saveConfig(classNumber, config);
} else if (provider === "kv-server") {
const serverUrl = getSetting("server.domain");
return newProviders.kv.server.saveConfig(serverUrl, config);
if (useServer) {
return kvProvider.server.saveData(key, data, date);
} else {
return kvProvider.local.saveData(data, date);
}
},
};
+20 -38
View File
@@ -23,11 +23,6 @@ const getHeaders = () => {
return headers;
};
// Get machine UUID from settings
const getMachineId = () => {
return getSetting("device.uuid");
};
// Removed migrateToKvStorage function - now handled by the dedicated migration tool
const initDB = async () => {
@@ -58,17 +53,13 @@ const formatDateForKey = (date) => {
export const kvProvider = {
// Local storage provider
local: {
async loadData(classNumber, date) {
async loadData(date) {
try {
if (!classNumber) {
return formatError("请先设置班号", "CONFIG_ERROR");
}
const formattedDate = formatDateForKey(date);
const key = `${DATA_KEY_PREFIX}${formattedDate}`;
const db = await initDB();
const data = await db.get("kv", `${classNumber}/${key}`);
const data = await db.get("kv", key);
if (!data) {
const today = new Date().toISOString().split("T")[0];
@@ -91,31 +82,23 @@ export const kvProvider = {
}
},
async saveData(classNumber, data, date) {
async saveData(data, date) {
try {
if (!classNumber) {
return formatError("请先设置班号", "CONFIG_ERROR");
}
const formattedDate = formatDateForKey(date);
const key = `${DATA_KEY_PREFIX}${formattedDate}`;
const db = await initDB();
await db.put("kv", JSON.stringify(data), `${classNumber}/${key}`);
await db.put("kv", JSON.stringify(data), key);
return formatResponse(null, "保存成功");
} catch (error) {
return formatError("保存本地数据失败:" + error);
}
},
async loadConfig(classNumber) {
async loadConfig() {
try {
if (!classNumber) {
return formatError("请先设置班号", "CONFIG_ERROR");
}
const db = await initDB();
const config = await db.get("kv", `${classNumber}/${CONFIG_KEY}`);
const config = await db.get("kv", CONFIG_KEY);
if (!config) {
return formatResponse({
@@ -134,14 +117,10 @@ export const kvProvider = {
}
},
async saveConfig(classNumber, config) {
async saveConfig(config) {
try {
if (!classNumber) {
return formatError("请先设置班号", "CONFIG_ERROR");
}
const db = await initDB();
await db.put("kv", JSON.stringify(config), `${classNumber}/${CONFIG_KEY}`);
await db.put("kv", JSON.stringify(config), CONFIG_KEY);
return formatResponse(null, "保存成功");
} catch (error) {
return formatError("保存本地配置失败:" + error);
@@ -151,9 +130,10 @@ export const kvProvider = {
// Server storage provider
server: {
async loadData(serverUrl, classNumber, date) {
async loadData(classNumber, date) {
try {
const machineId = getMachineId();
const serverUrl = getSetting("server.domain");
const machineId = getSetting("device.uuid");
const formattedDate = formatDateForKey(date);
const key = `${DATA_KEY_PREFIX}${formattedDate}`;
@@ -185,9 +165,10 @@ export const kvProvider = {
}
},
async saveData(serverUrl, classNumber, data, date) {
async saveData(classNumber, data, date) {
try {
const machineId = getMachineId();
const serverUrl = getSetting("server.domain");
const machineId = getSetting("device.uuid");
const formattedDate = formatDateForKey(date);
const key = `${DATA_KEY_PREFIX}${formattedDate}`;
@@ -203,9 +184,10 @@ export const kvProvider = {
}
},
async loadConfig(serverUrl) {
async loadConfig() {
try {
const machineId = getMachineId();
const serverUrl = getSetting("server.domain");
const machineId = getSetting("device.uuid");
const res = await axios.get(`${serverUrl}/${machineId}/${CONFIG_KEY}`, {
headers: getHeaders()
});
@@ -230,9 +212,10 @@ export const kvProvider = {
}
},
async saveConfig(serverUrl, config) {
async saveConfig(config) {
try {
const machineId = getMachineId();
const serverUrl = getSetting("server.domain");
const machineId = getSetting("device.uuid");
await axios.post(`${serverUrl}/${machineId}/${CONFIG_KEY}`, config, {
headers: getHeaders()
});
@@ -247,4 +230,3 @@ export const kvProvider = {
}
};
export { getMachineId };
+16 -3
View File
@@ -74,6 +74,12 @@ function generateUUID() {
});
}
// 新增: Classworks云端存储的默认设置
const classworksCloudDefaults = {
"server.domain": "http://localhost:3030",
"server.siteKey": "123456",
};
/**
* 所有配置项的定义
* @type {Object.<string, SettingDefinition>}
@@ -182,11 +188,11 @@ const settingsDefinitions = {
},
"server.provider": {
type: "string",
default: "indexedDB",
validate: (value) => ["server", "indexedDB", "kv-local", "kv-server"].includes(value),
default: "kv-local",
validate: (value) => ["kv-local", "kv-server", "classworkscloud"].includes(value),
description: "数据提供者",
icon: "mdi-database",
// 选择数据存储方式:使用本地IndexedDB或远程服务器
// 选择数据存储方式:使用本地存储或远程服务器
},
// 刷新设置
@@ -480,6 +486,13 @@ class SettingsManagerClass {
}
}
// 检查是否使用Classworks云端存储,并覆盖特定设置
if (this.settingsCache["server.provider"] === "classworkscloud") {
if (classworksCloudDefaults[key] !== undefined) {
return classworksCloudDefaults[key];
}
}
const value = this.settingsCache[key];
return value !== undefined ? value : definition.default;
}