feat: 后台线下支付订单强制上传支付凭证
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m15s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m15s
在后台创建订单接口中新增 payment_voucher_key 字段,线下支付方式 下该字段为必填,存储对象存储 file_key,便于后续追溯与审计。 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2220,6 +2220,10 @@ components:
|
||||
payment_method:
|
||||
description: 支付方式 (wallet:钱包支付, offline:线下支付)
|
||||
type: string
|
||||
payment_voucher_key:
|
||||
description: 线下支付凭证对象存储file_key(payment_method=offline时必填,通过/storage/upload-url上传图片后获得)
|
||||
maxLength: 500
|
||||
type: string
|
||||
required:
|
||||
- identifier
|
||||
- package_ids
|
||||
@@ -4945,7 +4949,7 @@ components:
|
||||
nullable: true
|
||||
type: string
|
||||
payment_method:
|
||||
description: 支付方式 (wallet:钱包支付, wechat:微信支付, alipay:支付宝支付)
|
||||
description: 支付方式 (wallet:钱包支付, wechat:微信支付, alipay:支付宝支付, offline:线下支付)
|
||||
type: string
|
||||
payment_status:
|
||||
description: 支付状态 (1:待支付, 2:已支付, 3:已取消, 4:已退款)
|
||||
@@ -4953,6 +4957,9 @@ components:
|
||||
payment_status_text:
|
||||
description: 支付状态文本
|
||||
type: string
|
||||
payment_voucher_key:
|
||||
description: 线下支付凭证对象存储file_key(仅线下支付订单有值)
|
||||
type: string
|
||||
purchase_remark:
|
||||
description: 购买备注
|
||||
type: string
|
||||
|
||||
@@ -12,9 +12,10 @@ type CreateOrderRequest struct {
|
||||
|
||||
// CreateAdminOrderRequest 后台订单创建请求(仅允许 wallet/offline)
|
||||
type CreateAdminOrderRequest struct {
|
||||
Identifier string `json:"identifier" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"资产标识符(ICCID 或 VirtualNo)"`
|
||||
PackageIDs []uint `json:"package_ids" validate:"required,min=1,max=10,dive,min=1" required:"true" minItems:"1" maxItems:"10" description:"套餐ID列表"`
|
||||
PaymentMethod string `json:"payment_method" validate:"required,oneof=wallet offline" required:"true" description:"支付方式 (wallet:钱包支付, offline:线下支付)"`
|
||||
Identifier string `json:"identifier" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"资产标识符(ICCID 或 VirtualNo)"`
|
||||
PackageIDs []uint `json:"package_ids" validate:"required,min=1,max=10,dive,min=1" required:"true" minItems:"1" maxItems:"10" description:"套餐ID列表"`
|
||||
PaymentMethod string `json:"payment_method" validate:"required,oneof=wallet offline" required:"true" description:"支付方式 (wallet:钱包支付, offline:线下支付)"`
|
||||
PaymentVoucherKey string `json:"payment_voucher_key" validate:"omitempty,max=500" maxLength:"500" description:"线下支付凭证对象存储file_key(payment_method=offline时必填,通过/storage/upload-url上传图片后获得)"`
|
||||
}
|
||||
|
||||
type OrderListRequest struct {
|
||||
@@ -52,10 +53,11 @@ type OrderResponse struct {
|
||||
IotCardID *uint `json:"iot_card_id,omitempty" description:"IoT卡ID"`
|
||||
DeviceID *uint `json:"device_id,omitempty" description:"设备ID"`
|
||||
TotalAmount int64 `json:"total_amount" description:"订单总金额(分)"`
|
||||
PaymentMethod string `json:"payment_method,omitempty" description:"支付方式 (wallet:钱包支付, wechat:微信支付, alipay:支付宝支付)"`
|
||||
PaymentMethod string `json:"payment_method,omitempty" description:"支付方式 (wallet:钱包支付, wechat:微信支付, alipay:支付宝支付, offline:线下支付)"`
|
||||
PaymentStatus int `json:"payment_status" description:"支付状态 (1:待支付, 2:已支付, 3:已取消, 4:已退款)"`
|
||||
PaymentStatusText string `json:"payment_status_text" description:"支付状态文本"`
|
||||
PaidAt *time.Time `json:"paid_at,omitempty" description:"支付时间"`
|
||||
PaymentVoucherKey string `json:"payment_voucher_key,omitempty" description:"线下支付凭证对象存储file_key(仅线下支付订单有值)"`
|
||||
IsPurchaseOnBehalf bool `json:"is_purchase_on_behalf" description:"是否为代购订单"`
|
||||
CommissionStatus int `json:"commission_status" description:"佣金状态 (1:待计算, 2:已计算)"`
|
||||
CommissionConfigVersion int `json:"commission_config_version" description:"佣金配置版本"`
|
||||
|
||||
@@ -63,6 +63,9 @@ type Order struct {
|
||||
|
||||
// 支付配置
|
||||
PaymentConfigID *uint `gorm:"column:payment_config_id;index;comment:支付配置ID(关联tb_wechat_config.id)" json:"payment_config_id,omitempty"`
|
||||
|
||||
// 线下支付凭证对象存储 file_key(仅线下支付订单必填)
|
||||
PaymentVoucherKey string `gorm:"column:payment_voucher_key;type:varchar(500);comment:线下支付凭证对象存储file_key" json:"payment_voucher_key,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@@ -351,6 +351,11 @@ func (s *Service) CreateLegacy(ctx context.Context, req *dto.CreateOrderRequest,
|
||||
// 与 CreateH5Order 的核心区别:后台订单不创建待支付状态,wallet 立即扣款,offline 立即激活
|
||||
// POST /api/admin/orders
|
||||
func (s *Service) CreateAdminOrder(ctx context.Context, req *dto.CreateAdminOrderRequest, buyerType string, buyerID uint) (*dto.OrderResponse, error) {
|
||||
// 线下支付必须上传支付凭证
|
||||
if req.PaymentMethod == model.PaymentMethodOffline && strings.TrimSpace(req.PaymentVoucherKey) == "" {
|
||||
return nil, errors.New(errors.CodeInvalidParam, "线下支付必须上传支付凭证")
|
||||
}
|
||||
|
||||
resolvedCard, resolvedDevice, resolveErr := s.resolveAssetByIdentifier(ctx, req.Identifier)
|
||||
if resolveErr != nil {
|
||||
return nil, resolveErr
|
||||
@@ -619,6 +624,11 @@ func (s *Service) CreateAdminOrder(ctx context.Context, req *dto.CreateAdminOrde
|
||||
PaymentConfigID: paymentConfigID,
|
||||
}
|
||||
|
||||
// 线下支付订单写入支付凭证 file_key
|
||||
if req.PaymentMethod == model.PaymentMethodOffline {
|
||||
order.PaymentVoucherKey = strings.TrimSpace(req.PaymentVoucherKey)
|
||||
}
|
||||
|
||||
items := s.buildOrderItems(userID, validationResult.Packages)
|
||||
|
||||
idempotencyKey := buildOrderIdempotencyKey(buyerType, buyerID, orderType, carrierType, carrierID, req.PackageIDs)
|
||||
@@ -2177,6 +2187,7 @@ func (s *Service) buildOrderResponse(order *model.Order, items []*model.OrderIte
|
||||
PaymentStatus: order.PaymentStatus,
|
||||
PaymentStatusText: statusText,
|
||||
PaidAt: order.PaidAt,
|
||||
PaymentVoucherKey: order.PaymentVoucherKey,
|
||||
IsPurchaseOnBehalf: order.IsPurchaseOnBehalf,
|
||||
CommissionStatus: order.CommissionStatus,
|
||||
CommissionConfigVersion: order.CommissionConfigVersion,
|
||||
|
||||
1
migrations/000109_add_payment_voucher_to_order.down.sql
Normal file
1
migrations/000109_add_payment_voucher_to_order.down.sql
Normal file
@@ -0,0 +1 @@
|
||||
ALTER TABLE tb_order DROP COLUMN IF EXISTS payment_voucher_key;
|
||||
2
migrations/000109_add_payment_voucher_to_order.up.sql
Normal file
2
migrations/000109_add_payment_voucher_to_order.up.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE tb_order ADD COLUMN IF NOT EXISTS payment_voucher_key VARCHAR(500);
|
||||
COMMENT ON COLUMN tb_order.payment_voucher_key IS '线下支付凭证对象存储 file_key(仅线下支付订单必填)';
|
||||
Reference in New Issue
Block a user