cloudcc-cli 2.2.6 → 2.2.7

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 (117) hide show
  1. package/.cloudcc-cache.json +24 -20
  2. package/README.md +12 -0
  3. package/bin/cc.js +7 -0
  4. package/java/com/cloudcc/core/BaseException.java +100 -0
  5. package/java/com/cloudcc/core/BusiException.java +43 -0
  6. package/java/com/cloudcc/core/CCService.java +3 -1
  7. package/java/com/cloudcc/core/StringUtils.java +7 -0
  8. package/java/com/cloudcc/core/TimeUtil.java +33 -0
  9. package/java/com/cloudcc/core/UserInfo.java +9 -0
  10. package/package.json +7 -1
  11. package/pom.xml +1 -1
  12. package/skill/BACKEND_CODE.md +114 -0
  13. package/skill/CLI_CHEATSHEET.md +90 -0
  14. package/skill/INSTALL_AND_BOOTSTRAP.md +59 -0
  15. package/skill/OBJECTS_AND_FIELDS.md +120 -0
  16. package/skill/REQUIREMENTS_BREAKDOWN.md +98 -0
  17. package/skill/SKILL.md +33 -0
  18. package/skill/VUE_CUSTOM_COMPONENT.md +50 -0
  19. package/src/api/backend-sdk-java.md +427 -0
  20. package/src/api/ccdk-sdk.md +1039 -0
  21. package/src/classes/doc.js +486 -0
  22. package/src/classes/index.js +1 -0
  23. package/src/mcp/cliRunner.js +61 -0
  24. package/src/mcp/index.js +41 -3
  25. package/src/mcp/tools/Application Creator/handler.js +7 -9
  26. package/src/mcp/tools/Approval/handler.js +34 -151
  27. package/src/mcp/tools/Class Creator/handler.js +18 -15
  28. package/src/mcp/tools/Class Detail Retriever/handler.js +8 -9
  29. package/src/mcp/tools/Class Editor Guide/handler.js +5 -19
  30. package/src/mcp/tools/Class List Retriever/handler.js +8 -3
  31. package/src/mcp/tools/Class Publisher/handler.js +7 -9
  32. package/src/mcp/tools/Class Puller/handler.js +6 -65
  33. package/src/mcp/tools/Client Script Detail Retriever/handler.js +12 -18
  34. package/src/mcp/tools/Client Script Editor Guide/handler.js +9 -605
  35. package/src/mcp/tools/Client Script List Retriever/handler.js +30 -33
  36. package/src/mcp/tools/Client Script Publisher/handler.js +12 -11
  37. package/src/mcp/tools/Client Script Puller/handler.js +23 -30
  38. package/src/mcp/tools/CloudCC Development Overview/handler.js +11 -5
  39. package/src/mcp/tools/Component Creator/handler.js +12 -11
  40. package/src/mcp/tools/Component Detail Retriever/handler.js +12 -9
  41. package/src/mcp/tools/Component Editor Guide/handler.js +5 -22
  42. package/src/mcp/tools/Component List Retriever/handler.js +21 -18
  43. package/src/mcp/tools/Component Publisher/handler.js +25 -3
  44. package/src/mcp/tools/Component Puller/handler.js +13 -16
  45. package/src/mcp/tools/Dev Environment Creator/handler.js +5 -72
  46. package/src/mcp/tools/Dev Environment Validator/handler.js +5 -66
  47. package/src/mcp/tools/Developer Key Setup Guide/handler.js +11 -20
  48. package/src/mcp/tools/JSP Migrator/handler.js +842 -0
  49. package/src/mcp/tools/Menu Creator/handler.js +7 -30
  50. package/src/mcp/tools/Object Creator/handler.js +14 -6
  51. package/src/mcp/tools/Object Fields Creator/handler.js +9 -10
  52. package/src/mcp/tools/Object Fields Retriever/handler.js +6 -3
  53. package/src/mcp/tools/Object List Retriever/handler.js +10 -7
  54. package/src/mcp/tools/Scheduled Class Creator/handler.js +12 -16
  55. package/src/mcp/tools/Scheduled Class Detail Retriever/handler.js +7 -9
  56. package/src/mcp/tools/Scheduled Class List Retriever/handler.js +21 -23
  57. package/src/mcp/tools/Scheduled Class Publisher/handler.js +7 -9
  58. package/src/mcp/tools/Scheduled Class Puller/handler.js +6 -70
  59. package/src/mcp/tools/Trigger Creator/handler.js +12 -20
  60. package/src/mcp/tools/Trigger Detail Retriever/handler.js +7 -9
  61. package/src/mcp/tools/Trigger Editor Guide/handler.js +10 -35
  62. package/src/mcp/tools/Trigger List Retriever/handler.js +12 -4
  63. package/src/mcp/tools/Trigger Publisher/handler.js +8 -11
  64. package/src/mcp/tools/Trigger Puller/handler.js +12 -17
  65. package/src/plugin/doc.js +801 -0
  66. package/src/plugin/index.js +1 -0
  67. package/src/project/doc.js +378 -0
  68. package/src/project/index.js +1 -0
  69. package/src/script/doc.js +259 -0
  70. package/src/script/index.js +1 -0
  71. package/src/timer/index.js +1 -0
  72. package/src/triggers/doc.js +342 -0
  73. package/src/triggers/index.js +5 -0
  74. package/target/classes/com/cloudcc/core/BaseException.class +0 -0
  75. package/target/classes/com/cloudcc/core/BusiException.class +0 -0
  76. package/target/classes/com/cloudcc/core/CCService.class +0 -0
  77. package/target/classes/com/cloudcc/core/StringUtils.class +0 -0
  78. package/target/classes/com/cloudcc/core/TimeUtil.class +0 -0
  79. package/target/classes/com/cloudcc/core/UserInfo.class +0 -0
  80. package/template/lib/ccopenapi-0.0.4.jar +0 -0
  81. package/test/application.cli.test.js +30 -0
  82. package/test/classes.cli.test.js +121 -0
  83. package/test/fields.cli.test.js +69 -0
  84. package/test/mcp.cli.test.js +21 -0
  85. package/test/menu.cli.test.js +41 -0
  86. package/test/object.cli.test.js +64 -0
  87. package/test/plugin.cli.test.js +109 -0
  88. package/test/script.cli.test.js +101 -0
  89. package/test/timer.cli.test.js +107 -0
  90. package/test/trigger.cli.test.js +146 -0
  91. package/.vscode/settings.json +0 -3
  92. package/bin/mcp-svc.js +0 -13
  93. package/src/mcp/MCP/345/234/272/346/231/257/346/250/241/346/213/237.md +0 -8
  94. package/src/mcp/index-sse-svc.js +0 -126
  95. package/src/mcp/index-streamable-svc.js +0 -180
  96. package/src/mcp/tools/Class Detail Retriever/prompt.js +0 -37
  97. package/src/mcp/tools/Class Editor Guide/prompt.js +0 -468
  98. package/src/mcp/tools/Class Publisher/prompt.js +0 -40
  99. package/src/mcp/tools/Class Puller/prompt.js +0 -49
  100. package/src/mcp/tools/Client Script Creator/handler.js +0 -179
  101. package/src/mcp/tools/CloudCC Development Overview/prompt.js +0 -871
  102. package/src/mcp/tools/Component Editor Guide/prompt.js +0 -519
  103. package/src/mcp/tools/Component Publisher/prompt.js +0 -659
  104. package/src/mcp/tools/Dev Environment Creator/prompt.js +0 -273
  105. package/src/mcp/tools/Dev Environment Validator/prompt.js +0 -193
  106. package/src/mcp/tools/Developer Key Setup Guide/prompt.js +0 -71
  107. package/src/mcp/tools/Object Fields Retriever/prompt.js +0 -10
  108. package/src/mcp/tools/Object List Retriever/prompt.js +0 -10
  109. package/src/mcp/tools/ccdk/fetcher.js +0 -18
  110. package/src/mcp/tools/ccdk/handler.js +0 -98
  111. package/src/mcp/tools/ccdk/prompt.js +0 -453
  112. package/target/ccopenapi-0.0.3-classes.jar +0 -0
  113. package/target/ccopenapi-0.0.3.jar +0 -0
  114. package/target/maven-archiver/pom.properties +0 -3
  115. package/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +0 -18
  116. package/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +0 -19
  117. package/template/lib/ccopenapi-0.0.3.jar +0 -0
