choice-coupon.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import ColResult from '@/components/col-result'
  2. import { useEventTracking } from '@/helpers/hooks'
  3. import request from '@/helpers/request'
  4. import { state } from '@/state'
  5. import Item from '@/views/coupons/item'
  6. import { Button, Loading } from 'vant'
  7. import { defineComponent, PropType } from 'vue'
  8. import styles from './index.module.less'
  9. export default defineComponent({
  10. name: 'choice-coupon',
  11. props: {
  12. orderAmount: {
  13. type: Number,
  14. default: 0
  15. },
  16. orderGoodsType: {
  17. type: Array,
  18. default: () => []
  19. },
  20. useCoupon: {
  21. type: Array,
  22. default: () => []
  23. },
  24. couponCategory: {
  25. type: String,
  26. default: 'UNIVERSAL'
  27. },
  28. couponList: {
  29. type: Array,
  30. default: () => []
  31. },
  32. usedLength: {
  33. type: String as PropType<'SINGLE' | 'MULTIPLE'>,
  34. default: 'MULTIPLE'
  35. }
  36. },
  37. emits: ['close', 'submit'],
  38. data() {
  39. return {
  40. list: [] as any,
  41. // consumeAmount: 0 // 消耗金额
  42. dataLoading: false
  43. }
  44. },
  45. computed: {
  46. // 使用优惠券的数量
  47. useLength() {
  48. return this.list.filter((list: any) => list.checked).length || 0
  49. }
  50. },
  51. async mounted() {
  52. // this.getList()
  53. // 处理显示已选择的优惠券
  54. // 处理可用优惠券是否支付使用
  55. this.couponList.forEach((item: any) => {
  56. this.useCoupon.forEach((coupon: any) => {
  57. if (item.couponIssueId === coupon.couponIssueId) {
  58. item.checked = true
  59. }
  60. })
  61. })
  62. const canUsable = this.couponList.filter((list: any) => !list.disabled)
  63. const canUsed = this.couponList.filter((list: any) => list.disabled)
  64. this.list = [...canUsable, ...canUsed]
  65. this.calcCoupon()
  66. useEventTracking('优惠券')
  67. },
  68. methods: {
  69. onSubmit() {
  70. // 返回选中的优惠券
  71. this.$emit(
  72. 'submit',
  73. this.list.filter((list: any) => list.checked)
  74. )
  75. this.list.forEach((item: any) => {
  76. item.checked = false
  77. })
  78. },
  79. onSelect(item: any) {
  80. item.checked = !item.checked
  81. this.calcCoupon()
  82. },
  83. calcCoupon() {
  84. // 已使用的优惠券
  85. const useList = this.list.filter((list: any) => list.checked)
  86. if(this.usedLength === 'SINGLE') {
  87. let usedMap: any = new Map()
  88. useList.forEach((item: any) => {
  89. const price = usedMap.get(item.couponCategory)
  90. usedMap.set(item.couponCategory, (price || 0) + item.useLimit)
  91. })
  92. // 判断使用优惠券之后还有没有其它优惠券可用
  93. this.list.forEach((item: any) => {
  94. let disabled = true
  95. if(item.couponCategory === 'UNIVERSAL') {
  96. this.orderGoodsType.forEach((goods: any) => {
  97. const useLastAmount = goods ? goods.price - (usedMap.get(item.couponCategory) || 0) : 0
  98. if(Number(item.useLimit) <= useLastAmount && disabled) {
  99. disabled = false
  100. }
  101. })
  102. } else {
  103. const disItem: any = this.orderGoodsType.find((goods: any) => goods.orderType === item.couponCategory)
  104. const useLastAmount = disItem ? disItem.price - (usedMap.get(item.couponCategory) || 0) : 0
  105. disabled = Number(item.useLimit) > useLastAmount
  106. }
  107. if (!item.checked && (useList.length > 0 || disabled)) {
  108. item.disabled = true
  109. } else {
  110. item.disabled = false
  111. }
  112. })
  113. usedMap = null
  114. } else {
  115. // 计算优惠券
  116. const limitCount = useList.map((list: any) => {
  117. return Number(list.useLimit || 0)
  118. })
  119. const usePrice =
  120. limitCount.length > 0
  121. ? limitCount.reduce((sum: any, list: any) => {
  122. return sum + list
  123. })
  124. : 0
  125. // 使用优惠券后,可判断的金额
  126. const useLastAmount = this.orderAmount - usePrice
  127. // 判断使用优惠券之后还有没有其它优惠券可用
  128. this.list.forEach((item: any) => {
  129. if (Number(item.useLimit) > useLastAmount && !item.checked) {
  130. item.disabled = true
  131. } else {
  132. item.disabled = false
  133. }
  134. })
  135. }
  136. }
  137. },
  138. render() {
  139. return (
  140. <div class={styles.choiceCoupon}>
  141. <div class={styles.couponTitle}>
  142. <span>优惠券</span>
  143. <i class={styles.iconClose} onClick={() => this.$emit('close')}></i>
  144. </div>
  145. <div class={styles.couponContent}>
  146. {!this.dataLoading ? (
  147. <>
  148. {this.list.length > 0 ? (
  149. <>
  150. {this.list.map((item: any) => (
  151. <Item item={item} isSelect onClick={this.onSelect} />
  152. ))}
  153. </>
  154. ) : (
  155. <ColResult
  156. btnStatus={false}
  157. tips="暂无优惠券"
  158. classImgSize="SMALL"
  159. />
  160. )}
  161. </>
  162. ) : (
  163. <Loading
  164. size={48}
  165. color="#2dc7aa"
  166. vertical
  167. style={{ height: '100%', justifyContent: 'center' }}
  168. >
  169. 加载中...
  170. </Loading>
  171. )}
  172. </div>
  173. <div class={[styles.couponFooter, 'van-hairline--top']}>
  174. <div class={styles.couponSelectText}>
  175. 已选<span>{this.useLength}</span>张
  176. </div>
  177. <Button
  178. type="primary"
  179. round
  180. class={state.projectType === 'tenant' && styles.btnTenant}
  181. style={{ minWidth: '105px', fontSize: '16px' }}
  182. onClick={this.onSubmit}
  183. >
  184. 确定
  185. </Button>
  186. </div>
  187. </div>
  188. )
  189. }
  190. })