cart.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  1. <template>
  2. <view class="content">
  3. <!-- 商品列表 -->
  4. <view class="goods-list">
  5. <view class="item" v-for="(item,index) in carts" :key="index">
  6. <label style="margin-right: 30upx;">
  7. <checkbox :value="item.checked" :checked="item.checked" @click="checkChange(item)" />
  8. </label>
  9. <image class="goods-img" :src="item.productAttrImage==null||item.productAttrImage==''?item.productImage:item.productAttrImage" mode="aspectFit"></image>
  10. <view class="info-box">
  11. <view>
  12. <view class="title-box">
  13. <view class="tag">{{utils.getDictLabelName("storeProductType",item.productType)}}</view>
  14. <view class="title ellipsis">{{ item.productName }}</view>
  15. </view>
  16. <view class="intro ellipsis">{{item.productAttrName}}</view>
  17. </view>
  18. <view class="price-num">
  19. <view class="price">
  20. <text class="unit">¥</text>
  21. <text class="text">{{item.price}}</text>
  22. </view>
  23. <view class="num-box">
  24. <view class="img-box" @click="delNum(item)">
  25. <image v-if="item.cartNum <= 1" src="../../static/images/jian.png" mode=""></image>
  26. <image v-else src="../../static/images/jian2.png" mode=""></image>
  27. </view>
  28. <input type="number" @change="changeNum($event,item)" :value="item.cartNum" />
  29. <view class="img-box" @click="addNum(item)">
  30. <image src="../../static/images/add.png" mode=""></image>
  31. </view>
  32. </view>
  33. </view>
  34. </view>
  35. </view>
  36. </view>
  37. <view v-if="carts.length == 0" class="no-data-box">
  38. <image src="../../static/images/no_data.png" mode="aspectFit"></image>
  39. <view class="empty-title">暂无数据</view>
  40. </view>
  41. <!-- 猜你喜欢 -->
  42. <view class="like-product">
  43. <likeProduct ref="product" />
  44. </view>
  45. <!-- 底部按钮 -->
  46. <view class="btn-foot">
  47. <view class="left">
  48. <label>
  49. <checkbox :checked="checkAll" @click="handleCheckAll()" />
  50. </label>
  51. <text class="text">全选</text>
  52. <text class="text" @click="delCart()">删除</text>
  53. </view>
  54. <view class="right">
  55. <view class="total">
  56. <text class="label">合计:</text>
  57. <view class="price">
  58. <text class="unit">¥</text>
  59. <text class="num">{{totalMoney.toFixed(2)}}</text>
  60. </view>
  61. </view>
  62. <view class="btn" @click="submit">结算</view>
  63. </view>
  64. </view>
  65. </view>
  66. </template>
  67. <script>
  68. import {getCarts,cartNum,delCart} from '@/api/product'
  69. import likeProduct from '@/components/likeProduct.vue'
  70. export default {
  71. components: {
  72. likeProduct
  73. },
  74. data() {
  75. return {
  76. totalMoney:0.00,
  77. carts:[],
  78. checkAll:false,
  79. }
  80. },
  81. onShow() {
  82. if(uni.getStorageSync('AppToken')){
  83. this.getCarts();
  84. }
  85. },
  86. onLoad() {
  87. if(uni.getStorageSync('AppToken')){
  88. this.getCarts();
  89. }
  90. },
  91. onReachBottom() {
  92. this.$refs.product.getGoodsProducts();
  93. },
  94. methods: {
  95. delCart(){
  96. var selectCarts=this.carts.filter(ele => ele.checked==true).map(ele => {
  97. return ele.id
  98. });
  99. if(selectCarts.length==0){
  100. uni.showToast({
  101. icon:'none',
  102. title: "请选择商品删除",
  103. });
  104. return;
  105. }
  106. let data = {ids:selectCarts};
  107. delCart(data).then(
  108. res => {
  109. if(res.code==200){
  110. uni.showToast({
  111. icon:'success',
  112. title: "操作成功",
  113. });
  114. this.getCarts()
  115. }else{
  116. uni.showToast({
  117. icon:'none',
  118. title: res.msg,
  119. });
  120. }
  121. },
  122. rej => {}
  123. );
  124. console.log(selectCarts)
  125. },
  126. computedMoney(){
  127. var money=0;
  128. var that=this;
  129. this.carts.forEach((item,index,arr)=>{
  130. if(item.checked){
  131. money+=item.price*item.cartNum;
  132. }
  133. })
  134. console.log(money);
  135. this.totalMoney=money;
  136. },
  137. handleCheckAll(){
  138. this.checkAll=!this.checkAll;
  139. var that=this;
  140. this.carts.forEach((item,index,arr)=>{
  141. item.checked=that.checkAll;
  142. })
  143. this.computedMoney();
  144. },
  145. checkChange(item){
  146. item.checked=!item.checked;
  147. this.computedMoney();
  148. },
  149. changeNum(e,item) {
  150. item.cartNum = e.detail.value.replace(/\D/g, '')
  151. if (item.cartNum <= 1) {
  152. uni.showToast({
  153. title: "已经是底线啦!",
  154. icon: "none",
  155. duration: 2000
  156. });
  157. return;
  158. }
  159. if(item.cartNum < 1) {
  160. item.cartNum = 1
  161. }
  162. if(item.cartNum>=item.stock){
  163. item.cartNum=item.stock;
  164. }
  165. this.changeCartNum(item)
  166. },
  167. changeCartNum(item){
  168. let data = {number:item.cartNum,id:item.id};
  169. cartNum(data).then(
  170. res => {
  171. if(res.code==200){
  172. uni.showToast({
  173. icon:'none',
  174. title: "操作成功",
  175. });
  176. this.computedMoney();
  177. }else{
  178. uni.showToast({
  179. icon:'none',
  180. title: res.msg,
  181. });
  182. }
  183. },
  184. rej => {}
  185. );
  186. },
  187. getCarts(){
  188. getCarts().then(
  189. res => {
  190. if(res.code==200){
  191. this.carts=res.carts;
  192. this.carts.forEach((item,index,arr)=>{
  193. item.checked=false;
  194. })
  195. this.computedMoney();
  196. }else{
  197. uni.showToast({
  198. icon:'none',
  199. title: "请求失败",
  200. });
  201. }
  202. },
  203. rej => {}
  204. );
  205. },
  206. // 购物车减法
  207. delNum(item) {
  208. if (item.cartNum <= 1) {
  209. uni.showToast({
  210. title: "已经是底线啦!",
  211. icon: "none",
  212. duration: 2000
  213. });
  214. return;
  215. }
  216. item.cartNum --
  217. if(item.cartNum < 1) {
  218. item.cartNum = 1
  219. }
  220. this.changeCartNum(item)
  221. },
  222. // 购物车加法
  223. addNum(item) {
  224. console.log(item)
  225. item.cartNum++
  226. if(item.cartNum>=item.stock){
  227. item.cartNum=item.stock;
  228. }
  229. this.changeCartNum(item)
  230. },
  231. // 结算
  232. submit() {
  233. var selectCarts=this.carts.filter(ele => ele.checked==true).map(ele => {
  234. return ele.id
  235. });
  236. if(selectCarts.length==0){
  237. uni.showToast({
  238. icon:'none',
  239. title: "请选择商品",
  240. });
  241. return;
  242. }
  243. uni.navigateTo({
  244. url: './confirmOrder?type=cart&cartIds='+selectCarts.toString()
  245. })
  246. },
  247. showProduct(item){
  248. uni.navigateTo({
  249. url: '../shopping/productDetails?productId='+item.productId
  250. })
  251. },
  252. }
  253. }
  254. </script>
  255. <style lang="scss">
  256. page {
  257. height: 100%;
  258. }
  259. .content{
  260. height: 100%;
  261. padding: 20upx;
  262. .goods-list{
  263. .item{
  264. box-sizing: border-box;
  265. height: 221upx;
  266. background: #FFFFFF;
  267. border-radius: 16upx;
  268. margin-bottom: 20upx;
  269. padding: 30upx;
  270. display: flex;
  271. align-items: center;
  272. &:last-child{
  273. margin-bottom: 0;
  274. }
  275. .goods-img{
  276. width: 160upx;
  277. height: 160upx;
  278. background: #FFFFFF;
  279. margin-right: 30upx;
  280. flex-shrink: 0;
  281. }
  282. .info-box{
  283. height: 160upx;
  284. display: flex;
  285. flex-direction: column;
  286. justify-content: space-between;
  287. width: calc(100% - 255upx);
  288. .title-box{
  289. width: 100%;
  290. display: flex;
  291. align-items: center;
  292. .tag{
  293. padding: 0 6upx;
  294. height: 30upx;
  295. line-height: 30upx;
  296. font-size: 22upx;
  297. font-family: PingFang SC;
  298. font-weight: bold;
  299. color: #FFFFFF;
  300. background: linear-gradient(90deg, #2BC7B9 0%, #2BC7A4 100%);
  301. border-radius: 4upx;
  302. margin-right: 10upx;
  303. flex-shrink: 0;
  304. }
  305. .title{
  306. flex: 1;
  307. font-size: 28upx;
  308. font-family: PingFang SC;
  309. font-weight: 500;
  310. color: #111111;
  311. line-height: 1;
  312. }
  313. }
  314. .intro{
  315. font-size: 24upx;
  316. font-family: PingFang SC;
  317. font-weight: 500;
  318. color: #999999;
  319. margin-top: 22upx;
  320. line-height: 1;
  321. }
  322. .price-num{
  323. display: flex;
  324. align-items: center;
  325. justify-content: space-between;
  326. .price{
  327. display: flex;
  328. align-items: flex-end;
  329. .unit{
  330. font-size: 24upx;
  331. font-family: PingFang SC;
  332. font-weight: 500;
  333. color: #FF6633;
  334. line-height: 1.2;
  335. margin-right: 4upx;
  336. }
  337. .text{
  338. font-size: 32upx;
  339. font-family: PingFang SC;
  340. font-weight: bold;
  341. color: #FF6633;
  342. line-height: 1;
  343. }
  344. }
  345. .num-box{
  346. display: flex;
  347. align-items: center;
  348. .img-box{
  349. width: 60upx;
  350. height: 60upx;
  351. // border-radius: 4upx;
  352. border: 1px solid #dddddd;
  353. display: flex;
  354. align-items: center;
  355. justify-content: center;
  356. image{
  357. width: 25rpx;
  358. height: 25rpx;
  359. }
  360. }
  361. input{
  362. width: 60upx;
  363. height: 60upx;
  364. line-height: 60upx;
  365. font-size: 28upx;
  366. font-family: PingFang SC;
  367. font-weight: 500;
  368. color: #111111;
  369. // border-radius: 4upx;
  370. border-top: 1px solid #dddddd;
  371. border-bottom: 1px solid #dddddd;
  372. text-align: center;
  373. // margin: 0 16upx;
  374. }
  375. }
  376. }
  377. }
  378. }
  379. }
  380. .like-product{
  381. padding-bottom: 120upx;
  382. }
  383. .btn-foot{
  384. box-sizing: border-box;
  385. width: 100%;
  386. height: 121upx;
  387. background: #FFFFFF;
  388. padding: 16upx 30upx 16upx 60upx;
  389. display: flex;
  390. align-items: center;
  391. justify-content: space-between;
  392. position: fixed;
  393. left: 0;
  394. bottom: 0;
  395. z-index: 99;
  396. .left{
  397. display: flex;
  398. align-items: center;
  399. .text{
  400. margin-left: 14upx;
  401. font-size: 28upx;
  402. font-family: PingFang SC;
  403. font-weight: 500;
  404. color: #666666;
  405. line-height: 1;
  406. }
  407. }
  408. .right{
  409. display: flex;
  410. align-items: center;
  411. .total{
  412. display: flex;
  413. align-items: flex-end;
  414. margin-right: 36upx;
  415. .label{
  416. font-size: 26upx;
  417. font-family: PingFang SC;
  418. font-weight: 500;
  419. color: #999999;
  420. line-height: 1.5;
  421. }
  422. .price{
  423. display: flex;
  424. align-items: flex-end;
  425. .unit{
  426. font-size: 32upx;
  427. font-family: PingFang SC;
  428. font-weight: bold;
  429. color: #FF6633;
  430. line-height: 1.2;
  431. margin-right: 10upx;
  432. }
  433. .num{
  434. font-size: 30upx;
  435. font-family: PingFang SC;
  436. font-weight: bold;
  437. color: #FF6633;
  438. line-height: 1;
  439. }
  440. }
  441. }
  442. .btn{
  443. width: 200upx;
  444. height: 88upx;
  445. line-height: 88upx;
  446. text-align: center;
  447. font-size: 30upx;
  448. font-family: PingFang SC;
  449. font-weight: bold;
  450. color: #FFFFFF;
  451. background: #2BC7B9;
  452. border-radius: 44upx;
  453. }
  454. }
  455. }
  456. }
  457. </style>