@@ -0,0 +1,486 @@
1
+ /**
2
+ * classes 文档统一入口(合并自 prompt.js + classEditor.js)
3
+ */
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+
7
+ function generateFullMarkdownDoc() {
8
+ const lines = [
9
+ '# CloudCC 自定义类开发指南',
10
+ '',
11
+ '> 本文档参考 CloudCC 官方「自定义类」文档整理而成:[自定义类](https://help.cloudcc.cn/product03/zi-ding-yi-lei/)。 ',
12
+ '> 目标:指导开发者在 CloudCC 平台上编写 Java 自定义类,熟练使用 `CCService`、`CCObject`、`SendEmail`、`DevLogger`、`TimeUtil` 等工具类,并理解类在触发器、定时作业、自定义组件中的调用方式。',
13
+ '',
14
+ '---',
15
+ '',
16
+ '## 1. 概念与使用场景',
17
+ '',
18
+ '### 1.1 什么是自定义类',
19
+ '',
20
+ '- 自定义类本质上是运行在 CloudCC 平台上的 Java 类。 ',
21
+ '- 可被以下模块调用:',
22
+ ' - 自定义按钮',
23
+ ' - 触发器',
24
+ ' - 定时类 / 定时作业',
25
+ ' - 自定义组件(通过 CCDK 请求自定义类)',
26
+ '- 典型用途:',
27
+ ' - 封装复杂业务逻辑',
28
+ ' - 查询 / 写入对象数据',
29
+ ' - 调用自定义设置、发送邮件、记录开发日志',
30
+ '',
31
+ '**注意**:调用 `CCService` 的方法时,需要对异常进行显式抛出或捕获。',
32
+ '',
33
+ '### 1.2 入口:进入类开发页面',
34
+ '',
35
+ '1. 登录 CloudCC 系统 ',
36
+ '2. 点击右上角头像,选择「开发者平台」(仅对管理员简档用户开放) ',
37
+ '3. 左侧菜单:`扩展 → 类`,进入类开发页面',
38
+ '',
39
+ '---',
40
+ '',
41
+ '## 2. 示例:查询客户对象数据(AccountClass)',
42
+ '',
43
+ '下面是一个官方示例类:查询客户对象数据并返回 JSON。',
44
+ '',
45
+ '```java',
46
+ 'import net.sf.json.JSONObject;',
47
+ 'import net.sf.json.JSONArray;',
48
+ 'import net.sf.json.JSON;',
49
+ '',
50
+ '/**',
51
+ ' * author:*** on 2022-10-12',
52
+ ' * 客户类',
53
+ ' */',
54
+ 'public class AccountClass {',
55
+ ' private CCService cs;',
56
+ ' private UserInfo userInfo;',
57
+ '',
58
+ ' public AccountClass(UserInfo userInfo) {',
59
+ ' this.userInfo = userInfo;',
60
+ ' cs = new CCService(userInfo);',
61
+ ' }',
62
+ '',
63
+ ' public JSONObject selectAccount() throws Exception {',
64
+ ' JSONObject rtninfo = new JSONObject(); // 返回结果',
65
+ ' JSONArray dataList = new JSONArray(); // 数据列表',
66
+ ' boolean flag = false;',
67
+ ' try {',
68
+ ' // 查询客户对象数据',
69
+ ' String sql = "select name, leixing, fenji, hangye from Account where is_deleted=\'0\' ";',
70
+ ' List<CCObject> accountList = cs.cqlQuery("Account", sql);',
71
+ '',
72
+ ' for (int i = 0; i < accountList.size(); i++) {',
73
+ ' String name = accountList.get(i).get("name") == null ? "" : accountList.get(i).get("name").toString();',
74
+ ' String type = accountList.get(i).get("leixing") == null ? "" : accountList.get(i).get("leixing").toString();',
75
+ ' String grade = accountList.get(i).get("fenji") == null ? "0" : accountList.get(i).get("fenji").toString();',
76
+ ' String industry = accountList.get(i).get("hangye") == null ? "0" : accountList.get(i).get("hangye").toString();',
77
+ '',
78
+ ' JSONObject data = new JSONObject();',
79
+ ' data.put("name", name);',
80
+ ' data.put("type", type);',
81
+ ' data.put("grade", grade);',
82
+ ' data.put("industry", industry);',
83
+ ' data.put("no", (i + 1) + ""); // 序号',
84
+ ' dataList.add(data);',
85
+ ' }',
86
+ ' flag = true;',
87
+ ' } catch (Exception e) {',
88
+ ' throw e;',
89
+ ' }',
90
+ ' rtninfo.put("status", flag);',
91
+ ' rtninfo.put("data", dataList.toString());',
92
+ ' return rtninfo;',
93
+ ' }',
94
+ '}',
95
+ '```',
96
+ '',
97
+ '要点:',
98
+ '- 构造函数接收 `UserInfo`,通过它实例化 `CCService`。 ',
99
+ '- 查询结果使用 `CCObject` 列表封装,再转为 `JSONObject`/`JSONArray` 返回。 ',
100
+ '- 方法签名抛出 `Exception`,调用方需要处理。',
101
+ '',
102
+ '---',
103
+ '',
104
+ '## 3. CCService:对象数据读写核心',
105
+ '',
106
+ '> `CCService` 是操作 CloudCC 对象(类似 ORM)的核心服务类,支持增删改查、自定义设置等。',
107
+ '',
108
+ '### 3.1 在类中实例化 CCService',
109
+ '',
110
+ '通用写法:',
111
+ '',
112
+ '```java',
113
+ 'public class DemoClass {',
114
+ ' private CCService cs;',
115
+ ' private UserInfo userInfo;',
116
+ '',
117
+ ' public DemoClass(UserInfo userInfo) {',
118
+ ' this.userInfo = userInfo;',
119
+ ' this.cs = new CCService(userInfo);',
120
+ ' }',
121
+ '}',
122
+ '```',
123
+ '',
124
+ '在触发器中则通常不需要手动实例化,可直接使用平台提供的 `cs`(见触发器指南)。',
125
+ '',
126
+ '### 3.2 新增记录:insert',
127
+ '',
128
+ '1. 通过 `CCObject` 构造要插入的记录 ',
129
+ '2. 调用 `cs.insert(对象)` 持久化到数据库',
130
+ '',
131
+ '```java',
132
+ '// 构造一个数据对象,传入对象 API 名称',
133
+ 'CCObject opp = new CCObject("Opportunity");',
134
+ '',
135
+ '// 给 CCObject 赋值,key 为字段 API 名称',
136
+ 'opp.put("name", "新建机会");',
137
+ 'opp.put("jine__c", 10000); // 示例:金额字段',
138
+ '',
139
+ '// 插入数据库',
140
+ 'cs.insert(opp);',
141
+ '```',
142
+ '',
143
+ '**注意**:ID、自动编号、创建人、创建时间等系统字段不需要也不应该手动赋值。',
144
+ '',
145
+ '### 3.3 查询记录:cquery',
146
+ '',
147
+ '`cquery` 提供多种重载,用于按条件和排序查询数据。',
148
+ '',
149
+ '- 返回对象全部记录:',
150
+ '',
151
+ '```java',
152
+ 'List<CCObject> opps = cs.cquery("Opportunity");',
153
+ '```',
154
+ '',
155
+ '- 按条件查询(where 表达式):',
156
+ '',
157
+ '```java',
158
+ 'List<CCObject> opps = cs.cquery(',
159
+ ' "Opportunity",',
160
+ ' "khmc__c = \'" + record_new.get("id") + "\'"',
161
+ ');',
162
+ '```',
163
+ '',
164
+ '- 按条件 + 排序:',
165
+ '',
166
+ '```java',
167
+ 'List<CCObject> opps = cs.cquery(',
168
+ ' "Opportunity",',
169
+ ' "khmc__c = \'" + record_new.get("id") + "\'",',
170
+ ' "jine__c desc"',
171
+ ');',
172
+ '```',
173
+ '',
174
+ '**注意**:条件与排序中的自定义字段 API 名称要加 `__c` 后缀。',
175
+ '',
176
+ '### 3.4 修改记录:update',
177
+ '',
178
+ '```java',
179
+ '// 先查询到目标记录',
180
+ 'List<CCObject> list = cs.cquery("Opportunity", "id = \'" + record_id + "\'");',
181
+ 'if (!list.isEmpty()) {',
182
+ ' CCObject opp = list.get(0);',
183
+ ' opp.put("name", "修改后的机会名称");',
184
+ ' cs.update(opp);',
185
+ '}',
186
+ '```',
187
+ '',
188
+ '### 3.5 删除记录:delete',
189
+ '',
190
+ '```java',
191
+ 'List<CCObject> list = cs.cquery("Opportunity", "id = \'" + record_id + "\'");',
192
+ 'if (!list.isEmpty()) {',
193
+ ' CCObject opp = list.get(0);',
194
+ ' cs.delete(opp);',
195
+ '}',
196
+ '```',
197
+ '',
198
+ '### 3.6 操作共享表',
199
+ '',
200
+ '#### 查询共享表',
201
+ '',
202
+ '```java',
203
+ '// isDataObject 传 false,表示查询共享表',
204
+ 'List<CCObject> shares = cs.cquery(',
205
+ ' "Opportunity",',
206
+ ' "userid = \'" + userId + "\'",',
207
+ ' false',
208
+ ');',
209
+ '```',
210
+ '',
211
+ '#### 删除共享表记录',
212
+ '',
213
+ '```java',
214
+ 'cs.deleteShareObjectBySql("Opportunity", "userid = \'" + userId + "\'");',
215
+ '```',
216
+ '',
217
+ '**注意**:共享表中表达式里的字段 **不需要加 `__c` 后缀**。',
218
+ '',
219
+ '### 3.7 自定义设置(CustomSetting)',
220
+ '',
221
+ '#### 列表类型自定义设置(List)',
222
+ '',
223
+ '- 返回某个 API 名称下的全部数据:',
224
+ '',
225
+ '```java',
226
+ 'Map listSettings = cs.getListCustomSetting("MyListSettingApiName");',
227
+ '```',
228
+ '',
229
+ '- 返回指定 `Name` 的单条数据:',
230
+ '',
231
+ '```java',
232
+ 'Map singleSetting = cs.getListCustomSetting("MyListSettingApiName", "SomeName");',
233
+ '```',
234
+ '',
235
+ '#### 层次结构类型自定义设置(Hierarchy)',
236
+ '',
237
+ '```java',
238
+ '// id 为简档 ID 或用户 ID',
239
+ 'Map hiSetting = cs.getCustomSetting("MyHierarchySettingApiName", profileOrUserId);',
240
+ '```',
241
+ '',
242
+ '---',
243
+ '',
244
+ '## 4. 常用工具类',
245
+ '',
246
+ '### 4.1 SendEmail:发送邮件',
247
+ '',
248
+ '```java',
249
+ 'SendEmail sendEmail = new SendEmail(userInfo);',
250
+ 'sendEmail.sendMailFromSystem(',
251
+ ' new String[]{"to@example.com"}, // 收件人',
252
+ ' new String[]{"cc@example.com"}, // 抄送',
253
+ ' new String[]{"bcc@example.com"}, // 密送',
254
+ ' "邮件主题",',
255
+ ' "邮件内容",',
256
+ ' true // 是否纯文本',
257
+ ');',
258
+ '```',
259
+ '',
260
+ '### 4.2 DevLogger:开发日志',
261
+ '',
262
+ '> 用于在自定义类中记录开发日志,便于排查问题。',
263
+ '',
264
+ '```java',
265
+ '// 初始化日志类',
266
+ 'DevLogger cclogger = new DevLogger(userInfo);',
267
+ '',
268
+ '// 打印 info 级别日志',
269
+ 'cclogger.devLogInfo("这是 info 日志");',
270
+ '',
271
+ '// 打印 error 级别日志',
272
+ 'cclogger.devLogError("这是 error 日志");',
273
+ '',
274
+ '// 打印异常堆栈',
275
+ 'try {',
276
+ ' // 业务逻辑',
277
+ '} catch (Exception e) {',
278
+ ' cclogger.devLogError("发生异常", e);',
279
+ ' throw e;',
280
+ '}',
281
+ '```',
282
+ '',
283
+ '### 4.3 TimeUtil:多时区日期时间',
284
+ '',
285
+ '> 为保证跨时区时间的准确性,推荐使用 `TimeUtil` 获取当前时间与时间格式化工具。',
286
+ '',
287
+ '- 获取当前时间(根据用户时区):',
288
+ '',
289
+ '```java',
290
+ 'TpSysTask task = new TpSysTask();',
291
+ 'task.setBeginTime(TimeUtil.getNowDate(userInfo));',
292
+ '```',
293
+ '',
294
+ '- 使用 `SimpleDateFormat` 时设置时区:',
295
+ '',
296
+ '```java',
297
+ 'SimpleDateFormat myDateFormat = new SimpleDateFormat("yyyy-MM-dd");',
298
+ 'myDateFormat.setTimeZone(TimeUtil.getUserTimeZone(userInfo));',
299
+ '```',
300
+ '',
301
+ '- 使用工具方法直接获取带时区的 `SimpleDateFormat`:',
302
+ '',
303
+ '```java',
304
+ 'SimpleDateFormat myDateFormat =',
305
+ ' TimeUtil.getSimpleDateFormat("yyyy-MM-dd", userInfo);',
306
+ '```',
307
+ '',
308
+ '- 使用 `Calendar` 时设置时区:',
309
+ '',
310
+ '```java',
311
+ '// 方式一',
312
+ 'Calendar cal = Calendar.getInstance(TimeUtil.getUserTimeZone(userInfo));',
313
+ '',
314
+ '// 方式二(推荐使用工具方法)',
315
+ 'Calendar cal2 = TimeUtil.getCalendar(userInfo);',
316
+ '```',
317
+ '',
318
+ '### 4.4 CCObject:数据载体',
319
+ '',
320
+ '```java',
321
+ '// 构造一个数据对象,传入对象 API 名称',
322
+ 'CCObject opp = new CCObject("Opportunity");',
323
+ '',
324
+ '// 构造一个共享表对象',
325
+ 'CCObject oppshare = new CCObject("Opportunity", CCObject.IS_SHARED);',
326
+ '',
327
+ '// 赋值',
328
+ 'opp.put("name", "value");',
329
+ '```',
330
+ '',
331
+ '---',
332
+ '',
333
+ '## 5. 自定义类与其他模块的配合',
334
+ '',
335
+ '### 5.1 触发器中使用类',
336
+ '',
337
+ '- 触发器可以直接调用自定义类中的方法,也可以直接使用 `CCService`。 ',
338
+ '- 触发器由 CloudCC 平台动态编译,调用写法与普通 Java 方法调用类似。',
339
+ '- 典型模式:',
340
+ ' - 在触发器中只做入口和参数准备',
341
+ ' - 将复杂逻辑委托给自定义类方法',
342
+ '',
343
+ '(触发器具体语法与最佳实践详见 `custom-trigger-dev.md`。)',
344
+ '',
345
+ '### 5.2 自定义类调用其他自定义类(PageClsInvoker)',
346
+ '',
347
+ '> 当需要在一个自定义类中调用另一个自定义类的方法时,可使用 `PageClsInvoker` 的 `invoker` 方法。',
348
+ '',
349
+ '`invoker` 有两个常用重载:',
350
+ '',
351
+ '```java',
352
+ 'Object invoker(String className, String method, List<Map> conlist, List<Map> arglist);',
353
+ 'Object invoker(String className, String method, List<Map> conlist, Map map);',
354
+ '```',
355
+ '',
356
+ '参数说明:',
357
+ '- `className`:目标自定义类名称',
358
+ '- `method`:要调用的方法名',
359
+ '- `conlist`:构造器参数列表(可为 `null`)',
360
+ ' - 每个 Map 包含:',
361
+ ' - `argType`:参数类型',
362
+ ' - `argValue`:参数值',
363
+ '- `arglist` / `map`:方法参数',
364
+ ' - 同样包含 `argType` 和 `argValue`',
365
+ '',
366
+ '#### 5.2.1 使用 Map 作为方法参数',
367
+ '',
368
+ '目标类:',
369
+ '',
370
+ '```java',
371
+ 'public class Hello {',
372
+ '',
373
+ ' public Hello() {}',
374
+ '',
375
+ ' public Hello(UserInfo userInfo) {',
376
+ ' System.out.print("测试");',
377
+ ' }',
378
+ '',
379
+ ' public void test5(Map map) throws Exception {',
380
+ ' System.out.print("获取 map 中的值" + map.get("name"));',
381
+ ' }',
382
+ '}',
383
+ '```',
384
+ '',
385
+ '调用方:',
386
+ '',
387
+ '```java',
388
+ 'List<Map> conlist = new ArrayList<Map>();',
389
+ '',
390
+ 'Map c = new HashMap();',
391
+ 'c.put("argType", UserInfo.class);',
392
+ 'c.put("argValue", userInfo);',
393
+ 'conlist.add(c);',
394
+ '',
395
+ 'Map m = new HashMap();',
396
+ 'm.put("name", "Alex");',
397
+ '',
398
+ 'new PageClsInvoker(userInfo).invoker("Hello", "test5", conlist, m);',
399
+ '```',
400
+ '',
401
+ '#### 5.2.2 使用 List<Map> 作为方法参数列表',
402
+ '',
403
+ '目标类:',
404
+ '',
405
+ '```java',
406
+ 'public class Hello {',
407
+ '',
408
+ ' public Hello() {}',
409
+ '',
410
+ ' public ServiceResult test3(UserInfo userInfo, String leadName) throws Exception {',
411
+ ' CCService cs = new CCService((UserInfo) userInfo);',
412
+ ' CCObject co = new CCObject("Lead");',
413
+ ' co.put("name", leadName);',
414
+ ' ServiceResult sr = cs.insert(co);',
415
+ ' return sr;',
416
+ ' }',
417
+ '}',
418
+ '```',
419
+ '',
420
+ '调用方:',
421
+ '',
422
+ '```java',
423
+ 'List<Map> arglist = new ArrayList<Map>();',
424
+ '',
425
+ 'Map u = new HashMap();',
426
+ 'u.put("argType", UserInfo.class);',
427
+ 'u.put("argValue", userInfo);',
428
+ 'arglist.add(u);',
429
+ '',
430
+ 'Map n = new HashMap();',
431
+ 'n.put("argType", String.class);',
432
+ 'n.put("argValue", "Alex");',
433
+ 'arglist.add(n);',
434
+ '',
435
+ 'new PageClsInvoker(userInfo).invoker("Hello", "test3", null, arglist);',
436
+ '```',
437
+ '',
438
+ '---',
439
+ '',
440
+ '## 6. 自定义类开发 Checklist',
441
+ '',
442
+ '- [ ] 类名、方法名与调用方(按钮/触发器/组件/定时作业)约定一致 ',
443
+ '- [ ] 构造函数正确接收 `UserInfo` 并实例化 `CCService` 等依赖 ',
444
+ '- [ ] 所有 `CCService` 操作(`insert`/`update`/`delete`/`cquery`)使用正确的对象 API 名称和字段 API 名称(自定义字段加 `__c`) ',
445
+ '- [ ] 访问共享表时,表达式中的字段未错误地添加 `__c` 后缀 ',
446
+ '- [ ] 涉及时间处理的逻辑统一使用 `TimeUtil`,避免时区问题 ',
447
+ '- [ ] 异常统一捕获并按需抛出,同时使用 `DevLogger` 记录关键错误信息 ',
448
+ '- [ ] 使用 `SendEmail` 时确认收件地址与内容来源安全可靠 ',
449
+ '- [ ] 使用 `PageClsInvoker` 跨类调用时,`argType` 与 `argValue` 类型匹配 ',
450
+ '- [ ] 对外暴露的方法返回结构(如 `JSONObject`)与前端/调用方约定一致,字段清晰、语义明确 ',
451
+ ];
452
+
453
+ const base = lines.join("\n");
454
+ const sdkPath = path.join(__dirname, "..", "api", "backend-sdk-java.md");
455
+ let sdkContent = "";
456
+ try {
457
+ sdkContent = fs.readFileSync(sdkPath, "utf8");
458
+ } catch (e) {
459
+ sdkContent = `# CloudCC 后端 SDK(Java)使用指南\n\n(未找到文件:${sdkPath})\n`;
460
+ }
461
+
462
+ return [
463
+ base,
464
+ "",
465
+ "---",
466
+ "",
467
+ "## 附录:后端 SDK(Java)速查",
468
+ "",
469
+ "> 来源:`src/api/backend-sdk-java.md`",
470
+ "",
471
+ sdkContent.trim(),
472
+ "",
473
+ ].join("\n");
474
+ }
475
+
476
+ function doc() {
477
+ const content = generateFullMarkdownDoc();
478
+ console.log(content);
479
+ return content;
480
+ }
481
+
482
+ // 兼容旧调用方:统一指向同一个方法(仍返回全量文档)
483
+ doc.getClassEditorDoc = doc;
484
+ doc.getEditGuide = doc;
485
+
486
+ module.exports = doc;
@@ -5,6 +5,7 @@ cc.pull = require("./pull")
5
5
  cc.get = require("./get")
