cloudcc-cli 2.2.1 → 2.2.3

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 (43) hide show
  1. package/README.md +21 -0
  2. package/bin/cc.js +1 -0
  3. package/bin/mcp.js +18 -0
  4. package/package.json +14 -6
  5. package/src/classes/create.js +1 -0
  6. package/src/classes/get.js +1 -0
  7. package/src/classes/publish.js +4 -0
  8. package/src/classes/pull.js +5 -1
  9. package/src/mcp/index.js +227 -0
  10. package/src/mcp/readme.md +132 -0
  11. package/src/mcp/tools/ccdk/fetcher.js +18 -0
  12. package/src/mcp/tools/ccdk/handler.js +98 -0
  13. package/src/mcp/tools/ccdk/prompt.js +453 -0
  14. package/src/mcp/tools/classes/handler.js +358 -0
  15. package/src/mcp/tools/classes/prompt.js +1261 -0
  16. package/src/mcp/tools/dev-env/fetcher.js +500 -0
  17. package/src/mcp/tools/dev-env/handler.js +92 -0
  18. package/src/mcp/tools/dev-env/prompt.js +256 -0
  19. package/src/mcp/tools/key-guide/fetcher.js +278 -0
  20. package/src/mcp/tools/key-guide/handler.js +43 -0
  21. package/src/mcp/tools/key-guide/prompt.js +71 -0
  22. package/src/mcp/tools/plugin/handler.js +92 -0
  23. package/src/mcp/tools/plugin/prompt.js +659 -0
  24. package/src/plugin/create.js +1 -2
  25. package/src/plugin/create1.js +1 -2
  26. package/src/plugin/publish.js +3 -0
  27. package/src/plugin/publish1.js +6 -2
  28. package/src/script/publish.js +3 -0
  29. package/src/script/pull.js +3 -0
  30. package/src/timer/publish.js +3 -0
  31. package/src/timer/pull.js +3 -0
  32. package/src/triggers/publish.js +3 -0
  33. package/src/triggers/pull.js +3 -0
  34. package/template/Appvue +452 -12
  35. package/template/cloudcc-cli.configjs +7 -1
  36. package/template/index.js +0 -4
  37. package/template/vueconfigjs +10 -10
  38. package/utils/checkVersion.js +2 -0
  39. package/utils/utils.js +32 -9
  40. package/template/demojava +0 -15
  41. package/template/indexvue +0 -29
  42. package/template/javaconfigjson +0 -3
  43. package/template/package-lockjson +0 -13952
