index.tsx 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import request from '@/helpers/request'
  2. import { state } from '@/state'
  3. import { Cell, Popup } from 'vant'
  4. import { defineComponent, PropType } from 'vue'
  5. import ChoiceCoupon from './choice-coupon'
  6. import styles from './index.module.less'
  7. /*
  8. * 订单类型对应优惠券类型
  9. */
  10. export const couponEnum = {
  11. UNIVERSAL: 'UNIVERSAL',
  12. VIP: 'VIP',
  13. SVIP: 'SVIP',
  14. PIANO_ROOM: 'PIANO',
  15. GOODS: 'MALL',
  16. MUSIC: 'MUSIC',
  17. VIP_COURSE: 'VIP_COURSE',
  18. DISCOUNT: 'DISCOUNT',
  19. PRACTICE: 'SPARRING',
  20. LIVE: 'LIVE',
  21. VIDEO: 'VIDEO',
  22. ALBUM: 'ALBUM'
  23. }
  24. export default defineComponent({
  25. name: 'use-conpon',
  26. props: {
  27. disabled: {
  28. type: Boolean,
  29. default: false
  30. },
  31. orderAmount: {
  32. type: Number,
  33. default: 0
  34. },
  35. orderType: {
  36. type: String,
  37. default: ''
  38. },
  39. orderGoodsType: {
  40. type: Array,
  41. default: () => []
  42. },
  43. discountPrice: {
  44. // 优惠券使用金额
  45. type: Number,
  46. default: 0
  47. },
  48. // 选择的优惠券
  49. couponId: {
  50. type: String,
  51. default: ''
  52. },
  53. usedLength: {
  54. type: String as PropType<'SINGLE' | 'MULTIPLE'>,
  55. default: 'SINGLE'
  56. }
  57. },
  58. emits: ['couponSelect'],
  59. data() {
  60. return {
  61. popupStatus: false,
  62. popupLoading: false,
  63. useCouponList: [] as any,
  64. useCouponLoading: false,
  65. useCouponCount: 0,
  66. dataLoading: false,
  67. list: [] as any
  68. }
  69. },
  70. computed: {
  71. couponCount() {
  72. const limitCount = this.useCouponList.map((list: any) => {
  73. return Number(list.discountPrice || 0)
  74. })
  75. let count = 0
  76. if (this.disabled) {
  77. count = this.discountPrice
  78. } else {
  79. count =
  80. limitCount.length > 0
  81. ? limitCount.reduce((sum: any, list: any) => {
  82. return sum + list
  83. })
  84. : 0
  85. }
  86. return count
  87. },
  88. couponCategory() {
  89. // 如果订单类型不在优惠券类型里面,则默认查询通用券
  90. const temp: any[] = []
  91. this.orderGoodsType.forEach((item: any) => {
  92. if(couponEnum[item.orderType]) {
  93. temp.push(couponEnum[item.orderType])
  94. }
  95. })
  96. return temp.join(',') + (temp.length ? ',UNIVERSAL' : 'UNIVERSAL')
  97. }
  98. },
  99. watch: {
  100. couponId(val: any) {
  101. // 为
  102. const ids = val ? val.split(',').map(i => Number(i)) : []
  103. const selectCouponList: any[] = []
  104. this.useCouponList.forEach((item: any) => {
  105. if(ids.includes(item.couponIssueId)) {
  106. selectCouponList.push(item)
  107. }
  108. });
  109. this.useCouponList = selectCouponList
  110. }
  111. },
  112. mounted() {
  113. this.getList()
  114. },
  115. methods: {
  116. resetCouponList() {
  117. this.list = []
  118. this.getList()
  119. },
  120. async getList() {
  121. if (this.dataLoading) return
  122. this.dataLoading = true
  123. try {
  124. const res = await request.post(`${state.platformApi}/couponInfo/page`, {
  125. data: {
  126. couponCategory: this.couponCategory,
  127. couponType: 'FULL_DISCOUNT',
  128. useState: 'USABLE',
  129. orderUse: 1,
  130. page: 1,
  131. rows: 100
  132. }
  133. })
  134. this.dataLoading = false
  135. const result = res.data || {}
  136. // 处理重复请求数据
  137. if (this.list.length > 0 && result.pageNo === 1) return
  138. this.list = result.rows || []
  139. // 处理可用优惠券是否支付使用
  140. this.list.forEach((item: any) => {
  141. item.checked = false
  142. if(item.couponCategory === 'UNIVERSAL') {
  143. let disabled = true;
  144. this.orderGoodsType.forEach((goods: any) => {
  145. if(item.useLimit <= goods.price && disabled) {
  146. disabled = false
  147. }
  148. })
  149. item.disabled = disabled
  150. } else {
  151. const disItem: any = this.orderGoodsType.find((goods: any) => couponEnum[goods.orderType] === item.couponCategory)
  152. const useLastAmount = disItem.price || 0
  153. // 如果使用金额大于订单金额则优惠券不可用
  154. if (item.useLimit > useLastAmount) {
  155. item.disabled = true
  156. } else {
  157. item.disabled = false
  158. }
  159. }
  160. })
  161. let count = 0
  162. this.list.forEach((item: any) => {
  163. if (!item.disabled) {
  164. count++
  165. }
  166. })
  167. // console.log(this.list, 'list')
  168. this.useCouponCount = count
  169. } catch {
  170. //
  171. }
  172. },
  173. // async getUseableCoupon() {
  174. // try {
  175. // this.useCouponLoading = true
  176. // // 判断是哪个端
  177. // const url =
  178. // state.platformType === 'STUDENT' ? '/api-student' : '/api-teacher'
  179. // const res = await request.get(`${url}/couponInfo/statInfo`)
  180. // this.useCouponLoading = false
  181. // const result = (res.data || []).find(
  182. // result => result.useState === 'USABLE'
  183. // )
  184. // this.useCouponCount = result.total || 0
  185. // } catch {
  186. // // TODO: handle
  187. // }
  188. // },
  189. onSubmit(item: any) {
  190. // useCouponList
  191. this.useCouponList = item
  192. this.$emit('couponSelect', item)
  193. this.popupStatus = false
  194. this.popupLoading = false
  195. }
  196. },
  197. render() {
  198. return (
  199. <>
  200. <Cell
  201. title="优惠券"
  202. class={styles.useCoupon}
  203. isLink={!this.disabled}
  204. clickable={false}
  205. v-slots={{
  206. value: () =>
  207. !this.useCouponLoading && (
  208. <>
  209. {/* 判断是否有选择优惠券 */}
  210. {this.couponCount > 0 ? (
  211. <span class={styles.couponCount}>
  212. <i>-¥</i>
  213. {this.couponCount}
  214. </span>
  215. ) : (
  216. <>
  217. {/* 判断是否有可以的优惠券 */}
  218. {this.useCouponCount > 0
  219. ? `${this.useCouponCount}张可使用`
  220. : '暂无可使用优惠券'}
  221. </>
  222. )}
  223. </>
  224. )
  225. }}
  226. onClick={() => {
  227. if (this.disabled) return
  228. this.popupStatus = true
  229. this.popupLoading = true
  230. }}
  231. ></Cell>
  232. <Popup
  233. v-model:show={this.popupStatus}
  234. position="bottom"
  235. round
  236. safeAreaInsetBottom={true}
  237. style={{ height: '75%' }}
  238. onClosed={() => {
  239. this.popupLoading = false
  240. }}
  241. >
  242. {/* 优化体验 */}
  243. {this.popupLoading && (
  244. <ChoiceCoupon
  245. usedLength={this.usedLength}
  246. couponCategory={this.couponCategory}
  247. useCoupon={this.useCouponList}
  248. orderAmount={this.orderAmount}
  249. orderGoodsType={this.orderGoodsType}
  250. couponList={this.list}
  251. onClose={() => (this.popupStatus = false)}
  252. onSubmit={(item: any) => this.onSubmit(item)}
  253. />
  254. )}
  255. </Popup>
  256. </>
  257. )
  258. }
  259. })