shopping-cart.vue 7.7 KB

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