Files
xdd-uniapp-new/pages/order/OrderSubmission/index.vue
T

883 lines
26 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 class="order-submission" style="padding: 30rpx;">
<view class="allAddress" style="background-color: #f6f6f6;">
<view
class="address acea-row row-middle"
style="flex-wrap: nowrap;margin: 0 0 30rpx 0;border-radius: 16rpx;"
v-if="shipping_type === 0"
@click="addressTap"
>
<image style="flex-shrink: 0;width: 48rpx;height: 48rpx;margin-right: 20rpx;"
:src="webUrl+'/20230304135530688212.png'" mode=""></image>
<view class="acea-row row-between-wrapper" style="flex-wrap: nowrap;flex-grow: 1;">
<view class="addressCon" v-if="addressInfo.realName">
<view class="name">
{{ addressInfo.realName }}
<text class="phone">{{ addressInfo.phone }}</text>
</view>
<view>
{{ addressInfo.province }}{{ addressInfo.city }}{{ addressInfo.district }}{{ addressInfo.detail }}
</view>
</view>
<view class="addressCon" v-else>
<view class="setaddress">设置收货地址</view>
</view>
<view class="iconfont icon-jiantou" style="flex-shrink: 0;"></view>
</view>
</view>
<div style="flex-wrap: nowrap;" class="address acea-row row-middle" v-else @click="showStoreList">
<image style="flex-shrink: 0;width: 48rpx;height: 48rpx;margin-right: 20rpx;"
:src="webUrl+'/20230304135530688212.png'" mode=""></image>
<view class="acea-row row-between-wrapper" style="flex-wrap: nowrap;flex-grow: 1;">
<div class="addressCon">
<div class="name">
{{ isNullOrEmpty(storeItems) ? systemStore.name : storeItems.name }}
<span
class="phone"
>{{ isNullOrEmpty(storeItems) ? systemStore.phone : storeItems.phone }}</span>
</div>
<div>{{ isNullOrEmpty(storeItems) ? systemStore.address : storeItems.address }}</div>
</div>
<div class="iconfont icon-jiantou"></div>
</view>
</div>
</view>
<OrderGoods :evaluate="0" :cartInfo="orderGroupInfo.cartInfo" title="商品列表"></OrderGoods>
<view class="wrapper" style="margin: 30rpx 0;border-radius: 16rpx;">
<view class="item acea-row row-between-wrapper" style="flex-wrap: nowrap;" v-if="shipping_type === 0">
<view class="acea-row row-middle" style="flex-wrap: nowrap;">
<image style="width: 32rpx;height: 32rpx;margin-right: 12rpx;" :src="webUrl+'/20210807230820761721.png'"
mode=""></image>
<text class="">快递费用</text>
</view>
<view class="discount" style="width: auto !important;">
{{ orderPrice.payPostage > 0 ? force2Decimal(orderPrice.payPostage) : "免运费" }}
</view>
</view>
<view v-else>
<view class="item acea-row row-between-wrapper">
<view>联系人</view>
<view class="discount">
<input type="text" placeholder="请填写您的联系姓名" v-model="contacts"/>
</view>
</view>
<view class="item acea-row row-between-wrapper">
<view>联系电话</view>
<view class="discount">
<input type="text" placeholder="请填写您的联系电话" v-model="contactsTel"/>
</view>
</view>
</view>
<view class="item" style="z-index: -1">
<view class="acea-row row-middle">
<image style="width: 32rpx;height: 32rpx;margin-right: 12rpx;" :src="webUrl+'/20210807230836494421.png'"
mode=""></image>
<text class="">备注信息150字以内)</text>
</view>
<textarea v-model="mark"></textarea>
</view>
</view>
<view class="wrapper" style="margin: 30rpx 0;border-radius: 16rpx;">
<view class="item">
<!-- <view>支付方式</view> -->
<view class="acea-row row-left row-middle">
<view class="acea-row row-middle" style="position: relative;">
<image style="width: 32rpx;height: 32rpx;margin-right: 12rpx;" :src="webUrl+'/20210807230846995104.png'"
mode=""></image>
<text class="pay-method-title">支付方式</text>
<!-- <text class="pink-dot"></text> -->
</view>
</view>
<view class="list">
<view
class="payItem acea-row row-middle"
:class="active === 'weixin' ? 'on' : ''"
@click="payItem('weixin')"
v-show="isWeixin"
style="flex-wrap: nowrap;"
>
<view class="name acea-row">
<view class="iconfont icon-weixin2" :class="active === 'weixin' ? 'bounceIn' : ''"></view>
微信支付
</view>
<view class="tip">微信快捷支付</view>
<label class="radio">
<radio style="transform: scale(0.7);" value="" :checked="active === 'weixin'" color="#FF0000"/>
<text></text>
</label>
</view>
<view
class="payItem acea-row row-middle"
:class="active === 'weixin' ? 'on' : ''"
@click="payItem('weixin')"
v-show="!isWeixin"
style="flex-wrap: nowrap;"
>
<view class="name acea-row ">
<view class="iconfont icon-weixin2" :class="active === 'weixin' ? 'bounceIn' : ''"></view>
微信支付
</view>
<view class="tip"></view>
<label class="radio">
<radio style="transform: scale(0.7);" value="" :checked="active === 'weixin'" color="#FF0000"/>
<text></text>
</label>
</view>
<view
class="payItem acea-row row-middle"
:class="active === 'yue' ? 'on' : ''"
@click="payItem('yue')"
style="flex-wrap: nowrap;"
>
<view class="name acea-row ">
<view style="background-color: #007AFF;" class="iconfont icon-icon-test"
:class="active === 'yue' ? 'bounceIn' : ''"></view>
余额支付
</view>
<view class="tip">可用余额{{ userInfo.nowMoney ? force2Decimal(userInfo.nowMoney) : 0.00 }}</view>
<label class="radio">
<radio style="transform: scale(0.7);" value="" :checked="active === 'yue'" color="#FF0000"/>
<text></text>
</label>
</view>
</view>
</view>
</view>
<view class="moneyList" style="margin-bottom:30rpx;border-radius: 16rpx;">
<view class="item acea-row row-between-wrapper" v-if="orderPrice.totalPrice !== undefined">
<view>商品总价</view>
<view class="money">{{ force2Decimal(orderPrice.totalPrice) }}</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="orderPrice.payPostage > 0">
<view>运费</view>
<view class="money">{{ force2Decimal(orderPrice.payPostage) }}</view>
</view>
<!-- <view class="item acea-row row-between-wrapper" v-if="orderPrice.couponPrice > 0">
<view>优惠券抵扣</view>
<view class="money">-{{ force2Decimal(orderPrice.couponPrice) }}</view>
</view>
<view class="item acea-row row-between-wrapper" v-if="orderPrice.deductionPrice > 0">
<view>积分抵扣</view>
<view class="money">-{{ force2Decimal(orderPrice.deductionPrice) }}</view>
</view> -->
</view>
<view v-if="canUsePoints" class="coupon-cell">
<view class="flex jc-between ai-center">
<view class="title">积分抵扣</view>
<view class="flex ai-center">
<u-switch
v-model="usePointsCheck"
size="20"
@change="usePointsCheckChange"
/>
</view>
</view>
<view v-if="usePointsCheck" class="flex jc-between ai-center points-cell">
<view>积分{{ orderPrice.usedPoints }}</view>
<view class="flex ai-center">
-{{ force2Decimal(orderPrice.deductionPrice) }}
</view>
</view>
</view>
<view class="coupon-cell flex jc-between ai-center" @click="changeCoupons">
<view class="title">优惠券</view>
<view class="flex ai-center">
<text style="color:#999999" v-if="couponList.usable.length===0"></text>
<view class="flex ai-center" v-else>
<text style="color:#FF564A">{{ couponIndex < 0 ? '去选择' : -couponList.usable[couponIndex].couponPrice }}
</text>
<view class="iconfont icon-jiantou" style="flex-shrink: 0;"></view>
</view>
</view>
</view>
<!-- v9 优惠券开始 -->
<u-popup
:show="show"
:round="10"
mode="bottom"
close-on-click-overlay
@close="changeCoupons"
>
<CouponsPopup
v-if="couponList.usable.length > 0"
:two-list="couponList"
@change="changeCoupons"
/>
</u-popup>
<!-- v9 优惠券结束 -->
<view style="height:80rpx"></view>
<view class="footer acea-row row-between-wrapper" style="height: 80rpx;">
<view style="margin-left: 30rpx;">
<text style="color: #000000;font-size: 24rpx;font-weight: bold;">合计:</text>
<text class="" style="color: #FF564A;font-size: 28rpx;font-weight: bold;">
{{ force2Decimal(orderPrice.payPrice) }}
</text>
</view>
<view class="settlement acea-row row-middle row-center" @click="subscribePay">立即结算</view>
</view>
<AddressWindow
v-model="showAddress"
ref="mychild"
:checked="addressInfo.id"
@checked="changeAddress"
@redirect="addressRedirect"
/>
<passkeyborad
ref='payPwdPop'
showMoney
:money="orderPrice.payPrice"
:show="isShowPayPwdPop"
@close="pwdPopClose"
@finish="pwdPopFinish"
/>
</view>
</template>
<script>
import passkeyborad from '@/components/yzc-paykeyboard/yzc-paykeyboard'
import OrderGoods from "@/components/OrderGoods";
import AddressWindow from "@/components/AddressWindow";
import {createOrder, postOrderComputed, postOrderConfirm} from "@/api/order";
import {mapGetters} from "vuex";
import {weappPay} from "@/libs/wechat";
import {isNullOrEmpty, isWeixin} from "@/utils";
import blPaymentPasswordInput from '@/components/blPaymentPasswordInput.vue';
import uniPopup from '@/components/uni-popup/uni-popup.vue';
import CouponsPopup from "@/components/CouponsPopup.vue"
const NAME = "OrderSubmission",
_isWeixin = isWeixin();
export default {
name: NAME,
components: {
OrderGoods,
AddressWindow,
blPaymentPasswordInput,
uniPopup,
passkeyborad,
CouponsPopup
},
props: {},
data: function () {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
isShowPayPwdPop: false,
offlinePayStatus: 2,
from: this.$deviceType,
deduction: true,
enableIntegral: true,
enableIntegralNum: 0,
isWeixin: _isWeixin,
pinkId: 0,
active: "weixin",
showCoupon: false,
showAddress: false,
addressInfo: {},
orderGroupInfo: {
priceGroup: {}
},
addressLoaded: false,
useIntegral: false,
orderPrice: {
payPrice: "计算中"
},
mark: "",
systemStore: {},
shipping_type: 0,
contacts: "",
contactsTel: "",
storeSelfMention: 0,
cartid: "",
lotteryRecordId:'',
payPassword: null,
// v9-2
couponList: {
unusable: [],
usable: []
},
couponId: uni.getStorageSync('couponId') || 0,
couponIndex: -1,
show: false,
// 是否使用积分开关
usePointsCheck: false,
// 要使用的积分数量(传0为不使用积分,目前需求是默认使用最大可使用的积分,所以只要传大于0的数值都会变为自动使用最大可用积分)
usePointsNumber: 0,
// 订单是否可以使用积分
canUsePoints: false,
// 订单最大可使用积分数量
maxPoints: 0
};
},
computed: mapGetters(["userInfo", "storeItems"]),
watch: {
useIntegral() {
this.computedPrice('useIntegral');
},
shipping_type() {
this.computedPrice('shipping_type');
},
couponId() {
this.couponIndex = this.couponList['usable']?.findIndex(item => item.id === this.couponId)
this.computedPrice('couponId')
}
},
onLoad: function () {
let that = this;
uni.$on('chooseAddress', (res) => {
console.log('监听到选择收货地址:' + JSON.stringify(res));
that.addressInfo = res;
//地址切换也要重新计算一下
that.computedPrice('onLoad chooseAddress');
})
console.log(that.$yroute);
if (that.$yroute.query.pinkid !== undefined) {
that.pinkId = that.$yroute.query.pinkid;
}
if (that.$yroute.query.id !== undefined) {
that.cartid = that.$yroute.query.id;
console.log(that.cartid)
}
if (that.$yroute.query.lotteryRecordId !== undefined) {
that.lotteryRecordId = that.$yroute.query.lotteryRecordId;
}
that.getCartInfo();
},
onUnload: function () {
console.log('关闭监听选择收货地址');
uni.$off('chooseAddress');
},
onShow: function () {
//获取用户信息
this.$store.dispatch("getUser", true);
},
methods: {
isNullOrEmpty,
showStoreList() {
this.$store.commit("get_to", "orders");
this.$yrouter.push({
path: "/pages/shop/StoreList/index"
});
},
force2Decimal(value) {
return this.$force2Decimal(value);
},
usePointsCheckChange(e) {
this.computedPrice()
},
// 计算订单金额
computedPrice(f) {
let shipping_type = this.shipping_type;
postOrderComputed(this.orderGroupInfo.orderKey, {
addressId: this.addressInfo.id,
useIntegral: this.useIntegral ? 1 : 0,
couponId: this.couponId || 0,
usePoints: this.usePointsCheck ? 1 : 0,
shipping_type: parseInt(shipping_type) + 1
}).then(res => {
const data = res.data;
if (data.status === "EXTEND_ORDER") {
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
}
});
} else {
this.orderPrice = data.result;
if (this.usePointsCheck) {
this.usePointsNumber = data.result.usedPoints
} else {
this.usePointsNumber = 0
}
}
});
},
getCartInfo() {
const _this = this
if (!_this.cartid && !_this.lotteryRecordId) {
uni.showToast({
title: "参数有误",
icon: "none",
duration: 2000
})
return this.$yrouter.back()
}
postOrderConfirm(_this.cartid,_this.lotteryRecordId).then(res => {
const { data } = res
_this.offlinePayStatus = data.offline_pay_status
_this.orderGroupInfo = data
_this.deduction = data.deduction
_this.couponList = data.couponList
if (_this.couponId > 0) {
_this.couponList['usable'].map((item, index) => {
if (item.id === _this.couponId) {
item.checked = true
_this.couponIndex = index
} else {
item.checked = false
}
})
uni.removeStorageSync('couponId')
} else {
uni.removeStorageSync('couponId')
}
_this.canUsePoints = data.canUsePoints
_this.maxPoints = data.maxPoints
// 如果允许使用积分,则默认开启
if (data.canUsePoints) {
_this.usePointsCheck = true
_this.usePointsNumber = data.maxPoints
}
_this.addressInfo = data.addressInfo || {}
_this.systemStore = data.systemStore || {}
_this.storeSelfMention = data.storeSelfMention
_this.computedPrice()
}).catch(err => {
uni.showToast({
title: err.msg,
icon: "none",
duration: 2000
})
})
},
addressTap: function () {
//改用跳转页面方式
this.$yrouter.push({
path: "/pages/user/address/AddressManagement/index",
query: {
choosMode: 1
}
});
},
addressRedirect() {
this.addressLoaded = false;
this.showAddress = false;
},
payItem: function (index) {
this.active = index;
},
changeAddress(addressInfo) {
this.addressInfo = addressInfo;
//地址切换也要重新计算一下
this.computedPrice('changeAddress');
},
pwdPopClose() {
this.isShowPayPwdPop = false;
},
pwdPopFinish(payPwd) {
this.payPassword = payPwd;
this.createOrder(true);
},
//支付密码输入监听
onInput(e) {
},
// 支付密码输入确认
onConfirm(e) {
this.payPassword = e.value;
this.$refs.popup.close();//关闭支付密码弹窗
this.$refs.secrity.clear();//清空支付密码
this.createOrder(true);
},
subscribePay() {
uni.requestSubscribeMessage({
tmplIds: ['7O3wKw7_D4t7yfSOlvecKuOQP8QEPY88uBx2FJg43HE', 'TSmTnGibZ8IxWCiRWOvLxha6-0u7tE-V1-WbDCiPkKU', '9Q6xLHe6HyjkU5Zn5k_2zxYPf2y4MxVyUbOSW8pcZRU'],
complete: () => this.createOrder(false)
})
},
createOrder(isyue) {
let shipping_type = this.shipping_type;
if (!this.active) {
uni.showToast({
title: "请选择支付方式",
icon: "none",
duration: 2000
});
return;
}
if (!this.addressInfo.id && !this.shipping_type) {
uni.showToast({
title: "请选择收货地址",
icon: "none",
duration: 2000
});
return;
}
if (this.shipping_type) {
if (
(this.contacts === "" || this.contactsTel === "") &&
this.shipping_type
) {
uni.showToast({
title: "请填写联系人或联系人电话",
icon: "none",
duration: 2000
});
return;
}
if (!/^1(3|4|5|7|8|9|6)\d{9}$/.test(this.contactsTel)) {
uni.showToast({
title: "请填写正确的手机号",
icon: "none",
duration: 2000
});
return;
}
if (!/^[\u4e00-\u9fa5\w]{2,16}$/.test(this.contacts)) {
uni.showToast({
title: "请填写您的真实姓名",
icon: "none",
duration: 2000
});
return;
}
}
//判断如果是余额支付,先要输入支付密码
if (this.active == 'yue' && !isyue) {
//先判断用户是否绑定过手机
if (this.userInfo.phone) {
//再判断用户是否设置过支付密码
if (this.userInfo.hasPwdPay) {
//显示输入支付密码
this.isShowPayPwdPop = true;
} else {
//设置支付密码
this.$yrouter.push("/pkg_user/views/payPassword?isSetMode=true");
}
} else {
//跳转到绑定手机
this.$yrouter.push("/pkg_user/views/bindPhone");
}
return;
}
uni.showLoading({
title: "生成订单中"
});
let from = {};
if (this.$deviceType == "app") {
from.from = "app";
}
console.log(this.storeItems, this.systemStore);
var params = {
realName: this.contacts,
phone: this.contactsTel,
addressId: this.addressInfo.id,
useIntegral: this.useIntegral ? 1 : 0,
couponId: this.couponId || 0,
usePoints: this.usePointsNumber || 0,
payType: this.active,
pinkId: this.pinkId,
seckillId: this.orderGroupInfo.seckill_id,
combinationId: this.orderGroupInfo.combination_id,
bargainId: this.orderGroupInfo.bargain_id,
from: this.from,
mark: this.mark || "",
shippingType: parseInt(shipping_type) + 1,
storeId: this.storeItems ? this.storeItems.id : this.systemStore.id,
...from
}
//余额支付的支付密码
if (this.active == 'yue') {
params.passwordPay = this.payPassword;
}
uni.removeStorageSync('couponId')
var that = this;
createOrder(this.orderGroupInfo.orderKey, params)
.then(res => {
uni.hideLoading();
const data = res.data;
switch (data.status) {
case "ORDER_EXIST":
case "EXTEND_ORDER":
uni.showToast({
title: res.msg,
icon: "none",
duration: 2000
});
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
}
});
break;
case "PAY_DEFICIENCY":
break;
case "PAY_ERROR":
uni.showToast({
title: res.msg,
icon: "none",
duration: 2000
});
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
}
});
break;
case "SUCCESS":
uni.showToast({
title: res.msg,
icon: "none",
duration: 2000
});
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
}
});
break;
case "WECHAT_H5_PAY":
// H5支付
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
}
});
setTimeout(() => {
// location.href = data.result.jsConfig.mweb_url;
}, 100);
break;
case "WECHAT_PAY":
// 小程序支付
weappPay(data.result.jsConfig).finally(() => {
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
}
});
});
break;
case "WECHAT_APP_PAY":
// APP支付
weappPay(data.result.jsConfig).finally(() => {
this.$yrouter.replace({
path: "/pages/order/OrderDetails/index",
query: {
id: data.result.orderId
}
});
});
break;
}
})
.catch(err => {
uni.hideLoading();
uni.showToast({
title:
err.msg ||
err.response.data.msg ||
err.response.data.message ||
"创建订单失败",
icon: "none",
duration: 2000
});
}).finally(function () {
that.isShowPayPwdPop = false;
that.$refs.payPwdPop.clear();//清空支付密码
that.$refs.payPwdPop.close();//关闭支付密码弹窗
});
},
// v9-2
changeCoupons() {
if (this.couponList.usable.length === 0) return
this.show = !this.show
this.couponId = uni.getStorageSync('couponId') || 0
},
}
};
</script>
<style scoped lang="less">
.pink-dot {
width: 24rpx;
height: 24rpx;
background: rgba(255, 86, 74, 0.4);
border-radius: 50%;
position: absolute;
z-index: 0;
bottom: 0;
right: -12rpx;
}
.pay-method-title {
font-size: 26rpx;
color: #080F1A;
font-weight: bold;
}
.goods-detail-title {
font-size: 36rpx;
color: #C2C5CC;
font-weight: bold;
}
.goods-detail-title.on {
color: #080F1A;
font-weight: normal;
}
.order-submission .footer {
background: #fff;
left: 0;
right: 0;
bottom: 0;
border-top: 1px solid #f6f6f6;
padding: 0 !important;
}
.order-submission .footer .settlement {
background-color: #FF564A;
color: #fff;
width: 198rpx;
height: 100%;
border-radius: 0 !important;
text-align: center;
}
.order-submission .wrapper .item .list .payItem {
border: none !important;
}
.order-submission .wrapper .item .list .payItem.on {
border-color: #eee !important;
color: inherit !important;
}
.order-submission .wrapper .shipping select {
color: #999;
padding-right: 0.15 * 100rpx;
}
.order-submission .wrapper .shipping .iconfont {
font-size: 0.3 * 100rpx;
color: #515151;
}
.order-submission .allAddress {
width: 100%;
}
.order-submission .allAddress .nav {
margin: 0 auto;
padding: 0 30rpx;
width: 100%;
box-sizing: border-box;
}
.order-submission .address .addressCon {
width: auto !important;
}
.order-submission .allAddress .nav .item {
flex: 1;
position: relative;
}
.order-submission .allAddress .nav .item.on {
position: relative;
}
.order-submission .allAddress .nav .item.on:before {
position: absolute;
bottom: 0;
content: "快递配送";
font-size: 0.28 * 100rpx;
display: block;
height: 0;
left: 0;
right: 0;
border-width: 0.4 * 100rpx;
border-style: solid;
border-color: #fff;
z-index: 9;
text-align: center;
line-height: 0.14 * 100rpx;
}
.order-submission .allAddress .nav .item:nth-of-type(2).on:before {
content: "到店自提";
border-width: 0.4 * 100rpx;
}
.order-submission .allAddress .nav .item.on2 {
position: relative;
}
.order-submission .allAddress .nav .item.on2:before {
position: absolute;
bottom: 0;
content: "到店自提";
font-size: 0.28 * 100rpx;
display: block;
height: 0;
left: 0;
right: 0;
border-width: 0.4 * 100rpx;
border-style: solid;
border-color: #d5e6e6;
text-align: center;
line-height: 0.14 * 100rpx;
}
.order-submission .allAddress .nav .item:nth-of-type(1).on2:before {
content: "快递配送";
border-width: 0.4 * 100rpx;
}
.order-submission .allAddress .address {
width: 6.91 * 100rpx;
height: 1.5 * 100rpx;
margin: 0 auto;
box-sizing: border-box;
}
.order-submission .allAddress .line {
width: 7.1 * 100rpx;
margin: 0 auto;
}
.order-submission .wrapper .item .discount input::placeholder {
color: #ccc;
}
.coupon-cell {
margin-top: 12rpx;
padding: 30rpx;
border-radius: 16rpx;
background-color: #FFFFFF;
font-size: 24rpx;
}
.points-cell {
padding: 20rpx 0 0 0;
color: #999;
}
</style>