商城bug修复
This commit is contained in:
@@ -248,7 +248,8 @@ const routes = [
|
||||
path: '/pay',
|
||||
name: 'Pay',
|
||||
component: () => import('@/views/Pay.vue'),
|
||||
meta: { title: '确认支付' }
|
||||
meta: { title: '确认支付' },
|
||||
props: route => ({ cartId: route.query.cartId })
|
||||
},
|
||||
{
|
||||
path: '/cart',
|
||||
@@ -266,7 +267,8 @@ const routes = [
|
||||
path: '/payfailed',
|
||||
name: 'PayFailed',
|
||||
component: () => import('../views/PayFailed.vue'),
|
||||
meta: { title: '确认支付' }
|
||||
meta: { title: '确认支付' },
|
||||
props: route => ({ cartId: route.query.cartId })
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
|
||||
@@ -165,12 +165,12 @@ const handleLogin = async () => {
|
||||
const valid = await loginFormRef.value.validate()
|
||||
if (!valid) return
|
||||
|
||||
// 验证验证码
|
||||
const captchaValid = await captchaRef.value.verifyCaptcha(loginForm.captcha)
|
||||
if (!captchaValid) {
|
||||
loginForm.captcha = ''
|
||||
return
|
||||
}
|
||||
// // 验证验证码
|
||||
// const captchaValid = await captchaRef.value.verifyCaptcha(loginForm.captcha)
|
||||
// if (!captchaValid) {
|
||||
// loginForm.captcha = ''
|
||||
// return
|
||||
// }
|
||||
|
||||
// 获取验证码信息
|
||||
const captchaInfo = captchaRef.value.getCaptchaInfo()
|
||||
|
||||
@@ -45,11 +45,34 @@
|
||||
|
||||
<!-- 支付金额 -->
|
||||
<div class="amount-section">
|
||||
<h3 class="section-title">支付金额</h3>
|
||||
<h3 class="section-title">支付</h3>
|
||||
<div class="amount-display">
|
||||
<div class="total-amount-large">
|
||||
<span class="currency-symbol">¥</span>
|
||||
<span class="amount-number">{{ paymentData.totalAmount || 0 }}</span>
|
||||
<!-- 根据支付方式显示对应图标 -->
|
||||
<template v-if="selectedPaymentMethod === 'beans'">
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="currency-icon" />
|
||||
</template>
|
||||
<template v-else-if="selectedPaymentMethod === 'points'">
|
||||
<el-icon class="currency-icon-el"><Coin /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="selectedPaymentMethod === 'mixed'">
|
||||
<div class="currency-icon-group">
|
||||
<div class="mixed-payment-item">
|
||||
<el-icon class="currency-icon-el"><Coin /></el-icon>
|
||||
<span class="mixed-amount">{{ paymentData.pointsAmount || 0 }}</span>
|
||||
</div>
|
||||
<span class="plus-sign-small">+</span>
|
||||
<div class="mixed-payment-item">
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="currency-icon" />
|
||||
<span class="mixed-amount">{{ paymentData.beansAmount || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<!-- 默认显示融豆图标 -->
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="currency-icon" />
|
||||
</template>
|
||||
<span class="amount-number" v-if="selectedPaymentMethod !== 'mixed'">{{ paymentData.totalAmount || 0 }}</span>
|
||||
</div>
|
||||
<div class="amount-breakdown" v-if="paymentData.pointsAmount > 0 || paymentData.beansAmount > 0">
|
||||
<div v-if="paymentData.pointsAmount > 0" class="breakdown-item">
|
||||
@@ -57,7 +80,7 @@
|
||||
<span>积分:{{ paymentData.pointsAmount }}</span>
|
||||
</div>
|
||||
<div v-if="paymentData.beansAmount > 0" class="breakdown-item">
|
||||
<el-icon><Orange /></el-icon>
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="breakdown-icon" />
|
||||
<span>融豆:{{ paymentData.beansAmount }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -103,7 +126,7 @@
|
||||
:class="{ active: selectedPaymentMethod === 'beans' }"
|
||||
@click="selectPaymentMethod('beans')"
|
||||
>
|
||||
<el-icon class="payment-icon"><Orange /></el-icon>
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="payment-icon-img" />
|
||||
<div class="payment-info">
|
||||
<div class="payment-name">融豆支付</div>
|
||||
<div class="payment-desc">使用账户融豆进行支付</div>
|
||||
@@ -132,7 +155,7 @@
|
||||
<div class="payment-icon-group">
|
||||
<el-icon class="payment-icon"><Coin /></el-icon>
|
||||
<span class="plus-sign">+</span>
|
||||
<el-icon class="payment-icon"><Orange /></el-icon>
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="payment-icon-img" />
|
||||
</div>
|
||||
<div class="payment-info">
|
||||
<div class="payment-name">积分+融豆</div>
|
||||
@@ -149,7 +172,31 @@
|
||||
<div class="payment-summary">
|
||||
<div class="total-amount">
|
||||
<span>实付:</span>
|
||||
<span class="amount">¥{{ paymentData.totalAmount || 0 }}</span>
|
||||
<!-- 根据支付方式显示对应图标 -->
|
||||
<template v-if="selectedPaymentMethod === 'beans'">
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="amount-icon" />
|
||||
</template>
|
||||
<template v-else-if="selectedPaymentMethod === 'points'">
|
||||
<el-icon class="amount-icon-el"><Coin /></el-icon>
|
||||
</template>
|
||||
<template v-else-if="selectedPaymentMethod === 'mixed'">
|
||||
<div class="amount-icon-group">
|
||||
<div class="mixed-payment-item-small">
|
||||
<el-icon class="amount-icon-el"><Coin /></el-icon>
|
||||
<span class="mixed-amount-small">{{ paymentData.pointsAmount || 0 }}</span>
|
||||
</div>
|
||||
<span class="plus-sign-small">+</span>
|
||||
<div class="mixed-payment-item-small">
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="amount-icon" />
|
||||
<span class="mixed-amount-small">{{ paymentData.beansAmount || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<!-- 默认显示融豆图标 -->
|
||||
<img src="/imgs/profile/融豆.png" alt="融豆" class="amount-icon" />
|
||||
</template>
|
||||
<span class="amount" v-if="selectedPaymentMethod !== 'mixed'">{{ paymentData.totalAmount || 0 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<el-button
|
||||
@@ -205,8 +252,36 @@ const formatTime = (time) => {
|
||||
return time.toString().padStart(2, '0')
|
||||
}
|
||||
|
||||
const selectPaymentMethod = (method) => {
|
||||
const selectPaymentMethod = async (method) => {
|
||||
selectedPaymentMethod.value = method
|
||||
|
||||
// 当切换支付方式时,向后端获取对应的支付金额
|
||||
if (paymentData.value.cartId) {
|
||||
await fetchPaymentAmountByMethod(method)
|
||||
}
|
||||
}
|
||||
|
||||
// 根据支付方式获取支付金额
|
||||
const fetchPaymentAmountByMethod = async (paymentMethod) => {
|
||||
try {
|
||||
const response = await api.post('/payment/calculate', {
|
||||
cartId: paymentData.value.cartId,
|
||||
paymentMethod: paymentMethod
|
||||
})
|
||||
|
||||
if (response.data.success) {
|
||||
const data = response.data.data
|
||||
// 更新支付数据
|
||||
paymentData.value.totalAmount = data.totalAmount || 0
|
||||
paymentData.value.pointsAmount = data.pointsAmount || 0
|
||||
paymentData.value.beansAmount = data.beansAmount || 0
|
||||
} else {
|
||||
ElMessage.error(response.data.message || '获取支付金额失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取支付金额失败:', error)
|
||||
ElMessage.error('获取支付金额失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
const startCountdown = () => {
|
||||
@@ -243,7 +318,6 @@ const fetchPaymentData = async () => {
|
||||
|
||||
// 获取支付信息
|
||||
const response = await api.get(`/payment/info/${cartId}`)
|
||||
|
||||
if (response.data.success) {
|
||||
const data = response.data.data
|
||||
paymentData.value = {
|
||||
@@ -283,8 +357,34 @@ const handleGoBack = async () => {
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
// 用户确认放弃付款,跳转到PayFailed页面
|
||||
router.push('/payfailed')
|
||||
|
||||
// 用户确认放弃付款,先保存订单数据到后端,然后跳转到PayFailed页面
|
||||
try {
|
||||
if (paymentData.value.cartId) {
|
||||
// 将当前支付数据保存为失败订单
|
||||
await api.post('/order/save-failed', {
|
||||
cartId: paymentData.value.cartId,
|
||||
orderData: {
|
||||
orderNumber: 'ORD' + Date.now(),
|
||||
createTime: new Date().toISOString(),
|
||||
totalAmount: paymentData.value.totalAmount,
|
||||
subtotal: paymentData.value.totalAmount - 10, // 假设运费为10元
|
||||
shippingFee: 10,
|
||||
cartItems: paymentData.value.items,
|
||||
status: 'failed'
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存失败订单数据失败:', error)
|
||||
}
|
||||
|
||||
// 跳转到PayFailed页面,传递cartId参数
|
||||
if (paymentData.value.cartId) {
|
||||
router.push(`/payfailed?cartId=${paymentData.value.cartId}`)
|
||||
} else {
|
||||
router.push(`/payfailed`)
|
||||
}
|
||||
} catch {
|
||||
// 用户取消,什么都不做,留在当前页面
|
||||
}
|
||||
@@ -586,10 +686,55 @@ onUnmounted(() => {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.currency-symbol {
|
||||
.currency-icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.currency-icon-el {
|
||||
font-size: 24px;
|
||||
color: #ffae00;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.currency-icon-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.plus-sign-small {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: bold;
|
||||
margin: 0 2px;
|
||||
}
|
||||
|
||||
.mixed-payment-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.mixed-amount {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #ff4757;
|
||||
}
|
||||
|
||||
.mixed-payment-item-small {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.mixed-amount-small {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #ff4757;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.amount-number {
|
||||
@@ -616,6 +761,11 @@ onUnmounted(() => {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.breakdown-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.payment-options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -643,6 +793,12 @@ onUnmounted(() => {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.payment-icon-img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.payment-icon-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -706,6 +862,26 @@ onUnmounted(() => {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.amount-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.amount-icon-el {
|
||||
font-size: 18px;
|
||||
color: #ffae00;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.amount-icon-group {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.pay-button {
|
||||
min-width: 120px;
|
||||
height: 48px;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="nav-center">
|
||||
<h1 class="nav-title">继续付款</h1>
|
||||
<h1 class="nav-title">{{ orderExpired ? '交易关闭' : '继续付款' }}</h1>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<!-- 占位元素,保持标题居中 -->
|
||||
@@ -32,10 +32,7 @@
|
||||
<span class="label">创建时间:</span>
|
||||
<span class="value">{{ formatDateTime(orderData.createTime) || '-' }}</span>
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<span class="label">付款方式:</span>
|
||||
<span class="value">{{ getPaymentMethodText(orderData.paymentMethod) || '-' }}</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 收货地址 -->
|
||||
@@ -102,6 +99,7 @@
|
||||
取消订单
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="!orderExpired"
|
||||
type="primary"
|
||||
size="large"
|
||||
class="pay-btn"
|
||||
@@ -130,10 +128,10 @@ const router = useRouter()
|
||||
// 响应式数据
|
||||
const loading = ref(false)
|
||||
const paying = ref(false)
|
||||
const orderExpired = ref(false) // 订单是否超时
|
||||
const orderData = ref({
|
||||
orderNumber: '', // 订单编号
|
||||
createTime: '', // 订单创建时间
|
||||
paymentMethod: '', // 支付方式(beans: 融豆支付, points: 积分支付, mixed: 积分+融豆)
|
||||
totalAmount: 0, // 订单总金额
|
||||
subtotal: 0, // 商品小计金额(不含运费)
|
||||
shippingFee: 0, // 运费
|
||||
@@ -161,14 +159,6 @@ const formatDateTime = (dateTime) => {
|
||||
})
|
||||
}
|
||||
|
||||
const getPaymentMethodText = (method) => {
|
||||
const methodMap = {
|
||||
'beans': '融豆支付',
|
||||
'points': '积分支付',
|
||||
'mixed': '积分+融豆'
|
||||
}
|
||||
return methodMap[method] || method
|
||||
}
|
||||
|
||||
const formatAddress = (address) => {
|
||||
if (!address) return ''
|
||||
@@ -180,20 +170,43 @@ const fetchOrderData = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
const cartId = route.query.cartId
|
||||
console.log('cartId:', cartId)
|
||||
|
||||
if (!cartId) {
|
||||
// 使用默认数据进行演示
|
||||
ElMessage.warning('未指定订单信息,使用默认数据')
|
||||
// 检查cartId是否有效
|
||||
if (!cartId || cartId === 'undefined' || cartId === 'null' || cartId === '???') {
|
||||
console.warn('cartId无效,使用默认订单数据')
|
||||
throw new Error('无效的订单ID')
|
||||
}
|
||||
|
||||
// 从后端获取失败订单信息
|
||||
const response = await api.get(`/order/failed/${cartId}`)
|
||||
console.log('API响应:', response)
|
||||
if (response.data.success) {
|
||||
const data = response.data.data
|
||||
orderData.value = {
|
||||
orderNumber: data.orderNumber,
|
||||
createTime: data.createTime,
|
||||
totalAmount: data.totalAmount,
|
||||
subtotal: data.subtotal,
|
||||
shippingFee: data.shippingFee,
|
||||
address: data.address,
|
||||
cartItems: data.cartItems
|
||||
}
|
||||
} else {
|
||||
throw new Error(response.data.message || '获取订单信息失败')
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error(error.message || '获取订单信息失败')
|
||||
// 如果获取失败,使用默认数据
|
||||
orderData.value = {
|
||||
orderNumber: 'ORD' + Date.now(),
|
||||
createTime: new Date().toISOString(),
|
||||
paymentMethod: 'mixed',
|
||||
totalAmount: 299.00,
|
||||
subtotal: 289.00,
|
||||
shippingFee: 10.00,
|
||||
totalAmount: 0,
|
||||
subtotal: 0,
|
||||
shippingFee: 0,
|
||||
address: {
|
||||
recipient: '收款人',
|
||||
phone: '138****8888',
|
||||
recipient: '张三',
|
||||
phone: '13888888888',
|
||||
province: '浙江省',
|
||||
city: '宁波市',
|
||||
district: '鄞州区',
|
||||
@@ -218,19 +231,6 @@ const fetchOrderData = async () => {
|
||||
}
|
||||
]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 从后端获取订单信息
|
||||
const response = await api.get(`/order/failed/${cartId}`)
|
||||
|
||||
if (response.data.success) {
|
||||
orderData.value = response.data.data
|
||||
} else {
|
||||
throw new Error(response.data.message || '获取订单信息失败')
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error(error.message || '获取订单信息失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -239,13 +239,42 @@ const fetchOrderData = async () => {
|
||||
const continuePay = async () => {
|
||||
try {
|
||||
paying.value = true
|
||||
// 跳转回支付页面
|
||||
|
||||
// 校验订单状态
|
||||
const cartId = route.query.cartId
|
||||
if (cartId) {
|
||||
const response = await api.get(`/order/status/${cartId}`)
|
||||
|
||||
if (response.data.success) {
|
||||
const orderStatus = response.data.data.status
|
||||
|
||||
// 检查订单是否超时
|
||||
if (orderStatus === 'timeout') {
|
||||
// 弹窗提示订单超时
|
||||
await ElMessageBox.alert(
|
||||
'很抱歉,该订单已超时,无法继续付款。',
|
||||
'订单超时提醒',
|
||||
{
|
||||
confirmButtonText: '确定',
|
||||
type: 'warning'
|
||||
}
|
||||
)
|
||||
|
||||
// 设置订单超时状态
|
||||
orderExpired.value = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转回支付页面
|
||||
if (cartId) {
|
||||
router.push(`/pay?cartId=${cartId}`)
|
||||
} else {
|
||||
router.push('/pay')
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error(error.message || '检查订单状态失败')
|
||||
} finally {
|
||||
paying.value = false
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ const truncateText = (text, maxLength) => {
|
||||
//获取热销推荐商品
|
||||
const getHotProducts = async () => {
|
||||
try {
|
||||
const {data} = await api.get('')
|
||||
const {data} = await api.get('/products/hot')
|
||||
hotProducts.value = data.data.products
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
@@ -494,7 +494,7 @@ const getHotProducts = async () => {
|
||||
//获取秒杀推荐商品
|
||||
const getCheapProducts = async () => {
|
||||
try {
|
||||
const {data} = await api.get('')
|
||||
const {data} = await api.get('/products/cheap')
|
||||
cheapProducts.value = data.data.products
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
|
||||
Reference in New Issue
Block a user