关于样式丑的说法,自行改成好看的就好
<style lang="less">
page {
background: #f4f4f4;
}
.cart-top {
background: #fff;
.receive {
padding: 20rpx;
display: flex;
justify-content: space-between;
}
.address {
padding: 0 20rpx 20rpx;
}
.address-bar {
display: block;
width: 750rpx;
height: 15rpx;
}
}
.list-title {
border-top: 20rpx #f4f4f4 solid;
padding: 20rpx;
border-bottom: 1px #dddddd solid;
background: #fff;
}
.ware-list {
padding-bottom: 80rpx;
background: #fff;
}
.ware-item {
display: flex;
padding: 0 20rpx;
}
.choice-button {
width: 70rpx;
display: flex;
align-items: center;
flex-shrink: 0;
}
.ware-content {
display: flex;
flex: 1;
padding: 20rpx 0;
justify-content: space-between;
align-items: center;
border-bottom: 1px #f5f5f5 solid;
.ware-image {
margin-right: 20rpx;
image {
display: block;
width: 160rpx;
height: 160rpx;
}
}
.ware-title {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
margin-bottom: 20rpx;
}
.ware-info {
flex: 1;
}
.ware-info-btm {
display: flex;
justify-content: space-between;
.ware-price {
font-size: 18px;
color: #ff6066;
span {
font-size: 12px;
}
}
}
}
.cart-total {
background: #fff;
display: flex;
justify-content: space-between;
align-items: center;
height: 95rpx;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
.total-button {
box-sizing: border-box;
padding-left: 20rpx;
margin-right: 50rpx;
display: flex;
align-items: center;
icon {
margin-right: 20rpx;
}
}
.total-center {
flex: 1;
.colorRed {
text {
font-size: 12px;
}
}
.price-tips {
color: #999;
font-size: 12px;
}
}
.accounts {
flex-shrink: 0;
width: 230rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #ff6066;
color: #fff;
}
}
.calculate {
display: flex;
.rect {
width: 50rpx;
height: 50rpx;
line-height: 50rpx;
border: 1px #666 solid;
text-align: center;
}
.number {
line-height: 50rpx;
width: 90rpx;
padding: 5rpx;
box-sizing: border-box;
text-align: center;
}
}
.cart-empty {
padding: 20rpx;
background: #fff;
text-align: center;
}
.empty{
display: flex;
padding:100rpx 0;
justify-content: center;
flex-direction: column;
align-items: center;
image{
width:120rpx;
height:120rpx;
margin-bottom:50rpx;
}
}
</style>
<template>
<view class="container">
<view wx:if="{{cartData.length > 0}}">
<!-- 收货人信息 -->
<view class="cart-top" wx:if="{{address.addr}}">
<view class="receive">
<view class="name">
收货人: {{address.userName}}
</view>
<view class="phonen-number">
{{address.telNumber}}
</view>
</view>
<view class="address">
收货地址: {{address.addr}}
</view>
<image src="../images/cart_border@2x.png" class="address-bar">
</view>
<view class="cart-empty" wx:if="{{!address.addr}}" bindtap="handleAddress">
添加地址
</view>
<view class="list-title">
优购生活馆
</view>
<!-- 购物车列表 -->
<view class="ware-list">
<view wx:for="{{cartData}}" wx:key="{{index}}">
<view class="ware-item">
<!-- 左侧的按钮 -->
<view class="choice-button" @tap="handleSelect({{item}})">
<icon type="success" color="{{item.checked ? 'red' : '#999'}}" size="18"/>
</view>
<view class="ware-content">
<!-- 左侧的图片 -->
<navigator class="ware-image" url="/pages/goods_detail?goods_id={{item.goods_id}}">
<image src="{{item.goods_small_logo}}"/>
</navigator>
<!-- 右边的商品信息 -->
<view class="ware-info">
<navigator url="/pages/goods_detail?goods_id={{item.goods_id}}" class="ware-title">
{{item.goods_name}}
</navigator>
<view class="ware-info-btm">
<view class="ware-price">
<span>¥</span>{{item.goods_price}}
</view>
<!-- 修改商品的数量 -->
<view class="calculate">
<view class="calculate">
<view class="rect" @tap="handleCompouted({{item}}, -1)">-</view>
<view class="number">{{item.count}}</view>
<view class="rect" @tap="handleCompouted({{item}}, 1)">+</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 结算 -->
<view class="cart-total">
<view class="total-button" @tap="handleAllSelect">
<icon type="success" color="{{allSelect ? 'red' : '#999'}}" size="18"/>全选
</view>
<view class="total-center">
<view class="total-price">
合计:
<text class="colorRed">
<text>¥</text>{{allPrice}}
</text>
</view>
<view class="price-tips">
包含运费
</view>
</view>
<view class="accounts" bindtap="handleSubmit" >
结算({{allCount}})
</view>
</view>
</view>
<!-- 购物车数量为空的时候 -->
<view class="empty" wx:if="{{cartData.length == 0}}" >
<image src="../images/cart_empty@2x.png"/>
购物车为空
</view>
</view>
</template>
<script>
import wepy from 'wepy';
import cartManage from '../utils/cartManage';
import request from '../utils/request';
import authManage from '../utils/authManage';
/*
1. 从商品详情页添加到购物车 cartManage.add
2. 动态修改购物车的总价格 cartManage.updatePrice
3. 修改购物车商品的选中状态 cartManage.update
4. 修改购物车商品全选的状态 cartManage.updataAllChecked
5. 修改购物车商品的数量 cartManage.update
*/
export default class Cart extends wepy.page {
config = {
navigationBarTitleText: '搜索'
};
data = {
// 存储购物车列表,默认是空数组
cartData: (cartManage.data && cartManage.data.goods) || [],
allSelect: true,
allPrice: 0,
address: {
userName: '',
telNumber: '',
addr: ''
},
allCount: cartManage.data.allCount
};
onShow() {
this.updateData();
// 页面打开时候判断是否是全选
this.cartData.forEach(v => {
if (!v.checked) {
this.allSelect = false;
}
});
}
// 判断是否是全选
isAllSelelct() {
const { cartData } = this;
// 只要有一个商品没选中, 取消全选状态
for (let i = 0, v; (v = cartData[i++]); ) {
if (!v.checked) {
this.allSelect = false;
return;
}
this.allSelect = true;
}
}
// 更新data数据
updateData() {
// 更新data的数据
this.cartData = cartManage.data.goods;
// 更新价格
this.allPrice = cartManage.data.allPrice;
// 更新总数
this.allCount = cartManage.data.allCount;
}
methods = {
handleCompouted: function(item, num) {
item.count += Number(num);
if (item.count == 0) {
// 调用对话弹窗 wx.showModal
wx.showModal({
content: '确定删除商品吗?',
success: res => {
if (res.confirm) {
// 点击确定就删除商品
cartManage.remove(item);
this.updateData();
this.$apply();
}
}
});
} else {
cartManage.update(item);
this.updateData();
}
},
handleSelect: function(item) {
item.checked = !item.checked;
cartManage.update(item);
this.updateData();
// 判断是否是全部选中
this.isAllSelelct();
},
// 点击全选时候触发
handleAllSelect: function() {
const { allSelect } = this;
this.allSelect = !allSelect;
cartManage.updataAllChecked(this.allSelect);
// 更新价格
this.allPrice = cartManage.data.allPrice;
},
// 添加收货地址
handleAddress: function() {
wx.chooseAddress({
success: res => {
this.address = {
userName: res.userName,
telNumber: res.telNumber,
addr: `${res.provinceName}${res.cityName}${res.countyName}${
res.detailInfo
}`
};
// 把收货地址存到本地
cartManage.addAddr(this.address);
this.$apply();
}
});
},
// 提交整个订单
handleSubmit: function() {
// 提交订单的参数
const data = {
order_price: this.allPrice,
consignee_addr: this.address.addr,
goods: this.cartData.map(v => {
return {
goods_id: v.goods_id,
goods_number: v.count,
goods_price: v.goods_price
};
})
};
// 判断是否登录
if (!authManage.isAuth) {
wx.navigateTo({
url: '/pages/login'
});
return;
}
// 提交订单
request({
url: 'api/public/v1/my/orders/create',
data,
method: 'POST',
header: { Authorization: authManage.getToken() },
success: res => {
const {data} = res.data;
this.pay( { order_number: data.order_number } )
}
});
}
};
// 处理订单支付
pay(data){
request({
url: "api/public/v1/my/orders/req_unifiedorder",
data,
method: 'POST',
header: { Authorization: authManage.getToken() },
success: res => {
const {data} = res.data;
wx.requestPayment(data.wxorder);
}
})
}
}
</script>
管理登录状态
// 管理登录状态
// 有个问题要注意, 当token过期时候我们没有处理
const authManage = {
// 判断是否已登录
isAuth: false,
// 初始化方法
init: function(){
this.isAuth = !!this.getToken();
},
// 把token保存到本地
setToken: function(token){
this.isAuth = true;
wx.setStorageSync("token", token)
},
// 获取token
getToken: function(){
return wx.getStorageSync("token");
}
}
authManage.init();
export default authManage;
管理购物车数据
// 管理购物车数据
// 把数据存储到本地,但是有些项目是通过接口来实现
// 管理购物车的单例
const cartManage = {
// 购物车数据
data: {
goods: [], // 购物车商品列表
allPrice: 0, // 合计价格
address: {}, // 收货地址
allCount: 0,
},
// 管理类初始化
init: function(){
// 初始化goods
this.data = this.getData() || this.data;
// 初始化合计价格
this.updatePrice();
},
// 把收货地址添加到本地存储
addAddr: function(addr){
this.data.address = addr;
this.setData();
},
// 添加商品
add: function(item){
const {goods} = this.data;
// 判断商品是否存在
let isEixst = false;
// 返回新的商品列表,新的列表可能是修改过商品的数量
const newGoods = goods.map(v => {
// 当商品存在时候数量加1
if(v.goods_id == item.goods_id){
// 确定商品存在
isEixst = true;
v.count += 1;
}
return v;
})
// 如果商品存在就不会调用push方法
if(isEixst){
this.data.goods = newGoods;
}else{
this.data.goods.push(item);
}
this.updatePrice();
},
// 删除商品
remove: function(item){
const {goods} = this.data;
const newGoods = goods.filter(v => {
// 如果找到该需要删除的商品, id相等的不返回, 相当于删除掉了该商品
return !(v.goods_id == item.goods_id)
});
this.data.goods = newGoods;
console.log(newGoods)
this.updatePrice();
},
// 更新商品
update: function(item){
const {goods} = this.data;
const newGoods = goods.map(v => {
// 找到需要更新的商品
if(item.goods_id == v.goods_id){
// 返回新的商品
return item;
}
return v;
});
this.data.goods = newGoods;
this.updatePrice();
},
// 管理所有商品的选中状态
// isChecked为true时候,就是全部选中
// isChecked为false时候, 就是全部不选中
updataAllChecked: function(isChecked){
const {goods} = this.data;
const newGoods = goods.map(v => {
v.checked = isChecked;
return v;
});
this.data.goods = newGoods;
this.updatePrice();
},
// 更新合计的价格
updatePrice: function(){
const {goods} = this.data;
let price = 0;
goods.forEach(v => {
// 商品必须是选中的状态
if(v.checked){
price += +v.goods_price * v.count;
}
})
this.data.allPrice = price;
this.updateAllCount();
this.setData();
return this.data.allPrice;
},
// 管理数量
updateAllCount: function(){
const {goods} = this.data;
// 通过循环过滤, 过滤的条件商品必须是选中状态
const newGoods = goods.filter(v => {
return v.checked
});
this.data.allCount = newGoods.length;
},
// 把数据存储到本地
setData: function(){
wx.setStorageSync("cartData", this.data);
},
// 把数据从本地存储获取回来
getData: function(){
return wx.getStorageSync("cartData")
}
}
// 执行初始化
cartManage.init();
export default cartManage;