This commit is contained in:
2026-03-13 15:51:59 +08:00
parent 4db2386bbf
commit 4e91f4cede
133 changed files with 19502 additions and 37 deletions

View File

@@ -0,0 +1,15 @@
package model
import "time"
// AdminUser 管理后台用户
func (AdminUser) TableName() string { return "admin_user" }
type AdminUser struct {
ID uint64 `gorm:"primaryKey;autoIncrement"`
Username string `gorm:"uniqueIndex;size:64;not null"`
PasswordHash string `gorm:"size:128;not null"`
Status int8 `gorm:"not null;default:1"` // 1=启用
CreatedAt time.Time
UpdatedAt time.Time
}

View File

@@ -0,0 +1,16 @@
package model
import "time"
// App 接入应用
type App struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;uniqueIndex;size:32;not null"`
AppSecret string `gorm:"column:app_secret;size:128;not null"` // AES 加密存储
AppName string `gorm:"column:app_name;size:64;not null"`
Status int8 `gorm:"column:status;not null;default:1"` // 1=启用 0=禁用
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (App) TableName() string { return "app" }

View File

@@ -0,0 +1,22 @@
package model
import "time"
// ChannelConfig 渠道配置
type ChannelConfig struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;size:32;not null;uniqueIndex:uk_app_channel"`
ChannelCode string `gorm:"column:channel_code;size:32;not null;uniqueIndex:uk_app_channel"`
MerchantID string `gorm:"column:merchant_id;size:64;not null"`
APIKey string `gorm:"column:api_key;type:text"` // AES 加密
PrivateKey string `gorm:"column:private_key;type:text"` // AES 加密
PublicKey string `gorm:"column:public_key;type:text"` // 渠道公钥(明文)
NotifyURL string `gorm:"column:notify_url;size:512;not null"`
Sandbox int8 `gorm:"column:sandbox;not null;default:0"` // 1=沙箱 0=生产
ExtraConfig JSONMap `gorm:"column:extra_config;type:json"`
Status int8 `gorm:"column:status;not null;default:1"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (ChannelConfig) TableName() string { return "channel_config" }

View File

@@ -0,0 +1,59 @@
package model
import "time"
// MerchantStatus 商户状态
type MerchantStatus string
const (
MerchantStatusPending MerchantStatus = "PENDING"
MerchantStatusActive MerchantStatus = "ACTIVE"
MerchantStatusFrozen MerchantStatus = "FROZEN"
MerchantStatusRejected MerchantStatus = "REJECTED"
)
// AuditStatus 进件审核状态
type AuditStatus string
const (
AuditStatusSubmitting AuditStatus = "SUBMITTING"
AuditStatusReviewing AuditStatus = "REVIEWING"
AuditStatusApproved AuditStatus = "APPROVED"
AuditStatusRejected AuditStatus = "REJECTED"
)
// Merchant 商户
type Merchant struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
MerchantID string `gorm:"column:merchant_id;uniqueIndex;size:32;not null"`
AppID string `gorm:"column:app_id;size:32;not null;default:'';index"`
MerchantName string `gorm:"column:merchant_name;size:128;not null"`
LicenseNo string `gorm:"column:license_no;size:64"`
LegalPerson string `gorm:"column:legal_person;size:64"`
BankAccount string `gorm:"column:bank_account;size:64"` // 脱敏
ChannelMerchantID string `gorm:"column:channel_merchant_id;size:64"`
Status MerchantStatus `gorm:"column:status;size:20;not null;default:PENDING;index"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (Merchant) TableName() string { return "merchant" }
// MerchantApplication 商户进件申请
// 一条记录对应一个商户在一个渠道的进件,(merchant_id, channel_code) 唯一
type MerchantApplication struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
ApplicationID string `gorm:"column:application_id;uniqueIndex;size:32;not null"`
MerchantID string `gorm:"column:merchant_id;size:32;not null;index"`
ChannelCode string `gorm:"column:channel_code;size:32;not null"`
ChannelMerchantID string `gorm:"column:channel_merchant_id;size:64;not null;default:''"`
SubmitData JSONMap `gorm:"column:submit_data;type:json"`
AuditStatus AuditStatus `gorm:"column:audit_status;size:20;not null;default:SUBMITTING"`
RejectReason string `gorm:"column:reject_reason;size:512"`
SubmittedAt time.Time `gorm:"column:submitted_at"`
AuditedAt *time.Time `gorm:"column:audited_at"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (MerchantApplication) TableName() string { return "merchant_application" }

View File

@@ -0,0 +1,37 @@
package model
import "time"
// NotifyStatus 通知状态
type NotifyStatus string
const (
NotifyStatusPending NotifyStatus = "PENDING"
NotifyStatusSuccess NotifyStatus = "SUCCESS"
NotifyStatusRetry NotifyStatus = "RETRY"
NotifyStatusGiveup NotifyStatus = "GIVEUP"
)
// NotifyType 通知类型
type NotifyType string
const (
NotifyTypePayment NotifyType = "PAYMENT"
NotifyTypeRefund NotifyType = "REFUND"
)
// NotifyLog 下游通知记录
type NotifyLog struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
TradeNo string `gorm:"column:trade_no;size:32;not null;uniqueIndex:uk_trade_notify_type"`
NotifyType NotifyType `gorm:"column:notify_type;size:20;not null;uniqueIndex:uk_trade_notify_type"`
NotifyURL string `gorm:"column:notify_url;size:512;not null"`
Status NotifyStatus `gorm:"column:status;size:20;not null;default:PENDING"`
RetryCount int `gorm:"column:retry_count;not null;default:0"`
NextRetryTime *time.Time `gorm:"column:next_retry_time;index:idx_status_next_retry"`
LastResponse string `gorm:"column:last_response;type:text"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (NotifyLog) TableName() string { return "notify_log" }

