neo-cmp-cli 1.12.2 → 1.12.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 (25) hide show
  1. package/dist/index2.js +1 -1
  2. package/dist/loaders/component-scope-style-loader2.js +1 -1
  3. package/dist/package.json.js +1 -1
  4. package/dist/utils/cmpUtils/createCmpByTemplate.js +1 -1
  5. package/dist/utils/cmpUtils/createCmpByZip.js +1 -1
  6. package/package.json +1 -1
  7. package/template/antd-custom-cmp-template/package.json +1 -1
  8. package/template/develop/EntityGrid Web /347/273/204/344/273/266/347/232/204/350/257/246/347/273/206/345/210/206/346/236/220/346/226/207/346/241/243.md" +868 -0
  9. package/template/develop/{EntityList → EntityList H5 }/347/273/204/344/273/266/347/232/204/350/257/246/347/273/206/345/210/206/346/236/220/346/226/207/346/241/243.md" +2 -1
  10. package/template/echarts-custom-cmp-template/package.json +1 -1
  11. package/template/empty-cmp/model.ts +2 -1
  12. package/template/empty-custom-cmp-template/package.json +1 -1
  13. package/template/neo-bi-cmps/package.json +1 -1
  14. package/template/neo-custom-cmp-template/package.json +1 -1
  15. package/template/neo-h5-cmps/package.json +1 -1
  16. package/template/neo-h5-cmps/src/components/openChatPageBtn__c/index.tsx +3 -0
  17. package/template/neo-h5-cmps/src/components/openChatPageBtn__c/model.ts +12 -0
  18. package/template/neo-order-cmps/package.json +1 -1
  19. package/template/react-custom-cmp-template/package.json +1 -1
  20. package/template/react-ts-custom-cmp-template/package.json +1 -1
  21. package/template/vue2-custom-cmp-template/package.json +1 -1
  22. package/template/develop/Neo /347/274/226/350/276/221/345/231/250/346/217/220/344/276/233/347/232/204/345/261/236/346/200/247/351/205/215/347/275/256/351/241/271.pdf +0 -0
  23. package/template/develop/demo1/index.jsx +0 -84
  24. package/template/develop/demo1/index1.jsx +0 -81
  25. package/template/develop//345/275/223/345/211/215/345/217/257/347/224/250/347/232/204/345/261/236/346/200/247/351/205/215/347/275/256/351/241/271.pdf +0 -0
