cloudcc-cli 2.3.8 → 2.4.0

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 (66) hide show
  1. package/.cursor/skills/{cloudcc-cli-dev → dev-guide}/SKILL.md +5 -1
  2. package/README.md +82 -1
  3. package/bin/cc.js +2 -1
  4. package/bin/index.js +1 -0
  5. package/cloudcc-dev-skill/SKILL.md +31 -8
  6. package/cloudcc-dev-skill/cloudcc-dev-html.md +42 -0
  7. package/cloudcc-dev-skill/config.json +2 -2
  8. package/mcp/index.js +27 -3
  9. package/mcp/tools/JSP Migrator/handler.js +51 -866
  10. package/mcp/tools/Object Creator/handler.js +14 -4
  11. package/mcp/tools/Object Fields Creator/handler.js +149 -3
  12. package/package.json +1 -1
  13. package/src/classes/docs/devguide.md +758 -364
  14. package/src/classes/docs/introduction.md +279 -143
  15. package/src/fields/buildFieldData.js +692 -0
  16. package/src/fields/create.js +10 -170
  17. package/src/fields/detail.js +37 -0
  18. package/src/fields/docs/devguide.md +168 -44
  19. package/src/fields/docs/introduction.md +2 -0
  20. package/src/fields/fields/A.js +3 -2
  21. package/src/fields/fields/AD.js +4 -2
  22. package/src/fields/fields/B.js +8 -5
  23. package/src/fields/fields/C.js +13 -5
  24. package/src/fields/fields/D.js +4 -4
  25. package/src/fields/fields/E.js +10 -5
  26. package/src/fields/fields/ENC.js +27 -8
  27. package/src/fields/fields/ENCD.js +27 -8
  28. package/src/fields/fields/F.js +4 -4
  29. package/src/fields/fields/FL.js +8 -4
  30. package/src/fields/fields/H.js +4 -4
  31. package/src/fields/fields/IMG.js +23 -5
  32. package/src/fields/fields/J.js +21 -6
  33. package/src/fields/fields/L.js +32 -8
  34. package/src/fields/fields/LT.js +23 -6
  35. package/src/fields/fields/M.js +2 -2
  36. package/src/fields/fields/MR.js +2 -2
  37. package/src/fields/fields/N.js +31 -8
  38. package/src/fields/fields/P.js +13 -5
  39. package/src/fields/fields/Q.js +42 -12
  40. package/src/fields/fields/S.js +19 -7
  41. package/src/fields/fields/SCORE.js +9 -4
  42. package/src/fields/fields/T.js +4 -4
  43. package/src/fields/fields/U.js +18 -5
  44. package/src/fields/fields/X.js +20 -6
  45. package/src/fields/fields/Y.js +17 -4
  46. package/src/fields/index.js +2 -0
  47. package/src/fields/update.js +148 -0
  48. package/src/jsp/analyze.js +17 -0
  49. package/src/jsp/doc.js +18 -0
  50. package/src/jsp/docs/devguide.md +111 -0
  51. package/src/jsp/docs/introduction.md +50 -0
  52. package/src/jsp/docs.js +21 -0
  53. package/src/jsp/index.js +14 -0
  54. package/src/jsp/migration.js +871 -0
  55. package/src/jsp/split.js +17 -0
  56. package/src/object/create.js +36 -10
  57. package/src/object/docs/devguide.md +6 -3
  58. package/src/project/docs/devguide.md +1 -1
  59. package/src/timer/docs/devguide.md +849 -400
  60. package/src/timer/docs/introduction.md +343 -231
  61. package/src/triggers/docs/devguide.md +929 -352
  62. package/src/triggers/docs/introduction.md +640 -369
  63. package/src/version/listModuleCommands.js +6 -0
  64. package/test/fields.cli.test.js +3 -1
  65. package/test/jsp.cli.test.js +70 -0
  66. package/test/object.cli.test.js +9 -1
@@ -1,404 +1,675 @@
1
- # CloudCC 触发器使用总结
1
+ # CloudCC 触发器 AI 概念规范
2
2
 
3
- > 基于生产环境 25 个触发器实例分析
4
- > 文档版本:v1.0
5
- > 更新时间:2026-03-24
3
+ ## 1. 文档目的
6
4
 
7
- ## 一、什么是触发器
5
+ 本文用于给 AI 提供一份稳定、抽象、可复用的触发器概念说明。
8
6
 
9
- CloudCC 触发器是符合 Java 语法规范的服务端代码,在特定业务事件发生时自动执行,用于实现业务逻辑自动化处理。
7
+ 目标不是描述某一个具体业务触发器怎么写,而是回答以下问题:
10
8
 
11
- 触发器本质:
9
+ - 触发器是什么
10
+ - 触发器能干什么
11
+ - 触发器的主要作用是什么
12
+ - 为什么要用触发器
13
+ - 触发器能解决哪些问题
14
+ - 什么时候应该使用触发器
15
+ - 在什么业务场景下适合使用触发器
16
+ - 什么时候不应该使用触发器
12
17
 
13
- - 一段 Java 代码,运行在 CloudCC 平台沙箱环境中
14
- - 使用 `CCService`、`CCObject` 等平台 API 类
15
- - 在数据变更的特定时刻(前/后)自动触发执行
18
+ 本文不包含业务代码,不绑定某一个对象字段设计,重点服务于 AI 后续做方案判断、实现选型和需求归类。
16
19
 
17
- ## 二、触发器能干什么
20
+ ## 2. 触发器是什么
18
21
 
19
- ### 2.1 核心能力
22
+ 触发器是 CloudCC 服务端的事件驱动逻辑入口。
20
23
 
