|
|
@@ -3,12 +3,20 @@
|
|
|
<div class="table-box" style="width: 100%; min-height: 100%; background-color: white">
|
|
|
<div class="header">
|
|
|
<el-button @click="goBack"> 返回 </el-button>
|
|
|
- <h2 class="title">{{ type == "add" ? "新建" : "编辑" }}运营活动</h2>
|
|
|
+ <h2 class="title">{{ type == "add" ? "新建" : "编辑" }}活动</h2>
|
|
|
</div>
|
|
|
<div class="form-wrapper">
|
|
|
<div class="form-wrapper-main">
|
|
|
<el-form ref="ruleFormRef" :model="activityModel" :rules="rules" class="formBox" label-width="140px">
|
|
|
<div class="form-content">
|
|
|
+ <!-- 活动类型 -->
|
|
|
+ <el-form-item label="活动类型" prop="activityType">
|
|
|
+ <el-select v-model="activityModel.activityType" class="form-input" clearable placeholder="请选择">
|
|
|
+ <el-option label="营销活动" :value="1" />
|
|
|
+ <el-option label="评论有礼" :value="2" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
<!-- 活动名称 -->
|
|
|
<el-form-item label="活动名称" prop="activityName">
|
|
|
<el-input v-model="activityModel.activityName" class="form-input" clearable maxlength="50" placeholder="请输入" />
|
|
|
@@ -29,35 +37,73 @@
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
|
|
|
- <!-- 用户可参与次数 -->
|
|
|
- <el-form-item label="用户可参与次数" prop="participationLimit">
|
|
|
- <el-input v-model="activityModel.participationLimit" placeholder="请输入" maxlength="4" />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- 活动规则 -->
|
|
|
- <el-form-item label="活动规则" prop="activityRule">
|
|
|
- <el-cascader
|
|
|
- v-model="activityModel.activityRule"
|
|
|
- :options="ruleCascaderOptions"
|
|
|
- :props="cascaderProps"
|
|
|
- class="form-input"
|
|
|
- clearable
|
|
|
- placeholder="请选择"
|
|
|
- style="width: 100%"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- 优惠券 -->
|
|
|
- <el-form-item label="优惠券" prop="couponId">
|
|
|
- <el-select v-model="activityModel.couponId" class="form-input" clearable filterable placeholder="请选择">
|
|
|
- <el-option v-for="item in couponList" :key="item.id" :label="item.name" :value="item.id" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
-
|
|
|
- <!-- 优惠券发放数量 -->
|
|
|
- <el-form-item label="优惠券发放数量" prop="couponQuantity">
|
|
|
- <el-input v-model="activityModel.couponQuantity" placeholder="请输入" maxlength="5" />
|
|
|
- </el-form-item>
|
|
|
+ <!-- 评论有礼相关字段 -->
|
|
|
+ <template v-if="activityModel.activityType === 1">
|
|
|
+ <!-- 用户可参与次数 -->
|
|
|
+ <el-form-item label="用户可参与次数" prop="participationLimit">
|
|
|
+ <el-input v-model="activityModel.participationLimit" placeholder="请输入" maxlength="4" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 活动规则 -->
|
|
|
+ <el-form-item label="活动规则" prop="activityRule">
|
|
|
+ <el-cascader
|
|
|
+ v-model="activityModel.activityRule"
|
|
|
+ :options="ruleCascaderOptions"
|
|
|
+ :props="cascaderProps"
|
|
|
+ class="form-input"
|
|
|
+ clearable
|
|
|
+ placeholder="请选择"
|
|
|
+ style="width: 100%"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 优惠券 -->
|
|
|
+ <el-form-item label="优惠券" prop="couponId">
|
|
|
+ <el-select v-model="activityModel.couponId" class="form-input" clearable filterable placeholder="请选择">
|
|
|
+ <el-option v-for="item in couponList" :key="item.id" :label="item.name" :value="item.id" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 优惠券发放数量 -->
|
|
|
+ <el-form-item label="优惠券发放数量" prop="couponQuantity">
|
|
|
+ <el-input v-model="activityModel.couponQuantity" placeholder="请输入" maxlength="5" />
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 营销活动相关字段 -->
|
|
|
+ <template v-if="activityModel.activityType === 2">
|
|
|
+ <!-- 报名时间 -->
|
|
|
+ <el-form-item class="activity-time-item" label="报名时间" prop="signupTimeRange">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="activityModel.signupTimeRange"
|
|
|
+ :disabled-date="disabledDate"
|
|
|
+ class="form-input"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ format="YYYY/MM/DD"
|
|
|
+ range-separator="-"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ type="daterange"
|
|
|
+ value-format="YYYY-MM-DD"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 活动限制人数 -->
|
|
|
+ <el-form-item label="活动限制人数" prop="activityLimitPeople">
|
|
|
+ <el-input v-model="activityModel.activityLimitPeople" placeholder="请输入" maxlength="6" />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <!-- 活动详情 -->
|
|
|
+ <el-form-item label="活动详情" prop="activityDetails">
|
|
|
+ <el-input
|
|
|
+ v-model="activityModel.activityDetails"
|
|
|
+ type="textarea"
|
|
|
+ :rows="6"
|
|
|
+ placeholder="请输入活动详情"
|
|
|
+ maxlength="1000"
|
|
|
+ show-word-limit
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
|
|
|
<!-- 上传图片方式 -->
|
|
|
<el-form-item label="活动图片类型" prop="uploadImgType">
|
|
|
@@ -234,6 +280,7 @@ const hasUnuploadedImages = computed(() => {
|
|
|
|
|
|
// ==================== 表单验证规则 ====================
|
|
|
const rules = reactive({
|
|
|
+ activityType: [{ required: true, message: "请选择活动类型", trigger: "change" }],
|
|
|
activityName: [{ required: true, message: "请输入活动名称", trigger: "blur" }],
|
|
|
activityTimeRange: [
|
|
|
{ required: true, message: "请选择活动时间", trigger: "change" },
|
|
|
@@ -269,14 +316,20 @@ const rules = reactive({
|
|
|
{ required: true, message: "请输入用户可参与次数", trigger: "blur" },
|
|
|
{
|
|
|
validator: (rule: any, value: any, callback: any) => {
|
|
|
- const numValue = Number(value);
|
|
|
- if (isNaN(numValue) || !Number.isInteger(numValue) || numValue <= 0) {
|
|
|
- callback(new Error("用户可参与次数必须为正整数"));
|
|
|
- return;
|
|
|
- }
|
|
|
- if (numValue > 9999) {
|
|
|
- callback(new Error("用户可参与次数必须小于9999"));
|
|
|
- return;
|
|
|
+ if (activityModel.value.activityType === 1) {
|
|
|
+ if (!value) {
|
|
|
+ callback(new Error("请输入用户可参与次数"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const numValue = Number(value);
|
|
|
+ if (isNaN(numValue) || !Number.isInteger(numValue) || numValue <= 0) {
|
|
|
+ callback(new Error("用户可参与次数必须为正整数"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (numValue > 9999) {
|
|
|
+ callback(new Error("用户可参与次数必须小于9999"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
callback();
|
|
|
},
|
|
|
@@ -287,34 +340,121 @@ const rules = reactive({
|
|
|
{ required: true, message: "请选择活动规则", trigger: "change" },
|
|
|
{
|
|
|
validator: (rule: any, value: any, callback: any) => {
|
|
|
- if (!value || !Array.isArray(value) || value.length < 2) {
|
|
|
- callback(new Error("请选择完整的活动规则(至少选择角色和行为)"));
|
|
|
- return;
|
|
|
+ if (activityModel.value.activityType === 1) {
|
|
|
+ if (!value || !Array.isArray(value) || value.length < 2) {
|
|
|
+ callback(new Error("请选择完整的活动规则(至少选择角色和行为)"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ },
|
|
|
+ trigger: "change"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ couponId: [
|
|
|
+ { required: true, message: "请选择优惠券", trigger: "change" },
|
|
|
+ {
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (activityModel.value.activityType === 1) {
|
|
|
+ if (!value) {
|
|
|
+ callback(new Error("请选择优惠券"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
callback();
|
|
|
},
|
|
|
trigger: "change"
|
|
|
}
|
|
|
],
|
|
|
- couponId: [{ required: true, message: "请选择优惠券", trigger: "change" }],
|
|
|
couponQuantity: [
|
|
|
{ required: true, message: "请输入优惠券发放数量", trigger: "blur" },
|
|
|
{
|
|
|
validator: (rule: any, value: any, callback: any) => {
|
|
|
- const numValue = Number(value);
|
|
|
- if (isNaN(numValue) || !Number.isInteger(numValue) || numValue <= 0) {
|
|
|
- callback(new Error("优惠券发放数量必须为正整数"));
|
|
|
- return;
|
|
|
+ if (activityModel.value.activityType === 1) {
|
|
|
+ if (!value) {
|
|
|
+ callback(new Error("请输入优惠券发放数量"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const numValue = Number(value);
|
|
|
+ if (isNaN(numValue) || !Number.isInteger(numValue) || numValue <= 0) {
|
|
|
+ callback(new Error("优惠券发放数量必须为正整数"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (numValue > 99999) {
|
|
|
+ callback(new Error("优惠券发放数量必须小于99999"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
- if (numValue > 99999) {
|
|
|
- callback(new Error("优惠券发放数量必须小于99999"));
|
|
|
- return;
|
|
|
+ callback();
|
|
|
+ },
|
|
|
+ trigger: "blur"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ signupTimeRange: [
|
|
|
+ { required: true, message: "请选择报名时间", trigger: "change" },
|
|
|
+ {
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (activityModel.value.activityType === 2) {
|
|
|
+ if (!value || !Array.isArray(value) || value.length !== 2) {
|
|
|
+ callback(new Error("请选择报名时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const [startTime, endTime] = value;
|
|
|
+ if (!startTime || !endTime) {
|
|
|
+ callback(new Error("请选择完整的报名时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const start = new Date(startTime);
|
|
|
+ const end = new Date(endTime);
|
|
|
+ if (start >= end) {
|
|
|
+ callback(new Error("报名开始时间必须早于报名结束时间"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ },
|
|
|
+ trigger: "change"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ activityLimitPeople: [
|
|
|
+ { required: true, message: "请输入活动限制人数", trigger: "blur" },
|
|
|
+ {
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (activityModel.value.activityType === 2) {
|
|
|
+ if (!value) {
|
|
|
+ callback(new Error("请输入活动限制人数"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const numValue = Number(value);
|
|
|
+ if (isNaN(numValue) || !Number.isInteger(numValue) || numValue <= 0) {
|
|
|
+ callback(new Error("活动限制人数必须为正整数"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (numValue > 999999) {
|
|
|
+ callback(new Error("活动限制人数必须小于999999"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
}
|
|
|
callback();
|
|
|
},
|
|
|
trigger: "blur"
|
|
|
}
|
|
|
],
|
|
|
+ activityDetails: [
|
|
|
+ { required: true, message: "请输入活动详情", trigger: ["blur", "change"] },
|
|
|
+ {
|
|
|
+ validator: (rule: any, value: any, callback: any) => {
|
|
|
+ if (activityModel.value.activityType === 2) {
|
|
|
+ if (!value || value.trim() === "") {
|
|
|
+ callback(new Error("请输入活动详情"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ callback();
|
|
|
+ },
|
|
|
+ trigger: ["blur", "change"]
|
|
|
+ }
|
|
|
+ ],
|
|
|
uploadImgType: [{ required: true, message: "请选择上传图片方式", trigger: "change" }],
|
|
|
imgDescribe: [
|
|
|
{
|
|
|
@@ -365,6 +505,8 @@ const rules = reactive({
|
|
|
|
|
|
// ==================== 活动信息数据模型 ====================
|
|
|
const activityModel = ref<any>({
|
|
|
+ // 活动类型:1-评论有礼,2-营销活动
|
|
|
+ activityType: 2,
|
|
|
// 活动宣传图(包含标题和详情)
|
|
|
promotionImages: null,
|
|
|
// 活动标题图片
|
|
|
@@ -379,14 +521,20 @@ const activityModel = ref<any>({
|
|
|
activityName: "",
|
|
|
// 活动时间范围
|
|
|
activityTimeRange: [],
|
|
|
- // 用户可参与次数
|
|
|
+ // 用户可参与次数(评论有礼)
|
|
|
participationLimit: "",
|
|
|
- // 活动规则(级联选择器的值数组)
|
|
|
+ // 活动规则(级联选择器的值数组)(评论有礼)
|
|
|
activityRule: [],
|
|
|
- // 优惠券ID
|
|
|
+ // 优惠券ID(评论有礼)
|
|
|
couponId: "",
|
|
|
- // 优惠券发放数量
|
|
|
+ // 优惠券发放数量(评论有礼)
|
|
|
couponQuantity: "",
|
|
|
+ // 报名时间范围(营销活动)
|
|
|
+ signupTimeRange: [],
|
|
|
+ // 活动限制人数(营销活动)
|
|
|
+ activityLimitPeople: "",
|
|
|
+ // 活动详情(营销活动)
|
|
|
+ activityDetails: "",
|
|
|
// 上传图片方式:1-正常用户,2-使用描述
|
|
|
uploadImgType: 1,
|
|
|
// 图片描述(当uploadImgType为2时使用)
|
|
|
@@ -778,6 +926,39 @@ const handlePictureCardPreview = (file: any) => {
|
|
|
// ==================== 监听器 ====================
|
|
|
|
|
|
/**
|
|
|
+ * 监听活动类型变化,切换时清除相关数据并重新验证
|
|
|
+ */
|
|
|
+watch(
|
|
|
+ () => activityModel.value.activityType,
|
|
|
+ (newVal, oldVal) => {
|
|
|
+ // 如果 oldVal 为空或 undefined,说明是初始化,不处理
|
|
|
+ if (oldVal === undefined || oldVal === null || oldVal === "") return;
|
|
|
+ // 如果新旧值相同,不处理
|
|
|
+ if (newVal === oldVal) return;
|
|
|
+
|
|
|
+ nextTick(() => {
|
|
|
+ if (newVal === 1) {
|
|
|
+ // 切换到评论有礼:清除营销活动相关字段
|
|
|
+ activityModel.value.signupTimeRange = [];
|
|
|
+ activityModel.value.activityLimitPeople = "";
|
|
|
+ activityModel.value.activityDetails = "";
|
|
|
+ // 清除营销活动字段的验证状态
|
|
|
+ ruleFormRef.value?.clearValidate(["signupTimeRange", "activityLimitPeople", "activityDetails"]);
|
|
|
+ } else if (newVal === 2) {
|
|
|
+ // 切换到营销活动:清除评论有礼相关字段
|
|
|
+ activityModel.value.participationLimit = "";
|
|
|
+ activityModel.value.activityRule = [];
|
|
|
+ activityModel.value.couponId = "";
|
|
|
+ activityModel.value.couponQuantity = "";
|
|
|
+ // 清除评论有礼字段的验证状态
|
|
|
+ ruleFormRef.value?.clearValidate(["participationLimit", "activityRule", "couponId", "couponQuantity"]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ { immediate: false }
|
|
|
+);
|
|
|
+
|
|
|
+/**
|
|
|
* 监听上传图片方式变化,切换时清除相关数据并重新验证
|
|
|
*/
|
|
|
watch(
|
|
|
@@ -861,12 +1042,28 @@ onMounted(async () => {
|
|
|
if (res.data.startTime && res.data.endTime) {
|
|
|
activityModel.value.activityTimeRange = [res.data.startTime, res.data.endTime];
|
|
|
}
|
|
|
- // 加载活动规则
|
|
|
+ // 加载活动规则(评论有礼)
|
|
|
if (res.data.activityRule) {
|
|
|
activityModel.value.activityRule = res.data.activityRule.split(",");
|
|
|
} else {
|
|
|
activityModel.value.activityRule = [];
|
|
|
}
|
|
|
+ // 加载报名开始时间(营销活动)
|
|
|
+ if (res.data.signupStartTime) {
|
|
|
+ activityModel.value.signupStartTime = res.data.signupStartTime;
|
|
|
+ }
|
|
|
+ // 加载报名结束时间(营销活动)
|
|
|
+ if (res.data.signupEndTime) {
|
|
|
+ activityModel.value.signupEndTime = res.data.signupEndTime;
|
|
|
+ }
|
|
|
+ // 加载活动限制人数(营销活动)
|
|
|
+ if (res.data.activityLimitPeople !== undefined) {
|
|
|
+ activityModel.value.activityLimitPeople = res.data.activityLimitPeople;
|
|
|
+ }
|
|
|
+ // 加载活动详情(营销活动)
|
|
|
+ if (res.data.activityDetails) {
|
|
|
+ activityModel.value.activityDetails = res.data.activityDetails;
|
|
|
+ }
|
|
|
// 加载上传图片方式
|
|
|
if (res.data.uploadImgType !== undefined) {
|
|
|
activityModel.value.uploadImgType = res.data.uploadImgType;
|
|
|
@@ -943,13 +1140,10 @@ const handleSubmit = async () => {
|
|
|
image_urls: [titleImageUrl.value, detailImageUrl.value]
|
|
|
};
|
|
|
const params: any = {
|
|
|
+ activityType: activityModel.value.activityType,
|
|
|
activityName: activityModel.value.activityName,
|
|
|
startTime: startTime,
|
|
|
endTime: endTime,
|
|
|
- participationLimit: activityModel.value.participationLimit,
|
|
|
- activityRule: activityModel.value.activityRule.join(","),
|
|
|
- couponId: activityModel.value.couponId,
|
|
|
- couponQuantity: activityModel.value.couponQuantity,
|
|
|
uploadImgType: activityModel.value.uploadImgType,
|
|
|
storeId: localGet("createdId"),
|
|
|
groupType: localGet("businessSection"),
|
|
|
@@ -957,6 +1151,32 @@ const handleSubmit = async () => {
|
|
|
auditParam: JSON.stringify(auditParam)
|
|
|
};
|
|
|
|
|
|
+ // 根据活动类型添加不同的字段,确保只提交对应类型的字段
|
|
|
+ if (activityModel.value.activityType === 1) {
|
|
|
+ // 评论有礼:只添加评论有礼相关字段
|
|
|
+ params.participationLimit = activityModel.value.participationLimit;
|
|
|
+ params.activityRule = activityModel.value.activityRule.join(",");
|
|
|
+ params.couponId = activityModel.value.couponId;
|
|
|
+ params.couponQuantity = activityModel.value.couponQuantity;
|
|
|
+ // 确保不包含营销活动的字段
|
|
|
+ delete params.signupStartTime;
|
|
|
+ delete params.signupEndTime;
|
|
|
+ delete params.activityLimitPeople;
|
|
|
+ delete params.activityDetails;
|
|
|
+ } else if (activityModel.value.activityType === 2) {
|
|
|
+ // 营销活动:只添加营销活动相关字段
|
|
|
+ const [signupStartTime, signupEndTime] = activityModel.value.signupTimeRange || [];
|
|
|
+ params.signupStartTime = signupStartTime;
|
|
|
+ params.signupEndTime = signupEndTime;
|
|
|
+ params.activityLimitPeople = activityModel.value.activityLimitPeople;
|
|
|
+ params.activityDetails = activityModel.value.activityDetails;
|
|
|
+ // 确保不包含评论有礼的字段
|
|
|
+ delete params.participationLimit;
|
|
|
+ delete params.activityRule;
|
|
|
+ delete params.couponId;
|
|
|
+ delete params.couponQuantity;
|
|
|
+ }
|
|
|
+
|
|
|
// 根据上传图片方式设置不同的参数
|
|
|
if (activityModel.value.uploadImgType === 1) {
|
|
|
// 正常用户:上传图片
|