6
6
  cc.pullList = require("./pullList")
7
7
  cc.detail = require("./detail")
8
+ cc.doc = require("./doc")
8
9
  function Classes(action, argvs) {
9
10
  cc[action](argvs[2], argvs[3])
10
11
  }
@@ -0,0 +1,61 @@
1
+ const path = require("path");
2
+ const { spawnSync } = require("child_process");
3
+
4
+ function runCcCommand(args, options = {}) {
5
+ const { cwd = process.cwd(), timeoutMs = 120000 } = options;
6
+ const ccEntry = path.resolve(__dirname, "../../bin/cc.js");
7
+
8
+ const result = spawnSync(process.execPath, [ccEntry, ...args], {
9
+ cwd,
10
+ encoding: "utf8",
11
+ timeout: timeoutMs,
12
+ maxBuffer: 10 * 1024 * 1024
13
+ });
14
+
15
+ const stdout = (result.stdout || "").trim();
16
+ const stderr = (result.stderr || "").trim();
17
+ const hasError = Boolean(result.error);
18
+ const code = typeof result.status === "number" ? result.status : -1;
19
+
20
+ return {
21
+ success: !hasError && code === 0,
22
+ code,
23
+ stdout,
24
+ stderr,
25
+ error: hasError ? result.error.message : ""
26
+ };
27
+ }
28
+
29
+ function buildRunDetail(runResult) {
30
+ return [runResult.error, runResult.stderr, runResult.stdout].filter(Boolean).join("\n");
31
+ }
32
+
33
+ function runCcJsonCommand(args, options = {}) {
34
+ const runResult = runCcCommand(args, options);
35
+ if (!runResult.success) {
36
+ return {
37
+ success: false,
38
+ runResult,
39
+ detail: buildRunDetail(runResult),
40
+ data: null
41
+ };
42
+ }
43
+
44
+ try {
45
+ const data = runResult.stdout ? JSON.parse(runResult.stdout) : null;
46
+ return { success: true, runResult, detail: "", data };
47
+ } catch (error) {
48
+ return {
49
+ success: false,
50
+ runResult,
51
+ detail: `JSON 解析失败: ${error.message}\n${buildRunDetail(runResult)}`,
52
+ data: null
53
+ };
54
+ }
55
+ }
56
+
57
+ module.exports = {
58
+ runCcCommand,
59
+ runCcJsonCommand,
60
+ buildRunDetail
61
+ };
package/src/mcp/index.js CHANGED
@@ -11,7 +11,6 @@ const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js");
11
11
  const { z } = require("zod");