View File

@@ -0,0 +1,25 @@
package model
import "time"
// SeqType 序列类型
type SeqType string
const (
SeqTypeTrade SeqType = "TRADE"
SeqTypeRefund SeqType = "REFUND"
SeqTypeSharing SeqType = "SHARING"
)
// OrderSequence 订单编码序列
type OrderSequence struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;size:32;not null;uniqueIndex:uk_app_type"`
SeqType SeqType `gorm:"column:seq_type;size:20;not null;uniqueIndex:uk_app_type"`
Prefix string `gorm:"column:prefix;size:8;not null"`
CurrentValue uint64 `gorm:"column:current_value;not null;default:0"`
Step int `gorm:"column:step;not null;default:1"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (OrderSequence) TableName() string { return "order_sequence" }

View File

@@ -0,0 +1,49 @@
package model
import "time"
// MatchStatus 匹配状态
type MatchStatus string
const (
MatchStatusMatched MatchStatus = "MATCHED"
MatchStatusPendingManual MatchStatus = "PENDING_MANUAL"
MatchStatusNameDiff MatchStatus = "NAME_DIFF" // 匹配成功但名称不一致
)
// SubMerchantAccount 子商户固定收款账户
type SubMerchantAccount struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;size:32;not null;index:idx_app_merchant"`
SubMerchantID string `gorm:"column:sub_merchant_id;size:64;not null;index:idx_app_merchant"`
ChannelCode string `gorm:"column:channel_code;size:32;not null"`
AccountType string `gorm:"column:account_type;size:20;not null"` // BANK_CARD
AccountNo string `gorm:"column:account_no;size:64;not null;index"` // 脱敏
AccountNoEnc string `gorm:"column:account_no_enc;type:text"` // AES 加密完整账号
AccountName string `gorm:"column:account_name;size:128;not null"`
BankName string `gorm:"column:bank_name;size:64"`
Status int8 `gorm:"column:status;not null;default:1"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (SubMerchantAccount) TableName() string { return "sub_merchant_account" }
// PaymentMatchLog 收款匹配记录
type PaymentMatchLog struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AccountID uint64 `gorm:"column:account_id;not null;index:idx_account_status"`
TradeNo string `gorm:"column:trade_no;size:32;index"`
IncomingAmount int64 `gorm:"column:incoming_amount;not null"`
IncomingRemark string `gorm:"column:incoming_remark;size:256"`
PayerName string `gorm:"column:payer_name;size:128"`
ChannelBillNo string `gorm:"column:channel_bill_no;size:64;index"`
MatchStatus MatchStatus `gorm:"column:match_status;size:20;not null;index:idx_account_status"`
NameDiff int8 `gorm:"column:name_diff;not null;default:0"` // 1=名称不一致
MatchTime *time.Time `gorm:"column:match_time"`
Operator string `gorm:"column:operator;size:64"` // 人工操作者
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (PaymentMatchLog) TableName() string { return "payment_match_log" }

View File

@@ -0,0 +1,58 @@
package model
import "time"
// ProfitSharingStatus 分润状态
type ProfitSharingStatus string
const (
ProfitSharingStatusPending ProfitSharingStatus = "PENDING"
ProfitSharingStatusProcessing ProfitSharingStatus = "PROCESSING"
ProfitSharingStatusSuccess ProfitSharingStatus = "SUCCESS"
ProfitSharingStatusFailed ProfitSharingStatus = "FAILED"
ProfitSharingStatusRollback ProfitSharingStatus = "ROLLBACK"
)
// ProfitSharingConfig 分润配置(应用级)
type ProfitSharingConfig struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;size:32;not null;uniqueIndex"`
ReceiverMerchantID string `gorm:"column:receiver_merchant_id;size:64;not null"`
ReceiverType string `gorm:"column:receiver_type;size:20;not null"` // PLATFORM / SUB_MERCHANT
MaxSharingRatio float64 `gorm:"column:max_sharing_ratio;type:decimal(5,4);not null"`
Status int8 `gorm:"column:status;not null;default:1"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (ProfitSharingConfig) TableName() string { return "profit_sharing_config" }
// ProfitSharingOrder 分润记录
type ProfitSharingOrder struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
SharingNo string `gorm:"column:sharing_no;uniqueIndex;size:32;not null"`
TradeNo string `gorm:"column:trade_no;uniqueIndex;size:32;not null"`
AppID string `gorm:"column:app_id;size:32;not null"`
ReceiverMerchantID string `gorm:"column:receiver_merchant_id;size:64;not null"`
SharingAmount int64 `gorm:"column:sharing_amount;not null"`
Status ProfitSharingStatus `gorm:"column:status;size:20;not null;default:PENDING"`
ChannelSharingNo string `gorm:"column:channel_sharing_no;size:64"`
FailReason string `gorm:"column:fail_reason;size:256"`
SharingTime *time.Time `gorm:"column:sharing_time"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (ProfitSharingOrder) TableName() string { return "profit_sharing_order" }
// ProfitSharingLog 分润流水
type ProfitSharingLog struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
SharingNo string `gorm:"column:sharing_no;size:32;not null;index"`
Action string `gorm:"column:action;size:20;not null"` // SPLIT / ROLLBACK
Amount int64 `gorm:"column:amount;not null"`
Status string `gorm:"column:status;size:20;not null"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
}
func (ProfitSharingLog) TableName() string { return "profit_sharing_log" }

View File

@@ -0,0 +1,44 @@
package model
import "time"
// ReconciliationStatus 对账单状态
type ReconciliationStatus string
const (
ReconciliationStatusPending ReconciliationStatus = "PENDING"
ReconciliationStatusMatched ReconciliationStatus = "MATCHED"
ReconciliationStatusException ReconciliationStatus = "EXCEPTION"
)
// ReconciliationReport 对账报告
type ReconciliationReport struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;size:32;not null;index:idx_app_date"`
ChannelCode string `gorm:"column:channel_code;size:32;not null"`
BillDate string `gorm:"column:bill_date;size:10;not null;index:idx_app_date"` // yyyy-MM-dd
TotalCount int `gorm:"column:total_count;not null;default:0"`
TotalAmount int64 `gorm:"column:total_amount;not null;default:0"` // 分
MatchedCount int `gorm:"column:matched_count;not null;default:0"`
ExceptionCount int `gorm:"column:exception_count;not null;default:0"`
Status ReconciliationStatus `gorm:"column:status;size:20;not null;default:PENDING"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (ReconciliationReport) TableName() string { return "reconciliation_report" }
// ReconciliationException 对账异常明细
type ReconciliationException struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
ReportID uint64 `gorm:"column:report_id;not null;index"`
TradeNo string `gorm:"column:trade_no;size:32;index"`
ChannelBillNo string `gorm:"column:channel_bill_no;size:64"`
ExceptionType string `gorm:"column:exception_type;size:32;not null"` // MISSING_LOCAL/MISSING_CHANNEL/AMOUNT_MISMATCH
LocalAmount int64 `gorm:"column:local_amount"`
ChannelAmount int64 `gorm:"column:channel_amount"`
Remark string `gorm:"column:remark;size:256"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
}
func (ReconciliationException) TableName() string { return "reconciliation_exception" }

