feat(员工代收款): 新增员工代收款账单闭环
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m20s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m20s
- 新增 6 张表与成对迁移 000212,扩展企业微信审批场景业务类型白名单 - 后台线下套餐订单与两条代理线下充值入账路径在来源成功事务内建账,来源唯一键幂等 - 核销申请、审批尝试记录、账单分摊预占与驳回重提,审批业务类型 employee_collection_approval - 企业微信终态消费幂等:通过转已核销、驳回释放预占、通过后撤销不回滚并转异常终态 - 退款成功事务内按 bill_id+refund_id 幂等冲销账单或仅写退款关联提示 - 线下收款方式字典、账单查询/统计/关闭、申请查询与代办权限,均写入事务内审计 OpenSpec Change: add-employee-collection-bills
This commit is contained in:
305
internal/model/dto/employee_collection_dto.go
Normal file
305
internal/model/dto/employee_collection_dto.go
Normal file
@@ -0,0 +1,305 @@
|
||||
package dto
|
||||
|
||||
import "time"
|
||||
|
||||
// CreateEmployeeCollectionPaymentMethodRequest 创建线下收款方式请求
|
||||
// 枚举说明:enabled 对应 constants.EmployeeCollectionPaymentMethodStatusEnabled/Disabled(1 启用、0 停用)。
|
||||
type CreateEmployeeCollectionPaymentMethodRequest struct {
|
||||
Code string `json:"code" validate:"required,min=1,max=64" required:"true" minLength:"1" maxLength:"64" description:"收款方式稳定编码,1-64 字符,未删除记录中唯一,被核销申请引用后不可修改"`
|
||||
Name string `json:"name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"收款方式名称,1-100 字符"`
|
||||
Sort *int64 `json:"sort" validate:"omitempty,min=0" minimum:"0" description:"排序值,非负整数,默认 0"`
|
||||
Enabled *bool `json:"enabled" description:"是否启用,默认启用;停用后新核销申请不可选择该方式"`
|
||||
Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"备注,最多 500 字符"`
|
||||
}
|
||||
|
||||
// UpdateEmployeeCollectionPaymentMethodRequest 更新线下收款方式请求
|
||||
// 全部字段可选:仅传入的字段被修改;已启用即被核销申请引用的记录不允许修改稳定编码。
|
||||
type UpdateEmployeeCollectionPaymentMethodRequest struct {
|
||||
Code *string `json:"code" validate:"omitempty,min=1,max=64" minLength:"1" maxLength:"64" description:"收款方式稳定编码,仅未被核销申请引用时可修改"`
|
||||
Name *string `json:"name" validate:"omitempty,min=1,max=100" minLength:"1" maxLength:"100" description:"收款方式名称"`
|
||||
Sort *int64 `json:"sort" validate:"omitempty,min=0" minimum:"0" description:"排序值,非负整数"`
|
||||
Enabled *bool `json:"enabled" description:"是否启用;停用后新核销申请不可选择该方式,历史申请仍展示冻结名称"`
|
||||
Remark *string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"备注,最多 500 字符"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionPaymentMethodListRequest 查询线下收款方式列表请求
|
||||
type EmployeeCollectionPaymentMethodListRequest 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"`
|
||||
Enabled *bool `json:"enabled" query:"enabled" description:"按启用状态过滤;超级管理员可查询全部,其他后台账号仅返回启用项"`
|
||||
Keyword string `json:"keyword" query:"keyword" validate:"omitempty,max=100" maxLength:"100" description:"按稳定编码或名称模糊搜索,最多 100 字符"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionPaymentMethodResponse 线下收款方式响应
|
||||
// 对外契约字段固定为 id/code/name/enabled,其余字段为维护与展示补充。
|
||||
type EmployeeCollectionPaymentMethodResponse struct {
|
||||
ID uint `json:"id" description:"收款方式ID"`
|
||||
Code string `json:"code" description:"收款方式稳定编码"`
|
||||
Name string `json:"name" description:"收款方式名称"`
|
||||
Enabled bool `json:"enabled" description:"是否启用;停用后新核销申请不可选择该方式"`
|
||||
Sort int64 `json:"sort" description:"排序值"`
|
||||
Remark string `json:"remark" description:"备注"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt time.Time `json:"updated_at" description:"更新时间"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionPaymentMethodListResponse 线下收款方式列表响应
|
||||
type EmployeeCollectionPaymentMethodListResponse struct {
|
||||
List []*EmployeeCollectionPaymentMethodResponse `json:"items" description:"收款方式列表"`
|
||||
Total int64 `json:"total" description:"总数"`
|
||||
Page int `json:"page" description:"当前页码"`
|
||||
PageSize int `json:"size" description:"每页条数"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillListRequest 查询员工代收款账单列表请求。
|
||||
// 枚举说明:source_type 对应 constants.EmployeeCollectionSourceTypeOrder/Recharge,
|
||||
// status 对应 constants.EmployeeCollectionBillStatusPending/Partial/Settled/Closed。
|
||||
type EmployeeCollectionBillListRequest 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"`
|
||||
SourceType *string `json:"source_type" query:"source_type" validate:"omitempty,oneof=order recharge" enum:"order,recharge" description:"按来源类型过滤 (order:后台线下套餐订单, recharge:代理线下充值)"`
|
||||
SourceNo *string `json:"source_no" query:"source_no" validate:"omitempty,max=64" maxLength:"64" description:"按来源单号精确过滤"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1 2 3" enum:"0,1,2,3" description:"按账单状态过滤 (0:待核销, 1:部分核销, 2:已核销, 3:已关闭)"`
|
||||
DebtorAccountID *uint `json:"debtor_account_id" query:"debtor_account_id" description:"按欠款人后台账号ID过滤;非超级管理员固定为当前账号,该参数被忽略"`
|
||||
CustomerID *uint `json:"customer_id" query:"customer_id" description:"按来源客户或店铺ID过滤,匹配来源订单买家或充值归属店铺"`
|
||||
CreatedFrom *string `json:"created_from" query:"created_from" description:"创建时间起始(YYYY-MM-DD,含当日 00:00:00)"`
|
||||
CreatedTo *string `json:"created_to" query:"created_to" description:"创建时间截止(YYYY-MM-DD,含当日 23:59:59)"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillStatisticsRequest 查询员工代收款账单统计请求。
|
||||
// 与账单列表使用同一批筛选字段与可见性范围,但不接受分页参数。
|
||||
type EmployeeCollectionBillStatisticsRequest struct {
|
||||
SourceType *string `json:"source_type" query:"source_type" validate:"omitempty,oneof=order recharge" enum:"order,recharge" description:"按来源类型过滤 (order:后台线下套餐订单, recharge:代理线下充值)"`
|
||||
SourceNo *string `json:"source_no" query:"source_no" validate:"omitempty,max=64" maxLength:"64" description:"按来源单号精确过滤"`
|
||||
Status *int `json:"status" query:"status" validate:"omitempty,oneof=0 1 2 3" enum:"0,1,2,3" description:"按账单状态过滤 (0:待核销, 1:部分核销, 2:已核销, 3:已关闭)"`
|
||||
DebtorAccountID *uint `json:"debtor_account_id" query:"debtor_account_id" description:"按欠款人后台账号ID过滤;非超级管理员固定为当前账号,该参数被忽略"`
|
||||
CustomerID *uint `json:"customer_id" query:"customer_id" description:"按来源客户或店铺ID过滤,匹配来源订单买家或充值归属店铺"`
|
||||
CreatedFrom *string `json:"created_from" query:"created_from" description:"创建时间起始(YYYY-MM-DD,含当日 00:00:00)"`
|
||||
CreatedTo *string `json:"created_to" query:"created_to" description:"创建时间截止(YYYY-MM-DD,含当日 23:59:59)"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillResponse 员工代收款账单行响应。
|
||||
type EmployeeCollectionBillResponse struct {
|
||||
ID uint `json:"id" description:"账单ID"`
|
||||
SourceType string `json:"source_type" description:"来源类型 (order:后台线下套餐订单, recharge:代理线下充值)"`
|
||||
SourceTypeName string `json:"source_type_name" description:"来源类型中文名称"`
|
||||
SourceID uint `json:"source_id" description:"来源业务主键ID"`
|
||||
SourceNo string `json:"source_no" description:"来源单号"`
|
||||
DebtorAccountID uint `json:"debtor_account_id" description:"欠款人后台账号ID"`
|
||||
DebtorSnapshot map[string]any `json:"debtor_snapshot" description:"欠款人账号只读快照(账号ID、名称、类型)"`
|
||||
CustomerSnapshot map[string]any `json:"customer_snapshot" description:"来源客户或店铺只读快照,不含付款凭证内容"`
|
||||
ReceivableAmount int64 `json:"receivable_amount" description:"应收金额(分)"`
|
||||
ReceivedAmount int64 `json:"received_amount" description:"已核销金额(分),仅企业微信最终通过的分摊计入"`
|
||||
ReservedAmount int64 `json:"reserved_amount" description:"审批中预占金额(分)"`
|
||||
RemainingAmount int64 `json:"remaining_amount" description:"剩余可核销金额(分),已关闭账单为 0"`
|
||||
Status int `json:"status" description:"账单状态 (0:待核销, 1:部分核销, 2:已核销, 3:已关闭)"`
|
||||
StatusName string `json:"status_name" description:"账单状态中文名称"`
|
||||
ApprovalPending bool `json:"approval_pending" description:"是否存在审批中分摊(预占大于零)"`
|
||||
ClosedReason string `json:"closed_reason" description:"关闭原因,仅已关闭账单有值"`
|
||||
ClosedAt *time.Time `json:"closed_at,omitempty" description:"关闭时间"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt time.Time `json:"updated_at" description:"最近更新时间"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillListResponse 员工代收款账单列表响应。
|
||||
type EmployeeCollectionBillListResponse struct {
|
||||
List []*EmployeeCollectionBillResponse `json:"items" description:"账单列表"`
|
||||
Total int64 `json:"total" description:"总数"`
|
||||
Page int `json:"page" description:"当前页码"`
|
||||
PageSize int `json:"size" description:"每页条数"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillStatisticsResponse 员工代收款账单统计响应。
|
||||
// 与账单列表使用同一筛选条件与可见性范围。
|
||||
type EmployeeCollectionBillStatisticsResponse struct {
|
||||
ReceivableTotal int64 `json:"receivable_total" description:"应收金额合计(分)"`
|
||||
ReceivedTotal int64 `json:"received_total" description:"已核销金额合计(分)"`
|
||||
UnsettledTotal int64 `json:"unsettled_total" description:"未核销金额合计(分),已关闭账单未核销余额按 0 计入"`
|
||||
PendingBillCount int64 `json:"pending_bill_count" description:"待处理账单数,即待核销或部分核销账单数量"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillRefundResponse 账单退款冲销关联响应。
|
||||
type EmployeeCollectionBillRefundResponse struct {
|
||||
ID uint `json:"id" description:"冲销关联ID"`
|
||||
RefundID uint `json:"refund_id" description:"退款申请ID"`
|
||||
SourceOrderID uint `json:"source_order_id" description:"账单来源订单ID"`
|
||||
RefundAmount int64 `json:"refund_amount" description:"本次退款成功金额(分)"`
|
||||
BillReceivableAmount int64 `json:"bill_receivable_amount" description:"冲销前账单应收金额快照(分)"`
|
||||
Outcome string `json:"outcome" description:"处理结果 (closed_full:来源订单全额退款关闭, reduced:按退款金额冲减应收, hint_only:仅记录退款关联提示)"`
|
||||
OutcomeName string `json:"outcome_name" description:"处理结果中文名称"`
|
||||
ReducedAmount int64 `json:"reduced_amount" description:"实际冲减应收金额(分)"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillAllocationResponse 账单分摊响应。
|
||||
type EmployeeCollectionBillAllocationResponse struct {
|
||||
ID uint `json:"id" description:"分摊ID"`
|
||||
ApplicationID uint `json:"application_id" description:"核销申请ID"`
|
||||
ApplicationStatus int `json:"application_status" description:"申请状态 (0:审批中, 1:已通过, 2:已驳回, 3:已撤销或已关闭)"`
|
||||
ApplicationStatusName string `json:"application_status_name" description:"申请状态中文名称"`
|
||||
AttemptID uint `json:"attempt_id" description:"所属审批尝试记录ID"`
|
||||
Amount int64 `json:"amount" description:"本次分摊金额(分)"`
|
||||
Status int `json:"status" description:"分摊状态 (0:审批中预占, 1:已通过, 2:已驳回或已释放)"`
|
||||
StatusName string `json:"status_name" description:"分摊状态中文名称"`
|
||||
ReleasedAt *time.Time `json:"released_at,omitempty" description:"预占释放时间,审批中为空"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillAttemptResponse 申请审批尝试记录响应,材料为本次提交的冻结快照。
|
||||
type EmployeeCollectionBillAttemptResponse struct {
|
||||
ID uint `json:"id" description:"审批尝试记录ID,同时是通用审批业务ID"`
|
||||
AttemptNo int `json:"attempt_no" description:"第几次提交,从 1 递增"`
|
||||
PaymentMethodID uint `json:"payment_method_id" description:"本次冻结的收款方式字典ID"`
|
||||
PaymentMethodCode string `json:"payment_method_code" description:"本次冻结的收款方式稳定编码"`
|
||||
PaymentMethodName string `json:"payment_method_name" description:"本次冻结的收款方式名称"`
|
||||
PaidAmount int64 `json:"paid_amount" description:"本次冻结的付款金额(分)"`
|
||||
PayerName string `json:"payer_name" description:"付款方名称"`
|
||||
PaidAt time.Time `json:"paid_at" description:"付款时间"`
|
||||
ExternalTransactionNo string `json:"external_transaction_no" description:"人工确认的外部交易流水号,申请人可原样核对与重用"`
|
||||
PaymentVoucherKeys []string `json:"payment_voucher_keys" description:"支付凭证对象存储Key列表,仅返回对象键引用"`
|
||||
Remark string `json:"remark" description:"本次提交备注"`
|
||||
SubmittedByAccountID uint `json:"submitted_by_account_id" description:"本次实际提交账号ID,代办时为超级管理员"`
|
||||
ActingReason string `json:"acting_reason" description:"本次代办原因,非代办为空"`
|
||||
AllocationSnapshot []map[string]any `json:"allocation_snapshot" description:"本次冻结的账单分摊快照"`
|
||||
ApprovalInstanceID *uint `json:"approval_instance_id,omitempty" description:"本次尝试关联的通用审批实例ID"`
|
||||
ApprovalStatus *int `json:"approval_status,omitempty" description:"通用审批实例状态 (0:提交中, 1:审批中, 2:已通过, 3:已拒绝, 4:已撤销, 5:通过后撤销, 6:已删除, 7:提交失败, 8:提交结果未知)"`
|
||||
ApprovalStatusName string `json:"approval_status_name" description:"通用审批实例状态中文名称"`
|
||||
ApprovalOpinion string `json:"approval_opinion" description:"渠道审批意见文本,取自通用审批实例终态决策快照;无意见时为空"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillApplicationResponse 账单关联的核销申请响应,含审批历史。
|
||||
type EmployeeCollectionBillApplicationResponse struct {
|
||||
ID uint `json:"id" description:"核销申请ID"`
|
||||
ApplicantAccountID uint `json:"applicant_account_id" description:"申请人后台账号ID"`
|
||||
ActingOperatorID uint `json:"acting_operator_id" description:"实际代办的超级管理员账号ID,0 表示本人办理"`
|
||||
ActingReason string `json:"acting_reason" description:"代办原因,非代办为空"`
|
||||
PaymentMethodID uint `json:"payment_method_id" description:"线下收款方式字典ID"`
|
||||
PaymentMethodCode string `json:"payment_method_code" description:"收款方式稳定编码快照"`
|
||||
PaymentMethodName string `json:"payment_method_name" description:"收款方式名称快照"`
|
||||
PaidAmount int64 `json:"paid_amount" description:"人工确认的付款金额(分)"`
|
||||
PayerName string `json:"payer_name" description:"付款方名称"`
|
||||
PaidAt time.Time `json:"paid_at" description:"付款时间"`
|
||||
ExternalTransactionNo string `json:"external_transaction_no" description:"外部交易流水号"`
|
||||
PaymentVoucherKeys []string `json:"payment_voucher_keys" description:"支付凭证对象存储Key列表,仅返回对象键引用"`
|
||||
Remark string `json:"remark" description:"申请备注"`
|
||||
Status int `json:"status" description:"申请状态 (0:审批中, 1:已通过, 2:已驳回, 3:已撤销或已关闭)"`
|
||||
StatusName string `json:"status_name" description:"申请状态中文名称"`
|
||||
LatestApprovalInstanceID uint `json:"latest_approval_instance_id" description:"最新通用审批实例ID,仅用于展示"`
|
||||
DecidedAt *time.Time `json:"decided_at,omitempty" description:"审批终态到达时间"`
|
||||
TerminalReason string `json:"terminal_reason" description:"异常终态说明,如企业微信通过后撤销"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
Attempts []*EmployeeCollectionBillAttemptResponse `json:"attempts" description:"该申请的审批尝试记录,按提交顺序排列"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillDetailResponse 员工代收款账单详情响应。
|
||||
type EmployeeCollectionBillDetailResponse struct {
|
||||
Bill *EmployeeCollectionBillResponse `json:"bill" description:"账单事实"`
|
||||
Refunds []*EmployeeCollectionBillRefundResponse `json:"refunds" description:"来源订单退款冲销关联"`
|
||||
Allocations []*EmployeeCollectionBillAllocationResponse `json:"allocations" description:"该账单的核销分摊"`
|
||||
Applications []*EmployeeCollectionBillApplicationResponse `json:"applications" description:"涉及该账单的核销申请与审批历史"`
|
||||
}
|
||||
|
||||
// CloseEmployeeCollectionBillRequest 关闭员工代收款账单请求
|
||||
type CloseEmployeeCollectionBillRequest struct {
|
||||
Reason string `json:"reason" validate:"required,min=1,max=500" required:"true" minLength:"1" maxLength:"500" description:"关闭原因,必填,最多 500 字符"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationAllocationRequest 核销申请中的单张账单分摊。
|
||||
type EmployeeCollectionApplicationAllocationRequest struct {
|
||||
BillID uint `json:"bill_id" validate:"required" required:"true" description:"目标员工代收款账单ID"`
|
||||
Amount int64 `json:"amount" validate:"required,min=1" required:"true" minimum:"1" description:"本次分摊金额(分),必须大于零且不超过该账单可核销余额"`
|
||||
}
|
||||
|
||||
// SubmitEmployeeCollectionApplicationRequest 创建或重提核销申请请求。
|
||||
// 枚举说明:allocations 由申请人提交,服务端按账单可核销余额与付款金额严格校验。
|
||||
type SubmitEmployeeCollectionApplicationRequest struct {
|
||||
PaymentMethodID uint `json:"payment_method_id" validate:"required" required:"true" description:"线下收款方式字典ID,必须是启用中的字典项"`
|
||||
PaidAmount int64 `json:"paid_amount" validate:"required,min=1" required:"true" minimum:"1" description:"人工确认的付款金额(分),必须大于零"`
|
||||
PayerName string `json:"payer_name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"付款方名称,1-100 字符"`
|
||||
PaidAt string `json:"paid_at" validate:"required" required:"true" description:"付款时间,带时区的 RFC3339 格式,如 2026-08-31T10:00:00+08:00"`
|
||||
ExternalTransactionNo string `json:"external_transaction_no" validate:"required,min=1,max=128" required:"true" minLength:"1" maxLength:"128" description:"经人工确认的外部交易流水号,OCR 结果必须人工更正后提交"`
|
||||
PaymentVoucherKeys []string `json:"payment_voucher_keys" validate:"required,min=1,max=5,dive,min=1,max=512" required:"true" minItems:"1" maxItems:"5" description:"支付凭证对象存储Key列表,1-5 个既有对象键引用"`
|
||||
Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"申请备注,最多 500 字符"`
|
||||
ActingReason string `json:"acting_reason" validate:"omitempty,max=500" maxLength:"500" description:"超级管理员代办原因,1-500 字符;代办时必填,本人办理不得填写"`
|
||||
Allocations []EmployeeCollectionApplicationAllocationRequest `json:"allocations" validate:"required,min=1,max=50,dive" required:"true" minItems:"1" maxItems:"50" description:"账单分摊列表,至少一条;每张账单本次只能出现一次"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationListRequest 查询核销申请列表请求。
|
||||
type EmployeeCollectionApplicationListRequest 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,oneof=0 1 2 3" enum:"0,1,2,3" description:"按申请状态过滤 (0:审批中, 1:已通过, 2:已驳回, 3:已撤销或已关闭)"`
|
||||
ApplicantAccountID *uint `json:"applicant_account_id" query:"applicant_account_id" description:"按申请人账号ID过滤;非超级管理员固定为当前账号,该参数被忽略"`
|
||||
PaymentMethodID *uint `json:"payment_method_id" query:"payment_method_id" description:"按线下收款方式字典ID过滤"`
|
||||
CreatedFrom *string `json:"created_from" query:"created_from" description:"创建时间起始(YYYY-MM-DD,含当日 00:00:00)"`
|
||||
CreatedTo *string `json:"created_to" query:"created_to" description:"创建时间截止(YYYY-MM-DD,含当日 23:59:59)"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationResponse 核销申请行响应。
|
||||
type EmployeeCollectionApplicationResponse struct {
|
||||
ID uint `json:"id" description:"核销申请ID"`
|
||||
ApplicantAccountID uint `json:"applicant_account_id" description:"申请人后台账号ID"`
|
||||
ActingOperatorID uint `json:"acting_operator_id" description:"实际代办的超级管理员账号ID,0 表示本人办理"`
|
||||
ActingReason string `json:"acting_reason" description:"代办原因,非代办为空"`
|
||||
PaymentMethodID uint `json:"payment_method_id" description:"线下收款方式字典ID"`
|
||||
PaymentMethodCode string `json:"payment_method_code" description:"收款方式稳定编码快照"`
|
||||
PaymentMethodName string `json:"payment_method_name" description:"收款方式名称快照,字典改名不影响历史申请"`
|
||||
PaidAmount int64 `json:"paid_amount" description:"人工确认的付款金额(分)"`
|
||||
PayerName string `json:"payer_name" description:"付款方名称"`
|
||||
PaidAt time.Time `json:"paid_at" description:"付款时间"`
|
||||
ExternalTransactionNo string `json:"external_transaction_no" description:"人工确认的外部交易流水号,申请人可原样核对与重用"`
|
||||
PaymentVoucherKeys []string `json:"payment_voucher_keys" description:"支付凭证对象存储Key列表,仅返回对象键引用"`
|
||||
Remark string `json:"remark" description:"申请备注"`
|
||||
Status int `json:"status" description:"申请状态 (0:审批中, 1:已通过, 2:已驳回, 3:已撤销或已关闭)"`
|
||||
StatusName string `json:"status_name" description:"申请状态中文名称"`
|
||||
LatestAttemptID uint `json:"latest_attempt_id" description:"最新审批尝试记录ID,仅用于展示"`
|
||||
LatestApprovalInstanceID uint `json:"latest_approval_instance_id" description:"最新通用审批实例ID,仅用于展示"`
|
||||
DecidedAt *time.Time `json:"decided_at,omitempty" description:"审批终态到达时间"`
|
||||
TerminalReason string `json:"terminal_reason" description:"异常终态说明,如企业微信通过后撤销"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt time.Time `json:"updated_at" description:"最近更新时间"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationListResponse 核销申请列表响应。
|
||||
type EmployeeCollectionApplicationListResponse struct {
|
||||
List []*EmployeeCollectionApplicationResponse `json:"items" description:"核销申请列表"`
|
||||
Total int64 `json:"total" description:"总数"`
|
||||
Page int `json:"page" description:"当前页码"`
|
||||
PageSize int `json:"size" description:"每页条数"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationAllocationResponse 核销申请分摊响应,含目标账单只读摘要。
|
||||
type EmployeeCollectionApplicationAllocationResponse struct {
|
||||
ID uint `json:"id" description:"分摊ID"`
|
||||
BillID uint `json:"bill_id" description:"目标账单ID"`
|
||||
Amount int64 `json:"amount" description:"本次分摊金额(分)"`
|
||||
Status int `json:"status" description:"分摊状态 (0:审批中预占, 1:已通过, 2:已驳回或已释放)"`
|
||||
StatusName string `json:"status_name" description:"分摊状态中文名称"`
|
||||
ReleasedAt *time.Time `json:"released_at,omitempty" description:"预占释放时间,审批中为空"`
|
||||
BillSourceType string `json:"bill_source_type" description:"账单来源类型 (order:后台线下套餐订单, recharge:代理线下充值)"`
|
||||
BillSourceNo string `json:"bill_source_no" description:"账单来源单号"`
|
||||
BillReceivableAmount int64 `json:"bill_receivable_amount" description:"账单应收金额(分)"`
|
||||
BillReceivedAmount int64 `json:"bill_received_amount" description:"账单已核销金额(分)"`
|
||||
BillReservedAmount int64 `json:"bill_reserved_amount" description:"账单审批中预占金额(分)"`
|
||||
BillStatus int `json:"bill_status" description:"账单状态 (0:待核销, 1:部分核销, 2:已核销, 3:已关闭)"`
|
||||
BillStatusName string `json:"bill_status_name" description:"账单状态中文名称"`
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationSubmitResponse 创建或重提核销申请响应。
|
||||
type EmployeeCollectionApplicationSubmitResponse struct {
|
||||
Application *EmployeeCollectionApplicationResponse `json:"application" description:"核销申请事实"`
|
||||
Attempt *EmployeeCollectionBillAttemptResponse `json:"attempt" description:"本次新增的审批尝试记录与冻结快照"`
|
||||
Allocations []*EmployeeCollectionApplicationAllocationResponse `json:"allocations" description:"本次账单分摊与预占结果"`
|
||||
ApprovalInstanceID uint `json:"approval_instance_id" description:"本次创建的企业微信通用审批实例ID"`
|
||||
ApprovalStatus int `json:"approval_status" description:"通用审批实例状态 (0:提交中, 1:审批中, 2:已通过, 3:已拒绝, 4:已撤销, 5:通过后撤销, 6:已删除, 7:提交失败, 8:提交结果未知)"`
|
||||
ApprovalStatusName string `json:"approval_status_name" description:"通用审批实例状态中文名称"`
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationDetailResponse 核销申请详情响应。
|
||||
type EmployeeCollectionApplicationDetailResponse struct {
|
||||
Application *EmployeeCollectionApplicationResponse `json:"application" description:"核销申请事实与最新审批引用"`
|
||||
Allocations []*EmployeeCollectionApplicationAllocationResponse `json:"allocations" description:"该申请当前的账单分摊"`
|
||||
Attempts []*EmployeeCollectionBillAttemptResponse `json:"attempts" description:"全部审批尝试记录,按提交顺序排列,历史材料不被覆盖"`
|
||||
}
|
||||
@@ -15,7 +15,7 @@ type CreateAdminOrderRequest struct {
|
||||
Identifier string `json:"identifier" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"资产标识符(卡支持 ICCID,设备支持 VirtualNo、IMEI 或 SN)"`
|
||||
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=5,dive,max=500" maxItems:"5" description:"线下支付凭证对象存储file_key列表(payment_method=offline时至少1个,最多5个,通过/storage/upload-url上传图片后获得)"`
|
||||
PaymentVoucherKey []string `json:"payment_voucher_key" validate:"omitempty,max=5,dive,max=500" maxItems:"5" description:"线下支付凭证对象存储file_key列表(最多5个,通过/storage/upload-url上传图片后获得);线下订单需付款凭证,但实际收款金额大于 0 且由平台账号操作的非赠送线下订单会生成员工代收款账单,该场景凭证由核销申请环节提供,创建订单时可为空"`
|
||||
}
|
||||
|
||||
type OrderListRequest struct {
|
||||
|
||||
150
internal/model/employee_collection.go
Normal file
150
internal/model/employee_collection.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// EmployeeCollectionPaymentMethod 是线下收款方式字典项。
|
||||
// 状态语义见 constants.EmployeeCollectionPaymentMethodStatus*;被业务引用后只可停用。
|
||||
type EmployeeCollectionPaymentMethod struct {
|
||||
gorm.Model
|
||||
BaseModel `gorm:"embedded"`
|
||||
Code string `gorm:"column:code;type:varchar(64);not null;comment:稳定编码,未删除记录中唯一" json:"code"`
|
||||
Name string `gorm:"column:name;type:varchar(100);not null;comment:收款方式名称" json:"name"`
|
||||
SortOrder int64 `gorm:"column:sort_order;type:bigint;not null;default:0;comment:排序值,从 0 递增" json:"sort_order"`
|
||||
Status int `gorm:"column:status;type:smallint;not null;default:1;comment:状态 0-禁用 1-启用" json:"status"`
|
||||
Remark string `gorm:"column:remark;type:varchar(500);not null;default:'';comment:备注" json:"remark"`
|
||||
}
|
||||
|
||||
// TableName 指定线下收款方式字典表名。
|
||||
func (EmployeeCollectionPaymentMethod) TableName() string {
|
||||
return "tb_employee_collection_payment_method"
|
||||
}
|
||||
|
||||
// EmployeeCollectionBill 是后台账号代客户经办业务形成的本地暂挂欠款。
|
||||
// 由来源成功事务按来源唯一键 SourceKey 幂等创建,不存在历史扫描或手工建账路径。
|
||||
type EmployeeCollectionBill struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
SourceType string `gorm:"column:source_type;type:varchar(20);not null;comment:来源类型 order/recharge" json:"source_type"`
|
||||
SourceID uint `gorm:"column:source_id;not null;comment:来源业务主键ID" json:"source_id"`
|
||||
SourceKey string `gorm:"column:source_key;type:varchar(64);not null;comment:来源唯一键 order:{id} / recharge:{id}" json:"source_key"`
|
||||
SourceNo string `gorm:"column:source_no;type:varchar(64);not null;default:'';comment:来源单号快照" json:"source_no"`
|
||||
DebtorAccountID uint `gorm:"column:debtor_account_id;not null;comment:欠款人后台账号ID" json:"debtor_account_id"`
|
||||
DebtorSnapshot datatypes.JSON `gorm:"column:debtor_snapshot;type:jsonb;not null;comment:欠款人账号快照" json:"debtor_snapshot"`
|
||||
CustomerSnapshot datatypes.JSON `gorm:"column:customer_snapshot;type:jsonb;not null;comment:来源客户或店铺只读快照" json:"customer_snapshot"`
|
||||
ReceivableAmount int64 `gorm:"column:receivable_amount;type:bigint;not null;comment:应收金额(分)" json:"receivable_amount"`
|
||||
ReceivedAmount int64 `gorm:"column:received_amount;type:bigint;not null;default:0;comment:已核销金额(分)" json:"received_amount"`
|
||||
ReservedAmount int64 `gorm:"column:reserved_amount;type:bigint;not null;default:0;comment:审批中预占金额(分)" json:"reserved_amount"`
|
||||
Status int `gorm:"column:status;type:smallint;not null;default:0;comment:状态 0-待核销 1-部分核销 2-已核销 3-已关闭" json:"status"`
|
||||
ClosedReason string `gorm:"column:closed_reason;type:varchar(500);not null;default:'';comment:关闭原因" json:"closed_reason"`
|
||||
ClosedAt *time.Time `gorm:"column:closed_at;type:timestamptz;comment:关闭时间" json:"closed_at,omitempty"`
|
||||
Creator uint `gorm:"column:creator;not null;default:0;comment:创建人用户ID" json:"creator"`
|
||||
Updater uint `gorm:"column:updater;not null;default:0;comment:最近更新人用户ID" json:"updater"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamptz;not null;autoUpdateTime" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定员工代收款账单表名。
|
||||
func (EmployeeCollectionBill) TableName() string {
|
||||
return "tb_employee_collection_bill"
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplication 是一笔外部付款的核销申请,只保存最新审批实例ID用于展示。
|
||||
type EmployeeCollectionApplication struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
ApplicantAccountID uint `gorm:"column:applicant_account_id;not null;comment:申请人后台账号ID" json:"applicant_account_id"`
|
||||
ActingOperatorID uint `gorm:"column:acting_operator_id;not null;default:0;comment:实际代办的超级管理员账号ID,0 表示本人办理" json:"acting_operator_id"`
|
||||
ActingReason string `gorm:"column:acting_reason;type:varchar(500);not null;default:'';comment:代办原因" json:"acting_reason"`
|
||||
PaymentMethodID uint `gorm:"column:payment_method_id;not null;comment:线下收款方式字典ID" json:"payment_method_id"`
|
||||
PaymentMethodCode string `gorm:"column:payment_method_code;type:varchar(64);not null;comment:收款方式编码快照" json:"payment_method_code"`
|
||||
PaymentMethodName string `gorm:"column:payment_method_name;type:varchar(100);not null;comment:收款方式名称快照" json:"payment_method_name"`
|
||||
PaidAmount int64 `gorm:"column:paid_amount;type:bigint;not null;comment:人工确认付款金额(分)" json:"paid_amount"`
|
||||
PayerName string `gorm:"column:payer_name;type:varchar(100);not null;default:'';comment:付款方名称" json:"payer_name"`
|
||||
PaidAt time.Time `gorm:"column:paid_at;type:timestamptz;not null;comment:付款时间" json:"paid_at"`
|
||||
ExternalTransactionNo string `gorm:"column:external_transaction_no;type:varchar(128);not null;default:'';comment:外部交易流水号" json:"external_transaction_no"`
|
||||
PaymentVoucherKeys StringJSONBArray `gorm:"column:payment_voucher_keys;type:jsonb;not null;comment:支付凭证对象存储Key列表" json:"payment_voucher_keys"`
|
||||
Remark string `gorm:"column:remark;type:varchar(500);not null;default:'';comment:申请备注" json:"remark"`
|
||||
Status int `gorm:"column:status;type:smallint;not null;default:0;comment:状态 0-审批中 1-已通过 2-已驳回 3-已撤销或已关闭" json:"status"`
|
||||
LatestAttemptID uint `gorm:"column:latest_attempt_id;not null;default:0;comment:最新审批尝试记录ID" json:"latest_attempt_id"`
|
||||
LatestApprovalInstanceID uint `gorm:"column:latest_approval_instance_id;not null;default:0;comment:最新通用审批实例ID" json:"latest_approval_instance_id"`
|
||||
DecidedAt *time.Time `gorm:"column:decided_at;type:timestamptz;comment:审批终态到达时间" json:"decided_at,omitempty"`
|
||||
TerminalReason string `gorm:"column:terminal_reason;type:varchar(500);not null;default:'';comment:异常终态说明" json:"terminal_reason"`
|
||||
Creator uint `gorm:"column:creator;not null;default:0;comment:创建人用户ID" json:"creator"`
|
||||
Updater uint `gorm:"column:updater;not null;default:0;comment:最近更新人用户ID" json:"updater"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamptz;not null;autoUpdateTime" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定核销申请表名。
|
||||
func (EmployeeCollectionApplication) TableName() string {
|
||||
return "tb_employee_collection_application"
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationAttempt 是同一申请每次提交或重提对应的不可变审批材料。
|
||||
// 其主键同时作为通用审批实例的业务ID,使每次提交各自持有独立审批实例。
|
||||
type EmployeeCollectionApplicationAttempt struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
ApplicationID uint `gorm:"column:application_id;not null;comment:所属核销申请ID" json:"application_id"`
|
||||
AttemptNo int `gorm:"column:attempt_no;type:int;not null;comment:第几次提交,从 1 递增" json:"attempt_no"`
|
||||
PaymentMethodID uint `gorm:"column:payment_method_id;not null;comment:本次冻结的收款方式字典ID" json:"payment_method_id"`
|
||||
PaymentMethodCode string `gorm:"column:payment_method_code;type:varchar(64);not null;comment:本次冻结的收款方式编码" json:"payment_method_code"`
|
||||
PaymentMethodName string `gorm:"column:payment_method_name;type:varchar(100);not null;comment:本次冻结的收款方式名称" json:"payment_method_name"`
|
||||
PaidAmount int64 `gorm:"column:paid_amount;type:bigint;not null;comment:本次冻结的付款金额(分)" json:"paid_amount"`
|
||||
PayerName string `gorm:"column:payer_name;type:varchar(100);not null;default:'';comment:本次冻结的付款方名称" json:"payer_name"`
|
||||
PaidAt time.Time `gorm:"column:paid_at;type:timestamptz;not null;comment:本次冻结的付款时间" json:"paid_at"`
|
||||
ExternalTransactionNo string `gorm:"column:external_transaction_no;type:varchar(128);not null;default:'';comment:本次冻结的外部交易流水号" json:"external_transaction_no"`
|
||||
PaymentVoucherKeys StringJSONBArray `gorm:"column:payment_voucher_keys;type:jsonb;not null;comment:本次冻结的支付凭证对象键列表" json:"payment_voucher_keys"`
|
||||
Remark string `gorm:"column:remark;type:varchar(500);not null;default:'';comment:本次冻结的备注" json:"remark"`
|
||||
SubmittedByAccountID uint `gorm:"column:submitted_by_account_id;not null;comment:本次实际提交账号ID" json:"submitted_by_account_id"`
|
||||
ActingReason string `gorm:"column:acting_reason;type:varchar(500);not null;default:'';comment:本次代办原因" json:"acting_reason"`
|
||||
AllocationSnapshot datatypes.JSON `gorm:"column:allocation_snapshot;type:jsonb;not null;comment:本次冻结的账单分摊快照" json:"allocation_snapshot"`
|
||||
ApprovalInstanceID *uint `gorm:"column:approval_instance_id;comment:本次尝试关联的通用审批实例ID" json:"approval_instance_id,omitempty"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 指定审批尝试记录表名。
|
||||
func (EmployeeCollectionApplicationAttempt) TableName() string {
|
||||
return "tb_employee_collection_application_attempt"
|
||||
}
|
||||
|
||||
// EmployeeCollectionApplicationAllocation 是申请对单张账单的本次分摊。
|
||||
// 审批中预占账单余额,终态释放预占或转入已核销金额。
|
||||
type EmployeeCollectionApplicationAllocation struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
ApplicationID uint `gorm:"column:application_id;not null;comment:所属核销申请ID" json:"application_id"`
|
||||
AttemptID uint `gorm:"column:attempt_id;not null;comment:所属审批尝试记录ID" json:"attempt_id"`
|
||||
BillID uint `gorm:"column:bill_id;not null;comment:目标账单ID" json:"bill_id"`
|
||||
Amount int64 `gorm:"column:amount;type:bigint;not null;comment:本次分摊金额(分)" json:"amount"`
|
||||
Status int `gorm:"column:status;type:smallint;not null;default:0;comment:状态 0-审批中预占 1-已通过 2-已驳回或已释放" json:"status"`
|
||||
ReleasedAt *time.Time `gorm:"column:released_at;type:timestamptz;comment:预占释放时间" json:"released_at,omitempty"`
|
||||
Creator uint `gorm:"column:creator;not null;default:0;comment:创建人用户ID" json:"creator"`
|
||||
Updater uint `gorm:"column:updater;not null;default:0;comment:最近更新人用户ID" json:"updater"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamptz;not null;autoUpdateTime" json:"updated_at"`
|
||||
}
|
||||
|
||||
// TableName 指定申请分摊表名。
|
||||
func (EmployeeCollectionApplicationAllocation) TableName() string {
|
||||
return "tb_employee_collection_application_allocation"
|
||||
}
|
||||
|
||||
// EmployeeCollectionBillRefund 是来源订单退款与账单之间的唯一冲销关联事实。
|
||||
type EmployeeCollectionBillRefund struct {
|
||||
ID uint `gorm:"column:id;primaryKey;autoIncrement" json:"id"`
|
||||
BillID uint `gorm:"column:bill_id;not null;comment:目标账单ID" json:"bill_id"`
|
||||
RefundID uint `gorm:"column:refund_id;not null;comment:退款申请ID" json:"refund_id"`
|
||||
SourceOrderID uint `gorm:"column:source_order_id;not null;comment:账单来源订单ID" json:"source_order_id"`
|
||||
RefundAmount int64 `gorm:"column:refund_amount;type:bigint;not null;comment:本次退款成功金额(分)" json:"refund_amount"`
|
||||
BillReceivableAmount int64 `gorm:"column:bill_receivable_amount;type:bigint;not null;comment:冲销前账单应收金额快照(分)" json:"bill_receivable_amount"`
|
||||
Outcome string `gorm:"column:outcome;type:varchar(20);not null;comment:处理结果 closed_full/reduced/hint_only" json:"outcome"`
|
||||
ReducedAmount int64 `gorm:"column:reduced_amount;type:bigint;not null;default:0;comment:实际冲减应收金额(分)" json:"reduced_amount"`
|
||||
CreatedAt time.Time `gorm:"column:created_at;type:timestamptz;not null;autoCreateTime" json:"created_at"`
|
||||
}
|
||||
|
||||
// TableName 指定退款冲销关联表名。
|
||||
func (EmployeeCollectionBillRefund) TableName() string {
|
||||
return "tb_employee_collection_bill_refund"
|
||||
}
|
||||
@@ -75,7 +75,8 @@ type Order struct {
|
||||
// 支付配置
|
||||
PaymentConfigID *uint `gorm:"column:payment_config_id;index;comment:支付配置ID(关联tb_wechat_config.id)" json:"payment_config_id,omitempty"`
|
||||
|
||||
// 线下支付凭证对象存储 file_key 列表(最多5个,仅线下支付订单必填)
|
||||
// 线下支付凭证对象存储 file_key 列表(最多5个,线下支付订单必填;
|
||||
// 会生成员工代收款账单的线下订单除外,该场景凭证由核销申请环节提供)
|
||||
PaymentVoucherKey StringJSONBArray `gorm:"column:payment_voucher_key;type:jsonb;comment:线下支付凭证对象存储file_key列表(jsonb存储[]string)" json:"payment_voucher_key"`
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user