package condflow import ( "strings" "git.fsdpf.net/go/reflux/valuex" "git.fsdpf.net/go/req" "github.com/samber/do/v2" ) const inputKey = "input" // FlowContext 流程执行上下文接口 // 用于在执行器方法调用时传递上下文信息 type FlowContext interface { Get(name string) valuex.Accessor // GetParam, Get 的别名 GetParam(key string) valuex.Accessor // Input 获取初始输入数据 Input() valuex.Accessor // LastResult 获取上一个 PushResult 的值 LastResult() valuex.Accessor // User 获取当前用户信息 User() req.User } // Context 执行器调用上下文接口,包含资源信息 type Context interface { FlowContext Res() req.Resource } // flowContext 执行器上下文实现 type flowContext struct { lookuper // user 用户信息 user req.User // 执行动作容器 executors do.Injector } type context struct { FlowContext res req.Resource } // NewFlowContext 创建新的执行器上下文 // input: 初始传入参数 // user: 用户信息 func NewFlowContext(app do.Injector, input valuex.Accessor, user req.User) *flowContext { return &flowContext{ lookuper: lookuper{ results: []result{ { key: inputKey, value: input, }, }, }, executors: app, user: user, } } // User 获取当前用户信息 func (c *flowContext) User() req.User { return c.user } func (c *flowContext) Get(key string) valuex.Accessor { if v, ok := c.Lookup(key); ok { return v } return valuex.Nil } func (c *flowContext) GetParam(key string) valuex.Accessor { return c.Get(key) } func (c *flowContext) GetActionInvoker(key string) (ActionInvoker, error) { index := strings.SplitN(key, "@", 2) invoker, err := do.InvokeNamed[ActionInvoker](c.executors, index[0]) if err != nil { return nil, err } return invoker, nil } // Fork 基于当前上下文创建新的上下文,使用新的 input // 新上下文会继承当前上下文的 user 和 executors,但使用新的 input 和空的 results func (c *flowContext) Fork(input valuex.Accessor) *flowContext { return &flowContext{ lookuper: lookuper{ results: []result{ { key: inputKey, value: input, }, }, }, executors: c.executors, user: c.user, } } func (ac *context) Res() req.Resource { return ac.res }