neo-cmp-cli 1.8.26 → 1.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,390 @@
1
+ # 组件事件配置面板中添加的事件动作保存到 cmpExt 流程分析
2
+
3
+ ## 整体流程概览
4
+
5
+ ```
6
+ 用户操作 → 事件面板 → 创建/更新事件实例 → 保存到内存 → 序列化时写入 cmpExt
7
+ ```
8
+
9
+ ## 详细流程分析
10
+
11
+ ### 1. 事件配置面板初始化
12
+
13
+ **文件**: `packages/neo-ui-designer-common/src/designerCmps/comConsole/propEditorCmps/events/collection/component.tsx`
14
+
15
+ - `EventCollections` 组件负责渲染事件配置面板
16
+ - 在 `componentDidMount` 时调用 `updateEvents()` 初始化事件列表
17
+ - 从两个数据源获取事件:
18
+ - **事件定义**: `FxAndEvent.getEventDefsByCom(com)` - 从元模型获取组件支持的事件定义
19
+ - **已保存的事件**: 从 `store.frontendExt.cmpExt` 和 `store.frontendExt.layoutExt` 中获取
20
+
21
+ ```typescript:47:89:packages/neo-ui-designer-common/src/designerCmps/comConsole/propEditorCmps/events/collection/component.tsx
22
+ updateEvents = () => {
23
+ const com = ComClicker.comSelected;
24
+ const store = com.$pageCom.$store;
25
+ const { cmpExt = [], layoutExt = [] } = store.frontendExt ?? {};
26
+ const netEvents = layoutExt.concat(cmpExt);
27
+
28
+ // 获取事件定义和已保存的事件实例
29
+ const curEvents = FxAndEvent.getEventDefsByCom(com);
30
+ const evtFxs = FxAndEvent.getEventsById(com.keyIdentifier);
31
+
32
+ // 合并数据,优先使用本地更新的事件
33
+ this.setState({
34
+ events: curEvents.map((eve) => {
35
+ const nativeEve = evtFxs.find((_) => _.apiKey === eve.apiKey);
36
+ if (nativeEve) {
37
+ return { ...eve, ...nativeEve };
38
+ }
39
+ const netEve = curNeoEvents.find((_) => _.apiKey === eve.apiKey);
40
+ if (netEve) {
41
+ return { ...eve, id: uuid(16), actions: netEve.actions };
42
+ }
43
+ return { ...eve, id: uuid(16) };
44
+ }),
45
+ });
46
+ };
47
+ ```
48
+
49
+ ### 2. 添加事件动作
50
+
51
+ **文件**: `packages/neo-ui-designer-common/src/designerCmps/comConsole/propEditorCmps/events/event/component.tsx`
52
+
53
+ - `Event` 组件渲染单个事件及其动作列表
54
+ - 点击"添加行为"按钮时,打开动作配置对话框
55
+
56
+ ```typescript:17:43:packages/neo-ui-designer-common/src/designerCmps/comConsole/propEditorCmps/events/event/component.tsx
57
+ export const Event: React.FC<IEvent> = (event) => {
58
+ // 创建或获取事件实例
59
+ const eventIns = FxAndEvent.createEvent(event);
60
+ const [actions, setActions] = useState(eventIns.actions);
61
+
62
+ // 当 actions 变化时,同步更新事件实例
63
+ useEffect(() => {
64
+ eventIns.setActions(actions);
65
+ }, [actions]);
66
+
67
+ // 新增 action
68
+ const addAction = () => {
69
+ NeoNavigator.openDialog({
70
+ bodySchema: {
71
+ type: 'neoDesignAction',
72
+ eventName: event.label,
73
+ eventParams: eventIns.eventParams,
74
+ cmpKeyIdentifier: event.cmpKeyIdentifier,
75
+ },
76
+ }).then((action: any) => {
77
+ setActions(actions.concat(action)); // 添加到本地状态
78
+ });
79
+ };
80
+ ```
81
+
82
+ **关键点**:
83
+ - `FxAndEvent.createEvent(event)` 创建或获取事件实例,存储在 `FxAndEvent.events` 数组中
84
+ - 通过 `useEffect` 监听 `actions` 变化,调用 `eventIns.setActions(actions)` 更新事件实例
85
+
86
+ ### 3. 动作配置对话框
87
+
88
+ **文件**: `packages/neo-ui-designer-common/src/designerCmps/comConsole/propEditorCmps/events/action/component.tsx`
89
+
90
+ - `CmpActionConfig` 组件提供动作配置界面
91
+ - 用户配置动作的各种属性(名称、执行条件、执行操作等)
92
+ - 点击"确认"时,创建动作实例并回调
93
+
94
+ ```typescript:359:374:packages/neo-ui-designer-common/src/designerCmps/comConsole/propEditorCmps/events/action/component.tsx
95
+ // 确认回传
96
+ const onConfirm = () => {
97
+ // 先校验,再保存
98
+ if (validate()) return;
99
+
100
+ // 创建动作实例
101
+ const newAction = FxAndEvent.createAction({
102
+ id: props.id ?? uuid(16),
103
+ label,
104
+ execMode,
105
+ actionType,
106
+ assignment,
107
+ condition,
108
+ function: aFunction,
109
+ });
110
+
111
+ // 回调给父组件(Event组件)
112
+ props.onConfirm(newAction);
113
+ NeoNavigator.goBack();
114
+ };
115
+ ```
116
+
117
+ ### 4. 事件实例管理
118
+
119
+ **文件**: `packages/neo-ui-designer-common/src/marionette/event.fx/index.ts`
120
+
121
+ `__FxAndEvent__` 类管理所有事件实例:
122
+
123
+ ```typescript:37:183:packages/neo-ui-designer-common/src/marionette/event.fx/index.ts
124
+ export class __FxAndEvent__ {
125
+ /**
126
+ * 此次布局编辑中新增的事件实例
127
+ */
128
+ private events: NeoEvent[] = [];
129
+
130
+ // 创建事件实例
131
+ createEvent = (props: INeoEvent): NeoEvent => {
132
+ let event = this.events.find((eve) => {
133
+ if (eve.id && props.id && eve.id === props.id) {
134
+ return true;
135
+ }
136
+ return false;
137
+ });
138
+ if (event) {
139
+ return event; // 已存在则返回
140
+ }
141
+ event = new NeoEvent(props);
142
+ this.events.push(event); // 添加到内存数组
143
+ return event;
144
+ };
145
+
146
+ // 创建动作实例
147
+ createAction = (props: INeoAction) => new NeoAction(props);
148
+ }
149
+ ```
150
+
151
+ **关键点**:
152
+ - `events` 数组存储本次编辑会话中所有创建/修改的事件实例
153
+ - `createEvent` 会检查是否已存在,避免重复创建
154
+ - 事件实例包含 `actions` 数组,存储该事件的所有动作
155
+
156
+ ### 5. 事件实例更新
157
+
158
+ **文件**: `packages/neo-ui-designer-common/src/marionette/event.fx/event.ts`
159
+
160
+ `NeoEvent` 类提供更新动作的方法:
161
+
162
+ ```typescript:40:64:packages/neo-ui-designer-common/src/marionette/event.fx/event.ts
163
+ // 增加 action
164
+ addAction = (action: NeoAction) => {
165
+ this.actions.push(action);
166
+ };
167
+
168
+ // 删除 action
169
+ delAction = (id) => {
170
+ this.actions.splice(
171
+ this.actions.findIndex((ac) => ac.id === id),
172
+ 1
173
+ );
174
+ };
175
+
176
+ // 更新 action
177
+ updateAction = (action) => {
178
+ this.actions = this.actions.map((ac) => {
179
+ if (ac.id === action.id) {
180
+ return action;
181
+ }
182
+ return ac;
183
+ });
184
+ };
185
+
186
+ setActions = (acs) => {
187
+ this.actions = acs;
188
+ };
189
+ ```
190
+
191
+ ### 6. 保存到 cmpExt
192
+
193
+ **文件**: `packages/neo-ui-designer-common/src/marionette/event.fx/index.ts`
194
+
195
+ 当需要保存布局时,调用 `getEventsDataNet()` 方法将内存中的事件实例转换为接口格式:
196
+
197
+ ```typescript:232:303:packages/neo-ui-designer-common/src/marionette/event.fx/index.ts
198
+ getEventsDataNet = () => {
199
+ const store = (window as any).$designer.rootCom.$store;
200
+
201
+ // 1. 获取服务端已经保存的 events
202
+ const _frontendExt = store.frontendExt;
203
+ const cmpExt = _frontendExt?.cmpExt ? [..._frontendExt.cmpExt] : [];
204
+ const layoutExt = _frontendExt?.layoutExt ? [..._frontendExt.layoutExt] : [];
205
+
206
+ // 2. 将此次布局编辑中新增的事件,合并到服务端数据中
207
+ for (const evt of this.events) {
208
+ // 根据事件类型决定保存到 cmpExt 还是 layoutExt
209
+ let eventList = [];
210
+ if (evt.isCmpEvent) {
211
+ eventList = cmpExt; // 组件事件保存到 cmpExt
212
+ } else {
213
+ eventList = layoutExt; // 布局事件保存到 layoutExt
214
+ }
215
+
216
+ if (eventList) {
217
+ // 查找此事件是否已存在
218
+ const index = eventList.findIndex(
219
+ (acc) =>
220
+ evt.cmpKeyIdentifier === acc.cmpKeyIdentifier &&
221
+ evt.apiKey === acc.apiKey
222
+ );
223
+
224
+ // 如果删除了所有 actions,则删除事件
225
+ if (evt.actions.length === 0) {
226
+ if (index !== -1) {
227
+ eventList.splice(index, 1);
228
+ }
229
+ } else {
230
+ // 更新或添加事件
231
+ if (index !== -1) {
232
+ eventList[index] = evt._json(); // 覆盖已存在的事件
233
+ } else {
234
+ eventList.push(evt._json()); // 添加新事件
235
+ }
236
+ }
237
+ }
238
+ }
239
+
240
+ return {
241
+ cmpExt: cmpExt.filter((cmp) =>
242
+ NeoApp.getComByKId(`${cmp.cmpKeyIdentifier}`)
243
+ ),
244
+ layoutExt: layoutExt.filter((lay) =>
245
+ NeoApp.getComByKId(`${lay.cmpKeyIdentifier}`)
246
+ ),
247
+ };
248
+ };
249
+ ```
250
+
251
+ **关键点**:
252
+ - `evt.isCmpEvent` 判断事件类型:`eventCategory === 2` 为组件事件,保存到 `cmpExt`
253
+ - `evt._json()` 方法将事件实例序列化为 JSON 格式,只包含必要字段:
254
+ ```typescript
255
+ _json = () => {
256
+ return pick({ ...this, actions: this.getActions() }, [
257
+ 'cmpKeyIdentifier',
258
+ 'apiKey',
259
+ 'actions',
260
+ ]);
261
+ };
262
+ ```
263
+
264
+ ### 7. 序列化保存
265
+
266
+ **文件**: `packages/neo-ui-designer-common/src/designer/basic.layout.designer.ts`
267
+
268
+ 设计器在保存布局时调用 `getSerializeData()`:
269
+
270
+ ```typescript:460:476:packages/neo-ui-designer-common/src/designer/basic.layout.designer.ts
271
+ getSerializeData(): any {
272
+ const layoutRoot = this.rootCom.querySelector(':neoLayoutRoot');
273
+ const schema = layoutRoot.$serialize();
274
+
275
+ const rst = {
276
+ layoutInfo: this.layoutInfo,
277
+ layoutCanvas: {
278
+ cmp: schema,
279
+ frontendExt: FxAndEvent.getEventsDataNet(), // 获取事件数据
280
+ },
281
+ };
282
+
283
+ return rst;
284
+ }
285
+ ```
286
+
287
+ ## 数据流向图
288
+
289
+ ```
290
+ ┌─────────────────────────────────────────────────────────────┐
291
+ │ 用户操作:在事件配置面板中添加动作 │
292
+ └────────────────────┬────────────────────────────────────────┘
293
+
294
+
295
+ ┌─────────────────────────────────────────────────────────────┐
296
+ │ Event 组件 │
297
+ │ - FxAndEvent.createEvent(event) 创建/获取事件实例 │
298
+ │ - setActions(actions) 更新事件实例的 actions 数组 │
299
+ └────────────────────┬────────────────────────────────────────┘
300
+
301
+
302
+ ┌─────────────────────────────────────────────────────────────┐
303
+ │ __FxAndEvent__ 类 │
304
+ │ - events: NeoEvent[] 存储所有事件实例 │
305
+ │ - createEvent() 创建事件实例 │
306
+ │ - createAction() 创建动作实例 │
307
+ └────────────────────┬────────────────────────────────────────┘
308
+
309
+
310
+ ┌─────────────────────────────────────────────────────────────┐
311
+ │ NeoEvent 类 │
312
+ │ - actions: NeoAction[] 存储动作列表 │
313
+ │ - setActions() 更新动作列表 │
314
+ │ - _json() 序列化为接口格式 │
315
+ └────────────────────┬────────────────────────────────────────┘
316
+
317
+
318
+ ┌─────────────────────────────────────────────────────────────┐
319
+ │ getEventsDataNet() 方法 │
320
+ │ - 遍历 events 数组 │
321
+ │ - 根据 isCmpEvent 判断保存到 cmpExt 或 layoutExt │
322
+ │ - 调用 evt._json() 序列化 │
323
+ └────────────────────┬────────────────────────────────────────┘
324
+
325
+
326
+ ┌─────────────────────────────────────────────────────────────┐
327
+ │ getSerializeData() 方法 │
328
+ │ - 调用 FxAndEvent.getEventsDataNet() │
329
+ │ - 返回包含 frontendExt 的序列化数据 │
330
+ └────────────────────┬────────────────────────────────────────┘
331
+
332
+
333
+ ┌─────────────────────────────────────────────────────────────┐
334
+ │ 保存到后端 │
335
+ │ - frontendExt.cmpExt 包含组件事件配置 │
336
+ │ - frontendExt.layoutExt 包含布局事件配置 │
337
+ └─────────────────────────────────────────────────────────────┘
338
+ ```
339
+
340
+ ## 关键数据结构
341
+
342
+ ### 事件实例 (NeoEvent)
343
+ ```typescript
344
+ {
345
+ id: string;
346
+ label: string;
347
+ apiKey: string; // 事件标识
348
+ eventCategory: number; // 2=组件事件, 其他=布局事件
349
+ cmpKeyIdentifier: string; // 组件标识
350
+ actions: NeoAction[]; // 动作列表
351
+ }
352
+ ```
353
+
354
+ ### 动作实例 (NeoAction)
355
+ ```typescript
356
+ {
357
+ id: string;
358
+ label: string;
359
+ execMode: number; // 执行模式:1=总是执行, 2=条件执行
360
+ actionType: number; // 动作类型:1=执行函数, 2=赋值
361
+ assignment: Array<...>; // 赋值规则(当 actionType=2 时)
362
+ condition: string; // 执行条件(当 execMode=2 时)
363
+ function: {...}; // 函数配置(当 actionType=1 时)
364
+ }
365
+ ```
366
+
367
+ ### cmpExt 中的事件数据格式
368
+ ```typescript
369
+ {
370
+ cmpKeyIdentifier: string; // 组件标识
371
+ apiKey: string; // 事件标识
372
+ actions: Array<{ // 动作列表(已序列化)
373
+ id: string;
374
+ label: string;
375
+ execMode: number;
376
+ actionType: number;
377
+ // ... 其他动作属性
378
+ }>;
379
+ }
380
+ ```
381
+
382
+ ## 总结
383
+
384
+ 1. **内存管理**: 事件实例存储在 `FxAndEvent.events` 数组中,只在编辑会话期间存在
385
+ 2. **实时更新**: 用户添加/修改/删除动作时,立即更新内存中的事件实例
386
+ 3. **延迟保存**: 只有在保存布局时,才调用 `getEventsDataNet()` 将内存数据写入 `cmpExt`
387
+ 4. **类型区分**: 根据 `eventCategory` 判断是组件事件(保存到 `cmpExt`)还是布局事件(保存到 `layoutExt`)
388
+ 5. **数据合并**: `getEventsDataNet()` 会将内存中的事件与已保存的事件合并,更新或新增
389
+
390
+
@@ -48,7 +48,7 @@
48
48
  "@commitlint/config-conventional": "^9.1.1",
