Skip to content

Commit 33fdbd9

Browse files
committed
access 中的req也与hook使用相同的field style + fix hook无法事务内
1 parent 2bbcb25 commit 33fdbd9

File tree

11 files changed

+173
-152
lines changed

11 files changed

+173
-152
lines changed

action/action.go

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ type Action struct {
4444
NewAction func(ctx context.Context, method string, req model.Map) *Action
4545

4646
HooksMap map[string][]*Hook
47+
48+
ret model.Map
4749
}
4850

4951
func New(ctx context.Context, actionConfig *config.ActionConfig, method string, req model.Map) *Action {
@@ -118,67 +120,68 @@ func (a *Action) parse() error {
118120
return nil
119121
}
120122

121-
func (a *Action) Result() (model.Map, error) {
122-
123-
err := a.parse()
124-
if err != nil {
125-
return nil, err
123+
func (a *Action) hookExecute(i int, inTransaction bool) error {
124+
k := a.tagRequest.ExecQueue[i]
125+
node := a.children[k]
126+
nodeHookReq := &HookReq{
127+
Node: node,
128+
Method: a.method,
129+
ctx: a.ctx,
130+
nextIdx: -1,
131+
isInTransaction: inTransaction,
132+
hooks: getHooksByAccessName(a.HooksMap, k),
126133
}
127134

128-
ret := model.Map{}
129-
130-
for _, k := range a.tagRequest.ExecQueue {
131-
node := a.children[k]
135+
nodeHookReq.handler = func(ctx context.Context, n *Node, method string) error {
132136

133-
actionHookReq := &HookReq{
134-
Node: node,
135-
Method: a.method,
136-
ctx: a.ctx,
137-
nextIdx: -1,
138-
isInTransaction: false,
139-
hooks: getHooksByAccessName(a.HooksMap, k),
137+
if i+1 < len(a.tagRequest.ExecQueue) {
138+
return a.hookExecute(i+1, inTransaction)
140139
}
141140

142-
actionHookReq.handler = func(ctx context.Context, n *Node, method string) error {
141+
// 执行完了普通hook的before,开始执行事务内
142+
if !inTransaction {
143+
143144
transactionHandler := noTransactionHandler
144145

145146
if a.tagRequest.Transaction != nil && *a.tagRequest.Transaction == true {
146147
h := GetTransactionHandler(a.ctx, a)
147148
if h == nil {
148-
err = consts.NewSysErr("transaction handler is nil")
149+
err := consts.NewSysErr("transaction handler is nil")
149150
return err
150151
}
151-
152152
transactionHandler = h
153-
154153
}
155154

156-
err = transactionHandler(a.ctx, func(ctx context.Context) error {
157-
for _, k := range a.tagRequest.ExecQueue {
158-
node := a.children[k]
159-
ret[k], err = node.execute(ctx, a.method)
160-
if err != nil {
161-
return err
162-
}
163-
}
164-
return nil
155+
err := transactionHandler(a.ctx, func(ctx context.Context) error {
156+
return a.hookExecute(0, !inTransaction)
165157
})
166158

167159
return err
168160
}
169161

170-
err = node.reqUpdate()
171-
if err != nil {
172-
return nil, err
173-
}
162+
var err error
163+
a.ret[k], err = node.execute(ctx, a.method)
164+
return err
165+
}
174166

175-
err := actionHookReq.Next()
176-
if err != nil {
177-
return nil, err
178-
}
167+
err := nodeHookReq.Next()
168+
return err
169+
}
170+
171+
func (a *Action) Result() (model.Map, error) {
172+
173+
err := a.parse()
174+
if err != nil {
175+
return nil, err
179176
}
180177

181-
return ret, nil
178+
a.ret = model.Map{}
179+
180+
err = a.hookExecute(0, false)
181+
if err != nil {
182+
a.err = err
183+
}
184+
return a.ret, err
182185
}
183186

184187
func checkTag(req model.Map, method string, requestCfg *config.ActionConfig) (*config.RequestConfig, error) {

action/hook.go

Lines changed: 10 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,6 @@ import (
55
"net/http"
66
)
77

8-
// const (
9-
// BeforeNodeExec = iota
10-
// AfterNodeExec
11-
// BeforeExecutorDo
12-
// AfterExecutorDo
13-
// )
14-
158
type HookReq struct {
169
Node *Node
1710
Method string
@@ -40,17 +33,7 @@ func (r *HookReq) Next() error {
4033

4134
var h *Hook
4235

43-
for r.nextIdx < len(r.hooks) && h == nil {
44-
45-
if r.nextIdx+1 >= len(r.hooks) {
46-
if r.isInTransaction {
47-
// finish all
48-
return r.handler(r.ctx, r.Node, r.Method)
49-
} else {
50-
r.nextIdx = -1
51-
r.isInTransaction = true
52-
}
53-
}
36+
for r.nextIdx+1 < len(r.hooks) && h == nil {
5437

5538
r.nextIdx++
5639

@@ -70,13 +53,17 @@ func (r *HookReq) Next() error {
7053

7154
}
7255

73-
if r.nextIdx < len(r.hooks) {
74-
if r.isInTransaction {
75-
return h.HandlerInTransaction(r.ctx, r)
76-
}
56+
if h != nil {
57+
if r.nextIdx < len(r.hooks) {
58+
if r.isInTransaction {
59+
return h.HandlerInTransaction(r.ctx, r)
60+
}
7761

78-
return h.Handler(r.ctx, r)
62+
return h.Handler(r.ctx, r)
63+
}
7964
}
65+
66+
return r.handler(r.ctx, r.Node, r.Method)
8067
}
8168

8269
}
@@ -95,42 +82,3 @@ func getHooksByAccessName(hooksMap map[string][]*Hook, accessName string) []*Hoo
9582
hooks := append(hooksMap["*"], hooksMap[accessName]...)
9683
return hooks
9784
}
98-
99-
//
100-
// type Hook2 struct {
101-
// For []string //
102-
// // Exec 事务外
103-
// BeforeNodeExec func(ctx context.Context, n *Node, method string) error
104-
// AfterNodeExec func(ctx context.Context, n *Node, method string) error
105-
//
106-
// // Do 事务内
107-
// BeforeExecutorDo func(ctx context.Context, n *Node, method string) error
108-
// AfterExecutorDo func(ctx context.Context, n *Node, method string) error
109-
// }
110-
//
111-
// func emitHook(ctx context.Context, hooksMap map[string][]Hook, hookAt int, node *Node, method string) error {
112-
//
113-
// hooks := append(hooksMap["*"], hooksMap[node.Key]...)
114-
// for _, hook := range hooks {
115-
//
116-
// var handler func(ctx context.Context, n *Node, method string) error
117-
// switch hookAt {
118-
// case BeforeNodeExec:
119-
// handler = hook.BeforeNodeExec
120-
// case AfterNodeExec:
121-
// handler = hook.AfterNodeExec
122-
// case BeforeExecutorDo:
123-
// handler = hook.BeforeExecutorDo
124-
// case AfterExecutorDo:
125-
// handler = hook.AfterExecutorDo
126-
// }
127-
//
128-
// if handler != nil {
129-
// err := handler(ctx, node, method)
130-
// if err != nil {
131-
// return err
132-
// }
133-
// }
134-
// }
135-
// return nil
136-
// }

action/node.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/glennliao/apijson-go/consts"
1010
"github.com/glennliao/apijson-go/model"
1111
"github.com/glennliao/apijson-go/util"
12+
"github.com/gogf/gf/v2/errors/gerror"
1213
"github.com/samber/lo"
1314
)
1415

@@ -190,12 +191,19 @@ func (n *Node) whereUpdate(ctx context.Context, method string, accessRoles []str
190191

191192
condition := config.NewConditionRet()
192193

194+
req := model.Map{}
195+
196+
for k, v := range item {
197+
k := n.Action.DbFieldStyle(ctx, n.RowKey, k)
198+
req[k] = v
199+
}
200+
193201
conditionReq := config.ConditionReq{
194202
AccessName: n.Key,
195203
TableAccessRoleList: accessRoles,
196204
Method: method,
197205
NodeRole: n.Role,
198-
NodeReq: item,
206+
NodeReq: req,
199207
}
200208

201209
err := n.Action.ActionConfig.ConditionFunc(ctx, conditionReq, condition)
@@ -205,11 +213,11 @@ func (n *Node) whereUpdate(ctx context.Context, method string, accessRoles []str
205213
}
206214

207215
if method == http.MethodPost {
208-
for k, v := range condition.Where() {
216+
for k, v := range condition.AllWhere() {
209217
n.Data[i][k] = v
210218
}
211219
} else {
212-
for k, v := range condition.Where() {
220+
for k, v := range condition.AllWhere() {
213221
n.Where[i][k] = v
214222
}
215223
}
@@ -343,7 +351,7 @@ func (n *Node) do(ctx context.Context, method string) (ret model.Map, err error)
343351

344352
rowKeyVal, err = n.Action.ActionConfig.RowKeyGen(ctx, access.RowKeyGen, n.Key, n.tableName, n.Data[i])
345353
if err != nil {
346-
return nil, err
354+
return nil, gerror.Wrap(err, "RowKeyGen")
347355
}
348356

349357
for k, v := range rowKeyVal {

action/z_hook_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package action
2+
3+
import (
4+
"testing"
5+
)
6+
7+
func TestHook(t *testing.T) {
8+
9+
}

config/access.go

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,34 +16,6 @@ type ConditionReq struct {
1616
NodeRole string // 节点的角色
1717
}
1818

19-
type ConditionRet struct {
20-
condition map[string]any
21-
rawCondition map[string][]any
22-
}
23-
24-
func NewConditionRet() *ConditionRet {
25-
c := ConditionRet{
26-
condition: map[string]any{},
27-
rawCondition: map[string][]any{},
28-
}
29-
return &c
30-
}
31-
32-
func (c *ConditionRet) Add(k string, v any) {
33-
c.condition[k] = v
34-
}
35-
36-
func (c *ConditionRet) AddRaw(k string, v ...any) {
37-
c.rawCondition[k] = v
38-
}
39-
40-
func (c *ConditionRet) Where() map[string]any {
41-
if len(c.rawCondition) > 0 {
42-
c.condition[consts.Raw] = c.rawCondition
43-
}
44-
return c.condition
45-
}
46-
4719
type AccessCondition func(ctx context.Context, req ConditionReq, condition *ConditionRet) error
4820

4921
type RoleReq struct {
@@ -79,6 +51,8 @@ type Access struct {
7951

8052
func NewAccess() *Access {
8153

54+
// fixme 统一access字段名大小写问题
55+
// fixme
8256
a := &Access{}
8357
a.ConditionFunc = defaultCondition
8458
a.DefaultRoleFunc = defaultRole

config/access_condition.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package config
2+
3+
import (
4+
"github.com/glennliao/apijson-go/consts"
5+
)
6+
7+
type ConditionRet struct {
8+
condition map[string]any
9+
rawCondition map[string][]any
10+
}
11+
12+
func NewConditionRet() *ConditionRet {
13+
c := ConditionRet{
14+
condition: map[string]any{},
15+
rawCondition: map[string][]any{},
16+
}
17+
return &c
18+
}
19+
20+
func (c *ConditionRet) Add(k string, v any) {
21+
c.condition[k] = v
22+
}
23+
24+
func (c *ConditionRet) AddRaw(k string, v ...any) {
25+
c.rawCondition[k] = v
26+
}
27+
28+
func (c *ConditionRet) AllWhere() map[string]any {
29+
if len(c.rawCondition) > 0 {
30+
c.condition[consts.Raw] = c.rawCondition
31+
}
32+
return c.condition
33+
}

config/functions.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,25 @@ import (
1212
const (
1313
ParamTypeInt = "int"
1414
ParamTypeString = "string"
15+
FromRes = "res" // 只从响应的数据字段中取, 不从用户传递的数据取
1516
)
1617

1718
type ParamItem struct {
1819
Type string
1920
Name string
2021
Desc string
2122
Default any
23+
From string // 指定参数从何处取值
24+
V string // 参数校验规则
2225
}
2326

2427
type Func struct {
25-
Desc string // 描述
26-
ParamList []ParamItem // 参数列表
27-
Batch bool // 是否为批量处理, 例如在获取列表后一次性将id传入, 然后按照传入的参数数组返回结果数组
28-
Handler func(ctx context.Context, param model.FuncParam) (res any, err error)
28+
Desc string // 描述
29+
// 参数可直接读取函数参数传递过来的, ''括起来
30+
ParamList []ParamItem // 参数列表 // fixme 限制参数来源,强制用户传递的无法覆盖内部的,减免权限的重复判断, 参数校验限制 , v (最大值,最小值,默认值, 自定义校验。 使用gvaild)
31+
32+
Batch bool // 是否为批量处理, 例如在获取列表后一次性将id传入, 然后按照传入的参数数组返回结果数组
33+
Handler func(ctx context.Context, param model.FuncParam) (res any, err error)
2934
}
3035

3136
type functions struct {
@@ -49,7 +54,7 @@ func (f *functions) Call(ctx context.Context, name string, param g.Map) (any, er
4954
return f.funcMap[name].Handler(ctx, params)
5055
}
5156

52-
// functions 提供的功能
57+
// functions 可能提供的功能
5358
// 1. 增加响应字段 -> 该字段需要与系统中别的数据结合处理,如果只是静态处理(去空格,与常量拼接等可直接前端处理即可) 目前会不受_access_ext 中field_get控制, 需处理. 响应字段修改(脱敏、加密、字典转换) 不提供前端控制, 由_access_ext处理
5459
// 2. 通过func节点获取一些系统信息
5560
// 3. actions 中 自定义校验参数、自定义校验权限, 请求体修改(批量字段替换处理?)

0 commit comments

Comments
 (0)