[CMS-VISUAL] F4: Banner 管理改「首页轮播/线上展厅」双 Tab,各 Tab 独立新增/尺寸提示,弹窗归属锚定打开时 Tab

This commit is contained in:
chenxing
2026-09-28 12:33:39 +08:00
parent 3a0f1e0cc9
commit 010fb39e85
+29 -23
View File
@@ -20,13 +20,16 @@ const linkTypeDict = [
];
const linkTypeText = (v: number) => linkTypeDict.find(i => i.value === v)?.label || "-";
/** 展示位(docs/12):home=首页轮播 / gallery=线上展厅图片画廊 */
/** 展示位(docs/12;docs/20 F4 双 Tab 化):home=首页轮播 / gallery=线上展厅图片画廊 */
const position = ref("home");
/** 弹窗打开时的展示位锚点(F4:保存归属以打开时所在 Tab 为准,弹窗期间切换 Tab 不串数据) */
const formPosition = ref("home");
const positionDict = [
{ value: "home", label: "首页轮播", tip: "轮播图设计尺寸建议 1920×560(皮肤包约定)" },
{ value: "gallery", label: "线上展厅", tip: "画廊图片设计尺寸建议 800×520,多图横向轮播(炫彩校园皮肤消费)" },
{ value: "home", label: "首页轮播", short: "轮播", addLabel: "新增轮播", tip: "轮播图设计尺寸建议 1920×560(皮肤包约定)" },
{ value: "gallery", label: "线上展厅", short: "展厅图片", addLabel: "新增展厅图片", tip: "画廊图片设计尺寸建议 800×520,多图横向轮播(炫彩校园皮肤消费)" },
];
const positionTip = computed(() => positionDict.find(p => p.value === position.value)?.tip || "");
const formPositionMeta = computed(() => positionDict.find(p => p.value === formPosition.value)!);
const modalTitle = computed(() => `${form.id ? "编辑" : "新增"}${formPositionMeta.value.short}`);
const columns = [
{
@@ -120,6 +123,7 @@ function openCreate() {
endTime: "",
status: 1,
});
formPosition.value = position.value;
modalVisible.value = true;
}
@@ -135,6 +139,7 @@ function openEdit(row: BannerVo) {
endTime: row.endTime || "",
status: row.status,
});
formPosition.value = position.value;
modalVisible.value = true;
}
@@ -154,7 +159,7 @@ async function save() {
return;
}
if (!form.imageUrl) {
Message.warning("请上传轮播图片");
Message.warning("请上传图片");
return;
}
saving.value = true;
@@ -163,7 +168,8 @@ async function save() {
.save({
id: form.id,
siteId: store.siteId!,
position: position.value,
// F4:保存归属以弹窗打开时所在 Tab 为准(弹窗期间切换 Tab 不串数据)
position: formPosition.value,
title: form.title,
imageUrl: form.imageUrl,
linkType: form.linkType,
@@ -184,7 +190,7 @@ async function save() {
function doDelete(row: BannerVo) {
MyConfirm({
title: "删除轮播",
title: `删除${formPositionMeta.value.short}`,
msg: `确定删除「${row.title}」吗?`,
async onOk() {
await bannerApi.delete({ id: row.id!, siteId: store.siteId! }).send();
@@ -204,34 +210,34 @@ watch(position, () => run());
<template>
<div class="page-wrapper">
<div class="main-container">
<div class="fix mb-12">
<Button class="fl" type="primary" size="large" @click="openCreate">
<Icon type="ios-add" />
新增轮播
</Button>
<span class="size-tip fr">{{ positionTip }}</span>
</div>
<!-- 展示位是筛选维度不是操作,按 bsch 规范归搜索区(左侧下拉) -->
<div class="search-wrap fix">
<Select v-model="position" class="search-wrap_sel">
<Option v-for="p in positionDict" :key="p.value" :value="p.value">{{ p.label }}</Option>
</Select>
</div>
<!-- F4(docs/20):首页轮播 / 线上展厅双 Tab——两个展示位尺寸与管理习惯不同,
各自独立列表、独立新增按钮、独立尺寸提示;切换 Tab 列表即时重载(watch position) -->
<Tabs v-model="position" class="banner-tabs">
<TabPane v-for="p in positionDict" :key="p.value" :label="p.label" :name="p.value">
<div class="fix mb-12">
<Button class="fl" type="primary" size="large" @click="openCreate">
<Icon type="ios-add" />
{{ p.addLabel }}
</Button>
<span class="size-tip fr">{{ p.tip }}</span>
</div>
</TabPane>
</Tabs>
<Table
class="link-table table-bottom-box"
:columns="columns"
:data="rows"
:height="tableHeight"
:loading="loading"
no-data-text="暂无轮播"
:no-data-text="position === 'home' ? '暂无轮播' : '暂无展厅图片'"
/>
<Modal v-model="modalVisible" :title="form.id ? '编辑轮播' : '新增轮播'" :mask-closable="false" width="560px">
<Modal v-model="modalVisible" :title="modalTitle" :mask-closable="false" width="560px">
<Form ref="formRef" :model="form" :rules="rules" :label-width="100">
<FormItem label="标题" prop="title">
<Input v-model="form.title" :maxlength="200" placeholder="alt 文案/无图兜底" />
</FormItem>
<FormItem label="轮播图片" required>
<FormItem :label="formPositionMeta.value.short" required>
<Upload
:action="uploadUrl() + '?siteId=' + store.siteId + '&scene=banner'"
with-credentials