Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
|
dc4d31a9fd | |
|
05f17b9c73 | |
|
ca7619af41 | |
|
10cdd32e95 | |
|
0e4226fd84 |
2
go.mod
2
go.mod
|
@ -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
4
go.sum
|
@ -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=
|
||||||
|
|
7
hook.go
7
hook.go
|
@ -2,6 +2,7 @@ package rest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"git.nobla.cn/golang/rest/types"
|
"git.nobla.cn/golang/rest/types"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
@ -77,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) {
|
||||||
|
@ -105,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) {
|
||||||
|
@ -133,7 +132,6 @@ func (hook *hookManager) afterSave(ctx context.Context, tx *gorm.DB, model any,
|
||||||
cb(ctx, tx, model, diff)
|
cb(ctx, tx, model, diff)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hook *hookManager) beforeDelete(ctx context.Context, tx *gorm.DB, model any) (err error) {
|
func (hook *hookManager) beforeDelete(ctx context.Context, tx *gorm.DB, model any) (err error) {
|
||||||
|
@ -161,7 +159,6 @@ func (hook *hookManager) afterDelete(ctx context.Context, tx *gorm.DB, model any
|
||||||
cb(ctx, tx, model)
|
cb(ctx, tx, model)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hook *hookManager) afterExport(ctx context.Context, filename string) {
|
func (hook *hookManager) afterExport(ctx context.Context, filename string) {
|
||||||
|
@ -174,7 +171,6 @@ func (hook *hookManager) afterExport(ctx context.Context, filename string) {
|
||||||
cb(ctx, filename)
|
cb(ctx, filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hook *hookManager) afterImport(ctx context.Context, ret *types.ImportResult) {
|
func (hook *hookManager) afterImport(ctx context.Context, ret *types.ImportResult) {
|
||||||
|
@ -187,7 +183,6 @@ func (hook *hookManager) afterImport(ctx context.Context, ret *types.ImportResul
|
||||||
cb(ctx, ret)
|
cb(ctx, ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hook *hookManager) BeforeCreate(cb BeforeCreate) {
|
func (hook *hookManager) BeforeCreate(cb BeforeCreate) {
|
||||||
|
|
17
model.go
17
model.go
|
@ -391,6 +391,7 @@ func (m *Model) Search(w http.ResponseWriter, r *http.Request) {
|
||||||
ModuleName: m.naming.ModuleName,
|
ModuleName: m.naming.ModuleName,
|
||||||
TableName: m.naming.TableName,
|
TableName: m.naming.TableName,
|
||||||
Scenario: types.ScenarioList,
|
Scenario: types.ScenarioList,
|
||||||
|
Context: m.db.Statement.Context,
|
||||||
})
|
})
|
||||||
if searchSchemas, err = m.schemaLookup(childCtx, m.getDB(), domainName, m.naming.ModuleName, m.naming.TableName, types.ScenarioSearch); err != nil {
|
if searchSchemas, err = m.schemaLookup(childCtx, m.getDB(), domainName, m.naming.ModuleName, m.naming.TableName, types.ScenarioSearch); err != nil {
|
||||||
m.response.Failure(w, types.RequestRecordNotFound, "record not found", nil)
|
m.response.Failure(w, types.RequestRecordNotFound, "record not found", nil)
|
||||||
|
@ -496,6 +497,7 @@ func (m *Model) Create(w http.ResponseWriter, r *http.Request) {
|
||||||
TableName: m.naming.TableName,
|
TableName: m.naming.TableName,
|
||||||
Scenario: types.ScenarioCreate,
|
Scenario: types.ScenarioCreate,
|
||||||
Schemas: schemas,
|
Schemas: schemas,
|
||||||
|
Context: m.db.Statement.Context,
|
||||||
})
|
})
|
||||||
dbSess := m.getDB().WithContext(childCtx)
|
dbSess := m.getDB().WithContext(childCtx)
|
||||||
if err = dbSess.Transaction(func(tx *gorm.DB) (errTx error) {
|
if err = dbSess.Transaction(func(tx *gorm.DB) (errTx error) {
|
||||||
|
@ -594,6 +596,7 @@ func (m *Model) Update(w http.ResponseWriter, r *http.Request) {
|
||||||
Scenario: types.ScenarioUpdate,
|
Scenario: types.ScenarioUpdate,
|
||||||
Schemas: schemas,
|
Schemas: schemas,
|
||||||
PrimaryKeyValue: idStr,
|
PrimaryKeyValue: idStr,
|
||||||
|
Context: m.db.Statement.Context,
|
||||||
})
|
})
|
||||||
dbSess := m.getDB().WithContext(childCtx)
|
dbSess := m.getDB().WithContext(childCtx)
|
||||||
if err = dbSess.Transaction(func(tx *gorm.DB) (errTx error) {
|
if err = dbSess.Transaction(func(tx *gorm.DB) (errTx error) {
|
||||||
|
@ -677,6 +680,7 @@ func (m *Model) Delete(w http.ResponseWriter, r *http.Request) {
|
||||||
TableName: m.naming.TableName,
|
TableName: m.naming.TableName,
|
||||||
Scenario: types.ScenarioDelete,
|
Scenario: types.ScenarioDelete,
|
||||||
PrimaryKeyValue: idStr,
|
PrimaryKeyValue: idStr,
|
||||||
|
Context: m.db.Statement.Context,
|
||||||
})
|
})
|
||||||
dbSess := m.getDB().WithContext(childCtx)
|
dbSess := m.getDB().WithContext(childCtx)
|
||||||
if err = dbSess.Transaction(func(tx *gorm.DB) (errTx error) {
|
if err = dbSess.Transaction(func(tx *gorm.DB) (errTx error) {
|
||||||
|
@ -691,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",
|
||||||
|
@ -794,6 +801,7 @@ func (m *Model) Export(w http.ResponseWriter, r *http.Request) {
|
||||||
ModuleName: m.naming.ModuleName,
|
ModuleName: m.naming.ModuleName,
|
||||||
TableName: m.naming.TableName,
|
TableName: m.naming.TableName,
|
||||||
Scenario: types.ScenarioExport,
|
Scenario: types.ScenarioExport,
|
||||||
|
Context: m.db.Statement.Context,
|
||||||
})
|
})
|
||||||
if searchSchemas, err = m.schemaLookup(childCtx, m.getDB(), domainName, m.naming.ModuleName, m.naming.TableName, types.ScenarioSearch); err != nil {
|
if searchSchemas, err = m.schemaLookup(childCtx, m.getDB(), domainName, m.naming.ModuleName, m.naming.TableName, types.ScenarioSearch); err != nil {
|
||||||
m.response.Failure(w, types.RequestRecordNotFound, "record not found", nil)
|
m.response.Failure(w, types.RequestRecordNotFound, "record not found", nil)
|
||||||
|
@ -1020,13 +1028,18 @@ func (m *Model) Import(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//这里用background的context
|
//这里用background的context
|
||||||
childCtx := context.WithValue(context.Background(), RuntimeScopeKey, &types.RuntimeScope{
|
pCtx := m.db.Statement.Context
|
||||||
|
if pCtx == nil {
|
||||||
|
pCtx = context.Background()
|
||||||
|
}
|
||||||
|
childCtx := context.WithValue(pCtx, RuntimeScopeKey, &types.RuntimeScope{
|
||||||
Domain: domainName,
|
Domain: domainName,
|
||||||
User: m.valueLookup(types.FieldUser, w, r),
|
User: m.valueLookup(types.FieldUser, w, r),
|
||||||
ModuleName: m.naming.ModuleName,
|
ModuleName: m.naming.ModuleName,
|
||||||
TableName: m.naming.TableName,
|
TableName: m.naming.TableName,
|
||||||
Scenario: types.ScenarioImport,
|
Scenario: types.ScenarioImport,
|
||||||
Schemas: schemas,
|
Schemas: schemas,
|
||||||
|
Context: m.db.Statement.Context,
|
||||||
})
|
})
|
||||||
if r.Method == http.MethodGet {
|
if r.Method == http.MethodGet {
|
||||||
//下载导入模板
|
//下载导入模板
|
||||||
|
|
|
@ -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}
|
||||||
|
}
|
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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":
|
||||||
|
|
16
query.go
16
query.go
|
@ -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
|
||||||
|
|
27
rest.go
27
rest.go
|
@ -673,13 +673,12 @@ func ModelTypes[T any](ctx context.Context, db *gorm.DB, model any, domainName,
|
||||||
} else {
|
} else {
|
||||||
feed.Label = fmt.Sprint(s)
|
feed.Label = fmt.Sprint(s)
|
||||||
}
|
}
|
||||||
continue
|
//这里不直接返回, 有可能key和value是同一个字段
|
||||||
}
|
}
|
||||||
if k == valueColumn {
|
if k == valueColumn {
|
||||||
if p, ok := v.(T); ok {
|
if p, ok := v.(T); ok {
|
||||||
feed.Value = p
|
feed.Value = p
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values = append(values, feed)
|
values = append(values, feed)
|
||||||
|
@ -703,25 +702,23 @@ func ModelTiers[T comparable](ctx context.Context, db *gorm.DB, model any, domai
|
||||||
for _, pairs := range result {
|
for _, pairs := range result {
|
||||||
feed := &types.TierValue[T]{}
|
feed := &types.TierValue[T]{}
|
||||||
for k, v := range pairs {
|
for k, v := range pairs {
|
||||||
|
if k == parentColumn {
|
||||||
|
if p, ok := v.(T); ok {
|
||||||
|
feed.Parent = p
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
if k == labelColumn {
|
if k == labelColumn {
|
||||||
if s, ok := v.(string); ok {
|
if s, ok := v.(string); ok {
|
||||||
feed.Label = s
|
feed.Label = s
|
||||||
} else {
|
} else {
|
||||||
feed.Label = fmt.Sprint(s)
|
feed.Label = fmt.Sprint(s)
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
if k == valueColumn {
|
if k == valueColumn {
|
||||||
if p, ok := v.(T); ok {
|
if p, ok := v.(T); ok {
|
||||||
feed.Value = p
|
feed.Value = p
|
||||||
}
|
}
|
||||||
continue
|
|
||||||
}
|
|
||||||
if k == parentColumn {
|
|
||||||
if p, ok := v.(T); ok {
|
|
||||||
feed.Parent = p
|
|
||||||
}
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values = append(values, feed)
|
values = append(values, feed)
|
||||||
|
@ -847,3 +844,13 @@ func OnAfterExport(cb AfterExport) {
|
||||||
func OnAfterImport(cb AfterImport) {
|
func OnAfterImport(cb AfterImport) {
|
||||||
hookMgr.AfterImport(cb)
|
hookMgr.AfterImport(cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RuntimeScopeFromContext 从上下文中获取运行时作用域
|
||||||
|
func RuntimeScopeFromContext(ctx context.Context) *types.RuntimeScope {
|
||||||
|
if v := ctx.Value(RuntimeScopeKey); v != nil {
|
||||||
|
if scope, ok := v.(*types.RuntimeScope); ok {
|
||||||
|
return scope
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
5
types.go
5
types.go
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,6 +206,7 @@ type (
|
||||||
Schemas []*Schema //字段schema
|
Schemas []*Schema //字段schema
|
||||||
Request *http.Request //HTTP请求结构
|
Request *http.Request //HTTP请求结构
|
||||||
PrimaryKeyValue any //主键
|
PrimaryKeyValue any //主键
|
||||||
|
Context context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
ImportResult struct {
|
ImportResult struct {
|
||||||
|
|
Loading…
Reference in New Issue