feat:【mall】diy editor 的 coupon-card 部分代码的优化
This commit is contained in:
@@ -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 () => <div>{text}</div>;
|
||||
},
|
||||
});
|
||||
|
||||
/** 优惠值 */
|
||||
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 () => (
|
||||
<div>
|
||||
<span class={'text-20px font-bold'}>{value}</span>
|
||||
<span>{suffix}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
/** 优惠描述 */
|
||||
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 () => (
|
||||
<div>
|
||||
<span>{useCondition}</span>
|
||||
<span>{discountDesc}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -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: '优惠券',
|
||||
|
||||
@@ -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 () => (
|
||||
<div>
|
||||
<span>{useCondition}</span>
|
||||
<span>{discountDesc}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -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 () => (
|
||||
<div>
|
||||
<span class={'text-20px font-bold'}>{value}</span>
|
||||
<span>{suffix}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -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 () => <div>{text}</div>;
|
||||
},
|
||||
});
|
||||
@@ -15,12 +15,19 @@ import {
|
||||
CouponValidTerm,
|
||||
} from './component';
|
||||
|
||||
/** 商品卡片 */
|
||||
/** 优惠劵卡片 */
|
||||
defineOptions({ name: 'CouponCard' });
|
||||
// 定义属性
|
||||
|
||||
/** 定义属性 */
|
||||
const props = defineProps<{ property: CouponCardProperty }>();
|
||||
// 商品列表
|
||||
const couponList = ref<MallCouponTemplateApi.CouponTemplate[]>([]);
|
||||
|
||||
const couponList = ref<MallCouponTemplateApi.CouponTemplate[]>([]); // 优惠劵列表
|
||||
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;
|
||||
});
|
||||
</script>
|
||||
@@ -86,17 +86,14 @@ onMounted(() => {
|
||||
v-for="(coupon, index) in couponList"
|
||||
:key="index"
|
||||
>
|
||||
<!-- 布局1:1列-->
|
||||
<!-- 布局 1:1 列-->
|
||||
<div
|
||||
v-if="property.columns === 1"
|
||||
class="ml-4 flex flex-row justify-between p-2"
|
||||
>
|
||||
<div class="flex flex-col justify-evenly gap-1">
|
||||
<!-- 优惠值 -->
|
||||
<CouponDiscount :coupon="coupon" />
|
||||
<!-- 优惠描述 -->
|
||||
<CouponDiscountDesc :coupon="coupon" />
|
||||
<!-- 有效期 -->
|
||||
<CouponValidTerm :coupon="coupon" />
|
||||
</div>
|
||||
<div class="flex flex-col justify-evenly">
|
||||
@@ -111,17 +108,14 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 布局2:2列-->
|
||||
<!-- 布局 2:2 列-->
|
||||
<div
|
||||
v-else-if="property.columns === 2"
|
||||
class="ml-4 flex flex-row justify-between p-2"
|
||||
>
|
||||
<div class="flex flex-col justify-evenly gap-1">
|
||||
<!-- 优惠值 -->
|
||||
<CouponDiscount :coupon="coupon" />
|
||||
<!-- 优惠描述 -->
|
||||
<CouponDiscountDesc :coupon="coupon" />
|
||||
<!-- 领取说明 -->
|
||||
<div v-if="coupon.totalCount >= 0">
|
||||
仅剩:{{ coupon.totalCount - coupon.takeCount }}张
|
||||
</div>
|
||||
@@ -139,11 +133,9 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 布局3:3列-->
|
||||
<!-- 布局 3:3 列-->
|
||||
<div v-else class="flex flex-col items-center justify-around gap-1 p-1">
|
||||
<!-- 优惠值 -->
|
||||
<CouponDiscount :coupon="coupon" />
|
||||
<!-- 优惠描述 -->
|
||||
<CouponDiscountDesc :coupon="coupon" />
|
||||
<div
|
||||
class="rounded-full px-2 py-0.5"
|
||||
@@ -159,4 +151,3 @@ onMounted(() => {
|
||||
</div>
|
||||
</ElScrollbar>
|
||||
</template>
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
@@ -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<MallCouponTemplateApi.CouponTemplate[]>([]);
|
||||
const couponList = ref<MallCouponTemplateApi.CouponTemplate[]>([]); // 已选择的优惠券列表
|
||||
const couponSelectDialog = ref();
|
||||
// 添加优惠券
|
||||
|
||||
/** 添加优惠劵 */
|
||||
const handleAddCoupon = () => {
|
||||
couponSelectDialog.value.open();
|
||||
};
|
||||
|
||||
/** 处理优惠劵选择 */
|
||||
const handleCouponSelect = () => {
|
||||
formData.value.couponIds = couponList.value.map((coupon) => coupon.id);
|
||||
};
|
||||
@@ -151,7 +155,9 @@ watch(
|
||||
</ElCard>
|
||||
</ElForm>
|
||||
</ComponentContainerProperty>
|
||||
|
||||
<!-- 优惠券选择 -->
|
||||
<!-- TODO @AI:优惠劵的选择 -->
|
||||
<CouponSelect
|
||||
ref="couponSelectDialog"
|
||||
v-model:multiple-selection="couponList"
|
||||
@@ -159,5 +165,3 @@ watch(
|
||||
@change="handleCouponSelect"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
|
||||
Reference in New Issue
Block a user