cloudcc-cli 2.3.1 → 2.3.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 (232) hide show
  1. package/.claude/settings.json +25 -0
  2. package/.cloudcc-cache.json +21 -4
  3. package/.cursor/skills/cloudcc-cli-dev.zip +0 -0
  4. package/.cursor/skills/cloudcc-cli-usage/SKILL.md +68 -0
  5. package/README.md +22 -0
  6. package/bin/cc.js +13 -8
  7. package/bin/index.js +9 -2
  8. package/bin/mcp.js +1 -1
  9. package/build/component-CCPlugin1774500425584.common.js +831 -0
  10. package/build/component-CCPlugin1774500425584.common.js.map +1 -0
  11. package/build/component-CCPlugin1774500425584.css +1 -0
  12. package/build/component-CCPlugin1774500425584.umd.js +874 -0
  13. package/build/component-CCPlugin1774500425584.umd.js.map +1 -0
  14. package/build/component-CCPlugin1774500425584.umd.min.js +8 -0
  15. package/build/component-CCPlugin1774500425584.umd.min.js.map +1 -0
  16. package/build/demo.html +1 -0
  17. package/{src/mcp → mcp}/tools/Class Editor Guide/handler.js +12 -4
  18. package/{src/mcp → mcp}/tools/Component Editor Guide/handler.js +15 -14
  19. package/{src/mcp → mcp}/tools/Trigger Editor Guide/handler.js +8 -2
  20. package/package.json +3 -2
  21. package/src/application/doc.js +46 -0
  22. package/src/application/docs/devguide.md +173 -0
  23. package/src/application/docs/introduction.md +81 -0
  24. package/src/application/index.js +1 -0
  25. package/src/brief/get.js +1 -1
  26. package/src/classes/create.js +6 -1
  27. package/src/classes/delete.js +7 -1
  28. package/src/classes/detail.js +8 -1
  29. package/src/classes/doc.js +49 -472
  30. package/src/classes/docs/devguide.md +541 -0
  31. package/src/classes/get.js +9 -2
  32. package/src/classes/index.js +2 -1
  33. package/src/classes/publish.js +6 -1
  34. package/src/classes/pull.js +6 -1
  35. package/src/classes/pullList.js +6 -3
  36. package/src/config/doc.js +31 -0
  37. package/src/config/docs/devguide.md +100 -0
  38. package/src/config/index.js +5 -0
  39. package/src/customPage/create.js +52 -19
  40. package/src/customPage/doc.js +46 -0
  41. package/src/customPage/docs/devguide.md +200 -0
  42. package/{.cursor/skills/cloudcc-cli-dev/docs//350/207/252/345/256/232/344/271/211/351/241/265/351/235/242.md → src/customPage/docs/introduction.md} +1 -5
  43. package/src/customPage/index.js +1 -0
  44. package/src/customSetting/create.js +9 -0
  45. package/src/customSetting/delete.js +10 -1
  46. package/src/customSetting/deleteCustomSettingField.js +43 -0
  47. package/src/customSetting/detail.js +10 -1
  48. package/src/customSetting/doc.js +22 -179
  49. package/src/customSetting/docs/devguide.md +181 -0
  50. package/src/customSetting/docs/introduction.md +3 -0
  51. package/src/customSetting/editCustomSettingField.js +34 -0
  52. package/src/customSetting/get.js +9 -0
  53. package/src/customSetting/index.js +6 -1
  54. package/src/customSetting/modify.js +30 -0
  55. package/src/customSetting/saveCustomSettingField.js +46 -0
  56. package/src/fields/doc.js +45 -0
  57. package/src/fields/docs/devguide.md +224 -0
  58. package/src/fields/docs/introduction.md +217 -0
  59. package/src/fields/index.js +1 -0
  60. package/src/globalSelectList/create.js +51 -0
  61. package/src/globalSelectList/delete.js +56 -0
  62. package/src/globalSelectList/detail.js +45 -0
  63. package/src/globalSelectList/doc.js +52 -0
  64. package/src/globalSelectList/docs/devguide.md +153 -0
  65. package/src/globalSelectList/docs/introduction.md +82 -0
  66. package/src/globalSelectList/get.js +31 -0
  67. package/src/globalSelectList/index.js +16 -0
  68. package/src/menu/create-page.js +43 -6
  69. package/src/menu/create-script.js +67 -19
  70. package/src/menu/doc.js +57 -0
  71. package/src/menu/docs/devguide.md +129 -0
  72. package/src/menu/docs/introduction.md +99 -0
  73. package/src/menu/index.js +1 -0
  74. package/src/menu/validator.js +80 -0
  75. package/src/object/doc.js +45 -0
  76. package/src/object/docs/devguide.md +112 -0
  77. package/src/object/docs/introduction.md +187 -0
  78. package/src/object/get.js +1 -23
  79. package/src/object/index.js +1 -0
  80. package/src/pagelayout/create.js +123 -0
  81. package/src/pagelayout/delete.js +57 -0
  82. package/src/pagelayout/doc.js +46 -0
  83. package/src/pagelayout/docs/devguide.md +83 -0
  84. package/src/pagelayout/docs/introduction.md +44 -0
  85. package/src/pagelayout/get.js +46 -0
  86. package/src/pagelayout/index.js +10 -0
  87. package/src/plugin/doc.js +43 -863
  88. package/src/plugin/docs/devguide.md +996 -0
  89. package/src/profile/create.js +108 -0
  90. package/src/profile/delete.js +59 -0
  91. package/src/profile/doc.js +46 -0
  92. package/src/profile/docs/devguide.md +77 -0
  93. package/src/profile/docs/introduction.md +123 -0
  94. package/src/profile/get.js +55 -0
  95. package/src/profile/index.js +14 -0
  96. package/src/project/doc.js +39 -372
  97. package/src/project/docs/devguide.md +359 -0
  98. package/src/project/docs/introduction.md +3 -0
  99. package/src/recordType/create.js +77 -0
  100. package/src/recordType/delete.js +52 -0
  101. package/src/recordType/doc.js +36 -0
  102. package/src/recordType/docs/devguide.md +160 -0
  103. package/src/recordType/docs/introduction.md +53 -0
  104. package/src/recordType/editInfo.js +39 -0
  105. package/src/recordType/editSave.js +47 -0
  106. package/src/recordType/getList.js +31 -0
  107. package/src/recordType/index.js +16 -3
  108. package/src/recordType/newInfo.js +39 -0
  109. package/src/recordType/validDelete.js +91 -0
  110. package/src/res.md +66 -0
  111. package/src/role/create.js +153 -0
  112. package/src/role/delete.js +59 -0
  113. package/src/role/doc.js +46 -0
  114. package/src/role/docs/devguide.md +81 -0
  115. package/src/role/docs/introduction.md +124 -0
  116. package/src/role/get.js +57 -0
  117. package/src/role/index.js +10 -0
  118. package/src/scheduleJob/doc.js +49 -0
  119. package/src/scheduleJob/docs/devguide.md +79 -0
  120. package/src/scheduleJob/docs/introduction.md +101 -0
  121. package/src/scheduleJob/index.js +5 -0
  122. package/src/script/delete.js +112 -0
  123. package/src/script/doc.js +31 -245
  124. package/src/script/docs/devguide.md +290 -0
  125. package/src/script/docs/introduction.md +48 -0
  126. package/src/script/index.js +1 -0
  127. package/src/staticResource/count.js +31 -10
  128. package/src/staticResource/create.js +97 -0
  129. package/src/staticResource/delete.js +30 -8
  130. package/src/staticResource/detail.js +32 -10
  131. package/src/staticResource/doc.js +21 -88
  132. package/src/staticResource/docs/devguide.md +157 -0
  133. package/src/staticResource/docs/introduction.md +3 -0
  134. package/src/staticResource/get.js +31 -8
  135. package/src/staticResource/index.js +2 -1
  136. package/src/timer/create.js +6 -1
  137. package/src/timer/delete.js +7 -1
  138. package/src/timer/detail.js +5 -5
  139. package/src/timer/doc.js +57 -0
  140. package/{.cursor/skills/cloudcc-cli-dev/docs/cloudcc/345/256/232/346/227/266/344/275/234/344/270/232.md → src/timer/docs/devguide.md} +83 -1
  141. package/src/timer/get.js +7 -1
  142. package/src/timer/index.js +3 -1
  143. package/src/timer/publish.js +6 -1
  144. package/src/timer/pull.js +6 -1
  145. package/src/timer/pullList.js +5 -3
  146. package/src/triggers/detail.js +5 -5
  147. package/src/triggers/doc.js +49 -364
  148. package/src/triggers/docs/devguide.md +442 -0
  149. package/src/triggers/get.js +7 -3
  150. package/src/triggers/index.js +1 -4
  151. package/src/triggers/pullList.js +7 -7
  152. package/src/user/create.js +50 -0
  153. package/src/user/delete.js +59 -0
  154. package/src/user/doc.js +46 -0
  155. package/src/user/docs/devguide.md +122 -0
  156. package/src/user/docs/introduction.md +124 -0
  157. package/src/user/get.js +112 -0
  158. package/src/user/index.js +12 -0
  159. package/src/user/update.js +96 -0
  160. package/src/user/view.js +60 -0
  161. package/test/classes.cli.test.js +7 -4
  162. package/test/customPage.cli.test.js +96 -0
  163. package/test/globalSelectList.cli.test.js +94 -0
  164. package/test/menu-script.cli.test.js +147 -0
  165. package/test/menu.cli.test.js +8 -1
  166. package/test/plugin.cli.test.js +5 -3
  167. package/test/timer.cli.test.js +15 -8
  168. package/test/trigger.cli.test.js +5 -3
  169. package/.cursor/skills/cloudcc-cli-dev/BACKEND_CLASS.md +0 -111
  170. package/.cursor/skills/cloudcc-cli-dev/BACKEND_SCHEDULE.md +0 -152
  171. package/.cursor/skills/cloudcc-cli-dev/BACKEND_TRIGGER.md +0 -150
  172. package/.cursor/skills/cloudcc-cli-dev/CLI_CHEATSHEET.md +0 -372
  173. package/.cursor/skills/cloudcc-cli-dev/CUSTOM-SETTING-API.md +0 -62
  174. package/.cursor/skills/cloudcc-cli-dev/INSTALL_AND_BOOTSTRAP.md +0 -62
  175. package/.cursor/skills/cloudcc-cli-dev/OBJECTS_AND_FIELDS.md +0 -214
  176. package/.cursor/skills/cloudcc-cli-dev/REQUIREMENTS_BREAKDOWN.md +0 -113
  177. package/.cursor/skills/cloudcc-cli-dev/SKILL.md +0 -66
  178. package/.cursor/skills/cloudcc-cli-dev/STATIC-RESOURCE-API.md +0 -60
  179. package/.cursor/skills/cloudcc-cli-dev/VUE_CUSTOM_COMPONENT.md +0 -151
  180. package/.cursor/skills/cloudcc-cli-dev/VUE_CUSTOM_PAGE.md +0 -216
  181. package/src/approval/approve.js +0 -105
  182. package/src/approval/get.js +0 -245
  183. package/src/approval/index.js +0 -11
  184. package/src/approval/reject.js +0 -105
  185. package/src/plugin/readme.md +0 -7
  186. /package/{src/mcp → mcp}/cliRunner.js +0 -0
  187. /package/{src/mcp → mcp}/index.js +0 -0
  188. /package/{src/mcp → mcp}/readme.md +0 -0
  189. /package/{src/mcp → mcp}/tools/Application Creator/handler.js +0 -0
  190. /package/{src/mcp → mcp}/tools/Approval/handler.js +0 -0
  191. /package/{src/mcp → mcp}/tools/Class Creator/handler.js +0 -0
  192. /package/{src/mcp → mcp}/tools/Class Detail Retriever/handler.js +0 -0
  193. /package/{src/mcp → mcp}/tools/Class List Retriever/handler.js +0 -0
  194. /package/{src/mcp → mcp}/tools/Class Publisher/handler.js +0 -0
  195. /package/{src/mcp → mcp}/tools/Class Puller/handler.js +0 -0
  196. /package/{src/mcp → mcp}/tools/Client Script Detail Retriever/handler.js +0 -0
  197. /package/{src/mcp → mcp}/tools/Client Script Editor Guide/handler.js +0 -0
  198. /package/{src/mcp → mcp}/tools/Client Script List Retriever/handler.js +0 -0
  199. /package/{src/mcp → mcp}/tools/Client Script Publisher/handler.js +0 -0
  200. /package/{src/mcp → mcp}/tools/Client Script Puller/handler.js +0 -0
  201. /package/{src/mcp → mcp}/tools/CloudCC Development Overview/handler.js +0 -0
  202. /package/{src/mcp → mcp}/tools/Component Creator/handler.js +0 -0
  203. /package/{src/mcp → mcp}/tools/Component Detail Retriever/handler.js +0 -0
  204. /package/{src/mcp → mcp}/tools/Component List Retriever/handler.js +0 -0
  205. /package/{src/mcp → mcp}/tools/Component Publisher/handler.js +0 -0
  206. /package/{src/mcp → mcp}/tools/Component Puller/handler.js +0 -0
  207. /package/{src/mcp → mcp}/tools/Dev Environment Creator/fetcher.js +0 -0
  208. /package/{src/mcp → mcp}/tools/Dev Environment Creator/handler.js +0 -0
  209. /package/{src/mcp → mcp}/tools/Dev Environment Validator/handler.js +0 -0
  210. /package/{src/mcp → mcp}/tools/Developer Key Setup Guide/fetcher.js +0 -0
  211. /package/{src/mcp → mcp}/tools/Developer Key Setup Guide/handler.js +0 -0
  212. /package/{src/mcp → mcp}/tools/JSP Migrator/handler.js +0 -0
  213. /package/{src/mcp → mcp}/tools/Menu Creator/handler.js +0 -0
  214. /package/{src/mcp → mcp}/tools/Object Creator/handler.js +0 -0
  215. /package/{src/mcp → mcp}/tools/Object Fields Creator/handler.js +0 -0
  216. /package/{src/mcp → mcp}/tools/Object Fields Retriever/handler.js +0 -0
  217. /package/{src/mcp → mcp}/tools/Object List Retriever/handler.js +0 -0
  218. /package/{src/mcp → mcp}/tools/Scheduled Class Creator/handler.js +0 -0
  219. /package/{src/mcp → mcp}/tools/Scheduled Class Detail Retriever/handler.js +0 -0
  220. /package/{src/mcp → mcp}/tools/Scheduled Class List Retriever/handler.js +0 -0
  221. /package/{src/mcp → mcp}/tools/Scheduled Class Publisher/handler.js +0 -0
  222. /package/{src/mcp → mcp}/tools/Scheduled Class Puller/handler.js +0 -0
  223. /package/{src/mcp → mcp}/tools/Trigger Creator/handler.js +0 -0
  224. /package/{src/mcp → mcp}/tools/Trigger Detail Retriever/handler.js +0 -0
  225. /package/{src/mcp → mcp}/tools/Trigger List Retriever/handler.js +0 -0
  226. /package/{src/mcp → mcp}/tools/Trigger Publisher/handler.js +0 -0
  227. /package/{src/mcp → mcp}/tools/Trigger Puller/handler.js +0 -0
  228. /package/{src/mcp → mcp}/tools/index.js +0 -0
  229. /package/{.cursor/skills/cloudcc-cli-dev/docs//350/207/252/345/256/232/344/271/211/347/261/273.md" → src/classes/docs/introduction.md} +0 -0
  230. /package/{.cursor/skills/cloudcc-cli-dev/docs/CloudCC/350/207/252/345/256/232/344/271/211/347/273/204/344/273/266/344/275/277/347/224/250/350/257/264/346/230/216.md" → src/plugin/docs/introduction.md} +0 -0
  231. /package/{.cursor/skills/cloudcc-cli-dev/docs/cloudcc/345/256/232/346/227/266/347/261/273.md" → src/timer/docs/introduction.md} +0 -0
  232. /package/{.cursor/skills/cloudcc-cli-dev/docs//350/247/246/345/217/221/345/231/250/347/261/273.md" → src/triggers/docs/introduction.md} +0 -0
@@ -0,0 +1,99 @@
1
+ # CloudCC 菜单模块介绍
2
+
3
+ ## 1. 模块定位
4
+
5
+ `menu` 模块用于在 CloudCC
6
+ 中创建和管理导航菜单(标签页),把对象、页面或脚本能力暴露给业务用户。
7
+
8
+ 在 CloudCC
9
+ 中,菜单是用户看到系统功能的主要入口。对象、页面、脚本等能力通常需要通过菜单挂载到应用中,才方便被终端用户访问。
10
+
11
+ ---
12
+
13
+ ## 2. 菜单能做什么
14
+
15
+ 通过菜单模块,你可以:
16
+
17
+ - 为自定义对象创建入口
18
+ - 为自定义页面创建入口
19
+ - 为自定义脚本创建入口
20
+ - 将入口加入应用导航
21
+ - 配置 PC 与移动端图标,统一产品体验
22
+
23
+ ---
24
+
25
+ ## 3. 支持的菜单类型
26
+
27
+ | 类型 | 说明 | 常见用途 |
28
+ | -------- | -------------- | ------------------------- |
29
+ | `object` | 自定义对象菜单 | 打开对象列表/详情能力 |
30
+ | `page` | 自定义页面菜单 | 打开 Lightning 自定义页面 |
31
+ | `script` | 自定义脚本菜单 | 点击后执行脚本逻辑 |
32
+ | `site` | 站点菜单 | 关联 Site.com 站点 |
33
+
34
+ ---
35
+
36
+ ## 4. 菜单在平台中的典型流程
37
+
38
+ 参考 CloudCC 官方「菜单」能力,创建菜单通常包含以下流程:
39
+
40
+ 1. 进入后台设置,打开菜单管理
41
+ 2. 新建菜单(对象菜单 / 页面菜单 / 脚本菜单)
42
+ 3. 配置菜单标签与图标
43
+ 4. 选择可见简档(决定谁能看到菜单)
44
+ 5. 选择要加入的应用程序(决定菜单出现在哪个应用)
45
+ 6. 保存并验证显示效果
46
+
47
+ 在 `cloudcc-cli` 中,你主要通过 `cc create menu ...` 完成第 2-3
48
+ 步;权限与应用归属建议在创建后补充核验。
49
+
50
+ ---
51
+
52
+ ## 5. 为什么要用菜单模块
53
+
54
+ 菜单模块解决的是“能力可访问性”问题:
55
+
56
+ - 只创建对象/页面,不创建菜单,用户通常无法在导航中直接发现该能力
57
+ - 通过菜单可将功能按业务场景组织到不同应用
58
+ - 结合简档权限,可对不同角色展示不同入口
59
+
60
+ ---
61
+
62
+ ## 6. 适用场景
63
+
64
+ 以下场景建议使用 `menu` 模块:
65
+
66
+ - 新建了自定义对象,需要给业务团队增加入口
67
+ - 开发了 Lightning 自定义页面,需要挂到导航栏
68
+ - 需要提供一个一键执行脚本的菜单入口
69
+ - 不同业务线需要在各自应用里看到不同菜单组合
70
+
71
+ ---
72
+
73
+ ## 7. 与其他模块的关系
74
+
75
+ `menu` 常与以下模块协同:
76
+
77
+ - `object`:菜单绑定对象能力
78
+ - `customPage`:菜单绑定页面能力
79
+ - `script`:菜单绑定脚本能力
80
+ - `application`:菜单最终出现在具体应用中
81
+ - `project`:提供连接配置与环境能力
82
+
83
+ ---
84
+
85
+ ## 8. 建议实践
86
+
87
+ - 菜单命名与对象/页面语义保持一致,降低学习成本
88
+ - 先在测试环境完成创建与权限验证,再推向生产
89
+ - 统一图标规范,避免同一应用内视觉风格不一致
90
+ - 创建后立即验证简档可见性与应用挂载是否正确
91
+
92
+ ---
93
+
94
+ ## 9. 相关文档与命令
95
+
96
+ ```bash
97
+ cc doc menu introduction
98
+ cc doc menu devguide
99
+ ```
package/src/menu/index.js CHANGED
@@ -2,6 +2,7 @@ const cc = {}
2
2
  cc.create = require("./create")
3
3
  cc.delete = require("./delete")
4
4
  cc.get = require("./get")
5
+ cc.doc = require("./doc")
5
6
  function main(action, argvs) {
6
7
  cc[action](argvs)
7
8
  }
@@ -0,0 +1,80 @@
1
+ const chalk = require('chalk');
2
+ const menuGet = require('./get');
3
+
4
+ /**
5
+ * 验证 pname 是否有效
6
+ * 规则:
7
+ * 1. 只能包含字母、数字、下划线
8
+ * 2. 开头必须是字母
9
+ * 3. 不能有中文
10
+ * 4. 必须唯一(查询现有菜单列表)
11
+ *
12
+ * @param {string} pname - 要验证的菜单名称
13
+ * @param {string} projectPath - 项目路径
14
+ * @param {string} currentType - 当前菜单类型 (script/page/object/site)
15
+ * @returns {Promise<{valid: boolean, message?: string}>}
16
+ */
17
+ async function validatePname(pname, projectPath, currentType) {
18
+ // 1. 检查是否为空
19
+ if (!pname || typeof pname !== 'string') {
20
+ return { valid: false, message: 'pname 不能为空' };
21
+ }
22
+
23
+ // 2. 检查长度
24
+ if (pname.length < 1 || pname.length > 50) {
25
+ return { valid: false, message: 'pname 长度必须在 1-50 个字符之间' };
26
+ }
27
+
28
+ // 3. 检查是否有中文
29
+ if (/[\u4e00-\u9fa5]/.test(pname)) {
30
+ return { valid: false, message: 'pname 不能包含中文字符' };
31
+ }
32
+
33
+ // 4. 检查开头必须是字母
34
+ if (!/^[a-zA-Z]/.test(pname)) {
35
+ return { valid: false, message: 'pname 必须以字母开头' };
36
+ }
37
+
38
+ // 5. 检查只能包含字母、数字、下划线
39
+ if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(pname)) {
40
+ return { valid: false, message: 'pname 只能包含字母、数字和下划线' };
41
+ }
42
+
43
+ // 6. 检查唯一性
44
+ try {
45
+ const argvs = ['', '', projectPath];
46
+ const existingMenus = await menuGet(argvs, true);
47
+
48
+ if (Array.isArray(existingMenus)) {
49
+ const duplicate = existingMenus.find(menu =>
50
+ menu.pname === pname && menu.type !== currentType
51
+ );
52
+ if (duplicate) {
53
+ return { valid: false, message: `pname "${pname}" 已被其他菜单使用` };
54
+ }
55
+ }
56
+ } catch (error) {
57
+ // 如果查询失败,记录警告但不阻止创建
58
+ console.error(chalk.yellow(`警告: 无法验证 pname 唯一性: ${error.message}`));
59
+ }
60
+
61
+ return { valid: true };
62
+ }
63
+
64
+ /**
65
+ * 格式化 pname(将不合法字符替换为下划线)
66
+ * @param {string} input - 输入字符串
67
+ * @returns {string} - 格式化后的字符串
68
+ */
69
+ function formatPname(input) {
70
+ if (!input || typeof input !== 'string') {
71
+ return '';
72
+ }
73
+ // 将非字母数字下划线字符替换为下划线
74
+ return input.replace(/[^0-9a-zA-Z_]/g, '_');
75
+ }
76
+
77
+ module.exports = {
78
+ validatePname,
79
+ formatPname
80
+ };
@@ -0,0 +1,45 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ const DOCS_DIR = path.join(__dirname, "docs");
5
+ const INTRODUCTION = path.join(DOCS_DIR, "introduction.md");
6
+ const DEVGUIDE = path.join(DOCS_DIR, "devguide.md");
7
+
8
+ function readDocOrFallback(filePath, fallback) {
9
+ try {
10
+ return fs.readFileSync(filePath, "utf8").trim();
11
+ } catch (e) {
12
+ return fallback;
13
+ }
14
+ }
15
+
16
+ function getIntroductionDoc() {
17
+ return readDocOrFallback(
18
+ INTRODUCTION,
19
+ `# CloudCC 自定义对象介绍\n\n(未找到文件:${INTRODUCTION})\n`
20
+ );
21
+ }
22
+
23
+ function getDevGuideDoc() {
24
+ return readDocOrFallback(
25
+ DEVGUIDE,
26
+ `# CloudCC 自定义对象开发指南\n\n(未找到文件:${DEVGUIDE})\n`
27
+ );
28
+ }
29
+
30
+ function doc(argvs = []) {
31
+ const subType = String(argvs[2] || "").trim().toLowerCase();
32
+ if (!subType || subType === "devguide") {
33
+ const content = getDevGuideDoc();
34
+ console.log(content);
35
+ return content;
36
+ }
37
+ if (subType === "introduction") {
38
+ const content = getIntroductionDoc();
39
+ console.log(content);
40
+ return content;
41
+ }
42
+ throw new Error(`doc 不支持的子命令: ${argvs[2]},请使用 introduction 或 devguide`);
43
+ }
44
+
45
+ module.exports = doc;
@@ -0,0 +1,112 @@
1
+ # CloudCC 自定义对象开发指南
2
+
3
+ ## 1. 模块定位
4
+
5
+ `object` 模块用于管理 CloudCC 自定义对象,当前提供查询、创建、删除三类能力。
6
+
7
+ 可通过以下命令读取文档:
8
+
9
+ ```bash
10
+ cc doc object introduction
11
+ cc doc object devguide
12
+ ```
13
+
14
+ ---
15
+
16
+ ## 2. 当前支持的命令
17
+
18
+ ```bash
19
+ cc get object <projectPath> [type]
20
+ cc create object <projectPath> <label> [nameLabel]
21
+ cc delete object <projectPath> <objid>
22
+ ```
23
+
24
+ 说明:
25
+
26
+ - `projectPath`:本地项目路径,用于读取 `cloudcc-cli.config.js`
27
+ - `label`:对象中文名称或展示名称
28
+ - `nameLabel`:对象 API 名称;不传时会基于 `label` 自动生成
29
+ - `objid`:对象 ID
30
+
31
+ ---
32
+
33
+ ## 3. 查询对象
34
+
35
+ ### 3.1 查询全部对象
36
+
37
+ ```bash
38
+ cc get object <projectPath>
39
+ ```
40
+
41
+ 返回标准对象和自定义对象的合并列表。
42
+
43
+ ### 3.2 按类型查询
44
+
45
+ ```bash
46
+ cc get object <projectPath> standard
47
+ cc get object <projectPath> custom
48
+ ```
49
+
50
+ 常见含义:
51
+
52
+ - `standard`:标准对象
53
+ - `custom`:自定义对象
54
+
55
+ ---
56
+
57
+ ## 4. 创建对象
58
+
59
+ ### 4.1 基本命令
60
+
61
+ ```bash
62
+ cc create object <projectPath> <label> [nameLabel]
63
+ ```
64
+
65
+ 规则:
66
+
67
+ - 若传入 `nameLabel`,则使用传入值作为对象 API 名称
68
+ - 若未传入 `nameLabel`,CLI 会根据 `label` 自动生成一个英文可用的 slug,并拼成对象 API 名称
69
+
70
+ ### 4.2 创建过程
71
+
72
+ 创建对象时,模块会:
73
+
74
+ 1. 读取项目配置
75
+ 2. 查询角色列表
76
+ 3. 自动生成对象权限配置
77
+ 4. 调用 `/api/customObject/saveButton` 创建对象
78
+
79
+ ---
80
+
81
+ ## 5. 删除对象
82
+
83
+ ### 5.1 基本命令
84
+
85
+ ```bash
86
+ cc delete object <projectPath> <objid>
87
+ ```
88
+
89
+ 删除前建议:
90
+
91
+ - 先确认对象未被页面、菜单、字段或自动化逻辑依赖
92
+ - 先保留对象 ID 与对象名称,避免误删
93
+
94
+ ---
95
+
96
+ ## 6. 开发前检查
97
+
98
+ - 已完成 `cc doc project devguide` 中的环境准备
99
+ - 项目根目录存在可用的 `cloudcc-cli.config.js`
100
+ - 当前环境密钥配置正确
101
+ - 已确认对象名称、API 名称、角色权限需求
102
+
103
+ ---
104
+
105
+ ## 7. 占位说明
106
+
107
+ 这份文档当前为初版开发指南,后续可继续补充:
108
+
109
+ - 对象建模规范
110
+ - 命名建议
111
+ - 角色权限说明
112
+ - 与字段、菜单、应用的联动关系
@@ -0,0 +1,187 @@
1
+ # CloudCC 自定义对象介绍
2
+
3
+ ## 1. 什么是自定义对象
4
+
5
+ 自定义对象是 CloudCC 平台中承载业务数据的核心建模能力。
6
+
7
+ 当标准对象无法满足业务需求时,可以通过自定义对象定义一类新的业务实体,用来存储、组织和管理企业自己的业务数据。
8
+
9
+ 可以把它理解为:
10
+
11
+ - 一个新的业务数据模型
12
+ - 一张由平台托管的业务数据表
13
+ - 后续字段、页面、菜单、权限、自动化逻辑的基础载体
14
+
15
+ ---
16
+
17
+ ## 2. 自定义对象能做什么
18
+
19
+ 创建一个自定义对象后,通常可以围绕它继续完成以下工作:
20
+
21
+ - 为对象添加字段,定义业务属性
22
+ - 为对象配置页面、菜单和应用入口
23
+ - 为对象编写触发器、后端类、客户端脚本等逻辑
24
+ - 作为报表、列表、详情页、审批流或自动化规则的数据基础
25
+ - 与其他对象建立关联关系,形成完整的业务模型
26
+
27
+ 也就是说,自定义对象不是孤立存在的,它往往是整个 CloudCC 二次开发的起点。
28
+
29
+ ---
30
+
31
+ ## 3. 主要作用是什么
32
+
33
+ 自定义对象的主要作用是把企业自己的业务概念,沉淀成平台可以管理和扩展的数据实体。
34
+
35
+ 例如,企业可能会有一些 CloudCC 标准对象中没有的业务概念:
36
+
37
+ - 渠道合作商
38
+ - 培训计划
39
+ - 项目立项单
40
+ - 售后服务工单
41
+ - 设备巡检记录
42
+ - 合同回款计划
43
+
44
+ 这些内容如果没有独立的数据对象,就很难被规范地管理、查询、统计和扩展。
45
+
46
+ 通过自定义对象,可以把这些业务概念平台化,后续再叠加字段、权限、页面和自动化逻辑,实现完整的业务支撑。
47
+
48
+ ---
49
+
50
+ ## 4. 为什么要用自定义对象
51
+
52
+ 使用自定义对象,通常是为了解决以下问题:
53
+
54
+ ### 4.1 标准对象不够用
55
+
56
+ 标准 CRM 对象更适合通用销售、客户、商机等场景。
57
+ 如果你的业务有明显的行业特性或内部流程特性,就需要自定义对象来承载这些专属数据。
58
+
59
+ ### 4.2 业务数据没有统一模型
60
+
61
+ 很多团队一开始会把业务数据分散在备注、Excel、附件或多个对象的扩展字段里。
62
+ 这样会导致:
63
+
64
+ - 数据结构混乱
65
+ - 难查询、难统计
66
+ - 权限和流程不好控制
67
+ - 后续开发成本越来越高
68
+
69
+ 自定义对象可以帮助团队建立统一的数据模型。
70
+
71
+ ### 4.3 后续扩展困难
72
+
73
+ 如果没有对象作为基础,就很难继续配置:
74
+
75
+ - 字段
76
+ - 页面
77
+ - 菜单
78
+ - 审批
79
+ - 触发器
80
+ - 自动化逻辑
81
+ - 报表与统计
82
+
83
+ 自定义对象本质上是在为后续的二次开发打地基。
84
+
85
+ ---
86
+
87
+ ## 5. 能解决哪些问题
88
+
89
+ 自定义对象通常可以解决以下几类问题:
90
+
91
+ - 业务实体无法落地存储的问题
92
+ - 非标准流程缺少独立数据载体的问题
93
+ - 数据分散、命名混乱、难以统一管理的问题
94
+ - 无法围绕某类业务数据做页面、权限、流程和自动化的问题
95
+ - 无法对特定业务做统计分析和生命周期管理的问题
96
+
97
+ ---
98
+
99
+ ## 6. 在什么情况下使用
100
+
101
+ 当出现以下情况时,通常就应该考虑使用自定义对象:
102
+
103
+ - 现有标准对象找不到合适的数据承载位置
104
+ - 一类业务数据有明确的独立含义,需要单独维护
105
+ - 需要给这类数据配置独立字段、列表、详情页或菜单入口
106
+ - 需要围绕这类数据编写触发器、后端逻辑或客户端脚本
107
+ - 需要对这类数据做独立的权限控制、流程控制或报表统计
108
+
109
+ 简单说,只要某类业务数据需要被“长期、规范、可扩展”地管理,就适合建成一个自定义对象。
110
+
111
+ ---
112
+
113
+ ## 7. 常见业务场景
114
+
115
+ ### 7.1 行业化业务扩展
116
+
117
+ 例如教育、制造、医疗、服务型企业,往往会有标准 CRM 没有的业务实体:
118
+
119
+ - 课程班级
120
+ - 设备档案
121
+ - 巡检计划
122
+ - 维修工单
123
+ - 服务回访单
124
+
125
+ 这类场景通常适合通过自定义对象建模。
126
+
127
+ ### 7.2 内部流程数字化
128
+
129
+ 如果企业希望把线下或半线下流程搬到 CloudCC 中管理,例如:
130
+
131
+ - 项目申请
132
+ - 费用登记
133
+ - 合同变更申请
134
+ - 客诉处理
135
+ - 交付验收记录
136
+
137
+ 这类流程通常都需要一个独立对象来沉淀流程数据。
138
+
139
+ ### 7.3 围绕客户或商机的扩展管理
140
+
141
+ 有些数据虽然与客户或商机有关,但不适合直接塞到标准对象里,例如:
142
+
143
+ - 客户拜访记录
144
+ - 渠道返佣记录
145
+ - 实施里程碑
146
+ - 回款计划
147
+
148
+ 这类场景可以用自定义对象做扩展,再通过关联字段与客户、商机连接起来。
149
+
150
+ ### 7.4 需要长期运营的数据台账
151
+
152
+ 比如:
153
+
154
+ - 资产台账
155
+ - 证照台账
156
+ - 项目档案
157
+ - 服务记录
158
+
159
+ 这类数据通常结构稳定、需要长期维护,很适合对象化管理。
160
+
161
+ ---
162
+
163
+ ## 8. 使用自定义对象时的理解方式
164
+
165
+ 在设计时,可以先问自己几个问题:
166
+
167
+ 1. 这是不是一类独立的业务实体?
168
+ 2. 这类数据是否需要独立字段和独立页面?
169
+ 3. 是否需要围绕它做权限、流程、自动化或报表?
170
+ 4. 这类数据未来会不会持续扩展?
171
+
172
+ 如果这几个问题大多回答为“是”,通常就说明应该考虑新建一个自定义对象。
173
+
174
+ ---
175
+
176
+ ## 9. 与其他模块的关系
177
+
178
+ 自定义对象通常和这些模块联动:
179
+
180
+ - `fields`:给对象增加字段
181
+ - `menu`:给对象增加菜单入口
182
+ - `application`:把对象放入应用
183
+ - `triggers`:围绕对象数据变化编写触发逻辑
184
+ - `classes`:围绕对象编写业务服务逻辑
185
+ - `script` / `plugin` / `customPage`:围绕对象做页面交互与前端扩展
186
+
187
+ 因此,自定义对象往往是 CloudCC 二次开发中最基础、最上游的建模模块之一。
package/src/object/get.js CHANGED
@@ -7,29 +7,7 @@ async function get(argvs, isMcp = false) {
7
7
  let object = argvs[4]
8
8
  let res = [];
9
9
  let config = await getPackageJson(path);
10
- if ("fields" === type) {
11
- object = JSON.parse(decodeURI(object))
12
- let fieldsResults = await postClass(config.setupSvc + "/api/fieldSetup/queryField", { prefix: object.objprefix }, config.accessToken)
13
- res = {
14
- ...object,
15
- stdFields: fieldsResults.data.stdFields.map((field) => {
16
- return {
17
- fieldname: field.labelName,
18
- apiname: field.schemefieldName,
19
- schemefieldType: field.schemefieldType,
20
- id: field.id
21
- }
22
- }),
23
- cusFields: fieldsResults.data.cusFields.map((field) => {
24
- return {
25
- fieldname: field.labelName,
26
- apiname: field.schemefieldName,
27
- schemefieldType: field.schemefieldType,
28
- id: field.id
29
- }
30
- })
31
- }
32
- } else if ("chat" === type) {
10
+ if ("chat" === type) {
33
11
  //get chat object
34
12
  let standardObjList = await postClass(config.setupSvc + "/api/customObject/standardObjList", {}, config.accessToken);
35
13
  standardObjList.data.map((item) => {
@@ -2,6 +2,7 @@ const cc = {}
2
2
  cc.get = require("./get")
3
3
  cc.create = require("./create")
4
4
  cc.delete = require("./delete")
5
+ cc.doc = require("./doc")
5
6
  function main(action, argvs) {
6
7
  cc[action](argvs)
7
8
  }
@@ -0,0 +1,123 @@
1
+ const { postClass } = require("../../utils/http");
2
+ const { getPackageJson } = require("../../utils/config");
3
+ const chalk = require("chalk");
4
+
5
+ /**
6
+ * 获取对象现有的页面布局列表
7
+ * @param {Object} config - 项目配置
8
+ * @param {string} objId - 对象 ID
9
+ * @returns {Promise<Array>} 页面布局列表
10
+ */
11
+ async function getExistingLayouts(config, objId) {
12
+ try {
13
+ const res = await postClass(
14
+ config.setupSvc + "/api/layout/newpage",
15
+ { objid: objId },
16
+ config.accessToken
17
+ );
18
+
19
+ if (res && res.result && res.data && Array.isArray(res.data) && res.data.length > 0) {
20
+ return res.data;
21
+ }
22
+
23
+ throw new Error("未找到可用的页面布局");
24
+ } catch (error) {
25
+ throw new Error("获取页面布局列表失败: " + error.message);
26
+ }
27
+ }
28
+
29
+ /**
30
+ * 复制创建页面布局
31
+ * @param {Object} config - 项目配置
32
+ * @param {string} objId - 对象 ID
33
+ * @param {string} layoutName - 新布局名称
34
+ * @param {string} sourceLayoutId - 源布局 ID
35
+ * @param {string} isCloneDynamic - 是否复制动态布局规则
36
+ * @returns {Promise<Object>} 创建结果
37
+ */
38
+ async function cloneLayout(config, objId, layoutName, sourceLayoutId, isCloneDynamic = "true") {
39
+ const res = await postClass(
40
+ config.setupSvc + "/api/layout/cloneLayout",
41
+ {
42
+ layoutId: sourceLayoutId,
43
+ layoutName: layoutName,
44
+ objid: objId,
45
+ isCloneDynamic: isCloneDynamic
46
+ },
47
+ config.accessToken
48
+ );
49
+
50
+ if (res && res.result) {
51
+ return res.data || res;
52
+ }
53
+
54
+ const msg = res && (res.returnInfo || res.message) ? (res.returnInfo || res.message) : "Unknown error";
55
+ throw new Error("Clone Layout Failed: " + msg);
56
+ }
57
+
58
+ /**
59
+ * 创建页面布局
60
+ * 用法:cc create pagelayout <projectPath> <objId> <layoutName> [sourceLayoutId] [isCloneDynamic]
61
+ * @param {Array} argvs - 命令行参数数组
62
+ * @returns {Promise<Object>} 创建结果
63
+ */
64
+ async function create(argvs) {
65
+ try {
66
+ // 命令行参数格式:cc create pagelayout <projectPath> <objId> <layoutName> [sourceLayoutId] [isCloneDynamic]
67
+ const projectPath = argvs[2] || process.cwd();
68
+ const objId = argvs[3];
69
+ const layoutName = argvs[4];
70
+ const sourceLayoutId = argvs[5];
71
+ const isCloneDynamic = argvs[6] || "true";
72
+
73
+ if (!objId) {
74
+ console.error();
75
+ console.error(chalk.red("Error: 缺少对象 ID"));
76
+ console.error("用法: cc create pagelayout <projectPath> <objId> <layoutName> [sourceLayoutId] [isCloneDynamic]");
77
+ console.error("示例:");
78
+ console.error(' cc create pagelayout . 20267D1465464C5OB6m5 "课程表2"');
79
+ console.error(" cc create pagelayout . 20267D1465464C5OB6m5 \"课程表2\" add20261DA7347CZPAUz");
80
+ console.error();
81
+ throw new Error("缺少必需参数: objId");
82
+ }
83
+
84
+ if (!layoutName) {
85
+ console.error();
86
+ console.error(chalk.red("Error: 缺少页面布局名称"));
87
+ console.error("用法: cc create pagelayout <projectPath> <objId> <layoutName> [sourceLayoutId] [isCloneDynamic]");
88
+ console.error();
89
+ throw new Error("缺少必需参数: layoutName");
90
+ }
91
+
92
+ const config = await getPackageJson(projectPath);
93
+
94
+ let targetLayoutId = sourceLayoutId;
95
+
96
+ // 如果没有指定源布局 ID,查询现有布局列表并选择第一个
97
+ if (!targetLayoutId) {
98
+ console.error();
99
+ console.error(chalk.blue("正在获取现有页面布局列表..."));
100
+ const layouts = await getExistingLayouts(config, objId);
101
+ targetLayoutId = layouts[0].id;
102
+ console.error(chalk.green(`将使用布局 "${layouts[0].layoutName}" (${targetLayoutId}) 作为复制源`));
103
+ }
104
+
105
+ console.error();
106
+ console.error(chalk.green(`Creating page layout "${layoutName}"...`));
107
+ console.error();
108
+
109
+ const result = await cloneLayout(config, objId, layoutName, targetLayoutId, isCloneDynamic);
110
+
111
+ console.error(chalk.green("页面布局创建成功!"));
112
+ console.log(JSON.stringify(result));
113
+
114
+ return result;
115
+
116
+ } catch (error) {
117
+ console.error();
118
+ console.error(chalk.red("页面布局创建失败:"), error.message || error);
119
+ throw error;
120
+ }
121
+ }
122
+
123
+ module.exports = create;