Files
junhong_cmp_fiber/internal/model/dto/refund_dto.go
break 5ed6b39deb
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
feat(收口): 补齐 8 月迭代缺口并同步 Spec 与证据链
- 新增六对成对迁移 000232–000237:H5 弹窗类型、退款结算标识与申请人备注、优先轮询事实字段与两个新终态、通道阈值命中留痕、手机号最近解绑人、提现资格校验留痕
- 退款:原因必填与申请人备注、来源支付与渠道流水冻结、线下处理流水号补录审计、按订单查询可选退款方式、企微审批材料补齐且新增字段缺失映射即明确失败
- 优先轮询:人工关闭、有效期到期独立周期任务、失败与过期人工重触发、事实字段与异常重试查询、资产解析端点只读投影
- 通道阈值:命中事实同事务留痕与命中记录查询;员工账单:列表筛选与详情投影;商户池:列表投影与统计周期语义;H5:弹窗类型与类别排序
- 手机号:有效关联数量与最近解绑人、短信验证码失败次数限制;导出:佣金明细十五列与报表序号列
- 时间筛选:三处新增筛选纳入统一严格解析契约,员工账单产生时间参数改名
- 同步 12 份主 Spec 需求、两端点与异步任务证据链,门禁 context-health 与 OpenSpec 校验通过
2026-09-18 15:34:29 +08:00

