shopping-cart.vue 7.6 KB

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