21
- | 能力 | 说明 | 示例 |
22
- | --- | --- | --- |
23
- | 自动赋值 | 在记录保存前自动计算并填充字段 | 个人业绩/部门业绩自动赋值 |
24
- | 数据校验 | 阻止不符合业务规则的数据保存 | 预算金额校验、审批金额验证 |
25
- | 关联更新 | 修改一条记录时自动更新关联记录 | 回款明细汇总到收款计划 |
26
- | 自动生成 | 根据业务规则自动创建新记录 | 审批通过后自动生成回款记录 |
27
- | 权限控制 | 自动设置数据共享权限 | 按部门/人员自动共享 |
28
- | 状态同步 | 审批状态变更后同步更新相关字段 | 预算审批状态回写 |
29
- | 汇总计算 | 实时汇总明细数据到主记录 | 部门业绩字段汇总 |
24
+ 它的核心特征是:
30
25
 
31
- ### 2.2 技术能力(基于 CCService API)
26
+ - 绑定在某个对象的某个事件时机上
27
+ - 由平台自动触发,不依赖用户手工执行
28
+ - 运行在服务端,不属于前端页面逻辑
29
+ - 更适合承接“必须发生”“不能绕过”“需要即时处理”的业务规则
32
30
 
33
- ```java
34
- // 1. 新增记录
35
- CCObject opp = new CCObject("Opportunity");
36
- opp.put("name", "value");
37
- cs.insert(opp);
31
+ 从 AI 的角度理解,触发器不是一个“功能页面”,也不是一个“批处理任务”,而是一个“跟着数据变化自动执行的业务守门人和联动器”。
38
32
 
39
- // 2. 查询记录
40
- // 查询指定字段
41
- List<CCObject> opps = cs.cqueryByFields(
42
- "Opportunity",
43
- "khmc__c='" + record_new.get("id") + "'",
44
- "id,name,createdate"
45
- );
33
+ ## 3. 触发器能干什么
46
34
 
47
- // 查询全部字段
48
- List<CCObject> all = cs.cquery("Opportunity", "khmc__c='" + record_new.get("id") + "'");
35
+ 触发器最常见的能力边界包括:
49
36
 
50
- // 复杂 SQL 查询
51
- List<CCObject> ccobjs = cs.cqlQuery(
52
- "Opportunity",
53
- "select sum(amount) as sumAmount from Opportunity where khmc = '0012001238ytwuiw'"
54
- );
37
+ - 数据校验:拦截非法数据、阻止错误提交、限制非法删除
38
+ - 自动赋值:补默认值、带出维度、自动回填关键字段
39
+ - 关联同步:修改当前记录时同步更新关联对象
40
+ - 自动生成:新建记录后自动派生子记录、中间记录、共享记录
41
+ - 状态推进:根据阶段、审批结果、业务动作推进状态机
42
+ - 审批控制:审批前校验,审批后回写、生成、通知、解锁
43
+ - 汇总计算:实时汇总金额、比例、成本、数量、状态
44
+ - 权限治理:自动共享、回收共享、同步负责人、调整协同关系
45
+ - 删除补偿:删除后重算汇总、清理关联、消除待办
46
+ - 通知与集成:发送待办、邮件、OA 通知,或向外部系统推送
55
47
 
56
- // 3. 修改记录
57
- cs.update(opp);
48
+ 一句话概括:
58
49
 
59
- // 4. 删除记录
60
- cs.delete(opp);
50
+ 触发器最适合做“和当前数据变更强相关、必须立即发生、必须由平台统一执行”的事情。
61
51
 
62
- // 5. 发送邮件通知
63
- SendEmail sendEmail = new SendEmail(userInfo);
64
- sendEmail.sendMailFromSystem(toAddress, ccAddress, bccAddress, subject, content, isText);
65
- ```
52
+ ## 4. 触发器的主要作用
66
53
 
67
- ## 三、触发器触发时机详解
54
+ ### 4.1 作为业务规则的统一入口
68
55
 
69
- ### 3.1 beforeUpsert(创建或更新前)
56
+ 很多规则不能只依赖前端页面校验,因为:
70
57
 
71
- 执行时机:记录保存之前,数据尚未写入数据库。
72
- 典型用途:
58
+ - 页面可能不止一个
59
+ - 导入、接口、批量操作也会写入数据
60
+ - 人工操作容易绕过流程
73
61
 
74
- - 自动计算字段值
75
- - 数据格式校验
76
- - 阻止非法数据保存(抛出异常)
77
- - 自动填充默认值
62
+ 触发器的作用,就是把规则放到平台层统一执行,让所有入口遵守同一套规则。
78
63
 
79
- 生产实例:
64
+ ### 4.2 作为跨对象联动的自动执行器
80
65
 
81
- | 触发器名称 | 对象 | 作用 |
82
- | --- | --- | --- |
83
- | 个人业绩/部门业绩赋值 | 对外付款 | 自动赋值业绩字段 |
84
- | 计算产研成本/净业绩 | 预算 | 自动计算成本、净业绩 |
85
- | 生成部门/个人业绩 | 净业绩拆分 | 自动创建业绩记录 |
86
- | 编辑更新部门业绩 | 净业绩拆分回款 | 更新前校验和计算 |
66
+ 业务里经常存在“一处变化,多处联动”的情况,例如:
87
67
 
88
- 代码示例:
68
+ - 商机变化后更新报价、合同、项目
69
+ - 明细变化后回写主记录汇总
70
+ - 审批通过后生成下游业务记录
89
71
 
