diff --git a/@doc/v0.2.md b/@doc/v0.2.md index dfd8c65..ce4c4d3 100755 --- a/@doc/v0.2.md +++ b/@doc/v0.2.md @@ -4,4 +4,7 @@ 1. 由全局配置改成apijson实例,可创建不同实例对应不同的内容 2. 代码内部 传递的accessName 都为 _access 配置中的alias -3. access/request配置可从配置文件中获取 \ No newline at end of file +3. access/request配置可从配置文件中获取 + +# vX.x +- 给action 增加then/catch/before/after等方法? \ No newline at end of file diff --git a/action/action.go b/action/action.go index 93bdc1f..b390b0d 100755 --- a/action/action.go +++ b/action/action.go @@ -2,6 +2,8 @@ package action import ( "context" + "strings" + "github.com/glennliao/apijson-go/config" "github.com/glennliao/apijson-go/consts" "github.com/glennliao/apijson-go/model" @@ -9,13 +11,12 @@ import ( "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" - "strings" ) // Action 非get查询的request表中的请求 type Action struct { ctx context.Context - tagRequest *config.Request + tagRequest *config.RequestConfig method string req model.Map @@ -30,7 +31,7 @@ type Action struct { // 关闭 request 验证开关, 默认否 NoRequestVerify bool - //Access *config.Access + // Access *config.Access // dbFieldStyle 数据库字段命名风格 请求传递到数据库中 DbFieldStyle config.FieldStyle @@ -75,7 +76,7 @@ func (a *Action) parse() error { } structure, ok := structures[key] if !ok { - if structure, ok = structures[structuresKey]; !ok { //User[]可读取User或者User[] + if structure, ok = structures[structuresKey]; !ok { // User[]可读取User或者User[] return gerror.New("structure错误: 400, 缺少" + key) } } @@ -158,7 +159,7 @@ func (a *Action) Result() (model.Map, error) { return ret, err } -func checkTag(req model.Map, method string, requestCfg *config.ActionConfig) (*config.Request, error) { +func checkTag(req model.Map, method string, requestCfg *config.ActionConfig) (*config.RequestConfig, error) { _tag, ok := req["tag"] if !ok { return nil, gerror.New("tag 缺失") diff --git a/action/hook.go b/action/hook.go index 21cba70..c443654 100755 --- a/action/hook.go +++ b/action/hook.go @@ -10,7 +10,7 @@ const ( ) type Hook struct { - For string // + For []string // // Exec 事务外 BeforeNodeExec func(ctx context.Context, n *Node, method string) error AfterNodeExec func(ctx context.Context, n *Node, method string) error @@ -23,7 +23,9 @@ type Hook struct { var hooksMap = map[string][]Hook{} func RegHook(h Hook) { - hooksMap[h.For] = append(hooksMap[h.For], h) + for _, item := range h.For { + hooksMap[item] = append(hooksMap[item], h) + } } func EmitHook(ctx context.Context, hookAt int, node *Node, method string) error { diff --git a/config/action_config.go b/config/action_config.go index e876a2f..ad77ab9 100755 --- a/config/action_config.go +++ b/config/action_config.go @@ -2,11 +2,12 @@ package config import ( "context" + "github.com/glennliao/apijson-go/model" ) type ActionConfig struct { - requestConfig *RequestConfig + requestConfig *RequestConfigs access *Access functions *functions rowKeyGenFuncMap map[string]RowKeyGenFuncHandler @@ -29,7 +30,7 @@ func (c *ActionConfig) Func(name string) Func { return c.functions.funcMap[name] } -func (c *ActionConfig) GetRequest(tag string, method string, version string) (*Request, error) { +func (c *ActionConfig) GetRequest(tag string, method string, version string) (*RequestConfig, error) { return c.requestConfig.GetRequest(tag, method, version) } diff --git a/config/config.go b/config/config.go index 0b823de..cd244c8 100755 --- a/config/config.go +++ b/config/config.go @@ -10,7 +10,7 @@ func RegAccessListProvider(name string, provider AccessListProvider) { accessListProviderMap[name] = provider } -type RequestListProvider func(ctx context.Context) []Request +type RequestListProvider func(ctx context.Context) []RequestConfig var requestListProviderMap = make(map[string]RequestListProvider) @@ -50,9 +50,9 @@ type Config struct { accessList []AccessConfig - requestConfig *RequestConfig - queryConfig *QueryConfig - actionConfig *ActionConfig + requestConfigs *RequestConfigs + queryConfig *QueryConfig + actionConfig *ActionConfig } func New() *Config { @@ -117,7 +117,7 @@ func (c *Config) ReLoad() { requestListProvider := requestListProviderMap[c.RequestListProvider] if requestListProvider != nil { requestList := requestListProvider(ctx) - c.requestConfig = NewRequestConfig(requestList) + c.requestConfigs = NewRequestConfig(requestList) } dbMetaProvider := dbMetaProviderMap[c.DbMetaProvider] @@ -134,7 +134,7 @@ func (c *Config) ReLoad() { } c.actionConfig = &ActionConfig{ - requestConfig: c.requestConfig, + requestConfig: c.requestConfigs, access: c.Access, functions: c.Functions, rowKeyGenFuncMap: c.rowKeyGenFuncMap, diff --git a/config/functions.go b/config/functions.go index 1a5e235..fd8d856 100755 --- a/config/functions.go +++ b/config/functions.go @@ -3,6 +3,7 @@ package config import ( "context" "fmt" + "github.com/glennliao/apijson-go/model" "github.com/gogf/gf/v2/frame/g" ) @@ -15,6 +16,7 @@ type ParamItem struct { type Func struct { ParamList []ParamItem + Batch bool // 是否为批量处理, 例如在获取列表后一次性将id传入, 然后按照传入的参数数组返回结果数组 Handler func(ctx context.Context, param model.Map) (res any, err error) } diff --git a/config/query_config.go b/config/query_config.go index 9392e17..76c7590 100755 --- a/config/query_config.go +++ b/config/query_config.go @@ -1,8 +1,9 @@ package config import ( - "github.com/samber/lo" "net/http" + + "github.com/samber/lo" ) type QueryConfig struct { diff --git a/config/request_config.go b/config/request_config.go index da362e7..466d2d7 100755 --- a/config/request_config.go +++ b/config/request_config.go @@ -1,15 +1,16 @@ package config import ( + "strings" + "github.com/glennliao/apijson-go/consts" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" - "strings" ) -type Request struct { +type RequestConfig struct { Debug int8 Version string Method string @@ -38,13 +39,13 @@ type Structure struct { Remove []string `json:"REMOVE,omitempty"` } -type RequestConfig struct { - requestMap map[string]*Request +type RequestConfigs struct { + requestMap map[string]*RequestConfig } -func NewRequestConfig(requestList []Request) *RequestConfig { - c := RequestConfig{} - requestMap := make(map[string]*Request) +func NewRequestConfig(requestList []RequestConfig) *RequestConfigs { + c := RequestConfigs{} + requestMap := make(map[string]*RequestConfig) for _, _item := range requestList { item := _item @@ -71,7 +72,7 @@ func getRequestFullKey(tag string, method string, version string) string { return tag + "@" + method + "@" + version } -func (c *RequestConfig) GetRequest(tag string, method string, version string) (*Request, error) { +func (c *RequestConfigs) GetRequest(tag string, method string, version string) (*RequestConfig, error) { if version == "" || version == "-1" || version == "0" { version = "latest" diff --git a/consts/node.go b/consts/node.go index 7703322..86864c8 100755 --- a/consts/node.go +++ b/consts/node.go @@ -18,6 +18,7 @@ const ( Count = "count" // page size Total = "total" Query = "query" + Alias = "@alias" ) const ( diff --git a/drivers/goframe/config/config.go b/drivers/goframe/config/config.go index fb9686b..d12cc63 100755 --- a/drivers/goframe/config/config.go +++ b/drivers/goframe/config/config.go @@ -16,8 +16,8 @@ var ( ProviderName = "db" ) -func RequestListProvider(ctx context.Context) []config.Request { - var requestList []config.Request +func RequestListProvider(ctx context.Context) []config.RequestConfig { + var requestList []config.RequestConfig err := g.DB().Model(TableRequest).OrderAsc("version").Scan(&requestList) if err != nil { panic(err) @@ -31,14 +31,14 @@ func RequestListProvider(ctx context.Context) []config.Request { } // provider处理 - //if strings.ToLower(tag) != tag { + // if strings.ToLower(tag) != tag { // // 本身大写, 如果没有外层, 则套一层 // if _, ok := item.Structure[tag]; !ok { // item.Structure = map[string]any{ // tag: item.Structure, // } // } - //} + // } for k, v := range item.Structure { structure := config.Structure{} diff --git a/drivers/json/config/config.go b/drivers/json/config/config.go new file mode 100644 index 0000000..16fda83 --- /dev/null +++ b/drivers/json/config/config.go @@ -0,0 +1,47 @@ +package config + +import ( + "context" + + "github.com/glennliao/apijson-go/config" + "github.com/gogf/gf/v2/util/gconv" +) + +func RequestListProvider(ctx context.Context, jsonStr string) config.RequestListProvider { + + return func(ctx context.Context) []config.RequestConfig { + var requestList []config.RequestConfig + err := gconv.Scan(jsonStr, &requestList) + if err != nil { + panic(err) + } + for i, request := range requestList { + if _, ok := request.Structure[request.Tag]; !ok { + requestList[i].Structure = map[string]*config.Structure{ + request.Tag: { + Must: nil, + Refuse: nil, + Unique: nil, + Insert: nil, + Update: nil, + Replace: nil, + Remove: nil, + }, + } + } + } + return requestList + } + +} + +func AccessListProvider(ctx context.Context, jsonStr string) config.AccessListProvider { + return func(ctx context.Context) []config.AccessConfig { + var accessList []config.AccessConfig + err := gconv.Scan(jsonStr, &accessList) + if err != nil { + panic(err) + } + return accessList + } +} diff --git a/query/node.go b/query/node.go index a548cc5..81bb742 100755 --- a/query/node.go +++ b/query/node.go @@ -60,7 +60,7 @@ type Node struct { // 节点的请求数据 req model.Map - simpleReqVal string //非对象结构 + simpleReqVal string // 非对象结构 // 节点数据执行器 executor executor.QueryExecutor @@ -71,6 +71,8 @@ type Node struct { // 执行完毕 finish bool + later bool // 后续执行 + ret any err error @@ -178,7 +180,7 @@ func (n *Node) buildChild() error { return nil } - //最大深度检查 + // 最大深度检查 maxDeep := n.queryContext.queryConfig.MaxTreeDeep() if len(strings.Split(n.Path, "/")) > maxDeep { return gerror.Newf("deep(%s) > %d", n.Path, maxDeep) diff --git a/query/node_func.go b/query/node_func.go index 0e5f359..5e50e57 100755 --- a/query/node_func.go +++ b/query/node_func.go @@ -25,10 +25,18 @@ func (h *funcNode) fetch() { _func := queryConfig.Func(functionName) + if n.isList && _func.Batch { + n.later = true + return + } + param := model.Map{} for i, item := range _func.ParamList { valNode := n.queryContext.pathNodes[paramKeys[i]] + // if valNode == nil { + // continue + // } if valNode.ret != nil { param[item.Name] = valNode.ret } else { diff --git a/query/node_query.go b/query/node_query.go index 43041e6..aef91ae 100755 --- a/query/node_query.go +++ b/query/node_query.go @@ -261,7 +261,7 @@ func (q *queryNode) fetch() { functionName, paramKeys := util.ParseFunctionsStr(v.(string)) _func := queryConfig.Func(functionName) - if n.isList { + if n.isList && n.ret != nil { for i, item := range n.ret.([]model.Map) { param := model.Map{} diff --git a/query/node_struct.go b/query/node_struct.go index 384c64a..9e8ba0d 100755 --- a/query/node_struct.go +++ b/query/node_struct.go @@ -1,11 +1,12 @@ package query import ( + "path/filepath" + "strings" + "github.com/glennliao/apijson-go/consts" "github.com/glennliao/apijson-go/model" "github.com/gogf/gf/v2/errors/gerror" - "path/filepath" - "strings" ) type structNode struct { @@ -134,9 +135,9 @@ func (h *structNode) result() { k = k[0 : len(k)-2] } - // todo 增加alias ?用来重命名返回的key,避免前端调整取值 - if node.req["@alias"] != nil { - k = node.req["@alias"].(string) + // 增加alias 用来重命名返回的key,避免前端调整取值 + if node.req[consts.Alias] != nil { + k = node.req[consts.Alias].(string) } retMap[k], err = node.Result() @@ -148,6 +149,7 @@ func (h *structNode) result() { n.err = err } } + n.ret = retMap } }