timer-bid.vue 7.5 KB

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