49
49
  "@types/react": "^16.9.11",
50
50
  "@types/react-dom": "^16.9.15",
51
- "neo-cmp-cli": "^1.8.26",
51
+ "neo-cmp-cli": "^1.9.0",
52
52
  "husky": "^4.2.5",
53
53
  "lint-staged": "^10.2.9",
54
54
  "prettier": "^2.0.5",
@@ -46,7 +46,7 @@
46
46
  "@commitlint/config-conventional": "^9.1.1",
47
47
  "@types/react": "^16.9.11",
48
48
  "@types/react-dom": "^16.9.15",
49
- "neo-cmp-cli": "^1.8.26",
49
+ "neo-cmp-cli": "^1.9.0",
50
50
  "husky": "^4.2.5",
51
51
  "lint-staged": "^10.2.9",
52
52
  "prettier": "^2.0.5"
@@ -54,7 +54,7 @@
54
54
  "@types/react": "^16.9.11",
55
55
  "@types/react-dom": "^16.9.15",
56
56
  "@types/axios": "^0.14.0",
57
- "neo-cmp-cli": "^1.8.26",
57
+ "neo-cmp-cli": "^1.9.0",
58
58
  "husky": "^4.2.5",
59
59
  "lint-staged": "^10.2.9",
60
60
  "prettier": "^2.0.5"
