From 958f64a9c85ad111dec3036a7667cbadc7fe113e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 28 Oct 2025 17:07:08 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=9A=E3=80=90mall=E3=80=91diy=20editor?= =?UTF-8?q?=20=E7=9A=84=20coupon-card=20=E9=83=A8=E5=88=86=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E7=9A=84=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mobile/coupon-card/component.tsx | 91 ++++++++++++++++++- .../components/mobile/coupon-card/config.ts | 31 +++---- .../coupon-card/coupon-discount-desc.tsx | 34 ------- .../mobile/coupon-card/coupon-discount.tsx | 34 ------- .../mobile/coupon-card/coupon-validTerm.tsx | 28 ------ .../components/mobile/coupon-card/index.vue | 43 ++++----- .../mobile/coupon-card/property.vue | 16 ++-- 7 files changed, 125 insertions(+), 152 deletions(-) delete mode 100644 apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-discount-desc.tsx delete mode 100644 apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-discount.tsx delete mode 100644 apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-validTerm.tsx diff --git a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/component.tsx b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/component.tsx index d4dbfee44..b09a30966 100644 --- a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/component.tsx +++ b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/component.tsx @@ -1,4 +1,87 @@ -// 导出所有优惠券相关组件 -export { CouponDiscount } from './coupon-discount'; -export { CouponDiscountDesc } from './coupon-discount-desc'; -export { CouponValidTerm } from './coupon-validTerm'; +import type { MallCouponTemplateApi } from '#/api/mall/promotion/coupon/couponTemplate'; + +import { defineComponent } from 'vue'; + +import { + CouponTemplateValidityTypeEnum, + PromotionDiscountTypeEnum, +} from '@vben/constants'; +import { floatToFixed2, formatDate } from '@vben/utils'; + +/** 有效期 */ +export const CouponValidTerm = defineComponent({ + name: 'CouponValidTerm', + props: { + coupon: { + type: Object as () => MallCouponTemplateApi.CouponTemplate, + required: true, + }, + }, + setup(props) { + const coupon = props.coupon as MallCouponTemplateApi.CouponTemplate; + const text = + coupon.validityType === CouponTemplateValidityTypeEnum.DATE.type + ? `有效期:${formatDate(coupon.validStartTime, 'YYYY-MM-DD')} 至 ${formatDate( + coupon.validEndTime, + 'YYYY-MM-DD', + )}` + : `领取后第 ${coupon.fixedStartTerm} - ${coupon.fixedEndTerm} 天内可用`; + return () =>
{text}
; + }, +}); + +/** 优惠值 */ +export const CouponDiscount = defineComponent({ + name: 'CouponDiscount', + props: { + coupon: { + type: Object as () => MallCouponTemplateApi.CouponTemplate, + required: true, + }, + }, + setup(props) { + const coupon = props.coupon as MallCouponTemplateApi.CouponTemplate; + // 折扣 + let value = `${(coupon.discountPercent ?? 0) / 10}`; + let suffix = ' 折'; + // 满减 + if (coupon.discountType === PromotionDiscountTypeEnum.PRICE.type) { + value = floatToFixed2(coupon.discountPrice); + suffix = ' 元'; + } + return () => ( +
+ {value} + {suffix} +
+ ); + }, +}); + +/** 优惠描述 */ +export const CouponDiscountDesc = defineComponent({ + name: 'CouponDiscountDesc', + props: { + coupon: { + type: Object as () => MallCouponTemplateApi.CouponTemplate, + required: true, + }, + }, + setup(props) { + const coupon = props.coupon as MallCouponTemplateApi.CouponTemplate; + // 使用条件 + const useCondition = + coupon.usePrice > 0 ? `满${floatToFixed2(coupon.usePrice)}元,` : ''; + // 优惠描述 + const discountDesc = + coupon.discountType === PromotionDiscountTypeEnum.PRICE.type + ? `减${floatToFixed2(coupon.discountPrice)}元` + : `打${(coupon.discountPercent ?? 0) / 10}折`; + return () => ( +
+ {useCondition} + {discountDesc} +
+ ); + }, +}); diff --git a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/config.ts b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/config.ts index 4392494d3..723461b4a 100644 --- a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/config.ts +++ b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/config.ts @@ -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: '优惠券', diff --git a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-discount-desc.tsx b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-discount-desc.tsx deleted file mode 100644 index a79e1f0cb..000000000 --- a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-discount-desc.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { MallCouponTemplateApi } from '#/api/mall/promotion/coupon/couponTemplate'; - -import { defineComponent } from 'vue'; - -import { PromotionDiscountTypeEnum } from '@vben/constants'; -import { floatToFixed2 } from '@vben/utils'; - -// 优惠描述 -export const CouponDiscountDesc = defineComponent({ - name: 'CouponDiscountDesc', - props: { - coupon: { - type: Object as () => MallCouponTemplateApi.CouponTemplate, - required: true, - }, - }, - setup(props) { - const coupon = props.coupon as MallCouponTemplateApi.CouponTemplate; - // 使用条件 - const useCondition = - coupon.usePrice > 0 ? `满${floatToFixed2(coupon.usePrice)}元,` : ''; - // 优惠描述 - const discountDesc = - coupon.discountType === PromotionDiscountTypeEnum.PRICE.type - ? `减${floatToFixed2(coupon.discountPrice)}元` - : `打${coupon.discountPercent / 10}折`; - return () => ( -
- {useCondition} - {discountDesc} -
- ); - }, -}); diff --git a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-discount.tsx b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-discount.tsx deleted file mode 100644 index 9f0c7f5b4..000000000 --- a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-discount.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import type { MallCouponTemplateApi } from '#/api/mall/promotion/coupon/couponTemplate'; - -import { defineComponent } from 'vue'; - -import { PromotionDiscountTypeEnum } from '@vben/constants'; -import { floatToFixed2 } from '@vben/utils'; - -// 优惠值 -export const CouponDiscount = defineComponent({ - name: 'CouponDiscount', - props: { - coupon: { - type: Object as () => MallCouponTemplateApi.CouponTemplate, - required: true, - }, - }, - setup(props) { - const coupon = props.coupon as MallCouponTemplateApi.CouponTemplate; - // 折扣 - let value = `${coupon.discountPercent / 10}`; - let suffix = ' 折'; - // 满减 - if (coupon.discountType === PromotionDiscountTypeEnum.PRICE.type) { - value = floatToFixed2(coupon.discountPrice); - suffix = ' 元'; - } - return () => ( -
- {value} - {suffix} -
- ); - }, -}); diff --git a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-validTerm.tsx b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-validTerm.tsx deleted file mode 100644 index 7b2e373b2..000000000 --- a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/coupon-validTerm.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import type { MallCouponTemplateApi } from '#/api/mall/promotion/coupon/couponTemplate'; - -import { defineComponent } from 'vue'; - -import { CouponTemplateValidityTypeEnum } from '@vben/constants'; -import { formatDate } from '@vben/utils'; - -// 有效期 -export const CouponValidTerm = defineComponent({ - name: 'CouponValidTerm', - props: { - coupon: { - type: Object as () => MallCouponTemplateApi.CouponTemplate, - required: true, - }, - }, - setup(props) { - const coupon = props.coupon as MallCouponTemplateApi.CouponTemplate; - const text = - coupon.validityType === CouponTemplateValidityTypeEnum.DATE.type - ? `有效期:${formatDate(coupon.validStartTime, 'YYYY-MM-DD')} 至 ${formatDate( - coupon.validEndTime, - 'YYYY-MM-DD', - )}` - : `领取后第 ${coupon.fixedStartTerm} - ${coupon.fixedEndTerm} 天内可用`; - return () =>
{text}
; - }, -}); diff --git a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/index.vue b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/index.vue index eb5fbb1a2..b97b54140 100644 --- a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/index.vue +++ b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/index.vue @@ -15,12 +15,19 @@ import { CouponValidTerm, } from './component'; -/** 商品卡片 */ +/** 优惠劵卡片 */ defineOptions({ name: 'CouponCard' }); -// 定义属性 + +/** 定义属性 */ const props = defineProps<{ property: CouponCardProperty }>(); -// 商品列表 -const couponList = ref([]); + +const couponList = ref([]); // 优惠劵列表 +const phoneWidth = ref(375); // 手机宽度 +const containerRef = ref(); // 容器引用 +const scrollbarWidth = ref('100%'); // 滚动条宽度 +const couponWidth = ref(375); // 优惠券宽度 + +/** 监听优惠券 ID 变化,加载优惠券列表 */ watch( () => props.property.couponIds, async () => { @@ -36,15 +43,7 @@ watch( }, ); -// 手机宽度 -const phoneWidth = ref(375); -// 容器 -const containerRef = ref(); -// 滚动条宽度 -const scrollbarWidth = ref('100%'); -// 优惠券的宽度 -const couponWidth = ref(375); -// 计算布局参数 +/** 计算布局参数 */ watch( () => [props.property, phoneWidth, couponList.value.length], () => { @@ -60,8 +59,9 @@ watch( }, { immediate: true, deep: true }, ); + +/** 提取手机宽度 */ onMounted(() => { - // 提取手机宽度 phoneWidth.value = containerRef.value?.wrapRef?.offsetWidth || 375; }); @@ -86,17 +86,14 @@ onMounted(() => { v-for="(coupon, index) in couponList" :key="index" > - +
- - -
@@ -111,17 +108,14 @@ onMounted(() => {
- +
- - -
仅剩:{{ coupon.totalCount - coupon.takeCount }}张
@@ -139,11 +133,9 @@ onMounted(() => {
- +
- -
{
- diff --git a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/property.vue b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/property.vue index 9778fdd62..9913bf542 100644 --- a/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/property.vue +++ b/apps/web-ele/src/views/mall/promotion/components/diy-editor/components/mobile/coupon-card/property.vue @@ -31,20 +31,24 @@ import ComponentContainerProperty from '../../component-container-property.vue'; // TODO: 添加组件 // import CouponSelect from '#/views/mall/promotion/coupon/components/coupon-select.vue'; -// 优惠券卡片属性面板 +/** 优惠券卡片属性面板 */ defineOptions({ name: 'CouponCardProperty' }); const props = defineProps<{ modelValue: CouponCardProperty }>(); + const emit = defineEmits(['update:modelValue']); + const formData = useVModel(props, 'modelValue', emit); -// 优惠券列表 -const couponList = ref([]); +const couponList = ref([]); // 已选择的优惠券列表 const couponSelectDialog = ref(); -// 添加优惠券 + +/** 添加优惠劵 */ const handleAddCoupon = () => { couponSelectDialog.value.open(); }; + +/** 处理优惠劵选择 */ const handleCouponSelect = () => { formData.value.couponIds = couponList.value.map((coupon) => coupon.id); }; @@ -151,7 +155,9 @@ watch( + + - -