cloudcc-cli 2.2.8 → 2.3.0
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 +32 -1
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_CLASS.md +97 -0
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_SCHEDULE.md +78 -0
- package/.cursor/skills/cloudcc-cli-dev/BACKEND_TRIGGER.md +137 -0
- package/.cursor/skills/cloudcc-cli-dev/CLI_CHEATSHEET.md +215 -0
- package/.cursor/skills/cloudcc-cli-dev/CUSTOM-SETTING-API.md +241 -0
- package/{cloudcc-cli-dev → .cursor/skills/cloudcc-cli-dev}/SKILL.md +7 -2
- package/.cursor/skills/cloudcc-cli-dev/VUE_CUSTOM_COMPONENT.md +151 -0
- package/README.md +22 -0
- package/bin/index.js +6 -0
- package/build/component-cc-test-001.common.js +831 -0
- package/build/component-cc-test-001.common.js.map +1 -0
- package/build/component-cc-test-001.css +1 -0
- package/build/component-cc-test-001.umd.js +874 -0
- package/build/component-cc-test-001.umd.js.map +1 -0
- package/build/component-cc-test-001.umd.min.js +8 -0
- package/build/component-cc-test-001.umd.min.js.map +1 -0
- package/build/demo.html +1 -0
- package/classes/CCdd/CCdd.java +22 -0
- package/classes/CCdd/CCddTest.java +11 -0
- package/classes/CCdd/config.json +1 -0
- package/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 +130 -0
- package/docs/cloudcc/345/256/232/346/227/266/344/275/234/344/270/232.md +472 -0
- package/docs/cloudcc/345/256/232/346/227/266/347/261/273.md +302 -0
- package/docs//350/207/252/345/256/232/344/271/211/347/261/273.md +258 -0
- package/docs//350/247/246/345/217/221/345/231/250/347/261/273.md +404 -0
- package/package.json +1 -1
- package/plugins/cc-test-001/cc-test-001.vue +32 -0
- package/plugins/cc-test-001/components/HelloWorld.vue +11 -0
- package/plugins/cc-test-001/config.json +6 -0
- package/schedule/CCdd/CCdd.java +11 -0
- package/schedule/CCdd/config.json +1 -0
- package/src/customPage/create.js +77 -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/doc.js +196 -0
- package/src/customSetting/index.js +7 -0
- package/src/plugin/delete.js +91 -0
- package/src/plugin/doc.js +76 -0
- package/src/plugin/index.js +1 -0
- package/src/triggers/doc.js +258 -222
- package/src/triggers/pullList.js +3 -0
- package/target/classes/CCdd/CCdd.class +0 -0
- package/target/classes/CCdd/CCddTest.class +0 -0
- package/target/classes/CCdd/config.json +1 -0
- package/cloudcc-cli-dev/BACKEND_CODE.md +0 -114
- package/cloudcc-cli-dev/CLI_CHEATSHEET.md +0 -90
- package/cloudcc-cli-dev/VUE_CUSTOM_COMPONENT.md +0 -50
- /package/{cloudcc-cli-dev → .cursor/skills/cloudcc-cli-dev}/INSTALL_AND_BOOTSTRAP.md +0 -0
- /package/{cloudcc-cli-dev → .cursor/skills/cloudcc-cli-dev}/OBJECTS_AND_FIELDS.md +0 -0
- /package/{cloudcc-cli-dev → .cursor/skills/cloudcc-cli-dev}/REQUIREMENTS_BREAKDOWN.md +0 -0
|
@@ -0,0 +1,85 @@
|
|
|
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 customPage list [pageNo] [pageSize] [projectPath]
|
|
10
|
+
*/
|
|
11
|
+
async function listCustomPage(argvs) {
|
|
12
|
+
const pageNo = parseInt(argvs[2], 10) || 1;
|
|
13
|
+
const pageSize = parseInt(argvs[3], 10) || 20;
|
|
14
|
+
const projectPath = argvs[4] || process.cwd();
|
|
15
|
+
|
|
16
|
+
const config = await getPackageJson(projectPath);
|
|
17
|
+
if (!config || !config.accessToken) {
|
|
18
|
+
console.error();
|
|
19
|
+
console.error(chalk.red('Error: Configuration not found or accessToken is missing'));
|
|
20
|
+
console.error();
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const devSvcDispatch = config.devSvcDispatch || '/devconsole';
|
|
25
|
+
const baseUrl = config.baseUrl || BaseUrl;
|
|
26
|
+
|
|
27
|
+
const header = {
|
|
28
|
+
appType: 'lightning-devconsole',
|
|
29
|
+
accessToken: config.accessToken,
|
|
30
|
+
source: 'lightning-devconsole',
|
|
31
|
+
version: 'public',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const body = {
|
|
35
|
+
pageNo,
|
|
36
|
+
pageSize,
|
|
37
|
+
condition: {
|
|
38
|
+
pageLabel: '',
|
|
39
|
+
dtBegin: '',
|
|
40
|
+
dtEnd: '',
|
|
41
|
+
pageApi: '',
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
console.error();
|
|
46
|
+
console.error(chalk.green(`Fetching custom page list (page ${pageNo}, size ${pageSize})...`));
|
|
47
|
+
|
|
48
|
+
const res = await post(
|
|
49
|
+
`${baseUrl}${devSvcDispatch}/custom/pc/1.0/post/pageCustomPage`,
|
|
50
|
+
body,
|
|
51
|
+
header
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (res && res.returnCode == 200) {
|
|
55
|
+
const data = res.data || {};
|
|
56
|
+
const records = data.records || data.list || data || [];
|
|
57
|
+
const total = data.total ?? (Array.isArray(records) ? records.length : 0);
|
|
58
|
+
|
|
59
|
+
console.error(chalk.green(`Success! Total: ${total}`));
|
|
60
|
+
console.error();
|
|
61
|
+
|
|
62
|
+
if (Array.isArray(records) && records.length > 0) {
|
|
63
|
+
records.forEach((item, index) => {
|
|
64
|
+
console.log(
|
|
65
|
+
chalk.cyan(`[${index + 1}]`) +
|
|
66
|
+
` ID: ${item.id || '-'}` +
|
|
67
|
+
` Label: ${item.pageLabel || '-'}` +
|
|
68
|
+
` API: ${item.pageApi || '-'}`
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
} else {
|
|
72
|
+
console.log(chalk.yellow('No custom pages found.'));
|
|
73
|
+
}
|
|
74
|
+
console.error();
|
|
75
|
+
} else {
|
|
76
|
+
const errMsg = res?.returnInfo || 'Unknown error';
|
|
77
|
+
console.error(chalk.red(`Fail: ${errMsg}`));
|
|
78
|
+
console.error();
|
|
79
|
+
throw new Error('List Custom Page Failed: ' + errMsg);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return res;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
module.exports = listCustomPage;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* customSetting 文档统一入口(全量一次性输出)
|
|
3
|
+
*/
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
|
|
7
|
+
function generateFullMarkdownDoc() {
|
|
8
|
+
const lines = [
|
|
9
|
+
"# CloudCC 自定义设置操作指南",
|
|
10
|
+
"",
|
|
11
|
+
"> 本文档按实际页面操作顺序整理,覆盖你提供的 7 个步骤图:",
|
|
12
|
+
"> 列表 -> 新建 -> 编辑 -> 详情建字段 -> 字段类型选择 -> 字段属性填写 -> 字段编辑。",
|
|
13
|
+
"",
|
|
14
|
+
"直接查看 CLI 文档:`cc doc customSetting`",
|
|
15
|
+
"",
|
|
16
|
+
"---",
|
|
17
|
+
"",
|
|
18
|
+
"## 1. 入口与列表页(图一)",
|
|
19
|
+
"",
|
|
20
|
+
"进入路径:`设置 -> 开发者空间 -> 自定义设置`。",
|
|
21
|
+
"",
|
|
22
|
+
"在列表页可看到:",
|
|
23
|
+
"- 标签",
|
|
24
|
+
"- 可见性",
|
|
25
|
+
"- 设置类型",
|
|
26
|
+
"- 描述",
|
|
27
|
+
"",
|
|
28
|
+
"右上角点击「新建」进入自定义设置创建弹窗。",
|
|
29
|
+
"",
|
|
30
|
+
"---",
|
|
31
|
+
"",
|
|
32
|
+
"## 2. 新建自定义设置(图二)",
|
|
33
|
+
"",
|
|
34
|
+
"点击图一右上角「新建」,弹出「自定义设置:新建」窗口,需要填写:",
|
|
35
|
+
"",
|
|
36
|
+
"- `标签`(必填)",
|
|
37
|
+
"- `对象名`(必填)",
|
|
38
|
+
"- `设置类型`(如:列表)",
|
|
39
|
+
"- `可见性`(如:公用)",
|
|
40
|
+
"- `描述`(可选)",
|
|
41
|
+
"",
|
|
42
|
+
"填写后保存,返回列表可看到新建记录。",
|
|
43
|
+
"",
|
|
44
|
+
"---",
|
|
45
|
+
"",
|
|
46
|
+
"## 3. 编辑自定义设置基础信息(图三)",
|
|
47
|
+
"",
|
|
48
|
+
"在列表中选择一条记录进入编辑弹窗「自定义设置:编辑」。",
|
|
49
|
+
"",
|
|
50
|
+
"常见行为:",
|
|
51
|
+
"- 可编辑:标签、可见性、描述等",
|
|
52
|
+
"- 对象名、设置类型通常按产品规则受限(常见为不可改)",
|
|
53
|
+
"",
|
|
54
|
+
"保存后回到列表,确认信息更新成功。",
|
|
55
|
+
"",
|
|
56
|
+
"---",
|
|
57
|
+
"",
|
|
58
|
+
"## 4. 进入详情并管理字段(图四)",
|
|
59
|
+
"",
|
|
60
|
+
"点击某条自定义设置后进入详情页,页面分为两块:",
|
|
61
|
+
"",
|
|
62
|
+
"1. 自定义设置详细信息(头部)",
|
|
63
|
+
"2. 自定义设置字段列表(下半区)",
|
|
64
|
+
"",
|
|
65
|
+
"在字段列表区域可点击「新建」,为当前自定义设置新增字段。",
|
|
66
|
+
"",
|
|
67
|
+
"---",
|
|
68
|
+
"",
|
|
69
|
+
"## 5. 新建字段 - 选择数据类型(图五)",
|
|
70
|
+
"",
|
|
71
|
+
"点击图四的「新建」后,进入「自定义字段」向导第一步:",
|
|
72
|
+
"",
|
|
73
|
+
"- 选择字段数据类型(如 URL、百分比、货币、电话、电子邮件、文本、日期等)",
|
|
74
|
+
"- 该步骤决定下一步字段属性表单内容",
|
|
75
|
+
"",
|
|
76
|
+
"选择完成后点击「下一步」。",
|
|
77
|
+
"",
|
|
78
|
+
"---",
|
|
79
|
+
"",
|
|
80
|
+
"## 6. 新建字段 - 填写字段属性并保存(图六)",
|
|
81
|
+
"",
|
|
82
|
+
"在第二步填写字段属性(示例为文本字段):",
|
|
83
|
+
"",
|
|
84
|
+
"- 字段标签(必填)",
|
|
85
|
+
"- 长度(如文本长度 255)",
|
|
86
|
+
"- 字段名 / API 名称(必填)",
|
|
87
|
+
"- 独有配置(如不允许重复值,按需开启)",
|
|
88
|
+
"",
|
|
89
|
+
"点击「保存」后,即在当前自定义设置下创建了一个新字段。",
|
|
90
|
+
"",
|
|
91
|
+
"---",
|
|
92
|
+
"",
|
|
93
|
+
"## 7. 编辑已有字段(图七)",
|
|
94
|
+
"",
|
|
95
|
+
"保存成功后回到字段列表,可看到新字段。点击某字段的操作菜单(如「...」)可进行:",
|
|
96
|
+
"",
|
|
97
|
+
"- 编辑:修改字段属性(可修改范围受字段类型和系统规则限制)",
|
|
98
|
+
"- 删除:移除该字段(建议先确认是否已有业务依赖)",
|
|
99
|
+
"",
|
|
100
|
+
"编辑保存后,字段列表会展示最新结果。",
|
|
101
|
+
"",
|
|
102
|
+
"---",
|
|
103
|
+
"",
|
|
104
|
+
"## 8. 新建字段支持的所有字段类型",
|
|
105
|
+
"",
|
|
106
|
+
"自定义设置详情页「新建字段」当前支持以下字段类型(与前端字段类型选择一致):",
|
|
107
|
+
"",
|
|
108
|
+
"| 类型代码(fdtype) | 类型名称 | 说明 |",
|
|
109
|
+
"|---|---|---|",
|
|
110
|
+
"| `U` | URL | 允许输入有效网址;点击后按打开方式在新/当前窗口打开 |",
|
|
111
|
+
"| `P` | 百分比 | 输入数字并自动添加百分号(如 10 -> 10%) |",
|
|
112
|
+
"| `c` | 币种 | 金额/币种类型字段 |",
|
|
113
|
+
"| `H` | 电话 | 输入电话号码并按电话格式展示 |",
|
|
114
|
+
"| `E` | 电子邮件 | 输入邮箱并校验格式(可用于“发送电子邮件”选择地址) |",
|
|
115
|
+
"| `B` | 复选框 | 布尔值(真/假) |",
|
|
116
|
+
"| `D` | 日期 | 输入或选择日期 |",
|
|
117
|
+
"| `F` | 日期和时间 | 输入或选择日期时间 |",
|
|
118
|
+
"| `N` | 数字 | 输入数字(会删除前置零) |",
|
|
119
|
+
"| `S` | 文本 | 字母数字组合文本 |",
|
|
120
|
+
"| `X` | 长文本 | 多行文本,最多 4000 字符 |",
|
|
121
|
+
"",
|
|
122
|
+
"在接口层面:新建/编辑字段使用 `POST /api/customsetting/saveField`,其中 `fdtype` 与 `tpSysSchemetableVO.schemefieldType` 建议保持一致(例如文本为 `S`,百分比为 `P`)。",
|
|
123
|
+
"",
|
|
124
|
+
"---",
|
|
125
|
+
"",
|
|
126
|
+
"## 9. Java 侧读取自定义设置(CCService)",
|
|
127
|
+
"",
|
|
128
|
+
"### 9.1 列表类型(List)",
|
|
129
|
+
"",
|
|
130
|
+
"```java",
|
|
131
|
+
"// 某 API 名称下的全部数据",
|
|
132
|
+
"Map listSettings = cs.getListCustomSetting(\"MyListSettingApiName\");",
|
|
133
|
+
"",
|
|
134
|
+
"// 指定 Name 的单条",
|
|
135
|
+
"Map singleSetting = cs.getListCustomSetting(\"MyListSettingApiName\", \"SomeName\");",
|
|
136
|
+
"```",
|
|
137
|
+
"",
|
|
138
|
+
"### 9.2 层次结构类型(Hierarchy)",
|
|
139
|
+
"",
|
|
140
|
+
"```java",
|
|
141
|
+
"// id 为简档 ID 或用户 ID",
|
|
142
|
+
"Map hiSetting = cs.getCustomSetting(\"MyHierarchySettingApiName\", profileOrUserId);",
|
|
143
|
+
"```",
|
|
144
|
+
"",
|
|
145
|
+
"---",
|
|
146
|
+
"",
|
|
147
|
+
"## 10. 操作 Checklist",
|
|
148
|
+
"",
|
|
149
|
+
"- [ ] 已在列表页确认目标自定义设置(标签/对象名)",
|
|
150
|
+
"- [ ] 新建时已正确选择设置类型与可见性",
|
|
151
|
+
"- [ ] 进入详情后通过字段向导完成字段新增",
|
|
152
|
+
"- [ ] 字段 `标签`、`API 名称`、`长度` 等配置符合规范",
|
|
153
|
+
"- [ ] 保存后已在字段列表验证新增或编辑结果",
|
|
154
|
+
"- [ ] 代码侧读取时,API 名称与平台配置保持一致",
|
|
155
|
+
"",
|
|
156
|
+
];
|
|
157
|
+
|
|
158
|
+
const base = lines.join("\n");
|
|
159
|
+
const apiPath = path.join(
|
|
160
|
+
__dirname,
|
|
161
|
+
"..",
|
|
162
|
+
"..",
|
|
163
|
+
"cloudcc-cli-dev",
|
|
164
|
+
"CUSTOM-SETTING-API.md"
|
|
165
|
+
);
|
|
166
|
+
let apiContent = "";
|
|
167
|
+
try {
|
|
168
|
+
apiContent = fs.readFileSync(apiPath, "utf8");
|
|
169
|
+
} catch (e) {
|
|
170
|
+
apiContent = `# 自定义设置相关接口\n\n(未找到文件:${apiPath})\n`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return [
|
|
174
|
+
base,
|
|
175
|
+
"",
|
|
176
|
+
"---",
|
|
177
|
+
"",
|
|
178
|
+
"## 附录:自定义设置 Setup 接口速查",
|
|
179
|
+
"",
|
|
180
|
+
"> 来源:`cloudcc-cli-dev/CUSTOM-SETTING-API.md`",
|
|
181
|
+
"",
|
|
182
|
+
apiContent.trim(),
|
|
183
|
+
"",
|
|
184
|
+
].join("\n");
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function doc() {
|
|
188
|
+
const content = generateFullMarkdownDoc();
|
|
189
|
+
console.log(content);
|
|
190
|
+
return content;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
doc.getClassEditorDoc = doc;
|
|
194
|
+
doc.getEditGuide = doc;
|
|
195
|
+
|
|
196
|
+
module.exports = doc;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const { getPackageJson } = require("../../utils/config");
|
|
5
|
+
const { post } = require("../../utils/http");
|
|
6
|
+
const BaseUrl = "https://developer.apis.cloudcc.cn";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 删除云端自定义组件
|
|
10
|
+
* 支持通过组件名或 ID 删除:
|
|
11
|
+
* - 传组件名时:从本地 plugins/<name>/config.json 读取 id 后删除
|
|
12
|
+
* - 传 ID 时:直接通过 ID 删除
|
|
13
|
+
*
|
|
14
|
+
* 用法:cc delete plugin <pluginNameOrId> [projectPath]
|
|
15
|
+
*/
|
|
16
|
+
async function deletePlugin(argvs) {
|
|
17
|
+
const input = argvs[2];
|
|
18
|
+
const projectPath = argvs[3] || process.cwd();
|
|
19
|
+
|
|
20
|
+
if (!input) {
|
|
21
|
+
console.error();
|
|
22
|
+
console.error(chalk.red('Error: Plugin name or ID is required'));
|
|
23
|
+
console.error(chalk.yellow('Usage: cc delete plugin <pluginNameOrId> [projectPath]'));
|
|
24
|
+
console.error();
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 先尝试将 input 作为组件名处理:检查本地 config.json 是否有 id
|
|
29
|
+
const configPath = path.join(projectPath, `plugins/${input}/config.json`);
|
|
30
|
+
if (fs.existsSync(configPath)) {
|
|
31
|
+
try {
|
|
32
|
+
const configContent = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
33
|
+
if (configContent.id) {
|
|
34
|
+
await deleteById(configContent.id, projectPath);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
} catch (error) {
|
|
38
|
+
console.error(chalk.yellow(`Warning: Failed to read config.json, treating input as ID: ${error.message}`));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// 作为 ID 处理
|
|
43
|
+
await deleteById(input, projectPath);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 通过 ID 删除云端组件
|
|
48
|
+
*/
|
|
49
|
+
async function deleteById(pluginId, projectPath) {
|
|
50
|
+
const config = await getPackageJson(projectPath);
|
|
51
|
+
if (!config || !config.accessToken) {
|
|
52
|
+
throw new Error('Configuration not found or accessToken is missing');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const devSvcDispatch = config.devSvcDispatch || '/devconsole';
|
|
56
|
+
const baseUrl = config.baseUrl || BaseUrl;
|
|
57
|
+
|
|
58
|
+
const header = {
|
|
59
|
+
"appType": "lightning-setup",
|
|
60
|
+
"appVersion": "0.0.1",
|
|
61
|
+
"accessToken": config.accessToken,
|
|
62
|
+
"source": "lightning-setup",
|
|
63
|
+
"version": "public"
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const body = {
|
|
67
|
+
"id": pluginId
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
console.error(chalk.green(`Deleting plugin (ID: ${pluginId}), please wait...`));
|
|
71
|
+
|
|
72
|
+
const res = await post(
|
|
73
|
+
`${baseUrl}${devSvcDispatch}/custom/pc/1.0/post/deleteCustomComp`,
|
|
74
|
+
body,
|
|
75
|
+
header
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
if (res && res.returnCode == 200) {
|
|
79
|
+
console.error(chalk.green(`Success! Plugin (ID: ${pluginId}) deleted from server.`));
|
|
80
|
+
console.error();
|
|
81
|
+
} else {
|
|
82
|
+
const errMsg = res?.returnInfo || 'Unknown error';
|
|
83
|
+
console.error(chalk.red(`Fail: ${errMsg}`));
|
|
84
|
+
console.error();
|
|
85
|
+
throw new Error('Delete Plugin Failed: ' + errMsg);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return res;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
module.exports = deletePlugin;
|
package/src/plugin/doc.js
CHANGED
|
@@ -13,6 +13,82 @@ function generateFullMarkdownDoc() {
|
|
|
13
13
|
"",
|
|
14
14
|
"---",
|
|
15
15
|
"",
|
|
16
|
+
"## 0. 自定义组件概述(能力与场景)",
|
|
17
|
+
"",
|
|
18
|
+
"本文节整合了仓库内实践用法,帮助你在开始编码前先判断:什么是自定义组件、能解决什么问题、何时该用。",
|
|
19
|
+
"",
|
|
20
|
+
"### 0.1 什么是自定义组件(本项目语境)",
|
|
21
|
+
"",
|
|
22
|
+
"在本项目中,**自定义组件**通常指以 **Vue 2 单文件组件(`.vue`)** 为入口、放在 `plugins/<插件名>/` 下,通过 `cloudccBuild` / `cloudccBuild2` 等 CLI 命令打包后,嵌入 CloudCC 页面或应用的前端能力单元。",
|
|
23
|
+
"",
|
|
24
|
+
"一个插件一般包含:",
|
|
25
|
+
"",
|
|
26
|
+
"| 内容 | 作用 |",
|
|
27
|
+
"|------|------|",
|
|
28
|
+
"| 入口 `.vue`(如 `cc-ai-chat.vue`) | 组件 UI 与业务逻辑 |",
|
|
29
|
+
"| `config.json` | 组件标识、名称、描述、分类、加载模式等元数据 |",
|
|
30
|
+
"| `components/`、`utils/` 等 | 子组件、HTTP 封装、适配器、第三方 SDK 封装 |",
|
|
31
|
+
"",
|
|
32
|
+
"入口组件中常见 `componentInfo` 对象,与 `config.json` 呼应,用于平台展示组件信息与加载策略。",
|
|
33
|
+
"",
|
|
34
|
+
"### 0.2 自定义组件能做什么",
|
|
35
|
+
"",
|
|
36
|
+
"- 扩展标准 CRM 页面:在记录页、列表页、门户中挂载专用界面",
|
|
37
|
+
"- 对接外部系统:接入 OpenAPI、Agent、地图、图可视化等复杂交互",
|
|
38
|
+
"- 使用 CloudCC 运行时能力:通过 `$CCDK` 读取用户、Token、网关、事件总线",
|
|
39
|
+
"- 实现独立数据层(按需):对接组织允许的外部存储或服务",
|
|
40
|
+
"- 搭建实施与诊断工具:同步、调试、日志、排查面板等运营能力",
|
|
41
|
+
"",
|
|
42
|
+
"一句话:自定义组件是在 CloudCC 宿主内运行、可独立版本化的前端扩展能力。",
|
|
43
|
+
"",
|
|
44
|
+
"### 0.3 为什么要用自定义组件",
|
|
45
|
+
"",
|
|
46
|
+
"| 原因 | 说明 |",
|
|
47
|
+
"|------|------|",
|
|
48
|
+
"| 标准功能边界 | 标准布局与字段配置难覆盖甘特图、对话式 AI、复杂工作台等场景 |",
|
|
49
|
+
"| 体验与品牌 | 需要统一交互、定制视觉与复合布局体验 |",
|
|
50
|
+
"| 集成成本 | 第三方 SaaS/自研 API 更适合在前端组件中做适配封装 |",
|
|
51
|
+
"| 迭代效率 | 前端组件可独立发版,与后端逻辑解耦,支持小步快跑 |",
|
|
52
|
+
"| 复用能力 | 同一组件可复用到多个页面,通过属性配置实现差异化 |",
|
|
53
|
+
"",
|
|
54
|
+
"### 0.4 典型可解决问题",
|
|
55
|
+
"",
|
|
56
|
+
"1. 平台可配置但体验较差:通过专用 UI 优化录入、查询、可视化流程",
|
|
57
|
+
"2. 必须与外部系统实时协同:在组件内完成请求与回调闭环",
|
|
58
|
+
"3. 需要强上下文:利用 `$CCDK` 获取当前用户、视图与凭证避免重复登录",
|
|
59
|
+
"4. 需要跨模块联动:借助总线事件让多个区域同步响应",
|
|
60
|
+
"5. 需要工具化交付:建设调试与运维面板降低人工操作风险",
|
|
61
|
+
"",
|
|
62
|
+
"### 0.5 什么时候优先考虑自定义组件",
|
|
63
|
+
"",
|
|
64
|
+
"| 场景类型 | 示例 |",
|
|
65
|
+
"|----------|------|",
|
|
66
|
+
"| 复杂可视化 | 甘特图、关系图、统计大屏 |",
|
|
67
|
+
"| 对话与智能助手 | 嵌入式 AI 聊天、Agent 工具面板 |",
|
|
68
|
+
"| 行业专用工作台 | 客户 360、项目工作台、专题门户 |",
|
|
69
|
+
"| 门户与附件增强 | 文件上传下载、模板导出导入 |",
|
|
70
|
+
"| 表单 + 外部库 | 自定义流程表单 + 第三方服务 |",
|
|
71
|
+
"| 实施与运维工具 | SQL 工具、健康检查、调试面板 |",
|
|
72
|
+
"",
|
|
73
|
+
"不建议强行使用自定义组件的场景:",
|
|
74
|
+
"- 仅靠标准字段、列表、校验即可满足需求时",
|
|
75
|
+
"- 需要强安全与一致性的核心业务规则(应放在服务端)",
|
|
76
|
+
"",
|
|
77
|
+
"### 0.6 开发与构建要点(仓库实践)",
|
|
78
|
+
"",
|
|
79
|
+
"- 依赖按需引入,避免插件无关依赖膨胀",
|
|
80
|
+
"- 使用 `npm run build-plugin`(`cloudccBuild`)产出发布包",
|
|
81
|
+
"- 本地通过 `npm run serve` 快速调试组件交互",
|
|
82
|
+
"- 运行环境通过注入 `$CCDK` 提供统一账号、网关、上传、日志与事件能力",
|
|
83
|
+
"",
|
|
84
|
+
"### 0.7 结论",
|
|
85
|
+
"",
|
|
86
|
+
"- 自定义组件 = CloudCC 宿主内的 Vue 插件包 + 元数据 + 可选 `$CCDK` 集成",
|
|
87
|
+
"- 核心价值:在保持平台一致性的同时,快速交付标准配置覆盖不到的能力",
|
|
88
|
+
"- 选型建议:复杂 UI、多系统集成、强上下文、工具化需求优先;可标准配置解决则优先标准方案",
|
|
89
|
+
"",
|
|
90
|
+
"---",
|
|
91
|
+
"",
|
|
16
92
|
"## 1. 快速上手:发布第一个组件",
|
|
17
93
|
"",
|
|
18
94
|
"### 1.1 启动项目",
|
package/src/plugin/index.js
CHANGED