cloudcc-cli 2.3.9 → 2.4.1
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/README.md +48 -0
- package/bin/cc.js +2 -1
- package/bin/index.js +1 -0
- package/cloudcc-dev-skill/SKILL.md +31 -8
- package/cloudcc-dev-skill/cloudcc-dev-html.md +42 -0
- package/cloudcc-dev-skill/config.json +2 -2
- package/mcp/index.js +10 -4
- package/mcp/tools/JSP Migrator/handler.js +51 -866
- package/mcp/tools/Object Creator/handler.js +14 -4
- package/mcp/tools/Trigger List Retriever/handler.js +24 -8
- package/package.json +1 -1
- package/src/classes/docs/devguide.md +863 -356
- package/src/classes/docs/introduction.md +279 -143
- package/src/jsp/analyze.js +17 -0
- package/src/jsp/doc.js +18 -0
- package/src/jsp/docs/devguide.md +111 -0
- package/src/jsp/docs/introduction.md +50 -0
- package/src/jsp/docs.js +21 -0
- package/src/jsp/index.js +14 -0
- package/src/jsp/migration.js +871 -0
- package/src/jsp/split.js +17 -0
- package/src/object/create.js +36 -10
- package/src/object/docs/devguide.md +6 -3
- package/src/project/docs/devguide.md +1 -1
- package/src/script/docs/devguide.md +22 -2
- package/src/timer/docs/devguide.md +1038 -400
- package/src/timer/docs/introduction.md +343 -231
- package/src/triggers/docs/devguide.md +1027 -329
- package/src/triggers/docs/introduction.md +640 -369
- package/src/triggers/get.js +8 -0
- package/src/version/listModuleCommands.js +6 -0
- package/target/classes/com/cloudcc/core/BaseException.class +0 -0
- package/target/classes/com/cloudcc/core/BusiException.class +0 -0
- package/target/classes/com/cloudcc/core/CCObject.class +0 -0
- package/target/classes/com/cloudcc/core/CCSchedule.class +0 -0
- package/target/classes/com/cloudcc/core/CCService.class +0 -0
- package/target/classes/com/cloudcc/core/CCTrigger.class +0 -0
- package/target/classes/com/cloudcc/core/CCTriggerHandler.class +0 -0
- package/target/classes/com/cloudcc/core/DevLogger.class +0 -0
- package/target/classes/com/cloudcc/core/OperatationEnum.class +0 -0
- package/target/classes/com/cloudcc/core/PeakInterf.class +0 -0
- package/target/classes/com/cloudcc/core/SendEmail.class +0 -0
- package/target/classes/com/cloudcc/core/ServiceResult.class +0 -0
- package/target/classes/com/cloudcc/core/StringUtils.class +0 -0
- package/target/classes/com/cloudcc/core/TimeUtil.class +0 -0
- package/target/classes/com/cloudcc/core/Tool$1.class +0 -0
- package/target/classes/com/cloudcc/core/Tool.class +0 -0
- package/target/classes/com/cloudcc/core/TriggerInvoker.class +0 -0
- package/target/classes/com/cloudcc/core/TriggerMethod.class +0 -0
- package/target/classes/com/cloudcc/core/TriggerTimeEnum.class +0 -0
- package/target/classes/com/cloudcc/core/UserInfo.class +0 -0
- package/test/jsp.cli.test.js +70 -0
- package/test/object.cli.test.js +9 -1
|
@@ -1,554 +1,1192 @@
|
|
|
1
|
-
# CloudCC
|
|
1
|
+
# CloudCC 定时器类 AI 开发规范
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## 1. 文档目的
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
本文用于约束 AI 在当前 CloudCC 项目中编写定时器类时的分析方式、实现方式、SDK 选型和输出要求。
|
|
6
|
+
|
|
7
|
+
目标不是让 AI “能写出代码”即可,而是让 AI 写出的定时器类:
|
|
8
|
+
|
|
9
|
+
- 适合放在定时器而不是触发器或页面脚本中
|
|
10
|
+
- 符合 CloudCC 官方 SDK 用法
|
|
11
|
+
- 符合 `cloudcc-cli` 的目录和发布约束
|
|
12
|
+
- 符合当前项目的主流实现模式
|
|
13
|
+
- 具备幂等性、可观测性、批量处理意识和时区安全意识
|
|
14
|
+
|
|
15
|
+
## 2. 依据来源
|
|
16
|
+
|
|
17
|
+
- 官方 SDK 文档提供 `CCObject`、`CCService`、`SendEmail`、`DevLogger`、`TimeUtil` 等核心 API 依据
|
|
18
|
+
- `2-timer-classes-analysis.md` 提供当前项目定时器使用场景和共性模式
|
|
19
|
+
- `timer devguide` 提供本地目录、CLI、发布和 SOURCE 区域约束
|
|
20
|
+
|
|
21
|
+
## 3. 与 introduction 的分工(避免重复)
|
|
22
|
+
|
|
23
|
+
为避免与 `timer introduction` 内容重复,本 `devguide` 只保留“开发落地规范”:
|
|
24
|
+
|
|
25
|
+
- 命令与入参(可直接执行)
|
|
26
|
+
- 目录与文件约束(可直接检查)
|
|
27
|
+
- SDK 用法与边界(可直接编码)
|
|
28
|
+
- 代码模板与禁止事项(可直接评审)
|
|
29
|
+
|
|
30
|
+
“定时器是什么、能解决什么、与触发器差异、适用/不适用场景”等概念说明,统一以 `cloudcc doc timer introduction` 为准。
|
|
31
|
+
|
|
32
|
+
## 4. 文件与交付规范
|
|
33
|
+
|
|
34
|
+
这是 AI 必须遵守的第一层约束。
|
|
6
35
|
|
|
7
|
-
|
|
36
|
+
### 4.1 目录与文件来源
|
|
8
37
|
|
|
9
|
-
|
|
38
|
+
- 定时器目录必须位于 `schedule/<类名>/`
|
|
39
|
+
- 每个定时器目录包含主类 `*.java` 和 `config.json`
|
|
40
|
+
- 定时器目录必须通过 `cloudcc create timer <name>` 创建
|
|
10
41
|
|
|
11
|
-
|
|
42
|
+
### 4.2 AI 不得做的事情
|
|
12
43
|
|
|
13
|
-
|
|
44
|
+
- 不要手工新建 `schedule/` 子目录
|
|
45
|
+
- 不要整包复制其他项目的定时器目录
|
|
46
|
+
- 不要手工修改 `config.json` 中的 `id` 或版本字段
|
|
47
|
+
- 不要在 `// @SOURCE_CONTENT_START` 与 `// @SOURCE_CONTENT_END` 之外写业务逻辑
|
|
14
48
|
|
|
15
|
-
###
|
|
49
|
+
### 4.3 AI 允许做的事情
|
|
50
|
+
|
|
51
|
+
- 只在 CLI 生成的主类 SOURCE 区域内实现业务逻辑
|
|
52
|
+
- 保持 `package schedule.<类名>;` 与目录名一致
|
|
53
|
+
- 让类继承 `CCSchedule`
|
|
54
|
+
- 构造方法名与类名一致
|
|
55
|
+
|
|
56
|
+
### 4.4 timer 模块支持的 CLI 命令总览(重点:入参)
|
|
57
|
+
|
|
58
|
+
说明:
|
|
59
|
+
|
|
60
|
+
- 下文命令中的资源名使用 `timer`,也可使用别名 `schedule`(两者路由到同一模块)。
|
|
61
|
+
- `projectPath` 未传时,默认使用当前工作目录。
|
|
62
|
+
|
|
63
|
+
#### 1) 创建定时类
|
|
64
|
+
|
|
65
|
+
命令:
|
|
16
66
|
|
|
17
67
|
```bash
|
|
18
68
|
cloudcc create timer <name>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
参数:
|
|
72
|
+
|
|
73
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
74
|
+
| --- | --- | --- | --- |
|
|
75
|
+
| `name` | 是 | `string` | 定时类名称(同时作为目录名、Java 类名) |
|
|
76
|
+
|
|
77
|
+
示例:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
cloudcc create timer DailySyncJob
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
#### 2) 发布定时类
|
|
86
|
+
|
|
87
|
+
命令:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
19
90
|
cloudcc publish timer <name>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
参数:
|
|
94
|
+
|
|
95
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
96
|
+
| --- | --- | --- | --- |
|
|
97
|
+
| `name` | 是 | `string` | 本地 `schedule/<name>/` 目录名 |
|
|
98
|
+
|
|
99
|
+
示例:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
cloudcc publish timer DailySyncJob
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
#### 3) 拉取定时类(按本地名称)
|
|
108
|
+
|
|
109
|
+
命令:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
20
112
|
cloudcc pull timer <name>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
参数:
|
|
116
|
+
|
|
117
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
118
|
+
| --- | --- | --- | --- |
|
|
119
|
+
| `name` | 是 | `string` | 本地 `schedule/<name>/` 目录名;会读取该目录 `config.json` 中的 `id` 到线上拉取 |
|
|
120
|
+
|
|
121
|
+
示例:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
cloudcc pull timer DailySyncJob
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
#### 4) 查询定时类列表(支持条件查询)
|
|
130
|
+
|
|
131
|
+
命令:
|
|
132
|
+
|
|
133
|
+
```bash
|
|
21
134
|
cloudcc get timer [listQueryJson] [projectPath]
|
|
22
|
-
|
|
23
|
-
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
`listQueryJson` 推荐结构:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"shownum": 2000,
|
|
142
|
+
"showpage": 1,
|
|
143
|
+
"sname": "",
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
字段说明:
|
|
148
|
+
|
|
149
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
150
|
+
| --- | --- | --- | --- |
|
|
151
|
+
| `shownum` | `number|string` | 否 | 每页条数,默认 `2000` |
|
|
152
|
+
| `showpage` | `number|string` | 否 | 页码,默认 `1` |
|
|
153
|
+
| `sname` | `string` | 否 | 名称筛选关键字,模糊查询 |
|
|
154
|
+
|
|
155
|
+
示例:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
cloudcc get timer "$(node -e 'console.log(encodeURI(JSON.stringify({shownum:2000,showpage:1,fid:\"\",sname:\"Daily\",rptcond:\"\",rptorder:\"\"})))')"
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
#### 5) 查看定时类详情
|
|
164
|
+
|
|
165
|
+
命令:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
cloudcc detail timer <name> <id>
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
参数规则(实现口径):
|
|
172
|
+
|
|
173
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
174
|
+
| --- | --- | --- | --- |
|
|
175
|
+
| `name` | 条件必填 | `string` | 传 `name` 时优先查本地;本地不完整时再走线上 |
|
|
176
|
+
| `id` | 条件必填 | `string` | 当 `name` 为空时,必须传 `id` 走线上查询 |
|
|
177
|
+
|
|
178
|
+
等价理解:`name` 与 `id` 至少传一个,优先使用 `name` 路径。
|
|
179
|
+
|
|
180
|
+
示例(按本地名):
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
cloudcc detail timer DailySyncJob
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
示例(按线上 id):
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
cloudcc detail timer "" a0Bxxxxxxxxxxxx
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
#### 6) 按 ID 拉取并落地到本地目录
|
|
195
|
+
|
|
196
|
+
命令:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
24
199
|
cloudcc pullList timer <id> <projectPath>
|
|
25
|
-
cloudcc delete timer <nameOrId> [projectPath]
|
|
26
|
-
cloudcc doc timer <introduction|devguide>
|
|
27
200
|
```
|
|
28
201
|
|
|
29
|
-
|
|
202
|
+
参数:
|
|
203
|
+
|
|
204
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
205
|
+
| --- | --- | --- | --- |
|
|
206
|
+
| `id` | 是 | `string` | 线上定时类 ID |
|
|
207
|
+
| `projectPath` | 是 | `string` | 项目根目录;会写入到 `<projectPath>/schedule/<name>/` |
|
|
208
|
+
|
|
209
|
+
示例:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
cloudcc pullList timer a0Bxxxxxxxxxxxx /path/to/project
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
#### 7) 删除定时类
|
|
218
|
+
|
|
219
|
+
命令:
|
|
30
220
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
- `id`:线上定时类 ID。`detail` 仅查服务器时:`cloudcc detail timer "" <id>`。`pullList` 必填。
|
|
35
|
-
- `nameOrId`:本地目录名或类 ID;若本地 `config.json` 含 `id`,删除时优先使用该 ID。
|
|
221
|
+
```bash
|
|
222
|
+
cloudcc delete timer <nameOrId> [projectPath]
|
|
223
|
+
```
|
|
36
224
|
|
|
37
|
-
|
|
225
|
+
参数规则:
|
|
38
226
|
|
|
39
|
-
|
|
|
40
|
-
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `pull` | 按本地 `id` 拉取远端源码,覆盖主类中 SOURCE 区域(需已发布) |
|
|
44
|
-
| `get` | 查询线上定时类列表(JSON 输出) |
|
|
45
|
-
| `detail` | 按类名优先读本地;或仅按 `id` 读服务器 |
|
|
46
|
-
| `pullList` | 按类 `id` 将线上定时类落到指定项目的 `schedule/<类名>/` |
|
|
47
|
-
| `delete` | 删除服务器上的定时类 |
|
|
48
|
-
| `doc` | 输出模块文档;`devguide` 含附录后端 Java SDK 速查 |
|
|
227
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
228
|
+
| --- | --- | --- | --- |
|
|
229
|
+
| `nameOrId` | 是 | `string` | 可传本地目录名或线上 ID;若本地 `schedule/<nameOrId>/config.json` 存在且带 `id`,优先使用其中 `id` 删除 |
|
|
230
|
+
| `projectPath` | 否 | `string` | 项目根目录,默认当前目录 |
|
|
49
231
|
|
|
50
|
-
|
|
232
|
+
示例(按名称):
|
|
51
233
|
|
|
52
234
|
```bash
|
|
53
|
-
|
|
54
|
-
|
|
235
|
+
cloudcc delete timer DailySyncJob
|
|
236
|
+
```
|
|
55
237
|
|
|
56
|
-
|
|
57
|
-
cloudcc create timer MySchedule
|
|
238
|
+
示例(按 id):
|
|
58
239
|
|
|
59
|
-
|
|
60
|
-
cloudcc
|
|
240
|
+
```bash
|
|
241
|
+
cloudcc delete timer a0Bxxxxxxxxxxxx
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
61
245
|
|
|
62
|
-
|
|
63
|
-
cloudcc pull timer MySchedule
|
|
246
|
+
#### 8) 文档命令
|
|
64
247
|
|
|
65
|
-
|
|
66
|
-
cloudcc pullList timer <线上类ID> <projectPath>
|
|
248
|
+
命令:
|
|
67
249
|
|
|
68
|
-
|
|
69
|
-
cloudcc
|
|
250
|
+
```bash
|
|
251
|
+
cloudcc doc timer <introduction|devguide>
|
|
70
252
|
```
|
|
71
253
|
|
|
72
|
-
|
|
254
|
+
参数:
|
|
255
|
+
|
|
256
|
+
| 参数 | 必填 | 类型 | 说明 |
|
|
257
|
+
| --- | --- | --- | --- |
|
|
258
|
+
| `introduction|devguide` | 是 | `string` | `introduction` 返回概念文档;`devguide` 返回开发规范(并附 SDK 速查) |
|
|
259
|
+
|
|
260
|
+
示例:
|
|
73
261
|
|
|
74
262
|
```bash
|
|
75
263
|
cloudcc doc timer introduction
|
|
76
264
|
cloudcc doc timer devguide
|
|
77
265
|
```
|
|
78
266
|
|
|
79
|
-
|
|
267
|
+
## 5. AI 编写定时器类的核心原则
|
|
80
268
|
|
|
81
|
-
|
|
269
|
+
### 5.1 先分析,再编码
|
|
82
270
|
|
|
83
|
-
|
|
271
|
+
AI 在写代码前,至少应明确以下内容:
|
|
84
272
|
|
|
85
|
-
|
|
273
|
+
- 主对象是什么
|
|
274
|
+
- 关联对象是什么
|
|
275
|
+
- 触发频率是什么
|
|
276
|
+
- 筛选条件是什么
|
|
277
|
+
- 执行动作是什么
|
|
278
|
+
- 是否存在重复执行风险
|
|
279
|
+
- 是否需要批量处理
|
|
280
|
+
- 是否需要通知
|
|
281
|
+
- 是否需要日志
|
|
282
|
+
- 是否需要失败补偿
|
|
86
283
|
|
|
87
|
-
|
|
88
|
-
- 关联自定义的业务逻辑代码(定时类)
|
|
89
|
-
- 系统自动在指定时间触发执行,无需人工干预
|
|
284
|
+
### 5.2 优先配置化,不要硬编码
|
|
90
285
|
|
|
91
|
-
|
|
286
|
+
以下信息如果未来可能变化,优先配置化,不要直接写死在代码里:
|
|
92
287
|
|
|
93
|
-
|
|
288
|
+
- 提醒天数
|
|
289
|
+
- 阈值条件
|
|
290
|
+
- 模版 ID
|
|
291
|
+
- 收件人范围
|
|
292
|
+
- 开关标记
|
|
293
|
+
- 外部接口地址或行为参数
|
|
94
294
|
|
|
95
|
-
|
|
295
|
+
如果必须读取配置,优先使用官方 SDK 的自定义设置能力。
|
|
96
296
|
|
|
97
|
-
###
|
|
297
|
+
### 5.3 必须考虑幂等性
|
|
98
298
|
|
|
99
|
-
|
|
299
|
+
定时器会重复执行,因此 AI 生成代码时必须避免“重复跑一次就重复造数据”。
|
|
100
300
|
|
|
101
|
-
|
|
102
|
-
- 每周生成销售报表
|
|
103
|
-
- 每月清理过期数据
|
|
301
|
+
常见幂等策略包括:
|
|
104
302
|
|
|
105
|
-
|
|
303
|
+
- 先判断是否已处理,再执行
|
|
304
|
+
- 通过状态位、标记位、执行日期控制重复执行
|
|
305
|
+
- 通过业务唯一键判断是否已存在目标记录
|
|
306
|
+
- 通过补偿表或日志表判断是否已成功处理
|
|
106
307
|
|
|
107
|
-
|
|
308
|
+
### 5.4 必须考虑批量处理
|
|
108
309
|
|
|
109
|
-
|
|
110
|
-
- 客户生日当天发送祝福
|
|
111
|
-
- 季度末自动生成业绩报告
|
|
310
|
+
定时器天然面向批量数据。AI 不能默认按“单笔页面逻辑”写法来写。
|
|
112
311
|
|
|
113
|
-
|
|
312
|
+
应优先考虑:
|
|
114
313
|
|
|
115
|
-
|
|
314
|
+
- 分页查询
|
|
315
|
+
- 分批写入
|
|
316
|
+
- 减少循环内查询
|
|
317
|
+
- 减少循环内单条更新
|
|
116
318
|
|
|
117
|
-
|
|
118
|
-
- 批量更新客户状态
|
|
119
|
-
- 计算佣金和业绩
|
|
319
|
+
### 5.5 必须考虑可观测性
|
|
120
320
|
|
|
121
|
-
|
|
321
|
+
AI 生成的定时器类至少要做到:
|
|
122
322
|
|
|
123
|
-
|
|
323
|
+
- 关键路径有日志
|
|
324
|
+
- 异常可定位
|
|
325
|
+
- 批处理数量可观察
|
|
326
|
+
- 失败信息可追踪
|
|
124
327
|
|
|
125
|
-
|
|
126
|
-
- 收款计划逾期 → 通知财务人员
|
|
127
|
-
- 资产即将失效 → 自动生成业务机会
|
|
328
|
+
### 5.6 必须考虑时区安全
|
|
128
329
|
|
|
129
|
-
|
|
330
|
+
涉及日期比较、日期格式化、写库时间时,不能默认依赖本地时区。
|
|
331
|
+
|
|
332
|
+
应优先使用 `TimeUtil`。
|
|
333
|
+
|
|
334
|
+
## 6. 官方 SDK 详细速查
|
|
130
335
|
|
|
131
|
-
|
|
336
|
+
- 本节优先给出方法签名、入参、返回值和使用场景
|
|
337
|
+
- 表中“必填”信息来源于官方文档
|
|
338
|
+
- 如果某个批量方法在当前项目里很常见,但官方页面没有展开签名,会单独标注“项目约定”
|
|
339
|
+
- 当前项目大量定时器直接调用 `this.cquery(...)`、`this.cqlQuery(...)`、`this.insert(...)` 等 inherited 方法;AI 在理解参数语义时,应以官方 `CCService` 版本为准
|
|
132
340
|
|
|
133
|
-
###
|
|
341
|
+
### 6.1 `CCObject`
|
|
134
342
|
|
|
135
|
-
|
|
136
|
-
|------|----------|----------|
|
|
137
|
-
| **准确性** | 可能遗忘、出错 | 100% 准时执行 |
|
|
138
|
-
| **效率** | 耗时耗力 | 自动执行,零人力成本 |
|
|
139
|
-
| **一致性** | 不同人操作可能有差异 | 每次执行逻辑一致 |
|
|
140
|
-
| **可扩展性** | 任务多了忙不过来 | 可同时运行多个任务 |
|
|
141
|
-
| **可追溯** | 难以追踪谁什么时候做的 | 完整执行日志 |
|
|
343
|
+
类定位:
|
|
142
344
|
|
|
143
|
-
|
|
345
|
+
- CloudCC 对象封装类
|
|
346
|
+
- 用于承载新增、更新、删除、共享等对象数据
|
|
144
347
|
|
|
348
|
+
#### 构造方法 1
|
|
349
|
+
|
|
350
|
+
```java
|
|
351
|
+
public CCObject()
|
|
145
352
|
```
|
|
146
|
-
|
|
353
|
+
|
|
354
|
+
说明:
|
|
355
|
+
|
|
356
|
+
- 官方提供默认构造
|
|
357
|
+
- 在当前项目定时器中较少单独使用
|
|
358
|
+
|
|
359
|
+
#### 构造方法 2
|
|
360
|
+
|
|
361
|
+
```java
|
|
362
|
+
public CCObject(String ccobj)
|
|
147
363
|
```
|
|
148
364
|
|
|
149
|
-
|
|
365
|
+
参数说明:
|
|
366
|
+
|
|
367
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
368
|
+
| --- | --- | --- | --- |
|
|
369
|
+
| `ccobj` | `String` | 是 | 对象 API 名 |
|
|
370
|
+
|
|
371
|
+
返回:
|
|
150
372
|
|
|
151
|
-
|
|
373
|
+
- `CCObject` 实例
|
|
152
374
|
|
|
153
|
-
|
|
375
|
+
AI 使用要求:
|
|
154
376
|
|
|
155
|
-
|
|
377
|
+
- 新增普通记录时优先用这个构造器
|
|
378
|
+
- `ccobj` 必须写对象 API 名,不要写对象标签名
|
|
156
379
|
|
|
157
|
-
|
|
380
|
+
#### 构造方法 3
|
|
158
381
|
|
|
382
|
+
```java
|
|
383
|
+
public CCObject(String ccobj, String isShared)
|
|
159
384
|
```
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
385
|
+
|
|
386
|
+
参数说明:
|
|
387
|
+
|
|
388
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
389
|
+
| --- | --- | --- | --- |
|
|
390
|
+
| `ccobj` | `String` | 是 | 对象 API 名 |
|
|
391
|
+
| `isShared` | `String` | 是 | 共享标识,官方建议使用 `CCObject.IS_SHARED` |
|
|
392
|
+
|
|
393
|
+
返回:
|
|
394
|
+
|
|
395
|
+
- `CCObject` 实例
|
|
396
|
+
|
|
397
|
+
AI 使用要求:
|
|
398
|
+
|
|
399
|
+
- 仅在共享表对象场景使用
|
|
400
|
+
- 不要自己发明共享标识字符串,优先使用 `CCObject.IS_SHARED`
|
|
401
|
+
|
|
402
|
+
#### 常用对象方法
|
|
403
|
+
|
|
404
|
+
官方文档列出:
|
|
405
|
+
|
|
406
|
+
- `getUserId()`
|
|
407
|
+
- `getOrgId()`
|
|
408
|
+
- `getRoleId()`
|
|
409
|
+
|
|
410
|
+
AI 使用要求:
|
|
411
|
+
|
|
412
|
+
- 如果需要读取当前对象上下文中的用户、组织、角色信息,可使用这些方法
|
|
413
|
+
- 定时器的主要业务数据写入仍以 `put` 为主
|
|
414
|
+
|
|
415
|
+
### 6.2 `CCService`
|
|
416
|
+
|
|
417
|
+
类定位:
|
|
418
|
+
|
|
419
|
+
- CloudCC 核心对象服务类
|
|
420
|
+
- 提供对象增删改查、自定义设置、共享删除等能力
|
|
421
|
+
|
|
422
|
+
#### 构造函数
|
|
423
|
+
|
|
424
|
+
```java
|
|
425
|
+
public CCService(UserInfo userInfo)
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
参数说明:
|
|
429
|
+
|
|
430
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
431
|
+
| --- | --- | --- | --- |
|
|
432
|
+
| `userInfo` | `UserInfo` | 是 | 当前用户对象 |
|
|
433
|
+
|
|
434
|
+
返回:
|
|
435
|
+
|
|
436
|
+
- `CCService` 实例
|
|
437
|
+
|
|
438
|
+
AI 使用要求:
|
|
439
|
+
|
|
440
|
+
- 定时器中默认先初始化 `CCService cs = new CCService(userInfo);`
|
|
441
|
+
- 除非使用 `CCSchedule` 已提供的同语义快捷方法,否则统一从 `cs` 调用 SDK
|
|
442
|
+
|
|
443
|
+
### 6.3 `insert`
|
|
444
|
+
|
|
445
|
+
方法签名:
|
|
446
|
+
|
|
447
|
+
```java
|
|
448
|
+
public ServiceResult insert(CCObject ccobj) throws BusiException
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
参数说明:
|
|
452
|
+
|
|
453
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
454
|
+
| --- | --- | --- | --- |
|
|
455
|
+
| `ccobj` | `CCObject` | 是 | 待新增的 CloudCC 对象 |
|
|
456
|
+
|
|
457
|
+
返回:
|
|
458
|
+
|
|
459
|
+
- `ServiceResult`
|
|
460
|
+
|
|
461
|
+
适用场景:
|
|
462
|
+
|
|
463
|
+
- 新增单条记录
|
|
464
|
+
- 新增任务、提醒、日志类单条对象
|
|
465
|
+
|
|
466
|
+
AI 使用要求:
|
|
467
|
+
|
|
468
|
+
- 先构造 `CCObject`,再 `put` 字段,最后 `insert`
|
|
469
|
+
- 不要在大批量循环里无脑逐条 `insert`
|
|
470
|
+
- 如果需要创建大量记录,优先考虑项目已有的批量写法
|
|
471
|
+
|
|
472
|
+
### 6.4 `cquery`
|
|
473
|
+
|
|
474
|
+
#### 查询普通数据
|
|
475
|
+
|
|
476
|
+
方法签名:
|
|
477
|
+
|
|
478
|
+
```java
|
|
479
|
+
public List<CCObject> cquery(String apiName, String condition, String order) throws Exception
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
参数说明:
|
|
483
|
+
|
|
484
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
485
|
+
| --- | --- | --- | --- |
|
|
486
|
+
| `apiName` | `String` | 是 | 对象 API 名 |
|
|
487
|
+
| `condition` | `String` | 否 | 查询条件;自定义字段 API 名要带 `__c` |
|
|
488
|
+
| `order` | `String` | 否 | 排序条件 |
|
|
489
|
+
|
|
490
|
+
返回:
|
|
491
|
+
|
|
492
|
+
- `List<CCObject>`
|
|
493
|
+
|
|
494
|
+
适用场景:
|
|
495
|
+
|
|
496
|
+
- 单对象简单条件查询
|
|
497
|
+
- 条件和排序较直接的巡检类定时器
|
|
498
|
+
|
|
499
|
+
AI 使用要求:
|
|
500
|
+
|
|
501
|
+
- 优先用于简单查询
|
|
502
|
+
- 不要把页面字段标签名写进条件
|
|
503
|
+
- 自定义字段必须用 API 名并带 `__c`
|
|
504
|
+
|
|
505
|
+
#### 查询共享数据
|
|
506
|
+
|
|
507
|
+
方法签名:
|
|
508
|
+
|
|
509
|
+
```java
|
|
510
|
+
public List<CCObject> cquery(String apiName, String condition, boolean isDataObject) throws Exception
|
|
164
511
|
```
|
|
165
512
|
|
|
166
|
-
|
|
513
|
+
参数说明:
|
|
514
|
+
|
|
515
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
516
|
+
| --- | --- | --- | --- |
|
|
517
|
+
| `apiName` | `String` | 是 | 对象 API 名 |
|
|
518
|
+
| `condition` | `String` | 否 | 查询条件 |
|
|
519
|
+
| `isDataObject` | `boolean` | 是 | 是否查询业务对象;共享数据场景按项目现有写法传入对应布尔值 |
|
|
520
|
+
|
|
521
|
+
返回:
|
|
522
|
+
|
|
523
|
+
- `List<CCObject>`
|
|
167
524
|
|
|
168
|
-
|
|
525
|
+
适用场景:
|
|
169
526
|
|
|
170
|
-
|
|
527
|
+
- 共享关系查询
|
|
528
|
+
- 权限治理类定时器
|
|
171
529
|
|
|
530
|
+
AI 使用要求:
|
|
531
|
+
|
|
532
|
+
- 涉及共享表查询时使用该重载
|
|
533
|
+
- 布尔参数不要凭空猜测语义,优先参考现有仓库同类写法
|
|
534
|
+
|
|
535
|
+
### 6.5 `cqlQuery`
|
|
536
|
+
|
|
537
|
+
方法签名:
|
|
538
|
+
|
|
539
|
+
```java
|
|
540
|
+
public List<CCObject> cqlQuery(String apiName, String cql) throws Exception
|
|
172
541
|
```
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
542
|
+
|
|
543
|
+
参数说明:
|
|
544
|
+
|
|
545
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
546
|
+
| --- | --- | --- | --- |
|
|
547
|
+
| `apiName` | `String` | 是 | 对象 API 名 |
|
|
548
|
+
| `cql` | `String` | 否 | SQL/CQL 查询语句,支持常见 `where` 条件 |
|
|
549
|
+
|
|
550
|
+
返回:
|
|
551
|
+
|
|
552
|
+
- `List<CCObject>`
|
|
553
|
+
|
|
554
|
+
适用场景:
|
|
555
|
+
|
|
556
|
+
- 联表查询
|
|
557
|
+
- 聚合查询
|
|
558
|
+
- 分组统计
|
|
559
|
+
- 报表底表查询
|
|
560
|
+
- 复杂分页场景
|
|
561
|
+
|
|
562
|
+
AI 使用要求:
|
|
563
|
+
|
|
564
|
+
- 复杂查询优先 `cqlQuery`
|
|
565
|
+
- 默认把它当“查询接口”使用
|
|
566
|
+
- 除非有充分依据,不要把它写成更新或删除通道
|
|
567
|
+
- 报表、底表、汇总类定时器优先考虑 `cqlQuery`
|
|
568
|
+
|
|
569
|
+
### 6.6 `update`
|
|
570
|
+
|
|
571
|
+
方法签名:
|
|
572
|
+
|
|
573
|
+
```java
|
|
574
|
+
public ServiceResult update(CCObject ccobj) throws Exception
|
|
176
575
|
```
|
|
177
576
|
|
|
178
|
-
|
|
577
|
+
参数说明:
|
|
578
|
+
|
|
579
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
580
|
+
| --- | --- | --- | --- |
|
|
581
|
+
| `ccobj` | `CCObject` | 是 | 待更新对象,必须含 `id` |
|
|
179
582
|
|
|
180
|
-
|
|
583
|
+
返回:
|
|
181
584
|
|
|
182
|
-
|
|
585
|
+
- `ServiceResult`
|
|
183
586
|
|
|
587
|
+
适用场景:
|
|
588
|
+
|
|
589
|
+
- 修改单条记录
|
|
590
|
+
- 回填单条标记、状态、编号
|
|
591
|
+
|
|
592
|
+
AI 使用要求:
|
|
593
|
+
|
|
594
|
+
- 更新前必须 `put("id", ...)`
|
|
595
|
+
- 仅回写必要字段,不要把无关字段全量覆盖
|
|
596
|
+
- 如果数据量大,优先改用批量更新策略
|
|
597
|
+
|
|
598
|
+
### 6.7 `delete`
|
|
599
|
+
|
|
600
|
+
方法签名:
|
|
601
|
+
|
|
602
|
+
```java
|
|
603
|
+
public ServiceResult delete(CCObject ccobj) throws Exception
|
|
184
604
|
```
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
605
|
+
|
|
606
|
+
参数说明:
|
|
607
|
+
|
|
608
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
609
|
+
| --- | --- | --- | --- |
|
|
610
|
+
| `ccobj` | `CCObject` | 是 | 待删除对象,通常至少包含 `id` |
|
|
611
|
+
|
|
612
|
+
返回:
|
|
613
|
+
|
|
614
|
+
- `ServiceResult`
|
|
615
|
+
|
|
616
|
+
适用场景:
|
|
617
|
+
|
|
618
|
+
- 删除普通业务记录
|
|
619
|
+
|
|
620
|
+
AI 使用要求:
|
|
621
|
+
|
|
622
|
+
- 删除前必须确认这是业务允许的动作
|
|
623
|
+
- 默认不要在定时器中做大批量物理/逻辑删除,除非需求明确
|
|
624
|
+
|
|
625
|
+
### 6.8 `deleteShareObjectBySql`
|
|
626
|
+
|
|
627
|
+
方法签名:
|
|
628
|
+
|
|
629
|
+
```java
|
|
630
|
+
public void deleteShareObjectBySql(String objectApiName, String expression) throws Exception
|
|
189
631
|
```
|
|
190
632
|
|
|
191
|
-
|
|
633
|
+
参数说明:
|
|
634
|
+
|
|
635
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
636
|
+
| --- | --- | --- | --- |
|
|
637
|
+
| `objectApiName` | `String` | 是 | 共享对象 API 名 |
|
|
638
|
+
| `expression` | `String` | 是 | SQL 表达式;官方说明字段名不需要加 `__c` |
|
|
639
|
+
|
|
640
|
+
返回:
|
|
641
|
+
|
|
642
|
+
- `void`
|
|
643
|
+
|
|
644
|
+
适用场景:
|
|
645
|
+
|
|
646
|
+
- 共享关系清理
|
|
647
|
+
- 权限治理类定时器
|
|
192
648
|
|
|
193
|
-
|
|
649
|
+
AI 使用要求:
|
|
194
650
|
|
|
195
|
-
|
|
651
|
+
- 优先用于共享对象删除,不要拿它删除普通业务对象
|
|
652
|
+
- 条件一定要收敛,避免误删共享关系
|
|
196
653
|
|
|
654
|
+
### 6.9 自定义设置 `getListCustomSetting`
|
|
655
|
+
|
|
656
|
+
#### 读取列表类型全部记录
|
|
657
|
+
|
|
658
|
+
方法签名:
|
|
659
|
+
|
|
660
|
+
```java
|
|
661
|
+
public Map getListCustomSetting(String objectApiName)
|
|
197
662
|
```
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
663
|
+
|
|
664
|
+
参数说明:
|
|
665
|
+
|
|
666
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
667
|
+
| --- | --- | --- | --- |
|
|
668
|
+
| `objectApiName` | `String` | 是 | 自定义设置 API 名 |
|
|
669
|
+
|
|
670
|
+
返回:
|
|
671
|
+
|
|
672
|
+
- `Map`
|
|
673
|
+
|
|
674
|
+
适用场景:
|
|
675
|
+
|
|
676
|
+
- 读取一整套配置项
|
|
677
|
+
- 读取阈值表、邮件配置表、组织映射配置
|
|
678
|
+
|
|
679
|
+
#### 读取列表类型单条记录
|
|
680
|
+
|
|
681
|
+
方法签名:
|
|
682
|
+
|
|
683
|
+
```java
|
|
684
|
+
Map map = cs.getListCustomSetting(String apiName, String name);
|
|
201
685
|
```
|
|
202
686
|
|
|
203
|
-
|
|
687
|
+
参数说明:
|
|
688
|
+
|
|
689
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
690
|
+
| --- | --- | --- | --- |
|
|
691
|
+
| `apiName` | `String` | 是 | 自定义设置 API 名 |
|
|
692
|
+
| `name` | `String` | 是 | 自定义设置记录名称 |
|
|
204
693
|
|
|
205
|
-
|
|
694
|
+
返回:
|
|
206
695
|
|
|
207
|
-
|
|
696
|
+
- `Map`
|
|
208
697
|
|
|
209
|
-
|
|
210
|
-
|------|----------|----------|
|
|
211
|
-
| 线索分配 | 新线索创建后 24 小时未分配 | 自动分配给销售主管 |
|
|
212
|
-
| 客户跟进提醒 | 客户最后联系时间 > 15 天 | 创建跟进活动并通知销售 |
|
|
213
|
-
| 商机推进提醒 | 商机停留当前阶段 > 30 天 | 提醒销售经理介入 |
|
|
214
|
-
| 业绩统计 | 每日 23:00 | 计算当日业绩并更新报表 |
|
|
698
|
+
AI 使用要求:
|
|
215
699
|
|
|
216
|
-
|
|
700
|
+
- 可配置项优先放自定义设置,不要硬编码
|
|
701
|
+
- 提醒阈值、开关、模板 ID、收件人规则都应优先配置化
|
|
217
702
|
|
|
218
|
-
|
|
219
|
-
|------|----------|----------|
|
|
220
|
-
| 服务到期提醒 | 服务合同到期前 30 天 | 发送续约提醒邮件 |
|
|
221
|
-
| 客户满意度调查 | 服务完成后 7 天 | 发送满意度调查问卷 |
|
|
222
|
-
| 生日祝福 | 客户生日当天 | 发送祝福短信/邮件 |
|
|
223
|
-
| 投诉升级 | 投诉 48 小时未处理 | 自动升级至上级主管 |
|
|
703
|
+
### 6.10 `getCustomSetting`
|
|
224
704
|
|
|
225
|
-
|
|
705
|
+
方法签名:
|
|
226
706
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
| 逾期通知 | 收款计划逾期 1 天 | 发送逾期通知并标记 |
|
|
231
|
-
| 发票生成 | 确认收款后 | 自动生成并发送发票 |
|
|
232
|
-
| 佣金计算 | 每月 1 日 | 计算销售佣金并生成报表 |
|
|
707
|
+
```java
|
|
708
|
+
public Map getCustomSetting(String objectApiName, String id)
|
|
709
|
+
```
|
|
233
710
|
|
|
234
|
-
|
|
711
|
+
参数说明:
|
|
235
712
|
|
|
236
|
-
|
|
|
237
|
-
|
|
238
|
-
|
|
|
239
|
-
|
|
|
240
|
-
| 数据同步 | 每日 2:00 | 同步 CRM 与外部系统数据 |
|
|
241
|
-
| 索引优化 | 每月 1 日 4:00 | 重建数据库索引提升性能 |
|
|
713
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
714
|
+
| --- | --- | --- | --- |
|
|
715
|
+
| `objectApiName` | `String` | 是 | 自定义设置 API 名 |
|
|
716
|
+
| `id` | `String` | 是 | 简档 ID 或用户 ID |
|
|
242
717
|
|
|
243
|
-
|
|
718
|
+
返回:
|
|
244
719
|
|
|
245
|
-
|
|
246
|
-
|------|----------|----------|
|
|
247
|
-
| 营销活动提醒 | 活动开始前 3 天 | 通知参与人员准备 |
|
|
248
|
-
| 线索培育 | 线索创建后第 3/7/14 天 | 发送培育邮件 |
|
|
249
|
-
| 活动效果分析 | 活动结束后 1 天 | 生成效果分析报告 |
|
|
250
|
-
| 客户分群更新 | 每日 5:00 | 根据行为更新客户分群 |
|
|
720
|
+
- `Map`
|
|
251
721
|
|
|
252
|
-
|
|
722
|
+
适用场景:
|
|
253
723
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
│ 调度配置 │
|
|
268
|
-
│ ├── 频率类型 (frequency): daily/weekly/monthly │
|
|
269
|
-
│ ├── 执行时间 (executetime): 08:00 │
|
|
270
|
-
│ ├── 星期 (weeks): Mon,Tues,Wed,Thur,Fri │
|
|
271
|
-
│ ├── 开始日期 (startdate): 2024-01-01 │
|
|
272
|
-
│ └── 结束日期 (enddate): 2024-12-31 │
|
|
273
|
-
├─────────────────────────────────────────────────────────┤
|
|
274
|
-
│ 关联程序 │
|
|
275
|
-
│ ├── 程序 ID (prgid) │
|
|
276
|
-
│ └── 定时类 (className): com.xxx.scheduler.MyJob │
|
|
277
|
-
└─────────────────────────────────────────────────────────┘
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
### 执行流程
|
|
281
|
-
|
|
282
|
-
```
|
|
283
|
-
┌─────────────┐
|
|
284
|
-
│ 系统时钟 │
|
|
285
|
-
└──────┬──────┘
|
|
286
|
-
│ 到达触发时间
|
|
287
|
-
▼
|
|
288
|
-
┌─────────────┐
|
|
289
|
-
│ 调度器检查 │ ──→ 是否在有效期内?
|
|
290
|
-
└──────┬──────┘ ──→ 状态是否激活?
|
|
291
|
-
│ 是
|
|
292
|
-
▼
|
|
293
|
-
┌─────────────┐
|
|
294
|
-
│ 加载定时类 │
|
|
295
|
-
└──────┬──────┘
|
|
296
|
-
│
|
|
297
|
-
▼
|
|
298
|
-
┌─────────────┐
|
|
299
|
-
│ 执行 main() │
|
|
300
|
-
└──────┬──────┘
|
|
301
|
-
│
|
|
302
|
-
▼
|
|
303
|
-
┌─────────────┐
|
|
304
|
-
│ 记录执行日志 │
|
|
305
|
-
└─────────────┘
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### 定时类示例
|
|
309
|
-
|
|
310
|
-
```javascript
|
|
311
|
-
/**
|
|
312
|
-
* 定时类:客户长时间未联系自动新建活动
|
|
313
|
-
* 程序 ID: ccp20213DC20298RebnS
|
|
314
|
-
*/
|
|
315
|
-
function main($CCDK, obj) {
|
|
316
|
-
// 1. 查询超过 15 天未联系的客户
|
|
317
|
-
const fifteenDaysAgo = new Date();
|
|
318
|
-
fifteenDaysAgo.setDate(fifteenDaysAgo.getDate() - 15);
|
|
319
|
-
|
|
320
|
-
const customers = $CCDK.query(`
|
|
321
|
-
SELECT Id, Name, OwnerId
|
|
322
|
-
FROM Account
|
|
323
|
-
WHERE LastActivityDate < '${fifteenDaysAgo.toISOString()}'
|
|
324
|
-
`);
|
|
325
|
-
|
|
326
|
-
// 2. 为每个客户创建跟进活动
|
|
327
|
-
customers.forEach(customer => {
|
|
328
|
-
$CCDK.create('Activity', {
|
|
329
|
-
Subject: `跟进客户:${customer.Name}`,
|
|
330
|
-
Type: 'Call',
|
|
331
|
-
Status: 'Not Started',
|
|
332
|
-
OwnerId: customer.OwnerId,
|
|
333
|
-
RelatedToId: customer.Id
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
return `已为 ${customers.length} 个客户创建跟进活动`;
|
|
338
|
-
}
|
|
724
|
+
- 分用户、分角色、分权限读取配置
|
|
725
|
+
- 不同组织或角色使用不同阈值/模版
|
|
726
|
+
|
|
727
|
+
### 6.11 `SendEmail`
|
|
728
|
+
|
|
729
|
+
类定位:
|
|
730
|
+
|
|
731
|
+
- 官方邮件发送服务
|
|
732
|
+
|
|
733
|
+
#### 构造函数
|
|
734
|
+
|
|
735
|
+
```java
|
|
736
|
+
public SendEmail(UserInfo userInfo)
|
|
339
737
|
```
|
|
340
738
|
|
|
341
|
-
|
|
739
|
+
参数说明:
|
|
740
|
+
|
|
741
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
742
|
+
| --- | --- | --- | --- |
|
|
743
|
+
| `userInfo` | `UserInfo` | 是 | 当前用户对象 |
|
|
744
|
+
|
|
745
|
+
#### `sendMailFromSystem`
|
|
342
746
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
│ │
|
|
355
|
-
│ 业务逻辑: │
|
|
356
|
-
│ 1. 扫描所有客户,找出最后联系时间 > 15 天的 │
|
|
357
|
-
│ 2. 为每个客户自动创建"跟进"活动 │
|
|
358
|
-
│ 3. 活动分配给对应的销售负责人 │
|
|
359
|
-
│ │
|
|
360
|
-
│ 价值:防止销售遗忘客户跟进,提升客户满意度 │
|
|
361
|
-
└─────────────────────────────────────────────────────┘
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
### 案例 2:计划收款日期 7 天后发送邮件
|
|
365
|
-
|
|
366
|
-
```
|
|
367
|
-
┌─────────────────────────────────────────────────────┐
|
|
368
|
-
│ 作业名称:计划收款日期 7 天后发送邮件 │
|
|
369
|
-
├─────────────────────────────────────────────────────┤
|
|
370
|
-
│ 执行时间:每天 上午 8:00 │
|
|
371
|
-
│ 有效期:2021-12-10 ~ 2034-12-31 │
|
|
372
|
-
│ 状态:✅ 运行中 │
|
|
373
|
-
│ │
|
|
374
|
-
│ 业务逻辑: │
|
|
375
|
-
│ 1. 查询收款计划日期 = 今天 + 7 天的记录 │
|
|
376
|
-
│ 2. 发送邮件给客户提醒付款 │
|
|
377
|
-
│ 3. 抄送财务人员和对应销售 │
|
|
378
|
-
│ │
|
|
379
|
-
│ 价值:提前提醒客户付款,降低逾期率,改善现金流 │
|
|
380
|
-
└─────────────────────────────────────────────────────┘
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### 案例 3:资产失效三个月自动生成业务机会
|
|
384
|
-
|
|
385
|
-
```
|
|
386
|
-
┌─────────────────────────────────────────────────────┐
|
|
387
|
-
│ 作业名称:资产失效三个月自动生成业务机会 │
|
|
388
|
-
├─────────────────────────────────────────────────────┤
|
|
389
|
-
│ 执行时间:每天 凌晨 1:00 │
|
|
390
|
-
│ 有效期:2021-12-10 ~ 2033-12-31 │
|
|
391
|
-
│ 状态:✅ 运行中 │
|
|
392
|
-
│ │
|
|
393
|
-
│ 业务逻辑: │
|
|
394
|
-
│ 1. 查询资产失效时间 = 今天 - 3 个月的记录 │
|
|
395
|
-
│ 2. 自动创建新的业务机会(续费/升级) │
|
|
396
|
-
│ 3. 分配给原销售或客户经理 │
|
|
397
|
-
│ │
|
|
398
|
-
│ 价值:抓住续费时机,提升客户生命周期价值 │
|
|
399
|
-
└─────────────────────────────────────────────────────┘
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
### 案例 4:报表订阅(已过期)
|
|
403
|
-
|
|
404
|
-
```
|
|
405
|
-
┌─────────────────────────────────────────────────────┐
|
|
406
|
-
│ 作业名称:报表订阅 - 销售部收款统计报表 │
|
|
407
|
-
├─────────────────────────────────────────────────────┤
|
|
408
|
-
│ 执行时间:每月 10 日 下午 4:00 │
|
|
409
|
-
│ 有效期:2025-01-01 ~ 2025-02-28 ⚠️ 已过期 │
|
|
410
|
-
│ 状态:⚠️ 需要续期或停用 │
|
|
411
|
-
│ │
|
|
412
|
-
│ 业务逻辑: │
|
|
413
|
-
│ 1. 生成销售部收款统计报表 │
|
|
414
|
-
│ 2. 发送邮件给销售总监和财务经理 │
|
|
415
|
-
│ │
|
|
416
|
-
│ 建议:如仍需此报表,需更新有效期 │
|
|
417
|
-
└─────────────────────────────────────────────────────┘
|
|
747
|
+
方法签名:
|
|
748
|
+
|
|
749
|
+
```java
|
|
750
|
+
public boolean sendMailFromSystem(
|
|
751
|
+
String[] toAddress,
|
|
752
|
+
String[] ccAddress,
|
|
753
|
+
String[] bccAddress,
|
|
754
|
+
String subject,
|
|
755
|
+
String content,
|
|
756
|
+
boolean isText
|
|
757
|
+
)
|
|
418
758
|
```
|
|
419
759
|
|
|
420
|
-
|
|
760
|
+
参数说明:
|
|
761
|
+
|
|
762
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
763
|
+
| --- | --- | --- | --- |
|
|
764
|
+
| `toAddress` | `String[]` | 是 | 收件人数组 |
|
|
765
|
+
| `ccAddress` | `String[]` | 是 | 抄送人数组,可传空数组 |
|
|
766
|
+
| `bccAddress` | `String[]` | 是 | 密送人数组,可传空数组 |
|
|
767
|
+
| `subject` | `String` | 是 | 邮件主题 |
|
|
768
|
+
| `content` | `String` | 是 | 邮件正文,支持 HTML |
|
|
769
|
+
| `isText` | `boolean` | 是 | `true` 为纯文本,`false` 为 HTML |
|
|
770
|
+
|
|
771
|
+
返回:
|
|
772
|
+
|
|
773
|
+
- `boolean`
|
|
774
|
+
|
|
775
|
+
适用场景:
|
|
776
|
+
|
|
777
|
+
- 简单通知
|
|
778
|
+
- 汇总提醒
|
|
779
|
+
- 失败告警
|
|
780
|
+
|
|
781
|
+
AI 使用要求:
|
|
421
782
|
|
|
422
|
-
|
|
783
|
+
- 优先聚合后发送,避免一条记录一封邮件
|
|
784
|
+
- HTML 邮件时 `isText` 应传 `false`
|
|
785
|
+
- 收件人为空时不要发
|
|
423
786
|
|
|
424
|
-
|
|
787
|
+
#### `sendEmailNew`
|
|
425
788
|
|
|
789
|
+
方法签名:
|
|
790
|
+
|
|
791
|
+
```java
|
|
792
|
+
public ServiceResult sendEmailNew(
|
|
793
|
+
String emailtemplateid,
|
|
794
|
+
String[] toaddress,
|
|
795
|
+
String[] ccaddress,
|
|
796
|
+
String[] bcaddress,
|
|
797
|
+
String id
|
|
798
|
+
) throws Exception
|
|
426
799
|
```
|
|
427
|
-
✅ 推荐:
|
|
428
|
-
- 报表生成:非工作时间(如 23:00 或凌晨)
|
|
429
|
-
- 邮件通知:工作时间开始前(如 8:00)
|
|
430
|
-
- 数据同步:系统负载低时(如 2:00-4:00)
|
|
431
800
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
801
|
+
参数说明:
|
|
802
|
+
|
|
803
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
804
|
+
| --- | --- | --- | --- |
|
|
805
|
+
| `emailtemplateid` | `String` | 是 | 邮件模板 ID |
|
|
806
|
+
| `toaddress` | `String[]` | 是 | 收件人数组 |
|
|
807
|
+
| `ccaddress` | `String[]` | 是 | 抄送人数组 |
|
|
808
|
+
| `bcaddress` | `String[]` | 是 | 密送人数组 |
|
|
809
|
+
| `id` | `String` | 是 | 关联记录 ID |
|
|
810
|
+
|
|
811
|
+
返回:
|
|
812
|
+
|
|
813
|
+
- `ServiceResult`
|
|
814
|
+
|
|
815
|
+
适用场景:
|
|
816
|
+
|
|
817
|
+
- 已存在标准模版的业务提醒
|
|
818
|
+
- 需要统一邮件样式的场景
|
|
819
|
+
|
|
820
|
+
AI 使用要求:
|
|
821
|
+
|
|
822
|
+
- 模板 ID 应优先配置化
|
|
823
|
+
- 关联记录 ID 应传实际业务记录,不要随意填空字符串
|
|
824
|
+
|
|
825
|
+
### 6.12 `DevLogger`
|
|
826
|
+
|
|
827
|
+
类定位:
|
|
828
|
+
|
|
829
|
+
- 官方运行日志采集工具
|
|
830
|
+
|
|
831
|
+
#### 构造函数
|
|
832
|
+
|
|
833
|
+
```java
|
|
834
|
+
public DevLogger(UserInfo userInfo)
|
|
435
835
|
```
|
|
436
836
|
|
|
437
|
-
|
|
837
|
+
参数说明:
|
|
838
|
+
|
|
839
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
840
|
+
| --- | --- | --- | --- |
|
|
841
|
+
| `userInfo` | `UserInfo` | 是 | 当前用户对象 |
|
|
438
842
|
|
|
843
|
+
#### `devLogInfo`
|
|
844
|
+
|
|
845
|
+
方法签名:
|
|
846
|
+
|
|
847
|
+
```java
|
|
848
|
+
public void devLogInfo(String info)
|
|
439
849
|
```
|
|
440
|
-
✅ 推荐:
|
|
441
|
-
- 长期任务:设置 5-10 年有效期
|
|
442
|
-
- 临时任务:设置明确结束日期
|
|
443
|
-
- 定期审查:每季度检查过期任务
|
|
444
850
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
851
|
+
参数说明:
|
|
852
|
+
|
|
853
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
854
|
+
| --- | --- | --- | --- |
|
|
855
|
+
| `info` | `String` | 是 | info 级别日志内容 |
|
|
856
|
+
|
|
857
|
+
返回:
|
|
858
|
+
|
|
859
|
+
- `void`
|
|
860
|
+
|
|
861
|
+
#### `devLogError`
|
|
862
|
+
|
|
863
|
+
方法签名:
|
|
864
|
+
|
|
865
|
+
```java
|
|
866
|
+
public void devLogError(String error, Throwable throwable)
|
|
448
867
|
```
|
|
449
868
|
|
|
450
|
-
|
|
869
|
+
参数说明:
|
|
451
870
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
871
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
872
|
+
| --- | --- | --- | --- |
|
|
873
|
+
| `error` | `String` | 是 | 错误日志内容 |
|
|
874
|
+
| `throwable` | `Throwable` | 否 | 异常对象 |
|
|
875
|
+
|
|
876
|
+
返回:
|
|
877
|
+
|
|
878
|
+
- `void`
|
|
879
|
+
|
|
880
|
+
AI 使用要求:
|
|
881
|
+
|
|
882
|
+
- 批处理开始、结束、数量、关键分支打 `info`
|
|
883
|
+
- 异常路径打 `error`
|
|
884
|
+
- 日志至少带业务主键、批次标识或关键条件
|
|
885
|
+
|
|
886
|
+
### 6.13 `TimeUtil`
|
|
887
|
+
|
|
888
|
+
类定位:
|
|
889
|
+
|
|
890
|
+
- 多时区安全时间工具
|
|
891
|
+
|
|
892
|
+
官方说明重点:
|
|
893
|
+
|
|
894
|
+
- `Date` 和 `Calendar` 基于本地时区
|
|
895
|
+
- 跨时区场景下应优先通过 `TimeUtil` 获取当前时间、时区和格式化工具
|
|
896
|
+
|
|
897
|
+
#### `getNowDate`
|
|
898
|
+
|
|
899
|
+
官方示例写法:
|
|
900
|
+
|
|
901
|
+
```java
|
|
902
|
+
TpSysTask task = new TpSysTask();
|
|
903
|
+
task.setBeginTime(TimeUtil.getNowDate(userInfo));
|
|
466
904
|
```
|
|
467
905
|
|
|
468
|
-
|
|
906
|
+
参数说明:
|
|
907
|
+
|
|
908
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
909
|
+
| --- | --- | --- | --- |
|
|
910
|
+
| `userInfo` | `UserInfo` | 是 | 当前用户对象 |
|
|
911
|
+
|
|
912
|
+
返回:
|
|
913
|
+
|
|
914
|
+
- 当前用户时区下的当前时间
|
|
915
|
+
|
|
916
|
+
#### `getUserTimeZone`
|
|
469
917
|
|
|
918
|
+
方法签名式写法:
|
|
919
|
+
|
|
920
|
+
```java
|
|
921
|
+
TimeZone tz = TimeUtil.getUserTimeZone(userInfo);
|
|
470
922
|
```
|
|
471
|
-
✅ 推荐:
|
|
472
|
-
- 批量操作代替循环单条处理
|
|
473
|
-
- 使用分页查询避免内存溢出
|
|
474
|
-
- 异步处理非关键逻辑
|
|
475
923
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
924
|
+
参数说明:
|
|
925
|
+
|
|
926
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
927
|
+
| --- | --- | --- | --- |
|
|
928
|
+
| `userInfo` | `UserInfo` | 是 | 当前用户对象 |
|
|
929
|
+
|
|
930
|
+
返回:
|
|
931
|
+
|
|
932
|
+
- `TimeZone`
|
|
933
|
+
|
|
934
|
+
#### `getSimpleDateFormat`
|
|
935
|
+
|
|
936
|
+
官方示例写法:
|
|
937
|
+
|
|
938
|
+
```java
|
|
939
|
+
SimpleDateFormat myDateFormat =
|
|
940
|
+
TimeUtil.getSimpleDateFormat("yyyy-MM-dd", userInfo);
|
|
480
941
|
```
|
|
481
942
|
|
|
482
|
-
|
|
943
|
+
参数说明:
|
|
944
|
+
|
|
945
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
946
|
+
| --- | --- | --- | --- |
|
|
947
|
+
| `format` | `String` | 是 | 日期格式;官方默认示例为 `yyyy-MM-dd` |
|
|
948
|
+
| `userInfo` | `UserInfo` | 是 | 当前用户对象 |
|
|
949
|
+
|
|
950
|
+
返回:
|
|
951
|
+
|
|
952
|
+
- 已绑定用户时区的 `SimpleDateFormat`
|
|
953
|
+
|
|
954
|
+
#### `getCalendar`
|
|
483
955
|
|
|
956
|
+
官方示例写法:
|
|
957
|
+
|
|
958
|
+
```java
|
|
959
|
+
Calendar cal = Calendar.getInstance(TimeUtil.getUserTimeZone(userInfo));
|
|
960
|
+
// 或
|
|
961
|
+
Calendar cal2 = TimeUtil.getCalendar(userInfo);
|
|
484
962
|
```
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
-
|
|
963
|
+
|
|
964
|
+
返回:
|
|
965
|
+
|
|
966
|
+
- 带用户时区的 `Calendar`
|
|
967
|
+
|
|
968
|
+
AI 使用要求:
|
|
969
|
+
|
|
970
|
+
- 涉及比较、格式化、写入时间时,优先使用 `TimeUtil`
|
|
971
|
+
- 不要默认直接使用裸 `new Date()`、裸 `SimpleDateFormat`、裸 `Calendar`
|
|
972
|
+
|
|
973
|
+
### 6.14 项目常见批量写法:`insertLt` / `updateLt`
|
|
974
|
+
|
|
975
|
+
说明:
|
|
976
|
+
|
|
977
|
+
- 这两个方法在当前项目定时器和 `cloudcc doc timer devguide` 示例中非常常见
|
|
978
|
+
- 官方链接页未在本次抓取结果中展开它们的详细签名表
|
|
979
|
+
- 因此,AI 不能“脑补重载签名”,必须沿用仓库已有写法
|
|
980
|
+
|
|
981
|
+
当前项目与文档中已出现的典型用法:
|
|
982
|
+
|
|
983
|
+
```java
|
|
984
|
+
cs.insertLt(batch);
|
|
985
|
+
cs.updateLt(batch);
|
|
489
986
|
```
|
|
490
987
|
|
|
491
|
-
|
|
988
|
+
AI 使用要求:
|
|
492
989
|
|
|
493
|
-
|
|
990
|
+
- 只在已有项目先例清晰时使用
|
|
991
|
+
- 参数形态优先沿用本仓库同类定时器
|
|
992
|
+
- 如果需求需要新的批量调用方式,而仓库中没有先例,应先说明依据不足,不要编造 API
|
|
494
993
|
|
|
495
|
-
###
|
|
994
|
+
### 6.15 本节给 AI 的结论
|
|
496
995
|
|
|
497
|
-
|
|
996
|
+
AI 编写定时器时,对 SDK 的使用顺序应默认如下:
|
|
498
997
|
|
|
499
|
-
|
|
998
|
+
1. 用 `CCService` 作为主入口
|
|
999
|
+
2. 用 `CCObject` 承载新增/更新对象
|
|
1000
|
+
3. 简单查询优先 `cquery`
|
|
1001
|
+
4. 联表和聚合优先 `cqlQuery`
|
|
1002
|
+
5. 单条写入用 `insert` / `update` / `delete`
|
|
1003
|
+
6. 通知用 `SendEmail`
|
|
1004
|
+
7. 观测用 `DevLogger`
|
|
1005
|
+
8. 时间统一走 `TimeUtil`
|
|
1006
|
+
9. 配置优先走 `getListCustomSetting` / `getCustomSetting`
|
|
1007
|
+
10. 批量方法只复用项目已验证写法,不凭空猜
|
|
500
1008
|
|
|
501
|
-
|
|
1009
|
+
## 7. 当前项目的定时器代码风格要求
|
|
502
1010
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
1011
|
+
### 7.1 当前项目更偏向这几类任务
|
|
1012
|
+
|
|
1013
|
+
- 提醒催办
|
|
1014
|
+
- 数据同步
|
|
1015
|
+
- 数据刷新与修正
|
|
1016
|
+
- 报表底表构建
|
|
1017
|
+
- 自动生成下游对象
|
|
1018
|
+
- 权限治理
|
|
1019
|
+
|
|
1020
|
+
因此,AI 生成方案时应优先往这些成熟模式靠拢,而不是引入与现有仓库明显脱节的实现风格。
|
|
1021
|
+
|
|
1022
|
+
### 7.2 当前项目中常见模式
|
|
1023
|
+
|
|
1024
|
+
- 先查数据,再按条件处理
|
|
1025
|
+
- 按责任人聚合后通知
|
|
1026
|
+
- 批量更新字段、状态、台账、底表
|
|
1027
|
+
- 在满足条件时自动生成任务或派生对象
|
|
1028
|
+
- 对接口失败记录做补偿和邮件告警
|
|
506
1029
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
1030
|
+
### 7.3 当前项目中 AI 应优先保留的工程意识
|
|
1031
|
+
|
|
1032
|
+
- 业务逻辑尽量清晰直白
|
|
1033
|
+
- 关键分支有日志
|
|
1034
|
+
- 批量处理避免深层嵌套查询
|
|
1035
|
+
- 数据写回前先判断是否真的需要写
|
|
1036
|
+
- 可能重复执行的逻辑必须考虑去重或状态控制
|
|
1037
|
+
|
|
1038
|
+
## 8. AI 实现模板
|
|
1039
|
+
|
|
1040
|
+
下面是推荐给 AI 的定时器实现骨架。
|
|
1041
|
+
|
|
1042
|
+
```java
|
|
1043
|
+
package schedule.示例定时器;
|
|
1044
|
+
|
|
1045
|
+
import com.cloudcc.core.*;
|
|
1046
|
+
|
|
1047
|
+
public class 示例定时器 extends CCSchedule {
|
|
1048
|
+
public 示例定时器() {
|
|
1049
|
+
// @SOURCE_CONTENT_START
|
|
1050
|
+
CCService cs = new CCService(userInfo);
|
|
1051
|
+
DevLogger log = new DevLogger(userInfo);
|
|
1052
|
+
try {
|
|
1053
|
+
java.util.Date now = TimeUtil.getNowDate(userInfo);
|
|
1054
|
+
java.text.SimpleDateFormat sdf =
|
|
1055
|
+
TimeUtil.getSimpleDateFormat("yyyy-MM-dd HH:mm:ss", userInfo);
|
|
1056
|
+
|
|
1057
|
+
log.devLogInfo("示例定时器 start, now=" + sdf.format(now));
|
|
1058
|
+
|
|
1059
|
+
// 1. 查询目标数据
|
|
1060
|
+
// 2. 判断是否满足执行条件
|
|
1061
|
+
// 3. 批量生成/更新/通知
|
|
1062
|
+
// 4. 记录处理数量与结果
|
|
1063
|
+
|
|
1064
|
+
log.devLogInfo("示例定时器 finish");
|
|
1065
|
+
} catch (Exception e) {
|
|
1066
|
+
log.devLogError("示例定时器 error", e);
|
|
1067
|
+
throw new RuntimeException(e.getMessage(), e);
|
|
1068
|
+
}
|
|
1069
|
+
// @SOURCE_CONTENT_END
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
510
1072
|
```
|
|
511
1073
|
|
|
512
|
-
|
|
1074
|
+
AI 可以在此基础上扩展,但不得破坏以下结构:
|
|
513
1075
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
| 启用/禁用作业 | 修改作业状态(需管理权限) |
|
|
519
|
-
| 修改执行时间 | 编辑作业的 executetime 和 frequency |
|
|
520
|
-
| 延长有效期 | 更新 enddate 字段 |
|
|
521
|
-
| 创建新作业 | 使用 cloudcc-cli 创建定时类并配置调度 |
|
|
1076
|
+
- `package schedule.<类名>;`
|
|
1077
|
+
- `extends CCSchedule`
|
|
1078
|
+
- 构造方法同名
|
|
1079
|
+
- SOURCE 边界完整
|
|
522
1080
|
|
|
523
|
-
|
|
1081
|
+
## 9. AI 生成定时器类时的必填设计项
|
|
524
1082
|
|
|
525
|
-
|
|
1083
|
+
AI 在输出实现前,应先在思路中覆盖以下设计项。
|
|
526
1084
|
|
|
527
|
-
###
|
|
1085
|
+
### 9.1 业务定义
|
|
528
1086
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
2. 作业状态是否为激活?
|
|
532
|
-
3. 定时类代码是否有错误?
|
|
533
|
-
4. 系统日志是否有报错?
|
|
1087
|
+
- 这个定时器服务什么业务目标
|
|
1088
|
+
- 为什么它应该是定时器,而不是触发器
|
|
534
1089
|
|
|
535
|
-
###
|
|
1090
|
+
### 9.2 数据范围
|
|
536
1091
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
1092
|
+
- 主对象
|
|
1093
|
+
- 关联对象
|
|
1094
|
+
- 查询条件
|
|
1095
|
+
- 是否全量
|
|
1096
|
+
- 是否增量
|
|
1097
|
+
- 是否分页
|
|
542
1098
|
|
|
543
|
-
###
|
|
1099
|
+
### 9.3 执行动作
|
|
544
1100
|
|
|
545
|
-
|
|
1101
|
+
- 是提醒、同步、修正、汇总、生成,还是权限治理
|
|
1102
|
+
- 动作顺序是什么
|
|
1103
|
+
- 失败后是否继续处理后续数据
|
|
546
1104
|
|
|
547
|
-
###
|
|
1105
|
+
### 9.4 幂等设计
|
|
548
1106
|
|
|
549
|
-
|
|
1107
|
+
- 如何防止重复新增
|
|
1108
|
+
- 如何防止重复通知
|
|
1109
|
+
- 如何防止重复推进状态
|
|
550
1110
|
|
|
551
|
-
|
|
1111
|
+
### 9.5 性能设计
|
|
1112
|
+
|
|
1113
|
+
- 是否存在循环内查询
|
|
1114
|
+
- 是否存在大量单条写入
|
|
1115
|
+
- 是否需要分批提交
|
|
1116
|
+
|
|
1117
|
+
### 9.6 观测与异常
|
|
1118
|
+
|
|
1119
|
+
- 哪些日志必须打
|
|
1120
|
+
- 哪些异常要抛出
|
|
1121
|
+
- 哪些异常要告警
|
|
1122
|
+
|
|
1123
|
+
### 9.7 配置化设计
|
|
1124
|
+
|
|
1125
|
+
- 阈值是否应该来自自定义设置
|
|
1126
|
+
- 邮件模版、收件人、开关是否应该配置化
|
|
1127
|
+
|
|
1128
|
+
## 10. AI 禁止事项
|
|
1129
|
+
|
|
1130
|
+
以下是 AI 在当前项目中编写定时器类时应明确避免的行为。
|
|
1131
|
+
|
|
1132
|
+
- 不要手工创建 `schedule/<name>/` 目录
|
|
1133
|
+
- 不要修改 `config.json` 的 `id`、版本字段
|
|
1134
|
+
- 不要在 SOURCE 区域之外写业务代码
|
|
1135
|
+
- 不要把明显实时场景错误地写成定时器
|
|
1136
|
+
- 不要在大循环里频繁嵌套查询,造成 N+1 问题
|
|
1137
|
+
- 不要在大批量处理中逐条单次写入而不考虑 `insertLt` / `updateLt`
|
|
1138
|
+
- 不要默认使用 `new Date()`、裸 `Calendar`、裸 `SimpleDateFormat` 处理业务时间
|
|
1139
|
+
- 不要吞掉异常而不打日志
|
|
1140
|
+
- 不要默认把邮箱、模版 ID、阈值、组织 ID 全部硬编码
|
|
1141
|
+
- 不要在没有明确理由时用 SQL 风格语句替代官方 CRUD
|
|
1142
|
+
- 不要无条件全表扫描并直接修改全量数据
|
|
1143
|
+
- 不要让定时器重复执行后反复创建相同记录、任务或邮件
|
|
1144
|
+
|
|
1145
|
+
## 11. AI 输出结果要求
|
|
1146
|
+
|
|
1147
|
+
AI 在完成定时器类开发时,输出说明至少应包含:
|
|
1148
|
+
|
|
1149
|
+
- 为什么选择定时器类
|
|
1150
|
+
- 主对象与处理范围
|
|
1151
|
+
- 执行条件
|
|
1152
|
+
- 核心动作
|
|
1153
|
+
- 幂等策略
|
|
1154
|
+
- 批量策略
|
|
1155
|
+
- 日志与异常策略
|
|
1156
|
+
- 是否使用通知
|
|
1157
|
+
- 是否使用配置化
|
|
1158
|
+
|
|
1159
|
+
如果未能做到其中某一项,AI 应显式说明原因,而不是默认省略。
|
|
1160
|
+
|
|
1161
|
+
## 12. 推荐给 AI 的任务描述模板
|
|
1162
|
+
|
|
1163
|
+
下面这个模板适合作为给 AI 下达定时器开发任务时的标准输入。
|
|
1164
|
+
|
|
1165
|
+
```text
|
|
1166
|
+
请为 CloudCC 编写一个定时器类,要求如下:
|
|
1167
|
+
|
|
1168
|
+
1. 定时器名称:
|
|
1169
|
+
2. 业务目标:
|
|
1170
|
+
3. 为什么需要定时执行:
|
|
1171
|
+
4. 主对象与关联对象:
|
|
1172
|
+
5. 查询范围(全量/增量/按日期/按状态):
|
|
1173
|
+
6. 满足什么条件后执行:
|
|
1174
|
+
7. 执行动作(提醒/同步/更新/生成/汇总/权限处理):
|
|
1175
|
+
8. 是否需要邮件或任务:
|
|
1176
|
+
9. 是否需要读取自定义设置:
|
|
1177
|
+
10. 幂等要求:
|
|
1178
|
+
11. 批量要求:
|
|
1179
|
+
12. 异常和日志要求:
|
|
1180
|
+
|
|
1181
|
+
请按当前项目的 CloudCC 定时器规范实现,并只在 SOURCE_CONTENT 区域内编写业务代码。
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
## 13. 最终结论
|
|
1185
|
+
|
|
1186
|
+
对 AI 而言,CloudCC 定时器类不是“会写 Java 就能写”,而是要同时满足三层约束:
|
|
552
1187
|
|
|
1188
|
+
- 第一层:必须符合 CloudCC 官方 SDK 的能力边界和推荐用法
|
|
1189
|
+
- 第二层:必须符合 `cloudcc-cli` 的目录、发布和 SOURCE 区域约束
|
|
1190
|
+
- 第三层:必须符合当前项目中定时器类的主流业务模式和工程风格
|
|
553
1191
|
|
|
554
|
-
|
|
1192
|
+
只有同时满足这三层要求,AI 生成的定时器类才能真正可落地、可维护、可发布。
|