timer-bid.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <script lang="ts" setup>
  2. /**
  3. * @Name: timer-bid.vue
  4. * @Description: 自动化-分时调价组件
  5. * @Author: Cheney
  6. */
  7. import { ref } from 'vue';
  8. import TimerBidTable from '/@/components/TimerBidTable/index.vue';
  9. import SelectTmpl from './select-tmpl.vue';
  10. import { userFormData } from './common';
  11. import SaveRuleDialog from '/@/views/components/auto/auto-campaigns/save-rule-dialog.vue';
  12. interface Props {
  13. data: {
  14. campaignId: string;
  15. campaignType: string;
  16. profileId: string;
  17. ruleType: number;
  18. };
  19. RuleStatusButton?: { [key: string]: any };
  20. //data: AutoCampaignRule;
  21. }
  22. const props = defineProps<Props>();
  23. const emits = defineEmits(['refresh']);
  24. const formRef = ref();
  25. const { formData, submitFormData } = userFormData(props);
  26. const tableRef = ref(null);
  27. const timeRange = ref('Option1');
  28. const schedule = ref('Option1');
  29. const bid = ref('1.0');
  30. const bidError = ref(''); // 错误信息
  31. const timeRangeOptions = [
  32. {
  33. value: 'Option1',
  34. label: '24小时: 00:00-23:59',
  35. },
  36. {
  37. value: 'Option2',
  38. label: '凌晨: 00:00-06:59',
  39. },
  40. {
  41. value: 'Option3',
  42. label: '上午: 7:00-11:59',
  43. },
  44. {
  45. value: 'Option4',
  46. label: '工作时: 9:00-16:59',
  47. },
  48. {
  49. value: 'Option5',
  50. label: '下午: 12:00-16:59',
  51. },
  52. {
  53. value: 'Option6',
  54. label: '晚上: 17:00-20:59',
  55. },
  56. {
  57. value: 'Option7',
  58. label: '深夜: 21:00-23:59',
  59. },
  60. ];
  61. const scheduleOptions = [
  62. {
  63. value: 'Option1',
  64. label: '每一天',
  65. },
  66. {
  67. value: 'Option2',
  68. label: '仅在工作日',
  69. },
  70. {
  71. value: 'Option3',
  72. label: '仅在周末',
  73. },
  74. ];
  75. const isVisible = ref(true);
  76. const submitDialogVisible = ref(false);
  77. async function submit() {
  78. formRef.value.validate(async (valid: any) => {
  79. if (valid) {
  80. await submitFormData();
  81. console.log('formData', formData.value);
  82. emits('refresh');
  83. submitDialogVisible.value = true;
  84. } else {
  85. console.log('验证失败');
  86. }
  87. });
  88. }
  89. function cancel() {
  90. emits('refresh');
  91. }
  92. function handleSubmit() {
  93. if (formData.value.useTmpl) {
  94. submit();
  95. } else {
  96. submitDialogVisible.value = true;
  97. }
  98. }
  99. function handleClose() {
  100. isVisible.value = false;
  101. }
  102. // 验证bid输入值是否合法
  103. function validateBid(value: string) {
  104. if (value === '') {
  105. bidError.value = ''; // 空值时不显示错误信息
  106. } else if (Number(value) >= 100 || Number(value) <= 0) {
  107. bidError.value = '请输入数值大于0且小于100的数值,可精确到小数点后2位';
  108. } else {
  109. bidError.value = '';
  110. }
  111. }
  112. function handleBidChange(value: string) {
  113. validateBid(value);
  114. }
  115. const handleApply = () => {
  116. validateBid(bid.value);
  117. if (!bidError.value && tableRef.value) {
  118. tableRef.value.applyBid(timeRange.value, schedule.value, parseFloat(bid.value));
  119. }
  120. };
  121. </script>
  122. <template>
  123. <div class="mx-5">
  124. <div class="asj-h2">分时调价</div>
  125. <div class="mt-3.5">
  126. 规则执行时区: PDT
  127. <div>
  128. <el-tag v-if="isVisible" class="custom-tag" closable color="#e7edf4" @close="handleClose">
  129. <template #default>
  130. <div class="tag-content">
  131. <strong>自动化分时规则:</strong>
  132. <p>
  133. 1.
  134. 应用分时调价后,如需手动修改竞价,只能在此操作。在亚马逊后台或其他第三方系统进行的调价操作,竞价将会被当前时段的自动化执行结果覆盖。
  135. </p>
  136. <p>2. 广告活动开启分时调价,规则的修改将在下一个整点生效。</p>
  137. </div>
  138. </template>
  139. </el-tag>
  140. </div>
  141. </div>
  142. <SelectTmpl :data="formData" />
  143. <el-card class="mt-3">
  144. <el-form ref="formRef" :model="formData" label-position="top" style="margin-top: 20px">
  145. <el-form-item prop="rule.conditions">
  146. <template #label>
  147. <span class="custom-title-icon"></span>
  148. <span class="asj-h3">设置竞价</span>
  149. </template>
  150. <div class="flex flex-col">
  151. <div class="flex gap-2 my-2">
  152. <el-select v-model="timeRange" :disabled="formData.useTmpl">
  153. <el-option v-for="item in timeRangeOptions" :key="item.value" :label="item.label" :value="item.value" />
  154. </el-select>
  155. <el-select v-model="schedule" :disabled="formData.useTmpl">
  156. <el-option v-for="item in scheduleOptions" :key="item.value" :label="item.label" :value="item.value" />
  157. </el-select>
  158. <el-input v-model="bid" :disabled="formData.useTmpl"
  159. clearable
  160. oninput="value=value.replace(/[^\d.]/g, '').replace(/\.{2,}/g, '.').replace('.', '$#$').replace(/\./g, '').replace('$#$', '.').replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3').replace(/^\./g, '')"
  161. placeholder="1.0"
  162. style="width: 150px"
  163. @change="handleBidChange"
  164. ></el-input>
  165. <div v-if="bidError" style="font-size: 12px;">{{ bidError }}</div>
  166. <el-button :disabled="formData.useTmpl" class="active-btn" link style="color: #3c58af"
  167. @click="handleApply">应用
  168. </el-button>
  169. </div>
  170. </div>
  171. </el-form-item>
  172. </el-form>
  173. <TimerBidTable
  174. ref="tableRef"
  175. :data="formData.rule.conditions"
  176. :disabled="formData.useTmpl"
  177. @click="formRef.clearValidate('rule.conditions')" />
  178. </el-card>
  179. <SaveRuleDialog
  180. v-model="submitDialogVisible"
  181. :formData="formData"
  182. :formRef="formRef"
  183. @submit="submit"
  184. />
  185. <div class="auto-page-foot">
  186. <el-button style="width: 200px" @click="cancel">取消</el-button>
  187. <el-button style="width: 200px" type="primary" @click="handleSubmit">提交</el-button>
  188. </div>
  189. </div>
  190. </template>
  191. <style scoped>
  192. .active-btn:hover {
  193. color: #7a9ce4 !important; /* 如果需要改变字体颜色 */
  194. transition: all 0.3s; /* 添加过渡效果 */
  195. }
  196. .active-btn:disabled {
  197. color: #c0c4cc !important;
  198. cursor: not-allowed;
  199. /* pointer-events: none; !* 禁用点击事件 *! */
  200. }
  201. .custom-title-icon {
  202. padding-right: 10px;
  203. }
  204. .custom-title-icon:before {
  205. content: '';
  206. width: 4px;
  207. height: 15px;
  208. background: #3569d6;
  209. position: absolute;
  210. transform: translateY(25%);
  211. }
  212. .custom-tag {
  213. height: auto;
  214. padding: 8px 8px 8px 16px;
  215. color: #505968;
  216. border-color: #abbbd8;
  217. align-items: flex-start !important;
  218. white-space: normal;
  219. line-height: 1.5;
  220. }
  221. .tag-content {
  222. display: block;
  223. max-width: 100%;
  224. }
  225. </style>