From 2d321aad9cf4387910587c549441b6743f9a378c Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 23:49:19 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=E5=A4=A7=E5=B9=85=E6=8F=90?= =?UTF-8?q?=E5=8D=87UIGF=E5=AF=BC=E5=85=A5=E9=80=9F=E5=BA=A6=20(#225)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial plan * perf: optimize gacha import with batch transactions and reduced UI delays - Wrap DB inserts in transactions (batches of 500) for mergeUIGF/mergeUIGF4 - Pre-transform all data before batch insert loop - Pass timeout: 0 to showLoading.update in progress callbacks - Remove 1500ms snackbar delay in cleanGachaRecords - Reduce per-item loading update delay in refreshGachaPool Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> * fix: increment progress counter per item instead of per batch for accurate progress display Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Mikachu2333 <63829496+Mikachu2333@users.noreply.github.com> --- .gitignore | 3 +- src/pages/User/Gacha.vue | 2 +- src/plugins/Sqlite/modules/userGacha.ts | 64 +++++++++++++++++------- src/plugins/Sqlite/modules/userGachaB.ts | 47 +++++++++++++---- 4 files changed, 84 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 11126eab..10229857 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ dist *.tsbuildinfo # Sentry Config File -.env.development.local \ No newline at end of file +.env.development.local +package-lock.json diff --git a/src/pages/User/Gacha.vue b/src/pages/User/Gacha.vue index fa050fcb..4a05da7b 100644 --- a/src/pages/User/Gacha.vue +++ b/src/pages/User/Gacha.vue @@ -549,7 +549,7 @@ async function refreshGachaPool( if (force) await showLoading.update(`[${label}] 第${page}页,${gachaRes.length}条`); for (const item of gachaRes) { if (!force) { - await showLoading.update(`[${item.item_type}][${item.time}] ${item.name}`); + await showLoading.update(`[${item.item_type}][${item.time}] ${item.name}`, { timeout: 0 }); } const tempItem: TGApp.Plugins.UIGF.GachaItem = { gacha_type: item.gacha_type, diff --git a/src/plugins/Sqlite/modules/userGacha.ts b/src/plugins/Sqlite/modules/userGacha.ts index e0c4fc2d..fae0431d 100644 --- a/src/plugins/Sqlite/modules/userGacha.ts +++ b/src/plugins/Sqlite/modules/userGacha.ts @@ -235,7 +235,6 @@ async function cleanGachaRecords( const res = await db.execute(sql); if (res.rowsAffected > 0) { showSnackbar.success(`[${uid}][${pool}][${time}]清理了${res.rowsAffected}条祈愿记录`); - await new Promise((resolve) => setTimeout(resolve, 1500)); } } } @@ -253,27 +252,40 @@ async function mergeUIGF( data: Array, showProgress: boolean = false, ): Promise { - let cnt = 0; + const db = await TGSqlite.getDB(); const len = data.length; - let progress = 0; + let cnt = 0; let timer: NodeJS.Timeout | null = null; if (showProgress) { timer = setInterval(async () => { - progress = Math.round((cnt / len) * 100 * 100) / 100; + const progress = Math.round((cnt / len) * 100 * 100) / 100; const current = data[cnt]?.time ?? ""; const name = data[cnt]?.name ?? ""; const rank = data[cnt]?.rank_type ?? "0"; - await showLoading.update(`[${progress}%][${current}] ${"⭐".repeat(Number(rank))}-${name}`); + await showLoading.update(`[${progress}%][${current}] ${"⭐".repeat(Number(rank))}-${name}`, { + timeout: 0, + }); }, 1000); } - for (const gacha of data) { - await insertGachaItem(uid, transGacha(gacha)); - cnt++; + const transformed = data.map((g) => transGacha(g)); + const BATCH_SIZE = 500; + for (let i = 0; i < transformed.length; i += BATCH_SIZE) { + const batch = transformed.slice(i, i + BATCH_SIZE); + await db.execute("BEGIN TRANSACTION;"); + try { + for (const item of batch) { + await insertGachaItem(uid, item); + cnt++; + } + await db.execute("COMMIT;"); + } catch (e) { + await db.execute("ROLLBACK;"); + throw e; + } } if (timer) { clearInterval(timer); - progress = 100; - await showLoading.update(`[${progress}%] 完成`); + await showLoading.update(`[100%] 完成`, { timeout: 0 }); } } @@ -288,27 +300,41 @@ async function mergeUIGF4( data: TGApp.Plugins.UIGF.GachaHk4e, showProgress: boolean = false, ): Promise { - let cnt: number = 0; + const db = await TGSqlite.getDB(); const len = data.list.length; - let progress: number = 0; + let cnt: number = 0; let timer: NodeJS.Timeout | null = null; if (showProgress) { timer = setInterval(async () => { - progress = Math.round((cnt / len) * 100 * 100) / 100; + const progress = Math.round((cnt / len) * 100 * 100) / 100; const current = data.list[cnt]?.time ?? ""; const name = data.list[cnt]?.name ?? data.list[cnt]?.item_id; const rank = data.list[cnt]?.rank_type ?? "0"; - await showLoading.update(`[${progress}%][${current}] ${"⭐".repeat(Number(rank))}-${name}`); + await showLoading.update(`[${progress}%][${current}] ${"⭐".repeat(Number(rank))}-${name}`, { + timeout: 0, + }); }, 1000); } - for (const gacha of data.list) { - await insertGachaItem(data.uid.toString(), transGacha(gacha, data.timezone)); - cnt++; + const uid = data.uid.toString(); + const transformed = data.list.map((g) => transGacha(g, data.timezone)); + const BATCH_SIZE = 500; + for (let i = 0; i < transformed.length; i += BATCH_SIZE) { + const batch = transformed.slice(i, i + BATCH_SIZE); + await db.execute("BEGIN TRANSACTION;"); + try { + for (const item of batch) { + await insertGachaItem(uid, item); + cnt++; + } + await db.execute("COMMIT;"); + } catch (e) { + await db.execute("ROLLBACK;"); + throw e; + } } if (timer) { clearInterval(timer); - progress = 100; - await showLoading.update(`[${progress}%] 完成`); + await showLoading.update(`[100%] 完成`, { timeout: 0 }); } } diff --git a/src/plugins/Sqlite/modules/userGachaB.ts b/src/plugins/Sqlite/modules/userGachaB.ts index 7cb896c3..af72ff70 100644 --- a/src/plugins/Sqlite/modules/userGachaB.ts +++ b/src/plugins/Sqlite/modules/userGachaB.ts @@ -65,8 +65,20 @@ async function insertGachaList( uid: string, list: Array, ): Promise { - for (const gacha of list) { - await insertGachaItem(uid, gacha); + const db = await TGSqlite.getDB(); + const BATCH_SIZE = 500; + for (let i = 0; i < list.length; i += BATCH_SIZE) { + const batch = list.slice(i, i + BATCH_SIZE); + await db.execute("BEGIN TRANSACTION;"); + try { + for (const gacha of batch) { + await insertGachaItem(uid, gacha); + } + await db.execute("COMMIT;"); + } catch (e) { + await db.execute("ROLLBACK;"); + throw e; + } } } @@ -106,27 +118,40 @@ async function mergeUIGF4( data: TGApp.Plugins.UIGF.GachaUgc, showProgress: boolean = false, ): Promise { - let cnt: number = 0; + const db = await TGSqlite.getDB(); const len = data.list.length; - let progress: number = 0; + let cnt: number = 0; let timer: NodeJS.Timeout | null = null; if (showProgress) { timer = setInterval(async () => { - progress = Math.round((cnt / len) * 100 * 100) / 100; + const progress = Math.round((cnt / len) * 100 * 100) / 100; const current = data.list[cnt].time ?? ""; const name = data.list[cnt].item_name ?? ""; const rank = data.list[cnt].rank_type ?? "0"; - await showLoading.update(`[${progress}%][${current}] ${"⭐".repeat(Number(rank))}-${name}`); + await showLoading.update(`[${progress}%][${current}] ${"⭐".repeat(Number(rank))}-${name}`, { + timeout: 0, + }); }, 1000); } - for (const gacha of data.list) { - await insertGachaItem(data.uid.toString(), transGacha(gacha, data.timezone)); - cnt++; + const uid = data.uid.toString(); + const BATCH_SIZE = 500; + for (let i = 0; i < data.list.length; i += BATCH_SIZE) { + const batch = data.list.slice(i, i + BATCH_SIZE); + await db.execute("BEGIN TRANSACTION;"); + try { + for (const gacha of batch) { + await insertGachaItem(uid, transGacha(gacha, data.timezone)); + cnt++; + } + await db.execute("COMMIT;"); + } catch (e) { + await db.execute("ROLLBACK;"); + throw e; + } } if (timer) { clearInterval(timer); - progress = 100; - await showLoading.update(`[${progress}%] 完成`); + await showLoading.update(`[100%] 完成`, { timeout: 0 }); } }