perf: maillist 缓存

dev/ckeditor
Lei OT 4 months ago
parent 8f3fdef2e6
commit 5ce589654a

@ -312,7 +312,9 @@ export const queryEmailListAction = async ({ opi_sn = '', pagesize = 10, last_id
const { errcode, result } = await fetchJSON(`${API_HOST}/v3/mail_list`, _params)
const ret = errcode === 0 ? result : []
if (!isEmpty(ret)) {
writeIndexDB([{key: cacheKey, data: ret}], 'maillist', 'mailbox')
const listids = [...new Set(ret.map(ele => ele.MAI_SN))];
writeIndexDB([{key: cacheKey, data: listids}], 'maillist', 'mailbox')
writeIndexDB(ret.map(ele => ({ data: ele, key: ele.MAI_SN})), 'listrow', 'mailbox')
}
return ret;
}

@ -150,12 +150,10 @@ export const useEmailList = (mailboxDirNode) => {
setIsFreshData(false)
const cacheKey = isEmpty(COLI_SN) ? `dir-${VKey}` : `order-${VKey}`
const readCache = await readIndexDB(cacheKey, 'maillist', 'mailbox')
if (!isEmpty(readCache)) {
const _x = readCache.data.map((ele) => ({
...ele,
key: ele.MAI_SN,
}))
const readCacheIDList = await readIndexDB(cacheKey, 'maillist', 'mailbox')
const readCacheListRowsMap = await readIndexDB(readCacheIDList.data, 'listrow', 'mailbox')
if (!isEmpty(readCacheIDList)) {
const _x = readCacheIDList.data.map((ele) => readCacheListRowsMap.get(ele).data || {})
setMailList(_x)
setLoading(false)
}

@ -107,12 +107,13 @@ const emailSlice = (set, get) => ({
let isNeedRefresh = false
if (!isEmpty(readCache)) {
setMailboxNestedDirsActive(readCache?.tree || [])
isNeedRefresh = Date.now() - readCache.timestamp > 4 * 60 * 60 * 1000
isNeedRefresh = Date.now() - readCache.timestamp > 1 * 60 * 60 * 1000
// isNeedRefresh = true; // test: 0
}
if (isEmpty(readCache) || isNeedRefresh) {
// > {4} 更新
const rootTree = await getRootMailboxDirAction({ opi_sn, userIdStr })
console.log('empty', opi_sn, userIdStr, isEmpty(readCache), isNeedRefresh, rootTree);
setMailboxNestedDirsActive(rootTree)
}
return false
@ -120,7 +121,7 @@ const emailSlice = (set, get) => ({
async initMailbox({ opi_sn, dei_sn, userId, userIdStr }) {
const { setCurrentMailboxOPI, setCurrentMailboxDEI, getOPIEmailDir } = get()
createIndexedDBStore(['dirs', 'maillist', 'mailinfo', 'draft'], 'mailbox')
createIndexedDBStore(['dirs', 'maillist', 'listrow', 'mailinfo', 'draft'], 'mailbox')
setCurrentMailboxOPI(opi_sn)
setCurrentMailboxDEI(dei_sn)
getOPIEmailDir(opi_sn, userIdStr)

@ -827,7 +827,23 @@ export const writeIndexDB = (rows, table, database) => {
}
};
export const readIndexDB = (key=null, table, database) => {
/**
* Reads data from an IndexedDB object store.
* It can read a single record by key, multiple records by an array of keys, or all records.
*
* @param {string|string[]|null} keys - The key(s) to read.
* - If `string`: Reads a single record and returns the data object directly.
* - If `string[]`: Reads multiple records and returns a Map of `rowkey` to `data` objects.
* - If `null` or `undefined` or `empty string/array`: Reads all records and returns a Map of `rowkey` to `data` objects.
* @param {string} table - The name of the IndexedDB object store (table).
* @param {string} database - The name of the IndexedDB database.
* @returns {Promise<any|Map<string, any>>} A promise that resolves with the data.
* - Single key: Resolves with the data object or `undefined` if not found.
* - Array of keys or All records: Resolves with a `Map` where keys are rowkeys and values are data objects.
* The Map will be empty if no records are found.
* - Rejects if there's an error opening the database or during the transaction.
*/
export const readIndexDB = (keys=null, table, database) => {
return new Promise((resolve, reject) => {
let openRequest = indexedDB.open(database)
openRequest.onupgradeneeded = function () {
@ -858,44 +874,80 @@ export const readIndexDB = (key=null, table, database) => {
let transaction = db.transaction(table, 'readonly')
let store = transaction.objectStore(table)
// read by key
const getRequest = isEmpty(key) ? store.all() : store.get(key);
getRequest.onsuccess = (event) => {
const result = event.target.result
if (result) {
console.log(`💾Found record with key ${key}:`, result)
resolve(result)
} else {
console.log(`No record found with key ${key}.`)
resolve();
}
}
// Handle array of keys
if (Array.isArray(keys) && keys.length > 0) {
const promises = keys.map(key => {
return new Promise((innerResolve) => {
const getRequest = store.get(key);
getRequest.onsuccess = (event) => {
const result = event.target.result;
if (result) {
// console.log(`💾Found record with key ${key}:`, result);
innerResolve([key, result]); // Resolve with [key, data] tuple
} else {
console.log(`No record found with key ${key}.`);
innerResolve(void 0); // Resolve with undefined for non-existent keys
}
};
getRequest.onerror = (event) => {
console.error(`Error getting record with key ${key}:`, event.target.error);
innerResolve(undefined); // Resolve with undefined on error, or innerReject if you want to fail fast
};
});
});
getRequest.onerror = (event) => {
console.error(`Error getting record with key ${key}:`, event.target.error)
Promise.all(promises)
.then(results => {
const resultMap = new Map();
results.forEach(item => {
if (item !== undefined) {
resultMap.set(item[0], item[1]); // item[0] is key, item[1] is data
}
});
resolve(resultMap);
})
.catch(error => {
console.error('Error during batch read:', error);
reject(error); // Reject the main promise if Promise.all encounters an error
});
} else if (!isEmpty(keys)) { // Handle single key
const getRequest = store.get(keys);
getRequest.onsuccess = (event) => {
const result = event.target.result;
if (result) {
console.log(`💾Found record with key ${keys}:`, result);
resolve(result);
} else {
console.log(`No record found with key ${keys}.`);
resolve();
}
};
getRequest.onerror = (event) => {
console.error(`Error getting record with key ${keys}:`, event.target.error);
reject(event.target.error);
};
} else { // Handle read all
const getAllRequest = store.getAll();
getAllRequest.onsuccess = (event) => {
const allData = event.target.result;
const resultMap = new Map();
if (allData && allData.length > 0) {
allData.forEach(item => {
resultMap.set(item.key, item);
});
console.log(`💾Found all records:`, resultMap);
resolve(resultMap);
} else {
console.log(`No records found.`);
resolve(resultMap); // Resolve with an empty Map if no records
}
};
getAllRequest.onerror = (event) => {
console.error(`Error getting all records:`, event.target.error);
reject(event.target.error);
};
}
// const request = store.openCursor(null, 'prev'); // 从后往前
// const results = [];
// let count = 0;
// request.onerror = function (e) {
// reject('Error getting records.')
// }
// request.onsuccess = function (e) {
// const cursor = e.target.result
// if (cursor) {
// if (count < limit) {
// results.unshift(cursor.value)
// count++
// cursor.continue()
// } else {
// console.log(JSON.stringify(results))
// resolve(results)
// }
// } else {
// console.log(JSON.stringify(results))
// resolve(results)
// }
// }
}
})
};

Loading…
Cancel
Save