@qingflow-tech/qingflow-cli 1.1.43-beta.4 → 1.1.43-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.md +3 -3
  2. package/package.json +1 -1
  3. package/pyproject.toml +1 -1
  4. package/skills/qingflow-app-form/SKILL.md +7 -6
  5. package/skills/qingflow-cli/reference/builder/30-schema-fields.md +3 -2
  6. package/src/qingflow_mcp/app_form_validator.py +97 -0
  7. package/src/qingflow_mcp/builder_facade/app_form.py +15 -2
  8. package/src/qingflow_mcp/builder_facade/app_form_schema.py +50 -5
  9. package/src/qingflow_mcp/builder_facade/schemas/app_form/manifest.json +5 -0
  10. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/complete.json +7 -12
  11. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/address.json +1 -1
  12. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/amount.json +6 -4
  13. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/attachment.json +1 -1
  14. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/code_block.json +1 -1
  15. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/data_relation.json +1 -1
  16. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/date.json +1 -1
  17. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/datetime.json +1 -1
  18. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/department.json +1 -1
  19. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/email.json +1 -1
  20. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/link.json +1 -1
  21. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/long_text.json +1 -1
  22. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/member.json +1 -1
  23. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/multi_select.json +1 -1
  24. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/number.json +6 -4
  25. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/phone.json +1 -1
  26. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/q_linker.json +1 -1
  27. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/relation.json +1 -1
  28. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/single_choice.json +1 -1
  29. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/single_select.json +1 -1
  30. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/subtable.json +7 -12
  31. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/fields/text.json +1 -1
  32. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/formula.json +1594 -0
  33. package/src/qingflow_mcp/builder_facade/schemas/app_form/v1alpha1/summary.json +1 -1
  34. package/src/qingflow_mcp/cli/commands/builder.py +2 -0
  35. package/src/qingflow_mcp/server_app_builder.py +7 -2
  36. package/src/qingflow_mcp/tools/ai_builder_tools.py +13 -3
