支付及优惠券页面更新
This commit is contained in:
BIN
public/imgs/shop/coupon/background.png
Normal file
BIN
public/imgs/shop/coupon/background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 KiB |
BIN
public/imgs/shop/coupon/bg_useful1.png
Normal file
BIN
public/imgs/shop/coupon/bg_useful1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
public/imgs/shop/coupon/bg_useful2.png
Normal file
BIN
public/imgs/shop/coupon/bg_useful2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
BIN
public/imgs/shop/coupon/bg_useless1.png
Normal file
BIN
public/imgs/shop/coupon/bg_useless1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
BIN
public/imgs/shop/coupon/bg_useless2.png
Normal file
BIN
public/imgs/shop/coupon/bg_useless2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -44,7 +44,7 @@
|
||||
import { ref, onMounted, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Refresh, Loading } from '@element-plus/icons-vue'
|
||||
import api from '@/utils/api'
|
||||
import api,{captchaAPI} from '@/utils/api'
|
||||
|
||||
// Props
|
||||
const props = defineProps({
|
||||
@@ -81,7 +81,7 @@ const loading = ref(false)
|
||||
const getCaptcha = async () => {
|
||||
try {
|
||||
loading.value = true
|
||||
const response = await api.get('/captcha/generate')
|
||||
const response = await captchaAPI.generate()
|
||||
|
||||
if (response.data.success) {
|
||||
captchaImage.value = response.data.data.image
|
||||
|
||||
@@ -312,7 +312,7 @@ router.beforeEach(async (to, from, next) => {
|
||||
}
|
||||
} else {
|
||||
// 普通用户页面认证逻辑
|
||||
console.log(userStore.isAuthenticated, 'isAuthenticated');
|
||||
// console.log(userStore.isAuthenticated, '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') {
|
||||
console.log('进来了');
|
||||
// console.log('进来了');
|
||||
|
||||
// 如果当前不在支付页面,静默重定向到支付页面(不显示额外通知)
|
||||
if (to.name !== 'Payment') {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { ref, computed } from 'vue'
|
||||
import api from '@/utils/api'
|
||||
import api,{authAPI} from '@/utils/api'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
export const useUserStore = defineStore('user', () => {
|
||||
@@ -23,10 +23,9 @@ export const useUserStore = defineStore('user', () => {
|
||||
token.value = newToken
|
||||
if (newToken) {
|
||||
localStorage.setItem('token', newToken)
|
||||
api.defaults.headers.common['Authorization'] = `Bearer ${newToken}`
|
||||
} else {
|
||||
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) => {
|
||||
try {
|
||||
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) {
|
||||
setToken(response.data.token)
|
||||
@@ -72,6 +73,7 @@ export const useUserStore = defineStore('user', () => {
|
||||
return { success: false, message }
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error,'error');
|
||||
const errorData = error.response?.data
|
||||
if (errorData?.needPayment) {
|
||||
// 处理403状态码返回的需要支付情况
|
||||
@@ -146,15 +148,13 @@ export const useUserStore = defineStore('user', () => {
|
||||
|
||||
try {
|
||||
// 确保请求头已设置
|
||||
if (token.value && !api.defaults.headers.common['Authorization']) {
|
||||
api.defaults.headers.common['Authorization'] = `Bearer ${token.value}`
|
||||
}
|
||||
|
||||
const response = await api.get('/auth/me')
|
||||
setUser(response.data.user)
|
||||
return true
|
||||
} catch (error) {
|
||||
// token无效,清除本地存储
|
||||
console.log('token无效,清除本地存储',error);
|
||||
setToken('')
|
||||
setUser(null)
|
||||
return false
|
||||
|
||||
192
src/utils/api.js
192
src/utils/api.js
@@ -1,65 +1,66 @@
|
||||
import axios from 'axios'
|
||||
import { ElMessage, ElLoading } from 'element-plus'
|
||||
import router from '@/router'
|
||||
import NProgress from 'nprogress'
|
||||
|
||||
// 创建axios实例
|
||||
const api = axios.create({
|
||||
baseURL: '/api',
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
// 工厂函数(复用拦截器逻辑)
|
||||
export const createRequest = (baseURL) => {
|
||||
const request = axios.create({
|
||||
baseURL,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
|
||||
// 初始化时设置token
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
request.defaults.headers.common['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
|
||||
// 初始化时设置token
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
api.defaults.headers.common['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
// 请求拦截器
|
||||
let loadingInstance = null
|
||||
api.interceptors.request.use(
|
||||
// 请求拦截器
|
||||
request.interceptors.request.use(
|
||||
(config) => {
|
||||
// 从localStorage获取token
|
||||
// 开始进度条
|
||||
NProgress.start()
|
||||
|
||||
// 显示加载动画(除了某些不需要的请求)
|
||||
if (!config.hideLoading) {
|
||||
showLoading()
|
||||
}
|
||||
|
||||
// 添加认证token
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
|
||||
// 显示加载动画(可选)
|
||||
if (config.showLoading !== false) {
|
||||
loadingInstance = ElLoading.service({
|
||||
text: '加载中...',
|
||||
background: 'rgba(0, 0, 0, 0.7)'
|
||||
})
|
||||
}
|
||||
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
if (loadingInstance) {
|
||||
loadingInstance.close()
|
||||
}
|
||||
hideLoading()
|
||||
NProgress.done()
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
api.interceptors.response.use(
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
(response) => {
|
||||
if (loadingInstance) {
|
||||
loadingInstance.close()
|
||||
}
|
||||
hideLoading()
|
||||
NProgress.done()
|
||||
return response
|
||||
},
|
||||
(error) => {
|
||||
if (loadingInstance) {
|
||||
loadingInstance.close()
|
||||
}
|
||||
hideLoading()
|
||||
NProgress.done()
|
||||
|
||||
const { response } = error
|
||||
|
||||
// 处理不同的错误状态码
|
||||
if (error.response) {
|
||||
if (response) {
|
||||
const { status, data } = error.response
|
||||
|
||||
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 = {
|
||||
get: (url, config = {}) => api.get(url, config),
|
||||
post: (url, data = {}, config = {}) => api.post(url, data, config),
|
||||
put: (url, data = {}, config = {}) => api.put(url, data, config),
|
||||
delete: (url, config = {}) => api.delete(url, config),
|
||||
patch: (url, data = {}, config = {}) => api.patch(url, data, config)
|
||||
const api = {
|
||||
get: (url, config = {}) => apiRequest.get(url, config),
|
||||
post: (url, data = {}, config = {}) => apiRequest.post(url, data, config),
|
||||
put: (url, data = {}, config = {}) => apiRequest.put(url, data, config),
|
||||
delete: (url, config = {}) => apiRequest.delete(url, config),
|
||||
patch: (url, data = {}, config = {}) => apiRequest.patch(url, data, config)
|
||||
}
|
||||
|
||||
|
||||
@@ -150,43 +191,43 @@ export const request = {
|
||||
// 用户相关API
|
||||
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
|
||||
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
|
||||
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
|
||||
@@ -195,7 +236,7 @@ export const uploadAPI = {
|
||||
uploadImage: (file) => {
|
||||
const formData = new FormData()
|
||||
formData.append('image', file)
|
||||
return request.post('/upload/image', formData, {
|
||||
return midRequest.post('/upload/image', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
@@ -206,7 +247,7 @@ export const uploadAPI = {
|
||||
uploadFile: (file) => {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
return request.post('/upload/file', formData, {
|
||||
return midRequest.post('/upload/file', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
@@ -217,24 +258,29 @@ export const uploadAPI = {
|
||||
// 支付相关API
|
||||
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
|
||||
export const transferAPI = {
|
||||
// 获取公户信息
|
||||
getPublicAccount: () => request.get('/transfers/public-account'),
|
||||
getPublicAccount: () => apiRequest.get('/transfers/public-account'),
|
||||
|
||||
// 创建转账记录
|
||||
create: (data) => {
|
||||
@@ -242,7 +288,7 @@ export const transferAPI = {
|
||||
Object.keys(data).forEach(key => {
|
||||
formData.append(key, data[key])
|
||||
})
|
||||
return request.post('/transfers', formData, {
|
||||
return apiRequest.post('/transfers', formData, {
|
||||
headers: {
|
||||
'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 = {
|
||||
getLowerUsers: (params) => request.get('/agents/distribution', { params }),
|
||||
getLowerUsers: (params) => apiRequest.get('/agents/distribution', { params }),
|
||||
}
|
||||
|
||||
export default api
|
||||
@@ -2,20 +2,70 @@
|
||||
<div class="coupon-container">
|
||||
<div class="header">
|
||||
<div class="back-btn" @click="$router.go(-1)"><</div>
|
||||
<div class="text">
|
||||
<div class="header-text">
|
||||
优惠券包
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<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="coupon-item" @click="getCoupon('2')">
|
||||
领折扣
|
||||
<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="coupon-item" @click="getCoupon('3')">
|
||||
领抵扣
|
||||
<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>
|
||||
</div>
|
||||
|
||||
@@ -30,11 +80,27 @@ import { ElMessage } from 'element-plus'
|
||||
|
||||
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 {
|
||||
console.log(userStore)
|
||||
const {data} = await api.get(`/coupon/${userStore.user.id}`,{
|
||||
params: {
|
||||
coupon_type: coupon_type,
|
||||
coupon_id: coupon_id
|
||||
}
|
||||
})
|
||||
@@ -50,18 +116,23 @@ const getCoupon = async (coupon_id) => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// getCoupon()
|
||||
getAllCoupons()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.coupon-container {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
background-image: url(/imgs/shop/coupon/background.png);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
margin-top: 25px;
|
||||
}
|
||||
|
||||
.back-btn {
|
||||
@@ -74,22 +145,161 @@ onMounted(() => {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
margin-left: 30px;
|
||||
margin-top: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.text {
|
||||
.header-text {
|
||||
width: 80px;
|
||||
height: 28px;
|
||||
angle: 0 deg;
|
||||
opacity: 1;
|
||||
font-family: SF Pro;
|
||||
font-weight: 650;
|
||||
font-style: Expanded Semibold;
|
||||
font-size: 20px;
|
||||
leading-trim: NONE;
|
||||
line-height: 28px;
|
||||
letter-spacing: 0%;
|
||||
color: #2F4FB5;
|
||||
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>
|
||||
|
||||
@@ -384,7 +384,7 @@ import {
|
||||
Orange,
|
||||
Check
|
||||
} from '@element-plus/icons-vue'
|
||||
import api from '@/utils/api'
|
||||
import api, { buyAPI } from '@/utils/api'
|
||||
import { getImageUrl } from '@/config'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -418,10 +418,10 @@ const totalPointsPrice = computed(() => {
|
||||
}, 0)
|
||||
})
|
||||
|
||||
// 计算人民币价格(融豆价格1:1换算)
|
||||
// 计算人民币价格(1融豆 = 1元)
|
||||
const getRMBPrice = () => {
|
||||
const totalRongdou = totalRongdouPrice.value
|
||||
return (totalRongdou).toFixed(2) // 假设1融豆=0.01元,可根据实际汇率调整
|
||||
return (totalRongdou).toFixed(2)
|
||||
}
|
||||
// 用户余额数据
|
||||
const userBalance = ref({
|
||||
@@ -747,7 +747,27 @@ const confirmPayment = async () => {
|
||||
|
||||
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 = {
|
||||
orderId: paymentData.value.orderId,
|
||||
addressId: selectedAddress.value.id,
|
||||
@@ -756,40 +776,12 @@ const confirmPayment = async () => {
|
||||
beansAmount: paymentData.value.beansAmount
|
||||
}
|
||||
|
||||
// 向后端发送订单支付请求
|
||||
const response = await api.post('/orders/confirm-payment', orderData)
|
||||
|
||||
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('订单创建成功!')
|
||||
|
||||
// 跳转到PayLoading页面,传递订单ID
|
||||
router.push({
|
||||
path: '/payloading',
|
||||
query: {
|
||||
orderId: paymentData.value.orderId
|
||||
}
|
||||
query: { orderId: paymentData.value.orderId }
|
||||
})
|
||||
} else {
|
||||
throw new Error(response.data.message || '创建订单失败')
|
||||
|
||||
@@ -309,6 +309,7 @@ const getProductDetail = async () => {
|
||||
})
|
||||
} catch (error) {
|
||||
ElMessage.error('获取商品详情失败')
|
||||
console.log('获取商品详情失败',error);
|
||||
router.go(-1)
|
||||
} finally {
|
||||
loading.value = false
|
||||
|
||||
@@ -16,7 +16,12 @@ export default defineConfig({
|
||||
proxy: {
|
||||
'/api': {
|
||||
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': {
|
||||
target: 'http://192.168.0.26:3000',
|
||||
|
||||
Reference in New Issue
Block a user