Refactor MigrationTool and data handling to support student list migration. Update index.vue and settings.vue to streamline configuration loading and improve data provider integration. Remove deprecated local and server storage providers for cleaner architecture.
This commit is contained in:
@@ -15,25 +15,27 @@ export const formatError = (message, code = "UNKNOWN_ERROR") => ({
|
||||
// Main data provider with simplified API
|
||||
export default {
|
||||
// Provider API methods
|
||||
loadData: async (key, date) => {
|
||||
loadData: async (key) => {
|
||||
const provider = getSetting("server.provider");
|
||||
const useServer = provider === "kv-server" || provider === "classworkscloud";
|
||||
const useServer =
|
||||
provider === "kv-server" || provider === "classworkscloud";
|
||||
|
||||
if (useServer) {
|
||||
return kvProvider.server.loadData(key, date);
|
||||
return kvProvider.server.loadData(key);
|
||||
} else {
|
||||
return kvProvider.local.loadData(date);
|
||||
return kvProvider.local.loadData(key);
|
||||
}
|
||||
},
|
||||
|
||||
saveData: async (key, data, date) => {
|
||||
saveData: async (key, data) => {
|
||||
const provider = getSetting("server.provider");
|
||||
const useServer = provider === "kv-server" || provider === "classworkscloud";
|
||||
const useServer =
|
||||
provider === "kv-server" || provider === "classworkscloud";
|
||||
|
||||
if (useServer) {
|
||||
return kvProvider.server.saveData(key, data, date);
|
||||
return kvProvider.server.saveData(key, data);
|
||||
} else {
|
||||
return kvProvider.local.saveData(data, date);
|
||||
return kvProvider.local.saveData(key, data);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
import { openDB } from 'idb';
|
||||
import { formatResponse, formatError } from '../dataProvider';
|
||||
import { defaultConfig, defaultHomework } from '../defaults/defaultData';
|
||||
|
||||
const DB_NAME = "ClassworksDB";
|
||||
const DB_VERSION = 1;
|
||||
|
||||
const initDB = async () => {
|
||||
return openDB(DB_NAME, DB_VERSION, {
|
||||
upgrade(db) {
|
||||
if (!db.objectStoreNames.contains("homework")) {
|
||||
db.createObjectStore("homework");
|
||||
}
|
||||
if (!db.objectStoreNames.contains("config")) {
|
||||
db.createObjectStore("config");
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const indexedDBProvider = {
|
||||
async loadData(key, date) {
|
||||
try {
|
||||
const classNumber = key.split("/").pop();
|
||||
if (!classNumber) {
|
||||
return formatError("请先设置班号", "CONFIG_ERROR");
|
||||
}
|
||||
|
||||
const db = await initDB();
|
||||
const storageKey = `homework_${classNumber}_${date}`;
|
||||
const data = await db.get("homework", storageKey);
|
||||
|
||||
if (!data) {
|
||||
const today = new Date().toISOString().split("T")[0];
|
||||
if (date === today) {
|
||||
return formatResponse(defaultHomework);
|
||||
}
|
||||
return formatError("数据不存在", "NOT_FOUND");
|
||||
}
|
||||
|
||||
return formatResponse(JSON.parse(data));
|
||||
} catch (error) {
|
||||
return formatError("读取IndexedDB数据失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async saveData(key, data, date) {
|
||||
try {
|
||||
const classNumber = key.split("/").pop();
|
||||
if (!classNumber) {
|
||||
return formatError("请先设置班号", "CONFIG_ERROR");
|
||||
}
|
||||
|
||||
const db = await initDB();
|
||||
const storageKey = `homework_${classNumber}_${date}`;
|
||||
await db.put("homework", JSON.stringify(data), storageKey);
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError("保存IndexedDB数据失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async loadConfig(key) {
|
||||
try {
|
||||
const classNumber = key.split("/").pop();
|
||||
if (!classNumber) {
|
||||
return formatError("请先设置班号", "CONFIG_ERROR");
|
||||
}
|
||||
|
||||
const db = await initDB();
|
||||
const storageKey = `config_${classNumber}`;
|
||||
const config = await db.get("config", storageKey);
|
||||
|
||||
if (!config) {
|
||||
return formatResponse(defaultConfig);
|
||||
}
|
||||
|
||||
return formatResponse(JSON.parse(config));
|
||||
} catch (error) {
|
||||
return formatError("读取IndexedDB配置失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async saveConfig(key, config) {
|
||||
try {
|
||||
const classNumber = key.split("/").pop();
|
||||
if (!classNumber) {
|
||||
return formatError("请先设置班号", "CONFIG_ERROR");
|
||||
}
|
||||
|
||||
const db = await initDB();
|
||||
const storageKey = `config_${classNumber}`;
|
||||
await db.put("config", JSON.stringify(config), storageKey);
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError("保存IndexedDB配置失败:" + error);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,11 +1,7 @@
|
||||
import axios from '@/axios/axios';
|
||||
import { formatResponse, formatError } from '../dataProvider';
|
||||
import { openDB } from 'idb';
|
||||
import { getSetting } from '../settings';
|
||||
|
||||
// Constants for key names
|
||||
const CONFIG_KEY = 'classworks-config';
|
||||
const DATA_KEY_PREFIX = 'classworks-data-';
|
||||
import axios from "@/axios/axios";
|
||||
import { formatResponse, formatError } from "../dataProvider";
|
||||
import { openDB } from "idb";
|
||||
import { getSetting } from "../settings";
|
||||
|
||||
// Database initialization for local storage
|
||||
const DB_NAME = "ClassworksDB";
|
||||
@@ -13,220 +9,104 @@ const DB_VERSION = 2;
|
||||
|
||||
// Helper function to get request headers with site key if available
|
||||
const getHeaders = () => {
|
||||
const headers = { Accept: "application/json" };
|
||||
const siteKey = getSetting("server.siteKey");
|
||||
const headers = { Accept: "application/json" };
|
||||
const siteKey = getSetting("server.siteKey");
|
||||
|
||||
if (siteKey) {
|
||||
headers['x-site-key'] = siteKey;
|
||||
}
|
||||
if (siteKey) {
|
||||
headers["x-site-key"] = siteKey;
|
||||
}
|
||||
|
||||
return headers;
|
||||
return headers;
|
||||
};
|
||||
|
||||
// Removed migrateToKvStorage function - now handled by the dedicated migration tool
|
||||
|
||||
const initDB = async () => {
|
||||
return openDB(DB_NAME, DB_VERSION, {
|
||||
upgrade(db) {
|
||||
// Create or update stores as needed
|
||||
if (!db.objectStoreNames.contains("kv")) {
|
||||
db.createObjectStore("kv");
|
||||
}
|
||||
return openDB(DB_NAME, DB_VERSION, {
|
||||
upgrade(db) {
|
||||
// Create or update stores as needed
|
||||
if (!db.objectStoreNames.contains("kv")) {
|
||||
db.createObjectStore("kv");
|
||||
}
|
||||
|
||||
// Add a system store for machine ID and other system settings
|
||||
if (!db.objectStoreNames.contains("system")) {
|
||||
db.createObjectStore("system");
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// Format date as YYYYMMDD for keys
|
||||
const formatDateForKey = (date) => {
|
||||
const d = new Date(date);
|
||||
const year = d.getFullYear();
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(d.getDate()).padStart(2, '0');
|
||||
return `${year}${month}${day}`;
|
||||
// Add a system store for machine ID and other system settings
|
||||
if (!db.objectStoreNames.contains("system")) {
|
||||
db.createObjectStore("system");
|
||||
}
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const kvProvider = {
|
||||
// Local storage provider
|
||||
local: {
|
||||
async loadData(date) {
|
||||
try {
|
||||
const formattedDate = formatDateForKey(date);
|
||||
const key = `${DATA_KEY_PREFIX}${formattedDate}`;
|
||||
// Local storage provider
|
||||
local: {
|
||||
async loadData(key) {
|
||||
try {
|
||||
const db = await initDB();
|
||||
const data = await db.get("kv", key);
|
||||
|
||||
const db = await initDB();
|
||||
const data = await db.get("kv", key);
|
||||
|
||||
if (!data) {
|
||||
const today = new Date().toISOString().split("T")[0];
|
||||
if (date === today) {
|
||||
// Return default data for today
|
||||
return formatResponse({
|
||||
homework: {},
|
||||
attendance: {
|
||||
absent: [],
|
||||
late: []
|
||||
}
|
||||
});
|
||||
}
|
||||
return formatError("数据不存在", "NOT_FOUND");
|
||||
}
|
||||
|
||||
return formatResponse(JSON.parse(data));
|
||||
} catch (error) {
|
||||
return formatError("读取本地数据失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async saveData(data, date) {
|
||||
try {
|
||||
const formattedDate = formatDateForKey(date);
|
||||
const key = `${DATA_KEY_PREFIX}${formattedDate}`;
|
||||
|
||||
const db = await initDB();
|
||||
await db.put("kv", JSON.stringify(data), key);
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError("保存本地数据失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async loadConfig() {
|
||||
try {
|
||||
const db = await initDB();
|
||||
const config = await db.get("kv", CONFIG_KEY);
|
||||
|
||||
if (!config) {
|
||||
return formatResponse({
|
||||
studentList: [
|
||||
"Classworks可以管理学生列表",
|
||||
'你可以点击设置,在其中找到"学生列表"',
|
||||
"在添加学生处输入学生姓名,点击添加",
|
||||
"或者点击高级编辑,从Excel表格中复制数据并粘贴进来",
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return formatResponse(JSON.parse(config));
|
||||
} catch (error) {
|
||||
return formatError("读取本地配置失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async saveConfig(config) {
|
||||
try {
|
||||
const db = await initDB();
|
||||
await db.put("kv", JSON.stringify(config), CONFIG_KEY);
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError("保存本地配置失败:" + error);
|
||||
}
|
||||
if (!data) {
|
||||
return formatError("数据不存在", "NOT_FOUND");
|
||||
}
|
||||
|
||||
return formatResponse(JSON.parse(data));
|
||||
} catch (error) {
|
||||
return formatError("读取本地数据失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
// Server storage provider
|
||||
server: {
|
||||
async loadData(classNumber, date) {
|
||||
try {
|
||||
const serverUrl = getSetting("server.domain");
|
||||
const machineId = getSetting("device.uuid");
|
||||
const formattedDate = formatDateForKey(date);
|
||||
const key = `${DATA_KEY_PREFIX}${formattedDate}`;
|
||||
async saveData(data, key) {
|
||||
try {
|
||||
//const formattedDate = formatDateForKey(date);
|
||||
//const key = `${DATA_KEY_PREFIX}${formattedDate}`;
|
||||
|
||||
const res = await axios.get(`${serverUrl}/${machineId}/${key}`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
const db = await initDB();
|
||||
await db.put("kv", JSON.stringify(data), key);
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError("保存本地数据失败:" + error);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
return formatResponse(res.data);
|
||||
} catch (error) {
|
||||
if (error.response?.status === 404) {
|
||||
const today = new Date().toISOString().split("T")[0];
|
||||
if (date === today) {
|
||||
// Return default data for today
|
||||
return formatResponse({
|
||||
homework: {},
|
||||
attendance: {
|
||||
absent: [],
|
||||
late: []
|
||||
}
|
||||
});
|
||||
}
|
||||
return formatError("数据不存在", "NOT_FOUND");
|
||||
}
|
||||
// Server storage provider
|
||||
server: {
|
||||
async loadData(key) {
|
||||
try {
|
||||
const serverUrl = getSetting("server.domain");
|
||||
const machineId = getSetting("device.uuid");
|
||||
|
||||
return formatError(
|
||||
error.response?.data?.message || "服务器连接失败",
|
||||
"NETWORK_ERROR"
|
||||
);
|
||||
}
|
||||
},
|
||||
const res = await axios.get(`${serverUrl}/${machineId}/${key}`, {
|
||||
headers: getHeaders(),
|
||||
});
|
||||
|
||||
async saveData(classNumber, data, date) {
|
||||
try {
|
||||
const serverUrl = getSetting("server.domain");
|
||||
const machineId = getSetting("device.uuid");
|
||||
const formattedDate = formatDateForKey(date);
|
||||
const key = `${DATA_KEY_PREFIX}${formattedDate}`;
|
||||
|
||||
await axios.post(`${serverUrl}/${machineId}/${key}`, data, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError(
|
||||
error.response?.data?.message || "保存失败",
|
||||
"SAVE_ERROR"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async loadConfig() {
|
||||
try {
|
||||
const serverUrl = getSetting("server.domain");
|
||||
const machineId = getSetting("device.uuid");
|
||||
const res = await axios.get(`${serverUrl}/${machineId}/${CONFIG_KEY}`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
|
||||
return formatResponse(res.data);
|
||||
} catch (error) {
|
||||
if (error.response?.status === 404) {
|
||||
return formatResponse({
|
||||
studentList: [
|
||||
"Classworks可以管理学生列表",
|
||||
'你可以点击设置,在其中找到"学生列表"',
|
||||
"在添加学生处输入学生姓名,点击添加",
|
||||
"或者点击高级编辑,从Excel表格中复制数据并粘贴进来",
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return formatError(
|
||||
error.response?.data?.message || "服务器连接失败",
|
||||
"NETWORK_ERROR"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async saveConfig(config) {
|
||||
try {
|
||||
const serverUrl = getSetting("server.domain");
|
||||
const machineId = getSetting("device.uuid");
|
||||
await axios.post(`${serverUrl}/${machineId}/${CONFIG_KEY}`, config, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError(
|
||||
error.response?.data?.message || "保存失败",
|
||||
"SAVE_ERROR"
|
||||
);
|
||||
}
|
||||
return formatResponse(res.data);
|
||||
} catch (error) {
|
||||
if (error.response?.status === 404) {
|
||||
return formatError("数据不存在", "NOT_FOUND");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return formatError(
|
||||
error.response?.data?.message || "服务器连接失败",
|
||||
"NETWORK_ERROR"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async saveData(key, data) {
|
||||
try {
|
||||
const serverUrl = getSetting("server.domain");
|
||||
const machineId = getSetting("device.uuid");
|
||||
await axios.post(`${serverUrl}/${machineId}/${key}`, data, {
|
||||
headers: getHeaders(),
|
||||
});
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError(
|
||||
error.response?.data?.message || "保存失败",
|
||||
"SAVE_ERROR"
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
import { formatResponse, formatError } from '../dataProvider';
|
||||
|
||||
export const localStorageProvider = {
|
||||
async loadData(key, date) {
|
||||
try {
|
||||
const classNumber = key.split("/").pop();
|
||||
if (!classNumber) {
|
||||
return formatError("请先设置班号", "CONFIG_ERROR");
|
||||
}
|
||||
|
||||
const storageKey = `homework_${classNumber}_${date}`;
|
||||
const rawData = localStorage.getItem(storageKey);
|
||||
|
||||
if (!rawData) {
|
||||
const today = new Date().toISOString().split("T")[0];
|
||||
if (date === today) {
|
||||
return formatResponse({
|
||||
homework: {},
|
||||
attendance: { absent: [], late: [] },
|
||||
});
|
||||
}
|
||||
return formatError("数据不存在", "NOT_FOUND");
|
||||
}
|
||||
|
||||
return formatResponse(JSON.parse(rawData));
|
||||
} catch (error) {
|
||||
return formatError("读取本地数据失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async saveData(key, data, date) {
|
||||
try {
|
||||
const classNumber = key.split("/").pop();
|
||||
if (!classNumber) {
|
||||
return formatError("请先设置班号", "CONFIG_ERROR");
|
||||
}
|
||||
|
||||
const storageKey = `homework_${classNumber}_${date}`; // 使用传入的date参数
|
||||
localStorage.setItem(storageKey, JSON.stringify(data));
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError("保存本地数据失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async loadConfig(key) {
|
||||
try {
|
||||
const classNumber = key.split("/").pop();
|
||||
if (!classNumber) {
|
||||
return formatError("请先设置班号", "CONFIG_ERROR");
|
||||
}
|
||||
|
||||
const storageKey = `config_${classNumber}`;
|
||||
const rawData = localStorage.getItem(storageKey);
|
||||
|
||||
if (!rawData) {
|
||||
return formatResponse({
|
||||
studentList: [],
|
||||
displayOptions: {},
|
||||
});
|
||||
}
|
||||
|
||||
return formatResponse(JSON.parse(rawData));
|
||||
} catch (error) {
|
||||
return formatError("读取本地配置失败:" + error);
|
||||
}
|
||||
},
|
||||
|
||||
async saveConfig(key, config) {
|
||||
try {
|
||||
const classNumber = key.split("/").pop();
|
||||
if (!classNumber) {
|
||||
return formatError("请先设置班号", "CONFIG_ERROR");
|
||||
}
|
||||
|
||||
const storageKey = `config_${classNumber}`;
|
||||
localStorage.setItem(storageKey, JSON.stringify(config));
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError("保存本地配置失败:" + error);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,84 +0,0 @@
|
||||
import axios from '@/axios/axios';
|
||||
import { formatResponse, formatError } from '../dataProvider';
|
||||
import { getSetting } from '../settings';
|
||||
|
||||
// Helper function to get request headers with site key if available
|
||||
const getHeaders = () => {
|
||||
const headers = { Accept: "application/json" };
|
||||
const siteKey = getSetting("server.siteKey");
|
||||
|
||||
if (siteKey) {
|
||||
headers['x-site-key'] = siteKey;
|
||||
}
|
||||
|
||||
return headers;
|
||||
};
|
||||
|
||||
export const serverProvider = {
|
||||
async loadData(key, date) {
|
||||
try {
|
||||
const res = await axios.get(`${key}/homework?date=${date}`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
if (res.data?.status === false) {
|
||||
return formatError(res.data.msg || "获取数据失败", "SERVER_ERROR");
|
||||
}
|
||||
return formatResponse(res.data);
|
||||
} catch (error) {
|
||||
return formatError(
|
||||
error.response?.data?.message || "服务器连接失败",
|
||||
"NETWORK_ERROR"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async saveData(key, data, date) {
|
||||
try {
|
||||
// 添加date参数到URL
|
||||
const url = date ? `${key}/homework?date=${date}` : `${key}/homework`;
|
||||
await axios.post(url, data, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError(
|
||||
error.response?.data?.message || "保存失败",
|
||||
"SAVE_ERROR"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async loadConfig(key) {
|
||||
try {
|
||||
const res = await axios.get(`${key}/config`, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
if (res.data?.status === false) {
|
||||
return formatError(res.data.msg || "获取配置失败", "SERVER_ERROR");
|
||||
}
|
||||
return formatResponse(res.data);
|
||||
} catch (error) {
|
||||
return formatError(
|
||||
error.response?.data?.message || "服务器连接失败",
|
||||
"NETWORK_ERROR"
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async saveConfig(key, config) {
|
||||
try {
|
||||
const res = await axios.put(`${key}/config`, config, {
|
||||
headers: getHeaders()
|
||||
});
|
||||
if (res.data?.status === false) {
|
||||
return formatError(res.data.msg || "保存失败", "SAVE_ERROR");
|
||||
}
|
||||
return formatResponse(null, "保存成功");
|
||||
} catch (error) {
|
||||
return formatError(
|
||||
error.response?.data?.message || "保存失败",
|
||||
"SAVE_ERROR"
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user