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.
- package/package.json +1 -1
- package/src/module/index.js +32 -26
- package/src/module/main.js +161 -267
- package/src/module/neoInit.js +1 -0
- package/src/neo/NeoUMDContent.js +5 -5
- package/src/neo/neoService.js +17 -18
- package/src/oss/publish2oss.js +174 -71
- package/src/template/antd-custom-cmp-template/README.md +26 -2
- package/src/template/antd-custom-cmp-template/neo.config.js +2 -2
- package/src/template/echarts-custom-cmp-template/README.md +26 -2
- package/src/template/echarts-custom-cmp-template/neo.config.js +4 -3
- package/src/template/empty-custom-cmp-template/README.md +26 -0
- package/src/template/empty-custom-cmp-template/neo.config.js +2 -2
- package/src/template/neo-custom-cmp-template/README.md +26 -2
- package/src/template/neo-custom-cmp-template/neo.config.js +1 -1
- package/src/template/react-custom-cmp-template/README.md +26 -2
- package/src/template/react-custom-cmp-template/neo.config.js +2 -2
- package/src/template/react-ts-custom-cmp-template/README.md +26 -2
- package/src/template/react-ts-custom-cmp-template/neo.config.js +2 -2
- package/src/template/vue2-custom-cmp-template/README.md +26 -2
- package/src/template/vue2-custom-cmp-template/neo.config.js +2 -2
- package/src/{cmpUtils → utils/cmpUtils}/createCmpByTemplate.js +7 -5
- package/src/{cmpUtils → utils/cmpUtils}/createCmpByZip.js +5 -2
- package/src/{cmpUtils → utils/cmpUtils}/createCommonModulesCode.js +2 -2
- package/src/{cmpUtils → utils/cmpUtils}/getCmpModelRegisterCode.js +1 -1
- package/src/{cmpUtils → utils/cmpUtils}/getCmpPreviewCode.js +1 -1
- package/src/{cmpUtils → utils/cmpUtils}/getCmpRegisterCode.js +1 -1
- package/src/{cmpUtils → utils/cmpUtils}/getCmpTypeByDir.js +2 -2
- package/src/{cmpUtils → utils/cmpUtils}/hasCmpTypeByDir.js +1 -1
- package/src/{cmpUtils → utils/cmpUtils}/previewCmp.js +3 -3
- package/src/{cmpUtils → utils/cmpUtils}/pullCmp.js +9 -9
- package/src/{cmpUtils → utils/cmpUtils}/pushCmp.js +7 -5
- package/src/utils/generateEntries.js +73 -0
- package/src/{projectUtils → utils/projectUtils}/createCmpProjectByTemplate.js +10 -6
- package/src/{projectUtils → utils/projectUtils}/createCmpProjectZip.js +1 -3
- package/src/{projectUtils → utils/projectUtils}/getEntries.js +2 -2
- package/src/{projectUtils → utils/projectUtils}/getEntriesWithAutoRegister.js +2 -2
- package/src/{projectUtils → utils/projectUtils}/updatePublishLog.js +1 -1
- package/src/template/neo-custom-cmp-template/pushCmp.js +0 -166
- /package/src/{projectUtils → utils/projectUtils}/hasNeoProject.js +0 -0
package/src/neo/neoService.js
CHANGED
|
@@ -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.
|
|
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(
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
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);
|
package/src/oss/publish2oss.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
-
|
|
186
|
-
|
|
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
|
-
|
|
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
|
-
|
|
210
|
-
|
|
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
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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/
|
|
6
|
-
- src/components/
|
|
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/
|
|
6
|
-
- src/components/
|
|
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/
|
|
6
|
-
- src/components/
|
|
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/
|
|
6
|
-
- src/components/
|
|
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 的相关配置
|