RewardRuleCouponSelect.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <template>
  2. <el-button class="ml-10px" type="text" @click="selectCoupon">添加优惠卷</el-button>
  3. <div
  4. v-for="(item, index) in list"
  5. :key="item.id"
  6. class="coupon-list-item p-x-10px mb-10px flex justify-between"
  7. >
  8. <div class="coupon-list-item-left flex items-center flex-wrap">
  9. <div class="mr-10px"> 优惠券名称:{{ item.name }}</div>
  10. <div class="mr-10px">
  11. 范围:
  12. <dict-tag :type="DICT_TYPE.PROMOTION_PRODUCT_SCOPE" :value="item.productScope" />
  13. </div>
  14. <div class="flex items-center">
  15. 优惠:
  16. <dict-tag :type="DICT_TYPE.PROMOTION_DISCOUNT_TYPE" :value="item.discountType" />
  17. {{ discountFormat(item) }}
  18. </div>
  19. </div>
  20. <div class="coupon-list-item-right">
  21. <el-input v-model="item.giveCount" class="w-150px! p-x-20px!" placeholder="" type="number" />
  22. <el-button class="ml-20px" link type="danger" @click="deleteCoupon(index)">删除</el-button>
  23. </div>
  24. </div>
  25. <!-- 优惠券选择 -->
  26. <CouponSelect ref="couponSelectRef" @change="handleCouponChange" />
  27. </template>
  28. <script lang="ts" setup>
  29. import { CouponSelect } from '@/views/mall/promotion/coupon/components'
  30. import * as CouponTemplateApi from '@/api/mall/promotion/coupon/couponTemplate'
  31. import { RewardRule } from '@/api/mall/promotion/reward/rewardActivity'
  32. import { DICT_TYPE } from '@/utils/dict'
  33. import { discountFormat } from '@/views/mall/promotion/coupon/formatter'
  34. import { isEmpty } from '@/utils/is'
  35. import { useVModel } from '@vueuse/core'
  36. import { findIndex } from '@/utils'
  37. defineOptions({ name: 'RewardRuleCouponSelect' })
  38. const props = defineProps<{
  39. modelValue: RewardRule
  40. }>()
  41. const emits = defineEmits<{
  42. (e: 'update:modelValue', v: any): void
  43. }>()
  44. const rewardRule = useVModel(props, 'modelValue', emits) // 赠送规则
  45. const list = ref<GiveCouponVO[]>([]) // 选择的优惠券列表
  46. /** 选择赠送的优惠卷类型拓展 */
  47. interface GiveCouponVO extends CouponTemplateApi.CouponTemplateVO {
  48. giveCount?: number
  49. }
  50. /** 选择优惠券 */
  51. const couponSelectRef = ref<InstanceType<typeof CouponSelect>>() // 优惠券选择
  52. const selectCoupon = () => {
  53. couponSelectRef.value?.open()
  54. }
  55. /** 选择优惠券后的回调 */
  56. const handleCouponChange = (val: CouponTemplateApi.CouponTemplateVO[]) => {
  57. for (const item of val) {
  58. if (list.value.some((v) => v.id === item.id)) {
  59. continue
  60. }
  61. list.value.push(item)
  62. }
  63. }
  64. /** 删除优惠券 */
  65. const deleteCoupon = (index: number) => {
  66. list.value.splice(index, 1)
  67. }
  68. /** 初始化赠送的优惠券列表 */
  69. const initGiveCouponList = async () => {
  70. // 朝赵优惠劵
  71. if (isEmpty(rewardRule.value) || isEmpty(rewardRule.value.couponIds)) {
  72. return
  73. }
  74. const data = await CouponTemplateApi.getCouponTemplateList(rewardRule.value.couponIds!)
  75. if (!data) {
  76. return
  77. }
  78. data.forEach((coupon) => {
  79. const index = findIndex(rewardRule.value.couponIds!, (couponId) => couponId === coupon.id)
  80. list.value.push({
  81. ...coupon,
  82. giveCount: rewardRule.value.couponCounts![index]
  83. })
  84. })
  85. }
  86. /** 设置赠送的优惠券 */
  87. const setGiveCouponList = () => {
  88. if (isEmpty(rewardRule.value) || isEmpty(list.value)) {
  89. return
  90. }
  91. rewardRule.value.couponIds = list.value.map((rule) => rule.id)
  92. rewardRule.value.couponCounts = list.value.map((rule) => rule.giveCount || 0)
  93. }
  94. defineExpose({ setGiveCouponList })
  95. /** 组件初始化 */
  96. onMounted(async () => {
  97. await nextTick()
  98. await initGiveCouponList()
  99. })
  100. </script>
  101. <style lang="scss" scoped>
  102. .coupon-list-item {
  103. border: 1px dashed var(--el-border-color-darker);
  104. border-radius: 8px;
  105. }
  106. </style>