1布局
2导航守卫
逻辑:在购物车的路由判断是否是登录状态,如果是登录状态可以直接进入,如果不是登录状态,跳转到登录页
{
path: "/cart",
name: "Cart",
component: () =>
import(/* webpackChunkName: "cart" */ "../views/Cart.vue"),
beforeEnter:(to, from, next)=>{
console.log( useUserStore().userInfo.id )
if( useUserStore().userInfo.id ){
next();
}else{
next('/login');
}
}
},
修改pinia
actions:{
//设置token
setToken( token ){
this.token = token;
},
//清除token
clearToken(){
this.token = '';
this.userInfo = {}; //增加退出登录,清除userInfo获取用户信息的内容
}
},
3 购物车 渲染和单选和全选,总价
课程id 存在一个数组当中
所有课程存入pinia当中
如果【课程id】.length = 【课程list】. length 就是全选,
3.1 获取数据
接口没有check。 上来给list的每一个对象都添加一个check
初始化时候调用
//生命周期
onBeforeMount(()=>{
getShopCarList().then(res=>{
cartStore.addCart( res.data.list );
})
})
3.2 全选,全不选
3.3 单选
要知道点击的是哪一个
3.4 总价和数量
3.5 代码
import { defineStore } from 'pinia'
export const useCartStore = defineStore({
id: 'cart',
state: () => {
return {
cartList:[],
select:[]
}
},
getters:{
checkAll( ){
return this.cartList.length == this.select.length;
},
total(){
let total = {
price:0,
number:0
}
this.cartList.forEach(v=>{
if( this.select.indexOf( v.id ) != -1 ){
total.price += v.discountPrice * v.counter;
total.number = this.select.length;
}
})
return total;
}
},
actions:{
//获取数据
getCartList( list ){
list.forEach(v=>{
v['check'] = true;
this.select.push( v.id );
})
this.cartList = list;
},
//全选
all(){
this.select = this.cartList.map(v=>{
v['check'] = true;
return v.id;
})
},
//全不选
unAll(){
this.cartList.forEach(v=>{
v['check'] = false;
})
this.select = [];
},
//单选
checkItem( index ){
let id = this.cartList[index].id;
let idx = this.select.indexOf(id);
if( idx > -1 ){
this.cartList[index].check = false;
this.select.splice(idx,1);
}else{
this.cartList[index].check = true;
this.select.push( id );
}
}
},
})
3.6 删除
//element
import { ElMessageBox } from 'element-plus';
import { ElMessage } from 'element-plus';
//删除购物车数据
const del = ( id )=>{
ElMessageBox.confirm('确定删除该课程吗?', '删除', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
createToken().then(res=>{
let token = res.data.token;
deleteShopCar({
id
},token).then(res=>{
if( res.meta.code =='200'){
ElMessage.success({
message: '删除成功!'
});
getShopCarList().then(res=>{
cartStore.cartList = res.data.list;
})
}
})
})
}).catch(() => {
ElMessage.info({
message: '已取消删除'
});
});
}
4 加入购物车
找到CourseInfo.vue组件的加入购物车按钮
<button class="btn-item" @click='addCart'>加入购物车</button>
import { addShopCar } from '@/utils/api/cart'
import { createToken } from '@/utils/api/createToken'
//加入购物车
const addCart = ()=>{
createToken().then(res=>{
let token = res.data.token;
addShopCar({
courseId,
memberId: useUserStore().userInfo.id
},token).then(res=>{
if( res.meta.code =='200' ){
ElMessage.success({
message: '加入购物车成功~'
});
return;
}else{
ElMessage.info({
message: '添加失败~该课程已经在购物车中了!'
});
}
})
})
}
5 进去确认订单页面
5.1、点击【去结算】
//去结算
let router = useRouter();
const goOrder = ()=>{
router.push('/confirmOrder');
}
5.2 页面渲染
进结算 在退出来,发现数量不对了。 因为在pinia里边数量不端push。所以在开头要先赋空
6 确认订单
7 支付宝支付
一、选择支付方式
<span
v-for='item in payModes'
:key='item.code'
@click='tabPayment(item)'
>{{ item.description }}</span>
//选择支付方式
const tabPayment = (item)=>{
payment.description = item.description;
alipayOrder({
courses:cartStore.orderList,
payModes:item.code
}).then(res=>{
payurl.value = res.data.payurl;
console.log( res );
orderNumber.value = res.data.orderNumber;
})
}
获取数据之后,将图片展示出来, 同时记录下订单号
因为不知道多会支付完成,所以要进行短轮询。去查询订单状态
二、确认订单: 去支付-短轮询查询
//[支付宝]短轮询查订单状态
const interPaymentAli = ()=>{
queryOrderWithAli({
orderNumber:orderNumber.value
}).then(res=>{
console.log( res )
if( res.meta.code=='200' ){
clearInterval(timer.value);
}
})
}
//去支付
const goPayment = ()=>{
timer.value = setInterval( interPaymentAli , 3500 );
dialogVisible.value = true;
}
8 微信支付
和支付宝类似
9 支付成功之后
跳转到成功页面, 删除购物车数据(批量删除)