90
- ```java
91
- CCObject record = (CCObject) data.get("record");
92
- BigDecimal income = record.getBigDecimal("ysr");
93
- BigDecimal cost = record.getBigDecimal("cycb");
94
- BigDecimal net = income.subtract(cost);
95
- record.put("jyj", net);
96
- if (net.compareTo(BigDecimal.ZERO) < 0) {
97
- throw new Exception("毛利不能为负数!");
98
- }
99
- ```
72
+ 这类动作不适合依赖用户手工补做,触发器可以在事件发生当下自动处理。
100
73
 
101
- ### 3.2 afterInsert(创建后)
74
+ ### 4.3 作为审批流程的补强层
102
75
 
103
- 执行时机:记录已成功创建,ID 已生成。
104
- 典型用途:
76
+ 审批流适合做流程配置,但复杂判断、跨对象处理、审批前后差异动作,往往需要触发器承接。
105
77
 
106
- - 基于新记录 ID 创建关联记录
107
- - 发送创建通知
108
- - 初始化关联数据
78
+ 因此,触发器在很多项目里不是替代审批流,而是补足审批流。
109
79
 
110
- 生产实例:
80
+ ### 4.4 作为数据质量和一致性的守门人
111
81
 
112
- | 触发器名称 | 对象 | 作用 |
113
- | --- | --- | --- |
114
- | 根据净业绩拆分生成净业绩拆分回款 | 回款明细 | 新建回款明细后自动生成回款记录 |
82
+ 触发器可以把很多“错误数据不要进来”“错误删除不能发生”“状态不能乱跳”“金额不能失真”这类要求,变成系统级约束。
115
83
 
116
- 代码示例:
84
+ ## 5. 为什么要用触发器
117
85
 
118
- ```java
119
- CCObject newRecord = (CCObject) data.get("record");
120
- String recordId = newRecord.getString("id");
86
+ 从业务价值看,触发器的意义主要有六点:
121
87
 
122
- CCObject hkRecord = new CCObject("Huikuan");
123
- hkRecord.put("mingxi__c", recordId);
124
- hkRecord.put("je", newRecord.get("je"));
125
- cs.insert(hkRecord);
126
- ```
88
+ - 实时:记录变化时立即执行,不需要等待定时任务
89
+ - 统一:不管数据从页面、导入还是接口进入,都走同一规则
90
+ - 强约束:关键校验可以做到不可绕过
91
+ - 自动化:减少人工补录、手工回填、人工同步
92
+ - 一致性:多对象、多字段、多状态之间能保持同步
93
+ - 可扩展:复杂流程、复杂校验、复杂派生逻辑都可以承载
127
94
 
128
- ### 3.3 afterUpsert(创建或更新后)
95
+ 如果一个规则满足以下特征,通常就值得优先考虑触发器:
129
96
 
