fix(users): keep management inside center
This commit is contained in:
1 parent
c3bfd12c69
commit
ce2b266890
44 files changed
+194
-2584
No files matched your search
@@ -36,16 +36,6 @@ export const extensionsSection = {
|
||||
canonicalDomain: 'extensions',
|
||||
section: 'push',
|
||||
}),
|
||||
schemaPage({
|
||||
key: 'extensions-docs-mode',
|
||||
name: 'ExtensionsDocsMode',
|
||||
label: '文档模式',
|
||||
route: '/extensions/docs-mode',
|
||||
title: '文档模式',
|
||||
desc: '文档专题内容模式与页面增强。',
|
||||
canonicalDomain: 'extensions',
|
||||
section: 'docs-mode',
|
||||
}),
|
||||
customPage({
|
||||
key: 'extensions-security',
|
||||
name: 'ExtensionsSecurity',
|
||||
|
||||
@@ -2,43 +2,6 @@
|
||||
<div class="aksrt-page-container">
|
||||
<PageHeader title="文档中心" desc="主题使用文档、开发指南、迁移说明和更新日志。" />
|
||||
|
||||
<!-- Docs Mode Status -->
|
||||
<n-card class="aksrt-docs__section" size="small">
|
||||
<div class="aksrt-docs__mode-status">
|
||||
<div class="aksrt-docs__mode-info">
|
||||
<FaIcon :icon="docsModeEnabled ? 'fas fa-book-open' : 'fas fa-book'" :size="18" :color="docsModeEnabled ? '#52c41a' : '#8a909c'" />
|
||||
<div>
|
||||
<strong>{{ docsModeEnabled ? '文档模式已启用' : '文档模式未启用' }}</strong>
|
||||
<p>{{ docsModeEnabled ? '文档导航页面和文档站式侧边栏已激活' : '启用后将激活文档导航页面模板和文档站式侧边栏' }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<n-space>
|
||||
<router-link to="/extensions/docs-mode" class="aksrt-docs__mode-link">
|
||||
<FaIcon icon="fas fa-cog" :size="12" />
|
||||
{{ docsModeEnabled ? '管理文档模式' : '启用文档模式' }}
|
||||
</router-link>
|
||||
</n-space>
|
||||
</div>
|
||||
</n-card>
|
||||
|
||||
<!-- Doc Pages Overview -->
|
||||
<n-card title="文档页面" size="small" class="aksrt-docs__section">
|
||||
<n-alert v-if="docPageCount === 0" type="info" size="small">
|
||||
尚未创建文档页面。在 WordPress 后台新建页面时,选择"文档导航页"或"专题聚合页"模板。
|
||||
</n-alert>
|
||||
<n-grid v-else :cols="3" :x-gap="12" :y-gap="12">
|
||||
<n-grid-item v-for="stat in docPageStats" :key="stat.key">
|
||||
<div class="aksrt-docs__stat">
|
||||
<FaIcon :icon="stat.icon" :size="16" :color="stat.color" />
|
||||
<div>
|
||||
<strong>{{ stat.value }}</strong>
|
||||
<p>{{ stat.label }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
</n-card>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<n-card title="常用操作" size="small" class="aksrt-docs__section">
|
||||
<n-grid :cols="2" :x-gap="12" :y-gap="12">
|
||||
@@ -130,13 +93,6 @@ import api from '@/api/index.js'
|
||||
|
||||
const themeVersion = ref(window.aksrtAdminData?.themeVersion || '3.4.0-dev')
|
||||
const dbSchemaVersion = ref('—')
|
||||
const docsModeEnabled = ref(false)
|
||||
const docPageCount = ref(0)
|
||||
const docPageStats = ref([
|
||||
{ key: 'total', icon: 'fas fa-file-alt', color: '#1890ff', value: 0, label: '文档页面' },
|
||||
{ key: 'nav', icon: 'fas fa-sitemap', color: '#722ed1', value: 0, label: '导航页' },
|
||||
{ key: 'special', icon: 'fas fa-layer-group', color: '#fa8c16', value: 0, label: '专题页' },
|
||||
])
|
||||
|
||||
const docs = ref([
|
||||
{ key: 'admin-ia-map', title: '后台 IA 蓝图', description: '完整的后台信息架构映射,12 个顶级分区及子页面清单。', icon: 'fas fa-sitemap', color: '#1890ff', file: 'admin-ia-map.md' },
|
||||
@@ -148,28 +104,6 @@ const docs = ref([
|
||||
])
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
const res = await api.getSchemaPage('extensions', 'docs-mode')
|
||||
if (res?.data) {
|
||||
docsModeEnabled.value = !!res.data.docs_mode_enabled
|
||||
}
|
||||
} catch {
|
||||
// Schema endpoint may not exist yet
|
||||
}
|
||||
|
||||
// Fetch doc page stats via REST if available
|
||||
try {
|
||||
const statsRes = await api.request('/docs/stats')
|
||||
if (statsRes?.data) {
|
||||
docPageCount.value = statsRes.data.total || 0
|
||||
docPageStats.value[0].value = statsRes.data.total || 0
|
||||
docPageStats.value[1].value = statsRes.data.nav_count || 0
|
||||
docPageStats.value[2].value = statsRes.data.special_count || 0
|
||||
}
|
||||
} catch {
|
||||
// Endpoint may not exist yet
|
||||
}
|
||||
|
||||
// Fetch schema version from health
|
||||
try {
|
||||
const healthRes = await api.getHealthCheck()
|
||||
@@ -189,69 +123,6 @@ function openDoc(doc) {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.aksrt-docs__mode-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.aksrt-docs__mode-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.aksrt-docs__mode-info strong {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
.aksrt-docs__mode-info p {
|
||||
margin: 2px 0 0;
|
||||
font-size: 12px;
|
||||
color: #8a909c;
|
||||
}
|
||||
|
||||
.aksrt-docs__mode-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 14px;
|
||||
border-radius: 6px;
|
||||
background: #f5f7fa;
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
font-size: 13px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.aksrt-docs__mode-link:hover {
|
||||
background: #e6f4ff;
|
||||
}
|
||||
|
||||
.aksrt-docs__stat {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 12px;
|
||||
border-radius: 6px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.aksrt-docs__stat strong {
|
||||
display: block;
|
||||
font-size: 20px;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
.aksrt-docs__stat p {
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
color: #8a909c;
|
||||
}
|
||||
|
||||
.aksrt-docs__grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
|
||||
|
||||
@@ -1,311 +0,0 @@
|
||||
<template>
|
||||
<div class="aksrt-page-container">
|
||||
<PageHeader title="文档模式" desc="启用文档专题内容模式,配置文档导航页面和文档站式体验。" />
|
||||
|
||||
<n-card class="aksrt-docs-mode__card" title="文档模式" size="small">
|
||||
<n-form label-placement="left" label-width="160">
|
||||
<n-form-item label="启用文档模式">
|
||||
<n-switch v-model:value="formData.docs_mode_enabled" />
|
||||
<n-text depth="3" style="margin-left: 12px; font-size: 12px;">
|
||||
开启后将激活文档导航页面模板和文档站式侧边栏
|
||||
</n-text>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item v-if="formData.docs_mode_enabled" label="文档首页模板">
|
||||
<n-select
|
||||
v-model:value="formData.docs_mode_default_template"
|
||||
:options="templateOptions"
|
||||
placeholder="选择文档首页模板"
|
||||
style="max-width: 360px;"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item v-if="formData.docs_mode_enabled" label="文档分类">
|
||||
<n-select
|
||||
v-model:value="formData.docs_mode_cats"
|
||||
:options="categoryOptions"
|
||||
:loading="categoriesLoading"
|
||||
multiple
|
||||
clearable
|
||||
filterable
|
||||
placeholder="选择用于文档模式的分类"
|
||||
style="max-width: 520px;"
|
||||
/>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item v-if="formData.docs_mode_enabled" label="首页排除">
|
||||
<n-switch v-model:value="formData.docs_mode_exclude" />
|
||||
<n-text depth="3" style="margin-left: 12px; font-size: 12px;">
|
||||
开启后,所选文档分类的内容不会出现在首页常规文章流中
|
||||
</n-text>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item v-if="formData.docs_mode_enabled" label="显示目录树">
|
||||
<n-switch v-model:value="formData.docs_mode_toc_enabled" />
|
||||
<n-text depth="3" style="margin-left: 12px; font-size: 12px;">
|
||||
在文档页面侧边栏显示章节目录树
|
||||
</n-text>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item v-if="formData.docs_mode_enabled" label="显示章节导航">
|
||||
<n-switch v-model:value="formData.docs_mode_chapter_nav_enabled" />
|
||||
<n-text depth="3" style="margin-left: 12px; font-size: 12px;">
|
||||
在文档底部显示上一章/下一章导航
|
||||
</n-text>
|
||||
</n-form-item>
|
||||
|
||||
<n-form-item v-if="formData.docs_mode_enabled" label="默认排序">
|
||||
<n-radio-group v-model:value="formData.docs_mode_default_order">
|
||||
<n-radio value="menu_order">按菜单顺序</n-radio>
|
||||
<n-radio value="date">按发布时间</n-radio>
|
||||
<n-radio value="title">按标题排序</n-radio>
|
||||
</n-radio-group>
|
||||
</n-form-item>
|
||||
</n-form>
|
||||
|
||||
<template #action>
|
||||
<n-space justify="end">
|
||||
<n-button @click="handleReset">重置</n-button>
|
||||
<n-button type="primary" :loading="saving" @click="handleSave">保存设置</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</n-card>
|
||||
|
||||
<n-card title="文档页面统计" size="small" class="aksrt-docs-mode__card">
|
||||
<n-grid :cols="3" :x-gap="12" :y-gap="12">
|
||||
<n-grid-item>
|
||||
<div class="aksrt-docs-mode__stat">
|
||||
<strong>{{ docStats.total || 0 }}</strong>
|
||||
<p>文档页面总数</p>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<div class="aksrt-docs-mode__stat">
|
||||
<strong>{{ docStats.nav_count || 0 }}</strong>
|
||||
<p>文档导航页</p>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
<n-grid-item>
|
||||
<div class="aksrt-docs-mode__stat">
|
||||
<strong>{{ docStats.special_count || 0 }}</strong>
|
||||
<p>专题聚合页</p>
|
||||
</div>
|
||||
</n-grid-item>
|
||||
</n-grid>
|
||||
</n-card>
|
||||
|
||||
<n-card title="可用页面模板" size="small" class="aksrt-docs-mode__card">
|
||||
<n-alert type="info" size="small" style="margin-bottom: 12px;">
|
||||
以下页面模板可用于创建文档类页面。在 WordPress 后台新建页面时,从"页面属性 → 模板"中选择对应模板。
|
||||
</n-alert>
|
||||
<n-list bordered size="small">
|
||||
<n-list-item v-for="tpl in availableTemplates" :key="tpl.file">
|
||||
<n-thing :title="tpl.name" :description="tpl.description">
|
||||
<template #avatar>
|
||||
<FaIcon :icon="tpl.icon" :size="18" color="#1890ff" />
|
||||
</template>
|
||||
<template #header-extra>
|
||||
<n-tag size="small" type="info">{{ tpl.file }}</n-tag>
|
||||
</template>
|
||||
</n-thing>
|
||||
</n-list-item>
|
||||
</n-list>
|
||||
</n-card>
|
||||
|
||||
<n-card title="快速入口" size="small" class="aksrt-docs-mode__card">
|
||||
<n-space>
|
||||
<router-link to="/page-display/special" class="aksrt-docs-mode__link">
|
||||
<FaIcon icon="fas fa-layer-group" :size="14" />
|
||||
专题页面配置
|
||||
</router-link>
|
||||
</n-space>
|
||||
</n-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useMessage } from 'naive-ui'
|
||||
import PageHeader from '@/components/PageHeader.vue'
|
||||
import FaIcon from '@/components/form/FaIcon.vue'
|
||||
import api from '@/api/index.js'
|
||||
|
||||
const message = useMessage()
|
||||
const saving = ref(false)
|
||||
const docStats = ref({ total: 0, nav_count: 0, special_count: 0 })
|
||||
const categoriesLoading = ref(false)
|
||||
const categoryOptions = ref([])
|
||||
|
||||
const defaults = {
|
||||
docs_mode_enabled: false,
|
||||
docs_mode_default_template: 'documentnav',
|
||||
docs_mode_toc_enabled: true,
|
||||
docs_mode_chapter_nav_enabled: true,
|
||||
docs_mode_default_order: 'menu_order',
|
||||
docs_mode_cats: [],
|
||||
docs_mode_exclude: true,
|
||||
}
|
||||
|
||||
const formData = ref({ ...defaults })
|
||||
|
||||
const templateOptions = [
|
||||
{ label: '文档导航页 (page-documentnav)', value: 'documentnav' },
|
||||
{ label: '专题聚合页 (page-special)', value: 'special' },
|
||||
]
|
||||
|
||||
const availableTemplates = [
|
||||
{
|
||||
file: 'page-documentnav.php',
|
||||
name: '文档导航页',
|
||||
description: '站式文档导航模板,支持侧边栏目录树、章节高亮和快速搜索。',
|
||||
icon: 'fas fa-book',
|
||||
},
|
||||
{
|
||||
file: 'page-special.php',
|
||||
name: '专题聚合页',
|
||||
description: '专题内容聚合模板,支持封面、摘要、多列布局和子页面矩阵。',
|
||||
icon: 'fas fa-layer-group',
|
||||
},
|
||||
{
|
||||
file: 'page-download.php',
|
||||
name: '下载中心页',
|
||||
description: '资源下载中心模板,支持资源类型筛选、权限说明和交易承接。',
|
||||
icon: 'fas fa-download',
|
||||
},
|
||||
{
|
||||
file: 'page-categories.php',
|
||||
name: '分类导航页',
|
||||
description: '全站分类导航模板,展示分类树和文章统计。',
|
||||
icon: 'fas fa-folder-open',
|
||||
},
|
||||
{
|
||||
file: 'page-friends.php',
|
||||
name: '友情链接页',
|
||||
description: '友情链接展示模板。',
|
||||
icon: 'fas fa-link',
|
||||
},
|
||||
]
|
||||
|
||||
onMounted(async () => {
|
||||
await Promise.all([loadSettings(), loadDocStats(), loadCategories()])
|
||||
})
|
||||
|
||||
async function loadSettings() {
|
||||
try {
|
||||
const res = await api.getSchemaPage('extensions', 'docs-mode')
|
||||
if (res?.data) {
|
||||
formData.value = {
|
||||
...defaults,
|
||||
...res.data,
|
||||
docs_mode_cats: normalizeCategoryIds(res.data.docs_mode_cats),
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Schema endpoint may not exist yet; use defaults
|
||||
}
|
||||
}
|
||||
|
||||
async function loadDocStats() {
|
||||
try {
|
||||
const statsRes = await api.request('/docs/stats')
|
||||
if (statsRes?.data) {
|
||||
docStats.value = statsRes.data
|
||||
}
|
||||
} catch {
|
||||
// Endpoint may not exist yet
|
||||
}
|
||||
}
|
||||
|
||||
async function loadCategories() {
|
||||
categoriesLoading.value = true
|
||||
try {
|
||||
const res = await api.getCategories()
|
||||
const items = res?.data || res || []
|
||||
categoryOptions.value = (Array.isArray(items) ? items : []).map((item) => ({
|
||||
label: item.name + (item.count ? ` (${item.count})` : ''),
|
||||
value: Number(item.term_id),
|
||||
}))
|
||||
} catch {
|
||||
categoryOptions.value = []
|
||||
} finally {
|
||||
categoriesLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeCategoryIds(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => Number(item)).filter((item) => Number.isFinite(item) && item > 0)
|
||||
}
|
||||
|
||||
if (typeof value === 'string' && value.trim()) {
|
||||
return value
|
||||
.split(',')
|
||||
.map((item) => Number(item.trim()))
|
||||
.filter((item) => Number.isFinite(item) && item > 0)
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
async function handleSave() {
|
||||
saving.value = true
|
||||
try {
|
||||
await api.saveSchemaPage('extensions', 'docs-mode', {
|
||||
...formData.value,
|
||||
docs_mode_cats: normalizeCategoryIds(formData.value.docs_mode_cats),
|
||||
})
|
||||
message.success('文档模式设置已保存')
|
||||
} catch (err) {
|
||||
message.error('保存失败: ' + (err?.message || '未知错误'))
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
formData.value = { ...defaults }
|
||||
message.info('已重置为默认值')
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.aksrt-docs-mode__card {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.aksrt-docs-mode__stat {
|
||||
text-align: center;
|
||||
padding: 12px;
|
||||
border-radius: 6px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.aksrt-docs-mode__stat strong {
|
||||
display: block;
|
||||
font-size: 24px;
|
||||
color: #1a1a2e;
|
||||
}
|
||||
|
||||
.aksrt-docs-mode__stat p {
|
||||
margin: 4px 0 0;
|
||||
font-size: 12px;
|
||||
color: #8a909c;
|
||||
}
|
||||
|
||||
.aksrt-docs-mode__link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 14px;
|
||||
border-radius: 6px;
|
||||
background: #f5f7fa;
|
||||
color: #1890ff;
|
||||
text-decoration: none;
|
||||
font-size: 13px;
|
||||
transition: background 0.2s;
|
||||
}
|
||||
|
||||
.aksrt-docs-mode__link:hover {
|
||||
background: #e6f4ff;
|
||||
}
|
||||
</style>
|
||||
@@ -84,7 +84,6 @@ const updateInfo = ref({
|
||||
|
||||
const guides = [
|
||||
{ key: 'rewrite', title: '伪静态配置', desc: '检查固定链接与重写规则', url: '/wp-admin/options-permalink.php' },
|
||||
{ key: 'docs-mode', title: '文档模式', desc: '配置文档分类与专题模板', url: '#/extensions/docs-mode' },
|
||||
{ key: 'oauth', title: '第三方登录', desc: '检查 GitHub / Gitee / QQ / Google 登录', url: '#/users/oauth' },
|
||||
{ key: 'backup', title: '设置快照', desc: '创建与恢复站点配置快照', url: '#/tools/backup' },
|
||||
{ key: 'health', title: '健康检查', desc: '查看 PHP / WP / 数据表状态', url: '#/tools/health' },
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
export const docsModeSchema = {
|
||||
key: 'extensions.docs-mode',
|
||||
title: '文档模式',
|
||||
icon: 'fas fa-book-open',
|
||||
description: '启用文档专题内容模式,配置文档导航页面和文档站式体验。',
|
||||
defaults: {
|
||||
docs_mode_enabled: false,
|
||||
docs_mode_default_template: 'documentnav',
|
||||
docs_mode_toc_enabled: true,
|
||||
docs_mode_chapter_nav_enabled: true,
|
||||
docs_mode_default_order: 'menu_order',
|
||||
docs_mode_cats: [],
|
||||
docs_mode_exclude: true,
|
||||
docs_mode_toc_depth: 3,
|
||||
docs_mode_chapter_title: '',
|
||||
docs_mode_style: 'default',
|
||||
docs_mode_icon: true,
|
||||
docs_mode_count: true,
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
key: 'basic',
|
||||
title: '基础配置',
|
||||
icon: 'fas fa-cog',
|
||||
fields: [
|
||||
{ key: 'docs_mode_enabled', label: '启用文档模式', type: 'switch', default: false, help: '开启后将激活文档导航页面模板和文档站式侧边栏' },
|
||||
{
|
||||
key: 'docs_mode_default_template',
|
||||
label: '文档首页模板',
|
||||
type: 'select',
|
||||
default: 'documentnav',
|
||||
options: [
|
||||
{ label: '文档导航页', value: 'documentnav' },
|
||||
{ label: '专题聚合页', value: 'special' },
|
||||
],
|
||||
dependsOn: { key: 'docs_mode_enabled', value: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'navigation',
|
||||
title: '导航设置',
|
||||
icon: 'fas fa-compass',
|
||||
fields: [
|
||||
{ key: 'docs_mode_toc_enabled', label: '显示目录树', type: 'switch', default: true, dependsOn: { key: 'docs_mode_enabled', value: true }, help: '在文档页面侧边栏显示章节目录树' },
|
||||
{ key: 'docs_mode_chapter_nav_enabled', label: '显示章节导航', type: 'switch', default: true, dependsOn: { key: 'docs_mode_enabled', value: true }, help: '在文档底部显示上一章/下一章导航' },
|
||||
{
|
||||
key: 'docs_mode_default_order',
|
||||
label: '默认排序',
|
||||
type: 'radio',
|
||||
default: 'menu_order',
|
||||
options: [
|
||||
{ label: '按菜单顺序', value: 'menu_order' },
|
||||
{ label: '按发布时间', value: 'date' },
|
||||
{ label: '按标题排序', value: 'title' },
|
||||
],
|
||||
dependsOn: { key: 'docs_mode_enabled', value: true },
|
||||
},
|
||||
{
|
||||
key: 'docs_mode_toc_depth',
|
||||
label: '目录深度',
|
||||
type: 'number',
|
||||
default: 3,
|
||||
min: 1,
|
||||
max: 6,
|
||||
dependsOn: { key: 'docs_mode_enabled', value: true },
|
||||
},
|
||||
{
|
||||
key: 'docs_mode_chapter_title',
|
||||
label: '章节标题',
|
||||
type: 'input',
|
||||
default: '',
|
||||
dependsOn: { key: 'docs_mode_enabled', value: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'filter',
|
||||
title: '筛选设置',
|
||||
icon: 'fas fa-filter',
|
||||
fields: [
|
||||
{
|
||||
key: 'docs_mode_cats',
|
||||
label: '文档分类',
|
||||
type: 'taxonomy_select',
|
||||
taxonomy: 'category',
|
||||
multiple: true,
|
||||
clearable: true,
|
||||
default: [],
|
||||
placeholder: '选择用于文档模式的分类',
|
||||
dependsOn: { key: 'docs_mode_enabled', value: true },
|
||||
},
|
||||
{
|
||||
key: 'docs_mode_exclude',
|
||||
label: '在首页排除此类内容',
|
||||
type: 'switch',
|
||||
default: true,
|
||||
dependsOn: { key: 'docs_mode_enabled', value: true },
|
||||
help: '开启后,所选文档分类的内容不会出现在首页常规文章流中。',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'style',
|
||||
title: '样式设置',
|
||||
icon: 'fas fa-palette',
|
||||
fields: [
|
||||
{
|
||||
key: 'docs_mode_style',
|
||||
label: '文档样式',
|
||||
type: 'select',
|
||||
default: 'default',
|
||||
options: [
|
||||
{ label: '默认', value: 'default' },
|
||||
{ label: '简洁', value: 'simple' },
|
||||
{ label: '卡片', value: 'card' },
|
||||
],
|
||||
dependsOn: { key: 'docs_mode_enabled', value: true },
|
||||
},
|
||||
{ key: 'docs_mode_icon', label: '显示图标', type: 'switch', default: true, dependsOn: { key: 'docs_mode_enabled', value: true } },
|
||||
{ key: 'docs_mode_count', label: '显示文章数', type: 'switch', default: true, dependsOn: { key: 'docs_mode_enabled', value: true } },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
@@ -6,11 +6,9 @@
|
||||
import { ipSchema } from './ip.js'
|
||||
import { auditSchema } from './audit.js'
|
||||
import { pushSchema } from './push.js'
|
||||
import { docsModeSchema } from './docs-mode.js'
|
||||
|
||||
export const extensionsSchemas = {
|
||||
ip: ipSchema,
|
||||
audit: auditSchema,
|
||||
push: pushSchema,
|
||||
'docs-mode': docsModeSchema,
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
/**
|
||||
* Document navigation page (zibll documentnav) styles.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
|
||||
.page-template-documentnav .document-nav-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 16px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page-template-documentnav .document-nav-aside {
|
||||
flex: 0 0 32%;
|
||||
max-width: 100%;
|
||||
min-width: 220px;
|
||||
}
|
||||
|
||||
.page-template-documentnav .document-nav-main {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.document-nav .panel-group {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.document-nav .panel {
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
border-top: 1px solid var(--main-border-color, #eee);
|
||||
}
|
||||
|
||||
.document-nav .panel-title {
|
||||
margin: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.document-nav .panel-toggle {
|
||||
padding: 10px;
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.document-nav .panel-toggle:not(.collapsed) {
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.document-nav .panel-toggle .fa {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.document-nav .panel-toggle:not(.collapsed) .fa {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.document-nav .panel-collapse {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.document-nav .panel-collapse.is-open,
|
||||
.document-nav .panel-collapse.in {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.document-nav .panel-child,
|
||||
.document-nav .category {
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.document-nav .cat-load {
|
||||
padding: 10px;
|
||||
display: block;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.document-nav > .panel-group > .cat-load {
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
.document-nav > .panel-group > .cat-load::before {
|
||||
content: '';
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
border: 0.1em solid var(--focus-color, var(--color-primary));
|
||||
border-radius: 1em;
|
||||
margin: 0 0.5em;
|
||||
vertical-align: 0.1em;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.document-nav .cat-load.active {
|
||||
background: var(--main-border-color, rgba(0, 0, 0, 0.06));
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.document-nav .loading {
|
||||
overflow: hidden;
|
||||
width: 0;
|
||||
opacity: 0;
|
||||
transition: 0.3s;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.document-nav .is-loading .loading,
|
||||
.document-nav .cat-load.is-loading .loading {
|
||||
width: 0.7em;
|
||||
opacity: 1;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
.document-nav-container {
|
||||
transition: 0.3s;
|
||||
min-height: 120px;
|
||||
}
|
||||
|
||||
.document-nav-container.is-loading {
|
||||
opacity: 0.55;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.document-search {
|
||||
position: relative;
|
||||
margin-bottom: 16px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.document-search .line-form {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.document-search .line-form-input {
|
||||
width: 100%;
|
||||
border: 1px solid var(--main-border-color, #ddd);
|
||||
border-radius: 8px;
|
||||
padding: 10px 40px 10px 12px;
|
||||
box-sizing: border-box;
|
||||
background: var(--main-bg-color, #fff);
|
||||
}
|
||||
|
||||
.document-search .abs-right {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
color: var(--muted-2-color, #888);
|
||||
}
|
||||
|
||||
.document-search .search-loading {
|
||||
inset: 0;
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 8px;
|
||||
background: color-mix(in srgb, var(--main-bg-color, #fff) 88%, transparent);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.document-search.is-loading .search-loading {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
display: block;
|
||||
padding: 12px 14px;
|
||||
background: var(--main-bg-color, #fff);
|
||||
border-bottom: 1px solid var(--muted-border-color, #eee);
|
||||
color: var(--main-color, inherit);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.list-group-item:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
a.list-group-item:hover,
|
||||
a.list-group-item:focus {
|
||||
background: var(--body-bg-color, #f7f7f8);
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.list-group-item .pull-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.list-group-item .badg-sm {
|
||||
font-size: 12px;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.list-group-item .focus-color {
|
||||
color: var(--focus-color, var(--color-primary));
|
||||
}
|
||||
|
||||
.document-nav-container .pagenav a {
|
||||
display: inline-block;
|
||||
min-width: 32px;
|
||||
padding: 4px 8px;
|
||||
margin: 2px;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
background: var(--surface-2, #f0f0f0);
|
||||
}
|
||||
|
||||
.document-nav-container .pagenav a.current {
|
||||
background: var(--focus-color, var(--color-primary));
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.history-search .search_keywords {
|
||||
display: inline-block;
|
||||
margin: 0 6px 6px 0;
|
||||
padding: 2px 8px;
|
||||
border-radius: 999px;
|
||||
background: var(--surface-2, #f0f0f0);
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.page-template-documentnav .document-nav-aside,
|
||||
.page-template-documentnav .document-nav-main {
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
}
|
||||
@@ -701,6 +701,15 @@ body.aksrt-user-center .uc-content,
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.uc-follow-management__list { display: grid; gap: 10px; margin-top: 16px; }
|
||||
.uc-follow-management__item { display: flex; align-items: center; gap: 12px; padding: 12px; border: 1px solid var(--border-color, rgba(15, 23, 42, .08)); border-radius: 12px; }
|
||||
.uc-follow-management__avatar img { display: block; width: 48px; height: 48px; border-radius: 50%; }
|
||||
.uc-follow-management__identity { display: grid; gap: 4px; min-width: 0; }
|
||||
.uc-follow-management__identity a { color: var(--color-ink-1); font-weight: 600; }
|
||||
.uc-follow-management__identity span { color: var(--color-ink-4); font-size: 12px; }
|
||||
.uc-follow-management__actions { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }
|
||||
@media (max-width: 560px) { .uc-follow-management__item { align-items: flex-start; flex-wrap: wrap; } .uc-follow-management__actions { width: 100%; margin-left: 60px; } }
|
||||
|
||||
.uc-service-grid__item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -994,6 +994,8 @@
|
||||
var nav = document.querySelectorAll('[data-aksrt-asset-tab]');
|
||||
if (!nav.length) return;
|
||||
nav.forEach(function (link) {
|
||||
if (link.dataset.aksrtAssetTabBound === 'true') return;
|
||||
link.dataset.aksrtAssetTabBound = 'true';
|
||||
link.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
var key = link.getAttribute('data-aksrt-asset-tab');
|
||||
@@ -1054,4 +1056,8 @@
|
||||
} else {
|
||||
bootAssets();
|
||||
}
|
||||
|
||||
if (window.AksrtFrontend && typeof window.AksrtFrontend.register === 'function') {
|
||||
window.AksrtFrontend.register('credits', function () { initAssetTabs(); });
|
||||
}
|
||||
})();
|
||||
@@ -1,197 +0,0 @@
|
||||
/**
|
||||
* Document navigation AJAX (zibll page-template documentnav subset).
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function ajaxUrl() {
|
||||
if (window.aksrtData && window.aksrtData.ajaxUrl) return window.aksrtData.ajaxUrl;
|
||||
return '/wp-admin/admin-ajax.php';
|
||||
}
|
||||
|
||||
function toast(msg, type) {
|
||||
if (window.aksrt && typeof window.aksrt.toast === 'function') {
|
||||
window.aksrt.toast(msg, type || 'info');
|
||||
return;
|
||||
}
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert(msg);
|
||||
}
|
||||
|
||||
function qs(sel, root) {
|
||||
return (root || document).querySelector(sel);
|
||||
}
|
||||
|
||||
function qsa(sel, root) {
|
||||
return Array.prototype.slice.call((root || document).querySelectorAll(sel));
|
||||
}
|
||||
|
||||
function documentAjax(triggerEl, data, url) {
|
||||
var container = qs('.document-nav-container');
|
||||
var searchBox = qs('.document-search');
|
||||
if (!container) return;
|
||||
|
||||
container.classList.add('is-loading');
|
||||
if (searchBox && data && data.search) searchBox.classList.add('is-loading');
|
||||
|
||||
data = data || {};
|
||||
data.one_cat = container.getAttribute('data-one-cat') || '';
|
||||
data.action = 'aksrt_documentnav_posts';
|
||||
|
||||
var body = new URLSearchParams();
|
||||
Object.keys(data).forEach(function (k) {
|
||||
if (data[k] !== undefined && data[k] !== null) body.append(k, data[k]);
|
||||
});
|
||||
|
||||
fetch(url || ajaxUrl(), {
|
||||
method: 'POST',
|
||||
credentials: 'same-origin',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' },
|
||||
body: body.toString(),
|
||||
})
|
||||
.then(function (r) { return r.json(); })
|
||||
.then(function (n) {
|
||||
if (!n || n.error || !n.html) {
|
||||
toast((n && n.msg) || '加载失败,请重试', 'danger');
|
||||
}
|
||||
if (n && n.html) container.innerHTML = n.html;
|
||||
if (n && n.history_search) {
|
||||
var hist = qs('.history-search > div');
|
||||
if (hist) hist.innerHTML = n.history_search;
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
toast('网络错误', 'danger');
|
||||
})
|
||||
.finally(function () {
|
||||
container.classList.remove('is-loading');
|
||||
if (searchBox) searchBox.classList.remove('is-loading');
|
||||
if (triggerEl && triggerEl.classList) triggerEl.classList.remove('is-loading');
|
||||
});
|
||||
}
|
||||
|
||||
function initAccordion() {
|
||||
var nav = qs('.document-nav');
|
||||
if (!nav) return;
|
||||
nav.addEventListener('click', function (e) {
|
||||
var toggle = e.target.closest('.panel-toggle[data-toggle="collapse"]');
|
||||
if (!toggle) return;
|
||||
e.preventDefault();
|
||||
var targetSel = toggle.getAttribute('data-target');
|
||||
var panel = targetSel ? qs(targetSel, nav) : null;
|
||||
if (!panel) return;
|
||||
var parentSel = toggle.getAttribute('data-parent');
|
||||
if (parentSel) {
|
||||
var parent = qs(parentSel, nav);
|
||||
if (parent) {
|
||||
qsa('.panel-collapse.is-open, .panel-collapse.in', parent).forEach(function (p) {
|
||||
if (p !== panel) {
|
||||
p.classList.remove('is-open', 'in');
|
||||
var t = parent.querySelector('[data-target="#' + p.id + '"]');
|
||||
if (t) t.classList.add('collapsed');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
var open = panel.classList.contains('is-open') || panel.classList.contains('in');
|
||||
if (open) {
|
||||
panel.classList.remove('is-open', 'in');
|
||||
toggle.classList.add('collapsed');
|
||||
} else {
|
||||
panel.classList.add('is-open', 'in');
|
||||
toggle.classList.remove('collapsed');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function initSearch() {
|
||||
var form = qs('.document-search-form');
|
||||
if (!form) return;
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var input = form.querySelector('[name="s"]');
|
||||
var search = input ? String(input.value || '').trim() : '';
|
||||
if (!search.length) {
|
||||
toast('请输入搜索关键词', 'warning');
|
||||
return;
|
||||
}
|
||||
if (search.length < 2) {
|
||||
toast('关键词太短', 'warning');
|
||||
return;
|
||||
}
|
||||
qsa('.cat-load').forEach(function (el) {
|
||||
el.classList.remove('is-loading', 'active');
|
||||
});
|
||||
documentAjax(qs('.document-search'), { search: search });
|
||||
});
|
||||
|
||||
document.addEventListener('click', function (e) {
|
||||
var kw = e.target.closest('.document-search .search_keywords');
|
||||
if (!kw) return;
|
||||
e.preventDefault();
|
||||
var text = (kw.textContent || '').trim();
|
||||
var input = qs('.document-search-form [name="s"]');
|
||||
if (input) {
|
||||
input.value = text;
|
||||
input.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
}
|
||||
if (form) form.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
|
||||
});
|
||||
}
|
||||
|
||||
function initCatLoad() {
|
||||
document.addEventListener('click', function (e) {
|
||||
var a = e.target.closest('.cat-load');
|
||||
if (!a) return;
|
||||
e.preventDefault();
|
||||
qsa('.cat-load').forEach(function (el) {
|
||||
el.classList.remove('is-loading', 'active');
|
||||
});
|
||||
a.classList.add('is-loading', 'active');
|
||||
var catId = a.getAttribute('data-cat-id') || a.getAttribute('cat-id') || '';
|
||||
documentAjax(a, { cat_id: catId });
|
||||
});
|
||||
}
|
||||
|
||||
function initPager() {
|
||||
document.addEventListener('click', function (e) {
|
||||
var a = e.target.closest('.document-nav-container .pagenav a');
|
||||
if (!a) return;
|
||||
e.preventDefault();
|
||||
var paged = a.getAttribute('data-paged') || '';
|
||||
var href = a.getAttribute('href') || '';
|
||||
if (paged) {
|
||||
// Prefer current context from last active cat or search.
|
||||
var active = qs('.cat-load.active');
|
||||
var searchInput = qs('.document-search-form [name="s"]');
|
||||
var data = { paged: paged };
|
||||
if (active) {
|
||||
data.cat_id = active.getAttribute('data-cat-id') || '';
|
||||
} else if (searchInput && searchInput.value) {
|
||||
data.search = searchInput.value.trim();
|
||||
}
|
||||
documentAjax(a, data);
|
||||
return;
|
||||
}
|
||||
if (href && href.indexOf('admin-ajax.php') !== -1) {
|
||||
documentAjax(a, {}, href);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (!qs('.document-nav-container') && !qs('.document-nav')) return;
|
||||
initAccordion();
|
||||
initSearch();
|
||||
initCatLoad();
|
||||
initPager();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@@ -97,6 +97,10 @@
|
||||
btn.title = '关注该用户';
|
||||
}
|
||||
|
||||
if (!isFollowing && btn.closest('.uc-follow-management__item')) {
|
||||
btn.closest('.uc-follow-management__item').remove();
|
||||
}
|
||||
|
||||
// Update follower count display if exists
|
||||
var countEl = document.querySelector('.aksrt-user-home__stat-value[data-followers]');
|
||||
if (countEl && count !== undefined) {
|
||||
|
||||
@@ -1,221 +0,0 @@
|
||||
/**
|
||||
* AKSRT 网址导航页 — search tabs, sticky cat nav, submit modal/AJAX.
|
||||
*
|
||||
* @package AKSRT
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
function qs(sel, root) {
|
||||
return (root || document).querySelector(sel);
|
||||
}
|
||||
|
||||
function qsa(sel, root) {
|
||||
return Array.prototype.slice.call((root || document).querySelectorAll(sel));
|
||||
}
|
||||
|
||||
function ajaxUrl() {
|
||||
if (window.aksrtData && window.aksrtData.ajaxUrl) return window.aksrtData.ajaxUrl;
|
||||
if (window.ajaxurl) return window.ajaxurl;
|
||||
return '/wp-admin/admin-ajax.php';
|
||||
}
|
||||
|
||||
function toast(msg, type) {
|
||||
if (window.aksrt && typeof window.aksrt.toast === 'function') {
|
||||
window.aksrt.toast(msg, type || 'info');
|
||||
return;
|
||||
}
|
||||
if (window.notyf) {
|
||||
try {
|
||||
window.notyf(msg, type === 'danger' ? 'danger' : '');
|
||||
return;
|
||||
} catch (e) { /* ignore */ }
|
||||
}
|
||||
// eslint-disable-next-line no-alert
|
||||
window.alert(msg);
|
||||
}
|
||||
|
||||
/* ---------- search engine tabs ---------- */
|
||||
function initSearchTabs() {
|
||||
var cover = qs('.link-page-search-cover');
|
||||
if (!cover) return;
|
||||
|
||||
qsa('.tab-nav-theme a[data-aksrt-tab-target]', cover).forEach(function (a) {
|
||||
a.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
var target = a.getAttribute('data-aksrt-tab-target');
|
||||
if (!target) return;
|
||||
qsa('.tab-nav-theme li', cover).forEach(function (li) {
|
||||
li.classList.remove('active');
|
||||
});
|
||||
if (a.parentElement) a.parentElement.classList.add('active');
|
||||
qsa('.tab-pane', cover).forEach(function (pane) {
|
||||
pane.classList.remove('active', 'in');
|
||||
});
|
||||
var pane = qs(target, cover);
|
||||
if (pane) pane.classList.add('active', 'in');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------- sticky category nav highlight ---------- */
|
||||
function initCatNav() {
|
||||
var wrap = qs('.links-page-container .fixed-wrap');
|
||||
if (!wrap) return;
|
||||
var nav = qs('.link-nav-box', wrap);
|
||||
var links = qsa('.link-nav-box a[href^="#"]', wrap);
|
||||
var sections = links
|
||||
.map(function (a) {
|
||||
var id = a.getAttribute('href');
|
||||
return id ? document.getElementById(id.replace(/^#/, '')) : null;
|
||||
})
|
||||
.filter(Boolean);
|
||||
if (!links.length || !sections.length) return;
|
||||
|
||||
links.forEach(function (a) {
|
||||
a.addEventListener('click', function (e) {
|
||||
var id = a.getAttribute('href');
|
||||
var el = id ? document.getElementById(id.replace(/^#/, '')) : null;
|
||||
if (!el) return;
|
||||
e.preventDefault();
|
||||
var top = el.getBoundingClientRect().top + window.pageYOffset - 90;
|
||||
window.scrollTo({ top: top, behavior: 'smooth' });
|
||||
});
|
||||
});
|
||||
|
||||
function updateActive() {
|
||||
var y = window.pageYOffset + 120;
|
||||
var current = sections[0];
|
||||
for (var i = 0; i < sections.length; i++) {
|
||||
if (sections[i].offsetTop <= y) current = sections[i];
|
||||
}
|
||||
if (!current) return;
|
||||
links.forEach(function (a) {
|
||||
var li = a.parentElement;
|
||||
if (!li) return;
|
||||
if (a.getAttribute('href') === '#' + current.id) {
|
||||
li.classList.add('active');
|
||||
} else {
|
||||
li.classList.remove('active');
|
||||
}
|
||||
});
|
||||
if (nav) nav.classList.add('affix');
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', updateActive, { passive: true });
|
||||
updateActive();
|
||||
}
|
||||
|
||||
/* ---------- submit modal ---------- */
|
||||
function initSubmitModal() {
|
||||
var modal = qs('#submit-links-modal');
|
||||
if (!modal) return;
|
||||
|
||||
function openModal(e) {
|
||||
if (e) e.preventDefault();
|
||||
modal.classList.add('is-open', 'show');
|
||||
modal.setAttribute('aria-hidden', 'false');
|
||||
document.documentElement.classList.add('aksrt-modal-open');
|
||||
}
|
||||
|
||||
function closeModal(e) {
|
||||
if (e) e.preventDefault();
|
||||
modal.classList.remove('is-open', 'show');
|
||||
modal.setAttribute('aria-hidden', 'true');
|
||||
document.documentElement.classList.remove('aksrt-modal-open');
|
||||
}
|
||||
|
||||
qsa('a[href="#submit-links-modal"], [data-toggle="modal"][href="#submit-links-modal"]').forEach(function (btn) {
|
||||
btn.addEventListener('click', openModal);
|
||||
});
|
||||
|
||||
qsa('[data-dismiss="modal"]', modal).forEach(function (btn) {
|
||||
btn.addEventListener('click', closeModal);
|
||||
});
|
||||
|
||||
modal.addEventListener('click', function (e) {
|
||||
if (e.target === modal) closeModal(e);
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', function (e) {
|
||||
if (e.key === 'Escape' && modal.classList.contains('is-open')) closeModal(e);
|
||||
});
|
||||
|
||||
var fileInput = qs('.aksrt-links-logo-input', modal);
|
||||
var preview = qs('.aksrt-links-logo-preview', modal);
|
||||
if (fileInput && preview) {
|
||||
fileInput.addEventListener('change', function () {
|
||||
var file = fileInput.files && fileInput.files[0];
|
||||
if (!file) return;
|
||||
var url = URL.createObjectURL(file);
|
||||
preview.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
var form = qs('.aksrt-links-submit-form', modal);
|
||||
if (!form) return;
|
||||
|
||||
form.addEventListener('submit', function (e) {
|
||||
e.preventDefault();
|
||||
var btn = qs('.aksrt-links-submit-btn', form);
|
||||
if (btn) {
|
||||
btn.disabled = true;
|
||||
btn.classList.add('loading');
|
||||
}
|
||||
|
||||
var fd = new FormData(form);
|
||||
if (!fd.get('action')) fd.set('action', 'aksrt_frontend_links_submit');
|
||||
|
||||
fetch(ajaxUrl(), {
|
||||
method: 'POST',
|
||||
body: fd,
|
||||
credentials: 'same-origin',
|
||||
})
|
||||
.then(function (r) {
|
||||
return r.json();
|
||||
})
|
||||
.then(function (data) {
|
||||
if (!data || data.error) {
|
||||
toast((data && data.msg) || '提交失败', 'danger');
|
||||
return;
|
||||
}
|
||||
toast(data.msg || '提交成功', 'success');
|
||||
if (data.reload) {
|
||||
window.setTimeout(function () {
|
||||
window.location.reload();
|
||||
}, 600);
|
||||
} else {
|
||||
closeModal();
|
||||
form.reset();
|
||||
}
|
||||
})
|
||||
.catch(function () {
|
||||
toast('网络错误,请稍后重试', 'danger');
|
||||
})
|
||||
.finally(function () {
|
||||
if (btn) {
|
||||
btn.disabled = false;
|
||||
btn.classList.remove('loading');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
if (!document.body.classList.contains('page-template-templates-pages-page-links-php')
|
||||
&& !qs('.page-template-links')
|
||||
&& !qs('.links-page-container')
|
||||
&& !qs('#submit-links-modal')) {
|
||||
// Still bind if modal exists alone.
|
||||
}
|
||||
initSearchTabs();
|
||||
initCatNav();
|
||||
initSubmitModal();
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
} else {
|
||||
init();
|
||||
}
|
||||
})();
|
||||
@@ -82,11 +82,11 @@
|
||||
}
|
||||
target.classList.add('is-loading');
|
||||
var url = restUrl.replace(/\/$/, '') + '/user-center/panel/' + encodeURIComponent(name);
|
||||
if (name === 'creator' || name === 'revenue') {
|
||||
if (name === 'creator' || name === 'revenue' || name === 'posts' || name === 'follow') {
|
||||
var params = queryParams || new URLSearchParams(window.location.search);
|
||||
var allowedParams = name === 'creator'
|
||||
? ['income_page']
|
||||
: ['reward_tab', 'commission_page', 'invite_page'];
|
||||
var allowedParams = name === 'creator' ? ['income_page'] :
|
||||
(name === 'revenue' ? ['reward_tab', 'commission_page', 'invite_page'] :
|
||||
(name === 'posts' ? ['post_status', 'posts_page'] : ['follow_list', 'follow_page']));
|
||||
allowedParams.forEach(function(key) {
|
||||
if (params.get(key)) url += (url.indexOf('?') === -1 ? '?' : '&') + key + '=' + encodeURIComponent(params.get(key));
|
||||
});
|
||||
@@ -328,6 +328,33 @@
|
||||
});
|
||||
}
|
||||
|
||||
function initPostDeletion() {
|
||||
if (document.documentElement.dataset.aksrtPostDeletionBound === 'true') return;
|
||||
document.documentElement.dataset.aksrtPostDeletionBound = 'true';
|
||||
document.addEventListener('click', function(e) {
|
||||
var btn = e.target && e.target.closest ? e.target.closest('[data-action="delete-post"]') : null;
|
||||
if (!btn || btn.disabled || !confirm('确定删除这篇文章?')) return;
|
||||
e.preventDefault();
|
||||
btn.disabled = true;
|
||||
var body = new URLSearchParams();
|
||||
body.set('action', 'aksrt_delete_post');
|
||||
body.set('post_id', btn.getAttribute('data-post-id') || '');
|
||||
body.set('nonce', btn.getAttribute('data-nonce') || submitNonce);
|
||||
fetch(ajaxUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }, credentials: 'same-origin', body: body.toString() })
|
||||
.then(function(response) { return response.json(); })
|
||||
.then(function(response) {
|
||||
if (!response || !response.success) throw new Error('delete-failed');
|
||||
var item = btn.closest('.profile-list-item');
|
||||
if (item) item.remove();
|
||||
if (typeof showToast === 'function') showToast('文章已删除');
|
||||
})
|
||||
.catch(function() {
|
||||
btn.disabled = false;
|
||||
if (typeof showToast === 'function') showToast(i18n.operationFailed || '操作失败');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* ==================== 通知中心 ==================== */
|
||||
function initNotifications() {
|
||||
var list = document.getElementById('aksrt-notification-list');
|
||||
@@ -755,6 +782,7 @@
|
||||
initProfileForm();
|
||||
initAuthForm();
|
||||
initUnfavorite();
|
||||
initPostDeletion();
|
||||
initNotifications();
|
||||
initSettings();
|
||||
});
|
||||
@@ -763,7 +791,8 @@
|
||||
initProfileForm();
|
||||
initAuthForm();
|
||||
initUnfavorite();
|
||||
initNotifications();
|
||||
initPostDeletion();
|
||||
initNotifications();
|
||||
initSettings();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user