|
|
@@ -0,0 +1,163 @@
|
|
|
+import { z } from '@hono/zod-openapi';
|
|
|
+import { UserSchema } from '@/server/modules/users/user.schema';
|
|
|
+
|
|
|
+// 支付状态枚举
|
|
|
+export enum PaymentStatus {
|
|
|
+ PENDING = 0,
|
|
|
+ COMPLETED = 1,
|
|
|
+ FAILED = 2,
|
|
|
+ CANCELLED = 3
|
|
|
+}
|
|
|
+
|
|
|
+// 支付类型枚举
|
|
|
+export enum PaymentType {
|
|
|
+ RECHARGE = 'recharge',
|
|
|
+ CONSUME = 'consume',
|
|
|
+ REFUND = 'refund'
|
|
|
+}
|
|
|
+
|
|
|
+// 基础支付实体 schema
|
|
|
+export const PaymentSchema = z.object({
|
|
|
+ id: z.number().int('支付记录ID必须是整数').positive('支付记录ID必须是正整数').openapi({
|
|
|
+ description: '支付记录ID',
|
|
|
+ example: 1
|
|
|
+ }),
|
|
|
+ userId: z.number().int('用户ID必须是整数').positive('用户ID必须是正整数').openapi({
|
|
|
+ description: '用户ID',
|
|
|
+ example: 123
|
|
|
+ }),
|
|
|
+ user: UserSchema.openapi({
|
|
|
+ description: '用户信息',
|
|
|
+ example: {
|
|
|
+ id: 123,
|
|
|
+ username: 'testuser',
|
|
|
+ nickname: '测试用户',
|
|
|
+ email: 'test@example.com'
|
|
|
+ }
|
|
|
+ }),
|
|
|
+ orderNo: z.string().min(1, '订单号不能为空').max(64, '订单号最多64个字符').openapi({
|
|
|
+ description: '订单号',
|
|
|
+ example: 'ORDER20240821123456'
|
|
|
+ }),
|
|
|
+ amount: z.coerce.number().positive('支付金额必须大于0').multipleOf(0.01, '支付金额最多保留两位小数').openapi({
|
|
|
+ description: '支付金额',
|
|
|
+ example: 99.99
|
|
|
+ }),
|
|
|
+ documentCount: z.coerce.number().int('文档处理次数必须是整数').min(1, '文档处理次数至少为1').openapi({
|
|
|
+ description: '文档处理次数',
|
|
|
+ example: 100
|
|
|
+ }),
|
|
|
+ paymentType: z.enum([PaymentType.RECHARGE, PaymentType.CONSUME, PaymentType.REFUND]).openapi({
|
|
|
+ description: '支付类型: recharge-充值, consume-消费, refund-退款',
|
|
|
+ example: PaymentType.RECHARGE
|
|
|
+ }),
|
|
|
+ status: z.coerce.number().int('支付状态必须是整数').min(0).max(3, '支付状态值只能是0-3').openapi({
|
|
|
+ description: '支付状态: 0-待支付,1-已完成,2-失败,3-已取消',
|
|
|
+ example: PaymentStatus.PENDING
|
|
|
+ }),
|
|
|
+ paymentMethod: z.string().max(20, '支付方式最多20个字符').nullable().openapi({
|
|
|
+ description: '支付方式: alipay, wechat',
|
|
|
+ example: 'alipay'
|
|
|
+ }),
|
|
|
+ transactionId: z.string().max(64, '第三方交易ID最多64个字符').nullable().openapi({
|
|
|
+ description: '第三方交易ID',
|
|
|
+ example: '202408211234567890'
|
|
|
+ }),
|
|
|
+ description: z.string().max(1000, '支付描述最多1000个字符').nullable().openapi({
|
|
|
+ description: '支付描述',
|
|
|
+ example: '购买100次文档处理服务'
|
|
|
+ }),
|
|
|
+ createdAt: z.coerce.date('创建时间格式不正确').openapi({
|
|
|
+ description: '创建时间',
|
|
|
+ example: '2024-08-21T10:30:00Z'
|
|
|
+ }),
|
|
|
+ updatedAt: z.coerce.date('更新时间格式不正确').openapi({
|
|
|
+ description: '更新时间',
|
|
|
+ example: '2024-08-21T10:30:00Z'
|
|
|
+ })
|
|
|
+});
|
|
|
+
|
|
|
+// 创建支付请求 schema
|
|
|
+export const CreatePaymentDto = z.object({
|
|
|
+ userId: z.coerce.number().int('用户ID必须是整数').positive('用户ID必须是正整数').openapi({
|
|
|
+ description: '用户ID',
|
|
|
+ example: 123
|
|
|
+ }),
|
|
|
+ amount: z.coerce.number().positive('支付金额必须大于0').multipleOf(0.01, '支付金额最多保留两位小数').openapi({
|
|
|
+ description: '支付金额',
|
|
|
+ example: 99.99
|
|
|
+ }),
|
|
|
+ documentCount: z.coerce.number().int('文档处理次数必须是整数').min(1, '文档处理次数至少为1').openapi({
|
|
|
+ description: '文档处理次数',
|
|
|
+ example: 100
|
|
|
+ }),
|
|
|
+ paymentType: z.enum([PaymentType.RECHARGE, PaymentType.CONSUME, PaymentType.REFUND]).openapi({
|
|
|
+ description: '支付类型: recharge-充值, consume-消费, refund-退款',
|
|
|
+ example: PaymentType.RECHARGE
|
|
|
+ }),
|
|
|
+ paymentMethod: z.string().max(20, '支付方式最多20个字符').optional().openapi({
|
|
|
+ description: '支付方式: alipay, wechat',
|
|
|
+ example: 'alipay'
|
|
|
+ }),
|
|
|
+ description: z.string().max(1000, '支付描述最多1000个字符').optional().openapi({
|
|
|
+ description: '支付描述',
|
|
|
+ example: '购买100次文档处理服务'
|
|
|
+ })
|
|
|
+});
|
|
|
+
|
|
|
+// 更新支付请求 schema
|
|
|
+export const UpdatePaymentDto = z.object({
|
|
|
+ amount: z.coerce.number().positive('支付金额必须大于0').multipleOf(0.01, '支付金额最多保留两位小数').optional().openapi({
|
|
|
+ description: '支付金额',
|
|
|
+ example: 99.99
|
|
|
+ }),
|
|
|
+ documentCount: z.coerce.number().int('文档处理次数必须是整数').min(1, '文档处理次数至少为1').optional().openapi({
|
|
|
+ description: '文档处理次数',
|
|
|
+ example: 100
|
|
|
+ }),
|
|
|
+ paymentType: z.enum([PaymentType.RECHARGE, PaymentType.CONSUME, PaymentType.REFUND]).optional().openapi({
|
|
|
+ description: '支付类型: recharge-充值, consume-消费, refund-退款',
|
|
|
+ example: PaymentType.RECHARGE
|
|
|
+ }),
|
|
|
+ status: z.coerce.number().int('支付状态必须是整数').min(0).max(3, '支付状态值只能是0-3').optional().openapi({
|
|
|
+ description: '支付状态: 0-待支付,1-已完成,2-失败,3-已取消',
|
|
|
+ example: PaymentStatus.COMPLETED
|
|
|
+ }),
|
|
|
+ paymentMethod: z.string().max(20, '支付方式最多20个字符').optional().openapi({
|
|
|
+ description: '支付方式: alipay, wechat',
|
|
|
+ example: 'alipay'
|
|
|
+ }),
|
|
|
+ transactionId: z.string().max(64, '第三方交易ID最多64个字符').optional().openapi({
|
|
|
+ description: '第三方交易ID',
|
|
|
+ example: '202408211234567890'
|
|
|
+ }),
|
|
|
+ description: z.string().max(1000, '支付描述最多1000个字符').optional().openapi({
|
|
|
+ description: '支付描述',
|
|
|
+ example: '购买100次文档处理服务'
|
|
|
+ })
|
|
|
+});
|
|
|
+
|
|
|
+// 支付列表响应 schema
|
|
|
+export const PaymentListResponse = z.object({
|
|
|
+ data: z.array(PaymentSchema),
|
|
|
+ pagination: z.object({
|
|
|
+ total: z.number().openapi({
|
|
|
+ example: 100,
|
|
|
+ description: '总记录数'
|
|
|
+ }),
|
|
|
+ current: z.number().openapi({
|
|
|
+ example: 1,
|
|
|
+ description: '当前页码'
|
|
|
+ }),
|
|
|
+ pageSize: z.number().openapi({
|
|
|
+ example: 10,
|
|
|
+ description: '每页数量'
|
|
|
+ })
|
|
|
+ })
|
|
|
+});
|
|
|
+
|
|
|
+// 类型导出
|
|
|
+export type Payment = z.infer<typeof PaymentSchema>;
|
|
|
+export type CreatePaymentRequest = z.infer<typeof CreatePaymentDto>;
|
|
|
+export type UpdatePaymentRequest = z.infer<typeof UpdatePaymentDto>;
|
|
|
+export type PaymentListResponseType = z.infer<typeof PaymentListResponse>;
|