cloudcc-cli 2.2.5 → 2.2.6

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/bin/cc.js CHANGED
@@ -2,7 +2,6 @@
2
2
  const chalk = require("chalk")
3
3
 
4
4
  let argvs = process.argv.splice(2);
5
-
6
5
  let action = argvs[0]
7
6
  // 处理版本查询命令
8
7
  if (action === '-version' || action === '-v' || action === '--version' || action === '--v') {
@@ -27,7 +26,6 @@ if (!type) {
27
26
  return;
28
27
  }
29
28
  const cc = require("./index")
30
-
31
29
  try {
32
30
  cc[argvs[1]](argvs[0], argvs);
33
31
  } catch (e) {
package/bin/index.js CHANGED
@@ -30,4 +30,8 @@ cc.fields = require("../src/fields/index")
30
30
 
31
31
  cc.approval = require("../src/approval/index")
32
32
 
33
+ cc.menu = require("../src/menu/index")
34
+
35
+ cc.application = require("../src/application/index")
36
+
33
37
  module.exports = cc;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudcc-cli",
3
- "version": "2.2.5",
3
+ "version": "2.2.6",
4
4
  "description": "cloudcc-cli",
5
5
  "author": "cloudcc",
6
6
  "license": "ISC",
@@ -0,0 +1,114 @@
1
+ const { postClass } = require("../../utils/http")
2
+ const { getPackageJson } = require("../../utils/config");
3
+ const briefGet = require("../brief/get");
4
+ const chalk = require('chalk')
5
+
6
+ /**
7
+ * 创建应用(Application)
8
+ * @param {Array} argvs - 命令行参数数组
9
+ * @returns {Promise<Object>} 创建结果
10
+ */
11
+ async function create(argvs) {
12
+ try {
13
+ // 命令行参数格式:cc create application <path> <p1> <p2> [duel1]
14
+ // argvs: ['application', 'create', path, p1, p2, duel1]
15
+ let path = argvs[2];
16
+ let p1 = argvs[3]; // 应用名称
17
+ let p2 = argvs[4]; // 应用代码
18
+ let duel1 = argvs[5]; // 菜单ID,多个时用逗号分隔,可选,默认为 "acf000001"
19
+
20
+ // 验证必需参数
21
+ if (!p1 || !p2) {
22
+ console.error();
23
+ console.error(chalk.red('Error: 缺少必需参数'));
24
+ console.error('用法: cc create application <path> <p1> <p2> [duel1]');
25
+ console.error(' path: 项目路径');
26
+ console.error(' p1: 应用名称');
27
+ console.error(' p2: 应用代码');
28
+ console.error(' duel1: 菜单ID(可选,多个时用逗号分隔,默认: acf000001)');
29
+ console.error();
30
+ throw new Error('缺少必需参数: p1 和 p2');
31
+ }
32
+
33
+ // 处理 duel1,确保始终包含 acf000001
34
+ const REQUIRED_MENU_ID = "acf000001";
35
+ if (!duel1) {
36
+ // 如果没有传入,使用默认值
37
+ duel1 = REQUIRED_MENU_ID;
38
+ } else {
39
+ // 如果传入了,确保 acf000001 在列表中
40
+ const menuIds = duel1.split(',').map(id => id.trim()).filter(id => id);
41
+ if (!menuIds.includes(REQUIRED_MENU_ID)) {
42
+ // 如果列表中没有 acf000001,添加到列表开头
43
+ menuIds.unshift(REQUIRED_MENU_ID);
44
+ }
45
+ duel1 = menuIds.join(',');
46
+ }
47
+
48
+ let config = await getPackageJson(path);
49
+
50
+ // 从 brief/get 获取角色ID列表(仍使用原始 argv 参数: path 位于 argvs[2])
51
+ // 注意:brief/get 的接口返回是 { success, data } 的格式
52
+ let briefData = await briefGet(argvs);
53
+
54
+ if (!briefData.success) {
55
+ console.error("获取角色列表失败:", briefData.message);
56
+ throw new Error("获取角色列表失败");
57
+ }
58
+
59
+ // 提取所有角色的 ID 列表,用逗号连接
60
+ const profileIdList = briefData.data.map(profile => profile.id);
61
+ const p12 = profileIdList.join(',');
62
+
63
+ // 构建请求体,使用用户提供的参数结构
64
+ const requestBody = {
65
+ "visited_0": "1",
66
+ "visited_1": "1",
67
+ "setupid": "TabSet",
68
+ "apptype": "app",
69
+ "p1": p1,
70
+ "p2": p2,
71
+ "p3": "",
72
+ "navigationStyle": "1",
73
+ "jump": "1",
74
+ "p4": "",
75
+ "appstyle": 21,
76
+ "p8": "home",
77
+ "duel1": duel1,
78
+ "visited_2": "1",
79
+ "visited_3": "1",
80
+ "p12": p12
81
+ };
82
+
83
+ // 显示创建进度
84
+ console.error();
85
+ console.error(chalk.green('Creating application, please wait...'));
86
+ console.error();
87
+
88
+ // 发送请求到服务器
89
+ const result = await postClass(
90
+ config.setupSvc + "/api/appProgram/tabSetDone",
91
+ requestBody,
92
+ config.accessToken
93
+ );
94
+
95
+ // API 返回结构中, result 字段决定调用是否成功
96
+ if (result && result.result) {
97
+ console.error();
98
+ console.error(chalk.green('Success!'));
99
+ console.error();
100
+ return result;
101
+ } else {
102
+ const msg = result && result.returnInfo ? result.returnInfo : 'Unknown error';
103
+ console.error();
104
+ console.error(chalk.red('Error:' + msg));
105
+ throw new Error('Create Application Failed: ' + msg);
106
+ }
107
+ } catch (error) {
108
+ console.error();
109
+ console.error(chalk.red("应用创建失败:"), error);
110
+ throw error;
111
+ }
112
+ }
113
+
114
+ module.exports = create;
@@ -0,0 +1,13 @@
1
+ const { postClass } = require("../../utils/http")
2
+ const { getPackageJson } = require("../../utils/config")
3
+
4
+ async function get(argvs, isMcp = false) {
5
+ // TODO: 实现获取应用列表的功能
6
+ let res = [];
7
+ if (!isMcp) {
8
+ console.log(JSON.stringify(res));
9
+ }
10
+ return res
11
+ }
12
+
13
+ module.exports = get;
@@ -0,0 +1,8 @@
1
+ const cc = {}
2
+ cc.get = require("./get")
3
+ cc.create = require("./create")
4
+ function main(action, argvs) {
5
+ cc[action](argvs)
6
+ }
7
+
8
+ module.exports = main;
package/src/mcp/index.js CHANGED
@@ -20,6 +20,10 @@ const customObjectHandler = require('./tools/Object Creator/handler.js');
20
20
  const objectListHandler = require('./tools/Object List Retriever/handler.js');
21
21
  const objectFieldsHandler = require('./tools/Object Fields Retriever/handler.js');
22
22
  const fieldCreatorHandler = require('./tools/Object Fields Creator/handler.js');
23
+ // 菜单相关工具处理器
24
+ const menuCreatorHandler = require('./tools/Menu Creator/handler.js');
25
+ // 应用相关工具处理器
26
+ const applicationCreatorHandler = require('./tools/Application Creator/handler.js');
23
27
  // 自定义类工具处理器
24
28
  const classesHandler = require("./tools/Class List Retriever/handler.js");
25
29
  const classCreatorHandler = require('./tools/Class Creator/handler.js');
@@ -58,7 +62,7 @@ const clientScriptPublisherHandler = require('./tools/Client Script Publisher/ha
58
62
  const cloudccOverviewHandler = require('./tools/CloudCC Development Overview/handler.js');
59
63
 
60
64
  const mcpServer = new McpServer({
61
- name: 'cctool',
65
+ name: 'cici',
62
66
  version: '1.0.0'
63
67
  });
64
68
 
@@ -68,11 +72,11 @@ mcpServer.registerTool(
68
72
  {
69
73
  description: '帮助开发者检查本地环境是否支持开发 CloudCC 应用(例如自定义组件、自定义类),并按步骤、关键词、平台或难度返回对应的操作或验证命令。',
70
74
  inputSchema: z.object({
71
- step: z.number().int().optional().describe('可选,按步骤号返回具体步骤'),
72
- search: z.string().optional().describe('可选,按关键词搜索步骤'),
73
- difficulty: z.enum(['easy', 'medium', 'hard']).optional().describe('可选,按难度过滤'),
75
+ // step: z.number().int().optional().describe('可选,按步骤号返回具体步骤'),
76
+ // search: z.string().optional().describe('可选,按关键词搜索步骤'),
77
+ // difficulty: z.enum(['easy', 'medium', 'hard']).optional().describe('可选,按难度过滤'),
74
78
  platform: z.enum(['windows', 'macos', 'linux']).optional().describe('可选,按平台获取命令'),
75
- command: z.boolean().optional().describe('可选,返回所有命令的汇总')
79
+ // command: z.boolean().optional().describe('可选,返回所有命令的汇总')
76
80
  })
77
81
  },
78
82
  devEnvValidatorHandler.getDevEnvSetup
@@ -84,11 +88,11 @@ mcpServer.registerTool(
84
88
  {
85
89
  description: '获取 CloudCC 开发环境搭建指南,帮助用户按步骤完成开发环境的安装与配置。',
86
90
  inputSchema: z.object({
87
- step: z.number().int().optional(),
88
- search: z.string().optional(),
89
- difficulty: z.enum(['easy', 'medium', 'hard']).optional(),
91
+ // step: z.number().int().optional(),
92
+ // search: z.string().optional(),
93
+ // difficulty: z.enum(['easy', 'medium', 'hard']).optional(),
90
94
  platform: z.enum(['windows', 'macos', 'linux']).optional(),
91
- command: z.boolean().optional(),
95
+ // command: z.boolean().optional(),
92
96
  })
93
97
  },
94
98
  devEnvHandler.getDevEnvSetup
@@ -161,6 +165,36 @@ mcpServer.registerTool(
161
165
  fieldCreatorHandler.createObjectField
162
166
  );
163
167
 
168
+ // ==================== Menu Creator ====================
169
+ mcpServer.registerTool(
170
+ 'create_menu',
171
+ {
172
+ description: '为 CloudCC CRM 创建菜单(标签页)。支持四种类型的菜单:object(自定义对象)、page(自定义页面)、script(自定义脚本)、site(站点)。菜单将在导航栏中显示,允许用户快速访问相应的资源。',
173
+ inputSchema: z.object({
174
+ menuType: z.enum(['object', 'page', 'script', 'site']).describe('菜单类型:object(自定义对象菜单)、page(自定义页面菜单)、script(自定义脚本菜单)、site(站点菜单)'),
175
+ resourceId: z.string().min(1).describe('资源ID。根据菜单类型不同,可以是:对象ID(object)、页面ID(page)、脚本ID(script)或站点ID(site)。可通过相应的列表工具获取'),
176
+ tabName: z.string().min(1).describe('菜单标签名称,将在导航栏中显示,建议使用对象的显示标签'),
177
+ projectPath: z.string().describe('项目根路径,默认为当前工作目录')
178
+ })
179
+ },
180
+ menuCreatorHandler.createMenuTool
181
+ );
182
+
183
+ // ==================== Application Creator ====================
184
+ mcpServer.registerTool(
185
+ 'create_application',
186
+ {
187
+ description: '在 CloudCC CRM 系统中创建一个应用(Application)。应用可以包含多个菜单,用于组织和管理相关的功能模块。',
188
+ inputSchema: z.object({
189
+ appName: z.string().min(1).describe('应用名称,将在系统中显示的标签'),
190
+ appCode: z.string().min(1).describe('应用代码,应用的唯一标识符'),
191
+ menuIds: z.string().optional().describe('菜单ID列表(可选),多个菜单ID时用逗号分隔。如果不提供,将使用默认菜单ID acf000001。如果提供,系统会自动确保 acf000001 包含在列表中'),
192
+ projectPath: z.string().describe('项目根路径,默认为当前工作目录')
193
+ })
194
+ },
195
+ applicationCreatorHandler.createApplicationTool
196
+ );
197
+
164
198
  // ==================== Class List Retriever ====================
165
199
  mcpServer.registerTool(
166
200
  'get_custom_class_list',
package/src/mcp/readme.md CHANGED
@@ -14,7 +14,7 @@
14
14
  * 检查当前环境的开发者密钥是否配置正确
15
15
  * 指导如何获取密钥,以及如何配置
16
16
 
17
- ### 4:创建应用程序Tool - App Creator
17
+ ### 4:创建应用程序Tool - App Creator
18
18
  * 创建一个应用程序
19
19
 
20
20
  ### 5:查询应用列表 - App List Retriever
@@ -131,7 +131,10 @@
131
131
  * 这是开始 CloudCC 开发前必须查看的工具
132
132
  * 需要使用知识库
133
133
 
134
- ### 42:审批Tool - Approval
134
+ ### 42:审批Tool - Approval
135
135
  * 拉取所有的待审批的记录
136
136
  * 通过id审批通过记录
137
- * 通过id拒绝审批通过记录
137
+ * 通过id拒绝审批通过记录
138
+
139
+ ### 43:菜单Tool - Menu ✅
140
+ * 创建自定义对象菜单
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Application Creator Handler
3
+ * 提供创建应用(Application)的 MCP 工具实现
4
+ */
5
+
6
+ const path = require('path');
7
+ const createApplication = require('../../../application/create');
8
+
9
+ /**
10
+ * 创建应用
11
+ * @param {{
12
+ * appName: string,
13
+ * appCode: string,
14
+ * menuIds?: string,
15
+ * projectPath?: string
16
+ * }} params
17
+ */
18
+ async function createApplicationTool(params = {}) {
19
+ try {
20
+ const { appName, appCode, menuIds, projectPath } = params;
21
+
22
+ // 验证必需参数
23
+ if (!appName || !appCode) {
24
+ return {
25
+ content: [{
26
+ type: 'text',
27
+ text: '✗ 参数缺失: appName (应用名称) 和 appCode (应用代码) 必须提供\n\n参数说明:\n- appName: 应用的显示名称\n- appCode: 应用的代码标识\n- menuIds: 菜单ID列表(可选,多个时用逗号分隔,默认包含 acf000001)\n- projectPath: 项目路径(可选,默认为当前工作目录)'
28
+ }]
29
+ };
30
+ }
31
+
32
+ const resolvedPath = path.resolve(projectPath || '.');
33
+
34
+ // 构建参数数组,格式: ['create', 'application', path, p1, p2, duel1]
35
+ // 注意:argvs[2] 是 path,argvs[3] 是 p1,argvs[4] 是 p2,argvs[5] 是 duel1
36
+ const argvs = [
37
+ 'create',
38
+ 'application',
39
+ resolvedPath,
40
+ appName,
41
+ appCode
42
+ ];
43
+
44
+ // 如果提供了 menuIds,添加到参数中
45
+ if (menuIds) {
46
+ argvs.push(menuIds);
47
+ }
48
+
49
+ // 调用创建函数
50
+ const result = await createApplication(argvs);
51
+
52
+ if (result && result.result) {
53
+ const appId = result.data?.COMMON_APPID || '未知';
54
+ return {
55
+ content: [{
56
+ type: 'text',
57
+ text: `✓ 应用创建成功!\n\n应用名称: ${appName}\n应用代码: ${appCode}\n应用ID: ${appId}\n项目目录: ${resolvedPath}\n菜单ID: ${menuIds || 'acf000001(默认)'}\n\n应用已成功创建并配置到 CloudCC 系统中。`
58
+ }]
59
+ };
60
+ } else {
61
+ return {
62
+ content: [{
63
+ type: 'text',
64
+ text: `⚠ 应用创建遇到问题\n\n请检查:\n1. 应用名称和应用代码是否符合规范\n2. CloudCC服务器连接是否正常\n3. 项目配置是否正确\n4. 是否有足够的权限创建应用\n5. 菜单ID是否正确`
65
+ }]
66
+ };
67
+ }
68
+ } catch (error) {
69
+ return {
70
+ content: [{
71
+ type: 'text',
72
+ text: `✗ 应用创建失败: ${error.message}\n\n错误详情:\n${error.stack || '无详细信息'}\n\n请检查:\n1. 应用名称和应用代码是否正确\n2. 项目路径是否正确\n3. CloudCC服务器连接是否正常\n4. 项目配置文件是否存在\n5. 菜单ID格式是否正确(多个时用逗号分隔)`
73
+ }]
74
+ };
75
+ }
76
+ }
77
+
78
+ module.exports = {
79
+ createApplicationTool
80
+ };
@@ -855,6 +855,7 @@ CloudCC 是一个功能强大的低代码 CRM 平台,提供:
855
855
  ✅ **丰富的前端能力** - Vue 组件、客户端脚本、CCDK API
856
856
  ✅ **标准化的开发流程** - 从环境搭建到部署发布的完整工具链
857
857
  ✅ **强大的 MCP 工具** - AI 辅助开发,提升开发效率
858
+ ✅ **Supabase MCP 集成** - Supabase MCP integration for database operations, authentication, storage, and real-time subscriptions. Manage your Supabase projects, run SQL queries, and interact with your backend directly. AI 可通过 Supabase MCP 与数据库、认证、存储及实时订阅交互,管理项目、执行 SQL、直接操作后端。
858
859
 
859
860
  **开发原则**:
860
861
  1. 编辑任何代码前,先使用 \`*_editor_guide\` 获取开发指南
@@ -864,7 +865,7 @@ CloudCC 是一个功能强大的低代码 CRM 平台,提供:
864
865
  `;
865
866
 
866
867
  module.exports = {
867
- prompts: {
868
- overviewContent
869
- }
868
+ prompts: {
869
+ overviewContent
870
+ }
870
871
  };
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Menu Creator Handler
3
+ * 提供创建菜单(标签页)的 MCP 工具实现
4
+ * 支持类型:object(自定义对象)、page(自定义页面)、script(自定义脚本)、site(站点)
5
+ */
6
+
7
+ const path = require('path');
8
+ const createObjectMenu = require('../../../menu/create-object');
9
+ const createPageMenu = require('../../../menu/create-page');
10
+ const createScriptMenu = require('../../../menu/create-script');
11
+ const createSiteMenu = require('../../../menu/create-site');
12
+
13
+ /**
14
+ * 创建菜单
15
+ * @param {{
16
+ * menuType: 'object' | 'page' | 'script' | 'site',
17
+ * resourceId: string,
18
+ * tabName: string,
19
+ * projectPath?: string
20
+ * }} params
21
+ */
22
+ async function createMenuTool(params = {}) {
23
+ try {
24
+ const { menuType, resourceId, tabName, projectPath } = params;
25
+
26
+ // 验证必需参数
27
+ if (!menuType || !resourceId || !tabName) {
28
+ return {
29
+ content: [{
30
+ type: 'text',
31
+ text: '✗ 参数缺失: menuType (菜单类型)、resourceId (资源ID) 和 tabName (标签名称) 必须提供\n\n支持的菜单类型:\n- object: 自定义对象菜单\n- page: 自定义页面菜单\n- script: 自定义脚本菜单\n- site: 站点菜单'
32
+ }]
33
+ };
34
+ }
35
+
36
+ // 验证菜单类型
37
+ const validTypes = ['object', 'page', 'script', 'site'];
38
+ if (!validTypes.includes(menuType)) {
39
+ return {
40
+ content: [{
41
+ type: 'text',
42
+ text: `✗ 无效的菜单类型: ${menuType}\n\n支持的菜单类型:\n- object: 自定义对象菜单\n- page: 自定义页面菜单\n- script: 自定义脚本菜单\n- site: 站点菜单`
43
+ }]
44
+ };
45
+ }
46
+
47
+ const resolvedPath = path.resolve(projectPath || '.');
48
+
49
+ // 构建参数数组,格式: ['create', 'menu', menuType, path, resourceId, tabName, tabStyle, mobileimg, cloudccservicetab]
50
+ const argvs = [
51
+ 'create',
52
+ 'menu',
53
+ menuType,
54
+ resolvedPath,
55
+ resourceId,
56
+ tabName
57
+ ];
58
+
59
+ // 根据菜单类型调用不同的创建函数
60
+ let result;
61
+ let resourceTypeName;
62
+
63
+ switch (menuType) {
64
+ case 'object':
65
+ result = await createObjectMenu(argvs);
66
+ resourceTypeName = '对象';
67
+ break;
68
+ case 'page':
69
+ result = await createPageMenu(argvs);
70
+ resourceTypeName = '页面';
71
+ break;
72
+ case 'script':
73
+ result = await createScriptMenu(argvs);
74
+ resourceTypeName = '脚本';
75
+ break;
76
+ case 'site':
77
+ result = await createSiteMenu(argvs);
78
+ resourceTypeName = '站点';
79
+ break;
80
+ }
81
+
82
+ if (result && result.result) {
83
+ return {
84
+ content: [{
85
+ type: 'text',
86
+ text: `✓ 自定义${resourceTypeName}菜单创建成功!\n\n菜单类型: ${menuType}\n资源ID: ${resourceId}\n标签名称: ${tabName}\n项目目录: ${resolvedPath}\n\n菜单已成功创建并配置到 CloudCC 系统中。`
87
+ }]
88
+ };
89
+ } else {
90
+ return {
91
+ content: [{
92
+ type: 'text',
93
+ text: `⚠ ${resourceTypeName}菜单创建遇到问题\n\n请检查:\n1. 资源ID是否正确\n2. 标签名称是否符合规范\n3. CloudCC服务器连接是否正常\n4. 项目配置是否正确\n5. 是否有足够的权限创建菜单`
94
+ }]
95
+ };
96
+ }
97
+ } catch (error) {
98
+ return {
99
+ content: [{
100
+ type: 'text',
101
+ text: `✗ 菜单创建失败: ${error.message}\n\n错误详情:\n${error.stack || '无详细信息'}\n\n请检查:\n1. 资源ID是否正确\n2. 项目路径是否正确\n3. CloudCC服务器连接是否正常\n4. 项目配置文件是否存在\n5. 菜单类型是否支持`
102
+ }]
103
+ };
104
+ }
105
+ }
106
+
107
+ module.exports = {
108
+ createMenuTool
109
+ };
@@ -16,7 +16,7 @@ async function editTrigger({ topic = 'overview' }) {
16
16
  // 触发器使用与自定义类和定时类相同的编辑指南
17
17
  // 只是继承的基类不同(CCTrigger vs CCClass vs CCSchedule)
18
18
  const result = await classEditorGuideHandler.editClass({ topic });
19
-
19
+
20
20
  // 在结果前添加触发器特定说明
21
21
  if (result.content && result.content[0]) {
22
22
  const triggerNote = `
@@ -32,8 +32,8 @@ async function editTrigger({ topic = 'overview' }) {
32
32
  5. 常见用途:数据验证、字段自动填充、关联数据更新、业务规则检查等
33
33
 
34
34
  触发器中可访问的特殊变量:
35
- - newList:新记录列表(insert/update操作)
36
- - oldList:旧记录列表(update/delete操作)
35
+ - record_new:新记录列表(insert/update操作)
36
+ - record_old:旧记录列表(update/delete操作)
37
37
  - trigger.isInsert:是否为插入操作
38
38
  - trigger.isUpdate:是否为更新操作
39
39
  - trigger.isDelete:是否为删除操作
@@ -46,7 +46,7 @@ async function editTrigger({ topic = 'overview' }) {
46
46
  `;
47
47
  result.content[0].text = triggerNote + result.content[0].text;
48
48
  }
49
-
49
+
50
50
  return result;
51
51
  } catch (error) {
52
52
  return { content: [{ type: 'text', text: `✗ 获取触发器编辑指南失败: ${error.message}` }] };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 构建公共的菜单字段
3
+ */
4
+ function buildCommonMenuFields(tabName, tabStyle, mobileimg, cloudccservicetab) {
5
+ const commonFields = {
6
+ tabName: tabName,
7
+ tabStyle: tabStyle,
8
+ mobileimg: mobileimg,
9
+ cloudccservicetab: cloudccservicetab,
10
+ };
11
+ return commonFields;
12
+ }
13
+
14
+ module.exports = {
15
+ buildCommonMenuFields
16
+ };
@@ -0,0 +1,94 @@
1
+ const { postClass } = require("../../utils/http")
2
+ const { getPackageJson } = require("../../utils/config");
3
+ const briefGet = require("../brief/get");
4
+ const objectGet = require("../object/get");
5
+ const chalk = require('chalk');
6
+ const { buildCommonMenuFields } = require('./common');
7
+
8
+ /**
9
+ * 创建自定义对象菜单
10
+ * @param {Array} argvs - 命令行参数数组
11
+ * @returns {Promise<Object>} 创建结果
12
+ */
13
+ async function createObjectMenu(argvs) {
14
+ try {
15
+ // 命令行参数格式:cc create menu object <path> <objectId> <tabName>
16
+ // argvs: ['create', 'menu', 'object', '.', 'objectId', 'tabName', ...]
17
+ let path = argvs[3]; // 路径 (argvs[3])
18
+ let objectId = argvs[4]; // 对象ID (p1)
19
+ let tabName = argvs[5]; // 标签名称
20
+ let tabStyle = "cloudtab145"; // 标签样式图标,默认 cloudtab145
21
+ let mobileimg = "cloudcc01"; // 移动端图标,默认 cloudcc01
22
+ let cloudccservicetab = "cloudccservicetab_1"; // 服务标签图标,默认 cloudccservicetab_1
23
+
24
+ if (!objectId || !tabName) {
25
+ console.error();
26
+ console.error(chalk.red('Error: 缺少必需参数'));
27
+ console.error('用法: cc create menu object <path> <objectId> <tabName> [tabStyle] [mobileimg] [cloudccservicetab]');
28
+ console.error();
29
+ throw new Error('缺少必需参数: objectId 和 tabName');
30
+ }
31
+
32
+ let config = await getPackageJson(path);
33
+
34
+ // 从 brief/get 获取角色ID列表
35
+ // briefGet 期望 argvs[2] 是 path,所以需要调整参数数组
36
+ const briefArgvs = [argvs[0], argvs[1], path]; // ['create', 'menu', path]
37
+ let briefData = await briefGet(briefArgvs);
38
+
39
+ if (!briefData.success) {
40
+ console.error("获取角色列表失败:", briefData.message);
41
+ throw new Error("获取角色列表失败");
42
+ }
43
+
44
+ // 提取所有角色的 ID 列表,格式为 "profileId_show"
45
+ const profileIds = briefData.data.map(profile => `${profile.id}_show`);
46
+
47
+ // 构建公共字段
48
+ const commonFields = buildCommonMenuFields(tabName, tabStyle, mobileimg, cloudccservicetab);
49
+
50
+ // 构建请求体
51
+ const requestBody = {
52
+ ed: "ed",
53
+ visited_0: "1",
54
+ visited_1: "1",
55
+ visited_2: "1",
56
+ allOrSome: "some",
57
+ type: "object",
58
+ p1: objectId,
59
+ ...commonFields,
60
+ profileIds: profileIds,
61
+ };
62
+
63
+ // 显示创建进度
64
+ console.error();
65
+ console.error(chalk.green('Creating object menu, please wait...'));
66
+ console.error();
67
+
68
+ // 发送请求到服务器
69
+ const result = await postClass(
70
+ config.setupSvc + "/api/customTab/tabSetDone",
71
+ requestBody,
72
+ config.accessToken
73
+ );
74
+
75
+ // API 返回结构中, result 字段决定调用是否成功
76
+ if (result && result.result) {
77
+ console.error();
78
+ console.error(chalk.green('Success!'));
79
+ console.error();
80
+ return result;
81
+ } else {
82
+ const msg = result && result.returnInfo ? result.returnInfo : 'Unknown error';
83
+ console.error();
84
+ console.error(chalk.red('Error:' + msg));
85
+ throw new Error('Create Object Menu Failed: ' + msg);
86
+ }
87
+ } catch (error) {
88
+ console.error();
89
+ console.error(chalk.red("自定义对象菜单创建失败:"), error);
90
+ throw error;
91
+ }
92
+ }
93
+
94
+ module.exports = createObjectMenu;