cloudcc-cli 2.3.1 → 2.3.2

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 +15 -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 +67 -0
  5. package/README.md +11 -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 +2 -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 +451 -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 +212 -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 +203 -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/doc.js +46 -0
  82. package/src/pagelayout/docs/devguide.md +295 -0
  83. package/src/pagelayout/docs/introduction.md +44 -0
  84. package/src/pagelayout/get.js +46 -0
  85. package/src/pagelayout/index.js +9 -0
  86. package/src/plugin/doc.js +43 -863
  87. package/src/plugin/docs/devguide.md +923 -0
  88. package/src/profile/create.js +108 -0
  89. package/src/profile/delete.js +59 -0
  90. package/src/profile/doc.js +46 -0
  91. package/src/profile/docs/devguide.md +332 -0
  92. package/src/profile/docs/introduction.md +123 -0
  93. package/src/profile/get.js +55 -0
  94. package/src/profile/index.js +14 -0
  95. package/src/project/doc.js +39 -372
  96. package/src/project/docs/devguide.md +359 -0
  97. package/src/project/docs/introduction.md +3 -0
  98. package/src/recordType/create.js +77 -0
  99. package/src/recordType/delete.js +52 -0
  100. package/src/recordType/doc.js +36 -0
  101. package/src/recordType/docs/devguide.md +160 -0
  102. package/src/recordType/docs/introduction.md +53 -0
  103. package/src/recordType/editInfo.js +39 -0
  104. package/src/recordType/editSave.js +47 -0
  105. package/src/recordType/getList.js +31 -0
  106. package/src/recordType/index.js +16 -3
  107. package/src/recordType/newInfo.js +39 -0
  108. package/src/recordType/validDelete.js +91 -0
  109. package/src/res.md +66 -0
  110. package/src/role/create.js +153 -0
  111. package/src/role/delete.js +59 -0
  112. package/src/role/doc.js +46 -0
  113. package/src/role/docs/devguide.md +387 -0
  114. package/src/role/docs/introduction.md +124 -0
  115. package/src/role/get.js +57 -0
  116. package/src/role/index.js +10 -0
  117. package/src/scheduleJob/doc.js +49 -0
  118. package/src/scheduleJob/docs/devguide.md +79 -0
  119. package/src/scheduleJob/docs/introduction.md +101 -0
  120. package/src/scheduleJob/index.js +5 -0
  121. package/src/script/delete.js +112 -0
  122. package/src/script/doc.js +31 -245
  123. package/src/script/docs/devguide.md +290 -0
  124. package/src/script/docs/introduction.md +48 -0
  125. package/src/script/index.js +1 -0
  126. package/src/staticResource/count.js +31 -10
  127. package/src/staticResource/create.js +97 -0
  128. package/src/staticResource/delete.js +30 -8
  129. package/src/staticResource/detail.js +32 -10
  130. package/src/staticResource/doc.js +21 -88
  131. package/src/staticResource/docs/devguide.md +157 -0
  132. package/src/staticResource/docs/introduction.md +3 -0
  133. package/src/staticResource/get.js +31 -8
  134. package/src/staticResource/index.js +2 -1
  135. package/src/timer/create.js +6 -1
  136. package/src/timer/delete.js +7 -1
  137. package/src/timer/detail.js +5 -5
  138. package/src/timer/doc.js +57 -0
  139. package/src/timer/get.js +7 -1
  140. package/src/timer/index.js +3 -1
  141. package/src/timer/publish.js +6 -1
  142. package/src/timer/pull.js +6 -1
  143. package/src/timer/pullList.js +5 -3
  144. package/src/triggers/detail.js +5 -5
  145. package/src/triggers/doc.js +49 -364
  146. package/src/triggers/docs/devguide.md +334 -0
  147. package/src/triggers/get.js +7 -3
  148. package/src/triggers/index.js +1 -4
  149. package/src/triggers/pullList.js +7 -7
  150. package/src/user/create.js +50 -0
  151. package/src/user/delete.js +59 -0
  152. package/src/user/doc.js +46 -0
  153. package/src/user/docs/devguide.md +634 -0
  154. package/src/user/docs/introduction.md +124 -0
  155. package/src/user/get.js +112 -0
  156. package/src/user/index.js +12 -0
  157. package/src/user/update.js +96 -0
  158. package/src/user/view.js +60 -0
  159. package/test/classes.cli.test.js +7 -4
  160. package/test/customPage.cli.test.js +96 -0
  161. package/test/globalSelectList.cli.test.js +94 -0
  162. package/test/menu-script.cli.test.js +147 -0
  163. package/test/menu.cli.test.js +8 -1
  164. package/test/plugin.cli.test.js +5 -3
  165. package/test/timer.cli.test.js +15 -8
  166. package/test/trigger.cli.test.js +5 -3
  167. package/tmp_customsetting_detail.json +1 -0
  168. package/.cursor/skills/cloudcc-cli-dev/BACKEND_CLASS.md +0 -111
  169. package/.cursor/skills/cloudcc-cli-dev/BACKEND_SCHEDULE.md +0 -152
  170. package/.cursor/skills/cloudcc-cli-dev/BACKEND_TRIGGER.md +0 -150
  171. package/.cursor/skills/cloudcc-cli-dev/CLI_CHEATSHEET.md +0 -372
  172. package/.cursor/skills/cloudcc-cli-dev/CUSTOM-SETTING-API.md +0 -62
  173. package/.cursor/skills/cloudcc-cli-dev/INSTALL_AND_BOOTSTRAP.md +0 -62
  174. package/.cursor/skills/cloudcc-cli-dev/OBJECTS_AND_FIELDS.md +0 -214
  175. package/.cursor/skills/cloudcc-cli-dev/REQUIREMENTS_BREAKDOWN.md +0 -113
  176. package/.cursor/skills/cloudcc-cli-dev/SKILL.md +0 -66
  177. package/.cursor/skills/cloudcc-cli-dev/STATIC-RESOURCE-API.md +0 -60
  178. package/.cursor/skills/cloudcc-cli-dev/VUE_CUSTOM_COMPONENT.md +0 -151
  179. package/.cursor/skills/cloudcc-cli-dev/VUE_CUSTOM_PAGE.md +0 -216
  180. package/src/approval/approve.js +0 -105
  181. package/src/approval/get.js +0 -245
  182. package/src/approval/index.js +0 -11
  183. package/src/approval/reject.js +0 -105
  184. package/src/plugin/readme.md +0 -7
  185. /package/{src/mcp → mcp}/cliRunner.js +0 -0
  186. /package/{src/mcp → mcp}/index.js +0 -0
  187. /package/{src/mcp → mcp}/readme.md +0 -0
  188. /package/{src/mcp → mcp}/tools/Application Creator/handler.js +0 -0
  189. /package/{src/mcp → mcp}/tools/Approval/handler.js +0 -0
  190. /package/{src/mcp → mcp}/tools/Class Creator/handler.js +0 -0
  191. /package/{src/mcp → mcp}/tools/Class Detail Retriever/handler.js +0 -0
  192. /package/{src/mcp → mcp}/tools/Class List Retriever/handler.js +0 -0
  193. /package/{src/mcp → mcp}/tools/Class Publisher/handler.js +0 -0
  194. /package/{src/mcp → mcp}/tools/Class Puller/handler.js +0 -0
  195. /package/{src/mcp → mcp}/tools/Client Script Detail Retriever/handler.js +0 -0
  196. /package/{src/mcp → mcp}/tools/Client Script Editor Guide/handler.js +0 -0
  197. /package/{src/mcp → mcp}/tools/Client Script List Retriever/handler.js +0 -0
  198. /package/{src/mcp → mcp}/tools/Client Script Publisher/handler.js +0 -0
  199. /package/{src/mcp → mcp}/tools/Client Script Puller/handler.js +0 -0
  200. /package/{src/mcp → mcp}/tools/CloudCC Development Overview/handler.js +0 -0
  201. /package/{src/mcp → mcp}/tools/Component Creator/handler.js +0 -0
  202. /package/{src/mcp → mcp}/tools/Component Detail Retriever/handler.js +0 -0
  203. /package/{src/mcp → mcp}/tools/Component List Retriever/handler.js +0 -0
  204. /package/{src/mcp → mcp}/tools/Component Publisher/handler.js +0 -0
  205. /package/{src/mcp → mcp}/tools/Component Puller/handler.js +0 -0
  206. /package/{src/mcp → mcp}/tools/Dev Environment Creator/fetcher.js +0 -0
  207. /package/{src/mcp → mcp}/tools/Dev Environment Creator/handler.js +0 -0
  208. /package/{src/mcp → mcp}/tools/Dev Environment Validator/handler.js +0 -0
  209. /package/{src/mcp → mcp}/tools/Developer Key Setup Guide/fetcher.js +0 -0
  210. /package/{src/mcp → mcp}/tools/Developer Key Setup Guide/handler.js +0 -0
  211. /package/{src/mcp → mcp}/tools/JSP Migrator/handler.js +0 -0
  212. /package/{src/mcp → mcp}/tools/Menu Creator/handler.js +0 -0
  213. /package/{src/mcp → mcp}/tools/Object Creator/handler.js +0 -0
  214. /package/{src/mcp → mcp}/tools/Object Fields Creator/handler.js +0 -0
  215. /package/{src/mcp → mcp}/tools/Object Fields Retriever/handler.js +0 -0
  216. /package/{src/mcp → mcp}/tools/Object List Retriever/handler.js +0 -0
  217. /package/{src/mcp → mcp}/tools/Scheduled Class Creator/handler.js +0 -0
  218. /package/{src/mcp → mcp}/tools/Scheduled Class Detail Retriever/handler.js +0 -0
  219. /package/{src/mcp → mcp}/tools/Scheduled Class List Retriever/handler.js +0 -0
  220. /package/{src/mcp → mcp}/tools/Scheduled Class Publisher/handler.js +0 -0
  221. /package/{src/mcp → mcp}/tools/Scheduled Class Puller/handler.js +0 -0
  222. /package/{src/mcp → mcp}/tools/Trigger Creator/handler.js +0 -0
  223. /package/{src/mcp → mcp}/tools/Trigger Detail Retriever/handler.js +0 -0
  224. /package/{src/mcp → mcp}/tools/Trigger List Retriever/handler.js +0 -0
  225. /package/{src/mcp → mcp}/tools/Trigger Publisher/handler.js +0 -0
  226. /package/{src/mcp → mcp}/tools/Trigger Puller/handler.js +0 -0
  227. /package/{src/mcp → mcp}/tools/index.js +0 -0
  228. /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
  229. /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
  230. /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} +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,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.layouts && Array.isArray(res.layouts) && res.layouts.length > 0) {
20
+ return res.layouts;
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;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * pagelayout 文档入口:正文均在 `docs/` 目录。
3
+ */
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+
7
+ const DOCS_DIR = path.join(__dirname, "docs");
8
+
9
+ function readDocFile(basename) {
10
+ return fs.readFileSync(path.join(DOCS_DIR, `${basename}.md`), "utf8");
11
+ }
12
+
13
+ /** 介绍文档:页面布局能力、类型与入口 */
14
+ function getIntroductionDoc() {
15
+ return readDocFile("introduction");
16
+ }
17
+
18
+ /** 开发指导:CLI 查询/创建等 */
19
+ function getDevGuideDoc() {
20
+ return readDocFile("devguide");
21
+ }
22
+
23
+ /**
24
+ * cc doc pagelayout <introduction|devguide>
25
+ * @param {string[]} argvs [doc, type, introduction|devguide, ...]
26
+ */
27
+ function doc(argvs) {
28
+ const subType = argvs[2];
29
+ const key = String(subType || "").trim().toLowerCase();
30
+ if (!key) {
31
+ throw new Error("cc doc pagelayout 需要子命令:introduction 或 devguide");
32
+ }
33
+ if (key === "introduction") {
34
+ const content = getIntroductionDoc();
35
+ console.log(content);
36
+ return content;
37
+ }
38
+ if (key === "devguide") {
39
+ const content = getDevGuideDoc();
40
+ console.log(content);
41
+ return content;
42
+ }
43
+ throw new Error(`doc 不支持的子命令: ${subType},请使用 introduction 或 devguide`);
44
+ }
45
+
46
+ module.exports = doc;
@@ -0,0 +1,295 @@
1
+ # CloudCC 页面布局使用总结
2
+
3
+ 页面布局(Page Layout)用于定义对象在详情页的字段展示方式,包括字段排列、分区、按钮位置等。
4
+
5
+ **前置条件**:页面布局操作需要先选中自定义对象或标准对象。
6
+
7
+ ---
8
+
9
+ ## 快速开始(CLI 命令)
10
+
11
+ ### 支持的页面布局操作
12
+
13
+ | 操作 | 说明 |
14
+ |------|------|
15
+ | `get` | 查询页面布局列表 |
16
+ | `create` | 创建/复制页面布局 |
17
+
18
+ ---
19
+
20
+ ## CLI 命令详解
21
+
22
+ ### 查询页面布局列表
23
+
24
+ 获取指定对象的页面布局列表。
25
+
26
+ ```bash
27
+ cc get pagelayout <projectPath> <objApiName>
28
+ ```
29
+
30
+ **参数说明:**
31
+
32
+ | 参数 | 必填 | 说明 |
33
+ |------|------|------|
34
+ | `projectPath` | 否 | 项目路径,`.` 表示当前目录 |
35
+ | `objApiName` | 是 | 对象 API 名称(前缀) |
36
+
37
+ **示例:**
38
+
39
+ ```bash
40
+ # 查询对象 b25 的页面布局列表
41
+ cc get pagelayout . b25
42
+
43
+ # 使用完整 API 名称
44
+ cc get pagelayout . Account
45
+ ```
46
+
47
+ ---
48
+
49
+ ### 创建页面布局
50
+
51
+ 基于现有布局创建新的页面布局。
52
+
53
+ ```bash
54
+ cc create pagelayout <projectPath> <objId> <layoutName> [sourceLayoutId] [isCloneDynamic]
55
+ ```
56
+
57
+ **参数说明:**
58
+
59
+ | 参数 | 必填 | 说明 |
60
+ |------|------|------|
61
+ | `projectPath` | 否 | 项目路径,`.` 表示当前目录 |
62
+ | `objId` | 是 | 对象 ID |
63
+ | `layoutName` | 是 | 新页面布局名称 |
64
+ | `sourceLayoutId` | 否 | 要复制的源布局 ID,不传则使用默认第一个 |
65
+ | `isCloneDynamic` | 否 | 是否复制动态布局规则,默认 `true` |
66
+
67
+ **示例:**
68
+
69
+ ```bash
70
+ # 创建页面布局(自动使用默认布局作为模板)
71
+ cc create pagelayout . 20267D1465464C5OB6m5 "课程表2"
72
+
73
+ # 指定源布局 ID 进行复制
74
+ cc create pagelayout . 20267D1465464C5OB6m5 "课程表2" add20261DA7347CZPAUz
75
+
76
+ # 不复制动态布局规则
77
+ cc create pagelayout . 20267D1465464C5OB6m5 "课程表2" add20261DA7347CZPAUz false
78
+ ```
79
+
80
+ ---
81
+
82
+ ## 完整工作流示例
83
+
84
+ ### 场景:为自定义对象创建新的页面布局
85
+
86
+ ```bash
87
+ # 1. 确认项目已初始化(有 cloudcc-cli.config.js)
88
+ cat cloudcc-cli.config.js
89
+
90
+ # 2. 查询对象的页面布局列表
91
+ cc get pagelayout . b25
92
+
93
+ # 3. 根据对象 ID 创建新布局
94
+ cc create pagelayout . 20267D1465464C5OB6m5 "新的布局名称"
95
+
96
+ # 4. 验证创建成功,再次查询列表
97
+ cc get pagelayout . b25
98
+ ```
99
+
100
+ ---
101
+
102
+ ## API 接口详情
103
+
104
+ ### 什么是页面布局?
105
+
106
+ **页面布局(Page Layout)** 定义了对象在详情页的展示方式,包括:
107
+ - 字段的排列和分组
108
+ - 相关列表的显示
109
+ - 操作按钮的位置
110
+ - 动态布局规则
111
+
112
+ ### 核心属性
113
+
114
+ | 属性 | 说明 | 示例 |
115
+ |------|------|------|
116
+ | **ID(id)** | 页面布局唯一标识 | `add20261DA7347CZPAUz` |
117
+ | **名称(layoutName)** | 页面布局显示名称 | `课程表布局` |
118
+ | **对象 ID(objid)** | 关联的对象 ID | `20267D1465464C5OB6m5` |
119
+
120
+ ---
121
+
122
+ ## 一、查询页面布局列表
123
+
124
+ ### 1.1 接口说明
125
+
126
+ **接口**: `POST /api/layout/queryPageLayout`
127
+
128
+ **请求参数**:
129
+
130
+ | 参数名 | 类型 | 必填 | 说明 |
131
+ |--------|------|------|------|
132
+ | `prefix` | string | 是 | 对象 API 名称前缀 |
133
+
134
+ **返回数据**:
135
+
136
+ ```javascript
137
+ {
138
+ "result": true,
139
+ "returnInfo": "操作成功",
140
+ "layouts": [
141
+ {
142
+ "id": "add20261DA7347CZPAUz",
143
+ "layoutName": "默认布局",
144
+ "objid": "20267D1465464C5OB6m5",
145
+ // ... 其他字段
146
+ }
147
+ ]
148
+ }
149
+ ```
150
+
151
+ **返回字段说明**:
152
+
153
+ | 字段 | 类型 | 说明 |
154
+ |------|------|------|
155
+ | `layouts` | array | 页面布局数组 |
156
+ | `layouts[].id` | string | 布局 ID |
157
+ | `layouts[].layoutName` | string | 布局名称 |
158
+ | `layouts[].objid` | string | 关联对象 ID |
159
+
160
+ ---
161
+
162
+ ## 二、创建页面布局
163
+
164
+ 创建页面布局是一个两步流程:
165
+
166
+ 1. **获取现有布局列表**:调用 `layout/newpage` 接口获取可用于复制的布局
167
+ 2. **复制创建新布局**:调用 `layout/cloneLayout` 接口基于选定布局创建新布局
168
+
169
+ ### 2.1 获取现有布局列表
170
+
171
+ **接口**: `POST /api/layout/newpage`
172
+
173
+ **请求参数**:
174
+
175
+ | 参数名 | 类型 | 必填 | 说明 |
176
+ |--------|------|------|------|
177
+ | `objid` | string | 是 | 对象 ID |
178
+
179
+ **返回数据**:
180
+
181
+ ```javascript
182
+ {
183
+ "result": true,
184
+ "returnInfo": "操作成功",
185
+ "layouts": [
186
+ {
187
+ "id": "add20261DA7347CZPAUz",
188
+ "layoutName": "默认布局",
189
+ "objid": "20267D1465464C5OB6m5"
190
+ }
191
+ ]
192
+ }
193
+ ```
194
+
195
+ **默认布局选择逻辑**:
196
+
197
+ - 返回列表中的第一个布局作为默认复制源
198
+
199
+ ### 2.2 复制创建新布局
200
+
201
+ **接口**: `POST /api/layout/cloneLayout`
202
+
203
+ **请求参数**:
204
+
205
+ | 参数名 | 类型 | 必填 | 说明 |
206
+ |--------|------|------|------|
207
+ | `layoutId` | string | 是 | 要复制的源布局 ID |
208
+ | `layoutName` | string | 是 | 新布局名称 |
209
+ | `objid` | string | 是 | 对象 ID |
210
+ | `isCloneDynamic` | string | 否 | 是否复制动态布局规则,默认 `"true"` |
211
+
212
+ **请求示例**:
213
+
214
+ ```javascript
215
+ {
216
+ "layoutId": "add20261DA7347CZPAUz",
217
+ "layoutName": "课程表2",
218
+ "objid": "20267D1465464C5OB6m5",
219
+ "isCloneDynamic": "true"
220
+ }
221
+ ```
222
+
223
+ **返回数据**:
224
+
225
+ ```javascript
226
+ {
227
+ "result": true,
228
+ "returnInfo": "操作成功",
229
+ "data": {
230
+ "id": "add2026XXXXXXXXXXXXX",
231
+ "layoutName": "课程表2"
232
+ }
233
+ }
234
+ ```
235
+
236
+ ---
237
+
238
+ ## 三、页面布局数据结构
239
+
240
+ ### 3.1 列表数据格式
241
+
242
+ ```javascript
243
+ {
244
+ id: "add20261DA7347CZPAUz",
245
+ layoutName: "默认布局",
246
+ objid: "20267D1465464C5OB6m5"
247
+ }
248
+ ```
249
+
250
+ ---
251
+
252
+ ## 四、最佳实践
253
+
254
+ ### 命名规范
255
+
256
+ | 项目 | 规范 | 示例 |
257
+ |------|------|------|
258
+ | 布局名称 | 使用描述性名称 | `标准详情页布局`、`移动端布局` |
259
+ | 复制源选择 | 选择结构最相近的布局作为复制源 | - |
260
+
261
+ ### 布局设计建议
262
+
263
+ - **按需复制动态布局规则**:如果源布局有复杂的动态规则,确认是否需要复制到新布局
264
+ - **避免重复创建**:创建前先查询现有布局,避免重复
265
+
266
+ ### 推荐操作流程
267
+
268
+ 1. 查看对象现有布局:`cc get pagelayout . <apiName>`
269
+ 2. 确定复制源布局 ID
270
+ 3. 创建新布局:`cc create pagelayout . <objId> <layoutName> [sourceLayoutId]`
271
+ 4. 验证创建结果
272
+
273
+ ---
274
+
275
+ ## 五、常见问题
276
+
277
+ **Q: 为什么查询页面布局需要先选中对象?**
278
+
279
+ A: 页面布局是绑定到具体对象的,不同对象有不同的字段和关联关系,因此必须先确定对象才能操作其页面布局。
280
+
281
+ **Q: 如何获取对象 ID?**
282
+
283
+ A: 可以通过对象 API 名称查询对象信息获取 ID,或从管理后台的对象管理页面获取。
284
+
285
+ **Q: isCloneDynamic 参数的作用是什么?**
286
+
287
+ A: 该参数控制是否复制源布局的动态布局规则。设置为 `"true"` 时会复制动态规则,设置为 `"false"` 则只复制静态布局。
288
+
289
+ **Q: 创建页面布局时报错 "对象不存在"?**
290
+
291
+ A: 请确认传入的 `objId` 是正确的对象 ID,且该对象在当前环境中存在。
292
+
293
+ ---
294
+
295
+ *文档版本:1.0 | 最后更新:2026-03-26*