"use client"; import React, { useState } from "react"; import { gql, useMutation } from "@apollo/client"; import { useForm } from "react-hook-form" import { z } from "zod" import { Settings, Globe, Palette, Shield, Users, Database, Mail, FileText, Server, HardDrive, Lock, User, ToggleLeft, RefreshCw, Download, Upload, Save, CheckCircle, AlertCircle, Loader2 } from "lucide-react"; import { AdminPanelConfig } from "@/types/admin-panel"; import { commonConfigSchema, zodErrorsToAdminErrors } from "@/lib/config-zod"; import { SiteOpsConfigType } from "@/types/site-config"; import { ConfigItemType } from "@/hooks/use-site-config"; import { UpdateConfig } from "@/types/config"; import { Button } from "@/components/ui/button"; import { toast } from "sonner"; import { zodResolver } from "@hookform/resolvers/zod"; import { Badge } from "@/components/ui/badge"; import { cn } from "@/lib/utils"; // GraphQL Mutation const UPDATE_CONFIG_BATCH = gql` mutation UpdateConfigBatch($input: [UpdateConfig!]!) { updateConfigBatch(input: $input) } `; // 创建基于后端数据的动态管理面板配置 export function createDynamicAdminConfig( data?: SiteOpsConfigType, onSave?: (values: Record) => Promise, onExport?: () => Promise, onImport?: (file: File) => Promise, configs?: ConfigItemType[] ): AdminPanelConfig { // 从后端数据获取初始值(安全访问嵌套属性) const getInitialValues = () => { if (!data) return {}; return { // Site 配置 'site.name': data.site?.info?.name || "MMAP System", 'site.description': "", 'site.keywords': "", 'site.url': "/", 'site.logo': data.site?.brand?.logo_url || "/images/logo.png", 'site.copyright': "", 'site.icp': "", 'site.icp_url': "", 'site.color_style': (data.site?.brand?.dark_mode_default ? 'dark' : 'light'), // User 配置 'user.default_avatar': "/images/avatar.png", 'user.default_role': 'user', 'user.register_invite_code': data.ops?.features?.invite_code_required ?? false, 'user.register_email_verification': data.ops?.features?.email_verification ?? false, 'user.open_login': true, 'user.open_reset_password': true, // Email 配置 'email.smtp_host': "", 'email.smtp_port': 465, 'email.smtp_user': "", 'email.smtp_password': "", 'email.smtp_from': "", 'email.smtp_from_name': "", 'email.smtp_from_email': "", 'email.system_template': "default", // Blog 配置 'blog.default_author': "", 'blog.default_category': "", 'blog.default_tag': "", 'blog.open_comment': true, // Logging 配置 'logging.level': 'info', 'logging.max_files': 10, 'logging.max_file_size': 10, // Cache 配置 'cache.ttl': 3600, 'cache.max_size': 1024, // Switch 配置 'switch.open_register': data.ops?.features?.registration_enabled ?? true, 'switch.open_login': true, 'switch.open_reset_password': true, 'switch.open_comment': true, 'switch.open_like': true, 'switch.open_share': true, 'switch.open_view': true }; }; return { header: { title: "系统配置管理", description: "管理站点配置、运营设置和系统参数", breadcrumbs: [ { label: "首页", href: "/" }, { label: "管理中心", href: "/admin" }, { label: "系统配置" } ], actions: [ { id: "refresh", label: "刷新数据", icon: , variant: "outline", onClick: () => window.location.reload() }, { id: "export", label: "导出配置", icon: , variant: "outline", onClick: onExport || (() => console.log("导出配置")) }, { id: "import", label: "导入配置", icon: , variant: "outline", onClick: () => { const input = document.createElement('input'); input.type = 'file'; input.accept = '.json'; input.onchange = (e) => { const file = (e.target as HTMLInputElement).files?.[0]; if (file && onImport) { onImport(file); } }; input.click(); } } ] }, tabs: [ // 内容配置 (Site + Blog) { id: "content", title: "内容配置", icon: , sections: [ { id: "site-basic", title: "站点信息", description: "网站基本信息和设置", icon: , fields: [ { id: "site.name", label: "网站名称", description: "显示在浏览器标题栏的网站名称", type: "input", value: data?.site?.info?.name || "MMAP System", placeholder: "请输入网站名称", validation: { required: true, minLength: 2, maxLength: 50 } }, { id: "site.description", label: "网站描述", description: "网站的简要描述信息", type: "textarea", rows: 3, value: "", placeholder: "请输入网站描述" }, { id: "site.keywords", label: "网站关键词", description: "SEO相关的关键词,用逗号分隔", type: "input", value: "", placeholder: "请输入关键词,用逗号分隔" }, { id: "site.url", label: "网站地址", description: "网站的主域名地址", type: "input", value: "/", placeholder: "请输入网站地址" } ] }, { id: "site-brand", title: "品牌设置", description: "网站品牌形象和主题配置", icon: , fields: [ { id: "site.logo", label: "Logo地址", description: "网站Logo图片的URL地址", type: "input", value: data?.site?.brand?.logo_url || "/images/logo.png", placeholder: "请输入Logo URL" }, { id: "site.color_style", label: "颜色风格", description: "网站的颜色主题风格", type: "select", value: (data?.site?.brand?.dark_mode_default ? 'dark' : 'light'), options: [ { label: "浅色主题", value: "light" }, { label: "深色主题", value: "dark" } ] } ] }, { id: "site-legal", title: "法律信息", description: "网站的法律相关信息", icon: , fields: [ { id: "site.copyright", label: "版权信息", description: "网站的版权声明", type: "input", value: "", placeholder: "请输入版权信息" }, { id: "site.icp", label: "ICP备案号", description: "网站的ICP备案号码", type: "input", value: "", placeholder: "请输入ICP备案号" }, { id: "site.icp_url", label: "ICP备案链接", description: "ICP备案查询链接", type: "input", value: "", placeholder: "请输入ICP备案链接" } ] }, { id: "blog-defaults", title: "博客设置", description: "博客功能的默认配置", icon: , fields: [ { id: "blog.default_author", label: "默认作者", description: "博客文章的默认作者", type: "input", value: "", placeholder: "请输入默认作者" }, { id: "blog.default_category", label: "默认分类", description: "博客文章的默认分类", type: "input", value: "", placeholder: "请输入默认分类" }, { id: "blog.default_tag", label: "默认标签", description: "博客文章的默认标签", type: "input", value: "", placeholder: "请输入默认标签" }, { id: "blog.open_comment", label: "开放评论", description: "是否允许用户对博客文章进行评论", type: "switch", value: true } ] } ] }, // 用户管理 (User + Switch) { id: "user", title: "用户管理", icon: , sections: [ { id: "user-defaults", title: "默认设置", description: "用户相关的默认配置", icon: , fields: [ { id: "user.default_avatar", label: "默认头像", description: "新用户的默认头像图片", type: "input", value: "/images/avatar.png", placeholder: "请输入默认头像URL" }, { id: "user.default_role", label: "默认角色", description: "新用户注册后的默认角色", type: "select", value: 'user', options: [ { label: "普通用户", value: "user" }, { label: "VIP用户", value: "vip" }, { label: "管理员", value: "admin" } ] } ] }, { id: "user-registration", title: "注册设置", description: "用户注册相关的配置", icon: , fields: [ { id: "user.register_invite_code", label: "需要邀请码", description: "注册时是否需要邀请码", type: "switch", value: data?.ops?.features?.invite_code_required ?? false }, { id: "user.register_email_verification", label: "需要邮箱验证", description: "注册后是否需要验证邮箱", type: "switch", value: data?.ops?.features?.email_verification ?? false } ] }, { id: "user-access", title: "访问控制", description: "用户访问和登录相关设置", icon: , fields: [ { id: "user.open_login", label: "开放登录", description: "是否允许用户登录", type: "switch", value: true }, { id: "user.open_reset_password", label: "开放重置密码", description: "是否允许用户重置密码", type: "switch", value: true } ] }, { id: "user-features", title: "功能开关", description: "用户相关功能的开关配置", icon: , fields: [ { id: "switch.open_register", label: "开放注册", description: "是否允许新用户注册", type: "switch", value: data?.ops?.features?.registration_enabled ?? true }, { id: "switch.open_comment", label: "开放评论", description: "是否允许用户进行评论", type: "switch", value: true }, { id: "switch.open_like", label: "开放点赞", description: "是否允许用户进行点赞", type: "switch", value: true }, { id: "switch.open_share", label: "开放分享", description: "是否允许用户分享内容", type: "switch", value: true }, { id: "switch.open_view", label: "开放查看", description: "是否允许用户查看内容", type: "switch", value: true } ] } ] }, // 邮件配置 { id: "email", title: "邮件配置", icon: , sections: [ { id: "email-smtp", title: "SMTP设置", description: "邮件服务器的SMTP配置", icon: , fields: [ { id: "email.smtp_host", label: "SMTP主机", description: "SMTP服务器地址", type: "input", value: "", placeholder: "请输入SMTP主机地址" }, { id: "email.smtp_port", label: "SMTP端口", description: "SMTP服务器端口号", type: "number", value: 465, validation: { required: true, min: 1, max: 65535 } }, { id: "email.smtp_user", label: "SMTP用户名", description: "SMTP服务器登录用户名", type: "input", value: "", placeholder: "请输入SMTP用户名" }, { id: "email.smtp_password", label: "SMTP密码", description: "SMTP服务器登录密码", type: "password", value: "", placeholder: "请输入SMTP密码" } ] }, { id: "email-sender", title: "发件人设置", description: "邮件发件人相关信息", icon: , fields: [ { id: "email.smtp_from", label: "发件人地址", description: "系统发送邮件的发件人地址", type: "email", value: "", placeholder: "请输入发件人邮箱" }, { id: "email.smtp_from_name", label: "发件人姓名", description: "系统发送邮件的发件人姓名", type: "input", value: "", placeholder: "请输入发件人姓名" }, { id: "email.smtp_from_email", label: "发件人邮箱", description: "系统发送邮件的发件人邮箱", type: "email", value: "", placeholder: "请输入发件人邮箱" } ] }, { id: "email-templates", title: "邮件模板", description: "邮件模板相关配置", icon: , fields: [ { id: "email.system_template", label: "系统模板", description: "系统邮件的默认模板", type: "select", value: "default", options: [ { label: "默认模板", value: "default" }, { label: "简洁模板", value: "simple" }, { label: "企业模板", value: "enterprise" } ] } ] } ] }, // 系统配置 (Logging + Cache) { id: "system", title: "系统配置", icon: , sections: [ { id: "logging-level", title: "日志级别", description: "系统日志的级别设置", icon: , fields: [ { id: "logging.level", label: "日志级别", description: "系统记录日志的最低级别", type: "select", value: 'info', options: [ { label: "调试", value: "debug" }, { label: "信息", value: "info" }, { label: "警告", value: "warn" }, { label: "错误", value: "error" }, { label: "致命", value: "fatal" } ] } ] }, { id: "logging-files", title: "日志文件管理", description: "日志文件的管理配置", icon: , fields: [ { id: "logging.max_files", label: "最大文件数", description: "保留的日志文件最大数量", type: "number", value: 10, validation: { required: true, min: 1, max: 100 } }, { id: "logging.max_file_size", label: "最大文件大小(MB)", description: "单个日志文件的最大大小", type: "number", value: 10, validation: { required: true, min: 1, max: 10240 } } ] }, { id: "cache-settings", title: "缓存设置", description: "系统缓存的配置参数", icon: , fields: [ { id: "cache.ttl", label: "缓存TTL(秒)", description: "缓存的生存时间,单位为秒", type: "number", value: 3600, validation: { required: true, min: 1, max: 86400 } }, { id: "cache.max_size", label: "最大缓存大小(MB)", description: "缓存的最大内存占用", type: "number", value: 1024, validation: { required: true, min: 1, max: 10000 } } ] } ] } ], // 配置选项 autoSave: false, // 禁用自动保存,使用手动保存 validateOnChange: true, onValidate: (values) => { const result = commonConfigSchema.safeParse(values); return zodErrorsToAdminErrors(result); } }; } // 配置更新Hook export function useConfigUpdate() { const [updateConfigBatch, { loading, error, data }] = useMutation(UPDATE_CONFIG_BATCH); const updateConfigs = async (configs: Record) => { try { // 将配置对象转换为UpdateConfig数组 const updateConfigs: UpdateConfig[] = Object.entries(configs).map(([key, value]) => ({ key, value: String(value), // 直接转换为字符串,避免JSON.stringify添加双引号 description: undefined, category: undefined, is_editable: true })); const result = await updateConfigBatch({ variables: { input: updateConfigs } }); if (result.data?.updateConfigBatch === "successed") { toast.success("配置更新成功!"); return true; } else { toast.error("配置更新失败"); return false; } } catch (err) { console.error("更新配置失败:", err); toast.error("配置更新失败,请检查网络连接"); return false; } }; return { updateConfigs, loading, error, data }; } // 配置保存按钮组件 export function ConfigSaveButton({ onSave, loading = false, disabled = false }: { onSave: () => void; loading?: boolean; disabled?: boolean; }) { return ( ); } // 配置状态指示器 export function ConfigStatusIndicator({ status, message }: { status: 'idle' | 'loading' | 'success' | 'error'; message?: string; }) { if (status === 'idle') return null; return (
{status === 'loading' && ( <> 保存中... )} {status === 'success' && ( <> 保存成功 )} {status === 'error' && ( <> {message || '保存失败'} )}
); }