@@ -0,0 +1,868 @@
1
+ # web端 EntityGrid 组件详细分析文档
2
+
3
+ ## 目录
4
+
5
+ - [组件概述](#组件概述)
6
+ - [核心功能](#核心功能)
7
+ - [组件架构](#组件架构)
8
+ - [主要属性说明](#主要属性说明)
9
+ - [生命周期方法](#生命周期方法)
10
+ - [核心方法详解](#核心方法详解)
11
+ - [使用示例](#使用示例)
12
+ - [扩展机制](#扩展机制)
13
+ - [注意事项](#注意事项)
14
+ - [常见问题](#常见问题)
15
+
16
+ ## 组件概述
17
+
18
+ `EntityGrid` 是 Neo UI Component Web 端的核心业务组件,用于展示和管理实体数据列表。它基于 AG-Grid 实现,支持表格视图、分屏视图、地图视图、BI 看板等多种展示模式,提供了完整的数据展示、筛选、排序、批量操作、单元格编辑等功能。
19
+
20
+ ### 技术栈
21
+
22
+ - **React**: 基于 React 类组件实现
23
+ - **MobX**: 使用 MobX 进行状态管理(通过 `@observer` 装饰器)
24
+ - **MobX State Tree**: Store 使用 MST 进行状态管理
25
+ - **AG-Grid**: 基于 AG-Grid 进行表格渲染
26
+ - **amis**: 通过 amis 框架进行布局和部分 UI 渲染
27
+ - **TypeScript**: 完整的类型定义支持
28
+
29
+ ### 组件位置
30
+
31
+ ```
32
+ packages/neo-ui-component-web/src/components/EntityGrid/
33
+ ├── component.tsx # 主组件实现
34
+ ├── amisRegister.tsx # amis 注册入口
35
+ ├── store.ts # Store 定义(EntityGridStore)
36
+ ├── interface/ # 接口定义
37
+ │ └── index.ts # 接口导出
38
+ ├── constant/ # 常量定义
39
+ │ ├── index.ts # 常量导出
40
+ │ ├── hoc.props.ts # HOC 透传属性
41
+ │ └── store.types.ts # Store 类型定义
42
+ ├── model/ # 数据模型
43
+ │ ├── dataSource.ts # 数据源
44
+ │ ├── dataView.ts # 数据视图
45
+ │ └── layout/ # 布局模型
46
+ ├── nex/ # Nex 扩展
47
+ │ ├── nexManager.ts # Nex 管理器
48
+ │ ├── nex.v1/ # Nex 1.0 实现
49
+ │ └── nex.v2/ # Nex 2.0 实现
50
+ ├── cmp/ # 内部组件
51
+ │ ├── EntityGridHeader.tsx # 头部
52
+ │ ├── EntityGridFooter.tsx # 底部
53
+ │ ├── empty.tsx # 空状态
54
+ │ ├── SmartView/ # SmartView 切换
55
+ │ ├── FilterList/ # 筛选列表
56
+ │ ├── BatchOperate/ # 批量操作
57
+ │ ├── MapView/ # 地图视图
58
+ │ └── splitView/ # 分屏视图
59
+ └── request/ # 请求相关
60
+ ```
61
+
62
+ ## 核心功能
63
+ 组件 cmpType: entityGrid
64
+
65
+ 基于 neoGrid 实现,而 neoGrid 又基于 aggrid 封装;
66
+ 注册 entityGrid 时,storeType 设置的是自定义的 store(EntityGridStore:packages/neo-ui-component-web/src/components/EntityGrid/store.ts)。
67
+
68
+ ### 1. 多种展示模式
69
+
70
+ 组件支持以下展示模式(通过 `displayMode` 控制):
71
+
72
+ - **`list`**: 列表视图(默认)- 标准表格展示
73
+ - **`listSplitView`**: 分屏视图 - 左侧列表 + 右侧详情
74
+ - **`listMapView`**: 地图视图 - 地图 + 列表联动
75
+ - **BI Board**: BI 看板视图(通过 `biListVisible` 控制)
76
+
77
+ ### 2. 数据展示功能
78
+
79
+ - **表格视图**: 基于 AG-Grid 的完整表格能力
80
+ - **SmartView 切换**: 支持多个视图配置切换
81
+ - **分页加载**: 支持服务端分页(serverSide)和客户端分页(clientSide)
82
+ - **树形结构**: 支持树形数据展示(`treeData: true`)
83
+ - **空状态处理**: 提供友好的空数据提示
84
+ - **错误处理**: 完善的错误提示和重试机制
85
+
86
+ ### 3. 筛选和排序
87
+
88
+ - **筛选功能**:
89
+ - 支持列头筛选
90
+ - 支持自定义筛选条件(`setCustomCondition`)
91
+ - 筛选条件持久化
92
+ - **排序功能**:
93
+ - 支持多列排序
94
+ - 支持升序/降序切换
95
+ - 排序状态持久化
96
+
97
+ ### 4. 批量操作
98
+
99
+ - **批量选择**: 支持单选/多选模式
100
+ - **批量操作按钮**: 支持批量编辑、删除、转移等操作
101
+ - **批量编辑**: 支持扣框编辑(单元格内联编辑)
102
+ - **Picker 模式**: 支持作为选择器使用(`pattern: 'pickView'`)
103
+
104
+ ### 5. 单元格编辑
105
+
106
+ - **扣框编辑**: 支持单元格内联编辑
107
+ - **批量保存**: 支持批量编辑后统一保存
108
+ - **权限控制**: 支持字段级编辑权限
109
+ - **校验**: 支持保存前校验
110
+
111
+ ### 6. 详情打开方式
112
+
113
+ - **单击**: 侧滑抽屉打开详情
114
+ - **双击**: 新页签打开详情
115
+ - **分屏视图**: 右侧直接展示详情
116
+ - **地图视图**: 点击地图标记打开详情
117
+
118
+ ### 7. 扩展机制
119
+
120
+ - **Nex 1.0**: 通过 `nexVersion: 1` 进行扩展
121
+ - **Nex 2.0**: 通过 `nexVersion: 2` 进行扩展
122
+ - **HOC 扩展**: 通过 `HOC_PROPS` 透传业务线扩展属性
123
+
124
+ ## 组件架构
125
+
126
+ ### 组件继承关系
127
+
128
+ ```typescript
129
+ @GridRenderer({ Layout: {} })
130
+ export default class ComponentRenderer extends Common<RendererProps>
131
+ ```
132
+
133
+ - `@GridRenderer({ Layout: {} })`: amis 网格渲染器装饰器
134
+ - `Common`: 即 `EntityGrid` 主组件
135
+ - 继承自 `React.Component`
136
+
137
+ ### 核心实例属性
138
+
139
+ ```typescript
140
+ class EntityGrid {
141
+ neoStore: DataStore // 导航栏相关 Store(多页签模式)
142
+ entityGridLayout: EntityGridLayout // 布局管理器
143
+ nexObj: NexManager // Nex 扩展实例
144
+ rightFloatElement: HTMLDivElement // 单元格编辑图标容器
145
+ uuid: string // 组件唯一标识
146
+ __com__: EntityGridPageCom // 页面 Com 实例(用于刷新等)
147
+ }
148
+ ```
149
+
150
+ ### Store 结构
151
+
152
+ 组件依赖 `EntityGridStore`(基于 MST),主要包含以下状态:
153
+
154
+ - **数据状态**: `rowData`, `totalCount`, `currentPage`
155
+ - **视图状态**: `displayMode`, `activeSmartView`, `dataListViews`
156
+ - **筛选状态**: `filterModel`, `headerCondition`
157
+ - **排序状态**: `sortModel`
158
+ - **加载状态**: `loading`, `ready`, `error`
159
+ - **权限状态**: `funPermission`, `dataPermission`
160
+ - **选中状态**: `selectedRowsID`, `selectedIds`
161
+ - **树形状态**: `treeExpandedAll`, `treeExpandState`(树形模式)
162
+
163
+ ### 布局结构
164
+
165
+ 组件采用 `EntityGridLayout` 进行布局管理,包含三个主要区域:
166
+
167
+ 1. **entityGridHeader**: 头部区域(搜索、SmartView、筛选、操作按钮)
168
+ 2. **entityGridBody**: 主体区域(表格/分屏/地图/BI 看板)
169
+ 3. **entityGridFooter**: 底部区域(分页、汇总等)
170
+
171
+ ## 主要属性说明
172
+
173
+ ### 基础属性
174
+
175
+ | 属性名 | 类型 | 默认值 | 说明 |
176
+ |--------|------|--------|------|
177
+ | `objectApiKey` | `string` | - | 实体的 ApiKey(必填) |
178
+ | `name` | `string` | - | 组件名称,用于 amis 通信(必填) |
179
+ | `pattern` | `string` | - | 使用模式:`entityView`/`pickView`/`simpleListView`/`globalSearchPage`/`secondaryList` |
180
+ | `height` | `string \| number` | `'100%'` | 组件高度 |
181
+ | `className` | `string` | `''` | 自定义样式类名 |
182
+
183
+ ### 数据加载属性
184
+
185
+ | 属性名 | 类型 | 默认值 | 说明 |
186
+ |--------|------|--------|------|
187
+ | `dataLoadType` | `LOAD_TYPE` | - | 数据加载方式:`serverSide`/`clientSide`/`auto`/`pagination` |
188
+ | `rowModelType` | `LOAD_TYPE` | - | AG-Grid 行模型类型 |
189
+ | `cacheBlockSize` | `number` | - | 服务端模式下单次请求条数 |
190
+ | `paginationPageSize` | `number` | - | 分页每页条数 |
191
+ | `agGridDataSource` | `object` | - | 自定义数据源 |
192
+
193
+ ### 列表配置属性
194
+
195
+ | 属性名 | 类型 | 默认值 | 说明 |
196
+ |--------|------|--------|------|
197
+ | `withOrder` | `boolean` | `true` | 是否显示序号列 |
198
+ | `withCheck` | `boolean` | `true` | 是否显示多选列 |
199
+ | `editable` | `boolean` | `true` | 是否支持单元格编辑 |
200
+ | `disableSearch` | `boolean` | `false` | 是否禁用搜索 |
201
+ | `disableExport` | `boolean` | `false` | 是否禁用导出 |
202
+ | `disablePagination` | `boolean` | `false` | 是否禁用分页 |
203
+ | `selectionMode` | `'single' \| 'multiple'` | - | 选择模式(Picker 下默认 single) |
204
+
205
+ ### 事件回调属性
206
+
207
+ | 属性名 | 类型 | 说明 |
208
+ |--------|------|------|
209
+ | `onRowSelected` | `(data, event) => void` | 行选中变化回调 |
210
+ | `onRecordChange` | `(data) => void` | 行数据变化回调 |
211
+ | `onGridReady` | `(gridModel) => void` | 表格就绪回调 |
212
+ | `onFirstDataRendered` | `() => void` | 首次数据渲染完成回调 |
213
+ | `onDataLoaded` | `(data) => void` | 数据加载完成回调 |
214
+ | `onDataRequest` | `(store) => void` | 数据请求前回调(可修改请求参数) |
215
+ | `onLayoutLoaded` | `(data) => void` | 布局加载完成回调 |
216
+ | `onLoadedDataComplete` | `(payload) => void` | 布局数据加载完成回调 |
217
+ | `onSmartViewChanged` | `(data) => void` | SmartView 切换回调 |
218
+ | `onSinglerClick` | `(clickData) => boolean` | 单击行拦截(返回 true 拦截默认逻辑) |
219
+ | `interceptClick` | `(clickData, options) => boolean` | 详情打开前拦截 |
220
+
221
+ ### 扩展属性(HOC_PROPS)
222
+
223
+ | 属性名 | 类型 | 说明 |
224
+ |--------|------|------|
225
+ | `batchButtons` | `array` | 批量操作按钮配置 |
226
+ | `entityButtons` | `array` | 列表操作按钮配置 |
227
+ | `shortcutButtons` | `array` | 快捷操作按钮配置 |
228
+ | `referData` | `object` | Picker 相关数据 |
229
+ | `selectedIds` | `array` | Picker 默认选中数据 |
230
+ | `searchCondition` | `object` | 初始搜索条件 |
231
+ | `additionalConditions` | `array` | 附加筛选条件 |
232
+ | `customToolbarButtons` | `array` | 自定义工具栏按钮 |
233
+ | `treeData` | `boolean` | 是否启用树形模式 |
234
+ | `treeParentIdField` | `string` | 树形父ID字段名 |
235
+ | `treeInitialLoadCount` | `number` | 树形每层初始加载数量 |
236
+ | `treeLoadMoreCount` | `number` | 树形加载更多数量 |
237
+
238
+ ### 其他属性
239
+
240
+ | 属性名 | 类型 | 说明 |
241
+ |--------|------|------|
242
+ | `pageInfo` | `object` | 页面信息,用于注册刷新方法 |
243
+ | `footerBlock` | `object` | 底部操作区配置 |
244
+ | `headerBlock` | `object` | 头部扩展配置 |
245
+ | `noPermission` | `ReactNode \| Function` | 无权限时展示内容 |
246
+ | `customEmptyMsg` | `string` | 自定义空数据提示 |
247
+ | `scene` | `string` | 场景标识(如 `standard`) |
248
+
249
+ ## 生命周期方法
250
+
251
+ ### componentWillMount(amis 包装层)
252
+
253
+ ```typescript
254
+ componentWillMount() {
255
+ const scoped = this.context as IScopedContext
256
+ scoped.registerComponent(this)
257
+ }
258
+ ```
259
+
260
+ - **作用**: 注册组件到 amis 的 ScopedContext
261
+ - **时机**: 组件挂载前
262
+
263
+ ### constructor
264
+
265
+ ```typescript
266
+ constructor(options) {
267
+ // 1. 解析 URL 参数(urlConditions, urlExpression, canCreate, canEdit)
268
+ // 2. 多页签模式下初始化 DataStore 和导航栏刷新方法
269
+ // 3. 初始化 NexManager
270
+ // 4. 调用 store.initGrid 初始化 Store
271
+ // 5. 创建 EntityGridLayout 布局
272
+ // 6. 如有 pageInfo,创建 EntityGridPageCom 并注册刷新方法
273
+ }
274
+ ```
275
+
276
+ ### componentDidMount
277
+
278
+ ```typescript
279
+ componentDidMount() {
280
+ // 1. 监听 customEventBus(cell_save, cell_cancel, refresh_grid)
281
+ // 2. 监听 onSlideChanged 事件
282
+ // 3. 监听 compositionstart/compositionend(中文输入法)
283
+ // 4. 监听 document click(清除详情行高亮)
284
+ // 5. 设置 __com__ 的 context
285
+ // 6. Safari 浏览器添加 is-safari 类名
286
+ }
287
+ ```
288
+
289
+ ### componentDidUpdate
290
+
291
+ ```typescript
292
+ componentDidUpdate() {
293
+ // 根据 store.aggridModel?.cellEditing 动态添加/移除 neo-entity-view-cell-editing 类名
294
+ }
295
+ ```
296
+
297
+ ### componentWillUnmount
298
+
299
+ ```typescript
300
+ componentWillUnmount() {
301
+ // 1. 移除所有事件监听
302
+ // 2. 清空 entityGridLayout 引用
303
+ // 3. 销毁 nexObj
304
+ // 4. 多页签模式下清理 neoStore
305
+ }
306
+ ```
307
+
308
+ ## 核心方法详解
309
+
310
+ ### 初始化方法
311
+
312
+ #### createLayout()
313
+
314
+ 创建布局结构:
315
+
316
+ ```typescript
317
+ createLayout = () => {
318
+ let entityGridLayout = {
319
+ grids: [
320
+ { type: 'entityGridHeader', name: 'entityGridHeader', ... },
321
+ { nameSpace: 'entityGridBody' },
322
+ { type: 'entityGridFooter', name: 'entityGridFooter', ... }
323
+ ]
324
+ }
325
+ // 支持 neoLayout 合并自定义布局
326
+ if (neoLayout) {
327
+ entityGridLayout = EntityGridLayout.commonMerge(neoLayout, entityGridLayout)
328
+ }
329
+ this.entityGridLayout = new EntityGridLayout(entityGridLayout)
330
+ }
331
+ ```
332
+
333
+ #### resetGrid(props)
334
+
335
+ 重置整个列表(刷新页面时使用):
336
+
337
+ ```typescript
338
+ resetGrid = (props) => {
339
+ this._hasDetailRowHighlight = false
340
+ store.clearStatus()
341
+ store.initGrid(props, this.t0)
342
+ this.nexObj.getInstance().getRef('header').clear()
343
+ }
344
+ ```
345
+
346
+ ### 点击处理方法
347
+
348
+ #### onLinkSingerClick(clickData)
349
+
350
+ 单击行处理逻辑:
351
+
352
+ 1. 堆叠视图模式下关闭所有弹框
353
+ 2. 若配置 `openDetailInNewTab` 则走双击逻辑
354
+ 3. Picker 模式:调用 `bridge?.detailOpenNew`
355
+ 4. 多页签模式:`NeoNavigator.openEntityDetail` 新页签打开
356
+ 5. 侧滑模式:`NeoNavigator.openEntityDetail` 抽屉打开
357
+ 6. 根据 `layoutMode` 决定抽屉全屏/80%
358
+
359
+ #### onLinkDoubleClick(clickData)
360
+
361
+ 双击行处理逻辑:新页签或新窗口打开详情页。
362
+
363
+ ### 视图切换方法
364
+
365
+ #### getGridView()
366
+
367
+ 获取可用视图列表(列表、分屏、地图、BI 看板、自定义视图):
368
+
369
+ ```typescript
370
+ getGridView = () => {
371
+ const views = []
372
+ if (store.biListVisible) { views.push({ component: biBoard, ... }) }
373
+ if (store.splitListVisible) { views.push({ component: splitView, ... }) }
374
+ if (store.mapListVisible) { views.push({ component: mapView, ... }) }
375
+ if (customViews({ store }).length > 0) { views.push(...customViews) }
376
+ if (views.length > 0) { views.unshift({ component: list, ... }) }
377
+ return views
378
+ }
379
+ ```
380
+
381
+ #### addGridBody(component)
382
+
383
+ 向 body 区域添加视图组件。
384
+
385
+ ### 指令方法(cmd_*)
386
+
387
+ 组件通过 `receive` 接收 amis 指令,支持以下 cmd:
388
+
389
+ | 指令 | 说明 |
390
+ |------|------|
391
+ | `cmd_refresh_grid` | 刷新列表数据 |
392
+ | `cmd_refresh_singleData` | 刷新单行数据 |
393
+ | `cmd_cell_save` | 单元格保存 |
394
+ | `cmd_cancel_edit` | 取消编辑 |
395
+ | `cmd_batch_save` | 批量保存 |
396
+ | `cmd_picker_sure` | Picker 确定 |
397
+ | `cmd_picker_close` | Picker 关闭 |
398
+ | `cmd_close` | 关闭页面 |
399
+
400
+ ### 树形模式方法
401
+
402
+ #### getTreeExpandButton()
403
+
404
+ 获取树形模式下的「展开全部」「收起全部」按钮配置。
405
+
406
+ ## 使用示例
407
+
408
+ ### 示例 1: 基础大列表(amis Schema)
409
+
410
+ ```typescript
411
+ import { NeoRenderer } from 'neo-ui-common'
412
+
413
+ // 通过 amis Schema 渲染
414
+ <NeoRenderer
415
+ schema={{
416
+ type: 'page',
417
+ body: [
418
+ {
419
+ type: 'entityGrid',
420
+ name: 'listviewx',
421
+ objectApiKey: 'account',
422
+ height: '100%',
423
+ pageInfo: {
424
+ pageKey: 'entityGrid',
425
+ scope: { objectApiKey: 'account' }
426
+ }
427
+ }
428
+ ]
429
+ }}
430
+ />
431
+ ```
432
+
433
+ ### 示例 2: NeoEntityGrid 标准组件(表单设计器)
434
+
435
+ ```typescript
436
+ import NeoEntityGrid from '@/components/GenBizComp/NeoEntityGrid'
437
+
438
+ <NeoEntityGrid
439
+ objectApiKey="account"
440
+ showView={true}
441
+ enableChangeView={true}
442
+ defaultViewId="default_view"
443
+ additionalConditions={[]}
444
+ paginationPageSize={10}
445
+ enableSearch={true}
446
+ enableHeaderOptions={true}
447
+ withOrder={true}
448
+ enableToolbar={true}
449
+ canEdit={true}
450
+ onRecordChange={(data) => console.log('数据变化', data)}
451
+ />
452
+ ```
453
+
454
+ ### 示例 3: Picker 列表(选择器)
455
+
456
+ ```typescript
457
+ {
458
+ type: 'entityGrid',
459
+ name: 'pickerList',
460
+ objectApiKey: 'contact',
461
+ pattern: 'pickView',
462
+ height: '100%',
463
+ selectionMode: 'multiple',
464
+ referData: {
465
+ referItemId: 'xxx',
466
+ referItemApiKey: 'accountId'
467
+ },
468
+ onSelectedCall: (selectedData) => {
469
+ console.log('选中的数据', selectedData)
470
+ },
471
+ shouldCloseDialog: true
472
+ }
473
+ ```
474
+
475
+ ### 示例 4: 二级列表(详情页相关列表)
476
+
477
+ ```typescript
478
+ {
479
+ type: 'entityGrid',
480
+ name: 'listviewx',
481
+ objectApiKey: 'opportunity',
482
+ pattern: 'secondaryList',
483
+ height: '100%',
484
+ isViewList: true,
485
+ data: { entityId: 123 },
486
+ onDataRequest: (store) => {
487
+ store.setCustomCondition([
488
+ { item: 456, type: 10, value: detailId }
489
+ ])
490
+ },
491
+ footerBlock: {
492
+ actions: {
493
+ type: 'button-group',
494
+ target: 'listviewx',
495
+ buttons: [
496
+ { type: 'action', actionType: 'reload', label: '取消', target: 'listviewx?cmd=cancel_edit' },
497
+ { type: 'action', actionType: 'reload', label: '保存', target: 'listviewx?cmd=batch_save' }
498
+ ]
499
+ }
500
+ }
501
+ }
502
+ ```
503
+
504
+ ### 示例 5: 自定义筛选条件
505
+
506
+ ```typescript
507
+ {
508
+ type: 'entityGrid',
509
+ name: 'listviewx',
510
+ objectApiKey: 'account',
511
+ additionalConditions: [
512
+ { item: 123, type: 1, value: 'active' }
513
+ ],
514
+ onDataRequest: (store) => {
515
+ // 动态设置额外条件
516
+ store.setCustomCondition([
517
+ { item: 456, type: 10, value: [1, 2, 3] }
518
+ ])
519
+ }
520
+ }
521
+ ```
522
+
523
+ ### 示例 6: 树形列表
524
+
525
+ ```typescript
526
+ {
527
+ type: 'entityGrid',
528
+ name: 'listviewx',
529
+ objectApiKey: 'order',
530
+ treeData: true,
531
+ treeParentIdField: 'parentId',
532
+ treeInitialLoadCount: 50,
533
+ treeLoadMoreCount: 20
534
+ }
535
+ ```
536
+
537
+ ### 示例 7: 扩展配置(Nex 2.0)
538
+
539
+ ```typescript
540
+ {
541
+ type: 'entityGrid',
542
+ name: 'listviewx',
543
+ objectApiKey: 'account',
544
+ nexVersion: 2,
545
+ entityList: {
546
+ openDetailInNewTab: true,
547
+ disableSearch: false,
548
+ dataList: {
549
+ beforeFieldRender: (event) => {
550
+ // 字段渲染前处理
551
+ return null
552
+ }
553
+ },
554
+ listButton: [
555
+ {
556
+ apiKey: 'customBtn',
557
+ label: '自定义按钮',
558
+ onClick: (event) => console.log(event)
559
+ }
560
+ ]
561
+ }
562
+ }
563
+ ```
564
+
565
+ ### 示例 8: 完整配置示例
566
+
567
+ ```typescript
568
+ {
569
+ type: 'entityGrid',
570
+ name: 'accountList',
571
+ objectApiKey: 'account',
572
+ height: '100%',
573
+ pattern: 'entityView',
574
+ scene: 'standard',
575
+
576
+ // 数据配置
577
+ rowModelType: 'serverSide',
578
+ dataLoadType: 'serverSide',
579
+ paginationPageSize: 20,
580
+
581
+ // 功能配置
582
+ withOrder: true,
583
+ withCheck: true,
584
+ editable: true,
585
+ disableSearch: false,
586
+ disableExport: false,
587
+
588
+ // 事件回调
589
+ onRowSelected: (data, event) => console.log('选中', data),
590
+ onRecordChange: (data) => console.log('变更', data),
591
+ onGridReady: (gridModel) => console.log('就绪', gridModel),
592
+ onDataRequest: (store) => {
593
+ // 请求前可修改 store 状态
594
+ },
595
+
596
+ // 底部操作
597
+ footerBlock: {
598
+ actions: {
599
+ type: 'button-group',
600
+ target: 'accountList',
601
+ buttons: [
602
+ { type: 'action', actionType: 'reload', label: '取消', target: 'accountList?cmd=cancel_edit' },
603
+ { type: 'action', actionType: 'reload', label: '保存', target: 'accountList?cmd=batch_save' }
604
+ ]
605
+ }
606
+ },
607
+
608
+ // 页面刷新
609
+ pageInfo: {
610
+ pageKey: 'entityGrid',
611
+ scope: { objectApiKey: 'account' }
612
+ }
613
+ }
614
+ ```
615
+
616
+ ## 扩展机制
617
+
618
+ ### Nex 1.0 扩展
619
+
620
+ 通过 `nexVersion: 1` 或默认,主要扩展点:
621
+
622
+ - `entityList.dataList.fields`: 字段扩展
623
+ - `entityList.dataList.onColumnResized`: 列宽变化
624
+ - `entityList.buttonGroup.actions`: 列表按钮
625
+ - `entityList.bulkButtonGroup.actions`: 批量操作按钮
626
+ - `entityList.listViews.disableLeftCustomView`: 禁用自定义视图
627
+
628
+ ### Nex 2.0 扩展
629
+
630
+ 通过 `nexVersion: 2`,主要扩展点:
631
+
632
+ - `entityList.dataList`: listItem、beforeFieldRender
633
+ - `entityList.listButton`: 列表按钮(事件形式)
634
+ - `entityList.multiButton`: 批量操作按钮(事件形式)
635
+ - `entityList.listViews`: 视图配置
636
+ - `entityList.openDetailInNewTab`: 详情在新页签打开
637
+
638
+ ### HOC 扩展
639
+
640
+ 通过 `HOC_PROPS` 和 `ExtGet` 透传业务线扩展:
641
+
642
+ ```typescript
643
+ // 业务线通过 ExtGet 获取扩展配置
644
+ store.ExtGet('treeData')
645
+ store.ExtGet('customToolbarButtons')
646
+ store.ExtGet('onDataRequest')
647
+ ```
648
+
649
+ ### 指令调用
650
+
651
+ 通过 amis 的 target 机制调用组件方法:
652
+
653
+ ```typescript
654
+ // 刷新列表
655
+ target: 'listviewx?cmd=refresh_grid'
656
+
657
+ // 批量保存
658
+ target: 'listviewx?cmd=batch_save'
659
+
660
+ // 取消编辑
661
+ target: 'listviewx?cmd=cancel_edit'
662
+ ```
663
+
664
+ ## 注意事项
665
+
666
+ ### 1. Store 初始化
667
+
668
+ - Store 由 amis 框架根据 `storeType: EntityGridStore.name` 自动创建
669
+ - 无需手动创建 Store 实例
670
+
671
+ ### 2. 模式区分
672
+
673
+ - `pattern='entityView'`: 标准大列表
674
+ - `pattern='pickView'`: Picker 选择器
675
+ - `pattern='secondaryList'`: 二级/相关列表
676
+ - `pattern='globalSearchPage'`: 全局搜索结果列表
677
+
678
+ ### 3. 必传参数
679
+
680
+ - **所有模式**: `objectApiKey`、`name`
681
+ - **Picker**: `referData`、`onSelectedCall`
682
+ - **二级列表**: `onDataRequest` 中设置 `setCustomCondition`
683
+
684
+ ### 4. 树形模式
685
+
686
+ - 需显式设置 `treeData: true`
687
+ - 支持 `treeParentIdField`、`treeInitialLoadCount`、`treeLoadMoreCount` 等配置
688
+ - 超过 1000 条时「展开全部」按钮禁用
689
+
690
+ ### 5. 性能优化
691
+
692
+ - 服务端模式(serverSide)适合大数据量
693
+ - 客户端模式(clientSide)适合小数据量
694
+ - `rowModelType: 'auto'` 会根据数据量自动切换
695
+
696
+ ### 6. 多页签集成
697
+
698
+ - 传入 `pageInfo` 可注册 `refreshPage`、`refreshData` 等刷新方法
699
+ - 通过 `NeoApp.openPageCom` 获取页面 Com 实例
700
+
701
+ ## 常见问题
702
+
703
+ ### Q1: 如何刷新列表数据?
704
+
705
+ **A**: 通过指令或 Store 方法:
706
+
707
+ ```typescript
708
+ // 方式1: amis 指令
709
+ target: 'listviewx?cmd=refresh_grid'
710
+
711
+ // 方式2: 通过 pageInfo 注册的 refreshData
712
+ const pageCom = NeoApp.getPageCom('EntityGridPage.account')
713
+ pageCom?.extApi?.refreshData()
714
+
715
+ // 方式3: 直接调用 store(需获取 store 引用)
716
+ store.reloadGrid(false)
717
+ ```
718
+
719
+ ### Q2: 如何拦截行点击打开详情?
720
+
721
+ **A**: 使用 `onSinglerClick` 或 `interceptClick`:
722
+
723
+ ```typescript
724
+ {
725
+ type: 'entityGrid',
726
+ onSinglerClick: (clickData) => {
727
+ // 自定义逻辑,返回 true 拦截默认打开详情
728
+ console.log('点击了', clickData)
729
+ return true
730
+ },
731
+ interceptClick: (clickData, { layoutMode, navigationType }) => {
732
+ // 更细粒度拦截,可获取 layoutMode 等
733
+ return false
734
+ }
735
+ }
736
+ ```
737
+
738
+ ### Q3: 如何获取选中的数据?
739
+
740
+ **A**: 通过 `onRowSelected` 回调或 Store:
741
+
742
+ ```typescript
743
+ // 方式1: 回调
744
+ onRowSelected: (selectedData, event) => {
745
+ const data = selectedData.map(({ data }) => data)
746
+ console.log('选中', data)
747
+ }
748
+
749
+ // 方式2: Store(需在 onGridReady 等时机获取)
750
+ const selectedData = store.getSelectedData()
751
+ ```
752
+
753
+ ### Q4: 如何自定义空状态提示?
754
+
755
+ **A**: 使用 `customEmptyMsg`:
756
+
757
+ ```typescript
758
+ {
759
+ type: 'entityGrid',
760
+ customEmptyMsg: '暂无数据,请先创建'
761
+ }
762
+ ```
763
+
764
+ ### Q5: 如何禁用某些功能?
765
+
766
+ **A**: 使用对应的禁用属性:
767
+
768
+ ```typescript
769
+ {
770
+ type: 'entityGrid',
771
+ disableSearch: true,
772
+ disableExport: true,
773
+ disablePagination: true,
774
+ withOrder: false,
775
+ withCheck: false,
776
+ editable: false
777
+ }
778
+ ```
779
+
780
+ ### Q6: Picker 模式如何获取选中结果?
781
+
782
+ **A**: 使用 `onSelectedCall` 回调:
783
+
784
+ ```typescript
785
+ {
786
+ type: 'entityGrid',
787
+ pattern: 'pickView',
788
+ onSelectedCall: (selectedData) => {
789
+ // selectedData 为选中的记录数组
790
+ console.log(selectedData)
791
+ closeDialog()
792
+ },
793
+ shouldCloseDialog: true // 选择后是否关闭弹窗
794
+ }
795
+ ```
796
+
797
+ ### Q7: 如何添加自定义工具栏按钮?
798
+
799
+ **A**: 使用 `customToolbarButtons`(业务线扩展):
800
+
801
+ ```typescript
802
+ {
803
+ type: 'entityGrid',
804
+ customToolbarButtons: [
805
+ {
806
+ key: 'customBtn',
807
+ label: '自定义',
808
+ icon: 'custom-icon',
809
+ onClick: () => console.log('clicked')
810
+ }
811
+ ]
812
+ }
813
+ ```
814
+
815
+ ### Q8: 树形列表如何配置?
816
+
817
+ **A**: 设置 `treeData` 及相关属性:
818
+
819
+ ```typescript
820
+ {
821
+ type: 'entityGrid',
822
+ treeData: true,
823
+ treeParentIdField: 'parentId',
824
+ treeInitialLoadCount: 50,
825
+ treeLoadMoreCount: 20
826
+ }
827
+ ```
828
+
829
+ ### Q9: 如何自定义详情打开方式?
830
+
831
+ **A**: 通过 Nex 扩展 `openDetailInNewTab`:
832
+
833
+ ```typescript
834
+ {
835
+ type: 'entityGrid',
836
+ nexVersion: 2,
837
+ entityList: {
838
+ openDetailInNewTab: true // 单击也在新页签打开
839
+ }
840
+ }
841
+ ```
842
+
843
+ ### Q10: 无权限时如何自定义展示?
844
+
845
+ **A**: 使用 `noPermission`:
846
+
847
+ ```typescript
848
+ {
849
+ type: 'entityGrid',
850
+ noPermission: () => <div>您没有权限查看此列表</div>
851
+ }
852
+ // 或
853
+ noPermission: <NoPermissionComponent />
854
+ ```
855
+
856
+ ## 总结
857
+
858
+ `EntityGrid` 是 Web 端功能强大的列表组件,基于 AG-Grid 提供了完整的数据展示、筛选、排序、批量操作、单元格编辑、多视图切换等功能。通过 amis Schema 配置即可使用,支持 Nex 扩展和 HOC 透传满足业务线定制需求。
859
+
860
+ 在使用时需要注意:
861
+
862
+ 1. 正确设置 `objectApiKey` 和 `name`
863
+ 2. 根据业务场景选择合适的 `pattern`
864
+ 3. 合理使用 `onDataRequest` 设置筛选条件
865
+ 4. 树形模式需显式开启 `treeData`
866
+ 5. 通过 `pageInfo` 集成多页签刷新能力
867
+
868
+ 更多详细信息请参考组件源码和 Store 定义。