新增:导航栏目设计拆分简单和高级展示方式

This commit is contained in:
2024-09-03 01:13:18 +08:00
parent bf43bdbab4
commit aa85c133e3
24 changed files with 1121 additions and 353 deletions
@@ -1,15 +1,21 @@
<!-- 编辑弹窗 -->
<template>
<ele-modal
<a-drawer
:width="1000"
:visible="visible"
:maskClosable="false"
:maxable="true"
:title="isUpdate ? '编辑内容' : '添加内容'"
:title="isUpdate ? '页面设计' : '添加页面设计'"
placement="left"
:confirm-loading="loading"
:body-style="{ paddingBottom: '28px' }"
@update:visible="updateVisible"
@ok="save"
>
<template #extra>
<a-button type="primary" style="margin-right: 8px" @click="save">保存</a-button>
<a-button @click="onPreview">预览</a-button>
</template>
<a-form
ref="formRef"
:model="form"
@@ -19,15 +25,6 @@
styleResponsive ? { md: 21, sm: 19, xs: 24 } : { flex: '1' }
"
>
<a-form-item label="Banner" name="photo">
<SelectFile
:placeholder="`请选择图片`"
:limit="1"
:data="images"
@done="chooseFile"
@del="onDeleteItem"
/>
</a-form-item>
<a-form-item label="网站SEO">
<a-space direction="vertical"
class="w-full">
@@ -51,48 +48,107 @@
/>
</a-space>
</a-form-item>
<a-form-item label="购买链接">
<a-space direction="vertical"
class="w-full">
<a-input
allow-clear
:maxlength="100"
placeholder="购买链接 buyUrl"
v-model:value="form.buyUrl"
/>
<a-form-item label="banner">
<a-space direction="vertical" class="w-full">
<div class="p-2">
<a-radio-group v-model:value="form.showBanner">
<a-radio :value="true">开启</a-radio>
<a-radio :value="false">关闭</a-radio>
</a-radio-group>
</div>
<template v-if="form.showBanner">
<SelectFile
:placeholder="`请选择背景图`"
:limit="1"
:data="images"
@done="chooseFile"
@del="onDeleteItem"
/>
<a-textarea
:rows="4"
:maxlength="200"
placeholder="Tailwind CSS风格"
v-model:value="form.style"
/>
<a-input
allow-clear
:maxlength="100"
:placeholder="`演示地址 demoUrl`"
v-model:value="form.demoUrl"
/>
<a-input
allow-clear
:maxlength="100"
:placeholder="`账号密码 admin,123456`"
v-model:value="form.account"
/>
<a-input
allow-clear
:maxlength="100"
:placeholder="`立即购买 buyUrl`"
v-model:value="form.buyUrl"
/>
<a-input
allow-clear
:maxlength="100"
:placeholder="`产品文档 docUrl`"
v-model:value="form.docUrl"
/>
</template>
</a-space>
<a-divider style="margin: 30px 0" />
</a-form-item>
<a-form-item label="展示方式" name="content">
<a-space direction="vertical" class="w-full">
<div class="p-1.5">
<a-radio-group v-model:value="form.showLayout">
<a-radio :value="false">简单</a-radio>
<a-radio :value="true">高级</a-radio>
</a-radio-group>
</div>
<template v-if="!form.showLayout">
<!-- 编辑器 -->
<div class="content">
<tinymce-editor
v-model:value="content"
:disabled="disabled"
:init="config"
placeholder="图片直接粘贴自动上传"
@paste="onPaste"
/>
</div>
</template>
<template v-if="form.showLayout">
<!-- 组件名称 -->
<a-space direction="vertical" class="w-full">
<template v-for="(item,index) in components" :key="index">
<a-card :title="`${item.name}`" class="layout-item w-full bg-gray-50 my-2">
<template #title>
<a-select
ref="select"
v-model:value="form.adType"
style="width: 120px"
>
<a-select-option value="图片广告">图片广告</a-select-option>
<a-select-option value="幻灯片">幻灯片</a-select-option>
<a-select-option value="视频广告">视频广告</a-select-option>
</a-select>
</template>
</a-card>
</template>
</a-space>
<a-button @click="addComponents">添加组件</a-button>
</template>
</a-space>
</a-form-item>
<a-form-item label="页面样式">
<a-space direction="vertical"
class="w-full">
<a-textarea
:rows="4"
:maxlength="200"
placeholder="Tailwind CSS风格"
v-model:value="form.style"
/>
</a-space>
</a-form-item>
<a-form-item label="页面内容" name="content">
<!-- 编辑器 -->
<div class="content">
<tinymce-editor
v-model:value="content"
:disabled="disabled"
:init="config"
placeholder="图片直接粘贴自动上传"
@paste="onPaste"
/>
</div>
</a-form-item>
<a-form-item label="状态" name="status">
<a-radio-group v-model:value="form.status">
<a-radio :value="0">开启</a-radio>
<a-radio :value="1">关闭</a-radio>
</a-radio-group>
</a-form-item>
<!-- <a-form-item label="状态" name="status">-->
<!-- <a-radio-group v-model:value="form.status">-->
<!-- <a-radio :value="0">开启</a-radio>-->
<!-- <a-radio :value="1">关闭</a-radio>-->
<!-- </a-radio-group>-->
<!-- </a-form-item>-->
</a-form>
</ele-modal>
</a-drawer>
</template>
<script lang="ts" setup>
@@ -119,6 +175,8 @@ const { styleResponsive } = storeToRefs(themeStore);
const disabled = ref(false);
// 编辑器内容,双向绑定
const content = ref<any>('');
// 组件列表
const components = ref<any[]>();
const props = defineProps<{
// 弹窗是否打开
@@ -151,14 +209,22 @@ const { form, resetFields, assignFields } = useFormData<Design>({
description: '',
keywords: '',
content: '',
buyUrl: '',
type: '',
categoryId: undefined,
style: '',
status: 0,
comments: '',
sortNumber: 100,
navigationId: undefined
navigationId: undefined,
showLayout: false,
layout: '',
btn: [],
showBanner: true,
buyUrl: '',
demoUrl: '',
account: '',
docUrl: ''
});
const editorRef = ref<InstanceType<typeof TinymceEditor> | null>(null);
@@ -326,6 +392,41 @@ const onDeleteItem = (index: number) => {
form.photo = '';
}
const addComponents = () => {
if(!components.value){
components.value = [];
}
components.value?.push({
type: 'card',
name: '组件名称',
css: '',
data: []
})
}
const options = [{
value: 'primary',
label: 'primary',
},{
value: 'success',
label: 'success',
},{
value: 'warning',
label: 'warning',
},{
value: 'danger',
label: 'danger',
},{
value: 'info',
label: 'info',
},{
value: 'text',
label: 'text',
}];
const delBtn = (index: number) => {
form.btn?.splice(index,1)
}
/* 保存编辑 */
const save = () => {
@@ -336,11 +437,14 @@ const save = () => {
.validate()
.then(() => {
loading.value = true;
console.log(form);
const formData = {
...form,
layout: JSON.stringify(form),
categoryId: props.categoryId,
content: content.value
content: content.value,
};
console.log(formData);
const saveOrUpdate = isUpdate.value ? updateDesign : addDesign;
saveOrUpdate(formData)
.then((msg) => {
@@ -367,15 +471,18 @@ watch(
if(props.categoryId){
content.value = '';
images.value = []
console.log(props.categoryId);
pageDesign({categoryId: props.categoryId,limit: 1}).then(res => {
const design = res?.list[0];
if(design){
assignFields(design);
if(design.layout){
assignFields(JSON.parse(design.layout));
}
if(design?.content){
content.value = design.content
}
if(design.photo){
form.photo = design.photo;
images.value.push({
uid: uuid(),
url: design.photo,
@@ -399,8 +506,3 @@ watch(
{ immediate: true }
);
</script>
<style lang="less">
.sdf{
display: none;
}
</style>
@@ -55,18 +55,15 @@
@pressEnter="save"
/>
</a-form-item>
<!-- <a-form-item-->
<!-- label="组件路径"-->
<!-- name="component"-->
<!-- v-if="isUpdate"-->
<!-- >-->
<!-- <a-input-->
<!-- allow-clear-->
<!-- placeholder="/pages/product/detail.vue"-->
<!-- v-model:value="form.component"-->
<!-- @pressEnter="save"-->
<!-- />-->
<!-- </a-form-item>-->
<a-form-item label="组件路径" name="component" v-if="isUpdate">
<a-input
allow-clear
disabled
placeholder="/pages/product/detail.vue"
v-model:value="form.component"
@pressEnter="save"
/>
</a-form-item>
<a-form-item label="css样式" name="style" v-if="isUpdate">
<a-input
allow-clear
@@ -202,7 +199,7 @@
navigationId: undefined,
model: 'custom',
code: undefined,
modelName: '通用模型',
modelName: '单页模型',
type: 0,
title: '',
parentId: 0,
@@ -314,11 +311,22 @@
]
});
const chooseModel = (item: Navigation) => {
const chooseModel = (item: any) => {
console.log(item);
form.model = `${item.value}`;
form.modelName = `${item.label}`;
form.componentPath = `${item.component}`;
if (item.value == 'custom') {
form.path = `/custom-${form.navigationId}`;
form.component = `/pages/[${item.value}]/index.vue`;
return;
}
if (item.value == 'links') {
form.path = `https://`;
form.component = `/pages/${item.value}/index.vue`;
return;
}
form.path = `/${item.value}/${form.navigationId}`;
form.component = `/pages/${item.value}/index.vue`;
};
const chooseFile = (data: FileRecord) => {
+57 -17
View File
@@ -35,6 +35,7 @@
<a-radio-group v-model:value="position" @change="reload">
<a-radio-button :value="1">顶部</a-radio-button>
<a-radio-button :value="2">底部</a-radio-button>
<a-radio-button :value="0">不限</a-radio-button>
</a-radio-group>
<a-divider type="vertical" />
<!-- 搜索表单 -->
@@ -49,7 +50,18 @@
</template>
<template #bodyCell="{ column, record, index }">
<template v-if="column.key === 'path'">
<span class="ele-text-placeholder">{{ record.path }}</span>
<span class="cursor-pointer" v-if="isDirectory(record)"></span>
<span
v-else
@click="openSpmUrl(record.path, record, record.navigationId)"
class="ele-text-placeholder cursor-pointer"
>{{ record.path }}</span
>
<!-- <span-->
<!-- class="ele-text-placeholder cursor-pointer"-->
<!-- @click="openSpmUrl(record.path, record, record.navigationId)"-->
<!-- >{{ record.path }}</span-->
<!-- >-->
</template>
<template v-if="column.key === 'component'">
<template v-if="!isDirectory(record)">
@@ -114,12 +126,8 @@
</template>
<template v-else-if="column.key === 'action'">
<a-space>
<a-tooltip :title="`添加自定义组件及样式`">
<a class="text-fuchsia-300" @click="openLayout(record)">布局</a>
</a-tooltip>
<a-divider type="vertical" />
<a-tooltip :title="`配置SEO及页面元素`">
<a class="text-gray-400" @click="openDesign(record)">内容</a>
<a-tooltip :title="`配置SEO及页面内容`">
<a class="text-fuchsia-300" @click="openDesign(record)">设计</a>
</a-tooltip>
<a-divider type="vertical" />
<a-tooltip :title="`添加子分类`">
@@ -193,6 +201,7 @@
import { openSpmUrl } from '@/utils/common';
import { getSiteInfo } from '@/api/layout';
import { Design } from '@/api/cms/design/model';
import router from '@/router';
// 表格实例
const tableRef = ref<InstanceType<typeof EleProTable> | null>(null);
@@ -312,6 +321,10 @@
where.top = undefined;
where.bottom = 0;
}
if (position.value == 0) {
where.top = undefined;
where.bottom = undefined;
}
where.isMpWeixin = false;
return listNavigation({ ...where });
};
@@ -344,22 +357,49 @@
showEdit.value = true;
};
// 跳转模型内容列表
const openDesign = (row?: Navigation) => {
categoryId.value = row?.navigationId;
showDesignEdit.value = true;
// // TODO 通用模型
// if (row?.model == 'custom') {
return;
// if (row && isDirectory(row)) {
// categoryId.value = row?.navigationId;
// showDesignEdit.value = true;
// return;
// }
//
// // TODO 文章列表
// if (row?.model === 'article') {
// router.push({
// path: '/cms/article',
// query: { categoryId: row.navigationId, type: row.type }
// });
// }
// TODO 单页模型
if (row?.model == 'custom') {
router.push({
path: `/cms/design`,
query: {
id: row.navigationId,
type: row.model
}
});
return;
}
// TODO 文章列表
if (row?.model === 'article') {
router.push({
path: `/cms/article`,
query: {
id: row.navigationId,
type: row.model
}
});
return;
}
// TODO 产品列表
if (row?.model === 'product') {
router.push({
path: '/goods/index',
query: { categoryId: row.navigationId, type: row.type }
});
return;
}
};
const openLayout = (row?: Navigation) => {