fix(admin): harden hero/banner round-trip and operator cross-links

Align enabled-meta semantics with frontend, allow truly empty titles on
update, use router navigation for manager deep-links, and document fixed
skeleton ownership in module schema copy.
This commit is contained in:
kate522 committed 2026-07-13 22:31:12 +08:00
1 parent dcc82a39e7
commit 24c135aeec
6 files changed
+64 -23

No files matched your search

@@ -2,11 +2,16 @@
<div class="aksrt-page-container content-page">
<PageHeader
title="Banner 管理"
desc="管理首页 Banner 数据,供固定首页和相关展示区域调用;可控制是否显示文字。"
desc="管理首页内容流 Banner 幻灯片(图片、文案、跳转、启用状态)。"
/>
<n-card class="aksrt-section-card" style="margin-bottom:16px;">
<template #header><strong>Banner 显示开关</strong></template>
<template #header>
<div class="aksrt-card-header-row">
<strong>Banner 显示开关</strong>
<n-button size="small" secondary @click="goHeaderComponents">顶部多功能组件(轮播参数)</n-button>
</div>
</template>
<n-form label-placement="left" label-width="180" class="aksrt-form">
<n-form-item label="显示首页 Banner">
<div class="aksrt-inline-setting">
@@ -111,13 +116,19 @@
<script setup>
import { h, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { NButton, NImage, NTag, useDialog, useMessage } from 'naive-ui'
import api from '@/api'
import { openMediaPicker } from '@/utils/media'
import PageHeader from '@/components/PageHeader.vue'
const router = useRouter()
const message = useMessage()
const dialog = useDialog()
function goHeaderComponents() {
router.push('/page-display/header-components')
}
const loading = ref(true)
const saving = ref(false)
const settingsLoading = ref(false)
+13 -2
View File
@@ -1,9 +1,14 @@
<template>
<div class="aksrt-page-container content-page">
<PageHeader title="Hero 轮播管理" desc="管理首页 Hero 轮播数据,供固定首页和相关展示区域调用;标题、副标题可留空。" />
<PageHeader title="Hero 轮播管理" desc="管理首页 Hero 幻灯片内容(图片/视频、文案、图层、跳转)。标题、副标题可留空。" />
<n-card class="aksrt-section-card" style="margin-bottom:16px;">
<template #header><strong>Hero 显示开关</strong></template>
<template #header>
<div class="aksrt-card-header-row">
<strong>Hero 显示开关</strong>
<n-button size="small" secondary @click="goHeaderComponents">顶部多功能组件(搜索/卡片/轮播参数)</n-button>
</div>
</template>
<n-form label-placement="left" label-width="160" class="aksrt-form">
<n-form-item label="显示首页 Hero">
<div class="aksrt-inline-setting">
@@ -196,13 +201,19 @@
<script setup>
import { h, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { NButton, NImage, NTag, useDialog, useMessage } from 'naive-ui'
import api from '@/api'
import { openMediaPicker } from '@/utils/media'
import PageHeader from '@/components/PageHeader.vue'
const router = useRouter()
const message = useMessage()
const dialog = useDialog()
function goHeaderComponents() {
router.push('/page-display/header-components')
}
const loading = ref(true)
const saving = ref(false)
const settingsLoading = ref(false)
@@ -184,9 +184,9 @@
如需调整首页首屏运营区,请前往对应管理页配置幻灯片内容或顶部组件参数。
</n-alert>
<n-space>
<n-button tag="a" href="#/page-display/hero" secondary type="primary">管理 Hero 轮播</n-button>
<n-button tag="a" href="#/page-display/banner" secondary type="primary">管理 Banner 轮播</n-button>
<n-button tag="a" href="#/page-display/header-components" secondary>
<n-button secondary type="primary" @click="router.push('/page-display/hero')">管理 Hero 轮播</n-button>
<n-button secondary type="primary" @click="router.push('/page-display/banner')">管理 Banner 轮播</n-button>
<n-button secondary @click="router.push('/page-display/header-components')">
顶部多功能组件
</n-button>
</n-space>
@@ -204,10 +204,12 @@
<script setup>
import { computed, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { useMessage } from 'naive-ui'
import api from '@/api'
import PageHeader from '@/components/PageHeader.vue'
const router = useRouter()
const message = useMessage()
const loading = ref(true)
const saving = ref(false)
+20
View File
@@ -178,6 +178,26 @@
padding: 24px 0;
}
#aksrt-admin-app .aksrt-card-header-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
width: 100%;
flex-wrap: wrap;
}
#aksrt-admin-app .aksrt-card-header-row__left {
display: inline-flex;
align-items: center;
gap: 8px;
min-width: 0;
}
#aksrt-admin-app .aksrt-card-header-row__title {
font-weight: 600;
}
/* ==================== 卡片 header 行(标题 + 按钮) ==================== */
#aksrt-admin-app .aksrt-card-header-row {
display: flex;
+5 -5
View File
@@ -46,7 +46,7 @@ export const MODULE_LIBRARY = [
type: 'hero',
label: 'Hero 首屏',
icon: 'image',
desc: '大图轮播首屏,支持叠加搜索框和图标卡片',
desc: '固定首页骨架:大图轮播首屏。幻灯片内容在「页面&显示 → Hero 轮播」维护;搜索/卡片参数见「顶部多功能组件」。',
defaultConfig: { with_search: true, show_cards: false, card_columns: 4, icon_cards: [] },
fields: [
{ key: 'with_search', type: 'switch', label: '显示搜索覆盖框' },
@@ -58,7 +58,7 @@ export const MODULE_LIBRARY = [
type: 'banner',
label: 'Banner 轮播',
icon: 'rectangle',
desc: '正文区轮播条',
desc: '固定首页骨架:正文区轮播条。幻灯片内容在「页面&显示 → Banner 轮播」维护。',
defaultConfig: {},
fields: [],
},
@@ -478,7 +478,7 @@ export const PRESET_TEMPLATES = [
{
key: 'resource_standard',
label: '资源站标准',
desc: 'Hero + Tabs + 最新资源 + 下载排行',
desc: 'Hero(固定骨架)+ Tabs + 最新资源 + 下载排行',
modules: [
{ type: 'hero', config: {} },
{ type: 'tabs', config: { count: 8, layout: 'grid-cms' } },
@@ -489,7 +489,7 @@ export const PRESET_TEMPLATES = [
{
key: 'news',
label: '资讯站',
desc: 'Banner + 多个分类块 + 标签云',
desc: 'Banner(固定骨架)+ 多个分类块 + 标签云',
modules: [
{ type: 'banner', config: {} },
{ type: 'category', config: { count: 8, columns: 4, layout: 'card' } },
@@ -500,7 +500,7 @@ export const PRESET_TEMPLATES = [
{
key: 'mixed',
label: '混合站',
desc: 'Hero + 最新文章 + 多个分类块',
desc: 'Hero(固定骨架)+ 最新文章 + 多个分类块',
modules: [
{ type: 'hero', config: {} },
{ type: 'recent', config: { post_type: 'post', count: 6, layout: 'card' } },