feat:【mall】diy editor 的 promotion-combination 优化
This commit is contained in:
@@ -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: '拼团',
|
||||
|
||||
@@ -15,9 +15,9 @@ import * as CombinationActivityApi from '#/api/mall/promotion/combination/combin
|
||||
|
||||
/** 拼团卡片 */
|
||||
defineOptions({ name: 'PromotionCombination' });
|
||||
// 定义属性
|
||||
|
||||
const props = defineProps<{ property: PromotionCombinationProperty }>();
|
||||
// 商品列表
|
||||
|
||||
const spuList = ref<MallSpuApi.Spu[]>([]);
|
||||
const spuIdList = ref<number[]>([]);
|
||||
const combinationActivityList = ref<
|
||||
@@ -30,7 +30,7 @@ watch(
|
||||
try {
|
||||
// 新添加的拼团组件,是没有活动ID的
|
||||
const activityIds = props.property.activityIds;
|
||||
// 检查活动ID的有效性
|
||||
// 检查活动 ID 的有效性
|
||||
if (Array.isArray(activityIds) && activityIds.length > 0) {
|
||||
// 获取拼团活动详情列表
|
||||
combinationActivityList.value =
|
||||
@@ -70,28 +70,21 @@ watch(
|
||||
},
|
||||
);
|
||||
|
||||
/**
|
||||
* 计算商品的间距
|
||||
* @param index 商品索引
|
||||
*/
|
||||
const calculateSpace = (index: number) => {
|
||||
// 商品的列数
|
||||
const columns = props.property.layoutType === 'twoCol' ? 2 : 1;
|
||||
// 第一列没有左边距
|
||||
const marginLeft = index % columns === 0 ? '0' : `${props.property.space}px`;
|
||||
// 第一行没有上边距
|
||||
const marginTop = index < columns ? '0' : `${props.property.space}px`;
|
||||
|
||||
/** 计算商品的间距 */
|
||||
function calculateSpace(index: number) {
|
||||
const columns = props.property.layoutType === 'twoCol' ? 2 : 1; // 商品的列数
|
||||
const marginLeft = index % columns === 0 ? '0' : `${props.property.space}px`; // 第一列没有左边距
|
||||
const marginTop = index < columns ? '0' : `${props.property.space}px`; // 第一行没有上边距
|
||||
return { marginLeft, marginTop };
|
||||
};
|
||||
}
|
||||
|
||||
// 容器
|
||||
const containerRef = ref();
|
||||
// 计算商品的宽度
|
||||
|
||||
/** 计算商品的宽度 */
|
||||
const calculateWidth = () => {
|
||||
let width = '100%';
|
||||
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
|
||||
if (props.property.layoutType === 'twoCol') {
|
||||
// 双列时每列的宽度为:(总宽度 - 间距)/ 2
|
||||
width = `${(containerRef.value.offsetWidth - props.property.space) / 2}px`;
|
||||
}
|
||||
return { width };
|
||||
@@ -117,7 +110,7 @@ const calculateWidth = () => {
|
||||
>
|
||||
<!-- 角标 -->
|
||||
<div
|
||||
v-if="property.badge.show"
|
||||
v-if="property.badge.show && property.badge.imgUrl"
|
||||
class="absolute left-0 top-0 z-[1] items-center justify-center"
|
||||
>
|
||||
<ElImage
|
||||
@@ -139,7 +132,7 @@ const calculateWidth = () => {
|
||||
<ElImage fit="cover" class="h-full w-full" :src="spu.picUrl" />
|
||||
</div>
|
||||
<div
|
||||
class="box-border flex flex-col gap-2 p-2"
|
||||
class="box-border flex flex-col gap-[8px] p-[8px]"
|
||||
:class="[
|
||||
{
|
||||
'w-full': property.layoutType !== 'oneColSmallImg',
|
||||
@@ -186,7 +179,7 @@ const calculateWidth = () => {
|
||||
class="ml-[4px] text-[10px] line-through"
|
||||
:style="{ color: property.fields.marketPrice.color }"
|
||||
>
|
||||
¥{{ fenToYuan(spu.marketPrice) }}
|
||||
¥{{ fenToYuan(spu.marketPrice!) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-[12px]">
|
||||
@@ -229,5 +222,3 @@ const calculateWidth = () => {
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { PromotionCombinationProperty } from './config';
|
||||
|
||||
import type { MallCombinationActivityApi } from '#/api/mall/promotion/combination/combinationActivity';
|
||||
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
import { CommonStatusEnum } from '@vben/constants';
|
||||
import { IconifyIcon } from '@vben/icons';
|
||||
|
||||
import { useVModel } from '@vueuse/core';
|
||||
import {
|
||||
ElCard,
|
||||
ElCheckbox,
|
||||
ElForm,
|
||||
ElFormItem,
|
||||
ElInput,
|
||||
ElRadioButton,
|
||||
ElRadioGroup,
|
||||
ElSlider,
|
||||
@@ -19,27 +17,20 @@ import {
|
||||
ElTooltip,
|
||||
} from 'element-plus';
|
||||
|
||||
import * as CombinationActivityApi from '#/api/mall/promotion/combination/combinationActivity';
|
||||
import UploadImg from '#/components/upload/image-upload.vue';
|
||||
import CombinationShowcase from '#/views/mall/promotion/combination/components/combination-showcase.vue';
|
||||
import { ColorInput } from '#/views/mall/promotion/components';
|
||||
|
||||
// 拼团属性面板
|
||||
import ComponentContainerProperty from '../../component-container-property.vue';
|
||||
|
||||
/** 拼团属性面板 */
|
||||
defineOptions({ name: 'PromotionCombinationProperty' });
|
||||
|
||||
const props = defineProps<{ modelValue: PromotionCombinationProperty }>();
|
||||
|
||||
const emit = defineEmits(['update:modelValue']);
|
||||
|
||||
const formData = useVModel(props, 'modelValue', emit);
|
||||
// 活动列表
|
||||
const activityList = ref<MallCombinationActivityApi.CombinationActivity[]>([]);
|
||||
onMounted(async () => {
|
||||
const { list } = await CombinationActivityApi.getCombinationActivityPage({
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
status: CommonStatusEnum.ENABLE,
|
||||
});
|
||||
activityList.value = list;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -66,8 +57,8 @@ onMounted(async () => {
|
||||
<IconifyIcon icon="fluent:text-column-two-24-filled" />
|
||||
</ElRadioButton>
|
||||
</ElTooltip>
|
||||
<!--<el-tooltip class="item" content="三列" placement="bottom">
|
||||
<el-radio-button value="threeCol">
|
||||
<!--<ElTooltip class="item" content="三列" placement="bottom">
|
||||
<ElRadioButton value="threeCol">
|
||||
<IconifyIcon icon="fluent:text-column-three-24-filled" />
|
||||
</ElRadioButton>
|
||||
</ElTooltip>-->
|
||||
@@ -115,8 +106,13 @@ onMounted(async () => {
|
||||
<ElSwitch v-model="formData.badge.show" />
|
||||
</ElFormItem>
|
||||
<ElFormItem label="角标" prop="badge.imgUrl" v-if="formData.badge.show">
|
||||
<UploadImg v-model="formData.badge.imgUrl" height="44px" width="72px">
|
||||
<template #tip> 建议尺寸:36 * 22</template>
|
||||
<UploadImg
|
||||
v-model="formData.badge.imgUrl"
|
||||
height="44px"
|
||||
width="72px"
|
||||
:show-description="false"
|
||||
>
|
||||
<template #tip> 建议尺寸:36 * 22 </template>
|
||||
</UploadImg>
|
||||
</ElFormItem>
|
||||
</ElCard>
|
||||
@@ -146,7 +142,7 @@ onMounted(async () => {
|
||||
width="56px"
|
||||
:show-description="false"
|
||||
>
|
||||
<template #tip> 建议尺寸:56 * 56</template>
|
||||
<template #tip> 建议尺寸:56 * 56 </template>
|
||||
</UploadImg>
|
||||
</ElFormItem>
|
||||
</template>
|
||||
@@ -186,5 +182,3 @@ onMounted(async () => {
|
||||
</ElForm>
|
||||
</ComponentContainerProperty>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
Reference in New Issue
Block a user