Merge branch 'fe-settings'

This commit is contained in:
root committed 2026-09-29 17:43:00 +08:00
commit 161e6e732a
13 files changed
+254 -111

No files matched your search

+18 -2
View File
@@ -1,5 +1,6 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
DEFAULT_SETTINGS,
type GlobalSettings,
type GlobalSettingsUpdate,
mergeSettings,
@@ -11,15 +12,30 @@ import { qk } from "~/lib/query-keys.ts";
export function useSettings() {
return useQuery({
queryKey: qk.settings,
queryFn: ({ signal }) => apiData<GlobalSettings>("/settings", { signal }),
queryFn: ({ signal }) => apiData<GlobalSettings>("/settings", { signal }).then(withSettingsDefaults),
});
}
/**
* 后端比前端旧时(滚动升级、回滚)响应里会缺新加的 key;按 key 用默认值补齐,
* 避免设置页读 `settings.<新key>.x` 直接崩掉。只补缺的,不覆盖已有值。
*/
export function withSettingsDefaults(s: GlobalSettings): GlobalSettings {
const out: Record<string, unknown> = { ...s };
for (const [k, def] of Object.entries(DEFAULT_SETTINGS)) {
const cur = out[k];
if (cur === undefined || cur === null) out[k] = def;
else if (typeof def === "object" && !Array.isArray(def) && typeof cur === "object") out[k] = { ...def, ...cur };
}
return out as GlobalSettings;
}
/** PATCH /settings,乐观更新(失败回滚) */
export function useUpdateSettings() {
const qc = useQueryClient();
return useMutation({
mutationFn: (patch: GlobalSettingsUpdate) => apiData<GlobalSettings>("/settings", { method: "PATCH", body: patch }),
mutationFn: (patch: GlobalSettingsUpdate) =>
apiData<GlobalSettings>("/settings", { method: "PATCH", body: patch }).then(withSettingsDefaults),
onMutate: async (patch) => {
await qc.cancelQueries({ queryKey: qk.settings });
const prev = qc.getQueryData<GlobalSettings>(qk.settings);