@@ -101,6 +110,7 @@ const collapsed = ref(false)
const pageError = ref(null)
const isMobile = ref(false)
const drawerActive = ref(false)
+const themeVersion = window.aksrtAdminData?.version || '9.0'
function checkMobile() {
isMobile.value = window.innerWidth < 768
@@ -205,7 +215,7 @@ function handleMenuClick(key) {
display: flex;
align-items: center;
justify-content: center;
- height: 60px;
+ height: 72px;
gap: 10px;
border-bottom: 1px solid var(--n-border-color, #efeff5);
}
@@ -222,7 +232,7 @@ function handleMenuClick(key) {
width: 28px;
height: 28px;
border-radius: 8px;
- background: #18a058;
+ background: linear-gradient(135deg, #65bff7 10%, #0d67b9 100%);
color: #fff;
font-size: 12px;
font-weight: 700;
@@ -237,7 +247,71 @@ function handleMenuClick(key) {
}
.aksrt-admin-content__inner {
- padding: 24px 28px;
+ padding: 30px;
+}
+
+.aksrt-csf-shell {
+ max-width: 1380px;
+ margin: 20px auto;
+ overflow: hidden;
+ border-radius: 8px;
+ box-shadow: 0 0 20px rgba(82, 82, 82, .1);
+}
+
+.aksrt-csf-header {
+ position: relative;
+ display: flex;
+ min-height: 108px;
+ align-items: center;
+ justify-content: space-between;
+ overflow: hidden;
+ padding: 22px 34px;
+ color: #fff;
+ background: linear-gradient(135deg, #f97794 10%, #623aa2 100%);
+}
+
+.aksrt-csf-header::before {
+ position: absolute;
+ left: 10%;
+ bottom: -25px;
+ content: 'AKSRT';
+ color: rgba(255, 255, 255, .05);
+ font-size: 100px;
+ font-weight: 800;
+ font-style: oblique;
+ transform: rotate(-5deg) scaleX(1.5);
+}
+
+.aksrt-csf-header h1,
+.aksrt-csf-header p {
+ position: relative;
+ z-index: 1;
+ margin: 0;
+ color: #fff;
+}
+
+.aksrt-csf-header h1 {
+ font-size: 26px;
+}
+
+.aksrt-csf-header h1 small {
+ margin-left: 8px;
+ font-size: 13px;
+ font-weight: 400;
+}
+
+.aksrt-csf-header p {
+ margin-top: 7px;
+ opacity: .78;
+}
+
+.aksrt-csf-version {
+ position: relative;
+ z-index: 1;
+ padding: 5px 12px;
+ border: 1px solid rgba(255, 255, 255, .3);
+ border-radius: 20px;
+ background: rgba(255, 255, 255, .1);
}
.aksrt-admin-mobile {
diff --git a/assets/admin/src/api/index.js b/assets/admin/src/api/index.js
index 2dad120a..be925358 100644
--- a/assets/admin/src/api/index.js
+++ b/assets/admin/src/api/index.js
@@ -19,12 +19,11 @@ function normalizeDomainKey(domain) {
/**
* Join REST base + endpoint correctly for both pretty and plain permalinks.
*
- * Pretty: https://site/wp-json/aksrt/v1 + /banners?kind=x
- * → https://site/wp-json/aksrt/v1/banners?kind=x
+ * Pretty: https://site/wp-json/aksrt/v1 + /settings/schema/global/common
+ * → https://site/wp-json/aksrt/v1/settings/schema/global/common
*
- * Plain: https://site/index.php?rest_route=/aksrt/v1 + /banners?kind=x
- * → https://site/index.php?rest_route=/aksrt/v1/banners&kind=x
- * (must NOT produce rest_route=/aksrt/v1/banners?kind=x)
+ * Plain: https://site/index.php?rest_route=/aksrt/v1 + /settings/schema/global/common
+ * → https://site/index.php?rest_route=/aksrt/v1/settings/schema/global/common
*
* @param {string} baseUrl
* @param {string} endpoint path starting with /, may include ?query
diff --git a/assets/admin/src/api/modules/global.js b/assets/admin/src/api/modules/global.js
index f4095d35..a3f26a98 100644
--- a/assets/admin/src/api/modules/global.js
+++ b/assets/admin/src/api/modules/global.js
@@ -7,9 +7,6 @@ export const globalApiMethods = {
saveMailSettings(data) { return this.request('/settings/mail', { method: 'POST', body: JSON.stringify(data) }) },
testMail(to) { return this.request('/mail/test', { method: 'POST', body: JSON.stringify({ to }) }) },
- getFooterSettings() { return this.request('/settings/footer') },
- saveFooterSettings(data) { return this.request('/settings/footer', { method: 'POST', body: JSON.stringify(data) }) },
-
getFooterTabbarSettings() { return this.request('/settings/footer-tabbar') },
saveFooterTabbarSettings(data) { return this.request('/settings/footer-tabbar', { method: 'POST', body: JSON.stringify(data) }) },
reorderFooterTabbar(ids) { return this.request('/settings/footer-tabbar/reorder', { method: 'POST', body: JSON.stringify({ ids }) }) },
diff --git a/assets/admin/src/api/modules/page-display.js b/assets/admin/src/api/modules/page-display.js
index ef29ca6e..5a071453 100644
--- a/assets/admin/src/api/modules/page-display.js
+++ b/assets/admin/src/api/modules/page-display.js
@@ -3,10 +3,6 @@ export const pageDisplayApiMethods = {
* 页面&显示 (Page Display)
* ================================================================ */
- getHomepageSettings() { return this.request('/settings/homepage') },
- saveHomepageSettings(data) { return this.request('/settings/homepage', { method: 'POST', body: JSON.stringify(data) }) },
- getHomepageCategories() { return this.request('/homepage/categories') },
-
getCategoryRecommendSettings() { return this.request('/settings/category-recommend') },
saveCategoryRecommendSettings(data) { return this.request('/settings/category-recommend', { method: 'POST', body: JSON.stringify(data) }) },
getCategories(taxonomy = 'category') {
@@ -16,13 +12,9 @@ export const pageDisplayApiMethods = {
updateCategoryMeta(id, data) { return this.request(`/categories/${id}/meta`, { method: 'POST', body: JSON.stringify(data) }) },
searchUsers(search = '', number = 20) { return this.request(`/users/search?search=${encodeURIComponent(search)}&number=${number}`) },
- getBanners() { return this.request('/banners') },
- createBanner(data) { return this.request('/banners', { method: 'POST', body: JSON.stringify(data) }) },
- updateBanner(id, data) { return this.request(`/banners/${id}`, { method: 'PUT', body: JSON.stringify(data) }) },
- deleteBanner(id) { return this.request(`/banners/${id}`, { method: 'DELETE' }) },
-
- getHomepageBanners() { return this.getBanners() },
- createHomepageBanner(data) { return this.createBanner(data) },
- updateHomepageBanner(id, data) { return this.updateBanner(id, data) },
- deleteHomepageBanner(id) { return this.deleteBanner(id) },
+ searchPageDisplayOptions(source, query = '', include = []) {
+ const params = new URLSearchParams({ query })
+ include.forEach(value => params.append('include[]', value))
+ return this.request(`/settings/schema/page_display/search/${encodeURIComponent(source)}?${params}`)
+ },
}
diff --git a/assets/admin/src/components/form/AksField.vue b/assets/admin/src/components/form/AksField.vue
index 3318d8b7..75f63a5e 100644
--- a/assets/admin/src/components/form/AksField.vue
+++ b/assets/admin/src/components/form/AksField.vue
@@ -1,6 +1,6 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+ {{ item.label }}
+
+ ↑
+ ↓
+
+
+
+
+
+
-
+
@@ -392,6 +454,7 @@
- {{ schema.addText || '添加一项' }}
+ {{ schema.button_title || schema.addText || '添加一项' }}
-
+
@@ -488,11 +551,11 @@
size="small"
dashed
block
- :disabled="schema.disabled"
+ :disabled="schema.disabled || reachedRepeaterMaximum"
@click="openRepeaterModal(-1)"
>
- {{ schema.addText || '添加一项' }}
+ {{ schema.button_title || schema.addText || '添加一项' }}
Array.isArray(props.modelValue) ? props.modelValue.length : 0)
+const reachedRepeaterMinimum = computed(() => repeaterLength.value <= Number(props.schema.min || 0))
+const reachedRepeaterMaximum = computed(() => Number(props.schema.max || 0) > 0 && repeaterLength.value >= Number(props.schema.max))
+
function fieldsetValue(field) {
const current = props.modelValue && typeof props.modelValue === 'object' && !Array.isArray(props.modelValue)
? props.modelValue
@@ -584,12 +651,94 @@ const normalizedOptions = computed(() => {
return opts.map(opt => {
if (typeof opt === 'string') return { label: opt, value: opt }
if (typeof opt === 'object' && opt !== null) {
- return { label: opt.label ?? opt.name ?? opt.value, value: opt.value ?? opt.label ?? opt.name }
+ return { ...opt, label: opt.label ?? opt.name ?? opt.value, value: opt.value ?? opt.label ?? opt.name }
}
return { label: String(opt), value: opt }
})
})
+const visibleNestedFields = computed(() => (props.schema.fields || []).filter(field => matchDependency(field.dependsOn, props.modelValue)))
+const linkTargetOptions = [{ label: '当前窗口', value: '' }, { label: '当前窗口', value: '_self' }, { label: '新窗口', value: '_blank' }]
+
+function matchDependency(rule, sourceValue) {
+ if (!rule) return true
+ const source = sourceValue && typeof sourceValue === 'object' ? sourceValue : {}
+ if (rule.all) return rule.all.every(item => matchDependency(item, source))
+ if (rule.any) return rule.any.some(item => matchDependency(item, source))
+ const value = source[rule.key]
+ if (rule.operator === 'truthy') return !!value
+ if (rule.operator === 'falsy') return !value
+ if (rule.operator === 'not_empty') return Array.isArray(value) ? value.length > 0 : value !== '' && value != null
+ if (rule.operator === 'empty') return Array.isArray(value) ? value.length === 0 : value === '' || value == null
+ if (rule.operator === 'eq') return value === rule.value
+ if (rule.operator === 'neq') return value !== rule.value
+ return rule.value === undefined || value === rule.value
+}
+
+function updateLink(key, value) {
+ emit('update:modelValue', { ...(props.modelValue || {}), [key]: value })
+}
+
+function selectedOptionLabel(options, value) {
+ return options.find(option => option.value === value)?.label || String(value)
+}
+
+function moveSelectedValue(index, delta) {
+ if (!Array.isArray(props.modelValue)) return
+ const target = index + delta
+ if (target < 0 || target >= props.modelValue.length) return
+ const values = [...props.modelValue]
+ ;[values[index], values[target]] = [values[target], values[index]]
+ emit('update:modelValue', values)
+}
+
+const sortableItems = computed(() => {
+ const definitions = new Map((props.schema.items || []).map(item => [item.key, item]))
+ const order = Object.keys(props.modelValue || {}).filter(key => definitions.has(key))
+ for (const key of definitions.keys()) if (!order.includes(key)) order.push(key)
+ return order.map(key => definitions.get(key))
+})
+
+function updateSortable(itemKey, fieldKey, value) {
+ const current = props.modelValue || {}
+ emit('update:modelValue', { ...current, [itemKey]: { ...(current[itemKey] || {}), [fieldKey]: value } })
+}
+
+function moveSortable(index, delta) {
+ const items = [...sortableItems.value]
+ const target = index + delta
+ if (target < 0 || target >= items.length) return
+ ;[items[index], items[target]] = [items[target], items[index]]
+ const current = props.modelValue || {}
+ emit('update:modelValue', Object.fromEntries(items.map(item => [item.key, current[item.key] || {}])))
+}
+
+const asyncOptions = ref([])
+const asyncLoading = ref(false)
+let asyncTimer = null
+
+async function loadAsyncOptions(query = '') {
+ if (props.schema.source === 'publish-types') {
+ asyncOptions.value = normalizedOptions.value
+ return
+ }
+ asyncLoading.value = true
+ try {
+ const selected = Array.isArray(props.modelValue) ? props.modelValue : (props.modelValue ? [props.modelValue] : [])
+ const response = await api.searchPageDisplayOptions(props.schema.source, query, query ? [] : selected)
+ asyncOptions.value = response?.data || []
+ } catch (error) {
+ asyncOptions.value = []
+ } finally {
+ asyncLoading.value = false
+ }
+}
+
+function handleAsyncSearch(query) {
+ clearTimeout(asyncTimer)
+ asyncTimer = setTimeout(() => loadAsyncOptions(query), 250)
+}
+
// ============ Taxonomy Select (async) ============
@@ -621,6 +770,9 @@ onMounted(() => {
if (props.schema.type === 'user_select') {
loadInitialUsers()
}
+ if (props.schema.type === 'async_select') {
+ loadAsyncOptions()
+ }
})
// ============ User Select (async search) ============
@@ -740,12 +892,14 @@ function createRepeaterItem() {
}
function addRepeaterItem() {
+ if (reachedRepeaterMaximum.value) return
const current = Array.isArray(props.modelValue) ? [...props.modelValue] : []
current.push(createRepeaterItem())
emit('update:modelValue', current)
}
function removeRepeaterItem(index) {
+ if (reachedRepeaterMinimum.value) return
const current = Array.isArray(props.modelValue) ? [...props.modelValue] : []
current.splice(index, 1)
emit('update:modelValue', current)
@@ -807,6 +961,7 @@ function getRepeaterPreviewDesc(item) {
}
function openRepeaterModal(index) {
+ if (index < 0 && reachedRepeaterMaximum.value) return
if (props.schema.disabled) return
if (index >= 0) {
const item = (props.modelValue || [])[index] || {}
@@ -998,6 +1153,74 @@ function confirmRepeaterModal() {
text-align: center;
}
+.aksrt-field__palette {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+
+.aksrt-field__palette-item {
+ width: 34px;
+ height: 26px;
+ padding: 0;
+ border: 3px solid #fff;
+ border-radius: 3px;
+ box-shadow: 0 0 0 1px #d8d8d8;
+ cursor: pointer;
+}
+
+.aksrt-field__palette-item.is-active {
+ box-shadow: 0 0 0 2px #2f8fce;
+}
+
+.aksrt-field__link {
+ display: grid;
+ grid-template-columns: minmax(220px, 1fr) 120px minmax(140px, .5fr);
+ gap: 8px;
+}
+
+.aksrt-field__sortable {
+ display: grid;
+ gap: 8px;
+}
+
+.aksrt-field__selected-order {
+ display: grid;
+ gap: 5px;
+ margin-top: 8px;
+}
+
+.aksrt-field__selected-order-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 5px 9px;
+ border: 1px solid #e6e8eb;
+ border-radius: 3px;
+ background: #fafafa;
+}
+
+.aksrt-field__sortable-item {
+ border: 1px solid #e5e5e5;
+ background: #fff;
+}
+
+.aksrt-field__sortable-head {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px 12px;
+ background: #f7f7f7;
+ cursor: move;
+}
+
+.aksrt-field__sortable-body {
+ display: grid;
+ grid-template-columns: repeat(2, minmax(0, 1fr));
+ gap: 16px;
+ padding: 12px;
+}
+
/* Repeater */
.aksrt-field__fieldset {
padding: 14px;
@@ -1059,6 +1282,11 @@ function confirmRepeaterModal() {
flex-direction: column;
align-items: flex-start;
}
+
+ .aksrt-field__link,
+ .aksrt-field__sortable-body {
+ grid-template-columns: 1fr;
+ }
}
/* Repeater list-modal */
diff --git a/assets/admin/src/components/form/AksFormRenderer.vue b/assets/admin/src/components/form/AksFormRenderer.vue
index 7a6231e6..3d8b0309 100644
--- a/assets/admin/src/components/form/AksFormRenderer.vue
+++ b/assets/admin/src/components/form/AksFormRenderer.vue
@@ -172,8 +172,16 @@ function matchDependsOn(dependsOn) {
return !!props.formData[dependsOn]
}
if (typeof dependsOn === 'object') {
- const { key, value, values, not } = dependsOn
+ if (Array.isArray(dependsOn.all)) return dependsOn.all.every(matchDependsOn)
+ if (Array.isArray(dependsOn.any)) return dependsOn.any.some(matchDependsOn)
+ const { key, value, values, not, operator } = dependsOn
const currentVal = props.formData[key]
+ if (operator === 'truthy') return !!currentVal
+ if (operator === 'falsy') return !currentVal
+ if (operator === 'not_empty') return Array.isArray(currentVal) ? currentVal.length > 0 : currentVal !== '' && currentVal != null
+ if (operator === 'empty') return Array.isArray(currentVal) ? currentVal.length === 0 : currentVal === '' || currentVal == null
+ if (operator === 'eq') return currentVal === value
+ if (operator === 'neq') return currentVal !== value
if (not) {
if (Array.isArray(values)) {
// eslint-disable-next-line eqeqeq
diff --git a/assets/admin/src/components/homepage/ModuleCanvas.vue b/assets/admin/src/components/homepage/ModuleCanvas.vue
deleted file mode 100644
index cb5b41f0..00000000
--- a/assets/admin/src/components/homepage/ModuleCanvas.vue
+++ /dev/null
@@ -1,313 +0,0 @@
-
-
-
-
-
-
-
- 添加模块
-
-
-
-
- 应用预设
-
-
-
- 导出
-
-
-
- 导入
-
-
-
-
-
-
-
暂无首页模块,点击"添加模块"或"应用预设"开始配置。
-
-
-
-
-
-
-
-
-
-
-
- {{ getModuleLabel(mod.type) }}
- {{ mod.title }}
-
-
- $emit('toggle', index, val)"
- @click.stop
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/admin/src/components/homepage/ModuleInspector.vue b/assets/admin/src/components/homepage/ModuleInspector.vue
deleted file mode 100644
index ca1e9bbe..00000000
--- a/assets/admin/src/components/homepage/ModuleInspector.vue
+++ /dev/null
@@ -1,399 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
- updateField('title', val)"
- />
-
-
-
- updateField('enabled', val)"
- />
-
-
-
-
-
-
-
-
- updateConfig(field.key, val)"
- />
-
-
- updateConfig(field.key, val)"
- />
-
-
- updateConfig(field.key, val)"
- />
-
-
- updateConfig(field.key, val)"
- />
-
-
- updateConfig(field.key, val)"
- />
-
-
- updateConfig(field.key, val)"
- >
-
-
- {{ opt.label }}
-
-
-
-
-
- updateConfig(field.key, val)"
- />
-
-
- updateConfig(field.key, val)"
- />
-
-
-
-
-
-
-
-
- updateRepeaterItem(field.key, idx, sub.key, val)"
- />
-
-
-
-
-
-
-
- 添加一项
-
-
-
-
-
-
- 此模块类型暂无可配置字段。
-
-
-
-
-
-
-
-
-
-
- 取消
- 确定
-
-
-
-
-
-
-
-
-
diff --git a/assets/admin/src/components/homepage/ModulePresetPicker.vue b/assets/admin/src/components/homepage/ModulePresetPicker.vue
deleted file mode 100644
index e15f1249..00000000
--- a/assets/admin/src/components/homepage/ModulePresetPicker.vue
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
- 选择一个预设模板快速配置首页模块。应用预设将替换当前所有模块。
-
-
-
-
-
-
{{ preset.desc }}
-
-
- {{ getModuleLabel(mod.type) }}
-
-
-
-
-
-
-
-
- 取消
-
- 应用预设
-
-
-
-
-
-
-
-
-
diff --git a/assets/admin/src/constants/sections/page-display.js b/assets/admin/src/constants/sections/page-display.js
index d9fb432d..8b0bb158 100644
--- a/assets/admin/src/constants/sections/page-display.js
+++ b/assets/admin/src/constants/sections/page-display.js
@@ -1,119 +1,28 @@
-import { renderFaIcon, schemaPage, customPage } from './helpers'
+import { renderFaIcon, schemaPage } from './helpers'
+
+const pages = [
+ ['header-nav', '顶部导航栏'],
+ ['header-components', '顶部多功能组件'],
+ ['footer', '底部页脚'],
+ ['homepage', '首页配置'],
+ ['category', '分类页面'],
+ ['tag', '标签页面'],
+ ['user-home', '用户主页'],
+ ['other', '其它页面'],
+]
export const pageDisplaySection = {
key: 'page-display',
label: '页面&显示',
icon: renderFaIcon('fa fas fa-desktop'),
route: '/page-display',
- children: [
- schemaPage({
- key: 'page-display-header-nav',
- name: 'PageDisplayHeaderNav',
- label: '顶部导航栏',
- route: '/page-display/header-nav',
- title: '顶部导航栏',
- desc: '导航栏布局、菜单位置、LOGO 与搜索入口配置。',
- canonicalDomain: 'page_display',
- section: 'header-nav',
- }),
- schemaPage({
- key: 'page-display-background',
- name: 'PageDisplayBackground',
- label: '全局背景',
- route: '/page-display/background',
- title: '全局背景',
- desc: '配置站点全局背景图、背景色、暗色模式背景和遮罩。',
- canonicalDomain: 'page_display',
- section: 'background',
- }),
- schemaPage({
- key: 'page-display-menu-decoration',
- name: 'PageDisplayMenuDecoration',
- label: '菜单装饰',
- route: '/page-display/menu-decoration',
- title: '菜单装饰',
- desc: '配置导航菜单的图标、徽章、下拉样式和图文卡片子菜单。',
- canonicalDomain: 'page_display',
- section: 'menu-decoration',
- }),
- schemaPage({
- key: 'page-display-header-components',
- name: 'PageDisplayHeaderComponents',
- label: '顶部多功能组件',
- route: '/page-display/header-components',
- title: '顶部多功能组件',
- desc: '配置顶部组件显示范围、幻灯片内容、轮播参数、搜索覆盖层与图标卡片。',
- canonicalDomain: 'page_display',
- section: 'header-components',
- }),
- customPage({
- key: 'page-display-banner',
- name: 'PageDisplayBanner',
- label: 'Banner 轮播',
- route: '/page-display/banner',
- title: 'Banner 管理',
- desc: '管理首页内容流 Banner 幻灯片(图片、文案、跳转、启用状态)。',
- component: 'BannerManager',
- canonicalDomain: 'page_display',
- section: 'banner',
- }),
- customPage({
- key: 'page-display-footer',
- name: 'PageDisplayFooter',
- label: '底部页脚',
- route: '/page-display/footer',
- title: '底部页脚',
- desc: '页脚布局、友链、版权信息配置。',
- component: 'FooterSettings',
- }),
- customPage({
- key: 'page-display-homepage',
- name: 'PageDisplayHomepage',
- label: '首页配置',
- route: '/page-display/homepage',
- title: '首页配置',
- desc: '首页内容模型、主列表、分类 Tab 与首页交互配置。',
- component: 'HomepageSettings',
- }),
- schemaPage({
- key: 'page-display-category',
- name: 'PageDisplayCategory',
- label: '分类页面',
- route: '/page-display/category',
- title: '分类页面',
- desc: '分类归档页的头图、简介、列表模式、侧栏配置。',
- canonicalDomain: 'page_display',
- section: 'category',
- }),
- schemaPage({
- key: 'page-display-tag',
- name: 'PageDisplayTag',
- label: '标签页面',
- route: '/page-display/tag',
- title: '标签页面',
- desc: '标签归档页的展示样式与配置。',
- canonicalDomain: 'page_display',
- section: 'tag',
- }),
- schemaPage({
- key: 'page-display-user-home',
- name: 'PageDisplayUserHome',
- label: '用户主页',
- route: '/page-display/user-home',
- title: '用户主页',
- desc: '用户公开主页的布局与展示配置。',
- canonicalDomain: 'page_display',
- section: 'user-home',
- }),
- schemaPage({
- key: 'page-display-other',
- name: 'PageDisplayOther',
- label: '其它页面',
- route: '/page-display/other',
- title: '其它页面',
- desc: '404 页面、搜索结果页等其它页面配置。',
- canonicalDomain: 'page_display',
- section: 'other',
- }),
- ],
+ children: pages.map(([section, label]) => schemaPage({
+ key: `page-display-${section}`,
+ name: `PageDisplay${section.split('-').map(part => part[0].toUpperCase() + part.slice(1)).join('')}`,
+ label,
+ route: `/page-display/${section}`,
+ title: label,
+ canonicalDomain: 'page_display',
+ section,
+ })),
}
diff --git a/assets/admin/src/pages/SchemaPage.vue b/assets/admin/src/pages/SchemaPage.vue
index 8ded7c11..a7ea9f37 100644
--- a/assets/admin/src/pages/SchemaPage.vue
+++ b/assets/admin/src/pages/SchemaPage.vue
@@ -130,6 +130,7 @@ const message = useMessage()
const showTestModal = ref(false)
const testLoading = ref(false)
const testResult = ref(null)
+const serverSchema = ref(null)
/** Resolve domain/section from props or route meta (canonicalDomain + section, with legacy fallback) */
const resolvedDomain = computed(() => normalizeSchemaDomain(props.domain || route.meta?.canonicalDomain || route.meta?.schemaDomain || resolveDomainFromPath(route.path)))
@@ -150,7 +151,9 @@ function resolveSectionFromPath(path) {
/** Load schema from the Vue-side registry */
const pageMeta = computed(() => {
- const schema = getSchema(resolvedDomain.value, resolvedSection.value)
+ const schema = resolvedDomain.value === 'page_display'
+ ? serverSchema.value
+ : getSchema(resolvedDomain.value, resolvedSection.value)
if (schema && schema.groups && schema.groups.length > 0) {
return {
title: schema.title || '',
@@ -170,7 +173,9 @@ const pageMeta = computed(() => {
/** Default values from schema */
const defaults = computed(() => {
- const schema = getSchema(resolvedDomain.value, resolvedSection.value)
+ const schema = resolvedDomain.value === 'page_display'
+ ? serverSchema.value
+ : getSchema(resolvedDomain.value, resolvedSection.value)
if (!schema) return {}
const d = {}
for (const group of schema.groups || []) {
@@ -188,7 +193,13 @@ const {
formData, loading, saving, loadError, dirty,
save: doSave, reload,
} = useSectionForm({
- fetch: () => api.getSchemaPage(resolvedDomain.value, resolvedSection.value),
+ fetch: async () => {
+ const response = await api.getSchemaPage(resolvedDomain.value, resolvedSection.value)
+ if (resolvedDomain.value === 'page_display') {
+ serverSchema.value = response?.schema || null
+ }
+ return response
+ },
submit: (data) => api.saveSchemaPage(resolvedDomain.value, resolvedSection.value, data),
defaults: defaults.value,
onSaved: () => {
@@ -426,6 +437,7 @@ function closeTestModal() {
watch([resolvedDomain, resolvedSection], ([nextDomain, nextSection], [prevDomain, prevSection]) => {
if (nextDomain !== prevDomain || nextSection !== prevSection) {
closeTestModal()
+ serverSchema.value = null
reload()
}
})
@@ -437,8 +449,8 @@ onBeforeUnmount(() => {
diff --git a/assets/admin/src/pages/content/FooterSettings.vue b/assets/admin/src/pages/content/FooterSettings.vue
deleted file mode 100644
index 0576a705..00000000
--- a/assets/admin/src/pages/content/FooterSettings.vue
+++ /dev/null
@@ -1,986 +0,0 @@
-
-
-
-
- 保存
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 选择
- 清除
-
-
-
-
-
-
- 选择
- 清除
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 页脚中的社交平台或联系入口。
-
-
-
-
- 标准联系字段
-
-
-
-
-
-
-
-
-
-
-
-
- 选择
- 清除
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 更多联系项
-
-
-
-
- 每项含描述、图标、链接、图片(hover 显示),用于补充标准联系方式。
-
-
-
-
-
-
-
-
-
-
-
-
- 页脚第二列的常用导航链接。
-
-
-
-
-
-
-
-
-
-
-
-
- 页脚补充链接区域。
-
-
-
-
-
-
-
-
-
-
-
-
- 站点友情链接列表,支持 Logo 头像、名称、URL 与简短描述。
-
-
-
-
-
-
-
-
-
-
-
-
- 显示在页脚第三列区域,每项含文字描述和二维码图片。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 选择
-
- 删除
-
-
![]()
-
-
-
-
-
-
-
-
-
- 插入在页脚底部区域(版权信息之后),支持 HTML。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 模板一(Zibll)
-
-
-
-
-
- 范围 1 - 20
-
-
-
-
-
-
-
-
-
-
-
- 保存页脚配置
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/assets/admin/src/pages/content/HomepageSettings.vue b/assets/admin/src/pages/content/HomepageSettings.vue
deleted file mode 100644
index 1ee561cf..00000000
--- a/assets/admin/src/pages/content/HomepageSettings.vue
+++ /dev/null
@@ -1,354 +0,0 @@
-
-
-
-
- 保存设置
-
-
-
-
-
-
-
- 首页说明
-
-
-
- 首页主列表只使用普通文章。下载/付费是文章能力(meta),不是第二种内容类型。当前为固定骨架模式,不再使用旧版自由模块画布。
-
-
-
-
-
-
- 主列表
-
-
-
- 首页主内容区保留 Zibll 式内容流,不建议关闭。
-
-
-
-
-
-
-
-
-
-
-
-
-
- 内联链接
- 下拉菜单
-
-
-
-
-
-
-
-
-
-
- 排除规则
-
-
-
- 主列表和首页 Tab 查询均排除这些文章。
-
-
-
- 主列表排除这些分类,首页 Tab 不能绑定已排除分类。
-
-
-
-
-
-
-
- 更多栏目
- + 添加栏目
-
-
-
-
-
-
-
-
-
-
-
-
- 暂无更多栏目,点击“添加栏目”创建分类 Tab。
-
-
-
-
- updateTab(index, 'term_id', val)"
- />
- updateTab(index, 'title', val)"
- />
- updateTab(index, 'orderby', val)"
- />
- updateTab(index, 'enabled', val)"
- />
- 删除
-
-
-
-
-
-
-
-
-
- 列表显示
-
- 首页文章列表/卡片模式、样式变体与缩略图比例统一由「文章&列表 → 文章列表」中的 Zibll 全局字段控制。
-
-
-
-
- 交互设置
-
-
-
- 关闭后排序链接使用整页跳转。
-
-
-
-
-
-
-
-
-
-
-
- 固定骨架说明
-
-
- 顶部多功能组件与 Banner 已作为固定首页骨架的一部分维护,不再由旧版首页模块编排驱动。
-
-
- 如需调整首页首屏运营区,请前往对应管理页配置幻灯片内容或顶部组件参数。
-
-
- 管理 Banner 轮播
-
- 顶部多功能组件
-
-
-
-
-
-
-
-
-
- 保存设置
-
-
-
-
-
-
-
diff --git a/assets/admin/src/pages/docs/DocsPage.vue b/assets/admin/src/pages/docs/DocsPage.vue
index eb58fad2..6f47316c 100644
--- a/assets/admin/src/pages/docs/DocsPage.vue
+++ b/assets/admin/src/pages/docs/DocsPage.vue
@@ -10,7 +10,7 @@
全局设置
-
Logo、背景、菜单装饰、自定义代码
+
Logo、导航栏、自定义代码
前往配置 →
diff --git a/assets/admin/src/router/component-loaders/core.js b/assets/admin/src/router/component-loaders/core.js
index 8c17ee01..94e637a9 100644
--- a/assets/admin/src/router/component-loaders/core.js
+++ b/assets/admin/src/router/component-loaders/core.js
@@ -4,9 +4,6 @@ export const corePageLoaders = {
NativeOpsRedirect: () => import('@/pages/placeholder/NativeOpsRedirect.vue'),
FloatingButtonsSettings: () => import('@/pages/content/FloatingButtonsSettings.vue'),
FooterTabbarSettings: () => import('@/pages/content/FooterTabbarSettings.vue'),
- FooterSettings: () => import('@/pages/content/FooterSettings.vue'),
- HomepageSettings: () => import('@/pages/content/HomepageSettings.vue'),
- BannerManager: () => import('@/pages/content/BannerManager.vue'),
PostPageSettings: () => import('@/pages/post-list/PostPageSettings.vue'),
CommentSettings: () => import('@/pages/post-list/CommentSettings.vue'),
PermissionsCapabilities: () => import('@/pages/permissions/PermissionsCapabilities.vue'),
diff --git a/assets/admin/src/schema/index.js b/assets/admin/src/schema/index.js
index 76c9c728..0ae8cc5d 100644
--- a/assets/admin/src/schema/index.js
+++ b/assets/admin/src/schema/index.js
@@ -27,7 +27,6 @@
* }
*/
import { globalSchemas } from './sections/global/index.js'
-import { pageDisplaySchemas } from './sections/page-display/index.js'
import { postListSchemas } from './sections/post-list/index.js'
import { permissionsSchemas } from './sections/permissions/index.js'
import { usersSchemas } from './sections/users/index.js'
@@ -58,7 +57,7 @@ export const CANONICAL_SCHEMA_DOMAINS = [
/** All schemas organized by domain */
export const ALL_SCHEMAS = Object.freeze({
global: globalSchemas,
- page_display: pageDisplaySchemas,
+ page_display: Object.freeze({}),
post_list: postListSchemas,
permissions: permissionsSchemas,
users: usersSchemas,
diff --git a/assets/admin/src/schema/sections/global/search.js b/assets/admin/src/schema/sections/global/search.js
index 7bca45bc..2fb99707 100644
--- a/assets/admin/src/schema/sections/global/search.js
+++ b/assets/admin/src/schema/sections/global/search.js
@@ -17,7 +17,7 @@ export const searchSchema = {
search_cat_in: '',
search_more_cat_obj: [],
search_custom_key_s: true,
- search_custom_key: ['title', 'content', 'excerpt', 'post_tag', 'forum_topic', 'shop_cat', 'shop_discount'],
+ search_custom_key: ['title', 'content', 'excerpt', 'category', 'post_tag'],
search_facets: {},
search_ms_s: false,
search_ms_opt: { api_url: 'http://127.0.0.1:7700', api_key: '', index_prefix: 'aksrt', synonyms: [{ key: 'wordpress', val: 'wp,wordp,wordpre' }] },
@@ -59,25 +59,16 @@ export const searchSchema = {
{ key: '404_search_s', label: '404 页面搜索', type: 'switch', default: true, help: '在 404 页面显示搜索功能' },
{ key: 'search_posts', label: '搜索框热门文章', type: 'switch', default: true, help: '在搜索面板中显示热门文章列表' },
{ key: 'search_no_page', label: '排除页面', type: 'switch', default: true, help: '搜索结果中排除页面(仅显示文章)' },
- { key: 'search_exclude_cats', label: '排除分类', type: 'taxonomy_select', taxonomy: ['category', 'shop_cat'], multiple: true, default: [], help: '搜索结果中排除的文章或商品分类' },
+ { key: 'search_exclude_cats', label: '排除分类', type: 'taxonomy_select', taxonomy: 'category', multiple: true, default: [], help: '搜索结果中排除的文章分类' },
{ key: 'search_custom_key_s', label: '自定义匹配范围', type: 'switch', default: true, help: '启用后可配置搜索匹配字段范围' },
- { key: 'search_custom_key', label: '匹配字段', type: 'checkbox', default: ['title', 'content', 'excerpt', 'post_tag', 'forum_topic', 'shop_cat', 'shop_discount'], dependsOn: { key: 'search_custom_key_s', value: true }, options: [
+ { key: 'search_custom_key', label: '匹配字段', type: 'checkbox', default: ['title', 'content', 'excerpt', 'category', 'post_tag'], dependsOn: { key: 'search_custom_key_s', value: true }, options: [
{ label: '标题', value: 'title' }, { label: '内容', value: 'content' }, { label: '简介', value: 'excerpt' },
- { label: '分类', value: 'category' }, { label: '标签', value: 'post_tag' }, { label: '专题', value: 'topics' },
+ { label: '分类', value: 'category' }, { label: '标签', value: 'post_tag' },
{ label: '评论', value: 'coment' }, { label: '作者昵称', value: 'user' },
- { label: '[帖子]话题', value: 'forum_topic' }, { label: '[帖子]标签', value: 'forum_tag' },
- { label: '[商品]分类', value: 'shop_cat' }, { label: '[商品]特色标签', value: 'shop_tag' }, { label: '[商品]优惠活动', value: 'shop_discount' },
] },
{ key: 'search_facets', label: '搜索筛选', type: 'fieldset', sanitizeType: 'array', default: {}, dependsOn: { key: 'search_ms_s', value: false }, help: '搜索结果中显示的筛选列表;启用 Meilisearch 后由搜索引擎生成关联筛选。', fields: [
{ key: 'category', label: '[文章] 分类', type: 'taxonomy_select', taxonomy: 'category', multiple: true, default: [] },
- { key: 'topics', label: '[文章] 专题', type: 'taxonomy_select', taxonomy: 'topics', multiple: true, default: [] },
{ key: 'post_tag', label: '[文章] 标签', type: 'taxonomy_select', taxonomy: 'post_tag', multiple: true, default: [] },
- { key: 'plate_id', label: '[论坛帖子] 板块 ID', type: 'input', default: '' },
- { key: 'forum_topic', label: '[论坛帖子] 话题', type: 'taxonomy_select', taxonomy: 'forum_topic', multiple: true, default: [] },
- { key: 'forum_tag', label: '[论坛帖子] 标签', type: 'taxonomy_select', taxonomy: 'forum_tag', multiple: true, default: [] },
- { key: 'shop_cat', label: '[商品] 分类', type: 'taxonomy_select', taxonomy: 'shop_cat', multiple: true, default: [] },
- { key: 'shop_discount', label: '[商品] 优惠活动', type: 'taxonomy_select', taxonomy: 'shop_discount', multiple: true, default: [] },
- { key: 'shop_tag', label: '[商品] 特色标签', type: 'taxonomy_select', taxonomy: 'shop_tag', multiple: true, default: [] },
] },
],
},
diff --git a/assets/admin/src/schema/sections/page-display/index.js b/assets/admin/src/schema/sections/page-display/index.js
deleted file mode 100644
index 60f05b32..00000000
--- a/assets/admin/src/schema/sections/page-display/index.js
+++ /dev/null
@@ -1,778 +0,0 @@
-/**
- * Page Display domain schemas.
- * Each key corresponds to a sub-page under the "页面&显示" section.
- */
-
-/** Theme asset base for layout previews (admin SPA). */
-function themeAsset(path) {
- const base = (typeof window !== 'undefined' && window.aksrtAdminData && window.aksrtAdminData.themeUri)
- ? String(window.aksrtAdminData.themeUri).replace(/\/$/, '')
- : ''
- return base ? `${base}/${path.replace(/^\//, '')}` : path
-}
-
-/** Homepage sort options — keep in sync with AKSRT_Settings_Home_Cms::homepage_allowed_sorts() */
-const sortOptions = [
- { label: '最近更新', value: 'modified' },
- { label: '发布时间', value: 'date' },
- { label: '浏览量', value: 'views' },
- { label: '点赞数', value: 'likes' },
- { label: '评论数', value: 'comments' },
- { label: '收藏数', value: 'favorites' },
- { label: '下载量', value: 'downloads' },
- { label: '随机', value: 'rand' },
-]
-
-export const pageDisplaySchemas = {
- /**
- * Header navigation settings
- */
- 'header-nav': {
- key: 'page_display.header-nav',
- title: '顶部导航栏',
- icon: 'fa fas fa-bars',
- description: '配置导航栏布局、菜单结构、搜索入口和用户入口。',
- defaults: {
- nav_fixed: true,
- nav_scroll_down_hide: true,
- header_layout: '1',
- nav_pay_vip: true,
- nav_user_pay_vip: true,
- nav_newposts_btns: ['post'],
- nav_user_newposts_btn: 'post',
- nav_user_newposts_btn_text: '发布文章',
- mobile_header_layout: 'center',
- mobile_navbar_align: 'left',
- nav_newposts: true,
- nav_newposts_text: '发布',
- nav_newposts_radius: true,
- nav_newposts_class: 'jb-blue',
- header_theme_custom: false,
- header_theme_bg_custom: '',
- header_theme_bg: '',
- header_theme_color_custom: '',
- },
- groups: [
- {
- key: 'layout',
- title: '导航栏布局',
- icon: 'fa fas fa-th-large',
- fields: [
- { key: 'nav_fixed', label: '导航栏一直固定在顶部', type: 'switch', default: true },
- { key: 'nav_scroll_down_hide', label: '下滚动隐藏,上滚动显示', type: 'switch', default: true, dependsOn: { key: 'nav_fixed', value: true } },
- ],
- },
- {
- key: 'layout-type',
- title: '布局类型',
- icon: 'fa fas fa-columns',
- fields: [
- {
- key: 'header_layout',
- label: '电脑端布局',
- type: 'image_select',
- default: '1',
- options: [
- { label: '布局 1(经典)', value: '1', image: themeAsset('assets/images/header-layout/header_layout_1.png') },
- { label: '布局 2(内联搜索)', value: '2', image: themeAsset('assets/images/header-layout/header_layout_2.png') },
- { label: '布局 3(紧凑)', value: '3', image: themeAsset('assets/images/header-layout/header_layout_3.png') },
- ],
- help: '不同布局切换导航 DOM 结构(与 zibll image_select 一致)',
- },
- {
- key: 'mobile_header_layout',
- label: '移动端布局',
- type: 'image_select',
- default: 'center',
- options: [
- { label: '居中(含搜索按钮)', value: 'center', image: themeAsset('assets/images/header-layout/mobile_header_layout_center.png') },
- { label: '靠左', value: 'left', image: themeAsset('assets/images/header-layout/mobile_header_layout_left.png') },
- ],
- },
- {
- key: 'mobile_navbar_align',
- label: '移动端菜单方向',
- type: 'radio',
- default: 'left',
- options: [
- { label: '顶部(关闭手势)', value: 'top' },
- { label: '左侧滑出', value: 'left' },
- { label: '右侧滑出', value: 'right' },
- ],
- },
- ],
- },
- {
- key: 'newposts',
- title: '发布按钮',
- icon: 'fa fas fa-pen',
- fields: [
- { key: 'nav_newposts', label: '启用发布按钮', type: 'switch', default: true },
- { key: 'nav_newposts_text', label: '按钮文案', type: 'input', default: '发布', dependsOn: { key: 'nav_newposts', value: true } },
- { key: 'nav_newposts_radius', label: '按钮圆角(胶囊)', type: 'switch', default: true, dependsOn: { key: 'nav_newposts', value: true } },
- { key: 'nav_newposts_class', label: '按钮颜色', type: 'select', default: 'jb-blue', options: [
- { label: '蓝色', value: 'jb-blue' },
- { label: '红色', value: 'jb-red' },
- { label: '绿色', value: 'jb-green' },
- { label: '黄色', value: 'jb-yellow' },
- { label: '紫色', value: 'jb-purple' },
- { label: '粉色', value: 'jb-pink' },
- ], dependsOn: { key: 'nav_newposts', value: true } },
- { key: 'nav_newposts_btns', label: '发布类型', type: 'checkbox', default: ['post'], options: [
- { label: '文章', value: 'post' },
- ], dependsOn: { key: 'nav_newposts', value: true } },
- { key: 'nav_user_newposts_btn', label: '用户卡发布类型', type: 'select', default: 'post', options: [
- { label: '文章', value: 'post' },
- ] },
- { key: 'nav_user_newposts_btn_text', label: '用户卡发布文案', type: 'input', default: '发布文章' },
- { key: 'nav_pay_vip', label: '导航栏开通会员按钮', type: 'switch', default: true },
- { key: 'nav_user_pay_vip', label: '用户框开通会员按钮', type: 'switch', default: true },
- ],
- },
- {
- key: 'color',
- title: '导航配色',
- icon: 'fa fas fa-paint-brush',
- fields: [
- { key: 'header_theme_custom', label: '自定义导航配色', type: 'switch', default: false, help: '启用后覆盖导航栏默认配色' },
- { key: 'header_theme_bg_custom', label: '导航背景色', type: 'color', default: '', dependsOn: { key: 'header_theme_custom', value: true } },
- { key: 'header_theme_bg', label: '导航背景色(备选)', type: 'color', default: '', dependsOn: { key: 'header_theme_custom', value: true } },
- { key: 'header_theme_color_custom', label: '导航文字色', type: 'color', default: '', dependsOn: { key: 'header_theme_custom', value: true } },
- ],
- },
- ],
- },
-
- /**
- * Category page settings
- */
- category: {
- key: 'page_display.category',
- title: '分类页面',
- icon: 'fa fas fa-folder-open',
- description: '为分类归档页配置头图、简介、列表模式、筛选条和侧边栏。',
- defaults: {
- category_cover_enabled: true,
- category_desc_enabled: true,
- category_header_style: 'cover',
- category_list_mode: 'grid',
- category_filter_bar: true,
- category_sidebar: true,
- category_per_page: 12,
- category_default_cover: '',
- category_post_count: true,
- category_orderby: 'modified',
- },
- groups: [
- {
- key: 'header',
- title: '分类头图',
- icon: 'fa fas fa-image',
- fields: [
- { key: 'category_header_style', label: '头部风格', type: 'radio', default: 'cover', options: [
- { label: '封面图', value: 'cover' },
- { label: '简洁标题', value: 'simple' },
- { label: '隐藏', value: 'none' },
- ]},
- { key: 'category_cover_enabled', label: '显示封面图', type: 'switch', default: true, dependsOn: { key: 'category_header_style', value: 'cover' } },
- { key: 'category_desc_enabled', label: '显示分类简介', type: 'switch', default: true },
- { key: 'category_default_cover', label: '默认封面图', type: 'upload', default: '', help: '未设置分类封面时使用的默认图片' },
- ],
- },
- {
- key: 'list',
- title: '列表设置',
- icon: 'fa fas fa-list',
- fields: [
- { key: 'category_list_mode', label: '列表模式', type: 'radio', default: 'grid', options: [
- { label: '网格', value: 'grid' },
- { label: '列表', value: 'list' },
- { label: '紧凑', value: 'compact' },
- ]},
- { key: 'category_per_page', label: '每页文章数', type: 'number', default: 12, min: 4, max: 48 },
- { key: 'category_filter_bar', label: '筛选条', type: 'switch', default: true, help: '子分类筛选和排序' },
- { key: 'category_sidebar', label: '侧边栏', type: 'switch', default: true },
- { key: 'category_post_count', label: '显示文章数', type: 'switch', default: true, help: '在分类列表中显示每篇文章的浏览次数' },
- ],
- },
- {
- key: 'orderby',
- title: '排序设置',
- icon: 'fa fas fa-sort',
- fields: [
- { key: 'category_orderby', label: '默认排序', type: 'select', default: 'modified', options: [
- { label: '最近更新', value: 'modified' },
- { label: '发布时间', value: 'date' },
- { label: '浏览数', value: 'views' },
- { label: '评论数', value: 'comments' },
- { label: '点赞数', value: 'likes' },
- ]},
- ],
- },
- ],
- },
-
- /**
- * Tag page settings
- */
- tag: {
- key: 'page_display.tag',
- title: '标签页面',
- icon: 'fa fas fa-tags',
- description: '为标签归档页配置展示样式和布局。',
- defaults: {
- tag_header_style: 'simple',
- tag_default_cover: '',
- tag_list_mode: 'grid',
- tag_sidebar: true,
- tag_per_page: 12,
- tag_post_count: true,
- tag_orderby: 'count',
- },
- groups: [
- {
- key: 'header',
- title: '标签头图',
- icon: 'fa fas fa-tag',
- fields: [
- { key: 'tag_header_style', label: '头部风格', type: 'radio', default: 'simple', options: [
- { label: '简洁标题', value: 'simple' },
- { label: '封面图', value: 'cover' },
- { label: '隐藏', value: 'none' },
- ]},
- { key: 'tag_default_cover', label: '默认封面图', type: 'upload', default: '' },
- ],
- },
- {
- key: 'list',
- title: '列表设置',
- icon: 'fa fas fa-list',
- fields: [
- { key: 'tag_list_mode', label: '列表模式', type: 'radio', default: 'grid', options: [
- { label: '网格', value: 'grid' },
- { label: '列表', value: 'list' },
- ]},
- { key: 'tag_per_page', label: '每页文章数', type: 'number', default: 12, min: 4, max: 48 },
- { key: 'tag_sidebar', label: '侧边栏', type: 'switch', default: true },
- { key: 'tag_post_count', label: '显示文章数', type: 'switch', default: true },
- ],
- },
- {
- key: 'orderby',
- title: '排序设置',
- icon: 'fa fas fa-sort',
- fields: [
- { key: 'tag_orderby', label: '默认排序', type: 'select', default: 'count', options: [
- { label: '文章数', value: 'count' },
- { label: '名称', value: 'name' },
- { label: '最近更新', value: 'modified' },
- ]},
- ],
- },
- ],
- },
-
- /**
- * User homepage settings
- */
- 'user-home': {
- key: 'page_display.user-home',
- title: '用户主页',
- icon: 'fa fas fa-user-circle',
- description: '公开用户主页对齐 Zibll 作者页:通栏头图 + Tab 计数;交易/快捷入口仅在用户中心。',
- defaults: {
- user_home_tabs: 'posts,favorites,comments,follow',
- user_home_tabs_order: 'posts,favorites,comments,follow',
- user_home_tabs_pc_hide: '',
- user_home_tabs_mobile_hide: '',
- user_home_sidebar: false,
- user_home_cover: true,
- user_home_route_identifier: 'nicename',
- user_home_follow: true,
- user_home_posts_per_page: 10,
- user_home_avatar: true,
- user_home_name: true,
- user_home_desc: true,
- user_home_stats: false,
- user_home_social: true,
- author_main_tab_swiper: false,
- user_home_message: true,
- user_home_private: true,
- user_home_paging_ajax: true,
- },
- groups: [
- {
- key: 'layout',
- title: '主页布局',
- icon: 'fa fas fa-th-large',
- fields: [
- { key: 'user_home_cover', label: '封面区域', type: 'switch', default: true, help: '用户主页顶部封面图' },
- { key: 'user_home_route_identifier', label: '主页 URL 标识', type: 'select', default: 'nicename', options: [{ label: '用户名 URL slug', value: 'nicename' }, { label: '数字用户 ID', value: 'uid' }] },
- { key: 'user_home_sidebar', label: '侧边栏(已弃用)', type: 'switch', default: false, help: '公开主页为通栏布局(对齐 Zibll author);运行时强制关闭。交易服务请去用户中心。' },
- { key: 'user_home_follow', label: '关注按钮', type: 'switch', default: true },
- { key: 'user_home_posts_per_page', label: '每页文章数', type: 'number', default: 10, min: 5, max: 50 },
- { key: 'user_home_paging_ajax', label: 'AJAX 翻页', type: 'switch', default: true, help: '使用 AJAX 加载替代传统翻页' },
- ],
- },
- {
- key: 'tabs',
- title: 'Tab 配置',
- icon: 'fa fas fa-columns',
- fields: [
- { key: 'user_home_tabs', label: '显示的 Tab', type: 'input', default: 'posts,favorites,comments,follow', help: '逗号分隔;默认 posts,favorites,comments,follow(粉丝)。可选 credits' },
- { key: 'user_home_tabs_order', label: 'Tab 显示顺序', type: 'input', default: 'posts,favorites,comments,follow', help: '逗号分隔,控制栏目顺序' },
- { key: 'user_home_tabs_pc_hide', label: 'PC 端隐藏', type: 'input', default: '', help: '逗号分隔要在 PC 端隐藏的栏目' },
- { key: 'user_home_tabs_mobile_hide', label: '移动端隐藏', type: 'input', default: '', help: '逗号分隔要在移动端隐藏的栏目' },
- { key: 'author_main_tab_swiper', label: '移动端滑动切换', type: 'switch', default: false, help: '移动端左右滑动切换栏目' },
- ],
- },
- {
- key: 'display',
- title: '展示设置',
- icon: 'fa fas fa-eye',
- fields: [
- { key: 'user_home_avatar', label: '显示头像', type: 'switch', default: true },
- { key: 'user_home_name', label: '显示用户名', type: 'switch', default: true },
- { key: 'user_home_desc', label: '显示个人简介', type: 'switch', default: true },
- { key: 'user_home_stats', label: '显示统计数据(已弃用)', type: 'switch', default: false, help: '计数已并入 Tab 角标,头图内不再重复文章/评论/收藏。' },
- { key: 'user_home_social', label: '显示社交链接', type: 'switch', default: true },
- { key: 'user_home_message', label: '私信/消息按钮', type: 'switch', default: true, help: '本人显示消息中心入口;访客显示私信入口' },
- { key: 'user_home_private', label: '留言按钮', type: 'switch', default: true, help: '预留开关,公开主页留言入口' },
- ],
- },
- ],
- },
-
- /**
- * Other pages settings (404, search results, etc.)
- */
- other: {
- key: 'page_display.other',
- title: '其它页面',
- icon: 'fa fas fa-file',
- description: '配置 404 页面、搜索结果页等特殊页面的展示。',
- defaults: {
- page_header_style: '1',
- page_header_cover_img: '',
- page_404_search: true,
- page_404_popular: true,
- page_404_message: '页面未找到',
- page_404_back: true,
- page_search_sidebar: true,
- page_search_per_page: 12,
- page_author_cover: true,
- page_author_sidebar: true,
- page_author_posts_per_page: 12,
- },
- groups: [
- {
- key: 'page-header',
- title: '统一页头',
- icon: 'fa fas fa-heading',
- fields: [
- { key: 'page_header_style', label: '页面标题样式', type: 'select', default: '1', options: [
- { label: '不显示', value: '' },
- { label: '简单', value: '1' },
- { label: '卡片', value: '2' },
- { label: '封面', value: '3' },
- ], help: '控制归档/搜索/页面的页头样式,单页可通过 post meta 覆盖' },
- { key: 'page_header_cover_img', label: '默认封面图', type: 'upload', default: '', help: '封面样式(样式3)的默认背景图,单页可覆盖' },
- ],
- },
- {
- key: 'page_404',
- title: '404 页面',
- icon: 'fa fas fa-exclamation-triangle',
- fields: [
- { key: 'page_404_message', label: '404 提示文字', type: 'input', default: '页面未找到' },
- { key: 'page_404_search', label: '显示搜索框', type: 'switch', default: true },
- { key: 'page_404_popular', label: '显示热门文章', type: 'switch', default: true },
- { key: 'page_404_back', label: '显示返回首页', type: 'switch', default: true },
- ],
- },
- {
- key: 'search_results',
- title: '搜索结果页',
- icon: 'fa fas fa-search',
- fields: [
- { key: 'page_search_sidebar', label: '搜索结果侧边栏', type: 'switch', default: true },
- { key: 'page_search_per_page', label: '每页结果数', type: 'number', default: 12, min: 4, max: 48 },
- ],
- },
- {
- key: 'author',
- title: '作者页面',
- icon: 'fa fas fa-user',
- fields: [
- { key: 'page_author_cover', label: '显示封面', type: 'switch', default: true },
- { key: 'page_author_sidebar', label: '显示侧边栏', type: 'switch', default: true },
- { key: 'page_author_posts_per_page', label: '每页文章数', type: 'number', default: 12, min: 4, max: 48 },
- ],
- },
- ],
- },
-
- /**
- * Global background settings
- */
- background: {
- key: 'page_display.background',
- title: '全局背景',
- icon: 'fa fas fa-image',
- description: '配置站点全局背景图、背景色、暗色模式背景和遮罩。',
- defaults: {
- bg_color: '',
- bg_image: '',
- bg_size: '100%',
- bg_position: 'center center',
- bg_repeat: 'no-repeat',
- bg_attachment: 'fixed',
- bg_dark_color: '',
- bg_dark_image: '',
- bg_overlay: false,
- bg_overlay_color: 'rgba(0, 0, 0, 0.3)',
- page_bg_color: '',
- page_bg_image: '',
- },
- groups: [
- {
- key: 'light',
- title: '亮色背景',
- icon: 'fa fas fa-sun',
- fields: [
- { key: 'bg_color', label: '背景颜色', type: 'color', default: '', help: '留空则使用主题默认背景色' },
- { key: 'bg_image', label: '背景图片', type: 'media', help: '推荐使用高分辨率图片' },
- { key: 'bg_size', label: '图片尺寸', type: 'select', default: 'cover', options: [
- { label: '覆盖 (Cover)', value: 'cover' },
- { label: '包含 (Contain)', value: 'contain' },
- { label: '原始大小', value: 'auto' },
- { label: '拉伸填充', value: '100% 100%' },
- { label: '100% 宽度(旧版兼容)', value: '100%' },
- ]},
- { key: 'bg_position', label: '图片位置', type: 'select', default: 'center center', options: [
- { label: '居中', value: 'center center' },
- { label: '顶部居中', value: 'top center' },
- { label: '底部居中', value: 'bottom center' },
- ]},
- { key: 'bg_repeat', label: '图片重复', type: 'select', default: 'no-repeat', options: [
- { label: '不重复', value: 'no-repeat' },
- { label: '平铺', value: 'repeat' },
- { label: '水平平铺', value: 'repeat-x' },
- { label: '垂直平铺', value: 'repeat-y' },
- ]},
- { key: 'bg_attachment', label: '固定方式', type: 'select', default: 'fixed', options: [
- { label: '固定 (视差)', value: 'fixed' },
- { label: '随内容滚动', value: 'scroll' },
- ]},
- ],
- },
- {
- key: 'dark',
- title: '暗色背景',
- icon: 'fa fas fa-moon',
- fields: [
- { key: 'bg_dark_color', label: '暗色背景颜色', type: 'color', default: '', help: '留空则使用主题默认暗色背景' },
- { key: 'bg_dark_image', label: '暗色背景图片', type: 'media', help: '暗色模式下显示的背景图' },
- ],
- },
- {
- key: 'overlay',
- title: '遮罩设置',
- icon: 'fa fas fa-clone',
- fields: [
- { key: 'bg_overlay', label: '启用背景遮罩', type: 'switch', default: false, help: '在背景图上方叠加半透明遮罩,提升文字可读性' },
- { key: 'bg_overlay_color', label: '遮罩颜色', type: 'input', default: 'rgba(0, 0, 0, 0.3)', dependsOn: { key: 'bg_overlay', value: true }, help: '支持 rgba/hex 色值' },
- ],
- },
- {
- key: 'page',
- title: '页面背景',
- icon: 'fa fas fa-file',
- fields: [
- { key: 'page_bg_color', label: '内容区背景色', type: 'color', default: '', help: '主内容区域的背景色' },
- { key: 'page_bg_image', label: '内容区背景图', type: 'media' },
- ],
- },
- ],
- },
-
- /**
- * Header components
- */
- 'header-components': {
- key: 'page_display.header-components',
- title: '顶部多功能组件',
- icon: 'fa fas fa-th',
- description: 'Zibll 顶部幻灯、搜索覆盖层和图标卡片的原始字段契约。',
- defaults: {
- header_slider_show: [],
- header_slider_show_type: '',
- header_slider_nav_color: '#ffffff',
- header_slider: [
- { background: themeAsset('assets/vendor/zibll/img/slider-bg.jpg'), link: { url: 'https://www.zibll.com/', target: '_blank' }, text: { desc: '', title: '' }, text_align: 'left-bottom', text_parallax: 30, text_size_m: 20, text_size_pc: 30 },
- { background: themeAsset('assets/vendor/zibll/img/user_t.jpg'), link: { url: 'https://www.zibll.com/', target: '_blank' }, text: { desc: '', title: '' }, text_align: 'left-bottom', text_parallax: 30, text_size_m: 20, text_size_pc: 30 },
- ],
- header_slider_option: { direction: 'horizontal', loop: true, button: true, pagination: true, effect: 'slide', scale_height: false, auto_height: false, pc_height: 550, m_height: 280, spacebetween: 0, speed: 0, autoplay: true, interval: 6 },
- header_slider_search_s: ['pc_s', 'm_s'],
- header_slider_search_option: { show_keywords: true, popular_limit: 6, show_input_cat: false, in_cat: '', more_cats: [], show_type: false, in_type: 'post', before_html: '更优雅的Wordpress主题
\n这是导航栏幻灯片多功能组件,可在后台进行配置
', after_html: '' },
- header_slider_card_s: ['pc_s', 'm_s'],
- header_slider_card_option: { show_widget_bg: false, icon_radius4: false, cards: [
- { icon: 'zibsvg-vip_1', customize_icon: '', icon_class: 'c-yellow', link: {}, title: '图标卡片', desc: '这是一个图标卡片示例' },
- { icon: 'zibsvg-vip_2', customize_icon: '', icon_class: 'c-blue-2', link: {}, title: '原创作品', desc: '这是一个图标卡片示例' },
- { icon: 'zibsvg-hot', customize_icon: '', icon_class: 'jb-pink', link: {}, title: '灵感来源NEW', desc: '这是一个图标卡片示例' },
- { icon: 'fa fas fa-ioxhost', customize_icon: '', icon_class: 'jb-cyan', link: {}, title: '系统工具 GO ', desc: '这是一个图标卡片示例' },
- ] },
- header_slider_filter_blur: ['pc_s', 'm_s'],
- },
- groups: [
- {
- key: 'visibility',
- title: '显示规则',
- icon: 'fa fas fa-eye',
- fields: [
- { key: 'header_slider_show', label: '启用顶部多功能组件的页面', type: 'checkbox', default: [], options: [
- { label: '首页', value: 'home' },
- { label: '分类页', value: 'category' },
- { label: '标签页', value: 'tag' },
- { label: '用户页', value: 'author' },
- { label: '文章页', value: 'single' },
- { label: '搜索页', value: 'search' },
- { label: '其它页面', value: 'page' },
- { label: '专题页', value: 'topics' },
- { label: '论坛首页', value: 'forum_home' },
- { label: '论坛板块', value: 'forum_plate' },
- { label: '论坛帖子', value: 'forum_post' },
- ] },
- { key: 'header_slider_show_type', label: '设备显示规则', type: 'radio', default: '', options: [
- { label: '全部', value: '' },
- { label: '仅电脑', value: 'only_pc' },
- { label: '仅移动', value: 'only_sm' },
- ], dependsOn: { key: 'header_slider_show', not: [] } },
- { key: 'header_slider_nav_color', label: '导航栏文字颜色', type: 'color', default: '#ffffff', dependsOn: { key: 'header_slider_show', not: [] } },
- ],
- },
- {
- key: 'slides',
- title: '背景内容',
- icon: 'fa fas fa-image',
- fields: [
- { key: 'header_slider', label: '幻灯片项目', type: 'json', sanitizeType: 'array', default: [
- { background: themeAsset('assets/vendor/zibll/img/slider-bg.jpg'), link: { url: 'https://www.zibll.com/', target: '_blank' }, text: { desc: '', title: '' }, text_align: 'left-bottom', text_parallax: 30, text_size_m: 20, text_size_pc: 30 },
- { background: themeAsset('assets/vendor/zibll/img/user_t.jpg'), link: { url: 'https://www.zibll.com/', target: '_blank' }, text: { desc: '', title: '' }, text_align: 'left-bottom', text_parallax: 30, text_size_m: 20, text_size_pc: 30 },
- ], help: '原始数组字段:background、background_video、video、hide、link、image_layer、text。' },
- ],
- },
- {
- key: 'slider-config',
- title: '背景显示设置',
- icon: 'fa fas fa-sliders-h',
- fields: [
- { key: 'header_slider_option', label: '幻灯片参数', type: 'json', sanitizeType: 'array', default: { direction: 'horizontal', loop: true, button: true, pagination: true, effect: 'slide', scale_height: false, auto_height: false, pc_height: 550, m_height: 280, spacebetween: 0, speed: 0, autoplay: true, interval: 6 } },
- ],
- },
- {
- key: 'search',
- title: '搜索组件',
- icon: 'fa fas fa-search',
- fields: [
- { key: 'header_slider_search_s', label: '显示设备', type: 'checkbox', default: ['pc_s', 'm_s'], options: [{ label: 'PC 端显示', value: 'pc_s' }, { label: '移动端显示', value: 'm_s' }] },
- { key: 'header_slider_search_option', label: '搜索组件参数', type: 'json', sanitizeType: 'array', default: { show_keywords: true, popular_limit: 6, show_input_cat: false, in_cat: '', more_cats: [], show_type: false, in_type: 'post', before_html: '更优雅的Wordpress主题
\n这是导航栏幻灯片多功能组件,可在后台进行配置
', after_html: '' } },
- ],
- },
- {
- key: 'cards',
- title: '图标卡片组件',
- icon: 'fa fas fa-th-large',
- fields: [
- { key: 'header_slider_card_s', label: '显示设备', type: 'checkbox', default: ['pc_s', 'm_s'], options: [{ label: 'PC 端显示', value: 'pc_s' }, { label: '移动端显示', value: 'm_s' }] },
- { key: 'header_slider_card_option', label: '图标卡片参数', type: 'json', sanitizeType: 'array', default: { show_widget_bg: false, icon_radius4: false, cards: [
- { icon: 'zibsvg-vip_1', customize_icon: '', icon_class: 'c-yellow', link: {}, title: '图标卡片', desc: '这是一个图标卡片示例' },
- { icon: 'zibsvg-vip_2', customize_icon: '', icon_class: 'c-blue-2', link: {}, title: '原创作品', desc: '这是一个图标卡片示例' },
- { icon: 'zibsvg-hot', customize_icon: '', icon_class: 'jb-pink', link: {}, title: '灵感来源NEW', desc: '这是一个图标卡片示例' },
- { icon: 'fa fas fa-ioxhost', customize_icon: '', icon_class: 'jb-cyan', link: {}, title: '系统工具 GO ', desc: '这是一个图标卡片示例' },
- ] } },
- { key: 'header_slider_filter_blur', label: '组件高斯模糊特效', type: 'checkbox', default: ['pc_s', 'm_s'], options: [{ label: 'PC 端开启', value: 'pc_s' }, { label: '移动端开启', value: 'm_s' }] },
- ],
- },
- ],
- },
-
- footer: {
- key: 'page_display.footer',
- title: '底部页脚',
- icon: 'fa fas fa-paw',
- description: '页脚布局、友链、版权信息配置。实际编辑界面在 FooterSettings.vue(customPage),此处为 REST 聚合描述。',
- defaults: {
- footer_columns: 3,
- footer_copyright: true,
- footer_icp: true,
- footer_police: true,
- footer_theme_custom: false,
- footer_theme_bg_custom: '',
- footer_theme_bg: '',
- footer_theme_color_custom: '',
- footer_contact_wechat_img: '',
- footer_contact_qq: '',
- footer_contact_weibo: '',
- footer_contact_email: '',
- footer_t1_m_s: ['pc', 'mobile'],
- footer_t1_img: '',
- footer_t1_img_dark: '',
- footer_t1_t: '',
- fcode_t1_code: '',
- footer_contact_m_s: ['pc', 'mobile'],
- footer_contact_more: '',
- fcode_t2_code_1: '',
- fcode_t2_code_2: '',
- footer_mini_img_m_s: ['pc', 'mobile'],
- footer_mini_img: '',
- fcode_customize_code: '',
- },
- groups: [
- {
- key: 'layout',
- title: '页脚布局',
- icon: 'fa fas fa-columns',
- fields: [
- { key: 'footer_columns', label: '页脚列数', type: 'number', default: 3, min: 1, max: 4 },
- { key: 'footer_copyright', label: '显示版权信息', type: 'switch', default: true },
- { key: 'footer_icp', label: '显示ICP备案', type: 'switch', default: true },
- { key: 'footer_police', label: '显示公安备案', type: 'switch', default: true },
- ],
- },
- {
- key: 'color',
- title: '页脚颜色',
- icon: 'fa fas fa-paint-brush',
- fields: [
- { key: 'footer_theme_custom', label: '自定义页脚颜色', type: 'switch', default: false },
- { key: 'footer_theme_bg_custom', label: '自定义背景色', type: 'color', default: '' },
- { key: 'footer_theme_bg', label: '背景图片', type: 'media', default: '' },
- { key: 'footer_theme_color_custom', label: '自定义文字颜色', type: 'color', default: '' },
- ],
- },
- {
- key: 'contact',
- title: '联系方式',
- icon: 'fa fas fa-address-book',
- fields: [
- { key: 'footer_contact_wechat_img', label: '微信二维码', type: 'media', default: '' },
- { key: 'footer_contact_qq', label: 'QQ', type: 'input', default: '' },
- { key: 'footer_contact_weibo', label: '微博', type: 'input', default: '' },
- { key: 'footer_contact_email', label: '邮箱', type: 'input', default: '' },
- ],
- },
- {
- key: 'brand',
- title: '品牌列(第一列)',
- icon: 'fa fas fa-building',
- fields: [
- { key: 'footer_t1_m_s', label: '显示设备', type: 'checkbox', default: ['pc', 'mobile'] },
- { key: 'footer_t1_img', label: '页脚 Logo(日间)', type: 'media', default: '' },
- { key: 'footer_t1_img_dark', label: '页脚 Logo(夜间)', type: 'media', default: '' },
- { key: 'footer_t1_t', label: '品牌标题', type: 'input', default: '' },
- { key: 'fcode_t1_code', label: '品牌列自定义代码', type: 'textarea', default: '' },
- ],
- },
- {
- key: 'contact_ext',
- title: '联系方式扩展',
- icon: 'fa fas fa-phone',
- fields: [
- { key: 'footer_contact_m_s', label: '显示设备', type: 'checkbox', default: ['pc', 'mobile'] },
- { key: 'footer_contact_more', label: '更多联系项', type: 'textarea', default: '' },
- { key: 'fcode_t2_code_1', label: '链接 HTML(fcode_t2_code_1)', type: 'textarea', default: '' },
- { key: 'fcode_t2_code_2', label: '链接下方自定义代码', type: 'textarea', default: '' },
- ],
- },
- {
- key: 'mini_qr',
- title: '二维码图片组(第三列)',
- icon: 'fa fas fa-qrcode',
- fields: [
- { key: 'footer_mini_img_m_s', label: '显示设备', type: 'checkbox', default: ['pc', 'mobile'] },
- { key: 'footer_mini_img', label: '二维码组', type: 'textarea', default: '' },
- ],
- },
- {
- key: 'custom',
- title: '底部自定义',
- icon: 'fa fas fa-code',
- fields: [
- { key: 'fcode_customize_code', label: '底部自定义代码', type: 'textarea', default: '' },
- ],
- },
- ],
- },
-
- /**
- * Homepage settings (already has a real Vue page)
- */
- homepage: {
- key: 'page_display.homepage',
- title: '首页配置',
- icon: 'fa fas fa-home',
- description: '配置首页主列表、分类 Tab 与首页交互。文章列表视觉统一由文章列表设置控制。',
- defaults: {
- homepage_tabs: [],
- homepage_sidebar_mini_enabled: true,
- homepage_default_sort: 'date',
- homepage_sort_ajax_enabled: true,
- homepage_sticky_tabs_enabled: true,
- home_posts_list_s: true,
- home_list_title: '最新发布',
- home_list_sort_enabled: true,
- home_list_sort_options: ['modified', 'date', 'views', 'likes', 'comments'],
- home_list_sort_dropdown: false,
- home_exclude_post_ids: [],
- home_exclude_category_ids: [],
- homepage_tab_posts_per_page: 6,
- homepage_tab_limit: 4,
- },
- groups: [
- {
- key: 'main-stream',
- title: '主列表',
- icon: 'fa fas fa-list',
- fields: [
- { key: 'home_posts_list_s', label: '启用主列表', type: 'switch', default: true },
- { key: 'index_list_title', label: '区块标题', type: 'input', default: '最新发布', dependsOn: { key: 'home_posts_list_s', value: true } },
- { key: 'home_list1_orderby_option.orderby', label: '默认排序', type: 'select', default: 'date', dependsOn: { key: 'home_posts_list_s', value: true }, options: sortOptions },
- { key: 'home_list1_orderby_s', label: '启用排序栏', type: 'switch', default: true, dependsOn: { key: 'home_posts_list_s', value: true } },
- { key: 'home_list_sort_dropdown', label: '排序栏下拉模式', type: 'switch', default: false, dependsOn: { key: 'home_list1_orderby_s', value: true } },
- { key: 'home_list1_orderby_option', label: '可用排序选项', type: 'checkbox', default: ['modified', 'date', 'views', 'likes', 'comments'], dependsOn: { key: 'home_list1_orderby_s', value: true }, options: sortOptions },
- ],
- },
- {
- key: 'exclude',
- title: '排除规则',
- icon: 'fa fas fa-filter',
- fields: [
- { key: 'home_exclude_posts', label: '排除文章 ID', type: 'array', default: [], help: '主列表和 Tab 查询均排除这些文章。' },
- { key: 'home_exclude_cats', label: '排除分类 ID', type: 'array', default: [], help: '主列表排除这些分类。' },
- ],
- },
- {
- key: 'tabs',
- title: '首页 Tab',
- icon: 'fa fas fa-tags',
- fields: [
- { key: 'home_lists', label: '首页 Tab', type: 'array', default: [], help: '分类 Tab 由 HomepageSettings.vue 中的可视化编辑器维护。' },
- { key: 'homepage_tab_limit', label: 'Tab 数量上限', type: 'number', default: 4, min: 1, max: 12 },
- { key: 'homepage_tab_posts_per_page', label: '每 Tab 文章数', type: 'number', default: 6, min: 1, max: 20 },
- { key: 'homepage_sticky_tabs_enabled', label: 'Tab 吸顶', type: 'switch', default: true },
- ],
- },
- {
- key: 'cards-sidebar',
- title: '侧栏与交互',
- icon: 'fa fas fa-columns',
- fields: [
- { key: 'homepage_sidebar_mini_enabled', label: '迷你侧栏列表', type: 'switch', default: true },
- { key: 'homepage_sort_ajax_enabled', label: '排序栏 AJAX', type: 'switch', default: true },
- ],
- },
- ],
- },
-
-}
diff --git a/assets/admin/src/style.css b/assets/admin/src/style.css
index b3aeaf7a..7de0ae32 100644
--- a/assets/admin/src/style.css
+++ b/assets/admin/src/style.css
@@ -37,7 +37,114 @@
#aksrt-admin-app .aksrt-admin-layout {
min-height: 100vh;
- background: #f5f7fb;
+ background: rgb(249, 250, 252);
+}
+
+#aksrt-admin-app .aksrt-csf-shell .n-layout-sider {
+ background: #fff;
+ border-right: 1px solid #f2f2f2;
+}
+
+#aksrt-admin-app .aksrt-csf-shell .n-menu-item-content {
+ border-bottom: 1px solid #f4f4f4;
+ border-radius: 0;
+}
+
+#aksrt-admin-app .aksrt-csf-shell .n-menu-item-content--selected,
+#aksrt-admin-app .aksrt-csf-shell .n-menu-item-content:hover {
+ color: #0997f5;
+ background: rgb(249, 250, 252);
+}
+
+#aksrt-admin-app .aksrt-schema-page {
+ max-width: none;
+}
+
+#aksrt-admin-app .aksrt-form-renderer__header {
+ margin: -30px -30px 0;
+ padding: 18px 30px;
+ border-bottom: 1px solid #eee;
+ background: #fff;
+}
+
+#aksrt-admin-app .aksrt-form-renderer__title {
+ color: #0991f5;
+ font-size: 19px;
+}
+
+#aksrt-admin-app .aksrt-field-group {
+ margin: 0 -30px;
+ border: 0;
+ border-radius: 0;
+ background: transparent;
+}
+
+#aksrt-admin-app .aksrt-field-group__body {
+ padding: 0;
+}
+
+#aksrt-admin-app .aksrt-field {
+ display: grid;
+ grid-template-columns: minmax(150px, 22%) minmax(0, 1fr);
+ column-gap: 24px;
+ align-items: start;
+ margin: 0;
+ padding: 20px 30px;
+ border-bottom: 1px solid #eee;
+}
+
+#aksrt-admin-app .aksrt-field > :not(.aksrt-field__label-row):not(.aksrt-field__desc):not(.aksrt-field__error) {
+ grid-column: 2;
+}
+
+#aksrt-admin-app .aksrt-field__label-row {
+ grid-column: 1;
+ grid-row: 1;
+ margin: 4px 0 0;
+}
+
+#aksrt-admin-app .aksrt-field__label {
+ color: #0991f5;
+ font-weight: 600;
+}
+
+#aksrt-admin-app .aksrt-field__desc {
+ grid-column: 1;
+ margin: 26px 0 0;
+}
+
+#aksrt-admin-app .aksrt-field--notice {
+ display: block;
+ padding-top: 14px;
+ padding-bottom: 14px;
+ background: #fff8e5;
+}
+
+#aksrt-admin-app .aksrt-field__fieldset .aksrt-field,
+#aksrt-admin-app .aksrt-field__repeater .aksrt-field,
+#aksrt-admin-app .aksrt-field__sortable .aksrt-field {
+ padding: 12px 0;
+ border-bottom-color: #eee;
+}
+
+#aksrt-admin-app .aksrt-field__repeater-item,
+#aksrt-admin-app .aksrt-field__fieldset {
+ border-radius: 2px;
+ background: #fff;
+}
+
+#aksrt-admin-app .aksrt-form-renderer__save-bar {
+ left: auto;
+ right: 0;
+ bottom: 0;
+ border-top: 1px solid #f2f2f2;
+ background: rgba(255, 255, 255, .96);
+}
+
+#aksrt-admin-app .aksrt-form-renderer__save-bar .n-button--primary-type {
+ border-radius: 30px;
+ background-image: linear-gradient(135deg, #65bff7 10%, #0d67b9 100%);
+ box-shadow: -1px 2px 10px rgba(1, 65, 139, .3);
}
#aksrt-admin-app .aksrt-page-container,
@@ -253,6 +360,24 @@
padding: 0;
}
+ #aksrt-admin-app .aksrt-form-renderer__header {
+ margin: -14px -12px 0;
+ padding: 14px 16px;
+ }
+
+ #aksrt-admin-app .aksrt-field-group {
+ margin: 0 -12px;
+ }
+
+ #aksrt-admin-app .aksrt-field {
+ display: block;
+ padding: 16px;
+ }
+
+ #aksrt-admin-app .aksrt-field__desc {
+ margin: 2px 0 8px;
+ }
+
#aksrt-admin-app .aksrt-page-title {
font-size: 18px;
margin-bottom: 8px;
diff --git a/assets/admin/src/utils/home-module-schema.js b/assets/admin/src/utils/home-module-schema.js
deleted file mode 100644
index e945003d..00000000
--- a/assets/admin/src/utils/home-module-schema.js
+++ /dev/null
@@ -1,491 +0,0 @@
-/**
- * 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 = [
- '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: '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' },
- ],
- },
- ],
- },
- {
- type: 'tabs',
- label: '分类 Tabs',
- icon: 'switcher',
- desc: '多分类 Tab 切换',
- defaultConfig: { cat_ids: [], count: 8, layout: 'card', 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' },
- ],
- },
- ],
- },
- {
- 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' },
- ],
- },
- ],
- },
- {
- 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: 'Tabs + 最新文章 + 下载排行;头部幻灯由导航系统独立渲染',
- modules: [
- { type: 'tabs', config: { count: 8, layout: 'card' } },
- { type: 'recent', config: { count: 8, layout: 'card' } },
- { 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: '最新文章 + 多个分类块;头部幻灯由导航系统独立渲染',
- modules: [
- { 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: '标题 + 高亮卡片 + FAQ + 按钮组',
- modules: [
- { 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: '数据网格 + 产品展示 + 合作伙伴',
- modules: [
- { type: 'data_grid', config: { title: '核心数据', columns: 4, style: 'number' } },
- { type: 'product_showcase', config: { title: '产品展示', columns: 3 } },
- { type: 'partner_marquee', config: { title: '合作伙伴', speed: 30 } },
- ],
- },
-]
diff --git a/assets/css/frontend/header-components/widget-device-visibility.css b/assets/css/frontend/header-components/widget-device-visibility.css
index 3508014c..8dea9eb1 100644
--- a/assets/css/frontend/header-components/widget-device-visibility.css
+++ b/assets/css/frontend/header-components/widget-device-visibility.css
@@ -11,14 +11,6 @@
}
}
-/* CMS freeform: do NOT pull the whole container — nav pull is only on .slide-header
- * (zibll body.nav-fixed .slide-header). Whole-container pull made homepage cards
- * differ from other page types that share the same component. */
-.home-modules > .header-components-container:first-child,
-.home-modules--fullbleed > .header-components-container:first-child {
- margin-top: 0;
-}
-
/* Fixed homepage hero under-nav is owned by Zibll main.css. */
/* ============================================================
diff --git a/assets/css/frontend/home-modules.css b/assets/css/frontend/home-modules.css
deleted file mode 100644
index 94cbed32..00000000
--- a/assets/css/frontend/home-modules.css
+++ /dev/null
@@ -1,16 +0,0 @@
-@import url("home-modules/base.css");
-@import url("home-modules/tabs.css");
-@import url("home-modules/tag-cloud.css");
-@import url("home-modules/ranking.css");
-@import url("home-modules/friend-links.css");
-@import url("home-modules/html-module.css");
-@import url("home-modules/responsive.css");
-@import url("home-modules/text-title.css");
-@import url("home-modules/button-group.css");
-@import url("home-modules/spacing.css");
-@import url("home-modules/faq.css");
-@import url("home-modules/data-grid.css");
-@import url("home-modules/highlight-cards.css");
-@import url("home-modules/partner-marquee.css");
-@import url("home-modules/product-showcase.css");
-@import url("home-modules/user-cards.css");
diff --git a/assets/css/frontend/home-modules/base.css b/assets/css/frontend/home-modules/base.css
deleted file mode 100644
index 3018ada0..00000000
--- a/assets/css/frontend/home-modules/base.css
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Home Modules · CMS 形态首页模块系统样式
- *
- * 仅在 site_profile=cms 时(首页)加载。
- *
- * 宽度模型:
- * - .home-modules > .home-module 锁定到 --container(默认 1280)
- * - .home-modules > .hero 走 full-bleed(不在此处约束)
- * - banner 模块的精细微调见 hero.css `.banner-slider.home-modules__banner`
- */
-
-.home-modules {
- display: flex;
- flex-direction: column;
- gap: var(--space-8, 40px);
- padding-bottom: var(--space-8, 40px);
-}
-
-.home-modules--fullbleed {
- width: 100%;
-}
-
-.home-modules--fullbleed > .home-module {
- max-width: 100%;
- padding-left: 0;
- padding-right: 0;
-}
-
-/* 容器宽度统一:所有非 hero 的 home-module 都对齐到 --container */
-.home-modules > .home-module {
- width: 100%;
- max-width: var(--container);
- margin-left: auto;
- margin-right: auto;
- padding-left: 16px;
- padding-right: 16px;
- box-sizing: border-box;
-}
-
-@media (min-width: 768px) {
- .home-modules > .home-module {
- padding-left: 24px;
- padding-right: 24px;
- }
-}
-
-/* ============ 公共 header ============ */
-.home-module__header {
- display: flex;
- align-items: center;
- justify-content: space-between;
- gap: var(--space-3, 12px);
- margin-bottom: var(--space-5, 20px);
- padding-bottom: var(--space-3, 12px);
- border-bottom: 1px solid var(--color-line-soft);
-}
-
-.home-module__title {
- display: flex;
- align-items: center;
- gap: 8px;
- font: 700 22px/1.2 var(--font-display);
- margin: 0;
- color: var(--color-ink);
-}
-
-.home-module__title i {
- color: var(--color-primary);
-}
-
-.home-module__more {
- display: inline-flex;
- align-items: center;
- gap: 4px;
- font: 500 13px/1 var(--font-ui);
- color: var(--color-primary);
- text-decoration: none;
-}
-
-.home-module__more:hover {
- color: var(--color-primary-active);
-}
-
-.home-module__admin-tools {
- display: flex;
- justify-content: flex-end;
- margin-top: 14px;
-}
-
diff --git a/assets/css/frontend/home-modules/button-group.css b/assets/css/frontend/home-modules/button-group.css
deleted file mode 100644
index 035a5607..00000000
--- a/assets/css/frontend/home-modules/button-group.css
+++ /dev/null
@@ -1,47 +0,0 @@
-/* Button Group */
-.home-module--button-group {
- padding: 32px 0;
-}
-
-.home-module__buttons {
- display: flex;
- flex-wrap: wrap;
- justify-content: center;
- gap: 12px;
- margin-top: 16px;
-}
-
-.aksrt-btn {
- display: inline-flex;
- align-items: center;
- gap: 6px;
- padding: 10px 24px;
- border-radius: var(--radius-btn, 4px);
- font-size: 14px;
- font-weight: 500;
- text-decoration: none;
- transition: opacity 0.2s, transform 0.2s, box-shadow 0.2s, background 0.2s;
-}
-
-.aksrt-btn:hover {
- opacity: 1;
- transform: translateY(-1px);
-}
-
-.aksrt-btn--primary {
- background: var(--color-primary);
- color: #fff;
- box-shadow: 0 8px 18px rgba(240, 68, 148, 0.22);
-}
-
-.aksrt-btn--outline {
- background: var(--surface-1);
- color: var(--color-primary);
- border: 1px solid var(--color-primary);
-}
-
-.aksrt-btn--ghost {
- background: var(--surface-4);
- color: var(--color-ink);
-}
-
diff --git a/assets/css/frontend/home-modules/data-grid.css b/assets/css/frontend/home-modules/data-grid.css
deleted file mode 100644
index 11383db7..00000000
--- a/assets/css/frontend/home-modules/data-grid.css
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Data Grid */
-.home-module--data-grid {
- padding: 32px 0;
-}
-
-.home-module__data-grid {
- display: grid;
- gap: 16px;
- text-align: center;
-}
-
-.aksrt-data-cell {
- padding: 24px 16px;
- background: var(--surface-1, #fff);
- border-radius: var(--main-radius, var(--radius, 8px));
- border: none;
- box-shadow: var(--shadow-sm);
- transition: box-shadow 0.2s ease;
-}
-
-.aksrt-data-cell:hover {
- box-shadow: var(--shadow);
- transform: none;
-}
-
-.aksrt-data-cell i {
- font-size: 24px;
- color: var(--color-primary);
- margin-bottom: 8px;
- display: block;
-}
-
-.aksrt-data-cell__value {
- font-size: 28px;
- font-weight: 700;
- color: var(--color-ink);
- display: block;
- margin-bottom: 4px;
-}
-
-.aksrt-data-cell__label {
- font-size: 13px;
- color: var(--color-ink-3);
-}
-
diff --git a/assets/css/frontend/home-modules/faq.css b/assets/css/frontend/home-modules/faq.css
deleted file mode 100644
index 57193228..00000000
--- a/assets/css/frontend/home-modules/faq.css
+++ /dev/null
@@ -1,56 +0,0 @@
-/* FAQ */
-.home-module--faq {
- padding: 32px 0;
-}
-
-.home-module__faq-grid {
- column-gap: 24px;
-}
-
-.aksrt-faq-item {
- break-inside: avoid;
- margin-bottom: 12px;
- border: none;
- border-radius: var(--main-radius, var(--radius, 8px));
- box-shadow: var(--shadow-sm);
- overflow: hidden;
- background: var(--surface-1, #fff);
-}
-
-.aksrt-faq-item__question {
- padding: 14px 16px;
- font-size: 15px;
- font-weight: 600;
- cursor: pointer;
- background: var(--surface-1, #fff);
- list-style: none;
- transition: color .18s ease, background .18s ease;
-}
-
-.aksrt-faq-item__question:hover {
- color: var(--color-primary);
- background: var(--surface-4);
-}
-
-.aksrt-faq-item__question::-webkit-details-marker {
- display: none;
-}
-
-.aksrt-faq-item__question::after {
- content: '+';
- float: right;
- font-weight: 400;
- transition: transform 0.2s;
-}
-
-.aksrt-faq-item[open] .aksrt-faq-item__question::after {
- content: '−';
-}
-
-.aksrt-faq-item__answer {
- padding: 0 16px 14px;
- font-size: 14px;
- color: var(--color-ink-3);
- line-height: 1.7;
-}
-
diff --git a/assets/css/frontend/home-modules/friend-links.css b/assets/css/frontend/home-modules/friend-links.css
deleted file mode 100644
index edba99c8..00000000
--- a/assets/css/frontend/home-modules/friend-links.css
+++ /dev/null
@@ -1,56 +0,0 @@
-/* ============ Friend Links ============ */
-.home-module__friends-list {
- list-style: none;
- margin: 0;
- padding: 0;
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
- gap: var(--space-3, 12px);
-}
-
-.home-module__friend-card {
- display: flex;
- align-items: center;
- gap: var(--space-3, 12px);
- padding: 12px;
- border-radius: var(--main-radius, var(--radius, 8px));
- border: none;
- box-shadow: var(--shadow-sm);
- background: var(--surface-1);
- color: var(--color-ink);
- text-decoration: none;
- transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
-}
-
-.home-module__friend-card:hover {
- box-shadow: var(--shadow);
- transform: translateY(-1px);
-}
-
-.home-module__friend-avatar {
- width: 40px;
- height: 40px;
- border-radius: 50%;
- object-fit: cover;
- flex: 0 0 40px;
-}
-
-.home-module__friend-meta {
- display: flex;
- flex-direction: column;
- gap: 2px;
- min-width: 0;
-}
-
-.home-module__friend-meta strong {
- font: 600 14px/1.2 var(--font-ui);
-}
-
-.home-module__friend-meta span {
- font-size: 12px;
- color: var(--color-ink-3);
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
diff --git a/assets/css/frontend/home-modules/highlight-cards.css b/assets/css/frontend/home-modules/highlight-cards.css
deleted file mode 100644
index ada42764..00000000
--- a/assets/css/frontend/home-modules/highlight-cards.css
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Highlight Cards */
-.home-module--highlight-cards {
- padding: 32px 0;
-}
-
-.home-module__highlight-grid {
- display: grid;
- gap: 16px;
-}
-
-.aksrt-highlight-card {
- padding: 24px;
- background: var(--surface-1, #fff);
- border-radius: var(--main-radius, var(--radius, 8px));
- border: none;
- box-shadow: var(--shadow-sm);
- text-decoration: none;
- color: inherit;
- transition: box-shadow 0.2s ease;
-}
-
-.aksrt-highlight-card:hover {
- box-shadow: var(--shadow);
- transform: none;
-}
-
-.aksrt-highlight-card__image {
- width: 100%;
- border-radius: var(--radius-sm, 4px);
- margin-bottom: 12px;
-}
-
-.aksrt-highlight-card__icon {
- width: 48px;
- height: 48px;
- display: flex;
- align-items: center;
- justify-content: center;
- border-radius: var(--radius-md, 8px);
- background: var(--color-primary-softer);
- color: var(--color-primary);
- font-size: 20px;
- margin-bottom: 12px;
-}
-
-.aksrt-highlight-card__title {
- font-size: 16px;
- font-weight: 600;
- margin: 0 0 8px;
-}
-
-.aksrt-highlight-card__desc {
- font-size: 13px;
- color: var(--color-ink-3);
- margin: 0;
- line-height: 1.6;
-}
-
diff --git a/assets/css/frontend/home-modules/html-module.css b/assets/css/frontend/home-modules/html-module.css
deleted file mode 100644
index 6439d3e8..00000000
--- a/assets/css/frontend/home-modules/html-module.css
+++ /dev/null
@@ -1,12 +0,0 @@
-/* ============ HTML Module ============ */
-.home-module--html .home-module__html-body {
- color: var(--color-ink);
- font-size: 15px;
- line-height: 1.75;
- padding: 20px 22px;
- background: var(--surface-1);
- border: none;
- border-radius: var(--radius-2xl, 16px);
- box-shadow: var(--shadow-sm);
-}
-
diff --git a/assets/css/frontend/home-modules/partner-marquee.css b/assets/css/frontend/home-modules/partner-marquee.css
deleted file mode 100644
index 09e16d1a..00000000
--- a/assets/css/frontend/home-modules/partner-marquee.css
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Partner Marquee */
-.home-module--partner-marquee {
- padding: 32px 0;
- overflow: hidden;
-}
-
-.aksrt-marquee {
- overflow: hidden;
- width: 100%;
-}
-
-.aksrt-marquee__track {
- display: flex;
- gap: 32px;
- width: max-content;
- animation: aksrt-marquee-scroll var(--marquee-duration, 30s) linear infinite;
-}
-
-.aksrt-marquee__item {
- flex-shrink: 0;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 10px 18px;
- border-radius: var(--main-radius, var(--radius, 8px));
- background: var(--surface-1);
- border: none;
- box-shadow: var(--shadow-sm);
-}
-
-.aksrt-marquee__item img {
- height: 40px;
- width: auto;
- opacity: 0.7;
- transition: opacity 0.2s;
-}
-
-.aksrt-marquee__item:hover img {
- opacity: 1;
-}
-
-@keyframes aksrt-marquee-scroll {
- 0% { transform: translateX(0); }
- 100% { transform: translateX(-50%); }
-}
-
diff --git a/assets/css/frontend/home-modules/product-showcase.css b/assets/css/frontend/home-modules/product-showcase.css
deleted file mode 100644
index 6fe0b42c..00000000
--- a/assets/css/frontend/home-modules/product-showcase.css
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Product Showcase */
-.home-module--product-showcase {
- padding: 32px 0;
-}
-
-.home-module__product-grid {
- display: grid;
- gap: 16px;
-}
-
-.aksrt-product-card {
- background: var(--surface-1, #fff);
- border-radius: var(--radius, 8px);
- border: none;
- box-shadow: var(--shadow-sm);
- overflow: hidden;
- text-decoration: none;
- color: inherit;
- transition: box-shadow 0.2s ease;
-}
-
-.aksrt-product-card:hover {
- box-shadow: var(--shadow);
-}
-
-.aksrt-product-card__image img {
- width: 100%;
- aspect-ratio: 1 / 1;
- object-fit: cover;
- border-radius: var(--radius, 8px) var(--radius, 8px) 0 0;
- display: block;
-}
-
-.aksrt-product-card__body {
- padding: 15px;
-}
-
-.aksrt-product-card__title {
- font-size: 16px;
- font-weight: 600;
- margin: 0 0 6px;
-}
-
-.aksrt-product-card__desc {
- font-size: 13px;
- color: var(--color-ink-3);
- margin: 0 0 8px;
- line-height: 1.5;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
-}
-
-.aksrt-product-card__price {
- font-size: 18px;
- font-weight: 700;
- color: var(--color-error);
-}
-
diff --git a/assets/css/frontend/home-modules/ranking.css b/assets/css/frontend/home-modules/ranking.css
deleted file mode 100644
index db9f00f0..00000000
--- a/assets/css/frontend/home-modules/ranking.css
+++ /dev/null
@@ -1,67 +0,0 @@
-/* ============ Ranking ============ */
-.home-module__ranking-list {
- list-style: none;
- margin: 0;
- padding: 0;
- display: grid;
- grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
- gap: var(--space-3, 12px);
-}
-
-.home-module__ranking-item {
- display: flex;
- align-items: center;
- gap: var(--space-3, 12px);
- padding: 12px 14px;
- background: var(--surface-1);
- border: none;
- border-radius: var(--main-radius, var(--radius, 8px));
- box-shadow: var(--shadow-sm);
- transition: box-shadow .18s ease, border-color .18s ease, transform .18s ease;
-}
-
-.home-module__ranking-item:hover {
- box-shadow: var(--shadow);
- transform: none;
-}
-
-.home-module__ranking-num {
- flex: 0 0 32px;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- border-radius: 50%;
- background: var(--surface-2);
- color: var(--color-ink-3);
- font: 700 13px/1 var(--font-ui);
-}
-
-.home-module__ranking-item--top .home-module__ranking-num {
- background: linear-gradient(135deg, #f59e0b 0%, #f97316 100%);
- color: #fff;
- box-shadow: 0 4px 8px rgba(245, 158, 11, .25);
-}
-
-.home-module__ranking-link {
- flex: 1 1 auto;
- color: var(--color-ink);
- text-decoration: none;
- font: 500 14px/1.4 var(--font-ui);
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.home-module__ranking-link:hover {
- color: var(--color-primary);
-}
-
-.home-module__ranking-value {
- flex: 0 0 auto;
- color: var(--color-ink-3);
- font-variant-numeric: tabular-nums;
- font: 500 12px/1 var(--font-ui);
-}
-
diff --git a/assets/css/frontend/home-modules/responsive.css b/assets/css/frontend/home-modules/responsive.css
deleted file mode 100644
index c52ac1ec..00000000
--- a/assets/css/frontend/home-modules/responsive.css
+++ /dev/null
@@ -1,278 +0,0 @@
-/* ============ Responsive ============ */
-@media (max-width: 640px) {
- .home-modules {
- gap: var(--space-7, 32px);
- }
- .home-module__header {
- flex-wrap: wrap;
- }
- .home-module__title {
- font-size: 18px;
- }
-}
-
-/* ============ Hotspot 热点推荐 ============ */
-
-/* 手机端隐藏 */
-.hotspot--desktop-only {
- display: none;
-}
-
-@media (min-width: 768px) {
- .hotspot--desktop-only {
- display: block;
- }
-}
-
-.hotspot__list {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-.hotspot__item {
- display: flex;
- align-items: flex-start;
- gap: var(--space-4, 16px);
- padding: var(--space-4, 16px) 0;
- border-bottom: 1px solid var(--color-line);
-}
-
-.hotspot__item:last-child {
- border-bottom: none;
-}
-
-.hotspot__num {
- flex: 0 0 32px;
- display: inline-flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- border-radius: var(--radius-avatar, 50%);
- font: 700 13px/1 var(--font-ui);
- background: var(--surface-2);
- color: var(--color-ink-3);
-}
-
-.hotspot__num--top {
- background: var(--color-primary);
- color: var(--color-on-primary, #fff);
-}
-
-.hotspot__body {
- flex: 1;
- min-width: 0;
-}
-
-.hotspot__title {
- display: block;
- font: 600 15px/1.4 var(--font-ui);
- color: var(--color-ink);
- text-decoration: none;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- transition: color 0.18s ease;
-}
-
-.hotspot__title:hover {
- color: var(--color-primary);
-}
-
-.hotspot__meta {
- display: flex;
- align-items: center;
- gap: var(--space-3, 12px);
- margin-top: var(--space-2, 8px);
- font: 400 12px/1 var(--font-ui);
- color: var(--color-ink-3);
-}
-
-.hotspot__cat {
- display: inline-block;
- padding: 2px 8px;
- border-radius: var(--radius-pill, 999px);
- background: var(--surface-2);
- font-size: 11px;
- font-weight: 500;
-}
-
-/* ============ 分类推荐卡片 ============ */
-
-.cat-cards-grid {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 20px;
-}
-
-.cat-card {
- background: var(--surface-2, #fff);
- border-radius: 10px;
- padding: 22px;
- box-shadow: 0 1px 6px rgba(0, 0, 0, 0.08);
- transition: box-shadow 0.2s ease, border-color 0.2s ease;
-}
-
-.cat-card:hover {
- box-shadow: var(--shadow-md);
-}
-
-/* 上部:封面 + 信息 */
-.cat-card__top {
- display: flex;
- align-items: flex-start;
- gap: 18px;
- margin-bottom: 18px;
-}
-
-.cat-card__banner {
- width: 145px;
- height: 95px;
- border-radius: 8px;
- overflow: hidden;
- position: relative;
- flex-shrink: 0;
- background: var(--surface-3, #f5f5f5);
-}
-
-.cat-card__cover {
- width: 100%;
- height: 100%;
- object-fit: cover;
- display: block;
- transition: transform 0.3s ease;
-}
-
-.cat-card:hover .cat-card__cover {
- transform: scale(1.02);
-}
-
-/* 浏览量胶囊:红底白字 */
-.cat-card__views {
- position: absolute;
- top: 8px;
- right: 8px;
- background: #f54343;
- color: #fff;
- font-size: 12px;
- font-weight: 600;
- padding: 2px 7px;
- border-radius: 15px;
- pointer-events: none;
- z-index: 1;
-}
-
-.cat-card__info {
- flex: 1;
- height: 95px;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-}
-
-.cat-card__name {
- font-size: 19px;
- font-weight: 600;
- color: var(--color-ink);
- line-height: 1.3;
-}
-
-.cat-card__desc {
- font-size: 13px;
- color: var(--color-ink-3);
- margin-top: 4px;
- line-height: 1.5;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
-}
-
-.cat-card__foot {
- display: flex;
- justify-content: space-between;
- align-items: center;
- font-size: 13px;
- color: var(--color-ink-4);
-}
-
-.cat-card__more {
- color: var(--color-primary);
- text-decoration: none;
- font-weight: 500;
-}
-
-.cat-card__more:hover {
- text-decoration: underline;
-}
-
-/* 下部:文章列表 */
-.cat-card__list {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-.cat-card__list li {
- display: flex;
- align-items: flex-start;
- font-size: 13.5px;
- color: var(--color-ink);
- line-height: 1.6;
- padding: 5px 0;
-}
-
-.cat-card__list li::before {
- content: "\25CF";
- color: var(--color-primary);
- font-size: 10px;
- margin-right: 8px;
- margin-top: 3px;
- flex-shrink: 0;
-}
-
-.cat-card__list li a {
- color: inherit;
- text-decoration: none;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- flex: 1;
- min-width: 0;
- transition: color 0.15s ease;
-}
-
-.cat-card__list li a:hover {
- color: var(--color-primary);
-}
-
-.cat-card__time {
- color: var(--color-ink-4);
- font-size: 12px;
- margin-left: auto;
- padding-left: 12px;
- white-space: nowrap;
- flex-shrink: 0;
-}
-
-/* 响应式 */
-@media (max-width: 767px) {
- .cat-cards-grid {
- grid-template-columns: 1fr;
- gap: 16px;
- }
-
- .cat-card__name {
- font-size: 16px;
- }
-
- .cat-card__info {
- height: auto;
- min-height: 95px;
- }
-}
-
-/* ============================================================
- * Phase 5: 运营型模块样式
- * ============================================================ */
diff --git a/assets/css/frontend/home-modules/spacing.css b/assets/css/frontend/home-modules/spacing.css
deleted file mode 100644
index c03325ac..00000000
--- a/assets/css/frontend/home-modules/spacing.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Spacing */
-.home-module--spacing {
- pointer-events: none;
-}
-
diff --git a/assets/css/frontend/home-modules/tabs.css b/assets/css/frontend/home-modules/tabs.css
deleted file mode 100644
index 3f22d00d..00000000
--- a/assets/css/frontend/home-modules/tabs.css
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ============ Tabs ============ */
-.home-module__header--tabs {
- flex-wrap: wrap;
- border-bottom: 0;
- padding-bottom: 0;
-}
-
-.home-module__tabs {
- display: flex;
- flex-wrap: wrap;
- gap: var(--space-2, 8px);
- border-bottom: 1px solid var(--color-line-soft);
- margin-top: var(--space-3, 12px);
- padding-bottom: 12px;
- width: 100%;
-}
-
-.home-module__tab {
- background: transparent;
- border: 0;
- padding: 9px 18px;
- font: 500 14px/1 var(--font-ui);
- color: var(--color-ink-3);
- cursor: pointer;
- border-radius: 999px;
- border-bottom: 0;
- transition: color .18s ease, border-color .18s ease, background .18s ease;
-}
-
-.home-module__tab:hover {
- color: var(--color-ink);
- background: var(--surface-4);
-}
-
-.home-module__tab.is-active {
- color: var(--color-primary);
- background: var(--color-primary-soft);
- box-shadow: inset 0 0 0 1px rgba(240, 68, 148, 0.08);
-}
-
-.home-module__tab-panel {
- margin-top: var(--space-5, 20px);
-}
-
-.index-tab-main .home-module__tab-panel.tab-pane[hidden],
-.home-tab-content .home-module__tab-panel.tab-pane[hidden] {
- display: none;
-}
-
-.home-module__tab-panel[hidden] {
- display: none;
-}
-
-.home-module__empty {
- color: var(--color-ink-3);
- text-align: center;
- padding: var(--space-7, 32px) 0;
-}
-
diff --git a/assets/css/frontend/home-modules/tag-cloud.css b/assets/css/frontend/home-modules/tag-cloud.css
deleted file mode 100644
index 424e4849..00000000
--- a/assets/css/frontend/home-modules/tag-cloud.css
+++ /dev/null
@@ -1,34 +0,0 @@
-/* ============ Tag Cloud ============ */
-.home-module__tag-cloud {
- list-style: none;
- margin: 0;
- padding: 0;
- display: flex;
- flex-wrap: wrap;
- gap: var(--space-2, 8px);
-}
-
-.home-module__tag {
- display: inline-flex;
- align-items: center;
- gap: 6px;
- padding: 6px 12px;
- border-radius: var(--radius-pill);
- background: var(--surface-4);
- color: var(--color-ink-2);
- font: 500 13px/1 var(--font-ui);
- text-decoration: none;
- transition: background .18s ease, color .18s ease, box-shadow .18s ease;
-}
-
-.home-module__tag:hover {
- background: var(--color-primary-soft);
- color: var(--color-primary);
- box-shadow: inset 0 0 0 1px rgba(240, 68, 148, 0.08);
-}
-
-.home-module__tag-count {
- font-variant-numeric: tabular-nums;
- opacity: .7;
-}
-
diff --git a/assets/css/frontend/home-modules/text-title.css b/assets/css/frontend/home-modules/text-title.css
deleted file mode 100644
index 3a6782e9..00000000
--- a/assets/css/frontend/home-modules/text-title.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/* Text Title */
-.home-module--text-title {
- padding: 24px 0;
-}
-
-.home-module--text-title .home-module__title {
- font-size: 28px;
- font-weight: 700;
- margin: 0 0 8px;
-}
-
-.home-module--text-title .home-module__subtitle {
- font-size: 15px;
- color: var(--color-ink-3);
- margin: 0;
-}
-
diff --git a/assets/css/frontend/home-modules/user-cards.css b/assets/css/frontend/home-modules/user-cards.css
deleted file mode 100644
index 89165e85..00000000
--- a/assets/css/frontend/home-modules/user-cards.css
+++ /dev/null
@@ -1,180 +0,0 @@
-/* ============ User Cards ============ */
-.home-module__users-grid {
- display: grid;
- grid-template-columns: repeat(var(--cols, 4), 1fr);
- gap: var(--space-4, 16px);
-}
-
-.home-module__user-card {
- display: flex;
- flex-direction: column;
- align-items: center;
- text-align: center;
- padding: 20px 15px;
- border-radius: var(--radius, 8px);
- border: none;
- background: var(--surface-1);
- box-shadow: var(--shadow-sm);
- transition: box-shadow 0.2s ease;
-}
-
-.home-module__user-card:hover {
- box-shadow: var(--shadow);
-}
-
-.home-module__user-link {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 8px;
- text-decoration: none;
- color: var(--color-ink);
-}
-
-.home-module__user-avatar {
- width: 64px;
- height: 64px;
- border-radius: 50%;
- object-fit: cover;
-}
-
-.home-module__user-name {
- font: 600 14px/1.2 var(--font-ui);
-}
-
-.home-module__user-bio {
- font-size: 12px;
- color: var(--color-ink-3);
- margin: 4px 0 0;
- line-height: 1.4;
- display: -webkit-box;
- -webkit-line-clamp: 2;
- -webkit-box-orient: vertical;
- overflow: hidden;
-}
-
-.home-module__user-stats {
- display: flex;
- gap: 12px;
- margin-top: 8px;
- font-size: 12px;
- color: var(--color-ink-2);
-}
-
-.home-module__user-stat {
- display: inline-flex;
- align-items: center;
- gap: 4px;
-}
-
-.home-module__user-stat i {
- font-size: 11px;
- color: var(--color-ink-3);
-}
-
-/* ============ More (Discover Categories) ============ */
-.home-module__more-grid {
- display: grid;
- grid-template-columns: repeat(var(--cols, 3), 1fr);
- gap: var(--space-4, 16px);
-}
-
-.home-module__more-card {
- border-radius: var(--radius);
- border: 1px solid var(--color-line);
- background: var(--surface-1);
- overflow: hidden;
- transition: border-color .18s ease, transform .18s ease;
-}
-
-.home-module__more-card:hover {
- border-color: var(--color-line);
- transform: none;
-}
-
-.home-module__more-link {
- display: block;
- text-decoration: none;
- color: inherit;
-}
-
-.home-module__more-cover {
- aspect-ratio: 16 / 9;
- overflow: hidden;
- background: var(--color-fill-2);
-}
-
-.home-module__more-cover img {
- width: 100%;
- height: 100%;
- object-fit: cover;
-}
-
-.home-module__more-cover--placeholder {
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 28px;
- color: var(--color-ink-3);
-}
-
-.home-module__more-body {
- padding: 12px;
- display: flex;
- flex-direction: column;
- gap: 2px;
-}
-
-.home-module__more-name {
- font: 600 14px/1.3 var(--font-ui);
-}
-
-.home-module__more-count {
- font-size: 12px;
- color: var(--color-ink-3);
-}
-
-.home-module__more-posts {
- list-style: none;
- margin: 0;
- padding: 0 12px 12px;
-}
-
-.home-module__more-posts li {
- border-top: 1px solid var(--color-line-light, rgba(0,0,0,.06));
-}
-
-.home-module__more-posts a {
- display: block;
- padding: 6px 0;
- font-size: 13px;
- color: var(--color-ink-2);
- text-decoration: none;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- transition: color .15s ease;
-}
-
-.home-module__more-posts a:hover {
- color: var(--color-primary);
-}
-
-/* 响应式 */
-@media (max-width: 767px) {
- .home-module__data-grid,
- .home-module__highlight-grid,
- .home-module__product-grid {
- grid-template-columns: 1fr !important;
- }
-
- .home-module__faq-grid {
- column-count: 1 !important;
- }
-
- .home-module__users-grid,
- .home-module__more-grid {
- grid-template-columns: 1fr 1fr !important;
- }
-}
-
diff --git a/assets/css/frontend/homepage-fixed/base-1.css b/assets/css/frontend/homepage-fixed/base-1.css
index e8fcff4d..cad7602b 100644
--- a/assets/css/frontend/homepage-fixed/base-1.css
+++ b/assets/css/frontend/homepage-fixed/base-1.css
@@ -127,22 +127,10 @@
margin-bottom: 20px;
}
-.aksrt-homepage__content-zone--operated.home-modules,
-.aksrt-homepage__content-zone--mid.home-modules,
-.aksrt-homepage__content-zone--supplement.home-modules {
- gap: 24px;
- padding-bottom: 0;
-}
-
.aksrt-homepage__content-zone--supplement {
padding-top: 4px;
}
-.aksrt-homepage__content-zone--featured.home-modules {
- gap: 24px;
- padding-bottom: 0;
-}
-
.aksrt-homepage__content-zone .widget-card:last-child,
.aksrt-homepage__aside .widget:last-child,
.aksrt-homepage__fluid-zone .widget-fluid:last-child {
diff --git a/assets/css/frontend/layout.css b/assets/css/frontend/layout.css
index 57cf54b7..12a8eea3 100644
--- a/assets/css/frontend/layout.css
+++ b/assets/css/frontend/layout.css
@@ -593,38 +593,10 @@ body.site-layout-3 .sidebar,
}
}
-/* CMS 模块在侧栏布局中的适配 */
.content-layout__primary--cms {
min-width: 0;
}
-.content-layout__primary--cms .home-modules {
- gap: var(--space-7, 32px);
-}
-
-.content-layout__primary--cms .home-modules > .home-module {
- max-width: 100%;
- padding-left: 0;
- padding-right: 0;
-}
-
-/* ============================================================
- * Phase 2 — 背景遮罩层级修正
- * body.aksrt-bg-overlay 的 ::before 需要 z-index: -1 让内容在其上方
- * ============================================================ */
-body.aksrt-bg-overlay {
- position: relative;
-}
-
-body.aksrt-bg-overlay::before {
- z-index: -1;
-}
-
-body.aksrt-bg-overlay .site-wrapper {
- position: relative;
- z-index: 0;
-}
-
/* ============================================================
* Phase 2 — 侧栏 widget 内链接增强
* ============================================================ */
diff --git a/assets/css/frontend/theme-background.css b/assets/css/frontend/theme-background.css
deleted file mode 100644
index 26da137f..00000000
--- a/assets/css/frontend/theme-background.css
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * AKSRT Theme Background System
- *
- * 全局背景图、夜间背景图、页面背景色/背景图。
- * 所有选择器均带 aksrt- 命名空间。
- */
-
-/* ========== 全局背景 ========== */
-.aksrt-bg-body {
- background-color: var(--aksrt-bg-color, transparent);
- background-image: var(--aksrt-bg-image, none);
- background-size: var(--aksrt-bg-size, cover);
- background-position: var(--aksrt-bg-position, center center);
- background-repeat: var(--aksrt-bg-repeat, no-repeat);
- background-attachment: var(--aksrt-bg-attachment, fixed);
-}
-
-/* ========== 夜间模式背景 ========== */
-.aksrt-bg-dark {
- background-color: var(--aksrt-bg-dark-color, transparent);
- background-image: var(--aksrt-bg-dark-image, none);
-}
-
-/* ========== 页面级背景 ========== */
-.aksrt-bg-page {
- background-color: var(--aksrt-page-bg-color, transparent);
- background-image: var(--aksrt-page-bg-image, none);
- background-size: cover;
- background-position: center center;
- background-repeat: no-repeat;
-}
-
-/* ========== 模块级背景 ========== */
-.aksrt-bg-module {
- background-color: var(--aksrt-module-bg-color, transparent);
- background-image: var(--aksrt-module-bg-image, none);
- background-size: cover;
- background-position: center center;
- background-repeat: no-repeat;
-}
-
-/* ========== 背景遮罩层(提升文字可读性)========== */
-.aksrt-bg-overlay {
- position: relative;
-}
-
-.aksrt-bg-overlay::before {
- content: '';
- position: absolute;
- inset: 0;
- background: var(--aksrt-bg-overlay-color, rgba(0, 0, 0, 0.3));
- pointer-events: none;
- z-index: 0;
-}
-
-.aksrt-bg-overlay > * {
- position: relative;
- z-index: 1;
-}
-
-/* ========== 暗色模式自动切换 ========== */
-@media (prefers-color-scheme: dark) {
- :root:not(.aksrt-light-mode) .aksrt-bg-body {
- background-color: var(--aksrt-bg-dark-color, var(--aksrt-bg-color, transparent));
- background-image: var(--aksrt-bg-dark-image, var(--aksrt-bg-image, none));
- }
-}
-
-html.aksrt-dark-mode .aksrt-bg-body {
- background-color: var(--aksrt-bg-dark-color, var(--aksrt-bg-color, transparent));
- background-image: var(--aksrt-bg-dark-image, var(--aksrt-bg-image, none));
-}
diff --git a/assets/images/footer/fcode_template_1.png b/assets/images/footer/fcode_template_1.png
new file mode 100644
index 00000000..a0f29280
Binary files /dev/null and b/assets/images/footer/fcode_template_1.png differ
diff --git a/assets/images/slider-align/conter-bottom.jpg b/assets/images/slider-align/conter-bottom.jpg
new file mode 100644
index 00000000..28990287
Binary files /dev/null and b/assets/images/slider-align/conter-bottom.jpg differ
diff --git a/assets/images/slider-align/conter-conter.jpg b/assets/images/slider-align/conter-conter.jpg
new file mode 100644
index 00000000..faa1636f
Binary files /dev/null and b/assets/images/slider-align/conter-conter.jpg differ
diff --git a/assets/images/slider-align/left-bottom.jpg b/assets/images/slider-align/left-bottom.jpg
new file mode 100644
index 00000000..57f4c809
Binary files /dev/null and b/assets/images/slider-align/left-bottom.jpg differ
diff --git a/assets/images/slider-align/left-conter.jpg b/assets/images/slider-align/left-conter.jpg
new file mode 100644
index 00000000..e01e872d
Binary files /dev/null and b/assets/images/slider-align/left-conter.jpg differ
diff --git a/assets/images/slider-align/right-bottom.jpg b/assets/images/slider-align/right-bottom.jpg
new file mode 100644
index 00000000..cbd9d7f4
Binary files /dev/null and b/assets/images/slider-align/right-bottom.jpg differ
diff --git a/assets/images/slider-align/right-conter.jpg b/assets/images/slider-align/right-conter.jpg
new file mode 100644
index 00000000..dbd2df68
Binary files /dev/null and b/assets/images/slider-align/right-conter.jpg differ
diff --git a/assets/js/cms-home-modules.js b/assets/js/cms-home-modules.js
deleted file mode 100644
index 740512ef..00000000
--- a/assets/js/cms-home-modules.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * AKSRT CMS Home Modules
- *
- * - Tab 切换:[data-aksrt-tabs] / [data-tab-target] / [data-tab-id]
- */
-(function () {
- 'use strict';
-
- function initTabs(scope) {
- const tablists = (scope || document).querySelectorAll('[data-aksrt-tabs]');
- tablists.forEach(function (list) {
- const buttons = list.querySelectorAll('.home-module__tab');
- const section = list.closest('.home-module--tabs');
- if (!section) return;
- const panels = section.querySelectorAll('.home-module__tab-panel');
-
- buttons.forEach(function (btn) {
- btn.addEventListener('click', function () {
- const target = btn.getAttribute('data-tab-target');
- if (!target) return;
-
- buttons.forEach(function (b) {
- b.classList.toggle('is-active', b === btn);
- b.setAttribute('aria-selected', b === btn ? 'true' : 'false');
- });
- panels.forEach(function (p) {
- const isMatch = p.getAttribute('data-tab-id') === target;
- p.classList.toggle('is-active', isMatch);
- if (isMatch) {
- p.removeAttribute('hidden');
- } else {
- p.setAttribute('hidden', '');
- }
- });
- });
- });
- });
- }
-
- // 监听 postMessage:iframe 预览模式下接收 reload 请求
- window.addEventListener('message', function (e) {
- if (!e.data || e.data.type !== 'aksrt-preview-reload') return;
- // 简单做:直接 reload
- window.location.reload();
- });
-
- if (document.readyState === 'loading') {
- document.addEventListener('DOMContentLoaded', function () { initTabs(); });
- } else {
- initTabs();
- }
-})();
diff --git a/assets/js/core/archive.js b/assets/js/core/archive.js
index 3a7fda75..dac332aa 100644
--- a/assets/js/core/archive.js
+++ b/assets/js/core/archive.js
@@ -21,9 +21,8 @@
var state = {
filter_cat: "",
filter_tag: "",
- sort: "latest",
- page: 1,
- cf: {}
+ sort: "date",
+ page: 1
};
var activeCat = bar.querySelector("[data-filter-cat].is-active");
@@ -31,12 +30,7 @@
var activeTag = bar.querySelector("[data-filter-tag].is-active");
if (activeTag) state.filter_tag = activeTag.dataset.filterTag || "";
var activeSort = bar.querySelector("[data-filter-sort].is-active");
- if (activeSort) state.sort = activeSort.dataset.filterSort || "latest";
- bar.querySelectorAll("[data-filter-cf].is-active").forEach(function (el) {
- var dimKey = el.dataset.filterCf || "";
- var dimVal = el.dataset.filterCfVal || "";
- if (dimKey) state.cf[dimKey] = dimVal;
- });
+ if (activeSort) state.sort = activeSort.dataset.filterSort || "date";
function buildUrl() {
var params = new URLSearchParams();
@@ -45,20 +39,8 @@
if (state.filter_cat) params.set("filter_cat", state.filter_cat);
if (state.filter_tag) params.set("filter_tag", state.filter_tag);
- var sortMap = { oldest: { orderby: "date", order: "ASC" }, popular: { orderby: "comment_count", order: "DESC" } };
- var s = sortMap[state.sort];
- params.set("sort", s ? s.orderby : "date");
- params.set("order", s ? s.order : "DESC");
+ params.set("sort", state.sort || "date");
params.set("page", String(state.page));
- var cfActive = {};
- var hasCf = false;
- for (var cfK in state.cf) {
- if (state.cf[cfK]) {
- cfActive[cfK] = state.cf[cfK];
- hasCf = true;
- }
- }
- if (hasCf) params.set("custom_filters", JSON.stringify(cfActive));
return REST_BASE + "?" + params.toString();
}
@@ -70,13 +52,7 @@
el.classList.toggle("is-active", (el.dataset.filterTag || "") === state.filter_tag);
});
bar.querySelectorAll("[data-filter-sort]").forEach(function (el) {
- el.classList.toggle("is-active", (el.dataset.filterSort || "latest") === state.sort);
- });
- bar.querySelectorAll("[data-filter-cf]").forEach(function (el) {
- var dimKey = el.dataset.filterCf || "";
- var dimVal = el.dataset.filterCfVal || "";
- var isActive = dimKey && (state.cf[dimKey] || "") === dimVal;
- el.classList.toggle("is-active", isActive);
+ el.classList.toggle("is-active", (el.dataset.filterSort || "date") === state.sort);
});
}
@@ -131,21 +107,9 @@
url.searchParams.delete("paged");
url.searchParams.delete("aksrt_filter_cat");
url.searchParams.delete("aksrt_filter_tag");
- url.searchParams.forEach(function (v, k) {
- if (k.indexOf("aksrt_cf_") === 0) url.searchParams.delete(k);
- });
if (state.filter_cat) url.searchParams.set("aksrt_filter_cat", state.filter_cat);
if (state.filter_tag) url.searchParams.set("aksrt_filter_tag", state.filter_tag);
- for (var cfK2 in state.cf) {
- if (state.cf[cfK2]) url.searchParams.set("aksrt_cf_" + cfK2, state.cf[cfK2]);
- }
- if (state.sort === "oldest") {
- url.searchParams.set("orderby", "date");
- url.searchParams.set("order", "asc");
- } else if (state.sort === "popular") {
- url.searchParams.set("orderby", "comment_count");
- url.searchParams.set("order", "desc");
- }
+ if (state.sort) url.searchParams.set("orderby", state.sort);
if (state.page > 1) url.searchParams.set("paged", String(state.page));
history.pushState({ aksrtArchive: true, state: Object.assign({}, state) }, "", url.toString());
}
@@ -156,7 +120,7 @@
}
bar.addEventListener("click", function (e) {
- var chip = e.target.closest("[data-filter-cat], [data-filter-tag], [data-filter-sort], [data-filter-cf]");
+ var chip = e.target.closest("[data-filter-cat], [data-filter-tag], [data-filter-sort]");
if (!chip) return;
e.preventDefault();
@@ -176,20 +140,12 @@
}
}
if (chip.dataset.filterSort !== undefined) {
- var newSort = chip.dataset.filterSort || "latest";
+ var newSort = chip.dataset.filterSort || "date";
if (newSort !== state.sort) {
state.sort = newSort;
changed = true;
}
}
- if (chip.dataset.filterCf !== undefined) {
- var cfKey = chip.dataset.filterCf;
- var cfVal = chip.dataset.filterCfVal || "";
- if ((state.cf[cfKey] || "") !== cfVal) {
- state.cf[cfKey] = cfVal;
- changed = true;
- }
- }
if (changed) {
state.page = 1;
diff --git a/category.php b/category.php
index 0fa2201e..b403f5ba 100644
--- a/category.php
+++ b/category.php
@@ -50,130 +50,28 @@ $has_sidebar = function_exists('aksrt_archive_has_sidebar')
: (!empty($archive_settings['show_sidebar']) && is_active_sidebar('cat_sidebar'));
$description = !empty($archive_settings['show_desc']) ? wp_kses_post((string) $archive_settings['description']) : '';
$header_style = (string) $archive_settings['header_style'];
-$filter_settings = class_exists('\AKSRT\Settings\Settings')
- ? \AKSRT\Settings\Settings::get_post_filter_settings()
- : ['enabled' => false, 'sort' => false, 'ajax_enabled' => false];
-if (!empty($filter_settings['enabled']) && !in_array('cat', $filter_settings['custom_filter_show'] ?? ['cat', 'tag'], true)) {
- $filter_settings['enabled'] = false;
-}
-$ajax_filter = !empty($filter_settings['ajax_enabled']) && !empty($filter_settings['enabled']);
-$cat_filter_config = class_exists('\AKSRT\Settings\Settings')
- ? \AKSRT\Settings\Settings::get_filter_config_for_category((int) $term->term_id)
- : ['dimensions' => []];
-$custom_dimensions = is_array($cat_filter_config['dimensions'] ?? null) ? $cat_filter_config['dimensions'] : [];
-$sort_state = function_exists('aksrt_archive_get_sort_state') ? aksrt_archive_get_sort_state() : ['current' => 'latest', 'links' => []];
+$ajax_filter = !empty($archive_settings['filter_bar']);
+$sort_state = function_exists('aksrt_archive_get_sort_state')
+ ? aksrt_archive_get_sort_state((array) ($archive_settings['orderby_option'] ?? []))
+ : ['current' => 'date', 'links' => []];
$current_sort = $sort_state['current'];
$sort_links = $sort_state['links'];
$render_config = function_exists('aksrt_archive_get_render_config')
? aksrt_archive_get_render_config(['context' => 'category'])
: ['context' => 'category'];
-$filter_terms = [];
-$filter_all_url = get_category_link($term->term_id);
-if (!empty($archive_settings['filter_bar'])) {
- $filter_terms = get_terms([
- 'taxonomy' => 'category',
- 'hide_empty' => true,
- 'parent' => $term->term_id,
- ]);
- if (empty($filter_terms) && !empty($term->parent)) {
- $filter_all_url = get_category_link((int) $term->parent);
- $filter_terms = get_terms([
- 'taxonomy' => 'category',
- 'hide_empty' => true,
- 'parent' => (int) $term->parent,
- ]);
- }
- if (is_wp_error($filter_terms)) {
- $filter_terms = [];
- }
-}
-
-$tag_filter_terms = [];
-$current_filter_cat = sanitize_text_field((string) get_query_var('aksrt_filter_cat', ''));
-$current_filter_tag = sanitize_text_field((string) get_query_var('aksrt_filter_tag', ''));
-$current_cf_values = [];
-foreach ($custom_dimensions as $dim) {
- $cf_key = 'aksrt_cf_' . $dim['key'];
- $current_cf_values[$dim['key']] = isset($_GET[$cf_key]) ? sanitize_key((string) $_GET[$cf_key]) : '';
-}
-if ($ajax_filter && !empty($filter_settings['cat_show_tag'])) {
- $tag_filter_terms = get_terms([
- 'taxonomy' => 'post_tag',
- 'hide_empty' => true,
- 'number' => 20,
- ]);
- if (is_wp_error($tag_filter_terms)) {
- $tag_filter_terms = [];
- }
-}
-
$filter_groups = [];
-if (!empty($filter_terms)) {
- $chips = [[
- 'label' => __('全部', 'aksrt'),
- 'url' => $filter_all_url,
- 'active' => empty($term->parent) && $current_filter_cat === '',
- 'attrs' => $ajax_filter ? ' data-filter-cat="0"' : '',
- ]];
- foreach ($filter_terms as $filter_term) {
- $is_current = ((int) $filter_term->term_id === (int) $term->term_id)
- || ($current_filter_cat !== '' && (int) $current_filter_cat === (int) $filter_term->term_id);
- $chips[] = [
- 'label' => $filter_term->name,
- 'url' => get_term_link($filter_term),
- 'active' => $is_current,
- 'attrs' => $ajax_filter ? ' data-filter-cat="' . (int) $filter_term->term_id . '"' : '',
- ];
+if (!empty($archive_settings['ajax_category_enabled']) && function_exists('aksrt_archive_build_term_filter_group')) {
+ $group = aksrt_archive_build_term_filter_group('category', (array) ($archive_settings['ajax_category'] ?? []), __('分类', 'aksrt'), $ajax_filter);
+ if ($group !== []) {
+ $filter_groups[] = $group;
}
- $filter_groups[] = [
- 'label' => __('分类导航', 'aksrt'),
- 'chips' => $chips,
- ];
}
-if (!empty($tag_filter_terms)) {
- $chips = [[
- 'label' => __('全部', 'aksrt'),
- 'url' => remove_query_arg(['aksrt_filter_tag']),
- 'active' => $current_filter_tag === '',
- 'attrs' => $ajax_filter ? ' data-filter-tag=""' : '',
- ]];
- foreach ($tag_filter_terms as $tag_term) {
- $is_current_tag = ($current_filter_tag !== '' && (int) $current_filter_tag === (int) $tag_term->term_id);
- $chips[] = [
- 'label' => $tag_term->name,
- 'url' => add_query_arg('aksrt_filter_tag', (int) $tag_term->term_id),
- 'active' => $is_current_tag,
- 'attrs' => $ajax_filter ? ' data-filter-tag="' . (int) $tag_term->term_id . '"' : '',
- ];
+if (!empty($archive_settings['ajax_tag_enabled']) && function_exists('aksrt_archive_build_term_filter_group')) {
+ $group = aksrt_archive_build_term_filter_group('post_tag', (array) ($archive_settings['ajax_tag'] ?? []), __('标签', 'aksrt'), $ajax_filter);
+ if ($group !== []) {
+ $filter_groups[] = $group;
}
- $filter_groups[] = [
- 'label' => __('标签', 'aksrt'),
- 'class' => 'archive-filter-bar__main--tags',
- 'chips' => $chips,
- ];
-}
-foreach ($custom_dimensions as $dim) {
- $chips = [[
- 'label' => __('全部', 'aksrt'),
- 'url' => remove_query_arg('aksrt_cf_' . $dim['key']),
- 'active' => ($current_cf_values[$dim['key']] ?? '') === '',
- 'attrs' => $ajax_filter ? ' data-filter-cf="' . esc_attr($dim['key']) . '" data-filter-cf-val=""' : '',
- ]];
- foreach ($dim['vals'] as $val) {
- $is_current_cf = ($current_cf_values[$dim['key']] ?? '') === $val['key'];
- $chips[] = [
- 'label' => $val['name'],
- 'url' => add_query_arg('aksrt_cf_' . $dim['key'], $val['key']),
- 'active' => $is_current_cf,
- 'attrs' => $ajax_filter ? ' data-filter-cf="' . esc_attr($dim['key']) . '" data-filter-cf-val="' . esc_attr($val['key']) . '"' : '',
- ];
- }
- $filter_groups[] = [
- 'label' => $dim['name'],
- 'class' => 'archive-filter-bar__main--custom',
- 'chips' => $chips,
- ];
}
if (function_exists('aksrt_archive_open_shell')) {
@@ -212,11 +110,12 @@ if (function_exists('aksrt_archive_open_shell')) {
'ajax_archive' => 'category',
'term_id' => (int) $term->term_id,
'aria_label' => __('分类筛选', 'aksrt'),
- 'meta_text' => sprintf(_n('%d 篇文章', '%d 篇文章', (int) $term->count, 'aksrt'), (int) $term->count),
+ 'meta_text' => !empty($archive_settings['post_count']) ? sprintf(_n('%d 篇文章', '%d 篇文章', (int) $term->count, 'aksrt'), (int) $term->count) : '',
'groups' => $filter_groups,
- 'sort_enabled' => !empty($filter_settings['enabled']) && !empty($filter_settings['sort']),
+ 'sort_enabled' => !empty($archive_settings['orderby_enabled']),
'sort_current' => $current_sort,
'sort_links' => $sort_links,
+ 'sort_labels' => class_exists('\AKSRT\Settings\Settings') ? \AKSRT\Settings\Settings::homepage_sort_labels() : [],
'sort_as_main' => false,
]);
}
diff --git a/footer.php b/footer.php
index d01e6f29..40effa71 100644
--- a/footer.php
+++ b/footer.php
@@ -13,34 +13,13 @@ defined('ABSPATH') || exit;
// 数据准备
$blog_name = function_exists('aksrt_get_site_logo_text') ? aksrt_get_site_logo_text() : get_bloginfo('name');
$has_settings = class_exists('\AKSRT\Settings\Settings');
-$search_placeholder = function_exists('aksrt_get_search_placeholder') ? aksrt_get_search_placeholder() : __('开启精彩搜索', 'aksrt');
-$search_hot_keywords = function_exists('aksrt_get_search_hot_keywords') ? aksrt_get_search_hot_keywords() : [];
-
-// 联系图标 / 社交链接(legacy contacts list — fallback for more icons)
-$footer_contacts = $has_settings ? \AKSRT\Settings\Settings::get_footer_contacts() : [];
-if (empty($footer_contacts) && function_exists('aksrt_get_about_info')) {
- $about = aksrt_get_about_info();
- $footer_contacts = $about['contacts'] ?? [];
-}
-
-// 友情链接 / 快速链接(仅当 fcode_t2_code_1 为空时回退)
-$friend_links = function_exists('aksrt_get_friend_links') ? aksrt_get_friend_links() : [];
-$quick_links = $has_settings ? \AKSRT\Settings\Settings::get_quick_links() : [];
-$more_links = $has_settings ? \AKSRT\Settings\Settings::get_more_links() : [];
-$hot_cat_count = $has_settings ? \AKSRT\Settings\Settings::get_hot_categories_count() : 0;
-
-// 备案 / 版权(customize 为空时回退)
-$filing = $has_settings ? \AKSRT\Settings\Settings::get_filing_settings() : ['icp_enabled' => true, 'icp_filing' => '', 'police_enabled' => true, 'police_filing' => ''];
-$icp_filing = !empty($filing['icp_enabled']) ? (string) ($filing['icp_filing'] ?? '') : '';
-$police_filing = !empty($filing['police_enabled']) ? (string) ($filing['police_filing'] ?? '') : '';
-$footer_text = $has_settings ? \AKSRT\Settings\Settings::footer_text() : '';
-$copyright_text = $has_settings ? \AKSRT\Settings\Settings::get_copyright_text() : '';
// §2.3 三列结构化字段(Zibll keys)
$footer_brand = $has_settings ? \AKSRT\Settings\Settings::get_footer_brand_settings() : ['m_s' => ['pc', 'mobile'], 'img' => '', 'img_dark' => '', 'title' => '', 'custom_code' => ''];
$footer_contact_ext = $has_settings ? \AKSRT\Settings\Settings::get_footer_contact_extended_settings() : ['m_s' => ['pc', 'mobile'], 'wechat_img' => '', 'qq' => '', 'weibo' => '', 'email' => '', 'more' => [], 'code_1' => '', 'code_2' => ''];
-$footer_mini = $has_settings ? \AKSRT\Settings\Settings::get_footer_mini_img_settings() : ['m_s' => ['pc', 'mobile'], 'items' => []];
+$footer_mini = $has_settings ? \AKSRT\Settings\Settings::get_footer_mini_img_settings() : ['m_s' => ['pc', 'mobile'], 'items' => [], 'items_2' => []];
$footer_customize_code = $has_settings ? \AKSRT\Settings\Settings::get_footer_customize_code() : '';
+$footer_template = $has_settings ? \AKSRT\Settings\Settings::get_footer_template() : 'template_1';
// 设备可见性 → Zibll hidden-xs(仅在不含 mobile 时隐藏移动端)
$_brand_show_sm = in_array('mobile', (array) ($footer_brand['m_s'] ?? []), true);
@@ -50,67 +29,6 @@ $_brand_xs_cls = $_brand_show_sm ? '' : ' hidden-xs';
$_contact_xs_cls = $_contact_show_sm ? '' : ' hidden-xs';
$_mini_xs_cls = $_mini_show_sm ? '' : ' hidden-xs';
-/**
- * 渲染快速链接 URL:支持外链 / 站内相对路径
- */
-$render_link_url = static function ($raw) {
- if (empty($raw)) {
- return '#';
- }
- if (strpos((string) $raw, 'http') === 0) {
- return esc_url($raw);
- }
- return esc_url(home_url($raw));
-};
-
-/**
- * 构建 fcode-links 回退 HTML(structured links)
- */
-$build_fallback_links_html = static function () use ($quick_links, $more_links, $friend_links, $hot_cat_count, $render_link_url) {
- $link_bits = [];
- foreach ((array) $quick_links as $ql) {
- $label = $ql['name'] ?? $ql['label'] ?? '';
- $url = $render_link_url($ql['url'] ?? '');
- if ($label !== '') {
- $link_bits[] = '' . esc_html($label) . '';
- }
- }
- foreach ((array) $more_links as $ml) {
- $label = $ml['name'] ?? $ml['label'] ?? '';
- $url = $render_link_url($ml['url'] ?? '');
- if ($label !== '') {
- $link_bits[] = '' . esc_html($label) . '';
- }
- }
- foreach ((array) $friend_links as $fl) {
- $label = $fl['name'] ?? '';
- $url = $fl['url'] ?? '#';
- if ($label !== '') {
- $link_bits[] = '' . esc_html($label) . '';
- }
- }
- if ($hot_cat_count > 0) {
- $_hot_cache_key = 'aksrt_footer_hot_cats_' . (int) $hot_cat_count;
- $_hot_cats = wp_cache_get($_hot_cache_key, 'aksrt');
- if (!is_array($_hot_cats)) {
- $_hot_cats = get_categories([
- 'orderby' => 'count',
- 'order' => 'DESC',
- 'number' => $hot_cat_count,
- 'hide_empty' => true,
- ]);
- if (!is_array($_hot_cats)) {
- $_hot_cats = [];
- }
- wp_cache_set($_hot_cache_key, $_hot_cats, 'aksrt', 12 * HOUR_IN_SECONDS);
- }
- foreach ($_hot_cats as $hc) {
- $link_bits[] = '' . esc_html($hc->name) . '';
- }
- }
- return implode(' ', $link_bits);
-};
-
// 品牌 / 联系 / 二维码列内容存在性
$_logo_html = '';
if (function_exists('aksrt_get_adaptive_theme_img')) {
@@ -124,45 +42,17 @@ if (function_exists('aksrt_get_adaptive_theme_img')) {
$_has_brand = $_logo_html !== '' || !empty($footer_brand['title']) || !empty($footer_brand['custom_code']);
$_fcode_links = trim((string) ($footer_contact_ext['code_1'] ?? ''));
-if ($_fcode_links === '') {
- $_fcode_links = $build_fallback_links_html();
-}
-$_fcode_links_is_raw = trim((string) ($footer_contact_ext['code_1'] ?? '')) !== '';
-$_has_contact_icons = !empty($footer_contacts)
- || !empty($footer_contact_ext['wechat_img'])
+$_has_contact_icons = !empty($footer_contact_ext['wechat_img'])
|| !empty($footer_contact_ext['qq'])
|| !empty($footer_contact_ext['email'])
|| !empty($footer_contact_ext['more'])
|| !empty($footer_contact_ext['weibo']);
$_has_links_col = $_fcode_links !== '' || !empty($footer_contact_ext['code_2']) || $_has_contact_icons;
-$_has_mini = !empty($footer_mini['items']);
+$_has_mini = !empty($footer_mini['items']) || !empty($footer_mini['items_2']);
$_has_cols = $_has_brand || $_has_links_col || $_has_mini;
-// 底栏:customize 优先;否则回退版权/备案
-$_footer_conter = trim((string) $footer_customize_code);
-if ($_footer_conter === '') {
- $footer_bits = [];
- if ($icp_filing !== '') {
- $footer_bits[] = '' . esc_html($icp_filing) . '';
- }
- if ($police_filing !== '') {
- $footer_bits[] = '' . esc_html($police_filing) . '';
- }
- $copy = '© ' . esc_html(gmdate('Y')) . ' ' . esc_html($blog_name) . '.';
- if ($copyright_text !== '') {
- $copy .= ' ' . wp_kses_post($copyright_text);
- }
- if ($footer_text !== '') {
- $copy .= ' ' . esc_html($footer_text);
- }
- if (!empty($footer_bits)) {
- $copy .= ' ' . implode(' · ', $footer_bits);
- }
- $_footer_conter = $copy;
-} else {
- $_footer_conter = wp_kses_post($_footer_conter);
-}
+$_footer_conter = wp_kses_post(trim((string) $footer_customize_code));
?>
@@ -173,7 +63,7 @@ if ($_footer_conter === '') {
-
@@ -288,21 +159,31 @@ if ($_footer_conter === '') {
-
-