View File

@@ -0,0 +1,32 @@
package model
import "time"
// RefundStatus 退款状态
type RefundStatus string
const (
RefundStatusPending RefundStatus = "PENDING"
RefundStatusProcessing RefundStatus = "PROCESSING"
RefundStatusSuccess RefundStatus = "SUCCESS"
RefundStatusFailed RefundStatus = "FAILED"
)
// RefundOrder 退款记录
type RefundOrder struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
RefundNo string `gorm:"column:refund_no;uniqueIndex;size:32;not null"`
TradeNo string `gorm:"column:trade_no;size:32;not null;index"`
AppID string `gorm:"column:app_id;size:32;not null"`
ChannelCode string `gorm:"column:channel_code;size:32;not null"`
ChannelRefundNo string `gorm:"column:channel_refund_no;size:64"`
RefundAmount int64 `gorm:"column:refund_amount;not null"`
Reason string `gorm:"column:reason;size:256"`
Status RefundStatus `gorm:"column:status;size:20;not null;default:PENDING"`
NotifyURL string `gorm:"column:notify_url;size:512"`
RefundTime *time.Time `gorm:"column:refund_time"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (RefundOrder) TableName() string { return "refund_order" }

View File

@@ -0,0 +1,56 @@
package model
import "time"
// PayMethodGroup 支付方式分组(用于服务费配置)
type PayMethodGroup string
const (
PayMethodGroupScan PayMethodGroup = "SCAN" // 扫码支付(微信/支付宝)
PayMethodGroupTransfer PayMethodGroup = "TRANSFER" // 对公转账
PayMethodGroupBalance PayMethodGroup = "BALANCE" // 余额支付
)
// ServiceFeeConfig 服务费配置
type ServiceFeeConfig struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;size:32;not null;uniqueIndex:uk_app_method"`
PayMethodGroup PayMethodGroup `gorm:"column:pay_method_group;size:20;not null;uniqueIndex:uk_app_method"`
FeeRate float64 `gorm:"column:fee_rate;type:decimal(6,4);not null"` // 0.0000 ~ 9.9999%
FeeReceiverMerchantID string `gorm:"column:fee_receiver_merchant_id;size:64;not null"`
Status int8 `gorm:"column:status;not null;default:1"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (ServiceFeeConfig) TableName() string { return "service_fee_config" }
// ServiceFeeLog 服务费流水
type ServiceFeeLog struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
TradeNo string `gorm:"column:trade_no;size:32;not null;uniqueIndex:uk_trade_action"`
ConfigID uint64 `gorm:"column:config_id;not null"`
FeeAmount int64 `gorm:"column:fee_amount;not null"`
FeeRate float64 `gorm:"column:fee_rate;type:decimal(6,4);not null"`
ReceiverMerchantID string `gorm:"column:receiver_merchant_id;size:64;not null"`
Action string `gorm:"column:action;size:20;not null;uniqueIndex:uk_trade_action"` // CHARGE / ROLLBACK
Status string `gorm:"column:status;size:20;not null;default:PENDING"`
ChannelSharingNo string `gorm:"column:channel_sharing_no;size:64"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (ServiceFeeLog) TableName() string { return "service_fee_log" }
// PayMethodToGroup 将支付方式映射到服务费分组
func PayMethodToGroup(m PayMethod) PayMethodGroup {
switch m {
case PayMethodWechatJSAPI, PayMethodWechatH5, PayMethodWechatNative,
PayMethodWechatMini, PayMethodAlipay, PayMethodQuickPay:
return PayMethodGroupScan
case PayMethodTransfer:
return PayMethodGroupTransfer
default:
return PayMethodGroupBalance
}
}

