cartPopup.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <template>
  2. <u-popup :show="show" mode="bottom" @close="close" @open="open" :round="10">
  3. <view class="my-popup padding">
  4. <view class="container-sel">
  5. <radio :checked="allSelected" color="#E51C23" @click="selectAll">全选
  6. </radio>
  7. <view class="dflex">
  8. <u-tag text="清空购物车" type="info" color="#000" borderColor="#fff" size="mini" icon="trash" plain
  9. @click="clearCart"></u-tag>
  10. </view>
  11. </view>
  12. <radio class="w-full padding-bottom-lg" color="#E51C23" v-for="(item, index) in carList" :key="index"
  13. :name="item.name" :checked="item.selected" @click="radioChange(item)">
  14. <my-goods :item="item" ref="my-goods">
  15. <view class="num-step">
  16. <u-number-box v-model="item.quantity" :min="1" @change="changeValue($event, item)" />
  17. </view>
  18. </my-goods>
  19. </radio>
  20. </view>
  21. <view class="cart-bottom padding-sm dflex-b" v-if="showShop">
  22. <view class="cart padding-lr">
  23. <uni-badge size="small" :text="buyCount" absolute="rightTop">
  24. <u-icon name="shopping-cart-fill" size="28" color="#FF873D"></u-icon>
  25. </uni-badge>
  26. <text class="cart-total">总计:¥{{total}}</text>
  27. </view>
  28. <view class="balance dflex-c background-gradient" @click="toBuy">去结算</view>
  29. </view>
  30. </u-popup>
  31. </template>
  32. <script>
  33. export default {
  34. name: "cartPopup",
  35. data() {
  36. return {
  37. show: false,
  38. allSelected: false,
  39. carList: [],
  40. showShop: false,
  41. total: 0,
  42. totalList: []
  43. };
  44. },
  45. mounted() {
  46. this.fatchDate()
  47. },
  48. methods: {
  49. openShop(v) {
  50. this.showShop = v
  51. },
  52. open() {},
  53. async fatchDate() {
  54. const e = uni.getStorageSync('carl')
  55. const params = {
  56. storeId: e.id
  57. }
  58. const res = await this.$request('get', `/front/shoppingCart/list`, params)
  59. if (res) {
  60. this.carList = res.data
  61. }
  62. },
  63. setShow(v) {
  64. this.show = v
  65. this.fatchDate()
  66. // 检查 carList 是否存在且至少有一个元素
  67. if (this.carList && this.carList.length > 0) {
  68. // 检查 carList 的第一个元素是否有 selected 属性
  69. if (!this.carList[0].hasOwnProperty('selected')) {
  70. // 如果没有 selected 属性,使用 map 方法添加 selected 属性
  71. this.carList = this.carList.map(item => ({
  72. ...item,
  73. selected: false
  74. }));
  75. }
  76. } else {
  77. // 如果 carList 不存在或没有元素,直接使用 map 方法添加 selected 属性
  78. this.carList = this.carList.map(item => ({
  79. ...item,
  80. selected: false
  81. }))
  82. }
  83. if (this.carList.length > 0) {
  84. this.allSelected = this.carList.every(car => car.selected)
  85. }
  86. },
  87. close() {
  88. this.show = false;
  89. },
  90. changeValue(value, v) {
  91. const e = uni.getStorageSync('carl')
  92. const userId = uni.getStorageSync('appUserId')
  93. const params = {
  94. id: v.id,
  95. storeId: e.id,
  96. storeName: e.name,
  97. skuId: v.skuId,
  98. basePrice: v.basePrice,
  99. quantity: value.value,
  100. extendProps: userId
  101. }
  102. this.$request('put', `/front/shoppingCart`, params, true)
  103. },
  104. selectAll() {
  105. this.allSelected = !this.allSelected
  106. this.carList.forEach(item => {
  107. item.selected = this.allSelected
  108. })
  109. this.$emit('selected-changed', this.carList)
  110. this.totalList = this.carList
  111. this.totalPrice()
  112. },
  113. clearCart() {
  114. const ids = this.carList.map(car => car.id);
  115. this.$request('delete', `/front/shoppingCart/${ids}`).then(response => {
  116. // 请求成功
  117. if (response.code == 200) {
  118. // 弹出消息
  119. uni.showToast({
  120. title: '已清空',
  121. icon: 'success',
  122. duration: 2000
  123. })
  124. this.carList = []
  125. this.$emit('selected-changed', []);
  126. this.show = false
  127. }
  128. }).catch(error => {
  129. // 请求失败
  130. console.error('请求失败:', error);
  131. })
  132. },
  133. radioChange(e) {
  134. e.selected = !e.selected
  135. // 检查是否所有车都被选中了
  136. this.allSelected = this.carList.every(car => car.selected)
  137. this.localList = this.carList.filter(car => car.selected === true);
  138. this.$emit('selected-changed', this.localList);
  139. this.totalList = this.localList
  140. this.totalPrice()
  141. },
  142. //计算selected为true的
  143. totalPrice() {
  144. let total = 0;
  145. for (let i = 0; i < this.totalList.length; i++) {
  146. // 检查商品是否有 selected 属性
  147. if (this.totalList[i].hasOwnProperty('selected')) {
  148. // 如果 selected 属性存在,只有当它为 true 时才计算
  149. if (this.totalList[i].selected) {
  150. let priceInCents = Math.round(this.totalList[i].price * 100);
  151. let quant = this.totalList[i].quantity;
  152. total += priceInCents * quant;
  153. }
  154. } else {
  155. // 如果 selected 属性不存在,直接计算所有商品
  156. let priceInCents = Math.round(this.carList[i].price * 100);
  157. let quant = this.carList[i].quantity;
  158. total += priceInCents * quant;
  159. }
  160. }
  161. // 将总价格转换回浮点数(以元为单位)
  162. this.total = (total / 100).toFixed(2);
  163. },
  164. }
  165. }
  166. </script>
  167. <style scoped lang="scss">
  168. .my-popup {
  169. width: 100%;
  170. max-height: 800rpx;
  171. overflow: auto;
  172. padding-bottom: 130rpx;
  173. .num-step {
  174. width: 200rpx;
  175. padding-top: 40rpx;
  176. }
  177. .container-sel {
  178. display: flex;
  179. justify-content: space-between;
  180. align-items: center;
  181. margin: 10px 0;
  182. }
  183. }
  184. .cart-bottom {
  185. width: 100%;
  186. position: fixed;
  187. left: 0;
  188. bottom: 0;
  189. height: 130rpx;
  190. box-sizing: border-box;
  191. background-color: #FFF;
  192. box-shadow: 0px -4px 16px 0px rgba(0, 0, 0, 0.15);
  193. z-index: 10800;
  194. .cart {
  195. width: calc(100% - 220rpx);
  196. border-radius: 5px;
  197. background-color: #FEEEE4;
  198. display: flex;
  199. align-items: center;
  200. height: 100%;
  201. .cart-total {
  202. padding-left: 40rpx;
  203. font-size: 16px;
  204. font-weight: 700;
  205. }
  206. }
  207. .balance {
  208. width: 200rpx;
  209. height: 100%;
  210. background-color: #FF0000;
  211. font-size: $uni-font-size-lg;
  212. border-radius: 5px;
  213. color: #FFF;
  214. }
  215. }
  216. </style>