index.vue 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <div>
  3. <div :class="titleClass">
  4. <span class="custom-title-icon"></span>
  5. 条件
  6. </div>
  7. <ConditionGroup
  8. ref="condiGroupRef"
  9. :disabled="disabled"
  10. v-for="(info, index) of condiGroups"
  11. :candidate-fields="candidateFields"
  12. :data="info"
  13. :key="info.key"
  14. :showDelGroupBtn="condiGroups.length > 1 && !disabled"
  15. @delete-group="delGroup(info.key)" />
  16. </div>
  17. <el-button type="success" @click="addConditionGroup" style="margin: 5px auto; display: block" :disabled="disabled">添加条件组</el-button>
  18. </template>
  19. <script lang="ts" setup>
  20. import { ref, watch } from 'vue'
  21. import ConditionGroup from './condition-group2.vue'
  22. import { useSymbolOptions } from '/@/components/conditionBuilder/utils'
  23. import XEUtils from 'xe-utils'
  24. interface Props {
  25. candidateFields: CandidateField[]
  26. data: ConditionGroupItem[]
  27. disabled: boolean
  28. titleClass: string
  29. }
  30. const props = withDefaults(defineProps<Props>(), {
  31. disabled: false,
  32. titleClass: 'asj-h3',
  33. candidateFields: () => {
  34. return [
  35. { label: '曝光量', value: 'impressions' },
  36. { label: '点击量', value: 'clicks' },
  37. { label: '花费', value: 'spend', prefix: '$' },
  38. { label: '点击率', value: 'ctr', suffix: '%' },
  39. { label: '单次点击费用', value: 'cpc', prefix: '$' },
  40. { label: '转化率', value: 'cr', suffix: '%' },
  41. { label: '广告订单数', value: 'order' },
  42. { label: '广告销售额', value: 'sale', prefix: '$' },
  43. { label: 'ACOS', value: 'acos', suffix: '%' }
  44. ]
  45. },
  46. })
  47. const condiGroups = ref(props.data)
  48. const condiGroupRef = ref()
  49. const { getSymbolOptions } = useSymbolOptions(props.candidateFields)
  50. const buildConditionGroup = () => {
  51. const field = props.candidateFields[0].value
  52. const symbol = getSymbolOptions(field)[0].value
  53. return {
  54. key: Math.random().toString(36).substring(2),
  55. day: 1,
  56. exceptDay: 0,
  57. items: [
  58. {
  59. dataType: field,
  60. dayType: symbol === 'in' || symbol === 'not_in' ? '' : 'sum',
  61. symbol: symbol,
  62. num: '',
  63. ranges: [],
  64. values: [],
  65. },
  66. ],
  67. }
  68. }
  69. const addConditionGroup = () => {
  70. condiGroups.value.push(buildConditionGroup())
  71. }
  72. if (condiGroups.value.length === 0) {
  73. addConditionGroup()
  74. }
  75. const delGroup = (key: string) => {
  76. XEUtils.remove(condiGroups.value, (item) => item.key === key)
  77. }
  78. const validate = async () => {
  79. const ret = []
  80. if (!condiGroupRef.value) return ret
  81. for (const info of condiGroupRef.value) {
  82. ret.push(await info.validate())
  83. }
  84. // console.log(52, ret)
  85. return ret
  86. }
  87. watch(
  88. () => props.data,
  89. () => {
  90. condiGroups.value = props.data
  91. },
  92. { deep: true }
  93. )
  94. defineExpose({ validate, addConditionGroup })
  95. </script>
  96. <style scoped>
  97. .custom-title-icon {
  98. padding-right: 10px;
  99. }
  100. .custom-title-icon:before {
  101. content: '';
  102. width: 4px;
  103. height: 15px;
  104. background: #3569d6;
  105. position: absolute;
  106. transform: translateY(25%);
  107. }
  108. </style>