12
12
 
13
13
  // 导入各个工具的处理器
14
- const ccdkHandler = require("./tools/ccdk/handler.js");
15
14
  const devEnvHandler = require("./tools/Dev Environment Creator/handler.js");
16
15
  const keyGuideHandler = require("./tools/Developer Key Setup Guide/handler.js");
17
16
  const devEnvValidatorHandler = require("./tools/Dev Environment Validator/handler.js");
@@ -52,12 +51,13 @@ const componentEditorGuideHandler = require('./tools/Component Editor Guide/hand
52
51
  const componentPullerHandler = require('./tools/Component Puller/handler.js');
53
52
  const componentPublisherHandler = require('./tools/Component Publisher/handler.js');
54
53
  // 客户端脚本工具处理器
55
- const clientScriptCreatorHandler = require('./tools/Client Script Creator/handler.js');
56
54
  const clientScriptListHandler = require('./tools/Client Script List Retriever/handler.js');
57
55
  const clientScriptDetailHandler = require('./tools/Client Script Detail Retriever/handler.js');
58
56
  const clientScriptEditorGuideHandler = require('./tools/Client Script Editor Guide/handler.js');
59
57
  const clientScriptPullerHandler = require('./tools/Client Script Puller/handler.js');
60
58
  const clientScriptPublisherHandler = require('./tools/Client Script Publisher/handler.js');
59
+ // JSP 迁移工具处理器
60
+ const jspMigratorHandler = require('./tools/JSP Migrator/handler.js');
61
61
  // CloudCC 开发项目概要工具处理器
62
62
  const cloudccOverviewHandler = require('./tools/CloudCC Development Overview/handler.js');
63
63
 
@@ -462,7 +462,7 @@ mcpServer.registerTool(
462
462
  mcpServer.registerTool(
463
463
  'publish_custom_component',
464
464
  {
465
- description: '将 Vue 自定义组件编译并发布到 CloudCC 服务器,必须使用返回的命令,在控制台执行',
465
+ description: '将 Vue 自定义组件编译并发布到 CloudCC 服务器',
466
466
  inputSchema: z.object({
467
467
  componentName: z.string().min(1).describe('要发布的组件名称'),
468
468
  projectPath: z.string().optional().describe('项目根目录路径,默认为当前工作目录')
@@ -662,4 +662,42 @@ mcpServer.registerTool(
662
662
  cloudccOverviewHandler.getCloudCCDevelopmentOverview
663
663
  );
664
664
 
665
+ // ==================== JSP Migration Analyzer 工具 ====================
666
+ mcpServer.registerTool(
667
+ 'analyze_jsp_migration',
668
+ {
669
+ description: '分析旧 JSP 页面,提取 reason 分支、对象依赖和迁移风险,输出迁移报告(不落地代码)。',
670
+ inputSchema: z.object({
671
+ jspPath: z.string().min(1).describe('JSP 文件路径(绝对路径或相对 projectPath)'),
672
+ helpDocPath: z.string().optional().describe('帮助文档路径(可选),如 jspTemp/帮助文档.md'),
673
+ projectPath: z.string().optional().describe('项目根路径,默认当前工作目录'),
674
+ className: z.string().optional().describe('可选,指定生成类名'),
675
+ componentName: z.string().optional().describe('可选,指定生成组件名'),
676
+ outputProjectPath: z.string().optional().describe('可选,输出项目路径,默认等于 projectPath'),
677
+ reportDir: z.string().optional().describe('可选,报告目录,默认 migration-report')
678
+ })
679
+ },
680
+ jspMigratorHandler.analyzeJspMigration
681
+ );
682
+
683
+ // ==================== JSP Splitter 工具 ====================
684
+ mcpServer.registerTool(
685
+ 'split_jsp_to_cloudcc',
686
+ {
687
+ description: '将旧 JSP 页面拆分为 CloudCC 自定义类和自定义组件,并生成迁移报告。支持 apply/dry-run 两种模式。',
688
+ inputSchema: z.object({
689
+ jspPath: z.string().min(1).describe('JSP 文件路径(绝对路径或相对 projectPath)'),
690
+ helpDocPath: z.string().optional().describe('帮助文档路径(可选),如 jspTemp/帮助文档.md'),
691
+ projectPath: z.string().optional().describe('项目根路径,默认当前工作目录'),
692
+ outputProjectPath: z.string().optional().describe('输出项目路径,默认等于 projectPath'),
693
+ className: z.string().optional().describe('可选,指定生成类名'),
694
+ componentName: z.string().optional().describe('可选,指定生成组件名'),
695
+ reportDir: z.string().optional().describe('可选,报告目录,默认 migration-report'),
696
+ mode: z.enum(['apply', 'dry-run']).optional().default('apply').describe('apply: 生成文件;dry-run: 仅分析'),
697
+ overwrite: z.boolean().optional().default(false).describe('是否覆盖已存在文件,默认 false')
698
+ })
699
+ },
700
+ jspMigratorHandler.splitJspToCloudcc
701
+ );
702
+
665
703
  module.exports = mcpServer;
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  const path = require('path');
7
- const createApplication = require('../../../application/create');
7
+ const { runCcCommand, buildRunDetail } = require('../../cliRunner');
8
8
 
9
9
  /**
10
10
  * 创建应用
@@ -33,7 +33,7 @@ async function createApplicationTool(params = {}) {
33
33
 
34
34
  // 构建参数数组,格式: ['create', 'application', path, p1, p2, duel1]
35
35
  // 注意:argvs[2] 是 path,argvs[3] 是 p1,argvs[4] 是 p2,argvs[5] 是 duel1
36
- const argvs = [
36
+ const args = [
37
37
  'create',
38
38
  'application',
39
39
  resolvedPath,
@@ -43,25 +43,23 @@ async function createApplicationTool(params = {}) {
43
43
 
44
44
  // 如果提供了 menuIds,添加到参数中
45
45
  if (menuIds) {
46
- argvs.push(menuIds);
46
+ args.push(menuIds);
47
47
  }
48
48
 
49
- // 调用创建函数
50
- const result = await createApplication(argvs);
49
+ const runResult = runCcCommand(args, { cwd: resolvedPath });
51
50
 
52
- if (result && result.result) {
53
- const appId = result.data?.COMMON_APPID || '未知';
51
+ if (runResult.success) {
54
52
  return {
55
53
  content: [{
56
54
  type: 'text',
57
- text: `✓ 应用创建成功!\n\n应用名称: ${appName}\n应用代码: ${appCode}\n应用ID: ${appId}\n项目目录: ${resolvedPath}\n菜单ID: ${menuIds || 'acf000001(默认)'}\n\n应用已成功创建并配置到 CloudCC 系统中。`
55
+ text: `✓ 应用创建成功!\n\n应用名称: ${appName}\n应用代码: ${appCode}\n项目目录: ${resolvedPath}\n菜单ID: ${menuIds || 'acf000001(默认)'}\n\n应用已成功创建并配置到 CloudCC 系统中。`
58
56
  }]
59
57
  };
60
58
  } else {
61
59
  return {
62
60
  content: [{
63
61
  type: 'text',
64
- text: `⚠ 应用创建遇到问题\n\n请检查:\n1. 应用名称和应用代码是否符合规范\n2. CloudCC服务器连接是否正常\n3. 项目配置是否正确\n4. 是否有足够的权限创建应用\n5. 菜单ID是否正确`
62
+ text: `⚠ 应用创建遇到问题\n\n${buildRunDetail(runResult) || 'cc 命令执行失败'}\n\n请检查:\n1. 应用名称和应用代码是否符合规范\n2. CloudCC服务器连接是否正常\n3. 项目配置是否正确\n4. 是否有足够的权限创建应用\n5. 菜单ID是否正确`
65
63
  }]
66
64
  };
67
65
  }