cloudcc-cli 2.2.9 → 2.3.1
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.
- package/.cloudcc-cache.json +4 -52
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_CLASS.md +15 -1
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_SCHEDULE.md +82 -8
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_TRIGGER.md +13 -0
- package/.cursor/skills/cloudcc-cli-dev/CLI_CHEATSHEET.md +234 -77
- package/.cursor/skills/cloudcc-cli-dev/CUSTOM-SETTING-API.md +62 -0
- package/.cursor/skills/cloudcc-cli-dev/INSTALL_AND_BOOTSTRAP.md +9 -6
- package/.cursor/skills/cloudcc-cli-dev/OBJECTS_AND_FIELDS.md +99 -5
- package/.cursor/skills/cloudcc-cli-dev/REQUIREMENTS_BREAKDOWN.md +15 -0
- package/.cursor/skills/cloudcc-cli-dev/SKILL.md +29 -7
- package/.cursor/skills/cloudcc-cli-dev/STATIC-RESOURCE-API.md +60 -0
- package/.cursor/skills/cloudcc-cli-dev/VUE_CUSTOM_PAGE.md +216 -0
- package/.cursor/skills/cloudcc-cli-dev/docs//350/207/252/345/256/232/344/271/211/351/241/265/351/235/242.md +228 -0
- package/README.md +23 -1
- package/bin/index.js +7 -0
- package/package.json +2 -2
- package/src/application/delete.js +59 -0
- package/src/application/get.js +31 -5
- package/src/application/index.js +1 -0
- package/src/classes/delete.js +43 -0
- package/src/classes/detail.js +14 -7
- package/src/classes/index.js +7 -1
- package/src/customPage/create.js +139 -0
- package/src/customPage/delete.js +65 -0
- package/src/customPage/get.js +85 -0
- package/src/customPage/index.js +10 -0
- package/src/customSetting/create.js +27 -0
- package/src/customSetting/delete.js +26 -0
- package/src/customSetting/detail.js +24 -0
- package/src/customSetting/doc.js +196 -0
- package/src/customSetting/get.js +25 -0
- package/src/customSetting/index.js +11 -0
- package/src/fields/delete.js +52 -0
- package/src/fields/index.js +1 -0
- package/src/menu/create-page.js +16 -25
- package/src/menu/create.js +9 -3
- package/src/menu/delete.js +59 -0
- package/src/menu/get.js +56 -0
- package/src/menu/index.js +2 -0
- package/src/object/delete.js +51 -0
- package/src/object/index.js +1 -0
- package/src/plugin/detail.js +14 -6
- package/src/plugin/publish1.js +3 -3
- package/src/recordType/get.js +1 -1
- package/src/scheduleJob/delete.js +26 -0
- package/src/scheduleJob/detail.js +23 -0
- package/src/scheduleJob/get.js +26 -0
- package/src/scheduleJob/index.js +10 -0
- package/src/staticResource/count.js +25 -0
- package/src/staticResource/delete.js +26 -0
- package/src/staticResource/detail.js +24 -0
- package/src/staticResource/doc.js +106 -0
- package/src/staticResource/get.js +25 -0
- package/src/staticResource/index.js +12 -0
- package/src/timer/delete.js +43 -0
- package/src/timer/index.js +1 -0
- package/src/triggers/delete.js +46 -0
- package/src/triggers/index.js +1 -0
- package/test/application.cli.test.js +49 -8
- package/test/classes.cli.test.js +9 -3
- package/test/customSetting.cli.test.js +84 -0
- package/test/fields.cli.test.js +18 -3
- package/test/menu.cli.test.js +34 -4
- package/test/object.cli.test.js +17 -1
- package/test/scheduleJob.cli.test.js +52 -0
- package/test/staticResource.cli.test.js +78 -0
- package/test/timer.cli.test.js +8 -2
- package/test/trigger.cli.test.js +8 -2
- package/build/component-cc-test-001.common.js +0 -831
- package/build/component-cc-test-001.common.js.map +0 -1
- package/build/component-cc-test-001.css +0 -1
- package/build/component-cc-test-001.umd.js +0 -874
- package/build/component-cc-test-001.umd.js.map +0 -1
- package/build/component-cc-test-001.umd.min.js +0 -8
- package/build/component-cc-test-001.umd.min.js.map +0 -1
- package/build/demo.html +0 -1
- package/core.zip +0 -0
- package/plugins/cc-test-001/cc-test-001.vue +0 -32
- package/plugins/cc-test-001/components/HelloWorld.vue +0 -11
- package/plugins/cc-test-001/config.json +0 -6
- package/target/ccopenapi-0.0.4-classes.jar +0 -0
- package/target/ccopenapi-0.0.4.jar +0 -0
- package/target/maven-archiver/pom.properties +0 -3
- package/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst +0 -20
- package/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst +0 -19
- /package/{docs → .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" +0 -0
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}/cloudcc/345/256/232/346/227/266/344/275/234/344/270/232.md" +0 -0
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}/cloudcc/345/256/232/346/227/266/347/261/273.md" +0 -0
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}//350/207/252/345/256/232/344/271/211/347/261/273.md" +0 -0
- /package/{docs → .cursor/skills/cloudcc-cli-dev/docs}//350/247/246/345/217/221/345/231/250/347/261/273.md" +0 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# CloudCC 自定义页面说明文档
|
|
2
|
+
|
|
3
|
+
## 一、什么是自定义页面
|
|
4
|
+
|
|
5
|
+
自定义页面是 CloudCC
|
|
6
|
+
平台提供的可视化页面构建工具,基于**自定义组件**创建,通过**拖拉拽**的方式调整页面布局、配置组件属性,实现各种业务需求。
|
|
7
|
+
|
|
8
|
+
### 核心特点
|
|
9
|
+
|
|
10
|
+
- 🎨 **可视化编辑** - 无需编码,通过拖拽组件快速搭建页面
|
|
11
|
+
- 🧩 **组件化** - 基于自定义组件构建,支持复用和扩展
|
|
12
|
+
- 📱 **自适应布局** - 支持像素、百分比、视口等多种单位
|
|
13
|
+
- 🔌 **灵活集成** - 支持菜单、内嵌、代码调用等多种使用方式
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 二、自定义页面能干什么
|
|
18
|
+
|
|
19
|
+
### 1. 快速构建业务页面
|
|
20
|
+
|
|
21
|
+
通过物料库中的基础组件和数据组件,快速搭建符合业务需求的页面,无需从零开始编码。
|
|
22
|
+
|
|
23
|
+
### 2. 灵活布局设计
|
|
24
|
+
|
|
25
|
+
- 支持固定宽高布局(像素单位)
|
|
26
|
+
- 支持自适应布局(百分比单位)
|
|
27
|
+
- 支持响应式布局(视口单位)
|
|
28
|
+
|
|
29
|
+
### 3. 组件间通信
|
|
30
|
+
|
|
31
|
+
通过 `$CCDK.CCBus` 实现组件间的消息传递,支持复杂业务逻辑的协同工作。
|
|
32
|
+
|
|
33
|
+
### 4. 多场景集成
|
|
34
|
+
|
|
35
|
+
- 创建独立菜单页面
|
|
36
|
+
- 内嵌到系统详情页
|
|
37
|
+
- 通过 `ccdk.openCustomPage()` 代码调用
|
|
38
|
+
|
|
39
|
+
### 5. 移动端调试
|
|
40
|
+
|
|
41
|
+
支持使用 eruda 插件在移动端 App 中调试 H5 页面。
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 三、主要作用
|
|
46
|
+
|
|
47
|
+
| 作用 | 说明 |
|
|
48
|
+
| --------------- | ---------------------------- |
|
|
49
|
+
| 🚀 **加速开发** | 可视化搭建,减少重复编码工作 |
|
|
50
|
+
| 🔄 **组件复用** | 一次开发组件,多处页面使用 |
|
|
51
|
+
| 🎯 **业务适配** | 灵活配置,快速响应业务变化 |
|
|
52
|
+
| 📦 **降低门槛** | 非开发人员也可参与页面搭建 |
|
|
53
|
+
| 🔧 **易于维护** | 组件化设计,修改影响范围可控 |
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 四、为什么要用自定义页面
|
|
58
|
+
|
|
59
|
+
### 传统开发方式的问题
|
|
60
|
+
|
|
61
|
+
- ❌ 每个页面都需要单独编码,重复工作多
|
|
62
|
+
- ❌ 样式和布局不统一,维护成本高
|
|
63
|
+
- ❌ 业务变更时需要修改代码,发布周期长
|
|
64
|
+
- ❌ 非开发人员无法参与,依赖开发资源
|
|
65
|
+
|
|
66
|
+
### 自定义页面的优势
|
|
67
|
+
|
|
68
|
+
- ✅ **标准化** - 统一的组件规范和页面结构
|
|
69
|
+
- ✅ **高效** - 拖拽式操作,分钟级完成页面搭建
|
|
70
|
+
- ✅ **灵活** - 组件可配置,适应不同业务场景
|
|
71
|
+
- ✅ **可扩展** - 支持自定义组件开发,满足特殊需求
|
|
72
|
+
- ✅ **低代码** - 业务人员可参与,减少开发依赖
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 五、自定义页面能解决哪些问题
|
|
77
|
+
|
|
78
|
+
### 1. 个性化业务需求
|
|
79
|
+
|
|
80
|
+
标准页面无法满足的个性化业务场景,通过自定义页面快速实现。
|
|
81
|
+
|
|
82
|
+
**示例**:特殊的审批流程页面、定制化的数据展示面板
|
|
83
|
+
|
|
84
|
+
### 2. 复杂数据展示
|
|
85
|
+
|
|
86
|
+
需要多维度、多格式展示数据的场景。
|
|
87
|
+
|
|
88
|
+
**示例**:仪表盘、统计报表、数据可视化大屏
|
|
89
|
+
|
|
90
|
+
### 3. 特殊交互需求
|
|
91
|
+
|
|
92
|
+
标准组件无法满足的交互逻辑。
|
|
93
|
+
|
|
94
|
+
**示例**:拖拽排序、动态表单、联动筛选
|
|
95
|
+
|
|
96
|
+
### 4. 第三方系统集成
|
|
97
|
+
|
|
98
|
+
需要嵌入外部系统或调用外部 API 的场景。
|
|
99
|
+
|
|
100
|
+
**示例**:嵌入 BI 报表、调用外部服务接口
|
|
101
|
+
|
|
102
|
+
### 5. 移动端适配
|
|
103
|
+
|
|
104
|
+
需要同时支持 PC 和移动端的页面。
|
|
105
|
+
|
|
106
|
+
**示例**:外勤人员使用的移动审批页面
|
|
107
|
+
|
|
108
|
+
### 6. 快速原型验证
|
|
109
|
+
|
|
110
|
+
业务需求不明确时,快速搭建原型进行验证。
|
|
111
|
+
|
|
112
|
+
**示例**:新功能 MVP 验证、用户反馈收集
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## 六、使用场景与业务场景
|
|
117
|
+
|
|
118
|
+
### 6.1 推荐使用自定义页面的场景
|
|
119
|
+
|
|
120
|
+
| 场景类型 | 具体场景 | 推荐理由 |
|
|
121
|
+
| --------------- | ---------------------------- | -------------------- |
|
|
122
|
+
| 📊 **数据展示** | 仪表盘、统计报表、数据大屏 | 灵活布局,多组件组合 |
|
|
123
|
+
| 📝 **表单录入** | 复杂表单、动态表单、多级表单 | 组件可配置,校验灵活 |
|
|
124
|
+
| 🔍 **查询搜索** | 高级搜索、多条件筛选 | 组件间通信方便 |
|
|
125
|
+
| 📋 **审批流程** | 定制化审批页、特殊流程 | 业务逻辑可定制 |
|
|
126
|
+
| 📱 **移动端** | 外勤应用、移动办公 | 自适应布局支持好 |
|
|
127
|
+
| 🔗 **系统集成** | 嵌入外部系统、API 调用 | 扩展性强 |
|
|
128
|
+
| 🎨 **品牌定制** | 企业个性化页面 | 样式可完全定制 |
|
|
129
|
+
|
|
130
|
+
### 6.2 不推荐使用自定义页面的场景
|
|
131
|
+
|
|
132
|
+
| 场景 | 原因 | 建议方案 |
|
|
133
|
+
| -------------- | ------------ | ---------------- |
|
|
134
|
+
| 标准 CRUD 操作 | 杀鸡用牛刀 | 使用系统标准页面 |
|
|
135
|
+
| 简单信息展示 | 过度设计 | 使用系统详情页 |
|
|
136
|
+
| 一次性使用 | 投入产出比低 | 评估是否需要 |
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 七、最佳实践
|
|
141
|
+
|
|
142
|
+
### 7.1 页面设计原则
|
|
143
|
+
|
|
144
|
+
```
|
|
145
|
+
┌─────────────────────────────────┐
|
|
146
|
+
│ 自定义页面 (100%) │
|
|
147
|
+
│ ┌───────────────────────────┐ │
|
|
148
|
+
│ │ 自定义组件 (100%) │ │
|
|
149
|
+
│ │ │ │
|
|
150
|
+
│ │ 组件内部自由布局 │ │
|
|
151
|
+
│ │ │ │
|
|
152
|
+
│ └───────────────────────────┘ │
|
|
153
|
+
└─────────────────────────────────┘
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
- 📐 **一页一组件** - 一个页面只放一个组件,画布和组件都设置 100% 宽高
|
|
157
|
+
- 🧩 **组件内布局** - 复杂布局在组件内部实现,保持页面简洁
|
|
158
|
+
- 🔄 **组件复用** - 通用功能封装成组件,多处复用
|
|
159
|
+
|
|
160
|
+
### 7.2 组件通信规范
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
// 组件 A - 接收消息
|
|
164
|
+
mounted() {
|
|
165
|
+
this.$CCDK.CCBus.$on('demoB2A', (args) => {
|
|
166
|
+
console.log("收到消息", args)
|
|
167
|
+
})
|
|
168
|
+
},
|
|
169
|
+
beforeDestroy() {
|
|
170
|
+
this.$CCDK.CCBus.$off('demoB2A') // 记得解绑
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// 组件 B - 发送消息
|
|
174
|
+
methods: {
|
|
175
|
+
emit() {
|
|
176
|
+
this.$CCDK.CCBus.$emit("demoB2A", "消息内容")
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### 7.3 页面入口选择
|
|
182
|
+
|
|
183
|
+
| 入口方式 | 适用场景 | 配置方式 |
|
|
184
|
+
| ---------- | ------------------ | ----------------------- |
|
|
185
|
+
| 菜单 | 独立功能模块 | 自定义页面菜单 |
|
|
186
|
+
| 内嵌详情页 | 关联业务展示 | 系统详情页配置 |
|
|
187
|
+
| 代码调用 | 动态跳转、条件打开 | `ccdk.openCustomPage()` |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## 八、快速开始
|
|
192
|
+
|
|
193
|
+
### 8.1 创建自定义页面
|
|
194
|
+
|
|
195
|
+
1. 登录 CloudCC 系统
|
|
196
|
+
2. 点击右上角头像 → 开发者控制台
|
|
197
|
+
3. 自定义布局 → 自定义页面 → 新建
|
|
198
|
+
4. 从物料库拖拽组件到画布
|
|
199
|
+
5. 配置组件属性
|
|
200
|
+
6. 保存页面
|
|
201
|
+
|
|
202
|
+
### 8.2 开发自定义组件
|
|
203
|
+
|
|
204
|
+
参考:[自定义组件开发文档](https://cloudccone.feishu.cn/wiki/AzyWwgHBPiEG2gkeDEXcb56snbb)
|
|
205
|
+
|
|
206
|
+
### 8.3 调试与发布
|
|
207
|
+
|
|
208
|
+
- 使用预览功能测试页面
|
|
209
|
+
- 移动端使用 eruda 调试
|
|
210
|
+
- 发布后配置页面入口
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## 九、总结
|
|
215
|
+
|
|
216
|
+
自定义页面是 CloudCC 平台提供的**低代码页面构建解决方案**,核心价值在于:
|
|
217
|
+
|
|
218
|
+
- 🎯 **提效** - 减少重复开发,加速交付
|
|
219
|
+
- 🔧 **灵活** - 适应各种业务场景
|
|
220
|
+
- 📦 **复用** - 组件化设计,一次开发多处使用
|
|
221
|
+
- 🚀 **扩展** - 支持自定义组件,无上限扩展
|
|
222
|
+
|
|
223
|
+
**适用原则**:标准功能优先,个性化需求用自定义页面。
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
_文档版本:1.0_\
|
|
228
|
+
_最后更新:2026-03-25_
|
package/README.md
CHANGED
|
@@ -22,6 +22,28 @@ sudo npm i -g cloudcc-cli
|
|
|
22
22
|
}
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
+
# ReleaseV2.3.1
|
|
26
|
+
|
|
27
|
+
#### Release Date: 2026-3-25
|
|
28
|
+
|
|
29
|
+
#### Release Scope: Full
|
|
30
|
+
|
|
31
|
+
#### Release Content
|
|
32
|
+
|
|
33
|
+
- Optimization
|
|
34
|
+
- Adjusted unit tests
|
|
35
|
+
|
|
36
|
+
# ReleaseV2.3.0
|
|
37
|
+
|
|
38
|
+
#### Release Date: 2026-3-25
|
|
39
|
+
|
|
40
|
+
#### Release Scope: Full
|
|
41
|
+
|
|
42
|
+
#### Release Content
|
|
43
|
+
|
|
44
|
+
- Optimization
|
|
45
|
+
- Fix class management commands
|
|
46
|
+
|
|
25
47
|
# ReleaseV2.2.9
|
|
26
48
|
|
|
27
49
|
#### Release Date: 2026-3-25
|
|
@@ -31,7 +53,7 @@ sudo npm i -g cloudcc-cli
|
|
|
31
53
|
#### Release Content
|
|
32
54
|
|
|
33
55
|
- Optimization
|
|
34
|
-
-
|
|
56
|
+
- Add delete component command
|
|
35
57
|
|
|
36
58
|
# ReleaseV2.2.8
|
|
37
59
|
|
package/bin/index.js
CHANGED
|
@@ -6,6 +6,11 @@ cc.plugin = require("../src/plugin/index")
|
|
|
6
6
|
|
|
7
7
|
cc.classes = require("../src/classes/index")
|
|
8
8
|
|
|
9
|
+
cc.customSetting = require("../src/customSetting/index")
|
|
10
|
+
|
|
11
|
+
cc.staticResource = require("../src/staticResource/index")
|
|
12
|
+
cc.customPage = require("../src/customPage/index")
|
|
13
|
+
|
|
9
14
|
cc.schedule = require("../src/timer/index")
|
|
10
15
|
|
|
11
16
|
cc.triggers = require("../src/triggers/index")
|
|
@@ -34,6 +39,8 @@ cc.menu = require("../src/menu/index")
|
|
|
34
39
|
|
|
35
40
|
cc.application = require("../src/application/index")
|
|
36
41
|
|
|
42
|
+
cc.scheduleJob = require("../src/scheduleJob/index")
|
|
43
|
+
|
|
37
44
|
|
|
38
45
|
|
|
39
46
|
module.exports = cc;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudcc-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "cloudcc-cli",
|
|
5
5
|
"author": "cloudcc",
|
|
6
6
|
"license": "ISC",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"cc-mcp": "bin/mcp.js"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
|
-
"test-cli-one": "node --test test/
|
|
19
|
+
"test-cli-one": "node --test test/menu.cli.test.js",
|
|
20
20
|
"test-cli-all": "node --test ",
|
|
21
21
|
"cc-pull": "git fetch --tags -f && git pull",
|
|
22
22
|
"publish-lib": "npm publish --registry https://registry.npmjs.org && git add . && git commit -m 'update' && git push && curl https://npmmirror.com/sync/cloudcc-cli",
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const chalk = require("chalk");
|
|
2
|
+
const { postClass } = require("../../utils/http");
|
|
3
|
+
const { getPackageJson } = require("../../utils/config");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 删除应用(Application)
|
|
7
|
+
* 用法:cc delete application <projectPath> <appId>
|
|
8
|
+
*/
|
|
9
|
+
async function remove(argvs) {
|
|
10
|
+
try {
|
|
11
|
+
const projectPath = argvs[2] || process.cwd();
|
|
12
|
+
const appId = argvs[3];
|
|
13
|
+
|
|
14
|
+
if (!appId) {
|
|
15
|
+
console.error();
|
|
16
|
+
console.error(chalk.red("Error: 缺少应用 ID"));
|
|
17
|
+
console.error(chalk.yellow("用法: cc delete application <projectPath> <appId>"));
|
|
18
|
+
console.error();
|
|
19
|
+
throw new Error("缺少必需参数: appId");
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const config = await getPackageJson(projectPath);
|
|
23
|
+
if (!config || !config.accessToken) {
|
|
24
|
+
console.error();
|
|
25
|
+
console.error(chalk.red("Error: 配置未找到或 accessToken 缺失"));
|
|
26
|
+
console.error();
|
|
27
|
+
throw new Error("配置未找到或 accessToken 缺失");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.error();
|
|
31
|
+
console.error(chalk.green(`Deleting application (${appId}), please wait...`));
|
|
32
|
+
console.error();
|
|
33
|
+
|
|
34
|
+
const result = await postClass(
|
|
35
|
+
config.setupSvc + "/api/appProgram/deleteApp",
|
|
36
|
+
{ id: appId },
|
|
37
|
+
config.accessToken
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (result && result.result) {
|
|
41
|
+
console.error();
|
|
42
|
+
console.error(chalk.green("Success! Application deleted."));
|
|
43
|
+
console.error();
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const msg = result && (result.returnInfo || result.message) ? (result.returnInfo || result.message) : "Unknown error";
|
|
48
|
+
console.error();
|
|
49
|
+
console.error(chalk.red("Error: " + msg));
|
|
50
|
+
console.error();
|
|
51
|
+
throw new Error("Delete Application Failed: " + msg);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error();
|
|
54
|
+
console.error(chalk.red("应用删除失败:"), error);
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
module.exports = remove;
|
package/src/application/get.js
CHANGED
|
@@ -2,12 +2,38 @@ const { postClass } = require("../../utils/http")
|
|
|
2
2
|
const { getPackageJson } = require("../../utils/config")
|
|
3
3
|
|
|
4
4
|
async function get(argvs, isMcp = false) {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
const projectPath = argvs[2] || process.cwd();
|
|
6
|
+
const condArg = argvs[3];
|
|
7
|
+
|
|
8
|
+
let body = {};
|
|
9
|
+
if (condArg) {
|
|
10
|
+
try {
|
|
11
|
+
body = JSON.parse(decodeURI(condArg));
|
|
12
|
+
} catch (e) {
|
|
13
|
+
throw new Error("Get Application List Failed: encodedCondJson 解析失败,请传 encodeURI(JSON.stringify(...))");
|
|
14
|
+
}
|
|
9
15
|
}
|
|
10
|
-
|
|
16
|
+
|
|
17
|
+
const config = await getPackageJson(projectPath);
|
|
18
|
+
const result = await postClass(
|
|
19
|
+
config.setupSvc + "/api/appProgram/queryAppList",
|
|
20
|
+
body,
|
|
21
|
+
config.accessToken
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
if (result && result.result) {
|
|
25
|
+
const data = result.data;
|
|
26
|
+
const rawList = Array.isArray(data)
|
|
27
|
+
? data
|
|
28
|
+
: (data && Array.isArray(data.list) ? data.list : []);
|
|
29
|
+
if (!isMcp) {
|
|
30
|
+
console.log(JSON.stringify(rawList));
|
|
31
|
+
}
|
|
32
|
+
return rawList;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const msg = result && (result.returnInfo || result.message) ? (result.returnInfo || result.message) : "Unknown error";
|
|
36
|
+
throw new Error("Get Application List Failed: " + msg);
|
|
11
37
|
}
|
|
12
38
|
|
|
13
39
|
module.exports = get;
|
package/src/application/index.js
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const { getPackageJson } = require("../../utils/config");
|
|
5
|
+
const { postClass } = require("../../utils/http");
|
|
6
|
+
|
|
7
|
+
async function remove(nameOrId, projectPath = process.cwd()) {
|
|
8
|
+
let classId = nameOrId;
|
|
9
|
+
const classPath = path.join(projectPath, `classes/${nameOrId}/`);
|
|
10
|
+
const configPath = path.join(classPath, "config.json");
|
|
11
|
+
|
|
12
|
+
if (fs.existsSync(configPath)) {
|
|
13
|
+
const configContent = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
14
|
+
if (configContent.id) {
|
|
15
|
+
classId = configContent.id;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!classId) {
|
|
20
|
+
throw new Error("Delete Class Failed: class name or id is required");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const config = await getPackageJson(projectPath);
|
|
24
|
+
console.error();
|
|
25
|
+
console.error(chalk.green(`Deleting class (${classId}), please wait...`));
|
|
26
|
+
console.error();
|
|
27
|
+
|
|
28
|
+
const res = await postClass(
|
|
29
|
+
config.setupSvc + "/api/ccfag/delete",
|
|
30
|
+
{ id: classId },
|
|
31
|
+
config.accessToken
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
if (res && res.result) {
|
|
35
|
+
console.error(chalk.green("Success! Class deleted."));
|
|
36
|
+
console.error();
|
|
37
|
+
return res;
|
|
38
|
+
}
|
|
39
|
+
const msg = res && (res.returnInfo || res.message) ? (res.returnInfo || res.message) : "Unknown error";
|
|
40
|
+
throw new Error("Delete Class Failed: " + msg);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = remove;
|
package/src/classes/detail.js
CHANGED
|
@@ -4,7 +4,14 @@ const path = require("path")
|
|
|
4
4
|
const { getPackageJson } = require("../../utils/config")
|
|
5
5
|
const { postClass } = require("../../utils/http")
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
function outputResult(result, isMcp) {
|
|
8
|
+
if (!isMcp) {
|
|
9
|
+
console.log(JSON.stringify(result));
|
|
10
|
+
}
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async function detail(name, id, isMcp = false) {
|
|
8
15
|
// 如果有 name,优先查询本地
|
|
9
16
|
if (name && name !== '') {
|
|
10
17
|
const classPath = path.join(process.cwd(), `classes/${name}/`);
|
|
@@ -15,14 +22,14 @@ async function detail(name, id) {
|
|
|
15
22
|
if (fs.existsSync(configPath) && fs.existsSync(javaFilePath)) {
|
|
16
23
|
let configContent = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
17
24
|
let javaContent = fs.readFileSync(javaFilePath, 'utf8');
|
|
18
|
-
return {
|
|
25
|
+
return outputResult({
|
|
19
26
|
name: configContent.name,
|
|
20
27
|
version: configContent.version,
|
|
21
28
|
id: configContent.id || null,
|
|
22
29
|
source: javaContent,
|
|
23
30
|
published: !!configContent.id,
|
|
24
31
|
fromLocal: true
|
|
25
|
-
};
|
|
32
|
+
}, isMcp);
|
|
26
33
|
}
|
|
27
34
|
|
|
28
35
|
// 本地文件不完整,从服务器拉取
|
|
@@ -44,10 +51,10 @@ async function detail(name, id) {
|
|
|
44
51
|
let res = await postClass(config.setupSvc + "/api/ccfag/detail", body, config.accessToken)
|
|
45
52
|
|
|
46
53
|
if (res.result) {
|
|
47
|
-
return {
|
|
54
|
+
return outputResult({
|
|
48
55
|
...res.data.trigger,
|
|
49
56
|
fromLocal: false
|
|
50
|
-
};
|
|
57
|
+
}, isMcp);
|
|
51
58
|
} else {
|
|
52
59
|
throw new Error('Get Class Details Failed: ' + res.returnInfo);
|
|
53
60
|
}
|
|
@@ -62,10 +69,10 @@ async function detail(name, id) {
|
|
|
62
69
|
let res = await postClass(config.setupSvc + "/api/ccfag/detail", body, config.accessToken)
|
|
63
70
|
|
|
64
71
|
if (res.result) {
|
|
65
|
-
return {
|
|
72
|
+
return outputResult({
|
|
66
73
|
...res.data.trigger,
|
|
67
74
|
fromLocal: false
|
|
68
|
-
};
|
|
75
|
+
}, isMcp);
|
|
69
76
|
} else {
|
|
70
77
|
throw new Error('Get Class Details Failed: ' + res.returnInfo);
|
|
71
78
|
}
|
package/src/classes/index.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
const cc = {}
|
|
2
|
-
|
|
2
|
+
cc.create = require("./create")
|
|
3
|
+
cc.publish = require("./publish")
|
|
4
|
+
cc.pull = require("./pull")
|
|
5
|
+
cc.get = require("./get")
|
|
6
|
+
cc.pullList = require("./pullList")
|
|
7
|
+
cc.detail = require("./detail")
|
|
3
8
|
cc.doc = require("./doc")
|
|
9
|
+
cc.delete = require("./delete")
|
|
4
10
|
function Classes(action, argvs) {
|
|
5
11
|
cc[action](argvs[2], argvs[3])
|
|
6
12
|
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const { getPackageJson } = require('../../utils/config');
|
|
3
|
+
const { post } = require('../../utils/http');
|
|
4
|
+
const BaseUrl = 'https://developer.apis.cloudcc.cn';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 新建自定义页面
|
|
8
|
+
*
|
|
9
|
+
* 用法:cc create customPage <pageLabel> <pageApi> <pluginId|compLabel> [projectPath]
|
|
10
|
+
*/
|
|
11
|
+
async function createCustomPage(argvs) {
|
|
12
|
+
const pageLabel = argvs[2];
|
|
13
|
+
const pageApi = argvs[3];
|
|
14
|
+
const pluginIdentifier = argvs[4];
|
|
15
|
+
const projectPath = argvs[5] || process.cwd();
|
|
16
|
+
|
|
17
|
+
if (!pageLabel || !pageApi || !pluginIdentifier) {
|
|
18
|
+
console.error();
|
|
19
|
+
console.error(chalk.red('Error: pageLabel, pageApi and pluginId/compLabel are required'));
|
|
20
|
+
console.error(chalk.yellow('Usage: cc create customPage <pageLabel> <pageApi> <pluginId|compLabel> [projectPath]'));
|
|
21
|
+
console.error();
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const config = await getPackageJson(projectPath);
|
|
26
|
+
if (!config || !config.accessToken) {
|
|
27
|
+
console.error();
|
|
28
|
+
console.error(chalk.red('Error: Configuration not found or accessToken is missing'));
|
|
29
|
+
console.error();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const devSvcDispatch = config.devSvcDispatch || '/devconsole';
|
|
34
|
+
const baseUrl = config.baseUrl || BaseUrl;
|
|
35
|
+
|
|
36
|
+
const header = {
|
|
37
|
+
appType: 'lightning-devconsole',
|
|
38
|
+
accessToken: config.accessToken,
|
|
39
|
+
source: 'lightning-devconsole',
|
|
40
|
+
version: 'public',
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// 先通过 listCustomComp 获取组件列表,再按组件标识匹配目标组件
|
|
44
|
+
const listRes = await post(
|
|
45
|
+
`${baseUrl}${devSvcDispatch}/custom/pc/1.0/post/listCustomComp`,
|
|
46
|
+
{ orgId: config.orgId || '' },
|
|
47
|
+
header
|
|
48
|
+
);
|
|
49
|
+
if (!listRes || String(listRes.returnCode) !== '200') {
|
|
50
|
+
throw new Error('Create Custom Page Failed: list custom components failed');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const groupedCompMap = listRes.data || {};
|
|
54
|
+
const compList = Array.isArray(groupedCompMap['label.dev.bizType.custom'])
|
|
55
|
+
? groupedCompMap['label.dev.bizType.custom']
|
|
56
|
+
: [];
|
|
57
|
+
if (compList.length === 0) {
|
|
58
|
+
throw new Error('Create Custom Page Failed: no custom components found');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let pluginDetail = compList.find(item =>
|
|
62
|
+
item &&
|
|
63
|
+
(item.id === pluginIdentifier || item.compLabel === pluginIdentifier || item.compUniName === pluginIdentifier)
|
|
64
|
+
);
|
|
65
|
+
if (!pluginDetail) {
|
|
66
|
+
throw new Error(`Create Custom Page Failed: component "${pluginIdentifier}" not found in custom component list`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let vueData = {};
|
|
70
|
+
try {
|
|
71
|
+
vueData = pluginDetail.vueData ? JSON.parse(pluginDetail.vueData) : {};
|
|
72
|
+
} catch (e) {
|
|
73
|
+
throw new Error('Create Custom Page Failed: plugin vueData is not valid JSON');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const randomId = (len = 10) => Math.random().toString(36).slice(2, 2 + len);
|
|
77
|
+
const itemId = randomId(10);
|
|
78
|
+
const compUniName = pluginDetail.compUniName || pluginDetail.component || pluginDetail.name;
|
|
79
|
+
const compLabel = pluginDetail.compLabel || pluginDetail.compName || compUniName;
|
|
80
|
+
const compDesc = pluginDetail.compDesc || '';
|
|
81
|
+
const templatePropObj = vueData.propObj && typeof vueData.propObj === 'object' ? vueData.propObj : {};
|
|
82
|
+
|
|
83
|
+
const pageContentItem = {
|
|
84
|
+
...vueData,
|
|
85
|
+
id: itemId,
|
|
86
|
+
comId: pluginDetail.id,
|
|
87
|
+
name: compUniName,
|
|
88
|
+
componentInfo: {
|
|
89
|
+
...(vueData.componentInfo || {}),
|
|
90
|
+
component: compUniName,
|
|
91
|
+
compName: compLabel,
|
|
92
|
+
compDesc,
|
|
93
|
+
},
|
|
94
|
+
propObj: {
|
|
95
|
+
...templatePropObj,
|
|
96
|
+
id: itemId,
|
|
97
|
+
key: templatePropObj.key || randomId(4),
|
|
98
|
+
pageApi,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const body = {
|
|
103
|
+
id: '',
|
|
104
|
+
pageLabel,
|
|
105
|
+
pageApi,
|
|
106
|
+
pageContent: JSON.stringify([pageContentItem]),
|
|
107
|
+
orgId: pluginDetail.orgId || config.orgId || '',
|
|
108
|
+
compList: [{
|
|
109
|
+
id: pluginDetail.id,
|
|
110
|
+
compUniName,
|
|
111
|
+
}],
|
|
112
|
+
canvasStyleData: JSON.stringify({ width: 100, height: 100, scale: 100, unit: '%', pageApi }),
|
|
113
|
+
isTemplate: 0,
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
console.error();
|
|
117
|
+
console.error(chalk.green(`Creating custom page "${pageLabel}" (api: ${pageApi}, component: ${pluginIdentifier}), please wait...`));
|
|
118
|
+
|
|
119
|
+
const res = await post(
|
|
120
|
+
`${baseUrl}${devSvcDispatch}/custom/pc/1.0/post/insertCustomPage`,
|
|
121
|
+
body,
|
|
122
|
+
header
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
if (res && String(res.returnCode) === '200') {
|
|
126
|
+
const id = res.data?.id || res.data || '';
|
|
127
|
+
console.error(chalk.green(`Success! Custom page created.${id ? ' ID: ' + id : ''}`));
|
|
128
|
+
console.error();
|
|
129
|
+
} else {
|
|
130
|
+
const errMsg = res?.returnInfo || 'Unknown error';
|
|
131
|
+
console.error(chalk.red(`Fail: ${errMsg}`));
|
|
132
|
+
console.error();
|
|
133
|
+
throw new Error('Create Custom Page Failed: ' + errMsg);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return res;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = createCustomPage;
|