559 lines
25 KiB
TypeScript
559 lines
25 KiB
TypeScript
"use client";
|
|
|
|
import React from "react";
|
|
import {
|
|
Settings,
|
|
Globe,
|
|
Palette,
|
|
Bell,
|
|
Shield,
|
|
Users,
|
|
Database,
|
|
Mail,
|
|
FileText,
|
|
MessageSquare,
|
|
Clock,
|
|
AlertTriangle,
|
|
Save,
|
|
RefreshCw,
|
|
Download,
|
|
Upload,
|
|
Server,
|
|
HardDrive
|
|
} from "lucide-react";
|
|
import { AdminPanelConfig } from "@/types/admin-panel";
|
|
import { commonConfigSchema, zodErrorsToAdminErrors } from "@/lib/config-zod";
|
|
// import { SiteOpsConfigType } from "@/types/site-config";
|
|
import { SiteOpsConfigType } from "@/types/site-config";
|
|
import { ConfigItemType } from "@/hooks/use-site-config";
|
|
|
|
// 创建基于后端数据的动态管理面板配置
|
|
export function createDynamicAdminConfig(
|
|
data?: SiteOpsConfigType,
|
|
onSave?: (values: Record<string, any>) => Promise<void>,
|
|
onExport?: () => Promise<void>,
|
|
onImport?: (file: File) => Promise<void>,
|
|
configs?: ConfigItemType[]
|
|
): AdminPanelConfig {
|
|
|
|
// 从后端数据获取初始值(安全访问嵌套属性)
|
|
const getInitialValues = () => {
|
|
if (!data) return {};
|
|
|
|
// helpers
|
|
const toDateTimeLocal = (value?: any) => {
|
|
if (!value) return "";
|
|
const d = new Date(value);
|
|
if (isNaN(d.getTime())) return "";
|
|
return d.toISOString().slice(0, 16);
|
|
};
|
|
|
|
const bannerText = data.notice_maintenance?.banner?.text || {
|
|
"zh-CN": "欢迎使用MMAP系统",
|
|
"en": "Welcome to MMAP System"
|
|
};
|
|
const maintenanceMsg = data.notice_maintenance?.maintenance_window?.message || {
|
|
"zh-CN": "系统维护中,请稍后再试",
|
|
"en": "System maintenance in progress"
|
|
};
|
|
const workingHours = data.docs_support?.channels?.working_hours || {
|
|
"zh-CN": "周一至周五 9:00-18:00",
|
|
"en": "Mon-Fri 9:00-18:00"
|
|
};
|
|
|
|
return {
|
|
// 站点信息
|
|
'site.info.name': data.site?.info?.name || "MMAP System",
|
|
'site.info.locale_default': data.site?.info?.locale_default || "zh-CN",
|
|
'site.info.locales_supported': data.site?.info?.locales_supported || ["zh-CN", "en"],
|
|
|
|
// 品牌配置
|
|
'site.brand.logo_url': data.site?.brand?.logo_url || "/images/logo.png",
|
|
'site.brand.primary_color': data.site?.brand?.primary_color || "#3B82F6",
|
|
'site.brand.dark_mode_default': data.site?.brand?.dark_mode_default || false,
|
|
|
|
// 页脚链接
|
|
'site.footer_links': data.site?.footer_links || [],
|
|
|
|
// 横幅公告
|
|
'notice.banner.enabled': data.notice_maintenance?.banner?.enabled || false,
|
|
'notice.banner.text': JSON.stringify(bannerText, null, 2),
|
|
|
|
// 维护窗口
|
|
'maintenance.window.enabled': data.notice_maintenance?.maintenance_window?.enabled || false,
|
|
'maintenance.window.start_time': toDateTimeLocal(data.notice_maintenance?.maintenance_window?.start_time),
|
|
'maintenance.window.end_time': toDateTimeLocal(data.notice_maintenance?.maintenance_window?.end_time),
|
|
'maintenance.window.message': JSON.stringify(maintenanceMsg, null, 2),
|
|
|
|
// 弹窗公告
|
|
'modal.announcements': data.notice_maintenance?.modal_announcements || [],
|
|
|
|
// 文档链接
|
|
'docs.links': data.docs_support?.links || [],
|
|
|
|
// 支持渠道
|
|
'support.channels.email': data.docs_support?.channels?.email || "support@mapp.com",
|
|
'support.channels.ticket_system': data.docs_support?.channels?.ticket_system || "/support/tickets",
|
|
'support.channels.chat_groups': data.docs_support?.channels?.chat_groups || [],
|
|
'support.channels.working_hours': JSON.stringify(workingHours, null, 2),
|
|
|
|
// 运营功能开关
|
|
'ops.features.registration_enabled': data.ops?.features?.registration_enabled ?? true,
|
|
'ops.features.invite_code_required': data.ops?.features?.invite_code_required ?? false,
|
|
'ops.features.email_verification': data.ops?.features?.email_verification ?? false,
|
|
|
|
// 运营限制
|
|
'ops.limits.max_users': data.ops?.limits?.max_users || 1000,
|
|
'ops.limits.max_invite_codes_per_user': data.ops?.limits?.max_invite_codes_per_user || 10,
|
|
'ops.limits.session_timeout_hours': data.ops?.limits?.session_timeout_hours || 24,
|
|
|
|
// 通知配置
|
|
'ops.notifications.welcome_email': data.ops?.notifications?.welcome_email ?? true,
|
|
'ops.notifications.system_announcements': data.ops?.notifications?.system_announcements ?? true,
|
|
'ops.notifications.maintenance_alerts': data.ops?.notifications?.maintenance_alerts ?? true,
|
|
|
|
// —— 通用配置(映射/默认)——
|
|
// 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,
|
|
|
|
// Switches
|
|
'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: <RefreshCw className="h-4 w-4" />,
|
|
variant: "outline",
|
|
onClick: () => window.location.reload()
|
|
},
|
|
{
|
|
id: "export",
|
|
label: "导出配置",
|
|
icon: <Download className="h-4 w-4" />,
|
|
variant: "outline",
|
|
onClick: onExport || (() => console.log("导出配置"))
|
|
},
|
|
{
|
|
id: "import",
|
|
label: "导入配置",
|
|
icon: <Upload className="h-4 w-4" />,
|
|
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: [
|
|
// 通用配置(基于 configs 动态生成)
|
|
{
|
|
id: "common",
|
|
title: "通用配置",
|
|
icon: <Settings className="h-4 w-4" />,
|
|
sections: []
|
|
},
|
|
// 站点设置
|
|
{
|
|
id: "site",
|
|
title: "站点设置",
|
|
icon: <Globe className="h-4 w-4" />,
|
|
sections: [
|
|
{
|
|
id: "site-info",
|
|
title: "基本信息",
|
|
description: "网站基本信息和国际化配置",
|
|
icon: <Settings className="h-5 w-5" />,
|
|
fields: [
|
|
{
|
|
id: "site.info.name",
|
|
label: "网站名称",
|
|
description: "显示在浏览器标题栏的网站名称",
|
|
type: "input",
|
|
value: data?.site?.info?.name || "MMAP System",
|
|
placeholder: "请输入网站名称",
|
|
validation: {
|
|
required: true,
|
|
minLength: 2,
|
|
maxLength: 50
|
|
}
|
|
},
|
|
{
|
|
id: "site.info.locale_default",
|
|
label: "默认语言",
|
|
description: "网站的默认显示语言",
|
|
type: "select",
|
|
value: data?.site?.info?.locale_default || "zh-CN",
|
|
options: [
|
|
{ label: "简体中文", value: "zh-CN" },
|
|
{ label: "English", value: "en" }
|
|
],
|
|
validation: {
|
|
required: true
|
|
}
|
|
},
|
|
{
|
|
id: "site.info.locales_supported",
|
|
label: "支持的语言",
|
|
description: "用户可以选择的所有语言选项",
|
|
type: "select",
|
|
value: data?.site?.info?.locales_supported || ["zh-CN", "en"],
|
|
multiple: true,
|
|
options: [
|
|
{ label: "简体中文", value: "zh-CN" },
|
|
{ label: "English", value: "en" },
|
|
{ label: "繁體中文", value: "zh-TW" },
|
|
{ label: "日本語", value: "ja" },
|
|
{ label: "한국어", value: "ko" }
|
|
]
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: "site-brand",
|
|
title: "品牌设置",
|
|
description: "网站品牌形象和主题配置",
|
|
icon: <Palette className="h-5 w-5" />,
|
|
fields: [
|
|
{
|
|
id: "site.brand.logo_url",
|
|
label: "Logo地址",
|
|
description: "网站Logo图片的URL地址",
|
|
type: "input",
|
|
value: data?.site?.brand?.logo_url || "/images/logo.png",
|
|
placeholder: "请输入Logo URL"
|
|
},
|
|
{
|
|
id: "site.brand.primary_color",
|
|
label: "主题色",
|
|
description: "网站的主要色彩,用于按钮、链接等",
|
|
type: "color",
|
|
value: data?.site?.brand?.primary_color || "#3B82F6"
|
|
},
|
|
{
|
|
id: "site.brand.dark_mode_default",
|
|
label: "默认深色模式",
|
|
description: "新用户访问时是否默认使用深色模式",
|
|
type: "switch",
|
|
value: data?.site?.brand?.dark_mode_default || false
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
|
|
// 公告维护
|
|
{
|
|
id: "notice",
|
|
title: "公告维护",
|
|
icon: <Bell className="h-4 w-4" />,
|
|
sections: [
|
|
{
|
|
id: "banner-notice",
|
|
title: "横幅公告",
|
|
description: "网站顶部横幅公告设置",
|
|
icon: <Bell className="h-5 w-5" />,
|
|
fields: [
|
|
{
|
|
id: "notice.banner.enabled",
|
|
label: "启用横幅公告",
|
|
description: "是否在网站顶部显示横幅公告",
|
|
type: "switch",
|
|
value: data?.notice_maintenance?.banner?.enabled || false
|
|
},
|
|
{
|
|
id: "notice.banner.text",
|
|
label: "公告内容",
|
|
description: "多语言公告文本",
|
|
type: "textarea",
|
|
rows: 6,
|
|
value: JSON.stringify(data?.notice_maintenance?.banner?.text || {
|
|
"zh-CN": "欢迎使用MMAP系统",
|
|
"en": "Welcome to MMAP System"
|
|
}, null, 2),
|
|
showWhen: (values) => values["notice.banner.enabled"] === true
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: "maintenance-window",
|
|
title: "维护窗口",
|
|
description: "系统维护时间配置",
|
|
icon: <AlertTriangle className="h-5 w-5" />,
|
|
fields: [
|
|
{
|
|
id: "maintenance.window.enabled",
|
|
label: "启用维护模式",
|
|
description: "启用后系统将显示维护页面",
|
|
type: "switch",
|
|
value: data?.notice_maintenance?.maintenance_window?.enabled || false
|
|
},
|
|
{
|
|
id: "maintenance.window.start_time",
|
|
label: "维护开始时间",
|
|
description: "维护窗口的开始时间",
|
|
type: "datetime-local",
|
|
value: (data?.notice_maintenance?.maintenance_window?.start_time ? new Date(data.notice_maintenance.maintenance_window.start_time).toISOString().slice(0, 16) : ""),
|
|
showWhen: (values) => values["maintenance.window.enabled"] === true
|
|
},
|
|
{
|
|
id: "maintenance.window.end_time",
|
|
label: "维护结束时间",
|
|
description: "维护窗口的结束时间",
|
|
type: "datetime-local",
|
|
value: (data?.notice_maintenance?.maintenance_window?.end_time ? new Date(data.notice_maintenance.maintenance_window.end_time).toISOString().slice(0, 16) : ""),
|
|
showWhen: (values) => values["maintenance.window.enabled"] === true
|
|
},
|
|
{
|
|
id: "maintenance.window.message",
|
|
label: "维护提示信息",
|
|
description: "维护期间显示给用户的多语言提示信息",
|
|
type: "textarea",
|
|
rows: 6,
|
|
value: JSON.stringify(data?.notice_maintenance?.maintenance_window?.message || {
|
|
"zh-CN": "系统维护中,请稍后再试",
|
|
"en": "System maintenance in progress"
|
|
}, null, 2),
|
|
showWhen: (values) => values["maintenance.window.enabled"] === true
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
|
|
// 运营配置
|
|
{
|
|
id: "operations",
|
|
title: "运营配置",
|
|
icon: <Users className="h-4 w-4" />,
|
|
sections: [
|
|
{
|
|
id: "feature-switches",
|
|
title: "功能开关",
|
|
description: "控制各项功能的启用状态",
|
|
icon: <Shield className="h-5 w-5" />,
|
|
fields: [
|
|
{
|
|
id: "ops.features.registration_enabled",
|
|
label: "开放注册",
|
|
description: "是否允许新用户注册",
|
|
type: "switch",
|
|
value: data?.ops?.features?.registration_enabled ?? true
|
|
},
|
|
{
|
|
id: "ops.features.invite_code_required",
|
|
label: "需要邀请码",
|
|
description: "注册时是否需要邀请码",
|
|
type: "switch",
|
|
value: data?.ops?.features?.invite_code_required ?? false,
|
|
showWhen: (values) => values["ops.features.registration_enabled"] === true
|
|
},
|
|
{
|
|
id: "ops.features.email_verification",
|
|
label: "邮箱验证",
|
|
description: "注册后是否需要验证邮箱",
|
|
type: "switch",
|
|
value: data?.ops?.features?.email_verification ?? false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: "limits-config",
|
|
title: "限制配置",
|
|
description: "系统资源和使用限制",
|
|
icon: <Database className="h-5 w-5" />,
|
|
fields: [
|
|
{
|
|
id: "ops.limits.max_users",
|
|
label: "最大用户数",
|
|
description: "系统允许的最大用户数量",
|
|
type: "number",
|
|
value: data?.ops?.limits?.max_users || 1000,
|
|
validation: {
|
|
required: true,
|
|
min: 1,
|
|
max: 100000
|
|
}
|
|
},
|
|
{
|
|
id: "ops.limits.max_invite_codes_per_user",
|
|
label: "用户最大邀请码数",
|
|
description: "每个用户最多可以生成的邀请码数量",
|
|
type: "number",
|
|
value: data?.ops?.limits?.max_invite_codes_per_user || 10,
|
|
validation: {
|
|
required: true,
|
|
min: 0,
|
|
max: 100
|
|
}
|
|
},
|
|
{
|
|
id: "ops.limits.session_timeout_hours",
|
|
label: "会话超时时间(小时)",
|
|
description: "用户会话的超时时间",
|
|
type: "number",
|
|
value: data?.ops?.limits?.session_timeout_hours || 24,
|
|
validation: {
|
|
required: true,
|
|
min: 1,
|
|
max: 720
|
|
}
|
|
}
|
|
]
|
|
},
|
|
{
|
|
id: "notifications-config",
|
|
title: "通知配置",
|
|
description: "系统通知和提醒设置",
|
|
icon: <Mail className="h-5 w-5" />,
|
|
fields: [
|
|
{
|
|
id: "ops.notifications.welcome_email",
|
|
label: "发送欢迎邮件",
|
|
description: "新用户注册后是否发送欢迎邮件",
|
|
type: "switch",
|
|
value: data?.ops?.notifications?.welcome_email ?? true
|
|
},
|
|
{
|
|
id: "ops.notifications.system_announcements",
|
|
label: "系统公告通知",
|
|
description: "是否发送系统公告通知",
|
|
type: "switch",
|
|
value: data?.ops?.notifications?.system_announcements ?? true
|
|
},
|
|
{
|
|
id: "ops.notifications.maintenance_alerts",
|
|
label: "维护提醒",
|
|
description: "系统维护前是否发送提醒通知",
|
|
type: "switch",
|
|
value: data?.ops?.notifications?.maintenance_alerts ?? true
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
|
|
// 支持文档
|
|
{
|
|
id: "support",
|
|
title: "支持文档",
|
|
icon: <FileText className="h-4 w-4" />,
|
|
sections: [
|
|
{
|
|
id: "support-channels",
|
|
title: "支持渠道",
|
|
description: "用户支持和服务渠道配置",
|
|
icon: <MessageSquare className="h-5 w-5" />,
|
|
fields: [
|
|
{
|
|
id: "support.channels.email",
|
|
label: "支持邮箱",
|
|
description: "用户联系支持的邮箱地址",
|
|
type: "email",
|
|
value: data?.docs_support?.channels?.email || "support@mapp.com",
|
|
validation: {
|
|
required: true,
|
|
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
}
|
|
},
|
|
{
|
|
id: "support.channels.ticket_system",
|
|
label: "工单系统地址",
|
|
description: "用户提交工单的系统地址",
|
|
type: "input",
|
|
value: data?.docs_support?.channels?.ticket_system || "/support/tickets"
|
|
},
|
|
{
|
|
id: "support.channels.working_hours",
|
|
label: "工作时间",
|
|
description: "多语言的工作时间说明",
|
|
type: "textarea",
|
|
rows: 6,
|
|
value: JSON.stringify(data?.docs_support?.channels?.working_hours || {
|
|
"zh-CN": "周一至周五 9:00-18:00",
|
|
"en": "Mon-Fri 9:00-18:00"
|
|
}, null, 2)
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
],
|
|
|
|
// 配置选项
|
|
autoSave: false, // 禁用自动保存,使用手动保存
|
|
validateOnChange: true,
|
|
onValidate: (values) => {
|
|
const result = commonConfigSchema.safeParse(values);
|
|
return zodErrorsToAdminErrors(result);
|
|
}
|
|
};
|
|
} |