130
- 执行时机:记录已成功保存(新增或修改)。
131
- 典型用途:
132
-
133
- - 汇总数据到父记录
134
- - 触发下游业务流程
135
- - 更新关联记录状态
136
-
137
- 生产实例:
138
-
139
- | 触发器名称 | 对象 | 作用 |
140
- | --- | --- | --- |
141
- | 金额汇总到收款计划 | 回款明细 | 汇总回款金额到收款计划 |
142
- | 更新部门业绩字段 | 部门业绩 | 汇总各维度业绩数据 |
143
- | 更新回款明细 | 回款明细 | 重建净业绩拆分回款记录 |
144
-
145
- 代码示例:
146
-
147
- ```java
148
- CCObject detail = (CCObject) data.get("record");
149
- String planId = detail.getString("skjh__c");
150
- List<CCObject> plans = cs.cqueryByFields("ShoukuanJihua", "id='" + planId + "'", "id,shyjje,yishouje");
151
- if (!plans.isEmpty()) {
152
- CCObject plan = plans.get(0);
153
- BigDecimal current = plan.getBigDecimal("yishouje");
154
- BigDecimal detailAmount = detail.getBigDecimal("je");
155
- plan.put("yishouje", current.add(detailAmount));
156
- cs.update(plan);
157
- }
158
- ```
159
-
160
- ### 3.4 afterDelete(删除后)
161
-
162
- 执行时机:记录已成功删除。
163
- 典型用途:
164
-
165
- - 清理关联数据
166
- - 反向汇总更新
167
-
168
- 生产实例:
169
-
170
- | 触发器名称 | 对象 | 作用 |
171
- | --- | --- | --- |
172
- | 回款明细删除 | 回款明细 | 删除后重新计算回款金额 |
173
-
174
- ### 3.5 approval(审批时)
175
-
176
- 执行时机:记录提交审批或审批通过时。
177
- 典型用途:
178
-
179
- - 审批前校验业务规则
180
- - 审批通过后执行业务操作
181
-
182
- 生产实例:
183
-
184
- | 触发器名称 | 对象 | 作用 |
185
- | --- | --- | --- |
186
- | 更新拆分审批状态 | 预算 | 审批通过后回写状态 |
187
- | 订单审批判断 | 订单 | 审批时校验收款计划 |
188
- | 审批通过计算剩余欠款 | 费用报销 | 审批后计算欠款 |
189
-
190
- ## 四、为什么要用触发器
191
-
192
- ### 4.1 解决的核心问题
193
-
194
- | 问题 | 传统方案 | 触发器方案 |
195
- | --- | --- | --- |
196
- | 数据一致性 | 依赖用户手动操作,容易遗漏 | 自动执行,保证数据准确 |
197
- | 业务规则执行 | 前端校验可绕过 | 平台层统一执行,无法绕过 |
198
- | 跨对象联动 | 需要多次手动操作 | 自动关联更新 |
199
- | 审批流程复杂逻辑 | 审批流配置无法实现 | Java 代码实现任意逻辑 |
200
- | 实时性要求 | 定时任务有延迟 | 实时触发,立即执行 |
201
-
202
- ### 4.2 对比其他方案
203
-
204
- | 方案 | 优点 | 缺点 | 适用场景 |
205
- | --- | --- | --- | --- |
206
- | 触发器 | 实时、自动、无法绕过 | 需要 Java 开发能力 | 核心业务逻辑 |
207
- | 审批流 | 配置简单、可视化 | 逻辑能力有限 | 简单审批流程 |
208
- | 工作流 | 可视化编排 | 复杂逻辑实现困难 | 跨系统流程编排 |
209
- | 定时任务 | 适合批量处理 | 有延迟 | 数据同步、报表生成 |
210
-
211
- ## 五、典型业务场景
212
-
213
- ### 5.1 财务业绩管理(核心场景)
214
-
215
- 触发器链路:
216
-
217
- ```text
218
- 订单 (Order)
219
- │ approval 触发器:审批判断
220
-
221
- 预算 (Budget)
222
- │ beforeUpsert: 计算产研成本/净业绩
223
- │ afterUpsert: 自动拆分/生成回款
224
-
225
- 净业绩拆分 (jyjcf)
226
- │ beforeUpsert: 生成部门/个人业绩
227
- │ afterUpsert: 校验金额累计是否超预算
228
-
229
- 部门业绩 (bmyj)
230
- │ afterUpsert: 更新部门业绩字段
231
- │ afterUpdate: 汇总部门资金池
232
- 回款明细 (cloudccproceeddetail)
233
- │ afterInsert: 生成净业绩拆分回款
234
- │ afterUpsert: 金额汇总到收款计划
235
- │ afterUpsert: 更新回款明细
236
- │ afterDelete: 回款明细删除
237
- ```
238
-
239
- 关键触发器说明:
240
-
241
- 1. 计算产研成本/净业绩(预算 - beforeUpsert)
242
- - 自动计算预算收入、产研成本、净业绩
243
- - 审批控制:毛利 < 0 阻止提交
244
- 2. 生成部门/个人业绩(净业绩拆分 - beforeUpsert)
245
- - 根据拆分规则自动创建业绩记录
246
- - 按 owner 部门与年份关联业绩主数据
247
- 3. 金额汇总到收款计划(回款明细 - afterUpsert)
248
- - 汇总同一回款单下的明细金额
249
- - 回填至收款计划(实际收款、余额、是否完成)
250
- 4. 更新部门业绩字段(部门业绩 - afterUpsert)
251
- - 按“类别 + 业绩计算方式”多维度汇总
252
- - 计算目标完成率
253
-
254
- ### 5.2 费用报销管理
255
-
256
- ```text
257
- 费用报销提交
258
-
259
-
260
- [approval 触发器] 验证审批时校验预算
261
- │ 校验:报销金额 <= 预算余额
262
-
263
- 审批通过
264
-
265
-
266
- [approval 触发器] 审批通过计算剩余欠款
267
- │ 计算:剩余欠款 = 借款 - 报销
268
- ```
269
-
270
- ### 5.3 借款还款管理
271
-
272
- | 触发器 | 对象 | 时机 | 作用 |
273
- | --- | --- | --- | --- |
274
- | 借款单触发器 | 借款单 | beforeUpsert | 借款前校验、自动计算 |
275
- | 还款记录审批通过更新借款单 | 还款记录 | approval | 审批后更新借款单 |
276
-
277
- ## 六、触发器开发最佳实践
278
-
279
- ### 6.1 代码规范
280
-
281
- ```java
282
- try {
283
- CCObject record = (CCObject) data.get("record");
284
- cs.update(record);
285
- } catch (Exception e) {
286
- System.out.println("触发器执行失败:" + e.getMessage());
287
- throw new Exception("业务校验失败:" + e.getMessage());
288
- }
289
- ```
290
-
291
- ### 6.2 性能优化
292
-
293
- ```java
294
- // 字段过滤,只查询需要的字段
295
- List<CCObject> records = cs.cqueryByFields(
296
- "Object__c",
297
- "status__c='active'",
298
- "id,name,amount__c"
299
- );
300
-
301
- // 批量操作使用 updateLt(避免递归)
302
- cs.updateLt(records);
303
- ```
304
-
305
- ### 6.3 避免递归触发
306
-
307
- ```java
308
- // 方法 1:使用 updateLt
309
- cs.updateLt(records);
310
-
311
- // 方法 2:添加标志位
312
- if ("true".equals(System.getProperty("trigger.running"))) {
313
- return;
314
- }
315
- System.setProperty("trigger.running", "true");
316
- cs.update(record);
317
- System.setProperty("trigger.running", "false");
318
- ```
319
-
320
- ## 七、触发器调试与监控
321
-
322
- ### 7.1 日志记录
323
-
324
- ```java
325
- System.out.println("=== 触发器开始执行 ===");
326
- System.out.println("对象:" + record.getSObjectName());
327
- System.out.println("操作:" + data.get("action"));
328
- System.out.println("记录 ID: " + record.get("id"));
329
- ```
330
-
331
- ### 7.2 常见问题排查
332
-
333
- | 问题 | 可能原因 | 解决方案 |
334
- | --- | --- | --- |
335
- | 触发器不执行 | 未激活、触发时机不对 | 检查状态和配置 |
336
- | 递归触发 | 更新操作再次触发触发器 | 使用 `updateLt` |
337
- | 性能问题 | 查询数据量过大 | 添加查询条件、字段过滤 |
338
- | 数据不一致 | 触发器执行失败 | 添加异常处理 |
339
-
340
- ## 八、总结
341
-
342
- ### 8.1 触发器的价值
343
-
344
- 1. 自动化:减少人工操作,降低出错率
345
- 2. 一致性:保证数据准确性和业务规则执行
346
- 3. 实时性:业务变更立即响应
347
- 4. 灵活性:Java 代码可实现复杂业务逻辑
348
-
349
- ### 8.2 何时使用触发器
350
-
351
- 适合使用:
352
-
353
- - 需要实时数据联动
354
- - 核心业务规则校验
355
- - 跨对象数据同步
356
- - 审批流程中的复杂逻辑
357
- - 自动创建/更新关联记录
358
-
359
- 不适合使用:
360
-
361
- - 简单字段默认值
362
- - 大批量数据处理
363
- - 跨系统集成
364
- - 用户界面交互
365
-
366
- ### 8.3 触发器开发 Checklist
367
-
368
- - 明确触发时机(before/after/approval)
369
- - 评估递归触发风险
370
- - 添加异常处理
371
- - 记录关键日志
372
- - 测试边界情况
373
- - 做大数据量场景性能测试
374
-
375
- ## 附录:25 个生产触发器清单
376
-
377
- | # | 名称 | 对象 | 时机 | 状态 |
378
- | --- | --- | --- | --- | --- |
379
- | 1 | 个人业绩/部门业绩赋值 | 对外付款 | beforeUpsert | ✅ |
380
- | 2 | 个人业绩/部门业绩赋值 | 费用报销 | beforeUpsert | ❌ |
381
- | 3 | 本部业绩统计 | 本部业绩统计 | beforeUpsert | ✅ |
382
- | 4 | 更新拆分审批状态 | 预算 | approval | ✅ |
383
- | 5 | 订单审批判断 | 订单 | approval | ✅ |
384
- | 6 | 根据净业绩拆分生成净业绩拆分回款 | 回款明细 | afterInsert | ✅ |
385
- | 7 | 金额汇总到收款计划 | 回款明细 | afterUpsert | ✅ |
386
- | 8 | 回款明细删除 | 回款明细 | afterDelete | ❌ |
387
- | 9 | 计算产研成本/净业绩 | 预算 | beforeUpsert | ✅ |
388
- | 10 | 保证金回款记录 | 概算 | afterUpdate | ✅ |
389
- | 11 | 校验金额累计是否超预算 | 净业绩拆分 | afterUpsert | ✅ |
390
- | 12 | 更新部门业绩字段 | 部门业绩 | afterUpsert | ✅ |
391
- | 13 | 汇总部门资金池 | 部门业绩 | afterUpdate | ✅ |
392
- | 14 | 编辑更新部门业绩 | 净业绩拆分回款 | beforeUpsert | ✅ |
393
- | 15 | 生成部门/个人业绩 | 净业绩拆分 | beforeUpsert | ✅ |
394
- | 16 | 更新回款明细 | 回款明细 | afterUpsert | ✅ |
395
- | 17 | (新)新建自动拆分/审批通过自动生成回款 | 预算 | afterUpsert | ✅ |
396
- | 18 | 提交审批验证金额 | 对外付款 | approval | ❌ |
397
- | 19 | 还款记录审批通过更新借款单 | 还款记录 | approval | ✅ |
398
- | 20 | 审批通过计算剩余欠款 | 费用报销 | approval | ✅ |
399
- | 21 | 借款单触发器 | 借款单 | beforeUpsert | ✅ |
400
- | 22 | 创建编辑项目任务时判断 | 项目任务 | beforeUpsert | ✅ |
401
- | 23 | 任务派工工时限制 | 项目任务 | afterUpsert | ✅ |
402
- | 24 | 测试 AI 代码生成 | 客户 | beforeInsert | ❌ |
403
- | 25 | 验证审批时校验预算 | 费用报销 | approval | ❌ |
97
+ - 需要即时生效
98
+ - 跟某条记录的新增、修改、删除、审批直接相关
99
+ - 不执行就会造成数据错误或流程错误
100
+ - 不能依赖人工补操作
404
101
 
