Pārlūkot izejas kodu

✨ feat<自动化规则>:效率工具-自动化规则;广告管理-自动化规则;
-定向规则广告类型筛选不能修改,且和模板中的类型保持一致,且不能被修改
-分时调价以及其他模板(除定向规则)进来时默认无筛选项
- 广告启/停,基于当前之前的时间不可选择
- 所有涉及频率设置的默认全部选中。
- 定向规则设置竞价不是输入框,只能输入数字和浮点数,右边需要货币符号参考xmars
- 模板删除时需要强提示
- 把模板广告活动改为:开启/暂停 广告活动
- 分时调价模板:默认值为1
- 开启/暂停 广告活动-表单修改
- 改为开启/暂停 广告活动-tab调整
- 定向规则模块-升高竞价-规则1-最大值禁用修改
- 提交逻辑修改

xinyan 7 mēneši atpakaļ
vecāks
revīzija
6f79a2c358

+ 2 - 2
.env.development

@@ -4,8 +4,8 @@ ENV='development'
 
 # 本地环境接口地址
 # VITE_API_URL = 'http://127.0.0.1:8000'
-# VITE_API_URL='http://192.168.1.225/'
-VITE_API_URL='http://192.168.1.25:8080/'
+VITE_API_URL='http://192.168.1.225/'
+# VITE_API_URL='http://192.168.1.25:8080/'
 # VITE_API_URL = 'http://amzads.zositechc.cn'
 
 # 是否启用按钮权限

+ 1 - 2
src/components/TimerBidTable/index.vue

@@ -179,7 +179,6 @@ function resetAllBid() {
 }
 
 function closeDialog(done: Function) {
-  // console.log("closeDialog")
   cancelBid();
   done();
 }
