feat: 开发采集、采集箱和商品编辑功能

This commit is contained in:
Joey
2026-08-15 22:17:26 +08:00
parent c61d1a3154
commit 36357843d0
130 changed files with 18005 additions and 12 deletions
+63
View File
@@ -0,0 +1,63 @@
/**
* IndexedDB 封装 —— 持久化 FileSystemDirectoryHandle
*
* chrome.storage 存不了 FileSystemDirectoryHandle(它不是 JSON 可序列化类型),
* 必须用 IndexedDB(structured clone 支持)。存一次后跨会话免重复授权。
*/
const DB_NAME = 'ozon-seller-kit';
const STORE = 'handles';
const ROOT_KEY = 'SH_ROOT_DIR';
function openDb(): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const req = indexedDB.open(DB_NAME, 1);
req.onupgradeneeded = () => {
if (!req.result.objectStoreNames.contains(STORE)) {
req.result.createObjectStore(STORE);
}
};
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
export async function idbSet(key: string, value: unknown): Promise<void> {
const db = await openDb();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE, 'readwrite');
tx.objectStore(STORE).put(value, key);
tx.oncomplete = () => {
db.close();
resolve();
};
tx.onerror = () => {
db.close();
reject(tx.error);
};
});
}
export async function idbGet<T>(key: string): Promise<T | null> {
const db = await openDb();
return new Promise((resolve, reject) => {
const tx = db.transaction(STORE, 'readonly');
const req = tx.objectStore(STORE).get(key);
req.onsuccess = () => {
db.close();
resolve((req.result as T) ?? null);
};
req.onerror = () => {
db.close();
reject(req.error);
};
});
}
export async function saveRootDir(handle: FileSystemDirectoryHandle): Promise<void> {
await idbSet(ROOT_KEY, handle);
}
export async function loadRootDir(): Promise<FileSystemDirectoryHandle | null> {
return idbGet<FileSystemDirectoryHandle>(ROOT_KEY);
}