@@ -29,7 +29,7 @@ import { xObject } from 'neo-open-api'; // Neo Open API
29
29
  import isEqual from 'lodash/isEqual';
30
30
  // 引入 neo-ui-common / aop
31
31
  // @ts-ignore
32
- import { aop } from 'neo-ui-common';
32
+ import { aop } from 'neo-ui-common'; // 后续考虑 使用 props.dispatchEvent 方法替代
33
33
  import './style.scss';
34
34
 
35
35
  const { Option } = Select;
@@ -234,10 +234,15 @@ export default class EntityForm extends React.PureComponent<
234
234
  * 表单提交事件
235
235
  */
236
236
  @aop
237
- submit() {
237
+ onSubmit() {
238
238
  console.log('触发了表单提交事件:', this.props);
239
239
  }
240
240
 
241
+ @aop
242
+ onBeforeSubmit(formValues: any) {
243
+ console.log('触发了表单提交前事件:', formValues);
244
+ }
245
+
241
246
  /**
242
247
  * 处理表单提交
243
248
  * 执行新增操作
@@ -247,6 +252,9 @@ export default class EntityForm extends React.PureComponent<
247
252
  const { xObjectApiKey } = this.props.xObjectDataApi || {};
248
253
  const { fieldList } = this.state;
249
254
 
255
+ // 触发表单提交事件
256
+ this.onBeforeSubmit(values);
257
+
250
258
  if (!xObjectApiKey) {
251
259
  message.error('请先选择要操作的对象');
252
260
  return;
@@ -307,7 +315,7 @@ export default class EntityForm extends React.PureComponent<
307
315
  }
308
316
 
309
317
  // 触发表单提交事件
310
- this.submit();
318
+ this.onSubmit();
311
319
  });
312
320
  }
313
321
 
@@ -53,20 +53,19 @@ export class EntityFormModel {
53
53
 
54
54
  /**
55
55
  * 声明当前组件会触发的所有事件
56
+ * 备注:页面设计器端可用于进行事件绑定,在组件属性配置模式中配置事件动作
56
57
  */
57
58
  events = [
58
59
  {
59
- helpText: '点击页签后触发该事件',
60
- apiKey: 'onChange',
61
- description: '点击页签触发该事件',
62
- label: '页签切换后',
63
- // cmpKeyIdentifier: '',
64
- // helpTextKey: '',
65
- // eventCategory: 2,
66
- // pageType: 1,
67
- // targetDevice: 1,
68
- // eventParams: '[{"apiKey":"eventParam","children":[{"apiKey":"target","label":"组件名称","type":"string"},{"apiKey":"cmp","label":"组件实例","type":"Object"},{"apiKey":"data","children":[{"apiKey":"tabKey","label":"页签key","type":"string"}],"label":"数据","type":"Object"}],"label":"事件入参","type":"Object"}]',
69
- // labelKey: 'XdMDNeoEvent.NeoTabContainer.onChange'
60
+ apiKey: 'onSubmit', // 事件名称
61
+ // description: '这是一个表单提交事件', // 暂未使用
62
+ label: '提交表单后', // 事件
63
+ helpText: '表单提交后触发该事件' // 信息icon hover 时的提示文本
64
+ },
65
+ {
66
+ apiKey: 'onBeforeSubmit',
67
+ label: '提交表单前',
68
+ helpText: '表单提交前触发该事件'
70
69
  },
71
70
  ];
72
71
 
@@ -45,7 +45,7 @@
45
45
  "devDependencies": {
46
46
  "@commitlint/cli": "^8.3.5",
47
47
  "@commitlint/config-conventional": "^9.1.1",
48
- "neo-cmp-cli": "^1.8.26",
48
+ "neo-cmp-cli": "^1.9.0",
49
49
  "husky": "^4.2.5",
50
50
  "lint-staged": "^10.2.9",
51
51
  "prettier": "^2.0.5"
@@ -47,7 +47,7 @@
47
47
  "@commitlint/config-conventional": "^9.1.1",
48
48
  "@types/react": "^16.9.11",
49
49
  "@types/react-dom": "^16.9.15",
50
- "neo-cmp-cli": "^1.8.26",
50
+ "neo-cmp-cli": "^1.9.0",
51
51
  "husky": "^4.2.5",
52
52
  "lint-staged": "^10.2.9",
53
53
  "prettier": "^2.0.5"
@@ -45,7 +45,7 @@
45
45
  "devDependencies": {
46
46
  "@commitlint/cli": "^8.3.5",
47
47
  "@commitlint/config-conventional": "^9.1.1",
48
- "neo-cmp-cli": "^1.8.26",
48
+ "neo-cmp-cli": "^1.9.0",
49
49
  "husky": "^4.2.5",
50
50
  "lint-staged": "^10.2.9",
51
51
  "prettier": "^2.0.5",
@@ -1,7 +1,7 @@
1
1
  const { execSync } = require('child_process');
2
2
 
3
3
  // 所有需要废弃的版本
4
- const versionsToDeprecate = ["1.8.20", "1.8.21", "1.8.22", "1.8.23", "1.8.24", "1.8.25"];
4
+ const versionsToDeprecate = ["1.8.25", "1.9.0"];
5
5
 
6
6
  const packageName = 'neo-cmp-cli';
7
7
  const deprecateMessage = '此版本为开发中版本(存在 bug),请升级到最新版本。';
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("ora"),r=require("../../neo/neoService.js"),t=require("../common.js");var o,s;exports.__require=function(){if(s)return o;s=1;const i=e,n=r.__require(),{errorLog:c,successLog:u}=t.__require();return o=async(e,r,t)=>{if(!r)return void c("未找到 NeoCRM 平台授权配置(neo.config.js / authConfig)。");const o=i("正在删除组件...").start();try{let s=t,i=[],a=null;t?i=t.cmpList||[]:(s=new n(r),o.info("正在获取自定义组件列表..."),i=await s.getCustomCmpList()),0===i.length&&(c("删除失败,当前租户暂无任何自定义组件。",o),process.exit(1)),a=s.getCmpInfoByCmpType(e),a||(c(`删除失败,当前租户不存在${e}自定义组件。`,o),process.exit(1)),o.info(`正在删除${e}自定义组件...`),await s.deleteCmp(e),u(`已成功删除${e}自定义组件!\n`,o)}catch(e){c(`删除自定义组件失败: ${e.message}`,o),process.exit(1)}},o};
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"}),require("lodash");const e=require("akfun"),r=require("../pathUtils.js"),o=require("ora"),t=require("../../neo/neoService.js"),i=require("../common.js"),s=require("./getCmpTypeByDir.js"),n=require("./createCmpByZip.js");var c,a;exports.__require=function(){if(a)return c;a=1;const{getConfigObj:p}=e,{catchCurPackageJson:u}=r.__require(),m=o,f=t.__require(),{getFramework:g,errorLog:q,successLog:C}=i.__require(),_=s.__require(),y=n.__require(),l=g(p(u()).framework);return c=async(e,r,o)=>{if(!r)return void q("未找到 NeoCRM 平台授权配置(neo.config.js / authConfig)。");_().indexOf(e)>-1&&(q(`当前项目目录中已存在${e}自定义组件。(./src/components 目录下)`),process.exit(1));const t=m("正在拉取组件...").start();try{let i=o,s=[],n={},c=null;o?(s=o.cmpList||[],n=o.cmpInfoMap||{}):(i=new f(r),t.info("正在获取自定义组件列表..."),s=await i.getCustomCmpList(),n=i.cmpInfoMap||{}),0===s.length&&(q("拉取失败,当前租户暂无任何自定义组件。",t),process.exit(1)),c=i.getCmpInfoByCmpType(e),c||(q(`拉取失败,当前租户不存在${e}自定义组件。`,t),process.exit(1)),c.framework&&c.framework!==l&&(q(`拉取失败,${e}自定义组件与当前项目技术栈不一致。`,t),process.exit(1));const a=i.getCodeLibByCmpType(e),p=await i.ensureValidToken();await y(a,{token:p,cmpName:e,componentBaseDir:"./src/components"})||(q(`拉取失败,${e}自定义组件源码解析失败,请检查源码文件是否正确。`,t),process.exit(1)),C(`已成功拉取${e}自定义组件!\n`,t)}catch(e){throw q(`拉取自定义组件失败: ${e.message}`,t),e}},c};
@@ -1 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("node:fs"),t=require("node:path"),o=require("lodash"),s=require("akfun"),r=require("../pathUtils.js"),i=require("ora"),a=require("../../neo/neoService.js"),n=require("../common.js"),c=require("../projectUtils/createCmpProjectZip.js");var l,p;exports.__require=function(){if(p)return l;p=1;const u=e,g=t,d=o,{getConfigObj:m}=s,{catchCurPackageJson:w}=r.__require(),h=i,b=a.__require(),{getFramework:y,errorLog:f,successLog:C}=n.__require(),$=c.__require(),q=m(w()),T=(e=[])=>e.map(e=>({label:e.label,description:e.description,propSchema:JSON.stringify(e)})),v=(e=[],t)=>e&&0!==e.length?e.map(e=>({...e,componentType:t})):[];return l=async(e,t)=>{const o=h("正在发布组件...").start();try{let s,r=new b(e);await r.ensureValidToken(),o.start("[1/4] 打包源码文件(含单个自定义组件源码)...");try{s=$(t,process.cwd(),e.assetsRoot),s?C(`[1/4] 源码文件打包完成: ${g.basename(s)}。`,o):f("[1/4] 源码文件打包失败,未返回 zip 文件路径。",o)}catch(e){f("[1/4] 源码文件打包失败。",o)}o.start("[2/4] 获取自定义组件构建产物...");const i=await r.getCmpAssets(t);let a;o.start("[3/4] 构建组件数据...");try{a=await(async(e,t)=>{if(!t||!t.cmpType)return f("自定义组件信息或组件名称不能为空"),null;const{cmpType:o}=t;if(!e||!u.existsSync(e))return f(`未找到自定义组件目录: ${e}`),null;const s=d.camelCase(o),r=g.join(e,`${s}Model.js`),i=globalThis.window;globalThis.window||(globalThis.window={console:console,neoRequire:()=>{},postMessage:()=>{}});try{u.existsSync(r)?require(r):(f(`未找到自定义组件模型文件,请检查以下路径是否存在:${r}`),process.exit(1)),globalThis.window&&globalThis.window.NEOEditorCustomModels||(f(`模型文件未导出有效模型方法(CatchCustomCmpModelClass),模型文件地址: ${r} `),process.exit(1));const e=globalThis.window.NEOEditorCustomModels[o];e||(f(`未找到自定义组件模型类(${o}),模型文件地址: ${r} `),process.exit(1));const s=new e;s||(f(`未找到自定义组件模型信息(${o}),模型文件地址: ${r} `),process.exit(1));const i={...t,version:q.version||"1.0.0",framework:q.framework?y(q.framework):0,label:s.label||o,description:s.description||"",componentCategory:(s.tags||["自定义组件"]).join(","),targetPage:s.targetPage||["customPage"],targetObject:s.targetObject||["all"],targetApplication:s.targetApplication||["all"],targetDevice:s.targetDevice||"all",iconUrl:s.iconUrl||s.iconUrl,defaultProps:JSON.stringify(s.defaultComProps||{}),previewProps:JSON.stringify(s.previewComProps||{}),props:T(s.propsSchema||[]),events:v(s.events||[],o),functions:s.functions||s.actions||[],exposedToDesigner:void 0===s.exposedToDesigner||s.exposedToDesigner,namespace:s.namespace||"neo-cmp-cli",enableDuplicate:void 0===s.enableDuplicate||s.enableDuplicate};return console.log(`自定义组件模型信息(${o}):`,d.omit(i,["assetFile","modelAssetFile","cssAssetFile","codeLibFile"])),i}catch(e){return f(`自定义组件模型文件解析失败 (${r||"未知路径"}): ${e.message}`),f(e.stack),null}finally{void 0===i?delete globalThis.window:globalThis.window=i}})(e.assetsRoot,i),a?C("[3/4] 组件数据构建完成。",o):f(`[3/4] 未获取到自定义组件模型信息(${t})。`,o)}catch(e){f(`[3/4] 组件数据构建失败: ${e.message}`,o)}o.start("[4/4] 保存组件信息到 NeoCRM 平台...");try{await r.updateCustomComponent(a),C("[4/4] 组件信息保存成功",o)}catch(e){f("[4/4] 组件信息保存失败",o)}const{tenant_id:n,instance_uri:c}=r.tokenCache||{};console.log(`\n✅ 自定义组件发布成功!\n(当前租户 ID: ${n},所在租户的 API 域名: ${c}。)`)}catch(e){try{o&&o.isSpinning&&f(`❌ 自定义组件发布失败: ${e.message}`,o)}catch{f(`\n❌ 自定义组件发布失败: ${e.message}`)}throw e}},l};