@@ -267,7 +266,7 @@ watch(
               @mouseover="handleMouseMove(week, hour)"
               @mouseup="handleMouseUp">
             <span class="cell-text"> {{
-                info.value || info.value == 0 ? Number(info.value).toFixed(2) : '0.00'
+                info.value ? Number(info.value).toFixed(2) : ''
               }} </span>
           </td>
         </tr>

+ 2 - 2
src/components/conditionBuilder/condition-group2.vue

@@ -7,8 +7,8 @@
             <el-option v-for="item in periodEnum" :key="item.value" :label="item.label" :value="item.value"></el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="排除" required prop="exceptDay">
-          <el-select v-model="formData.exceptDay">
+        <el-form-item label="排除" prop="exceptDay">
+          <el-select v-model="formData.exceptDay" :disabled="formData.day <= 1">
             <el-option v-for="item in excludeEnum" :key="item.value" :label="item.label" :value="item.value" :disabled="formData.day <= item.value">
             </el-option>
           </el-select>

+ 8 - 21
src/views/adManage/sp/campaigns/campaignDetail/automation/index.vue

@@ -12,8 +12,9 @@ import SwitchCampaign from '/@/views/components/auto/auto-campaigns/switch-campa
 import TargetRule from '/@/views/components/auto/auto-campaigns/target-rule.vue';
 import SearchTermRule from '/@/views/components/auto/auto-campaigns/search-term.vue';
 import NegKeywordRule from '/@/views/components/auto/auto-campaigns/neg-keyword.vue';
-import { postCampaignStatus } from './api';
+import { getCampaignRuleInfo, postCampaignStatus } from './api';
 import { ElMessage } from 'element-plus';
+import { userFormData } from '/@/views/components/auto/auto-campaigns/common';
 
 
 interface Props {
@@ -40,21 +41,6 @@ const baseData = ref({
   ruleType: activeTab,
 });
 
-async function initData() {
-  // const resp = await api.getCampaignRuleInfo(baseData.value);
-  // const info = resp.data[0];
-  // if (info) {
-  //   for (const i of ['1', '2', '3', '4', '5', '6']) {
-  //     RuleStatusButton.value[i] = info.RuleStatusButton[i];
-  //   }
-  //   console.log('Initialized RuleStatusButton', RuleStatusButton.value); // 添加调试信息
-  // }
-}
-
-async function changeTab() {
-  // await initData();
-}
-
 async function changeStatus(newStatus: number, tabIndex: string) {
   const body = {
     ...baseData.value,
@@ -65,8 +51,9 @@ async function changeStatus(newStatus: number, tabIndex: string) {
     const response = await postCampaignStatus(body);
     if (response.code === 2000) {
       ElMessage.success('更新状态成功');
-      const resp = await getCampaignRuleInfo(baseData.value);
-      RuleStatusButton.value = resp.data[0].RuleStatusButton;
+      // const resp = await getCampaignRuleInfo(baseData.value);
+      // RuleStatusButton.value = resp.data[0].RuleStatusButton;
+      console.log("=>(index.vue:57) RuleStatusButton.value", RuleStatusButton.value);
     } else if (response.code == 5000) {
       ElMessage.warning(`${ response.data.description }`);
     } else {
@@ -120,13 +107,13 @@ onMounted(async () => {
       </template>
       <TimerBudget v-if="activeTab === 2" :RuleStatusButton="RuleStatusButton" :data="baseData" @refresh="refresh(2)" />
     </el-tab-pane>
-    <el-tab-pane :name="3" label="广告活动">
+    <el-tab-pane :name="3" label="开启/暂停广告活动">
       <template #label>
         <div class="tab-label">
           <el-switch v-model="RuleStatusButton['3']" :active-value="1" :disabled="RuleStatusButton['3'] === '-'"
                      :inactive-value="0" size="small" @change="(val) => changeStatus(val, '3')" @click.stop="">
           </el-switch>
-          <span>广告活动</span>
+          <span>开启/暂停广告活动</span>
         </div>
       </template>
       <SwitchCampaign v-if="activeTab === 3" :RuleStatusButton="RuleStatusButton" :data="baseData"
@@ -178,6 +165,6 @@ onMounted(async () => {
   display: flex;
   justify-content: space-between;
   align-items: center;
-  width: 120px;
+  width: 155px;
 }
 </style>

+ 1 - 1
src/views/components/auto/auto-campaigns/common.ts

@@ -66,7 +66,7 @@ export const userFormData = (props: Props) => {
       delete body.rule.id
     }
     console.log('body', body);
-    await api.saveCampaignRule(body)
+    // await api.saveCampaignRule(body)
   }
 
   watch(

+ 23 - 22
src/views/components/auto/auto-campaigns/neg-keyword.vue

@@ -12,6 +12,8 @@ import conditionBuilder from '/@/components/conditionBuilder/index.vue';
 import XEUtils from 'xe-utils';
 import { userFormData } from './common';
 import SaveRuleDialog from '/@/views/components/auto/auto-campaigns/save-rule-dialog.vue';
+import { ElMessage } from 'element-plus';
+
 
 interface Props {
   data: {
@@ -33,27 +35,26 @@ const { formData, submitFormData } = userFormData(props);
 const submitDialogVisible = ref(false);
 
 const submitForm = async () => {
+  await submitFormData();
+  ElMessage.success('保存成功');
+  emits('refresh');
+};
+
+const cancel = () => {
+  emits('refresh');
+};
+
+async function handleSubmit() {
   const valid2 = await searchTermAddRef.value.validate();
   const valid3 = !XEUtils.includes(await condiBuilderRef.value.validate(), false);
   formRef.value.validate(async (valid: boolean) => {
-    if (valid && valid2 && valid3) {
-      await submitFormData();
-      emits('refresh');
+    if (!valid || !valid2 || !valid3) return;
+    if (formData.value.useTmpl) {
+      await submitForm();
     } else {
-      console.log('验证失败:', [valid, valid2, valid3]);
+      submitDialogVisible.value = true;
     }
   });
-};
-const cancel = () => {
-  emits('refresh');
-};
-
-function handleSubmit() {
-  if (formData.value.useTmpl) {
-    submitForm();
-  } else {
-    submitDialogVisible.value = true;
-  }
 }
 </script>
 
@@ -62,14 +63,14 @@ function handleSubmit() {
     <div class="asj-h2">添加否定词</div>
     <SelectTmpl :data="formData" />
     <el-card class="mt-3">
-      <FreqSetting :rule="formData.rule" :disabled="formData.useTmpl" />
+      <FreqSetting :disabled="formData.useTmpl" :rule="formData.rule" />
       <el-divider />
-      <el-form :model="formData" label-position="top" ref="formRef" :disabled="formData.useTmpl">
-        <SearchTermAdd :rule="formData.rule" ref="searchTermAddRef" :disabled="formData.useTmpl" />
+      <el-form ref="formRef" :disabled="formData.useTmpl" :model="formData" label-position="top">
+        <SearchTermAdd ref="searchTermAddRef" :disabled="formData.useTmpl" :rule="formData.rule" />
         <el-form-item
-          prop="rule.action.matchType"
-          required
-          :rules="{ required: true, message: '请至少选择一种匹配方式', trigger: 'change' }">
+            :rules="{ required: true, message: '请至少选择一种匹配方式', trigger: 'change' }"
+            prop="rule.action.matchType"
+            required>
           <template #label>
             <span class="asj-h3">匹配方式</span>
           </template>
@@ -82,7 +83,7 @@ function handleSubmit() {
     </el-card>
     <el-card class="mt-3">
 
-    <conditionBuilder :data="formData.rule.conditions" ref="condiBuilderRef" :disabled="formData.useTmpl" />
+      <conditionBuilder ref="condiBuilderRef" :data="formData.rule.conditions" :disabled="formData.useTmpl" />
     </el-card>
     <SaveRuleDialog
         v-model="submitDialogVisible"

+ 20 - 16
src/views/components/auto/auto-campaigns/search-term.vue

@@ -13,6 +13,7 @@ import conditionBuilder from '/@/components/conditionBuilder/index.vue';
 import { userFormData } from './common';
 import XEUtils from 'xe-utils';
 import SaveRuleDialog from '/@/views/components/auto/auto-campaigns/save-rule-dialog.vue';
+import { ElMessage } from 'element-plus';
 
 interface Props {
   data: {
@@ -34,29 +35,32 @@ const condiBuilderRef = ref();
 const { formData, submitFormData } = userFormData(props);
 const submitDialogVisible = ref(false);
 
-const submitForm = async () => {
+async function submitForm() {
+  await submitFormData();
+  ElMessage.success('保存成功');
+  emits('refresh');
+}
+
+const cancel = () => {
+  emits('refresh');
+};
+
+async function handleSubmit() {
   const valid2 = await searchTermAddRef.value.validate();
   const valid3 = searchTermBidRef.value.valid;
   const valid4 = !XEUtils.includes(await condiBuilderRef.value.validate(), false);
   formRef.value.validate(async (valid: boolean) => {
-    if (valid && valid2 && valid3 && valid4) {
-      await submitFormData();
-      emits('refresh');
+    if (!valid ||! valid2 ||! valid3 ||! valid4) return;
+    try {
+      if (formData.value.useTmpl) {
+      await submitForm();
     } else {
-      console.log('验证失败:', [valid, valid2, valid3, valid4]);
+      submitDialogVisible.value = true;
+    }
+    }catch (error) {
+      console.error('提交失败:', error);
     }
   });
-};
-const cancel = () => {
-  emits('refresh');
-};
-
-function handleSubmit() {
-  if (formData.value.useTmpl) {
-    submitForm();
-  } else {
-    submitDialogVisible.value = true;
-  }
 }
 </script>
 

+ 78 - 24
src/views/components/auto/auto-campaigns/switch-campaign.vue

@@ -11,6 +11,7 @@ import conditionBuilder from '/@/components/conditionBuilder/index.vue';
 import { userFormData } from './common';
 import FreqSetting from '../freq-setting.vue';
 import SaveRuleDialog from '/@/views/components/auto/auto-campaigns/save-rule-dialog.vue';
+import { ElMessage } from 'element-plus';
 
 interface Props {
   data: {
@@ -30,6 +31,7 @@ const { formData, submitFormData } = userFormData(props);
 formData.value.rule.action.state = [];
 formData.value.rule.action.setTime = '';
 const submitDialogVisible = ref(false);
+const showError = ref(false);
 
 const condidateFields = [
   { label: '曝光量', value: 'impressions' },
@@ -37,6 +39,31 @@ const condidateFields = [
   { label: '转化率', value: 'cr', suffix: '%' },
   { label: '单次点击费用', value: 'cpc', prefix: '$' },
 ];
+const defaultTime = new Date()
+
+function disabledDate(date) {
+  return date < new Date().setHours(0, 0, 0, 0);
+}
+
+// 限制小时
+const disabledHour = () => {
+  const arrs = []
+  for (let i = 0; i < 24; i++) {
+    if (new Date().getHours() <= i) continue;
+    arrs.push(i)
+  }
+  return arrs;
+}
+
+// 限制分
+const disabledMinute = () => {
+  const arrs = []
+  for (let i = 0; i < 60; i++) {
+    if (new Date().getMinutes() <= i) continue;
+    arrs.push(i)
+  }
+  return arrs;
+}
 
 function addConditions() {
   if (formData.value.rule.conditions.length === 0) {
@@ -46,36 +73,55 @@ function addConditions() {
 
 async function validateConditionsForm() {
   const validList = await condiBuilderRef.value.validate();
-  if (validList.includes(false)) {
-    return false;
-  }
-  return true;
+  return !validList.includes(false);
 }
 
 async function submitForm() {
-  const valid2 = await validateConditionsForm();
-  formRef.value.validate(async (valid: any) => {
-    if (valid && valid2) {
-      await submitFormData();
-      emits('refresh');
-    } else {
-      console.log('验证失败');
-    }
-  });
+  await submitFormData();
+  ElMessage.success('保存成功');
+  emits('refresh');
 }
 
 function cancel() {
   emits('refresh');
 }
 
-function handleSubmit() {
-  if (formData.value.useTmpl) {
-    submitForm();
-  } else {
-    submitDialogVisible.value = true;
-  }
+async function handleSubmit() {
+  const valid2 = await validateConditionsForm();
+  formRef.value.validate(async (valid: any) => {
+    if (!valid || !valid2) return;
+
+    if (formData.value.rule.action.state.length === 0) return;
+
+    const selectedTime = new Date(formData.value.rule.action.setTime);
+    if (selectedTime <= new Date()) {
+      ElMessage.error('保存失败,请重新选择时间');
+      return;
+    }
+
+    try {
+      if (formData.value.useTmpl) {
+        await submitForm();
+      } else {
+        submitDialogVisible.value = true;
+      }
+    } catch (error) {
+      console.error('提交失败:', error);
+    }
+  });
 }
 
+// watch(() => formData.value.useTmpl, (newValue) => {
+//   if (!newValue) {
+//     // clearForm();
+//   }
+// });
+//
+// function clearForm() {
+//   formData.value.rule.action.state = [];
+//   formData.value.rule.action.setTime = '';
+//   formData.value.rule.conditions = [];
+// }
 </script>
 
 <template>
@@ -98,16 +144,24 @@ function handleSubmit() {
                 prop="rule.action.setTime"
                 :rules="[{ required: formData.rule.action.state.includes('enabled'), message: '必填项', trigger: 'blur' }]">
                 <el-date-picker
-                  v-model="formData.rule.action.setTime"
-                  type="datetime"
-                  format="YYYY-MM-DD HH:mm"
-                  time-format="HH:mm"
-                  value-format="YYYY-MM-DD HH:mm" />
+                    v-model="formData.rule.action.setTime"
+                    type="datetime"
+                    format="YYYY-MM-DD HH:mm"
+                    time-format="HH:mm"
+                    value-format="YYYY-MM-DD HH:mm"
+                    :disabled-date="disabledDate"
+                    :disabled-hours="disabledHour"
+                    :disabled-minutes="disabledMinute"
+                    :default-time="defaultTime"
+                />
               </el-form-item>
             </div>
           </div>
           <el-checkbox label="paused" @click="addConditions">暂停</el-checkbox>
         </el-checkbox-group>
+        <el-form-item v-if="formData.rule.action.state.length === 0" style="color: red">
+          <span style="font-size: 12px;">请至少选择一种操作</span>
+        </el-form-item>
       </el-form>
       <div v-show="formData.rule.action.state.includes('paused')">
         <conditionBuilder

+ 24 - 22
src/views/components/auto/auto-campaigns/target-rule.vue

@@ -13,6 +13,7 @@ import { userFormData } from './common';
 import TargetRuleSetting from '../target-rule-setting.vue';
 import SaveRuleDialog from '/@/views/components/auto/auto-campaigns/save-rule-dialog.vue';
 
+
 interface Props {
   data: {
     campaignId: string;
@@ -31,27 +32,28 @@ const { formData, submitFormData } = userFormData(props);
 const submitDialogVisible = ref(false);
 
 const submitForm = async () => {
-  const valid2 = await ruleSettingRef.value.validateForm();
-  formRef.value.validate(async (valid: boolean) => {
-    if (valid && valid2) {
-      await submitFormData();
-      emits('refresh');
-    } else {
-      console.log('验证失败:', [valid, valid2]);
-    }
-  });
+  await submitFormData();
+  ELMessage.success('保存成功');
+  emits('refresh');
 };
 
 function cancel() {
   emits('refresh');
 }
 
-function handleSubmit() {
-  if (formData.value.useTmpl) {
-    submitForm();
-  } else {
-    submitDialogVisible.value = true;
-  }
+async function handleSubmit() {
+  const valid2 = await ruleSettingRef.value.validateForm();
+  formRef.value.validate(async (valid: boolean) => {
+    if (!valid || !valid2) {
+      return;
+    } else {
+      if (formData.value.useTmpl) {
+        await submitForm();
+      } else {
+        submitDialogVisible.value = true;
+      }
+    }
+  });
 }
 </script>
 
@@ -60,25 +62,25 @@ function handleSubmit() {
     <div class="asj-h2">定向规则</div>
     <SelectTmpl :data="formData" />
     <el-card class="mt-3">
-      <el-form class="custom-card" :model="formData" label-position="top" ref="formRef">
+      <el-form ref="formRef" :model="formData" class="custom-card" label-position="top">
         <el-form-item>
           <!--<template #label>
             <span class="custom-title-icon"></span>
             <span class="asj-h3">生效对象</span>
           </template>-->
-          <FreqSetting :rule="formData.rule" :disabled="formData.useTmpl" />
+          <FreqSetting :disabled="formData.useTmpl" :rule="formData.rule" />
           <el-divider />
           <TargetSelect
-            mode="auto"
-            :data="formData.rule"
-            :useTmpl="formData.useTmpl"
-            :campaign-id="data.campaignId"></TargetSelect>
+              :campaign-id="data.campaignId"
+              :data="formData.rule"
+              :useTmpl="formData.useTmpl"
+              mode="auto"></TargetSelect>
         </el-form-item>
       </el-form>
     </el-card>
 
     <el-card class="mt-3">
-      <TargetRuleSetting :rule="formData.rule" ref="ruleSettingRef" :disabled="formData.useTmpl" />
+      <TargetRuleSetting ref="ruleSettingRef" :disabled="formData.useTmpl" :rule="formData.rule" />
     </el-card>
     <SaveRuleDialog
         v-model="submitDialogVisible"

+ 16 - 15
src/views/components/auto/auto-campaigns/timer-bid.vue

@@ -10,6 +10,7 @@ import TimerBidTable from '/@/components/TimerBidTable/index.vue';
 import SelectTmpl from './select-tmpl.vue';
 import { userFormData } from './common';
 import SaveRuleDialog from '/@/views/components/auto/auto-campaigns/save-rule-dialog.vue';
+import { ElMessage } from 'element-plus'
 
 interface Props {
   data: {
@@ -82,27 +83,27 @@ const isVisible = ref(true);
 const submitDialogVisible = ref(false);
 
 async function submit() {
-  formRef.value.validate(async (valid: any) => {
-    if (valid) {
-      await submitFormData();
-      emits('refresh');
-      submitDialogVisible.value = true;
-    } else {
-      console.log('验证失败');
-    }
-  });
+  await submitFormData();
+  ElMessage.success('保存成功');
+  emits('refresh');
 }
 
 function cancel() {
   emits('refresh');
 }
 
-function handleSubmit() {
-  if (formData.value.useTmpl) {
-    submit();
-  } else {
-    submitDialogVisible.value = true;
-  }
+async function handleSubmit() {
+  formRef.value.validate(async (valid: boolean) => {
+    if (!valid) {
+      return;
+    } else {
+      if (formData.value.useTmpl) {
+        await submit();
+      } else {
+        submitDialogVisible.value = true;
+      }
+    }
+  });
 }
 
 function handleClose() {

+ 14 - 13
src/views/components/auto/auto-campaigns/timer-budget.vue

@@ -43,22 +43,23 @@ function checkConditions(rule: any, value: any, callback: any) {
 }
 
 async function submitForm() {
-  formRef.value.validate(async (valid: any) => {
-    if (valid) {
-      await submitFormData();
-      emits('refresh');
-    } else {
-      console.log('验证失败');
-    }
-  });
+  await submitFormData();
+  ElMessage.success('保存成功');
+  emits('refresh');
 }
 
 function handleSubmit() {
-  if (formData.value.useTmpl) {
-    submitForm();
-  } else {
-    submitDialogVisible.value = true;
-  }
+  formRef.value.validate(async (valid: boolean) => {
+    if (!valid) {
+      return;
+    } else {
+      if (formData.value.useTmpl) {
+        await submit();
+      } else {
+        submitDialogVisible.value = true;
+      }
+    }
+  });
 }
 
 function cancel() {

+ 4 - 0
src/views/components/auto/freq-setting.vue

@@ -14,6 +14,10 @@ interface Props {
 }
 
 const props = defineProps<Props>();
+
+// 初始化 rule.weekdays 为全选的状态
+props.rule.weekdays = [0, 1, 2, 3, 4, 5, 6];
+
 </script>
 
 <template>

+ 47 - 7
src/views/components/auto/target-rule-setting.vue

@@ -5,7 +5,7 @@
  * @Author: Cheney
  */
 
-import { ref, computed } from 'vue';
+import { ref, computed, onBeforeUnmount } from 'vue';
 import { Plus } from '@element-plus/icons-vue';
 import conditionBuilder from '/@/components/conditionBuilder/index.vue';
 import InputFloat from '/@/components/input-float/index.vue';
@@ -45,6 +45,8 @@ const candidateFields = [
 ];
 
 const { getSymbolOptions } = useSymbolOptions(candidateFields);
+const maxIsDisabled = ref([]);
+const minIsDisabled = ref([]);
 const ruleFormRef = ref();
 const condiBuilderRef = ref();
 const actionModel = ref('bid-ratio');
@@ -62,6 +64,11 @@ const maxRuleNumber = computed(() => {
   return ret;
 });
 
+onMounted(() => {
+  maxIsDisabled.value.push(!props.rule.action.max);
+  minIsDisabled.value.push(!props.rule.action.min);
+})
+
 function checkFloat(rule: any, value: any, callback: any) {
   if (XEUtils.toNumber(value) <= 0) {
     callback(new Error('请输入大于0的数值!'));
@@ -106,21 +113,34 @@ function addRule(actionType: string, index: number = -1) {
     ordering: maxRuleNumber.value[actionType] + 1,
     show: true,
   };
+
   if (index === -1) {
     props.rule.conditions.push(rule);
+    if (actionType === 'increase'){
+      maxIsDisabled.value.push(false);
+    }else if (actionType === 'decrease'){
+      minIsDisabled.value.push(false);
+    }
   } else {
     props.rule.conditions.splice(index + 1, 0, rule);
+    maxIsDisabled.value.splice(index + 1, 0, false); // 添加一个初始值
+    minIsDisabled.value.splice(index + 1, 0, false); // 添加一个初始值
   }
 }
 
 if (props.rule.conditions.length === 0) {
   props.rule.campaignType = 'sp';
   props.rule.activeModel = 'campaign';
-  addRule('increase', -1);
+  // addRule('increase', -1);
 }
 
 function delRule(index: number) {
   props.rule.conditions.splice(index, 1);
+  if (actionType === 'increase'){
+    maxIsDisabled.value.splice(index, 1);
+  }else if (actionType === 'decrease'){
+    minIsDisabled.value.splice(index, 1);
+  }
 }
 
 function changeAction(action: any) {
@@ -159,6 +179,20 @@ async function validateForm() {
   return valid1 && valid2;
 }
 
+function onMaxCheckboxChange(index: number) {
+  if (!maxIsDisabled.value[index]) {
+    // 如果复选框被取消勾选,禁用输入框并清空对应的值
+    props.rule.conditions[index].action.max = '';
+  }
+}
+
+function onMinCheckboxChange(index: number) {
+  if (!minIsDisabled.value[index]) {
+    // 如果复选框被取消勾选,禁用输入框并清空对应的值
+    props.rule.conditions[index].action.min = '';
+  }
+}
+
 defineExpose({ validateForm });
 </script>
 
@@ -212,15 +246,21 @@ defineExpose({ validateForm });
                   style="width: 120px">
                 </InputFloat>
               </el-form-item>
-              <el-form-item label="最大值" v-if="info.actionType === 'increase'" prop="max" :rules="{ validator: checkMinMax }">
-                <InputFloat v-model="info.action.max" style="width: 120px" prefix="$"></InputFloat>
+              <el-form-item label="最大值" v-if="info.actionType === 'increase'" prop="max">
+                <template v-slot:label>
+                  <el-checkbox v-model="maxIsDisabled[index]" @change="onMaxCheckboxChange(index)">最大值</el-checkbox>
+                </template>
+                <InputFloat :disabled="!maxIsDisabled[index]" v-model="info.action.max" style="width: 120px" prefix="$"></InputFloat>
               </el-form-item>
-              <el-form-item label="最小值" v-else prop="min" :rules="{ validator: checkMinMax }">
-                <InputFloat v-model="info.action.min" style="width: 120px" prefix="$"></InputFloat>
+              <el-form-item label="最小值" v-else prop="min" >
+                <template v-slot:label>
+                  <el-checkbox v-model="minIsDisabled[index]" @change="onMinCheckboxChange(index)">最小值</el-checkbox>
+                </template>
+                <InputFloat :disabled="!minIsDisabled[index]" v-model="info.action.min" style="width: 120px" prefix="$"></InputFloat>
               </el-form-item>
             </div>
             <el-form-item v-if="info.actionType === 'set'" prop="set">
-              <el-input v-model="info.action.set"></el-input>
+              <InputFloat v-model="info.action.set" style="width: 120px" prefix="$"></InputFloat>
             </el-form-item>
           </el-form>
           <conditionBuilder

+ 28 - 28
src/views/efTools/automation/components/adActivityDialog.vue

@@ -11,56 +11,43 @@ import { useShopInfo } from '/@/stores/shopInfo';
 import { ElMessage } from 'element-plus';
 import TargetRuleDialog from '/@/views/efTools/automation/components/targetRuleDialog.vue';
 import { DocumentAdd } from '@element-plus/icons-vue';
+import { allCampaignTypes ,campaignStatus} from '/@/views/efTools/utils/enum';
 
+const shopInfo = useShopInfo();
+const { profile } = storeToRefs(shopInfo);
 
 const props = defineProps({
-  templateId: {
-    type: [String, Number],
+  rowData:{
+    type: Object,
     required: true,
   },
-  activeModel: {
-    type: String,
-  },
   modelValue: {
     type: Boolean,
     required: true,
   },
 });
 const emits = defineEmits([ 'confirmSuccess']);
-const shopInfo = useShopInfo();
-const { profile } = storeToRefs(shopInfo);
-const { templateId } = toRefs(props);
-const { activeModel } = toRefs(props);
-
-// const dialogVisible = ref(false);
+const { rowData } = toRefs(props);
+const templateId = ref(rowData.value.id);
+const activeModel = ref(rowData.value.rule.activeModel);
+const campaignType = ref(rowData.value.rule.campaignType);
 const dialogVisible = defineModel({ default: false });
 
-const targetRuleDialogVisible = ref(false);
 
 // 定向规则
-//const adGroupId = ref('')
-//const campaignId = ref('')
+const targetRuleDialogVisible = ref(false);
 const selectedTargetedRow = ref(null);
 const targetLength = ref(0);
 let selectedGroups = [];
 
 // 筛选条件
 const searchAdCampaign = ref('');
-const selectedCampaignType = ref('sp');
+// const selectedCampaignType = ref('');
+const selectedCampaignType = ref(campaignType.value || ''); // 默认选中当前的 campaignType
 const selectedAdGroup = ref('');
 const selectedStatus = ref('');
-
-const campaignType = [
-  { value: 'sb', label: 'SB' },
-  { value: 'sp', label: 'SP' },
-  { value: 'sd', label: 'SD' },
-];
 const adGroups = ref([]);
-const campaignStatus = [
-  { value: 0, label: '未存档' },
-  { value: 'ENABLED', label: '已启用' },
-  { value: 'PAUSED', label: '已暂停' },
-];
+
 // 表格
 const currentPage = ref(1);
 const pageSize = ref(25);
@@ -71,6 +58,19 @@ const xGridOne = ref(null);
 const xGridTwo = ref(null);
 let selectedAds = ref([]);
 
+// 计算属性,动态生成可选的 campaignType
+const filteredCampaignType = computed(() => {
+  const selectedCampaignType = props.rowData.rule.campaignType;
+
+  // 如果 selectedCampaignType 有值,过滤出该值的选项
+  if (selectedCampaignType) {
+    return allCampaignTypes.filter(item => item.value === selectedCampaignType);
+  }
+
+  // 否则,返回所有选项
+  return allCampaignTypes;
+});
+
 const selectedColumns = computed(() => [
   {
     field: 'campaignName',
@@ -155,7 +155,7 @@ async function fetchAdCampaign() {
   }
   try {
     loading.value = true;
-    const cachedSelectedAds = [...selectedAds.value];
+    // const cachedSelectedAds = [...selectedAds.value];
     if (profile.value.profile_id && templateId.value){
     const resp = await getRelationCampaign({
       profileId: profile.value.profile_id,
@@ -513,7 +513,7 @@ onMounted(() => {
                   @change="handleAdCampaignChange()"></el-input>
         <div class="custom-inline">
           <el-select v-model="selectedCampaignType" placeholder="选择广告类型">
-            <el-option v-for="item in campaignType"
+            <el-option v-for="item in filteredCampaignType"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value"

+ 81 - 59
src/views/efTools/automation/index.vue

@@ -1,6 +1,6 @@
 <script lang="ts" setup>
 import { onMounted, provide, reactive, ref, Ref } from 'vue';
-import { Search } from '@element-plus/icons-vue';
+import { Search, WarningFilled } from '@element-plus/icons-vue';
 import { TemplateType } from '../utils/enum';
 import { DelObj, GetList } from '/@/views/efTools/automation/api';
 import SelectBotton from '/@/components/select-button/index.vue';
@@ -18,8 +18,9 @@ import AutomatedRuleTips from '/@/views/efTools/automation/components/automatedR
 const autoInfo = ref(false);
 //关联广告活动弹窗
 const isDialogVisible = ref(false);
-const templateId = ref('');
-const activeModel = ref('');
+// const templateId = ref('');
+// const activeModel = ref('');
+const rowData = ref({});
 provide('isDialogVisible', isDialogVisible);
 
 //查询
@@ -53,60 +54,6 @@ const dyComponents = {
   6: NegKeywordTmpl,
 };
 
-function refreshTable() {
-  showDrawer.value = false;
-  getList();
-}
-
-const showDialog = (row: any) => {
-  templateId.value = row.id;
-  activeModel.value = row.rule.activeModel;
-  isDialogVisible.value = true;
-};
-
-function handleClick() {
-  autoInfo.value = true;
-}
-
-function createTmpl(val: number) {
-  mode.value = 'add';
-  delete formData.value.id;
-  formData.value.name = '';
-  formData.value.rule = {
-    type: val,
-    campaignType: '',
-    campaignAd: [],
-    action: {},
-    activeModel: '',
-    setTime: '',
-    weekdays: [],
-    conditions: [],
-  };
-  showDrawer.value = true;
-}
-
-function editTmpl(row: any) {
-  mode.value = 'edit';
-  formData.value.id = row.id;
-  formData.value.name = row.name;
-  formData.value.rule = row.rule;
-  showDrawer.value = true;
-}
-
-async function deleteTmpl(row: any) {
-  await DelObj(row.id);
-  await getList();
-}
-
-async function submitFormData() {
-  if (mode.value === 'add') {
-    await AddObj(formData.value);
-  } else if (mode.value === 'edit') {
-    await UpdateObj(formData.value);
-  }
-  refreshTable();
-}
-
 //表格配置
 const gridOptions = reactive({
   //border: 'inner',
@@ -161,6 +108,61 @@ const gridEvents = {
   },
 };
 
+function refreshTable() {
+  showDrawer.value = false;
+  getList();
+}
+
+const showDialog = (row: any) => {
+  // templateId.value = row.id;
+  // activeModel.value = row.rule.activeModel;
+  rowData.value = row;
+  isDialogVisible.value = true;
+};
+
+function handleClick() {
+  autoInfo.value = true;
+}
+
+function createTmpl(val: number) {
+  mode.value = 'add';
+  delete formData.value.id;
+  formData.value.name = '';
+  formData.value.rule = {
+    type: val,
+    campaignType: '',
+    campaignAd: [],
+    action: {},
+    activeModel: '',
+    setTime: '',
+    weekdays: [],
+    conditions: [],
+  };
+  showDrawer.value = true;
+}
+
+function editTmpl(row: any) {
+  mode.value = 'edit';
+  formData.value.id = row.id;
+  formData.value.name = row.name;
+  formData.value.rule = row.rule;
+  showDrawer.value = true;
+}
+
+async function deleteTmpl(row: any) {
+  await DelObj(row.id);
+  await getList();
+}
+
+async function submitFormData() {
+  if (mode.value === 'add') {
+    await AddObj(formData.value);
+  } else if (mode.value === 'edit') {
+    await UpdateObj(formData.value);
+  }
+  refreshTable();
+}
+
 function handleTypeChange() {
   localStorage.setItem('templateType', JSON.stringify(templateType.value));
   getList();
@@ -269,7 +271,27 @@ onMounted(() => {
       <template #operate="{ row }">
         <el-button icon="Edit" style="color: #0b52a7" type="text" @click="editTmpl(row)"></el-button>
         <el-button icon="SetUp" style="color: #0b52a7" type="text" @click="showDialog(row)"></el-button>
-        <el-button icon="Delete" style="color: #0b52a7" type="text" @click="deleteTmpl(row)"></el-button>
+        <el-popconfirm
+            width="300"
+            :icon="WarningFilled"
+            icon-color="#ff8d2b"
+            title="删除模板后,所有使用该模板的广告活动将暂停相关自动化规则"
+            @confirm="deleteTmpl(row)"
+        >
+          <template #reference>
+            <el-button icon="Delete" style="color: #0b52a7" type="text"></el-button>
+          </template>
+          <template #actions="{ confirm, cancel }">
+            <el-button size="small" @click="cancel">No!</el-button>
+            <el-button
+                type="danger"
+                size="small"
+                @click="confirm"
+            >
+              Yes?
+            </el-button>
+          </template>
+        </el-popconfirm>
       </template>
       <template #type="{row}">
         <!--<el-tag :type="getTagType(row.rule.typeLabelWithColor.type)">-->
@@ -290,7 +312,7 @@ onMounted(() => {
           @refresh="refreshTable"></component>
     </div>
   </el-drawer>
-  <AdActivityDialog v-if="isDialogVisible" v-model="isDialogVisible" :activeModel="activeModel" :templateId="templateId" @confirmSuccess="getList"/>
+  <AdActivityDialog v-if="isDialogVisible" v-model="isDialogVisible" :rowData @confirmSuccess="getList"/>
   <AutomatedRuleTips v-model="autoInfo"></AutomatedRuleTips>
 </template>
 

+ 13 - 1
src/views/efTools/utils/enum.ts

@@ -2,7 +2,7 @@ export const TemplateType = [
   { label: '所有类型', value: '' },
   { label: '分时调价', value: 1 },
   { label: '分时预算', value: 2 },
-  { label: '广告活动', value: 3 },
+  { label: '开启/暂停 广告活动', value: 3 },
   { label: '定向规则', value: 4 },
   { label: '添加搜索词', value: 5 },
   { label: '添加否定词', value: 6 },
@@ -14,3 +14,15 @@ export const MatchType = [
   { label: '词组匹配', value: 'PHRASE' },
   { label: '精准匹配', value: 'EXACT' },
 ];
+
+export const allCampaignTypes = [
+  { value: 'sb', label: 'SB' },
+  { value: 'sp', label: 'SP' },
+  { value: 'sd', label: 'SD' },
+];
+
+export const campaignStatus = [
+  { value: 0, label: '未存档' },
+  { value: 'ENABLED', label: '已启用' },
+  { value: 'PAUSED', label: '已暂停' },
+];