cart.vue 11 KB

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