增加支付功能
This commit is contained in:
@@ -137,6 +137,19 @@ func Init(_ string) {
|
||||
new(BackendOaPayrollItem),
|
||||
new(BackendEmployeeFile),
|
||||
new(BackendEmployeeFileRecord),
|
||||
|
||||
// 平台端支付模块(docs/sql/create_platform_payment.sql)
|
||||
new(PlatformPaymentChannel),
|
||||
new(PlatformPaymentOrder),
|
||||
new(PlatformPaymentOrderLog),
|
||||
new(PlatformPaymentCallbackLog),
|
||||
new(PlatformPaymentChannelBill),
|
||||
new(PlatformPaymentReconcileDiff),
|
||||
new(PlatformPaymentRefund),
|
||||
|
||||
// 平台端推广佣金(docs/sql/create_platform_commission.sql)
|
||||
new(PlatformCommissionRule),
|
||||
new(PlatformCommissionOrder),
|
||||
)
|
||||
|
||||
// 创建全局 Ormer
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// =============================================================
|
||||
// 平台端推广佣金模型(表结构见 docs/sql/create_platform_commission.sql)
|
||||
// 业务约定:
|
||||
// 1. 佣金由平台自有资金支出,与租户收款资金流解耦;
|
||||
// 2. 佣金在「业务订单支付成功」事件上按启用中的规则生成,初始状态 payable;
|
||||
// 3. 一笔支付单 + 同一推广方只生成一张佣金单(uk_pay_promoter,业务层再按 pay_no 查重)。
|
||||
// =============================================================
|
||||
|
||||
// PlatformCommissionRule 佣金规则 yz_platform_commission_rule
|
||||
type PlatformCommissionRule struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
RuleName string `orm:"column(rule_name);size(128)" json:"rule_name"`
|
||||
CalcType string `orm:"column(calc_type);size(20)" json:"calc_type"`
|
||||
Value int64 `orm:"column(value);default(0)" json:"value"`
|
||||
TierJSON *string `orm:"column(tier_json);type(text);null" json:"-"`
|
||||
OrderType string `orm:"column(order_type);size(32)" json:"order_type"`
|
||||
Status int8 `orm:"column(status);default(1)" json:"status"`
|
||||
Remark string `orm:"column(remark);size(255)" json:"remark"`
|
||||
CreateUserID string `orm:"column(create_user_id);size(64)" json:"create_user_id"`
|
||||
CreateUserName string `orm:"column(create_user_name);size(128)" json:"create_user_name"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformCommissionRule) TableName() string { return "yz_platform_commission_rule" }
|
||||
|
||||
// 计算方式
|
||||
const (
|
||||
CommissionCalcPercent = "percent" // 按比例:value = 百分比 × 100(5% 存 500)
|
||||
CommissionCalcFixed = "fixed" // 固定金额:value = 分
|
||||
CommissionCalcTiered = "tiered" // 阶梯:value 忽略,明细见 tier_json
|
||||
)
|
||||
|
||||
// 适用订单类型
|
||||
const (
|
||||
CommissionOrderTypeAll = "all"
|
||||
CommissionOrderTypePlatformUsage = "platform_usage"
|
||||
CommissionOrderTypeModuleShop = "module_shop"
|
||||
CommissionOrderTypeServiceFee = "service_fee"
|
||||
)
|
||||
|
||||
// CommissionTier 阶梯档位(tier_json 数组元素)
|
||||
type CommissionTier struct {
|
||||
Min int64 `json:"min"` // 起始金额(分,含)
|
||||
Max *int64 `json:"max"` // 结束金额(分,不含);null 表示不限
|
||||
Rate int64 `json:"rate"` // 比例:百分比 × 100
|
||||
}
|
||||
|
||||
// PlatformCommissionOrder 佣金单(台账) yz_platform_commission_order
|
||||
type PlatformCommissionOrder struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
CommissionNo string `orm:"column(commission_no);size(40)" json:"commission_no"`
|
||||
PayNo string `orm:"column(pay_no);size(40)" json:"pay_no"`
|
||||
OutTradeNo string `orm:"column(out_trade_no);size(64)" json:"out_trade_no"`
|
||||
RuleID uint64 `orm:"column(rule_id);default(0)" json:"rule_id"`
|
||||
RuleName string `orm:"column(rule_name);size(128)" json:"rule_name"`
|
||||
CalcType string `orm:"column(calc_type);size(20)" json:"calc_type"`
|
||||
PromoterID string `orm:"column(promoter_id);size(64)" json:"promoter_id"`
|
||||
PromoterName string `orm:"column(promoter_name);size(128)" json:"promoter_name"`
|
||||
PromoterType string `orm:"column(promoter_type);size(32)" json:"promoter_type"`
|
||||
BaseAmount int64 `orm:"column(base_amount);default(0)" json:"base_amount"`
|
||||
Amount int64 `orm:"column(amount);default(0)" json:"amount"`
|
||||
Status string `orm:"column(status);size(20)" json:"status"`
|
||||
PayMethod string `orm:"column(pay_method);size(20)" json:"pay_method"`
|
||||
PayVoucher string `orm:"column(pay_voucher);size(255)" json:"pay_voucher"`
|
||||
PaidAt *time.Time `orm:"column(paid_at);type(datetime);null" json:"paid_at"`
|
||||
PaidUserID string `orm:"column(paid_user_id);size(64)" json:"paid_user_id"`
|
||||
PaidUserName string `orm:"column(paid_user_name);size(128)" json:"paid_user_name"`
|
||||
Remark string `orm:"column(remark);size(255)" json:"remark"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformCommissionOrder) TableName() string { return "yz_platform_commission_order" }
|
||||
|
||||
// 佣金状态
|
||||
const (
|
||||
CommissionStatusPayable = "payable" // 应付
|
||||
CommissionStatusSettled = "settled" // 已付
|
||||
CommissionStatusTaxProcessing = "tax_processing" // 税务处理中
|
||||
CommissionStatusCanceled = "canceled" // 已作废
|
||||
)
|
||||
|
||||
// 发放方式
|
||||
const (
|
||||
CommissionPayBank = "bank" // 银行转账
|
||||
CommissionPayBalance = "balance" // 余额抵扣
|
||||
CommissionPayManual = "manual" // 人工发放
|
||||
CommissionPayOffset = "offset" // 下期抵扣
|
||||
)
|
||||
@@ -0,0 +1,214 @@
|
||||
package models
|
||||
|
||||
import "time"
|
||||
|
||||
// =============================================================
|
||||
// 平台端支付模块模型(表结构见 docs/sql/create_platform_payment.sql)
|
||||
// 约定:
|
||||
// 1. 金额字段一律 int64,单位「分」;
|
||||
// 2. 状态字段存英文枚举字符串(前端 StatusTag 直接映射);
|
||||
// 3. 渠道密钥类参数不落明文,config_json 存 AES-GCM 密文(见 services/payment/crypto.go);
|
||||
// 4. 软删除统一用 delete_time,查询时 Filter("delete_time__isnull", true)。
|
||||
// =============================================================
|
||||
|
||||
// PlatformPaymentChannel 平台支付渠道配置 yz_platform_payment_channel
|
||||
type PlatformPaymentChannel struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
Channel string `orm:"column(channel);size(32)" json:"channel"`
|
||||
Name string `orm:"column(name);size(64)" json:"name"`
|
||||
MerchantNo string `orm:"column(merchant_no);size(128)" json:"merchant_no"`
|
||||
ConfigJSON *string `orm:"column(config_json);type(text);null" json:"-"`
|
||||
CertJSON *string `orm:"column(cert_json);type(text);null" json:"-"`
|
||||
CallbackURL string `orm:"column(callback_url);size(255)" json:"callback_url"`
|
||||
Enabled int8 `orm:"column(enabled);default(0)" json:"enabled"`
|
||||
ExtraJSON *string `orm:"column(extra_json);type(text);null" json:"-"`
|
||||
LastTestTime *time.Time `orm:"column(last_test_time);type(datetime);null" json:"last_test_time"`
|
||||
LastTestResult string `orm:"column(last_test_result);size(255)" json:"last_test_result"`
|
||||
Remark string `orm:"column(remark);size(255)" json:"remark"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformPaymentChannel) TableName() string { return "yz_platform_payment_channel" }
|
||||
|
||||
// PlatformPaymentOrder 平台支付单 yz_platform_payment_order
|
||||
type PlatformPaymentOrder struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
PayNo string `orm:"column(pay_no);size(40)" json:"pay_no"`
|
||||
OutTradeNo string `orm:"column(out_trade_no);size(64)" json:"out_trade_no"`
|
||||
OrderType string `orm:"column(order_type);size(32)" json:"order_type"`
|
||||
Subject string `orm:"column(subject);size(255)" json:"subject"`
|
||||
TenantID string `orm:"column(tenant_id);size(64)" json:"tenant_id"`
|
||||
TenantName string `orm:"column(tenant_name);size(128)" json:"tenant_name"`
|
||||
Amount int64 `orm:"column(amount);default(0)" json:"amount"`
|
||||
OrderAmount int64 `orm:"column(order_amount);default(0)" json:"order_amount"`
|
||||
Currency string `orm:"column(currency);size(8)" json:"currency"`
|
||||
Channel string `orm:"column(channel);size(32)" json:"channel"`
|
||||
MerchantNo string `orm:"column(merchant_no);size(128)" json:"merchant_no"`
|
||||
ChannelTradeNo string `orm:"column(channel_trade_no);size(64)" json:"channel_trade_no"`
|
||||
Status string `orm:"column(status);size(20)" json:"status"`
|
||||
RefundAmount int64 `orm:"column(refund_amount);default(0)" json:"refund_amount"`
|
||||
ClientIP string `orm:"column(client_ip);size(64)" json:"client_ip"`
|
||||
ReturnURL string `orm:"column(return_url);size(255)" json:"return_url"`
|
||||
NotifyURL string `orm:"column(notify_url);size(255)" json:"notify_url"`
|
||||
ExpireAt *time.Time `orm:"column(expire_at);type(datetime);null" json:"expire_at"`
|
||||
PaidAt *time.Time `orm:"column(paid_at);type(datetime);null" json:"paid_at"`
|
||||
ClosedAt *time.Time `orm:"column(closed_at);type(datetime);null" json:"closed_at"`
|
||||
NotifyAt *time.Time `orm:"column(notify_at);type(datetime);null" json:"notify_at"`
|
||||
LastQueryAt *time.Time `orm:"column(last_query_at);type(datetime);null" json:"last_query_at"`
|
||||
OrderSynced int8 `orm:"column(order_synced);default(0)" json:"order_synced"`
|
||||
PromoterID string `orm:"column(promoter_id);size(64)" json:"promoter_id"`
|
||||
PromoterName string `orm:"column(promoter_name);size(128)" json:"promoter_name"`
|
||||
PromoterType string `orm:"column(promoter_type);size(32)" json:"promoter_type"`
|
||||
Remark string `orm:"column(remark);size(255)" json:"remark"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformPaymentOrder) TableName() string { return "yz_platform_payment_order" }
|
||||
|
||||
// 支付单状态枚举
|
||||
const (
|
||||
PayStatusCreated = "created" // 已创建
|
||||
PayStatusPending = "pending" // 待支付
|
||||
PayStatusPaying = "paying" // 支付中
|
||||
PayStatusPaid = "paid" // 支付成功
|
||||
PayStatusFailed = "failed" // 支付失败
|
||||
PayStatusClosed = "closed" // 已关闭
|
||||
PayStatusRefunding = "refunding" // 退回中
|
||||
PayStatusRefunded = "refunded" // 已退回
|
||||
)
|
||||
|
||||
// PlatformPaymentOrderLog 支付单状态流转流水 yz_platform_payment_order_log
|
||||
type PlatformPaymentOrderLog struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
PayNo string `orm:"column(pay_no);size(40)" json:"pay_no"`
|
||||
FromStatus string `orm:"column(from_status);size(20)" json:"from_status"`
|
||||
ToStatus string `orm:"column(to_status);size(20)" json:"to_status"`
|
||||
Operator string `orm:"column(operator);size(64)" json:"operator"`
|
||||
Remark string `orm:"column(remark);size(500)" json:"remark"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformPaymentOrderLog) TableName() string { return "yz_platform_payment_order_log" }
|
||||
|
||||
// PlatformPaymentCallbackLog 渠道回调日志 yz_platform_payment_callback_log
|
||||
type PlatformPaymentCallbackLog struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
Channel string `orm:"column(channel);size(32)" json:"channel"`
|
||||
EventType string `orm:"column(event_type);size(64)" json:"event_type"`
|
||||
EventID string `orm:"column(event_id);size(128)" json:"event_id"`
|
||||
PayNo string `orm:"column(pay_no);size(40)" json:"pay_no"`
|
||||
OutTradeNo string `orm:"column(out_trade_no);size(64)" json:"out_trade_no"`
|
||||
ChannelTradeNo string `orm:"column(channel_trade_no);size(64)" json:"channel_trade_no"`
|
||||
TradeState string `orm:"column(trade_state);size(32)" json:"trade_state"`
|
||||
Amount int64 `orm:"column(amount);default(0)" json:"amount"`
|
||||
VerifyResult int8 `orm:"column(verify_result);default(0)" json:"verify_result"`
|
||||
IsDuplicate int8 `orm:"column(is_duplicate);default(0)" json:"is_duplicate"`
|
||||
HandleResult int8 `orm:"column(handle_result);default(0)" json:"handle_result"`
|
||||
HandleMsg string `orm:"column(handle_msg);size(255)" json:"handle_msg"`
|
||||
RawBody *string `orm:"column(raw_body);type(text);null" json:"raw_body"`
|
||||
ClientIP string `orm:"column(client_ip);size(64)" json:"client_ip"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformPaymentCallbackLog) TableName() string {
|
||||
return "yz_platform_payment_callback_log"
|
||||
}
|
||||
|
||||
// PlatformPaymentChannelBill 渠道账单明细 yz_platform_payment_channel_bill
|
||||
type PlatformPaymentChannelBill struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
Channel string `orm:"column(channel);size(32)" json:"channel"`
|
||||
BillDate time.Time `orm:"column(bill_date);type(date)" json:"bill_date"`
|
||||
ChannelTradeNo string `orm:"column(channel_trade_no);size(64)" json:"channel_trade_no"`
|
||||
OutTradeNo string `orm:"column(out_trade_no);size(64)" json:"out_trade_no"`
|
||||
Amount int64 `orm:"column(amount);default(0)" json:"amount"`
|
||||
Fee int64 `orm:"column(fee);default(0)" json:"fee"`
|
||||
TradeState string `orm:"column(trade_state);size(32)" json:"trade_state"`
|
||||
TradeTime *time.Time `orm:"column(trade_time);type(datetime);null" json:"trade_time"`
|
||||
IsMatched int8 `orm:"column(is_matched);default(0)" json:"is_matched"`
|
||||
MatchedPayNo string `orm:"column(matched_pay_no);size(40)" json:"matched_pay_no"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformPaymentChannelBill) TableName() string {
|
||||
return "yz_platform_payment_channel_bill"
|
||||
}
|
||||
|
||||
// PlatformPaymentReconcileDiff 对账差异 yz_platform_payment_reconcile_diff
|
||||
type PlatformPaymentReconcileDiff struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
Channel string `orm:"column(channel);size(32)" json:"channel"`
|
||||
BillDate time.Time `orm:"column(bill_date);type(date)" json:"bill_date"`
|
||||
BatchNo string `orm:"column(batch_no);size(40)" json:"batch_no"`
|
||||
LocalTradeNo string `orm:"column(local_trade_no);size(64)" json:"local_trade_no"`
|
||||
ChannelTradeNo string `orm:"column(channel_trade_no);size(64)" json:"channel_trade_no"`
|
||||
LocalAmount *int64 `orm:"column(local_amount);null" json:"local_amount"`
|
||||
ChannelAmount *int64 `orm:"column(channel_amount);null" json:"channel_amount"`
|
||||
DiffAmount int64 `orm:"column(diff_amount);default(0)" json:"diff_amount"`
|
||||
DiffType string `orm:"column(diff_type);size(20)" json:"diff_type"`
|
||||
HandleStatus string `orm:"column(handle_status);size(20)" json:"handle_status"`
|
||||
HandleUserID string `orm:"column(handle_user_id);size(64)" json:"handle_user_id"`
|
||||
HandleUserName string `orm:"column(handle_user_name);size(128)" json:"handle_user_name"`
|
||||
HandleTime *time.Time `orm:"column(handle_time);type(datetime);null" json:"handle_time"`
|
||||
Remark string `orm:"column(remark);size(500)" json:"remark"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformPaymentReconcileDiff) TableName() string {
|
||||
return "yz_platform_payment_reconcile_diff"
|
||||
}
|
||||
|
||||
// 对账差异类型 / 处理状态
|
||||
const (
|
||||
DiffTypeLong = "long" // 长款:渠道有、本地无
|
||||
DiffTypeShort = "short" // 短款:本地有、渠道无
|
||||
DiffTypeStatusMismatch = "status_mismatch" // 状态不一致
|
||||
)
|
||||
|
||||
const (
|
||||
DiffHandleUnhandled = "unhandled"
|
||||
DiffHandleHandling = "handling"
|
||||
DiffHandleHandled = "handled"
|
||||
DiffHandleIgnored = "ignored"
|
||||
)
|
||||
|
||||
// PlatformPaymentRefund 手动原路退回记录 yz_platform_payment_refund
|
||||
type PlatformPaymentRefund struct {
|
||||
ID uint64 `orm:"column(id);pk;auto" json:"id"`
|
||||
RefundNo string `orm:"column(refund_no);size(40)" json:"refund_no"`
|
||||
PayNo string `orm:"column(pay_no);size(40)" json:"pay_no"`
|
||||
OutTradeNo string `orm:"column(out_trade_no);size(64)" json:"out_trade_no"`
|
||||
Channel string `orm:"column(channel);size(32)" json:"channel"`
|
||||
ChannelRefundNo string `orm:"column(channel_refund_no);size(64)" json:"channel_refund_no"`
|
||||
Amount int64 `orm:"column(amount);default(0)" json:"amount"`
|
||||
Reason string `orm:"column(reason);size(500)" json:"reason"`
|
||||
Status string `orm:"column(status);size(20)" json:"status"`
|
||||
FailReason string `orm:"column(fail_reason);size(500)" json:"fail_reason"`
|
||||
OperatorID string `orm:"column(operator_id);size(64)" json:"operator_id"`
|
||||
OperatorName string `orm:"column(operator_name);size(128)" json:"operator_name"`
|
||||
FinishedAt *time.Time `orm:"column(finished_at);type(datetime);null" json:"finished_at"`
|
||||
Remark string `orm:"column(remark);size(500)" json:"remark"`
|
||||
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)" json:"create_time"`
|
||||
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)" json:"update_time"`
|
||||
DeleteTime *time.Time `orm:"column(delete_time);type(datetime);null" json:"delete_time"`
|
||||
}
|
||||
|
||||
func (m *PlatformPaymentRefund) TableName() string { return "yz_platform_payment_refund" }
|
||||
|
||||
// 退回状态
|
||||
const (
|
||||
RefundStatusProcessing = "processing"
|
||||
RefundStatusSuccess = "success"
|
||||
RefundStatusFailed = "failed"
|
||||
)
|
||||
Reference in New Issue
Block a user