index.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <route lang="json5">
  2. {
  3. style: {
  4. navigationBarTitleText: '购物车',
  5. navigationBarBackgroundColor: '#fff',
  6. },
  7. }
  8. </route>
  9. <script setup lang="ts">
  10. import TiltedButton from '@/components/tilted-button.vue'
  11. import Product from '../components/product.vue'
  12. import { shoppingBag } from '@designer-hub/assets/src/assets/svgs/index'
  13. import InvertedTrapezoidButton from '@/components/inverted-trapezoid-button.vue'
  14. import TrapeziumButton from '@/components/trapezium-button.vue'
  15. import {
  16. deleteProductItemBuy,
  17. getProductItemBuy,
  18. productPlacing,
  19. } from '../../../../core/libs/requests'
  20. import PageHelper from '@/components/page-helper.vue'
  21. import BottomAppBar from '@/components/bottom-app-bar.vue'
  22. import { useUserStore } from '../../../../store'
  23. import { useRouter } from '../../../../core/utils/router'
  24. import { storeToRefs } from 'pinia'
  25. import { requestToast } from '../../../../core/utils/common'
  26. import type { ComponentExposed } from 'vue-component-type-helpers'
  27. const pageHelperRef = ref<ComponentExposed<typeof PageHelper>>()
  28. const userStore = useUserStore()
  29. const router = useRouter()
  30. const { userInfo } = storeToRefs(userStore)
  31. const a = ref(1)
  32. const selected = ref([])
  33. const points = computed(() =>
  34. selected.value.reduce((acc, item) => acc + item.points * item.nums, 0),
  35. )
  36. const handleSelect = (product) => {
  37. if (selected.value.map((it) => it.productId).includes(product.productId)) {
  38. selected.value = selected.value.filter(({ productId }) => productId !== product.productId)
  39. } else {
  40. selected.value = [...selected.value, product]
  41. }
  42. }
  43. const handleDelete = async (product: any) => {
  44. await requestToast(
  45. () =>
  46. deleteProductItemBuy({
  47. doList: [
  48. {
  49. productId: product.productId,
  50. userId: userInfo.value.userId,
  51. id: product.id,
  52. deleted: true,
  53. },
  54. ],
  55. }),
  56. {
  57. successTitle: '删除成功',
  58. success: true,
  59. },
  60. )
  61. await pageHelperRef.value?.refresh()
  62. }
  63. const handlePlaceOrder = async () => {
  64. if (!selected.value.length) {
  65. uni.showToast({ title: '请选择商品', icon: 'none' })
  66. return ''
  67. }
  68. const { code, data: res } = await requestToast(() =>
  69. productPlacing({
  70. isShoppingCart: 1,
  71. userId: userInfo.value.userId,
  72. list: selected.value.map(({ productId, prodcutName, productCoverImgUrl, nums, points }) => ({
  73. productId,
  74. productName: prodcutName,
  75. orderImgUrl: productCoverImgUrl,
  76. nums,
  77. points,
  78. })),
  79. couponList: [],
  80. }),
  81. )
  82. if (code === 0) {
  83. // router.push(`/pages/home/mall/confirm-order`)
  84. await deleteProductItemBuy({
  85. doList: selected.value.map(({ productId }) => ({
  86. productId,
  87. deleted: true,
  88. userId: userInfo.value.userId,
  89. })),
  90. })
  91. router.push(`/pages/home/mall/confirm-order/index?data=${JSON.stringify(res)}`)
  92. }
  93. }
  94. </script>
  95. <template>
  96. <view class="flex-grow flex flex-col gap-14 bg-white px-3.5 py-6">
  97. <PageHelper
  98. ref="pageHelperRef"
  99. :request="getProductItemBuy"
  100. :query="{ userId: userInfo.userId }"
  101. class="flex-grow flex flex-col"
  102. >
  103. <template #default="{ source }">
  104. <div class="flex-grow flex flex-col gap-8">
  105. <!-- {{ selected }} -->
  106. <template v-for="(it, i) in source.list" :key="i">
  107. <wd-swipe-action>
  108. <div class="flex gap-3">
  109. <div class="flex items-center" @click="handleSelect(it)">
  110. <div
  111. class="w-4 h-4 rounded-full border border-black/60 border-solid"
  112. :class="`${selected.map((it) => it.productId).includes(it.productId) ? 'bg-black' : ''}`"
  113. ></div>
  114. </div>
  115. <div class="w-[110px] h-[110px] bg-[#f6f6f6] rounded-2xl">
  116. <wd-img width="100%" height="100%" :src="it.productCoverImgUrl"></wd-img>
  117. </div>
  118. <div class="flex flex-col justify-between flex-1">
  119. <div
  120. class="text-black/40 text-base font-normal font-['PingFang_SC'] leading-normal"
  121. >
  122. {{ it.prodcutName }}
  123. </div>
  124. <div class="flex items-center">
  125. <div
  126. class="text-[#ef4343] text-[22px] font-normal font-['D-DIN Exp'] leading-normal"
  127. >
  128. {{ it.points }}
  129. </div>
  130. <div
  131. class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-[34px]"
  132. >
  133. 积分
  134. </div>
  135. <div class="flex-1"></div>
  136. {{ it.nums }}
  137. <!-- <wd-input-number v-model="it.nums" /> -->
  138. </div>
  139. </div>
  140. </div>
  141. <template #right>
  142. <view class="h-full">
  143. <view
  144. class="inline-block h-full bg-[#ef4343] text-white flex items-center px-5"
  145. @click="handleDelete(it)"
  146. >
  147. 删除
  148. </view>
  149. </view>
  150. </template>
  151. </wd-swipe-action>
  152. </template>
  153. </div>
  154. </template>
  155. </PageHelper>
  156. <BottomAppBar fixed border>
  157. <div class="h-[63px] bg-white backdrop-blur-[20px] flex px-3.5 items-center justify-between">
  158. <div class="flex items-end gap-1.25">
  159. <div class="text-[#ef4343] text-2xl font-normal font-['D-DIN_Exp'] leading-6">
  160. {{ points }}
  161. </div>
  162. <div class="text-black text-base font-normal font-['PingFang_SC'] leading-5">积分</div>
  163. </div>
  164. <div class="" @click="handlePlaceOrder">
  165. <TiltedButton size="large">
  166. <div
  167. class="w-[49px] h-[22px] text-white text-base font-normal font-['PingFang_SC'] leading-tight"
  168. >
  169. <div
  170. class="w-[65px] h-[22px] text-white text-base font-normal font-['PingFang_SC'] leading-tight"
  171. >
  172. 去结算
  173. </div>
  174. </div>
  175. </TiltedButton>
  176. </div>
  177. </div>
  178. </BottomAppBar>
  179. </view>
  180. </template>
  181. <style scoped lang="scss"></style>