suke-mp/src/pages/mall/subs/order/order-confirm.vue

547 lines
14 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>
<scroll-view scroll-y>
<view class='content'>
<view class='c-flex-row'>
<view class='tab c-flex-row' :class='{"tab-active": tabIndex === 0}' @click.stop='tabIndex=0'>
<image :src='assetsUrl("ic_order_dd.png")' />
<text>到店</text>
</view>
<view class='tab c-flex-row' :class='{"tab-active": tabIndex === 1}' @click.stop='tabIndex=1'>
<image :src='assetsUrl("ic_order_yj.png")' />
<text>邮寄</text>
</view>
</view>
<view v-show='tabIndex==1' class='address-view c-flex-column'
@click.stop='goPath("/pages/mine/subs/address/index")'>
<view v-if='deliveryAddress?.addrid'>
<view class='user-info c-flex-row'>
<text class='status' v-if='deliveryAddress?.defaultstatus==1'>默认</text>
<text>{{ deliveryAddress?.name }}</text>
<text>{{ deliveryAddress?.mobile }}</text>
<view style='flex: 1' />
<image :src='assetsUrl("ic_arrow_right_gray.png")' />
</view>
<view class='addr c-flex-row'>
<image :src='assetsUrl("ic_location.png")' />
<text>{{ deliveryAddress?.addr }}</text>
</view>
</view>
<view v-else class='user-info c-flex-row'>
<text style='flex: 1'>请选择收货地址</text>
<image :src='assetsUrl("ic_arrow_right_gray.png")' />
</view>
<image class='dashed-line' :src='assetsUrl("ic_address_dashed_line.png")' />
</view>
<view class='goods-info-view c-flex-column'>
<view class='c-flex-row' style='margin-bottom: 20rpx' v-for='(item,index) in orderBean?.orderGoods'
:key='index'>
<image class='goods-image' :src='item.images||defaultImage' />
<view class='c-flex-column' style='flex: 1;'>
<view class='c-flex-row'>
<text class='goods-name'>{{ item.name || '未知' }}</text>
</view>
<text style='color: #999999;margin-top: 30rpx'>
{{ item.code }}
</text>
<view class='bottom-sku-view c-flex-row'>
<text>
{{ item.checkedStock.colorName||'均色' }}{{ item.checkedStock.sizeName||'均码' }} x{{ item.checkedStock.count }}
</text>
<text>¥{{ item.price }}</text>
</view>
</view>
</view>
<view class='divider' />
<view class='remark-view c-flex-row'>
<text>备注</text>
<input placeholder='请填写订单备注' @input='orderBean!.remark = $event.detail.value' />
</view>
</view>
<view class='card-view'>
<view class='c-flex-row'>
<text class='card-view-title'>商品总价</text>
<text class='card-view-value'>{{ orderBean?.totalPrice || 0 }}</text>
</view>
<view class='c-flex-row' style='display: none'>
<text class='card-view-title'>运费</text>
<text class='card-view-value'>0</text>
</view>
<view class='c-flex-row' @click.stop='showCouponDialog'>
<text class='card-view-title'>优惠券
<text style='font-size: 22rpx;color: #F32B2B;'>已选最大优惠</text>
</text>
<view class='card-view-value' style='color: #F32B2B;margin: 0'>-{{ checkedCoupon?.reduce || 0 }}
<image :src='assetsUrl("ic_arrow_right_gray.png")' />
</view>
</view>
<view class='divider' />
<view class='c-flex-row'>
<view style='flex: 1' />
<view class='c-flex-row'>
<text class='card-view-value'>共1件商品 合计
<text style='font-size: 34rpx;color:#F32B2B'>¥{{ totalPrice || 0 }}</text>
</text>
</view>
</view>
</view>
<view class='payment-way c-flex-row' @click.stop='changePayment'>
<text>支付方式</text>
<view>{{ paymentType === 0 ? '微信支付' : '余额' }}
<image style='display: none' :src='assetsUrl("ic_arrow_right_gray.png")' />
</view>
</view>
<view class='bottom-view c-flex-row'>
<text>合计</text>
<text>{{ totalPrice || 0 }}</text>
<sqb-pay @navigateTo='navigateTo'
:return_url='buildSqbParams.return_url'
:total_amount='buildSqbParams.total_amount'
:terminal_sn='buildSqbParams.terminal_sn'
:client_sn='buildSqbParams.client_sn'
:subject='buildSqbParams.subject'
:subject_img='buildSqbParams.subject_img '
:merchant_name='buildSqbParams.merchant_name'
:notify_url='buildSqbParams.notify_url'
:sign='buildSqbParams.sign'>
<button class='confirm-order' @click='createOrder'>确认订单</button>
</sqb-pay>
</view>
</view>
</scroll-view>
<payment-dialog ref='paymentDialogRef' @change='args => paymentType=args' />
<coupon-dialog ref='couponDialogRef' @confirm='confirmCoupon' :order-price='orderBean?.totalPrice' />
</template>
<script lang='ts' setup>
import { assetsUrl, defaultImage } from '@/utils/assets';
import PaymentDialog from '@/components/payment-dialog.vue';
import CouponDialog from '@/pages/mall/subs/components/coupon-dialog.vue';
import { goPath, parseParameter, showToast, sortASCII } from '@/utils';
import { hexMD5 } from '@/utils/common/md5';
import { getPaymentList, orderCreate, overPayment } from '@/api/order';
import { CouponBean } from '@/api/user/types';
import { OrderBean } from '@/api/order/types';
import { useUserStore } from '@/store';
import { handlePayResult } from '@/utils/order';
import useShoppingCartStore from '@/store/modules/shoppingcart';
const userStore = useUserStore();
const { userInfo, terminalInfo, deliveryAddress } = storeToRefs(userStore);
const shoppingCartStore = useShoppingCartStore();
const couponDialogRef = ref();
const paymentDialogRef = ref();
const paymentType = ref(0);
const tabIndex = ref(0);
const checkedCoupon = ref<CouponBean>();
const orderBean = ref<OrderBean>();
onLoad((e) => {
orderBean.value = JSON.parse(decodeURIComponent(e?.orderBean));
createOrder();
});
const totalPrice = computed(() => {
return (orderBean?.value?.totalPrice || 0) - (checkedCoupon.value?.reduce || 0);
});
const buildSqbParams = computed(() => {
const params = sortASCII({
client_sn: orderBean.value?.id || '',
return_url: '/pages/common/payresult/index',
total_amount: Number(((totalPrice.value || 0) * 100).toFixed(2)),
terminal_sn: terminalInfo.value.terminalSn,
subject: orderBean?.value?.orderGoods[0].name||'未知',
subject_img: orderBean?.value?.orderGoods[0].images || '',
merchant_name: terminalInfo.value.companyName,
notify_url: 'https://www.baidu.com'
}, true);
return {
...params,
sign: hexMD5(parseParameter(params) + '&key=' + terminalInfo.value.terminalKey).toUpperCase()
};
});
const changePayment = () => {
// paymentDialogRef.value.show();
};
const showCouponDialog = () => {
couponDialogRef.value.show();
};
const confirmCoupon = (item: CouponBean) => {
checkedCoupon.value = item;
createOrder();
};
const navigateTo = (e: any) => {
handlePayResult(orderBean.value?.id, e, {
onSuccess: () => {
console.log('pay success');
payment();
},
onFailure: () => {
console.error('pay onFailure');
if(orderBean.value?.id) {
orderBean.value.id = '';
}
createOrder();
}
});
};
const createOrder = async () => {
//邮寄
if(tabIndex.value == 1 && !deliveryAddress.value.addrid) {
showToast('请选择收货地址');
return;
}
const params = {
// 'discount': 0,
// 'freePrice': 0,
'reducePrice': checkedCoupon.value == undefined ? 0 : checkedCoupon.value?.reduce,
'totalPrice': totalPrice.value,
// 'integral': 0,
// 'allowIntegral': 0,
// 'produceIntegralNumber': 0,
'couponIds': checkedCoupon.value?.id,
'remark': orderBean.value?.remark,
'address': tabIndex.value == 0 ? undefined : JSON.stringify(deliveryAddress.value),
'orderGoods': orderBean?.value?.orderGoods?.map(item => (
{
'goodsId': item.id,
'goodsCode': item.code,
'goodsNum': item.checkedStock.count,
'stockId': item.checkedStock.stockId,
'originPrice': item.price,
// 'consumePrice': item.price * ((userInfo.value?.levelEntity?.discount || 0) / 100),
'consumePrice': item.consumePrice,
'discount': userInfo.value?.levelEntity?.discount || 0
// 'discountOriginPrice': 0,
// 'produceIntegral': 0,
// 'priceModify': [0],
// 'offset': 0
}
))
};
if(orderBean.value?.id == undefined || orderBean.value?.id == '') {
await uni.showLoading();
const result = await orderCreate(params);
orderBean.value!.id = result.id;
uni.hideLoading();
}
//删除购物车已存在商品
orderBean?.value?.orderGoods?.forEach(item => {
const index = shoppingCartStore.getSameGoodsIndex(item.id, item.checkedStock.colorId, item.checkedStock.sizeId);
if(index >= 0) {
shoppingCartStore.delete(index);
}
});
};
const payment = async () => {
await uni.showLoading();
const paymentList = await getPaymentList(orderBean.value?.id || '');
const paymentParams = {
orderId: orderBean?.value?.id,
produceIntegralNumber: Math.round((orderBean?.value?.totalPrice || 0) + (orderBean?.value?.useGold || 0)),
transactionPrice: orderBean?.value?.totalPrice,
useGold: orderBean.value?.useGold || 0,
detailBos: [{
integralNumber: Math.floor(orderBean?.value?.totalPrice || 0),
onlinePayResult: '',
payName: '收钱吧',
payTypeId: paymentList.find((res: any) => res.type === 'ShouQianBa')?.id,
transactionPrice: Number(orderBean?.value?.totalPrice)
}]
};
await overPayment(paymentParams);
showToast('支付成功', {
icon: 'success',
complete: () => {
uni.navigateBack();
uni.hideLoading();
}
});
};
</script>
<style lang='scss' scoped>
.content {
padding: 20rpx 30rpx 200rpx 30rpx;
}
.tab {
height: 63rpx;
background: #E8E8E8;
border-radius: 10rpx 0 10rpx 0;
align-items: center;
justify-content: center;
margin-top: 17rpx;
flex: 1;
text {
font-weight: bold;
font-size: 30rpx;
color: #333333;
margin-left: 10rpx;
}
}
.tab:nth-of-type(1) {
border-radius: 10rpx 0 0 0;
}
.tab:nth-of-type(2) {
border-radius: 0 10rpx 0 0;
}
.tab-active {
background: #FFFFFF;
}
.tab:nth-of-type(1) image {
width: 42rpx;
height: 42rpx;
}
.tab:nth-of-type(2) image {
width: 38rpx;
height: 29rpx;
}
.address-view {
padding-top: 38rpx;
background: #FFFFFF;
.user-info {
margin-left: 20rpx;
margin-right: 20rpx;
.status {
padding: 2rpx 10rpx;
font-size: 24rpx;
color: #F32B2B;
border-radius: 5rpx;
border: 1rpx solid #F32B2B;
margin-right: 12rpx;
}
text:nth-of-type(n+2) {
font-weight: bold;
font-size: 30rpx;
color: #333333;
margin-left: 10rpx;
}
image {
width: 8rpx;
height: 16rpx;
}
}
.addr {
margin-top: 15rpx;
margin-left: 20rpx;
image {
width: 30rpx;
height: 37rpx;
}
text {
font-weight: 400;
font-size: 26rpx;
color: #999999;
margin-left: 16rpx;
}
}
.dashed-line {
width: 100%;
height: 8rpx;
margin-top: 37rpx;
}
}
.goods-info-view {
display: flex;
position: relative;
background: #FFFFFF;
margin-top: 20rpx;
border-radius: 10rpx;
padding: 30rpx 20rpx;
.goods-image {
width: 180rpx;
height: 180rpx;
border-radius: 10rpx;
margin-right: 20rpx;
}
.goods-name {
font-size: 30rpx;
font-weight: 400;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
overflow: hidden;
margin-right: 20rpx;
color: #333333;
flex: 1;
}
.bottom-sku-view {
display: flex;
justify-content: space-between;
margin-top: 10rpx;
text:nth-of-type(1) {
font-size: 26rpx;
font-weight: 400;
flex: 1;
color: #999999;
}
text:nth-of-type(2) {
font-size: 30rpx;
color: #333333;
font-weight: bold;
margin-right: 5rpx;
}
text:nth-of-type(3) {
font-size: 34rpx;
color: #333333;
font-weight: bold;
}
}
.divider {
margin: 30rpx 0;
}
.remark-view {
text {
font-weight: 400;
font-size: 28rpx;
color: #333333;
flex: 1;
}
input {
min-width: 200rpx;
font-weight: 400;
text-align: right;
font-size: 28rpx;
color: #333333;
z-index: 0;
}
}
}
.card-view {
margin-top: 20rpx;
padding: 0 25rpx 0 23rpx;
view:not(.divider):nth-of-type(n+1) {
margin: 20rpx 0;
.card-view-title {
font-weight: 400;
font-size: 30rpx;
color: #333333;
flex: 1;
}
.card-view-value {
font-weight: 400;
font-size: 26rpx;
color: #333333;
image {
width: 8rpx;
height: 16rpx;
margin-left: 16rpx;
}
}
}
}
.payment-way {
background: #FFFFFF;
border-radius: 10rpx;
padding: 22rpx 23rpx;
margin-top: 20rpx;
text:nth-of-type(1) {
font-weight: bold;
font-size: 30rpx;
color: #333333;
flex: 1;
}
view:nth-of-type(1) {
font-weight: 400;
font-size: 28rpx;
color: #333333;
image {
width: 8rpx;
height: 16rpx;
margin-left: 13rpx;
}
}
}
.bottom-view {
background: #FFFFFF;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 30rpx 78rpx 30rpx;
text:nth-of-type(1) {
font-weight: 400;
font-size: 30rpx;
color: #333333;
}
text:nth-of-type(2) {
font-weight: bold;
font-size: 36rpx;
color: #F32B2B;
margin-left: 14rpx;
flex: 1;
}
sqb-pay .confirm-order {
display: flex;
padding: 0 45rpx;
height: 80rpx;
border: 2rpx solid #F32B2B;
font-weight: bold;
font-size: 30rpx;
color: #F32B2B;
align-items: center;
justify-content: center;
background: #FFFFFF;
border-radius: 40rpx;
}
}
</style>