|
|
@@ -1,18 +1,18 @@
|
|
|
<template>
|
|
|
<ele-modal v-model="visible" :title="title" width="800px" :append-to-body="true" :close-on-click-modal="false">
|
|
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
|
|
|
- <el-form-item label="活动名称" prop="name">
|
|
|
- <el-input v-model="form.name" placeholder="请输入活动名称" maxlength="20" show-word-limit />
|
|
|
+ <el-form-item label="活动名称" prop="activityName">
|
|
|
+ <el-input v-model="form.activityName" placeholder="请输入活动名称" maxlength="20" show-word-limit />
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="使用商品" required>
|
|
|
- <el-radio-group v-model="form.productType">
|
|
|
- <el-radio label="all">所有商品</el-radio>
|
|
|
- <el-radio label="specific">指定商品</el-radio>
|
|
|
+ <el-radio-group v-model="form.scope">
|
|
|
+ <el-radio label="1">所有商品</el-radio>
|
|
|
+ <el-radio label="2">指定商品</el-radio>
|
|
|
</el-radio-group>
|
|
|
- <div v-if="form.productType === 'specific'" class="mt-2">
|
|
|
- <el-button type="primary" plain size="small">选择商品</el-button>
|
|
|
- <span class="text-gray-400 text-xs ml-2">已选 {{ form.products.length }} 个商品</span>
|
|
|
+ <div v-if="form.scope === '2'" class="mt-2 w-full">
|
|
|
+ <el-input v-model="form.isbnText" type="textarea" :rows="4" placeholder="请输入商品ISBN,多个用逗号或换行分隔" />
|
|
|
+ <span class="text-gray-400 text-xs ml-2">已输入 {{ isbnCount }} 个ISBN</span>
|
|
|
</div>
|
|
|
</el-form-item>
|
|
|
|
|
|
@@ -23,40 +23,40 @@
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="设置优惠" required>
|
|
|
- <el-radio-group v-model="form.discountType" class="mb-4">
|
|
|
- <el-radio label="tiered">阶梯优惠</el-radio>
|
|
|
- <el-radio label="nocap">上不封顶</el-radio>
|
|
|
+ <el-radio-group v-model="form.type" class="mb-4">
|
|
|
+ <el-radio label="1">阶梯优惠</el-radio>
|
|
|
+ <el-radio label="2">上不封顶</el-radio>
|
|
|
</el-radio-group>
|
|
|
|
|
|
- <!-- Tiered Discount -->
|
|
|
- <div v-if="form.discountType === 'tiered'" class="bg-gray-50 p-4 rounded">
|
|
|
- <div v-for="(tier, index) in form.tiers" :key="index" class="flex items-center mb-2 last:mb-0">
|
|
|
+ <!-- Tiered Discount (Type 1) -->
|
|
|
+ <div v-if="form.type === '1'" class="bg-gray-50 p-4 rounded">
|
|
|
+ <div v-for="(tier, index) in form.stepList" :key="index" class="flex items-center mb-2 last:mb-0">
|
|
|
<span class="mr-2">满</span>
|
|
|
- <el-input-number v-model="tier.threshold" :min="0" :precision="2" :controls="false"
|
|
|
+ <el-input-number v-model="tier.thresholdMoney" :min="0" :precision="2" :controls="false"
|
|
|
class="!w-[100px]" />
|
|
|
<span class="mx-2">元</span>
|
|
|
<span class="mr-2">减</span>
|
|
|
- <el-input-number v-model="tier.discount" :min="0" :precision="2" :controls="false"
|
|
|
+ <el-input-number v-model="tier.discountMoney" :min="0" :precision="2" :controls="false"
|
|
|
class="!w-[100px]" />
|
|
|
<span class="mx-2">元</span>
|
|
|
- <el-button v-if="form.tiers.length > 1" type="danger" link @click="removeTier(index)">
|
|
|
+ <el-button v-if="form.stepList.length > 1" type="danger" link @click="removeTier(index)">
|
|
|
删除
|
|
|
</el-button>
|
|
|
</div>
|
|
|
- <el-button v-if="form.tiers.length < 5" type="success" class="mt-2 w-full" @click="addTier">
|
|
|
+ <el-button v-if="form.stepList.length < 5" type="success" class="mt-2 w-full" @click="addTier">
|
|
|
增加一级优惠
|
|
|
</el-button>
|
|
|
<div class="text-orange-400 text-xs mt-2">最多可设置5个阶梯</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- No Cap Discount -->
|
|
|
+ <!-- No Cap Discount (Type 2) -->
|
|
|
<div v-else class="bg-gray-50 p-4 rounded flex items-center">
|
|
|
<span class="mr-2">每满</span>
|
|
|
- <el-input-number v-model="form.nocap.threshold" :min="0" :precision="2" :controls="false"
|
|
|
+ <el-input-number v-model="form.thresholdMoney" :min="0" :precision="2" :controls="false"
|
|
|
class="!w-[100px]" />
|
|
|
<span class="mx-2">元</span>
|
|
|
<span class="mr-2">减</span>
|
|
|
- <el-input-number v-model="form.nocap.discount" :min="0" :precision="2" :controls="false"
|
|
|
+ <el-input-number v-model="form.discountMoney" :min="0" :precision="2" :controls="false"
|
|
|
class="!w-[100px]" />
|
|
|
<span class="mx-2">元</span>
|
|
|
</div>
|
|
|
@@ -72,6 +72,7 @@
|
|
|
<script setup>
|
|
|
import { ref, reactive, computed, watch } from 'vue';
|
|
|
import { EleMessage } from 'ele-admin-plus/es';
|
|
|
+import request from '@/utils/request';
|
|
|
|
|
|
const props = defineProps({
|
|
|
modelValue: Boolean,
|
|
|
@@ -89,74 +90,124 @@ const title = computed(() => props.data ? '编辑活动' : '新建活动');
|
|
|
|
|
|
const formRef = ref(null);
|
|
|
const form = reactive({
|
|
|
- name: '',
|
|
|
- productType: 'all',
|
|
|
- products: [],
|
|
|
+ id: undefined,
|
|
|
+ activityName: '',
|
|
|
+ scope: '1',
|
|
|
+ isbnText: '',
|
|
|
dateRange: [],
|
|
|
- discountType: 'tiered',
|
|
|
- tiers: [{ threshold: undefined, discount: undefined }],
|
|
|
- nocap: { threshold: undefined, discount: undefined }
|
|
|
+ type: '1',
|
|
|
+ stepList: [{ thresholdMoney: undefined, discountMoney: undefined }],
|
|
|
+ thresholdMoney: undefined,
|
|
|
+ discountMoney: undefined
|
|
|
+});
|
|
|
+
|
|
|
+const isbnCount = computed(() => {
|
|
|
+ if (!form.isbnText) return 0;
|
|
|
+ return form.isbnText.split(/[\n,]/).filter(item => item.trim()).length;
|
|
|
});
|
|
|
|
|
|
const rules = {
|
|
|
- name: [{ required: true, message: '请输入活动名称', trigger: 'blur' }],
|
|
|
+ activityName: [{ required: true, message: '请输入活动名称', trigger: 'blur' }],
|
|
|
dateRange: [{ required: true, message: '请选择活动时间', trigger: 'change', type: 'array' }]
|
|
|
};
|
|
|
|
|
|
watch(() => props.data, (val) => {
|
|
|
if (val) {
|
|
|
- // Populate form with val
|
|
|
- Object.assign(form, JSON.parse(JSON.stringify(val)));
|
|
|
- // Handle specific data transformations if needed
|
|
|
+ form.id = val.id;
|
|
|
+ form.activityName = val.activityName;
|
|
|
+ form.scope = String(val.scope || '1');
|
|
|
+ form.type = String(val.type || '1');
|
|
|
+ form.thresholdMoney = val.thresholdMoney;
|
|
|
+ form.discountMoney = val.discountMoney;
|
|
|
+ form.stepList = val.stepList && val.stepList.length ? JSON.parse(JSON.stringify(val.stepList)) : [{ thresholdMoney: undefined, discountMoney: undefined }];
|
|
|
+
|
|
|
if (val.startTime && val.endTime) {
|
|
|
form.dateRange = [val.startTime, val.endTime];
|
|
|
+ } else {
|
|
|
+ form.dateRange = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ // Handle bookIsbnList if available (assuming API might return it or we handle it)
|
|
|
+ // Since we are using textarea for input, we join array to string
|
|
|
+ // Note: The list API doesn't show bookIsbnList. If edit needs it, it might be missing.
|
|
|
+ // We will assume if it's there, we use it.
|
|
|
+ if (val.bookIsbnList && Array.isArray(val.bookIsbnList)) {
|
|
|
+ form.isbnText = val.bookIsbnList.join('\n');
|
|
|
+ } else {
|
|
|
+ form.isbnText = '';
|
|
|
}
|
|
|
} else {
|
|
|
- // Reset form
|
|
|
- form.name = '';
|
|
|
- form.productType = 'all';
|
|
|
- form.products = [];
|
|
|
+ form.id = undefined;
|
|
|
+ form.activityName = '';
|
|
|
+ form.scope = '1';
|
|
|
+ form.isbnText = '';
|
|
|
form.dateRange = [];
|
|
|
- form.discountType = 'tiered';
|
|
|
- form.tiers = [{ threshold: undefined, discount: undefined }];
|
|
|
- form.nocap = { threshold: undefined, discount: undefined };
|
|
|
+ form.type = '1';
|
|
|
+ form.stepList = [{ thresholdMoney: undefined, discountMoney: undefined }];
|
|
|
+ form.thresholdMoney = undefined;
|
|
|
+ form.discountMoney = undefined;
|
|
|
}
|
|
|
}, { immediate: true });
|
|
|
|
|
|
const addTier = () => {
|
|
|
- if (form.tiers.length >= 5) return;
|
|
|
- form.tiers.push({ threshold: undefined, discount: undefined });
|
|
|
+ if (form.stepList.length >= 5) return;
|
|
|
+ form.stepList.push({ thresholdMoney: undefined, discountMoney: undefined });
|
|
|
};
|
|
|
|
|
|
const removeTier = (index) => {
|
|
|
- form.tiers.splice(index, 1);
|
|
|
+ form.stepList.splice(index, 1);
|
|
|
};
|
|
|
|
|
|
const handleSubmit = async () => {
|
|
|
if (!formRef.value) return;
|
|
|
await formRef.value.validate(async (valid) => {
|
|
|
if (valid) {
|
|
|
- // Validation for tiers/nocap
|
|
|
- if (form.discountType === 'tiered') {
|
|
|
- for (const tier of form.tiers) {
|
|
|
- if (!tier.threshold || !tier.discount) {
|
|
|
+ // Validation
|
|
|
+ if (form.type === '1') {
|
|
|
+ for (const tier of form.stepList) {
|
|
|
+ if (!tier.thresholdMoney || !tier.discountMoney) {
|
|
|
EleMessage.error('请完善阶梯优惠信息');
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
- if (!form.nocap.threshold || !form.nocap.discount) {
|
|
|
+ if (!form.thresholdMoney || !form.discountMoney) {
|
|
|
EleMessage.error('请完善上不封顶优惠信息');
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Simulate API call
|
|
|
- setTimeout(() => {
|
|
|
- EleMessage.success(props.data ? '修改成功' : '添加成功');
|
|
|
- emit('success');
|
|
|
- visible.value = false;
|
|
|
- }, 500);
|
|
|
+ if (form.scope === '2' && !form.isbnText) {
|
|
|
+ EleMessage.error('请输入指定商品ISBN');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const payload = {
|
|
|
+ id: form.id,
|
|
|
+ activityName: form.activityName,
|
|
|
+ scope: form.scope,
|
|
|
+ type: form.type,
|
|
|
+ startTime: form.dateRange[0],
|
|
|
+ endTime: form.dateRange[1],
|
|
|
+ thresholdMoney: form.type === '2' ? form.thresholdMoney : undefined,
|
|
|
+ discountMoney: form.type === '2' ? form.discountMoney : undefined,
|
|
|
+ stepList: form.type === '1' ? form.stepList : undefined,
|
|
|
+ bookIsbnList: form.scope === '2' ? form.isbnText.split(/[\n,]/).map(s => s.trim()).filter(s => s) : undefined
|
|
|
+ };
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await request.post('/shop/shopDiscountInfo/setDiscount', payload);
|
|
|
+ if (res.data.code === 200) {
|
|
|
+ EleMessage.success(form.id ? '修改成功' : '添加成功');
|
|
|
+ emit('success');
|
|
|
+ visible.value = false;
|
|
|
+ } else {
|
|
|
+ EleMessage.error(res.data.msg || '操作失败');
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(error);
|
|
|
+ EleMessage.error('操作失败');
|
|
|
+ }
|
|
|
}
|
|
|
});
|
|
|
};
|