@@ -0,0 +1,1261 @@
1
+ /**
2
+ * Classes 工具知识库
3
+ * 提供 Java 类模板、配置结构、API 文档和错误信息
4
+ */
5
+
6
+ /**
7
+ * Java 类模板示例
8
+ */
9
+ const javaClassTemplate = {
10
+ name: 'Java自定义类模板',
11
+ description: 'CloudCC 自定义类的标准结构,包含源码标记和基础依赖',
12
+ example: `package classes.{ClassName};
13
+
14
+ import com.cloudcc.core.*;
15
+ // @SOURCE_CONTENT_START
16
+ public class {ClassName}{
17
+ private UserInfo userInfo;
18
+ private CCService cs;
19
+
20
+ public {ClassName}(UserInfo userInfo){
21
+ this(userInfo,new CCService(userInfo));
22
+ }
23
+ public {ClassName}(UserInfo userInfo,CCService cs){
24
+ this.userInfo = userInfo;
25
+ this.cs=cs;
26
+ }
27
+
28
+ public String getName(String str){
29
+ str = "demo";
30
+ return str;
31
+ }
32
+ }
33
+ // @SOURCE_CONTENT_END`,
34
+ notes: [
35
+ '源码标记 @SOURCE_CONTENT_START 和 @SOURCE_CONTENT_END 用于标识可编辑区域',
36
+ '发布时只会上传标记之间的内容到服务器',
37
+ '从服务器拉取时会替换标记之间的内容',
38
+ 'UserInfo 和 CCService 是 CloudCC 提供的核心服务类'
39
+ ]
40
+ };
41
+
42
+ /**
43
+ * config.json 配置文件结构
44
+ */
45
+ const configStructure = {
46
+ name: 'config.json配置结构',
47
+ description: '每个自定义类目录下的配置文件',
48
+ fields: {
49
+ name: {
50
+ type: 'string',
51
+ required: true,
52
+ description: '类名,必须与文件名和package中的类名一致'
53
+ },
54
+ version: {
55
+ type: 'string',
56
+ required: true,
57
+ description: '版本号,通常为 "2"',
58
+ default: '2'
59
+ },
60
+ id: {
61
+ type: 'string',
62
+ required: false,
63
+ description: '类的服务器ID,首次发布后自动生成并保存'
64
+ }
65
+ },
66
+ example: {
67
+ name: 'MyClass',
68
+ version: '2',
69
+ id: 'abc123def456'
70
+ }
71
+ };
72
+
73
+ /**
74
+ * CCService 常用 API 文档
75
+ */
76
+ const ccServiceApis = {
77
+ name: 'CCService API',
78
+ description: 'CloudCC 核心服务类,提供数据操作和业务逻辑功能',
79
+ apis: {
80
+ query: {
81
+ description: '查询对象数据',
82
+ signature: 'List<Map<String, Object>> query(String objectApiName, String fields, String condition)',
83
+ example: 'List<Map<String, Object>> accounts = cs.query("account", "id,name,email", "name like \'%公司%\'");'
84
+ },
85
+ save: {
86
+ description: '保存或更新对象数据',
87
+ signature: 'String save(String objectApiName, Map<String, Object> data)',
88
+ example: 'Map<String, Object> data = new HashMap<>();\ndata.put("name", "测试账户");\nString id = cs.save("account", data);'
89
+ },
90
+ delete: {
91
+ description: '删除对象数据',
92
+ signature: 'boolean delete(String objectApiName, String id)',
93
+ example: 'boolean result = cs.delete("account", "accountId123");'
94
+ },
95
+ executeFunction: {
96
+ description: '执行服务器端函数',
97
+ signature: 'Object executeFunction(String functionName, Object... params)',
98
+ example: 'Object result = cs.executeFunction("myFunction", param1, param2);'
99
+ }
100
+ }
101
+ };
102
+
103
+ /**
104
+ * UserInfo 常用属性文档
105
+ */
106
+ const userInfoDocs = {
107
+ name: 'UserInfo API',
108
+ description: 'CloudCC 用户信息类,包含当前用户和组织信息',
109
+ properties: {
110
+ userId: {
111
+ type: 'String',
112
+ description: '当前用户ID'
113
+ },
114
+ userName: {
115
+ type: 'String',
116
+ description: '当前用户名称'
117
+ },
118
+ accountId: {
119
+ type: 'String',
120
+ description: '当前用户所属账户ID'
121
+ },
122
+ organizationId: {
123
+ type: 'String',
124
+ description: '组织ID'
125
+ }
126
+ },
127
+ example: 'String currentUserId = userInfo.getUserId();'
128
+ };
129
+
130
+ /**
131
+ * 错误信息映射表
132
+ */
133
+ const errorMessages = {
134
+ 'CLASS_ID_NOT_EXIST': {
135
+ message: 'Class ID 不存在,请先发布类到服务器',
136
+ solution: '使用 publish_class 工具先发布该类,系统会自动生成并保存 ID 到 config.json'
137
+ },
138
+ 'CLASS_NOT_FOUND': {
139
+ message: '本地找不到该类文件',
140
+ solution: '确认类名正确,或使用 create_class 工具创建新类'
141
+ },
142
+ 'CONFIG_NOT_FOUND': {
143
+ message: 'config.json 配置文件不存在',
144
+ solution: '类目录下必须包含 config.json 文件,可能需要重新创建该类'
145
+ },
146
+ 'INVALID_CLASS_NAME': {
147
+ message: '类名不符合 Java 命名规范',
148
+ solution: '类名必须以字母开头,只能包含字母、数字和下划线'
149
+ },
150
+ 'PROJECT_CONFIG_ERROR': {
151
+ message: '无法读取项目配置',
152
+ solution: '确保在 CloudCC 项目根目录下执行,且存在 cloudcc-cli.config.js 或 package.json 配置文件'
153
+ },
154
+ 'NETWORK_ERROR': {
155
+ message: 'API 调用失败',
156
+ solution: '检查网络连接和 accessToken 配置是否正确'
157
+ },
158
+ 'PUBLISH_FAILED': {
159
+ message: '发布类到服务器失败',
160
+ solution: '检查 accessToken 和 setupSvc 配置是否正确,确认网络连接正常'
161
+ },
162
+ 'PULL_FAILED': {
163
+ message: '从服务器拉取类失败',
164
+ solution: '确认类 ID 存在且有权限访问,检查 accessToken 配置'
165
+ }
166
+ };
167
+
168
+ /**
169
+ * 常见问题和解决方案
170
+ */
171
+ const faq = [
172
+ {
173
+ question: '如何创建一个新的自定义类?',
174
+ answer: '使用 create_class 工具,提供类名参数。系统会在 classes/{ClassName}/ 目录下生成三个文件:主类文件、测试类文件和 config.json'
175
+ },
176
+ {
177
+ question: '如何发布类到服务器?',
178
+ answer: '使用 publish_class 工具,提供类名。首次发布会自动保存服务器返回的 ID 到 config.json'
179
+ },
180
+ {
181
+ question: '如何同步服务器上的最新代码?',
182
+ answer: '使用 pull_class 工具,提供类名。系统会用服务器上的最新代码替换 @SOURCE_CONTENT_START 和 @SOURCE_CONTENT_END 之间的内容'
183
+ },
184
+ {
185
+ question: '如何批量下载多个类?',
186
+ answer: '使用 pull_multiple_classes 工具,提供类 ID 数组。系统会为每个类创建完整的目录结构'
187
+ },
188
+ {
189
+ question: '@SOURCE_CONTENT_START 标记有什么用?',
190
+ answer: '这些标记定义了可编辑的源码区域。发布时只上传标记之间的内容,拉取时也只替换这部分内容,保持包声明和导入语句不变'
191
+ }
192
+ ];
193
+
194
+ /**
195
+ * 工具使用指南
196
+ */
197
+ const usageGuide = {
198
+ workflow: [
199
+ '1. 使用 create_class 创建新类',
200
+ '2. 在生成的 .java 文件中编写业务逻辑(在 @SOURCE_CONTENT_START 标记之间)',
201
+ '3. 使用 publish_class 发布到服务器',
202
+ '4. 在服务器上测试和验证',
203
+ '5. 如需修改,本地编辑后重新发布',
204
+ '6. 如需同步服务器上的修改,使用 pull_class'
205
+ ],
206
+ bestPractices: [
207
+ '保持类名与文件名一致',
208
+ '不要手动修改 config.json 中的 id 字段',
209
+ '使用版本控制(Git)管理源码',
210
+ '定期备份重要的类文件',
211
+ '测试类(*Test.java)用于本地调试'
212
+ ]
213
+ };
214
+
215
+ /**
216
+ * EditClass 工具知识库 - 编辑类时需要的核心 API 文档
217
+ */
218
+
219
+ /**
220
+ * 从 CCService 提取 API 文档
221
+ */
222
+ function extractCCServiceApis() {
223
+ return {
224
+ name: 'CCService 数据操作 API',
225
+ description: '核心服务类,用于数据增删改查和业务逻辑操作',
226
+ apis: {
227
+ // 查询方法
228
+ cquery: {
229
+ description: '无条件查询所有数据',
230
+ signature: 'List<CCObject> cquery(String apiName)',
231
+ example: 'List<CCObject> accounts = cs.cquery("account");',
232
+ returns: 'CCObject 列表'
233
+ },
234
+ cqueryWithCondition: {
235
+ description: '条件查询数据',
236
+ signature: 'List<CCObject> cquery(String apiName, String expression)',
237
+ example: 'List<CCObject> result = cs.cquery("account", "name like \'%销售%\'");',
238
+ returns: 'CCObject 列表',
239
+ params: [
240
+ { name: 'apiName', type: 'String', desc: '对象 API 名称,如 account, contact 等' },
241
+ { name: 'expression', type: 'String', desc: '查询条件,支持 like, =, >, <, >= <= 等操作符' }
242
+ ]
243
+ },
244
+ cqlQuery: {
245
+ description: 'CQL 条件查询(推荐)',
246
+ signature: 'List<CCObject> cqlQuery(String apiName, String expression)',
247
+ example: 'List<CCObject> result = cs.cqlQuery("account", "status = \'active\'");',
248
+ returns: 'CCObject 列表',
249
+ note: '性能比 cquery 更优,推荐使用'
250
+ },
251
+
252
+ // 插入方法
253
+ insert: {
254
+ description: '新增单条记录',
255
+ signature: 'ServiceResult insert(CCObject cobj)',
256
+ example: `CCObject obj = new CCObject("account");
257
+ obj.put("name", "新客户");
258
+ obj.put("type", "1");
259
+ ServiceResult sr = cs.insert(obj);
260
+ String id = sr.get("id"); // 获取新增记录的 ID`,
261
+ returns: 'ServiceResult 包含新增记录的 ID'
262
+ },
263
+ insertBatch: {
264
+ description: '批量新增记录',
265
+ signature: 'ServiceResult insert(List<CCObject> datalist)',
266
+ example: `List<CCObject> list = new ArrayList<>();
267
+ for(int i=0; i<3; i++) {
268
+ CCObject obj = new CCObject("account");
269
+ obj.put("name", "客户"+i);
270
+ list.add(obj);
271
+ }
272
+ ServiceResult sr = cs.insert(list);`,
273
+ returns: 'ServiceResult 包含所有新增记录的 ID'
274
+ },
275
+
276
+ // 更新方法
277
+ update: {
278
+ description: '更新单条记录',
279
+ signature: 'void update(CCObject cobj)',
280
+ example: `CCObject obj = new CCObject("account");
281
+ obj.put("id", "existingId");
282
+ obj.put("name", "更新的名称");
283
+ cs.update(obj);`,
284
+ note: 'CCObject 必须包含 id 字段用于标识更新的记录'
285
+ },
286
+
287
+ // 删除方法
288
+ delete: {
289
+ description: '删除记录',
290
+ signature: 'void delete(CCObject cobj)',
291
+ example: `CCObject obj = new CCObject("account");
292
+ obj.put("id", "recordId");
293
+ cs.delete(obj);`
294
+ },
295
+
296
+ // Upsert 方法
297
+ upsert: {
298
+ description: '新增或更新记录(有 id 则更新,无则新增)',
299
+ signature: 'ServiceResult upsert(CCObject cobj)',
300
+ example: `CCObject obj = new CCObject("account");
301
+ obj.put("id", "existingId"); // 存在则更新,不存在则新增
302
+ obj.put("name", "账户名称");
303
+ ServiceResult sr = cs.upsert(obj);`,
304
+ returns: 'ServiceResult 包含记录的 ID'
305
+ },
306
+
307
+ // 邮件方法
308
+ sendEmail: {
309
+ description: '发送邮件',
310
+ signature: 'String sendEmail(String subject, String htmlBody, String toAddress, String relatedid, String ccaddress, String bccaddress, String attachmentId, String s, String s1)',
311
+ example: 'cs.sendEmail("邮件主题", "<h1>邮件内容</h1>", "user@example.com", "", "", "", "", "", "");',
312
+ note: '该方法支持 HTML 格式的邮件内容'
313
+ }
314
+ },
315
+ bestPractices: [
316
+ '查询时优先使用 cqlQuery,性能更优',
317
+ '批量操作使用 insertBatch 而非循环调用 insert',
318
+ '修改数据前建议先查询验证数据存在',
319
+ '操作后检查 ServiceResult 的返回值确保成功',
320
+ '大量数据操作建议分批处理以避免超时'
321
+ ]
322
+ };
323
+ }
324
+
325
+ /**
326
+ * 从 CCObject 提取对象操作文档
327
+ */
328
+ function extractCCObjectDocs() {
329
+ return {
330
+ name: 'CCObject 对象操作',
331
+ description: 'CloudCC 数据对象,继承自 HashMap<String, Object>,用于存储和传递业务数据。是所有数据操作的核心载体',
332
+
333
+ // 核心常量
334
+ constants: {
335
+ OBJECT_API: {
336
+ value: 'CCObjectAPI',
337
+ desc: '对象 API 名称的键常量,用于标识对象类型',
338
+ usage: 'obj.put(CCObject.OBJECT_API, "account");'
339
+ },
340
+ IS_SHARED: {
341
+ value: 'isShared',
342
+ desc: '对象共享状态的键常量',
343
+ usage: 'obj.put(CCObject.IS_SHARED, "true");'
344
+ },
345
+ SUM: {
346
+ value: 'sum',
347
+ desc: '汇总字段的键前缀常量',
348
+ usage: 'obj.putSumValue("amount", "10000"); // 存储为 "sumamount"'
349
+ }
350
+ },
351
+
352
+ // 构造方法
353
+ constructors: [
354
+ {
355
+ signature: 'CCObject()',
356
+ desc: '创建空的 CCObject 对象',
357
+ example: `CCObject obj = new CCObject();
358
+ obj.put("CCObjectAPI", "account"); // 需手动指定对象类型`,
359
+ usage: '适用于动态确定对象类型的场景'
360
+ },
361
+ {
362
+ signature: 'CCObject(String ccobj)',
363
+ desc: '创建指定对象类型的 CCObject',
364
+ example: `CCObject account = new CCObject("account");
365
+ CCObject contact = new CCObject("contact");
366
+ CCObject opportunity = new CCObject("opportunity");`,
367
+ usage: '最常用的构造方式,自动设置 CCObjectAPI 字段',
368
+ recommended: true
369
+ },
370
+ {
371
+ signature: 'CCObject(String ccobj, String isShared)',
372
+ desc: '创建带共享状态的 CCObject',
373
+ example: `CCObject obj = new CCObject("account", "true");
374
+ // 等同于:
375
+ // CCObject obj = new CCObject("account");
376
+ // obj.put("isShared", "true");`,
377
+ usage: '创建需要共享的对象时使用',
378
+ note: '第二个参数会被存储为 "isShared" 字段值'
379
+ }
380
+ ],
381
+
382
+ // 核心方法
383
+ methods: {
384
+ dataAccess: {
385
+ title: '数据存取方法(继承自 HashMap)',
386
+ items: [
387
+ {
388
+ name: 'put(String key, Object value)',
389
+ desc: '设置字段值,key 为字段 API 名称',
390
+ returns: 'Object - 旧值或 null',
391
+ example: `obj.put("name", "销售部");
392
+ obj.put("type", "1");
393
+ obj.put("amount", 50000);
394
+ obj.put("status", "active");
395
+ obj.put("id", "recordId123"); // 更新时必须设置 id`
396
+ },
397
+ {
398
+ name: 'get(String key)',
399
+ desc: '获取字段值,返回 Object 需要类型转换',
400
+ returns: 'Object - 字段值或 null',
401
+ example: `String name = (String) obj.get("name");
402
+ Integer amount = (Integer) obj.get("amount");
403
+ String id = (String) obj.get("id");
404
+
405
+ // 安全获取,避免空指针
406
+ Object value = obj.get("field");
407
+ if (value != null) {
408
+ String strValue = value.toString();
409
+ }`
410
+ },
411
+ {
412
+ name: 'containsKey(String key)',
413
+ desc: '检查是否包含指定字段',
414
+ returns: 'boolean',
415
+ example: `if (obj.containsKey("id")) {
416
+ // 更新操作
417
+ cs.update(obj);
418
+ } else {
419
+ // 新增操作
420
+ cs.insert(obj);
421
+ }`
422
+ },
423
+ {
424
+ name: 'remove(String key)',
425
+ desc: '移除指定字段',
426
+ returns: 'Object - 被移除的值',
427
+ example: `obj.remove("tempField"); // 清理临时字段`
428
+ },
429
+ {
430
+ name: 'keySet()',
431
+ desc: '获取所有字段名集合',
432
+ returns: 'Set<String>',
433
+ example: `for (String key : obj.keySet()) {
434
+ Object value = obj.get(key);
435
+ DevLogger.devLogInfo(key + " = " + value);
436
+ }`
437
+ }
438
+ ]
439
+ },
440
+
441
+ specificMethods: {
442
+ title: 'CCObject 特有方法',
443
+ items: [
444
+ {
445
+ name: 'getObjectApiName()',
446
+ desc: '获取对象的 API 名称(即对象类型)',
447
+ returns: 'String - 对象 API 名称',
448
+ example: `CCObject obj = new CCObject("account");
449
+ String apiName = obj.getObjectApiName(); // 返回 "account"
450
+
451
+ // 用于判断对象类型
452
+ if ("account".equals(obj.getObjectApiName())) {
453
+ // 处理客户对象
454
+ }`
455
+ },
456
+ {
457
+ name: 'putSumValue(String sumValueKey, String value)',
458
+ desc: '存储汇总字段值,会自动添加 "sum" 前缀',
459
+ returns: 'void',
460
+ example: `obj.putSumValue("amount", "10000");
461
+ // 实际存储的 key 是 "sumamount"
462
+
463
+ obj.putSumValue("quantity", "100");
464
+ // 实际存储的 key 是 "sumquantity"`
465
+ },
466
+ {
467
+ name: 'getSumValue(String sumValueKey)',
468
+ desc: '获取汇总字段值',
469
+ returns: 'Object - 汇总值',
470
+ example: `Object total = obj.getSumValue("amount");
471
+ // 实际获取的是 "sumamount" 字段的值
472
+
473
+ String totalStr = (String) obj.getSumValue("amount");
474
+ DevLogger.devLogInfo("总金额: " + totalStr);`
475
+ }
476
+ ]
477
+ }
478
+ },
479
+
480
+ // 最佳实践
481
+ bestPractices: {
482
+ creation: [
483
+ '推荐使用 new CCObject("objectApi") 构造方法,自动设置对象类型',
484
+ '对象类型使用小写字母和下划线,如 account, custom_object',
485
+ '创建后立即设置必填字段,避免后续遗漏'
486
+ ],
487
+ dataManipulation: [
488
+ '获取字段值时进行类型转换和 null 检查',
489
+ '使用 containsKey() 判断字段是否存在',
490
+ '更新操作必须包含 id 字段',
491
+ '日期时间字段使用标准格式(yyyy-MM-dd HH:mm:ss)'
492
+ ],
493
+ withCCService: [
494
+ '新增前确保 CCObjectAPI 已设置',
495
+ '更新前先查询获取完整数据,避免覆盖其他字段',
496
+ '批量操作使用 List<CCObject> 提升性能',
497
+ '操作后检查返回的 ServiceResult'
498
+ ]
499
+ },
500
+
501
+ // 常见使用场景
502
+ usageExamples: [
503
+ {
504
+ scenario: '创建新记录',
505
+ code: `CCObject account = new CCObject("account");
506
+ account.put("name", "新客户公司");
507
+ account.put("type", "1"); // 客户类型
508
+ account.put("industry", "制造业");
509
+ account.put("status", "active");
510
+ account.put("owner", userInfo.getUserId());
511
+
512
+ ServiceResult result = cs.insert(account);
513
+ String newId = (String) result.get("id");
514
+ DevLogger.devLogInfo("新增成功,ID: " + newId);`
515
+ },
516
+ {
517
+ scenario: '更新现有记录',
518
+ code: `// 先查询获取完整数据
519
+ List<CCObject> list = cs.cquery("account", "id = 'accountId123'");
520
+ if (list.size() > 0) {
521
+ CCObject account = list.get(0);
522
+ account.put("name", "更新后的名称");
523
+ account.put("status", "inactive");
524
+ cs.update(account);
525
+ DevLogger.devLogInfo("更新成功");
526
+ }`
527
+ },
528
+ {
529
+ scenario: '批量创建记录',
530
+ code: `List<CCObject> contacts = new ArrayList<>();
531
+ for (int i = 0; i < 10; i++) {
532
+ CCObject contact = new CCObject("contact");
533
+ contact.put("name", "联系人" + i);
534
+ contact.put("email", "contact" + i + "@example.com");
535
+ contact.put("account", accountId); // 关联到客户
536
+ contacts.add(contact);
537
+ }
538
+
539
+ ServiceResult result = cs.insert(contacts);
540
+ DevLogger.devLogInfo("批量新增完成");`
541
+ },
542
+ {
543
+ scenario: '使用汇总字段',
544
+ code: `CCObject opportunity = new CCObject("opportunity");
545
+ opportunity.put("name", "大客户项目");
546
+ opportunity.put("stage", "商务谈判");
547
+ opportunity.put("amount", 500000);
548
+
549
+ // 设置汇总字段
550
+ opportunity.putSumValue("totalAmount", "500000");
551
+ opportunity.putSumValue("productCount", "3");
552
+
553
+ ServiceResult result = cs.insert(opportunity);
554
+
555
+ // 读取汇总字段
556
+ String total = (String) opportunity.getSumValue("totalAmount");
557
+ DevLogger.devLogInfo("总金额: " + total);`
558
+ },
559
+ {
560
+ scenario: '动态字段处理',
561
+ code: `CCObject obj = new CCObject("custom_object");
562
+
563
+ // 遍历所有字段
564
+ for (String key : obj.keySet()) {
565
+ Object value = obj.get(key);
566
+ if (value != null && !value.toString().isEmpty()) {
567
+ DevLogger.devLogInfo(key + ": " + value);
568
+ }
569
+ }
570
+
571
+ // 条件设置字段
572
+ if (obj.containsKey("status")) {
573
+ obj.put("lastModified", new Date());
574
+ }
575
+
576
+ // 清理空字段
577
+ List<String> keysToRemove = new ArrayList<>();
578
+ for (String key : obj.keySet()) {
579
+ if (obj.get(key) == null) {
580
+ keysToRemove.add(key);
581
+ }
582
+ }
583
+ for (String key : keysToRemove) {
584
+ obj.remove(key);
585
+ }`
586
+ }
587
+ ],
588
+
589
+ // 常见对象类型及其字段
590
+ commonObjects: [
591
+ {
592
+ name: 'account',
593
+ label: '客户/账户',
594
+ commonFields: [
595
+ 'id - 记录ID',
596
+ 'name - 客户名称',
597
+ 'type - 客户类型',
598
+ 'industry - 行业',
599
+ 'status - 状态',
600
+ 'owner - 负责人',
601
+ 'email - 邮箱',
602
+ 'phone - 电话',
603
+ 'website - 网站',
604
+ 'description - 描述'
605
+ ]
606
+ },
607
+ {
608
+ name: 'contact',
609
+ label: '联系人',
610
+ commonFields: [
611
+ 'id - 记录ID',
612
+ 'name - 姓名',
613
+ 'account - 所属客户',
614
+ 'email - 邮箱',
615
+ 'phone - 电话',
616
+ 'mobile - 手机',
617
+ 'title - 职位',
618
+ 'department - 部门'
619
+ ]
620
+ },
621
+ {
622
+ name: 'opportunity',
623
+ label: '商机',
624
+ commonFields: [
625
+ 'id - 记录ID',
626
+ 'name - 商机名称',
627
+ 'account - 客户',
628
+ 'stage - 阶段',
629
+ 'amount - 金额',
630
+ 'closeDate - 预计成交日期',
631
+ 'probability - 赢率',
632
+ 'owner - 负责人'
633
+ ]
634
+ },
635
+ {
636
+ name: 'task',
637
+ label: '任务',
638
+ commonFields: [
639
+ 'id - 记录ID',
640
+ 'subject - 主题',
641
+ 'status - 状态',
642
+ 'priority - 优先级',
643
+ 'owner - 负责人',
644
+ 'dueDate - 截止日期',
645
+ 'relatedTo - 相关对象',
646
+ 'description - 描述'
647
+ ]
648
+ }
649
+ ],
650
+
651
+ // 注意事项
652
+ notes: [
653
+ 'CCObject 继承自 HashMap,拥有 HashMap 的所有方法',
654
+ '字段名使用对象的 API 名称,非标签名称',
655
+ 'get() 方法返回 Object 类型,需要进行类型转换',
656
+ '汇总字段会自动添加 "sum" 前缀',
657
+ '与 CCService 配合使用完成数据的增删改查',
658
+ '更新操作必须包含 id 字段标识记录',
659
+ '建议对字段值进行 null 检查,避免空指针异常'
660
+ ]
661
+ };
662
+ }
663
+
664
+ /**
665
+ * 从 SendEmail 提取邮件发送文档
666
+ */
667
+ function extractSendEmailDocs() {
668
+ return {
669
+ name: 'SendEmail 邮件服务',
670
+ description: '用于发送系统邮件和模板邮件',
671
+ methods: {
672
+ sendMailFromSystem: {
673
+ description: '发送自定义内容邮件',
674
+ signature: 'ServiceResult sendMailFromSystem(String[] toAddress, String[] ccAddress, String bccAddress, String subject, String content, boolean isText)',
675
+ example: `SendEmail sender = new SendEmail(userInfo);
676
+ String[] toAddress = {"recipient@example.com"};
677
+ String[] ccAddress = {"cc@example.com"};
678
+ ServiceResult result = sender.sendMailFromSystem(
679
+ toAddress,
680
+ ccAddress,
681
+ "bcc@example.com",
682
+ "邮件主题",
683
+ "<h1>邮件正文</h1>",
684
+ false // 非纯文本,支持 HTML
685
+ );`,
686
+ params: [
687
+ { name: 'toAddress', type: 'String[]', desc: '收件人邮箱数组' },
688
+ { name: 'ccAddress', type: 'String[]', desc: '抄送人邮箱数组' },
689
+ { name: 'bccAddress', type: 'String', desc: '密送人邮箱' },
690
+ { name: 'subject', type: 'String', desc: '邮件主题' },
691
+ { name: 'content', type: 'String', desc: '邮件内容,支持 HTML' },
692
+ { name: 'isText', type: 'boolean', desc: '是否纯文本,false 表示支持 HTML' }
693
+ ]
694
+ },
695
+ sendEmailNew: {
696
+ description: '使用模板发送邮件',
697
+ signature: 'ServiceResult sendEmailNew(String templateId, String[] toAddress, String[] ccAddress, String bccAddress, String recordId)',
698
+ example: `SendEmail sender = new SendEmail(userInfo);
699
+ ServiceResult result = sender.sendEmailNew(
700
+ "templateId123",
701
+ new String[]{"user@example.com"},
702
+ new String[]{"cc@example.com"},
703
+ "bcc@example.com",
704
+ "recordId456" // 关联的业务记录 ID
705
+ );`,
706
+ params: [
707
+ { name: 'templateId', type: 'String', desc: '邮件模板 ID' },
708
+ { name: 'toAddress', type: 'String[]', desc: '收件人邮箱数组' },
709
+ { name: 'ccAddress', type: 'String[]', desc: '抄送人邮箱数组' },
710
+ { name: 'bccAddress', type: 'String', desc: '密送人邮箱' },
711
+ { name: 'recordId', type: 'String', desc: '关联的业务记录 ID,用于邮件中获取相关数据' }
712
+ ]
713
+ }
714
+ }
715
+ };
716
+ }
717
+
718
+ /**
719
+ * 从 TimeUtil 提取时间工具文档
720
+ */
721
+ function extractTimeUtilDocs() {
722
+ return {
723
+ name: 'TimeUtil 时间工具',
724
+ description: '用于时间格式化和时区处理',
725
+ methods: {
726
+ getSimpleDateFormat: {
727
+ description: '获取日期格式化器',
728
+ signature: 'static SimpleDateFormat getSimpleDateFormat(String string, UserInfo userInfo)',
729
+ example: `SimpleDateFormat sdf = TimeUtil.getSimpleDateFormat("yyyy-MM-dd HH:mm:ss", userInfo);
730
+ Date date = new Date();
731
+ String dateStr = sdf.format(date);`,
732
+ commonFormats: [
733
+ 'yyyy-MM-dd HH:mm:ss',
734
+ 'yyyy-MM-dd',
735
+ 'MM/dd/yyyy',
736
+ 'HH:mm:ss',
737
+ 'yyyy-MM-dd HH:mm'
738
+ ]
739
+ }
740
+ }
741
+ };
742
+ }
743
+
744
+ /**
745
+ * 从 UserInfo 提取用户信息文档
746
+ */
747
+ function extractUserInfoDocs() {
748
+ return {
749
+ name: 'UserInfo 用户信息',
750
+ description: '当前用户和权限信息',
751
+ properties: [
752
+ {
753
+ name: 'getUserId()',
754
+ desc: '获取当前用户 ID',
755
+ returns: 'String 用户 ID'
756
+ },
757
+ {
758
+ name: 'getRoleId()',
759
+ desc: '获取用户角色 ID',
760
+ returns: 'String 角色 ID'
761
+ },
762
+ {
763
+ name: 'getLoginName()',
764
+ desc: '获取登录名',
765
+ returns: 'String 登录名'
766
+ },
767
+ {
768
+ name: 'getUserName()',
769
+ desc: '获取用户名称',
770
+ returns: 'String 用户名'
771
+ },
772
+ {
773
+ name: 'getProfileId()',
774
+ desc: '获取配置文件 ID',
775
+ returns: 'String 配置文件 ID'
776
+ },
777
+ {
778
+ name: 'isIspartner()',
779
+ desc: '判断是否为合作伙伴',
780
+ returns: 'Boolean'
781
+ },
782
+ {
783
+ name: 'setBinding(String bind) / getBinding()',
784
+ desc: '获取/设置绑定信息',
785
+ returns: 'String 绑定信息'
786
+ }
787
+ ],
788
+ usage: 'UserInfo userInfo 作为参数传递给 CCService 和其他服务类,用于身份验证和权限检查'
789
+ };
790
+ }
791
+
792
+ /**
793
+ * 从 DevLogger 提取日志文档
794
+ */
795
+ function extractDevLoggerDocs() {
796
+ return {
797
+ name: 'DevLogger 开发日志',
798
+ description: '用于调试和记录程序运行状态',
799
+ methods: [
800
+ {
801
+ name: 'devLogInfo(String log)',
802
+ desc: '输出 Info 级别日志',
803
+ example: 'DevLogger.devLogInfo("处理开始");',
804
+ usage: '记录程序正常执行信息'
805
+ },
806
+ {
807
+ name: 'devLogError(String log)',
808
+ desc: '输出 Error 级别日志',
809
+ example: 'DevLogger.devLogError("数据查询失败");',
810
+ usage: '记录错误信息'
811
+ },
812
+ {
813
+ name: 'devLogError(String log, Exception e)',
814
+ desc: '输出异常日志',
815
+ example: `try {
816
+ // 某些操作
817
+ } catch(Exception e) {
818
+ DevLogger.devLogError("操作失败", e);
819
+ }`,
820
+ usage: '记录异常堆栈信息'
821
+ }
822
+ ],
823
+ tips: [
824
+ '开发环境中使用日志调试代码逻辑',
825
+ '生产环境中根据需要调整日志级别',
826
+ '避免输出敏感信息到日志'
827
+ ]
828
+ };
829
+ }
830
+
831
+ /**
832
+ * 常见编辑需求场景
833
+ */
834
+ function getEditScenarios() {
835
+ return [
836
+ {
837
+ scenario: '客户数据维护',
838
+ description: '新增、更新、删除客户信息',
839
+ example: `CCObject account = new CCObject("account");
840
+ account.put("name", "新客户名称");
841
+ account.put("type", "重点客户");
842
+ account.put("industry", "制造业");
843
+ ServiceResult result = cs.insert(account);
844
+ if(result != null) {
845
+ DevLogger.devLogInfo("客户创建成功: " + result.get("id"));
846
+ }`
847
+ },
848
+ {
849
+ scenario: '批量数据导入',
850
+ description: '批量新增或更新大量记录',
851
+ example: `List<CCObject> list = new ArrayList<>();
852
+ for(CCObject data : importData) {
853
+ CCObject obj = new CCObject("contact");
854
+ obj.put("name", data.get("name"));
855
+ obj.put("email", data.get("email"));
856
+ list.add(obj);
857
+ }
858
+ ServiceResult result = cs.insert(list);
859
+ DevLogger.devLogInfo("导入完成: " + result.get("id"));`
860
+ },
861
+ {
862
+ scenario: '条件查询和处理',
863
+ description: '查询符合条件的记录并处理',
864
+ example: `List<CCObject> records = cs.cqlQuery("opportunity", "stage = '商务谈判' AND amount > 50000");
865
+ for(CCObject record : records) {
866
+ record.put("priority", "high");
867
+ cs.update(record);
868
+ DevLogger.devLogInfo("更新商机: " + record.get("id"));
869
+ }`
870
+ },
871
+ {
872
+ scenario: '发送通知邮件',
873
+ description: '基于业务逻辑发送邮件通知',
874
+ example: `SendEmail sender = new SendEmail(userInfo);
875
+ List<CCObject> tasks = cs.cqlQuery("task", "status = 'pending'");
876
+ for(CCObject task : tasks) {
877
+ String[] recipients = {(String)task.get("ownerEmail")};
878
+ sender.sendMailFromSystem(recipients, null, null,
879
+ "任务提醒: " + task.get("subject"),
880
+ "<p>您有一个待处理的任务,请及时处理。</p>",
881
+ false
882
+ );
883
+ }`
884
+ }
885
+ ];
886
+ }
887
+
888
+ /**
889
+ * 编辑类的最佳实践
890
+ */
891
+ function getEditBestPractices() {
892
+ return {
893
+ dataValidation: [
894
+ '新增或更新前验证数据的合法性',
895
+ '检查必填字段是否为空',
896
+ '验证数据格式是否正确',
897
+ '检查是否存在重复数据'
898
+ ],
899
+ errorHandling: [
900
+ '使用 try-catch 捕获异常',
901
+ '使用 DevLogger 记录错误信息',
902
+ '对关键操作进行日志记录',
903
+ '返回有意义的错误提示'
904
+ ],
905
+ performance: [
906
+ '使用批量操作替代循环调用',
907
+ '避免在循环中进行数据库查询',
908
+ '大数据量操作时分批处理',
909
+ '优先使用条件查询减少数据传输'
910
+ ],
911
+ security: [
912
+ '验证用户权限和数据访问权限',
913
+ '不要在日志中输出敏感数据',
914
+ '对外部输入进行验证和清理',
915
+ '使用 UserInfo 进行权限检查'
916
+ ]
917
+ };
918
+ }
919
+
920
+ /**
921
+ * EditClass 工具知识库对象
922
+ */
923
+ const editCCServiceApis = extractCCServiceApis();
924
+ const editCCObjectDocs = extractCCObjectDocs();
925
+ const editSendEmailDocs = extractSendEmailDocs();
926
+ const editTimeUtilDocs = extractTimeUtilDocs();
927
+ const editUserInfoDocs = extractUserInfoDocs();
928
+ const editDevLoggerDocs = extractDevLoggerDocs();
929
+ const editScenarios = getEditScenarios();
930
+ const editBestPractices = getEditBestPractices();
931
+
932
+ /**
933
+ * 通用文档生成工具函数
934
+ */
935
+
936
+ /**
937
+ * 格式化 API 文档
938
+ */
939
+ function formatApiDocs(api) {
940
+ const lines = [`### ${api.name}\n${api.description}\n`];
941
+
942
+ for (const [key, method] of Object.entries(api.apis || api.methods || {})) {
943
+ lines.push(`#### ${method.description}`);
944
+ lines.push(`\`\`\`java\n${method.example}\n\`\`\``);
945
+
946
+ if (method.params) {
947
+ lines.push('**参数**:');
948
+ method.params.forEach(p => {
949
+ lines.push(`- ${p.name} (${p.type}): ${p.desc}`);
950
+ });
951
+ }
952
+ if (method.returns) lines.push(`**返回**: ${method.returns}`);
953
+ if (method.note) lines.push(`**提示**: ${method.note}`);
954
+ lines.push('');
955
+ }
956
+
957
+ if (api.bestPractices) {
958
+ lines.push('### 最佳实践');
959
+ api.bestPractices.forEach(p => {
960
+ lines.push(`- ${p}`);
961
+ });
962
+ }
963
+
964
+ return lines.join('\n');
965
+ }
966
+
967
+ /**
968
+ * 生成概览
969
+ */
970
+ function generateOverview() {
971
+ const topics = [
972
+ '1. **ccservice** - CCService 数据操作 API(查询、新增、更新、删除等)',
973
+ '2. **object** - CCObject 对象操作方法',
974
+ '3. **email** - SendEmail 邮件服务',
975
+ '4. **time** - TimeUtil 时间格式化工具',
976
+ '5. **user** - UserInfo 用户信息获取',
977
+ '6. **logger** - DevLogger 日志输出',
978
+ '7. **scenarios** - 常见编辑场景示例',
979
+ '8. **bestpractices** - 编辑最佳实践'
980
+ ];
981
+
982
+ const navs = [
983
+ '- 编写数据操作代码 → 使用 `topic: \'ccservice\'` 或 `topic: \'object\'`',
984
+ '- 发送邮件或处理时间 → 使用 `topic: \'email\'` 或 `topic: \'time\'`',
985
+ '- 获取用户信息或日志 → 使用 `topic: \'user\'` 或 `topic: \'logger\'`',
986
+ '- 查看常见场景或最佳实践 → 使用 `topic: \'scenarios\'` 或 `topic: \'bestpractices\'`'
987
+ ];
988
+
989
+ return [
990
+ '## CloudCC 自定义类编辑知识库',
991
+ '',
992
+ '### 可用主题',
993
+ '',
994
+ ...topics,
995
+ '',
996
+ '### 快速导航',
997
+ ...navs
998
+ ].join('\n');
999
+ }
1000
+
1001
+ /**
1002
+ * 生成 CCService 指南
1003
+ */
1004
+ function generateCCServiceGuide() {
1005
+ return formatApiDocs(editCCServiceApis);
1006
+ }
1007
+
1008
+ /**
1009
+ * 生成 CCObject 指南
1010
+ */
1011
+ function generateCCObjectGuide() {
1012
+ const obj = editCCObjectDocs;
1013
+ const lines = [`### ${obj.name}\n${obj.description}\n`, '#### 构造方法'];
1014
+
1015
+ obj.constructors.forEach(c => {
1016
+ lines.push(`**${c.signature}**: ${c.desc}`);
1017
+ lines.push(`\`\`\`java\n${c.example}\n\`\`\``);
1018
+ if (c.recommended) lines.push('⭐ 推荐使用\n');
1019
+ });
1020
+
1021
+ lines.push('#### 数据存取方法');
1022
+ if (obj.methods?.dataAccess?.items) {
1023
+ obj.methods.dataAccess.items.forEach(item => {
1024
+ lines.push(`- **${item.name}**: ${item.desc}`);
1025
+ lines.push(` \`\`\`java\n ${item.example}\n \`\`\``);
1026
+ });
1027
+ }
1028
+
1029
+ lines.push('#### 常见对象类型');
1030
+ obj.commonObjects.forEach(o => {
1031
+ lines.push(`- **${o.name}**: ${o.label}`);
1032
+ lines.push(` 常用字段: ${o.commonFields.slice(0, 3).join(', ')}...`);
1033
+ });
1034
+
1035
+ if (obj.bestPractices) {
1036
+ lines.push('\n### 最佳实践');
1037
+ for (const [category, practices] of Object.entries(obj.bestPractices)) {
1038
+ const catName = category === 'creation' ? '创建对象' :
1039
+ category === 'dataManipulation' ? '数据操作' : '与 CCService 集成';
1040
+ lines.push(`**${catName}**:`);
1041
+ practices.forEach(p => lines.push(`- ${p}`));
1042
+ }
1043
+ }
1044
+
1045
+ return lines.join('\n');
1046
+ }
1047
+
1048
+ /**
1049
+ * 生成邮件服务指南
1050
+ */
1051
+ function generateEmailGuide() {
1052
+ return formatApiDocs({ ...editSendEmailDocs, apis: editSendEmailDocs.methods });
1053
+ }
1054
+
1055
+ /**
1056
+ * 生成时间工具指南
1057
+ */
1058
+ function generateTimeUtilGuide() {
1059
+ const lines = [`### ${editTimeUtilDocs.name}\n${editTimeUtilDocs.description}\n`];
1060
+
1061
+ for (const [key, method] of Object.entries(editTimeUtilDocs.methods)) {
1062
+ lines.push(`#### ${method.description}`);
1063
+ lines.push(`\`\`\`java\n${method.example}\n\`\`\``);
1064
+ if (method.commonFormats) {
1065
+ lines.push('**常见时间格式**:');
1066
+ method.commonFormats.forEach(fmt => lines.push(`- \`${fmt}\``));
1067
+ }
1068
+ lines.push('');
1069
+ }
1070
+
1071
+ return lines.join('\n');
1072
+ }
1073
+
1074
+ /**
1075
+ * 生成用户信息指南
1076
+ */
1077
+ function generateUserInfoGuide() {
1078
+ const lines = [`### ${editUserInfoDocs.name}\n${editUserInfoDocs.description}\n`, '**属性和方法**:'];
1079
+
1080
+ editUserInfoDocs.properties.forEach(prop => {
1081
+ lines.push(`- \`${prop.name}\`: ${prop.desc}`);
1082
+ lines.push(` 返回: ${prop.returns}`);
1083
+ });
1084
+
1085
+ lines.push(`\n**使用场景**: ${editUserInfoDocs.usage}`);
1086
+ return lines.join('\n');
1087
+ }
1088
+
1089
+ /**
1090
+ * 生成日志输出指南
1091
+ */
1092
+ function generateLoggerGuide() {
1093
+ const lines = [`### ${editDevLoggerDocs.name}\n${editDevLoggerDocs.description}\n`];
1094
+
1095
+ editDevLoggerDocs.methods.forEach(method => {
1096
+ lines.push(`#### ${method.name}`);
1097
+ lines.push(`${method.desc} - ${method.usage}`);
1098
+ lines.push(`\`\`\`java\n${method.example}\n\`\`\`\n`);
1099
+ });
1100
+
1101
+ lines.push('### 使用建议');
1102
+ editDevLoggerDocs.tips.forEach(tip => lines.push(`- ${tip}`));
1103
+
1104
+ return lines.join('\n');
1105
+ }
1106
+
1107
+ /**
1108
+ * 生成常见场景
1109
+ */
1110
+ function generateScenariosGuide() {
1111
+ const lines = ['## 常见编辑场景\n'];
1112
+
1113
+ editScenarios.forEach(scenario => {
1114
+ lines.push(`### ${scenario.scenario}`);
1115
+ lines.push(scenario.description);
1116
+ lines.push('\n**示例代码**:');
1117
+ lines.push(`\`\`\`java\n${scenario.example}\n\`\`\`\n`);
1118
+ });
1119
+
1120
+ return lines.join('\n');
1121
+ }
1122
+
1123
+ /**
1124
+ * 生成最佳实践
1125
+ */
1126
+ function generateBestPracticesGuide() {
1127
+ const lines = ['## 编辑类最佳实践\n'];
1128
+ const catMap = {
1129
+ dataValidation: '数据验证',
1130
+ errorHandling: '错误处理',
1131
+ performance: '性能优化',
1132
+ security: '安全性'
1133
+ };
1134
+
1135
+ for (const [category, items] of Object.entries(editBestPractices)) {
1136
+ lines.push(`### ${catMap[category] || category}`);
1137
+ items.forEach(p => lines.push(`- ${p}`));
1138
+ lines.push('');
1139
+ }
1140
+
1141
+ return lines.join('\n');
1142
+ }
1143
+
1144
+ /**
1145
+ * 获取指定主题的编辑文档
1146
+ */
1147
+ function getEditGuide(topic) {
1148
+ const guides = {
1149
+ overview: generateOverview,
1150
+ ccservice: generateCCServiceGuide,
1151
+ object: generateCCObjectGuide,
1152
+ email: generateEmailGuide,
1153
+ time: generateTimeUtilGuide,
1154
+ user: generateUserInfoGuide,
1155
+ logger: generateLoggerGuide,
1156
+ scenarios: generateScenariosGuide,
1157
+ bestpractices: generateBestPracticesGuide
1158
+ };
1159
+
1160
+ const result = guides[topic] ? guides[topic]() : `✗ 未知的主题: ${topic}\n\n支持的主题: ${Object.keys(guides).join(', ')}`;
1161
+
1162
+ // 如果包含代码示例或最佳实践,添加 CloudCC 标准 API 规范提示
1163
+ if (result.includes('```java') || result.includes('最佳实践')) {
1164
+ return result + getCloudCCApiStandards();
1165
+ }
1166
+
1167
+ return result;
1168
+ }
1169
+
1170
+ /**
1171
+ * 获取 CloudCC 标准 API 规范
1172
+ * 确保编辑代码符合 CloudCC 的标准
1173
+ */
1174
+ function getCloudCCApiStandards() {
1175
+ return `
1176
+
1177
+ ## ⚠️ CloudCC 代码标准规范
1178
+
1179
+ ### 常用 API 速查表
1180
+
1181
+ **DevLogger 日志输出**(正确用法):
1182
+ \`\`\`java
1183
+ // ✅ 正确
1184
+ DevLogger.devLogInfo("日志信息"); // 输出 Info 级别
1185
+ DevLogger.devLogError("错误信息"); // 输出 Error 级别
1186
+ DevLogger.devLogError("错误信息", e); // 输出异常堆栈
1187
+
1188
+ // ❌ 错误(不存在这些方法)
1189
+ DevLogger.error("..."); // ✗ 无此方法
1190
+ DevLogger.warn("..."); // ✗ 无此方法
1191
+ DevLogger.debug("..."); // ✗ 无此方法
1192
+ \`\`\`
1193
+
1194
+ **CCService 数据操作**(常用方法):
1195
+ \`\`\`java
1196
+ // 查询(推荐使用 cqlQuery)
1197
+ List<CCObject> list = cs.cquery("account");
1198
+ List<CCObject> list = cs.cqlQuery("account", "status = 'active'");
1199
+
1200
+ // 新增/更新/删除/Upsert
1201
+ ServiceResult sr = cs.insert(obj);
1202
+ cs.update(obj);
1203
+ cs.delete(obj);
1204
+ ServiceResult sr = cs.upsert(obj);
1205
+
1206
+ // ❌ 过时 API(不推荐)
1207
+ List<Map> map = cs.query(...); // 已过时,使用 cquery 或 cqlQuery
1208
+ \`\`\`
1209
+
1210
+ **CCObject 对象操作**(标准模式):
1211
+ \`\`\`java
1212
+ // 创建对象(标准做法)
1213
+ CCObject obj = new CCObject("account");
1214
+
1215
+ // 存取字段
1216
+ obj.put("name", "值");
1217
+ String value = (String) obj.get("name");
1218
+
1219
+ // 检查字段存在
1220
+ if (obj.containsKey("id")) {
1221
+ // 执行更新操作
1222
+ cs.update(obj);
1223
+ } else {
1224
+ // 执行新增操作
1225
+ cs.insert(obj);
1226
+ }
1227
+ \`\`\`
1228
+
1229
+ ### 编码检查清单
1230
+ - [ ] 日志使用 \`DevLogger.devLogInfo()\` 或 \`DevLogger.devLogError()\`
1231
+ - [ ] 查询优先使用 \`cs.cqlQuery()\` 而非 \`cs.query()\`
1232
+ - [ ] CCObject 使用 \`new CCObject("apiName")\` 标准构造
1233
+ - [ ] 操作后检查 \`ServiceResult\` 返回值
1234
+ - [ ] 异常处理使用 try-catch 并用 DevLogger 记录
1235
+ - [ ] 获取字段值进行类型转换:\`(String) obj.get("field")\`
1236
+ - [ ] 关键操作添加日志记录便于调试
1237
+
1238
+ ### 常见错误及修正
1239
+
1240
+ | 错误代码 | 正确写法 |
1241
+ |--------|--------|
1242
+ | \`DevLogger.error(...)\` | \`DevLogger.devLogError(...)\` |
1243
+ | \`DevLogger.warn(...)\` | \`DevLogger.devLogInfo(...)\` |
1244
+ | \`cs.query(...)\` | \`cs.cqlQuery(...)\` |
1245
+ | \`new CCObject()\` 无参 | \`new CCObject("account")\` |
1246
+ | \`obj.get("field")\` 不转换 | \`(String) obj.get("field")\` |
1247
+ `;
1248
+ }
1249
+
1250
+ module.exports = {
1251
+ // Classes 工具核心知识库(供 handler 使用)
1252
+ javaClassTemplate, // viewCreateGuide() 使用
1253
+ configStructure, // viewCreateGuide() 使用
1254
+ ccServiceApis, // viewApiDocs() 使用
1255
+ errorMessages, // viewFAQ() 使用
1256
+ faq, // viewFAQ() 使用
1257
+ usageGuide, // viewCreateGuide() 使用
1258
+
1259
+ // 文档生成函数(供 editClass 使用)
1260
+ getEditGuide
1261
+ };