feat(c2c): 支持绿积分(GREEN_POINTS)作为默认支付方式

- 后端 paymentMethod 字段从 PostgreSQL 枚举改为 String,支持逗号分隔多种支付方式
- 添加数据库迁移将 C2cPaymentMethod 枚举列转为 TEXT 类型
- DTO 验证改为 @IsString() 接受 GREEN_POINTS 及其组合
- 前端保持发送完整的支付方式列表(含 GREEN_POINTS)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-01-29 11:39:00 -08:00
parent 263f1ecf8e
commit 83fa6bec74
6 changed files with 24 additions and 35 deletions

View File

@ -0,0 +1,5 @@
-- AlterTable: Change payment_method from enum to text to support comma-separated values and GREEN_POINTS
ALTER TABLE "c2c_orders" ALTER COLUMN "payment_method" TYPE TEXT USING "payment_method"::TEXT;
-- DropEnum (only if not used elsewhere)
DROP TYPE IF EXISTS "C2cPaymentMethod";

View File

@ -637,13 +637,6 @@ enum C2cOrderStatus {
EXPIRED // 已过期
}
// C2C收款方式
enum C2cPaymentMethod {
ALIPAY // 支付宝
WECHAT // 微信
BANK // 银行卡
}
// C2C订单
model C2cOrder {
id String @id @default(uuid())
@ -671,7 +664,7 @@ model C2cOrder {
maxAmount Decimal @default(0) @map("max_amount") @db.Decimal(30, 8) // 最大交易量
// 卖方收款信息(卖单必填,买单买家需提供)
paymentMethod C2cPaymentMethod? @map("payment_method") // 收款方式
paymentMethod String? @map("payment_method") // 收款方式GREEN_POINTS/ALIPAY/WECHAT/BANK可逗号分隔
paymentAccount String? @map("payment_account") // 收款账号
paymentQrCode String? @map("payment_qr_code") // 收款二维码URL
paymentRealName String? @map("payment_real_name") // 收款人实名

View File

@ -144,7 +144,7 @@ export class C2cController {
minAmount: dto.minAmount,
maxAmount: dto.maxAmount,
// 收款信息
paymentMethod: dto.paymentMethod as any,
paymentMethod: dto.paymentMethod,
paymentAccount: dto.paymentAccount,
paymentQrCode: dto.paymentQrCode,
paymentRealName: dto.paymentRealName,
@ -185,7 +185,7 @@ export class C2cController {
const order = await this.c2cService.takeOrder(orderNo, accountSequence, {
quantity: dto.quantity,
// 收款信息接买单时由taker提供
paymentMethod: dto.paymentMethod as any,
paymentMethod: dto.paymentMethod,
paymentAccount: dto.paymentAccount,
paymentQrCode: dto.paymentQrCode,
paymentRealName: dto.paymentRealName,

View File

@ -20,6 +20,7 @@ export enum C2cOrderStatus {
// 收款方式
export enum C2cPaymentMethod {
GREEN_POINTS = 'GREEN_POINTS', // 绿积分(默认)
ALIPAY = 'ALIPAY', // 支付宝
WECHAT = 'WECHAT', // 微信
BANK = 'BANK', // 银行卡
@ -50,11 +51,11 @@ export class CreateC2cOrderDto {
@IsNumberString()
maxAmount?: string;
// 收款信息(卖单必填
@ApiPropertyOptional({ enum: ['ALIPAY', 'WECHAT', 'BANK'], description: '收款方式' })
// 收款信息(卖单可选,支持逗号分隔多种方式如 'ALIPAY,WECHAT'
@ApiPropertyOptional({ description: '收款方式ALIPAY/WECHAT/BANK可逗号分隔' })
@IsOptional()
@IsIn(['ALIPAY', 'WECHAT', 'BANK'])
paymentMethod?: 'ALIPAY' | 'WECHAT' | 'BANK';
@IsString()
paymentMethod?: string;
@ApiPropertyOptional({ description: '收款账号' })
@IsOptional()
@ -84,10 +85,10 @@ export class TakeC2cOrderDto {
quantity?: string;
// 买单被接单时,买家需要提供收款信息
@ApiPropertyOptional({ enum: ['ALIPAY', 'WECHAT', 'BANK'], description: '收款方式(接买单时需提供' })
@ApiPropertyOptional({ description: '收款方式GREEN_POINTS/ALIPAY/WECHAT/BANK可逗号分隔' })
@IsOptional()
@IsIn(['ALIPAY', 'WECHAT', 'BANK'])
paymentMethod?: 'ALIPAY' | 'WECHAT' | 'BANK';
@IsString()
paymentMethod?: string;
@ApiPropertyOptional({ description: '收款账号(接买单时需提供)' })
@IsOptional()

View File

@ -25,13 +25,12 @@ const C2C_ORDER_STATUS = {
// C2C 收款方式常量
const C2C_PAYMENT_METHOD = {
GREEN_POINTS: 'GREEN_POINTS',
ALIPAY: 'ALIPAY',
WECHAT: 'WECHAT',
BANK: 'BANK',
} as const;
type C2cPaymentMethod = typeof C2C_PAYMENT_METHOD[keyof typeof C2C_PAYMENT_METHOD];
// 默认超时时间配置(分钟)
const DEFAULT_PAYMENT_TIMEOUT_MINUTES = 15;
const DEFAULT_CONFIRM_TIMEOUT_MINUTES = 60;
@ -84,7 +83,7 @@ export class C2cService {
minAmount?: string;
maxAmount?: string;
// 收款信息(卖单必填)
paymentMethod?: C2cPaymentMethod;
paymentMethod?: string;
paymentAccount?: string;
paymentQrCode?: string;
paymentRealName?: string;
@ -188,7 +187,7 @@ export class C2cService {
options?: {
quantity?: string;
// 收款信息接买单时由taker提供因为taker是卖方
paymentMethod?: C2cPaymentMethod;
paymentMethod?: string;
paymentAccount?: string;
paymentQrCode?: string;
paymentRealName?: string;

View File

@ -17,16 +17,8 @@ const C2C_ORDER_STATUS = {
EXPIRED: 'EXPIRED',
} as const;
// C2C 收款方式常量
const C2C_PAYMENT_METHOD = {
ALIPAY: 'ALIPAY',
WECHAT: 'WECHAT',
BANK: 'BANK',
} as const;
type C2cOrderType = typeof C2C_ORDER_TYPE[keyof typeof C2C_ORDER_TYPE];
type C2cOrderStatus = typeof C2C_ORDER_STATUS[keyof typeof C2C_ORDER_STATUS];
type C2cPaymentMethod = typeof C2C_PAYMENT_METHOD[keyof typeof C2C_PAYMENT_METHOD];
export interface C2cOrderEntity {
id: string;
@ -47,7 +39,7 @@ export interface C2cOrderEntity {
minAmount: string;
maxAmount: string;
// 收款信息
paymentMethod?: C2cPaymentMethod | null;
paymentMethod?: string | null;
paymentAccount?: string | null;
paymentQrCode?: string | null;
paymentRealName?: string | null;
@ -107,7 +99,7 @@ export class C2cOrderRepository {
minAmount?: string;
maxAmount?: string;
// 收款信息
paymentMethod?: C2cPaymentMethod;
paymentMethod?: string;
paymentAccount?: string;
paymentQrCode?: string;
paymentRealName?: string;
@ -130,7 +122,7 @@ export class C2cOrderRepository {
minAmount: data.minAmount || '0',
maxAmount: data.maxAmount || '0',
// 收款信息
paymentMethod: data.paymentMethod as any,
paymentMethod: data.paymentMethod,
paymentAccount: data.paymentAccount,
paymentQrCode: data.paymentQrCode,
paymentRealName: data.paymentRealName,
@ -154,7 +146,7 @@ export class C2cOrderRepository {
takerPhone: string;
takerNickname: string;
// 收款信息接买单时由taker提供
paymentMethod: C2cPaymentMethod;
paymentMethod: string;
paymentAccount: string;
paymentQrCode: string;
paymentRealName: string;
@ -174,7 +166,6 @@ export class C2cOrderRepository {
data: {
status: status as any,
...additionalData,
paymentMethod: additionalData?.paymentMethod as any,
},
});
return this.toEntity(record);
@ -352,7 +343,7 @@ export class C2cOrderRepository {
minAmount: record.minAmount.toString(),
maxAmount: record.maxAmount.toString(),
// 收款信息
paymentMethod: record.paymentMethod as C2cPaymentMethod | null,
paymentMethod: record.paymentMethod,
paymentAccount: record.paymentAccount,
paymentQrCode: record.paymentQrCode,
paymentRealName: record.paymentRealName,