You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
zhishifufei_uniapp/pages/special/confirm_order.vue

801 lines
20 KiB

10 months ago
<template>
<BaseContainer class="order-confirm">
<NavBar title="提交订单" />
<template v-if="cartInfo && cartInfo.length">
<view class="contact" @click="addressCheck">
<view>
<template v-if="addressChecked">
<template v-for="item in address">
<template v-if="item.id === addressChecked">
<view :key="item.id">
<text>{{ item.real_name }}</text>
<text>{{ item.phone }}</text>
</view>
<view class="address">
<text>[默认]</text>
<text>{{ item.province }}{{ item.city }}{{ item.district
}}{{ item.detail }}</text>
</view>
</template>
</template>
</template>
<template v-else>选择收货地址</template>
</view>
<view class="iconfont iconxiangyou"></view>
</view>
<view class="content">
<view class="goods">
<view v-for="item in cartInfo" :key="item.id" class="item">
<view>
<image mode="aspectFit" :src="item.productInfo.image" />
</view>
<view class="item-bd">
<view class="name">{{ item.productInfo.store_name }}</view>
<view class="wrap">
<view class="money">
{{
level ? item.productInfo.vip_price : item.productInfo.price
}}
</view>
<view class="count">
<view class="button flex flex-center" :class="{
disabled: item.cart_num === 1,
}" @click="setNum(item, false)">
10 months ago
-
</view>
<input v-model.number="item.cart_num" type="number" readonly />
10 months ago
<view class="button flex flex-center" :class="{
disabled: item.cart_num === item.productInfo.stock,
}" @click="setNum(item, true)">
10 months ago
+
</view>
</view>
</view>
</view>
</view>
</view>
<view class="postage">
<view>邮费</view>
<view>{{ postage }}</view>
</view>
9 months ago
<!-- <view class="deduct">
10 months ago
<view>{{ goldName }}抵扣</view>
<view>
当前{{ goldName }}
<text style="margin-left: 0.5em">{{ goldNum }}</text>
</view>
<view v-if="goldNum" :class="[
useGold ? 'iconxuanzhong1' : 'iconweixuanzhong',
'iconfont2',
]" @click="useGold = !useGold"></view>
9 months ago
</view> -->
</view>
10 months ago
<view class="remark">
<view>备注信息</view>
<textarea auto-height placeholder-style="color: #ccc" v-model="signs.mark" placeholder="选填备注信息"></textarea>
</view>
<view class="footer flex flex-center-x">
<view class="message">
<view class="message-bd">
{{ number }}合计
<view class="money"><text></text>{{ total }}</view>
</view>
<!-- <view v-if="useGold" class="message-ft">抵扣减{{ diko }}</view> -->
10 months ago
</view>
<view class="submit-btn flex flex-center" @click="pay">立即结算</view>
</view>
<view :class="{ mask: popupShow }" @click="popupShow = false"></view>
<!-- 地址弹窗 -->
<view class="popup" :class="{ on: popupShow }">
<view class="close-button" @click="popupShow = false"></view>
<view class="head">选择地址</view>
<view class="cont">
<view class="pick-label" v-for="item of address" :key="item.id" @click="handlePickAddress(item.id)">
<view :class="{ active: item.id == addressChecked }">
<view>{{ item.real_name }} {{ item.phone }}</view>
<view>
{{ item.province }}{{ item.city }}{{ item.district
}}{{ item.detail }}
</view>
</view>
</view>
</view>
<view class="foot">
<view class="choose-other-btn" @click="go_address">选择其他地址</view>
</view>
</view>
<!-- 支付弹窗 -->
<PayDialog :open.sync="payDialogOpen" :signs="signs" :money="Number(totals)" :now_money="Number(now_money)"
:special_id="addressChecked" :pay_type_num="pay_type_num" :is-wechat="isWechat" :is-alipay="Boolean(is_alipay)"
:is-balance="isyue" :template-id="templateId" :isMember="level ? true : false"
:memberMoney="Number(vip_price_subtract)" :wxpay-h5="wxpayH5" :use-gold="useGold" @change="changeVal" />
<web-view v-if="urls" :src="urls"></web-view>
</template>
</BaseContainer>
</template>
<script>
import {
getConfirmOrderInfo,
getOrderPrice,
getSpecialTemplateIds,
aliPayApp,
aliPayWap
} from "@/api/special";
import { getUserAddressList } from "@/api/auth";
import PayDialog from "@/components/PayDialog/index.vue";
export default {
components: {
PayDialog,
},
data() {
return {
cartId: null,
isWechat: false,
loginShow: false,
site_name: "",
payDialogOpen: false, // 是否显示支付弹窗
pay_type_num: 40,
pinkId: "",
link_pay_uid: "",
isyue: true, //余额是否开启
is_alipay: true, //支付宝是否开启
now_money: 0, //余额
cartInfo: [],
priceGroup: {},
popupShow: false,
totalPrice: 0,
address: [],
addressChecked: 0,
totals: 0,
postages: 0,
orderKey: "",
signs: {
key: "",
mark: "",
},
templateId: "",
wxpayH5: false,
level: 0,
useGold: false,
goldNum: 0,
ratio: 0,
number: 0,
goldName: '',
urls: '',
isOpenWeixing: false,
vip_price_subtract: 0,//下单时提示开会员减金额
};
},
onLoad({ cartId }) {
this.cartId = cartId;
this.getData().then(this.getAddress);
},
onShow() {
if (this.isOpenWeixing && this.orderId) {
this.$util.wxh5PayIsSuccess(this.orderId, 1, this)
this.isOpenWeixing = false
}
},
computed: {
url() {
return this.isWechat ? "/pages/index/login" : "/pages/login/phone_check";
},
total() {
if (!this.cartInfo || !this.cartInfo.length) {
return;
}
let sum = 0;
this.cartInfo.length > 0 && this.cartInfo.forEach(v => {
sum += Number(v.cart_num) * Number(this.level ? v.productInfo.vip_price : v.productInfo.price);
});
this.totals = sum;
10 months ago
this.totals = this.$util.Add(this.totals, this.postages);
this.totals = this.$util.Sub(
this.totals,
this.useGold ? this.$util.Mul(this.goldNum, this.ratio) : 0
);
if (this.totals < 0) {
this.totals = 0;
}
return this.totals;
},
postage() {
if (!this.cartInfo || !this.cartInfo.length) {
return;
}
let sumPostages = 0;
this.cartInfo.forEach(v => {
if (
!v.productInfo.is_postage &&
(v.productInfo.free_shipping === 0 ||
v.productInfo.free_shipping >= v.cart_num)
) {
sumPostages += Number(v.productInfo.postage);
}
});
this.postages = sumPostages;
return this.postages === 0 ? '包邮' : `${this.postages}`;
10 months ago
},
diko() {
if (!this.cartInfo || !this.cartInfo.length) {
return;
}
let totals = this.$util.Mul(
this.cartInfo[0].productInfo[this.level ? "vip_price" : "price"],
this.number
);
totals = this.$util.Add(totals, this.postages);
let goldTotals = this.$util.Mul(this.goldNum, this.ratio);
if (totals >= goldTotals) {
return goldTotals;
} else {
return totals;
}
},
},
watch: {
addressChecked() {
this.popupShow = false;
this.subscribeTemplate();
},
cartInfo: {
deep: true,
handler() {
let total = 0;
if (this.cartInfo && this.cartInfo.length > 0) {
this.cartInfo.forEach(v => {
total += Number(v.cart_num || 0);
})
}
this.number = total;
},
},
10 months ago
},
methods: {
handlePickAddress(id) {
this.addressChecked = id;
this.popupShow = false;
},
setNum(item, type) {
10 months ago
if (type) {
// add
item.cart_num++;
} else if (!type && item.cart_num > 1) {
10 months ago
// sub
item.cart_num--;
10 months ago
}
},
async getData() {
uni.showLoading({ mask: true });
try {
const { data } = await getConfirmOrderInfo(this.cartId);
uni.hideLoading();
Object.assign(this, {
...data,
goldNum: data.gold_num,
goldName: data.gold_name,
signs: {
key: data.orderKey,
mark: "",
},
});
let total = 0;
if (data.cartInfo && data.cartInfo.length > 0) {
data.cartInfo.forEach(v => {
total += Number(v.cart_num || 0);
})
}
this.number = total;
10 months ago
} catch (err) {
uni.hideLoading();
this.$util.showMsg(err.msg);
}
},
subscribeTemplate() {
getSpecialTemplateIds(this.pay_type_num, this.addressChecked).then(
({ msg }) => {
this.templateId = msg;
}
);
},
async getAddress() {
uni.showLoading({ mask: true });
try {
const { data } = await getUserAddressList();
uni.hideLoading();
this.address = data;
let result = data.find((value) => value.is_default);
if (result) {
this.addressChecked = result.id;
}
} catch (err) {
uni.hideLoading();
this.$util.showMsg(err.msg);
}
},
addressCheck() {
if (this.address.length) {
this.popupShow = true;
} else {
this.go_address();
}
},
go_address() {
this.getOrderPrice(1);
},
async getOrderPrice(n) {
uni.showLoading({ mask: true });
const numArr = [];
this.cartInfo.forEach(v => {
numArr.push(v.cart_num);
});
10 months ago
try {
const { data } = await getOrderPrice(this.cartId, numArr.join(','));
10 months ago
uni.hideLoading();
if (n) {
uni.navigateTo({
url: "/pages/my/edit_address?cartId=" + this.cartId,
});
} else {
this.signs.key = data.orderKey;
this.priceGroup = data.priceGroup;
this.payDialogOpen = true;
this.vip_price_subtract = data.vip_price_subtract; //下单时提示开会员减金额
}
} catch (err) {
this.nullProduct(err.msg)
uni.hideLoading();
}
},
pay() {
if (!this.addressChecked) {
return this.$util.showMsg("请选择收货地址");
}
this.$util.checkLogin(() => {
this.getOrderPrice(0);
});
},
pay_order(data) {
this.orderId = data.data.result.orderId || "";
switch (data.data.status) {
case "PAY_ERROR":
case "ORDER_EXIST":
case "ORDER_ERROR":
this.extendOrder(data.msg);
break;
case "EXTEND_ORDER":
this.extendOrder(data.msg);
break;
case "WECHAT_PAY":
this.wechatPay(data.data.result.jsConfig);
break;
case "WECHAT_ROUTINE_PAY":
this.$util.wechatRoutinePay(data.data.result.jsConfig, this);
break;
case "WECHAT_H5_PAY":
this.payDialogOpen = false;
this.$util.wechatH5Pay(data.data.result.jsConfig, this);
break;
case "SUCCESS":
this.successOrder(data.msg);
break;
case "ZHIFUBAO_PAY":
this.aliPay(data.data.result, 'goods')
break;
case 'TOUTIAO_PAY':
this.$util.toutiaoPay(data.data.result.jsConfig, this);
break;
case 'KUAISHOU_PAY':
this.$util.kuaishouPay(data.data.result.jsConfig, this);
break;
}
},
aliPay(msn, type) {
this.$util.aliPay(msn, type, this)
},
wechatPay: function (config) {
this.$util.weixinpay(config, this)
},
successOrder(msg) {
this.$util.showMsg(msg ? msg : "支付成功", 'success');
this.$util.refreshPage("/pages/special/order_store_list?type=1")
},
extendOrder(msg) {
if (typeof msg === "object") {
if (msg.errMsg === "chooseWXPay:cancel") {
msg = "微信支付取消";
} else {
msg = "支付失败";
}
} else {
msg = "支付失败";
}
this.$util.showMsg(msg, 'error');
this.$util.refreshPage("/pages/special/order_store_list?type=0")
},
nullProduct(msg) {
this.$util.showMsg(msg);
this.$util.refreshPage("/pages/special/order_store_list?type=0")
},
enter() {
this.loginShow = true;
},
//关闭登录
loginClose(value) {
this.loginShow = false;
value && this.logComplete();
},
//登录完成回调事件
logComplete() {
this.loginShow = false;
},
changeVal(opt) {
if (typeof opt != "object") opt = {};
var action = opt.action || "";
var value = opt.value || "";
this[action] && this[action](value);
},
},
};
</script>
<style>
page {
background-color: #f5f5f5;
}
</style>
<style scoped lang="scss">
.order-confirm .contact>view:first-child {
flex: 1;
}
.order-confirm .contact>view>view:first-child {
font-weight: bold;
font-size: 30rpx;
color: #282828;
}
.order-confirm .contact text {
vertical-align: middle;
}
.order-confirm .contact text+text {
margin-left: 30rpx;
}
.order-confirm .contact .address {
margin-top: 12rpx;
font-size: 26rpx;
color: #666;
}
.order-confirm .contact .address text text {
margin-left: 15rpx;
}
.order-confirm .contact .address text:first-child {
color: #ff4a4a;
}
.order-confirm .content {
margin-top: 12rpx;
background-color: #ffffff;
}
.order-confirm .goods .item {
display: flex;
padding: 20rpx 30rpx;
}
.order-confirm .goods image {
display: block;
width: 140rpx;
height: 140rpx;
border-radius: 10rpx;
object-fit: contain;
}
.order-confirm .goods .item-bd {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
padding-left: 20rpx;
}
.order-confirm .goods .name {
-webkit-line-clamp: 2;
overflow: hidden;
font-size: 28rpx;
line-height: 39rpx;
color: #333333;
}
.order-confirm .goods .wrap {
display: flex;
align-items: center;
}
.order-confirm .goods .money {
flex: 1;
font-weight: 500;
font-size: 32rpx;
line-height: 45rpx;
color: #ff6b00;
}
.order-confirm .goods .count {
display: flex;
}
.order-confirm .goods .count .button {
width: 40rpx;
height: 40rpx;
text-align: right;
font-weight: bold;
font-size: 22rpx;
color: #282828;
}
.order-confirm .goods .count .button:first-child {
text-align: left;
}
.order-confirm .goods .count .button.disabled {
color: #dedede;
}
.order-confirm .goods .count input {
width: 68rpx;
height: 40rpx;
border-radius: 2rpx;
background-color: #f2f2f2;
text-align: center;
font-size: 22rpx;
color: #282828;
}
.order-confirm .content .postage {
display: flex;
align-items: center;
height: 96rpx;
padding: 0 30rpx;
font-size: 30rpx;
color: #999999;
}
.order-confirm .content .postage view:first-child {
flex: 1;
color: #333333;
}
.order-confirm .content .deduct {
display: flex;
align-items: center;
height: 96rpx;
padding: 0 30rpx;
border-top: 1px solid #f2f2f2;
font-size: 30rpx;
color: #999999;
}
.order-confirm .content .deduct view:first-child {
flex: 1;
color: #333333;
}
.order-confirm .content .deduct text {
font-size: 32rpx;
color: #ff6b00;
}
.order-confirm .content .deduct .iconfont2 {
margin-left: 20rpx;
font-size: 38rpx;
color: #cccccc;
cursor: pointer;
}
.order-confirm .content .deduct .iconxuanzhong1 {
color: #2c8eff;
}
.order-confirm .remark {
display: flex;
padding: 22rpx 30rpx;
margin-top: 12rpx;
background-color: #ffffff;
font-size: 30rpx;
line-height: 42rpx;
color: #333333;
}
.order-confirm .remark textarea {
flex: 1;
margin-left: 20rpx;
font-size: 28rpx;
line-height: 40rpx;
resize: none;
min-height: 4em;
}
.order-confirm .footer {
position: fixed;
right: 0;
bottom: 0;
left: 0;
z-index: 54;
padding-right: calc(30rpx + constant(safe-area-inset-right));
padding-right: calc(30rpx + env(safe-area-inset-right));
padding-bottom: var(--safe-bottom);
padding-left: calc(30rpx + constant(safe-area-inset-left));
padding-left: calc(30rpx + env(safe-area-inset-left));
background-color: #ffffff;
}
.order-confirm .footer .message {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
height: 100rpx;
}
.order-confirm .footer .message-bd {
font-size: 28rpx;
line-height: 40rpx;
color: #333333;
}
.order-confirm .footer .money {
display: inline;
color: #ff5656;
}
.order-confirm .footer .money text {
font-size: 20rpx;
}
.order-confirm .footer .message-ft {
font-size: 20rpx;
color: #999999;
}
.order-confirm .footer .submit-btn {
width: 240rpx;
height: 70rpx;
border-radius: 35rpx;
margin-left: 30rpx;
background: linear-gradient(90deg, #409dff 0%, #1e85fb 100%);
font-size: 30rpx;
color: #ffffff;
}
.order-confirm .popup {
position: fixed;
bottom: 0;
left: 0;
z-index: 99;
display: flex;
flex-direction: column;
width: 100%;
height: 920rpx;
border-top-left-radius: 16rpx;
border-top-right-radius: 16rpx;
background-color: #ffffff;
transform: translateY(100%);
transition: 0.3s;
}
.order-confirm .popup.on {
transform: translateY(0);
}
.order-confirm .popup .head {
height: 100rpx;
font-weight: bold;
font-size: 32rpx;
line-height: 100rpx;
text-align: center;
color: #282828;
}
/* 提交订单 */
.order-confirm .contact {
display: flex;
align-items: center;
min-height: 140rpx;
padding: 30rpx;
background: #ffffff url("@/static/images/address-line.jpg") left top/749rpx 3rpx repeat-x;
cursor: pointer;
}
.order-confirm .popup .pick-label>view {
padding: 30rpx 126rpx 30rpx 60rpx;
background: url("@/static/icon/address.png") left center/33rpx no-repeat;
font-size: 25rpx;
color: #343434;
&.active {
background: url("@/static/icon/address2.png") left center/33rpx no-repeat,
url("@/static/icon/bingo.png") right center/28rpx no-repeat;
color: #2a8eff;
}
}
.order-confirm .popup .cont {
flex: 1;
-webkit-overflow-scrolling: touch;
overflow: auto;
}
.order-confirm .popup .pick-label {
display: block;
padding-right: 30rpx;
padding-left: 30rpx;
}
.order-confirm .popup .pick-label+.pick-label {
border-top: 1px solid #eee;
}
.order-confirm .popup .close-button {
position: absolute;
top: 50rpx;
right: 30rpx;
width: 28rpx;
height: 28rpx;
background: url("@/static/icon/wrong.png") center/cover no-repeat;
transform: translateY(-50%);
}
.order-confirm .popup .pick-label>view view:first-child {
margin-bottom: 12rpx;
font-weight: bold;
font-size: 28rpx;
color: #282828;
}
.order-confirm .popup .foot {
padding: 56rpx 30rpx;
}
.order-confirm .popup .foot .choose-other-btn {
display: block;
width: 100%;
height: 86rpx;
border-radius: 43rpx;
background-color: #2a8eff;
font-weight: bold;
font-size: 30rpx;
line-height: 86rpx;
text-align: center;
color: #ffffff;
}
</style>