feat: 添加无限画布设置(启用/禁用、默认模型)

This commit is contained in:
Your Name 2026-02-01 22:41:42 +08:00
parent c8e565d016
commit 51196ea0dd
4 changed files with 68 additions and 5 deletions

View File

@ -166,6 +166,8 @@ type SiteSettings = {
tutorialVideoUrl: string | null;
tutorialEnabled: boolean;
rankingEnabled: boolean;
canvasEnabled: boolean;
canvasDefaultModelId: string | null;
};
type NavLink = {
@ -378,6 +380,8 @@ export function AdminSettingsClient() {
tutorialVideoUrl: null,
tutorialEnabled: false,
rankingEnabled: true,
canvasEnabled: true,
canvasDefaultModelId: null,
});
useEffect(() => {
@ -403,6 +407,8 @@ export function AdminSettingsClient() {
tutorialVideoUrl: siteSettingsData.tutorialVideoUrl || null,
tutorialEnabled: siteSettingsData.tutorialEnabled ?? false,
rankingEnabled: siteSettingsData.rankingEnabled ?? true,
canvasEnabled: siteSettingsData.canvasEnabled ?? true,
canvasDefaultModelId: siteSettingsData.canvasDefaultModelId || null,
});
}
}, [siteSettingsData]);
@ -2567,6 +2573,50 @@ export function AdminSettingsClient() {
</>
)}
</div>
{/* 无限画布设置 */}
<div className="border-t pt-4">
<div className="flex items-center justify-between mb-4">
<div className="space-y-0.5">
<Label htmlFor="canvasEnabled">无限画布功能</Label>
<div className="text-sm text-muted-foreground">
开启后,用户可以使用无限画布进行图片编辑和生成
</div>
</div>
<Switch
id="canvasEnabled"
checked={siteSettings.canvasEnabled}
onCheckedChange={(checked) => setSiteSettings({ ...siteSettings, canvasEnabled: checked })}
/>
</div>
{siteSettings.canvasEnabled && (
<div className="space-y-2">
<Label htmlFor="canvasDefaultModelId">画布默认生图模型</Label>
<Select
value={siteSettings.canvasDefaultModelId || "auto"}
onValueChange={(value) => setSiteSettings({
...siteSettings,
canvasDefaultModelId: value === "auto" ? null : value
})}
>
<SelectTrigger id="canvasDefaultModelId">
<SelectValue placeholder="选择默认模型" />
</SelectTrigger>
<SelectContent>
<SelectItem value="auto">智能自动(推荐)</SelectItem>
{modelsData?.models?.filter((m: any) => m.supportsImageGen).map((model: any) => (
<SelectItem key={model.id} value={model.id}>
{model.displayName}
</SelectItem>
))}
</SelectContent>
</Select>
<div className="text-xs text-muted-foreground">
设置无限画布中用户的默认生图模型。"智能自动"会根据用户需求自动选择最佳模型。
</div>
</div>
)}
</div>
</div>
<Button onClick={handleSaveSiteSettings}>
<Save className="mr-2 h-4 w-4" /> 保存设置

View File

@ -41,6 +41,8 @@ export async function GET() {
tutorialVideoUrl: null,
tutorialEnabled: false,
rankingEnabled: true,
canvasEnabled: true,
canvasDefaultModelId: null,
};
const response = NextResponse.json({
@ -84,6 +86,8 @@ const updateSchema = z.object({
tutorialVideoUrl: z.string().nullable().optional(),
tutorialEnabled: z.boolean().optional(),
rankingEnabled: z.boolean().optional(),
canvasEnabled: z.boolean().optional(),
canvasDefaultModelId: z.string().nullable().optional(),
});
// PUT /api/site-settings - 更新网站设置(仅管理员)
@ -143,6 +147,8 @@ export async function PUT(request: NextRequest) {
tutorialVideoUrl: data.tutorialVideoUrl,
tutorialEnabled: data.tutorialEnabled ?? false,
rankingEnabled: data.rankingEnabled ?? true,
canvasEnabled: data.canvasEnabled ?? true,
canvasDefaultModelId: data.canvasDefaultModelId,
updatedBy: session.user.id,
})
.returning();

View File

@ -199,11 +199,13 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
}>;
}>("/api/models", fetcher);
// 获取网站设置(包含广告横幅配置)
// 获取网站设置(包含广告横幅配置和画布设置)
const { data: siteSettings } = useSWR<{
bannerEnabled?: boolean;
bannerText?: string;
bannerLink?: string | null;
canvasEnabled?: boolean;
canvasDefaultModelId?: string | null;
}>("/api/site-settings", fetcher);
// 过滤支持图片生成的模型
@ -221,12 +223,14 @@ export function CanvasChatPanel({ chatId, initialMessages = [], onClose, onOpenF
// 所有可选模型(智能自动 + 生图模型)
const allModels = [SMART_AUTO_MODEL, ...imageModels];
// 默认选择智能自动模型
// 默认选择模型(根据系统设置)
useEffect(() => {
if (!selectedModelId) {
setSelectedModelId("auto"); // 默认使用智能自动模式
if (!selectedModelId && siteSettings) {
// 使用系统设置的默认模型,如果没有设置则使用智能自动
const defaultModel = siteSettings.canvasDefaultModelId || "auto";
setSelectedModelId(defaultModel);
}
}, [selectedModelId]);
}, [selectedModelId, siteSettings]);
const currentModelIdRef = useRef(selectedModelId);
const imageParamsRef = useRef(imageParams);

View File

@ -306,6 +306,9 @@ export const siteSettings = pgTable("SiteSettings", {
tutorialEnabled: boolean("tutorialEnabled").notNull().default(false), // 是否显示功能教程按钮
// 精选榜设置
rankingEnabled: boolean("rankingEnabled").notNull().default(true), // 是否显示精选榜按钮
// 无限画布设置
canvasEnabled: boolean("canvasEnabled").notNull().default(true), // 是否启用无限画布功能
canvasDefaultModelId: varchar("canvasDefaultModelId", { length: 128 }), // 画布默认生图模型ID(null表示智能自动)
updatedAt: timestamp("updatedAt").notNull().defaultNow(),
updatedBy: uuid("updatedBy").references(() => user.id),
});