德文
只放部分代码,详细请看源码
购物车
购物车有2部分需要注意的点,一部分是同步购物车(登录状态与未登录状态),一部分是对订单分享的处理。
同步购物车
未登录状态
未登录状态是将数据储存到所有数据储存到vuex中进行数据持久化处理,不需要调用接口,同一个浏览器,可以长其使用之前的数据
登录状态
加入购物车调用 cart/add
接口,需要传商品id, 商品数量(num),报告版本(price_edition),请求失败,提示错误信息,请求成功,将数据存入到vuex当中去,下面代码是报告详情添加到购物车,因为需要选择版本所以不能直接传 this.viewDetails
,
if (this.$store.state.token) {
this.$ajaxPost("cart/add", {
id: this.viewDetails.id,
num: "1",
price_edition: this.price.id,
}).then((res) => {
console.log("列表", res);
if (res.code == 10022) {
this.$message({
message: res.message,
type: "error",
offset: 200,
});
}
if (res.code == 0) {
//弹出加入购物车成功弹窗
this.addToCarSuccessfully = true;
let obj = {
category: this.viewDetails.category,
name: this.viewDetails.name,
goods_id: this.viewDetails.id,
price_id: this.price.id,
price_name: this.price.edition,
usdPrice: this.price.usdPrice, //价格问题
url: this.viewDetails.url,
thumb: this.viewDetails.thumb,
number: 1,
price_edition: this.price.id,
discount_amount: this.viewDetails.discount_amount,
discount: this.viewDetails.discount,
};
console.log("obj", obj, this.getCartLists);
let cartList = this.getCartLists.slice();
// .slice()数组深拷贝,VUEX就报错,不能直接操作state里面的属性,但是可以创建一个副本
let datas = {
// ...data,
...obj,
};
cartList.push(datas);
this.$store.commit("setCartInfor", cartList);
}
});
}
登录状态是使用后台接口的数据,来进行操作的包括增删改查,都是一些简单的数据处理,唯一的问题就是需要跟后台沟通好,传递的参数类型需要好好沟通。(比如删除没有沟通好耽误很长的时间)
if (!this.$store.state.token) {
console.log("未登录");
this.removeState(rows);
this.$message({
message: "Successfully deleted",
type: "success",
offset: 200,
});
} else {
console.log("已登录", this.cartList);
let id = [];
let ids = [];
for (let i = 0; i < this.cartList.length; i++) {
for (let o = 0; o < rows.length; o++) {
console.log("已登录", rows[o], this.cartList[i]);
if (this.cartList[i].id == rows[o].id) {
id.push(rows[o].id);
ids.push({
goods_id: rows[o].id,
price_edition: rows[o].price_edition,
});
}
}
}
console.log("传入接口的id", id);
// id = id.toString();
this.$ajaxPost("cart/delete", {
ids: id,
}).then((res) => {
console.log(res);
if (res.code == 0) {
// this.removeState(rows);
this.$message({
message: "Successfully deleted",
type: "success",
offset: 200,
});
this.getcart();
// console.log(res);
console.log("同步vuex的id", ids);
this.removeState(ids);
// this.$store.commit("setCartInfor", cartList);
} else {
this.$message({
message: res.message,
type: "error",
offset: 200,
});
}
});
同步登录与未登录
如果用户在未登录的情况下添加到购物车中,登录后需要进行数据同步,调用/cart/sync
接口来将商品的id,数量,以及版本传递给后台进行数据的合并
const removeDuplicateObj = (val) => {
// 缓存用于记录
const newArr = [];
for (const t of val) {
// 检查缓存中是否已经存在
// console.log(t);
if (
newArr.find(
(c) =>
c.goods_id == t[0].goods_id &&
c.price_edition == t[0].price_edition
)
) {
// 已经存在说明以前记录过,现在这个就是多余的,直接忽略
continue;
}
// 不存在就说明以前没遇到过,把它记录下来
newArr.push(t[0]);
}
// 记录结果就是过滤后的结果
return newArr;
};
let CartData = removeDuplicateObj(val);
console.log(CartData);
if (this.$store.state.cartList.length > 0) {
console.log(1);
//请求是在vuex中进行的
this.$store.dispatch("handleSynCart", CartData);
console.log(this.$store.state.cartList);
} else {
console.log(2);
this.$store.dispatch("handleCar");
}
this.$router.go(-1);
// console.log("99999999", res.data);
} else {
this.$nextTick(() => {
// 以服务的方式调用的 Loading 需要异步关闭
setTimeout(() => this.$nuxt.$loading.finish(), 500);
});
this.$message({
message: res.message,
type: "warning",
});
}
注意:
登录的情况下,数据的改变也需要对vuex中的数据进行修改,因为购物车左上角的小红点是按vuex中购物车的数量来进行计算的
分享
分享大部分都需要在订单页进行处理,购物车页面只需要用btoa()将商品数据转换成二进制字符串,拼接到链接上,添加name来判断是购物车的状态还是直接付款的状态,同时把购物车的数据存到vuex中的订单列表里。
buyNow(data) {
console.log("去购买");
console.log(data);
this.$router.push({
name: "Pay2",
params: {
product_id: window.btoa(data.id),
price_edition: window.btoa(data.price_edition),
languageIndex: window.btoa(0),
},
});
this.$store.commit("setOrderList", [data]);
},
订单***
订单需要注意的点非常多,整个网页的难点基本上都在订单页面。
添加订单
添加订单分为六种(细分有八种),分别为未登录通过报告列表直接付款,未登录通过报告详情直接付款,未登录通过购物车直接付款(购物车的商品可能是报告列表或者报告详情的,vuex中的数据会不一样,需要注意),登录通过报告列表直接付款,登录通过报告详情直接付款,登录通过购物车直接付款。
未登录直接下单
未登录通过报告列表直接付款与未登录通过报告详情直接付款很类似,但也不完全相同,并且需要做分享的处理,和购物车类似用btoa()将商品数据转换成二进制字符串,拼接到链接上,报告详情的数据要注意,数据不同key名可能不同,并且需要选择版本,将这些数据存到vuex中(不需要用订单列表接口),
登录直接下单
登录直接下单实际上和未登录的类似,唯一需要注意的是数据回显问题,用户信息回显,优惠券的处理,稍后再进行处理
buyNow(data) {
console.log("去购买");
console.log(window.btoa(this.price.id));
this.$router.push({
name: "Pay",
params: {
product_id: window.btoa(data.id),
price_edition: window.btoa(this.price.id),
languageIndex: window.btoa(this.currentLan),
},
});
let price_cont = {
goods_id: data.id,
price_name: this.price.edition,
usdPrice: this.usdPrice.price, //价格问题,加入的是原价
number: 1,
// product_number: data.number,
price_edition: this.price.id,
};
let datas = {
...data,
...price_cont,
};
console.log("datas", datas);
this.$store.commit("setOrderList", [datas]);
},
未登录直接下单&&登录直接下单的分享
上面分享提到过了,不给予赘述。
分享***
直接付款分享
分享的思路就是将之前传过来的二进制字符串进行解密(传的数据是报告列表接口需要的参数,看到这就基本上明白了吧)没错!就是将解密出来的数据通过报告详情的接口,不用vuex中的数据,重新请求拿到订单所需要的数据,(注意:需要拿到的价格需要计算是否打折)。
购物车分享
购物车分享的思路和直接付款的相同,但也不完全相同,购物车需要调用的接口不用报告详情的了,用购物车详情的接口,直接把解密出的购物车数据存到vuex中
if (this.$route.name == "Pay2") {
console.log(this.$route.params, this.$route);
console.log(window.atob(this.$route.params.list));
// JSON.parse(JSON.stringify(res.data))
console.log(JSON.parse(window.atob(this.$route.params.list))); //数组
let params = JSON.parse(window.atob(this.$route.params.list));
console.log(params);
this.$ajaxPost("cart/share", {
cart: JSON.parse(JSON.stringify(window.atob(this.$route.params.list))),
}).then((res) => {
console.log(11111111, res);
this.$store.commit("setOrderList", res.data);
this.calculate();
if (this.$store.state.orderList) {
console.log("订单", this.$store.state.orderList);
if (this.$store.state.orderList.list) {
let counts = 0;
let num = 0;
this.$store.state.orderList.list.forEach((item) => {
console.log(item.usdPrice, item.number);
counts += Number(item.number);
num += Number(item.usdPrice * item.number);
console.log(num, counts);
this.pic.push(num, counts);
});
console.log(this.pic[this.$store.state.orderList.list.length - 1]);
this.$nextTick(() => {
this.pic[this.$store.state.orderList.list.length - 1];
});
return this.$nextTick(() => {
this.pic[this.$store.state.orderList.list.length - 1];
});
} else {
let counts = 0;
let num = 0;
let arr = [];
this.$store.state.orderList.forEach((item) => {
console.log(num);
console.log(item.usdPrice);
counts += Number(item.number);
num += Number(item.usdPrice * item.number);
console.log(num, counts);
arr.push(num, counts);
});
console.log(this.total, counts);
console.log(this.pic);
console.log(arr[arr.length - 2]);
this.pic = [arr[arr.length - 2], arr[arr.length - 1]];
return this.$nextTick(() => {
this.pic;
});
}
}
});
}
数据回显
用户信息的回显非常简单,判断vuex中是否有token,有就将vuex中的userinfo数据拿出来进行回显,值得注意就是要和同事沟通好,这个需要登录后才能拿到。
优惠券**
优惠券有多种状态:(状态非常多,按步骤走,不然非常非常乱)
1.用户未登录,输入优惠券码获取优惠券,分为百分比优惠券,直减优惠券,超额优惠券,
2.用户未登录,如果直减优惠券的价格大于商品的价格,为超额状态,价格无变化。
3.如果未使用,则添加到优惠券列表里,
4.用户登录,不需输入优惠券码,自动选择最优优惠券,
5.用户登录,如果优惠券直减价格大于商品价格,优惠券列表不反回该优惠券,故无法使用
6.用户登录,并且优惠券列表有优惠券,且关掉最优优惠券,点击input框,显示优惠券列表。
7.用户登录,并且有优惠券,且商品自带打折
8.用户未登录,商品自带打折
9.用户登录,有优惠券,输入优惠券码
总价计算**
计算并不复杂,复杂的是有非常多的情况,不一一解释了,如上所述
支付***
支付的情况分为四种,登录直接下单,登录购物车下单,未登录直接下单,登录购物车下单,所需传递的参数都不一样。需要调用 /order/create-and-pay
接口传参,传递的参数详细看接口文档。
支付需要很多处理,需要做轮循,来进行判断订单状态,并且需要调用这个接口is-order-create
来判断订单是否创建成功,需要调用这个接口is-order-pay
来判断订单是否支付成功。 订单状态分为三种:订单创建失败,订单创建成功未付款,订单创建成功已付款。(注意:订单发送请求的方式也很特殊,需要用原生js的方法再页面拼一个form表单来发送请求,目的是为了打开一个新的页面,不会影响之前的页面),如果支付失败(超时):会弹出一个提示,支付成功会跳转到支付成功页面。
this.payState = 2;
this.$nextTick(() => {
this.$nuxt.$loading.start();
});
// console.log('let data = this.orderGoodsData;');
// console.log(this.orderGoodsData);
let data = this.orderGoodsData;
console.log(this.getLoginCode);
console.log(data);
// debugger;
if (!this.getLoginCode) {
console.log(this.userDetails);
let userData = {
position_id: this.userDetails.ids[0],
first_name: this.userDetails.first_name,
last_name: this.userDetails.last_name,
email: this.userDetails.email,
phone: this.userDetails.phone,
company: this.userDetails.company,
country_id: this.userDetails.country_id,
channel_id: this.userDetails.channel_id,
};
data = {
...data,
...userData,
};
}
console.log(data);
// let token = getToken();
let token = this.$store.state.token;
var temp_order_id =
token + parseInt(Math.random() * (999 - 100 + 1) + 100, 10); // 100 - 999 的随机数
var actionUrl = "api/order/create-and-pay";
var form1 = document.createElement("form");
var form_id = "form_" + new Date().getTime();
form1.id = form_id;
form1.name = form_id;
form1.action = actionUrl;
form1.method = "POST";
form1.target = "_blank";
let input;
data.temp_order_id = temp_order_id;
data.token = token;
for (let i in data) {
input = document.createElement("input");
input.type = "hidden";
input.name = i;
input.value = data[i];
form1.appendChild(input);
}
document.body.appendChild(form1);
this.$refs.butPay.$el.setAttribute("form", form_id);
sessionStorage.removeItem("enterLoginStatus");
console.log(form1, form_id);
支付成功
支付成功也没有什么要注意的,就是一些样式的问题和计算问题.
\