View File

@@ -0,0 +1,103 @@
package model
import (
"database/sql/driver"
"encoding/json"
"fmt"
"time"
)
// TradeStatus 交易状态
type TradeStatus string
const (
TradeStatusCreating TradeStatus = "CREATING"
TradeStatusPaying TradeStatus = "PAYING"
TradeStatusPaid TradeStatus = "PAID"
TradeStatusClosed TradeStatus = "CLOSED"
TradeStatusFailed TradeStatus = "FAILED"
TradeStatusCreateFailed TradeStatus = "CREATE_FAILED"
TradeStatusRefunded TradeStatus = "REFUNDED"
)
// PayMethod 支付方式
type PayMethod string
const (
PayMethodWechatJSAPI PayMethod = "WECHAT_JSAPI"
PayMethodWechatH5 PayMethod = "WECHAT_H5"
PayMethodWechatNative PayMethod = "WECHAT_NATIVE"
PayMethodWechatMini PayMethod = "WECHAT_MINI"
PayMethodAlipay PayMethod = "ALIPAY"
PayMethodQuickPay PayMethod = "QUICK_PAY"
PayMethodTransfer PayMethod = "TRANSFER" // 对公转账
)
// JSONMap JSON 字段类型
type JSONMap map[string]any
func (j JSONMap) Value() (driver.Value, error) {
if j == nil {
return nil, nil
}
b, err := json.Marshal(j)
return string(b), err
}
func (j *JSONMap) Scan(value any) error {
if value == nil {
*j = nil
return nil
}
var bytes []byte
switch v := value.(type) {
case string:
bytes = []byte(v)
case []byte:
bytes = v
default:
return fmt.Errorf("unsupported type: %T", value)
}
return json.Unmarshal(bytes, j)
}
// TradeOrder 交易订单
type TradeOrder struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
TradeNo string `gorm:"column:trade_no;uniqueIndex;size:32;not null"`
MerchantOrderNo string `gorm:"column:merchant_order_no;size:64;not null"`
AppID string `gorm:"column:app_id;size:32;not null;index:idx_app_merchant,unique"`
ChannelCode string `gorm:"column:channel_code;size:32;not null"`
ChannelTradeNo string `gorm:"column:channel_trade_no;size:64;index"`
PayMethod PayMethod `gorm:"column:pay_method;size:32;not null"`
Amount int64 `gorm:"column:amount;not null"`
ProfitSharingAmount int64 `gorm:"column:profit_sharing_amount;not null;default:0"`
ServiceFeeAmount int64 `gorm:"column:service_fee_amount;not null;default:0"`
Subject string `gorm:"column:subject;size:256;not null"`
NotifyURL string `gorm:"column:notify_url;size:512;not null"`
Status TradeStatus `gorm:"column:status;size:20;not null;default:CREATING"`
Extra JSONMap `gorm:"column:extra;type:json"`
ChannelExtra JSONMap `gorm:"column:channel_extra;type:json"`
ExpireTime time.Time `gorm:"column:expire_time;not null"`
PayTime *time.Time `gorm:"column:pay_time"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (TradeOrder) TableName() string { return "trade_order" }
// CanTransitTo 校验状态流转是否合法
func (t TradeStatus) CanTransitTo(next TradeStatus) bool {
allowed := map[TradeStatus][]TradeStatus{
TradeStatusCreating: {TradeStatusPaying, TradeStatusCreateFailed},
TradeStatusPaying: {TradeStatusPaid, TradeStatusClosed, TradeStatusFailed},
TradeStatusPaid: {TradeStatusRefunded},
TradeStatusCreateFailed: {TradeStatusPaying},
}
for _, s := range allowed[t] {
if s == next {
return true
}
}
return false
}

View File

@@ -0,0 +1,41 @@
package model
import "time"
// WechatBinding 商户微信公众号绑定
type WechatBinding struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;size:32;not null;uniqueIndex"`
WxAppID string `gorm:"column:wx_app_id;size:32;not null"` // 微信公众号/小程序 AppID
WxSecret string `gorm:"column:wx_secret;type:text;not null"` // AES 加密存储
TemplateID string `gorm:"column:template_id;size:64;not null"` // 消息模板 ID
Status int8 `gorm:"column:status;not null;default:1"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime:milli"`
}
func (WechatBinding) TableName() string { return "wechat_binding" }
// WechatMessageStatus 微信消息发送状态
type WechatMessageStatus string
const (
WechatMessageStatusPending WechatMessageStatus = "PENDING"
WechatMessageStatusSuccess WechatMessageStatus = "SUCCESS"
WechatMessageStatusFailed WechatMessageStatus = "FAILED"
)
// WechatMessageLog 微信消息发送日志
type WechatMessageLog struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
AppID string `gorm:"column:app_id;size:32;not null;index"`
TradeNo string `gorm:"column:trade_no;size:32;index"`
OpenID string `gorm:"column:open_id;size:64;not null"`
TemplateID string `gorm:"column:template_id;size:64;not null"`
Status WechatMessageStatus `gorm:"column:status;size:20;not null;default:PENDING"`
ErrMsg string `gorm:"column:err_msg;size:256"`
SentAt *time.Time `gorm:"column:sent_at"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime:milli"`
}
func (WechatMessageLog) TableName() string { return "wechat_message_log" }