refactor(设置): 站点配置去掉从来没人读的网址、简称、页脚三项和 AI 小助手开关
库里 options 表那几行旧值留着,没有代码再读。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ee649b81b1
commit
20a6f667d8
6 files changed
+4
-107
No files matched your search
@@ -52,27 +52,19 @@ function isAlive(lastHeartbeat: string) {
|
|||||||
|
|
||||||
/** camelCase 契约 ←→ options 表里的 snake_case key */
|
/** camelCase 契约 ←→ options 表里的 snake_case key */
|
||||||
const OPTION_KEYS = {
|
const OPTION_KEYS = {
|
||||||
websiteBaseUrl: "website_base_url",
|
|
||||||
websiteName: "website_name",
|
websiteName: "website_name",
|
||||||
websiteNameShortcut: "website_name_shortcut",
|
|
||||||
websiteFooter: "website_footer",
|
|
||||||
allowRegister: "allow_register",
|
allowRegister: "allow_register",
|
||||||
submissionListShowAll: "submission_list_show_all",
|
submissionListShowAll: "submission_list_show_all",
|
||||||
classList: "class_list",
|
classList: "class_list",
|
||||||
enableMaxkb: "enable_maxkb",
|
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
adminConfRoutes.get("/website", requireSuperAdmin, async (c) => {
|
adminConfRoutes.get("/website", requireSuperAdmin, async (c) => {
|
||||||
const options = await getWebsiteOptions()
|
const options = await getWebsiteOptions()
|
||||||
return success(c, {
|
return success(c, {
|
||||||
websiteBaseUrl: options.website_base_url,
|
|
||||||
websiteName: options.website_name,
|
websiteName: options.website_name,
|
||||||
websiteNameShortcut: options.website_name_shortcut,
|
|
||||||
websiteFooter: options.website_footer,
|
|
||||||
allowRegister: options.allow_register,
|
allowRegister: options.allow_register,
|
||||||
submissionListShowAll: options.submission_list_show_all,
|
submissionListShowAll: options.submission_list_show_all,
|
||||||
classList: options.class_list,
|
classList: options.class_list,
|
||||||
enableMaxkb: options.enable_maxkb,
|
|
||||||
} satisfies WebsiteConfig)
|
} satisfies WebsiteConfig)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -14,14 +14,10 @@ export const siteRoutes = new Hono()
|
|||||||
siteRoutes.get("/site", async (c) => {
|
siteRoutes.get("/site", async (c) => {
|
||||||
const options = await getWebsiteOptions()
|
const options = await getWebsiteOptions()
|
||||||
return success(c, {
|
return success(c, {
|
||||||
websiteBaseUrl: options.website_base_url,
|
|
||||||
websiteName: options.website_name,
|
websiteName: options.website_name,
|
||||||
websiteNameShortcut: options.website_name_shortcut,
|
|
||||||
websiteFooter: options.website_footer,
|
|
||||||
allowRegister: options.allow_register,
|
allowRegister: options.allow_register,
|
||||||
submissionListShowAll: options.submission_list_show_all,
|
submissionListShowAll: options.submission_list_show_all,
|
||||||
classList: options.class_list,
|
classList: options.class_list,
|
||||||
enableMaxkb: options.enable_maxkb,
|
|
||||||
} satisfies WebsiteConfig)
|
} satisfies WebsiteConfig)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -3,14 +3,10 @@ import { inArray } from "drizzle-orm"
|
|||||||
import { db, schema } from "../db"
|
import { db, schema } from "../db"
|
||||||
|
|
||||||
export const websiteOptionDefaults = {
|
export const websiteOptionDefaults = {
|
||||||
website_base_url: "http://127.0.0.1",
|
|
||||||
website_name: "Online Judge",
|
website_name: "Online Judge",
|
||||||
website_name_shortcut: "oj",
|
|
||||||
website_footer: "Online Judge Footer",
|
|
||||||
allow_register: true,
|
allow_register: true,
|
||||||
submission_list_show_all: true,
|
submission_list_show_all: true,
|
||||||
class_list: [] as string[],
|
class_list: [] as string[],
|
||||||
enable_maxkb: true,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getOptions<const T extends readonly string[]>(keys: T) {
|
export async function getOptions<const T extends readonly string[]>(keys: T) {
|
||||||
|
|||||||
@@ -1,83 +0,0 @@
|
|||||||
import { useConfigStore } from "shared/store/config"
|
|
||||||
import { useUserStore } from "shared/store/user"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MaxKB 知识库挂件的加载 / 卸载。
|
|
||||||
*
|
|
||||||
* 两个前提同时满足才加载:**已登录**(挂件本身就要登录才能用)且**后台开关打开**。
|
|
||||||
* 任一条件变假就把脚本和它建出来的 DOM 一起撤掉。
|
|
||||||
*
|
|
||||||
* 脚本**只在这里注入**。原来 vite 有个 inject-maxkb 插件把 <script src> 写进
|
|
||||||
* index.html,Vue 还没启动就已经加载执行了,后台开关根本拦不住 —— 别再加回去。
|
|
||||||
*
|
|
||||||
* 配置的实时推送不归这里管:App.vue 的 useConfigUpdate() 收 /ws/config 的广播、
|
|
||||||
* 写进 configStore,下面那个 watch 自然就跟着动。这里再开一条连接是重复的,
|
|
||||||
* 而且没登录时会撞 401(后端 /ws/config 要求会话)。
|
|
||||||
*/
|
|
||||||
export function useMaxKB() {
|
|
||||||
const configStore = useConfigStore()
|
|
||||||
const userStore = useUserStore()
|
|
||||||
const isLoaded = ref(false)
|
|
||||||
|
|
||||||
const url = import.meta.env.PUBLIC_MAXKB_URL
|
|
||||||
|
|
||||||
const loadMaxKBScript = () => {
|
|
||||||
// 没配地址就什么都不做。这道判断原来在 vite 插件里,插件删掉之后挪过来,
|
|
||||||
// 否则会拿 undefined 当 src 去请求一个 /undefined
|
|
||||||
if (!url) return
|
|
||||||
if (!userStore.isAuthed) return
|
|
||||||
if (!configStore.config.enableMaxkb) return
|
|
||||||
|
|
||||||
if (document.querySelector(`script[src="${url}"]`)) {
|
|
||||||
isLoaded.value = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const script = document.createElement("script")
|
|
||||||
script.src = url
|
|
||||||
script.async = true
|
|
||||||
script.defer = true
|
|
||||||
script.onload = () => {
|
|
||||||
isLoaded.value = true
|
|
||||||
}
|
|
||||||
script.onerror = () => {
|
|
||||||
console.error("Failed to load MaxKB script")
|
|
||||||
}
|
|
||||||
document.head.appendChild(script)
|
|
||||||
}
|
|
||||||
|
|
||||||
const removeMaxKBScript = () => {
|
|
||||||
if (!url) return
|
|
||||||
document.querySelector(`script[src="${url}"]`)?.remove()
|
|
||||||
// 脚本删掉只是不再重复执行,它已经建出来的挂件 DOM 得自己收拾
|
|
||||||
const removeElements = () => {
|
|
||||||
document.querySelectorAll('[id^="maxkb-"]').forEach((el) => el.remove())
|
|
||||||
}
|
|
||||||
if (document.readyState === "complete") {
|
|
||||||
removeElements()
|
|
||||||
} else {
|
|
||||||
window.addEventListener("load", removeElements, { once: true })
|
|
||||||
}
|
|
||||||
isLoaded.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 登录态和开关任一变化都重新判一次。immediate 是必须的:
|
|
||||||
// 页面加载时这两个值就已经定了,不会再触发一次变化
|
|
||||||
watch(
|
|
||||||
() => [userStore.isAuthed, configStore.config.enableMaxkb] as const,
|
|
||||||
([authed, enabled]) => {
|
|
||||||
if (authed && enabled) {
|
|
||||||
loadMaxKBScript()
|
|
||||||
} else {
|
|
||||||
removeMaxKBScript()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ immediate: true },
|
|
||||||
)
|
|
||||||
|
|
||||||
return {
|
|
||||||
loadMaxKBScript,
|
|
||||||
removeMaxKBScript,
|
|
||||||
isLoaded: readonly(isLoaded),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -314,14 +314,10 @@ export const resetPasswordResponseSchema = z.object({ password: z.string() })
|
|||||||
// ---------------------------------------------------------------- 站点配置 / 运维
|
// ---------------------------------------------------------------- 站点配置 / 运维
|
||||||
|
|
||||||
export const updateWebsiteConfigRequestSchema = z.object({
|
export const updateWebsiteConfigRequestSchema = z.object({
|
||||||
websiteBaseUrl: z.string().max(256),
|
|
||||||
websiteName: z.string().trim().min(1).max(64),
|
websiteName: z.string().trim().min(1).max(64),
|
||||||
websiteNameShortcut: z.string().trim().min(1).max(32),
|
|
||||||
websiteFooter: z.string().max(1024 * 64),
|
|
||||||
allowRegister: z.boolean(),
|
allowRegister: z.boolean(),
|
||||||
submissionListShowAll: z.boolean(),
|
submissionListShowAll: z.boolean(),
|
||||||
classList: z.array(z.string()),
|
classList: z.array(z.string()),
|
||||||
enableMaxkb: z.boolean(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
export const judgeServerSchema = z.object({
|
export const judgeServerSchema = z.object({
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 站点配置。网址、简称、页脚三项 2026-10-13 删了(前后端从来没读过,改了也看不到变化),
|
||||||
|
* AI 小助手(MaxKB 挂件)连同开关一起删了。options 表里那几行旧值留着,没人读
|
||||||
|
*/
|
||||||
export const websiteConfigSchema = z.object({
|
export const websiteConfigSchema = z.object({
|
||||||
websiteBaseUrl: z.string(),
|
|
||||||
websiteName: z.string(),
|
websiteName: z.string(),
|
||||||
websiteNameShortcut: z.string(),
|
|
||||||
websiteFooter: z.string(),
|
|
||||||
allowRegister: z.boolean(),
|
allowRegister: z.boolean(),
|
||||||
submissionListShowAll: z.boolean(),
|
submissionListShowAll: z.boolean(),
|
||||||
classList: z.array(z.string()),
|
classList: z.array(z.string()),
|
||||||
enableMaxkb: z.boolean(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in new issue
Block a user