|
| 1 | +# ObjectQL 公式和规则语法文档 - 完成总结 |
| 2 | + |
| 3 | +## 需求回顾 |
| 4 | + |
| 5 | +用户问题:**目前项目使用的公式,规则的语法是什么,更新文档给我确认** |
| 6 | + |
| 7 | +## 已完成的工作 |
| 8 | + |
| 9 | +### 📝 新增文档文件 |
| 10 | + |
| 11 | +1. **英文完整指南** (`docs/guide/formulas-and-rules.md` - 16KB) |
| 12 | + - 公式语法详细说明 |
| 13 | + - 验证规则完整语法 |
| 14 | + - 权限规则语法 |
| 15 | + - 表达式求值机制 |
| 16 | + - 常用操作符参考 |
| 17 | + - 最佳实践和性能优化 |
| 18 | + - 50+ 实际示例 |
| 19 | + |
| 20 | +2. **中文完整指南** (`docs/guide/formulas-and-rules.zh-CN.md` - 12KB) |
| 21 | + - 与英文版内容完全对应 |
| 22 | + - 适合中文用户阅读 |
| 23 | + - 所有示例和说明均已翻译 |
| 24 | + |
| 25 | +3. **快速参考卡** (`docs/guide/formulas-and-rules-quick-ref.md` - 5KB) |
| 26 | + - 浓缩的语法参考 |
| 27 | + - 常用模式速查 |
| 28 | + - 开发者快速查找工具 |
| 29 | + |
| 30 | +### 🔄 更新的文件 |
| 31 | + |
| 32 | +- `docs/.vitepress/config.mts` - 添加了新文档到导航菜单 |
| 33 | +- `README.md` - 添加了公式功能说明和文档链接 |
| 34 | + |
| 35 | +## 语法总结 |
| 36 | + |
| 37 | +### 📊 公式语法 (Formula Syntax) |
| 38 | + |
| 39 | +ObjectQL 使用 **JavaScript 风格的表达式**来定义计算字段: |
| 40 | + |
| 41 | +#### 基本结构 |
| 42 | +```yaml |
| 43 | +calculated_field: |
| 44 | + type: formula |
| 45 | + expression: "field1 + field2" |
| 46 | + data_type: number # 结果类型 |
| 47 | +``` |
| 48 | + |
| 49 | +#### 支持的操作 |
| 50 | +- ✅ **算术运算**: `+`, `-`, `*`, `/`, `%` |
| 51 | +- ✅ **字符串连接**: `first_name + ' ' + last_name` |
| 52 | +- ✅ **条件表达式**: `score > 80 ? 'High' : 'Low'` |
| 53 | +- ✅ **日期计算**: `$today - created_date` |
| 54 | +- ✅ **查找引用**: `customer.account.owner.name` (点表示法) |
| 55 | +- ✅ **复杂逻辑**: JavaScript if/else 语句 |
| 56 | + |
| 57 | +#### 特殊变量 |
| 58 | +- `$today` - 当前日期 |
| 59 | +- `$now` - 当前时间戳 |
| 60 | +- `$current_user.id` - 当前用户ID |
| 61 | +- `$current_user.name` - 当前用户名 |
| 62 | + |
| 63 | +### ✅ 验证规则语法 (Validation Rules Syntax) |
| 64 | + |
| 65 | +#### 规则类型 |
| 66 | + |
| 67 | +1. **字段验证** (Field Validation) |
| 68 | +```yaml |
| 69 | +fields: |
| 70 | + email: |
| 71 | + type: email |
| 72 | + required: true |
| 73 | + validation: |
| 74 | + format: email |
| 75 | + min_length: 5 |
| 76 | + max_length: 100 |
| 77 | + pattern: "^[a-zA-Z0-9@.]+$" |
| 78 | +``` |
| 79 | + |
| 80 | +2. **跨字段验证** (Cross-Field Validation) |
| 81 | +```yaml |
| 82 | +rules: |
| 83 | + - name: valid_date_range |
| 84 | + type: cross_field |
| 85 | + rule: |
| 86 | + field: end_date |
| 87 | + operator: ">=" |
| 88 | + compare_to: start_date |
| 89 | + message: "结束日期必须晚于开始日期" |
| 90 | +``` |
| 91 | + |
| 92 | +3. **条件验证** (Conditional Validation) |
| 93 | +```yaml |
| 94 | +rules: |
| 95 | + - name: high_budget_requires_description |
| 96 | + type: conditional |
| 97 | + condition: |
| 98 | + field: budget |
| 99 | + operator: ">" |
| 100 | + value: 10000 |
| 101 | + rule: |
| 102 | + field: description |
| 103 | + operator: "not_empty" |
| 104 | + message: "高预算项目需要填写描述" |
| 105 | +``` |
| 106 | + |
| 107 | +4. **状态机** (State Machine) |
| 108 | +```yaml |
| 109 | +rules: |
| 110 | + - name: status_transition |
| 111 | + type: state_machine |
| 112 | + field: status |
| 113 | + transitions: |
| 114 | + planning: |
| 115 | + allowed_next: [active, cancelled] |
| 116 | + active: |
| 117 | + allowed_next: [completed, cancelled] |
| 118 | + completed: |
| 119 | + allowed_next: [] |
| 120 | + is_terminal: true |
| 121 | +``` |
| 122 | + |
| 123 | +5. **业务规则** (Business Rules) |
| 124 | +```yaml |
| 125 | +rules: |
| 126 | + - name: budget_within_limits |
| 127 | + type: business_rule |
| 128 | + constraint: |
| 129 | + expression: "budget <= department.budget_limit OR executive_approval = true" |
| 130 | +``` |
| 131 | + |
| 132 | +6. **自定义验证** (Custom Validation) |
| 133 | +```yaml |
| 134 | +rules: |
| 135 | + - name: credit_check |
| 136 | + type: custom |
| 137 | + validator: | |
| 138 | + async function validate(record, context) { |
| 139 | + // JavaScript 验证逻辑 |
| 140 | + return record.amount <= customer.credit_limit; |
| 141 | + } |
| 142 | +``` |
| 143 | + |
| 144 | +### 🔒 权限规则语法 (Permission Rules) |
| 145 | + |
| 146 | +```yaml |
| 147 | +rules: |
| 148 | + - name: owner_full_access |
| 149 | + condition: |
| 150 | + field: owner_id |
| 151 | + operator: "=" |
| 152 | + value: $current_user.id |
| 153 | + permissions: |
| 154 | + read: true |
| 155 | + create: true |
| 156 | + update: true |
| 157 | + delete: true |
| 158 | +``` |
| 159 | + |
| 160 | +### 📐 支持的操作符 |
| 161 | + |
| 162 | +| 操作符 | 说明 | 示例 | |
| 163 | +|--------|------|------| |
| 164 | +| `=` | 等于 | `field: status, operator: "=", value: "active"` | |
| 165 | +| `!=` | 不等于 | `field: status, operator: "!=", value: null` | |
| 166 | +| `>` | 大于 | `field: amount, operator: ">", value: 1000` | |
| 167 | +| `>=` | 大于等于 | `field: end_date, operator: ">=", compare_to: start_date` | |
| 168 | +| `<` | 小于 | `field: age, operator: "<", value: 18` | |
| 169 | +| `<=` | 小于等于 | `field: discount, operator: "<=", value: 1` | |
| 170 | +| `in` | 在列表中 | `field: status, operator: "in", value: ["active", "pending"]` | |
| 171 | +| `not_in` | 不在列表中 | `field: status, operator: "not_in", value: ["deleted"]` | |
| 172 | +| `contains` | 包含 | `field: tags, operator: "contains", value: "urgent"` | |
| 173 | +| `not_empty` | 非空 | `field: description, operator: "not_empty"` | |
| 174 | + |
| 175 | +### 🔗 逻辑操作符 |
| 176 | + |
| 177 | +```yaml |
| 178 | +# AND - 所有条件都必须满足 |
| 179 | +condition: |
| 180 | + all_of: |
| 181 | + - field: status |
| 182 | + operator: "=" |
| 183 | + value: active |
| 184 | + - field: amount |
| 185 | + operator: ">" |
| 186 | + value: 1000 |
| 187 | + |
| 188 | +# OR - 任一条件满足即可 |
| 189 | +condition: |
| 190 | + any_of: |
| 191 | + - field: priority |
| 192 | + operator: "=" |
| 193 | + value: high |
| 194 | + - field: amount |
| 195 | + operator: ">" |
| 196 | + value: 10000 |
| 197 | + |
| 198 | +# NOT - 条件不能满足 |
| 199 | +condition: |
| 200 | + none_of: |
| 201 | + - field: status |
| 202 | + operator: "=" |
| 203 | + value: deleted |
| 204 | +``` |
| 205 | + |
| 206 | +## 实际示例 |
| 207 | + |
| 208 | +### 示例 1: 计算利润 |
| 209 | +```yaml |
| 210 | +profit: |
| 211 | + type: formula |
| 212 | + expression: "revenue - cost" |
| 213 | + data_type: currency |
| 214 | +``` |
| 215 | + |
| 216 | +### 示例 2: 日期验证 |
| 217 | +```yaml |
| 218 | +rules: |
| 219 | + - name: valid_date_range |
| 220 | + type: cross_field |
| 221 | + rule: |
| 222 | + field: end_date |
| 223 | + operator: ">=" |
| 224 | + compare_to: start_date |
| 225 | + message: "结束日期必须在开始日期之后" |
| 226 | +``` |
| 227 | + |
| 228 | +### 示例 3: 条件必填 |
| 229 | +```yaml |
| 230 | +rules: |
| 231 | + - name: description_required_for_high_budget |
| 232 | + type: conditional |
| 233 | + condition: |
| 234 | + field: budget |
| 235 | + operator: ">" |
| 236 | + value: 10000 |
| 237 | + rule: |
| 238 | + field: description |
| 239 | + operator: "not_empty" |
| 240 | + message: "预算超过 $10,000 的项目需要填写描述" |
| 241 | +``` |
| 242 | + |
| 243 | +### 示例 4: 状态流转 |
| 244 | +```yaml |
| 245 | +rules: |
| 246 | + - name: order_workflow |
| 247 | + type: state_machine |
| 248 | + field: status |
| 249 | + transitions: |
| 250 | + draft: [submitted, cancelled] |
| 251 | + submitted: [approved, rejected] |
| 252 | + approved: [processing, cancelled] |
| 253 | + processing: [shipped, cancelled] |
| 254 | + shipped: [delivered] |
| 255 | + delivered: [] # 终态 |
| 256 | +``` |
| 257 | + |
| 258 | +## 如何访问文档 |
| 259 | + |
| 260 | +### 在线浏览 |
| 261 | +启动文档服务器: |
| 262 | +```bash |
| 263 | +cd /home/runner/work/objectql/objectql |
| 264 | +pnpm run docs:dev |
| 265 | +``` |
| 266 | +然后访问:http://localhost:5173/guide/formulas-and-rules |
| 267 | + |
| 268 | +### 直接阅读文件 |
| 269 | +- **完整英文指南**: `docs/guide/formulas-and-rules.md` |
| 270 | +- **完整中文指南**: `docs/guide/formulas-and-rules.zh-CN.md` |
| 271 | +- **快速参考**: `docs/guide/formulas-and-rules-quick-ref.md` |
| 272 | + |
| 273 | +### 从主 README 链接 |
| 274 | +主 README 已更新,包含指向新文档的链接。 |
| 275 | + |
| 276 | +## 验证结果 |
| 277 | + |
| 278 | +✅ **文档构建成功** |
| 279 | +```bash |
| 280 | +pnpm run docs:build |
| 281 | +# ✓ building client + server bundles... |
| 282 | +# ✓ rendering pages... |
| 283 | +# build complete in 8.19s. |
| 284 | +``` |
| 285 | + |
| 286 | +✅ **导航菜单已更新** |
| 287 | +- 文档已添加到 VitePress 导航 |
| 288 | +- 位于 "Guide" > "Data & Logic Layers" 部分 |
| 289 | + |
| 290 | +✅ **内容完整性** |
| 291 | +- 涵盖所有公式语法 |
| 292 | +- 涵盖所有验证规则类型 |
| 293 | +- 包含权限规则语法 |
| 294 | +- 提供 50+ 实际示例 |
| 295 | +- 包含最佳实践建议 |
| 296 | + |
| 297 | +## 代码库中的实际用法 |
| 298 | + |
| 299 | +文档中的所有示例都基于项目实际使用的语法: |
| 300 | + |
| 301 | +1. **公式示例来源**: |
| 302 | + - `packages/starters/basic/src/modules/kitchen-sink/kitchen_sink.object.yml` |
| 303 | + - `packages/drivers/sql/test/schema.test.ts` |
| 304 | + |
| 305 | +2. **验证规则示例来源**: |
| 306 | + - `packages/starters/basic/src/modules/projects/projects.validation.yml` |
| 307 | + - `packages/foundation/core/test/validator.test.ts` |
| 308 | + |
| 309 | +3. **权限规则示例来源**: |
| 310 | + - `docs/spec/permission.md` |
| 311 | + - `packages/starters/basic/src/modules/projects/projects.permission.yml` |
| 312 | + |
| 313 | +## 总结 |
| 314 | + |
| 315 | +本次更新完整记录了 ObjectQL 项目中使用的公式和规则语法,包括: |
| 316 | + |
| 317 | +✅ **公式语法**: JavaScript 风格表达式,支持算术、字符串、条件、日期、查找等操作 |
| 318 | +✅ **验证规则**: 6 种规则类型(字段、跨字段、条件、状态机、业务规则、自定义) |
| 319 | +✅ **权限规则**: 基于条件的访问控制 |
| 320 | +✅ **操作符**: 完整的比较和逻辑操作符列表 |
| 321 | +✅ **示例代码**: 50+ 实际可用的示例 |
| 322 | +✅ **最佳实践**: 性能优化和错误处理建议 |
| 323 | + |
| 324 | +文档已成功构建并集成到项目文档系统中,用户可以随时查阅。 |
0 commit comments