WuYongJie 8705b9846a
Some checks failed
CI Check / check (push) Has been cancelled
feat: 统一弹窗样式系统与分类管理优化
- 创建统一的Modal组件,采用Apple风格设计
- 实现毛玻璃效果、圆角、动画和细边框描边
- 修复弹窗打开时背景滚动问题
- 修复分类管理中重复卡片和数组字符串显示问题
- 优化选项解析逻辑,添加去重和过滤机制
2025-11-25 09:37:00 +08:00

193 lines
6.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { NextRequest, NextResponse } from 'next/server'
import { getServerSession } from 'next-auth'
import { authOptions } from '@/lib/auth'
import { prisma } from '@/lib/prisma'
import { defaultLogos, featureFlags } from '@/lib/config'
import { cache } from '@/lib/cache'
import { ensureSystemSettingsOptionalColumns } from '@/lib/system-settings-columns'
const CACHE_KEY = 'system-settings'
const CACHE_TTL = 60000 // 1分钟缓存
// GET - 获取系统设置(带缓存)
export async function GET() {
try {
await ensureSystemSettingsOptionalColumns()
// 先尝试从缓存获取
const cachedSettings = cache.get(CACHE_KEY)
if (cachedSettings) {
return NextResponse.json(cachedSettings)
}
// 获取或创建系统设置
// 使用 select 来避免查询不存在的字段
let settings = await prisma.systemSettings.findFirst({
select: {
id: true,
headerBgColor: true,
siteName: true,
updatedAt: true,
createdAt: true,
headerLogoUrl: true,
loginLogoUrl: true,
s3AccessKey: true,
s3Bucket: true,
s3Endpoint: true,
s3PublicUrl: true,
s3Region: true,
s3SecretKey: true,
enableRegistration: true,
enableUserActivation: true,
enableAiImageEdit: true,
enableTunnelService: true,
// enabledBuiltinTemplates 可能不存在,先不查询
},
}) as any
// 如果字段存在,尝试查询它
try {
const fullSettings = await prisma.$queryRaw<Array<{ enabledBuiltinTemplates?: string | null }>>`
SELECT "enabledBuiltinTemplates" FROM "system_settings" LIMIT 1
`
if (fullSettings[0] && settings) {
settings.enabledBuiltinTemplates = fullSettings[0].enabledBuiltinTemplates
}
} catch {
// 字段不存在,设置为 null(表示全部启用)
if (settings) {
settings.enabledBuiltinTemplates = null
}
}
if (!settings) {
// 如果不存在,创建默认设置
settings = await prisma.systemSettings.create({
data: {
headerBgColor: '#1f2937',
headerLogoUrl: defaultLogos.header,
loginLogoUrl: defaultLogos.login,
siteName: '由壹点3D素材',
enableUserActivation: false,
enableRegistration: true,
enableAiImageEdit: featureFlags.aiEditEnabled,
enableTunnelService: featureFlags.tunnelEnabled,
},
})
}
// 存入缓存
cache.set(CACHE_KEY, settings, CACHE_TTL)
return NextResponse.json(settings)
} catch (error) {
console.error('[SystemSettings] Get error:', error)
return NextResponse.json(
{ error: '获取系统设置失败' },
{ status: 500 }
)
}
}
// PUT - 更新系统设置(仅管理员)
export async function PUT(request: NextRequest) {
try {
await ensureSystemSettingsOptionalColumns()
const session = await getServerSession(authOptions)
const isSuperAdmin = (session?.user as any)?.isSuperAdmin
if (!session || session.user.role !== 'ADMIN') {
return NextResponse.json(
{ error: '无权限' },
{ status: 403 }
)
}
const body = await request.json()
const {
headerBgColor,
siteName,
headerLogoUrl,
loginLogoUrl,
s3Endpoint,
s3AccessKey,
s3SecretKey,
s3Bucket,
s3Region,
s3PublicUrl,
enableUserActivation,
enableRegistration,
enableAiImageEdit,
enableTunnelService,
enabledBuiltinTemplates,
} = body
// 只有最高权限账号可以修改 enableUserActivation
if (
(enableUserActivation !== undefined ||
enableAiImageEdit !== undefined ||
enableTunnelService !== undefined) &&
!isSuperAdmin
) {
return NextResponse.json(
{ error: '只有最高权限账号可以修改受保护的功能开关' },
{ status: 403 }
)
}
// 获取或创建系统设置
let settings = await prisma.systemSettings.findFirst()
if (!settings) {
// 创建
settings = await prisma.systemSettings.create({
data: {
headerBgColor: headerBgColor || '#1f2937',
headerLogoUrl: headerLogoUrl ?? defaultLogos.header,
loginLogoUrl: loginLogoUrl ?? defaultLogos.login,
siteName: siteName || '由壹点3D素材',
enableUserActivation: enableUserActivation !== undefined ? enableUserActivation : false,
enableRegistration: enableRegistration !== undefined ? enableRegistration : true,
enableAiImageEdit:
enableAiImageEdit !== undefined ? enableAiImageEdit : featureFlags.aiEditEnabled,
enableTunnelService:
enableTunnelService !== undefined ? enableTunnelService : featureFlags.tunnelEnabled,
}
})
} else {
// 更新
const updateData: any = {}
if (headerBgColor !== undefined) updateData.headerBgColor = headerBgColor
if (siteName !== undefined) updateData.siteName = siteName
if (headerLogoUrl !== undefined) updateData.headerLogoUrl = headerLogoUrl
if (loginLogoUrl !== undefined) updateData.loginLogoUrl = loginLogoUrl
if (s3Endpoint !== undefined) updateData.s3Endpoint = s3Endpoint
if (s3AccessKey !== undefined) updateData.s3AccessKey = s3AccessKey
if (s3SecretKey !== undefined) updateData.s3SecretKey = s3SecretKey
if (s3Bucket !== undefined) updateData.s3Bucket = s3Bucket
if (s3Region !== undefined) updateData.s3Region = s3Region
if (s3PublicUrl !== undefined) updateData.s3PublicUrl = s3PublicUrl
if (enableUserActivation !== undefined) updateData.enableUserActivation = enableUserActivation
if (enableRegistration !== undefined) updateData.enableRegistration = enableRegistration
if (enableAiImageEdit !== undefined) updateData.enableAiImageEdit = enableAiImageEdit
if (enableTunnelService !== undefined) updateData.enableTunnelService = enableTunnelService
if (enabledBuiltinTemplates !== undefined) updateData.enabledBuiltinTemplates = enabledBuiltinTemplates
settings = await prisma.systemSettings.update({
where: { id: settings.id },
data: updateData,
})
}
// 清除缓存,强制下次重新加载
cache.delete(CACHE_KEY)
return NextResponse.json(settings)
} catch (error) {
console.error('Update system settings error:', error)
return NextResponse.json(
{ error: '更新系统设置失败' },
{ status: 500 }
)
}
}