diff --git a/apps/api/src/routes/admin/conf.ts b/apps/api/src/routes/admin/conf.ts index 507f1f3..23b3f81 100644 --- a/apps/api/src/routes/admin/conf.ts +++ b/apps/api/src/routes/admin/conf.ts @@ -83,7 +83,9 @@ adminConfRoutes.post("/website", requireSuperAdmin, async (c) => { set: { value: sql`excluded.value` }, }) // 广播给所有开着页面的人,改完立刻生效不必刷新,对齐旧 push_config_update。 - // 推的是 options 表里的 snake_case key —— 前端 configStore.config 用的就是这套键名。 + // 推的是 options 表里的 snake_case key。**前端 store 的字段是驼峰**, + // 换名在前端 configUpdate.ts 里做 —— 这里曾经注释成「前端用的就是这套键名」, + // 结果前端照着直接 `key in store` 判断,一条也命中不了,整个实时生效空转了很久。 for (const entry of entries) await publishConfigUpdate(entry.key, entry.value) return success(c, null) }) diff --git a/apps/web/src/shared/composables/configUpdate.ts b/apps/web/src/shared/composables/configUpdate.ts index 4974f36..9efbd75 100644 --- a/apps/web/src/shared/composables/configUpdate.ts +++ b/apps/web/src/shared/composables/configUpdate.ts @@ -5,17 +5,30 @@ import { type ConfigUpdate, } from "shared/composables/websocket" +/** + * 后端推的是 options 表里的 snake_case 键(`enable_maxkb`), + * store 里的字段是驼峰(`enableMaxkb`)—— 两边对不上,这里负责换。 + * + * 原来是直接 `data.key in configStore.config`,snake 键永远命中不了驼峰字段, + * 于是**一条配置都写不进去**,整个「改完不必刷新」是空转的:站点名称、页脚、 + * 班级名单、允许注册、提交列表看全部、知识库挂件,全都要刷新才生效。 + */ +function toCamel(key: string) { + return key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase()) +} + export function useConfigUpdate() { const configStore = useConfigStore() const userStore = useUserStore() // 处理 WebSocket 配置更新 const handleConfigUpdate = (data: ConfigUpdate) => { - // 更新全局配置 - 使用响应式方式 - if (data.key in configStore.config) { - // 直接修改 ref 的值来触发响应式更新 - ;(configStore.config as any)[data.key] = data.value - } + const field = toCamel(data.key) + // 认不出来的键直接忽略:后端将来多推一个字段,不该把 store 撑出个野字段 + if (!(field in configStore.config)) return + ;(configStore.config as any)[field] = data.value + // getConfig() 里也是这么设的,站点改名后标签页跟着变,别只更新页面里那份 + if (field === "websiteName") document.title = data.value } // 初始化 WebSocket - handler 会在 onMounted 时自动添加 diff --git a/apps/web/src/shared/composables/maxkb.ts b/apps/web/src/shared/composables/maxkb.ts index 480d009..2741466 100644 --- a/apps/web/src/shared/composables/maxkb.ts +++ b/apps/web/src/shared/composables/maxkb.ts @@ -1,126 +1,72 @@ import { useConfigStore } from "shared/store/config" import { useUserStore } from "shared/store/user" -import { - useConfigWebSocket, - type ConfigUpdate, -} from "shared/composables/websocket" +/** + * MaxKB 知识库挂件的加载 / 卸载。 + * + * 两个前提同时满足才加载:**已登录**(挂件本身就要登录才能用)且**后台开关打开**。 + * 任一条件变假就把脚本和它建出来的 DOM 一起撤掉。 + * + * 脚本**只在这里注入**。原来 vite 有个 inject-maxkb 插件把