shoppingCart.vue 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <template>
  2. <view class="shopping-wrapper">
  3. <view class="goods-box">
  4. <view class="goods-list" v-if="num>0" >
  5. <view class=" display-flex-center mb20" v-for="(item, index) in list" :key="index">
  6. <u-checkbox-group @change="checkedDataChange" v-model="item.checkedData" size="20"
  7. >
  8. <u-checkbox :name="item.id" shape="circle" label=" " activeColor="#C29556"></u-checkbox>
  9. </u-checkbox-group>
  10. <image class="ml10 mr20" style="width: 176rpx; height: 176rpx; border-radius: 12rpx;flex-shrink: 0;"
  11. :src="item.goods_cover" mode="aspectFill">
  12. </image>
  13. <view class="list-info">
  14. <view class="fs14 fw400 color-333">{{item.goods_name}}</view>
  15. <view class="fw400 color-888 fs12 mt8 mb8">{{item.sku.goods_spec}}</view>
  16. <view class="display-flex-between">
  17. <text class="fw400 color-888 fs12 mb8">¥<text class="fw700 color-333 fs16 mb8">{{item.sku.price_selling}}</text></text>
  18. <u-number-box min="1" :name="item.id"
  19. :max=" item.goods_type == 'goods' ? item.sku.stock_total : 1" v-model="item.num"
  20. @change="numChange" button-size="24">
  21. <view
  22. slot="minus"
  23. class="minus"
  24. >
  25. <u-icon
  26. name="minus"
  27. size="12"
  28. ></u-icon>
  29. </view>
  30. <text
  31. slot="input"
  32. style="width: 48rpx;text-align: center;line-height: 48rpx;font-size: 24rpx"
  33. class="input"
  34. >{{item.num}}</text>
  35. <view
  36. slot="plus"
  37. class="plus"
  38. >
  39. <u-icon
  40. name="plus"
  41. size="12"
  42. ></u-icon>
  43. </view>
  44. </u-number-box>
  45. </view>
  46. </view>
  47. </view>
  48. <u-divider ></u-divider>
  49. <view style="width: 100%" class="display-flex-end">
  50. <view class="color-333 fs12 fw400">共{{ num }}件商品&nbsp;&nbsp;总计:<text class=" fs12 fw400">¥</text><text class="fw700 fs20">{{totalPrice2}}</text></view>
  51. </view>
  52. </view>
  53. </view>
  54. <view class="bottom-box display-flex-between">
  55. <view class="display-flex-center ">
  56. <u-checkbox-group @change="allCheckedChange" v-model="allChecked" size="20" >
  57. <u-checkbox activeColor="#C29556" name="all" shape="circle" label=" "></u-checkbox>
  58. </u-checkbox-group>
  59. <view class="color-333 mr5" @click="allCheckedClick">全选</view>
  60. <view class="color-333" @click="showDel=true">删除</view>
  61. </view>
  62. <view class="display-flex-content-center mb5 ">
  63. <view class="color-333 fs14 fw400 ">总计:<text class="color-556 fs12 fw400">¥</text><text class="fw700 fs20 color-556">{{totalPrice}}</text></view>
  64. <view class="common-btn" :class="[settleDisabled ? 'common-btn-disabled' : '']" @click="toSettle">结算
  65. </view>
  66. </view>
  67. </view>
  68. <tabbarCom :zIndex="100" current="3"></tabbarCom>
  69. <!-- 删除确认 -->
  70. <u-modal :show="showDel" showCancelButton @cancel="showDel= false" @close="showDel=false" @confirm="delData"
  71. :asyncClose="true" title="确认删除吗!" ></u-modal>
  72. </view>
  73. </template>
  74. <script>
  75. import tabbarCom from "@/components/tabbar/tabbar.vue"
  76. export default {
  77. components: {
  78. tabbarCom
  79. },
  80. data() {
  81. return {
  82. list: [],
  83. checkedFlag:false,
  84. allChecked: [],
  85. checkValue: [],
  86. radiovalue1: [],
  87. isGift: '0',
  88. num:0,
  89. showDel:false,
  90. options: [{
  91. text: '取消',
  92. style: {
  93. backgroundColor: '#007aff'
  94. }
  95. }, {
  96. text: '确认',
  97. style: {
  98. backgroundColor: '#dd524d'
  99. }
  100. }]
  101. }
  102. },
  103. computed: {
  104. totalPrice() {
  105. const checkedData = this.list.filter(item => item.checkedData.length != 0)
  106. let result = 0
  107. checkedData.forEach(item => {
  108. const num = item.num
  109. const price = item.sku.price_selling
  110. result = result + (num * price)
  111. })
  112. return result.toFixed(2)
  113. },
  114. totalPrice2() {
  115. let result = 0
  116. this.num =0;
  117. this.list.forEach(item => {
  118. let num = item.num
  119. const price = item.sku.price_selling
  120. result = result + (num * price)
  121. this.num = this.num+num
  122. })
  123. return result.toFixed(2)
  124. },
  125. settleDisabled() {
  126. const checkedData = this.list.filter(item => item.checkedData.length != 0)
  127. const giftData = this.list.find(item => item.checkedData.length != 0 && item.goods_type == 'gift')
  128. let result = checkedData.length == 0
  129. if (giftData) {
  130. this.isGift = '1'
  131. const {
  132. limit_money = 0, price_selling = 0
  133. } = giftData.sku
  134. result = this.totalPrice < (Number(limit_money) + Number(price_selling))
  135. } else {
  136. this.isGift = '0'
  137. }
  138. return result
  139. }
  140. },
  141. onLoad() {
  142. },
  143. onShow() {
  144. this.allChecked = []
  145. this.getData()
  146. },
  147. methods: {
  148. getData() {
  149. this.$api.getShoppingCartData().then(res => {
  150. this.list = res.data
  151. if (!this.list.length) {
  152. this.allChecked = []
  153. }
  154. this.list.forEach(item => {
  155. item.sourceNum = item.num
  156. if (!item.checkedData) {
  157. this.$set(item, 'checkedData', [])
  158. }
  159. })
  160. })
  161. },
  162. toSettle() {
  163. // 去结算
  164. if (this.settleDisabled) return
  165. let checkedData = this.list.filter(item => item.checkedData.length)
  166. let checkedIds = checkedData.map(item => item.id)
  167. uni.navigateTo({
  168. url: `/subPages/settleCenter/settleCenter?type=cart&ids=${checkedIds.join('_')}&isGift=${this.isGift}`
  169. })
  170. // this.$api.createPrevOrderByCart({ id: checkedIds }).then(res => {
  171. // // uni.setStorageSync('currentCartOrder', checkedData)
  172. // uni.navigateTo({
  173. // url: `/subPages/settleCenter/settleCenter?type=cart&ids=${checkedIds.join('_')}`
  174. // })
  175. // })
  176. },
  177. checkedDataChange() {
  178. this.$nextTick(() => {
  179. const notChecked = this.list.filter(item => item.checkedData.length === 0)
  180. if (notChecked.length === 0) {
  181. // 全选
  182. this.allChecked = ['all']
  183. } else {
  184. this.allChecked = []
  185. }
  186. })
  187. },
  188. allCheckedChange(value) {
  189. if (value.length) {
  190. this.list.forEach(item => {
  191. item.checkedData = [item.id]
  192. })
  193. this.checkedFlag=true
  194. } else {
  195. this.list.forEach(item => {
  196. item.checkedData = []
  197. })
  198. this.checkedFlag=false
  199. }
  200. },
  201. allCheckedClick() {
  202. if (!this.checkedFlag) {
  203. this.list.forEach(item => {
  204. item.checkedData = [item.id]
  205. })
  206. this.checkedFlag=true
  207. this.allChecked=['all']
  208. } else {
  209. this.list.forEach(item => {
  210. item.checkedData = []
  211. })
  212. this.allChecked=[]
  213. this.checkedFlag=false
  214. }
  215. },
  216. delData() {
  217. // 删除
  218. let checkedIds = this.list.filter(item => item.checkedData.length)
  219. checkedIds = checkedIds.map(item => item.id)
  220. if (checkedIds.length) {
  221. this.$api.deleteShoppingCart({
  222. id: checkedIds
  223. }).then(res => {
  224. this.showDel = false
  225. this.getData()
  226. uni.showToast({
  227. title: '删除成功'
  228. })
  229. })
  230. }else{
  231. this.showDel = false
  232. uni.showToast({
  233. icon: 'none',
  234. title: '请选择删除的商品!'
  235. })
  236. }
  237. },
  238. numChange(item) {
  239. const {
  240. name,
  241. value
  242. } = item
  243. const currentItem = this.list.find(cart => cart.id == name)
  244. const currentIndex = this.list.findIndex(cart => cart.id == name)
  245. const sourceNum = currentItem.sourceNum
  246. const params = {
  247. id: name,
  248. num: Math.abs(value - sourceNum)
  249. }
  250. let currentApi = null
  251. if (value > sourceNum) {
  252. // 购物车增加
  253. currentApi = this.$api.plusShoppingCart
  254. } else if (value < sourceNum) {
  255. // 购物车数量减少
  256. currentApi = this.$api.subShoppingCart
  257. }
  258. if (currentApi) {
  259. currentApi(params).then(res => {
  260. this.list[currentIndex].num = res.data.num
  261. this.list[currentIndex].sourceNum = res.data.num
  262. })
  263. }
  264. },
  265. }
  266. }
  267. </script>
  268. <style lang="scss" scoped>
  269. .shopping-wrapper {
  270. padding-bottom: 178rpx;
  271. .goods-box {
  272. margin-top: 20rpx;
  273. padding: 0 20rpx;
  274. .goods-list {
  275. padding: 45rpx 34rpx;
  276. background-color: #fff;
  277. margin-bottom: 20rpx;
  278. border-radius: 24rpx;
  279. .list-info {
  280. width: 100%;
  281. }
  282. }
  283. }
  284. .bottom-box {
  285. background-color: #fff;
  286. height: calc(169rpx - env(safe-area-inset-bottom));
  287. position: fixed;
  288. bottom: calc(env(safe-area-inset-bottom) + 120rpx);
  289. left: 0;
  290. right: 0;
  291. z-index: 9999;
  292. padding: 10rpx 35rpx;
  293. .common-btn {
  294. flex-shrink: 0;
  295. height: 60rpx;
  296. line-height: 60rpx;
  297. width: 150rpx;
  298. margin-left: 30rpx;
  299. background-color:#C29556;
  300. border-color: #C29556;
  301. }
  302. .common-btn-disabled {
  303. background: #EEEFF1;
  304. color: #1D161F;
  305. border-color: #EEEFF1;
  306. }
  307. }
  308. }
  309. .minus {
  310. width: 48rpx;
  311. height: 48rpx;
  312. background: #FFFFFF;
  313. margin-top: 16rpx;
  314. border-radius: 8rpx 0rpx 0rpx 8rpx;
  315. border: 1rpx solid #CCCCCC;
  316. @include flex;
  317. justify-content: center;
  318. align-items: center;
  319. }
  320. .input {
  321. height: 48rpx;
  322. width: 48rpx;
  323. background: #FFFFFF;
  324. border-radius: 0rpx 0rpx 0rpx 0rpx;
  325. border: 1rpx solid #CCCCCC;
  326. margin-top: 16rpx;
  327. }
  328. .plus {
  329. width: 48rpx;
  330. height: 48rpx;
  331. background-color: #FFFFFF;
  332. border-radius: 0rpx 8rpx 8rpx 0rpx;
  333. border: 1rpx solid #CCCCCC;
  334. display: flex;
  335. justify-content: center;
  336. align-items: center;
  337. margin-top: 16rpx;
  338. }
  339. </style>