neo-cmp-cli 1.6.0-beta.1 → 1.6.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/package.json +1 -1
  2. package/src/module/index.js +32 -26
  3. package/src/module/main.js +161 -267
  4. package/src/module/neoInit.js +1 -0
  5. package/src/neo/NeoUMDContent.js +5 -5
  6. package/src/neo/neoService.js +17 -18
  7. package/src/oss/publish2oss.js +174 -71
  8. package/src/template/antd-custom-cmp-template/README.md +26 -2
  9. package/src/template/antd-custom-cmp-template/neo.config.js +2 -2
  10. package/src/template/echarts-custom-cmp-template/README.md +26 -2
  11. package/src/template/echarts-custom-cmp-template/neo.config.js +4 -3
  12. package/src/template/empty-custom-cmp-template/README.md +26 -0
  13. package/src/template/empty-custom-cmp-template/neo.config.js +2 -2
  14. package/src/template/neo-custom-cmp-template/README.md +26 -2
  15. package/src/template/neo-custom-cmp-template/neo.config.js +1 -1
  16. package/src/template/react-custom-cmp-template/README.md +26 -2
  17. package/src/template/react-custom-cmp-template/neo.config.js +2 -2
  18. package/src/template/react-ts-custom-cmp-template/README.md +26 -2
  19. package/src/template/react-ts-custom-cmp-template/neo.config.js +2 -2
  20. package/src/template/vue2-custom-cmp-template/README.md +26 -2
  21. package/src/template/vue2-custom-cmp-template/neo.config.js +2 -2
  22. package/src/{cmpUtils → utils/cmpUtils}/createCmpByTemplate.js +7 -5
  23. package/src/{cmpUtils → utils/cmpUtils}/createCmpByZip.js +5 -2
  24. package/src/{cmpUtils → utils/cmpUtils}/createCommonModulesCode.js +2 -2
  25. package/src/{cmpUtils → utils/cmpUtils}/getCmpModelRegisterCode.js +1 -1
  26. package/src/{cmpUtils → utils/cmpUtils}/getCmpPreviewCode.js +1 -1
  27. package/src/{cmpUtils → utils/cmpUtils}/getCmpRegisterCode.js +1 -1
  28. package/src/{cmpUtils → utils/cmpUtils}/getCmpTypeByDir.js +2 -2
  29. package/src/{cmpUtils → utils/cmpUtils}/hasCmpTypeByDir.js +1 -1
  30. package/src/{cmpUtils → utils/cmpUtils}/previewCmp.js +3 -3
  31. package/src/{cmpUtils → utils/cmpUtils}/pullCmp.js +9 -9
  32. package/src/{cmpUtils → utils/cmpUtils}/pushCmp.js +7 -5
  33. package/src/utils/generateEntries.js +73 -0
  34. package/src/{projectUtils → utils/projectUtils}/createCmpProjectByTemplate.js +10 -6
  35. package/src/{projectUtils → utils/projectUtils}/createCmpProjectZip.js +1 -3
  36. package/src/{projectUtils → utils/projectUtils}/getEntries.js +2 -2
  37. package/src/{projectUtils → utils/projectUtils}/getEntriesWithAutoRegister.js +2 -2
  38. package/src/{projectUtils → utils/projectUtils}/updatePublishLog.js +1 -1
  39. package/src/template/neo-custom-cmp-template/pushCmp.js +0 -166
  40. /package/src/{projectUtils → utils/projectUtils}/hasNeoProject.js +0 -0
@@ -5,7 +5,7 @@ const path = require('path');
5
5
  const ora = require('ora');
6
6
  const _ = require('lodash');
7
7
  const { resolve } = require('akfun');
8
- const updatePublishLog = require('../projectUtils/updatePublishLog');
8
+ const updatePublishLog = require('../utils/projectUtils/updatePublishLog');
9
9
  const { getFramework } = require('../utils/common');
10
10
 
11
11
  // NeoCRM 平台默认 API 配置
@@ -37,7 +37,7 @@ const cmpFields = [
37
37
  'plugin',
38
38
  'modelAsset',
39
39
  'cssAsset',
40
- 'codeLib',
40
+ 'codeLib'
41
41
  ];
42
42
 
43
43
  /**
@@ -57,18 +57,13 @@ class NeoService {
57
57
  * @param {string} config.auth.password 密码
58
58
  */