102
+ ## 6. 触发器能解决哪些问题
103
+
104
+ ### 6.1 数据准入问题
105
+
106
+ 典型问题:
107
+
108
+ - 必填项不完整
109
+ - 金额、比例、数量不合法
110
+ - 当前状态下不允许编辑、提交或删除
111
+ - 数据重复、冲突或越界
112
+
113
+ 触发器价值:
114
+
115
+ - 在保存前拦截问题数据
116
+ - 防止脏数据进入系统
117
+ - 保证关键规则不依赖人工记忆
118
+
119
+ ### 6.2 数据联动问题
120
+
121
+ 典型问题:
122
+
123
+ - 一个对象更新后,关联对象没有同步
124
+ - 主子表口径不一致
125
+ - 上下游业务单据状态脱节
126
+
127
+ 触发器价值:
128
+
129
+ - 把联动逻辑自动化
130
+ - 降低人工同步遗漏
131
+ - 保持对象间状态一致
132
+
133
+ ### 6.3 审批补强问题
134
+
135
+ 典型问题:
136
+
137
+ - 审批前需要复杂校验
138
+ - 审批通过后要生成下游数据
139
+ - 审批撤回后要回滚状态或清待办
140
+
141
+ 触发器价值:
142
+
143
+ - 承接审批流无法直接表达的规则
144
+ - 让审批前后动作自动执行
145
+ - 让流程控制更严密
146
+
147
+ ### 6.4 实时计算问题
148
+
149
+ 典型问题:
150
+
151
+ - 汇总金额、成本、比例、回款、认款需要即时准确
152
+ - 主记录字段依赖明细变化实时重算
153
+
154
+ 触发器价值:
155
+
156
+ - 在数据变化当下重算
157
+ - 避免报表、页面、审批依据口径失真
158
+
159
+ ### 6.5 权限与协同问题
160
+
161
+ 典型问题:
162
+
163
+ - 负责人变化后共享关系未更新
164
+ - 团队成员、部门共享、审批参与人没有同步
165
+
166
+ 触发器价值:
167
+
168
+ - 自动修正共享与权限关系
169
+ - 保证协同对象始终正确
170
+
171
+ ### 6.6 通知与集成问题
172
+
173
+ 典型问题:
174
+
175
+ - 某个业务事件发生后需要推送 OA、邮件、外部系统
176
+ - 人员提醒、待办生成、外部回传不能漏
177
+
178
+ 触发器价值:
179
+
180
+ - 把事件和通知、集成绑定起来
181
+ - 保证关键动作发生时立即通知或同步
182
+
183
+ ## 7. 什么时候应该使用触发器
184
+
185
+ AI 在判断方案时,可以先问自己四个问题:
186
+
187
+ - 这是由某条记录的新增、修改、删除、审批直接触发的吗
188
+ - 这件事必须立刻发生吗
189
+ - 这件事必须由平台统一执行、不能依赖人工吗
190
+ - 这件事如果不在当前时点做,会导致数据错误或流程错误吗
191
+
192
+ 如果以上问题大部分回答是“是”,通常就适合触发器。
193
+
194
+ ### 7.1 适合使用触发器的情况
195
+
196
+ - 记录保存前必须校验
197
+ - 记录保存时必须自动赋值
198
+ - 记录保存后必须立即联动其他对象
199
+ - 删除后必须立刻做反向更新或清理
200
+ - 提交审批或审批通过时必须执行业务动作
201
+ - 关键业务状态必须平台层统一约束
202
+ - 关键共享关系和负责人关系必须自动维护
203
+
204
+ ### 7.2 不适合优先使用触发器的情况
205
+
206
+ - 按天、按周、按月执行的任务
207
+ - 一次要扫描大量历史数据的批处理
208
+ - 失败后需要复杂重试和补偿的长链路集成
209
+ - 强依赖前端交互和页面反馈的场景
210
+ - 只是简单展示或轻量交互
211
+ - 只是一个手动按钮动作,不需要事件自动触发
212
+
213
+ ## 8. 触发器与其他实现方式的边界
214
+
215
+ AI 在做方案选型时,必须区分触发器、自定义类、定时器、页面脚本的边界。
216
+
217
+ ### 8.1 触发器
218
+
219
+ 适合:
220
+
221
+ - 单条记录事件驱动
222
+ - 需要即时执行
223
+ - 需要强规则约束
224
+
225
+ 关键词:
226
+
227
+ - 自动触发
228
+ - 紧贴对象生命周期
229
+ - 平台统一执行
230
+
231
+ ### 8.2 自定义类
232
+
233
+ 适合:
234
+
235
+ - 可复用的服务逻辑
236
+ - 多入口共用能力
237
+ - 复杂计算、复杂集成、复杂流程编排
238
+
239
+ 关键词:
240
+
241
+ - 服务能力
242
+ - 复用
243
+ - 被触发器、按钮、页面、定时器调用
244
+
245
+ ### 8.3 定时器类
246
+
247
+ 适合:
248
+
249
+ - 周期任务
250
+ - 批量扫描
251
+ - 后台修复
252
+ - 延迟处理
253
+
254
+ 关键词:
255
+
256
+ - 按时间触发
257
+ - 批量
258
+ - 巡检和补偿
259
+
260
+ ### 8.4 页面脚本或页面组件
261
+
262
+ 适合:
263
+
264
+ - 前端交互
265
+ - 页面展示
266
+ - 用户即时输入反馈
267
+
268
+ 关键词:
269
+
270
+ - 页面体验
271
+ - 界面交互
272
+ - 非服务端强规则
273
+
274
+ ### 8.5 AI 的默认判断原则
275
+
276
+ 可以简单记成一句话:
277
+
278
+ - 实时事件规则,用触发器
279
+ - 通用能力沉到自定义类
280
+ - 周期批处理用定时器
281
+ - 页面交互留给前端
282
+
283
+ ## 9. 按触发时机逐个分析
284
+
285
+ 以下内容用于帮助 AI 判断“同样是触发器,应该挂在哪个时机”。
286
+
287
+ ### 9.1 `beforeInsert`
288
+
289
+ 主要作用:
290
+
291
+ - 新建前校验
292
+ - 新建前默认值填充
293
+ - 新建前防重和准入控制
294
+
295
+ 为什么要用:
296
+
297
+ - 因为记录还没入库,最适合做拦截和初始值处理
298
+
299
+ 解决的问题:
300
+
301
+ - 不合法记录进入系统
302
+ - 新建记录缺少关键字段
303
+
304
+ 适用场景:
305
+
306
+ - 新建商机、报价、合同、客户时的必填校验
307
+ - 编号规则、初始状态、默认负责人赋值
308
+
309
+ ### 9.2 `beforeUpdate`
310
+
311
+ 主要作用:
312
+
313
+ - 编辑前限制
314
+ - 状态切换限制
315
+ - 变更前业务保护
316
+
317
+ 为什么要用:
318
+
319
+ - 很多业务错误不是发生在创建时,而是发生在后续修改时
320
+
321
+ 解决的问题:
322
+
323
+ - 已审批数据被误改
324
+ - 不允许的状态回退或跳转
325
+ - 已锁定记录被继续编辑
326
+
327
+ 适用场景:
328
+
329
+ - 合同、商机、报价、项目状态变更控制
330
+ - 金额、阶段、负责人变更限制
331
+
332
+ ### 9.3 `beforeUpsert`
333
+
334
+ 主要作用:
335
+
336
+ - 同时覆盖新建与更新的统一校验
337
+ - 同时覆盖新建与更新的统一赋值
338
+
339
+ 为什么要用:
340
+
341
+ - 当规则对“新建”和“更新”都成立时,用一个入口更稳定
342
+
343
+ 解决的问题:
344
+
345
+ - 同一规则在创建和修改场景下实现不一致
346
+
347
+ 适用场景:
348
+
349
+ - 统一口径的金额、比例、分类字段计算
350
+ - 创建和更新都要执行的格式和业务校验
351
+
352
+ ### 9.4 `afterInsert`
353
+
354
+ 主要作用:
355
+
356
+ - 根据新记录生成关联记录
357
+ - 创建后发送通知或初始化下游数据
358
+
359
+ 为什么要用:
360
+
361
+ - 只有创建成功后,记录 ID 和上下文才完整
362
+
363
+ 解决的问题:
364
+
365
+ - 派生数据漏建
366
+ - 新建后没有初始化关联关系
367
+
368
+ 适用场景:
369
+
370
+ - 新建后自动生成工作包、分期、子表、共享记录、待办
371
+
372
+ ### 9.5 `afterUpdate`
373
+
374
+ 主要作用:
375
+
376
+ - 对编辑后的结果做定向联动
377
+ - 在特定字段变化后触发后续动作
378
+
379
+ 为什么要用:
380
+
381
+ - 有些动作只适合在修改后做,不适合在新建时做
382
+
383
+ 解决的问题:
384
+
385
+ - 修改后的状态、金额、负责人未同步到下游
386
+
387
+ 适用场景:
388
+
389
+ - 状态推进后的通知、同步、创建或解锁动作
390
+
391
+ ### 9.6 `afterUpsert`
392
+
393
+ 主要作用:
394
+
395
+ - 在新增或更新成功后做统一联动
396
+ - 做汇总、回写、同步、派生
397
+
398
+ 为什么要用:
399
+
400
+ - 它适合承接“只要保存成功就要处理”的通用后置动作
401
+
402
+ 解决的问题:
403
+
404
+ - 主子记录口径不同步
405
+ - 上下游对象字段不同步
406
+
407
+ 适用场景:
408
+
409
+ - 汇总金额、同步状态、回写父记录、刷新关联对象
410
+
411
+ ### 9.7 `beforeDelete`
412
+
413
+ 主要作用:
414
+
415
+ - 删除前拦截
416
+ - 删除前检查依赖
417
+
418
+ 为什么要用:
419
+
420
+ - 一旦删除完成,恢复成本就高
421
+
422
+ 解决的问题:
423
+
424
+ - 误删关键记录
425
+ - 删除造成数据断链
426
+
427
+ 适用场景:
428
+
429
+ - 已提交、已审批、已关联、已汇总数据不允许删除
430
+
431
+ ### 9.8 `afterDelete`
432
+
433
+ 主要作用:
434
+
435
+ - 删除后清理和补偿
436
+ - 删除后重算汇总
437
+
438
+ 为什么要用:
439
+
440
+ - 删除已经发生,此时适合做回收和反向修复
441
+
442
+ 解决的问题:
443
+
444
+ - 删除后主记录口径未重算
445
+ - 删除后待办、共享、派生数据残留
446
+
447
+ 适用场景:
448
+
449
+ - 删除子记录后重算父记录金额或比例
450
+ - 删除业务记录后取消待办、清理关联
451
+
452
+ ### 9.9 `approval`
453
+
454
+ 主要作用:
455
+
456
+ - 审批提交前校验
457
+ - 审批通过后推进业务
458
+ - 审批撤回或拒绝后回滚状态
459
+
460
+ 为什么要用:
461
+
462
+ - 审批节点往往是业务控制最严格的节点
463
+
464
+ 解决的问题:
465
+
466
+ - 提交审批前条件不满足
467
+ - 审批通过后下游业务没有自动启动
468
+ - 审批撤回后状态没有恢复
469
+
470
+ 适用场景:
471
+
472
+ - 审批前预算、金额、附件、状态校验
473
+ - 审批通过后生成记录、推送系统、发送待办、解锁或锁定对象
474
+
475
+ ## 10. 当前项目里最常见的十类业务场景
476
+
477
+ ### 10.1 数据校验与限制类
478
+
479
+ 主要作用:
480
+
481
+ - 阻止非法新增、非法编辑、非法删除、非法提交
482
+
483
+ 解决问题:
484
+
485
+ - 数据错误进入系统
486
+ - 关键业务口径被破坏
487
+
488
+ 适用场景:
489
+
490
+ - 金额、比例、状态、字段必填、重复判断、删除限制
491
+
492
+ ### 10.2 自动生成与初始化类
493
+
494
+ 主要作用:
495
+
496
+ - 自动生成关联记录、默认结构、初始化业务数据
497
+
498
+ 解决问题:
499
+
500
+ - 派生数据依赖人工创建
501
+ - 新建后缺少后续业务支撑数据
502
+
503
+ 适用场景:
504
+
505
+ - 生成项目、生成分期、生成工作包、生成共享记录、初始化统计数据
506
+
507
+ ### 10.3 更新与同步类
508
+
509
+ 主要作用:
510
+
511
+ - 跨对象更新、回写、同步、补齐字段
512
+
513
+ 解决问题:
514
+
515
+ - 一个对象变化后下游对象未更新
516
+ - 业务链条断裂
517
+
518
+ 适用场景:
519
+
520
+ - 商机到报价、报价到合同、合同到项目、明细到主表的同步
521
+
522
+ ### 10.4 审批与流程推进类
523
+
524
+ 主要作用:
525
+
526
+ - 审批节点前后控制和流程驱动
527
+
528
+ 解决问题:
529
+
530
+ - 审批前条件校验不足
531
+ - 审批通过后流程没有自动衔接
532
+
533
+ 适用场景:
534
+
535
+ - 提交审批校验、审批通过回写、撤回消办、审批后生成下游业务数据
536
+
537
+ ### 10.5 共享与权限治理类
538
+
539
+ 主要作用:
540
+
541
+ - 自动维护共享范围、协同关系、负责人体系
542
+
543
+ 解决问题:
544
+
545
+ - 人员变化后共享关系错乱
546
+ - 团队协同对象不准确
547
+
548
+ 适用场景:
549
+
550
+ - 共享规则、负责人变化、审批参与人分配、项目成员同步
551
+
552
+ ### 10.6 通知与集成类
553
+
554
+ 主要作用:
555
+
556
+ - 业务事件发生时推送待办、邮件、OA 或外部系统
557
+
558
+ 解决问题:
559
+
560
+ - 关键动作无人感知
561
+ - 外部系统数据不同步
562
+
563
+ 适用场景:
564
+
565
+ - 审批待办、邮件提醒、OA 推送、SAP/BI/第三方系统同步
566
+
567
+ ### 10.7 汇总与计算类
568
+
569
+ 主要作用:
570
+
571
+ - 实时计算金额、比例、成本、回款、认款、汇总字段
572
+
573
+ 解决问题:
574
+
575
+ - 主记录汇总失真
576
+ - 审批依据和财务口径不一致
577
+
578
+ 适用场景:
579
+
580
+ - 报价、合同额、预算、回款、成本、项目作业比例
581
+
582
+ ### 10.8 删除补偿与清理类
583
+
584
+ 主要作用:
585
+
586
+ - 删除后重算、清理、取消、恢复
587
+
588
+ 解决问题:
589
+
590
+ - 删除后出现残留数据或统计错误
591
+
592
+ 适用场景:
593
+
594
+ - 删除子记录后重算父记录
595
+ - 删除后取消待办、清理共享、清空关联
596
+
597
+ ### 10.9 编号与编码治理类
598
+
599
+ 主要作用:
600
+
601
+ - 统一管理编号、编码、命名规则
602
+
603
+ 解决问题:
604
+
605
+ - 手工编号重复
606
+ - 编码规则不统一
607
+
608
+ 适用场景:
609
+
610
+ - 合同编号、物料编码、产品线编码、业务单据编码
611
+
612
+ ### 10.10 导入迁移与修复类
613
+
614
+ 主要作用:
615
+
616
+ - 为导入、迁移、历史修复提供自动化处理
617
+
618
+ 解决问题:
619
+
620
+ - 导入数据结构不完整
621
+ - 历史数据缺少标准化处理
622
+
623
+ 适用场景:
624
+
625
+ - 导入后回填、迁移中间表修复、初始化历史口径
626
+
627
+ ## 11. AI 在使用触发器概念时应遵守的判断顺序
628
+
629
+ AI 在看到一个需求时,建议按以下顺序判断:
630
+
631
+ 1. 先判断是不是“记录事件驱动”
632
+ 2. 再判断是不是“必须立即执行”
633
+ 3. 再判断是不是“必须平台层强约束”
634
+ 4. 再判断是不是“和审批节点直接相关”
635
+ 5. 再判断是“保存前控制”还是“保存后联动”
636
+ 6. 再判断是否需要把复杂逻辑下沉到自定义类
637
+
638
+ 如果一个需求只是“事件入口很薄,真正逻辑很重”,AI 应优先采用:
639
+
640
+ - 触发器做入口
641
+ - 自定义类做核心能力
642
+
643
+ 不要把所有复杂逻辑都直接堆在触发器里。
644
+
645
+ ## 12. AI 不应把触发器当成什么
646
+
647
+ AI 不应把触发器当成以下东西:
648
+
649
+ - 周期批处理器
650
+ - 大规模数据修复器
651
+ - 前端交互逻辑容器
652
+ - 任意可复用服务类的替代品
653
+ - 所有问题的默认答案
654
+
655
+ 触发器的价值,在于“紧贴对象生命周期做即时规则和即时联动”,而不是替代一切后端能力。
656
+
657
+ ## 13. 最终结论
658
+
659
+ 从概念上看,CloudCC 触发器最适合承接四类核心职责:
660
+
661
+ - 守门:保存前、删除前、审批前的规则校验和拦截
662
+ - 联动:保存后、审批后的同步、回写、生成、通知
663
+ - 治理:共享、权限、状态、编号、流程秩序的维护
664
+ - 计算:金额、比例、成本、回款、汇总口径的实时更新
665
+
666
+ 因此,AI 在未来遇到以下描述时,应优先联想到触发器:
667
+
668
+ - 保存时必须校验
669
+ - 修改后必须同步
670
+ - 审批后必须生成
671
+ - 删除后必须重算
672
+ - 负责人变化后必须共享
673
+ - 关键状态不能被绕过
674
+
675
+ 如果需求不是“即时事件驱动”,或者需要“周期批处理、复杂重试、长链路集成、前端交互”,就不应优先落到触发器。