From 771e290fb9e06ebd139e2b34e8e0e4d411225ed9 Mon Sep 17 00:00:00 2001 From: zhangshun <453905631@qq.com> Date: Wed, 27 May 2026 09:21:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=A8=A1=E5=9E=8B=E5=AD=97?= =?UTF-8?q?=E5=85=B8=E5=8A=A0=E8=BD=BD=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 4 +-- web/src/pages/app/modules/models.ts | 47 ++++++++++++++++++++++++----- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/.env.example b/.env.example index 7e9e0ef..9531c24 100644 --- a/.env.example +++ b/.env.example @@ -5,8 +5,8 @@ DB_PATH= # login: show login page # fixed: auto login with FIXED_LOGIN_USERNAME and open model library directly -APP_AUTH_MODE=fixed -FIXED_LOGIN_USERNAME=viewer +APP_AUTH_MODE=login +FIXED_LOGIN_USERNAME= FIXED_LOGIN_ROLE=user ALLOW_USER_EDIT_SYSTEM_LIBRARY=false diff --git a/web/src/pages/app/modules/models.ts b/web/src/pages/app/modules/models.ts index a101732..a41fa8b 100644 --- a/web/src/pages/app/modules/models.ts +++ b/web/src/pages/app/modules/models.ts @@ -22,6 +22,8 @@ type UploadModelPayload = { }; const defaultOperationTree = JSON.stringify({ OperationTree: "[]" }); +let dictionariesLoaded = false; +let dictionariesLoading: Promise | null = null; export function bindModelActions() { const isAdmin = getCurrentUser()?.role === "admin"; @@ -38,7 +40,10 @@ export function bindModelActions() { document.querySelector("#manageDictionariesBtn")?.addEventListener("click", async () => { try { const { openDictionaryManager } = await import("./dictionaries"); - await openDictionaryManager(loadModels); + await openDictionaryManager(async () => { + invalidateDictionaries(); + await loadModels(); + }); } catch (error) { notifyError(error); } @@ -158,12 +163,37 @@ export async function loadModels() { }); } -async function loadDictionaries() { - const result = await api("/api/dictionaries"); - appState.brands = result.brands; - appState.types = result.types; - syncDictionarySelect("#brandFilter", result.brands, "全部品牌", appState.filters.brandId); - syncDictionarySelect("#typeFilter", result.types, "全部类型", appState.filters.typeId); +async function loadDictionaries(force = false) { + if (!force && dictionariesLoaded) { + syncDictionaryFilters(); + return; + } + if (!force && dictionariesLoading) { + await dictionariesLoading; + syncDictionaryFilters(); + return; + } + + dictionariesLoading = api("/api/dictionaries") + .then((result) => { + appState.brands = result.brands; + appState.types = result.types; + dictionariesLoaded = true; + }) + .finally(() => { + dictionariesLoading = null; + }); + await dictionariesLoading; + syncDictionaryFilters(); +} + +function invalidateDictionaries() { + dictionariesLoaded = false; +} + +function syncDictionaryFilters() { + syncDictionarySelect("#brandFilter", appState.brands, "全部品牌", appState.filters.brandId); + syncDictionarySelect("#typeFilter", appState.types, "全部类型", appState.filters.typeId); } function syncDictionarySelect(selector: string, items: { id: number; name: string }[], emptyText: string, value: string) { @@ -312,6 +342,7 @@ async function openUploadModelDialog() { }); if (result) { + invalidateDictionaries(); await loadModels(); } } @@ -391,6 +422,7 @@ export async function openProcessModelUploadDialog(input?: { }); if (result) { + invalidateDictionaries(); await loadModels(); } } @@ -565,6 +597,7 @@ async function editModel(id: number) { } }) }); + invalidateDictionaries(); await loadModels(); }