feat: 新增退款管理模块 — 完整的退款审批流程、佣金回扣和资产重置
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m8s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m8s
新增退款申请全生命周期管理:创建/列表/详情/审批通过/拒绝/退回/重新提交 审批通过后异步执行佣金全额回扣(扣减各代理佣金钱包)和资产重置(套餐失效+停机+世代重置) 新增 tb_refund_request 表(迁移 000093)、RefundRequest Model、8 个 DTO 新增 Store/Service/Handler/路由注册,仅平台用户可访问
This commit is contained in:
84
internal/model/dto/refund_dto.go
Normal file
84
internal/model/dto/refund_dto.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package dto
|
||||
|
||||
// CreateRefundRequest 创建退款申请请求
|
||||
type CreateRefundRequest struct {
|
||||
OrderID uint `json:"order_id" validate:"required" required:"true" description:"关联订单ID"`
|
||||
ActualReceivedAmount int64 `json:"actual_received_amount" validate:"required,min=1" required:"true" minimum:"1" description:"实收金额(分)"`
|
||||
RequestedRefundAmount int64 `json:"requested_refund_amount" validate:"required,min=1" required:"true" minimum:"1" description:"申请退款金额(分)"`
|
||||
RefundReason string `json:"refund_reason" validate:"omitempty,max=1000" maxLength:"1000" description:"退款原因"`
|
||||
PackageUsageID *uint `json:"package_usage_id" validate:"omitempty" description:"关联套餐使用记录ID(可选)"`
|
||||
}
|
||||
|
||||
// RefundIDRequest 退款申请ID路径参数
|
||||
type RefundIDRequest struct {
|
||||
ID uint `path:"id" description:"退款申请ID" required:"true"`
|
||||
}
|
||||
|
||||
// RejectRefundRequest 拒绝退款申请请求
|
||||
type RejectRefundRequest struct {
|
||||
ID uint `json:"-" params:"id" path:"id" validate:"required" description:"退款申请ID"`
|
||||
RejectReason string `json:"reject_reason" validate:"required,max=500" required:"true" maxLength:"500" description:"拒绝原因(必填)"`
|
||||
}
|
||||
|
||||
// ResubmitRefundRequest 重新提交退款申请请求
|
||||
// 退款单被退回后,可修改部分字段后重新提交
|
||||
type ResubmitRefundRequest struct {
|
||||
ID uint `json:"-" params:"id" path:"id" validate:"required" description:"退款申请ID"`
|
||||
ActualReceivedAmount *int64 `json:"actual_received_amount" validate:"omitempty,min=1" minimum:"1" description:"实收金额(分)"`
|
||||
RequestedRefundAmount *int64 `json:"requested_refund_amount" validate:"omitempty,min=1" minimum:"1" description:"申请退款金额(分)"`
|
||||
RefundReason *string `json:"refund_reason" validate:"omitempty,max=1000" maxLength:"1000" description:"退款原因"`
|
||||
}
|
||||
|
||||
// ApproveRefundRequest 审批通过退款申请请求
|
||||
type ApproveRefundRequest struct {
|
||||
ID uint `json:"-" params:"id" path:"id" validate:"required" description:"退款申请ID"`
|
||||
ApprovedRefundAmount *int64 `json:"approved_refund_amount" validate:"omitempty,min=1" minimum:"1" description:"审批实际退款金额(分),不填则使用申请金额"`
|
||||
Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"审批备注"`
|
||||
}
|
||||
|
||||
// ReturnRefundRequest 退回退款申请请求
|
||||
type ReturnRefundRequest struct {
|
||||
ID uint `json:"-" params:"id" path:"id" validate:"required" description:"退款申请ID"`
|
||||
Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"退回备注"`
|
||||
}
|
||||
|
||||
// RefundListRequest 退款申请列表查询请求
|
||||
type RefundListRequest struct {
|
||||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码(默认1)"`
|
||||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量(默认20,最大100)"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"状态 (1:待审批, 2:已通过, 3:已拒绝, 4:已退回)"`
|
||||
OrderID *uint `json:"order_id" query:"order_id" validate:"omitempty" description:"关联订单ID"`
|
||||
ShopID *uint `json:"shop_id" query:"shop_id" validate:"omitempty" description:"店铺ID"`
|
||||
}
|
||||
|
||||
// RefundResponse 退款申请详情响应
|
||||
type RefundResponse struct {
|
||||
ID uint `json:"id" description:"退款申请ID"`
|
||||
RefundNo string `json:"refund_no" description:"退款单号"`
|
||||
OrderID uint `json:"order_id" description:"关联订单ID"`
|
||||
PackageUsageID *uint `json:"package_usage_id,omitempty" description:"关联套餐使用记录ID"`
|
||||
ShopID *uint `json:"shop_id,omitempty" description:"店铺ID"`
|
||||
ActualReceivedAmount int64 `json:"actual_received_amount" description:"实收金额(分)"`
|
||||
RequestedRefundAmount int64 `json:"requested_refund_amount" description:"申请退款金额(分)"`
|
||||
ApprovedRefundAmount *int64 `json:"approved_refund_amount,omitempty" description:"审批实际退款金额(分)"`
|
||||
RefundReason string `json:"refund_reason" description:"退款原因"`
|
||||
Status int `json:"status" description:"状态 (1:待审批, 2:已通过, 3:已拒绝, 4:已退回)"`
|
||||
ProcessorID *uint `json:"processor_id,omitempty" description:"审批人ID"`
|
||||
ProcessedAt string `json:"processed_at,omitempty" description:"审批时间"`
|
||||
RejectReason string `json:"reject_reason,omitempty" description:"拒绝原因"`
|
||||
Remark string `json:"remark,omitempty" description:"审批备注"`
|
||||
CommissionDeducted bool `json:"commission_deducted" description:"佣金是否已回扣"`
|
||||
AssetReset bool `json:"asset_reset" description:"资产是否已重置"`
|
||||
Creator uint `json:"creator" description:"创建人ID"`
|
||||
Updater uint `json:"updater" description:"更新人ID"`
|
||||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
|
||||
// RefundListResponse 退款申请列表分页响应
|
||||
type RefundListResponse struct {
|
||||
Items []RefundResponse `json:"items" description:"退款申请列表"`
|
||||
Total int64 `json:"total" description:"总记录数"`
|
||||
Page int `json:"page" description:"当前页码"`
|
||||
Size int `json:"size" description:"每页数量"`
|
||||
}
|
||||
53
internal/model/refund.go
Normal file
53
internal/model/refund.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// RefundRequest 退款申请模型
|
||||
// 记录退款申请的完整生命周期,包含退款单号、关联订单、金额、状态流转、审批信息等
|
||||
// 状态流转:1(待审批) → 2(已通过)/3(已拒绝)/4(已退回),4(已退回) → 1(待审批)
|
||||
type RefundRequest struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
|
||||
// 退款单基础信息
|
||||
RefundNo string `gorm:"column:refund_no;type:varchar(50);uniqueIndex:idx_refund_request_refund_no,where:deleted_at IS NULL;not null;comment:退款单号(RF+日期时间+6位随机数)" json:"refund_no"`
|
||||
OrderID uint `gorm:"column:order_id;index;not null;comment:关联订单ID" json:"order_id"`
|
||||
PackageUsageID *uint `gorm:"column:package_usage_id;comment:关联套餐使用记录ID(可选)" json:"package_usage_id,omitempty"`
|
||||
ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(从订单获取,用于数据权限过滤)" json:"shop_id,omitempty"`
|
||||
|
||||
// 金额信息
|
||||
ActualReceivedAmount int64 `gorm:"column:actual_received_amount;type:bigint;not null;comment:实收金额(分)" json:"actual_received_amount"`
|
||||
RequestedRefundAmount int64 `gorm:"column:requested_refund_amount;type:bigint;not null;comment:申请退款金额(分)" json:"requested_refund_amount"`
|
||||
ApprovedRefundAmount *int64 `gorm:"column:approved_refund_amount;type:bigint;comment:审批实际退款金额(分)" json:"approved_refund_amount,omitempty"`
|
||||
|
||||
// 退款原因和状态
|
||||
RefundReason string `gorm:"column:refund_reason;type:text;comment:退款原因" json:"refund_reason"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;index;comment:状态 1-待审批 2-已通过 3-已拒绝 4-已退回" json:"status"`
|
||||
|
||||
// 审批信息
|
||||
ProcessorID *uint `gorm:"column:processor_id;comment:审批人ID" json:"processor_id,omitempty"`
|
||||
ProcessedAt *time.Time `gorm:"column:processed_at;comment:审批时间" json:"processed_at,omitempty"`
|
||||
RejectReason string `gorm:"column:reject_reason;type:text;comment:拒绝原因" json:"reject_reason,omitempty"`
|
||||
Remark string `gorm:"column:remark;type:text;comment:审批备注" json:"remark,omitempty"`
|
||||
|
||||
// 后处理标记
|
||||
CommissionDeducted bool `gorm:"column:commission_deducted;not null;default:false;comment:佣金是否已回扣" json:"commission_deducted"`
|
||||
AssetReset bool `gorm:"column:asset_reset;not null;default:false;comment:资产是否已重置(套餐停用+停机+世代重置)" json:"asset_reset"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
func (RefundRequest) TableName() string {
|
||||
return "tb_refund_request"
|
||||
}
|
||||
|
||||
// 退款状态常量
|
||||
const (
|
||||
RefundStatusPending = 1 // 待审批
|
||||
RefundStatusApproved = 2 // 已通过
|
||||
RefundStatusRejected = 3 // 已拒绝
|
||||
RefundStatusReturned = 4 // 已退回
|
||||
)
|
||||
Reference in New Issue
Block a user