1
0

feat: 增强模板条件渲染表达式支持

使用 simpleeval 库替换原有的简单正则匹配,支持复杂的条件表达式评估。新增 ConditionEvaluator 类处理条件逻辑,支持比较运算、逻辑运算、成员测试、数学计算和内置函数,同时保持向后兼容性。
This commit is contained in:
2026-03-03 17:28:23 +08:00
parent 01a93ce13b
commit 16ca9d77cd
16 changed files with 1437 additions and 31 deletions

View File

@@ -0,0 +1,179 @@
# Enhanced Condition Evaluation
## Purpose
增强条件评估能力提供基于 simpleeval 的安全表达式评估引擎,支持复杂的条件判断、逻辑运算、数学计算和成员测试。该能力用于模板系统的 visible 字段,允许用户使用 Python 风格的表达式来控制元素的显示条件。
## Requirements
### Requirement: 系统必须支持比较运算符
系统 SHALL 支持所有标准的比较运算符,用于数值和字符串的比较。
#### Scenario: 数值大于比较
- **WHEN** 表达式为 `{count > 0}` 且变量 `count` 的值为 5
- **THEN** 表达式评估结果为 True
#### Scenario: 数值小于等于比较
- **WHEN** 表达式为 `{price <= 100}` 且变量 `price` 的值为 100
- **THEN** 表达式评估结果为 True
#### Scenario: 字符串相等比较
- **WHEN** 表达式为 `{status == 'active'}` 且变量 `status` 的值为 "active"
- **THEN** 表达式评估结果为 True
#### Scenario: 字符串不等比较
- **WHEN** 表达式为 `{status != 'inactive'}` 且变量 `status` 的值为 "active"
- **THEN** 表达式评估结果为 True
### Requirement: 系统必须支持逻辑运算符
系统 SHALL 支持逻辑运算符 and、or、not用于组合多个条件。
#### Scenario: 逻辑与运算
- **WHEN** 表达式为 `{count > 0 and status == 'active'}` 且变量 `count` 为 5`status` 为 "active"
- **THEN** 表达式评估结果为 True
#### Scenario: 逻辑或运算
- **WHEN** 表达式为 `{count > 0 or status == 'active'}` 且变量 `count` 为 0`status` 为 "active"
- **THEN** 表达式评估结果为 True
#### Scenario: 逻辑非运算
- **WHEN** 表达式为 `{not (count == 0)}` 且变量 `count` 为 5
- **THEN** 表达式评估结果为 True
#### Scenario: 复杂逻辑组合
- **WHEN** 表达式为 `{(score >= 60 and score <= 100) or is_admin}` 且变量 `score` 为 75`is_admin` 为 False
- **THEN** 表达式评估结果为 True
### Requirement: 系统必须支持成员测试
系统 SHALL 支持 in 和 not in 运算符,用于测试值是否在集合中。
#### Scenario: 列表成员测试
- **WHEN** 表达式为 `{status in ['draft', 'review', 'published']}` 且变量 `status` 为 "draft"
- **THEN** 表达式评估结果为 True
#### Scenario: 列表非成员测试
- **WHEN** 表达式为 `{status not in ['draft', 'review']}` 且变量 `status` 为 "active"
- **THEN** 表达式评估结果为 True
#### Scenario: 字符串包含测试
- **WHEN** 表达式为 `{'test' in status}` 且变量 `status` 为 "test-version"
- **THEN** 表达式评估结果为 True
#### Scenario: 元组成员测试
- **WHEN** 表达式为 `{level in (1, 2, 3)}` 且变量 `level` 为 2
- **THEN** 表达式评估结果为 True
### Requirement: 系统必须支持数学运算
系统 SHALL 支持基本的数学运算符,用于条件判断中的计算。
#### Scenario: 加法运算
- **WHEN** 表达式为 `{(price + tax) > 100}` 且变量 `price` 为 90`tax` 为 15
- **THEN** 表达式评估结果为 True
#### Scenario: 乘法运算
- **WHEN** 表达式为 `{(price * discount) > 50}` 且变量 `price` 为 100`discount` 为 0.8
- **THEN** 表达式评估结果为 True
#### Scenario: 除法运算
- **WHEN** 表达式为 `{(total / count) >= 10}` 且变量 `total` 为 100`count` 为 5
- **THEN** 表达式评估结果为 True
### Requirement: 系统必须支持内置函数
系统 SHALL 支持安全的内置函数,用于类型转换和基本操作。
#### Scenario: 类型转换函数
- **WHEN** 表达式为 `{int(value) > 100}` 且变量 `value` 为 "150"
- **THEN** 表达式评估结果为 True
#### Scenario: 长度函数
- **WHEN** 表达式为 `{len(items) > 0}` 且变量 `items` 为 [1, 2, 3]
- **THEN** 表达式评估结果为 True
#### Scenario: 布尔转换函数
- **WHEN** 表达式为 `{bool(value)}` 且变量 `value` 为 "text"
- **THEN** 表达式评估结果为 True
### Requirement: 系统必须提供详细的错误信息
系统 SHALL 在表达式评估失败时提供清晰的错误信息,帮助用户快速定位问题。
#### Scenario: 变量未定义错误
- **WHEN** 表达式为 `{undefined_var > 0}` 但变量 `undefined_var` 未提供
- **THEN** 系统抛出错误,提示"条件表达式中的变量未定义: undefined_var",并列出可用变量
#### Scenario: 函数未定义错误
- **WHEN** 表达式为 `{custom_func(value)}` 但函数 `custom_func` 不在白名单中
- **THEN** 系统抛出错误,提示"条件表达式中使用了不支持的函数: custom_func",并列出支持的函数
#### Scenario: 语法错误
- **WHEN** 表达式为 `{count > }` 包含语法错误
- **THEN** 系统抛出错误,提示"条件表达式语法错误",并显示具体的语法问题
### Requirement: 系统必须实施安全限制
系统 SHALL 限制表达式的复杂度和能力,防止恶意或危险的操作。
#### Scenario: 表达式长度限制
- **WHEN** 表达式长度超过 500 字符
- **THEN** 系统抛出错误,提示"条件表达式过长"
#### Scenario: 禁止属性访问
- **WHEN** 表达式为 `{obj.attr}` 尝试访问对象属性
- **THEN** 系统抛出错误,提示"不支持的语法特性"
#### Scenario: 禁止函数定义
- **WHEN** 表达式包含 lambda 或 def 关键字
- **THEN** 系统抛出错误,提示"不支持的语法特性"
#### Scenario: 白名单函数限制
- **WHEN** 表达式使用了不在白名单中的函数(如 eval、exec、open
- **THEN** 系统拒绝执行,抛出错误
### Requirement: 系统必须支持表达式提取
系统 SHALL 能够从 `{expression}` 格式的字符串中提取实际的表达式内容。
#### Scenario: 提取带花括号的表达式
- **WHEN** 条件字符串为 `{count > 0}`
- **THEN** 系统提取出表达式 `count > 0`
#### Scenario: 提取带空白的表达式
- **WHEN** 条件字符串为 `{ count > 0 }`
- **THEN** 系统提取出表达式 `count > 0`(去除首尾空白)
#### Scenario: 处理不带花括号的表达式
- **WHEN** 条件字符串为 `count > 0`(不带花括号)
- **THEN** 系统直接使用该字符串作为表达式