cloudcc-cli 2.2.8 → 2.3.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.
- package/.cloudcc-cache.json +32 -1
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_CLASS.md +97 -0
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_SCHEDULE.md +78 -0
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_TRIGGER.md +137 -0
- package/.cursor/skills/cloudcc-cli-dev/CLI_CHEATSHEET.md +215 -0
- package/.cursor/skills/cloudcc-cli-dev/CUSTOM-SETTING-API.md +241 -0
- package/{cloudcc-cli-dev → .cursor/skills/cloudcc-cli-dev}/SKILL.md +7 -2
- package/.cursor/skills/cloudcc-cli-dev/VUE_CUSTOM_COMPONENT.md +151 -0
- package/README.md +22 -0
- package/bin/index.js +6 -0
- package/build/component-cc-test-001.common.js +831 -0
- package/build/component-cc-test-001.common.js.map +1 -0
- package/build/component-cc-test-001.css +1 -0
- package/build/component-cc-test-001.umd.js +874 -0
- package/build/component-cc-test-001.umd.js.map +1 -0
- package/build/component-cc-test-001.umd.min.js +8 -0
- package/build/component-cc-test-001.umd.min.js.map +1 -0
- package/build/demo.html +1 -0
- package/classes/CCdd/CCdd.java +22 -0
- package/classes/CCdd/CCddTest.java +11 -0
- package/classes/CCdd/config.json +1 -0
- package/docs/CloudCC/350/207/252/345/256/232/344/271/211/347/273/204/344/273/266/344/275/277/347/224/250/350/257/264/346/230/216.md +130 -0
- package/docs/cloudcc/345/256/232/346/227/266/344/275/234/344/270/232.md +472 -0
- package/docs/cloudcc/345/256/232/346/227/266/347/261/273.md +302 -0
- package/docs//350/207/252/345/256/232/344/271/211/347/261/273.md +258 -0
- package/docs//350/247/246/345/217/221/345/231/250/347/261/273.md +404 -0
- package/package.json +1 -1
- package/plugins/cc-test-001/cc-test-001.vue +32 -0
- package/plugins/cc-test-001/components/HelloWorld.vue +11 -0
- package/plugins/cc-test-001/config.json +6 -0
- package/schedule/CCdd/CCdd.java +11 -0
- package/schedule/CCdd/config.json +1 -0
- package/src/customPage/create.js +77 -0
- package/src/customPage/delete.js +65 -0
- package/src/customPage/get.js +85 -0
- package/src/customPage/index.js +10 -0
- package/src/customSetting/doc.js +196 -0
- package/src/customSetting/index.js +7 -0
- package/src/plugin/delete.js +91 -0
- package/src/plugin/doc.js +76 -0
- package/src/plugin/index.js +1 -0
- package/src/triggers/doc.js +258 -222
- package/src/triggers/pullList.js +3 -0
- package/target/classes/CCdd/CCdd.class +0 -0
- package/target/classes/CCdd/CCddTest.class +0 -0
- package/target/classes/CCdd/config.json +1 -0
- package/cloudcc-cli-dev/BACKEND_CODE.md +0 -114
- package/cloudcc-cli-dev/CLI_CHEATSHEET.md +0 -90
- package/cloudcc-cli-dev/VUE_CUSTOM_COMPONENT.md +0 -50
- /package/{cloudcc-cli-dev → .cursor/skills/cloudcc-cli-dev}/INSTALL_AND_BOOTSTRAP.md +0 -0
- /package/{cloudcc-cli-dev → .cursor/skills/cloudcc-cli-dev}/OBJECTS_AND_FIELDS.md +0 -0
- /package/{cloudcc-cli-dev → .cursor/skills/cloudcc-cli-dev}/REQUIREMENTS_BREAKDOWN.md +0 -0
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
# CloudCC 触发器使用总结
|
|
2
|
+
|
|
3
|
+
> 基于生产环境 25 个触发器实例分析
|
|
4
|
+
> 文档版本:v1.0
|
|
5
|
+
> 更新时间:2026-03-24
|
|
6
|
+
|
|
7
|
+
## 一、什么是触发器
|
|
8
|
+
|
|
9
|
+
CloudCC 触发器是符合 Java 语法规范的服务端代码,在特定业务事件发生时自动执行,用于实现业务逻辑自动化处理。
|
|
10
|
+
|
|
11
|
+
触发器本质:
|
|
12
|
+
|
|
13
|
+
- 一段 Java 代码,运行在 CloudCC 平台沙箱环境中
|
|
14
|
+
- 使用 `CCService`、`CCObject` 等平台 API 类
|
|
15
|
+
- 在数据变更的特定时刻(前/后)自动触发执行
|
|
16
|
+
|
|
17
|
+
## 二、触发器能干什么
|
|
18
|
+
|
|
19
|
+
### 2.1 核心能力
|
|
20
|
+
|
|
21
|
+
| 能力 | 说明 | 示例 |
|
|
22
|
+
| --- | --- | --- |
|
|
23
|
+
| 自动赋值 | 在记录保存前自动计算并填充字段 | 个人业绩/部门业绩自动赋值 |
|
|
24
|
+
| 数据校验 | 阻止不符合业务规则的数据保存 | 预算金额校验、审批金额验证 |
|
|
25
|
+
| 关联更新 | 修改一条记录时自动更新关联记录 | 回款明细汇总到收款计划 |
|
|
26
|
+
| 自动生成 | 根据业务规则自动创建新记录 | 审批通过后自动生成回款记录 |
|
|
27
|
+
| 权限控制 | 自动设置数据共享权限 | 按部门/人员自动共享 |
|
|
28
|
+
| 状态同步 | 审批状态变更后同步更新相关字段 | 预算审批状态回写 |
|
|
29
|
+
| 汇总计算 | 实时汇总明细数据到主记录 | 部门业绩字段汇总 |
|
|
30
|
+
|
|
31
|
+
### 2.2 技术能力(基于 CCService API)
|
|
32
|
+
|
|
33
|
+
```java
|
|
34
|
+
// 1. 新增记录
|
|
35
|
+
CCObject opp = new CCObject("Opportunity");
|
|
36
|
+
opp.put("name", "value");
|
|
37
|
+
cs.insert(opp);
|
|
38
|
+
|
|
39
|
+
// 2. 查询记录
|
|
40
|
+
// 查询指定字段
|
|
41
|
+
List<CCObject> opps = cs.cqueryByFields(
|
|
42
|
+
"Opportunity",
|
|
43
|
+
"khmc__c='" + record_new.get("id") + "'",
|
|
44
|
+
"id,name,createdate"
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
// 查询全部字段
|
|
48
|
+
List<CCObject> all = cs.cquery("Opportunity", "khmc__c='" + record_new.get("id") + "'");
|
|
49
|
+
|
|
50
|
+
// 复杂 SQL 查询
|
|
51
|
+
List<CCObject> ccobjs = cs.cqlQuery(
|
|
52
|
+
"Opportunity",
|
|
53
|
+
"select sum(amount) as sumAmount from Opportunity where khmc = '0012001238ytwuiw'"
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
// 3. 修改记录
|
|
57
|
+
cs.update(opp);
|
|
58
|
+
|
|
59
|
+
// 4. 删除记录
|
|
60
|
+
cs.delete(opp);
|
|
61
|
+
|
|
62
|
+
// 5. 发送邮件通知
|
|
63
|
+
SendEmail sendEmail = new SendEmail(userInfo);
|
|
64
|
+
sendEmail.sendMailFromSystem(toAddress, ccAddress, bccAddress, subject, content, isText);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 三、触发器触发时机详解
|
|
68
|
+
|
|
69
|
+
### 3.1 beforeUpsert(创建或更新前)
|
|
70
|
+
|
|
71
|
+
执行时机:记录保存之前,数据尚未写入数据库。
|
|
72
|
+
典型用途:
|
|
73
|
+
|
|
74
|
+
- 自动计算字段值
|
|
75
|
+
- 数据格式校验
|
|
76
|
+
- 阻止非法数据保存(抛出异常)
|
|
77
|
+
- 自动填充默认值
|
|
78
|
+
|
|
79
|
+
生产实例:
|
|
80
|
+
|
|
81
|
+
| 触发器名称 | 对象 | 作用 |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| 个人业绩/部门业绩赋值 | 对外付款 | 自动赋值业绩字段 |
|
|
84
|
+
| 计算产研成本/净业绩 | 预算 | 自动计算成本、净业绩 |
|
|
85
|
+
| 生成部门/个人业绩 | 净业绩拆分 | 自动创建业绩记录 |
|
|
86
|
+
| 编辑更新部门业绩 | 净业绩拆分回款 | 更新前校验和计算 |
|
|
87
|
+
|
|
88
|
+
代码示例:
|
|
89
|
+
|
|
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
|
+
```
|
|
100
|
+
|
|
101
|
+
### 3.2 afterInsert(创建后)
|
|
102
|
+
|
|
103
|
+
执行时机:记录已成功创建,ID 已生成。
|
|
104
|
+
典型用途:
|
|
105
|
+
|
|
106
|
+
- 基于新记录 ID 创建关联记录
|
|
107
|
+
- 发送创建通知
|
|
108
|
+
- 初始化关联数据
|
|
109
|
+
|
|
110
|
+
生产实例:
|
|
111
|
+
|
|
112
|
+
| 触发器名称 | 对象 | 作用 |
|
|
113
|
+
| --- | --- | --- |
|
|
114
|
+
| 根据净业绩拆分生成净业绩拆分回款 | 回款明细 | 新建回款明细后自动生成回款记录 |
|
|
115
|
+
|
|
116
|
+
代码示例:
|
|
117
|
+
|
|
118
|
+
```java
|
|
119
|
+
CCObject newRecord = (CCObject) data.get("record");
|
|
120
|
+
String recordId = newRecord.getString("id");
|
|
121
|
+
|
|
122
|
+
CCObject hkRecord = new CCObject("Huikuan");
|
|
123
|
+
hkRecord.put("mingxi__c", recordId);
|
|
124
|
+
hkRecord.put("je", newRecord.get("je"));
|
|
125
|
+
cs.insert(hkRecord);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 3.3 afterUpsert(创建或更新后)
|
|
129
|
+
|
|
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 | ❌ |
|
|
404
|
+
|
package/package.json
CHANGED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="cc-container">
|
|
3
|
+
<HelloWorld />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script>
|
|
8
|
+
import HelloWorld from "./components/HelloWorld.vue";
|
|
9
|
+
export default {
|
|
10
|
+
components: {
|
|
11
|
+
HelloWorld,
|
|
12
|
+
},
|
|
13
|
+
data() {
|
|
14
|
+
return {
|
|
15
|
+
componentInfo: {
|
|
16
|
+
|
|
17
|
+
component: "component-cc-test-001",
|
|
18
|
+
|
|
19
|
+
compName: "compName-cc-test-001",
|
|
20
|
+
|
|
21
|
+
compDesc: "Component description information",
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
</script>
|
|
27
|
+
<style lang="scss" scoped>
|
|
28
|
+
.cc-container {
|
|
29
|
+
text-align: center;
|
|
30
|
+
padding: 8px;
|
|
31
|
+
}
|
|
32
|
+
</style>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"CCdd","version":"2"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getPackageJson } = require('../../utils/config');
|
|
3
|
+
const { post } = require('../../utils/http');
|
|
4
|
+
const BaseUrl = 'https://developer.apis.cloudcc.cn';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 新建自定义页面
|
|
8
|
+
*
|
|
9
|
+
* 用法:cc customPage create <pageLabel> <pageApi> [projectPath]
|
|
10
|
+
*/
|
|
11
|
+
async function createCustomPage(argvs) {
|
|
12
|
+
const pageLabel = argvs[2];
|
|
13
|
+
const pageApi = argvs[3];
|
|
14
|
+
const projectPath = argvs[4] || process.cwd();
|
|
15
|
+
|
|
16
|
+
if (!pageLabel || !pageApi) {
|
|
17
|
+
console.error();
|
|
18
|
+
console.error(chalk.red('Error: pageLabel and pageApi are required'));
|
|
19
|
+
console.error(chalk.yellow('Usage: cc customPage create <pageLabel> <pageApi> [projectPath]'));
|
|
20
|
+
console.error();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const config = await getPackageJson(projectPath);
|
|
25
|
+
if (!config || !config.accessToken) {
|
|
26
|
+
console.error();
|
|
27
|
+
console.error(chalk.red('Error: Configuration not found or accessToken is missing'));
|
|
28
|
+
console.error();
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const devSvcDispatch = config.devSvcDispatch || '/devconsole';
|
|
33
|
+
const baseUrl = config.baseUrl || BaseUrl;
|
|
34
|
+
|
|
35
|
+
const header = {
|
|
36
|
+
appType: 'lightning-devconsole',
|
|
37
|
+
accessToken: config.accessToken,
|
|
38
|
+
source: 'lightning-devconsole',
|
|
39
|
+
version: 'public',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const body = {
|
|
43
|
+
id: '',
|
|
44
|
+
pageLabel,
|
|
45
|
+
pageApi,
|
|
46
|
+
pageContent: '[]',
|
|
47
|
+
orgId: config.orgId || '',
|
|
48
|
+
renderVersion: '',
|
|
49
|
+
compList: [],
|
|
50
|
+
canvasStyleData: JSON.stringify({ width: 100, height: 100, scale: 100, unit: '%' }),
|
|
51
|
+
isTemplate: 0,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
console.error();
|
|
55
|
+
console.error(chalk.green(`Creating custom page "${pageLabel}" (api: ${pageApi}), please wait...`));
|
|
56
|
+
|
|
57
|
+
const res = await post(
|
|
58
|
+
`${baseUrl}${devSvcDispatch}/custom/pc/1.0/post/insertCustomPage`,
|
|
59
|
+
body,
|
|
60
|
+
header
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
if (res && res.returnCode == 200) {
|
|
64
|
+
const id = res.data?.id || res.data || '';
|
|
65
|
+
console.error(chalk.green(`Success! Custom page created.${id ? ' ID: ' + id : ''}`));
|
|
66
|
+
console.error();
|
|
67
|
+
} else {
|
|
68
|
+
const errMsg = res?.returnInfo || 'Unknown error';
|
|
69
|
+
console.error(chalk.red(`Fail: ${errMsg}`));
|
|
70
|
+
console.error();
|
|
71
|
+
throw new Error('Create Custom Page Failed: ' + errMsg);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return res;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = createCustomPage;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getPackageJson } = require('../../utils/config');
|
|
3
|
+
const { post } = require('../../utils/http');
|
|
4
|
+
const BaseUrl = 'https://developer.apis.cloudcc.cn';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 删除自定义页面
|
|
8
|
+
*
|
|
9
|
+
* 用法:cc customPage delete <id> [projectPath]
|
|
10
|
+
*/
|
|
11
|
+
async function deleteCustomPage(argvs) {
|
|
12
|
+
const id = argvs[2];
|
|
13
|
+
const projectPath = argvs[3] || process.cwd();
|
|
14
|
+
|
|
15
|
+
if (!id) {
|
|
16
|
+
console.error();
|
|
17
|
+
console.error(chalk.red('Error: Custom page ID is required'));
|
|
18
|
+
console.error(chalk.yellow('Usage: cc customPage delete <id> [projectPath]'));
|
|
19
|
+
console.error();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const config = await getPackageJson(projectPath);
|
|
24
|
+
if (!config || !config.accessToken) {
|
|
25
|
+
console.error();
|
|
26
|
+
console.error(chalk.red('Error: Configuration not found or accessToken is missing'));
|
|
27
|
+
console.error();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const devSvcDispatch = config.devSvcDispatch || '/devconsole';
|
|
32
|
+
const baseUrl = config.baseUrl || BaseUrl;
|
|
33
|
+
|
|
34
|
+
const header = {
|
|
35
|
+
appType: 'lightning-devconsole',
|
|
36
|
+
accessToken: config.accessToken,
|
|
37
|
+
source: 'lightning-devconsole',
|
|
38
|
+
version: 'public',
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const body = { id };
|
|
42
|
+
|
|
43
|
+
console.error();
|
|
44
|
+
console.error(chalk.green(`Deleting custom page (ID: ${id}), please wait...`));
|
|
45
|
+
|
|
46
|
+
const res = await post(
|
|
47
|
+
`${baseUrl}${devSvcDispatch}/custom/pc/1.0/post/deleteCustomPage`,
|
|
48
|
+
body,
|
|
49
|
+
header
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
if (res && res.returnCode == 200) {
|
|
53
|
+
console.error(chalk.green(`Success! Custom page (ID: ${id}) deleted.`));
|
|
54
|
+
console.error();
|
|
55
|
+
} else {
|
|
56
|
+
const errMsg = res?.returnInfo || 'Unknown error';
|
|
57
|
+
console.error(chalk.red(`Fail: ${errMsg}`));
|
|
58
|
+
console.error();
|
|
59
|
+
throw new Error('Delete Custom Page Failed: ' + errMsg);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return res;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = deleteCustomPage;
|