cloudcc-cli 2.2.5 → 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 (130) hide show
  1. package/.cloudcc-cache.json +38 -0
  2. package/README.md +1435 -522
  3. package/bin/cc.js +7 -2
  4. package/bin/index.js +4 -0
  5. package/java/com/cloudcc/core/BaseException.java +100 -0
  6. package/java/com/cloudcc/core/BusiException.java +43 -0
  7. package/java/com/cloudcc/core/CCService.java +3 -1
  8. package/java/com/cloudcc/core/StringUtils.java +7 -0
  9. package/java/com/cloudcc/core/TimeUtil.java +33 -0
  10. package/java/com/cloudcc/core/UserInfo.java +9 -0
  11. package/package.json +7 -1
  12. package/pom.xml +1 -1
  13. package/skill/BACKEND_CODE.md +114 -0
  14. package/skill/CLI_CHEATSHEET.md +90 -0
  15. package/skill/INSTALL_AND_BOOTSTRAP.md +59 -0
  16. package/skill/OBJECTS_AND_FIELDS.md +120 -0
  17. package/skill/REQUIREMENTS_BREAKDOWN.md +98 -0
  18. package/skill/SKILL.md +33 -0
  19. package/skill/VUE_CUSTOM_COMPONENT.md +50 -0
  20. package/src/api/backend-sdk-java.md +427 -0
  21. package/src/api/ccdk-sdk.md +1039 -0
  22. package/src/application/create.js +114 -0
  23. package/src/application/get.js +13 -0
  24. package/src/application/index.js +8 -0
  25. package/src/classes/doc.js +486 -0
  26. package/src/classes/index.js +1 -0
  27. package/src/mcp/cliRunner.js +61 -0
  28. package/src/mcp/index.js +84 -12
  29. package/src/mcp/readme.md +6 -3
  30. package/src/mcp/tools/Application Creator/handler.js +78 -0
  31. package/src/mcp/tools/Approval/handler.js +34 -151
  32. package/src/mcp/tools/Class Creator/handler.js +18 -15
  33. package/src/mcp/tools/Class Detail Retriever/handler.js +8 -9
  34. package/src/mcp/tools/Class Editor Guide/handler.js +5 -19
  35. package/src/mcp/tools/Class List Retriever/handler.js +8 -3
  36. package/src/mcp/tools/Class Publisher/handler.js +7 -9
  37. package/src/mcp/tools/Class Puller/handler.js +6 -65
  38. package/src/mcp/tools/Client Script Detail Retriever/handler.js +12 -18
  39. package/src/mcp/tools/Client Script Editor Guide/handler.js +9 -605
  40. package/src/mcp/tools/Client Script List Retriever/handler.js +30 -33
  41. package/src/mcp/tools/Client Script Publisher/handler.js +12 -11
  42. package/src/mcp/tools/Client Script Puller/handler.js +23 -30
  43. package/src/mcp/tools/CloudCC Development Overview/handler.js +11 -5
  44. package/src/mcp/tools/Component Creator/handler.js +12 -11
  45. package/src/mcp/tools/Component Detail Retriever/handler.js +12 -9
  46. package/src/mcp/tools/Component Editor Guide/handler.js +5 -22
  47. package/src/mcp/tools/Component List Retriever/handler.js +21 -18
  48. package/src/mcp/tools/Component Publisher/handler.js +25 -3
  49. package/src/mcp/tools/Component Puller/handler.js +13 -16
  50. package/src/mcp/tools/Dev Environment Creator/handler.js +5 -72
  51. package/src/mcp/tools/Dev Environment Validator/handler.js +5 -66
  52. package/src/mcp/tools/Developer Key Setup Guide/handler.js +11 -20
  53. package/src/mcp/tools/JSP Migrator/handler.js +842 -0
  54. package/src/mcp/tools/Menu Creator/handler.js +86 -0
  55. package/src/mcp/tools/Object Creator/handler.js +14 -6
  56. package/src/mcp/tools/Object Fields Creator/handler.js +9 -10
  57. package/src/mcp/tools/Object Fields Retriever/handler.js +6 -3
  58. package/src/mcp/tools/Object List Retriever/handler.js +10 -7
  59. package/src/mcp/tools/Scheduled Class Creator/handler.js +12 -16
  60. package/src/mcp/tools/Scheduled Class Detail Retriever/handler.js +7 -9
  61. package/src/mcp/tools/Scheduled Class List Retriever/handler.js +21 -23
  62. package/src/mcp/tools/Scheduled Class Publisher/handler.js +7 -9
  63. package/src/mcp/tools/Scheduled Class Puller/handler.js +6 -70
  64. package/src/mcp/tools/Trigger Creator/handler.js +12 -20
  65. package/src/mcp/tools/Trigger Detail Retriever/handler.js +7 -9
  66. package/src/mcp/tools/Trigger Editor Guide/handler.js +10 -35
  67. package/src/mcp/tools/Trigger List Retriever/handler.js +12 -4
  68. package/src/mcp/tools/Trigger Publisher/handler.js +8 -11
  69. package/src/mcp/tools/Trigger Puller/handler.js +12 -17
  70. package/src/menu/common.js +16 -0
  71. package/src/menu/create-object.js +94 -0
  72. package/src/menu/create-page.js +108 -0
  73. package/src/menu/create-script.js +108 -0
  74. package/src/menu/create-site.js +108 -0
  75. package/src/menu/create.js +54 -0
  76. package/src/menu/index.js +7 -0
  77. package/src/plugin/doc.js +801 -0
  78. package/src/plugin/index.js +1 -0
  79. package/src/plugin/pull.js +3 -0
  80. package/src/project/doc.js +378 -0
  81. package/src/project/index.js +1 -0
  82. package/src/script/doc.js +259 -0
  83. package/src/script/index.js +1 -0
  84. package/src/timer/index.js +1 -0
  85. package/src/triggers/doc.js +342 -0
  86. package/src/triggers/index.js +5 -0
  87. package/target/classes/com/cloudcc/core/BaseException.class +0 -0
  88. package/target/classes/com/cloudcc/core/BusiException.class +0 -0
  89. package/target/classes/com/cloudcc/core/CCService.class +0 -0
  90. package/target/classes/com/cloudcc/core/StringUtils.class +0 -0
  91. package/target/classes/com/cloudcc/core/TimeUtil.class +0 -0
  92. package/target/classes/com/cloudcc/core/UserInfo.class +0 -0
  93. package/template/lib/ccopenapi-0.0.4.jar +0 -0
  94. package/test/application.cli.test.js +30 -0
  95. package/test/classes.cli.test.js +121 -0
  96. package/test/fields.cli.test.js +69 -0
  97. package/test/mcp.cli.test.js +21 -0
  98. package/test/menu.cli.test.js +41 -0
  99. package/test/object.cli.test.js +64 -0
  100. package/test/plugin.cli.test.js +109 -0
  101. package/test/script.cli.test.js +101 -0
  102. package/test/timer.cli.test.js +107 -0
  103. package/test/trigger.cli.test.js +146 -0
  104. package/.vscode/settings.json +0 -3
  105. package/bin/mcp-svc.js +0 -13
  106. package/src/mcp/MCP/345/234/272/346/231/257/346/250/241/346/213/237.md +0 -8
  107. package/src/mcp/index-sse-svc.js +0 -126
  108. package/src/mcp/index-streamable-svc.js +0 -180
  109. package/src/mcp/tools/Class Detail Retriever/prompt.js +0 -37
  110. package/src/mcp/tools/Class Editor Guide/prompt.js +0 -468
  111. package/src/mcp/tools/Class Publisher/prompt.js +0 -40
  112. package/src/mcp/tools/Class Puller/prompt.js +0 -49
  113. package/src/mcp/tools/Client Script Creator/handler.js +0 -179
  114. package/src/mcp/tools/CloudCC Development Overview/prompt.js +0 -870
  115. package/src/mcp/tools/Component Editor Guide/prompt.js +0 -519
  116. package/src/mcp/tools/Component Publisher/prompt.js +0 -659
  117. package/src/mcp/tools/Dev Environment Creator/prompt.js +0 -273
  118. package/src/mcp/tools/Dev Environment Validator/prompt.js +0 -193
  119. package/src/mcp/tools/Developer Key Setup Guide/prompt.js +0 -71
  120. package/src/mcp/tools/Object Fields Retriever/prompt.js +0 -10
  121. package/src/mcp/tools/Object List Retriever/prompt.js +0 -10
  122. package/src/mcp/tools/ccdk/fetcher.js +0 -18
  123. package/src/mcp/tools/ccdk/handler.js +0 -98
  124. package/src/mcp/tools/ccdk/prompt.js +0 -453
  125. package/target/ccopenapi-0.0.3-classes.jar +0 -0
  126. package/target/ccopenapi-0.0.3.jar +0 -0
  127. package/target/maven-archiver/pom.properties +0 -3
  128. package/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +0 -18
  129. package/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +0 -19
  130. package/template/lib/ccopenapi-0.0.3.jar +0 -0