199 lines
21 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package dto
// CreateRefundRequest 创建退款申请请求
type CreateRefundRequest struct {
OrderID uint `json:"order_id" validate:"required" required:"true" description:"关联订单ID"`
ActualReceivedAmount *int64 `json:"actual_received_amount" validate:"omitempty" description:"已废弃:实收金额由系统从原成功支付记录或订单实际收款派生并冻结,提交人填写无效"`
Method string `json:"method" validate:"required,oneof=original_route customer_account asset_wallet agent_wallet" required:"true" description:"退款方式 (original_route:原路退款, customer_account:客户收款信息退款, asset_wallet:退回资产钱包, agent_wallet:退回代理主钱包)"`
CustomerAccountInfo string `json:"customer_account_info" validate:"omitempty,max=1000" maxLength:"1000" description:"客户收款信息,仅客户收款信息退款方式必填,不得复用公司线下收款方式字典"`
RequestedRefundAmount int64 `json:"requested_refund_amount" validate:"required,min=1" required:"true" minimum:"1" description:"申请退款金额(分)"`
RefundVoucherKey []string `json:"refund_voucher_key" validate:"omitempty,max=5,dive,max=500" maxItems:"5" description:"退款凭证对象存储file_key列表最多5个仅客户收款信息退款方式必填通过/storage/upload-url上传图片后获得"`
RefundReason string `json:"refund_reason" validate:"required,max=1000" required:"true" maxLength:"1000" description:"退款原因(必填,去除首尾空白后不得为空)"`
// Remark 是申请人备注,随本次提交冻结进当次审批尝试快照;与审批备注(详情响应中的 remark语义不同。
Remark *string `json:"remark" validate:"omitempty,max=500" maxLength:"500" 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:"已废弃:实收金额由系统从原成功支付记录或订单实际收款派生并冻结,提交人填写无效"`
Method *string `json:"method" validate:"omitempty,oneof=original_route customer_account asset_wallet agent_wallet" description:"退款方式 (original_route:原路退款, customer_account:客户收款信息退款, asset_wallet:退回资产钱包, agent_wallet:退回代理主钱包),不填沿用原有方式"`
CustomerAccountInfo *string `json:"customer_account_info" validate:"omitempty,max=1000" maxLength:"1000" description:"客户收款信息,仅客户收款信息退款方式必填,不得复用公司线下收款方式字典"`
RequestedRefundAmount *int64 `json:"requested_refund_amount" validate:"omitempty,min=1" minimum:"1" description:"申请退款金额(分)"`
RefundVoucherKey *[]string `json:"refund_voucher_key" validate:"omitempty,max=5,dive,max=500" maxItems:"5" description:"退款凭证对象存储file_key列表重新提交时可替换客户收款信息退款方式必填最多5个"`
RefundReason *string `json:"refund_reason" validate:"omitempty,max=1000" maxLength:"1000" description:"退款原因(不填沿用原有原因;重提时去除首尾空白后不得为空)"`
// Remark 是本次重提的申请人备注,随本次尝试冻结;不填沿用该退款单最近一次尝试的备注。
Remark *string `json:"remark" validate:"omitempty,max=500" maxLength:"500" 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=6" minimum:"1" maximum:"6" description:"状态 (1:待审批, 2:已通过, 3:已拒绝, 4:已退回, 5:原路退款处理中, 6:原路退款失败)"`
OrderID *uint `json:"order_id" query:"order_id" validate:"omitempty" description:"关联订单ID"`
ShopID *uint `json:"shop_id" query:"shop_id" validate:"omitempty" description:"店铺ID"`
AssetIdentifier string `json:"asset_identifier" query:"asset_identifier" validate:"omitempty,max=100" maxLength:"100" description:"资产标识精确检索ICCID 或 设备虚拟号,非空时精确匹配)"`
}
// RefundResponse 退款申请详情响应
type RefundResponse struct {
ID uint `json:"id" description:"退款申请ID"`
RefundNo string `json:"refund_no" description:"退款单号"`
OrderID uint `json:"order_id" description:"关联订单ID"`
OrderNo string `json:"order_no" description:"订单号"`
AssetIdentifier string `json:"asset_identifier,omitempty" description:"下单时资产的标识符快照(卡为 ICCID设备优先使用 VirtualNo缺失时使用 IMEI"`
AssetType string `json:"asset_type,omitempty" description:"资产类型 (card:单卡, device:设备)"`
IotCardID *uint `json:"iot_card_id,omitempty" description:"IoT卡ID"`
DeviceID *uint `json:"device_id,omitempty" description:"设备ID"`
PackageUsageID *uint `json:"package_usage_id,omitempty" description:"关联套餐使用记录ID"`
// 当前退款套餐用量:按冻结套餐使用记录 → 订单主套餐 → 订单任一套餐的优先级解析,
// 只用于展示、查询与导出,不参与退款金额校验、套餐失效或佣金回溯。
RefundPackageUsedMB int64 `json:"refund_package_used_mb" description:"当前退款套餐已用量MB真实流量解析不到套餐时为0"`
RefundPackageTotalMB int64 `json:"refund_package_total_mb" description:"当前退款套餐总量MB真实流量解析不到套餐时为0"`
ShopID *uint `json:"shop_id,omitempty" description:"店铺ID"`
ShopName string `json:"shop_name,omitempty" description:"店铺名称"`
ActualReceivedAmount int64 `json:"actual_received_amount" description:"实收金额(分)"`
RequestedRefundAmount int64 `json:"requested_refund_amount" description:"申请退款金额(分)"`
ApprovedRefundAmount *int64 `json:"approved_refund_amount,omitempty" description:"审批实际退款金额(分)"`
RefundVoucherKey []string `json:"refund_voucher_key" description:"退款凭证对象存储file_key列表最多5个"`
RefundReason string `json:"refund_reason" description:"退款原因"`
Status int `json:"status" description:"状态 (1:待审批, 2:已通过, 3:已拒绝, 4:已退回, 5:原路退款处理中, 6:原路退款失败)"`
StatusName string `json:"status_name" description:"状态名称(中文)"`
Method string `json:"method" description:"退款方式 (original_route:原路退款, customer_account:客户收款信息退款, asset_wallet:退回资产钱包, agent_wallet:退回代理主钱包),空表示未接入方式的存量申请"`
MethodName string `json:"method_name" description:"退款方式中文名称"`
FrozenActualReceivedAmount int64 `json:"frozen_actual_received_amount" description:"系统派生并冻结的权威实收金额(分),作为可退金额上限"`
CustomerAccountInfo string `json:"customer_account_info" description:"客户收款信息自由文本快照,仅客户收款信息退款方式有值"`
ChannelRefundStatus int `json:"channel_refund_status" description:"渠道原路退款状态 (0:未发起, 1:处理中, 2:已成功, 3:已失败)0 表示未发起渠道退款或不适用该退款方式"`
ChannelRefundStatusName string `json:"channel_refund_status_name" description:"渠道原路退款状态中文名称"`
ChannelRefundNo string `json:"channel_refund_no" description:"渠道退款流水号,渠道明确成功或失败后回填"`
ChannelRefundRequestNo string `json:"channel_refund_request_no" description:"渠道退款请求号快照,用于幂等与对账"`
ChannelRefundAmount int64 `json:"channel_refund_amount" description:"提交渠道的退款金额快照(分)"`
ChannelRefundedAt string `json:"channel_refunded_at,omitempty" description:"渠道明确退款成功时间"`
// 结算标识:前两项是冻结的来源支付事实,第三项是财务补录的线下处理流水号,语义互不相同。
SourcePaymentNo string `json:"source_payment_no" description:"冻结的来源支付单号,取创建申请时的原成功支付记录;线下订单无线上支付记录时为空字符串"`
OriginalChannelTradeNo string `json:"original_channel_trade_no" description:"冻结的原支付渠道交易流水号,取创建申请时的原成功支付记录;线下订单无线上支付记录时为空字符串"`
OfflineSettlementNo string `json:"offline_settlement_no" description:"线下退款处理流水号或凭证编号,由授权账号补录或更正;与渠道退款流水号语义不同"`
OfflineSettledAt string `json:"offline_settled_at,omitempty" description:"线下退款处理流水号最近一次登记或更正时间"`
OfflineSettledBy uint `json:"offline_settled_by" description:"线下退款处理流水号最近一次登记或更正的操作账号ID0 表示未登记"`
FailureReason string `json:"failure_reason" description:"结构化失败分类稳定编码 (channel_rejected:渠道明确拒绝, credential_invalid:渠道凭证失效, insufficient_balance:渠道余额不足, timeout_unknown:超时或结果未知, approval_rejected:企业微信驳回或关闭, revoked_after_approved:企业微信通过后撤销, payment_fact_invalid:本地原支付事实不可用),空表示无失败"`
FailureReasonName string `json:"failure_reason_name" description:"失败分类中文名称"`
FailureMessage string `json:"failure_message" description:"失败安全摘要,供人工排查;不含渠道凭证等敏感内容"`
AnomalyFlag int `json:"anomaly_flag" description:"异常标记 (0:无异常, 1:有异常,需人工处理)"`
AnomalyReason string `json:"anomaly_reason" description:"异常原因说明,无异常时为空"`
LatestAttemptID uint `json:"latest_attempt_id" description:"最新审批尝试记录ID仅用于展示"`
LatestApprovalInstanceID uint `json:"latest_approval_instance_id" description:"最新通用审批实例ID仅用于展示"`
Attempts []RefundAttemptResponse `json:"attempts" description:"审批尝试记录,按提交顺序排列,历史材料不被覆盖;无尝试记录时为空数组"`
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:"退款后资产处理是否完成"`
SubmitterID uint `json:"submitter_id" description:"提交人账号ID"`
SubmitterName string `json:"submitter_name" description:"提交人账号名称"`
ApprovalInstanceID *uint `json:"approval_instance_id,omitempty" description:"通用审批实例ID"`
ApprovalProvider string `json:"approval_provider,omitempty" description:"审批渠道企业微信为wecom"`
ApprovalStatus *int `json:"approval_status,omitempty" description:"审批状态 (0:提交中, 1:审批中, 2:已通过, 3:已拒绝, 4:已撤销, 5:通过后撤销, 6:已删除, 7:提交失败, 8:提交结果未知)"`
ApprovalStatusName string `json:"approval_status_name,omitempty" 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:"每页数量"`
}
// RefundAttemptResponse 退款审批尝试响应,材料为本次提交的冻结快照。
type RefundAttemptResponse struct {
ID uint `json:"id" description:"审批尝试记录ID同时是通用审批业务ID"`
AttemptNo int `json:"attempt_no" description:"第几次提交,从 1 递增"`
Method string `json:"method" description:"本次冻结的退款方式 (original_route:原路退款, customer_account:客户收款信息退款, asset_wallet:退回资产钱包, agent_wallet:退回代理主钱包)"`
MethodName string `json:"method_name" description:"本次冻结的退款方式中文名称"`
RefundAmount int64 `json:"refund_amount" description:"本次提交冻结的申请退款金额(分)"`
FrozenActualReceivedAmount int64 `json:"frozen_actual_received_amount" description:"本次提交冻结的权威实收金额(分)"`
RefundReason string `json:"refund_reason" description:"本次提交的退款原因"`
Remark string `json:"remark" description:"本次提交冻结的申请人备注快照,未填写时为空;与审批备注(详情响应中的 remark不是同一字段"`
CustomerAccountInfo string `json:"customer_account_info" description:"本次冻结的客户收款信息快照,非客户收款信息退款方式为空"`
CustomerVoucherKey []string `json:"customer_voucher_key" description:"客户收款凭证对象存储file_key列表仅返回对象键引用"`
ChannelRefundRequestNo string `json:"channel_refund_request_no" description:"本次提交使用的渠道退款请求号快照,用于幂等与对账"`
SubmittedByAccountID uint `json:"submitted_by_account_id" description:"本次实际提交账号ID"`
ApprovalInstanceID uint `json:"approval_instance_id" description:"本次尝试关联的通用审批实例ID0 表示未关联"`
ApprovalStatus *int `json:"approval_status,omitempty" description:"通用审批实例状态 (0:提交中, 1:审批中, 2:已通过, 3:已拒绝, 4:已撤销, 5:通过后撤销, 6:已删除, 7:提交失败, 8:提交结果未知)"`
ApprovalStatusName string `json:"approval_status_name" description:"通用审批实例状态中文名称"`
CreatedAt string `json:"created_at" description:"创建时间"`
}
// RefundOrderOptionsRequest 按来源订单查询可选退款方式请求。
type RefundOrderOptionsRequest struct {
OrderID uint `json:"order_id" query:"order_id" validate:"required,min=1" required:"true" minimum:"1" description:"来源订单ID"`
}
// RefundMethodOptionResponse 描述一种可选退款方式及其当前可用性。
type RefundMethodOptionResponse struct {
Method string `json:"method" description:"退款方式 (original_route:原路退款, customer_account:客户收款信息退款, asset_wallet:退回资产钱包, agent_wallet:退回代理主钱包)"`
MethodName string `json:"method_name" description:"退款方式中文名称"`
Available bool `json:"available" description:"该方式当前是否可用"`
Unavailable string `json:"unavailable_reason" description:"不可用原因;可用时为空字符串"`
}
// RefundCapabilityResponse 是原路退款能力校验结果投影。
type RefundCapabilityResponse struct {
Available bool `json:"available" description:"原路退款能力校验是否通过(凭证完整性、服务商类型与渠道可退时限)"`
Unavailable string `json:"unavailable_reason" description:"不通过原因;通过时为空字符串"`
}
// RefundOrderOptionsResponse 按来源订单查询可选退款方式响应。
type RefundOrderOptionsResponse struct {
OrderID uint `json:"order_id" description:"来源订单ID"`
OrderNo string `json:"order_no" description:"来源订单号"`
OrderPaymentType string `json:"order_payment_type" description:"来源订单支付方式 (wechat:微信, alipay:支付宝, wallet:钱包, offline:后台线下)"`
Methods []RefundMethodOptionResponse `json:"methods" description:"可选退款方式集合,含每种方式的可用性与不可用原因;判定事实缺失时为空数组"`
MerchantID *uint `json:"merchant_id,omitempty" description:"原收款商户ID无实际收款商户时为空"`
MerchantName string `json:"merchant_name" description:"原收款商户名称快照,无实际收款商户时为空字符串"`
OriginalChannelTradeNo string `json:"original_channel_trade_no" description:"原支付渠道交易流水号,无线上支付记录时为空字符串"`
RefundCapability RefundCapabilityResponse `json:"refund_capability" description:"原路退款能力校验结果"`
// UnavailableReason 在判定所需事实缺失(如无原成功支付记录或订单支付方式不支持退款)时说明原因,
// 使调用方得到不可用原因而不是请求失败。
UnavailableReason string `json:"unavailable_reason" description:"整体判定不可用时的原因,可用时为空字符串"`
}
// OfflineSettlementRequest 登记或更正线下退款处理流水号请求。
type OfflineSettlementRequest struct {
ID uint `json:"-" params:"id" path:"id" validate:"required" description:"退款申请ID"`
// OfflineSettlementNo 记录财务实际执行的线下退款处理流水号或凭证编号;重复提交即更正,历史值由审计留存。
OfflineSettlementNo string `json:"offline_settlement_no" validate:"required,max=128" required:"true" maxLength:"128" description:"线下退款处理流水号或凭证编号(必填,去除首尾空白后不得为空)"`
}