59
59
  constructor(config = {}) {
60
- const { assetsRoot, neoBaseURL, tokenAPI, auth } = config;
60
+ const { assetsRoot, neoBaseURL, tokenAPI, auth } = config || {};
61
61
  if (!auth) {
62
62
  throw new Error('auth 不能为空');
63
63
  }
64
- if (
65
- !auth.client_id ||
66
- !auth.client_secret ||
67
- !auth.username ||
68
- !auth.password
69
- ) {
64
+ if (!auth.client_id || !auth.client_secret || !auth.username || !auth.password) {
70
65
  throw new Error(
71
- 'auth 配置不完整,需要包含 client_id、client_secret、username、password'
66
+ 'neoConfig / auth 配置不完整,需要包含 client_id、client_secret、username、password'
72
67
  );
73
68
  }
74
69
 
@@ -380,6 +375,7 @@ class NeoService {
380
375
  console.error(`未找到自定义组件资源目录: ${this.assetsRoot}`);
381
376
  return;
382
377
  }
378
+
383
379
  // 当前组件信息
384
380
  const curCmpInfo = {
385
381
  cmpType
@@ -462,7 +458,7 @@ class NeoService {
462
458
  throw new Error(`更新组件失败: ${response.data.message || '未知错误'}`);
463
459
  }
464
460
 
465
- spinner.succeed(message ? `组件更新成功: ${message}。` : '组件更新成功。');
461
+ spinner.clear();
466
462
  } catch (error) {
467
463
  spinner.fail('更新组件失败。');
468
464
  if (error.message) {
@@ -492,13 +488,17 @@ class NeoService {
492
488
  try {
493
489
  let queryAllAPI = this.buildFullUrl(NeoCrmAPI.queryAll);
494
490
  queryAllAPI += `?fields=${cmpFields.join(',')}`;
495
- const response = await axios.post(queryAllAPI, {}, {
496
- headers: {
497
- Authorization: `Bearer ${token}`,
498
- 'xsy-inner-source': 'bff',
499
- 'Content-Type': 'application/json'
491
+ const response = await axios.post(
492
+ queryAllAPI,
493
+ {},
494
+ {
495
+ headers: {
496
+ Authorization: `Bearer ${token}`,
497
+ 'xsy-inner-source': 'bff',
498
+ 'Content-Type': 'application/json'
499
+ }
500
500
  }
501
- });
501
+ );
502
502
  const { code, message } = response.data || {};
503
503
 
504
504
  if (code && code !== 200) {
@@ -506,7 +506,6 @@ class NeoService {
506
506
  }
507
507
 
508
508
  this.updateCustomCmpList(response.data.data || []);
509
-
510
509
  } catch (error) {
511
510
  if (error.message) {
512
511
  console.error('获取自定义组件列表失败:', error.message);
@@ -2,9 +2,10 @@ const { aliBOS, baiduBOS } = require('akfun');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
  const _ = require('lodash');
5
+ const ora = require('ora');
5
6
  const { catchCurPackageJson } = require('../utils/pathUtils');
6
7
  const getConfigObj = require('../utils/getConfigObj');
7
- const updatePublishLog = require('../projectUtils/updatePublishLog');
8
+ const updatePublishLog = require('../utils/projectUtils/updatePublishLog');
8
9
 
9
10
  // 获取当前项目的package文件
10
11
  const currentPackageJsonDir = catchCurPackageJson();
@@ -40,7 +41,11 @@ const getFilePath = (ossType, bucket, objectKey) => {
40
41
  baidu: 'bj.bcebos.com',
41
42
  ali: 'oss-cn-beijing.aliyuncs.com'
42
43
  };
43
- return `https://${bucket}.${regions[ossType]}/${objectKey}`;
44
+ const region = regions[ossType];
45
+ if (!region) {
46
+ throw new Error(`不支持的oss类型: ${ossType}`);
47
+ }
48
+ return `https://${bucket}.${region}/${objectKey}`;
44
49
  };
45
50
 
46
51
  // 获取上传成功和失败的文件信息
@@ -92,12 +97,12 @@ const getResultFilesByWidgetName = (files) => {
92
97
  }
93
98
  let widgetName = file.widgetName;
94
99
  const curCmpInfo = {
95
- 'cmpType': _.kebabCase(widgetName),
96
- }
100
+ cmpType: _.kebabCase(widgetName)
101
+ };
97
102
 
98
103
  if (widgetName.includes('Model')) {
99
104
  widgetName = widgetName.replace('Model', '');
100
- curCmpInfo.cmpType = _.kebabCase(widgetName),
105
+ curCmpInfo.cmpType = _.kebabCase(widgetName);
101
106
  curCmpInfo.modelAsset = !file.success ? `${file.error}[${file.ossPath}]` : file.ossPath;
102
107
  } else if (file.fileName.endsWith('.css')) {
103
108
  curCmpInfo.cssAsset = !file.success ? `${file.error}[${file.ossPath}]` : file.ossPath;
@@ -146,6 +151,75 @@ function addVersionToFilename(
146
151
  return `${projectName}/${baseName}-${version}${extension}`;
147
152
  }
148
153
 
154
+ /**
155
+ * 上传单个文件到 OSS
156
+ * @param {object} bosClient OSS 客户端实例
157
+ * @param {string} filePath 文件路径
158
+ * @param {string} objectKey OSS 对象键
159
+ * @param {string} ossType OSS 类型
160
+ * @param {object} ossConfig OSS 配置
161
+ * @param {object} fileInfo 文件信息
162
+ * @returns {Promise<object>} 上传结果
163
+ */
164
+ async function uploadSingleFile(bosClient, filePath, objectKey, ossType, ossConfig, fileInfo) {
165
+ const fileName = path.basename(filePath);
166
+ const fileSizeKB = (fs.statSync(filePath).size / 1024).toFixed(2);
167
+ const spinner = ora(`正在上传文件: ${fileName} (${fileSizeKB}KB)...`).start();
168
+
169
+ try {
170
+ // 判断线上是否存在重名文件,避免被覆盖
171
+ const historyResult = await bosClient.get(objectKey);
172
+ if (historyResult && historyResult.url) {
173
+ spinner.warn(`文件已存在,跳过上传: ${fileName}`);
174
+ return {
175
+ success: false,
176
+ status: '文件上传失败',
177
+ widgetName: fileInfo.name,
178
+ fileName: fileName,
179
+ filepath: filePath,
180
+ ossPath: historyResult.url,
181
+ error: '线上存在重名文件。'
182
+ };
183
+ }
184
+
185
+ // 上传文件
186
+ const result = await bosClient.upload(objectKey, filePath);
187
+ const ossPath = getFilePath(ossType, ossConfig.bucket, objectKey);
188
+ spinner.succeed(`文件上传成功: ${fileName} -> ${ossPath}`);
189
+
190
+ return {
191
+ success: true,
192
+ status: '文件上传成功',
193
+ fileName: fileName,
194
+ widgetName: fileInfo.name,
195
+ filepath: filePath,
196
+ ossPath: ossPath,
197
+ resultMsg: result
198
+ };
199
+ } catch (error) {
200
+ spinner.fail(`文件上传失败: ${fileName}`);
201
+
202
+ // 输出详细的错误信息
203
+ console.error(`\n========== 上传文件详情 ==========`);
204
+ console.error(`文件路径: ${filePath}`);
205
+ console.error(`OSS 对象键: ${objectKey}`);
206
+ console.error(`错误信息: ${error.message}`);
207
+ if (error.stack) {
208
+ console.error(`错误堆栈:`, error.stack);
209
+ }
210
+ console.error(`==================================\n`);
211
+
212
+ return {
213
+ success: false,
214
+ status: '文件上传失败',
215
+ widgetName: fileInfo.name,
216
+ fileName: fileName,
217
+ filepath: filePath,
218
+ error: error.message
219
+ };
220
+ }
221
+ }
222
+
149
223
  /**
150
224
  * 将构建产物上传到指定 oss 存储桶
151
225
  *
@@ -154,91 +228,120 @@ function addVersionToFilename(
154
228
  * @param {string} assetsRoot 构建产物的目录
155
229
  * @param {array} fileExtensions 需要上传的文件类型,默认 ['.js', '.css']
156
230
  */
157
- const publish2oss = (ossType, ossConfig, assetsRoot, fileExtensions = ['.js', '.css']) => {
231
+ const publish2oss = async (ossType, ossConfig, assetsRoot, fileExtensions = ['.js', '.css']) => {
232
+ // 参数验证
158
233
  if (ossType !== 'baidu' && ossType !== 'ali') {
159
234
  console.error(`不支持的oss类型: ${ossType}`);
160
235
  return;
161
236
  }
162
- const bosClient = getBosClient(ossType, ossConfig);
237
+
238
+ if (!ossConfig) {
239
+ console.error('ossConfig 不能为空');
240
+ return;
241
+ }
242
+
163
243
  if (!assetsRoot) {
164
244
  console.error('assetsRoot 不能为空');
165
245
  return;
166
246
  }
247
+
248
+ // 检查目录是否存在
167
249
  if (!fs.existsSync(assetsRoot)) {
168
250
  console.error(`assetsRoot 不存在: ${assetsRoot}`);
169
251
  return;
170
252
  }
171
- const files = fs.readdirSync(assetsRoot); // 读取构建目录下的所有文件
172
-
173
- // 并行上传所有指定类型的文件
174
- const uploadPromises = files.map(async (file) => {
175
- const filePath = path.join(assetsRoot, file);
176
- // 获取文件状态
177
- const fileStat = fs.statSync(filePath);
178
- // 检查文件扩展名
179
- // const fileExt = path.extname(file);
180
- const fileInfo = path.parse(filePath);
181
- if (fileStat.isFile() && fileExtensions.includes(fileInfo.ext)) {
182
- const objectKey = addVersionToFilename(file);
253
+
254
+ // 检查目录是否为目录
255
+ const assetsRootStat = fs.statSync(assetsRoot);
256
+ if (!assetsRootStat.isDirectory()) {
257
+ console.error(`assetsRoot 不是目录: ${assetsRoot}`);
258
+ return;
259
+ }
260
+
261
+ // 创建 OSS 客户端
262
+ const bosClient = getBosClient(ossType, ossConfig);
263
+ if (!bosClient) {
264
+ console.error(`无法创建 OSS 客户端,请检查 ossType 和 ossConfig 配置`);
265
+ return;
266
+ }
267
+
268
+ // 读取构建目录下的所有文件
269
+ const files = fs.readdirSync(assetsRoot);
270
+ if (files.length === 0) {
271
+ console.warn(`构建目录为空: ${assetsRoot}`);
272
+ return;
273
+ }
274
+
275
+ const spinner = ora('正在准备上传文件...').start();
276
+
277
+ try {
278
+ // 过滤出需要上传的文件
279
+ const filesToUpload = files.filter((file) => {
280
+ const filePath = path.join(assetsRoot, file);
183
281
  try {
184
- // 判断线上是否存在重名文件,避免被覆盖
185
- const historyResult = await bosClient.get(objectKey);
186
- if (historyResult && historyResult.url) {
187
- return {
188
- success: false,
189
- status: '文件上传失败',
190
- widgetName: fileInfo.name,
191
- fileName: file,
192
- filepath: filePath,
193
- ossPath: historyResult.url,
194
- error: '线上存在重名文件。'
195
- };
282
+ const fileStat = fs.statSync(filePath);
283
+ if (!fileStat.isFile()) {
284
+ return false;
196
285
  }
197
- // 上传文件
198
- const result = await bosClient.upload(objectKey, filePath);
199
- return {
200
- success: true,
201
- status: '文件上传成功',
202
- fileName: file,
203
- widgetName: fileInfo.name,
204
- filepath: filePath,
205
- ossPath: getFilePath(ossType, ossConfig.bucket, objectKey),
206
- resultMsg: result
207
- };
286
+ const fileInfo = path.parse(filePath);
287
+ return fileExtensions.includes(fileInfo.ext);
208
288
  } catch (error) {
209
- return {
210
- success: false,
211
- status: '文件上传失败',
212
- widgetName: fileInfo.name,
213
- fileName: file,
214
- filepath: filePath,
215
- error: error.message
216
- };
289
+ console.warn(`无法读取文件状态: ${filePath}`, error.message);
290
+ return false;
217
291
  }
292
+ });
293
+
294
+ if (filesToUpload.length === 0) {
295
+ spinner.warn('未找到需要上传的文件');
296
+ return;
218
297
  }
219
- });
220
298
 
221
- Promise.all(uploadPromises)
222
- .then((results) => {
223
- /*
224
- const { succeedFiles, errorFiles } = getResultFiles(results);
225
- if (succeedFiles.length > 0) {
226
- console.info('已成功上传如下文件:\n', succeedFiles);
227
- }
228
- if (errorFiles.length > 0) {
229
- console.info('上传失败的文件有:\n', errorFiles);
230
- }
231
- */
232
- const widgetFilesMap = getResultFilesByWidgetName(results);
233
- if (widgetFilesMap) {
234
- console.info('上传至 OSS 的文件信息:\n', widgetFilesMap);
235
- // 更新发布日志
236
- updatePublishLog(widgetFilesMap);
237
- }
238
- })
239
- .catch((error) => {
240
- console.error('批量上传文件异常:\n', error);
299
+ spinner.succeed(`找到 ${filesToUpload.length} 个文件需要上传`);
300
+
301
+ // 并行上传所有指定类型的文件
302
+ const uploadPromises = filesToUpload.map(async (file) => {
303
+ const filePath = path.join(assetsRoot, file);
304
+ const fileInfo = path.parse(filePath);
305
+ const objectKey = addVersionToFilename(file);
306
+
307
+ return await uploadSingleFile(bosClient, filePath, objectKey, ossType, ossConfig, fileInfo);
241
308
  });
309
+
310
+ // 等待所有文件上传完成
311
+ const results = await Promise.all(uploadPromises);
312
+
313
+ // 过滤掉 undefined 结果(不符合条件的文件)
314
+ const validResults = results.filter((result) => result !== undefined);
315
+
316
+ // 处理上传结果
317
+ const widgetFilesMap = getResultFilesByWidgetName(validResults);
318
+ if (widgetFilesMap && Object.keys(widgetFilesMap).length > 0) {
319
+ console.info('\n上传至 OSS 的文件信息:\n', widgetFilesMap);
320
+ // 更新发布日志
321
+ updatePublishLog(widgetFilesMap);
322
+ } else {
323
+ console.warn('未生成有效的文件上传结果');
324
+ }
325
+
326
+ // 统计上传结果
327
+ const succeedCount = validResults.filter((r) => r && r.success).length;
328
+ const failCount = validResults.filter((r) => r && !r.success).length;
329
+
330
+ if (failCount > 0) {
331
+ console.warn(`\n上传完成:成功 ${succeedCount} 个,失败 ${failCount} 个`);
332
+ } else {
333
+ console.info(`\n✅ 所有文件上传成功!共 ${succeedCount} 个文件`);
334
+ }
335
+ } catch (error) {
336
+ spinner.fail('批量上传文件异常');
337
+ console.error('\n========== 批量上传异常 ==========');
338
+ console.error('错误信息:', error.message);
339
+ if (error.stack) {
340
+ console.error('错误堆栈:', error.stack);
341
+ }
342
+ console.error('==================================\n');
343
+ throw error;
344
+ }
242
345
  };
243
346
 
244
347
  module.exports = publish2oss;
@@ -2,8 +2,8 @@
2
2
  - src: 自定义组件源码;
3
3
  - src/assets: 存放组件静态资源,比如 css、img等;
4
4
  - src/components: 存放自定义组件代码,每个自定义组件以自身名称(cmpType 数值)作为目录进行存放;
5
- - src/components/info-card/index.tsx: 自定义组件的内容文件;
6
- - src/components/info-card/model.ts: 自定义组件的模型文件,用于对接页面设计器;
5
+ - src/components/xxCmp/index.tsx: 自定义组件的内容文件;
6
+ - src/components/xxCmp/model.ts: 自定义组件的模型文件,用于对接页面设计器;
7
7
  - neo.config.js: neo-cmp-cli 配置文件。
8
8
 
9
9
  ### 组件开发规范
@@ -43,5 +43,29 @@ $ npm run linkDebug
43
43
  $ npm run pushCmp
44
44
  ```
45
45
 
46
+ ##### 需自行添加 NeoCRM 授权配置
47
+ ```javascript
48
+ module.exports = {
49
+ neoConfig: {
50
+ neoBaseURL: 'https://crm-cd.xiaoshouyi.com', // 平台根地址(默认:https://crm.xiaoshouyi.com)
51
+ tokenAPI: 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
52
+ // NeoCRM 授权配置
53
+ auth: {
54
+ client_id: 'xx', // 客户端 ID,从创建连接器的客户端信息中获取(Client_Id)
55
+ client_secret: 'xxx', // 客户端秘钥,从创建连接器的客户端信息中获取(Client_Secret)
56
+ username: 'xx', // 用户在销售易系统中的用户名
57
+ /**
58
+ * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
59
+ * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
60
+ */
61
+ password: 'xx xx' // 用户账户密码 + 8 位安全令牌
62
+ },
63
+ },
64
+ }
65
+ ```
66
+ 1、客户端 ID 和 客户端秘钥 需通过 创建连接器 获取,获取方式见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / 创建连接器;
67
+ 2、如何获取 安全令牌 见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / OAuth安全认证 / 密码模式 / 获取令牌;
68
+ 3、发布成功后即可在 NeoCRM 对应租户环境的页面设计器和表单设计器中使用此自定义组件。
69
+
46
70
  ### 配置项说明(neo-cmp-cli)
47
71
  [请查看neo-cmp-cli](https://github.com/wibetter/neo-cmp-cli)
@@ -110,8 +110,8 @@ module.exports = {
110
110
  * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
111
111
  * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
112
112
  */
113
- password: 'xx xx' // 用户账户密码 + 8 位安全令牌
114
- }
113
+ password: 'xx xx', // 用户账户密码 + 8 位安全令牌
114
+ },
115
115
  },
116
116
  pushCmp: {
117
117
  // 用于构建并发布至 NeoCRM 的相关配置
@@ -2,8 +2,8 @@
2
2
  - src: 自定义组件源码;
3
3
  - src/assets: 存放组件静态资源,比如 css、img等;
4
4
  - src/components: 存放自定义组件代码,每个自定义组件以自身名称(cmpType 数值)作为目录进行存放;
5
- - src/components/info-card/: 信息卡片组件;
6
- - src/components/chart-widget/: 酷炫图表组件(新增);
5
+ - src/components/xxCmp/index: 自定义组件的内容文件;
6
+ - src/components/xxCmp/model: 自定义组件的模型文件,用于对接页面设计器;
7
7
  - neo.config.js: neo-cmp-cli 配置文件。
8
8
 
9
9
  ### 🎨 酷炫图表组件 (Chart Widget)
@@ -87,5 +87,29 @@ $ npm run linkDebug
87
87
  $ npm run pushCmp
88
88
  ```
89
89
 
90
+ ##### 需自行添加 NeoCRM 授权配置
91
+ ```javascript
92
+ module.exports = {
93
+ neoConfig: {
94
+ neoBaseURL: 'https://crm-cd.xiaoshouyi.com', // 平台根地址(默认:https://crm.xiaoshouyi.com)
95
+ tokenAPI: 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
96
+ // NeoCRM 授权配置
97
+ auth: {
98
+ client_id: 'xx', // 客户端 ID,从创建连接器的客户端信息中获取(Client_Id)
99
+ client_secret: 'xxx', // 客户端秘钥,从创建连接器的客户端信息中获取(Client_Secret)
100
+ username: 'xx', // 用户在销售易系统中的用户名
101
+ /**
102
+ * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
103
+ * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
104
+ */
105
+ password: 'xx xx' // 用户账户密码 + 8 位安全令牌
106
+ },
107
+ },
108
+ }
109
+ ```
110
+ 1、客户端 ID 和 客户端秘钥 需通过 创建连接器 获取,获取方式见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / 创建连接器;
111
+ 2、如何获取 安全令牌 见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / OAuth安全认证 / 密码模式 / 获取令牌;
112
+ 3、发布成功后即可在 NeoCRM 对应租户环境的页面设计器和表单设计器中使用此自定义组件。
113
+
90
114
  ### 配置项说明(neo-cmp-cli)
91
115
  [请查看neo-cmp-cli](https://github.com/wibetter/neo-cmp-cli)
@@ -42,7 +42,8 @@ module.exports = {
42
42
  ///*
43
43
  neoCommonModule: {
44
44
  // neoExports: ['xxModule'], // 自定义组件 共享出来的模块,支持数组和对象形式
45
- neoExports: { // 对象写法
45
+ neoExports: {
46
+ // 对象写法
46
47
  'chart-widget': path.resolve('./src/components/chart-widget'), // 导出图表自定义组件
47
48
  'neo-register': 'neo-register', // 导出 Neo 注册模块
48
49
  },
@@ -111,8 +112,8 @@ module.exports = {
111
112
  * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
112
113
  * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
113
114
  */
114
- password: 'xx xx' // 用户账户密码 + 8 位安全令牌
115
- }
115
+ password: 'xx xx', // 用户账户密码 + 8 位安全令牌
116
+ },
116
117
  },
117
118
  pushCmp: {
118
119
  // 用于构建并发布至 NeoCRM 的相关配置
@@ -2,6 +2,8 @@
2
2
  - src: 自定义组件源码;
3
3
  - src/assets: 存放组件静态资源,比如 css、img等;
4
4
  - src/components: 存放自定义组件代码,每个自定义组件以自身名称(cmpType 数值)作为目录进行存放;
5
+ - src/components/xxCmp/index: 自定义组件的内容文件;
6
+ - src/components/xxCmp/model: 自定义组件的模型文件,用于对接页面设计器;
5
7
  - neo.config.js: neo-cmp-cli 配置文件。
6
8
 
7
9
  ### 组件开发规范
@@ -41,5 +43,29 @@ $ npm run linkDebug
41
43
  $ npm run pushCmp
42
44
  ```
43
45
 
46
+ ##### 需自行添加 NeoCRM 授权配置
47
+ ```javascript
48
+ module.exports = {
49
+ neoConfig: {
50
+ neoBaseURL: 'https://crm-cd.xiaoshouyi.com', // 平台根地址(默认:https://crm.xiaoshouyi.com)
51
+ tokenAPI: 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
52
+ // NeoCRM 授权配置
53
+ auth: {
54
+ client_id: 'xx', // 客户端 ID,从创建连接器的客户端信息中获取(Client_Id)
55
+ client_secret: 'xxx', // 客户端秘钥,从创建连接器的客户端信息中获取(Client_Secret)
56
+ username: 'xx', // 用户在销售易系统中的用户名
57
+ /**
58
+ * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
59
+ * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
60
+ */
61
+ password: 'xx xx' // 用户账户密码 + 8 位安全令牌
62
+ },
63
+ },
64
+ }
65
+ ```
66
+ 1、客户端 ID 和 客户端秘钥 需通过 创建连接器 获取,获取方式见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / 创建连接器;
67
+ 2、如何获取 安全令牌 见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / OAuth安全认证 / 密码模式 / 获取令牌;
68
+ 3、发布成功后即可在 NeoCRM 对应租户环境的页面设计器和表单设计器中使用此自定义组件。
69
+
44
70
  ### 配置项说明(neo-cmp-cli)
45
71
  [请查看neo-cmp-cli](https://github.com/wibetter/neo-cmp-cli)
@@ -110,8 +110,8 @@ module.exports = {
110
110
  * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
111
111
  * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
112
112
  */
113
- password: 'xx xx' // 用户账户密码 + 8 位安全令牌
114
- }
113
+ password: 'xx xx', // 用户账户密码 + 8 位安全令牌
114
+ },
115
115
  },
116
116
  pushCmp: {
117
117
  // 用于构建并发布至 NeoCRM 的相关配置
@@ -2,8 +2,8 @@
2
2
  - src: 自定义组件源码;
3
3
  - src/assets: 存放组件静态资源,比如 css、img等;
4
4
  - src/components: 存放自定义组件代码,每个自定义组件以自身名称(cmpType 数值)作为目录进行存放;
5
- - src/components/entity-table/index.tsx: 自定义组件的内容文件;
6
- - src/components/entity-table/model.ts: 自定义组件的模型文件,用于对接页面设计器;
5
+ - src/components/xxCmp/index: 自定义组件的内容文件;
6
+ - src/components/xxCmp/model: 自定义组件的模型文件,用于对接页面设计器;
7
7
  - neo.config.js: neo-cmp-cli 配置文件。
8
8
 
9
9
  ### 组件开发规范
@@ -44,5 +44,29 @@ $ npm run linkDebug
44
44
  $ npm run pushCmp
45
45
  ```
46
46
 
47
+ ##### 需自行添加 NeoCRM 授权配置
48
+ ```javascript
49
+ module.exports = {
50
+ neoConfig: {
51
+ neoBaseURL: 'https://crm-cd.xiaoshouyi.com', // 平台根地址(默认:https://crm.xiaoshouyi.com)
52
+ tokenAPI: 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
53
+ // NeoCRM 授权配置
54
+ auth: {
55
+ client_id: 'xx', // 客户端 ID,从创建连接器的客户端信息中获取(Client_Id)
56
+ client_secret: 'xxx', // 客户端秘钥,从创建连接器的客户端信息中获取(Client_Secret)
57
+ username: 'xx', // 用户在销售易系统中的用户名
58
+ /**
59
+ * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
60
+ * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
61
+ */
62
+ password: 'xx xx' // 用户账户密码 + 8 位安全令牌
63
+ },
64
+ },
65
+ }
66
+ ```
67
+ 1、客户端 ID 和 客户端秘钥 需通过 创建连接器 获取,获取方式见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / 创建连接器;
68
+ 2、如何获取 安全令牌 见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / OAuth安全认证 / 密码模式 / 获取令牌;
69
+ 3、发布成功后即可在 NeoCRM 对应租户环境的页面设计器和表单设计器中使用此自定义组件。
70
+
47
71
  ### 前端工程配置项说明(neo-cmp-cli)
48
72
  [请查看neo-cmp-cli](https://github.com/wibetter/neo-cmp-cli)
@@ -118,7 +118,7 @@ module.exports = {
118
118
  * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
119
119
  * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
120
120
  */
121
- password: auth.password || 'xx xx' // 用户账户密码 + 8 位安全令牌
121
+ password: auth.password || 'xx xx', // 用户账户密码 + 8 位安全令牌
122
122
  },
123
123
  },
124
124
  pushCmp: {
@@ -2,8 +2,8 @@
2
2
  - src: 自定义组件源码;
3
3
  - src/assets: 存放组件静态资源,比如 css、img等;
4
4
  - src/components: 存放自定义组件代码,每个自定义组件以自身名称(cmpType 数值)作为目录进行存放;
5
- - src/components/info-card/index.jsx: 自定义组件的内容文件;
6
- - src/components/info-card/model.js: 自定义组件的模型文件,用于对接页面设计器;
5
+ - src/components/xxCmp/index: 自定义组件的内容文件;
6
+ - src/components/xxCmp/model: 自定义组件的模型文件,用于对接页面设计器;
7
7
  - neo.config.js: neo-cmp-cli 配置文件。
8
8
 
9
9
  ### 组件开发规范
@@ -43,5 +43,29 @@ $ npm run linkDebug
43
43
  $ npm run pushCmp
44
44
  ```
45
45
 
46
+ ##### 需自行添加 NeoCRM 授权配置
47
+ ```javascript
48
+ module.exports = {
49
+ neoConfig: {
50
+ neoBaseURL: 'https://crm-cd.xiaoshouyi.com', // 平台根地址(默认:https://crm.xiaoshouyi.com)
51
+ tokenAPI: 'https://login-cd.xiaoshouyi.com/auc/oauth2/token', // Token 获取接口地址(默认:https://login.xiaoshouyi.com/auc/oauth2/token)
52
+ // NeoCRM 授权配置
53
+ auth: {
54
+ client_id: 'xx', // 客户端 ID,从创建连接器的客户端信息中获取(Client_Id)
55
+ client_secret: 'xxx', // 客户端秘钥,从创建连接器的客户端信息中获取(Client_Secret)
56
+ username: 'xx', // 用户在销售易系统中的用户名
57
+ /**
58
+ * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
59
+ * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
60
+ */
61
+ password: 'xx xx' // 用户账户密码 + 8 位安全令牌
62
+ },
63
+ },
64
+ }
65
+ ```
66
+ 1、客户端 ID 和 客户端秘钥 需通过 创建连接器 获取,获取方式见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / 创建连接器;
67
+ 2、如何获取 安全令牌 见:[https://doc.xiaoshouyi.com](https://doc.xiaoshouyi.com) / OAuth安全认证 / 密码模式 / 获取令牌;
68
+ 3、发布成功后即可在 NeoCRM 对应租户环境的页面设计器和表单设计器中使用此自定义组件。
69
+
46
70
  ### 配置项说明(neo-cmp-cli)
47
71
  [请查看neo-cmp-cli](https://github.com/wibetter/neo-cmp-cli)
@@ -109,8 +109,8 @@ module.exports = {
109
109
  * password 为 用户在销售易系统中的账号密码加上 8 位安全令牌。
110
110
  * 例如,用户密码为 123456,安全令牌为 ABCDEFGH,则 password 的值应为 123456ABCDEFGH。
111
111
  */
112
- password: 'xx xx' // 用户账户密码 + 8 位安全令牌
113
- }
112
+ password: 'xx xx', // 用户账户密码 + 8 位安全令牌
113
+ },
114
114
  },
115
115
  pushCmp: {
116
116
  // 用于构建并发布至 NeoCRM 的相关配置