@@ -0,0 +1,114 @@
1
+ const { postClass } = require("../../utils/http")
2
+ const { getPackageJson } = require("../../utils/config");
3
+ const briefGet = require("../brief/get");
4
+ const chalk = require('chalk')
5
+
6
+ /**
7
+ * 创建应用(Application)
8
+ * @param {Array} argvs - 命令行参数数组
9
+ * @returns {Promise<Object>} 创建结果
10
+ */
11
+ async function create(argvs) {
12
+ try {
13
+ // 命令行参数格式:cc create application <path> <p1> <p2> [duel1]
14
+ // argvs: ['application', 'create', path, p1, p2, duel1]
15
+ let path = argvs[2];
16
+ let p1 = argvs[3]; // 应用名称
17
+ let p2 = argvs[4]; // 应用代码
18
+ let duel1 = argvs[5]; // 菜单ID,多个时用逗号分隔,可选,默认为 "acf000001"
19
+
20
+ // 验证必需参数
21
+ if (!p1 || !p2) {
22
+ console.error();
23
+ console.error(chalk.red('Error: 缺少必需参数'));
24
+ console.error('用法: cc create application <path> <p1> <p2> [duel1]');
25
+ console.error(' path: 项目路径');
26
+ console.error(' p1: 应用名称');
27
+ console.error(' p2: 应用代码');
28
+ console.error(' duel1: 菜单ID(可选,多个时用逗号分隔,默认: acf000001)');
29
+ console.error();
30
+ throw new Error('缺少必需参数: p1 和 p2');
31
+ }
32
+
33
+ // 处理 duel1,确保始终包含 acf000001
34
+ const REQUIRED_MENU_ID = "acf000001";
35
+ if (!duel1) {
36
+ // 如果没有传入,使用默认值
37
+ duel1 = REQUIRED_MENU_ID;
38
+ } else {
39
+ // 如果传入了,确保 acf000001 在列表中
40
+ const menuIds = duel1.split(',').map(id => id.trim()).filter(id => id);
41
+ if (!menuIds.includes(REQUIRED_MENU_ID)) {
42
+ // 如果列表中没有 acf000001,添加到列表开头
43
+ menuIds.unshift(REQUIRED_MENU_ID);
44
+ }
45
+ duel1 = menuIds.join(',');
46
+ }
47
+
48
+ let config = await getPackageJson(path);
49
+
50
+ // 从 brief/get 获取角色ID列表(仍使用原始 argv 参数: path 位于 argvs[2])
51
+ // 注意:brief/get 的接口返回是 { success, data } 的格式
52
+ let briefData = await briefGet(argvs);
53
+
54
+ if (!briefData.success) {
55
+ console.error("获取角色列表失败:", briefData.message);
56
+ throw new Error("获取角色列表失败");
57
+ }
58
+
59
+ // 提取所有角色的 ID 列表,用逗号连接
60
+ const profileIdList = briefData.data.map(profile => profile.id);
61
+ const p12 = profileIdList.join(',');
62
+
63
+ // 构建请求体,使用用户提供的参数结构
64
+ const requestBody = {
65
+ "visited_0": "1",
66
+ "visited_1": "1",
67
+ "setupid": "TabSet",
68
+ "apptype": "app",
69
+ "p1": p1,
70
+ "p2": p2,
71
+ "p3": "",
72
+ "navigationStyle": "1",
73
+ "jump": "1",
74
+ "p4": "",
75
+ "appstyle": 21,
76
+ "p8": "home",
77
+ "duel1": duel1,
78
+ "visited_2": "1",
79
+ "visited_3": "1",
80
+ "p12": p12
81
+ };
82
+
83
+ // 显示创建进度
84
+ console.error();
85
+ console.error(chalk.green('Creating application, please wait...'));
86
+ console.error();
87
+
88
+ // 发送请求到服务器
89
+ const result = await postClass(
90
+ config.setupSvc + "/api/appProgram/tabSetDone",
91
+ requestBody,
92
+ config.accessToken
93
+ );
94
+
95
+ // API 返回结构中, result 字段决定调用是否成功
96
+ if (result && result.result) {
97
+ console.error();
98
+ console.error(chalk.green('Success!'));
99
+ console.error();
100
+ return result;
101
+ } else {
102
+ const msg = result && result.returnInfo ? result.returnInfo : 'Unknown error';
103
+ console.error();
104
+ console.error(chalk.red('Error:' + msg));
105
+ throw new Error('Create Application Failed: ' + msg);
106
+ }
107
+ } catch (error) {
108
+ console.error();
109
+ console.error(chalk.red("应用创建失败:"), error);
110
+ throw error;
111
+ }
112
+ }
113
+
114
+ module.exports = create;
@@ -0,0 +1,13 @@
1
+ const { postClass } = require("../../utils/http")
2
+ const { getPackageJson } = require("../../utils/config")
3
+
4
+ async function get(argvs, isMcp = false) {
5
+ // TODO: 实现获取应用列表的功能
6
+ let res = [];
7
+ if (!isMcp) {
8
+ console.log(JSON.stringify(res));
9
+ }
10
+ return res
11
+ }
12
+
13
+ module.exports = get;
@@ -0,0 +1,8 @@
1
+ const cc = {}
2
+ cc.get = require("./get")
3
+ cc.create = require("./create")
4
+ function main(action, argvs) {
5
+ cc[action](argvs)
6
+ }
7
+
8
+ module.exports = main;
@@ -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
  }