review:【antd/ele】【mall】营销活动的实现

This commit is contained in:
YunaiV
2025-12-29 07:03:00 +08:00
parent 6da4a39ff9
commit 029b2ffaab
4 changed files with 11 additions and 19 deletions

View File

@@ -40,6 +40,7 @@ defineOptions({ name: 'DiscountActivityForm' });
const emit = defineEmits(['success']); const emit = defineEmits(['success']);
/** 折扣类型枚举 */ /** 折扣类型枚举 */
// TODO @puhui999这里可以使用 biz-mall 里的枚举噢;
const PromotionDiscountTypeEnum = { const PromotionDiscountTypeEnum = {
PRICE: { type: 1 }, // 满减 PRICE: { type: 1 }, // 满减
PERCENT: { type: 2 }, // 折扣 PERCENT: { type: 2 }, // 折扣
@@ -233,36 +234,33 @@ const [Modal, modalApi] = useVbenModal({
if (!valid) { if (!valid) {
return; return;
} }
// 校验是否选择了商品 // 校验是否选择了商品
if (spuList.value.length === 0) { if (spuList.value.length === 0) {
message.warning('请选择活动商品'); message.warning('请选择活动商品');
return; return;
} }
modalApi.lock(); modalApi.lock();
// 提交表单
try { try {
// 获取折扣商品配置 // 获取折扣商品配置
// TODO @puhui999structuredClone 执行会报错;
const products = structuredClone( const products = structuredClone(
spuAndSkuListRef.value?.getSkuConfigs('productConfig') || [], spuAndSkuListRef.value?.getSkuConfigs('productConfig') || [],
) as MallDiscountActivityApi.DiscountProduct[]; ) as MallDiscountActivityApi.DiscountProduct[];
// 转换金额为分 // 转换金额为分
products.forEach((item) => { products.forEach((item) => {
item.discountPercent = convertToInteger(item.discountPercent); item.discountPercent = convertToInteger(item.discountPercent);
item.discountPrice = convertToInteger(item.discountPrice); item.discountPrice = convertToInteger(item.discountPrice);
}); });
const data = structuredClone( const data = structuredClone(
await formApi.getValues(), await formApi.getValues(),
) as MallDiscountActivityApi.DiscountActivity; ) as MallDiscountActivityApi.DiscountActivity;
data.products = products; data.products = products;
// 提交请求 // 提交请求
await (formData.value?.id await (formData.value?.id
? updateDiscountActivity(data) ? updateDiscountActivity(data)
: createDiscountActivity(data)); : createDiscountActivity(data));
// 关闭并提示
await modalApi.close(); await modalApi.close();
emit('success'); emit('success');
message.success($t('ui.actionMessage.operationSuccess')); message.success($t('ui.actionMessage.operationSuccess'));
@@ -275,18 +273,15 @@ const [Modal, modalApi] = useVbenModal({
await resetForm(); await resetForm();
return; return;
} }
// 加载数据 // 加载数据
const data = modalApi.getData<MallDiscountActivityApi.DiscountActivity>(); const data = modalApi.getData<MallDiscountActivityApi.DiscountActivity>();
if (!data || !data.id) { if (!data || !data.id) {
return; return;
} }
modalApi.lock(); modalApi.lock();
try { try {
const activityData = await getDiscountActivity(data.id); const activityData = await getDiscountActivity(data.id);
formData.value = activityData; formData.value = activityData;
// 加载商品详情 // 加载商品详情
if (activityData.products && activityData.products.length > 0) { if (activityData.products && activityData.products.length > 0) {
// 按 spuId 分组 // 按 spuId 分组
@@ -301,15 +296,13 @@ const [Modal, modalApi] = useVbenModal({
} }
spuProductsMap.get(spuId)!.push(product); spuProductsMap.get(spuId)!.push(product);
} }
// 加载每个 SPU 的详情 // 加载每个 SPU 的详情
for (const [spuId, products] of spuProductsMap) { for (const [spuId, products] of spuProductsMap) {
const skuIdArr = products.map((p) => p.skuId); const skuIdArr = products.map((p) => p.skuId);
await getSpuDetails(spuId, skuIdArr, products, 'load'); await getSpuDetails(spuId, skuIdArr, products, 'load');
} }
} }
// 设置到 values
// 设置表单值
await formApi.setValues(activityData); await formApi.setValues(activityData);
} finally { } finally {
modalApi.unlock(); modalApi.unlock();

View File

@@ -53,6 +53,7 @@ const [Form, formApi] = useVbenForm({
const [Modal, modalApi] = useVbenModal({ const [Modal, modalApi] = useVbenModal({
async onConfirm() { async onConfirm() {
// 在验证前同步 formData.rules 到表单中 // 在验证前同步 formData.rules 到表单中
// TODO @puhui999选择了分类、或者商品还是报没选择
await formApi.setFieldValue('rules', formData.value.rules || []); await formApi.setFieldValue('rules', formData.value.rules || []);
const { valid } = await formApi.validate(); const { valid } = await formApi.validate();
if (!valid) { if (!valid) {
@@ -104,7 +105,6 @@ const [Modal, modalApi] = useVbenModal({
modalApi.lock(); modalApi.lock();
try { try {
const result = await getReward(data.id); const result = await getReward(data.id);
// valueFormat: 'x' 配置下,直接使用时间戳
result.startAndEndTime = [ result.startAndEndTime = [
result.startTime ? String(result.startTime) : undefined, result.startTime ? String(result.startTime) : undefined,
result.endTime ? String(result.endTime) : undefined, result.endTime ? String(result.endTime) : undefined,

View File

@@ -176,9 +176,7 @@ onMounted(() => {
/> />
<div class="flex flex-1 items-center justify-between"> <div class="flex flex-1 items-center justify-between">
<div class="flex flex-col"> <div class="flex flex-col">
<h4 <h4 class="mb-1 text-sm text-black/85 dark:text-white/85">
class="mb-[4px] text-[14px] text-black/85 dark:text-white/85"
>
{{ getDictLabel(DICT_TYPE.SYSTEM_SOCIAL_TYPE, item.type) }} {{ getDictLabel(DICT_TYPE.SYSTEM_SOCIAL_TYPE, item.type) }}
</h4> </h4>
<span class="text-black/45 dark:text-white/45"> <span class="text-black/45 dark:text-white/45">
@@ -186,9 +184,9 @@ onMounted(() => {
{{ item.socialUser?.nickname || item.socialUser?.openid }} {{ item.socialUser?.nickname || item.socialUser?.openid }}
</template> </template>
<template v-else> <template v-else>
绑定{{ 绑定
getDictLabel(DICT_TYPE.SYSTEM_SOCIAL_TYPE, item.type) {{ getDictLabel(DICT_TYPE.SYSTEM_SOCIAL_TYPE, item.type) }}
}}账号 账号
</template> </template>
</span> </span>
</div> </div>

View File

@@ -65,6 +65,7 @@ const [Modal, modalApi] = useVbenModal({
// 使用 formData.value 作为基础,确保 rules 来自 formData // 使用 formData.value 作为基础,确保 rules 来自 formData
const data = { ...values, ...formData.value }; const data = { ...values, ...formData.value };
if (data.startAndEndTime && Array.isArray(data.startAndEndTime)) { if (data.startAndEndTime && Array.isArray(data.startAndEndTime)) {
// TODO @puhui999这里 ele 会告警antd 不会告警,可能要看看;
data.startTime = Number(data.startAndEndTime[0]); data.startTime = Number(data.startAndEndTime[0]);
data.endTime = Number(data.startAndEndTime[1]); data.endTime = Number(data.startAndEndTime[1]);
delete data.startAndEndTime; delete data.startAndEndTime;