@@ -0,0 +1,1594 @@
1
+ {
2
+ "$id": "https://builder.qingflow.com/schemas/app-form-apply/v1alpha1/formula.json",
3
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
4
+ "description": "轻流 AppForm 公式表达式契约。用于 defaultType=3 的 defaultValue,以及其他明确声明接受公式文本的配置。",
5
+ "minLength": 1,
6
+ "title": "Qingflow AppForm v1alpha1 formula expression",
7
+ "type": "string",
8
+ "x-qingflow-field-references": {
9
+ "dynamicConcatExample": {
10
+ "fieldMapping": [
11
+ {
12
+ "fieldName": "文本字段",
13
+ "queId": 101,
14
+ "reference": "#queId_101$"
15
+ },
16
+ {
17
+ "fieldName": "数字字段",
18
+ "queId": 102,
19
+ "reference": "#queId_102$"
20
+ }
21
+ ],
22
+ "formula": "CONCAT(\"文本字段:\", #queId_101$, \" / 数字字段:\", #queId_102$)",
23
+ "meaning": "随两个字段当前值变化的动态拼接。"
24
+ },
25
+ "examples": [
26
+ "#queId_101$",
27
+ "CONCAT(\"文本字段:\", #queId_101$, \" / 数字字段:\", #queId_102$)",
28
+ "IF(#queId_103$ > 0, #queId_101$, #queId_102$)"
29
+ ],
30
+ "meaning": "引用当前应用中 queId 为 fieldId 的字段值。",
31
+ "nonDynamicExamples": [
32
+ {
33
+ "expression": "CONCAT(\"文本字段:\", \"测试文本\", \" / 数字字段:\", \"12.50\")",
34
+ "meaning": "仅拼接固定字符串;它不会引用文本字段或数字字段的当前值。"
35
+ },
36
+ {
37
+ "expression": "CONCAT(\"文本字段:\", \"文本字段\", \" / 数字字段:\", \"数字字段\")",
38
+ "meaning": "字段名称被当作固定字符串,不能作为字段引用。"
39
+ }
40
+ ],
41
+ "rules": [
42
+ "fieldId 必须是目标字段实际保存后的十进制 queId;引用标记必须完整且不能加引号。",
43
+ "字段 name、字段标题、字段描述及字段默认值不能作为公式变量或引用标记。",
44
+ "动态拼接必须在 CONCAT 中传入 #queId_<fieldId>$,不能以字段名称或默认值字符串代替。"
45
+ ],
46
+ "syntax": "#queId_<fieldId>$"
47
+ },
48
+ "x-qingflow-functions": {
49
+ "AND": {
50
+ "category": "logical",
51
+ "example": "AND(#queId_101$ > 0, #queId_102$ > 0)",
52
+ "meaning": "判断所有条件是否都为真。",
53
+ "parameters": [
54
+ {
55
+ "description": "一个或多个布尔条件",
56
+ "name": "conditions",
57
+ "variadic": true
58
+ }
59
+ ],
60
+ "returns": {
61
+ "description": "全部为真时返回 TRUE,否则返回 FALSE",
62
+ "type": "boolean"
63
+ },
64
+ "signatures": [
65
+ "AND(condition1, condition2, ...)"
66
+ ]
67
+ },
68
+ "AVERAGE": {
69
+ "category": "number",
70
+ "example": "AVERAGE(#queId_101$, #queId_102$)",
71
+ "meaning": "计算所有数字参数和列表元素的算术平均值。",
72
+ "parameters": [
73
+ {
74
+ "description": "数字、数字字段或数字列表",
75
+ "name": "values",
76
+ "variadic": true
77
+ }
78
+ ],
79
+ "returns": {
80
+ "description": "平均值;没有数值时返回 0",
81
+ "type": "number"
82
+ },
83
+ "signatures": [
84
+ "AVERAGE(value1, value2, ...)"
85
+ ]
86
+ },
87
+ "BASE64": {
88
+ "category": "utility",
89
+ "example": "BASE64(#queId_101$)",
90
+ "meaning": "将文本编码为 Base64。",
91
+ "parameters": [
92
+ {
93
+ "description": "待编码值",
94
+ "name": "value"
95
+ }
96
+ ],
97
+ "returns": {
98
+ "description": "Base64 文本",
99
+ "type": "string"
100
+ },
101
+ "signatures": [
102
+ "BASE64(value)"
103
+ ]
104
+ },
105
+ "CONCAT": {
106
+ "category": "text",
107
+ "example": "CONCAT(\"文本字段:\", #queId_101$, \" / 数字字段:\", #queId_102$)",
108
+ "meaning": "按参数顺序直接拼接文本;列表参数会先展开。要拼接字段当前值时,字段参数必须使用未加引号的 #queId_<字段ID>$,不能使用字段 name 或默认值字符串。",
109
+ "parameters": [
110
+ {
111
+ "description": "要拼接的字段当前值(#queId_<字段ID>$)、静态文本或其他值;字段 name 不是合法变量",
112
+ "name": "values",
113
+ "variadic": true
114
+ }
115
+ ],
116
+ "returns": {
117
+ "description": "拼接后的文本",
118
+ "type": "string"
119
+ },
120
+ "signatures": [
121
+ "CONCAT(value1, value2, ...)"
122
+ ]
123
+ },
124
+ "COUNT": {
125
+ "category": "number",
126
+ "example": "COUNT(#queId_101$, #queId_102$)",
127
+ "meaning": "统计非 null 参数包含的值数量,列表按元素计数。",
128
+ "parameters": [
129
+ {
130
+ "description": "待计数的值或列表",
131
+ "name": "values",
132
+ "variadic": true
133
+ }
134
+ ],
135
+ "returns": {
136
+ "description": "值数量",
137
+ "type": "number"
138
+ },
139
+ "signatures": [
140
+ "COUNT(value1, value2, ...)"
141
+ ]
142
+ },
143
+ "COUNTIF": {
144
+ "category": "number",
145
+ "example": "COUNTIF(#queId_101$, \">=60\")",
146
+ "meaning": "统计列表中满足比较条件的元素数量。",
147
+ "parameters": [
148
+ {
149
+ "description": "待统计列表",
150
+ "name": "values"
151
+ },
152
+ {
153
+ "description": "精确匹配文本,或以 !、>、<、= 开头的比较表达式文本",
154
+ "name": "compare"
155
+ }
156
+ ],
157
+ "returns": {
158
+ "description": "满足条件的元素数量",
159
+ "type": "number"
160
+ },
161
+ "signatures": [
162
+ "COUNTIF(values, compare)"
163
+ ]
164
+ },
165
+ "CURDATE": {
166
+ "category": "date",
167
+ "example": "CURDATE()",
168
+ "meaning": "取得公式执行时的当前日期。",
169
+ "parameters": [],
170
+ "returns": {
171
+ "description": "yyyy-MM-dd 格式的当前日期",
172
+ "type": "string"
173
+ },
174
+ "signatures": [
175
+ "CURDATE()"
176
+ ]
177
+ },
178
+ "DATE": {
179
+ "category": "date",
180
+ "example": "DATE(2026, 8, 20, 9, 30, 0)",
181
+ "meaning": "用年、月、日以及可选的时、分、秒构造日期时间。",
182
+ "parameters": [
183
+ {
184
+ "description": "年份",
185
+ "name": "year"
186
+ },
187
+ {
188
+ "description": "月份",
189
+ "name": "month"
190
+ },
191
+ {
192
+ "description": "日",
193
+ "name": "day"
194
+ },
195
+ {
196
+ "description": "可选的小时、分钟、秒",
197
+ "name": "timeParts",
198
+ "optional": true,
199
+ "variadic": true
200
+ }
201
+ ],
202
+ "returns": {
203
+ "description": "yyyy-MM-dd HH:mm:ss 格式文本;参数无效时返回 null",
204
+ "type": "string | null"
205
+ },
206
+ "signatures": [
207
+ "DATE(year, month, day)",
208
+ "DATE(year, month, day, hour, minute, second)"
209
+ ]
210
+ },
211
+ "DATEDELTA": {
212
+ "category": "date",
213
+ "example": "DATEDELTA(#queId_101$, 7, \"D\")",
214
+ "meaning": "给日期时间增加或减少指定单位的数量。",
215
+ "parameters": [
216
+ {
217
+ "description": "原日期或日期时间",
218
+ "name": "date"
219
+ },
220
+ {
221
+ "description": "增减数量,正数增加、负数减少",
222
+ "name": "number"
223
+ },
224
+ {
225
+ "description": "可选单位:Y 年、M 月、D 日、H 时、MIN 分;省略或无法识别时按 D",
226
+ "name": "unit",
227
+ "optional": true
228
+ }
229
+ ],
230
+ "returns": {
231
+ "description": "yyyy-MM-dd HH:mm:ss 格式的计算结果",
232
+ "type": "string | null"
233
+ },
234
+ "signatures": [
235
+ "DATEDELTA(date, days)",
236
+ "DATEDELTA(date, number, unit)"
237
+ ]
238
+ },
239
+ "DATETOTIMESTAMP": {
240
+ "category": "date",
241
+ "example": "DATETOTIMESTAMP(#queId_101$)",
242
+ "meaning": "将日期时间转换为 13 位毫秒时间戳。",
243
+ "parameters": [
244
+ {
245
+ "description": "日期或日期时间",
246
+ "name": "value"
247
+ }
248
+ ],
249
+ "returns": {
250
+ "description": "毫秒时间戳文本;无法解析时返回 null",
251
+ "type": "string | null"
252
+ },
253
+ "signatures": [
254
+ "DATETOTIMESTAMP(value)"
255
+ ]
256
+ },
257
+ "DAY": {
258
+ "category": "date",
259
+ "example": "DAY(#queId_101$)",
260
+ "meaning": "提取日期或日期时间中的日。",
261
+ "parameters": [
262
+ {
263
+ "description": "日期或日期时间",
264
+ "name": "date"
265
+ }
266
+ ],
267
+ "returns": {
268
+ "description": "月内日期文本",
269
+ "type": "string | null"
270
+ },
271
+ "signatures": [
272
+ "DAY(date)"
273
+ ]
274
+ },
275
+ "DAYS": {
276
+ "category": "date",
277
+ "example": "DAYS(#queId_102$, #queId_101$)",
278
+ "meaning": "计算结束日期时间与开始日期时间之间的天数,支持按行对齐的列表。",
279
+ "parameters": [
280
+ {
281
+ "description": "结束日期或列表",
282
+ "name": "end"
283
+ },
284
+ {
285
+ "description": "开始日期或列表",
286
+ "name": "start"
287
+ }
288
+ ],
289
+ "returns": {
290
+ "description": "天数文本列表,可包含负数",
291
+ "type": "list"
292
+ },
293
+ "signatures": [
294
+ "DAYS(end, start)"
295
+ ]
296
+ },
297
+ "DETRIPLEDES": {
298
+ "category": "utility",
299
+ "example": "DETRIPLEDES(#queId_101$, \"123456789012345678901234\")",
300
+ "meaning": "解密由兼容 3DES 参数生成的 Base64 密文。",
301
+ "parameters": [
302
+ {
303
+ "description": "Base64 密文",
304
+ "name": "content"
305
+ },
306
+ {
307
+ "description": "加密时使用的密钥",
308
+ "name": "secret"
309
+ },
310
+ {
311
+ "description": "非 ECB 模式使用的 8 字节向量",
312
+ "name": "iv",
313
+ "optional": true
314
+ },
315
+ {
316
+ "description": "加密时使用的模式",
317
+ "name": "mode",
318
+ "optional": true
319
+ },
320
+ {
321
+ "description": "加密时使用的填充模式",
322
+ "name": "padding",
323
+ "optional": true
324
+ }
325
+ ],
326
+ "returns": {
327
+ "description": "解密后的文本",
328
+ "type": "string"
329
+ },
330
+ "signatures": [
331
+ "DETRIPLEDES(content, secret)",
332
+ "DETRIPLEDES(content, secret, iv, mode, padding)"
333
+ ]
334
+ },
335
+ "FIRST": {
336
+ "category": "text",
337
+ "example": "FIRST(#queId_101$)",
338
+ "meaning": "取得列表中的第一个值并转为文本。",
339
+ "parameters": [
340
+ {
341
+ "description": "列表或产生列表的字段引用",
342
+ "name": "values"
343
+ }
344
+ ],
345
+ "returns": {
346
+ "description": "第一个值;空列表返回空字符串",
347
+ "type": "string"
348
+ },
349
+ "signatures": [
350
+ "FIRST(values)"
351
+ ]
352
+ },
353
+ "GETUSEREMAIL": {
354
+ "category": "context",
355
+ "example": "GETUSEREMAIL()",
356
+ "meaning": "取得当前执行用户的邮箱。",
357
+ "parameters": [],
358
+ "returns": {
359
+ "description": "当前用户邮箱;无法取得时为空字符串",
360
+ "type": "string"
361
+ },
362
+ "signatures": [
363
+ "GETUSEREMAIL()"
364
+ ]
365
+ },
366
+ "GETUSERNAME": {
367
+ "category": "context",
368
+ "example": "GETUSERNAME()",
369
+ "meaning": "取得当前执行用户在当前工作区中的显示名称。",
370
+ "parameters": [],
371
+ "returns": {
372
+ "description": "当前用户显示名称;无法取得时为空字符串",
373
+ "type": "string"
374
+ },
375
+ "signatures": [
376
+ "GETUSERNAME()"
377
+ ]
378
+ },
379
+ "HOUR": {
380
+ "category": "date",
381
+ "example": "HOUR(#queId_101$)",
382
+ "meaning": "提取日期时间中的小时。",
383
+ "parameters": [
384
+ {
385
+ "description": "日期时间",
386
+ "name": "date"
387
+ }
388
+ ],
389
+ "returns": {
390
+ "description": "0 至 23 的小时文本",
391
+ "type": "string | null"
392
+ },
393
+ "signatures": [
394
+ "HOUR(date)"
395
+ ]
396
+ },
397
+ "IF": {
398
+ "category": "logical",
399
+ "example": "IF(#queId_101$ >= 60, \"通过\", \"未通过\")",
400
+ "meaning": "根据一个条件返回两个候选值之一。",
401
+ "parameters": [
402
+ {
403
+ "description": "布尔条件",
404
+ "name": "condition"
405
+ },
406
+ {
407
+ "description": "条件为真时返回的值",
408
+ "name": "valueIfTrue"
409
+ },
410
+ {
411
+ "description": "条件为假时返回的值",
412
+ "name": "valueIfFalse"
413
+ }
414
+ ],
415
+ "returns": {
416
+ "description": "选中的分支值",
417
+ "type": "any"
418
+ },
419
+ "signatures": [
420
+ "IF(condition, valueIfTrue, valueIfFalse)"
421
+ ]
422
+ },
423
+ "IFS": {
424
+ "category": "logical",
425
+ "example": "IFS(#queId_101$ >= 90, \"优秀\", #queId_101$ >= 60, \"通过\", TRUE, \"未通过\")",
426
+ "meaning": "按顺序判断多组条件并返回第一组真条件对应的文本。",
427
+ "parameters": [
428
+ {
429
+ "description": "条件和值交替排列,条件按顺序求值",
430
+ "name": "conditionValuePairs",
431
+ "variadic": true
432
+ }
433
+ ],
434
+ "returns": {
435
+ "description": "第一组成立条件对应的文本;均不成立时返回空字符串",
436
+ "type": "string"
437
+ },
438
+ "signatures": [
439
+ "IFS(condition1, value1, condition2, value2, ...)"
440
+ ]
441
+ },
442
+ "INT": {
443
+ "category": "number",
444
+ "example": "INT(#queId_101$)",
445
+ "meaning": "将数字向负无穷方向取整。",
446
+ "parameters": [
447
+ {
448
+ "description": "数字",
449
+ "name": "value"
450
+ }
451
+ ],
452
+ "returns": {
453
+ "description": "整数值",
454
+ "type": "number"
455
+ },
456
+ "signatures": [
457
+ "INT(value)"
458
+ ]
459
+ },
460
+ "ISEMPTY": {
461
+ "category": "text",
462
+ "example": "ISEMPTY(#queId_101$)",
463
+ "meaning": "判断值转换为文本后是否为空。",
464
+ "parameters": [
465
+ {
466
+ "description": "待判断值",
467
+ "name": "value"
468
+ }
469
+ ],
470
+ "returns": {
471
+ "description": "为空时返回 TRUE,否则返回 FALSE",
472
+ "type": "boolean"
473
+ },
474
+ "signatures": [
475
+ "ISEMPTY(value)"
476
+ ]
477
+ },
478
+ "JADEPTID": {
479
+ "category": "context",
480
+ "example": "JADEPTID()",
481
+ "meaning": "取得当前用户的集成组织 ID。",
482
+ "parameters": [],
483
+ "returns": {
484
+ "description": "组织 ID;没有对应信息时为空字符串",
485
+ "type": "string"
486
+ },
487
+ "signatures": [
488
+ "JADEPTID()"
489
+ ]
490
+ },
491
+ "JADEPTNAME": {
492
+ "category": "context",
493
+ "example": "JADEPTNAME()",
494
+ "meaning": "取得当前用户的集成组织名称。",
495
+ "parameters": [],
496
+ "returns": {
497
+ "description": "组织名称;没有对应信息时为空字符串",
498
+ "type": "string"
499
+ },
500
+ "signatures": [
501
+ "JADEPTNAME()"
502
+ ]
503
+ },
504
+ "JAID": {
505
+ "category": "context",
506
+ "example": "JAID()",
507
+ "meaning": "取得当前用户的集成身份 SID。",
508
+ "parameters": [],
509
+ "returns": {
510
+ "description": "集成身份 SID;没有对应信息时为空字符串",
511
+ "type": "string"
512
+ },
513
+ "signatures": [
514
+ "JAID()"
515
+ ]
516
+ },
517
+ "JANAME": {
518
+ "category": "context",
519
+ "example": "JANAME()",
520
+ "meaning": "取得当前用户名称,与 GETUSERNAME 的当前实现一致。",
521
+ "parameters": [],
522
+ "returns": {
523
+ "description": "当前用户显示名称",
524
+ "type": "string"
525
+ },
526
+ "signatures": [
527
+ "JANAME()"
528
+ ]
529
+ },
530
+ "JATYPE": {
531
+ "category": "context",
532
+ "example": "JATYPE()",
533
+ "meaning": "取得当前用户的集成用户类型。",
534
+ "parameters": [],
535
+ "returns": {
536
+ "description": "学生、校友、教职工、博士后、集体账号或其他;没有对应信息时为空字符串",
537
+ "type": "string"
538
+ },
539
+ "signatures": [
540
+ "JATYPE()"
541
+ ]
542
+ },
543
+ "JOIN": {
544
+ "category": "text",
545
+ "example": "JOIN(\",\", #queId_101$, #queId_102$)",
546
+ "meaning": "使用指定分隔符连接一个或多个值;列表参数会先展开。",
547
+ "parameters": [
548
+ {
549
+ "description": "连接分隔符",
550
+ "name": "delimiter"
551
+ },
552
+ {
553
+ "description": "要连接的值",
554
+ "name": "values",
555
+ "variadic": true
556
+ }
557
+ ],
558
+ "returns": {
559
+ "description": "带分隔符的连接文本",
560
+ "type": "string"
561
+ },
562
+ "signatures": [
563
+ "JOIN(delimiter, value1, value2, ...)"
564
+ ]
565
+ },
566
+ "LAST": {
567
+ "category": "text",
568
+ "example": "LAST(#queId_101$)",
569
+ "meaning": "取得列表中的最后一个值并转为文本。",
570
+ "parameters": [
571
+ {
572
+ "description": "列表或产生列表的字段引用",
573
+ "name": "values"
574
+ }
575
+ ],
576
+ "returns": {
577
+ "description": "最后一个值;空列表返回空字符串",
578
+ "type": "string"
579
+ },
580
+ "signatures": [
581
+ "LAST(values)"
582
+ ]
583
+ },
584
+ "LEFT": {
585
+ "category": "text",
586
+ "example": "LEFT(#queId_101$, 3)",
587
+ "meaning": "从文本左侧截取指定数量的字符。",
588
+ "parameters": [
589
+ {
590
+ "description": "原文本",
591
+ "name": "text"
592
+ },
593
+ {
594
+ "description": "截取字符数",
595
+ "name": "numChars"
596
+ }
597
+ ],
598
+ "returns": {
599
+ "description": "截取后的文本",
600
+ "type": "string"
601
+ },
602
+ "signatures": [
603
+ "LEFT(text, numChars)"
604
+ ]
605
+ },
606
+ "LEN": {
607
+ "category": "text",
608
+ "example": "LEN(#queId_101$)",
609
+ "meaning": "返回文本字符数。",
610
+ "parameters": [
611
+ {
612
+ "description": "待计算长度的值",
613
+ "name": "value"
614
+ }
615
+ ],
616
+ "returns": {
617
+ "description": "字符数;空文本返回 0",
618
+ "type": "number"
619
+ },
620
+ "signatures": [
621
+ "LEN(value)"
622
+ ]
623
+ },
624
+ "LN": {
625
+ "category": "number",
626
+ "example": "LN(#queId_101$)",
627
+ "meaning": "计算正数的自然对数。",
628
+ "parameters": [
629
+ {
630
+ "description": "大于 0 的数字",
631
+ "name": "number"
632
+ }
633
+ ],
634
+ "returns": {
635
+ "description": "自然对数;输入不大于 0 时返回 null",
636
+ "type": "number | null"
637
+ },
638
+ "signatures": [
639
+ "LN(number)"
640
+ ]
641
+ },
642
+ "LOWER": {
643
+ "category": "text",
644
+ "example": "LOWER(#queId_101$)",
645
+ "meaning": "将文本转换为小写。",
646
+ "parameters": [
647
+ {
648
+ "description": "待转换值",
649
+ "name": "value"
650
+ }
651
+ ],
652
+ "returns": {
653
+ "description": "小写文本",
654
+ "type": "string"
655
+ },
656
+ "signatures": [
657
+ "LOWER(value)"
658
+ ]
659
+ },
660
+ "MAX": {
661
+ "category": "number",
662
+ "example": "MAX(#queId_101$, #queId_102$)",
663
+ "meaning": "返回数字或日期参数中的最大值。",
664
+ "parameters": [
665
+ {
666
+ "description": "数字、日期或对应列表",
667
+ "name": "values",
668
+ "variadic": true
669
+ }
670
+ ],
671
+ "returns": {
672
+ "description": "最大数字或最晚日期",
673
+ "type": "number | string | null"
674
+ },
675
+ "signatures": [
676
+ "MAX(value1, value2, ...)"
677
+ ]
678
+ },
679
+ "MD5": {
680
+ "category": "utility",
681
+ "example": "MD5(#queId_101$, 32)",
682
+ "meaning": "计算文本的 MD5 摘要。",
683
+ "parameters": [
684
+ {
685
+ "description": "待摘要值",
686
+ "name": "value"
687
+ },
688
+ {
689
+ "description": "可选 16 或 32;其他值按 32 位处理",
690
+ "name": "length",
691
+ "optional": true
692
+ }
693
+ ],
694
+ "returns": {
695
+ "description": "16 位或 32 位小写十六进制摘要;空文本返回 null",
696
+ "type": "string | null"
697
+ },
698
+ "signatures": [
699
+ "MD5(value)",
700
+ "MD5(value, length)"
701
+ ]
702
+ },
703
+ "MID": {
704
+ "category": "text",
705
+ "example": "MID(#queId_101$, 2, 3)",
706
+ "meaning": "从文本的指定位置开始截取指定数量的字符,位置从 1 开始。",
707
+ "parameters": [
708
+ {
709
+ "description": "原文本",
710
+ "name": "text"
711
+ },
712
+ {
713
+ "description": "起始位置,从 1 开始",
714
+ "name": "startNum"
715
+ },
716
+ {
717
+ "description": "截取字符数",
718
+ "name": "numChars"
719
+ }
720
+ ],
721
+ "returns": {
722
+ "description": "截取后的文本",
723
+ "type": "string"
724
+ },
725
+ "signatures": [
726
+ "MID(text, startNum, numChars)"
727
+ ]
728
+ },
729
+ "MIN": {
730
+ "category": "number",
731
+ "example": "MIN(#queId_101$, #queId_102$)",
732
+ "meaning": "返回数字或日期参数中的最小值。",
733
+ "parameters": [
734
+ {
735
+ "description": "数字、日期或对应列表",
736
+ "name": "values",
737
+ "variadic": true
738
+ }
739
+ ],
740
+ "returns": {
741
+ "description": "最小数字或最早日期",
742
+ "type": "number | string | null"
743
+ },
744
+ "signatures": [
745
+ "MIN(value1, value2, ...)"
746
+ ]
747
+ },
748
+ "MINUTE": {
749
+ "category": "date",
750
+ "example": "MINUTE(#queId_101$)",
751
+ "meaning": "提取日期时间中的分钟。",
752
+ "parameters": [
753
+ {
754
+ "description": "日期时间",
755
+ "name": "date"
756
+ }
757
+ ],
758
+ "returns": {
759
+ "description": "分钟文本",
760
+ "type": "string | null"
761
+ },
762
+ "signatures": [
763
+ "MINUTE(date)"
764
+ ]
765
+ },
766
+ "MOD": {
767
+ "category": "number",
768
+ "example": "MOD(#queId_101$, 2)",
769
+ "meaning": "返回两数相除的整数余数。",
770
+ "parameters": [
771
+ {
772
+ "description": "被除数",
773
+ "name": "number"
774
+ },
775
+ {
776
+ "description": "除数",
777
+ "name": "divisor"
778
+ }
779
+ ],
780
+ "returns": {
781
+ "description": "余数;除数为 0 时返回 0",
782
+ "type": "integer | null"
783
+ },
784
+ "signatures": [
785
+ "MOD(number, divisor)"
786
+ ]
787
+ },
788
+ "MONTH": {
789
+ "category": "date",
790
+ "example": "MONTH(#queId_101$)",
791
+ "meaning": "提取日期或日期时间中的月份。",
792
+ "parameters": [
793
+ {
794
+ "description": "日期或日期时间",
795
+ "name": "date"
796
+ }
797
+ ],
798
+ "returns": {
799
+ "description": "1 至 12 的月份文本",
800
+ "type": "string | null"
801
+ },
802
+ "signatures": [
803
+ "MONTH(date)"
804
+ ]
805
+ },
806
+ "NETWORKDAYS": {
807
+ "category": "date",
808
+ "example": "NETWORKDAYS(#queId_101$, #queId_102$, \"1000001\", \"2026-10-01\")",
809
+ "meaning": "计算两个日期之间包含首尾日期的工作日数,可自定义休息日和假期。",
810
+ "parameters": [
811
+ {
812
+ "description": "开始日期",
813
+ "name": "startDate"
814
+ },
815
+ {
816
+ "description": "结束日期",
817
+ "name": "endDate"
818
+ },
819
+ {
820
+ "description": "可选 7 位 0/1 文本,从周日到周六,1 表示休息;省略时为 1000001",
821
+ "name": "weekend",
822
+ "optional": true
823
+ },
824
+ {
825
+ "description": "可选假期日期",
826
+ "name": "holidays",
827
+ "optional": true,
828
+ "variadic": true
829
+ }
830
+ ],
831
+ "returns": {
832
+ "description": "工作日数量文本;反向区间返回负数",
833
+ "type": "string | null"
834
+ },
835
+ "signatures": [
836
+ "NETWORKDAYS(startDate, endDate)",
837
+ "NETWORKDAYS(startDate, endDate, weekend, holiday1, holiday2, ...)"
838
+ ]
839
+ },
840
+ "NOT": {
841
+ "category": "logical",
842
+ "example": "NOT(ISEMPTY(#queId_101$))",
843
+ "meaning": "对布尔值取反。",
844
+ "parameters": [
845
+ {
846
+ "description": "布尔值",
847
+ "name": "value"
848
+ }
849
+ ],
850
+ "returns": {
851
+ "description": "输入值的逻辑反值",
852
+ "type": "boolean"
853
+ },
854
+ "signatures": [
855
+ "NOT(value)"
856
+ ]
857
+ },
858
+ "NOW": {
859
+ "category": "date",
860
+ "example": "NOW()",
861
+ "meaning": "取得公式执行时的当前日期时间。",
862
+ "parameters": [],
863
+ "returns": {
864
+ "description": "yyyy-MM-dd HH:mm:ss 格式的当前日期时间",
865
+ "type": "string"
866
+ },
867
+ "signatures": [
868
+ "NOW()"
869
+ ]
870
+ },
871
+ "NUM": {
872
+ "category": "text",
873
+ "example": "NUM(\"订单金额 12.50 元\")",
874
+ "meaning": "从每个文本值中提取首次出现的数字。",
875
+ "parameters": [
876
+ {
877
+ "description": "包含数字的文本或列表",
878
+ "name": "values",
879
+ "variadic": true
880
+ }
881
+ ],
882
+ "returns": {
883
+ "description": "单个输入返回首个数字,多个值返回数字列表,未找到时返回 null",
884
+ "type": "number | list | null"
885
+ },
886
+ "signatures": [
887
+ "NUM(value1, value2, ...)"
888
+ ]
889
+ },
890
+ "OR": {
891
+ "category": "logical",
892
+ "example": "OR(#queId_101$ == \"A\", #queId_101$ == \"B\")",
893
+ "meaning": "判断是否至少有一个条件为真。",
894
+ "parameters": [
895
+ {
896
+ "description": "一个或多个布尔条件",
897
+ "name": "conditions",
898
+ "variadic": true
899
+ }
900
+ ],
901
+ "returns": {
902
+ "description": "至少一个为真时返回 TRUE,否则返回 FALSE",
903
+ "type": "boolean"
904
+ },
905
+ "signatures": [
906
+ "OR(condition1, condition2, ...)"
907
+ ]
908
+ },
909
+ "POWER": {
910
+ "category": "number",
911
+ "example": "POWER(#queId_101$, 2)",
912
+ "meaning": "计算指定数字的幂。",
913
+ "parameters": [
914
+ {
915
+ "description": "底数",
916
+ "name": "number"
917
+ },
918
+ {
919
+ "description": "指数,可为整数或小数",
920
+ "name": "power"
921
+ }
922
+ ],
923
+ "returns": {
924
+ "description": "幂运算结果的数字文本",
925
+ "type": "string"
926
+ },
927
+ "signatures": [
928
+ "POWER(number, power)"
929
+ ]
930
+ },
931
+ "PRODUCT": {
932
+ "category": "number",
933
+ "example": "PRODUCT(#queId_101$, #queId_102$)",
934
+ "meaning": "计算所有数字参数和列表元素的乘积。",
935
+ "parameters": [
936
+ {
937
+ "description": "数字、数字字段或数字列表",
938
+ "name": "values",
939
+ "variadic": true
940
+ }
941
+ ],
942
+ "returns": {
943
+ "description": "数值乘积;没有数值时返回 1",
944
+ "type": "number"
945
+ },
946
+ "signatures": [
947
+ "PRODUCT(value1, value2, ...)"
948
+ ]
949
+ },
950
+ "RDID": {
951
+ "category": "utility",
952
+ "example": "RDID()",
953
+ "meaning": "生成一个随机 UUID。",
954
+ "parameters": [],
955
+ "returns": {
956
+ "description": "UUID 文本",
957
+ "type": "string"
958
+ },
959
+ "signatures": [
960
+ "RDID()"
961
+ ]
962
+ },
963
+ "RECNO": {
964
+ "category": "context",
965
+ "example": "RECNO()",
966
+ "meaning": "取得当前表单被打开的次数。",
967
+ "parameters": [],
968
+ "returns": {
969
+ "description": "表单访问次数;无法取得时返回 0",
970
+ "type": "integer"
971
+ },
972
+ "signatures": [
973
+ "RECNO()"
974
+ ]
975
+ },
976
+ "REGTEST": {
977
+ "category": "utility",
978
+ "example": "REGTEST(#queId_101$, \"^[A-Z]+$\", \"i\")",
979
+ "meaning": "使用正则表达式测试文本或列表中是否有匹配项。",
980
+ "parameters": [
981
+ {
982
+ "description": "待测试文本或列表",
983
+ "name": "text"
984
+ },
985
+ {
986
+ "description": "正则表达式文本",
987
+ "name": "pattern"
988
+ },
989
+ {
990
+ "description": "正则标志,例如 i、m 或空字符串",
991
+ "name": "flags"
992
+ }
993
+ ],
994
+ "returns": {
995
+ "description": "任一值匹配时返回 TRUE",
996
+ "type": "boolean"
997
+ },
998
+ "signatures": [
999
+ "REGTEST(text, pattern, flags)"
1000
+ ]
1001
+ },
1002
+ "REPLACE": {
1003
+ "category": "text",
1004
+ "example": "REPLACE(#queId_101$, 1, 2, \"新\")",
1005
+ "meaning": "从指定位置替换指定数量的字符,位置从 1 开始。",
1006
+ "parameters": [
1007
+ {
1008
+ "description": "原文本",
1009
+ "name": "oldText"
1010
+ },
1011
+ {
1012
+ "description": "替换起始位置,从 1 开始",
1013
+ "name": "startNumber"
1014
+ },
1015
+ {
1016
+ "description": "要替换的字符数",
1017
+ "name": "numberChars"
1018
+ },
1019
+ {
1020
+ "description": "替代文本",
1021
+ "name": "newText"
1022
+ }
1023
+ ],
1024
+ "returns": {
1025
+ "description": "替换后的文本",
1026
+ "type": "string"
1027
+ },
1028
+ "signatures": [
1029
+ "REPLACE(oldText, startNumber, numberChars, newText)"
1030
+ ]
1031
+ },
1032
+ "RIGHT": {
1033
+ "category": "text",
1034
+ "example": "RIGHT(#queId_101$, 4)",
1035
+ "meaning": "从文本右侧截取指定数量的字符。",
1036
+ "parameters": [
1037
+ {
1038
+ "description": "原文本",
1039
+ "name": "text"
1040
+ },
1041
+ {
1042
+ "description": "截取字符数",
1043
+ "name": "numChars"
1044
+ }
1045
+ ],
1046
+ "returns": {
1047
+ "description": "截取后的文本",
1048
+ "type": "string"
1049
+ },
1050
+ "signatures": [
1051
+ "RIGHT(text, numChars)"
1052
+ ]
1053
+ },
1054
+ "RMBUPPER": {
1055
+ "category": "text",
1056
+ "example": "RMBUPPER(#queId_101$)",
1057
+ "meaning": "将数字转换为中文大写金额。",
1058
+ "parameters": [
1059
+ {
1060
+ "description": "不超过 15 位的数字",
1061
+ "name": "value"
1062
+ }
1063
+ ],
1064
+ "returns": {
1065
+ "description": "中文大写金额;输入无效或过大时返回 null",
1066
+ "type": "string | null"
1067
+ },
1068
+ "signatures": [
1069
+ "RMBUPPER(value)"
1070
+ ]
1071
+ },
1072
+ "ROUND": {
1073
+ "category": "number",
1074
+ "example": "ROUND(#queId_101$, 2)",
1075
+ "meaning": "按四舍五入保留指定小数位。",
1076
+ "parameters": [
1077
+ {
1078
+ "description": "数字",
1079
+ "name": "value"
1080
+ },
1081
+ {
1082
+ "description": "保留的小数位数",
1083
+ "name": "numDigits"
1084
+ }
1085
+ ],
1086
+ "returns": {
1087
+ "description": "保留固定位数的数字文本",
1088
+ "type": "string | null"
1089
+ },
1090
+ "signatures": [
1091
+ "ROUND(value, numDigits)"
1092
+ ]
1093
+ },
1094
+ "ROUNDDOWN": {
1095
+ "category": "number",
1096
+ "example": "ROUNDDOWN(#queId_101$, 2)",
1097
+ "meaning": "向负无穷方向舍入并保留指定小数位。",
1098
+ "parameters": [
1099
+ {
1100
+ "description": "数字",
1101
+ "name": "value"
1102
+ },
1103
+ {
1104
+ "description": "保留的小数位数",
1105
+ "name": "numDigits"
1106
+ }
1107
+ ],
1108
+ "returns": {
1109
+ "description": "舍入后的数字文本",
1110
+ "type": "string | null"
1111
+ },
1112
+ "signatures": [
1113
+ "ROUNDDOWN(value, numDigits)"
1114
+ ]
1115
+ },
1116
+ "ROUNDUP": {
1117
+ "category": "number",
1118
+ "example": "ROUNDUP(#queId_101$, 2)",
1119
+ "meaning": "向正无穷方向舍入并保留指定小数位。",
1120
+ "parameters": [
1121
+ {
1122
+ "description": "数字",
1123
+ "name": "value"
1124
+ },
1125
+ {
1126
+ "description": "保留的小数位数",
1127
+ "name": "numDigits"
1128
+ }
1129
+ ],
1130
+ "returns": {
1131
+ "description": "舍入后的数字文本",
1132
+ "type": "string | null"
1133
+ },
1134
+ "signatures": [
1135
+ "ROUNDUP(value, numDigits)"
1136
+ ]
1137
+ },
1138
+ "SEARCH": {
1139
+ "category": "text",
1140
+ "example": "SEARCH(\"-\", #queId_101$)",
1141
+ "meaning": "查找文本首次出现的位置,位置从 1 开始。",
1142
+ "parameters": [
1143
+ {
1144
+ "description": "要查找的文本",
1145
+ "name": "searchText"
1146
+ },
1147
+ {
1148
+ "description": "被查找的原文本",
1149
+ "name": "targetText"
1150
+ },
1151
+ {
1152
+ "description": "可选起始位置,从 1 开始",
1153
+ "name": "beginPos",
1154
+ "optional": true
1155
+ }
1156
+ ],
1157
+ "returns": {
1158
+ "description": "首次出现的位置;未找到返回 0",
1159
+ "type": "integer"
1160
+ },
1161
+ "signatures": [
1162
+ "SEARCH(searchText, targetText)",
1163
+ "SEARCH(searchText, targetText, beginPos)"
1164
+ ]
1165
+ },
1166
+ "SECOND": {
1167
+ "category": "date",
1168
+ "example": "SECOND(#queId_101$)",
1169
+ "meaning": "提取日期时间中的秒。",
1170
+ "parameters": [
1171
+ {
1172
+ "description": "日期时间",
1173
+ "name": "date"
1174
+ }
1175
+ ],
1176
+ "returns": {
1177
+ "description": "秒文本",
1178
+ "type": "string | null"
1179
+ },
1180
+ "signatures": [
1181
+ "SECOND(date)"
1182
+ ]
1183
+ },
1184
+ "SQRT": {
1185
+ "category": "number",
1186
+ "example": "SQRT(#queId_101$)",
1187
+ "meaning": "计算非负数的平方根。",
1188
+ "parameters": [
1189
+ {
1190
+ "description": "非负数字",
1191
+ "name": "value"
1192
+ }
1193
+ ],
1194
+ "returns": {
1195
+ "description": "平方根的数字文本;负数或 null 返回 null",
1196
+ "type": "string | null"
1197
+ },
1198
+ "signatures": [
1199
+ "SQRT(value)"
1200
+ ]
1201
+ },
1202
+ "SUM": {
1203
+ "category": "number",
1204
+ "example": "SUM(#queId_101$, #queId_102$, 10)",
1205
+ "meaning": "计算所有数字参数和列表元素的总和。",
1206
+ "parameters": [
1207
+ {
1208
+ "description": "数字、数字字段或数字列表",
1209
+ "name": "values",
1210
+ "variadic": true
1211
+ }
1212
+ ],
1213
+ "returns": {
1214
+ "description": "数值总和",
1215
+ "type": "number"
1216
+ },
1217
+ "signatures": [
1218
+ "SUM(value1, value2, ...)"
1219
+ ]
1220
+ },
1221
+ "SUMIF": {
1222
+ "category": "number",
1223
+ "example": "SUMIF(#queId_101$, \"华东\", #queId_102$)",
1224
+ "meaning": "对条件范围中等于指定值的对应数字求和。",
1225
+ "parameters": [
1226
+ {
1227
+ "description": "用于逐项比较的列表",
1228
+ "name": "base"
1229
+ },
1230
+ {
1231
+ "description": "匹配值",
1232
+ "name": "compare"
1233
+ },
1234
+ {
1235
+ "description": "匹配后按相同索引求和的数字列表",
1236
+ "name": "values"
1237
+ }
1238
+ ],
1239
+ "returns": {
1240
+ "description": "满足条件项对应数值的总和",
1241
+ "type": "number"
1242
+ },
1243
+ "signatures": [
1244
+ "SUMIF(base, compare, values)"
1245
+ ]
1246
+ },
1247
+ "SUMPRODUCT": {
1248
+ "category": "number",
1249
+ "example": "SUMPRODUCT(#queId_101$, #queId_102$)",
1250
+ "meaning": "将多个等序列按索引逐项相乘后求和,以最短序列长度为准。",
1251
+ "parameters": [
1252
+ {
1253
+ "description": "两个或更多按行对齐的数字列表",
1254
+ "name": "valueLists",
1255
+ "variadic": true
1256
+ }
1257
+ ],
1258
+ "returns": {
1259
+ "description": "逐项乘积之和",
1260
+ "type": "number"
1261
+ },
1262
+ "signatures": [
1263
+ "SUMPRODUCT(values1, values2, ...)"
1264
+ ]
1265
+ },
1266
+ "TEXT": {
1267
+ "category": "text",
1268
+ "example": "TEXT(#queId_101$, \"yyyy-MM-dd\")",
1269
+ "meaning": "将日期或日期时间按指定格式转为文本,也支持 E、EE、EEE 星期格式。",
1270
+ "parameters": [
1271
+ {
1272
+ "description": "日期、日期时间或可转换值",
1273
+ "name": "value"
1274
+ },
1275
+ {
1276
+ "description": "格式,例如 yyyy-MM-dd、yyyy-MM-dd HH:mm:ss、E、EE 或 EEE",
1277
+ "name": "textFormat"
1278
+ }
1279
+ ],
1280
+ "returns": {
1281
+ "description": "格式化后的文本;无法解析日期时返回空字符串",
1282
+ "type": "string"
1283
+ },
1284
+ "signatures": [
1285
+ "TEXT(value, textFormat)"
1286
+ ]
1287
+ },
1288
+ "TEXTDEPT": {
1289
+ "category": "context",
1290
+ "example": "TEXTDEPT(#queId_101$, \"name\")",
1291
+ "meaning": "把部门字段中的部门 ID 转换为 ID 或部门名称,列表结果用逗号连接。",
1292
+ "parameters": [
1293
+ {
1294
+ "description": "部门 ID 或其列表,通常来自部门字段",
1295
+ "name": "departmentIds"
1296
+ },
1297
+ {
1298
+ "description": "id 返回部门 ID,name 返回部门名称",
1299
+ "name": "mode"
1300
+ }
1301
+ ],
1302
+ "returns": {
1303
+ "description": "转换后的部门 ID 或名称",
1304
+ "type": "string | integer"
1305
+ },
1306
+ "signatures": [
1307
+ "TEXTDEPT(departmentIds, mode)"
1308
+ ]
1309
+ },
1310
+ "TEXTUSER": {
1311
+ "category": "context",
1312
+ "example": "TEXTUSER(#queId_101$, \"name\")",
1313
+ "meaning": "把成员字段中的邮箱标识转换为邮箱或成员名称,列表结果用逗号连接。",
1314
+ "parameters": [
1315
+ {
1316
+ "description": "成员邮箱标识或其列表,通常来自成员字段",
1317
+ "name": "emails"
1318
+ },
1319
+ {
1320
+ "description": "email 返回邮箱,name 返回名称",
1321
+ "name": "mode"
1322
+ }
1323
+ ],
1324
+ "returns": {
1325
+ "description": "转换后的邮箱或名称文本",
1326
+ "type": "string"
1327
+ },
1328
+ "signatures": [
1329
+ "TEXTUSER(emails, mode)"
1330
+ ]
1331
+ },
1332
+ "TIMESTAMPTODATE": {
1333
+ "category": "date",
1334
+ "example": "TIMESTAMPTODATE(1755648000000)",
1335
+ "meaning": "将 10 位秒时间戳或 13 位毫秒时间戳转换为日期时间。",
1336
+ "parameters": [
1337
+ {
1338
+ "description": "10 位或 13 位时间戳",
1339
+ "name": "value"
1340
+ }
1341
+ ],
1342
+ "returns": {
1343
+ "description": "yyyy-MM-dd HH:mm:ss 格式文本",
1344
+ "type": "string | null"
1345
+ },
1346
+ "signatures": [
1347
+ "TIMESTAMPTODATE(value)"
1348
+ ]
1349
+ },
1350
+ "TRIPLEDES": {
1351
+ "category": "utility",
1352
+ "example": "TRIPLEDES(#queId_101$, \"123456789012345678901234\", NULL, \"ECB\", \"PKCS5PADDING\")",
1353
+ "meaning": "使用 3DES 加密文本并返回 Base64 密文。",
1354
+ "parameters": [
1355
+ {
1356
+ "description": "明文",
1357
+ "name": "content"
1358
+ },
1359
+ {
1360
+ "description": "长度至少 24 且为 8 的倍数的密钥",
1361
+ "name": "secret"
1362
+ },
1363
+ {
1364
+ "description": "8 字节向量;ECB 模式可传 NULL",
1365
+ "name": "iv"
1366
+ },
1367
+ {
1368
+ "description": "可选 ECB、CBC、CTR、OFB、CFB;省略时为 ECB",
1369
+ "name": "mode",
1370
+ "optional": true
1371
+ },
1372
+ {
1373
+ "description": "可选 NOPADDING、PKCS5PADDING、ISO10126;省略时为 NOPADDING",
1374
+ "name": "padding",
1375
+ "optional": true
1376
+ }
1377
+ ],
1378
+ "returns": {
1379
+ "description": "Base64 编码的加密结果",
1380
+ "type": "string"
1381
+ },
1382
+ "signatures": [
1383
+ "TRIPLEDES(content, secret, iv)",
1384
+ "TRIPLEDES(content, secret, iv, mode)",
1385
+ "TRIPLEDES(content, secret, iv, mode, padding)"
1386
+ ]
1387
+ },
1388
+ "UNICODEDECODE": {
1389
+ "category": "utility",
1390
+ "example": "UNICODEDECODE(#queId_101$)",
1391
+ "meaning": "将文本中的四位十六进制 Unicode 转义序列解码为字符。",
1392
+ "parameters": [
1393
+ {
1394
+ "description": "包含 \\uXXXX 序列的文本",
1395
+ "name": "value"
1396
+ }
1397
+ ],
1398
+ "returns": {
1399
+ "description": "解码后的文本",
1400
+ "type": "string"
1401
+ },
1402
+ "signatures": [
1403
+ "UNICODEDECODE(value)"
1404
+ ]
1405
+ },
1406
+ "UNICODEENCODE": {
1407
+ "category": "utility",
1408
+ "example": "UNICODEENCODE(#queId_101$)",
1409
+ "meaning": "将每个字符编码为四位十六进制 Unicode 转义序列。",
1410
+ "parameters": [
1411
+ {
1412
+ "description": "待编码值",
1413
+ "name": "value"
1414
+ }
1415
+ ],
1416
+ "returns": {
1417
+ "description": "由 \\uXXXX 序列组成的文本",
1418
+ "type": "string"
1419
+ },
1420
+ "signatures": [
1421
+ "UNICODEENCODE(value)"
1422
+ ]
1423
+ },
1424
+ "UPPER": {
1425
+ "category": "text",
1426
+ "example": "UPPER(#queId_101$)",
1427
+ "meaning": "将文本转换为大写。",
1428
+ "parameters": [
1429
+ {
1430
+ "description": "待转换值",
1431
+ "name": "value"
1432
+ }
1433
+ ],
1434
+ "returns": {
1435
+ "description": "大写文本",
1436
+ "type": "string"
1437
+ },
1438
+ "signatures": [
1439
+ "UPPER(value)"
1440
+ ]
1441
+ },
1442
+ "XOR": {
1443
+ "category": "logical",
1444
+ "example": "XOR(#queId_101$ > 0, #queId_102$ > 0)",
1445
+ "meaning": "对两个布尔值执行异或。",
1446
+ "parameters": [
1447
+ {
1448
+ "description": "第一个布尔值",
1449
+ "name": "value1"
1450
+ },
1451
+ {
1452
+ "description": "第二个布尔值",
1453
+ "name": "value2"
1454
+ }
1455
+ ],
1456
+ "returns": {
1457
+ "description": "两个值不同时返回 TRUE,相同时返回 FALSE",
1458
+ "type": "boolean"
1459
+ },
1460
+ "signatures": [
1461
+ "XOR(value1, value2)"
1462
+ ]
1463
+ },
1464
+ "YEAR": {
1465
+ "category": "date",
1466
+ "example": "YEAR(#queId_101$)",
1467
+ "meaning": "提取日期或日期时间中的年份。",
1468
+ "parameters": [
1469
+ {
1470
+ "description": "日期或日期时间",
1471
+ "name": "date"
1472
+ }
1473
+ ],
1474
+ "returns": {
1475
+ "description": "四位年份文本",
1476
+ "type": "string | null"
1477
+ },
1478
+ "signatures": [
1479
+ "YEAR(date)"
1480
+ ]
1481
+ }
1482
+ },
1483
+ "x-qingflow-literals": [
1484
+ {
1485
+ "kind": "integer",
1486
+ "meaning": "整数",
1487
+ "syntax": "123"
1488
+ },
1489
+ {
1490
+ "kind": "decimal",
1491
+ "meaning": "小数",
1492
+ "syntax": "12.50"
1493
+ },
1494
+ {
1495
+ "kind": "string",
1496
+ "meaning": "双引号字符串,支持常见反斜杠转义和 Unicode 转义",
1497
+ "syntax": "\"文本\""
1498
+ },
1499
+ {
1500
+ "kind": "boolean",
1501
+ "meaning": "布尔值,也接受对应的小写形式",
1502
+ "syntax": "TRUE | FALSE"
1503
+ },
1504
+ {
1505
+ "kind": "null",
1506
+ "meaning": "空值,也接受小写 null",
1507
+ "syntax": "NULL"
1508
+ },
1509
+ {
1510
+ "kind": "list",
1511
+ "meaning": "表达式列表",
1512
+ "syntax": "[expr1, expr2, ...]"
1513
+ }
1514
+ ],
1515
+ "x-qingflow-operators": [
1516
+ {
1517
+ "example": "-#queId_101$",
1518
+ "meaning": "数值取负",
1519
+ "syntax": "-expr"
1520
+ },
1521
+ {
1522
+ "example": "#queId_101$ * 2",
1523
+ "meaning": "乘法",
1524
+ "syntax": "expr * expr"
1525
+ },
1526
+ {
1527
+ "example": "#queId_101$ / 100",
1528
+ "meaning": "除法;除数为 0 时结果按后端公式引擎规则处理为 0",
1529
+ "syntax": "expr / expr"
1530
+ },
1531
+ {
1532
+ "example": "#queId_101$ + #queId_102$",
1533
+ "meaning": "数值加法",
1534
+ "syntax": "expr + expr"
1535
+ },
1536
+ {
1537
+ "example": "#queId_101$ - #queId_102$",
1538
+ "meaning": "数值减法",
1539
+ "syntax": "expr - expr"
1540
+ },
1541
+ {
1542
+ "example": "#queId_101$ >= 60",
1543
+ "meaning": "相等、不等及大小比较,返回布尔值",
1544
+ "syntax": "== | != | < | <= | > | >="
1545
+ },
1546
+ {
1547
+ "example": "NOT #queId_101$",
1548
+ "meaning": "逻辑非",
1549
+ "syntax": "NOT expr"
1550
+ },
1551
+ {
1552
+ "example": "#queId_101$ XOR #queId_102$",
1553
+ "meaning": "逻辑异或",
1554
+ "syntax": "expr XOR expr"
1555
+ },
1556
+ {
1557
+ "example": "#queId_101$ > 0 and #queId_102$ > 0",
1558
+ "meaning": "逻辑与",
1559
+ "syntax": "expr and expr"
1560
+ },
1561
+ {
1562
+ "example": "#queId_101$ > 0 or #queId_102$ > 0",
1563
+ "meaning": "逻辑或",
1564
+ "syntax": "expr or expr"
1565
+ },
1566
+ {
1567
+ "example": "(#queId_101$ + #queId_102$) * 2",
1568
+ "meaning": "显式控制计算优先级",
1569
+ "syntax": "(expr)"
1570
+ }
1571
+ ],
1572
+ "x-qingflow-usage": {
1573
+ "appFormExample": {
1574
+ "defaultType": 3,
1575
+ "defaultValue": "CONCAT(\"文本字段:\", #queId_101$, \" / 数字字段:\", #queId_102$)",
1576
+ "questionType": "text"
1577
+ },
1578
+ "notes": [
1579
+ "不要把 #queId_<字段ID>$ 当作普通字符串加引号。",
1580
+ "字段 name 仅用于 AppForm 声明中的字段定位,不能写入公式作为变量;例如 文本字段 和 \"文本字段\" 都不是字段引用。",
1581
+ "\"测试文本\"、\"12.50\" 等带引号文本只是静态字面量,不会随对应字段值变化。",
1582
+ "创建声明中没有已回读 queId 的字段不能作为动态公式引用;无法解析的 ID 会导致校验或绑定失败。",
1583
+ "函数参数使用英文逗号或中文逗号分隔,括号支持半角或全角形式。"
1584
+ ],
1585
+ "steps": [
1586
+ "先通过 app_form_get 获取已保存字段的 queId。",
1587
+ "将公式字段的 defaultType 设置为 3。",
1588
+ "将未编码的公式文本直接写入 defaultValue;builder 负责后端所需的编码处理。",
1589
+ "字段引用必须使用 #queId_<字段ID>$,函数名使用大写形式,字符串使用双引号。",
1590
+ "需要拼接字段当前值时,将该字段的实际 queId 写成未加引号的 #queId_<字段ID>$;字段 name、字段标题和字段默认值都不能替代字段引用。",
1591
+ "新建应用的同一次 create 声明中尚未获得 queId 时,不得虚构 queId 或以字段 name 代替:先创建字段,app_form_get 回读实际 queId 后,再提交公式默认值更新。"
1592
+ ]
1593
+ }
1594
+ }