Files
gxtyzx-uniapp/src/package/goods/checkout.vue
T
2024-07-10 13:50:01 +08:00

550 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>
<view class="container">
<!-- deBug信息 -->
<view class="web-debug web-text-success" style="display: none">
场馆ID:{{ merchantId }} 场馆编号:{{ merchantCode }} 场馆名称:{{ merchantName }} 日期:{{ dateTime }} 星期:{{ week }} 订单总金额:{{ totalPrice }} 类型:{{
type
}}
商品信息:{{ goodsList }}
</view>
<!-- {{ address }} -->
<uni-card :border="false" :is-shadow="false">
<uv-cell
v-if="address.name"
:title="`${address.name} &nbsp; ${address.phone}`"
:label="`${address.address}`"
icon="map"
:cellStyle="{ padding: '5px 0' }"
:border="false"
@click="openAddressList"
>
<template v-slot:right-icon>
<uv-icon name="arrow-right"></uv-icon>
</template>
</uv-cell>
</uni-card>
<uni-card title="订单信息" :border="false" :is-shadow="false">
<uv-cell-group :customStyle="{ backgroundColor: '#ffffff' }" :border="false">
<block v-if="goodsList.length == 0">
<span class="web-text-secondary">商品不存在</span>
</block>
<block v-if="goodsList">
<block v-for="(item, index) in goodsList" :key="index">
<uv-cell :title="`${item.goodsName}`" :label="`${item.comments}`" :cellStyle="{ padding: '10px 0' }" :border="false" :value="`¥${item.price}`">
<template v-slot:icon>
<uv-avatar :src="item.image" size="60" shape="square"></uv-avatar>
</template>
</uv-cell>
</block>
</block>
</uv-cell-group>
</uni-card>
<uni-card title="选择支付方式" :border="false" :is-shadow="false">
<uv-cell-group :customStyle="{ backgroundColor: '#ffffff' }" :border="false">
<block v-for="(item, index) in payment" :key="index">
<uv-cell
:title="`${item.name}`"
:icon="`${item.image}`"
:cellStyle="{ padding: '20rpx 10rpx', borderRadius: '8rpx', backgroundColor: item.type == payType ? '#f6fff1' : '' }"
:border="false"
@click="onPayType(item.type)"
>
<template v-slot:right-icon>
<uv-icon v-if="item.type == payType" size="30rpx" name="checkbox-mark"></uv-icon>
</template>
</uv-cell>
</block>
</uv-cell-group>
<view slot="actions" class="card-actions">
<view class="card-actions-item" @click="actionsClick('分享')">
<span class="web-text-danger">已优惠¥0.00</span>
<span class="web-text-heading">¥{{ totalPrice || 0.0 }}</span>
</view>
</view>
</uni-card>
<view class="xieyi web-cell web-text-secondary web-cell-align-top">
<view class="web-cell web-cell-content web-cell-align-top">
<uni-icons type="circle" size="20" color="#a4a5a7" v-if="!disabled" @click="onDisabled"></uni-icons>
<uni-icons type="checkbox" size="20" color="#11a954" v-else @click="onDisabled"></uni-icons>
<view class="text" @click="onDisabled">
<text>同意以下服务条款</text>
<text class="link" @click.stop="navTo('/package/article/detail?articleId=501')">《广西体育中心预定条款》</text>
<text class="link" @click.stop="navTo('/package/article/detail?articleId=502')">《用户服务协议和隐私政策》</text>
</view>
</view>
</view>
<!-- 支付按钮 -->
<uv-gap height="50"></uv-gap>
<view class="checkout-car">
<view class="car-total">
<text style="color: #ebcf00">合计¥</text>
<uv-count-to :startVal="0" decimals="2" duration="100" color="#ebcf00" bold :endVal="totalPrice"></uv-count-to>
</view>
<uv-button
class="save-btn"
:disabled="!disabled || goodsList.length == 0"
:customStyle="{ background: 'linear-gradient(to right, #70b915, #008e04)', borderRadius: '0 30px 30px 0', color: '#ffffff', border: 'none', padding: '22px 30px' }"
text="提交订单"
@click="save"
></uv-button>
</view>
</view>
<!-- 收货地址选择弹窗 -->
<uni-popup ref="addForm" type="center" border-radius="10px 10px 0 0">
<uni-card title="选择收货地址" :border="false" :is-shadow="false" :padding="0">
<view class="address-body web-cell web-cell-align-top">
<view class="web-cell-content">
<uv-cell-group :customStyle="{ backgroundColor: '#ffffff' }" :border="false">
<block v-for="(item, index) in addressList" :key="index">
<uv-cell :cellStyle="{ padding: '10px 0' }" :label="item.address" @click="onAddress(item)">
<template v-slot:icon>
<uv-avatar :text="item.type" fontSize="12" size="32" randomBgColor></uv-avatar>
</template>
<template v-slot:title>
<view class="title-bar">
<text class="web-text-heading" style="font-weight: 700">{{ item.name }}</text>
<text class="web-text-secondary">{{ item.phone }}</text>
<uni-tag v-if="item.isDefault" text="默认" size="mini" inverted type="success"></uni-tag>
</view>
</template>
<template v-slot:right-icon>
<uni-icons type="right" style="color: #999999"></uni-icons>
</template>
</uv-cell>
</block>
<uv-button class="add-address" :customStyle="{ borderRadius: '30px' }" text="收货地址管理" @click="navTo('/package/user/address')"></uv-button>
</uv-cell-group>
</view>
</view>
</uni-card>
</uni-popup>
<!-- 支付密码弹窗 -->
<uni-popup ref="payPasswordForm" type="center" border-radius="10px 10px 0 0">
<uni-card title="请输入支付密码" :border="false" :is-shadow="false" :padding="0">
<view class="pay-password-card">
<uni-forms ref="form" :label-width="80">
<uni-forms-item label="支付密码" name="payPassword" required>
<uv-code-input mode="box" dot :space="0" :maxlength="6" hairline v-model="payPassword" @finish="onPayPassword"></uv-code-input>
</uni-forms-item>
<!-- <uv-button
class="to-pay-btn"
:customStyle="{ background: 'linear-gradient(to right, #70b915, #008e04)', borderRadius: '30px', color: '#ffffff' }"
text="确定支付"
:disabled="disabledPayPayPassword"
@click="onPayPassword"
></uv-button> -->
</uni-forms>
<text @click="navTo(`/package/user/pay-password`)" class="web-text-primary">忘记支付密码?</text>
</view>
</uni-card>
</uni-popup>
<!-- 登录组件 -->
<ws-login ref="login" :logo="logo" @done="reload" />
</template>
<script>
import * as Api from '@/api/shop/order';
import * as UserAddressApi from '@/api/shop/userAddress';
import * as PaymentApi from '@/api/system/payment';
import { checkPayPassword } from '@/api/passport/login';
import { storeToRefs } from 'pinia';
import { getWeek, getKey } from '@/utils/common';
import { useCarStore } from '@/store/modules/car';
import { useUserStore } from '@/store/modules/user';
const userStore = useUserStore();
const carStore = useCarStore();
const { goodsList, totalPrice, carNum, merchantId, merchantName, merchantCode, type, dateTime } = storeToRefs(carStore);
export default {
data() {
return {
orderId: 0,
goodsId: 0,
userInfo: {},
address: {},
addressList: [],
week: 0,
goodsList,
// 订单总金额
totalPrice,
reducePrice: 0,
merchantId,
merchantName,
merchantCode,
getWeek,
payType: 1,
payment: [],
isLogin: false,
disabled: false,
// 支付密码是否正确
isPayPasswordCorrect: false,
disabledPayPayPassword: false,
payPassword: ''
};
},
onLoad(option) {
this.orderId = option.orderId;
this.reload();
},
onShow() {
// 登录状态
if (uni.getStorageSync('user_id') && uni.getStorageSync('access_token')) {
this.isLogin = true;
}
this.openLogin();
},
methods: {
async reload() {
const app = this;
const { orderId } = this;
// 当前登录用户信息
const userInfo = await userStore.fetchUserInfo();
app.userInfo = userInfo;
UserAddressApi.pageUserAddress({
userId: uni.getStorageSync('user_id')
}).then((res) => {
app.addressList = res.list;
const arr = res.list.filter((d) => d.isDefault === true);
app.address = arr[0];
});
// 读取支付方式列表
PaymentApi.select({ status: true }).then((list) => {
app.payment = list
.filter((d) => d.type < 2)
.map((d) => {
if (d.code == 'balancePay') {
d.name = `${d.name} (¥${userInfo.balance})`;
}
return d;
});
});
// if (orderId > 0) {
// Api.getOrder(orderId).then(data => {
// app.merchantId = data.merchantId
// app.merchantName = data.merchantName
// app.merchantCode = data.merchantCode
// app.payType = data.payType
// app.orderInfo = data.orderInfoList
// app.totalPrice = data.totalPrice
// app.dateTime = data.orderInfoList[0].dateTime
// })
// }
},
onDisabled() {
this.disabled = !this.disabled;
},
navTo(url) {
uni.navigateTo({
url
});
},
openUrl(url) {
if (!this.isLogin) {
this.$refs.login.open('bottom');
return false;
} else {
uni.navigateTo({
url
});
}
},
onAddress(item) {
this.address = item;
this.$refs.addForm.close();
},
// 切换支付方式
onPayType(index) {
this.payType = index;
},
openAddressList() {
this.$refs.addForm.open('center');
},
// 弹出登录提示框
openLogin() {
if (!this.isLogin) {
this.$refs.login.open('bottom');
return false;
}
},
// 验证支付密码
onPayPassword() {
if (this.payPassword == '' || !this.payPassword) {
uni.showToast({
title: '请输入支付密码',
icon: 'none'
});
return false;
}
this.disabledPayPayPassword = true;
const { payPassword } = this;
checkPayPassword({ payPassword })
.then((res) => {
this.disabledPayPayPassword = false;
this.isPayPasswordCorrect = true;
this.save();
})
.catch((err) => {
uni.showToast({
title: err.message,
icon: 'none'
});
this.disabledPayPayPassword = false;
});
},
save() {
const app = this;
const { form, payType } = this;
if (!this.disabled) {
uni.showToast({
title: '请先阅读并同意服务协议',
icon: 'none'
});
return false;
}
if (carStore.goodsList.length == 0) {
uni.showToast({
title: '订单信息不存在',
icon: 'none'
});
return false;
}
if (app.payType == 0 && !this.isPayPasswordCorrect) {
this.$refs.payPasswordForm.open('center');
return false;
}
uni.showLoading({
title: '订单提交中.'
});
Api.addOrder({
type: 0, // 0商城订单
orderId: this.orderId,
merchantId: this.merchantId,
merchantCode: this.merchantCode,
merchantName: this.merchantName,
totalPrice: this.totalPrice,
payPrice: this.totalPrice - this.reducePrice,
goodsList: this.goodsList,
comments: this.goodsList[0].goodsName,
// 微信支付
payType: this.payType,
// 下单日期
dateTime: this.dateTime
})
.then((data) => {
const orderInfo = data;
// 调起微信支付
if (app.payType == 1) {
// #ifdef MP-WEIXIN
uni.requestPayment({
provider: orderInfo.provider, // 服务提供商
timeStamp: orderInfo.timeStamp, // 时间戳
nonceStr: orderInfo.nonceStr, // 随机字符串
package: orderInfo.package,
signType: orderInfo.signType, // 签名算法
paySign: orderInfo.paySign, // 签名
success: function (res) {
// 业务逻辑。。。
uni.showToast({
title: '支付成功',
icon: 'success'
});
setTimeout(function () {
app.disabled = false;
uni.navigateTo({
url: '/package/goods/order'
});
}, 500);
},
fail: function (err) {
console.log('支付失败', err);
app.disabled = false;
uni.navigateTo({
url: '/package/goods/order'
});
}
});
// #endif
}
// 使用余额支付
if (app.payType == 0) {
if (!orderInfo) {
return uni.showToast({
title: '支付失败',
icon: 'error'
});
}
if (orderInfo) {
uni.showToast({
title: '支付成功',
icon: 'success'
});
setTimeout(function () {
app.disabled = false;
app.$refs.payPasswordForm.close();
uni.reLaunch({
url: '/package/goods/order',
success: function (e) {
var page = getCurrentPages()[0];
if (page == undefined || page == null) return;
page.onLoad();
}
});
}, 1500);
}
}
uni.hideLoading();
})
.catch((res) => {
uni.showToast({
title: res.message || '请检查您的网络.',
icon: 'none'
});
uni.hideLoading();
});
}
}
};
</script>
<style>
page {
background-size: 100%;
background-repeat: no-repeat;
background-color: #f0f2f5;
width: 750rpx;
overflow-x: hidden;
}
</style>
<style lang="scss" scoped>
.container {
}
.checkout-car {
width: 700rpx;
left: 25rpx;
position: fixed;
bottom: 30rpx;
display: flex;
justify-content: space-between;
background-color: #000000;
border-radius: 100px;
align-items: center;
.car-selected {
color: #ccc;
display: flex;
align-items: center;
padding: 0 20rpx;
}
.car-total {
display: flex;
color: #ebcf00;
align-items: center;
padding-left: 40rpx;
.save-btn {
}
}
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: flex-end;
height: 45px;
border-top: 1px #eee solid;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
.web-text-heading {
font-size: 38rpx;
margin-left: 28rpx;
}
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
.address-body {
width: 660rpx;
margin: auto;
}
.add-address {
width: 600rpx !important;
margin: 40rpx auto;
}
.btn-bar {
width: 700rpx;
left: 25rpx;
position: fixed;
bottom: 30rpx;
margin: auto;
clear: both;
}
.title-bar {
display: flex;
.web-text-heading {
margin-right: 20rpx;
}
.web-text-secondary {
margin-right: 20rpx;
}
}
.xieyi {
margin-bottom: 80rpx;
padding: 0 30rpx;
.text {
margin-left: 5rpx;
.link {
color: #0f80ff;
}
}
}
.pay-password-card {
width: 600rpx;
min-height: 300rpx;
margin: 30rpx auto;
background-color: #ffffff;
text-align: center;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
.web-text-primary {
line-height: 2rem;
padding: 20rpx 0;
}
}
.to-pay-btn {
width: 400rpx !important;
margin: 40rpx auto;
}
</style>