新增:导航栏目设计拆分简单和高级展示方式
This commit is contained in:
@@ -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) => {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user