chore: 初始提交 - 移除所有硬编码凭据,统一从环境变量读取

This commit is contained in:
yangxiangyuan
2026-06-11 17:10:58 +08:00
commit c223c79b36
1699 changed files with 313940 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
// IndexedDB 存储封装
const DB = (function () {
const DB_NAME = 'calendar_reminder';
const DB_VERSION = 2; // 升级版本以创建 outbox 队列
const STORE_EVENTS = 'events';
const STORE_OUTBOX = 'outbox';
let _db;
function openDB() {
return new Promise((resolve, reject) => {
const req = indexedDB.open(DB_NAME, DB_VERSION);
req.onupgradeneeded = (ev) => {
const db = ev.target.result;
// 事件存储
if (!db.objectStoreNames.contains(STORE_EVENTS)) {
const store = db.createObjectStore(STORE_EVENTS, { keyPath: 'id' });
store.createIndex('by_start', 'start');
store.createIndex('by_updated', 'updatedAt');
}
// 离线 outbox 队列
if (!db.objectStoreNames.contains(STORE_OUTBOX)) {
db.createObjectStore(STORE_OUTBOX, { keyPath: 'id' });
}
};
req.onsuccess = () => {
_db = req.result;
resolve(_db);
};
req.onerror = () => reject(req.error);
});
}
function tx(storeName, mode = 'readonly') {
const t = _db.transaction(storeName, mode);
return t.objectStore(storeName);
}
async function initDB() {
if (_db) return _db;
return await openDB();
}
function addEvent(ev) {
return new Promise((resolve, reject) => {
const store = tx(STORE_EVENTS, 'readwrite');
const req = store.add(ev);
req.onsuccess = () => resolve(ev);
req.onerror = () => reject(req.error);
});
}
function updateEvent(ev) {
return new Promise((resolve, reject) => {
const store = tx(STORE_EVENTS, 'readwrite');
const req = store.put(ev);
req.onsuccess = () => resolve(ev);
req.onerror = () => reject(req.error);
});
}
function deleteEvent(id) {
return new Promise((resolve, reject) => {
const store = tx(STORE_EVENTS, 'readwrite');
const req = store.delete(id);
req.onsuccess = () => resolve();
req.onerror = () => reject(req.error);
});
}
function getEvent(id) {
return new Promise((resolve, reject) => {
const store = tx(STORE_EVENTS, 'readonly');
const req = store.get(id);
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
function listEventsByMonth(year, month) {
// month: 1..12
const start = new Date(Date.UTC(year, month - 1, 1, 0, 0, 0));
const end = new Date(Date.UTC(year, month, 0, 23, 59, 59));
return new Promise((resolve, reject) => {
const store = tx(STORE_EVENTS, 'readonly');
const idx = store.index('by_start');
const range = IDBKeyRange.bound(start.toISOString(), end.toISOString());
const result = [];
const req = idx.openCursor(range);
req.onsuccess = (e) => {
const cursor = e.target.result;
if (cursor) {
result.push(cursor.value);
cursor.continue();
} else {
resolve(result);
}
};
req.onerror = () => reject(req.error);
});
}
// --- Outbox 队列 ---
function genId() { return Date.now() + '-' + Math.random().toString(36).slice(2); }
function addOutbox(entry) {
return new Promise((resolve, reject) => {
const store = tx(STORE_OUTBOX, 'readwrite');
const req = store.add(entry);
req.onsuccess = () => resolve(entry);
req.onerror = () => reject(req.error);
});
}
function addOutboxUpsert(ev) {
const entry = { id: genId(), type: 'upsert', payload: ev, timestamp: new Date().toISOString() };
return addOutbox(entry);
}
function addOutboxDelete(id) {
const entry = { id: genId(), type: 'delete', payload: { id }, timestamp: new Date().toISOString() };
return addOutbox(entry);
}
function listOutbox() {
return new Promise((resolve, reject) => {
const store = tx(STORE_OUTBOX, 'readonly');
const result = [];
const req = store.openCursor();
req.onsuccess = (e) => {
const cursor = e.target.result;
if (cursor) { result.push(cursor.value); cursor.continue(); }
else { resolve(result); }
};
req.onerror = () => reject(req.error);
});
}
function removeOutbox(id) {
return new Promise((resolve, reject) => {
const store = tx(STORE_OUTBOX, 'readwrite');
const req = store.delete(id);
req.onsuccess = () => resolve();
req.onerror = () => reject(req.error);
});
}
return {
initDB,
addEvent,
updateEvent,
deleteEvent,
getEvent,
listEventsByMonth,
// outbox
addOutboxUpsert,
addOutboxDelete,
listOutbox,
removeOutbox,
};
})();
window.DB = DB;