Compare commits

...

2 Commits

Author SHA1 Message Date
Yavolte dc4d31a9fd fix model afterdelete 2025-08-15 09:37:07 +08:00
Yavolte 05f17b9c73 修改生成ID插件出错 2025-08-06 10:47:45 +08:00
11 changed files with 98 additions and 26 deletions

2
go.mod
View File

@ -4,8 +4,10 @@ go 1.22.9
require ( require (
git.nobla.cn/golang/kos v0.1.32 git.nobla.cn/golang/kos v0.1.32
github.com/bwmarrin/snowflake v0.3.0
github.com/cespare/xxhash/v2 v2.3.0 github.com/cespare/xxhash/v2 v2.3.0
github.com/go-playground/validator/v10 v10.23.0 github.com/go-playground/validator/v10 v10.23.0
github.com/google/uuid v1.6.0
github.com/longbridgeapp/sqlparser v0.3.2 github.com/longbridgeapp/sqlparser v0.3.2
github.com/rs/xid v1.6.0 github.com/rs/xid v1.6.0
github.com/uole/sqlparser v0.0.1 github.com/uole/sqlparser v0.0.1

4
go.sum
View File

@ -1,5 +1,7 @@
git.nobla.cn/golang/kos v0.1.32 h1:sFVCA7vKc8dPUd0cxzwExOSPX2mmMh2IuwL6cYS1pBc= git.nobla.cn/golang/kos v0.1.32 h1:sFVCA7vKc8dPUd0cxzwExOSPX2mmMh2IuwL6cYS1pBc=
git.nobla.cn/golang/kos v0.1.32/go.mod h1:35Z070+5oB39WcVrh5DDlnVeftL/Ccmscw2MZFe9fUg= git.nobla.cn/golang/kos v0.1.32/go.mod h1:35Z070+5oB39WcVrh5DDlnVeftL/Ccmscw2MZFe9fUg=
github.com/bwmarrin/snowflake v0.3.0 h1:xm67bEhkKh6ij1790JB83OujPR5CzNe8QuQqAgISZN0=
github.com/bwmarrin/snowflake v0.3.0/go.mod h1:NdZxfVWX+oR6y2K0o6qAYv6gIOP9rjG0/E9WsDpxqwE=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -16,6 +18,8 @@ github.com/go-playground/validator/v10 v10.23.0 h1:/PwmTwZhS0dPkav3cdK9kV1FsAmrL
github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-playground/validator/v10 v10.23.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M= github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8= github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=

View File

@ -78,7 +78,6 @@ func (hook *hookManager) afterCreate(ctx context.Context, tx *gorm.DB, model any
cb(ctx, tx, model, diff) cb(ctx, tx, model, diff)
} }
} }
return
} }
func (hook *hookManager) beforeUpdate(ctx context.Context, tx *gorm.DB, model any) (err error) { func (hook *hookManager) beforeUpdate(ctx context.Context, tx *gorm.DB, model any) (err error) {
@ -106,7 +105,6 @@ func (hook *hookManager) afterUpdate(ctx context.Context, tx *gorm.DB, model any
cb(ctx, tx, model, diff) cb(ctx, tx, model, diff)
} }
} }
return
} }
func (hook *hookManager) beforeSave(ctx context.Context, tx *gorm.DB, model any) (err error) { func (hook *hookManager) beforeSave(ctx context.Context, tx *gorm.DB, model any) (err error) {

View File

@ -695,9 +695,12 @@ func (m *Model) Delete(w http.ResponseWriter, r *http.Request) {
if errTx != nil { if errTx != nil {
return return
} }
m.getHook().afterDelete(childCtx, tx, model)
return return
}); err == nil { }); err == nil {
if deleter, ok := model.(afterDeleted); ok {
deleter.AfterDeleted(childCtx, dbSess)
}
m.getHook().afterDelete(childCtx, dbSess, model)
m.response.Success(w, types.DeleteResponse{ m.response.Success(w, types.DeleteResponse{
ID: idStr, ID: idStr,
Status: "deleted", Status: "deleted",

View File

@ -0,0 +1,51 @@
package identity
import (
"github.com/bwmarrin/snowflake"
"github.com/google/uuid"
"github.com/rs/xid"
)
type Engine interface {
NextID() string
}
type (
XidEngine struct {
}
UUIDEngine struct {
}
SnowflakeEngine struct {
e *snowflake.Node
}
)
func (e *XidEngine) NextID() string {
return xid.New().String()
}
func (e *UUIDEngine) NextID() string {
return uuid.New().String()
}
func (e *SnowflakeEngine) NextID() string {
return e.e.Generate().String()
}
func NewXidEngine() *XidEngine {
return &XidEngine{}
}
func NewUUIDEngine() *UUIDEngine {
return &UUIDEngine{}
}
func NewSnowflakeEngine(nodeID int64) *SnowflakeEngine {
node, err := snowflake.NewNode(nodeID)
if err != nil {
panic(err)
}
return &SnowflakeEngine{e: node}
}

View File

@ -1,13 +1,14 @@
package identity package identity
import ( import (
"github.com/rs/xid" "reflect"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/schema" "gorm.io/gorm/schema"
"reflect"
) )
type Identify struct { type Identify struct {
e Engine
} }
func (identity *Identify) Name() string { func (identity *Identify) Name() string {
@ -20,7 +21,7 @@ func (identity *Identify) Initialize(db *gorm.DB) (err error) {
} }
func (identity *Identify) NextID() string { func (identity *Identify) NextID() string {
return xid.New().String() return identity.e.NextID()
} }
func (identity *Identify) Grant(db *gorm.DB) { func (identity *Identify) Grant(db *gorm.DB) {
@ -31,10 +32,13 @@ func (identity *Identify) Grant(db *gorm.DB) {
if db.Statement.Schema == nil { if db.Statement.Schema == nil {
return return
} }
if field = db.Statement.Schema.LookUpField("ID"); field == nil { for _, column := range db.Statement.Schema.Fields {
return if column.PrimaryKey {
field = column
break
}
} }
if field.DataType != schema.String { if field == nil || field.DataType != schema.String {
return return
} }
if db.Statement.ReflectValue.Kind() == reflect.Array || db.Statement.ReflectValue.Kind() == reflect.Slice { if db.Statement.ReflectValue.Kind() == reflect.Array || db.Statement.ReflectValue.Kind() == reflect.Slice {
@ -47,11 +51,16 @@ func (identity *Identify) Grant(db *gorm.DB) {
} }
} else { } else {
if _, zero := field.ValueOf(db.Statement.Context, db.Statement.ReflectValue); zero { if _, zero := field.ValueOf(db.Statement.Context, db.Statement.ReflectValue); zero {
db.Statement.SetColumn("ID", identity.NextID()) db.Statement.SetColumn(field.Name, identity.NextID())
} }
} }
} }
func New() *Identify { func New(e Engine) *Identify {
return &Identify{} if e == nil {
e = NewXidEngine()
}
return &Identify{
e: e,
}
} }

View File

@ -1,11 +1,12 @@
package validate package validate
import ( import (
"git.nobla.cn/golang/rest/types"
"gorm.io/gorm"
"reflect" "reflect"
"regexp" "regexp"
"strconv" "strconv"
"git.nobla.cn/golang/rest/types"
"gorm.io/gorm"
) )
const ( const (
@ -14,7 +15,7 @@ const (
var ( var (
scopeCtxKey = &validateScope{} scopeCtxKey = &validateScope{}
telephoneRegex = regexp.MustCompile("^\\d{5,20}$") telephoneRegex = regexp.MustCompile(`^\d{5,20}$`)
) )
type ( type (
@ -62,7 +63,6 @@ func formatError(rule types.Rule, scm *types.Schema, tag string) string {
switch tag { switch tag {
case "db_unique": case "db_unique":
s = scm.Label + "值已经存在." s = scm.Label + "值已经存在."
break
case "required": case "required":
s = scm.Label + "值不能为空." s = scm.Label + "值不能为空."
case "max": case "max":

View File

@ -17,7 +17,7 @@ type (
db *gorm.DB db *gorm.DB
condition string condition string
fields []string fields []string
params []interface{} params []any
table string table string
joins []join joins []join
orderBy []string orderBy []string
@ -28,9 +28,9 @@ type (
} }
condition struct { condition struct {
Field string `json:"field"` Field string `json:"field"`
Value interface{} `json:"value"` Value any `json:"value"`
Expr string `json:"expr"` Expr string `json:"expr"`
} }
join struct { join struct {
@ -60,16 +60,16 @@ func (query *Query) compile() (*gorm.DB, error) {
if query.table != "" { if query.table != "" {
db = db.Table(query.table) db = db.Table(query.table)
} }
if query.joins != nil && len(query.joins) > 0 { if len(query.joins) > 0 {
for _, joinEntity := range query.joins { for _, joinEntity := range query.joins {
cs, ps := query.buildConditions("OR", false, joinEntity.Conditions...) cs, ps := query.buildConditions("OR", false, joinEntity.Conditions...)
db = db.Joins(joinEntity.Direction+" JOIN "+joinEntity.Table+" ON "+cs, ps...) db = db.Joins(joinEntity.Direction+" JOIN "+joinEntity.Table+" ON "+cs, ps...)
} }
} }
if query.orderBy != nil && len(query.orderBy) > 0 { if len(query.orderBy) > 0 {
db = db.Order(strings.Join(query.orderBy, ",")) db = db.Order(strings.Join(query.orderBy, ","))
} }
if query.groupBy != nil && len(query.groupBy) > 0 { if len(query.groupBy) > 0 {
db = db.Group(strings.Join(query.groupBy, ",")) db = db.Group(strings.Join(query.groupBy, ","))
} }
if query.offset > 0 { if query.offset > 0 {
@ -366,7 +366,7 @@ func (query *Query) ResetSelect() *Query {
return query return query
} }
func (query *Query) Count(v interface{}) (i int64) { func (query *Query) Count(v any) (i int64) {
var ( var (
db *gorm.DB db *gorm.DB
err error err error

View File

@ -62,6 +62,11 @@ type (
AfterSaved(ctx context.Context, tx *gorm.DB) AfterSaved(ctx context.Context, tx *gorm.DB)
} }
//删除后的回调
afterDeleted interface {
AfterDeleted(ctx context.Context, tx *gorm.DB)
}
sqlCountResponse struct { sqlCountResponse struct {
Count int64 `json:"count"` Count int64 `json:"count"`
} }

View File

@ -20,7 +20,7 @@ func (n Scenarios) Value() (driver.Value, error) {
} }
// Scan implements the Scanner interface. // Scan implements the Scanner interface.
func (n *Rule) Scan(value interface{}) error { func (n *Rule) Scan(value any) error {
if value == nil { if value == nil {
return nil return nil
} }

View File

@ -63,7 +63,7 @@ func (n Scenarios) Has(str string) bool {
} }
// Scan implements the Scanner interface. // Scan implements the Scanner interface.
func (n *Scenarios) Scan(value interface{}) error { func (n *Scenarios) Scan(value any) error {
if value == nil { if value == nil {
return nil return nil
} }