Prechádzať zdrojové kódy

✨ feat<自动化规则>:效率工具-自动化规则;广告管理-自动化规则;
--开启/暂停广告活动:暂停-条件组件修改为必填;删除按钮修改;选择时间限制,禁用此时此刻前的时间;
--分时调价:TimerBidTable初始化时默认值为1;
--自动化tab:开关调用接口;
--添加搜索词:设置竞价处改为复选框;实现勾选时显示匹配类型
--定向规则:升高/降低竞价时,最大值非必填,勾选时有值;actionModel默认值为“bid-ratio”,修改actionModel每一个规则互相独立;添加规则排序功能,根据排序优先执行;

xinyan 7 mesiacov pred
rodič
commit
eece0cb2ae

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

@@ -223,7 +223,7 @@ watch(
         for (let i = 0; i < 7; i++) {
           const tmp = [];
           for (let j = 0; j < 24; j++) {
-            tmp.push(0);
+            tmp.push(1);
           }
           props.data.push(tmp);
         }

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

@@ -19,6 +19,7 @@
           :prop="getFormProp(conditionInfo, index)"
           :rules="{ validator: checkRight, trigger: getFormTrigger(conditionInfo) }">
           <template #label>
+            <span class="required-star" v-if="index === 0" style="color:#f56c6c; margin-right: 4px;">*</span>
             <span v-if="index === 0">条件:</span>
             <span class="and-span" v-else>&</span>
           </template>
@@ -81,14 +82,15 @@
         添加条件
       </el-button>
     </div>
-    <el-button type="danger" @click="deleteConditionGroup" :icon="Delete" v-show="showDelGroupBtn">删除组</el-button>
+    <el-button type="danger" @click="deleteConditionGroup" :icon="RemoveFilled" link
+               size="large" v-show="showDelGroupBtn"></el-button>
   </div>
   <el-divider border-style="dashed" class="condition-group-divider"> 或 </el-divider>
 </template>
 
 <script lang="ts" setup>
 import { ref, reactive, computed, watch } from 'vue'
-import { Delete, Plus } from '@element-plus/icons-vue'
+import { Delete, Plus, RemoveFilled } from '@element-plus/icons-vue';
 import InputFloat from '/@/components/input-float/index.vue'
 import TagsInput from '/@/components/tags-input/index.vue'
 import RangeFloat from '/@/components/range-float/index.vue'

+ 1 - 1
src/components/input-float/index.vue

@@ -14,7 +14,7 @@ const props = defineProps({
   },
   precision: {
     type: Number,
-    default: 2,
+    // default: 2,
   },
   prefix: {
     type: String,

+ 74 - 63
src/views/adManage/sb/campaigns/campaignDetail/automation/index.vue

@@ -17,34 +17,14 @@ const props = defineProps<Props>();
 const campaignType = 'sb';
 const activeTab = ref(1);
 const RuleStatusButton = ref({
-  '1': '-',
-  '2': '-',
-  '3': '-',
-  '4': '-',
-  '5': '-',
-  '6': '-',
-});
-// const height = ref(800)
-// const campaignRuleStatus = ref({
-//   campaignId: props.campaignId,
-//   campaignType: campaignType,
-//   profileId: props.profileId,
-//   ruleType: activeTab.value,
-//   templateName: '',
-//   useTmpl: false,
-//   template: null,
-//   rule: {
-//     type: activeTab.value,
-//     campaignType: campaignType,
-//     campaignAd: [],
-//     action: {},
-//     activeModel: '',
-//     setTime: '',
-//     weekdays: [],
-//     conditions: [],
-//   },
-//   RuleStatusButton: RuleStatusButton,
-// })
+  '1': 0,
+  '2': 0,
+  '3': 0,
+  '4': 0,
+  '5': 0,
+  '6': 0,
+})
+
 const baseData = ref({
   campaignId: props.campaignId,
   campaignType: campaignType,
@@ -52,22 +32,33 @@ const baseData = ref({
   ruleType: activeTab,
 });
 
-onMounted(async () => {
-  await initData();
-});
-
-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];
+async function changeStatus(newStatus: number, tabIndex: string) {
+  const body = {
+    ...baseData.value,
+    ruleType: Number(tabIndex),
+    status: newStatus
+  };
+  try {
+    const response = await postCampaignStatus(body);
+    if (response.code === 2000) {
+      ElMessage.success('更新状态成功');
+      // const resp = await getCampaignRuleInfo(baseData.value);
+      // RuleStatusButton.value = resp.data[0].RuleStatusButton;
+    } else if (response.code == 5000) {
+      ElMessage.warning(`${ response.data.description }`);
+    } else {
+      ElMessage.error('状态更新失败');
     }
+  } catch (error) {
+    console.log('error:', error);
   }
 }
-
-async function changeTab() {
-  // await initData()
+function updateRuleStatusButton(newValue) {
+  if (newValue !== undefined) {
+    RuleStatusButton.value = { ...RuleStatusButton.value, ...newValue }
+  } else {
+    console.error('接收到的 newValue 是 undefined')
+  }
 }
 
 async function refresh(tab: number) {
@@ -76,64 +67,84 @@ async function refresh(tab: number) {
     activeTab.value = tab;
   });
 }
+
+onMounted(async () => {
+  // await initData();
+});
 </script>
 
 <template>
-  <el-tabs tab-position="left" v-model="activeTab" @tab-change="changeTab">
-    <el-tab-pane label="分时调价" :name="1">
+  <el-tabs v-model="activeTab" tab-position="left" @tab-change="changeTab">
+    <el-tab-pane :name="1" label="分时调价">
       <template #label>
         <div class="tab-label">
-          <el-switch size="small" v-model="RuleStatusButton['1']" :disabled="RuleStatusButton['1'] === '-'"></el-switch>
+          <el-switch v-model="RuleStatusButton['1']" :active-value="1" :disabled="RuleStatusButton['1'] === '-'"
+                     :inactive-value="0" size="small" @change="(val) => changeStatus(val, '1')" @click.stop="">
+          </el-switch>
           <span>分时调价</span>
         </div>
       </template>
-      <TimerBid :data="baseData" :RuleStatusButton="RuleStatusButton" @refresh="refresh(1)" v-if="activeTab === 1" />
+      <TimerBid v-if="activeTab === 1" :RuleStatusButton="RuleStatusButton" :data="baseData" @refresh="refresh(1)"  @updateRuleStatusButton="updateRuleStatusButton"/>
     </el-tab-pane>
-    <el-tab-pane label="分时预算" :name="2">
+    <el-tab-pane :name="2" label="分时预算">
       <template #label>
         <div class="tab-label">
-          <el-switch size="small" v-model="RuleStatusButton['2']" :disabled="RuleStatusButton['2'] === '-'"></el-switch>
+          <el-switch v-model="RuleStatusButton['2']" :active-value="1" :disabled="RuleStatusButton['2'] === '-'"
+                     :inactive-value="0" size="small" @change="(val) => changeStatus(val, '2')" @click.stop="">
+          </el-switch>
           <span>分时预算</span>
         </div>
       </template>
-      <TimerBudget :data="baseData" :RuleStatusButton="RuleStatusButton" @refresh="refresh(2)" v-if="activeTab === 2" />
+      <TimerBudget v-if="activeTab === 2" :RuleStatusButton="RuleStatusButton" :data="baseData" @refresh="refresh(2)" />
     </el-tab-pane>
-    <el-tab-pane label="广告活动" :name="3">
+    <el-tab-pane :name="3" label="开启/暂停广告活动">
       <template #label>
         <div class="tab-label">
-          <el-switch size="small" v-model="RuleStatusButton['3']" :disabled="RuleStatusButton['3'] === '-'"></el-switch>
-          <span>广告活动</span>
+          <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>
         </div>
       </template>
-      <SwitchCampaign :data="baseData" :RuleStatusButton="RuleStatusButton" @refresh="refresh(3)" v-if="activeTab === 3" />
+      <SwitchCampaign v-if="activeTab === 3" :RuleStatusButton="RuleStatusButton" :data="baseData"
+                      @refresh="refresh(3)" />
     </el-tab-pane>
-    <el-tab-pane label="定向规则" :name="4">
+    <el-tab-pane :name="4" label="定向规则">
       <template #label>
         <div class="tab-label">
-          <el-switch size="small" v-model="RuleStatusButton['4']" :disabled="RuleStatusButton['4'] === '-'"></el-switch>
+          <el-switch v-model="RuleStatusButton['4']" :active-value="1" :disabled="RuleStatusButton['4'] === '-'"
+                     :inactive-value="0" size="small" @change="(val) => changeStatus(val, '4')" @click.stop="">
+          </el-switch>
           <span>定向规则</span>
         </div>
       </template>
-      <TargetRule :data="baseData" :RuleStatusButton="RuleStatusButton" @refresh="refresh(4)" v-if="activeTab === 4"></TargetRule>
+      <TargetRule v-if="activeTab === 4" :RuleStatusButton="RuleStatusButton" :data="baseData"
+                  @refresh="refresh(4)"></TargetRule>
     </el-tab-pane>
-    <el-tab-pane label="添加搜索词" :name="5">
+    <el-tab-pane :name="5" label="添加搜索词">
       <template #label>
         <div class="tab-label">
-          <el-switch size="small" v-model="RuleStatusButton['5']" :disabled="RuleStatusButton['5'] === '-'"></el-switch>
+          <el-switch v-model="RuleStatusButton['5']" :active-value="1" :disabled="RuleStatusButton['5'] === '-'"
+                     :inactive-value="0" size="small" @change="(val) => changeStatus(val, '5')" @click.stop="">
+          </el-switch>
           <span>添加搜索词</span>
         </div>
       </template>
-      <SearchTermRule :data="baseData" :RuleStatusButton="RuleStatusButton" @refresh="refresh(5)" v-if="activeTab === 5">
+      <SearchTermRule v-if="activeTab === 5" :RuleStatusButton="RuleStatusButton" :data="baseData"
+                      @refresh="refresh(5)">
       </SearchTermRule>
     </el-tab-pane>
-    <el-tab-pane label="添加否定词" :name="6">
+    <el-tab-pane :name="6" label="添加否定词">
       <template #label>
         <div class="tab-label">
-          <el-switch size="small" v-model="RuleStatusButton['6']" :disabled="RuleStatusButton['6'] === '-'"></el-switch>
+          <el-switch v-model="RuleStatusButton['6']" :active-value="1" :disabled="RuleStatusButton['6'] === '-'"
+                     :inactive-value="0" size="small" @change="(val) => changeStatus(val, '6')" @click.stop="">
+          </el-switch>
           <span>添加否定词</span>
         </div>
       </template>
-      <NegKeywordRule :data="baseData" :RuleStatusButton="RuleStatusButton" @refresh="refresh(6)" v-if="activeTab === 6">
+      <NegKeywordRule v-if="activeTab === 6" :RuleStatusButton="RuleStatusButton" :data="baseData"
+                      @refresh="refresh(6)">
       </NegKeywordRule>
     </el-tab-pane>
   </el-tabs>
@@ -144,6 +155,6 @@ async function refresh(tab: number) {
   display: flex;
   justify-content: space-between;
   align-items: center;
-  width: 120px;
+  width: 155px;
 }
-</style>
+</style>

+ 0 - 1
src/views/adManage/sp/campaigns/campaignDetail/automation/index.vue

@@ -53,7 +53,6 @@ async function changeStatus(newStatus: number, tabIndex: string) {
       ElMessage.success('更新状态成功');
       // 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 {

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

@@ -93,8 +93,8 @@ async function handleSubmit() {
 
     if (formData.value.rule.action.state.length === 0) return;
 
-    const selectedTime = new Date(formData.value.rule.action.setTime);
-    if (selectedTime <= new Date()) {
+    const selectedTime = new Date(formData.value.rule.action.setTime).setSeconds(0, 0);;
+    if (selectedTime < new Date().setSeconds(0, 0)) {
       ElMessage.error('保存失败,请重新选择时间');
       return;
     }

+ 3 - 5
src/views/components/auto/auto-campaigns/target-rule.vue

@@ -64,12 +64,10 @@ async function handleSubmit() {
     <el-card class="mt-3">
       <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 :disabled="formData.useTmpl" :rule="formData.rule" />
           <el-divider />
+          <!-- 生效对象 -->
           <TargetSelect
               :campaign-id="data.campaignId"
               :data="formData.rule"
@@ -78,7 +76,7 @@ async function handleSubmit() {
         </el-form-item>
       </el-form>
     </el-card>
-
+    <!--规则设置-->
     <el-card class="mt-3">
       <TargetRuleSetting ref="ruleSettingRef" :disabled="formData.useTmpl" :rule="formData.rule" />
     </el-card>

+ 46 - 11
src/views/components/auto/search-term-bid.vue

@@ -9,11 +9,14 @@ import { computed } from 'vue';
 import STBidInput from './st-bid-input.vue';
 import XEUtils from 'xe-utils';
 
+
 interface Props {
   action: RuleSearchTermAction;
 }
 
 const props = defineProps<Props>();
+const keywordBidding = ref(false);
+const productBidding = ref(false);
 const MatchTypeMap = {
   EXACT: '精准匹配',
   BROAD: '广泛匹配',
@@ -21,9 +24,36 @@ const MatchTypeMap = {
 };
 if (!props.action.keywords) {
   props.action.keywords = [
-    { bidType: '1', type: 'increase', numType: '1', defaultBidding: '1.00', min: '', max: '', matchType: 'EXACT', use: false },
-    { bidType: '1', type: 'increase', numType: '1', defaultBidding: '1.00', min: '', max: '', matchType: 'BROAD', use: false },
-    { bidType: '1', type: 'increase', numType: '1', defaultBidding: '1.00', min: '', max: '', matchType: 'PHRASE', use: false },
+    {
+      bidType: '1',
+      type: 'increase',
+      numType: '1',
+      defaultBidding: '1.00',
+      min: '',
+      max: '',
+      matchType: 'EXACT',
+      use: false
+    },
+    {
+      bidType: '1',
+      type: 'increase',
+      numType: '1',
+      defaultBidding: '1.00',
+      min: '',
+      max: '',
+      matchType: 'BROAD',
+      use: false
+    },
+    {
+      bidType: '1',
+      type: 'increase',
+      numType: '1',
+      defaultBidding: '1.00',
+      min: '',
+      max: '',
+      matchType: 'PHRASE',
+      use: false
+    },
   ];
 }
 if (!props.action.target) {
@@ -54,17 +84,22 @@ defineExpose({ valid });
       <span class="custom-title-icon"></span>
       设置竞价
     </div>
-    <div>关键词竞价:</div>
-    <div v-for="(info, index) in action.keywords" class="bid">
+    <div>
+      <el-checkbox v-model="keywordBidding" label="关键词竞价" size="large"></el-checkbox>
+    </div>
+
+    <div v-for="(info, index) in action.keywords" v-if="keywordBidding" class="bid">
       <el-checkbox v-model="info.use" :label="info.matchType">{{ MatchTypeMap[info.matchType] }}</el-checkbox>
-      <STBidInput :bid-data="info" :index="index" v-show="info.use"></STBidInput>
+      <STBidInput v-show="info.use" :bid-data="info" :index="index"></STBidInput>
+    </div>
+    <div>
+      <el-checkbox v-model="productBidding" label="商品定向竞价" size="large"></el-checkbox>
     </div>
-    <div>商品定向竞价:</div>
-    <div class="bid target">
-      <el-checkbox label="target" v-model="action.target.use">竞价</el-checkbox>
-      <STBidInput :bid-data="action.target" v-show="action.target.use"></STBidInput>
+    <div v-if="productBidding" class="bid target">
+      <el-checkbox v-model="action.target.use" label="target">竞价</el-checkbox>
+      <STBidInput v-show="action.target.use" :bid-data="action.target"></STBidInput>
     </div>
-    <p v-show="!valid" style="font-size: small; color: #f56c6c">请至少设置一种竞价方式!</p>
+    <p v-show="!valid" style="font-size: small; color: #f56c6c">请至少选择一种竞价方式!</p>
   </div>
 </template>
 

+ 169 - 59
src/views/components/auto/target-rule-setting.vue

@@ -5,14 +5,15 @@
  * @Author: Cheney
  */
 
-import { ref, computed, onBeforeUnmount } from 'vue';
-import { Plus } from '@element-plus/icons-vue';
+import { computed, ref } from 'vue';
+import { Bottom, InfoFilled, Plus, Top } from '@element-plus/icons-vue';
 import conditionBuilder from '/@/components/conditionBuilder/index.vue';
 import InputFloat from '/@/components/input-float/index.vue';
 import { useSymbolOptions } from '/@/components/conditionBuilder/utils';
 import { ActionList, RuleNameMap } from './enum';
 import XEUtils from 'xe-utils';
 
+
 interface Props {
   rule: AutoRule;
   disabled?: boolean;
@@ -44,12 +45,16 @@ const candidateFields = [
   { label: '关键词名称', value: 'keywords', type: 'array' },
 ];
 
+const isVisible = ref(true);
+const setting = ref('edit');
+
 const { getSymbolOptions } = useSymbolOptions(candidateFields);
 const maxIsDisabled = ref([]);
 const minIsDisabled = ref([]);
 const ruleFormRef = ref();
 const condiBuilderRef = ref();
-const actionModel = ref('bid-ratio');
+const actionModel = ref([]);
+let ruleInfo = {};
 
 const maxRuleNumber = computed(() => {
   const ret = {
@@ -64,10 +69,10 @@ const maxRuleNumber = computed(() => {
   return ret;
 });
 
-onMounted(() => {
-  maxIsDisabled.value.push(!props.rule.action.max);
-  minIsDisabled.value.push(!props.rule.action.min);
-})
+
+watch(() => props.rule, (newRule) => {
+  ruleInfo = newRule.conditions[0].action;
+});
 
 function checkFloat(rule: any, value: any, callback: any) {
   if (XEUtils.toNumber(value) <= 0) {
@@ -115,15 +120,19 @@ function addRule(actionType: string, index: number = -1) {
   };
 
   if (index === -1) {
+    // 第一条规则
     props.rule.conditions.push(rule);
-    if (actionType === 'increase'){
-      maxIsDisabled.value.push(false);
-    }else if (actionType === 'decrease'){
-      minIsDisabled.value.push(false);
+    if (actionType === 'increase') {
+      actionModel.value.push('bid-ratio');
+      maxIsDisabled.value.push(ruleInfo.max !== '' && ruleInfo.max !== undefined);
+    } else if (actionType === 'decrease') {
+      actionModel.value.push('bid-ratio');
+      minIsDisabled.value.push(ruleInfo.min);
     }
   } else {
     props.rule.conditions.splice(index + 1, 0, rule);
     maxIsDisabled.value.splice(index + 1, 0, false); // 添加一个初始值
+    actionModel.value.splice(index + 1, 0, 'bid-ratio'); // 添加一个初始值
     minIsDisabled.value.splice(index + 1, 0, false); // 添加一个初始值
   }
 }
@@ -131,20 +140,21 @@ function addRule(actionType: string, index: number = -1) {
 if (props.rule.conditions.length === 0) {
   props.rule.campaignType = 'sp';
   props.rule.activeModel = 'campaign';
-  // addRule('increase', -1);
+  console.log('actionModel.value',actionModel.value);
+  addRule('increase', -1);
 }
 
-function delRule(index: number) {
+function delRule(actionType: string, index: number) {
   props.rule.conditions.splice(index, 1);
-  if (actionType === 'increase'){
+  if (actionType === 'increase') {
     maxIsDisabled.value.splice(index, 1);
-  }else if (actionType === 'decrease'){
+  } else if (actionType === 'decrease') {
     minIsDisabled.value.splice(index, 1);
   }
 }
 
-function changeAction(action: any) {
-  const [a, b] = actionModel.value.split('-');
+function changeAction(actionModel: any, action: any) {
+  const [a, b] = actionModel.split('-');
   action.baseType = a;
   action.numType = b;
   action.set = '';
@@ -174,25 +184,60 @@ async function validateRuleForm() {
 }
 
 async function validateForm() {
+  // 当没有勾选最大值、最小值时,清空action的max和min值
+  props.rule.conditions.forEach((condition, index) => {
+    if (!maxIsDisabled.value[index]) {
+      condition.action.max = '';
+    }
+    if (!minIsDisabled.value[index]) {
+      condition.action.min = '';
+    }
+  });
   const valid1 = await validateRuleForm();
   const valid2 = await validateConditionsForm();
   return valid1 && valid2;
 }
 
-function onMaxCheckboxChange(index: number) {
-  if (!maxIsDisabled.value[index]) {
-    // 如果复选框被取消勾选,禁用输入框并清空对应的值
-    props.rule.conditions[index].action.max = '';
+function handleClose() {
+  isVisible.value = false;
+}
+
+function moveUp(index) {
+  if (index > 0) {
+    const temp = props.rule.conditions[index];
+    props.rule.conditions[index] = props.rule.conditions[index - 1];
+    props.rule.conditions[index - 1] = temp;
+    // 更新ordering
+    updateOrdering();
   }
 }
 
-function onMinCheckboxChange(index: number) {
-  if (!minIsDisabled.value[index]) {
-    // 如果复选框被取消勾选,禁用输入框并清空对应的值
-    props.rule.conditions[index].action.min = '';
+function moveDown(index) {
+  if (index < props.rule.conditions.length - 1) {
+    const temp = props.rule.conditions[index];
+    props.rule.conditions[index] = props.rule.conditions[index + 1];
+    props.rule.conditions[index + 1] = temp;
+    // 更新ordering
+    updateOrdering();
   }
 }
 
+function updateOrdering() {
+  props.rule.conditions.forEach((condition, index) => {
+    condition.ordering = index + 1; // 重新计算ordering,从1开始
+  });
+}
+
+function getActionModelLabel(value) {
+  const option = ActionList.find(option => option.value === value);
+  return option ? option.label : '';
+}
+
+// 获取对应 set 值的后缀
+function getSetSuffix(numType) {
+  return numType === 'num' ? '$' : numType === 'ratio' ? '%' : '';
+}
+
 defineExpose({ validateForm });
 </script>
 
@@ -202,22 +247,42 @@ defineExpose({ validateForm });
       <span class="custom-title-icon"></span>
       规则设置
     </div>
-    <div class="rule-setting-container">
-      <div v-for="(info, index) in rule.conditions" class="rule-setting-item" :key="info.actionType + info.ordering">
+    <!--提示信息-->
+    <div>
+      <el-tag v-if="isVisible" class="custom-tag" closable color="#e7edf4" @close="handleClose">
+        <template #default>
+          <div class="tag-content">
+            <el-icon style="color: #0b52a7">
+              <InfoFilled />
+            </el-icon>
+            可设置多个规则,如果一个对象命中多个规则,系统只是执行优先级最高的规则
+          </div>
+        </template>
+      </el-tag>
+    </div>
+    <div class="mt-5">
+      <el-radio-group v-model="setting" size="small">
+        <el-radio-button label="编辑" value="edit" />
+        <el-radio-button label="排序" value="order" />
+      </el-radio-group>
+    </div>
+    <div v-if="setting === 'edit'" class="rule-setting-container">
+      <div v-for="(info, index) in rule.conditions" :key="info.actionType + info.ordering" class="rule-setting-item">
         <div class="rule-setting-title">
           <div class="asj-h3">{{ RuleNameMap[info.actionType] }} - 规则{{ info.ordering }}</div>
           <div class="rule-setting-opration">
-            <el-tooltip content="添加规则" placement="top" effect="dark" v-if="!disabled">
-              <el-icon @click="addRule(info.actionType, index)" :disabled="disabled">
+            <el-tooltip v-if="!disabled" content="添加规则" effect="dark" placement="top">
+              <el-icon :disabled="disabled" @click="addRule(info.actionType, index)">
                 <Plus />
               </el-icon>
             </el-tooltip>
-            <el-tooltip content="删除规则" placement="top" effect="dark" v-if="rule.conditions.length !== 1 && !disabled">
-              <el-icon @click="delRule(index)">
+            <el-tooltip v-if="rule.conditions.length !== 1 && !disabled" content="删除规则" effect="dark"
+                        placement="top">
+              <el-icon @click="delRule(info.actionType,index)">
                 <DeleteFilled />
               </el-icon>
             </el-tooltip>
-            <el-tooltip content="收起/展开规则" placement="top" effect="dark">
+            <el-tooltip content="收起/展开规则" effect="dark" placement="top">
               <el-icon @click="info.show = !info.show">
                 <ArrowDown />
               </el-icon>
@@ -225,62 +290,92 @@ defineExpose({ validateForm });
           </div>
         </div>
         <div v-show="info.show">
-          <el-form :inline="true" :model="info.action" ref="ruleFormRef" :disabled="disabled">
+          <el-form ref="ruleFormRef" :disabled="disabled" :inline="true" :model="info.action">
             <!-- 竞价规则下面的下拉框和两个输入框 -->
             <div v-if="info.actionType === 'increase' || info.actionType === 'decrease'">
               <el-form-item>
-                <el-select v-model="actionModel" @change="changeAction(info.action)" style="width: 250px">
+                <el-select v-model="actionModel[index]" style="width: 250px"
+                           @change="changeAction(actionModel[index], info.action)">
                   <el-option
-                    v-for="item in ActionList"
-                    :key="item.value"
-                    :value="item.value"
-                    :label="item.label.replace('_', info.actionType === 'increase' ? '升高' : '降低')">
+                      v-for="item in ActionList"
+                      :key="item.value"
+                      :label="item.label.replace('_', info.actionType === 'increase' ? '升高' : '降低')"
+                      :value="item.value">
                   </el-option>
                 </el-select>
               </el-form-item>
-              <el-form-item prop="set" :rules="{ validator: checkFloat }">
+              <el-form-item :rules="{ validator: checkFloat }" prop="set">
                 <InputFloat
-                  v-model="info.action.set"
-                  :prefix="info.action.numType === 'num' ? '$' : ''"
-                  :suffix="info.action.numType === 'ratio' ? '%' : ''"
-                  style="width: 120px">
+                    v-model="info.action.set"
+                    :prefix="info.action.numType === 'num' ? '$' : ''"
+                    :suffix="info.action.numType === 'ratio' ? '%' : ''"
+                    style="width: 120px">
                 </InputFloat>
               </el-form-item>
-              <el-form-item label="最大值" v-if="info.actionType === 'increase'" prop="max">
+              <el-form-item v-if="info.actionType === 'increase'" label="最大值" prop="max">
                 <template v-slot:label>
-                  <el-checkbox v-model="maxIsDisabled[index]" @change="onMaxCheckboxChange(index)">最大值</el-checkbox>
+                  <el-checkbox v-model="maxIsDisabled[index]">最大值</el-checkbox>
                 </template>
-                <InputFloat :disabled="!maxIsDisabled[index]" v-model="info.action.max" style="width: 120px" prefix="$"></InputFloat>
+                <InputFloat v-model="info.action.max" :disabled="!maxIsDisabled[index]" prefix="$"
+                            style="width: 120px"></InputFloat>
               </el-form-item>
-              <el-form-item label="最小值" v-else prop="min" >
+              <el-form-item v-else label="最小值" prop="min">
                 <template v-slot:label>
-                  <el-checkbox v-model="minIsDisabled[index]" @change="onMinCheckboxChange(index)">最小值</el-checkbox>
+                  <el-checkbox v-model="minIsDisabled[index]">最小值</el-checkbox>
                 </template>
-                <InputFloat :disabled="!minIsDisabled[index]" v-model="info.action.min" style="width: 120px" prefix="$"></InputFloat>
+                <InputFloat v-model="info.action.min" :disabled="!minIsDisabled[index]" prefix="$"
+                            style="width: 120px"></InputFloat>
               </el-form-item>
             </div>
             <el-form-item v-if="info.actionType === 'set'" prop="set">
-              <InputFloat v-model="info.action.set" style="width: 120px" prefix="$"></InputFloat>
+              <InputFloat v-model="info.action.set" prefix="$" style="width: 120px"></InputFloat>
             </el-form-item>
           </el-form>
           <conditionBuilder
-            :data="info.conditions"
-            :candidate-fields="candidateFields"
-            ref="condiBuilderRef"
-            :disabled="disabled" />
+              ref="condiBuilderRef"
+              :candidate-fields="candidateFields"
+              :data="info.conditions"
+              :disabled="disabled" />
         </div>
       </div>
-      <el-popover placement="bottom-start" trigger="hover" :disabled="disabled">
+      <el-popover :disabled="disabled" placement="bottom-start" trigger="hover">
         <template #reference>
-          <el-button :icon="Plus" type="warning" :disabled="disabled">添加规则</el-button>
+          <el-button :disabled="disabled" :icon="Plus" type="warning">添加规则</el-button>
         </template>
         <div class="popver-content">
-          <span class="popver-content-item" v-for="[name, title] of Object.entries(RuleNameMap)" @click="addRule(name)">{{
-            title
-          }}</span>
+          <span v-for="[name, title] of Object.entries(RuleNameMap)" class="popver-content-item" @click="addRule(name)">{{
+              title
+            }}</span>
         </div>
       </el-popover>
     </div>
+    <div v-if="setting === 'order'" class="mt-2">
+      <div v-for="(info, index) in rule.conditions" :key="info.actionType + info.ordering">
+        <el-row>
+          <el-col :span="20">
+            <el-card body-style="padding: 12px 10px;" class="rule-setting-item" draggable="true" shadow="hover">
+              {{ RuleNameMap[info.actionType] }} - 规则{{ info.ordering }}
+              <span v-if="info.actionType === 'increase' || info.actionType === 'decrease'">
+                 {{
+                  getActionModelLabel(actionModel[index]).replace('_', info.actionType === 'increase' ? '升高' : '降低')
+                }}
+                {{ info.action.set }}
+              <span v-if="info.action.set && info.action.numType">
+                {{ getSetSuffix(info.action.numType) }}
+              </span>
+              </span>
+            </el-card>
+          </el-col>
+          <el-col :span="4">
+            <div class="mt-3 pl-2">
+              <el-button :disabled="index === 0" :icon="Top" link type="primary" @click="moveUp(index)"></el-button>
+              <el-button :disabled="index === rule.conditions.length - 1" :icon="Bottom" link type="primary"
+                         @click="moveDown(index)"></el-button>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -336,4 +431,19 @@ defineExpose({ validateForm });
   position: absolute;
   transform: translateY(25%);
 }
+
+.tag-content {
+  display: block;
+  max-width: 100%;
+}
+
+.rule-setting-item {
+  width: 100%;
+  margin: 5px 0;
+  padding: 0;
+  border-radius: 0 !important;
+  font-size: 13px;
+  font-weight: 500;
+}
+
 </style>

+ 0 - 1
src/views/reportManage/dataCenter/normalDisplay/components/DateTendency/index.vue

@@ -351,7 +351,6 @@ function changeMetric() {
   chartObj.setOption(option, true); // 使用 true 作为第二个参数,强制完全刷新
 
   // 获取所有 y 轴的刻度标签
-  console.log('123', statDim.value);
   if (statDim.value != 'week') {
     const salesLabels = ['销售额', '上年销售额', '上月销售额'];
     let commonMin = Infinity;

+ 1 - 0
src/views/reportManage/dataCenter/normalDisplay/components/Selector/index.vue

@@ -100,6 +100,7 @@ async function fetchFilteredData() {
   }
 
   filteredData.value = filters;
+  console.log("=>(index.vue:103) filters", filters);
   try {
     const response = await getTasksId(filters);
     updateData.value = response.data.map(item => item.id).join(',');