|
|
@@ -81,8 +81,8 @@
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 4. 活动详情图 -->
|
|
|
- <div class="form-item-card">
|
|
|
+ <!-- 4. 活动详情图(仅营销活动需要) -->
|
|
|
+ <div v-if="activityModel.activityType === 'MARKETING'" class="form-item-card">
|
|
|
<div class="form-item card-item">
|
|
|
<div class="form-label form-label-col">活动详情图 <span class="required">*</span></div>
|
|
|
<div class="detail-upload-wrapper upload-slot-dashed">
|
|
|
@@ -401,10 +401,11 @@ const imageViewerInitialIndex = ref(0);
|
|
|
|
|
|
// 是否有未上传的图片
|
|
|
const hasUnuploadedImages = computed(() => {
|
|
|
- return (
|
|
|
- titleFileList.value.some(file => file.status === "ready" || file.status === "uploading") ||
|
|
|
- detailFileList.value.some(file => file.status === "ready" || file.status === "uploading")
|
|
|
- );
|
|
|
+ const titlePending = titleFileList.value.some(file => file.status === "ready" || file.status === "uploading");
|
|
|
+ const detailPending =
|
|
|
+ activityModel.value.activityType === "MARKETING" &&
|
|
|
+ detailFileList.value.some(file => file.status === "ready" || file.status === "uploading");
|
|
|
+ return titlePending || detailPending;
|
|
|
});
|
|
|
|
|
|
// ==================== 表单验证规则 ====================
|
|
|
@@ -646,6 +647,10 @@ const rules = reactive({
|
|
|
{
|
|
|
required: true,
|
|
|
validator: (_rule: any, _value: any, callback: any) => {
|
|
|
+ if (activityModel.value.activityType !== "MARKETING") {
|
|
|
+ callback();
|
|
|
+ return;
|
|
|
+ }
|
|
|
const successFiles = detailFileList.value.filter((f: any) => f.status === "success" && f.url);
|
|
|
if (successFiles.length === 0) {
|
|
|
callback(new Error("请上传活动详情图"));
|
|
|
@@ -1204,9 +1209,10 @@ const handlegetTime = (val: string) => {
|
|
|
return val || "";
|
|
|
};
|
|
|
|
|
|
-/** 将 AI 接口返回写入 banner / 详情图 */
|
|
|
+/** 将 AI 接口返回写入 banner / 详情图(评价有礼仅写入 banner) */
|
|
|
const applyPromotionImagesFromResponse = (data: any) => {
|
|
|
if (!data || typeof data !== "object") return;
|
|
|
+ const isMarketing = activityModel.value.activityType === "MARKETING";
|
|
|
|
|
|
const titleObj = data.activityTitleImg;
|
|
|
if (titleObj && titleObj.imgUrl) {
|
|
|
@@ -1231,6 +1237,13 @@ const applyPromotionImagesFromResponse = (data: any) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (!isMarketing) {
|
|
|
+ nextTick(() => {
|
|
|
+ ruleFormRef.value?.validateField(["activityTitleImage"]);
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
const detailObj = data.activityDetailImg;
|
|
|
if (detailObj) {
|
|
|
let urls: string[] = [];
|
|
|
@@ -1282,7 +1295,11 @@ const handleAiGenerate = async () => {
|
|
|
if (res && res.code == 200) {
|
|
|
applyPromotionImagesFromResponse(res.data);
|
|
|
nextTick(() => {
|
|
|
- ruleFormRef.value?.validateField(["activityTitleImage", "activityDetailImage"]);
|
|
|
+ const fields: string[] =
|
|
|
+ activityModel.value.activityType === "MARKETING"
|
|
|
+ ? ["activityTitleImage", "activityDetailImage"]
|
|
|
+ : ["activityTitleImage"];
|
|
|
+ ruleFormRef.value?.validateField(fields);
|
|
|
});
|
|
|
ElMessage.success(res.msg || "图片生成成功");
|
|
|
} else {
|
|
|
@@ -1340,13 +1357,22 @@ watch(
|
|
|
"voucherQuantity"
|
|
|
]);
|
|
|
} else if (typeValue === "COMMENT") {
|
|
|
- // 切换到评论有礼:清除营销活动相关字段
|
|
|
+ // 切换到评论有礼:清除营销活动相关字段(含活动详情图,评价有礼不需要)
|
|
|
activityModel.value.signupTimeRange = [];
|
|
|
activityModel.value.activityLimitPeople = "";
|
|
|
activityModel.value.activityDetails = "";
|
|
|
+ const detailUids = new Set(detailFileList.value.map((f: any) => f.uid));
|
|
|
+ detailFileList.value.forEach((f: any) => {
|
|
|
+ if (f?.url && String(f.url).startsWith("blob:")) URL.revokeObjectURL(f.url);
|
|
|
+ });
|
|
|
+ detailFileList.value = [];
|
|
|
+ detailImageUrl.value = "";
|
|
|
+ activityModel.value.activityDetailImg = null;
|
|
|
+ activityModel.value.activityDetailImage = "";
|
|
|
+ pendingUploadFiles.value = pendingUploadFiles.value.filter((f: any) => !detailUids.has(f.uid));
|
|
|
activityModel.value.discountCouponType = activityModel.value.rewardType === "VOUCHER" ? 1 : 2;
|
|
|
// 清除营销活动字段的验证状态
|
|
|
- ruleFormRef.value?.clearValidate(["signupTimeRange", "activityLimitPeople", "activityDetails"]);
|
|
|
+ ruleFormRef.value?.clearValidate(["signupTimeRange", "activityLimitPeople", "activityDetails", "activityDetailImage"]);
|
|
|
// 加载优惠券列表
|
|
|
loadCouponList();
|
|
|
}
|
|
|
@@ -1579,10 +1605,9 @@ onMounted(async () => {
|
|
|
titleFileList.value = [titleFile];
|
|
|
}
|
|
|
}
|
|
|
- // 如果有详情图片,添加到文件列表(支持多张图片,可能是字符串或数组)
|
|
|
- if (res.data.activityDetailImgUrl) {
|
|
|
+ // 营销活动:加载详情图(评价有礼不需要)
|
|
|
+ if (activityModel.value.activityType === "MARKETING" && res.data.activityDetailImgUrl) {
|
|
|
let detailImgUrls: string[] = [];
|
|
|
- // 如果是字符串,可能是逗号分隔的多张图片
|
|
|
if (typeof res.data.activityDetailImgUrl === "string") {
|
|
|
detailImgUrls = res.data.activityDetailImgUrl.split(",").filter((url: string) => url.trim());
|
|
|
} else if (Array.isArray(res.data.activityDetailImgUrl)) {
|
|
|
@@ -1593,9 +1618,13 @@ onMounted(async () => {
|
|
|
detailImageUrl.value = detailImgUrls.join(",");
|
|
|
activityModel.value.activityDetailImg = res.data.activityDetailImgUrl;
|
|
|
activityModel.value.activityDetailImage = detailImgUrls.join(",");
|
|
|
- // 将多张图片添加到文件列表
|
|
|
detailFileList.value = detailImgUrls.map((url: string) => handleImageParam(url));
|
|
|
}
|
|
|
+ } else if (activityModel.value.activityType === "COMMENT") {
|
|
|
+ detailFileList.value = [];
|
|
|
+ detailImageUrl.value = "";
|
|
|
+ activityModel.value.activityDetailImg = null;
|
|
|
+ activityModel.value.activityDetailImage = "";
|
|
|
}
|
|
|
}
|
|
|
} catch (error) {
|
|
|
@@ -1650,11 +1679,18 @@ const handleSubmit = async () => {
|
|
|
// 活动时间:开始日期传当天 00:00:00,结束日期传当天 23:59:59
|
|
|
const startTime = activityStartDate ? `${activityStartDate} 00:00:00` : "";
|
|
|
const endTime = activityEndDate ? `${activityEndDate} 23:59:59` : "";
|
|
|
+ const detailUrls =
|
|
|
+ activityModel.value.activityType === "MARKETING" && detailImageUrl.value
|
|
|
+ ? detailImageUrl.value
|
|
|
+ .split(",")
|
|
|
+ .map((s: string) => s.trim())
|
|
|
+ .filter(Boolean)
|
|
|
+ : [];
|
|
|
const auditParam = {
|
|
|
text: activityModel.value.imgDescribe?.trim()
|
|
|
? `${activityModel.value.activityName},${activityModel.value.imgDescribe.trim()}`
|
|
|
: activityModel.value.activityName,
|
|
|
- image_urls: [titleImageUrl.value, ...(detailImageUrl.value ? detailImageUrl.value.split(",") : [])].filter(Boolean)
|
|
|
+ image_urls: [titleImageUrl.value, ...detailUrls].filter(Boolean)
|
|
|
};
|
|
|
const params: any = {
|
|
|
activityType: activityModel.value.activityType,
|
|
|
@@ -1696,7 +1732,7 @@ const handleSubmit = async () => {
|
|
|
storeId: localGet("createdId")
|
|
|
};
|
|
|
params.activityDetailImg = {
|
|
|
- imgUrl: detailImageUrl.value,
|
|
|
+ imgUrl: activityModel.value.activityType === "MARKETING" ? detailImageUrl.value : "",
|
|
|
imgSort: 0,
|
|
|
storeId: localGet("createdId")
|
|
|
};
|