"use client" import {useEffect, useState} from "react" import {useMutation, useQueryClient, type UseQueryResult} from "@tanstack/react-query" import {Globe, Loader2, Mail, Search, Server, Sparkles} from "lucide-react" import {Button} from "@/components/ui/button" import {Card, CardContent, CardDescription, CardHeader, CardTitle} from "@/components/ui/card" import {Input} from "@/components/ui/input" import {Label} from "@/components/ui/label" import {Switch} from "@/components/ui/switch" import {Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle} from "@/components/ui/dialog" import {Badge} from "@/components/ui/badge" import services from "@/lib/services" import type {SystemConfig} from "@/lib/services/admin" import {toast} from "sonner" interface SystemTabProps { configs: Record systemConfigsQuery: UseQueryResult } export function SystemTab({ configs, systemConfigsQuery }: SystemTabProps) { const queryClient = useQueryClient() const [serverAddress, setServerAddress] = useState("") const [siteName, setSiteName] = useState("") const [smtpHost, setSmtpHost] = useState("") const [smtpPort, setSmtpPort] = useState("") const [smtpUsername, setSmtpUsername] = useState("") const [smtpPassword, setSmtpPassword] = useState("") const [smtpTestOpen, setSmtpTestOpen] = useState(false) const [smtpTestTo, setSmtpTestTo] = useState("") const [smtpTestLog, setSmtpTestLog] = useState("") const [smtpTestSuccess, setSmtpTestSuccess] = useState(null) const [smtpTestError, setSmtpTestError] = useState("") useEffect(() => { if (systemConfigsQuery.data) { setServerAddress(configs["server_address"]?.value || "") setSiteName(configs["site_name"]?.value || "") setSmtpHost(configs["smtp_host"]?.value || "") setSmtpPort(configs["smtp_port"]?.value || "587") setSmtpUsername(configs["smtp_username"]?.value || "") setSmtpPassword(configs["smtp_password"]?.value || "") } }, [systemConfigsQuery.data, configs]) const handleDetectAddress = () => { if (typeof window !== "undefined") { setServerAddress(window.location.origin) toast.success("已自动获取当前域名并填充") } } const updateConfigMutation = useMutation({ mutationFn: async ({ key, value }: { key: string; value: boolean }) => { const config = configs[key] if (!config) { throw new Error(`缺少配置项: ${key}`) } await services.adminSystemConfig.updateSystemConfig(key, { value: value ? "true" : "false", description: config.description, }) }, onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["admin", "system-configs"] }) await queryClient.invalidateQueries({ queryKey: ["public-config"] }) toast.success("配置已更新") }, onError: (error: Error) => { toast.error(error.message || "更新配置失败") }, }) const saveSystemMutation = useMutation({ mutationFn: async () => { const currentAddrCfg = configs["server_address"] const currentSiteCfg = configs["site_name"] await Promise.all([ services.adminSystemConfig.updateSystemConfig("server_address", { value: serverAddress, description: currentAddrCfg?.description || "服务器地址", }), services.adminSystemConfig.updateSystemConfig("site_name", { value: siteName, description: currentSiteCfg?.description || "系统平台的展示名称", }), ]) }, onSuccess: async () => { await Promise.all([ queryClient.invalidateQueries({ queryKey: ["admin", "system-configs"] }), queryClient.invalidateQueries({ queryKey: ["public-config"] }), ]) toast.success("通用配置已成功保存") }, onError: (error: Error) => { toast.error(error.message || "保存配置失败") }, }) const handleSystemSave = (e: React.FormEvent) => { e.preventDefault() saveSystemMutation.mutate() } const saveSmtpMutation = useMutation({ mutationFn: async () => { const updates = [ { key: "smtp_host", value: smtpHost }, { key: "smtp_port", value: smtpPort }, { key: "smtp_username", value: smtpUsername }, { key: "smtp_password", value: smtpPassword }, ] for (const update of updates) { const currentCfg = configs[update.key] if (update.key === "smtp_password" && (update.value === "" || update.value === "******")) { // If already configured and sent empty or mask, skip updating it (keep existing) if (currentCfg && currentCfg.value === "******") { continue } } await services.adminSystemConfig.updateSystemConfig(update.key, { value: update.value, description: currentCfg?.description || "", }) } }, onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["admin", "system-configs"] }) toast.success("SMTP 邮件配置已成功保存") }, onError: (error: Error) => { toast.error(error.message || "保存配置失败") }, }) const handleSmtpSave = (e: React.FormEvent) => { e.preventDefault() saveSmtpMutation.mutate() } const testSmtpMutation = useMutation({ mutationFn: async () => { setSmtpTestLog("正在发起连接测试...\n") setSmtpTestSuccess(null) setSmtpTestError("") const res = await services.adminSystemConfig.testSMTP({ smtp_host: smtpHost, smtp_port: parseInt(smtpPort, 10) || 587, smtp_username: smtpUsername, smtp_password: smtpPassword, to: smtpTestTo, }) return res }, onSuccess: (data) => { setSmtpTestLog(data.log) if (data.success) { setSmtpTestSuccess(true) toast.success("测试邮件发送成功") } else { setSmtpTestSuccess(false) setSmtpTestError(data.error || "发送失败,请检查配置和日志。") toast.error("测试邮件发送失败") } }, onError: (error: Error) => { setSmtpTestSuccess(false) setSmtpTestError(error.message || "请求发送失败") setSmtpTestLog((prev) => prev + `\n[请求错误] ${error.message}\n`) toast.error(error.message || "测试请求发送失败") }, }) const handleSmtpTestSubmit = (e: React.FormEvent) => { e.preventDefault() if (!smtpTestTo) { toast.error("请输入目标邮箱地址") return } testSmtpMutation.mutate() } const indexingEnabled = configs["search_engine_indexing_enabled"]?.value === "true" return (
{/* 通用设置 */}
通用设置 配置站点标识、服务地址与搜索引擎收录策略
setSiteName(e.target.value)} placeholder="例如: OpenFlare" className="border-dashed bg-card text-xs" />

用于网页标题、登录注册页面、管理后台与系统邮件。

setServerAddress(e.target.value)} placeholder="例如: https://example.com" className="border-dashed bg-card text-xs" />

限定 API 的允许来源;留空将开放任意来源访问。

搜索引擎抓取与收录 {indexingEnabled ? "允许收录" : "禁止收录"}

控制 Google、Baidu、Bing 等搜索引擎是否可以索引公开页面。

updateConfigMutation.mutate({ key: "search_engine_indexing_enabled", value: checked }) } />
地址变更会影响跨域访问策略,请填写完整协议与域名。
{/* SMTP 邮件设置 */}
SMTP 邮件设置 配置系统的邮件发送服务 (SMTP)
setSmtpHost(e.target.value)} placeholder="例如: smtp.example.com" className="bg-card border-dashed text-xs" />
setSmtpPort(e.target.value)} placeholder="例如: 587 或 465" className="bg-card border-dashed text-xs" />
setSmtpUsername(e.target.value)} placeholder="例如: sender@example.com" className="bg-card border-dashed text-xs" />
setSmtpPassword(e.target.value)} placeholder={configs["smtp_password"]?.value === "******" ? "•••••• (已配置,留空或输入新值)" : "输入凭证密码"} className="bg-card border-dashed text-xs" />
SMTP 发件测试 输入接收测试邮件的邮箱地址。系统将使用您在表单中当前填写的 SMTP 配置进行发件测试。
setSmtpTestTo(e.target.value)} placeholder="例如: receiver@example.com" className="bg-card border-dashed text-xs" disabled={testSmtpMutation.isPending} />
{smtpTestLog && (
                  {smtpTestLog}
                
)} {smtpTestSuccess === true && (
测试成功!邮件已顺利发出。
)} {smtpTestSuccess === false && (
测试失败:{smtpTestError}
)}
) }