feat:【antd】【mall】diy-editor 的 config.ts 同步。

This commit is contained in:
YunaiV
2025-11-03 22:53:13 +08:00
parent bd38cf4c7d
commit 06309e40b8
29 changed files with 394 additions and 674 deletions

View File

@@ -14,16 +14,15 @@ import { componentConfigs } from './mobile/index';
/** 组件库:目前左侧的【基础组件】、【图文组件】部分 */
defineOptions({ name: 'ComponentLibrary' });
// 组件列表
/** 组件列表 */
const props = defineProps<{
list: DiyComponentLibrary[];
}>();
// 组件分组
const groups = reactive<any[]>([]);
// 展开的折叠面板
const extendGroups = reactive<string[]>([]);
// 监听 list 属性,按照 DiyComponentLibrary 的 name 分组
const groups = reactive<any[]>([]); // 组件分组
const extendGroups = reactive<string[]>([]); // 展开的折叠面板
/** 监听 list 属性,按照 DiyComponentLibrary 的 name 分组 */
watch(
() => props.list,
() => {
@@ -53,7 +52,7 @@ watch(
},
);
// 克隆组件
/** 克隆组件 */
const handleCloneComponent = (component: DiyComponent<any>) => {
const instance = cloneDeep(component);
instance.uid = Date.now();
@@ -62,7 +61,9 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
</script>
<template>
<div class="editor-left w-[261px]">
<div
class="editor-left z-[1] w-[261px] shrink-0 select-none shadow-[8px_0_8px_-8px_rgb(0_0_0/0.12)]"
>
<div class="h-full overflow-y-auto">
<Collapse v-model:active-key="extendGroups">
<CollapsePanel
@@ -71,7 +72,7 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
:header="group.name"
>
<draggable
class="component-container"
class="flex flex-wrap items-center"
ghost-class="draggable-ghost"
item-key="index"
:list="group.components"
@@ -79,13 +80,22 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
:group="{ name: 'component', pull: 'clone', put: false }"
:clone="handleCloneComponent"
:animation="200"
:force-fallback="true"
:force-fallback="false"
>
<template #item="{ element }">
<div>
<div class="drag-placement">组件放置区域</div>
<div class="component">
<IconifyIcon :icon="element.icon" :size="32" />
<div class="hidden text-white">组件放置区域</div>
<div
class="component flex h-[86px] w-[86px] cursor-move flex-col items-center justify-center border-b border-r [&:nth-of-type(3n)]:border-r-0"
:style="{
borderColor: 'var(--ant-color-split)',
}"
>
<IconifyIcon
:icon="element.icon"
:size="32"
class="mb-1 text-gray-500"
/>
<span class="mt-1 text-xs">{{ element.name }}</span>
</div>
</div>
@@ -99,11 +109,6 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
<style scoped lang="scss">
.editor-left {
z-index: 1;
flex-shrink: 0;
user-select: none;
box-shadow: 8px 0 8px -8px rgb(0 0 0 / 12%);
:deep(.ant-collapse) {
border-top: none;
}
@@ -112,8 +117,8 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
border-bottom: none;
}
:deep(.ant-collapse-content) {
padding-bottom: 0;
:deep(.ant-collapse-content-box) {
padding: 0;
}
:deep(.ant-collapse-header) {
@@ -124,50 +129,19 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
border-bottom: none;
}
.component-container {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.component {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 86px;
height: 86px;
cursor: move;
border-right: 1px solid var(--ant-color-border-secondary);
border-bottom: 1px solid var(--ant-color-border-secondary);
.anticon {
margin-bottom: 4px;
color: gray;
}
}
/* 组件 hover 和 active 状态(需要 CSS 变量)*/
.component.active,
.component:hover {
color: var(--ant-color-white);
background: var(--ant-color-primary);
.anticon {
:deep(.iconify) {
color: var(--ant-color-white);
}
}
.component:nth-of-type(3n) {
border-right: none;
}
}
/* 拖拽占位提示,默认不显示 */
.drag-placement {
display: none;
color: #fff;
}
/* 拖拽区域全局样式 */
.drag-area {
/* 拖拽到手机区域时的样式 */
.draggable-ghost {
@@ -203,14 +177,12 @@ const handleCloneComponent = (component: DiyComponent<any>) => {
background: #5487df;
}
/* 拖拽时隐藏组件 */
.component {
display: none;
display: none; /* 拖拽时隐藏组件 */
}
/* 拖拽时显示占位提示 */
.drag-placement {
display: block;
.hidden {
display: block !important; /* 拖拽时显示占位提示 */
}
}
}

View File

@@ -2,32 +2,24 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 轮播图属性 */
export interface CarouselProperty {
// 类型:默认 | 卡片
type: 'card' | 'default';
// 指示器样式:点 | 数字
indicator: 'dot' | 'number';
// 是否自动播放
autoplay: boolean;
// 播放间隔
interval: number;
// 轮播内容
items: CarouselItemProperty[];
// 组件样式
style: ComponentStyle;
}
// 轮播内容属性
export interface CarouselItemProperty {
// 类型:图片 | 视频
type: 'img' | 'video';
// 图片链接
imgUrl: string;
// 视频链接
videoUrl: string;
// 跳转链接
url: string;
type: 'card' | 'default'; // 类型:默认 | 卡片
indicator: 'dot' | 'number'; // 指示器样式:点 | 数字
autoplay: boolean; // 是否自动播放
interval: number; // 播放间隔
height: number; // 轮播高度
items: CarouselItemProperty[]; // 轮播内容
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 轮播内容属性 */
export interface CarouselItemProperty {
type: 'img' | 'video'; // 类型:图片 | 视频
imgUrl: string; // 图片链接
videoUrl: string; // 视频链接
url: string; // 跳转链接
}
/** 定义组件 */
export const component = {
id: 'Carousel',
name: '轮播图',
@@ -37,6 +29,7 @@ export const component = {
indicator: 'dot',
autoplay: false,
interval: 3,
height: 174,
items: [
{
type: 'img',

View File

@@ -2,19 +2,14 @@ import type { DiyComponent } from '../../../util';
/** 分割线属性 */
export interface DividerProperty {
// 高度
height: number;
// 线宽
lineWidth: number;
// 边距类型
paddingType: 'horizontal' | 'none';
// 颜色
lineColor: string;
// 类型
borderType: 'dashed' | 'dotted' | 'none' | 'solid';
height: number; // 高度
lineWidth: number; // 线宽
paddingType: 'horizontal' | 'none'; // 边距类型
lineColor: string; // 颜色
borderType: 'dashed' | 'dotted' | 'none' | 'solid'; // 类型
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'Divider',
name: '分割线',

View File

@@ -2,19 +2,17 @@ import type { DiyComponent } from '../../../util';
/** 弹窗广告属性 */
export interface PopoverProperty {
list: PopoverItemProperty[];
list: PopoverItemProperty[]; // 弹窗列表
}
/** 弹窗广告项目属性 */
export interface PopoverItemProperty {
// 图片地址
imgUrl: string;
// 跳转连接
url: string;
// 显示类型:仅显示一次、每次启动都会显示
showType: 'always' | 'once';
imgUrl: string; // 图片地址
url: string; // 跳转连接
showType: 'always' | 'once'; // 显示类型:仅显示一次、每次启动都会显示
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'Popover',
name: '弹窗广告',

View File

@@ -1,29 +1,20 @@
import type { ComponentStyle, DiyComponent } from '../../../util';
/** 商品卡片属性 */
/** 优惠劵卡片属性 */
export interface CouponCardProperty {
// 列数
columns: number;
// 背景图
bgImg: string;
// 文字颜色
textColor: string;
// 按钮样式
columns: number; // 列数
bgImg: string; // 背景图
textColor: string; // 文字颜色
button: {
// 背景颜色
bgColor: string;
// 颜色
color: string;
};
// 间距
space: number;
// 优惠券编号列表
couponIds: number[];
// 组件样式
style: ComponentStyle;
bgColor: string; // 背景颜色
color: string; // 文字颜色
}; // 按钮样式
space: number; // 间距
couponIds: number[]; // 优惠券编号列表
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'CouponCard',
name: '优惠券',

View File

@@ -1,28 +1,21 @@
import type { DiyComponent } from '../../../util';
// 悬浮按钮属性
/** 悬浮按钮属性 */
export interface FloatingActionButtonProperty {
// 展开方向
direction: 'horizontal' | 'vertical';
// 是否显示文字
showText: boolean;
// 按钮列表
list: FloatingActionButtonItemProperty[];
direction: 'horizontal' | 'vertical'; // 展开方向
showText: boolean; // 是否显示文字
list: FloatingActionButtonItemProperty[]; // 按钮列表
}
// 悬浮按钮项属性
/** 悬浮按钮项属性 */
export interface FloatingActionButtonItemProperty {
// 图片地址
imgUrl: string;
// 跳转连接
url: string;
// 文字
text: string;
// 文字颜色
textColor: string;
imgUrl: string; // 图片地址
url: string; // 跳转连接
text: string; // 文字
textColor: string; // 文字颜色
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'FloatingActionButton',
name: '悬浮按钮',

View File

@@ -2,31 +2,22 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 热区属性 */
export interface HotZoneProperty {
// 图片地址
imgUrl: string;
// 导航菜单列表
list: HotZoneItemProperty[];
// 组件样式
style: ComponentStyle;
imgUrl: string; // 图片地址
list: HotZoneItemProperty[]; // 导航菜单列表
style: ComponentStyle; // 组件样式
}
/** 热区项目属性 */
export interface HotZoneItemProperty {
// 链接的名称
name: string;
// 链接
url: string;
//
width: number;
// 高
height: number;
// 上
top: number;
// 左
left: number;
name: string; // 链接的名称
url: string; // 链接
width: number; //
height: number; // 高
top: number; //
left: number; // 左
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'HotZone',
name: '热区',

View File

@@ -2,15 +2,12 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 图片展示属性 */
export interface ImageBarProperty {
// 图片链接
imgUrl: string;
// 跳转链接
url: string;
// 组件样式
style: ComponentStyle;
imgUrl: string; // 图片链接
url: string; // 跳转链接
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'ImageBar',
name: '图片展示',

View File

@@ -2,39 +2,24 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 广告魔方属性 */
export interface MagicCubeProperty {
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间隔
space: number;
// 导航菜单列表
list: MagicCubeItemProperty[];
// 组件样式
style: ComponentStyle;
borderRadiusTop: number; // 上圆角
borderRadiusBottom: number; // 下圆角
space: number; // 间隔
list: MagicCubeItemProperty[]; // 导航菜单列表
style: ComponentStyle; // 组件样式
}
/** 广告魔方项目属性 */
export interface MagicCubeItemProperty {
// 图标链接
imgUrl: string;
// 链接
url: string;
//
width: number;
// 高
height: number;
// 上
top: number;
// 左
left: number;
// 右
right: number;
// 下
bottom: number;
imgUrl: string; // 图标链接
url: string; // 链接
width: number; //
height: number; // 高
top: number; //
left: number; // 左
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'MagicCube',
name: '广告魔方',

View File

@@ -4,41 +4,28 @@ import { cloneDeep } from '@vben/utils';
/** 宫格导航属性 */
export interface MenuGridProperty {
// 列数
column: number;
// 导航菜单列表
list: MenuGridItemProperty[];
// 组件样式
style: ComponentStyle;
column: number; // 列数
list: MenuGridItemProperty[]; // 导航菜单列表
style: ComponentStyle; // 组件样式
}
/** 宫格导航项目属性 */
export interface MenuGridItemProperty {
// 图标链接
iconUrl: string;
// 标题
title: string;
// 标题颜色
titleColor: string;
// 副标题
subtitle: string;
// 副标题颜色
subtitleColor: string;
// 链接
url: string;
// 角标
iconUrl: string; // 图标链接
title: string; // 标题
titleColor: string; // 标题颜色
subtitle: string; // 副标题
subtitleColor: string; // 标题颜色
url: string; // 链接
badge: {
// 角标背景颜色
bgColor: string;
// 是否显示
show: boolean;
// 角标文字
text: string;
// 角标文字颜色
textColor: string;
bgColor: string; // 角标背景颜色
show: boolean; // 是否显示
text: string; // 角标文字
textColor: string; // 角标文字颜色
};
}
/** 宫格导航项目默认属性 */
export const EMPTY_MENU_GRID_ITEM_PROPERTY = {
title: '标题',
titleColor: '#333',
@@ -51,7 +38,7 @@ export const EMPTY_MENU_GRID_ITEM_PROPERTY = {
},
} as MenuGridItemProperty;
// 定义组件
/** 定义组件 */
export const component = {
id: 'MenuGrid',
name: '宫格导航',

View File

@@ -4,28 +4,21 @@ import { cloneDeep } from '@vben/utils';
/** 列表导航属性 */
export interface MenuListProperty {
// 导航菜单列表
list: MenuListItemProperty[];
// 组件样式
style: ComponentStyle;
list: MenuListItemProperty[]; // 导航菜单列表
style: ComponentStyle; // 组件样式
}
/** 列表导航项目属性 */
export interface MenuListItemProperty {
// 图标链接
iconUrl: string;
// 标题
title: string;
// 标题颜色
titleColor: string;
// 副标题
subtitle: string;
// 副标题颜色
subtitleColor: string;
// 链接
url: string;
iconUrl: string; // 图标链接
title: string; // 标题
titleColor: string; // 标题颜色
subtitle: string; // 副标题
subtitleColor: string; // 标题颜色
url: string; // 链接
}
/** 空的列表导航项目属性 */
export const EMPTY_MENU_LIST_ITEM_PROPERTY = {
title: '标题',
titleColor: '#333',
@@ -33,7 +26,7 @@ export const EMPTY_MENU_LIST_ITEM_PROPERTY = {
subtitleColor: '#bbb',
};
// 定义组件
/** 定义组件 */
export const component = {
id: 'MenuList',
name: '列表导航',

View File

@@ -4,40 +4,28 @@ import { cloneDeep } from '@vben/utils';
/** 菜单导航属性 */
export interface MenuSwiperProperty {
// 布局: 图标+文字 | 图标
layout: 'icon' | 'iconText';
//
row: number;
// 列数
column: number;
// 导航菜单列表
list: MenuSwiperItemProperty[];
// 组件样式
style: ComponentStyle;
}
/** 菜单导航项目属性 */
export interface MenuSwiperItemProperty {
// 图标链接
iconUrl: string;
// 标题
title: string;
// 标题颜色
titleColor: string;
// 链接
url: string;
// 角标
badge: {
// 角标背景颜色
bgColor: string;
// 是否显示
show: boolean;
// 角标文字
text: string;
// 角标文字颜色
textColor: string;
};
layout: 'icon' | 'iconText'; // 布局:图标+文字 | 图标
row: number; // 行数
column: number; //
list: MenuSwiperItemProperty[]; // 导航菜单列表
style: ComponentStyle; // 组件样式
}
/** 菜单导航项目属性 */
export interface MenuSwiperItemProperty {
iconUrl: string; // 图标链接
title: string; // 标题
titleColor: string; // 标题颜色
url: string; // 链接
badge: {
bgColor: string; // 角标背景颜色
show: boolean; // 是否显示
text: string; // 角标文字
textColor: string; // 角标文字颜色
}; // 角标
}
/** 空菜单导航项目属性 */
export const EMPTY_MENU_SWIPER_ITEM_PROPERTY = {
title: '标题',
titleColor: '#333',
@@ -48,7 +36,7 @@ export const EMPTY_MENU_SWIPER_ITEM_PROPERTY = {
},
} as MenuSwiperItemProperty;
// 定义组件
/** 定义组件 */
export const component = {
id: 'MenuSwiper',
name: '菜单导航',

View File

@@ -2,56 +2,38 @@ import type { DiyComponent } from '../../../util';
/** 顶部导航栏属性 */
export interface NavigationBarProperty {
// 背景类型
bgType: 'color' | 'img';
// 背景颜色
bgColor: string;
// 图片链接
bgImg: string;
// 样式类型:默认 | 沉浸式
styleType: 'inner' | 'normal';
// 常驻显示
alwaysShow: boolean;
// 小程序单元格列表
mpCells: NavigationBarCellProperty[];
// 其它平台单元格列表
otherCells: NavigationBarCellProperty[];
// 本地变量
bgType: 'color' | 'img'; // 背景类型
bgColor: string; // 背景颜色
bgImg: string; // 图片链接
styleType: 'inner' | 'normal'; // 样式类型:默认 | 沉浸式
alwaysShow: boolean; // 常驻显示
mpCells: NavigationBarCellProperty[]; // 小程序单元格列表
otherCells: NavigationBarCellProperty[]; // 其它平台单元格列表
_local: {
// 预览顶部导航(小程序)
previewMp: boolean;
// 预览顶部导航(非小程序)
previewOther: boolean;
};
previewMp: boolean; // 预览顶部导航(小程序)
previewOther: boolean; // 预览顶部导航(非小程序)
}; // 本地变量
}
/** 顶部导航栏 - 单元格 属性 */
export interface NavigationBarCellProperty {
// 类型:文字 | 图片 | 搜索框
type: 'image' | 'search' | 'text';
//
width: number;
// 高度
height: number;
// 顶部位置
top: number;
// 左侧位置
left: number;
// 文字内容
text: string;
// 文字颜色
textColor: string;
// 图片地址
imgUrl: string;
// 图片链接
url: string;
// 搜索框:提示文字
placeholder: string;
// 搜索框:边框圆角半径
borderRadius: number;
type: 'image' | 'search' | 'text'; // 类型:文字 | 图片 | 搜索框
width: number; // 宽度
height: number; //
top: number; // 顶部位置
left: number; // 左侧位置
text: string; // 文字内容
textColor: string; // 文字颜色
imgUrl: string; // 图片地址
url: string; // 图片链接
backgroundColor: string; // 搜索框:框体颜色
placeholder: string; // 搜索框:提示文字
placeholderPosition: string; // 搜索框:提示文字位置
showScan: boolean; // 搜索框:是否显示扫一扫
borderRadius: number; // 搜索框:边框圆角半径
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'NavigationBar',
name: '顶部导航栏',

View File

@@ -2,27 +2,20 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 公告栏属性 */
export interface NoticeBarProperty {
// 图标地址
iconUrl: string;
// 公告内容列表
contents: NoticeContentProperty[];
// 背景颜色
backgroundColor: string;
// 文字颜色
textColor: string;
// 组件样式
style: ComponentStyle;
iconUrl: string; // 图标地址
contents: NoticeContentProperty[]; // 公告内容列表
backgroundColor: string; // 背景颜色
textColor: string; // 文字颜色
style: ComponentStyle; // 组件样式
}
/** 内容属性 */
export interface NoticeContentProperty {
// 内容文字
text: string;
// 链接地址
url: string;
text: string; // 内容文字
url: string; // 链接地址
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'NoticeBar',
name: '公告栏',

View File

@@ -2,15 +2,12 @@ import type { DiyComponent } from '../../../util';
/** 页面设置属性 */
export interface PageConfigProperty {
// 页面描述
description: string;
// 页面背景颜色
backgroundColor: string;
// 页面背景图片
backgroundImage: string;
description: string; // 页面描述
backgroundColor: string; // 页面背景颜色
backgroundImage: string; // 页面背景图片
}
// 定义页面组件
/** 定义页面组件 */
export const component = {
id: 'PageConfig',
name: '页面设置',

View File

@@ -2,63 +2,40 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 商品卡片属性 */
export interface ProductCardProperty {
// 布局类型:单列大图 | 单列小图 | 双列
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol';
// 商品字段
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'; // 布局类型:单列大图 | 单列小图 | 双列
fields: {
// 商品简介
introduction: ProductCardFieldProperty;
// 商品市场价
marketPrice: ProductCardFieldProperty;
// 商品名称
name: ProductCardFieldProperty;
// 商品价格
price: ProductCardFieldProperty;
// 商品销量
salesCount: ProductCardFieldProperty;
// 商品库存
stock: ProductCardFieldProperty;
};
// 角标
introduction: ProductCardFieldProperty; // 商品简介
marketPrice: ProductCardFieldProperty; // 商品市场价
name: ProductCardFieldProperty; // 商品名称
price: ProductCardFieldProperty; // 商品价格
salesCount: ProductCardFieldProperty; // 商品销量
stock: ProductCardFieldProperty; // 商品库存
}; // 商品字段
badge: {
// 角标图片
imgUrl: string;
// 是否显示
show: boolean;
};
// 按钮
imgUrl: string; // 角标图片
show: boolean; // 是否显示
}; // 角标
btnBuy: {
// 文字按钮:背景渐变起始颜色
bgBeginColor: string;
// 文字按钮:背景渐变结束颜色
bgEndColor: string;
// 图片按钮:图片地址
imgUrl: string;
// 文字
text: string;
// 类型:文字 | 图片
type: 'img' | 'text';
};
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 商品编号列表
spuIds: number[];
// 组件样式
style: ComponentStyle;
}
// 商品字段
export interface ProductCardFieldProperty {
// 是否显示
show: boolean;
// 颜色
color: string;
bgBeginColor: string; // 文字按钮:背景渐变起始颜色
bgEndColor: string; // 文字按钮:背景渐变结束颜色
imgUrl: string; // 图片按钮:图片地址
text: string; // 文字
type: 'img' | 'text'; // 类型:文字 | 图片
}; // 按钮
borderRadiusTop: number; // 上圆角
borderRadiusBottom: number; // 下圆角
space: number; // 间距
spuIds: number[]; // 商品编号列表
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 商品字段属性 */
export interface ProductCardFieldProperty {
show: boolean; // 是否显示
color: string; // 颜色
}
/** 定义组件 */
export const component = {
id: 'ProductCard',
name: '商品卡片',

View File

@@ -2,42 +2,29 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 商品栏属性 */
export interface ProductListProperty {
// 布局类型:双列 | 三列 | 水平滑动
layoutType: 'horizSwiper' | 'threeCol' | 'twoCol';
// 商品字段
layoutType: 'horizSwiper' | 'threeCol' | 'twoCol'; // 布局类型:双列 | 三列 | 水平滑动
fields: {
// 商品名称
name: ProductListFieldProperty;
// 商品价格
price: ProductListFieldProperty;
};
// 角标
name: ProductListFieldProperty; // 商品名称
price: ProductListFieldProperty; // 商品价格
}; // 商品字段
badge: {
// 角标图片
imgUrl: string;
// 是否显示
show: boolean;
};
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 商品编号列表
spuIds: number[];
// 组件样式
style: ComponentStyle;
}
// 商品字段
export interface ProductListFieldProperty {
// 是否显示
show: boolean;
// 颜色
color: string;
imgUrl: string; // 角标图片
show: boolean; // 是否显示
}; // 角标
borderRadiusTop: number; // 上圆角
borderRadiusBottom: number; // 下圆角
space: number; // 间距
spuIds: number[]; // 商品编号列表
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 商品字段属性 */
export interface ProductListFieldProperty {
show: boolean; // 是否显示
color: string; // 颜色
}
/** 定义组件 */
export const component = {
id: 'ProductList',
name: '商品栏',

View File

@@ -2,13 +2,11 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 营销文章属性 */
export interface PromotionArticleProperty {
// 文章编号
id: number;
// 组件样式
style: ComponentStyle;
id: number; // 文章编号
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'PromotionArticle',
name: '营销文章',

View File

@@ -2,64 +2,40 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 拼团属性 */
export interface PromotionCombinationProperty {
// 布局类型:单列 | 三列
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol';
// 商品字段
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'; // 布局类型:单列 | 三列
fields: {
// 商品简介
introduction: PromotionCombinationFieldProperty;
// 市场价
marketPrice: PromotionCombinationFieldProperty;
// 商品名称
name: PromotionCombinationFieldProperty;
// 商品价格
price: PromotionCombinationFieldProperty;
// 商品销量
salesCount: PromotionCombinationFieldProperty;
// 商品库存
stock: PromotionCombinationFieldProperty;
};
// 角标
introduction: PromotionCombinationFieldProperty; // 商品简介
marketPrice: PromotionCombinationFieldProperty; // 市场价
name: PromotionCombinationFieldProperty; // 商品名称
price: PromotionCombinationFieldProperty; // 商品价格
salesCount: PromotionCombinationFieldProperty; // 商品销量
stock: PromotionCombinationFieldProperty; // 商品库存
}; // 商品字段
badge: {
// 角标图片
imgUrl: string;
// 是否显示
show: boolean;
};
// 按钮
imgUrl: string; // 角标图片
show: boolean; // 是否显示
}; // 角标
btnBuy: {
// 文字按钮:背景渐变起始颜色
bgBeginColor: string;
// 文字按钮:背景渐变结束颜色
bgEndColor: string;
// 图片按钮:图片地址
imgUrl: string;
// 文字
text: string;
// 类型:文字 | 图片
type: 'img' | 'text';
};
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 拼团活动编号
activityIds: number[];
// 组件样式
style: ComponentStyle;
bgBeginColor: string; // 文字按钮:背景渐变起始颜色
bgEndColor: string; // 文字按钮:背景渐变结束颜色
imgUrl: string; // 图片按钮:图片地址
text: string; // 文字
type: 'img' | 'text'; // 类型:文字 | 图片
}; // 按钮
borderRadiusTop: number; // 上圆角
borderRadiusBottom: number; // 下圆角
space: number; // 间距
activityIds: number[]; // 拼团活动编号
style: ComponentStyle; // 组件样式
}
// 商品字段
/** 商品字段属性 */
export interface PromotionCombinationFieldProperty {
// 是否显示
show: boolean;
// 颜色
color: string;
show: boolean; // 是否显示
color: string; // 颜色
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'PromotionCombination',
name: '拼团',

View File

@@ -2,64 +2,41 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 积分商城属性 */
export interface PromotionPointProperty {
// 布局类型:单列 | 三列
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol';
// 商品字段
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'; // 布局类型:单列 | 三列
fields: {
// 商品简介
introduction: PromotionPointFieldProperty;
// 市场价
marketPrice: PromotionPointFieldProperty;
// 商品名称
name: PromotionPointFieldProperty;
// 商品价格
price: PromotionPointFieldProperty;
// 商品销量
salesCount: PromotionPointFieldProperty;
// 商品库存
stock: PromotionPointFieldProperty;
};
// 角标
introduction: PromotionPointFieldProperty; // 商品简介
marketPrice: PromotionPointFieldProperty; // 市场价
name: PromotionPointFieldProperty; // 商品名称
price: PromotionPointFieldProperty; // 商品价格
salesCount: PromotionPointFieldProperty; // 商品销量
stock: PromotionPointFieldProperty; // 商品库存
}; // 商品字段
badge: {
// 角标图片
imgUrl: string;
// 是否显示
show: boolean;
};
imgUrl: string; // 角标图片
show: boolean; // 是否显示
}; // 角标
// 按钮
btnBuy: {
// 文字按钮:背景渐变起始颜色
bgBeginColor: string;
// 文字按钮:背景渐变结束颜色
bgEndColor: string;
// 图片按钮:图片地址
imgUrl: string;
// 文字
text: string;
// 类型:文字 | 图片
type: 'img' | 'text';
};
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 秒杀活动编号
activityIds: number[];
// 组件样式
style: ComponentStyle;
bgBeginColor: string; // 文字按钮:背景渐变起始颜色
bgEndColor: string; // 文字按钮:背景渐变结束颜色
imgUrl: string; // 图片按钮:图片地址
text: string; // 文字
type: 'img' | 'text'; // 类型:文字 | 图片
}; // 按钮
borderRadiusTop: number; // 上圆角
borderRadiusBottom: number; // 下圆角
space: number; // 间距
activityIds: number[]; // 积分活动编号
style: ComponentStyle; // 组件样式
}
// 商品字段
/** 商品字段属性 */
export interface PromotionPointFieldProperty {
// 是否显示
show: boolean;
// 颜色
color: string;
show: boolean; // 是否显示
color: string; // 颜色
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'PromotionPoint',
name: '积分商城',

View File

@@ -2,64 +2,40 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 秒杀属性 */
export interface PromotionSeckillProperty {
// 布局类型:单列 | 三列
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol';
// 商品字段
layoutType: 'oneColBigImg' | 'oneColSmallImg' | 'twoCol'; // 布局类型:单列 | 三列
fields: {
// 商品简介
introduction: PromotionSeckillFieldProperty;
// 市场价
marketPrice: PromotionSeckillFieldProperty;
// 商品名称
name: PromotionSeckillFieldProperty;
// 商品价格
price: PromotionSeckillFieldProperty;
// 商品销量
salesCount: PromotionSeckillFieldProperty;
// 商品库存
stock: PromotionSeckillFieldProperty;
};
// 角标
introduction: PromotionSeckillFieldProperty; // 商品简介
marketPrice: PromotionSeckillFieldProperty; // 市场价
name: PromotionSeckillFieldProperty; // 商品名称
price: PromotionSeckillFieldProperty; // 商品价格
salesCount: PromotionSeckillFieldProperty; // 商品销量
stock: PromotionSeckillFieldProperty; // 商品库存
}; // 商品字段
badge: {
// 角标图片
imgUrl: string;
// 是否显示
show: boolean;
};
// 按钮
imgUrl: string; // 角标图片
show: boolean; // 是否显示
}; // 角标
btnBuy: {
// 文字按钮:背景渐变起始颜色
bgBeginColor: string;
// 文字按钮:背景渐变结束颜色
bgEndColor: string;
// 图片按钮:图片地址
imgUrl: string;
// 文字
text: string;
// 类型:文字 | 图片
type: 'img' | 'text';
};
// 上圆角
borderRadiusTop: number;
// 下圆角
borderRadiusBottom: number;
// 间距
space: number;
// 秒杀活动编号
activityIds: number[];
// 组件样式
style: ComponentStyle;
bgBeginColor: string; // 文字按钮:背景渐变起始颜色
bgEndColor: string; // 文字按钮:背景渐变结束颜色
imgUrl: string; // 图片按钮:图片地址
text: string; // 文字
type: 'img' | 'text'; // 类型:文字 | 图片
}; // 按钮
borderRadiusTop: number; // 上圆角
borderRadiusBottom: number; // 下圆角
space: number; // 间距
activityIds: number[]; // 秒杀活动编号
style: ComponentStyle; // 组件样式
}
// 商品字段
/** 商品字段属性 */
export interface PromotionSeckillFieldProperty {
// 是否显示
show: boolean;
// 颜色
color: string;
show: boolean; // 是否显示
color: string; // 颜色
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'PromotionSeckill',
name: '秒杀',

View File

@@ -13,10 +13,10 @@ export interface SearchProperty {
style: ComponentStyle;
}
// 文字位置
/** 文字位置 */
export type PlaceholderPosition = 'center' | 'left';
// 定义组件
/** 定义组件 */
export const component = {
id: 'SearchBar',
name: '搜索框',

View File

@@ -2,41 +2,29 @@ import type { DiyComponent } from '../../../util';
/** 底部导航菜单属性 */
export interface TabBarProperty {
// 选项列表
items: TabBarItemProperty[];
// 主题
theme: string;
// 样式
style: TabBarStyle;
items: TabBarItemProperty[]; // 选项列表
theme: string; // 主题
style: TabBarStyle; // 样式
}
// 选项属性
/** 选项属性 */
export interface TabBarItemProperty {
// 标签文字
text: string;
// 链接
url: string;
// 默认图标链接
iconUrl: string;
// 选中的图标链接
activeIconUrl: string;
text: string; // 标签文字
url: string; // 链接
iconUrl: string; // 默认图标链接
activeIconUrl: string; // 选中的图标链接
}
// 样式
/** 样式 */
export interface TabBarStyle {
// 背景类型
bgType: 'color' | 'img';
// 背景颜色
bgColor: string;
// 图片链接
bgImg: string;
// 默认颜色
color: string;
// 选中的颜色
activeColor: string;
bgType: 'color' | 'img'; // 背景类型
bgColor: string; // 背景颜色
bgImg: string; // 图片链接
color: string; // 默认颜色
activeColor: string; // 选中的颜色
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'TabBar',
name: '底部导航',

View File

@@ -2,46 +2,28 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 标题栏属性 */
export interface TitleBarProperty {
// 背景图
bgImgUrl: string;
// 偏移
marginLeft: number;
// 显示位置
textAlign: 'center' | 'left';
// 主标题
title: string;
// 副标题
description: string;
// 标题大小
titleSize: number;
// 描述大小
descriptionSize: number;
// 标题粗细
titleWeight: number;
// 描述粗细
descriptionWeight: number;
// 标题颜色
titleColor: string;
// 描述颜色
descriptionColor: string;
// 高度
height: number;
// 查看更多
bgImgUrl: string; // 背景图
marginLeft: number; // 偏移
textAlign: 'center' | 'left'; // 显示位置
title: string; // 主标题
description: string; // 副标题
titleSize: number; // 标题大小
descriptionSize: number; // 描述大小
titleWeight: number; // 标题粗细
descriptionWeight: number; // 描述粗细
titleColor: string; // 标题颜色
descriptionColor: string; // 描述颜色
height: number; // 高度
more: {
// 是否显示查看更多
show: false;
// 自定义文字
text: string;
// 样式选择
type: 'all' | 'icon' | 'text';
// 链接
url: string;
};
// 组件样式
style: ComponentStyle;
show: false; // 是否显示查看更多
text: string; // 自定义文字
type: 'all' | 'icon' | 'text'; // 样式选择
url: string; // 链接
}; // 查看更多
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'TitleBar',
name: '标题栏',

View File

@@ -2,11 +2,10 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 用户卡片属性 */
export interface UserCardProperty {
// 组件样式
style: ComponentStyle;
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'UserCard',
name: '用户卡片',

View File

@@ -2,11 +2,10 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 用户订单属性 */
export interface UserOrderProperty {
// 组件样式
style: ComponentStyle;
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'UserOrder',
name: '用户订单',

View File

@@ -2,11 +2,10 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 用户资产属性 */
export interface UserWalletProperty {
// 组件样式
style: ComponentStyle;
style: ComponentStyle; // 组件样式
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'UserWallet',
name: '用户资产',

View File

@@ -2,23 +2,18 @@ import type { ComponentStyle, DiyComponent } from '../../../util';
/** 视频播放属性 */
export interface VideoPlayerProperty {
// 视频链接
videoUrl: string;
// 封面链接
posterUrl: string;
// 是否自动播放
autoplay: boolean;
// 组件样式
style: VideoPlayerStyle;
videoUrl: string; // 视频链接
posterUrl: string; // 封面链接
autoplay: boolean; // 是否自动播放
style: VideoPlayerStyle; // 组件样式
}
// 视频播放样式
/** 视频播放样式 */
export interface VideoPlayerStyle extends ComponentStyle {
// 视频高度
height: number;
height: number; // 视频高度
}
// 定义组件
/** 定义组件 */
export const component = {
id: 'VideoPlayer',
name: '视频播放',

View File

@@ -3,12 +3,12 @@ import type { DiyComponent, DiyComponentLibrary, PageConfig } from './util';
import { onMounted, ref, unref, watch } from 'vue';
import { IFrame } from '@vben/common-ui';
import { useVbenModal } from '@vben/common-ui';
import { IconifyIcon } from '@vben/icons';
import { cloneDeep, isEmpty, isString } from '@vben/utils';
import { useQRCode } from '@vueuse/integrations/useQRCode';
import { Button, Card, Modal, Tag, Tooltip } from 'ant-design-vue';
import { Button, Card, Image, Tag, Tooltip } from 'ant-design-vue';
import draggable from 'vuedraggable';
import statusBarImg from '#/assets/imgs/diy/statusBar.png';
@@ -37,7 +37,7 @@ const props = defineProps({
previewUrl: { type: String, default: '' }, // 预览地址:提供了预览地址,才会显示预览按钮
});
const emits = defineEmits(['reset', 'preview', 'save', 'update:modelValue']); // 工具栏操作
const emits = defineEmits(['reset', 'save', 'update:modelValue']); // 工具栏操作
const qrcode = useQRCode(props.previewUrl, {
errorCorrectionLevel: 'H',
@@ -68,17 +68,20 @@ watch(
isString(props.modelValue) && !isEmpty(props.modelValue)
? (JSON.parse(props.modelValue) as PageConfig)
: props.modelValue;
// TODO @AI这里可以简化么idea 提示 Invalid 'typeof' check: 'modelValue' cannot have type 'string'
// noinspection SuspiciousTypeOfGuard
pageConfigComponent.value.property =
(typeof modelValue !== 'string' && modelValue?.page) ||
PAGE_CONFIG_COMPONENT.property;
// noinspection SuspiciousTypeOfGuard
navigationBarComponent.value.property =
(typeof modelValue !== 'string' && modelValue?.navigationBar) ||
NAVIGATION_BAR_COMPONENT.property;
// noinspection SuspiciousTypeOfGuard
tabBarComponent.value.property =
(typeof modelValue !== 'string' && modelValue?.tabBar) ||
TAB_BAR_COMPONENT.property;
// 查找对应的页面组件
// noinspection SuspiciousTypeOfGuard
pageComponents.value = (
(typeof modelValue !== 'string' && modelValue?.components) ||
[]
@@ -99,6 +102,11 @@ watch(
if (!val || selectedComponentIndex.value === -1) {
return;
}
// 如果是基础设置页,默认选中的索引改成 -1为了防止删除组件后切换到此页导致报错
// https://gitee.com/yudaocode/yudao-ui-admin-vue3/pulls/792
if (props.showTabBar) {
selectedComponentIndex.value = -1;
}
pageComponents.value[selectedComponentIndex.value] =
selectedComponent.value!;
},
@@ -251,12 +259,17 @@ function handleReset() {
emits('reset');
}
// TODO @AI搞成 modal 来?
const [PreviewModal, previewModalApi] = useVbenModal({
showConfirmButton: false,
showCancelButton: false,
onCancel() {
previewModalApi.close();
},
});
/** 预览 */
const previewDialogVisible = ref(false);
function handlePreview() {
previewDialogVisible.value = true;
emits('preview');
previewModalApi.open();
}
/** 设置默认选中的组件 */
@@ -457,19 +470,18 @@ onMounted(() => {
</div>
<!-- 预览弹框 -->
<Modal v-model:open="previewDialogVisible" title="预览" width="700">
<PreviewModal title="预览" class="w-700px">
<div class="flex justify-around">
<IFrame
<iframe
:src="previewUrl"
class="h-[667px] w-[375px] rounded-lg border-4 border-solid p-0.5"
/>
></iframe>
<div class="flex flex-col">
<div class="text-base">手机扫码预览</div>
<img :src="qrcode" alt="qrcode" class="w-1/2" />
<!-- <Qrcode :text="previewUrl" logo="/logo.gif" /> -->
<Image :src="qrcode" alt="qrcode" />
</div>
</div>
</Modal>
</PreviewModal>
</div>
</template>
<style lang="scss" scoped>