feat(payment): 初始化支付模块核心代码
- 添加支付常量类PaymentConstants,定义支付状态、微信、支付宝、银联等相关常量 - 创建微信支付类型常量类WechatPayType,支持JSAPI、NATIVE、H5、APP支付方式 - 新增支付控制器PaymentController,提供创建支付、查询状态、退款等统一接口 - 实现支付回调控制器PaymentNotifyController,处理微信、支付宝、银联异步通知 - 添加支付请求数据传输对象PaymentRequest,支持多种支付方式参数校验 - 定义支付响应、状态更新请求等相关DTO类- 集成Swagger注解,完善接口文档说明- 添加参数校验和异常处理机制,确保支付流程安全可靠
This commit is contained in:
@@ -106,3 +106,40 @@ export async function getClinicPrescription(id: number) {
|
||||
}
|
||||
return Promise.reject(new Error(res.message));
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信支付返回数据
|
||||
*/
|
||||
export interface WxPayResult {
|
||||
prepayId: string;
|
||||
orderNo: string;
|
||||
timeStamp: string;
|
||||
nonceStr: string;
|
||||
package: string;
|
||||
signType: string;
|
||||
paySign: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处方订单创建请求
|
||||
*/
|
||||
export interface PrescriptionOrderRequest {
|
||||
// 处方ID
|
||||
prescriptionId: number;
|
||||
// 支付方式 0余额支付, 1微信支付,3支付宝
|
||||
payType: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建处方订单并支付
|
||||
*/
|
||||
export async function createPrescriptionOrder(data: PrescriptionOrderRequest) {
|
||||
const res = await request.post<ApiResult<WxPayResult>>(
|
||||
'/clinic/clinic-prescription/order',
|
||||
data
|
||||
);
|
||||
if (res.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.message));
|
||||
}
|
||||
|
||||
13
src/api/payment/index.ts
Normal file
13
src/api/payment/index.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import request from '@/utils/request';
|
||||
import type { ApiResult } from '@/api';
|
||||
|
||||
/**
|
||||
* 统一支付
|
||||
*/
|
||||
export async function pay(data: any) {
|
||||
const res = await request.post<ApiResult<any>>('/payment/create',data);
|
||||
if (res.code === 0) {
|
||||
return res.data;
|
||||
}
|
||||
return Promise.reject(new Error(res.message));
|
||||
}
|
||||
29
src/api/payment/model/index.ts
Normal file
29
src/api/payment/model/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
|
||||
/**
|
||||
* 首页布局样式
|
||||
*/
|
||||
export interface Layout {
|
||||
// 内容区域的宽度
|
||||
width?: string;
|
||||
// 文字颜色
|
||||
color?: string;
|
||||
// 高亮颜色
|
||||
hover?: string;
|
||||
// 背景颜色
|
||||
backgroundColor?: string;
|
||||
headerStyle?: any;
|
||||
siteNameStyle?: any;
|
||||
showBanner?: boolean;
|
||||
// 背景图片
|
||||
banner?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码参数
|
||||
*/
|
||||
export interface UpdatePasswordParam {
|
||||
// 新密码
|
||||
password: string;
|
||||
// 原始密码
|
||||
oldPassword: string;
|
||||
}
|
||||
@@ -4,11 +4,11 @@ import {Button, Cell, CellGroup, Space, Empty, ConfigProvider, Tag} from '@nutui
|
||||
import {View, Text} from '@tarojs/components'
|
||||
import {ClinicPrescription} from "@/api/clinic/clinicPrescription/model";
|
||||
import {
|
||||
pageClinicPrescription
|
||||
pageClinicPrescription,
|
||||
WxPayResult
|
||||
} from "@/api/clinic/clinicPrescription";
|
||||
import {copyText} from "@/utils/common";
|
||||
import {PaymentHandler} from "@/utils/payment";
|
||||
import {OrderCreateRequest} from "@/api/shop/shopOrder/model";
|
||||
import {pay} from "@/api/payment";
|
||||
|
||||
const ClinicPrescriptionList = () => {
|
||||
const [list, setList] = useState<ClinicPrescription[]>([])
|
||||
@@ -35,18 +35,137 @@ const ClinicPrescriptionList = () => {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理微信支付
|
||||
*/
|
||||
const handleWechatPay = async (result: WxPayResult): Promise<void> => {
|
||||
console.log('处理微信支付:', result);
|
||||
|
||||
if (!result) {
|
||||
throw new Error('微信支付参数错误');
|
||||
}
|
||||
|
||||
// 验证微信支付必要参数
|
||||
if (!result.timeStamp || !result.nonceStr || !result.package || !result.paySign) {
|
||||
throw new Error('微信支付参数不完整');
|
||||
}
|
||||
|
||||
try {
|
||||
await Taro.requestPayment({
|
||||
timeStamp: result.timeStamp,
|
||||
nonceStr: result.nonceStr,
|
||||
package: result.package,
|
||||
signType: result.signType as any,
|
||||
paySign: result.paySign,
|
||||
});
|
||||
|
||||
console.log('微信支付成功');
|
||||
} catch (payError: any) {
|
||||
console.error('微信支付失败:', payError);
|
||||
|
||||
// 处理微信支付特定错误
|
||||
if (payError.errMsg) {
|
||||
if (payError.errMsg.includes('cancel')) {
|
||||
throw new Error('用户取消支付');
|
||||
} else if (payError.errMsg.includes('fail')) {
|
||||
throw new Error('微信支付失败,请重试');
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('微信支付失败');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 统一支付入口
|
||||
*/
|
||||
const onPay = async (item: ClinicPrescription) => {
|
||||
const orderData = {
|
||||
...item
|
||||
if (!item.id) {
|
||||
Taro.showToast({
|
||||
title: '处方信息缺失',
|
||||
icon: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
console.log(orderData,'统一支付入口统一支付入口统一支付入口')
|
||||
|
||||
Taro.showLoading({title: '支付中...'});
|
||||
|
||||
try {
|
||||
// 执行支付
|
||||
await PaymentHandler.pay(orderData, 1);
|
||||
// 调用统一支付接口
|
||||
const result = await pay(
|
||||
// addressId: 10951,
|
||||
// orderId: 0,
|
||||
// deliveryType: 0,
|
||||
// paymentType: 'JSAPI',
|
||||
// amount: 1,
|
||||
// subject: '开处方'
|
||||
{
|
||||
"paymentType": "WECHAT",
|
||||
"amount": 100.00,
|
||||
"subject": "网站建设服务订单",
|
||||
"description": "网站建设服务",
|
||||
"orderInfo": {
|
||||
"type": 0,
|
||||
"realName": "无",
|
||||
"address": "无",
|
||||
"addressId": 0,
|
||||
"deliveryType": 0,
|
||||
"channel": 0,
|
||||
"merchantId": null,
|
||||
"merchantName": null,
|
||||
"couponId": null,
|
||||
"comments": "网站建设服务订单",
|
||||
"goodsItems": [
|
||||
{
|
||||
"goodsId": 10004,
|
||||
"skuId": null,
|
||||
"quantity": 1,
|
||||
"specInfo": null
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
);
|
||||
console.log(result, 'resultresultresultresultresultresult')
|
||||
|
||||
console.log('订单创建结果:', result);
|
||||
|
||||
if (!result) {
|
||||
throw new Error('创建订单失败');
|
||||
}
|
||||
|
||||
if (!result.orderNo) {
|
||||
throw new Error('订单号获取失败');
|
||||
}
|
||||
|
||||
// 调用微信支付
|
||||
await handleWechatPay(result);
|
||||
|
||||
// 支付成功
|
||||
console.log('支付成功,订单号:', result.orderNo);
|
||||
|
||||
Taro.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
// 延迟刷新列表
|
||||
setTimeout(() => {
|
||||
reload();
|
||||
}, 2000);
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('支付失败:', error);
|
||||
|
||||
// 获取错误信息
|
||||
const errorMessage = error.message || '支付失败,请重试';
|
||||
|
||||
Taro.showToast({
|
||||
title: errorMessage,
|
||||
icon: 'error'
|
||||
});
|
||||
} finally {
|
||||
Taro.hideLoading();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -123,7 +242,7 @@ const ClinicPrescriptionList = () => {
|
||||
<Cell>
|
||||
<Space className="w-full justify-end">
|
||||
<Button
|
||||
type={'warning'}
|
||||
type={'danger'}
|
||||
onClick={() => onPay(item)}
|
||||
>
|
||||
去支付
|
||||
|
||||
Reference in New Issue
Block a user