feat: 就地通过评审,并为已过审用户提供默认可关的免审发布

帖/评管理入口可直接通过;站点默认信任已有 published 内容的用户后续直发。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-16 05:37:57 +08:00
parent b0170a99fd
commit f3145b24ff
14 changed files with 330 additions and 40 deletions

View File

@@ -528,19 +528,25 @@ export async function fetchBoards(): Promise<{ boards: BoardWithCount[] }> {
return res.json();
}
// 公开站点设置:accent 为站点主题色 hex(空串=内置默认)
// 公开站点设置:accent 为站点主题色 hex(空串=内置默认);
// trust_reviewed_publish 为已过审用户后续免审(缺省/未配置视为 true)
export interface PublicSettings {
accent: string;
trust_reviewed_publish: boolean;
}
// SSR 读取公开站点设置(主题色注入用);后端不可用时降级为默认色,不阻塞渲染
export async function fetchPublicSettings(): Promise<PublicSettings> {
try {
const res = await fetch(`${API_BASE}/api/settings`, ssrInit());
if (!res.ok) return { accent: "" };
return (await res.json()) as PublicSettings;
if (!res.ok) return { accent: "", trust_reviewed_publish: true };
const data = (await res.json()) as Partial<PublicSettings>;
return {
accent: data.accent ?? "",
trust_reviewed_publish: data.trust_reviewed_publish !== false,
};
} catch {
return { accent: "" };
return { accent: "", trust_reviewed_publish: true };
}
}
@@ -1417,19 +1423,31 @@ export async function apiGetSettings(): Promise<PublicSettings> {
// no-store:主题同步必须读到管理员刚保存的最新配色,不走浏览器缓存
const res = await fetchWithRefresh("/api/settings", { method: "GET", cache: "no-store" });
if (!res.ok) throw new Error("获取站点设置失败");
return res.json();
const data = (await res.json()) as Partial<PublicSettings>;
return {
accent: data.accent ?? "",
trust_reviewed_publish: data.trust_reviewed_publish !== false,
};
}
// 更新站点主题色;accent 传空串恢复默认
export async function apiUpdateSiteSettings(accent: string): Promise<PublicSettings> {
export type UpdateSiteSettingsBody = {
accent?: string;
trust_reviewed_publish?: boolean;
};
// 更新站点设置(字段可选);accent 传空串恢复默认主题色
export async function apiUpdateSiteSettings(body: UpdateSiteSettingsBody): Promise<PublicSettings> {
const res = await fetchWithRefresh("/api/admin/settings", {
method: "PUT",
headers: clientHeaders({ "Content-Type": "application/json" }),
body: JSON.stringify({ accent }),
body: JSON.stringify(body),
});
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(data.error || "保存设置失败");
return { accent: data.accent ?? "" };
return {
accent: data.accent ?? "",
trust_reviewed_publish: data.trust_reviewed_publish !== false,
};
}
// ===== 板块(客户端,供角色授权弹窗勾选) =====