Files
condition/README.md
T
what dcfd2f42da docs: 补充 README,说明当前分支的能力范围
配合 v1-legacy 维护分支的拆分,记录 master 这条线(Condition/ConditionExpr
表达式树、TokenValue、JSON 序列化、engine 规则引擎)目前有哪些能力,跟
v1-legacy 分支做区分;顺带记一下 engine.go 那个已知的 nil user 问题。
2026-08-21 09:03:29 +08:00

3.2 KiB
Raw Blame History

git.fsdpf.net/go/conditionmaster

条件表达式 DSL:把一组条件(等值/比较/模糊匹配/IN 等)组织成可嵌套的 AND/OR 树,渲染成 db-v2 的表达式(db.Expression),供权限过滤、规则引擎等场景复用同一套条件描述。配合 "-v2" 系列项目使用。

这个仓库有什么

Condition/ConditionExpr

  • Condition:条件树的节点,AppendTo/SetCondition/SetExpr 组装子条件/表达式, ToSql(m TokenValue) db.Expression 渲染成 db-v2 的表达式树——内部用 exp.NewExpressionList(this.typ, conditions...) 构造,不是手工拼 SQL 字符串。 ConditionTypeexp.ExpressionListTypeAND/OR)的类型别名。
  • ConditionExpr:单个表达式(字段 + 操作符 + 值),ConditionOperatorexp.BooleanOperation 的类型别名(EQ/NE/GT/LIKE/IN 等),跟 db-v2 的操作符 体系直接对齐,不用自己维护一份字符串常量再转换。
  • util.goToConditionOperator(op string) ConditionOperator 把字符串(比如从配置/请求 参数解析出来的)转成 ConditionOperator

TokenValuetoken_value.go

条件渲染时取值用的接口:GetParam(k string) valuex.Accessor(配合 reflux/valuex 统一属性 访问方式)+ User() req.UserNewTokenValue(x valuex.Accessor, opts ...tValueOpt) 构造, WithUser(user) 显式指定用户;不传时会尝试从 x 上探测 User() 方法,两者都拿不到会 panic——TokenValue 必须绑定一个具体用户,不支持匿名/无用户场景。

JSON 序列化(condition_json.go

Condition/ConditionExpr 都实现了 MarshalJSON/UnmarshalJSON(内部过一层 DTO 结构避免 递归),FromMap(m map[string]any) (*Condition, error) 直接从已解析好的 map 构造,不用先转 成 JSON 字符串再解析一遍——典型场景是权限配置、规则条件存在数据库的 JSON 列里,读出来直接 反序列化成 Condition 用。

engine 子包:规则引擎

Engine[T any]:按 Case(cond *condition.Condition, cb func(data T, g req.GlobalParams) error) 注册一组"条件 -> 回调"规则,Execute(data T) 对传入数据求值,命中第一个条件为真的分支就 调用对应回调(Default(cb) 兜底)。内部通过 db/enginesqlite3 内存库)把 data(用 reflux.R 包装)当成一行虚拟数据跑 SQL 判断条件是否成立,不用自己写一套表达式求值器。 EngineOptionDebug()/Relation(...))控制调试日志和关联字段展开。

已知问题

engine.go 在调用方没有显式传 GlobalParams 时,会用 nil user 构造一个兜底值,这跟 TokenValue 现在强制要求非 nil user 冲突,TestEngine 目前会 panic——待 Engine.Execute 支持显式传 user 时一并解决,暂时未修。

分支状态

master 是持续开发中的新架构,跟老仓库 v1-legacy 分支不兼容——Condition.ToSql 从手工 拼 SQL 字符串换成了 db-v2 表达式树,TokenValuereq.GlobalParams 换成了 reflux/valuexengine 包的连接管理也换成了 db/engine。还在用老版 API 的老项目,参见 v1-legacy 分支。