fix(admin): restore Vite admin source files

This commit is contained in:
2026-08-17 20:02:36 +08:00
parent 8fe3a89c36
commit ac5c0b2dd7
114 changed files with 17272 additions and 0 deletions
@@ -0,0 +1,514 @@
/**
* AKSRT CMS Home Module Schema
*
* 定义每类模块的:
* - 元数据(label / icon / desc)
* - 默认 config
* - 表单字段(用于配置抽屉自动生成 UI)
*
* 字段类型 type:
* - text n-input
* - number n-input-number
* - select n-select (options)
* - radio n-radio-group (options)
* - switch n-switch
* - cats n-select (multiple, 动态加载分类)
* - cat n-select (single, 动态加载分类)
* - textarea n-input type=textarea
*/
export const MODULE_TYPES = [
'hero',
'banner',
'category',
'tabs',
'ranking',
'recent',
'tag_cloud',
'friend_links',
'html',
'hotspot',
'category_recommend_cards',
'text_title',
'button_group',
'spacing',
'faq',
'data_grid',
'highlight_cards',
'partner_marquee',
'product_showcase',
'user',
'more',
]
export const MODULE_LIBRARY = [
{
type: 'hero',
label: 'Hero 首屏',
icon: 'image',
desc: '固定首页骨架:大图轮播首屏。幻灯片内容在「页面&显示 → Hero 轮播」维护;搜索/卡片参数见「顶部多功能组件」。',
defaultConfig: { with_search: true, show_cards: false, card_columns: 4, icon_cards: [] },
fields: [
{ key: 'with_search', type: 'switch', label: '显示搜索覆盖框' },
{ key: 'show_cards', type: 'switch', label: '显示图标卡片覆盖' },
{ key: 'card_columns', type: 'number', label: '卡片列数', min: 2, max: 6 },
],
},
{
type: 'banner',
label: 'Banner 轮播',
icon: 'rectangle',
desc: '固定首页骨架:正文区轮播条。幻灯片内容在「页面&显示 → Banner 轮播」维护。',
defaultConfig: {},
fields: [],
},
{
type: 'category',
label: '分类块',
icon: 'folder',
desc: '指定分类的最新内容网格',
defaultConfig: { cat_id: 0, count: 8, layout: 'card', columns: 4, title: '' },
fields: [
{ key: 'title', type: 'text', label: '标题(留空用分类名)' },
{ key: 'cat_id', type: 'cat', label: '分类' },
{ key: 'count', type: 'number', label: '数量', min: 1, max: 20 },
{ key: 'columns', type: 'number', label: '列数', min: 1, max: 6 },
{
key: 'layout', type: 'select', label: '布局',
options: [
{ label: '卡片', value: 'card' },
{ label: '列表', value: 'list' },
{ label: '瀑布流', value: 'masonry' },
{ label: '资源网格', value: 'grid-cms' },
],
},
],
},
{
type: 'tabs',
label: '分类 Tabs',
icon: 'switcher',
desc: '多分类 Tab 切换',
defaultConfig: { cat_ids: [], count: 8, layout: 'grid-cms', title: '' },
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'cat_ids', type: 'cats', label: '分类列表' },
{ key: 'count', type: 'number', label: '每个 Tab 数量', min: 1, max: 20 },
{
key: 'layout', type: 'select', label: '布局',
options: [
{ label: '卡片', value: 'card' },
{ label: '列表', value: 'list' },
{ label: '瀑布流', value: 'masonry' },
{ label: '资源网格', value: 'grid-cms' },
],
},
],
},
{
type: 'ranking',
label: '排行榜',
icon: 'trophy',
desc: '按下载量 / 阅读量 / 评论数排序(普通文章)',
defaultConfig: { metric: 'downloads', count: 6, title: '' },
fields: [
{ key: 'title', type: 'text', label: '标题' },
{
key: 'metric', type: 'radio', label: '排序依据',
options: [
{ label: '下载量', value: 'downloads' },
{ label: '阅读量', value: 'views' },
{ label: '评论数', value: 'comments' },
],
},
{ key: 'count', type: 'number', label: '数量', min: 1, max: 20 },
],
},
{
type: 'recent',
label: '最新文章',
icon: 'clock',
desc: '按时间倒序的最新文章',
defaultConfig: { count: 6, layout: 'card', title: '' },
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'count', type: 'number', label: '数量', min: 1, max: 20 },
{
key: 'layout', type: 'select', label: '布局',
options: [
{ label: '卡片', value: 'card' },
{ label: '列表', value: 'list' },
{ label: '瀑布流', value: 'masonry' },
{ label: '资源网格', value: 'grid-cms' },
],
},
],
},
{
type: 'tag_cloud',
label: '标签云',
icon: 'tag',
desc: '按使用频率展示热门标签',
defaultConfig: { limit: 30, title: '' },
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'limit', type: 'number', label: '数量', min: 5, max: 100 },
],
},
{
type: 'friend_links',
label: '友情链接',
icon: 'link',
desc: '展示已配置的友链',
defaultConfig: { category: '', title: '' },
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'category', type: 'text', label: '分类筛选(可空)' },
],
},
{
type: 'html',
label: '自定义 HTML',
icon: 'code',
desc: '自由插入 HTML 片段(受 wp_kses_post 清洗)',
defaultConfig: { html: '', title: '' },
fields: [
{ key: 'title', type: 'text', label: '标题(可空)' },
{ key: 'html', type: 'textarea', label: 'HTML 内容', rows: 6 },
],
},
{
type: 'hotspot',
label: '热点推荐',
icon: 'fire',
desc: '文章推荐列表(纯文本,仅桌面端显示)',
defaultConfig: { count: 6, source: 'auto', title: '' },
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'count', type: 'number', label: '数量', min: 3, max: 20 },
{
key: 'source', type: 'select', label: '数据来源',
options: [
{ label: '自动推荐(推荐文章优先)', value: 'auto' },
{ label: '最新文章', value: 'recent' },
{ label: '最热文章(按阅读量)', value: 'views' },
],
},
],
},
{
type: 'category_recommend_cards',
label: '分类推荐卡片',
icon: 'grid',
desc: '4 张分类卡片 2×2 布局,含封面图、浏览量胶囊和文章列表',
defaultConfig: {
title: '分类推荐',
cat_ids: [],
show_views: true,
show_dates: true,
},
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'cat_ids', type: 'cats', label: '分类(按选择顺序对应卡片 1-4)' },
{ key: 'show_views', type: 'switch', label: '显示浏览量胶囊' },
{ key: 'show_dates', type: 'switch', label: '显示发布时间' },
],
},
{
type: 'text_title',
label: '标题文案',
icon: 'font-colors',
desc: '带标题、副标题和可选按钮的文案区块',
defaultConfig: {
title: '',
desc: '',
align: 'left',
style: 'default',
button_text: '',
button_url: '',
button_style: 'primary',
},
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'desc', type: 'textarea', label: '副标题/描述', rows: 2 },
{ key: 'align', type: 'radio', label: '对齐', options: [
{ label: '左对齐', value: 'left' },
{ label: '居中', value: 'center' },
{ label: '右对齐', value: 'right' },
]},
{ key: 'style', type: 'select', label: '样式', options: [
{ label: '默认', value: 'default' },
{ label: '带左边框', value: 'bordered' },
{ label: '带背景', value: 'bg' },
]},
{ key: 'button_text', type: 'text', label: '按钮文字(可空)' },
{ key: 'button_url', type: 'text', label: '按钮链接' },
{ key: 'button_style', type: 'select', label: '按钮样式', options: [
{ label: '主色', value: 'primary' },
{ label: '轮廓', value: 'outline' },
{ label: '文字', value: 'text' },
]},
],
},
{
type: 'button_group',
label: '按钮组',
icon: 'th-large',
desc: '多按钮横向排列,适合快捷入口',
defaultConfig: {
title: '',
buttons: [],
columns: 4,
style: 'card',
},
fields: [
{ key: 'title', type: 'text', label: '标题(可空)' },
{ key: 'columns', type: 'number', label: '每行列数', min: 2, max: 6 },
{ key: 'style', type: 'select', label: '按钮样式', options: [
{ label: '卡片', value: 'card' },
{ label: '图标', value: 'icon' },
{ label: '文字', value: 'text' },
]},
],
},
{
type: 'spacing',
label: '间距分隔',
icon: 'swap',
desc: '模块间间距或分隔线',
defaultConfig: {
height: 40,
divider: false,
divider_style: 'solid',
},
fields: [
{ key: 'height', type: 'number', label: '高度 (px)', min: 0, max: 200 },
{ key: 'divider', type: 'switch', label: '显示分隔线' },
{ key: 'divider_style', type: 'select', label: '分隔线样式', options: [
{ label: '实线', value: 'solid' },
{ label: '虚线', value: 'dashed' },
{ label: '点线', value: 'dotted' },
]},
],
},
{
type: 'faq',
label: '常见问题',
icon: 'question-circle',
desc: '折叠式 FAQ 列表',
defaultConfig: {
title: '常见问题',
items: [],
style: 'accordion',
},
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'style', type: 'radio', label: '样式', options: [
{ label: '手风琴', value: 'accordion' },
{ label: '卡片', value: 'card' },
]},
],
},
{
type: 'data_grid',
label: '数据网格',
icon: 'table',
desc: '多列数据卡片展示(统计、特征等)',
defaultConfig: {
title: '',
columns: 4,
items: [],
style: 'number',
},
fields: [
{ key: 'title', type: 'text', label: '标题(可空)' },
{ key: 'columns', type: 'number', label: '列数', min: 2, max: 6 },
{ key: 'style', type: 'select', label: '样式', options: [
{ label: '数字突出', value: 'number' },
{ label: '图标突出', value: 'icon' },
{ label: '简洁', value: 'minimal' },
]},
],
},
{
type: 'highlight_cards',
label: '高亮卡片',
icon: 'star',
desc: '带配色的特色卡片网格',
defaultConfig: {
title: '',
columns: 3,
cards: [],
},
fields: [
{ key: 'title', type: 'text', label: '标题(可空)' },
{ key: 'columns', type: 'number', label: '列数', min: 2, max: 4 },
],
},
{
type: 'partner_marquee',
label: '合作伙伴',
icon: 'handshake',
desc: 'Logo 滚动展示(合作伙伴/品牌墙)',
defaultConfig: {
title: '合作伙伴',
logos: [],
speed: 30,
pause_on_hover: true,
columns: 5,
},
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'speed', type: 'number', label: '滚动速度', min: 10, max: 100 },
{ key: 'pause_on_hover', type: 'switch', label: '鼠标悬停暂停' },
{ key: 'columns', type: 'number', label: '可见列数', min: 3, max: 8 },
],
},
{
type: 'product_showcase',
label: '产品展示',
icon: 'shopping-bag',
desc: '产品/商品卡片网格(为商城 Phase 预留)',
defaultConfig: {
title: '产品展示',
columns: 3,
count: 6,
source: 'manual',
show_price: true,
show_button: true,
},
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'columns', type: 'number', label: '列数', min: 2, max: 4 },
{ key: 'count', type: 'number', label: '数量', min: 1, max: 12 },
{ key: 'source', type: 'select', label: '数据来源', options: [
{ label: '手动配置', value: 'manual' },
{ label: '最新商品', value: 'latest' },
{ label: '热门商品', value: 'popular' },
]},
{ key: 'show_price', type: 'switch', label: '显示价格' },
{ key: 'show_button', type: 'switch', label: '显示购买按钮' },
],
},
{
type: 'user',
label: '用户卡片',
icon: 'user',
desc: '推荐用户卡片(头像、简介、关注按钮)',
defaultConfig: {
title: '推荐用户',
user_ids: [],
count: 4,
columns: 4,
order: 'recent',
show_stats: true,
},
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'count', type: 'number', label: '用户数量', min: 1, max: 12 },
{ key: 'columns', type: 'number', label: '列数', min: 2, max: 6 },
{ key: 'order', type: 'select', label: '排序', options: [
{ label: '最近注册', value: 'recent' },
{ label: '文章最多', value: 'posts' },
{ label: '手动指定', value: 'manual' },
]},
{ key: 'show_stats', type: 'switch', label: '显示统计数据' },
],
},
{
type: 'more',
label: '发现更多',
icon: 'th',
desc: '分类卡片网格(封面、文章数、最近文章)',
defaultConfig: {
title: '发现更多',
cat_ids: [],
count: 6,
columns: 3,
show_post_count: true,
show_latest_posts: true,
latest_count: 5,
},
fields: [
{ key: 'title', type: 'text', label: '标题' },
{ key: 'count', type: 'number', label: '分类数量', min: 1, max: 12 },
{ key: 'columns', type: 'number', label: '列数', min: 2, max: 4 },
{ key: 'show_post_count', type: 'switch', label: '显示文章数' },
{ key: 'show_latest_posts', type: 'switch', label: '显示最近文章' },
{ key: 'latest_count', type: 'number', label: '最近文章数', min: 1, max: 10 },
],
},
]
export function getModuleMeta(type) {
return MODULE_LIBRARY.find(m => m.type === type) || null
}
export function makeDefaultModule(type) {
const meta = getModuleMeta(type)
if (!meta) return null
return {
type,
config: JSON.parse(JSON.stringify(meta.defaultConfig || {})),
}
}
export const PRESET_TEMPLATES = [
{
key: 'resource_standard',
label: '资源站标准',
desc: 'Hero(固定骨架)+ Tabs + 最新文章 + 下载排行',
modules: [
{ type: 'hero', config: {} },
{ type: 'tabs', config: { count: 8, layout: 'grid-cms' } },
{ type: 'recent', config: { count: 8, layout: 'grid-cms' } },
{ type: 'ranking', config: { metric: 'downloads', count: 6 } },
],
},
{
key: 'news',
label: '资讯站',
desc: 'Banner(固定骨架)+ 多个分类块 + 标签云',
modules: [
{ type: 'banner', config: {} },
{ type: 'category', config: { count: 8, columns: 4, layout: 'card' } },
{ type: 'category', config: { count: 8, columns: 4, layout: 'card' } },
{ type: 'tag_cloud', config: { limit: 30 } },
],
},
{
key: 'mixed',
label: '混合站',
desc: 'Hero(固定骨架)+ 最新文章 + 多个分类块',
modules: [
{ type: 'hero', config: {} },
{ type: 'recent', config: { count: 6, layout: 'card' } },
{ type: 'category', config: { count: 6, columns: 3, layout: 'card' } },
{ type: 'category', config: { count: 6, columns: 3, layout: 'card' } },
],
},
{
key: 'landing',
label: '落地页',
desc: 'Hero + 标题 + 高亮卡片 + FAQ + 按钮组',
modules: [
{ type: 'hero', config: {} },
{ type: 'text_title', config: { title: '为什么选择我们', align: 'center', style: 'default' } },
{ type: 'highlight_cards', config: { columns: 3 } },
{ type: 'spacing', config: { height: 40 } },
{ type: 'faq', config: { title: '常见问题' } },
{ type: 'button_group', config: { columns: 3, style: 'card' } },
],
},
{
key: 'corporate',
label: '企业站',
desc: 'Hero + 数据网格 + 产品展示 + 合作伙伴',
modules: [
{ type: 'hero', config: {} },
{ type: 'data_grid', config: { title: '核心数据', columns: 4, style: 'number' } },
{ type: 'product_showcase', config: { title: '产品展示', columns: 3 } },
{ type: 'partner_marquee', config: { title: '合作伙伴', speed: 30 } },
],
},
]
+40
View File
@@ -0,0 +1,40 @@
export function openMediaPicker(options = {}) {
const wpMedia = window.wp?.media
if (!wpMedia) {
throw new Error('当前后台未加载 WordPress 媒体库。')
}
const frame = wpMedia({
title: options.title || '选择图片',
button: {
text: options.buttonText || '使用此图片',
},
library: {
type: options.type || 'image',
},
multiple: false,
})
return new Promise((resolve, reject) => {
frame.on('select', () => {
const attachment = frame.state().get('selection').first()?.toJSON()
if (!attachment?.url) {
reject(new Error('未选择有效的媒体资源。'))
return
}
resolve(attachment)
})
frame.on('close', () => {
const hasSelection = frame.state().get('selection').length > 0
if (!hasSelection) {
resolve(null)
}
})
frame.open()
})
}