[feat] 重新梳理依赖

This commit is contained in:
what 2024-05-09 13:15:24 +08:00
parent 9172fb2f34
commit bddd754869
28 changed files with 341 additions and 1075 deletions

View File

@ -5,16 +5,16 @@ import (
"strings" "strings"
"unicode" "unicode"
"git.fsdpf.net/go/contracts"
"git.fsdpf.net/go/contracts/res_type" "git.fsdpf.net/go/contracts/res_type"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
) )
type QueryField struct { type QueryField struct {
ResField ResField
typ contracts.QueryDataType `db:"dataType"` typ req.RouteParamType `db:"dataType"`
alias string `db:"alias"` alias string `db:"alias"`
isExpr bool `db:"isExpr"` isExpr bool `db:"isExpr"`
isOmitempty bool isOmitempty bool
ignored bool ignored bool
} }
@ -35,20 +35,20 @@ func (this QueryField) IsOmitempty() bool {
return this.isOmitempty return this.isOmitempty
} }
func (this QueryField) Type() contracts.QueryDataType { func (this QueryField) Type() req.RouteParamType {
return this.typ return this.typ
} }
func (this *QueryField) SetOptions(options int) contracts.QueryField { func (this *QueryField) SetOptions(options byte) req.QueryField {
if options&contracts.QueryField_IsExpr != 0 { if options&req.IsExpr != 0 {
this.isExpr = true this.isExpr = true
} }
if options&contracts.QueryField_IsOmitempty != 0 { if options&req.IsOmitempty != 0 {
this.isOmitempty = true this.isOmitempty = true
} }
if options&contracts.QueryField_Ignored != 0 { if options&req.Ignored != 0 {
this.ignored = true this.ignored = true
} }
@ -101,19 +101,19 @@ func (this *QueryField) ToStructField(tags ...string) reflect.StructField {
} }
switch this.typ { switch this.typ {
case contracts.QueryDataType_String: case req.ReqString:
typ = reflect.TypeOf(string("")) typ = reflect.TypeOf(string(""))
case contracts.QueryDataType_Number: case req.ReqNumber:
typ = reflect.TypeOf(res_type.ResFieldByNumber(0)) typ = reflect.TypeOf(res_type.ResFieldByNumber(0))
case contracts.QueryDataType_Integer: case req.ReqInteger:
typ = reflect.TypeOf(res_type.ResFieldByInteger(0)) typ = reflect.TypeOf(res_type.ResFieldByInteger(0))
case contracts.QueryDataType_Float: case req.ReqFloat:
typ = reflect.TypeOf(res_type.ResFieldByFloat(0)) typ = reflect.TypeOf(res_type.ResFieldByFloat(0))
case contracts.QueryDataType_Bool: case req.ReqBool:
typ = reflect.TypeOf(true) typ = reflect.TypeOf(true)
case contracts.QueryDataType_Array: case req.ReqArray:
typ = reflect.TypeOf([]any{}) typ = reflect.TypeOf([]any{})
case contracts.QueryDataType_Json: case req.ReqJson:
typ = reflect.TypeOf(map[string]any{}) typ = reflect.TypeOf(map[string]any{})
} }

View File

@ -1,5 +1,7 @@
package base package base
import "git.fsdpf.net/go/condition"
type ResCondition struct { type ResCondition struct {
Id int `db:"id"` Id int `db:"id"`
Pid int `db:"pid"` Pid int `db:"pid"`
@ -36,3 +38,54 @@ type ResWhereExpr struct {
} }
type GetResConditions func(categoryUuid string) []ResCondition 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
}

View File

@ -7,24 +7,24 @@ import (
"strconv" "strconv"
"strings" "strings"
"git.fsdpf.net/go/contracts"
"git.fsdpf.net/go/contracts/res_type" "git.fsdpf.net/go/contracts/res_type"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/db/schema" "git.fsdpf.net/go/db/schema"
"git.fsdpf.net/go/req"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/spf13/cast" "github.com/spf13/cast"
) )
// 资源字段 // 资源字段
type ResField struct { type ResField struct {
Uuid string `db:"uuid"` Uuid string `db:"uuid"`
Name string `db:"name"` Name string `db:"name"`
Code string `db:"code"` Code string `db:"code"`
CodeResource string `db:"codeResource"` CodeResource string `db:"codeResource"`
DataType contracts.ResDataType `db:"table_type"` DataType req.ResDataType `db:"table_type"`
Length string `db:"length"` Length string `db:"length"`
Comment string `db:"comment"` Comment string `db:"comment"`
Default string `db:"default"` Default string `db:"default"`
} }
func (this ResField) ToStructField(tags ...string) reflect.StructField { func (this ResField) ToStructField(tags ...string) reflect.StructField {
@ -38,16 +38,16 @@ func (this ResField) ToStructField(tags ...string) reflect.StructField {
} }
switch this.DataType { switch this.DataType {
case contracts.ResDataType_String, contracts.ResDataType_Text, contracts.ResDataType_Enum, case req.ResString, req.ResText, req.ResEnum,
contracts.ResDataType_Timestamp, contracts.ResDataType_Date, contracts.ResDataType_Datetime: req.ResTimestamp, req.ResDate, req.ResDatetime:
typ = reflect.TypeOf(string("")) typ = reflect.TypeOf(string(""))
case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger: case req.ResInteger, req.ResSmallInteger:
typ = reflect.TypeOf(res_type.ResFieldByInteger(0)) typ = reflect.TypeOf(res_type.ResFieldByInteger(0))
case contracts.ResDataType_Decimal: case req.ResDecimal:
typ = reflect.TypeOf(float64(0)) typ = reflect.TypeOf(float64(0))
case contracts.ResDataType_Boolean: case req.ResBoolean:
typ = reflect.TypeOf(true) typ = reflect.TypeOf(true)
case contracts.ResDataType_Json: case req.ResJson:
if this.Default != "" && this.Default[0:1] == "[" { if this.Default != "" && this.Default[0:1] == "[" {
typ = reflect.TypeOf([]any{}) typ = reflect.TypeOf([]any{})
} else { } else {
@ -74,47 +74,47 @@ func (this ResField) GetName() string {
return this.Name return this.Name
} }
func (this ResField) GetDataType() contracts.ResDataType { func (this ResField) GetDataType() req.ResDataType {
return this.DataType return this.DataType
} }
func (this ResField) GetQueryDataType() contracts.QueryDataType { func (this ResField) GetQueryDataType() req.RouteParamType {
switch this.GetDataType() { switch this.GetDataType() {
case contracts.ResDataType_Enum, case req.ResEnum,
contracts.ResDataType_Timestamp, contracts.ResDataType_Date, req.ResTimestamp, req.ResDate,
contracts.ResDataType_Datetime, contracts.ResDataType_String, req.ResDatetime, req.ResString,
contracts.ResDataType_Text: req.ResText:
return contracts.QueryDataType_String return req.ReqString
case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger: case req.ResInteger, req.ResSmallInteger:
return contracts.QueryDataType_Integer return req.ReqInteger
case contracts.ResDataType_Decimal: case req.ResDecimal:
return contracts.QueryDataType_Float return req.ReqFloat
case contracts.ResDataType_Boolean: case req.ResBoolean:
return contracts.QueryDataType_Bool return req.ReqBool
case contracts.ResDataType_Json: case req.ResJson:
if this.Default != "" && this.Default[0:1] == "[" { 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 { func (this ResField) ToValue(v any) any {
switch this.DataType { switch this.DataType {
case contracts.ResDataType_String, contracts.ResDataType_Text, contracts.ResDataType_Enum, case req.ResString, req.ResText, req.ResEnum,
contracts.ResDataType_Timestamp, contracts.ResDataType_Date, contracts.ResDataType_Datetime: req.ResTimestamp, req.ResDate, req.ResDatetime:
return strings.Trim(cast.ToString(v), " ") return strings.Trim(cast.ToString(v), " ")
case contracts.ResDataType_Integer, contracts.ResDataType_SmallInteger: case req.ResInteger, req.ResSmallInteger:
return cast.ToInt(v) return cast.ToInt(v)
case contracts.ResDataType_Decimal: case req.ResDecimal:
return strings.Trim(cast.ToString(v), " ") return strings.Trim(cast.ToString(v), " ")
case contracts.ResDataType_Boolean: case req.ResBoolean:
if v, _ := strconv.ParseBool(fmt.Sprintf("%v", v)); v { if v, _ := strconv.ParseBool(fmt.Sprintf("%v", v)); v {
return 1 return 1
} }
return 0 return 0
case contracts.ResDataType_Json: case req.ResJson:
if v == nil { if v == nil {
if this.Default != "" && this.Default[0:1] == "[" { if this.Default != "" && this.Default[0:1] == "[" {
return db.Raw("'[]'") return db.Raw("'[]'")
@ -142,7 +142,7 @@ func (this ResField) ToValue(v any) any {
} }
func (this ResField) GetRawDefault(driver string) db.Expression { 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] == "[" { if this.Default != "" && this.Default[0:1] == "[" {
return db.Raw("'[]'") return db.Raw("'[]'")
} else if this.Default != "" && this.Default[0:1] == "{" { } else if this.Default != "" && this.Default[0:1] == "{" {
@ -150,7 +150,7 @@ func (this ResField) GetRawDefault(driver string) db.Expression {
} else if this.Default == "" { } else if this.Default == "" {
return db.Raw("'{}'") return db.Raw("'{}'")
} }
} else if this.DataType == contracts.ResDataType_Boolean { } else if this.DataType == req.ResBoolean {
if v, _ := strconv.ParseBool(this.Default); v { if v, _ := strconv.ParseBool(this.Default); v {
return db.Raw("'1'") return db.Raw("'1'")
} }
@ -169,7 +169,7 @@ func (this ResField) GetRawDefault(driver string) db.Expression {
} }
if this.Default == "" { 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("NULL")
} }
return db.Raw("''") return db.Raw("''")
@ -255,7 +255,7 @@ func (this ResField) ToBlueprint(table *schema.Blueprint) (temp *schema.ColumnDe
return temp 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{ o := &QueryField{
ResField: this, ResField: this,
typ: t, typ: t,

View File

@ -2,6 +2,7 @@ package base
import ( import (
"git.fsdpf.net/go/contracts" "git.fsdpf.net/go/contracts"
"git.fsdpf.net/go/req"
) )
type ResRelation struct { type ResRelation struct {
@ -23,7 +24,7 @@ type GetResRelations func(categoryUuid string) []ResRelation
type GetOrmJoinsByResRelations func(root string, items []ResRelation) []contracts.Join 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) { func GetJoinResDependencies(root string, items []ResRelation) (dependencies []string) {

View File

@ -11,8 +11,8 @@ import (
"github.com/samber/lo" "github.com/samber/lo"
"git.fsdpf.net/go/contracts" "git.fsdpf.net/go/contracts"
"git.fsdpf.net/go/contracts/support"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
) )
// 资源变更事件 // 资源变更事件
@ -29,7 +29,7 @@ type ResChangeEventTopicPayload struct {
type ResChangeRecordTopicPayload struct { type ResChangeRecordTopicPayload struct {
Type string // insert | delete | update Type string // insert | delete | update
User contracts.User // 操作用户 User req.User // 操作用户
Res Resource // 变更资源 Res Resource // 变更资源
Result sql.Result // 执行结果 Result sql.Result // 执行结果
Old []map[string]any // 旧数据 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 { for _, item := range this.Fields {
result = append(result, item) result = append(result, item)
} }
@ -100,15 +100,15 @@ func (this Resource) GetFields() (result []contracts.ResField) {
} }
// 资源字段 // 资源字段
func (this Resource) GetField(code string) (contracts.ResField, bool) { func (this Resource) GetField(code string) (req.ResField, bool) {
return lo.Find(this.GetFields(), func(v contracts.ResField) bool { return lo.Find(this.GetFields(), func(v req.ResField) bool {
return v.GetCode() == code return v.GetCode() == code
}) })
} }
// 判断资源字段 // 判断资源字段
func (this Resource) HasField(code string) bool { 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 return v.GetCode() == code
}) })
} }
@ -147,7 +147,7 @@ func (this Resource) GetDBDriver() string {
return this.GetDBConn().GetConfig().Driver 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)...) 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 { func (this Resource) GetDBTable(params ...any) *db.Builder {
builder := this.GetDBBuilder() builder := this.GetDBBuilder()
var user contracts.User var user req.User
alias := this.Code alias := this.Code
for _, param := range params { for _, param := range params {
@ -173,7 +173,7 @@ func (this Resource) GetDBTable(params ...any) *db.Builder {
builder.Tx = v builder.Tx = v
case string: case string:
alias = v alias = v
case contracts.User: case req.User:
user = v user = v
} }
} }
@ -213,7 +213,7 @@ func (this Resource) GetDBTable(params ...any) *db.Builder {
return builder.Table(string(this.GetTable()), alias) 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 isFullRight := false
isFullNot := false isFullNot := false
@ -268,7 +268,7 @@ func (this Resource) WithRolesCondition(b *db.Builder, t string, u contracts.Use
return db.ToSql() return db.ToSql()
} else if conditions.IsNotEmpty() { } else if conditions.IsNotEmpty() {
oOrm := NewOrm(this, nil) oOrm := NewOrm(this, nil)
oOrm.SetGlobalParams(support.NewGlobalParam("{}", u)) oOrm.SetGlobalParams(req.NewGlobalParam("{}", u))
db.Where(conditions.ToSql(oOrm.GetModel())) 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() { for _, field := range this.GetFields() {
fCode := field.GetCode() 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{} old := []map[string]any{}
builder.Before(func(b *db.Builder, t string, data ...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{ return &Resource{
Uuid: code, Uuid: code,
PUuid: pRes.Uuid, PUuid: pRes.Uuid,

View File

@ -3,7 +3,7 @@ package base
import ( import (
"github.com/samber/lo" "github.com/samber/lo"
"git.fsdpf.net/go/contracts" "git.fsdpf.net/go/req"
) )
type user struct { type user struct {
@ -12,7 +12,7 @@ type user struct {
username string username string
nickname string nickname string
roles []string roles []string
runtime contracts.UserRuntime runtime req.UserRuntime
} }
func (this user) ID() int64 { func (this user) ID() int64 {
@ -47,19 +47,19 @@ func (this user) IsAnonymous() bool {
return this.id == 0 return this.id == 0
} }
func (this user) Runtime() contracts.UserRuntime { func (this user) Runtime() req.UserRuntime {
return this.runtime return this.runtime
} }
// 获取匿名用户 // 获取匿名用户
func GetAnonymous(opts ...contracts.UserRuntimeOption) contracts.User { func GetAnonymous(opts ...req.UserRuntimeOption) req.User {
u := user{ u := user{
id: 0, id: 0,
uuid: "00000000-0000-0000-0000-000000000000", uuid: "00000000-0000-0000-0000-000000000000",
username: "anonymous", username: "anonymous",
nickname: "匿名者", nickname: "匿名者",
roles: []string{"00000000-0000-0000-0000-000000000000"}, roles: []string{"00000000-0000-0000-0000-000000000000"},
runtime: contracts.UserRuntime{}, runtime: req.UserRuntime{},
} }
for _, opt := range opts { 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{ u := user{
id: -1, id: -1,
uuid: "ffffffff-ffff-ffff-ffff-ffffffffffff", uuid: "ffffffff-ffff-ffff-ffff-ffffffffffff",
username: "system", username: "system",
nickname: "系统", nickname: "系统",
roles: []string{"ffffffff-ffff-ffff-ffff-ffffffffffff"}, roles: []string{"ffffffff-ffff-ffff-ffff-ffffffffffff"},
runtime: contracts.UserRuntime{}, runtime: req.UserRuntime{},
} }
for _, opt := range opts { for _, opt := range opts {

View File

@ -1,7 +1,9 @@
package contracts package contracts
import "git.fsdpf.net/go/req"
type Captcha interface { type Captcha interface {
RouteMiddleware req.RouteMiddleware
Verify(answer string, clear bool) error 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)
} }

View File

@ -1,6 +1,7 @@
package contracts package contracts
import ( import (
"git.fsdpf.net/go/req"
"github.com/samber/do" "github.com/samber/do"
) )
@ -10,7 +11,7 @@ type Controller interface {
// 获取 Container // 获取 Container
Container() *do.Injector Container() *do.Injector
// 派遣一个任务 // 派遣一个任务
Dispatch(job string, payload any, u User) error Dispatch(job string, payload any, u req.User) error
} }
type BaseController struct { type BaseController struct {
@ -25,7 +26,7 @@ func (BaseController) Init() error {
return nil 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) return do.MustInvoke[JobService](this.Container()).Dispatch(job, payload, u)
} }

View File

@ -1,5 +1,7 @@
package contracts package contracts
import "git.fsdpf.net/go/req"
type CronService interface { type CronService interface {
Start() error Start() error
Stop() error Stop() error
@ -9,13 +11,13 @@ type CronService interface {
type Cron interface { type Cron interface {
Controller Controller
// 任务处理 // 任务处理
Run(User) error Run(req.User) error
} }
type CronBase struct { type CronBase struct {
Controller Controller
} }
func (CronBase) Run(User) error { func (CronBase) Run(req.User) error {
return nil return nil
} }

View File

@ -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
}

13
go.mod
View File

@ -3,23 +3,26 @@ module git.fsdpf.net/go/contracts
go 1.21 go 1.21
require ( require (
git.fsdpf.net/go/db v0.0.0-20230621051209-5740d112407f git.fsdpf.net/go/condition v0.0.0-20240509034445-afc243ea916e
github.com/go-chi/chi/v5 v5.0.10 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/golang/protobuf v1.5.2
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
github.com/jhump/protoreflect v1.15.1 github.com/jhump/protoreflect v1.15.1
github.com/lestrrat-go/jwx v1.2.25 github.com/lestrrat-go/jwx v1.2.25
github.com/samber/do v1.6.0 github.com/samber/do v1.6.0
github.com/samber/lo v1.38.1 github.com/samber/lo v1.39.0
github.com/spf13/cast v1.5.0 github.com/spf13/cast v1.6.0
github.com/spf13/viper v1.15.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 github.com/tidwall/sjson v1.2.5
google.golang.org/grpc v1.52.0 google.golang.org/grpc v1.52.0
) )
require ( 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/bufbuild/protocompile v0.4.0 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect

34
go.sum
View File

@ -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.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= 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= 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 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-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/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/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= 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/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 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= 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 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-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/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/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 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= 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 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= 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 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= 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 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= 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= 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.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= 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.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 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=

41
http.go
View File

@ -3,6 +3,7 @@ package contracts
import ( import (
"net/http" "net/http"
"git.fsdpf.net/go/req"
"github.com/samber/do" "github.com/samber/do"
) )
@ -19,36 +20,36 @@ type HttpController interface {
Controller Controller
// 获取用户信息 // 获取用户信息
User() User User() req.User
// 获取请求信息 // 获取请求信息
Request() *http.Request 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() // Invoke()
// 数据库权限 // 数据库权限
AuthDB() ResAuthDB AuthDB() req.ResAuthDB
} }
type WsController interface { type WsController interface {
HttpController HttpController
// 请求处理 // 请求处理
ExecuteWS(GlobalParams) error ExecuteWS(req.GlobalParams) error
// 获取 Ws 客户端 // 获取 Ws 客户端
WsClient() WsClient WsClient() WsClient
// 获取 Ws 标识 // 获取 Ws 标识
WsClientId(GlobalParams) WsClientID WsClientId(req.GlobalParams) WsClientID
// 获取 Ws 分组 // 获取 Ws 分组
WsClientGroup(GlobalParams) WsClientGroup WsClientGroup(req.GlobalParams) WsClientGroup
} }
type HttpHandleController struct { type HttpHandleController struct {
@ -65,27 +66,27 @@ func (this HttpHandleController) Request() *http.Request {
return this.request return this.request
} }
func (this HttpHandleController) Route() Route { func (this HttpHandleController) Route() req.Route {
return this.Request().Context().Value(RouteCtx{Name: "Route"}).(Route) return this.Request().Context().Value(req.RouteCtx{Name: "Route"}).(req.Route)
} }
func (this HttpHandleController) User() User { func (this HttpHandleController) User() req.User {
return this.Request().Context().Value(RouteCtx{Name: "User"}).(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) { func (this HttpHandleController) Call(code string, params map[string]any, category ...req.RouteCategory) (req.HttpResponse, error) {
return do.MustInvoke[Router](this.Container()).Call(this.Request(), code, params, category...) 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 return nil
} }
func (HttpHandleController) AuthDB() ResAuthDB { func (HttpHandleController) AuthDB() req.ResAuthDB {
return ResAuthOn return req.ResAuthOn
} }
func (WsHandleController) ExecuteWS(params GlobalParams) error { func (WsHandleController) ExecuteWS(params req.GlobalParams) error {
return nil return nil
} }
@ -93,12 +94,12 @@ func (this WsHandleController) WsClient() WsClient {
return this.ws return this.ws
} }
func (WsHandleController) WsClientId(GlobalParams) WsClientID { func (WsHandleController) WsClientId(req.GlobalParams) WsClientID {
wsClientID++ wsClientID++
return wsClientID return wsClientID
} }
func (WsHandleController) WsClientGroup(GlobalParams) WsClientGroup { func (WsHandleController) WsClientGroup(req.GlobalParams) WsClientGroup {
return defaultWsClientGroup return defaultWsClientGroup
} }

8
job.go
View File

@ -1,22 +1,24 @@
package contracts package contracts
import "git.fsdpf.net/go/req"
type JobService interface { type JobService interface {
Start() error Start() error
Stop() error Stop() error
Restart() error Restart() error
Dispatch(job string, payload any, u User) error Dispatch(job string, payload any, u req.User) error
} }
type Job interface { type Job interface {
Controller Controller
// 任务处理 // 任务处理
Handle(any, User) error Handle(any, req.User) error
} }
type JobBase struct { type JobBase struct {
Controller Controller
} }
func (JobBase) Handle(any, User) error { func (JobBase) Handle(any, req.User) error {
return nil return nil
} }

21
mqtt.go
View File

@ -1,6 +1,7 @@
package contracts package contracts
import ( import (
"git.fsdpf.net/go/req"
"github.com/samber/do" "github.com/samber/do"
) )
@ -36,15 +37,15 @@ type Mqtt interface {
// 断开链接 // 断开链接
// OnDisconnect(g GlobalParams, topic string) error // 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 // OnRetainMessage(g GlobalParams, topic string) error
// Qos消息完成事件 // Qos消息完成事件
@ -59,23 +60,23 @@ type MqttHandle struct {
Controller Controller
} }
func (this *MqttHandle) OnSubscribed(g GlobalParams, topic string) error { func (this *MqttHandle) OnSubscribed(g req.GlobalParams, topic string) error {
return ErrFuncNotImplemented return ErrFuncNotImplemented
} }
func (this MqttHandle) OnUnsubscribed(g GlobalParams, topic string) error { func (this MqttHandle) OnUnsubscribed(g req.GlobalParams, topic string) error {
return ErrFuncNotImplemented 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 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 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 return nil, ErrFuncNotImplemented
} }

104
orm.go
View File

@ -3,7 +3,9 @@ package contracts
import ( import (
"reflect" "reflect"
"git.fsdpf.net/go/condition"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
) )
type OrmExecute int type OrmExecute int
@ -30,47 +32,18 @@ const (
RelationType_Right RelationType = "right" 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 ( const (
OrderByDirection_ASC OrderByDirection = db.ORDER_ASC OrderByDirection_ASC OrderByDirection = db.ORDER_ASC
OrderByDirection_DESC OrderByDirection = db.ORDER_DESC OrderByDirection_DESC OrderByDirection = db.ORDER_DESC
) )
type Orm interface { type Orm interface {
SetGlobalParams(g GlobalParams) Orm SetGlobalParams(g req.GlobalParams) Orm
GetModel(params ...string) Model GetModel(params ...string) Model
SetRelationModel(m Model) Model SetRelationModel(m Model) Model
SetQueryField(qf QueryField) error SetQueryField(qf req.QueryField) error
SetOrderBy(params []OrderBy) error SetOrderBy(params []OrderBy) error
SetCondition(cond Condition) error SetCondition(cond *condition.Condition) error
SetController(ctr OrmController) error SetController(ctr OrmController) error
Execute(OrmExecute) (any, error) Execute(OrmExecute) (any, error)
Clone(tx *db.Transaction) Orm Clone(tx *db.Transaction) Orm
@ -83,9 +56,9 @@ type Relation interface {
AppendTo(Model) AppendTo(Model)
Type() RelationType Type() RelationType
SetType(RelationType) SetType(RelationType)
SetCondition(Condition) Condition SetCondition(*condition.Condition) *condition.Condition
SetPrependCondition(Condition) Condition SetPrependCondition(*condition.Condition) *condition.Condition
GetCondition() Condition GetCondition() *condition.Condition
GetRelationResource() string GetRelationResource() string
GetRelationField() string GetRelationField() string
GetRelationForeignKey() string GetRelationForeignKey() string
@ -94,26 +67,26 @@ type Relation interface {
type Join interface { type Join interface {
Relation Relation
GetCode() string GetCode() string
GetResource() Resource GetResource() req.Resource
// GetDependencies(items []ResRelation, dependencies ...string) []string // GetDependencies(items []ResRelation, dependencies ...string) []string
Inject(dbBuilder *db.Builder, m Model) Inject(dbBuilder *db.Builder, m Model)
} }
type Model interface { type Model interface {
Relation Relation
ModelParam condition.TokenValue
GetCode() string GetCode() string
GetPrimaryKey() string GetPrimaryKey() string
GetQueryFieldsStruct(extends ...reflect.StructField) any GetQueryFieldsStruct(extends ...reflect.StructField) any
GetQueryFieldsSliceStruct(fields ...reflect.StructField) any GetQueryFieldsSliceStruct(fields ...reflect.StructField) any
GetAttribute() map[string]any GetAttribute() map[string]any
GetResult() reflect.Value GetResult() reflect.Value
GetResource() Resource GetResource() req.Resource
QueryBuilder() *db.Builder QueryBuilder() *db.Builder
GetTransaction() *db.Transaction GetTransaction() *db.Transaction
SetQueryField(QueryField) SetQueryField(req.QueryField)
SetRelationResult(code string, vItems reflect.Value) SetRelationResult(code string, vItems reflect.Value)
GetJoinsCode() []string GetJoinsCode() []string
SetAuthDB(ResAuthDB) SetAuthDB(req.ResAuthDB)
SetOrderBy(params ...OrderBy) Model SetOrderBy(params ...OrderBy) Model
SetGroupBy(params ...GroupBy) Model SetGroupBy(params ...GroupBy) Model
SetJoin(Join) Model SetJoin(Join) Model
@ -130,43 +103,8 @@ type Model interface {
// Exists() (bool, error) // Exists() (bool, error)
} }
type ModelParam interface {
GetParam(k string) GlobalParams
GetGlobalParamsUser() User
}
type OrmController interface { type OrmController interface {
AuthDB() ResAuthDB AuthDB() req.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
} }
type OrderBy interface { type OrderBy interface {
@ -192,13 +130,13 @@ type QueryWithRecursive interface {
// @param rForeignKey 关联外键, 如 id // @param rForeignKey 关联外键, 如 id
type NewOrmRelation func(t RelationType, m Model, rResource, rField, rForeignKey string) Model 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 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 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

View File

@ -1,6 +1,7 @@
package contracts package contracts
import ( import (
"git.fsdpf.net/go/req"
"github.com/samber/do" "github.com/samber/do"
"github.com/samber/lo" "github.com/samber/lo"
) )
@ -8,25 +9,25 @@ import (
type ResEvent string type ResEvent string
type ResListener interface { type ResListener interface {
Insert(new map[string]any, u User, id int64) error Insert(new map[string]any, u req.User, id int64) error
Update(new map[string]any, u User, old map[string]any) error Update(new map[string]any, u req.User, old map[string]any) error
Delete(old map[string]any, u User) error Delete(old map[string]any, u req.User) error
GetResource() Resource GetResource() req.Resource
GetCode() string GetCode() string
} }
type BaseListener struct { type BaseListener struct {
Container *do.Injector Container *do.Injector
res Resource // 监听资源 res req.Resource // 监听资源
code string // code code string // code
events []string // 监听动作 events []string // 监听动作
} }
func (this BaseListener) GetCode() string { func (this BaseListener) GetCode() string {
return this.code return this.code
} }
func (this BaseListener) GetResource() Resource { func (this BaseListener) GetResource() req.Resource {
return this.res return this.res
} }
@ -34,18 +35,18 @@ func (this BaseListener) HasEvent(event string) bool {
return lo.Contains(this.events, event) 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 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 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 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} return &BaseListener{code: code, res: res, Container: container}
} }

View File

@ -1,111 +1,6 @@
package contracts package contracts
import ( import "git.fsdpf.net/go/req"
"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
}
// 资源 // 资源
type GetResource func(code string) (Resource, bool) type GetResource func(code string) (req.Resource, bool)

View File

@ -1,10 +0,0 @@
package contracts
import (
"net/http"
)
type HttpResponse interface {
Get(path ...string) GlobalParams
Send(w http.ResponseWriter, r *http.Request)
}

View File

@ -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
}

View File

@ -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)}
}

View File

@ -5,34 +5,36 @@ import (
"reflect" "reflect"
"strings" "strings"
"git.fsdpf.net/go/condition"
"git.fsdpf.net/go/contracts" "git.fsdpf.net/go/contracts"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/utils"
"github.com/samber/do" "github.com/samber/do"
"github.com/samber/lo" "github.com/samber/lo"
"github.com/spf13/cast" "github.com/spf13/cast"
) )
type Operation struct { type Operation struct {
Uuid string `json:"uuid"` Uuid string `json:"uuid"`
Name string `json:"name"` Name string `json:"name"`
Code string `json:"code"` Code string `json:"code"`
Icon string `json:"icon"` Icon string `json:"icon"`
Size string `json:"size"` Size string `json:"size"`
Block bool `json:"block"` Block bool `json:"block"`
Ghost bool `json:"ghost"` Ghost bool `json:"ghost"`
Shape string `json:"shape"` Shape string `json:"shape"`
Type string `json:"type"` Type string `json:"type"`
PopConfirm any `json:"popConfirm,omitempty"` PopConfirm any `json:"popConfirm,omitempty"`
Widget string `json:"widget"` Widget string `json:"widget"`
WidgetType string `json:"widgetType"` WidgetType string `json:"widgetType"`
WidgetProps any `json:"widgetProps"` WidgetProps any `json:"widgetProps"`
WidgetSetting any `json:"widgetSetting"` WidgetSetting any `json:"widgetSetting"`
WidgetContainerSetting any `json:"widgetContainerSetting"` WidgetContainerSetting any `json:"widgetContainerSetting"`
IsRefresh int `json:"isRefresh"` IsRefresh int `json:"isRefresh"`
NoAuthType string `json:"noAuthType"` NoAuthType string `json:"noAuthType"`
Roles []string `json:"-"` Roles []string `json:"-"`
Children []Operation `json:"children,omitempty"` Children []Operation `json:"children,omitempty"`
AccessCondition contracts.Condition `json:"-"` AccessCondition *condition.Condition `json:"-"`
} }
type OperationAccess struct { 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) { func (o Operation) ToDBColumn(model contracts.Model, container *do.Injector) (column db.Expression, field reflect.StructField) {
GetOrmConditionByRes := do.MustInvoke[contracts.GetOrmConditionByRes](container) GetOrmConditionByRes := do.MustInvoke[contracts.GetOrmConditionByRes](container)
NewOrmCondition := do.MustInvoke[contracts.NewOrmCondition](container)
uuid := strings.ReplaceAll(o.Uuid, "-", "_") uuid := strings.ReplaceAll(o.Uuid, "-", "_")
// 主键 // 主键
pk := model.GetCode() + "." + model.GetPrimaryKey() 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() { if c := GetOrmConditionByRes(o.Uuid, "operation access condition "+uuid); c.IsNotEmpty() {
cond.SetCondition(c) cond.SetCondition(c)
@ -63,7 +64,7 @@ func (o Operation) ToDBColumn(model contracts.Model, container *do.Injector) (co
// 主键类型 // 主键类型
tPkType := reflect.TypeOf("") 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 tPkType = tPk.Type
} }
field = reflect.StructField{ field = reflect.StructField{
@ -149,7 +150,7 @@ func NewOperationAccess(m contracts.Model) OperationAccess {
// 主键类型 // 主键类型
tPkType := reflect.String 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() { switch tPk.Type.Kind() {
case reflect.Int, reflect.Int32, reflect.Int64, case reflect.Int, reflect.Int32, reflect.Int64,
reflect.Uint, reflect.Uint32, reflect.Uint64: reflect.Uint, reflect.Uint32, reflect.Uint64:

View File

@ -8,6 +8,7 @@ import (
"strings" "strings"
"git.fsdpf.net/go/contracts" "git.fsdpf.net/go/contracts"
"git.fsdpf.net/go/req"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/samber/lo" "github.com/samber/lo"
) )
@ -40,8 +41,8 @@ var wsUpgrader = websocket.Upgrader{
}, },
} }
func (this RawResponse) Get(path ...string) contracts.GlobalParams { func (this RawResponse) Get(path ...string) req.GlobalParams {
return lo.Ternary(len(path) == 0, NewGlobalParam(string(this.raw), nil), NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, "."))) 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) { 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 { func (this JsonResponse) Get(path ...string) req.GlobalParams {
return lo.Ternary(len(path) == 0, NewGlobalParam(string(this.raw), nil), NewGlobalParam(string(this.raw), nil).Get(strings.Join(path, "."))) 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) { 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{ if resp, err := json.Marshal(map[string]any{
"code": this.code, "code": this.code,
"msg": this.msg, "msg": this.msg,
}); err == nil { }); 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 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{ if resp, err := json.Marshal(map[string]any{
"code": this.code, "code": this.code,
"msg": this.msg, "msg": this.msg,
"error": string(this.stack), "error": string(this.stack),
}); err == nil { }); 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 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{ if resp, err := json.Marshal(map[string]any{
"name": this.name, "name": this.name,
"disposition": this.disposition, "disposition": this.disposition,
}); err == nil { }); 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 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} return &RawResponse{raw: b}
} }
func NewJsonResponse(b []byte) contracts.HttpResponse { func NewJsonResponse(b []byte) req.HttpResponse {
return &JsonResponse{raw: b} 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} 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} 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()))) 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 var err error
// fmt.Printf("%#v \n", data) // fmt.Printf("%#v \n", data)
switch v := data.(type) { switch v := data.(type) {
case contracts.HttpResponse: case req.HttpResponse:
return v return v
case contracts.Errno: case contracts.Errno:
return NewMsgResponse(v.Error(), v.Code) return NewMsgResponse(v.Error(), v.Code)

View File

@ -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的CapLen以及数组的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
}

View File

@ -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))
}

53
user.go
View File

@ -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
}
}

View File

@ -4,6 +4,7 @@ import (
"net/http" "net/http"
"git.fsdpf.net/go/db" "git.fsdpf.net/go/db"
"git.fsdpf.net/go/req"
) )
type UserApprovalExecute int type UserApprovalExecute int
@ -51,9 +52,9 @@ type UserApproval interface {
// 审批流名称 // 审批流名称
Name() string 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) Execute(id int64, status UserApprovalExecute, r *http.Request, tx *db.Transaction) (current, next UserApprovalFlow, err error)
} }

35
ws.go Normal file
View File

@ -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
}