Browse Source

refactor(auth): 移除小程序登录接口并优化手机验证码发送

refactor(user): 重构充值流程,将订单创建移至支付组件

feat(login): 实现真实手机验证码发送接口并优化登录流程

refactor(payment): 重构微信支付组件,支持真实支付状态查询

style(api): 格式化用户相关API代码,移除无用接口
master
前端-胡立永 3 weeks ago
parent
commit
aebd71d86c
6 changed files with 485 additions and 434 deletions
  1. BIN
      dist.zip
  2. +5
    -24
      src/api/auth.js
  3. +271
    -321
      src/api/user.js
  4. +57
    -23
      src/components/auth/LoginRegisterModal.vue
  5. +134
    -44
      src/components/common/WechatPayment.vue
  6. +18
    -22
      src/views/user/Recharge.vue

BIN
dist.zip View File


+ 5
- 24
src/api/auth.js View File

@ -4,24 +4,6 @@ import api from './index.js';
* 授权登录相关接口 * 授权登录相关接口
*/ */
export const authApi = { export const authApi = {
/**
* 微信小程序授权登录
* @param {Object} params 登录参数
* @param {string} params.code 参数信息
* @param {string} params.encryptedData 解密
* @param {string} params.headimgurl 用户头像
* @param {string} params.id 标识
* @param {string} params.iv 解密标签
* @param {string} params.nickName 用户姓名
* @param {string} params.openid 用户唯一标识
* @param {string} params.session_key 会话密钥
* @param {string} params.shareId 邀请者销售标识
* @param {string} params.state 类型
* @param {string} params.vid 参数信息
*/
appletLogin(params) {
return api.get('/all_login/appletLogin', { params });
},
/** /**
* pc端手机号码验证码登录 * pc端手机号码验证码登录
@ -34,13 +16,12 @@ export const authApi = {
}, },
/** /**
* 绑定手机号码
* @param {string} code 授权码
* 发送手机验证码
* @param {Object} params 参数
* @param {string} params.phone 手机号
*/ */
bindPhone(code) {
return api.get('/all_login/bindPhone', {
params: { code }
});
phoneSendCode(params) {
return api.get('/all_login/phoneSendCode', { params });
}, },
/** /**


+ 271
- 321
src/api/user.js View File

@ -4,356 +4,306 @@ import api from './index.js';
* 我的-流水相关接口 * 我的-流水相关接口
*/ */
export const moneyApi = { export const moneyApi = {
/**
* 获取我的流水列表带分页
* @param {Object} params 查询参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
* @param {number} params.status 状态
*/
getMyMoneyLogPage(params) {
return api.get('/all_money/getMyMoneyLogPage', { params });
},
/**
* 获取我的可用积分数
*/
getMyMoneyNum() {
return api.get('/all_money/getMyMoneyNum');
}
/**
* 获取我的流水列表带分页
* @param {Object} params 查询参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
* @param {number} params.status 状态
*/
getMyMoneyLogPage(params) {
return api.get('/all_money/getMyMoneyLogPage', { params });
},
/**
* 获取我的可用积分数
*/
getMyMoneyNum() {
return api.get('/all_money/getMyMoneyNum');
}
}; };
/** /**
* 我的-评论相关接口 * 我的-评论相关接口
*/ */
export const commentApi = { export const commentApi = {
/**
* 删除评论信息
* @param {string} commentId 评论ID
*/
deleteComment(commentId) {
return api.get('/my_comment/deleteComment', {
params: { commentId }
});
},
/**
* 获取评论详情
* @param {string} commentId 评论ID
*/
getCommentDetail(commentId) {
return api.post('/my_comment/getCommentDetail', null, {
params: { commentId }
});
},
/**
* 根据书籍标识查询评论信息列表带分页
* @param {Object} params 查询参数
* @param {string} params.bookId 书籍ID
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
*/
getCommentList(params) {
return api.get('/my_comment/getCommentList', { params });
},
/**
* 获取我的评论列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
* @param {string} params.type 类型
*/
getMyCommentList(params) {
return api.get('/my_comment/getMyCommentList', { params });
},
/**
* 获取我的评论数
*/
getMyCommentNum() {
return api.get('/my_comment/getMyCommentNum');
},
/**
* 获取回复我的评论列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
* @param {string} params.type 类型 N-未读 Y-已读
*/
getMyReplyCommentList(params) {
return api.get('/my_comment/getMyReplyCommentList', { params });
},
/**
* 回复评论信息
* @param {Object} params 回复参数
* @param {string} params.commentId 评论ID
* @param {string} params.content 回复内容
*/
replyComment(params) {
return api.post('/my_comment/replyComment', null, { params });
},
/**
* 保存评论信息
* @param {Object} params 评论参数
* @param {string} params.bookId 书籍ID
* @param {string} params.content 评论内容
*/
saveComment(params) {
return api.post('/my_comment/saveComment', null, { params });
},
/**
* 更新评论已读状态
* @param {string} commentId 评论ID
*/
updateCommentRead() {
return api.post('/my_comment/updateCommentRead');
}
/**
* 删除评论信息
* @param {string} commentId 评论ID
*/
deleteComment(commentId) {
return api.get('/my_comment/deleteComment', {
params: { commentId }
});
},
/**
* 获取评论详情
* @param {string} commentId 评论ID
*/
getCommentDetail(commentId) {
return api.post('/my_comment/getCommentDetail', null, {
params: { commentId }
});
},
/**
* 根据书籍标识查询评论信息列表带分页
* @param {Object} params 查询参数
* @param {string} params.bookId 书籍ID
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
*/
getCommentList(params) {
return api.get('/my_comment/getCommentList', { params });
},
/**
* 获取我的评论列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
* @param {string} params.type 类型
*/
getMyCommentList(params) {
return api.get('/my_comment/getMyCommentList', { params });
},
/**
* 获取我的评论数
*/
getMyCommentNum() {
return api.get('/my_comment/getMyCommentNum');
},
/**
* 获取回复我的评论列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
* @param {string} params.type 类型 N-未读 Y-已读
*/
getMyReplyCommentList(params) {
return api.get('/my_comment/getMyReplyCommentList', { params });
},
/**
* 回复评论信息
* @param {Object} params 回复参数
* @param {string} params.commentId 评论ID
* @param {string} params.content 回复内容
*/
replyComment(params) {
return api.post('/my_comment/replyComment', null, { params });
},
/**
* 保存评论信息
* @param {Object} params 评论参数
* @param {string} params.bookId 书籍ID
* @param {string} params.content 评论内容
*/
saveComment(params) {
return api.post('/my_comment/saveComment', null, { params });
},
/**
* 更新评论已读状态
* @param {string} commentId 评论ID
*/
updateCommentRead() {
return api.post('/my_comment/updateCommentRead');
}
}; };
/** /**
* 我的-任务中心相关接口 * 我的-任务中心相关接口
*/ */
export const taskApi = { export const taskApi = {
/**
* 点击更多任务
* @param {string} taskId 任务ID
*/
clickMoreTask(taskId) {
return api.post('/my_task/clickMoreTask', null, {
params: { taskId }
});
},
/**
* 点击签到任务
* @param {string} taskId 任务ID
*/
clickSignTask(taskId) {
return api.get('/my_task/clickSignTask', {
params: { taskId }
});
},
/**
* 获取更多任务列表
* @param {string} token token
*/
getMoreTaskList(token) {
return api.get('/my_task/getMoreTaskList', {
params: { token }
});
},
/**
* 获取更多任务记录列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
*/
getMoreTaskRecordPage(params) {
return api.get('/my_task/getMoreTaskRecordPage', { params });
},
/**
* 获取我的推荐票数
*/
getMyRecommendTicketNum() {
return api.get('/my_task/getMyRecommendTicketNum');
},
/**
* 获取我的推荐任务列表
* @param {string} token token
*/
getSignTaskList(token) {
return api.get('/my_task/getSignTaskList', {
params: { token }
});
},
/**
* 获取我的推荐任务记录列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
*/
getSignTaskRecordPage(params) {
return api.get('/my_task/getSignTaskRecordPage', { params });
},
/**
* 获取我当天是否已经签到
*/
getSignTaskToday() {
return api.get('/my_task/getSignTaskToday');
}
/**
* 点击更多任务
* @param {string} taskId 任务ID
*/
clickMoreTask(taskId) {
return api.post('/my_task/clickMoreTask', null, {
params: { taskId }
});
},
/**
* 点击签到任务
* @param {string} taskId 任务ID
*/
clickSignTask(taskId) {
return api.get('/my_task/clickSignTask', {
params: { taskId }
});
},
/**
* 获取更多任务列表
* @param {string} token token
*/
getMoreTaskList(token) {
return api.get('/my_task/getMoreTaskList', {
params: { token }
});
},
/**
* 获取更多任务记录列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
*/
getMoreTaskRecordPage(params) {
return api.get('/my_task/getMoreTaskRecordPage', { params });
},
/**
* 获取我的推荐票数
*/
getMyRecommendTicketNum() {
return api.get('/my_task/getMyRecommendTicketNum');
},
/**
* 获取我的推荐任务列表
* @param {string} token token
*/
getSignTaskList(token) {
return api.get('/my_task/getSignTaskList', {
params: { token }
});
},
/**
* 获取我的推荐任务记录列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
*/
getSignTaskRecordPage(params) {
return api.get('/my_task/getSignTaskRecordPage', { params });
},
/**
* 获取我当天是否已经签到
*/
getSignTaskToday() {
return api.get('/my_task/getSignTaskToday');
}
}; };
/** /**
* 我的-申请成为作家相关接口 * 我的-申请成为作家相关接口
*/ */
export const writerApi = { export const writerApi = {
/**
* 查询我的笔名以及简介
*/
getMyWriter() {
return api.get('/my_writer/getMyWriter');
},
/**
* 填写或修改笔名以及简介成为作家
* @param {Object} params 作家信息
* @param {string} params.details 简介
* @param {string} params.penName 笔名
*/
saveOrUpdateWriter(params) {
return api.post('/my_writer/saveOrUpdateWriter', null, { params });
}
/**
* 查询我的笔名以及简介
*/
getMyWriter() {
return api.get('/my_writer/getMyWriter');
},
/**
* 填写或修改笔名以及简介成为作家
* @param {Object} params 作家信息
* @param {string} params.details 简介
* @param {string} params.penName 笔名
*/
saveOrUpdateWriter(params) {
return api.post('/my_writer/saveOrUpdateWriter', null, { params });
}
}; };
/** /**
* 我的-礼物订阅接口 * 我的-礼物订阅接口
*/ */
export const orderApi = { export const orderApi = {
/**
* 创建订单
* @param {Object} params 订单参数
* @param {string} params.giftId 礼物ID
* @param {number} params.num 数量
* @param {string} params.token token
*/
createOrder(params) {
return api.post('/my_order/createOrder', null, { params });
},
/**
* 查询礼物详情
* @param {string} giftId 礼物ID
*/
getGiftDetail(giftId) {
return api.get('/my_order/getGiftDetail', {
params: { giftId }
});
},
/**
* 查询互动打赏礼物信息列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
*/
getInteractionGiftList(params) {
return api.get('/my_order/getInteractionGiftList', { params });
},
/**
* 查询我的礼物包订单列表
* @param {Object} params 查询参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
* @param {string} params.token token
*/
getMyGiftList(params) {
return api.get('/my_order/getMyGiftList', { params });
},
/**
* 支付订单
* @param {Object} params 支付参数
* @param {string} params.orderId 订单ID
* @param {string} params.token token
*/
payOrder(params) {
return api.post('/my_order/payOrder', null, { params });
},
/**
* 支付成功
* @param {string} orderId 订单ID
*/
paySuccess(orderId) {
return api.post('/my_order/paySuccess', null, {
params: { orderId }
});
},
/**
* 购买章节
* @param {Object} params 购买参数
* @param {string} params.bookId 书籍ID
* @param {string} params.novelId 章节ID
*/
buyNovel(params) {
return api.post('/my_order/buyNovel', null, { params });
},
/**
* 创建支付套餐订单
* @param {string} packageId 套餐ID
*/
createPayPackageOrder(params) {
return api.post('/my_order/createPayPackageOrder', null, {
params
});
},
/**
* 充值套餐列表
*/
getPayPackageList() {
return api.get('/my_order/getPayPackageList');
},
/**
* 根据书籍id礼物id赠送礼物
* @param {Object} params 赠送参数
* @param {string} params.bookId 书籍ID
* @param {string} params.giftId 礼物ID
* @param {number} params.num 数量
*/
giveGift(params) {
return api.post('/my_order/giveGift', null, { params });
}
/**
* 查询礼物详情
* @param {string} giftId 礼物ID
*/
getGiftDetail(giftId) {
return api.get('/my_order/getGiftDetail', {
params: { giftId }
});
},
/**
* 查询互动打赏礼物信息列表
* @param {Object} params 分页参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
*/
getInteractionGiftList(params) {
return api.get('/my_order/getInteractionGiftList', { params });
},
/**
* 查询我的礼物包订单列表
* @param {Object} params 查询参数
* @param {number} params.pageNo 当前页
* @param {number} params.pageSize 显示条数
* @param {string} params.token token
*/
getMyGiftList(params) {
return api.get('/my_order/getMyGiftList', { params });
},
/**
* 购买章节
* @param {Object} params 购买参数
* @param {string} params.bookId 书籍ID
* @param {string} params.novelId 章节ID
*/
buyNovel(params) {
return api.post('/my_order/buyNovel', null, { params });
},
/**
* 创建支付套餐订单
* @param {string} packageId 套餐ID
*/
createPayPackageOrder(params) {
return api.post('/my_order/createPayPackageOrder', null, {
params
});
},
/**
* 充值套餐列表
*/
getPayPackageList() {
return api.get('/my_order/getPayPackageList');
},
/**
* 根据书籍id礼物id赠送礼物
* @param {Object} params 赠送参数
* @param {string} params.bookId 书籍ID
* @param {string} params.giftId 礼物ID
* @param {number} params.num 数量
*/
giveGift(params) {
return api.post('/my_order/giveGift', null, { params });
}
}; };
/** /**
* 微信支付相关接口 * 微信支付相关接口
*/ */
export const wechatPayApi = { export const wechatPayApi = {
/**
* 创建微信支付订单
* @param {Object} params 支付参数
* @param {string} params.orderId 订单ID
* @param {number} params.totalFee 支付金额
* @param {string} params.body 商品描述
*/
createWechatPayOrder(params) {
return api.post('/wechat_pay/createOrder', null, { params });
},
/**
* 查询微信支付订单状态
* @param {string} outTradeNo 商户订单号
*/
queryWechatPayStatus(outTradeNo) {
return api.get('/wechat_pay/queryOrder', {
params: { outTradeNo }
});
},
/**
* 取消微信支付订单
* @param {string} outTradeNo 商户订单号
*/
cancelWechatPayOrder(outTradeNo) {
return api.post('/wechat_pay/cancelOrder', null, {
params: { outTradeNo }
});
}
/**
* 查询微信支付订单状态
* @param {string} outTradeNo 商户订单号
*/
queryWechatPayStatus(outTradeNo) {
return api.get('/my_order/queryOrder', {
params: { outTradeNo }
});
},
}; };

+ 57
- 23
src/components/auth/LoginRegisterModal.vue View File

@ -6,9 +6,9 @@
<div class="phone-input"> <div class="phone-input">
<el-select v-model="countryCode" class="country-code"> <el-select v-model="countryCode" class="country-code">
<el-option label="+86" value="+86" /> <el-option label="+86" value="+86" />
<el-option label="+852" value="+852" />
<!-- <el-option label="+852" value="+852" />
<el-option label="+853" value="+853" /> <el-option label="+853" value="+853" />
<el-option label="+886" value="+886" />
<el-option label="+886" value="+886" /> -->
</el-select> </el-select>
<el-input v-model="phone" placeholder="手机号" /> <el-input v-model="phone" placeholder="手机号" />
</div> </div>
@ -44,6 +44,7 @@
import { ref, computed } from 'vue'; import { ref, computed } from 'vue';
import { ElMessage } from 'element-plus'; import { ElMessage } from 'element-plus';
import { useMainStore } from '@/store'; import { useMainStore } from '@/store';
import { authApi } from '@/api/auth';
export default { export default {
name: 'LoginRegisterModal', name: 'LoginRegisterModal',
@ -92,51 +93,83 @@ export default {
return true; return true;
}; };
const sendVerificationCode = () => {
const sendVerificationCode = async () => {
if (!phone.value) { if (!phone.value) {
ElMessage.error('请输入手机号'); ElMessage.error('请输入手机号');
return; return;
} }
// API
ElMessage.success(`验证码已发送至 ${countryCode.value}${phone.value}`);
//
const phoneRegex = /^1[3-9]\d{9}$/;
if (!phoneRegex.test(phone.value)) {
ElMessage.error('请输入正确的手机号格式');
return;
}
//
countdownActive.value = true;
countdown.value = 60;
try {
//
const response = await authApi.phoneSendCode({
phone: phone.value
});
const timer = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(timer);
countdownActive.value = false;
if (response.success) {
ElMessage.success(`验证码已发送至 ${countryCode.value}${phone.value}`);
//
countdownActive.value = true;
countdown.value = 60;
const timer = setInterval(() => {
countdown.value--;
if (countdown.value <= 0) {
clearInterval(timer);
countdownActive.value = false;
}
}, 1000);
} else {
ElMessage.error(response.message || '发送验证码失败,请稍后重试');
} }
}, 1000);
} catch (error) {
console.error('发送验证码失败:', error);
ElMessage.error('发送验证码失败,请稍后重试');
}
}; };
const handleSubmit = async () => { const handleSubmit = async () => {
if (!validateForm()) return; if (!validateForm()) return;
try { try {
// APIAPI
if (isLogin.value) { if (isLogin.value) {
//
await store.login({
// - API
const response = await authApi.phoneLogin({
phone: phone.value, phone: phone.value,
code: verificationCode.value code: verificationCode.value
}); });
emit('login-success');
ElMessage.success('登录成功');
if (response.success && response.result) {
// 使storelogin
await store.handleLoginSuccess(response.result);
emit('login-success');
ElMessage.success('登录成功');
} else {
throw new Error(response.message || '登录失败');
}
} else { } else {
//
await store.register({
// - 使
const response = await authApi.phoneLogin({
phone: phone.value, phone: phone.value,
code: verificationCode.value code: verificationCode.value
}); });
emit('register-success');
ElMessage.success('注册成功');
if (response.success && response.result) {
await store.handleLoginSuccess(response.result);
emit('register-success');
ElMessage.success('注册成功');
} else {
throw new Error(response.message || '注册失败');
}
} }
// //
@ -145,6 +178,7 @@ export default {
// //
resetForm(); resetForm();
} catch (error) { } catch (error) {
console.error('登录/注册失败:', error);
ElMessage.error(error.message || '操作失败,请稍后重试'); ElMessage.error(error.message || '操作失败,请稍后重试');
} }
}; };


+ 134
- 44
src/components/common/WechatPayment.vue View File

@ -7,7 +7,6 @@
width="400px" width="400px"
:close-on-click-modal="false" :close-on-click-modal="false"
:close-on-press-escape="false" :close-on-press-escape="false"
@close="handleCancel"
> >
<div class="payment-content"> <div class="payment-content">
<!-- 支付信息 --> <!-- 支付信息 -->
@ -24,6 +23,7 @@
<div class="qr-container"> <div class="qr-container">
<div class="qr-code" ref="qrCodeRef"> <div class="qr-code" ref="qrCodeRef">
<!-- 二维码将在这里生成 --> <!-- 二维码将在这里生成 -->
<div style="color: #999; font-size: 12px;">正在加载支付二维码...</div>
</div> </div>
<div class="qr-tips"> <div class="qr-tips">
<el-icon class="scan-icon"><Iphone /></el-icon> <el-icon class="scan-icon"><Iphone /></el-icon>
@ -103,7 +103,7 @@
<script> <script>
import { ref, computed, nextTick, onUnmounted, watch } from 'vue'; import { ref, computed, nextTick, onUnmounted, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus'; import { ElMessage, ElMessageBox } from 'element-plus';
import { orderApi } from '@/api/user';
import { orderApi, wechatPayApi } from '@/api/user';
import { import {
Iphone, Iphone,
Loading, Loading,
@ -111,9 +111,9 @@ import {
CircleClose, CircleClose,
Clock Clock
} from '@element-plus/icons-vue'; } from '@element-plus/icons-vue';
import { wechatPayApi } from '@/api/user.js';
import QRCode from 'qrcode'; import QRCode from 'qrcode';
export default { export default {
name: 'WechatPayment', name: 'WechatPayment',
components: { components: {
@ -133,10 +133,6 @@ export default {
paymentData: { paymentData: {
type: Object, type: Object,
default: () => ({ default: () => ({
orderId: '', // ID
title: '商品支付', //
amount: 0, //
body: '' //
}) })
} }
}, },
@ -156,6 +152,7 @@ export default {
let pollingTimer = null; let pollingTimer = null;
let countdownTimer = null; let countdownTimer = null;
let outTradeNo = ''; let outTradeNo = '';
let orderId = '';
// //
const formatAmount = (amount) => { const formatAmount = (amount) => {
@ -172,22 +169,58 @@ export default {
// //
const generateQrCode = async (codeUrl) => { const generateQrCode = async (codeUrl) => {
try { try {
console.log('开始生成二维码');
// DOM
await nextTick(); await nextTick();
if (qrCodeRef.value) {
qrCodeRef.value.innerHTML = '';
await QRCode.toCanvas(qrCodeRef.value, codeUrl, {
width: 200,
height: 200,
margin: 1,
color: {
dark: '#000000',
light: '#FFFFFF'
}
});
// DOM
let retryCount = 0;
while (!qrCodeRef.value && retryCount < 20) {
await new Promise(resolve => setTimeout(resolve, 100));
retryCount++;
await nextTick();
} }
if (!qrCodeRef.value) {
throw new Error('二维码容器元素未找到');
}
//
qrCodeRef.value.innerHTML = '';
//
const canvas = document.createElement('canvas');
await QRCode.toCanvas(canvas, codeUrl, {
width: 200,
height: 200,
margin: 1,
color: {
dark: '#000000',
light: '#FFFFFF'
}
});
// canvas
qrCodeRef.value.appendChild(canvas);
console.log('二维码生成成功');
} catch (error) { } catch (error) {
console.error('生成二维码失败:', error); console.error('生成二维码失败:', error);
ElMessage.error('生成二维码失败');
ElMessage.error(`生成二维码失败: ${error.message}`);
//
if (qrCodeRef.value) {
qrCodeRef.value.innerHTML = `
<div style="width: 200px; height: 200px; border: 2px dashed #ccc; display: flex; align-items: center; justify-content: center; color: #999; font-size: 14px; text-align: center;">
二维码生成失败<br/>请点击刷新重试
</div>
`;
} else {
//
paymentStatus.value = 'failed';
errorMessage.value = '二维码容器未找到,请刷新页面重试';
}
} }
}; };
@ -196,33 +229,36 @@ export default {
try { try {
paymentStatus.value = 'loading'; paymentStatus.value = 'loading';
if (!props.paymentData.packageId) {
throw new Error('缺少套餐ID');
}
const params = { const params = {
orderId: props.paymentData.orderId,
totalFee: props.paymentData.amount,
body: props.paymentData.body || props.paymentData.title
packageId: props.paymentData.packageId,
payType: 'web'
}; };
// API
await new Promise(resolve => setTimeout(resolve, 1000));
const mockResponse = {
code: 200,
result: {
codeUrl: `weixin://wxpay/bizpayurl?pr=${Math.random().toString(36).substr(2, 9)}`,
outTradeNo: `ORDER_${Date.now()}`
}
};
//
const result = await orderApi.createPayPackageOrder(params);
if (mockResponse.code === 200 && mockResponse.result) {
const { codeUrl, outTradeNo: tradeNo } = mockResponse.result;
outTradeNo = tradeNo;
await generateQrCode(codeUrl);
if (result.success && result.result) {
const { codeURL, orderId: responseOrderId } = result.result;
orderId = responseOrderId;
outTradeNo = responseOrderId; // 使orderIdoutTradeNo
// pendingDOM
paymentStatus.value = 'pending'; paymentStatus.value = 'pending';
// DOM
await nextTick();
await new Promise(resolve => setTimeout(resolve, 100)); // 100msDOM
await generateQrCode(codeURL);
startPolling(); startPolling();
startCountdown(); startCountdown();
} else { } else {
throw new Error('创建支付订单失败');
throw new Error(result.message || '创建支付订单失败');
} }
} catch (error) { } catch (error) {
console.error('创建支付订单失败:', error); console.error('创建支付订单失败:', error);
@ -254,19 +290,63 @@ export default {
// //
const checkPaymentStatus = async () => { const checkPaymentStatus = async () => {
try { try {
//
if (Math.random() > 0.95) {
handlePaymentSuccess();
if (!outTradeNo) {
return; return;
} }
// API
// const response = await wechatPayApi.queryWechatPayStatus(outTradeNo);
//
const response = await wechatPayApi.queryWechatPayStatus(outTradeNo);
if (response.success) {
const paymentState = response.result;
console.log('支付状态查询结果:', paymentState);
switch (paymentState) {
case 'SUCCESS':
//
handlePaymentSuccess();
break;
case 'CLOSED':
case 'REVOKED':
case 'PAYERROR':
//
handlePaymentFailed(getPaymentStateMessage(paymentState));
break;
case 'REFUND':
// 退
handlePaymentFailed('支付已退款');
break;
case 'NOTPAY':
case 'USERPAYING':
//
console.log('支付状态:', getPaymentStateMessage(paymentState));
break;
default:
console.log('未知支付状态:', paymentState);
break;
}
}
} catch (error) { } catch (error) {
console.error('查询支付状态失败:', error); console.error('查询支付状态失败:', error);
//
} }
}; };
//
const getPaymentStateMessage = (state) => {
const stateMap = {
'SUCCESS': '支付成功',
'REFUND': '转入退款',
'NOTPAY': '未支付',
'CLOSED': '已关闭',
'REVOKED': '已撤销',
'USERPAYING': '用户支付中',
'PAYERROR': '支付失败'
};
return stateMap[state] || `未知状态: ${state}`;
};
// //
const handlePaymentSuccess = () => { const handlePaymentSuccess = () => {
paymentStatus.value = 'success'; paymentStatus.value = 'success';
@ -274,7 +354,7 @@ export default {
stopCountdown(); stopCountdown();
ElMessage.success('支付成功!'); ElMessage.success('支付成功!');
emit('success', outTradeNo);
emit('success', orderId);
setTimeout(() => { setTimeout(() => {
visible.value = false; visible.value = false;
@ -368,7 +448,7 @@ export default {
// //
watch(visible, (newVal) => { watch(visible, (newVal) => {
if (newVal && props.paymentData.orderId) {
if (newVal && props.paymentData.packageId) {
createPaymentOrder(); createPaymentOrder();
} else { } else {
stopPolling(); stopPolling();
@ -376,6 +456,7 @@ export default {
paymentStatus.value = 'loading'; paymentStatus.value = 'loading';
errorMessage.value = ''; errorMessage.value = '';
outTradeNo = ''; outTradeNo = '';
orderId = '';
} }
}); });
@ -441,11 +522,20 @@ export default {
margin-bottom: 16px; margin-bottom: 16px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center;
min-height: 200px;
min-width: 200px;
:deep(canvas) { :deep(canvas) {
border-radius: 8px; border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
max-width: 100%;
height: auto;
} }
// 便
border: 1px solid #eee;
border-radius: 8px;
} }
.qr-tips { .qr-tips {


+ 18
- 22
src/views/user/Recharge.vue View File

@ -97,12 +97,12 @@ const rechargePackages = ref([]);
// //
const showPaymentModal = ref(false); const showPaymentModal = ref(false);
const currentOrderId = ref('');
const paymentData = computed(() => ({ const paymentData = computed(() => ({
orderId: currentOrderId.value,
title: `充值${totalBeans.value}豆豆`, title: `充值${totalBeans.value}豆豆`,
amount: Math.round(totalPrice.value * 100), // amount: Math.round(totalPrice.value * 100), //
body: `充值套餐 - ${totalBeans.value}豆豆`
body: `充值套餐 - ${totalBeans.value}豆豆`,
packageId: selectedPackage.value !== null ? rechargePackages.value[selectedPackage.value].id : null
})); }));
// //
@ -147,29 +147,24 @@ const handleRecharge = async () => {
return; return;
} }
if (selectedPackage.value === null) {
ElMessage.warning('请选择充值套餐');
return;
}
try { try {
//
const result = await orderApi.createPayPackageOrder({
packageId : rechargePackages.value[selectedPackage.value].id,
payType : 'web'
});
// ID
currentOrderId.value = result.result;
//
showPaymentModal.value = true; showPaymentModal.value = true;
} catch (error) { } catch (error) {
console.error('创建订单失败:', error);
ElMessage.error('创建订单失败,请重试');
console.error('发起支付失败:', error);
ElMessage.error('发起支付失败,请重试');
} }
}; };
// //
const handlePaymentSuccess = async (outTradeNo) => {
const handlePaymentSuccess = async (orderId) => {
try { try {
//
await orderApi.paySuccess(currentOrderId.value);
ElMessage.success(`充值成功,获得${totalBeans.value}豆豆`); ElMessage.success(`充值成功,获得${totalBeans.value}豆豆`);
// //
@ -180,7 +175,6 @@ const handlePaymentSuccess = async (outTradeNo) => {
// //
selectedPackage.value = null; selectedPackage.value = null;
currentOrderId.value = '';
// //
setTimeout(() => { setTimeout(() => {
@ -188,22 +182,24 @@ const handlePaymentSuccess = async (outTradeNo) => {
}, 2000); }, 2000);
} catch (error) { } catch (error) {
console.error('支付确认失败:', error);
ElMessage.error('支付确认失败,请联系客服');
console.error('更新用户信息失败:', error);
ElMessage.error('支付成功,但更新用户信息失败,请刷新页面');
// 使
showPaymentModal.value = false;
selectedPackage.value = null;
} }
}; };
// //
const handlePaymentCancel = () => { const handlePaymentCancel = () => {
showPaymentModal.value = false; showPaymentModal.value = false;
currentOrderId.value = '';
ElMessage.info('已取消支付'); ElMessage.info('已取消支付');
}; };
// //
const handlePaymentFailed = (errorMessage) => { const handlePaymentFailed = (errorMessage) => {
showPaymentModal.value = false; showPaymentModal.value = false;
currentOrderId.value = '';
ElMessage.error(errorMessage || '支付失败,请重试'); ElMessage.error(errorMessage || '支付失败,请重试');
}; };


Loading…
Cancel
Save