feat(payment): 初始化支付模块核心代码

- 添加支付常量类PaymentConstants,定义支付状态、微信、支付宝、银联等相关常量
- 创建微信支付类型常量类WechatPayType,支持JSAPI、NATIVE、H5、APP支付方式
- 新增支付控制器PaymentController,提供创建支付、查询状态、退款等统一接口
- 实现支付回调控制器PaymentNotifyController,处理微信、支付宝、银联异步通知
- 添加支付请求数据传输对象PaymentRequest,支持多种支付方式参数校验
- 定义支付响应、状态更新请求等相关DTO类- 集成Swagger注解,完善接口文档说明- 添加参数校验和异常处理机制,确保支付流程安全可靠
This commit is contained in:
2025-11-03 12:31:47 +08:00
parent 894b4bf7ce
commit 5749fab9e8
25 changed files with 4952 additions and 9 deletions

View File

@@ -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
View 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));
}

View 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;
}

View File

@@ -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)}
>