diff --git a/apps/web-antd/src/views/mall/promotion/rewardActivity/data.ts b/apps/web-antd/src/views/mall/promotion/rewardActivity/data.ts index 613a4a7e7..c1232e43f 100644 --- a/apps/web-antd/src/views/mall/promotion/rewardActivity/data.ts +++ b/apps/web-antd/src/views/mall/promotion/rewardActivity/data.ts @@ -138,6 +138,7 @@ export function useFormSchema(): VbenFormSchema[] { componentProps: { showTime: true, format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', placeholder: [ $t('utils.rangePicker.beginTime'), $t('utils.rangePicker.endTime'), @@ -217,13 +218,15 @@ export function useFormSchema(): VbenFormSchema[] { }, rules: 'required', }, - // TODO @puhui999:1)新增时:一直报:“请输入优惠设置”;2)修改老数据,出现报“请求参数类型错误:50.00”; { fieldName: 'rules', label: '优惠设置', component: 'Input', formItemClass: 'items-start', - rules: 'required', + rules: z + .array(z.any()) + .min(1, { message: '请添加至少一条优惠规则' }) + .default([]), }, { fieldName: 'productScopeValues', // 隐藏字段:用于自动同步 productScopeValues diff --git a/apps/web-antd/src/views/mall/promotion/rewardActivity/modules/form.vue b/apps/web-antd/src/views/mall/promotion/rewardActivity/modules/form.vue index 99e323193..de911c629 100644 --- a/apps/web-antd/src/views/mall/promotion/rewardActivity/modules/form.vue +++ b/apps/web-antd/src/views/mall/promotion/rewardActivity/modules/form.vue @@ -8,10 +8,9 @@ import { PromotionConditionTypeEnum, PromotionProductScopeEnum, } from '@vben/constants'; -import { convertToInteger, formatToFraction } from '@vben/utils'; +import { cloneDeep, convertToInteger, formatToFraction } from '@vben/utils'; import { message } from 'ant-design-vue'; -import dayjs from 'dayjs'; import { useVbenForm } from '#/adapter/form'; import { @@ -53,6 +52,8 @@ const [Form, formApi] = useVbenForm({ const [Modal, modalApi] = useVbenModal({ async onConfirm() { + // 在验证前同步 formData.rules 到表单中 + await formApi.setFieldValue('rules', formData.value.rules || []); const { valid } = await formApi.validate(); if (!valid) { return; @@ -61,18 +62,24 @@ const [Modal, modalApi] = useVbenModal({ // 提交表单 try { const values = await formApi.getValues(); - const data = { ...formData.value, ...values }; + // 使用 formData.value 作为基础,确保 rules 来自 formData + const data = { ...values, ...formData.value }; if (data.startAndEndTime && Array.isArray(data.startAndEndTime)) { data.startTime = data.startAndEndTime[0]; data.endTime = data.startAndEndTime[1]; delete data.startAndEndTime; } - data.rules?.forEach((item: any) => { + // 深拷贝 rules 避免修改原始数据 + const rules = cloneDeep( + data.rules, + ) as unknown as MallRewardActivityApi.RewardRule[]; + rules.forEach((item: any) => { item.discountPrice = convertToInteger(item.discountPrice || 0); if (data.conditionType === PromotionConditionTypeEnum.PRICE.type) { item.limit = convertToInteger(item.limit || 0); } }); + data.rules = rules; await (data.id ? updateRewardActivity(data as MallRewardActivityApi.RewardActivity) : createRewardActivity(data as MallRewardActivityApi.RewardActivity)); @@ -97,9 +104,10 @@ const [Modal, modalApi] = useVbenModal({ modalApi.lock(); try { const result = await getReward(data.id); + // valueFormat: 'x' 配置下,直接使用时间戳 result.startAndEndTime = [ - result.startTime ? dayjs(result.startTime) : undefined, - result.endTime ? dayjs(result.endTime) : undefined, + result.startTime ? String(result.startTime) : undefined, + result.endTime ? String(result.endTime) : undefined, ] as any[]; result.rules?.forEach((item: any) => { item.discountPrice = formatToFraction(item.discountPrice || 0); diff --git a/apps/web-ele/src/views/mall/promotion/rewardActivity/data.ts b/apps/web-ele/src/views/mall/promotion/rewardActivity/data.ts index 57ebd0acb..c1232e43f 100644 --- a/apps/web-ele/src/views/mall/promotion/rewardActivity/data.ts +++ b/apps/web-ele/src/views/mall/promotion/rewardActivity/data.ts @@ -138,6 +138,7 @@ export function useFormSchema(): VbenFormSchema[] { componentProps: { showTime: true, format: 'YYYY-MM-DD HH:mm:ss', + valueFormat: 'x', placeholder: [ $t('utils.rangePicker.beginTime'), $t('utils.rangePicker.endTime'), @@ -222,7 +223,10 @@ export function useFormSchema(): VbenFormSchema[] { label: '优惠设置', component: 'Input', formItemClass: 'items-start', - rules: 'required', + rules: z + .array(z.any()) + .min(1, { message: '请添加至少一条优惠规则' }) + .default([]), }, { fieldName: 'productScopeValues', // 隐藏字段:用于自动同步 productScopeValues diff --git a/apps/web-ele/src/views/mall/promotion/rewardActivity/modules/form.vue b/apps/web-ele/src/views/mall/promotion/rewardActivity/modules/form.vue index b2f3bec94..199242efb 100644 --- a/apps/web-ele/src/views/mall/promotion/rewardActivity/modules/form.vue +++ b/apps/web-ele/src/views/mall/promotion/rewardActivity/modules/form.vue @@ -8,7 +8,7 @@ import { PromotionConditionTypeEnum, PromotionProductScopeEnum, } from '@vben/constants'; -import { convertToInteger, formatToFraction } from '@vben/utils'; +import { cloneDeep, convertToInteger, formatToFraction } from '@vben/utils'; import { ElMessage } from 'element-plus'; @@ -52,6 +52,8 @@ const [Form, formApi] = useVbenForm({ const [Modal, modalApi] = useVbenModal({ async onConfirm() { + // 在验证前同步 formData.rules 到表单中 + await formApi.setFieldValue('rules', formData.value.rules || []); const { valid } = await formApi.validate(); if (!valid) { return; @@ -60,18 +62,24 @@ const [Modal, modalApi] = useVbenModal({ // 提交表单 try { const values = await formApi.getValues(); - const data = { ...formData.value, ...values }; + // 使用 formData.value 作为基础,确保 rules 来自 formData + const data = { ...values, ...formData.value }; if (data.startAndEndTime && Array.isArray(data.startAndEndTime)) { - data.startTime = data.startAndEndTime[0]; - data.endTime = data.startAndEndTime[1]; + data.startTime = Number(data.startAndEndTime[0]); + data.endTime = Number(data.startAndEndTime[1]); delete data.startAndEndTime; } - data.rules?.forEach((item: any) => { + // 深拷贝 rules 避免修改原始数据 + const rules = cloneDeep( + data.rules, + ) as unknown as MallRewardActivityApi.RewardRule[]; + rules.forEach((item: any) => { item.discountPrice = convertToInteger(item.discountPrice || 0); if (data.conditionType === PromotionConditionTypeEnum.PRICE.type) { item.limit = convertToInteger(item.limit || 0); } }); + data.rules = rules; await (data.id ? updateRewardActivity(data as MallRewardActivityApi.RewardActivity) : createRewardActivity(data as MallRewardActivityApi.RewardActivity)); @@ -96,7 +104,11 @@ const [Modal, modalApi] = useVbenModal({ modalApi.lock(); try { const result = await getReward(data.id); - result.startAndEndTime = [result.startTime, result.endTime] as any[]; + // valueFormat: 'x' 配置下,直接使用时间戳字符串 + result.startAndEndTime = [ + result.startTime ? String(result.startTime) : undefined, + result.endTime ? String(result.endTime) : undefined, + ] as any[]; result.rules?.forEach((item: any) => { item.discountPrice = formatToFraction(item.discountPrice || 0); if (result.conditionType === PromotionConditionTypeEnum.PRICE.type) {