switch-campaign.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <script lang="ts" setup>
  2. /**
  3. * @Name: switch-campaign
  4. * @Description: 自动化-广告活动
  5. * @Author: Cheney
  6. */
  7. import { ref, watch } from 'vue';
  8. import SelectTmpl from './select-tmpl.vue';
  9. import conditionBuilder from '/@/components/conditionBuilder/index.vue';
  10. import { userFormData } from './common';
  11. import FreqSetting from '../freq-setting.vue';
  12. import SaveRuleDialog from '/@/views/components/auto/auto-campaigns/save-rule-dialog.vue';
  13. import { ElMessage } from 'element-plus';
  14. interface Props {
  15. data: {
  16. campaignId: string;
  17. campaignType: string;
  18. profileId: string;
  19. ruleType: number;
  20. };
  21. RuleStatusButton?: { [key: string]: any };
  22. }
  23. const props = defineProps<Props>();
  24. const emits = defineEmits(['refresh', 'updateRuleStatusButton']);
  25. const formRef = ref();
  26. const condiBuilderRef = ref();
  27. const { formData, submitFormData } = userFormData(props);
  28. formData.value.rule.action.state = [];
  29. formData.value.rule.action.setTime = '';
  30. const submitDialogVisible = ref(false);
  31. const showError = ref(false);
  32. const condidateFields = [
  33. { label: '曝光量', value: 'impressions' },
  34. { label: '点击量', value: 'clicks' },
  35. { label: '转化率', value: 'cr', suffix: '%' },
  36. { label: '单次点击费用', value: 'cpc', prefix: '$' },
  37. ];
  38. const defaultTime = new Date();
  39. function disabledDate(date) {
  40. return date < new Date().setHours(0, 0, 0, 0);
  41. }
  42. // 限制小时
  43. const disabledHour = () => {
  44. const arrs = [];
  45. for (let i = 0; i < 24; i++) {
  46. if (new Date().getHours() <= i) continue;
  47. arrs.push(i);
  48. }
  49. return arrs;
  50. };
  51. // 限制分
  52. const disabledMinute = () => {
  53. const arrs = [];
  54. for (let i = 0; i < 60; i++) {
  55. if (new Date().getMinutes() <= i) continue;
  56. arrs.push(i);
  57. }
  58. return arrs;
  59. };
  60. function addConditions() {
  61. if (formData.value.rule.conditions.length === 0) {
  62. condiBuilderRef.value.addConditionGroup();
  63. }
  64. }
  65. async function validateConditionsForm() {
  66. const validList = await condiBuilderRef.value.validate();
  67. console.log('=>(switch-campaign.vue:77) validList', validList);
  68. return !validList.includes(false);
  69. }
  70. async function submitForm() {
  71. await submitFormData();
  72. ElMessage.success('保存成功');
  73. emits('refresh');
  74. }
  75. function cancel() {
  76. emits('refresh');
  77. }
  78. async function handleSubmit() {
  79. const valid2 = await validateConditionsForm();
  80. formRef.value.validate(async (valid: any) => {
  81. const actionState = formData.value.rule.action.state;
  82. if (!valid || (actionState.includes('paused') && !valid2)) return;
  83. if (formData.value.rule.action.state.length === 0) return;
  84. const selectedTime = new Date(formData.value.rule.action.setTime).setSeconds(0, 0);;
  85. if (selectedTime < new Date().setSeconds(0, 0)) {
  86. ElMessage.error('保存失败,请重新选择时间');
  87. return;
  88. }
  89. try {
  90. if (formData.value.useTmpl) {
  91. await submitForm();
  92. } else {
  93. submitDialogVisible.value = true;
  94. }
  95. } catch (error) {
  96. console.error('提交失败:', error);
  97. }
  98. });
  99. }
  100. watch(() => formData.value, (newData) => {
  101. emits('updateRuleStatusButton', newData.RuleStatusButton);
  102. });
  103. </script>
  104. <template>
  105. <div class="mx-5">
  106. <div class="asj-h2">开启/暂停广告活动</div>
  107. <SelectTmpl :data="formData" />
  108. <el-card class="mt-3">
  109. <FreqSetting :disabled="formData.useTmpl" :rule="formData.rule" />
  110. <el-divider />
  111. <el-form ref="formRef" :disabled="formData.useTmpl" :model="formData" label-position="top"
  112. style="margin-top: 20px">
  113. <div class="asj-h3">
  114. <span class="custom-title-icon"></span>
  115. 操作
  116. </div>
  117. <el-checkbox-group v-model="formData.rule.action.state" :disabled="formData.useTmpl">
  118. <div>
  119. <el-checkbox label="enabled">开始</el-checkbox>
  120. <div v-show="formData.rule.action.state.includes('enabled')" style="display: block; margin: 10px 0">
  121. <el-form-item
  122. :rules="[{ required: formData.rule.action.state.includes('enabled'), message: '必填项', trigger: 'blur' }]"
  123. prop="rule.action.setTime">
  124. <el-date-picker
  125. v-model="formData.rule.action.setTime"
  126. :default-time="defaultTime"
  127. :disabled-date="disabledDate"
  128. :disabled-hours="disabledHour"
  129. :disabled-minutes="disabledMinute"
  130. format="YYYY-MM-DD HH:mm"
  131. time-format="HH:mm"
  132. type="datetime"
  133. value-format="YYYY-MM-DD HH:mm"
  134. />
  135. </el-form-item>
  136. </div>
  137. </div>
  138. <el-checkbox label="paused" @click="addConditions">暂停</el-checkbox>
  139. </el-checkbox-group>
  140. <el-form-item v-if="formData.rule.action.state.length === 0" style="color: red">
  141. <span style="font-size: 12px;">请至少选择一种操作</span>
  142. </el-form-item>
  143. </el-form>
  144. <div v-show="formData.rule.action.state.includes('paused')">
  145. <conditionBuilder
  146. ref="condiBuilderRef"
  147. :candidate-fields="condidateFields"
  148. :data="formData.rule.conditions"
  149. :disabled="formData.useTmpl" />
  150. </div>
  151. </el-card>
  152. <SaveRuleDialog
  153. v-model="submitDialogVisible"
  154. :formData="formData"
  155. :formRef="formRef"
  156. @submit="submitForm"
  157. />
  158. <div class="auto-page-foot">
  159. <el-button style="width: 200px" @click="cancel">取消</el-button>
  160. <el-button style="width: 200px" type="primary" @click="handleSubmit">提交</el-button>
  161. </div>
  162. </div>
  163. </template>
  164. <style scoped>
  165. .custom-title-icon {
  166. padding-right: 10px;
  167. }
  168. .custom-title-icon:before {
  169. content: '';
  170. width: 4px;
  171. height: 15px;
  172. background: #3569d6;
  173. position: absolute;
  174. transform: translateY(25%);
  175. }
  176. </style>