feat: add payout account review flow

This commit is contained in:
2026-01-16 15:17:43 +08:00
parent daaacc3fa4
commit 028c462eaa
21 changed files with 1100 additions and 151 deletions

View File

@@ -40,9 +40,9 @@ type Content struct {
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;type:timestamp with time zone" json:"deleted_at"`
Key string `gorm:"column:key;type:character varying(32);comment:Musical key/tone" json:"key"` // Musical key/tone
IsPinned bool `gorm:"column:is_pinned;type:boolean;comment:Whether content is pinned/featured" json:"is_pinned"` // Whether content is pinned/featured
Comments []*Comment `gorm:"foreignKey:ContentID;references:ID" json:"comments,omitempty"`
Author *User `gorm:"foreignKey:UserID;references:ID" json:"author,omitempty"`
ContentAssets []*ContentAsset `gorm:"foreignKey:ContentID;references:ID" json:"content_assets,omitempty"`
Comments []*Comment `gorm:"foreignKey:ContentID;references:ID" json:"comments,omitempty"`
}
// Quick operations without importing query package

View File

@@ -46,12 +46,6 @@ func newContent(db *gorm.DB, opts ...gen.DOOption) contentQuery {
_contentQuery.DeletedAt = field.NewField(tableName, "deleted_at")
_contentQuery.Key = field.NewString(tableName, "key")
_contentQuery.IsPinned = field.NewBool(tableName, "is_pinned")
_contentQuery.Comments = contentQueryHasManyComments{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("Comments", "Comment"),
}
_contentQuery.Author = contentQueryBelongsToAuthor{
db: db.Session(&gorm.Session{}),
@@ -64,6 +58,12 @@ func newContent(db *gorm.DB, opts ...gen.DOOption) contentQuery {
RelationField: field.NewRelation("ContentAssets", "ContentAsset"),
}
_contentQuery.Comments = contentQueryHasManyComments{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("Comments", "Comment"),
}
_contentQuery.fillFieldMap()
return _contentQuery
@@ -94,12 +94,12 @@ type contentQuery struct {
DeletedAt field.Field
Key field.String // Musical key/tone
IsPinned field.Bool // Whether content is pinned/featured
Comments contentQueryHasManyComments
Author contentQueryBelongsToAuthor
Author contentQueryBelongsToAuthor
ContentAssets contentQueryHasManyContentAssets
Comments contentQueryHasManyComments
fieldMap map[string]field.Expr
}
@@ -195,104 +195,23 @@ func (c *contentQuery) fillFieldMap() {
func (c contentQuery) clone(db *gorm.DB) contentQuery {
c.contentQueryDo.ReplaceConnPool(db.Statement.ConnPool)
c.Comments.db = db.Session(&gorm.Session{Initialized: true})
c.Comments.db.Statement.ConnPool = db.Statement.ConnPool
c.Author.db = db.Session(&gorm.Session{Initialized: true})
c.Author.db.Statement.ConnPool = db.Statement.ConnPool
c.ContentAssets.db = db.Session(&gorm.Session{Initialized: true})
c.ContentAssets.db.Statement.ConnPool = db.Statement.ConnPool
c.Comments.db = db.Session(&gorm.Session{Initialized: true})
c.Comments.db.Statement.ConnPool = db.Statement.ConnPool
return c
}
func (c contentQuery) replaceDB(db *gorm.DB) contentQuery {
c.contentQueryDo.ReplaceDB(db)
c.Comments.db = db.Session(&gorm.Session{})
c.Author.db = db.Session(&gorm.Session{})
c.ContentAssets.db = db.Session(&gorm.Session{})
c.Comments.db = db.Session(&gorm.Session{})
return c
}
type contentQueryHasManyComments struct {
db *gorm.DB
field.RelationField
}
func (a contentQueryHasManyComments) Where(conds ...field.Expr) *contentQueryHasManyComments {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a contentQueryHasManyComments) WithContext(ctx context.Context) *contentQueryHasManyComments {
a.db = a.db.WithContext(ctx)
return &a
}
func (a contentQueryHasManyComments) Session(session *gorm.Session) *contentQueryHasManyComments {
a.db = a.db.Session(session)
return &a
}
func (a contentQueryHasManyComments) Model(m *Content) *contentQueryHasManyCommentsTx {
return &contentQueryHasManyCommentsTx{a.db.Model(m).Association(a.Name())}
}
func (a contentQueryHasManyComments) Unscoped() *contentQueryHasManyComments {
a.db = a.db.Unscoped()
return &a
}
type contentQueryHasManyCommentsTx struct{ tx *gorm.Association }
func (a contentQueryHasManyCommentsTx) Find() (result []*Comment, err error) {
return result, a.tx.Find(&result)
}
func (a contentQueryHasManyCommentsTx) Append(values ...*Comment) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a contentQueryHasManyCommentsTx) Replace(values ...*Comment) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a contentQueryHasManyCommentsTx) Delete(values ...*Comment) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a contentQueryHasManyCommentsTx) Clear() error {
return a.tx.Clear()
}
func (a contentQueryHasManyCommentsTx) Count() int64 {
return a.tx.Count()
}
func (a contentQueryHasManyCommentsTx) Unscoped() *contentQueryHasManyCommentsTx {
a.tx = a.tx.Unscoped()
return &a
}
type contentQueryBelongsToAuthor struct {
db *gorm.DB
@@ -455,6 +374,87 @@ func (a contentQueryHasManyContentAssetsTx) Unscoped() *contentQueryHasManyConte
return &a
}
type contentQueryHasManyComments struct {
db *gorm.DB
field.RelationField
}
func (a contentQueryHasManyComments) Where(conds ...field.Expr) *contentQueryHasManyComments {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a contentQueryHasManyComments) WithContext(ctx context.Context) *contentQueryHasManyComments {
a.db = a.db.WithContext(ctx)
return &a
}
func (a contentQueryHasManyComments) Session(session *gorm.Session) *contentQueryHasManyComments {
a.db = a.db.Session(session)
return &a
}
func (a contentQueryHasManyComments) Model(m *Content) *contentQueryHasManyCommentsTx {
return &contentQueryHasManyCommentsTx{a.db.Model(m).Association(a.Name())}
}
func (a contentQueryHasManyComments) Unscoped() *contentQueryHasManyComments {
a.db = a.db.Unscoped()
return &a
}
type contentQueryHasManyCommentsTx struct{ tx *gorm.Association }
func (a contentQueryHasManyCommentsTx) Find() (result []*Comment, err error) {
return result, a.tx.Find(&result)
}
func (a contentQueryHasManyCommentsTx) Append(values ...*Comment) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a contentQueryHasManyCommentsTx) Replace(values ...*Comment) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a contentQueryHasManyCommentsTx) Delete(values ...*Comment) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a contentQueryHasManyCommentsTx) Clear() error {
return a.tx.Clear()
}
func (a contentQueryHasManyCommentsTx) Count() int64 {
return a.tx.Count()
}
func (a contentQueryHasManyCommentsTx) Unscoped() *contentQueryHasManyCommentsTx {
a.tx = a.tx.Unscoped()
return &a
}
type contentQueryDo struct{ gen.DO }
func (c contentQueryDo) Debug() *contentQueryDo {

View File

@@ -8,6 +8,8 @@ import (
"context"
"time"
"quyun/v2/pkg/consts"
"go.ipao.vip/gen"
)
@@ -15,15 +17,19 @@ const TableNamePayoutAccount = "payout_accounts"
// PayoutAccount mapped from table <payout_accounts>
type PayoutAccount struct {
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
Type string `gorm:"column:type;type:character varying(32);not null" json:"type"`
Name string `gorm:"column:name;type:character varying(128);not null" json:"name"`
Account string `gorm:"column:account;type:character varying(128);not null" json:"account"`
Realname string `gorm:"column:realname;type:character varying(128);not null" json:"realname"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"`
ID int64 `gorm:"column:id;type:bigint;primaryKey;autoIncrement:true" json:"id"`
TenantID int64 `gorm:"column:tenant_id;type:bigint;not null" json:"tenant_id"`
UserID int64 `gorm:"column:user_id;type:bigint;not null" json:"user_id"`
Type consts.PayoutAccountType `gorm:"column:type;type:character varying(32);not null" json:"type"`
Name string `gorm:"column:name;type:character varying(128);not null" json:"name"`
Account string `gorm:"column:account;type:character varying(128);not null" json:"account"`
Realname string `gorm:"column:realname;type:character varying(128);not null" json:"realname"`
CreatedAt time.Time `gorm:"column:created_at;type:timestamp with time zone;default:now()" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at;type:timestamp with time zone;default:now()" json:"updated_at"`
Status consts.PayoutAccountStatus `gorm:"column:status;type:character varying(32);not null;default:pending;comment:结算账户审核状态;用途:控制提现账户可用性;默认 pending。" json:"status"` // 结算账户审核状态;用途:控制提现账户可用性;默认 pending。
ReviewedBy int64 `gorm:"column:reviewed_by;type:bigint;not null;comment:结算账户审核操作者ID用途审计追踪默认 0 表示未审核。" json:"reviewed_by"` // 结算账户审核操作者ID用途审计追踪默认 0 表示未审核。
ReviewedAt time.Time `gorm:"column:reviewed_at;type:timestamp with time zone;comment:结算账户审核时间;用途:记录审核完成时间;未审核为空。" json:"reviewed_at"` // 结算账户审核时间;用途:记录审核完成时间;未审核为空。
ReviewReason string `gorm:"column:review_reason;type:character varying(255);not null;comment:结算账户审核说明;用途:驳回原因或备注;默认空字符串。" json:"review_reason"` // 结算账户审核说明;用途:驳回原因或备注;默认空字符串。
}
// Quick operations without importing query package

View File

@@ -28,12 +28,16 @@ func newPayoutAccount(db *gorm.DB, opts ...gen.DOOption) payoutAccountQuery {
_payoutAccountQuery.ID = field.NewInt64(tableName, "id")
_payoutAccountQuery.TenantID = field.NewInt64(tableName, "tenant_id")
_payoutAccountQuery.UserID = field.NewInt64(tableName, "user_id")
_payoutAccountQuery.Type = field.NewString(tableName, "type")
_payoutAccountQuery.Type = field.NewField(tableName, "type")
_payoutAccountQuery.Name = field.NewString(tableName, "name")
_payoutAccountQuery.Account = field.NewString(tableName, "account")
_payoutAccountQuery.Realname = field.NewString(tableName, "realname")
_payoutAccountQuery.CreatedAt = field.NewTime(tableName, "created_at")
_payoutAccountQuery.UpdatedAt = field.NewTime(tableName, "updated_at")
_payoutAccountQuery.Status = field.NewField(tableName, "status")
_payoutAccountQuery.ReviewedBy = field.NewInt64(tableName, "reviewed_by")
_payoutAccountQuery.ReviewedAt = field.NewTime(tableName, "reviewed_at")
_payoutAccountQuery.ReviewReason = field.NewString(tableName, "review_reason")
_payoutAccountQuery.fillFieldMap()
@@ -43,16 +47,20 @@ func newPayoutAccount(db *gorm.DB, opts ...gen.DOOption) payoutAccountQuery {
type payoutAccountQuery struct {
payoutAccountQueryDo payoutAccountQueryDo
ALL field.Asterisk
ID field.Int64
TenantID field.Int64
UserID field.Int64
Type field.String
Name field.String
Account field.String
Realname field.String
CreatedAt field.Time
UpdatedAt field.Time
ALL field.Asterisk
ID field.Int64
TenantID field.Int64
UserID field.Int64
Type field.Field
Name field.String
Account field.String
Realname field.String
CreatedAt field.Time
UpdatedAt field.Time
Status field.Field // 结算账户审核状态;用途:控制提现账户可用性;默认 pending。
ReviewedBy field.Int64 // 结算账户审核操作者ID用途审计追踪默认 0 表示未审核。
ReviewedAt field.Time // 结算账户审核时间;用途:记录审核完成时间;未审核为空。
ReviewReason field.String // 结算账户审核说明;用途:驳回原因或备注;默认空字符串。
fieldMap map[string]field.Expr
}
@@ -72,12 +80,16 @@ func (p *payoutAccountQuery) updateTableName(table string) *payoutAccountQuery {
p.ID = field.NewInt64(table, "id")
p.TenantID = field.NewInt64(table, "tenant_id")
p.UserID = field.NewInt64(table, "user_id")
p.Type = field.NewString(table, "type")
p.Type = field.NewField(table, "type")
p.Name = field.NewString(table, "name")
p.Account = field.NewString(table, "account")
p.Realname = field.NewString(table, "realname")
p.CreatedAt = field.NewTime(table, "created_at")
p.UpdatedAt = field.NewTime(table, "updated_at")
p.Status = field.NewField(table, "status")
p.ReviewedBy = field.NewInt64(table, "reviewed_by")
p.ReviewedAt = field.NewTime(table, "reviewed_at")
p.ReviewReason = field.NewString(table, "review_reason")
p.fillFieldMap()
@@ -110,7 +122,7 @@ func (p *payoutAccountQuery) GetFieldByName(fieldName string) (field.OrderExpr,
}
func (p *payoutAccountQuery) fillFieldMap() {
p.fieldMap = make(map[string]field.Expr, 9)
p.fieldMap = make(map[string]field.Expr, 13)
p.fieldMap["id"] = p.ID
p.fieldMap["tenant_id"] = p.TenantID
p.fieldMap["user_id"] = p.UserID
@@ -120,6 +132,10 @@ func (p *payoutAccountQuery) fillFieldMap() {
p.fieldMap["realname"] = p.Realname
p.fieldMap["created_at"] = p.CreatedAt
p.fieldMap["updated_at"] = p.UpdatedAt
p.fieldMap["status"] = p.Status
p.fieldMap["reviewed_by"] = p.ReviewedBy
p.fieldMap["reviewed_at"] = p.ReviewedAt
p.fieldMap["review_reason"] = p.ReviewReason
}
func (p payoutAccountQuery) clone(db *gorm.DB) payoutAccountQuery {