From bddd7548695f2b1ea058c323b6ce80e61d5d371d Mon Sep 17 00:00:00 2001 From: what Date: Thu, 9 May 2024 13:15:24 +0800 Subject: [PATCH] =?UTF-8?q?[feat]=20=E9=87=8D=E6=96=B0=E6=A2=B3=E7=90=86?= =?UTF-8?q?=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- base/query_field.go | 32 +++--- base/res_condition.go | 53 +++++++++ base/res_field.go | 84 +++++++-------- base/res_relation.go | 3 +- base/resource.go | 28 ++--- base/user.go | 14 +-- captcha.go | 6 +- controller.go | 5 +- cron.go | 6 +- global_params.go | 55 ---------- go.mod | 13 ++- go.sum | 34 ++++++ http.go | 41 +++---- job.go | 8 +- mqtt.go | 21 ++-- orm.go | 104 ++++-------------- res_listener.go | 25 ++--- resource.go | 109 +------------------ response.go | 10 -- routing.go | 139 ------------------------ support/global_params.go | 228 --------------------------------------- support/list.go | 49 ++++----- support/response.go | 35 +++--- support/util.go | 175 ------------------------------ support/utils_test.go | 46 -------- user.go | 53 --------- user_approval.go | 5 +- ws.go | 35 ++++++ 28 files changed, 341 insertions(+), 1075 deletions(-) delete mode 100644 global_params.go delete mode 100644 response.go delete mode 100644 routing.go delete mode 100644 support/global_params.go delete mode 100644 support/util.go delete mode 100644 support/utils_test.go delete mode 100644 user.go create mode 100644 ws.go diff --git a/base/query_field.go b/base/query_field.go index 46829c9..8d4c3a3 100644 --- a/base/query_field.go +++ b/base/query_field.go @@ -5,16 +5,16 @@ import ( "strings" "unicode" - "git.fsdpf.net/go/contracts" "git.fsdpf.net/go/contracts/res_type" "git.fsdpf.net/go/db" + "git.fsdpf.net/go/req" ) type QueryField struct { ResField - typ contracts.QueryDataType `db:"dataType"` - alias string `db:"alias"` - isExpr bool `db:"isExpr"` + typ req.RouteParamType `db:"dataType"` + alias string `db:"alias"` + isExpr bool `db:"isExpr"` isOmitempty bool ignored bool } @@ -35,20 +35,20 @@ func (this QueryField) IsOmitempty() bool { return this.isOmitempty } -func (this QueryField) Type() contracts.QueryDataType { +func (this QueryField) Type() req.RouteParamType { return this.typ } -func (this *QueryField) SetOptions(options int) contracts.QueryField { - if options&contracts.QueryField_IsExpr != 0 { +func (this *QueryField) SetOptions(options byte) req.QueryField { + if options&req.IsExpr != 0 { this.isExpr = true } - if options&contracts.QueryField_IsOmitempty != 0 { + if options&req.IsOmitempty != 0 { this.isOmitempty = true } - if options&contracts.QueryField_Ignored != 0 { + if options&req.Ignored != 0 { this.ignored = true } @@ -101,19 +101,19 @@ func (this *QueryField) ToStructField(tags ...string) reflect.StructField { } switch this.typ { - case contracts.QueryDataType_String: + case req.ReqString: typ = reflect.TypeOf(string("")) - case contracts.QueryDataType_Number: + case req.ReqNumber: typ = reflect.TypeOf(res_type.ResFieldByNumber(0)) - case contracts.QueryDataType_Integer: + case req.ReqInteger: typ = reflect.TypeOf(res_type.ResFieldByInteger(0)) - case contracts.QueryDataType_Float: + case req.ReqFloat: typ = reflect.TypeOf(res_type.ResFieldByFloat(0)) - case contracts.QueryDataType_Bool: + case req.ReqBool: typ = reflect.TypeOf(true) - case contracts.QueryDataType_Array: + case req.ReqArray: typ = reflect.TypeOf([]any{}) - case contracts.QueryDataType_Json: + case req.ReqJson: typ = reflect.TypeOf(map[string]any{}) } diff --git a/base/res_condition.go b/base/res_condition.go index 4b351d6..255bfe1 100644 --- a/base/res_condition.go +++ b/base/res_condition.go @@ -1,5 +1,7 @@ package base +import "git.fsdpf.net/go/condition" + type ResCondition struct { Id int `db:"id"` Pid int `db:"pid"` @@ -36,3 +38,54 @@ type ResWhereExpr struct { } type GetResConditions func(categoryUuid string) []ResCondition + +// Create Condition By Resource +func NewConditionByRes(items []ResCondition, opts ...condition.Option) (root *condition.Condition) { + conditions := map[int]any{} + + for _, item := range items { + switch item.Type { + case "and": + conditions[item.Id] = condition.New() + case "or": + conditions[item.Id] = condition.New(condition.Type(condition.OR)) + case "expr": + conditions[item.Id] = condition.NewExpr( + item.ColumnResource, item.Column, + condition.Token(item.Value, condition.TokenType(item.ValueType)), + condition.Operator(condition.ConditionOperator(item.Operator)), + condition.FieldSqlFn(item.ColumnSqlFunc, item.ColumnSqlFuncParam), + condition.IgnoreEmptyParma(item.IgnoreEmptyParma), + ) + } + + if item.Pid == 0 && (item.Type == "and" || item.Type == "or") { + root = conditions[item.Id].(*condition.Condition) + } + } + + for _, item := range items { + parent := root + + if item.Pid == 0 { + continue + } else { + parent = conditions[item.Pid].(*condition.Condition) + } + + switch item.Type { + case "and", "or": + parent.SetCondition(conditions[item.Id].(*condition.Condition)) + case "expr": + parent.SetExpr(conditions[item.Id].(*condition.ConditionExpr)) + } + } + + if root == nil { + root = condition.New() + } + + root.SetOption(opts...) + + return root +} diff --git a/base/res_field.go b/base/res_field.go index ddf2ab2..5b8f7a2 100644 --- a/base/res_field.go +++ b/base/res_field.go @@ -7,24 +7,24 @@ import ( "strconv" "strings" - "git.fsdpf.net/go/contracts" "git.fsdpf.net/go/contracts/res_type" "git.fsdpf.net/go/db" "git.fsdpf.net/go/db/schema" + "git.fsdpf.net/go/req" "github.com/google/uuid" "github.com/spf13/cast" ) // 资源字段 type ResField struct { - Uuid string `db:"uuid"` - Name string `db:"name"` - Code string `db:"code"` - CodeResource string `db:"codeResource"` - DataType contracts.ResDataType `db:"table_type"` - Length string `db:"length"` - Comment string `db:"comment"` - Default string `db:"default"` + Uuid string `db:"uuid"` + Name string `db:"name"` + Code string `db:"code"` + CodeResource string `db:"codeResource"` + DataType req.ResDataType `db:"table_type"` + Length string `db:"length"` + Comment string `db:"comment"` + Default string `db:"default"` } func (this ResField) ToStructField(tags ...string) reflect.StructField { @@ -38,16 +38,16 @@ func (this ResField) ToStructField(tags ...string) reflect.StructField { } switch this.DataType { - case contracts.ResDataType_String, contracts.ResDataType_Text, contracts.ResDataType_Enum, - contracts.ResDataType_Timestamp, contracts.ResDataType_Date, contracts.ResDataType_Datetime: + case req.ResString, req.ResText, req.ResEnum, + req.ResTimestamp, req.ResDate, req.ResDatetime: typ = reflect.TypeOf(string("")) - case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger: + case req.ResInteger, req.ResSmallInteger: typ = reflect.TypeOf(res_type.ResFieldByInteger(0)) - case contracts.ResDataType_Decimal: + case req.ResDecimal: typ = reflect.TypeOf(float64(0)) - case contracts.ResDataType_Boolean: + case req.ResBoolean: typ = reflect.TypeOf(true) - case contracts.ResDataType_Json: + case req.ResJson: if this.Default != "" && this.Default[0:1] == "[" { typ = reflect.TypeOf([]any{}) } else { @@ -74,47 +74,47 @@ func (this ResField) GetName() string { return this.Name } -func (this ResField) GetDataType() contracts.ResDataType { +func (this ResField) GetDataType() req.ResDataType { return this.DataType } -func (this ResField) GetQueryDataType() contracts.QueryDataType { +func (this ResField) GetQueryDataType() req.RouteParamType { switch this.GetDataType() { - case contracts.ResDataType_Enum, - contracts.ResDataType_Timestamp, contracts.ResDataType_Date, - contracts.ResDataType_Datetime, contracts.ResDataType_String, - contracts.ResDataType_Text: - return contracts.QueryDataType_String - case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger: - return contracts.QueryDataType_Integer - case contracts.ResDataType_Decimal: - return contracts.QueryDataType_Float - case contracts.ResDataType_Boolean: - return contracts.QueryDataType_Bool - case contracts.ResDataType_Json: + case req.ResEnum, + req.ResTimestamp, req.ResDate, + req.ResDatetime, req.ResString, + req.ResText: + return req.ReqString + case req.ResInteger, req.ResSmallInteger: + return req.ReqInteger + case req.ResDecimal: + return req.ReqFloat + case req.ResBoolean: + return req.ReqBool + case req.ResJson: if this.Default != "" && this.Default[0:1] == "[" { - return contracts.QueryDataType_Array + return req.ReqArray } - return contracts.QueryDataType_Json + return req.ReqJson } - return contracts.QueryDataType_String + return req.ReqString } func (this ResField) ToValue(v any) any { switch this.DataType { - case contracts.ResDataType_String, contracts.ResDataType_Text, contracts.ResDataType_Enum, - contracts.ResDataType_Timestamp, contracts.ResDataType_Date, contracts.ResDataType_Datetime: + case req.ResString, req.ResText, req.ResEnum, + req.ResTimestamp, req.ResDate, req.ResDatetime: return strings.Trim(cast.ToString(v), " ") - case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger: + case req.ResInteger, req.ResSmallInteger: return cast.ToInt(v) - case contracts.ResDataType_Decimal: + case req.ResDecimal: return strings.Trim(cast.ToString(v), " ") - case contracts.ResDataType_Boolean: + case req.ResBoolean: if v, _ := strconv.ParseBool(fmt.Sprintf("%v", v)); v { return 1 } return 0 - case contracts.ResDataType_Json: + case req.ResJson: if v == nil { if this.Default != "" && this.Default[0:1] == "[" { return db.Raw("'[]'") @@ -142,7 +142,7 @@ func (this ResField) ToValue(v any) any { } func (this ResField) GetRawDefault(driver string) db.Expression { - if this.DataType == contracts.ResDataType_Json { + if this.DataType == req.ResJson { if this.Default != "" && this.Default[0:1] == "[" { return db.Raw("'[]'") } else if this.Default != "" && this.Default[0:1] == "{" { @@ -150,7 +150,7 @@ func (this ResField) GetRawDefault(driver string) db.Expression { } else if this.Default == "" { return db.Raw("'{}'") } - } else if this.DataType == contracts.ResDataType_Boolean { + } else if this.DataType == req.ResBoolean { if v, _ := strconv.ParseBool(this.Default); v { return db.Raw("'1'") } @@ -169,7 +169,7 @@ func (this ResField) GetRawDefault(driver string) db.Expression { } if this.Default == "" { - if this.GetDataType() == contracts.ResDataType_Date || this.GetDataType() == contracts.ResDataType_Datetime { + if this.GetDataType() == req.ResDate || this.GetDataType() == req.ResDatetime { return db.Raw("NULL") } return db.Raw("''") @@ -255,7 +255,7 @@ func (this ResField) ToBlueprint(table *schema.Blueprint) (temp *schema.ColumnDe return temp } -func (this ResField) ToQueryField(t contracts.QueryDataType, alias string, options int) contracts.QueryField { +func (this ResField) ToQueryField(t req.RouteParamType, alias string, options byte) req.QueryField { o := &QueryField{ ResField: this, typ: t, diff --git a/base/res_relation.go b/base/res_relation.go index df31f4f..2e7890b 100644 --- a/base/res_relation.go +++ b/base/res_relation.go @@ -2,6 +2,7 @@ package base import ( "git.fsdpf.net/go/contracts" + "git.fsdpf.net/go/req" ) type ResRelation struct { @@ -23,7 +24,7 @@ type GetResRelations func(categoryUuid string) []ResRelation type GetOrmJoinsByResRelations func(root string, items []ResRelation) []contracts.Join // 获取被关联对象的资源 -type GetResRelationResource func(r ResRelation) (contracts.Resource, bool) +type GetResRelationResource func(r ResRelation) (req.Resource, bool) // 资源关联依赖 func GetJoinResDependencies(root string, items []ResRelation) (dependencies []string) { diff --git a/base/resource.go b/base/resource.go index f942cad..684b826 100644 --- a/base/resource.go +++ b/base/resource.go @@ -11,8 +11,8 @@ import ( "github.com/samber/lo" "git.fsdpf.net/go/contracts" - "git.fsdpf.net/go/contracts/support" "git.fsdpf.net/go/db" + "git.fsdpf.net/go/req" ) // 资源变更事件 @@ -29,7 +29,7 @@ type ResChangeEventTopicPayload struct { type ResChangeRecordTopicPayload struct { Type string // insert | delete | update - User contracts.User // 操作用户 + User req.User // 操作用户 Res Resource // 变更资源 Result sql.Result // 执行结果 Old []map[string]any // 旧数据 @@ -92,7 +92,7 @@ func (this Resource) IsSystem() bool { } // 资源字段 -func (this Resource) GetFields() (result []contracts.ResField) { +func (this Resource) GetFields() (result []req.ResField) { for _, item := range this.Fields { result = append(result, item) } @@ -100,15 +100,15 @@ func (this Resource) GetFields() (result []contracts.ResField) { } // 资源字段 -func (this Resource) GetField(code string) (contracts.ResField, bool) { - return lo.Find(this.GetFields(), func(v contracts.ResField) bool { +func (this Resource) GetField(code string) (req.ResField, bool) { + return lo.Find(this.GetFields(), func(v req.ResField) bool { return v.GetCode() == code }) } // 判断资源字段 func (this Resource) HasField(code string) bool { - return lo.SomeBy(this.GetFields(), func(v contracts.ResField) bool { + return lo.SomeBy(this.GetFields(), func(v req.ResField) bool { return v.GetCode() == code }) } @@ -147,7 +147,7 @@ func (this Resource) GetDBDriver() string { return this.GetDBConn().GetConfig().Driver } -func (this Resource) GetAuthDBTable(u contracts.User, params ...any) *db.Builder { +func (this Resource) GetAuthDBTable(u req.User, params ...any) *db.Builder { builder := this.GetDBTable(append(params, u)...) // 数据权限过滤 @@ -164,7 +164,7 @@ func (this Resource) GetAuthDBTable(u contracts.User, params ...any) *db.Builder func (this Resource) GetDBTable(params ...any) *db.Builder { builder := this.GetDBBuilder() - var user contracts.User + var user req.User alias := this.Code for _, param := range params { @@ -173,7 +173,7 @@ func (this Resource) GetDBTable(params ...any) *db.Builder { builder.Tx = v case string: alias = v - case contracts.User: + case req.User: user = v } } @@ -213,7 +213,7 @@ func (this Resource) GetDBTable(params ...any) *db.Builder { return builder.Table(string(this.GetTable()), alias) } -func (this Resource) WithRolesCondition(b *db.Builder, t string, u contracts.User) error { +func (this Resource) WithRolesCondition(b *db.Builder, t string, u req.User) error { isFullRight := false isFullNot := false @@ -268,7 +268,7 @@ func (this Resource) WithRolesCondition(b *db.Builder, t string, u contracts.Use return db.ToSql() } else if conditions.IsNotEmpty() { oOrm := NewOrm(this, nil) - oOrm.SetGlobalParams(support.NewGlobalParam("{}", u)) + oOrm.SetGlobalParams(req.NewGlobalParam("{}", u)) db.Where(conditions.ToSql(oOrm.GetModel())) @@ -322,7 +322,7 @@ func (this Resource) formatSaveValue(data map[string]any) { } // 填充保存数据 -func (this Resource) fillSaveValue(data map[string]any, u contracts.User, t string) { +func (this Resource) fillSaveValue(data map[string]any, u req.User, t string) { for _, field := range this.GetFields() { fCode := field.GetCode() @@ -401,7 +401,7 @@ func (this Resource) onResEvent(builder *db.Builder) { } // 用户事件 -func (this Resource) onUserEvent(builder *db.Builder, user contracts.User) { +func (this Resource) onUserEvent(builder *db.Builder, user req.User) { old := []map[string]any{} builder.Before(func(b *db.Builder, t string, data ...map[string]any) { @@ -439,7 +439,7 @@ func (this Resource) onUserEvent(builder *db.Builder, user contracts.User) { }) } -func NewVirtualResource(pRes Resource, code, name, sql string, fields []ResField) contracts.Resource { +func NewVirtualResource(pRes Resource, code, name, sql string, fields []ResField) req.Resource { return &Resource{ Uuid: code, PUuid: pRes.Uuid, diff --git a/base/user.go b/base/user.go index 7f2113e..50d55af 100644 --- a/base/user.go +++ b/base/user.go @@ -3,7 +3,7 @@ package base import ( "github.com/samber/lo" - "git.fsdpf.net/go/contracts" + "git.fsdpf.net/go/req" ) type user struct { @@ -12,7 +12,7 @@ type user struct { username string nickname string roles []string - runtime contracts.UserRuntime + runtime req.UserRuntime } func (this user) ID() int64 { @@ -47,19 +47,19 @@ func (this user) IsAnonymous() bool { return this.id == 0 } -func (this user) Runtime() contracts.UserRuntime { +func (this user) Runtime() req.UserRuntime { return this.runtime } // 获取匿名用户 -func GetAnonymous(opts ...contracts.UserRuntimeOption) contracts.User { +func GetAnonymous(opts ...req.UserRuntimeOption) req.User { u := user{ id: 0, uuid: "00000000-0000-0000-0000-000000000000", username: "anonymous", nickname: "匿名者", roles: []string{"00000000-0000-0000-0000-000000000000"}, - runtime: contracts.UserRuntime{}, + runtime: req.UserRuntime{}, } for _, opt := range opts { @@ -70,14 +70,14 @@ func GetAnonymous(opts ...contracts.UserRuntimeOption) contracts.User { } // 系统用户 -func GetSystemUser(opts ...contracts.UserRuntimeOption) contracts.User { +func GetSystemUser(opts ...req.UserRuntimeOption) req.User { u := user{ id: -1, uuid: "ffffffff-ffff-ffff-ffff-ffffffffffff", username: "system", nickname: "系统", roles: []string{"ffffffff-ffff-ffff-ffff-ffffffffffff"}, - runtime: contracts.UserRuntime{}, + runtime: req.UserRuntime{}, } for _, opt := range opts { diff --git a/captcha.go b/captcha.go index 0787e05..f5ebbc9 100644 --- a/captcha.go +++ b/captcha.go @@ -1,7 +1,9 @@ package contracts +import "git.fsdpf.net/go/req" + type Captcha interface { - RouteMiddleware + req.RouteMiddleware Verify(answer string, clear bool) error - Generate(captchaUuid, recipient, ip string, u User) (body string, id int64, err error) + Generate(captchaUuid, recipient, ip string, u req.User) (body string, id int64, err error) } diff --git a/controller.go b/controller.go index a1a401f..910bfa2 100644 --- a/controller.go +++ b/controller.go @@ -1,6 +1,7 @@ package contracts import ( + "git.fsdpf.net/go/req" "github.com/samber/do" ) @@ -10,7 +11,7 @@ type Controller interface { // 获取 Container Container() *do.Injector // 派遣一个任务 - Dispatch(job string, payload any, u User) error + Dispatch(job string, payload any, u req.User) error } type BaseController struct { @@ -25,7 +26,7 @@ func (BaseController) Init() error { return nil } -func (this BaseController) Dispatch(job string, payload any, u User) error { +func (this BaseController) Dispatch(job string, payload any, u req.User) error { return do.MustInvoke[JobService](this.Container()).Dispatch(job, payload, u) } diff --git a/cron.go b/cron.go index 9e373f6..4315fd3 100644 --- a/cron.go +++ b/cron.go @@ -1,5 +1,7 @@ package contracts +import "git.fsdpf.net/go/req" + type CronService interface { Start() error Stop() error @@ -9,13 +11,13 @@ type CronService interface { type Cron interface { Controller // 任务处理 - Run(User) error + Run(req.User) error } type CronBase struct { Controller } -func (CronBase) Run(User) error { +func (CronBase) Run(req.User) error { return nil } diff --git a/global_params.go b/global_params.go deleted file mode 100644 index a67d01d..0000000 --- a/global_params.go +++ /dev/null @@ -1,55 +0,0 @@ -package contracts - -import ( - "time" -) - -type GlobalParams interface { - User() User - // 获取路径内容 - Get(p string) GlobalParams - // 路径包裹 - Wrapped(p string) GlobalParams - // 追加到新 json - AppendTo(root, p string) GlobalParams - // 通过路径设置参数 - Set(p string, v any) bool - // 通过路径设置原始参数 - SetRaw(p string, v string) bool - // 删除路径参数 - Delete(p string) bool - // 获取原始JOSN字符串 - Raw() string - // 转数组 GlobalParams - Array() []GlobalParams - // 判断内容是否存在 - Exists() bool - - Value() any - Bool() bool - Time() time.Time - TimeInDefaultLocation(l *time.Location) time.Time - Float64() float64 - Float32() float32 - Int64() int64 - Int32() int32 - Int16() int16 - Int8() int8 - Int() int - Uint() uint - Uint64() uint64 - Uint32() uint32 - Uint16() uint16 - Uint8() uint8 - String() string - StringMapString() map[string]string - StringMapStringSlice() map[string][]string - StringMapBool() map[string]bool - StringMapInt() map[string]int - StringMapInt64() map[string]int64 - StringMap() map[string]any - Slice() []any - BoolSlice() []bool - StringSlice() []string - IntSlice() []int -} diff --git a/go.mod b/go.mod index 96afcb7..1c19bdc 100644 --- a/go.mod +++ b/go.mod @@ -3,23 +3,26 @@ module git.fsdpf.net/go/contracts go 1.21 require ( - git.fsdpf.net/go/db v0.0.0-20230621051209-5740d112407f - github.com/go-chi/chi/v5 v5.0.10 + git.fsdpf.net/go/condition v0.0.0-20240509034445-afc243ea916e + git.fsdpf.net/go/db v0.0.0-20230731125324-11651ea6640b + github.com/go-chi/chi/v5 v5.0.12 github.com/golang/protobuf v1.5.2 github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.5.0 github.com/jhump/protoreflect v1.15.1 github.com/lestrrat-go/jwx v1.2.25 github.com/samber/do v1.6.0 - github.com/samber/lo v1.38.1 - github.com/spf13/cast v1.5.0 + github.com/samber/lo v1.39.0 + github.com/spf13/cast v1.6.0 github.com/spf13/viper v1.15.0 - github.com/tidwall/gjson v1.14.4 + github.com/tidwall/gjson v1.17.1 github.com/tidwall/sjson v1.2.5 google.golang.org/grpc v1.52.0 ) require ( + git.fsdpf.net/go/req v0.0.0-20240509034400-4ef8c130a758 // indirect + git.fsdpf.net/go/utils v0.0.0-20240509025914-c03a9cb48aff // indirect github.com/bufbuild/protocompile v0.4.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect diff --git a/go.sum b/go.sum index 532189d..26e2b21 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,34 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +git.fsdpf.net/go/condition v0.0.0-20240509022115-37018837d1b0 h1:MHjkN+zrSCqb7Qswn9fFrHT4XaoDnGbXz0ssSKnWnQk= +git.fsdpf.net/go/condition v0.0.0-20240509022115-37018837d1b0/go.mod h1:Zj9yrMa/A3WICTc9zn3W55ociuoBompEsVPo6EUXW5Q= +git.fsdpf.net/go/condition v0.0.0-20240509023514-a871ccfa75ac h1:pJQ0sFjPtv/RCy8k0mC/Kpn/j6As5bSqXyG0MWaylhc= +git.fsdpf.net/go/condition v0.0.0-20240509023514-a871ccfa75ac/go.mod h1:Zj9yrMa/A3WICTc9zn3W55ociuoBompEsVPo6EUXW5Q= +git.fsdpf.net/go/condition v0.0.0-20240509024751-9694d9033266 h1:s5On5PKF1ZiIGgq6R2Nk/2GcURuZxDAVK1Sru54Ybn0= +git.fsdpf.net/go/condition v0.0.0-20240509024751-9694d9033266/go.mod h1:Zj9yrMa/A3WICTc9zn3W55ociuoBompEsVPo6EUXW5Q= +git.fsdpf.net/go/condition v0.0.0-20240509030058-b0e337133e44 h1:XHJxWJuofEL7TLMDBsywi48nciaon8bEFOJLMYkOrNk= +git.fsdpf.net/go/condition v0.0.0-20240509030058-b0e337133e44/go.mod h1:xgX0fc3LEgrPk9tihGQqoQND4EWlNgYbLCi70TuCvvM= +git.fsdpf.net/go/condition v0.0.0-20240509034445-afc243ea916e h1:ZfwjqZS5URF4Y0JfQeytSdmXimJ4l74ooWRppza+3Tk= +git.fsdpf.net/go/condition v0.0.0-20240509034445-afc243ea916e/go.mod h1:K5ocyKVxgC5mI1k/crgrEozK0r51qAavWg0hweXo6PU= git.fsdpf.net/go/db v0.0.0-20230621051209-5740d112407f h1:H+/H6j+hyFMgSy+tUNmymRy7/PWQRjjp8qY/DrhwrsY= git.fsdpf.net/go/db v0.0.0-20230621051209-5740d112407f/go.mod h1:397Sdx1cJS0OlHtTX1bVl//9k3Xn0Klnc6jC4MAkb6w= +git.fsdpf.net/go/db v0.0.0-20230731125324-11651ea6640b h1:fRgWNOQ9dAYuUZHQ24oi1XqRbJIcJvZGbnQDaAKI7IY= +git.fsdpf.net/go/db v0.0.0-20230731125324-11651ea6640b/go.mod h1:397Sdx1cJS0OlHtTX1bVl//9k3Xn0Klnc6jC4MAkb6w= +git.fsdpf.net/go/req v0.0.0-20240508133526-672fc634ef20 h1:PhjRtac2r0Vn1WBBzhRhz4//bJhHgkf/SHZe3mQYPto= +git.fsdpf.net/go/req v0.0.0-20240508133526-672fc634ef20/go.mod h1:S+p7t3XclKxsvaXQng7AMmqEGq11FSnMzxOtv1z8JUw= +git.fsdpf.net/go/req v0.0.0-20240509031332-f00b993f9c7d h1:TKNhQWDKyL50eVC/ptur1YuRkjRnKOlMsE1Y9tFCVbk= +git.fsdpf.net/go/req v0.0.0-20240509031332-f00b993f9c7d/go.mod h1:S+p7t3XclKxsvaXQng7AMmqEGq11FSnMzxOtv1z8JUw= +git.fsdpf.net/go/req v0.0.0-20240509031626-6501b5ed0f2b h1:KlVBAuWnFt1lcRTCcBU165MIldJqleO/LahWrd3FvUA= +git.fsdpf.net/go/req v0.0.0-20240509031626-6501b5ed0f2b/go.mod h1:S+p7t3XclKxsvaXQng7AMmqEGq11FSnMzxOtv1z8JUw= +git.fsdpf.net/go/req v0.0.0-20240509033523-c8cda2d8db56 h1:7ElgXUzt75brzOr44mItipTQTk++kZNoGOyTWHLxkTU= +git.fsdpf.net/go/req v0.0.0-20240509033523-c8cda2d8db56/go.mod h1:S+p7t3XclKxsvaXQng7AMmqEGq11FSnMzxOtv1z8JUw= +git.fsdpf.net/go/req v0.0.0-20240509033936-f8a11598db60 h1:hHrEcUSbtajC2LAo2fvEo7yrSSDeM/s5FAuQluP7yZQ= +git.fsdpf.net/go/req v0.0.0-20240509033936-f8a11598db60/go.mod h1:S+p7t3XclKxsvaXQng7AMmqEGq11FSnMzxOtv1z8JUw= +git.fsdpf.net/go/req v0.0.0-20240509034400-4ef8c130a758 h1:nHys8Bwb29b/FvnE100KVH62aD2j5CEPxTQ/RRHo27k= +git.fsdpf.net/go/req v0.0.0-20240509034400-4ef8c130a758/go.mod h1:S+p7t3XclKxsvaXQng7AMmqEGq11FSnMzxOtv1z8JUw= +git.fsdpf.net/go/utils v0.0.0-20240509025914-c03a9cb48aff h1:1hokQGKGIstoI7WDBir2N24OGgnussZ3GmucK4TQRuI= +git.fsdpf.net/go/utils v0.0.0-20240509025914-c03a9cb48aff/go.mod h1:NUoyQtFr905YT+pi850mvSf4YX0WghQIcMQkTvize5o= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= @@ -67,6 +93,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/chi/v5 v5.0.12 h1:9euLV5sTrTNTRUU9POmDUvfxyj6LAABLUcEWO+JJb4s= +github.com/go-chi/chi/v5 v5.0.12/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -186,10 +214,14 @@ github.com/samber/do v1.6.0 h1:Jy/N++BXINDB6lAx5wBlbpHlUdl0FKpLWgGEV9YWqaU= github.com/samber/do v1.6.0/go.mod h1:DWqBvumy8dyb2vEnYZE7D7zaVEB64J45B0NjTlY/M4k= github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= +github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -213,6 +245,8 @@ github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNG github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= diff --git a/http.go b/http.go index 05401a0..5bb8ff6 100644 --- a/http.go +++ b/http.go @@ -3,6 +3,7 @@ package contracts import ( "net/http" + "git.fsdpf.net/go/req" "github.com/samber/do" ) @@ -19,36 +20,36 @@ type HttpController interface { Controller // 获取用户信息 - User() User + User() req.User // 获取请求信息 Request() *http.Request // 请求处理 - Execute(GlobalParams) any + Execute(req.GlobalParams) any // 路由信息 - Route() Route + Route() req.Route // 内部调用 - Call(code string, params map[string]any, category ...RouteCategory) (HttpResponse, error) + Call(code string, params map[string]any, category ...req.RouteCategory) (req.HttpResponse, error) // 内部调用 // Invoke() // 数据库权限 - AuthDB() ResAuthDB + AuthDB() req.ResAuthDB } type WsController interface { HttpController // 请求处理 - ExecuteWS(GlobalParams) error + ExecuteWS(req.GlobalParams) error // 获取 Ws 客户端 WsClient() WsClient // 获取 Ws 标识 - WsClientId(GlobalParams) WsClientID + WsClientId(req.GlobalParams) WsClientID // 获取 Ws 分组 - WsClientGroup(GlobalParams) WsClientGroup + WsClientGroup(req.GlobalParams) WsClientGroup } type HttpHandleController struct { @@ -65,27 +66,27 @@ func (this HttpHandleController) Request() *http.Request { return this.request } -func (this HttpHandleController) Route() Route { - return this.Request().Context().Value(RouteCtx{Name: "Route"}).(Route) +func (this HttpHandleController) Route() req.Route { + return this.Request().Context().Value(req.RouteCtx{Name: "Route"}).(req.Route) } -func (this HttpHandleController) User() User { - return this.Request().Context().Value(RouteCtx{Name: "User"}).(User) +func (this HttpHandleController) User() req.User { + return this.Request().Context().Value(req.RouteCtx{Name: "User"}).(req.User) } -func (this HttpHandleController) Call(code string, params map[string]any, category ...RouteCategory) (HttpResponse, error) { - return do.MustInvoke[Router](this.Container()).Call(this.Request(), code, params, category...) +func (this HttpHandleController) Call(code string, params map[string]any, category ...req.RouteCategory) (req.HttpResponse, error) { + return do.MustInvoke[req.Router](this.Container()).Call(this.Request(), code, params, category...) } -func (HttpHandleController) Execute(params GlobalParams) any { +func (HttpHandleController) Execute(params req.GlobalParams) any { return nil } -func (HttpHandleController) AuthDB() ResAuthDB { - return ResAuthOn +func (HttpHandleController) AuthDB() req.ResAuthDB { + return req.ResAuthOn } -func (WsHandleController) ExecuteWS(params GlobalParams) error { +func (WsHandleController) ExecuteWS(params req.GlobalParams) error { return nil } @@ -93,12 +94,12 @@ func (this WsHandleController) WsClient() WsClient { return this.ws } -func (WsHandleController) WsClientId(GlobalParams) WsClientID { +func (WsHandleController) WsClientId(req.GlobalParams) WsClientID { wsClientID++ return wsClientID } -func (WsHandleController) WsClientGroup(GlobalParams) WsClientGroup { +func (WsHandleController) WsClientGroup(req.GlobalParams) WsClientGroup { return defaultWsClientGroup } diff --git a/job.go b/job.go index 83e5352..0443c02 100644 --- a/job.go +++ b/job.go @@ -1,22 +1,24 @@ package contracts +import "git.fsdpf.net/go/req" + type JobService interface { Start() error Stop() error Restart() error - Dispatch(job string, payload any, u User) error + Dispatch(job string, payload any, u req.User) error } type Job interface { Controller // 任务处理 - Handle(any, User) error + Handle(any, req.User) error } type JobBase struct { Controller } -func (JobBase) Handle(any, User) error { +func (JobBase) Handle(any, req.User) error { return nil } diff --git a/mqtt.go b/mqtt.go index 456e282..876f75e 100644 --- a/mqtt.go +++ b/mqtt.go @@ -1,6 +1,7 @@ package contracts import ( + "git.fsdpf.net/go/req" "github.com/samber/do" ) @@ -36,15 +37,15 @@ type Mqtt interface { // 断开链接 // OnDisconnect(g GlobalParams, topic string) error // 订阅事件 - OnSubscribed(g GlobalParams, topic string) error + OnSubscribed(g req.GlobalParams, topic string) error // 取消订阅事件 - OnUnsubscribed(g GlobalParams, topic string) error + OnUnsubscribed(g req.GlobalParams, topic string) error // 消息发布事件 - OnMessage(g GlobalParams, topic string, retain bool, qos byte) error + OnMessage(g req.GlobalParams, topic string, retain bool, qos byte) error // 消息被丢弃 - OnMessageDropped(g GlobalParams, topic string, retain bool, qos byte) error + OnMessageDropped(g req.GlobalParams, topic string, retain bool, qos byte) error // 原生消息修改 - OnPublish(g GlobalParams, topic string, retain bool, qos byte, raw []byte) ([]byte, error) + OnPublish(g req.GlobalParams, topic string, retain bool, qos byte, raw []byte) ([]byte, error) // 保留类型消息事件 // OnRetainMessage(g GlobalParams, topic string) error // Qos消息完成事件 @@ -59,23 +60,23 @@ type MqttHandle struct { Controller } -func (this *MqttHandle) OnSubscribed(g GlobalParams, topic string) error { +func (this *MqttHandle) OnSubscribed(g req.GlobalParams, topic string) error { return ErrFuncNotImplemented } -func (this MqttHandle) OnUnsubscribed(g GlobalParams, topic string) error { +func (this MqttHandle) OnUnsubscribed(g req.GlobalParams, topic string) error { return ErrFuncNotImplemented } -func (this MqttHandle) OnMessage(g GlobalParams, topic string, retain bool, qos byte) error { +func (this MqttHandle) OnMessage(g req.GlobalParams, topic string, retain bool, qos byte) error { return ErrFuncNotImplemented } -func (this MqttHandle) OnMessageDropped(g GlobalParams, topic string, retain bool, qos byte) error { +func (this MqttHandle) OnMessageDropped(g req.GlobalParams, topic string, retain bool, qos byte) error { return ErrFuncNotImplemented } -func (this MqttHandle) OnPublish(g GlobalParams, topic string, retain bool, qos byte, raw []byte) ([]byte, error) { +func (this MqttHandle) OnPublish(g req.GlobalParams, topic string, retain bool, qos byte, raw []byte) ([]byte, error) { return nil, ErrFuncNotImplemented } diff --git a/orm.go b/orm.go index 8dc56f7..7a30a6a 100644 --- a/orm.go +++ b/orm.go @@ -3,7 +3,9 @@ package contracts import ( "reflect" + "git.fsdpf.net/go/condition" "git.fsdpf.net/go/db" + "git.fsdpf.net/go/req" ) type OrmExecute int @@ -30,47 +32,18 @@ const ( RelationType_Right RelationType = "right" ) -const ( - ConditionType_OR ConditionType = "OR" - ConditionType_AND ConditionType = "AND" -) - -const ( - ConditionTokenType_SQL ConditionTokenType = "sql" - ConditionTokenType_FUNC ConditionTokenType = "func" - ConditionTokenType_PARAM ConditionTokenType = "param" - ConditionTokenType_STRING ConditionTokenType = "string" -) - -const ( - ConditionOperator_IS_NULL ConditionOperator = "IS NULL" - ConditionOperator_IS_NOT_NULL ConditionOperator = "IS NOT NULL" - ConditionOperator_EQ ConditionOperator = "=" - ConditionOperator_NE ConditionOperator = "!=" - ConditionOperator_GT ConditionOperator = ">" - ConditionOperator_GE ConditionOperator = ">=" - ConditionOperator_LT ConditionOperator = "<" - ConditionOperator_LE ConditionOperator = "<=" - ConditionOperator_LIKE ConditionOperator = "LIKE" - ConditionOperator_NOT_LIKE ConditionOperator = "NOT LIKE" - ConditionOperator_IN ConditionOperator = "IN" - ConditionOperator_NOT_IN ConditionOperator = "NOT IN" - ConditionOperator_REGEXP ConditionOperator = "REGEXP" - ConditionOperator_NOT_REGEXP ConditionOperator = "NOT REGEXP" -) - const ( OrderByDirection_ASC OrderByDirection = db.ORDER_ASC OrderByDirection_DESC OrderByDirection = db.ORDER_DESC ) type Orm interface { - SetGlobalParams(g GlobalParams) Orm + SetGlobalParams(g req.GlobalParams) Orm GetModel(params ...string) Model SetRelationModel(m Model) Model - SetQueryField(qf QueryField) error + SetQueryField(qf req.QueryField) error SetOrderBy(params []OrderBy) error - SetCondition(cond Condition) error + SetCondition(cond *condition.Condition) error SetController(ctr OrmController) error Execute(OrmExecute) (any, error) Clone(tx *db.Transaction) Orm @@ -83,9 +56,9 @@ type Relation interface { AppendTo(Model) Type() RelationType SetType(RelationType) - SetCondition(Condition) Condition - SetPrependCondition(Condition) Condition - GetCondition() Condition + SetCondition(*condition.Condition) *condition.Condition + SetPrependCondition(*condition.Condition) *condition.Condition + GetCondition() *condition.Condition GetRelationResource() string GetRelationField() string GetRelationForeignKey() string @@ -94,26 +67,26 @@ type Relation interface { type Join interface { Relation GetCode() string - GetResource() Resource + GetResource() req.Resource // GetDependencies(items []ResRelation, dependencies ...string) []string Inject(dbBuilder *db.Builder, m Model) } type Model interface { Relation - ModelParam + condition.TokenValue GetCode() string GetPrimaryKey() string GetQueryFieldsStruct(extends ...reflect.StructField) any GetQueryFieldsSliceStruct(fields ...reflect.StructField) any GetAttribute() map[string]any GetResult() reflect.Value - GetResource() Resource + GetResource() req.Resource QueryBuilder() *db.Builder GetTransaction() *db.Transaction - SetQueryField(QueryField) + SetQueryField(req.QueryField) SetRelationResult(code string, vItems reflect.Value) GetJoinsCode() []string - SetAuthDB(ResAuthDB) + SetAuthDB(req.ResAuthDB) SetOrderBy(params ...OrderBy) Model SetGroupBy(params ...GroupBy) Model SetJoin(Join) Model @@ -130,43 +103,8 @@ type Model interface { // Exists() (bool, error) } -type ModelParam interface { - GetParam(k string) GlobalParams - GetGlobalParamsUser() User -} - type OrmController interface { - AuthDB() ResAuthDB -} - -type Condition interface { - Type() ConditionType - IsEmpty() bool - IsNotEmpty() bool - IsAlwaysRight() bool - ToSql(ModelParam) db.Expression - AppendTo(Condition) - SetExpr(ConditionExpr) Condition - SetCondition(Condition) Condition - SetMatchPrefix(string) Condition - GetFields(operator ConditionOperator, types ...ConditionTokenType) map[string]string - GetFieldsValue(m ModelParam, isWithResource bool) map[string]any -} - -type ConditionExpr interface { - GetField() string - GetFieldResource() string - GetOperator() ConditionOperator - - SetMatchPrefix(string) ConditionExpr - - AppendTo(Condition) - ToSql(m ModelParam) db.Expression - GetTokenName() string - GetTokenType() ConditionTokenType - GetTokenValue(ModelParam) any - GetTokenSqlValue(ModelParam) string - IsIgnoreEmptyParma(ModelParam) bool + AuthDB() req.ResAuthDB } type OrderBy interface { @@ -192,13 +130,13 @@ type QueryWithRecursive interface { // @param rForeignKey 关联外键, 如 id type NewOrmRelation func(t RelationType, m Model, rResource, rField, rForeignKey string) Model -type NewOrmJoin func(t RelationType, res Resource, alias, rResource, rField, rForeignKey string) Join +type NewOrmJoin func(t RelationType, res req.Resource, alias, rResource, rField, rForeignKey string) Join -type NewOrmCondition func(typ ConditionType, describe string) Condition +type NewOrmCondition func(typ ConditionType, describe string) *condition.Condition -type NewOrmConditionExpr func(rResource, rField, token string, operator ConditionOperator, tType ConditionTokenType, ignoreEmptyParma bool) ConditionExpr +type NewOrmConditionExpr func(rResource, rField, token string, operator ConditionOperator, tType ConditionTokenType, ignoreEmptyParma bool) *condition.ConditionExpr -type NewOrmConditionFuncExpr func(rResource, rField, token string, operator ConditionOperator, tType ConditionTokenType, ignoreEmptyParma bool, fn, fnParam string) ConditionExpr +type NewOrmConditionFuncExpr func(rResource, rField, token string, operator ConditionOperator, tType ConditionTokenType, ignoreEmptyParma bool, fn, fnParam string) *condition.ConditionExpr type NewOrmQueryWithRecursive func(pField, cField string, root any, isWithoutCondition bool, depth int) QueryWithRecursive @@ -206,8 +144,8 @@ type NewOrmOrderBy func(sql string, direction OrderByDirection) OrderBy type NewOrmGroupBy func(sql string) GroupBy -type NewOrmModel func(res Resource, code, name string) Model +type NewOrmModel func(res req.Resource, code, name string) Model -type NewOrm func(res Resource, tx *db.Transaction) Orm +type NewOrm func(res req.Resource, tx *db.Transaction) Orm -type GetOrmConditionByRes func(categoryUuid string, describe string) Condition +type GetOrmConditionByRes func(categoryUuid string, describe string) *condition.Condition diff --git a/res_listener.go b/res_listener.go index b3d84fb..1fab6a8 100644 --- a/res_listener.go +++ b/res_listener.go @@ -1,6 +1,7 @@ package contracts import ( + "git.fsdpf.net/go/req" "github.com/samber/do" "github.com/samber/lo" ) @@ -8,25 +9,25 @@ import ( type ResEvent string type ResListener interface { - Insert(new map[string]any, u User, id int64) error - Update(new map[string]any, u User, old map[string]any) error - Delete(old map[string]any, u User) error - GetResource() Resource + Insert(new map[string]any, u req.User, id int64) error + Update(new map[string]any, u req.User, old map[string]any) error + Delete(old map[string]any, u req.User) error + GetResource() req.Resource GetCode() string } type BaseListener struct { Container *do.Injector - res Resource // 监听资源 - code string // code - events []string // 监听动作 + res req.Resource // 监听资源 + code string // code + events []string // 监听动作 } func (this BaseListener) GetCode() string { return this.code } -func (this BaseListener) GetResource() Resource { +func (this BaseListener) GetResource() req.Resource { return this.res } @@ -34,18 +35,18 @@ func (this BaseListener) HasEvent(event string) bool { return lo.Contains(this.events, event) } -func (BaseListener) Insert(new map[string]any, u User, id int64) error { +func (BaseListener) Insert(new map[string]any, u req.User, id int64) error { return nil } -func (BaseListener) Update(new map[string]any, u User, old map[string]any) error { +func (BaseListener) Update(new map[string]any, u req.User, old map[string]any) error { return nil } -func (BaseListener) Delete(old map[string]any, u User) error { +func (BaseListener) Delete(old map[string]any, u req.User) error { return nil } -func NewBaseListener(code string, res Resource, container *do.Injector) *BaseListener { +func NewBaseListener(code string, res req.Resource, container *do.Injector) *BaseListener { return &BaseListener{code: code, res: res, Container: container} } diff --git a/resource.go b/resource.go index 22ef835..cb10ade 100644 --- a/resource.go +++ b/resource.go @@ -1,111 +1,6 @@ package contracts -import ( - "reflect" - - "git.fsdpf.net/go/db" - "git.fsdpf.net/go/db/schema" -) - -type ResDataType string -type ResConditionType string -type ResConditionTokenType string -type ResConditionOperator string -type ResAuthDB int - -type QueryDataType string - -const ( - // 关闭权限过滤 - ResAuthOff ResAuthDB = iota - // 开启权限过滤, 不包括关联资源 - ResAuthOn - // 开启权限过滤, 包括关联资源 - ResAuthAll -) - -const ( - ResDataType_String ResDataType = "string" - ResDataType_Text ResDataType = "text" - ResDataType_Integer ResDataType = "integer" - ResDataType_SmallInteger ResDataType = "smallInteger" - ResDataType_Decimal ResDataType = "decimal" - ResDataType_Boolean ResDataType = "boolean" - ResDataType_Json ResDataType = "json" - ResDataType_Enum ResDataType = "enum" - ResDataType_Timestamp ResDataType = "timestamp" - ResDataType_Date ResDataType = "date" - ResDataType_Datetime ResDataType = "dateTime" -) - -const ( - QueryDataType_Number QueryDataType = "number" - QueryDataType_Integer QueryDataType = "integer" - QueryDataType_Float QueryDataType = "float" - QueryDataType_String QueryDataType = "string" - QueryDataType_Bool QueryDataType = "bool" - QueryDataType_Array QueryDataType = "array" - QueryDataType_Json QueryDataType = "json" -) - -const ( - QueryField_IsExpr = 1 << iota - QueryField_IsOmitempty - QueryField_Ignored -) - -type Resource interface { - GetUuid() string - GetName() string - GetCode() string - GetPrimarykey() string - GetFields() []ResField - GetField(string) (ResField, bool) - HasField(string) bool - - BeginTransaction() (*db.Transaction, error) - - GetTable() db.Expression - GetDBConn() *db.Connection - GetDBBuilder() *db.Builder - GetDBTable(params ...any) *db.Builder - GetAuthDBTable(u User, params ...any) *db.Builder - GetStruct(extends ...reflect.StructField) any - GetSliceStruct(extends ...reflect.StructField) any - - WithRolesCondition(b *db.Builder, t string, u User) error - - // 是否虚拟资源 - IsVirtual() bool - // 是否系统资源 - IsSystem() bool -} - -type ResField interface { - GetName() string - GetCode() string - GetCodeResource() string - GetDataType() ResDataType - GetQueryDataType() QueryDataType - GetRawDefault(driver string) db.Expression - ToStructField(tags ...string) reflect.StructField - ToValue(any) any - ToBlueprint(table *schema.Blueprint) *schema.ColumnDefinition - ToQueryField(t QueryDataType, alias string, options int) QueryField -} - -type QueryField interface { - ResField - Type() QueryDataType - Alias() string - GetCodeOrAlias() string - IsExpr() bool - IsOmitempty() bool - Ignored() bool - SetOptions(int) QueryField - ToSql() db.Expression - ToStructField(tags ...string) reflect.StructField -} +import "git.fsdpf.net/go/req" // 资源 -type GetResource func(code string) (Resource, bool) +type GetResource func(code string) (req.Resource, bool) diff --git a/response.go b/response.go deleted file mode 100644 index 4750f22..0000000 --- a/response.go +++ /dev/null @@ -1,10 +0,0 @@ -package contracts - -import ( - "net/http" -) - -type HttpResponse interface { - Get(path ...string) GlobalParams - Send(w http.ResponseWriter, r *http.Request) -} diff --git a/routing.go b/routing.go deleted file mode 100644 index 2326363..0000000 --- a/routing.go +++ /dev/null @@ -1,139 +0,0 @@ -package contracts - -import ( - "net/http" - - "github.com/go-chi/chi/v5" - "github.com/gorilla/websocket" -) - -type RouteMethod string -type RouteCategory string -type RouteService string -type RouteParamType string -type RouteParamCategory string - -type RouteCtx struct { - Name string -} - -const ( - RouteMethod_GET RouteMethod = "GET" - RouteMethod_POST RouteMethod = "POST" - RouteMethod_PUT RouteMethod = "PUT" - RouteMethod_DELETE RouteMethod = "DELETE" -) - -const ( - RouteCategory_WS RouteCategory = "ws" - RouteCategory_GRPC RouteCategory = "grpc" - RouteCategory_FUNC RouteCategory = "func" - RouteCategory_SHOW RouteCategory = "show" - RouteCategory_QUERY RouteCategory = "query" - RouteCategory_STORE RouteCategory = "store" - RouteCategory_DESTROY RouteCategory = "destroy" - RouteCategory_STRUCTURE RouteCategory = "structure" -) - -const ( - RouteService_API RouteService = "api" - RouteService_FSM RouteService = "fsm" - RouteService_LIST RouteService = "list" - RouteService_XLSX RouteService = "xlsx" - RouteService_IMPORT RouteService = "import" - RouteService_PRINT RouteService = "print" - RouteService_LAYOUT RouteService = "layout" - RouteService_GRID_LAYOUT RouteService = "grid-layout" - RouteService_GRID_LAYOUT_FORM RouteService = "grid-layout-form" - RouteService_ECHART RouteService = "echart" - RouteService_APPROVAL RouteService = "approval" - RouteService_SELECTOR RouteService = "selector" - RouteService_LIST_DETAIL RouteService = "list-detail" - RouteService_LIST_DATA_STORE RouteService = "list-data-store" - RouteService_LIST_GRID_LAYOUT RouteService = "list-grid-layout" - RouteService_LIST_CONDITION_LAYOUT RouteService = "list-condition-layout" - RouteService_LIST_OPERATIONS_ACCESS RouteService = "list-operations-access" -) - -const ( - RouteParam_STRING RouteParamType = "string" - RouteParam_BOOL RouteParamType = "bool" - RouteParam_NUMBER RouteParamType = "number" - RouteParam_INTEGER RouteParamType = "integer" - RouteParam_FLOAT RouteParamType = "float" - RouteParam_JSON RouteParamType = "json" - RouteParam_ARRAY RouteParamType = "array" - RouteParam_ANY RouteParamType = "any" -) - -const ( - RouteParamCategory_ROUTER RouteParamCategory = "router" - RouteParamCategory_HEADER RouteParamCategory = "header" - RouteParamCategory_PARAM RouteParamCategory = "param" -) - -func (k RouteCtx) String() string { - return k.Name -} - -type RouteMiddleware interface { - HttpMiddleware(r Route) func(next http.Handler) http.Handler -} - -type Router interface { - Call(r *http.Request, code string, params map[string]any, category ...RouteCategory) (HttpResponse, error) - Get(uuid string, category ...RouteCategory) (Route, bool) - Register(cr chi.Router) - RefreshRoutes() error -} - -type Route interface { - GetUuid() string - GetCode() string - GetPrimaryKey() string - GetUri() string - GetUris() []string - GetParamValues(*http.Request, ...RouteParam) (GlobalParams, error) - GetResource() Resource - GetCategory() RouteCategory - GetService() RouteService - GetRoles() []string - MakeRequest(r *http.Request, params map[string]any) (*http.Request, error) -} - -type RouteParam interface { - GetCode() string - GetDataType() RouteParamType - GetCategory() RouteParamCategory - IsRequired() bool - InjectRequestToGlobalParams(*http.Request, GlobalParams) error -} - -type WsClientGroup string -type WsClientID uint - -// type WsClient struct { -// User -// Group WsClientGroup -// Socket *websocket.Conn -// } - -type WsClient interface { - User - Socket() *websocket.Conn - WsClientID() WsClientID - WsClientGroup() WsClientGroup - WsClientManage() WsClientManage - Lock() - Unlock() -} - -type WsClientManage interface { - Register(WsClient) bool - Unregister(WsClient) - GetClients(func(WsClient) bool) []WsClient -} - -type WsChannelManage interface { - Channel(string) WsClientManage -} diff --git a/support/global_params.go b/support/global_params.go deleted file mode 100644 index a06f3a0..0000000 --- a/support/global_params.go +++ /dev/null @@ -1,228 +0,0 @@ -package support - -import ( - "time" - - "github.com/samber/lo" - "github.com/spf13/cast" - "github.com/tidwall/gjson" - "github.com/tidwall/sjson" - - "git.fsdpf.net/go/contracts" -) - -type GlobalParams struct { - user *contracts.User - gjson gjson.Result -} - -// 获取用户信息 -func (this GlobalParams) User() contracts.User { - return *this.user -} - -// 获取指定路径的 value -func (this GlobalParams) Get(key string) contracts.GlobalParams { - return &GlobalParams{ - user: this.user, - gjson: this.gjson.Get(key), - } -} - -// -func (this GlobalParams) Array() []contracts.GlobalParams { - return lo.Map(this.gjson.Array(), func(item gjson.Result, _ int) contracts.GlobalParams { - return &GlobalParams{user: this.user, gjson: gjson.Parse(item.Raw)} - }) -} - -// 获取golang原始类型 -func (this GlobalParams) Value() any { - return this.gjson.Value() -} - -func (this GlobalParams) Raw() string { - return this.gjson.Raw -} - -// 设置json值 -func (this *GlobalParams) Set(p string, v any) bool { - if s, err := sjson.Set(this.Raw(), p, v); err != nil { - return false - } else { - this.gjson = gjson.Parse(s) - } - return true -} - -// 设置json原始值 -func (this *GlobalParams) SetRaw(p, v string) bool { - if s, err := sjson.SetRaw(this.Raw(), p, v); err != nil { - return false - } else { - this.gjson = gjson.Parse(s) - } - return true -} - -// 删除路径内容 -func (this *GlobalParams) Delete(p string) bool { - if s, err := sjson.Delete(this.Raw(), p); err != nil { - return false - } else { - this.gjson = gjson.Parse(s) - } - return true -} - -// 路径包裹 -func (this *GlobalParams) Wrapped(p string) contracts.GlobalParams { - return this.AppendTo("", p) -} - -// 包裹内容 -func (this *GlobalParams) AppendTo(root, p string) contracts.GlobalParams { - if root != "" && !gjson.Valid(root) { - root = "" - } - return NewGlobalParam(lo.Must(sjson.SetRaw(root, p, this.Raw())), *this.user) -} - -// 判断值是否存在 -func (this GlobalParams) Exists() bool { - return this.gjson.Exists() -} - -// to Bool -func (this GlobalParams) Bool() bool { - return cast.ToBool(this.Value()) -} - -// to Time -func (this GlobalParams) Time() time.Time { - return cast.ToTime(this.Value()) -} - -// to Location Time -func (this GlobalParams) TimeInDefaultLocation(location *time.Location) time.Time { - return cast.ToTimeInDefaultLocation(this, location) -} - -// to float64 -func (this GlobalParams) Float64() float64 { - return cast.ToFloat64(this.Value()) -} - -// to float32 -func (this GlobalParams) Float32() float32 { - return cast.ToFloat32(this.Value()) -} - -// to int64 -func (this GlobalParams) Int64() int64 { - return cast.ToInt64(this.Value()) -} - -// to int32 -func (this GlobalParams) Int32() int32 { - return cast.ToInt32(this.Value()) -} - -// to int16 -func (this GlobalParams) Int16() int16 { - return cast.ToInt16(this.Value()) -} - -// to int8 -func (this GlobalParams) Int8() int8 { - return cast.ToInt8(this.Value()) -} - -// to int -func (this GlobalParams) Int() int { - return cast.ToInt(this.Value()) -} - -// to uint -func (this GlobalParams) Uint() uint { - return cast.ToUint(this.Value()) -} - -// to uint64 -func (this GlobalParams) Uint64() uint64 { - return cast.ToUint64(this.Value()) -} - -// to uint32 -func (this GlobalParams) Uint32() uint32 { - return cast.ToUint32(this.Value()) -} - -// to uint16 -func (this GlobalParams) Uint16() uint16 { - return cast.ToUint16(this.Value()) -} - -// to uint8 -func (this GlobalParams) Uint8() uint8 { - return cast.ToUint8(this.Value()) -} - -// to string -func (this GlobalParams) String() string { - return cast.ToString(this.Value()) -} - -// to map[string]string -func (this GlobalParams) StringMapString() map[string]string { - return cast.ToStringMapString(this.Value()) -} - -// to map[string][]string -func (this GlobalParams) StringMapStringSlice() map[string][]string { - return cast.ToStringMapStringSlice(this.Value()) -} - -// to map[string]bool -func (this GlobalParams) StringMapBool() map[string]bool { - return cast.ToStringMapBool(this.Value()) -} - -// to map[string]int -func (this GlobalParams) StringMapInt() map[string]int { - return cast.ToStringMapInt(this.Value()) -} - -// to map[string]int64 -func (this GlobalParams) StringMapInt64() map[string]int64 { - return cast.ToStringMapInt64(this.Value()) -} - -// to map[string]any -func (this GlobalParams) StringMap() map[string]any { - return cast.ToStringMap(this.Value()) -} - -// to []any -func (this GlobalParams) Slice() []any { - return cast.ToSlice(this.Value()) -} - -// to []bool -func (this GlobalParams) BoolSlice() []bool { - return cast.ToBoolSlice(this.Value()) -} - -// to []string -func (this GlobalParams) StringSlice() []string { - return cast.ToStringSlice(this.Value()) -} - -// to []int -func (this GlobalParams) IntSlice() []int { - return cast.ToIntSlice(this.Value()) -} - -func NewGlobalParam(data string, user contracts.User) contracts.GlobalParams { - return &GlobalParams{user: &user, gjson: gjson.Parse(data)} -} diff --git a/support/list.go b/support/list.go index 730d0ae..56736e9 100644 --- a/support/list.go +++ b/support/list.go @@ -5,34 +5,36 @@ import ( "reflect" "strings" + "git.fsdpf.net/go/condition" "git.fsdpf.net/go/contracts" "git.fsdpf.net/go/db" + "git.fsdpf.net/go/utils" "github.com/samber/do" "github.com/samber/lo" "github.com/spf13/cast" ) type Operation struct { - Uuid string `json:"uuid"` - Name string `json:"name"` - Code string `json:"code"` - Icon string `json:"icon"` - Size string `json:"size"` - Block bool `json:"block"` - Ghost bool `json:"ghost"` - Shape string `json:"shape"` - Type string `json:"type"` - PopConfirm any `json:"popConfirm,omitempty"` - Widget string `json:"widget"` - WidgetType string `json:"widgetType"` - WidgetProps any `json:"widgetProps"` - WidgetSetting any `json:"widgetSetting"` - WidgetContainerSetting any `json:"widgetContainerSetting"` - IsRefresh int `json:"isRefresh"` - NoAuthType string `json:"noAuthType"` - Roles []string `json:"-"` - Children []Operation `json:"children,omitempty"` - AccessCondition contracts.Condition `json:"-"` + Uuid string `json:"uuid"` + Name string `json:"name"` + Code string `json:"code"` + Icon string `json:"icon"` + Size string `json:"size"` + Block bool `json:"block"` + Ghost bool `json:"ghost"` + Shape string `json:"shape"` + Type string `json:"type"` + PopConfirm any `json:"popConfirm,omitempty"` + Widget string `json:"widget"` + WidgetType string `json:"widgetType"` + WidgetProps any `json:"widgetProps"` + WidgetSetting any `json:"widgetSetting"` + WidgetContainerSetting any `json:"widgetContainerSetting"` + IsRefresh int `json:"isRefresh"` + NoAuthType string `json:"noAuthType"` + Roles []string `json:"-"` + Children []Operation `json:"children,omitempty"` + AccessCondition *condition.Condition `json:"-"` } type OperationAccess struct { @@ -42,14 +44,13 @@ type OperationAccess struct { func (o Operation) ToDBColumn(model contracts.Model, container *do.Injector) (column db.Expression, field reflect.StructField) { GetOrmConditionByRes := do.MustInvoke[contracts.GetOrmConditionByRes](container) - NewOrmCondition := do.MustInvoke[contracts.NewOrmCondition](container) uuid := strings.ReplaceAll(o.Uuid, "-", "_") // 主键 pk := model.GetCode() + "." + model.GetPrimaryKey() - cond := lo.Ternary(o.AccessCondition != nil, o.AccessCondition, NewOrmCondition(contracts.ConditionType_AND, "operation access condition "+uuid)) + cond := lo.Ternary(o.AccessCondition != nil, o.AccessCondition, condition.New(condition.Describe("operation access condition "+uuid))) if c := GetOrmConditionByRes(o.Uuid, "operation access condition "+uuid); c.IsNotEmpty() { cond.SetCondition(c) @@ -63,7 +64,7 @@ func (o Operation) ToDBColumn(model contracts.Model, container *do.Injector) (co // 主键类型 tPkType := reflect.TypeOf("") - if tPk, ok := GetStructField(model.GetQueryFieldsStruct(), model.GetPrimaryKey()); ok { + if tPk, ok := utils.GetStructField(model.GetQueryFieldsStruct(), model.GetPrimaryKey()); ok { tPkType = tPk.Type } field = reflect.StructField{ @@ -149,7 +150,7 @@ func NewOperationAccess(m contracts.Model) OperationAccess { // 主键类型 tPkType := reflect.String - if tPk, ok := GetStructField(m.GetQueryFieldsStruct(), m.GetPrimaryKey()); ok { + if tPk, ok := utils.GetStructField(m.GetQueryFieldsStruct(), m.GetPrimaryKey()); ok { switch tPk.Type.Kind() { case reflect.Int, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint32, reflect.Uint64: diff --git a/support/response.go b/support/response.go index faa3191..ad49b38 100644 --- a/support/response.go +++ b/support/response.go @@ -8,6 +8,7 @@ import ( "strings" "git.fsdpf.net/go/contracts" + "git.fsdpf.net/go/req" "github.com/gorilla/websocket" "github.com/samber/lo" ) @@ -40,8 +41,8 @@ var wsUpgrader = websocket.Upgrader{ }, } -func (this RawResponse) Get(path ...string) contracts.GlobalParams { - return lo.Ternary(len(path) == 0, NewGlobalParam(string(this.raw), nil), NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, "."))) +func (this RawResponse) Get(path ...string) req.GlobalParams { + return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(this.raw), nil), req.NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, "."))) } func (this RawResponse) Send(w http.ResponseWriter, r *http.Request) { @@ -54,8 +55,8 @@ func (this RawResponse) Send(w http.ResponseWriter, r *http.Request) { } } -func (this JsonResponse) Get(path ...string) contracts.GlobalParams { - return lo.Ternary(len(path) == 0, NewGlobalParam(string(this.raw), nil), NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, "."))) +func (this JsonResponse) Get(path ...string) req.GlobalParams { + return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(this.raw), nil), req.NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, "."))) } func (this JsonResponse) Send(w http.ResponseWriter, r *http.Request) { @@ -69,12 +70,12 @@ func (this JsonResponse) Send(w http.ResponseWriter, r *http.Request) { } } -func (this MsgResponse) Get(path ...string) contracts.GlobalParams { +func (this MsgResponse) Get(path ...string) req.GlobalParams { if resp, err := json.Marshal(map[string]any{ "code": this.code, "msg": this.msg, }); err == nil { - return lo.Ternary(len(path) == 0, NewGlobalParam(string(resp), nil), NewGlobalParam(string(resp), nil).Get(strings.Join(path, "."))) + return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(resp), nil), req.NewGlobalParam(string(resp), nil).Get(strings.Join(path, "."))) } return nil @@ -88,13 +89,13 @@ func (this MsgResponse) Send(w http.ResponseWriter, r *http.Request) { } } -func (this ErrResponse) Get(path ...string) contracts.GlobalParams { +func (this ErrResponse) Get(path ...string) req.GlobalParams { if resp, err := json.Marshal(map[string]any{ "code": this.code, "msg": this.msg, "error": string(this.stack), }); err == nil { - return lo.Ternary(len(path) == 0, NewGlobalParam(string(resp), nil), NewGlobalParam(string(resp), nil).Get(strings.Join(path, "."))) + return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(resp), nil), req.NewGlobalParam(string(resp), nil).Get(strings.Join(path, "."))) } return nil @@ -108,12 +109,12 @@ func (this ErrResponse) Send(w http.ResponseWriter, r *http.Request) { } } -func (this FileResponse) Get(path ...string) contracts.GlobalParams { +func (this FileResponse) Get(path ...string) req.GlobalParams { if resp, err := json.Marshal(map[string]any{ "name": this.name, "disposition": this.disposition, }); err == nil { - return lo.Ternary(len(path) == 0, NewGlobalParam(string(resp), nil), NewGlobalParam(string(resp), nil).Get(strings.Join(path, "."))) + return lo.Ternary(len(path) == 0, req.NewGlobalParam(string(resp), nil), req.NewGlobalParam(string(resp), nil).Get(strings.Join(path, "."))) } return nil @@ -130,31 +131,31 @@ func (this FileResponse) Send(w http.ResponseWriter, r *http.Request) { } } -func NewRawResponse(b []byte) contracts.HttpResponse { +func NewRawResponse(b []byte) req.HttpResponse { return &RawResponse{raw: b} } -func NewJsonResponse(b []byte) contracts.HttpResponse { +func NewJsonResponse(b []byte) req.HttpResponse { return &JsonResponse{raw: b} } -func NewFileResponse(name string, disposition string) contracts.HttpResponse { +func NewFileResponse(name string, disposition string) req.HttpResponse { return &FileResponse{name: name, disposition: disposition} } -func NewMsgResponse(msg string, code int) contracts.HttpResponse { +func NewMsgResponse(msg string, code int) req.HttpResponse { return &MsgResponse{msg: msg, code: code} } -func NewErrResponse(err *contracts.Err) contracts.HttpResponse { +func NewErrResponse(err *contracts.Err) req.HttpResponse { return NewJsonResponse([]byte(fmt.Sprintf(`{"code": %d, "msg": %q}`, err.Code, err.Error()))) } -func HttpResponse(data any) contracts.HttpResponse { +func HttpResponse(data any) req.HttpResponse { var err error // fmt.Printf("%#v \n", data) switch v := data.(type) { - case contracts.HttpResponse: + case req.HttpResponse: return v case contracts.Errno: return NewMsgResponse(v.Error(), v.Code) diff --git a/support/util.go b/support/util.go deleted file mode 100644 index 7480f38..0000000 --- a/support/util.go +++ /dev/null @@ -1,175 +0,0 @@ -package support - -import ( - "fmt" - "os" - "path/filepath" - "reflect" - "strings" - "unsafe" - - "github.com/spf13/cast" -) - -func GetFieldValue(i any, k string) any { - v := reflect.ValueOf(i) - - var kv reflect.Value - - if v.Kind() == reflect.Ptr { - v = reflect.Indirect(v) - } - - if v.Kind() == reflect.Struct { - kv = v.FieldByName(k) - } else if v.Kind() == reflect.Map { - for _, key := range v.MapKeys() { - if key.String() == k { - kv = v.MapIndex(key) - } - } - } - - switch kv.Kind() { - case reflect.String: - return kv.String() - case reflect.Bool: - return kv.Bool() - case reflect.Float32, reflect.Float64: - return kv.Float() - case reflect.Int, reflect.Int64: - return int(kv.Int()) - case reflect.Invalid: - return nil - } - - return kv.Interface() -} - -func GetStructField(item any, key string) (field reflect.StructField, ok bool) { - vItem := reflect.TypeOf(item) - - if vItem.Kind() == reflect.Ptr { - vItem = vItem.Elem() - } - - if vItem.Kind() != reflect.Struct { - return field, false - } - - return vItem.FieldByName(UcFirst(key)) -} - -func InterfaceToSlice(i any) (ret []any) { - rv := reflect.ValueOf(i) - - if rv.Kind() == reflect.Ptr { - rv = reflect.Indirect(rv) - } - - if rv.Kind() != reflect.Slice { - panic("请传入切片类型数据") - } - - for i := 0; i < rv.Len(); i++ { - ret = append(ret, rv.Index(i).Interface()) - } - - return ret -} - -func SliceConvert(origSlice any, newSliceType reflect.Type) any { - sv := reflect.ValueOf(origSlice) - - if sv.Kind() != reflect.Slice { - panic(fmt.Sprintf("无效切片类型 %T (来源)", origSlice)) - } - - if newSliceType.Kind() != reflect.Slice { - panic(fmt.Sprintf("无效切片类型 %T (目标)", newSliceType)) - } - - // 生成新类型的切片 - newSlice := reflect.New(newSliceType) - - // hdr指向到新生成切片的SliceHeader - hdr := (*reflect.SliceHeader)(unsafe.Pointer(newSlice.Pointer())) - - var newElemSize = int(sv.Type().Elem().Size()) / int(newSliceType.Elem().Size()) - - // 设置SliceHeader的Cap,Len,以及数组的ptr - hdr.Cap = sv.Cap() * newElemSize - hdr.Len = sv.Len() * newElemSize - hdr.Data = uintptr(sv.Pointer()) - - return newSlice.Elem().Interface() -} - -func DeepSearch(m map[string]any, path []string) map[string]any { - for _, k := range path { - m2, ok := m[k] - if !ok { - // intermediate key does not exist - // => create it and continue from there - m3 := make(map[string]interface{}) - m[k] = m3 - m = m3 - continue - } - m3, ok := m2.(map[string]interface{}) - if !ok { - // intermediate key is a value - // => replace with a new map - m3 = make(map[string]interface{}) - m[k] = m3 - } - // continue search from here - m = m3 - } - return m -} - -func MergeMap(shadow map[string]any, m map[string]any) map[string]any { - if shadow == nil { - shadow = make(map[string]any) - } - - var m2 map[string]any - - for k, val := range m { - switch val.(type) { - case map[string]any: - m2 = val.(map[string]any) - case map[any]any: - m2 = cast.ToStringMap(val) - default: - // immediate value - shadow[k] = val - continue - } - // recursively merge to shadow map - shadow[k] = MergeMap(cast.ToStringMap(shadow[k]), m2) - } - return shadow -} - -func UcFirst(s string) string { - if s == "" { - return "" - } - return strings.ToUpper(s[:1]) + s[1:] -} - -func StudlyCase(s string) string { - return strings.Replace(strings.Title(strings.Replace(s, "-", " ", -1)), " ", "", -1) -} - -func GetAbsPath(s string) string { - if strings.HasPrefix(s, "/") { - return s - } else if dir, err := os.Getwd(); err == nil { - return filepath.Join(dir, s) - } - - return s -} diff --git a/support/utils_test.go b/support/utils_test.go deleted file mode 100644 index 2d0b3e5..0000000 --- a/support/utils_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package support - -import ( - "testing" -) - -func TestDeepSearch(t *testing.T) { - m := map[string]any{ - "a": 1, - "b": map[string]any{ - "c": 2, - }, - } - - mb := DeepSearch(m, []string{"b", "a"}) - - t.Log(m) - - mb["cc"] = "3" - - t.Log(m) -} - -func TestMergeMap(t *testing.T) { - m1 := map[string]any{ - "a": 1, - "b": map[string]any{ - "c": 2, - "a": 1, - "b": map[string]any{ - "c": 2, - "a": 1, - }, - }, - } - - m2 := map[string]any{ - "a": 11, - "b": map[string]any{ - "c": 22, - "cc": 33, - }, - } - - t.Log(MergeMap(m1, m2)) -} diff --git a/user.go b/user.go deleted file mode 100644 index 48e0144..0000000 --- a/user.go +++ /dev/null @@ -1,53 +0,0 @@ -package contracts - -type UserRuntime struct { - platform string - saas string -} - -// 账号运行平台 -func (this UserRuntime) Platform() string { - return this.platform -} - -// 账号运行租户 -func (this UserRuntime) SaaS() string { - return this.saas -} - -type User interface { - Runtime() UserRuntime - // 用户ID - ID() int64 - // 用户UUID - Uuid() string - // 用户名称 - Username() string - // 用户昵称 - Nickname() string - // 用户明细 - GetUserInfo() map[string]any - // 用户权限 - Roles() []string - // 用户权限检查 - HasUserRoles(roles ...string) bool - // 是否匿名用户 - IsAnonymous() bool -} - -// 用户 -type GetUser func(uuid string, options ...UserRuntimeOption) (User, error) - -type UserRuntimeOption func(option *UserRuntime) - -func UserRuntimePlatform(value string) UserRuntimeOption { - return func(option *UserRuntime) { - option.platform = value - } -} - -func UserRuntimeSaaS(value string) UserRuntimeOption { - return func(option *UserRuntime) { - option.saas = value - } -} diff --git a/user_approval.go b/user_approval.go index 06cfb4c..c4064e0 100644 --- a/user_approval.go +++ b/user_approval.go @@ -4,6 +4,7 @@ import ( "net/http" "git.fsdpf.net/go/db" + "git.fsdpf.net/go/req" ) type UserApprovalExecute int @@ -51,9 +52,9 @@ type UserApproval interface { // 审批流名称 Name() string // 发起审批请求 - RequestApproval(Route, *http.Request) any + RequestApproval(req.Route, *http.Request) any // 判断发起审批请求权限 - HasUserRoles(User) bool + HasUserRoles(req.User) bool // 获取审批列表标记字段值 Execute(id int64, status UserApprovalExecute, r *http.Request, tx *db.Transaction) (current, next UserApprovalFlow, err error) } diff --git a/ws.go b/ws.go new file mode 100644 index 0000000..0cb19e5 --- /dev/null +++ b/ws.go @@ -0,0 +1,35 @@ +package contracts + +import ( + "git.fsdpf.net/go/req" + "github.com/gorilla/websocket" +) + +type WsClientGroup string +type WsClientID uint + +// type WsClient struct { +// User +// Group WsClientGroup +// Socket *websocket.Conn +// } + +type WsClient interface { + req.User + Socket() *websocket.Conn + WsClientID() WsClientID + WsClientGroup() WsClientGroup + WsClientManage() WsClientManage + Lock() + Unlock() +} + +type WsClientManage interface { + Register(WsClient) bool + Unregister(WsClient) + GetClients(func(WsClient) bool) []WsClient +} + +type WsChannelManage interface { + Channel(string) WsClientManage +}