shuinishop/pages/tabBar/cart/cart.vue

638 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view>
<view v-if="showHeader" class="status" :style="{position:headerPosition,top:statusTop}"></view>
<view v-if="showHeader" class="header" :style="{position:headerPosition,top:headerTop}">
<view class="title">购物车</view>
</view>
<!-- 占位 -->
<view v-if="showHeader" class="place"></view>
<!-- 商品列表 -->
<view class="goods-list">
<view class="tis" v-if="goodsList.length==0">购物车是空的哦~</view>
<view class="row" v-for="(row,index) in goodsList" :key="index" >
<!-- 删除按钮 -->
<view class="menu" @tap.stop="deleteGoods(row.id)">
<view class="icon shanchu"></view>
</view>
<!-- 商品 -->
<view class="carrier" :class="[theIndex==index?'open':oldIndex==index?'close':'']" @touchstart="touchStart(index,$event)" @touchmove="touchMove(index,$event)" @touchend="touchEnd(index,$event)">
<view style=" width: 100%; padding: 20rpx 0 20rpx 150rpx;">
{{row.username}}
</view>
<view style="display: flex;width:100%">
<!-- checkbox -->
<view class="checkbox-box" @tap="selected(index)">
<view class="checkbox">
<view :class="[row.selected?'on':'']"></view>
</view>
</view>
<!-- 商品信息 -->
<view class="goods-info" @tap="toGoods(row)">
<view class="img">
<image :src="row.picurl"></image>
</view>
<view class="info">
<view class="title">{{row.title}}</view>
<!-- <view class="spec">{{row.spec}}</view> -->
<view class="price-number">
<view class="price">¥{{row._price}}</view>
<!-- <view style="display: flex;flex-shrink:0"> -->
<view class="number">
<view class="sub" @tap.stop="sub(index)">
<view class="icon jian"></view>
</view>
<view class="input" @tap.stop="discard">
<input type="number" v-model="row._num" @input="sum($event,index)" />
</view>
<view class="add" @tap.stop="add(index)">
<view class="icon jia"></view>
</view>
</view>
<icon type="cancel" size="26" @tap.stop="deleteGood(row.id, index)"/>
<!-- </view> -->
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 脚部菜单 -->
<view class="footer" :style="{bottom:footerbottom}">
<view class="checkbox-box" @tap="allSelect">
<view class="checkbox">
<view :class="[isAllselected?'on':'']"></view>
</view>
<view class="text">全选</view>
</view>
<!-- <view class="delBtn" @tap="deleteList" v-if="selectedList.length>0">删除</view> -->
<view class="settlement">
<view class="sum">总计(不含运费):<view class="money">¥{{sumPrice}}</view></view>
<view class="btn" @tap="toConfirmation">结算
<!-- ({{selectedList.length}}) -->
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
sumPrice:'0.00',
headerPosition:"fixed",
headerTop:null,
statusTop:null,
showHeader:true,
selectedList:[],
isAllselected:false,
goodsList:[
{id:1,img:'/static/img/goods/p1.jpg',name:'商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题',spec:'规格:S码',price:127.5,number:1,selected:false},
{id:2,img:'/static/img/goods/p2.jpg',name:'商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题',spec:'规格:S码',price:127.5,number:1,selected:false},
{id:3,img:'/static/img/goods/p3.jpg',name:'商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题',spec:'规格:S码',price:127.5,number:1,selected:false},
{id:4,img:'/static/img/goods/p4.jpg',name:'商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题',spec:'规格:S码',price:127.5,number:1,selected:false},
{id:5,img:'/static/img/goods/p5.jpg',name:'商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题商品标题',spec:'规格:S码',price:127.5,number:1,selected:false}
],
//控制滑动效果
theIndex:null,
oldIndex:null,
isStop:false
}
},
onPageScroll(e){
//兼容iOS端下拉时顶部漂移
this.headerPosition = e.scrollTop>=0?"fixed":"absolute";
this.headerTop = e.scrollTop>=0?null:0;
this.statusTop = e.scrollTop>=0?null:-this.statusHeight+'px';
},
//下拉刷新需要自己在page.json文件中配置开启页面下拉刷新 "enablePullDownRefresh": true
onPullDownRefresh() {
this.getCart()
uni.stopPullDownRefresh()
},
onLoad() {
//兼容H5下结算条位置
// #ifdef H5
this.footerbottom = document.getElementsByTagName('uni-tabbar')[0].offsetHeight+'px';
// #endif
// #ifdef APP-PLUS
this.showHeader = false;
this.statusHeight = plus.navigator.getStatusbarHeight();
// #endif
},
onShow() {
this.getCart()
},
methods: {
getCart(){
this.$u.api.getCart().then(res=>{
var goodslist = []
for(var i=0;i<res.data.length;i++){
// for(var m=0;m<res.data[i].length;m++){
// res.data[i].shops[m].shopId = res.data[i].uid
// }
goodslist = goodslist.concat(res.data[i].shops)
}
this.goodsList = goodslist
this.selectedList=[]
this.isAllselected = false
this.sumPrice='0.00'
})
},
//加入商品 参数 goods:商品数据
joinGoods(goods){
/*
* 这里只是展示一种添加逻辑,模板并没有做从其他页面加入商品到购物车的具体动作,
* 在实际应用上前端并不会直接插入记录到goodsList这一个动作一般是更新列表和本地列表缓存。
* 一般商城购物车的增删改动作是由后端来完成的,
* 后端记录后返回前端更新前端缓存
*/
let len = this.goodsList.length;
let isFind = false;//是否找到ID一样的商品
for(let i=0;i<len;i++){
let row = this.goodsList[i];
if(row.id==goods.id )
{ //找到商品一样的商品
this.goodsList[i].number++;//数量自增
isFind = true;//找到一样的商品
break;//跳出循环
}
}
if(!isFind){
//没有找到一样的商品,新增一行到购物车商品列表头部
this.goodsList[i].unshift(goods);
}
},
//控制左滑删除效果-begin
touchStart(index,event){
//多点触控不触发
if(event.touches.length>1){
this.isStop = true;
return ;
}
this.oldIndex = this.theIndex;
this.theIndex = null;
//初始坐标
this.initXY = [event.touches[0].pageX,event.touches[0].pageY];
},
touchMove(index,event){
//多点触控不触发
if(event.touches.length>1){
this.isStop = true;
return ;
}
let moveX = event.touches[0].pageX - this.initXY[0];
let moveY = event.touches[0].pageY - this.initXY[1];
if(this.isStop||Math.abs(moveX)<5){
return ;
}
if (Math.abs(moveY) > Math.abs(moveX)){
// 竖向滑动-不触发左滑效果
this.isStop = true;
return;
}
if(moveX<0){
this.theIndex = index;
this.isStop = true;
}else if(moveX>0){
if(this.theIndex!=null&&this.oldIndex==this.theIndex){
this.oldIndex = index;
this.theIndex = null;
this.isStop = true;
setTimeout(()=>{
this.oldIndex = null;
},150)
}
}
},
touchEnd(index,$event){
//结束禁止触发效果
this.isStop = false;
},
//控制左滑删除效果-end
//商品跳转
toGoods(e){
uni.showToast({title: '商品'+e.id,icon:"none"});
uni.navigateTo({
url: '../../goods/goods?id='+e.id
});
},
//跳转确认订单页面
toConfirmation(){
let tmpList=[];
let len = this.goodsList.length;
for(let i=0;i<len;i++){
if(this.goodsList[i].selected) {
let good = {
id: this.goodsList[i].id,
picurl: this.goodsList[i].picurl,
title: this.goodsList[i].title,
// spec: '规格:' + this.goodsData.spec[this.selectSpec],
price: this.goodsList[i].price,
_num: this.goodsList[i]._num,
shopId: this.goodsList[i].uid
};
tmpList.push(good);
}
}
if(tmpList.length<1){
uni.showToast({
title:'请选择商品结算',
icon:'none'
});
return ;
}
uni.setStorage({
key:'buylist',
data:tmpList,
success: () => {
uni.navigateTo({
url:'../../order/confirmation'
})
}
})
},
//删除商品
deleteGoods(id){
let len = this.goodsList.length;
this.$u.api.removeFromCart(id).then(res=>{
for(let i=0;i<len;i++){
if(id==this.goodsList[i].id){
this.goodsList.splice(i, 1);
break;
}
}
this.selectedList.splice(this.selectedList.indexOf(id), 1);
this.sum();
this.oldIndex = null;
this.theIndex = null;
}).catch(e=>{
uni.showToast({
title:'移除失败'
})
})
},
//移除一件商品
deleteGood(id, index){
var that = this
that.$u.api.removeFromCart(id).then(res=>{
that.goodsList.splice(index, 1)
this.sum()
})
},
// 删除商品s
deleteList(){
let len = this.selectedList.length;
while (this.selectedList.length>0)
{
this.deleteGoods(this.selectedList[0]);
}
this.selectedList = [];
this.isAllselected = this.selectedList.length == this.goodsList.length && this.goodsList.length>0;
this.sum();
},
// 选中商品
selected(index){
this.goodsList[index].selected = this.goodsList[index].selected?false:true;
let i = this.selectedList.indexOf(this.goodsList[index].id);
i>-1?this.selectedList.splice(i, 1):this.selectedList.push(this.goodsList[index].id);
this.isAllselected = this.selectedList.length == this.goodsList.length;
this.sum();
},
//全选
allSelect(){
let len = this.goodsList.length;
let arr = [];
for(let i=0;i<len;i++){
this.goodsList[i].selected = this.isAllselected? false : true;
arr.push(this.goodsList[i].id);
}
this.selectedList = this.isAllselected?[]:arr;
this.isAllselected = this.isAllselected||this.goodsList.length==0?false : true;
this.sum();
},
// 减少数量
sub(index){
if(this.goodsList[index]._num<=1){
return;
}
this.goodsList[index]._num--;
this.sum();
},
// 增加数量
add(index){
this.goodsList[index]._num++;
this.sum();
},
// 合计
sum(e,index){
this.sumPrice=0;
let len = this.goodsList.length;
for(let i=0;i<len;i++){
if(this.goodsList[i].selected) {
if(e && i==index){
this.sumPrice = this.sumPrice + (e.detail.value*this.goodsList[i]._price);
}else{
this.sumPrice = this.sumPrice + (this.goodsList[i]._num*this.goodsList[i]._price);
}
}
}
this.sumPrice = this.sumPrice.toFixed(2);
},
discard() {
//丢弃
}
}
}
</script>
<style lang="scss">
page{position: relative;background-color: #fff;}
.checkbox-box{
display: flex;
align-items: center;
.checkbox{
width: 35upx;
height: 35upx;
border-radius: 100%;
border: solid 2upx #f06c7a;
display: flex;
justify-content: center;
align-items: center;
.on{
width: 25upx;
height: 25upx;
border-radius: 100%;
background-color: #f06c7a;
}
}
.text{
font-size: 28upx;
margin-left: 10upx;
}
}
.status {
width: 100%;
height: 0;
position: fixed;
z-index: 10;
background-color: #fff;
top: 0;
/* #ifdef APP-PLUS */
height: var(--status-bar-height);//覆盖样式
/* #endif */
}
.header{
width: 92%;
padding: 0 4%;
height: 100upx;
display: flex;
align-items: center;
position: fixed;
top: 0;
z-index: 10;
background-color: #fff;
/* #ifdef APP-PLUS */
top: var(--status-bar-height);
/* #endif */
.title{
font-size: 36upx;
}
}
.place{
background-color: #ffffff;
height: 100upx;
/* #ifdef APP-PLUS */
margin-top: var(--status-bar-height);
/* #endif */
}
.goods-list{
width: 100%;
padding: 20upx 0 120upx 0;
.tis{
width: 100%;
height: 60upx;
display: flex;
justify-content: center;
align-items: center;
font-size: 32upx;
}
.row{
width: calc(92%);
height: calc(22vw + 110upx);
margin: 20upx auto;
border-radius: 15upx;
box-shadow: 0upx 5upx 20upx rgba(0,0,0,0.1);
display: flex;
align-items: center;
position: relative;
overflow: hidden;
z-index: 4;
border: 0;
.menu{
.icon{
color: #fff;
// font-size: 25upx;
}
position: absolute;
width: 30%;
height: 100%;
right: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: red;
color: #fff;
z-index: 2;
}
.carrier{
flex-direction: column;
@keyframes showMenu {
0% {transform: translateX(0);}100% {transform: translateX(-30%);}
}
@keyframes closeMenu {
0% {transform: translateX(-30%);}100% {transform: translateX(0);}
}
&.open{
animation: showMenu 0.25s linear both;
}
&.close{
animation: closeMenu 0.15s linear both;
}
background-color: #fff;
.checkbox-box{
padding-left: 20upx;
flex-shrink: 0;
height: 22vw;
margin-right: 20upx;
}
position: absolute;
width: 100%;
padding: 0 0;
height: 100%;
z-index: 3;
display: flex;
align-items: center;
.goods-info{
width: 100%;
display: flex;
padding-right: 20upx;
.img{
width: 22vw;
height: 22vw;
border-radius: 10upx;
overflow: hidden;
flex-shrink: 0;
margin-right: 10upx;
image{
width: 22vw;
height: 22vw;
}
}
.info{
width: 100%;
height: 22vw;
overflow: hidden;
display: flex;
flex-wrap: wrap;
position: relative;
.title{
width: 100%;
font-size: 28upx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
// text-align: justify;
overflow: hidden;
}
.spec{
font-size: 20upx;
background-color: #f3f3f3;
color: #a7a7a7;
height: 30upx;
display: flex;
align-items: center;
padding: 0 10upx;
border-radius: 15upx;
margin-bottom: 20vw;
}
.price-number{
position: absolute;
width: 100%;
bottom: 0upx;
display: flex;
justify-content: space-between;
align-items: flex-end;
font-size: 28upx;
height: 60upx;
.price{
}
.number{
display: flex;
justify-content: center;
align-items: flex-end;
margin-right: 10upx;
.input{
width: 60upx;
height: 60upx;
margin: 0 10upx;
background-color: #f3f3f3;
input{
width: 60upx;
height: 60upx;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
font-size: 26upx;
}
}
.sub ,.add{
width: 45upx;
height: 45upx;
background-color: #f3f3f3;
border-radius: 5upx;
.icon{
font-size: 22upx;
width: 45upx;
height: 45upx;
display: flex;
justify-content: center;
align-items: center;
}
}
}
}
}
}
}
}
}
.footer{
width: 92%;
padding: 0 4%;
background-color: #fbfbfb;
height: 100upx;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 28upx;
position: fixed;
bottom: 0upx;
z-index: 5;
.delBtn{
border: solid 1upx #f06c7a;
color: #f06c7a;
padding: 0 30upx;
height: 50upx;
border-radius: 30upx;
display: flex;
justify-content: center;
align-items: center;
}
.settlement{
width: 75%;
display: flex;
justify-content: flex-end;
align-items: center;
.sum{
width: 75%;
font-size: 28upx;
margin-right: 10upx;
display: flex;
justify-content: flex-end;
.money{
font-weight: 600;
}
}
.btn{
padding: 0 30upx;
height: 50upx;
background-color: #f06c7a;
color: #fff;
display: flex;
justify-content: center;
align-items: center;
border-radius: 30upx;
}
}
}
</style>