shopping-cart.vue 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  1. <template>
  2. <view class="shopping-cart">
  3. <view class="header">
  4. <view class="title">
  5. 我的购物车
  6. </view>
  7. <view style="position: relative;">
  8. <view class="sub-title">购物车订单</view>
  9. </view>
  10. </view>
  11. <view v-if="cart.length===0" style="margin: 20upx auto;text-align: center; font-size: 28upx;color: #999999;">
  12. 暂未添加任何商品
  13. </view>
  14. <view class="shopping-cart-item" v-for="seller in cart">
  15. <view class="shopping-cart-item-head">
  16. <view class="select">
  17. <checkbox class="checkbox" :checked="seller.checked" @tap="selectSeller(seller.seller_id)" />
  18. </view>
  19. <view class="factory-name">{{seller.seller_nickname?seller.seller_nickname:'省心直供(该厂家暂未设置昵称)'}}</view>
  20. </view>
  21. <view class="shopping-cart-info">
  22. <view class="product-item" v-for="product in seller.products"
  23. @longpress="longpress(product.id,product.spec_index)">
  24. <view class="select">
  25. <checkbox class="checkbox" :checked="product.checked"
  26. @tap="select(product.id,product.spec_index)" />
  27. </view>
  28. <view class="product-image">
  29. <image class="image" :src="product.spec_image|imagesFilter" mode="scaleToFill"></image>
  30. </view>
  31. <view class="product-info">
  32. <view class="row row-1">
  33. <text class="title"><text class="sxzg-icon">省心直供</text>{{product.name}}</text>
  34. </view>
  35. <view class="row">
  36. <view class="spec">{{product.spec_name}}</view>
  37. </view>
  38. <view class="row row-2">
  39. <text class="org-price">¥{{product.spec_org_price}}</text>
  40. </view>
  41. <view class="row">
  42. <text class="sxj-icon">省心价</text>
  43. <text class="price">¥{{product.spec_price}}</text>
  44. </view>
  45. </view>
  46. <view class="counter">
  47. <view class="sub" @tap="subnum(product.id,product.num,product.spec_index)">-</view>
  48. <input class="num" type="text" v-model="product.num" />
  49. <view class="plus" @tap="plusnum(product.id,product.num,product.spec_index)">+</view>
  50. </view>
  51. </view>
  52. </view>
  53. </view>
  54. <view class="footer">
  55. <view class="select-all">
  56. <label @tap="selectAll()">
  57. <checkbox color="#ff5d5b" class="checkbox" :checked="checkall" />全选
  58. </label>
  59. </view>
  60. <view class="total">合计 <text>¥{{total}}</text></view>
  61. <view class="settlement"><button class="settlement-btn" type="default" @tap="buy">结算</button></view>
  62. </view>
  63. </view>
  64. </template>
  65. <script>
  66. import {
  67. mapState
  68. } from 'vuex'
  69. export default {
  70. data() {
  71. return {
  72. checkall: false
  73. }
  74. },
  75. computed: mapState({
  76. cart: state => state.cart,
  77. total() {
  78. return this.$store.getters['cart/total']
  79. }
  80. }),
  81. onLoad() {
  82. // uni.removeStorageSync("cart")
  83. },
  84. methods: {
  85. selectSeller(seller_id) {
  86. this.$store.commit("cart/selectSeller", {
  87. seller_id: seller_id
  88. })
  89. },
  90. select(id, spec_index) {
  91. this.$store.commit("cart/select", {
  92. id: id,
  93. spec_index: spec_index
  94. })
  95. },
  96. selectAll() {
  97. this.checkall = !this.checkall;
  98. this.$store.commit("cart/selectAll", {
  99. checked: this.checkall
  100. })
  101. },
  102. subnum(id, num, spec_index) {
  103. if (num === 1) {
  104. uni.showModal({
  105. title: "移除商品",
  106. content: "确认移除该商品?",
  107. success: (res) => {
  108. if (res.confirm) {
  109. this.$store.commit("cart/remove", {
  110. id: id,
  111. num: num,
  112. spec_index: spec_index
  113. })
  114. }
  115. }
  116. })
  117. } else {
  118. num--
  119. }
  120. this.$store.commit("cart/numchange", {
  121. id: id,
  122. num: num,
  123. spec_index: spec_index
  124. })
  125. },
  126. plusnum(id, num, spec_index) {
  127. num++
  128. this.$store.commit("cart/numchange", {
  129. id: id,
  130. num: num,
  131. spec_index: spec_index
  132. })
  133. },
  134. longpress(id, spec_index) {
  135. uni.showActionSheet({
  136. itemList: ['删除'],
  137. itemColor: "#FF5D5B",
  138. success: (res)=> {
  139. if (res.tapIndex === 0) {
  140. this.$store.commit("cart/remove", {
  141. id: id,
  142. spec_index: spec_index
  143. })
  144. uni.showToast({
  145. icon: "none",
  146. title: "删除成功"
  147. })
  148. }
  149. },
  150. })
  151. },
  152. buy() {
  153. let i = 0;
  154. let postData = {}
  155. for (let seller of this.cart) {
  156. for (let product of seller.products) {
  157. if (product.checked) {
  158. postData[`products[${i}]`] = JSON.stringify({
  159. id: product.id,
  160. spec_index: product.spec_index,
  161. num: product.num
  162. })
  163. i++;
  164. }
  165. }
  166. }
  167. this.$http.post({
  168. url: '/order/create',
  169. data: postData,
  170. success: (res) => {
  171. for (const [key, value] of Object.entries(postData)) {
  172. console.log(value)
  173. this.$store.commit("cart/remove", JSON.parse(value))
  174. }
  175. uni.navigateTo({
  176. url: "/pages/order/cashier?order_no=" + res.data.data
  177. })
  178. }
  179. })
  180. }
  181. }
  182. }
  183. </script>
  184. <style lang="scss">
  185. .header {
  186. margin: 20upx;
  187. background: white;
  188. text-align: center;
  189. border-radius: 20upx;
  190. padding-bottom: 10upx;
  191. .title {
  192. height: 100upx;
  193. font-size: 32upx;
  194. line-height: 100upx;
  195. // font-weight: bold;
  196. }
  197. .sub-title {
  198. font-size: 28upx;
  199. color: #999999;
  200. }
  201. }
  202. .shopping-cart {
  203. padding-bottom: 80upx;
  204. overflow: hidden;
  205. position: relative;
  206. }
  207. .shopping-cart-item {
  208. padding: 20upx;
  209. background: white;
  210. // padding-left: 100upx;
  211. margin: 20upx;
  212. border-radius: 20upx;
  213. .shopping-cart-item-head {
  214. margin-bottom: 20upx;
  215. font-size: 28upx;
  216. font-weight: bold;
  217. position: relative;
  218. display: flex;
  219. }
  220. .select {
  221. align-self: center;
  222. position: relative;
  223. margin-top: -4upx;
  224. margin-right: 20upx;
  225. }
  226. .checkbox {
  227. transform: scale(0.7);
  228. /deep/ .uni-checkbox-input {
  229. border: 2upx solid #CCCCCC;
  230. &.uni-checkbox-input-checked {
  231. color: $primary-color !important;
  232. }
  233. }
  234. /deep/ .uni-checkbox-input:hover {
  235. border: 2upx solid #CCCCCC;
  236. }
  237. }
  238. .product-item {
  239. display: flex;
  240. position: relative;
  241. margin-bottom: 20upx;
  242. .checkbox::before {
  243. top: 70upx;
  244. }
  245. .product-image {
  246. margin-right: 20upx;
  247. width: 180upx;
  248. height: 180upx;
  249. .image {
  250. width: 180upx;
  251. height: 180upx;
  252. margin-top: 5upx;
  253. }
  254. }
  255. .title {
  256. font-size: 24rpx;
  257. display: inline-block;
  258. white-space: normal;
  259. display: -webkit-box;
  260. -webkit-box-orient: vertical;
  261. -webkit-line-clamp: 2;
  262. overflow: hidden;
  263. height: 68upx;
  264. }
  265. .spec {
  266. font-size: 22upx;
  267. background: #CCCCCC;
  268. color: white;
  269. padding: 0 5upx;
  270. border-radius: 10upx;
  271. margin-top: 10upx;
  272. // display: inline-block;
  273. }
  274. .counter {
  275. position: absolute;
  276. bottom: 0upx;
  277. right: 10upx;
  278. display: flex;
  279. border: 2upx solid #CCCCCC;
  280. font-size: 28upx;
  281. align-items: center;
  282. border-radius: 10upx;
  283. .sub,
  284. .plus {
  285. // transform: scale(0.5);
  286. font-weight: 0;
  287. width: 42upx;
  288. text-align: center;
  289. &:active {
  290. background: rgba(0, 0, 0, .1);
  291. }
  292. }
  293. .num {
  294. text-align: center;
  295. font-size: 24upx;
  296. border-left: 2upx solid #EEEEEE;
  297. border-right: 2upx solid #EEEEEE;
  298. width: 50upx;
  299. }
  300. }
  301. }
  302. }
  303. .sxzg-icon {
  304. color: $primary-color;
  305. font-size: 16rpx;
  306. width: 80rpx;
  307. text-align: center;
  308. line-height: normal;
  309. border: 2rpx solid $primary-color;
  310. border-radius: 20rpx;
  311. display: inline-block;
  312. position: relative;
  313. top: -4rpx;
  314. margin-right: 10upx;
  315. // transform: scale(0.9);
  316. }
  317. .sxj-icon {
  318. background: $primary-color;
  319. color: white;
  320. font-size: 20upx;
  321. padding: 0 5upx;
  322. border-radius: 5upx;
  323. vertical-align: middle;
  324. }
  325. .row {
  326. display: flex;
  327. align-items: center;
  328. }
  329. .org-price {
  330. text-decoration: line-through;
  331. font-size: 26rpx;
  332. color: #cccccc;
  333. }
  334. .price {
  335. font-size: 26rpx;
  336. color: $primary-color;
  337. font-weight: bold;
  338. }
  339. .footer {
  340. display: flex;
  341. position: fixed;
  342. height: 100upx;
  343. background: $primary-color;
  344. bottom: 0;
  345. width: 100%;
  346. box-shadow: 0 0 10upx #999999;
  347. align-items: center;
  348. /* #ifdef H5 */
  349. bottom: 90upx;
  350. /* #endif */
  351. color: white;
  352. .select-all {
  353. width: 200upx;
  354. flex: 0 0 200upx;
  355. position: relative;
  356. margin-left: 20upx;
  357. .checkbox {
  358. transform: scale(0.7);
  359. position: relative;
  360. top: -4upx
  361. }
  362. /deep/ .uni-checkbox-input {
  363. border: none;
  364. }
  365. /deep/ .uni-checkbox-input:hover {
  366. border: none;
  367. }
  368. }
  369. .total {
  370. flex-grow: 1;
  371. text-align: right;
  372. }
  373. .settlement {
  374. flex-grow: 0;
  375. text-align: right;
  376. margin: 0 20upx;
  377. }
  378. .settlement-btn {
  379. background: #ffa82e;
  380. padding: 15upx 60upx;
  381. color: white;
  382. line-height: normal;
  383. font-size: 32upx;
  384. border-radius: 50upx;
  385. }
  386. }
  387. </style>