支付及优惠券页面更新

This commit is contained in:
dzl
2025-10-13 17:27:49 +08:00
parent 60a3cba975
commit 9dc618b255
13 changed files with 388 additions and 134 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -44,7 +44,7 @@
import { ref, onMounted, watch } from 'vue' import { ref, onMounted, watch } from 'vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { Refresh, Loading } from '@element-plus/icons-vue' import { Refresh, Loading } from '@element-plus/icons-vue'
import api from '@/utils/api' import api,{captchaAPI} from '@/utils/api'
// Props // Props
const props = defineProps({ const props = defineProps({
@@ -81,7 +81,7 @@ const loading = ref(false)
const getCaptcha = async () => { const getCaptcha = async () => {
try { try {
loading.value = true loading.value = true
const response = await api.get('/captcha/generate') const response = await captchaAPI.generate()
if (response.data.success) { if (response.data.success) {
captchaImage.value = response.data.data.image captchaImage.value = response.data.data.image

View File

@@ -312,7 +312,7 @@ router.beforeEach(async (to, from, next) => {
} }
} else { } else {
// 普通用户页面认证逻辑 // 普通用户页面认证逻辑
console.log(userStore.isAuthenticated, 'isAuthenticated'); // console.log(userStore.isAuthenticated, 'isAuthenticated');
if (!userStore.isAuthenticated) { if (!userStore.isAuthenticated) {
// 尝试从本地存储恢复登录状态 // 尝试从本地存储恢复登录状态
@@ -328,10 +328,10 @@ router.beforeEach(async (to, from, next) => {
} }
// 检查支付状态(管理员除外) // 检查支付状态(管理员除外)
console.log(userStore.user); // console.log(userStore.user);
if (userStore.user && userStore.user.role !== 'admin' && userStore.user.payment_status === 'unpaid') { if (userStore.user && userStore.user.role !== 'admin' && userStore.user.payment_status === 'unpaid') {
console.log('进来了'); // console.log('进来了');
// 如果当前不在支付页面,静默重定向到支付页面(不显示额外通知) // 如果当前不在支付页面,静默重定向到支付页面(不显示额外通知)
if (to.name !== 'Payment') { if (to.name !== 'Payment') {

View File

@@ -1,6 +1,6 @@
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import { ref, computed } from 'vue' import { ref, computed } from 'vue'
import api from '@/utils/api' import api,{authAPI} from '@/utils/api'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
export const useUserStore = defineStore('user', () => { export const useUserStore = defineStore('user', () => {
@@ -23,10 +23,9 @@ export const useUserStore = defineStore('user', () => {
token.value = newToken token.value = newToken
if (newToken) { if (newToken) {
localStorage.setItem('token', newToken) localStorage.setItem('token', newToken)
api.defaults.headers.common['Authorization'] = `Bearer ${newToken}`
} else { } else {
localStorage.removeItem('token') localStorage.removeItem('token')
delete api.defaults.headers.common['Authorization'] console.log('token已移除');
} }
} }
@@ -39,7 +38,9 @@ export const useUserStore = defineStore('user', () => {
const login = async (credentials) => { const login = async (credentials) => {
try { try {
loading.value = true loading.value = true
const response = await api.post('/auth/login', credentials) const response = await authAPI.login(credentials)
console.log('response',response);
if (response.data.success && response.data.token) { if (response.data.success && response.data.token) {
setToken(response.data.token) setToken(response.data.token)
@@ -72,6 +73,7 @@ export const useUserStore = defineStore('user', () => {
return { success: false, message } return { success: false, message }
} }
} catch (error) { } catch (error) {
console.log(error,'error');
const errorData = error.response?.data const errorData = error.response?.data
if (errorData?.needPayment) { if (errorData?.needPayment) {
// 处理403状态码返回的需要支付情况 // 处理403状态码返回的需要支付情况
@@ -146,15 +148,13 @@ export const useUserStore = defineStore('user', () => {
try { try {
// 确保请求头已设置 // 确保请求头已设置
if (token.value && !api.defaults.headers.common['Authorization']) {
api.defaults.headers.common['Authorization'] = `Bearer ${token.value}`
}
const response = await api.get('/auth/me') const response = await api.get('/auth/me')
setUser(response.data.user) setUser(response.data.user)
return true return true
} catch (error) { } catch (error) {
// token无效清除本地存储 // token无效清除本地存储
console.log('token无效清除本地存储',error);
setToken('') setToken('')
setUser(null) setUser(null)
return false return false

View File

@@ -1,65 +1,66 @@
import axios from 'axios' import axios from 'axios'
import { ElMessage, ElLoading } from 'element-plus' import { ElMessage, ElLoading } from 'element-plus'
import router from '@/router' import router from '@/router'
import NProgress from 'nprogress'
// 创建axios实例 // 创建axios实例
const api = axios.create({ // 工厂函数(复用拦截器逻辑)
baseURL: '/api', export const createRequest = (baseURL) => {
const request = axios.create({
baseURL,
timeout: 10000, timeout: 10000,
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
}) })
// 初始化时设置token // 初始化时设置token
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
if (token) { if (token) {
api.defaults.headers.common['Authorization'] = `Bearer ${token}` request.defaults.headers.common['Authorization'] = `Bearer ${token}`
} }
// 请求拦截器 // 请求拦截器
let loadingInstance = null request.interceptors.request.use(
api.interceptors.request.use(
(config) => { (config) => {
// 从localStorage获取token // 开始进度条
NProgress.start()
// 显示加载动画(除了某些不需要的请求)
if (!config.hideLoading) {
showLoading()
}
// 添加认证token
const token = localStorage.getItem('token') const token = localStorage.getItem('token')
if (token) { if (token) {
config.headers.Authorization = `Bearer ${token}` config.headers.Authorization = `Bearer ${token}`
} }
// 显示加载动画(可选)
if (config.showLoading !== false) {
loadingInstance = ElLoading.service({
text: '加载中...',
background: 'rgba(0, 0, 0, 0.7)'
})
}
return config return config
}, },
(error) => { (error) => {
if (loadingInstance) { hideLoading()
loadingInstance.close() NProgress.done()
}
return Promise.reject(error) return Promise.reject(error)
} }
) )
// 响应拦截器 // 响应拦截器
api.interceptors.response.use( request.interceptors.response.use(
(response) => { (response) => {
if (loadingInstance) { hideLoading()
loadingInstance.close() NProgress.done()
}
return response return response
}, },
(error) => { (error) => {
if (loadingInstance) { hideLoading()
loadingInstance.close() NProgress.done()
}
const { response } = error
// 处理不同的错误状态码 // 处理不同的错误状态码
if (error.response) { if (response) {
const { status, data } = error.response const { status, data } = error.response
switch (status) { switch (status) {
@@ -136,13 +137,53 @@ api.interceptors.response.use(
} }
) )
return request
}
let loadingInstance = null
let requestCount = 0
let isLoggingOut = false // 防止重复登出
// 显示加载
const showLoading = () => {
if (requestCount === 0) {
loadingInstance = ElLoading.service({
text: '加载中...',
background: 'rgba(0, 0, 0, 0.7)'
})
}
requestCount++
}
// 隐藏加载
const hideLoading = () => {
requestCount--
if (requestCount <= 0) {
requestCount = 0
if (loadingInstance) {
loadingInstance.close()
loadingInstance = null
}
}
}
// 生成不同的实例
export const apiRequest = createRequest('/api')
export const midRequest = createRequest('/mid')
// 初始化时设置token
const token = localStorage.getItem('token')
if (token) {
apiRequest.defaults.headers.common['Authorization'] = `Bearer ${token}`
}
// 封装常用的请求方法 // 封装常用的请求方法
export const request = { const api = {
get: (url, config = {}) => api.get(url, config), get: (url, config = {}) => apiRequest.get(url, config),
post: (url, data = {}, config = {}) => api.post(url, data, config), post: (url, data = {}, config = {}) => apiRequest.post(url, data, config),
put: (url, data = {}, config = {}) => api.put(url, data, config), put: (url, data = {}, config = {}) => apiRequest.put(url, data, config),
delete: (url, config = {}) => api.delete(url, config), delete: (url, config = {}) => apiRequest.delete(url, config),
patch: (url, data = {}, config = {}) => api.patch(url, data, config) patch: (url, data = {}, config = {}) => apiRequest.patch(url, data, config)
} }
@@ -150,43 +191,43 @@ export const request = {
// 用户相关API // 用户相关API
export const userAPI = { export const userAPI = {
// 获取用户列表 // 获取用户列表
getList: (params = {}) => request.get('/users', { params }), getList: (params = {}) => apiRequest.get('/users', { params }),
// 获取用户详情 // 获取用户详情
getDetail: (id) => request.get(`/users/${id}`), getDetail: (id) => apiRequest.get(`/users/${id}`),
// 更新用户信息 // 更新用户信息
update: (id, data) => request.put(`/users/${id}`, data), update: (id, data) => apiRequest.put(`/users/${id}`, data),
// 删除用户 // 删除用户
delete: (id) => request.delete(`/users/${id}`), delete: (id) => apiRequest.delete(`/users/${id}`),
// 获取用户统计 // 获取用户统计
getStats: () => request.get('/users/stats/overview') getStats: () => apiRequest.get('/users/stats/overview')
} }
// 认证相关API // 认证相关API
export const authAPI = { export const authAPI = {
// 登录 // 登录
login: (data) => request.post('/auth/login', data), login: (data) => midRequest.post('/auth/login', data),
// 注册 // 注册
register: (data) => request.post('/auth/register', data), register: (data) => midRequest.post('/auth/register', data),
// 获取当前用户信息 // 获取当前用户信息
me: () => request.get('/auth/me'), me: () => apiRequest.get('/auth/me'),
// 修改密码 // 修改密码
changePassword: (data) => request.put('/auth/change-password', data) changePassword: (data) => apiRequest.put('/auth/change-password', data)
} }
// 验证码相关API // 验证码相关API
export const captchaAPI = { export const captchaAPI = {
// 生成验证码 // 生成验证码
generate: () => request.get('/captcha/generate'), generate: () => midRequest.get('/captcha/generate'),
// 验证验证码 // 验证验证码
verify: (data) => request.post('/captcha/verify', data) verify: (data) => midRequest.post('/captcha/verify', data)
} }
// 文件上传API // 文件上传API
@@ -195,7 +236,7 @@ export const uploadAPI = {
uploadImage: (file) => { uploadImage: (file) => {
const formData = new FormData() const formData = new FormData()
formData.append('image', file) formData.append('image', file)
return request.post('/upload/image', formData, { return midRequest.post('/upload/image', formData, {
headers: { headers: {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
} }
@@ -206,7 +247,7 @@ export const uploadAPI = {
uploadFile: (file) => { uploadFile: (file) => {
const formData = new FormData() const formData = new FormData()
formData.append('file', file) formData.append('file', file)
return request.post('/upload/file', formData, { return midRequest.post('/upload/file', formData, {
headers: { headers: {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
} }
@@ -217,24 +258,29 @@ export const uploadAPI = {
// 支付相关API // 支付相关API
export const paymentAPI = { export const paymentAPI = {
// 获取支付方式 // 获取支付方式
getMethods: () => request.get('/payment/methods'), getMethods: () => apiRequest.get('/payment/methods'),
// 创建支付订单 // 创建支付订单
createOrder: (data) => request.post('/payment/create-order', data), createOrder: (data) => apiRequest.post('/payment/create-order', data),
// 查询支付状态 // 查询支付状态
queryStatus: (outTradeNo) => request.get(`/payment/query-status/${outTradeNo}`), queryStatus: (outTradeNo) => apiRequest.get(`/payment/query-status/${outTradeNo}`),
getOrder: () => request.get('/payment/check-status'), getOrder: () => apiRequest.get('/payment/check-status'),
// 获取支付记录 // 获取支付记录
getOrders: (params = {}) => request.get('/payment/orders', { params }) getOrders: (params = {}) => apiRequest.get('/payment/orders', { params })
}
// 购买商品
export const buyAPI = {
buy: (data) => midRequest.post('/payment/create-order', data),
} }
// 转账相关API // 转账相关API
export const transferAPI = { export const transferAPI = {
// 获取公户信息 // 获取公户信息
getPublicAccount: () => request.get('/transfers/public-account'), getPublicAccount: () => apiRequest.get('/transfers/public-account'),
// 创建转账记录 // 创建转账记录
create: (data) => { create: (data) => {
@@ -242,7 +288,7 @@ export const transferAPI = {
Object.keys(data).forEach(key => { Object.keys(data).forEach(key => {
formData.append(key, data[key]) formData.append(key, data[key])
}) })
return request.post('/transfers', formData, { return apiRequest.post('/transfers', formData, {
headers: { headers: {
'Content-Type': 'multipart/form-data' 'Content-Type': 'multipart/form-data'
} }
@@ -250,38 +296,38 @@ export const transferAPI = {
}, },
// 确认转账 // 确认转账
confirm: (id) => request.put(`/transfers/${id}/confirm`), confirm: (id) => apiRequest.put(`/transfers/${id}/confirm`),
// 拒绝转账 // 拒绝转账
reject: (id) => request.put(`/transfers/${id}/reject`), reject: (id) => apiRequest.put(`/transfers/${id}/reject`),
// 确认收款 // 确认收款
confirmReceived: (id) => request.post('/transfers/confirm-received', { transfer_id: id }), confirmReceived: (id) => apiRequest.post('/transfers/confirm-received', { transfer_id: id }),
// 确认未收到款 // 确认未收到款
confirmNotReceived: (id) => request.post('/transfers/confirm-not-received', { transfer_id: id }), confirmNotReceived: (id) => apiRequest.post('/transfers/confirm-not-received', { transfer_id: id }),
// 获取用户转账记录 // 获取用户转账记录
getUserTransfers: (params = {}) => request.get('/transfers/user', { params }), getUserTransfers: (params = {}) => apiRequest.get('/transfers/user', { params }),
// 获取指定用户的转账记录 // 获取指定用户的转账记录
getUserTransfersByUserId: (userId, params = {}) => request.get(`/transfers/user/${userId}`, { params }), getUserTransfersByUserId: (userId, params = {}) => apiRequest.get(`/transfers/user/${userId}`, { params }),
// 获取待确认转账 // 获取待确认转账
getPendingTransfers: (params = {}) => request.get('/transfers/pending', { params }), getPendingTransfers: (params = {}) => apiRequest.get('/transfers/pending', { params }),
// 获取用户账户信息 // 获取用户账户信息
getUserAccount: () => request.get('/transfers/account'), getUserAccount: () => apiRequest.get('/transfers/account'),
// 获取转账列表(管理员) // 获取转账列表(管理员)
getList: (params = {}) => request.get('/transfers', { params }), getList: (params = {}) => apiRequest.get('/transfers', { params }),
// 获取转账统计 // 获取转账统计
getStats: () => request.get('/transfers/stats') getStats: () => apiRequest.get('/transfers/stats')
} }
export const distributionAPI = { export const distributionAPI = {
getLowerUsers: (params) => request.get('/agents/distribution', { params }), getLowerUsers: (params) => apiRequest.get('/agents/distribution', { params }),
} }
export default api export default api

View File

@@ -2,20 +2,70 @@
<div class="coupon-container"> <div class="coupon-container">
<div class="header"> <div class="header">
<div class="back-btn" @click="$router.go(-1)"><</div> <div class="back-btn" @click="$router.go(-1)"><</div>
<div class="text"> <div class="header-text">
优惠券包 优惠券包
</div> </div>
</div> </div>
<div class="coupon-content"> <div class="coupon-content">
<div class="coupon-item" @click="getCoupon('1')"> <div class="discount_for_a_amount_container">
领满减 <div class="container-title">
满减券限量
</div>
<div class="coupons-content">
<div class="coupon-item" v-for="coupon in coupons" :key="coupon.id">
<div class="coupon-filtered-item" v-if="coupon.type === 'discount_for_a_amount'"
:style="{
backgroundImage: coupon.got
? 'url(/imgs/shop/coupon/bg_useless1.png)'
: 'url(/imgs/shop/coupon/bg_useful1.png)'
}">
<div class="text-left">{{ coupon.discount }}</div>
<div class="text-mid-w">{{ coupon.for_a_amount }}可用</div>
<div class="text-right" @click="getCoupon('discount_for_a_amount',coupon.id)" v-if="!coupon.got">立即领取</div>
<div class="text-right" v-else>已领取</div>
</div>
</div>
</div>
</div>
<div class="discount_container">
<div class="container-title" style="margin-bottom: 10px;">
抵扣券限量
</div>
<div class="coupons-content grid-container">
<div class="coupon-item" v-for="coupon in coupons" :key="coupon.id">
<div class="coupon-filtered-item2" v-if="coupon.type === 'deduction'"
:style="{
backgroundImage: coupon.got
? 'url(/imgs/shop/coupon/bg_useless2.png)'
: 'url(/imgs/shop/coupon/bg_useful2.png)'
}">
<div class="text-top">{{ coupon.price }}</div>
<div class="text-mid-h">无门槛</div>
<div class="text-bottom" @click="getCoupon('deduction',coupon.id)" v-if="!coupon.got">立即领取</div>
<div class="text-bottom" v-else>已领取</div>
</div>
</div>
</div>
</div>
<div class="deduction_container">
<div class="container-title">
折扣券限量
</div>
<div class="coupons-content">
<div class="coupon-item" v-for="coupon in coupons" :key="coupon.id">
<div class="coupon-filtered-item" v-if="coupon.type === 'discount'"
:style="{
backgroundImage: coupon.got
? 'url(/imgs/shop/coupon/bg_useless1.png)'
: 'url(/imgs/shop/coupon/bg_useful1.png)'
}">
<div class="text-left">{{ coupon.precent/10 }}</div>
<div class="text-right" @click="getCoupon('discount',coupon.id)" v-if="!coupon.got">立即领取</div>
<div class="text-right" v-else>已领取</div>
</div>
</div> </div>
<div class="coupon-item" @click="getCoupon('2')">
领折扣
</div> </div>
<div class="coupon-item" @click="getCoupon('3')">
领抵扣
</div> </div>
</div> </div>
@@ -30,11 +80,27 @@ import { ElMessage } from 'element-plus'
const userStore = useUserStore() const userStore = useUserStore()
const getCoupon = async (coupon_id) => { const coupons = ref([])
const getAllCoupons = async () => {
const {data} = await api.get('/coupon',{
params: {
user_id: userStore.user.id
}
})
if (data.success) {
coupons.value = data.coupon
console.log(123,coupons.value)
} else {
ElMessage.error(data.message || '优惠券领取失败')
}
}
const getCoupon = async (coupon_type,coupon_id) => {
try { try {
console.log(userStore)
const {data} = await api.get(`/coupon/${userStore.user.id}`,{ const {data} = await api.get(`/coupon/${userStore.user.id}`,{
params: { params: {
coupon_type: coupon_type,
coupon_id: coupon_id coupon_id: coupon_id
} }
}) })
@@ -50,18 +116,23 @@ const getCoupon = async (coupon_id) => {
} }
onMounted(() => { onMounted(() => {
// getCoupon() getAllCoupons()
}) })
</script> </script>
<style scoped> <style scoped>
.coupon-container {
width: 100%;
height: 100vh;
background-image: url(/imgs/shop/coupon/background.png);
}
.header { .header {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding-left: 20px; padding-left: 20px;
position: relative; position: relative;
margin-top: 25px;
} }
.back-btn { .back-btn {
@@ -77,19 +148,158 @@ onMounted(() => {
margin-top: 5px; margin-top: 5px;
} }
.text { .header-text {
width: 80px; width: 80px;
height: 28px; height: 28px;
angle: 0 deg;
opacity: 1; opacity: 1;
font-family: SF Pro; font-family: SF Pro;
font-weight: 650; font-weight: 650;
font-style: Expanded Semibold; font-style: Expanded Semibold;
font-size: 20px; font-size: 20px;
leading-trim: NONE;
line-height: 28px; line-height: 28px;
letter-spacing: 0%; letter-spacing: 0%;
color: #2F4FB5; color: #2F4FB5;
text-align: center; text-align: center;
} }
.coupon-content {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px;
padding: 20px;
height: 100vh;
}
.discount_for_a_amount_container,
.discount_container,
.deduction_container {
background: white;
width: 348px;
padding: 10px;
top: 32px;
opacity: 1;
border-radius: 8px;
margin-bottom: 20px;
}
.container-title {
width: 96;
height: 20;
top: 324px;
left: 105px;
opacity: 1;
font-family: SF Pro;
font-weight: 700;
font-style: Bold;
font-size: 16px;
line-height: 20px;
letter-spacing: 0%;
color: #2F4FB5;
text-align: center;
}
.coupon-filtered-item {
width: 324px;
height: 66px;
top: 58px;
left: 12px;
opacity: 1;
background-size: 100% 100%;
margin-top: 10px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
}
.text-left {
font-size: 25px;
font-weight: bold;
color: #305DEF;
}
.text-mid-w {
font-size: 14px;
color: #305DEF;
flex: 1;
text-align: center;
font-family: SF Pro;
font-weight: 590;
font-style: Semibold;
font-size: 16px;
line-height: 20px;
letter-spacing: 0%;
}
.text-right {
font-size: 14px;
color: #ffffff;
cursor: pointer;
padding: 5px 10px;
border-radius: 100px;
background: #305DEF;
transition: background-color 0.3s;
margin-right: -10px;
}
.text-right:hover {
background-color: #305DEF;
}
.grid-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
justify-items: center;
}
.coupon-item {
display: contents;
}
.coupon-filtered-item2 {
width: 83px;
height: 94px;
opacity: 1;
border-radius: 4px;
background-size: 100% 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 10px 0;
}
.text-top {
font-family: SF Pro;
font-weight: 700;
font-style: Bold;
font-size: 18px;
line-height: 20px;
letter-spacing: 0%;
color: #305DEF;
}
.text-mid-h {
font-family: SF Pro;
font-weight: 400;
font-style: Regular;
font-size: 15px;
line-height: 20px;
letter-spacing: 0%;
color: #305DEF;
margin-top: 10px;
}
.text-bottom {
font-size: 10px;
color: #305DEF;
cursor: pointer;
padding: 5px 10px;
border-radius: 100px;
transition: background-color 0.3s;
margin-top: 8px;
}
</style> </style>

View File

@@ -384,7 +384,7 @@ import {
Orange, Orange,
Check Check
} from '@element-plus/icons-vue' } from '@element-plus/icons-vue'
import api from '@/utils/api' import api, { buyAPI } from '@/utils/api'
import { getImageUrl } from '@/config' import { getImageUrl } from '@/config'
const route = useRoute() const route = useRoute()
@@ -418,10 +418,10 @@ const totalPointsPrice = computed(() => {
}, 0) }, 0)
}) })
// 计算人民币价格(融豆价格1:1换算 // 计算人民币价格(1融豆 = 1元
const getRMBPrice = () => { const getRMBPrice = () => {
const totalRongdou = totalRongdouPrice.value const totalRongdou = totalRongdouPrice.value
return (totalRongdou).toFixed(2) // 假设1融豆=0.01元,可根据实际汇率调整 return (totalRongdou).toFixed(2)
} }
// 用户余额数据 // 用户余额数据
const userBalance = ref({ const userBalance = ref({
@@ -747,7 +747,27 @@ const confirmPayment = async () => {
paying.value = true paying.value = true
// 创建订单数据 if (selectedPaymentMethod.value === 'wechat_h5' || selectedPaymentMethod.value === 'alipay_wap') {
const amount = Number(getRMBPrice())
const response = await buyAPI.buy({
paymentMethod: selectedPaymentMethod.value,
amount: amount*100
})
if (response?.data?.success) {
const payUrl = response.data.data?.payUrl
if (payUrl) {
window.location.href = payUrl
return
} else {
throw new Error('未获取到支付链接')
}
} else {
throw new Error(response?.data?.message || '创建支付订单失败')
}
}
// 其他支付方式:走原订单确认流程
const orderData = { const orderData = {
orderId: paymentData.value.orderId, orderId: paymentData.value.orderId,
addressId: selectedAddress.value.id, addressId: selectedAddress.value.id,
@@ -756,40 +776,12 @@ const confirmPayment = async () => {
beansAmount: paymentData.value.beansAmount beansAmount: paymentData.value.beansAmount
} }
// 向后端发送订单支付请求
const response = await api.post('/orders/confirm-payment', orderData) const response = await api.post('/orders/confirm-payment', orderData)
if (response.data.success) { if (response.data.success) {
// 微信支付
if (selectedPaymentMethod.value === 'wechat_h5') {
// 获取支付URL并跳转
const payUrl = response.data.data?.payUrl
if (payUrl) {
// 跳转到第三方支付页面
window.location.href = payUrl
return // 不再执行后续代码
}
}
// 支付宝支付
if (selectedPaymentMethod.value === 'alipay_wap') {
// 获取支付URL并跳转
const payUrl = response.data.data?.payUrl
if (payUrl) {
// 跳转到支付宝支付页面
window.location.href = payUrl
return // 不再执行后续代码
}
}
ElMessage.success('订单创建成功!') ElMessage.success('订单创建成功!')
// 跳转到PayLoading页面传递订单ID
router.push({ router.push({
path: '/payloading', path: '/payloading',
query: { query: { orderId: paymentData.value.orderId }
orderId: paymentData.value.orderId
}
}) })
} else { } else {
throw new Error(response.data.message || '创建订单失败') throw new Error(response.data.message || '创建订单失败')

View File

@@ -309,6 +309,7 @@ const getProductDetail = async () => {
}) })
} catch (error) { } catch (error) {
ElMessage.error('获取商品详情失败') ElMessage.error('获取商品详情失败')
console.log('获取商品详情失败',error);
router.go(-1) router.go(-1)
} finally { } finally {
loading.value = false loading.value = false

View File

@@ -16,7 +16,12 @@ export default defineConfig({
proxy: { proxy: {
'/api': { '/api': {
target: 'http://192.168.0.26:3000', target: 'http://192.168.0.26:3000',
changeOrigin: true changeOrigin: true,
},
'/mid': {
target: 'http://192.168.0.12:3005',
changeOrigin: true,
// rewrite: (path) => path.replace(/^\/mid/, '')
}, },
'/uploads': { '/uploads': {
target: 'http://192.168.0.26:3000', target: 'http://192.168.0.26:3000',