neo-cmp-cli 1.2.12 → 1.2.13
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/template/antd-custom-cmp-template/package.json +1 -1
- package/src/template/develop/neo-custom-cmp-template/package.json +1 -1
- package/src/template/echarts-custom-cmp-template/package.json +1 -1
- package/src/template/neo-custom-cmp-template/README.md +1 -1
- package/src/template/neo-custom-cmp-template/package.json +2 -2
- package/src/template/neo-custom-cmp-template/src/assets/img/detail.svg +1 -0
- package/src/template/neo-custom-cmp-template/src/components/contact-card-list/README.md +2 -7
- package/src/template/neo-custom-cmp-template/src/components/contact-card-list/index.tsx +13 -1
- package/src/template/neo-custom-cmp-template/src/components/contact-form/index.tsx +2 -3
- package/src/template/neo-custom-cmp-template/src/components/entity-detail/README.md +193 -0
- package/src/template/neo-custom-cmp-template/src/components/entity-detail/index.tsx +325 -0
- package/src/template/neo-custom-cmp-template/src/components/entity-detail/model.ts +125 -0
- package/src/template/neo-custom-cmp-template/src/components/entity-detail/style.scss +292 -0
- package/src/template/neo-custom-cmp-template/src/components/object-card-list/README.md +61 -0
- package/src/template/neo-custom-cmp-template/src/components/object-card-list/index.tsx +201 -0
- package/src/template/neo-custom-cmp-template/src/components/object-card-list/model.ts +66 -0
- package/src/template/neo-custom-cmp-template/src/components/object-card-list/style.scss +260 -0
- package/src/template/neo-custom-cmp-template/src/components/xobject-table/README.md +3 -11
- package/src/template/neo-custom-cmp-template/src/components/xobject-table/index.tsx +76 -58
- package/src/template/neo-custom-cmp-template/src/components/xobject-table/model.ts +21 -3
- package/src/template/react-custom-cmp-template/package.json +1 -1
- package/src/template/react-ts-custom-cmp-template/package.json +1 -1
- package/src/template/vue2-custom-cmp-template/package.json +1 -1
- package/src/template/neo-custom-cmp-template/src/components/xobject-table-v2/README.md +0 -108
- package/src/template/neo-custom-cmp-template/src/components/xobject-table-v2/index.tsx +0 -729
- package/src/template/neo-custom-cmp-template/src/components/xobject-table-v2/model.ts +0 -122
- package/src/template/neo-custom-cmp-template/src/components/xobject-table-v2/style.scss +0 -304
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file 数据卡片列表组件对接编辑器的描述文件
|
|
3
|
+
*/
|
|
4
|
+
export class ObjectCardListModel {
|
|
5
|
+
/**
|
|
6
|
+
* cmpType 为自定义组件名称,用于标识组件的唯一性
|
|
7
|
+
* 在构建时根据当前组件目录名称自动生成
|
|
8
|
+
*/
|
|
9
|
+
// cmpType: string = 'object-card-list';
|
|
10
|
+
|
|
11
|
+
// 组件名称,用于设置在编辑器左侧组件面板中展示的名称
|
|
12
|
+
label: string = '数据卡片列表';
|
|
13
|
+
|
|
14
|
+
// 组件描述,用于设置在编辑器左侧组件面板中展示的描述
|
|
15
|
+
description: string = '展示数据信息的卡片列表组件,支持姓名和手机号展示';
|
|
16
|
+
|
|
17
|
+
// 分类标签,用于设置在编辑器左侧组件面板哪个分类中展示(可设置多个分类标签)
|
|
18
|
+
tags: string[] = ['自定义组件'];
|
|
19
|
+
|
|
20
|
+
// 组件图标,用于设置在编辑器左侧组件面板中展示的图标
|
|
21
|
+
iconSrc: string = 'https://custom-widgets.bj.bcebos.com/data-list.svg';
|
|
22
|
+
|
|
23
|
+
// 初次插入页面的默认属性数据
|
|
24
|
+
defaultComProps = {
|
|
25
|
+
title: '数据卡片列表',
|
|
26
|
+
label: '数据卡片列表',
|
|
27
|
+
xObjectDataApi: {
|
|
28
|
+
xObjectApiKey: 'customContact__c',
|
|
29
|
+
fields: ['id', 'name', 'phone__c'],
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// 设计器端预览时展示的默认数据
|
|
34
|
+
previewComProps = {
|
|
35
|
+
label: '数据卡片列表',
|
|
36
|
+
title: '数据卡片列表',
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 组件面板配置,用于生成编辑器右侧属性配置面板内容
|
|
41
|
+
*/
|
|
42
|
+
propsSchema = [
|
|
43
|
+
{
|
|
44
|
+
type: 'textarea',
|
|
45
|
+
name: 'title',
|
|
46
|
+
label: '组件标题',
|
|
47
|
+
value: '数据卡片列表',
|
|
48
|
+
placeholder: '请输入组件标题',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'xObjectDataApi', // 用于获取实体业务数据列表的配置项
|
|
52
|
+
name: 'xObjectDataApi',
|
|
53
|
+
label: '实体数据源',
|
|
54
|
+
placeholder: '请选择实体数据源',
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
// 支持 函数式写法:propsSchemaCreator,com 为组件实例。优先级比 propsSchema 高
|
|
59
|
+
/*
|
|
60
|
+
propsSchemaCreator = (com: any) => {
|
|
61
|
+
return [];
|
|
62
|
+
};
|
|
63
|
+
*/
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default ObjectCardListModel;
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
.object-card-list-container {
|
|
2
|
+
position: relative;
|
|
3
|
+
box-sizing: border-box;
|
|
4
|
+
height: 100%;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
margin: 6px 12px;
|
|
8
|
+
padding: 12px;
|
|
9
|
+
background-color: #fff;
|
|
10
|
+
border-radius: 8px;
|
|
11
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
12
|
+
|
|
13
|
+
.card-list-header {
|
|
14
|
+
flex-shrink: 0;
|
|
15
|
+
margin-bottom: 16px;
|
|
16
|
+
border-bottom: 1px solid #f0f0f0;
|
|
17
|
+
padding-bottom: 12px;
|
|
18
|
+
|
|
19
|
+
.header-content {
|
|
20
|
+
display: flex;
|
|
21
|
+
justify-content: space-between;
|
|
22
|
+
align-items: center;
|
|
23
|
+
gap: 16px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.header-title {
|
|
27
|
+
margin: 0;
|
|
28
|
+
font-family: PingFangSC-Medium, -apple-system, BlinkMacSystemFont,
|
|
29
|
+
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
30
|
+
font-size: 18px;
|
|
31
|
+
font-weight: 500;
|
|
32
|
+
line-height: 1.4;
|
|
33
|
+
color: #262626;
|
|
34
|
+
flex: 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.refresh-button {
|
|
38
|
+
flex-shrink: 0;
|
|
39
|
+
border-radius: 6px;
|
|
40
|
+
font-size: 13px;
|
|
41
|
+
height: 32px;
|
|
42
|
+
padding: 4px 12px;
|
|
43
|
+
box-shadow: 0 2px 4px rgba(24, 144, 255, 0.2);
|
|
44
|
+
transition: all 0.3s ease;
|
|
45
|
+
|
|
46
|
+
&:hover {
|
|
47
|
+
box-shadow: 0 4px 8px rgba(24, 144, 255, 0.3);
|
|
48
|
+
transform: translateY(-1px);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
&:active {
|
|
52
|
+
transform: translateY(0);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.anticon {
|
|
56
|
+
font-size: 12px;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.card-list-content {
|
|
62
|
+
flex: 1;
|
|
63
|
+
overflow-y: auto;
|
|
64
|
+
|
|
65
|
+
.error-container {
|
|
66
|
+
display: flex;
|
|
67
|
+
justify-content: center;
|
|
68
|
+
align-items: center;
|
|
69
|
+
min-height: 300px;
|
|
70
|
+
padding: 20px;
|
|
71
|
+
|
|
72
|
+
.retry-button {
|
|
73
|
+
padding: 8px 16px;
|
|
74
|
+
background-color: #1890ff;
|
|
75
|
+
color: white;
|
|
76
|
+
border: none;
|
|
77
|
+
border-radius: 4px;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
font-size: 14px;
|
|
80
|
+
transition: background-color 0.3s;
|
|
81
|
+
|
|
82
|
+
&:hover {
|
|
83
|
+
background-color: #40a9ff;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
&:active {
|
|
87
|
+
background-color: #096dd9;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.object-card {
|
|
94
|
+
height: 100%;
|
|
95
|
+
border-radius: 12px;
|
|
96
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
|
97
|
+
transition: all 0.3s ease;
|
|
98
|
+
border: 1px solid #f0f0f0;
|
|
99
|
+
|
|
100
|
+
&:hover {
|
|
101
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
|
102
|
+
transform: translateY(-2px);
|
|
103
|
+
border-color: #d9d9d9;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.ant-card-body {
|
|
107
|
+
padding: 16px;
|
|
108
|
+
height: 100%;
|
|
109
|
+
display: flex;
|
|
110
|
+
align-items: center;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.object-card-content {
|
|
114
|
+
display: flex;
|
|
115
|
+
align-items: center;
|
|
116
|
+
width: 100%;
|
|
117
|
+
gap: 12px;
|
|
118
|
+
|
|
119
|
+
.object-avatar {
|
|
120
|
+
flex-shrink: 0;
|
|
121
|
+
|
|
122
|
+
.avatar-icon {
|
|
123
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
124
|
+
border: 2px solid #fff;
|
|
125
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.object-info {
|
|
130
|
+
flex: 1;
|
|
131
|
+
min-width: 0;
|
|
132
|
+
|
|
133
|
+
.object-name,
|
|
134
|
+
.object-phone {
|
|
135
|
+
display: flex;
|
|
136
|
+
align-items: center;
|
|
137
|
+
margin-bottom: 4px;
|
|
138
|
+
gap: 6px;
|
|
139
|
+
|
|
140
|
+
&:last-child {
|
|
141
|
+
margin-bottom: 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.info-icon {
|
|
145
|
+
font-size: 12px;
|
|
146
|
+
color: #8c8c8c;
|
|
147
|
+
flex-shrink: 0;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.name-text,
|
|
151
|
+
.phone-text {
|
|
152
|
+
font-size: 14px;
|
|
153
|
+
line-height: 1.4;
|
|
154
|
+
overflow: hidden;
|
|
155
|
+
text-overflow: ellipsis;
|
|
156
|
+
white-space: nowrap;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.name-text {
|
|
160
|
+
color: #262626;
|
|
161
|
+
font-weight: 500;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.phone-text {
|
|
165
|
+
color: #595959;
|
|
166
|
+
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo,
|
|
167
|
+
Courier, monospace;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.object-name {
|
|
172
|
+
margin-bottom: 8px;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 响应式设计
|
|
179
|
+
@media (max-width: 768px) {
|
|
180
|
+
margin: 4px 8px;
|
|
181
|
+
padding: 8px;
|
|
182
|
+
|
|
183
|
+
.card-list-header {
|
|
184
|
+
margin-bottom: 12px;
|
|
185
|
+
padding-bottom: 8px;
|
|
186
|
+
|
|
187
|
+
.header-content {
|
|
188
|
+
gap: 12px;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.header-title {
|
|
192
|
+
font-size: 16px;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.refresh-button {
|
|
196
|
+
height: 28px;
|
|
197
|
+
padding: 2px 8px;
|
|
198
|
+
font-size: 12px;
|
|
199
|
+
|
|
200
|
+
.anticon {
|
|
201
|
+
font-size: 11px;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.object-card {
|
|
207
|
+
.ant-card-body {
|
|
208
|
+
padding: 12px;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.object-card-content {
|
|
212
|
+
gap: 8px;
|
|
213
|
+
|
|
214
|
+
.object-avatar {
|
|
215
|
+
.avatar-icon {
|
|
216
|
+
width: 40px !important;
|
|
217
|
+
height: 40px !important;
|
|
218
|
+
line-height: 40px !important;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.object-info {
|
|
223
|
+
.object-name,
|
|
224
|
+
.object-phone {
|
|
225
|
+
.name-text,
|
|
226
|
+
.phone-text {
|
|
227
|
+
font-size: 13px;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@media (max-width: 480px) {
|
|
236
|
+
.object-card {
|
|
237
|
+
.object-card-content {
|
|
238
|
+
flex-direction: column;
|
|
239
|
+
text-align: center;
|
|
240
|
+
gap: 8px;
|
|
241
|
+
|
|
242
|
+
.object-info {
|
|
243
|
+
.object-name,
|
|
244
|
+
.object-phone {
|
|
245
|
+
justify-content: center;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// 全局样式覆盖
|
|
254
|
+
.ant-spin-container {
|
|
255
|
+
min-height: 200px;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.ant-empty {
|
|
259
|
+
padding: 40px 20px;
|
|
260
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# XObject 数据表格组件
|
|
2
|
-
基于 XObject 的数据表格组件,支持增删改查操作,表格列根据 `
|
|
2
|
+
基于 XObject 的数据表格组件,支持增删改查操作,表格列根据 `xObject.getDesc` 返回的 fields 动态生成。
|
|
3
|
+
备注:使用 Neo Open API SDK(neo-open-api) 提供的方法实现数据对象的增删改查相关操作。
|
|
3
4
|
|
|
4
5
|
## 功能特性
|
|
5
6
|
|
|
@@ -58,20 +59,11 @@ import XObjectTable from './components/xobject-table';
|
|
|
58
59
|
- **React**:前端框架
|
|
59
60
|
- **TypeScript**:类型支持
|
|
60
61
|
|
|
61
|
-
### 主要方法
|
|
62
|
-
|
|
63
|
-
- `getXObjectDesc()`:获取 XObject 字段描述
|
|
64
|
-
- `getEntityList()`:获取实体列表
|
|
65
|
-
- `queryXObjectData()`:查询数据列表
|
|
66
|
-
- `createXObject()`:创建数据记录
|
|
67
|
-
- `updateXObject()`:更新数据记录
|
|
68
|
-
- `deleteXObject()`:删除数据记录
|
|
69
|
-
|
|
70
62
|
### 数据流程
|
|
71
63
|
|
|
72
64
|
1. **初始化**:组件挂载时获取实体列表和字段描述
|
|
73
65
|
2. **列生成**:根据字段描述动态生成表格列
|
|
74
|
-
3. **数据加载**:使用 `
|
|
66
|
+
3. **数据加载**:使用 `xObject.query` 获取数据列表
|
|
75
67
|
4. **操作处理**:通过对应的 API 方法处理增删改操作
|
|
76
68
|
|
|
77
69
|
## 样式定制
|
|
@@ -29,14 +29,8 @@ import {
|
|
|
29
29
|
ReloadOutlined,
|
|
30
30
|
} from '@ant-design/icons';
|
|
31
31
|
import moment from 'moment';
|
|
32
|
-
|
|
33
|
-
import {
|
|
34
|
-
getEntityTypeList,
|
|
35
|
-
getXObjectDesc,
|
|
36
|
-
createXObject,
|
|
37
|
-
updateXObject,
|
|
38
|
-
deleteXObject,
|
|
39
|
-
} from '$utils/xobjects';
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
import { xObject } from 'neo-open-api'; // Neo Open API
|
|
40
34
|
import './style.scss';
|
|
41
35
|
|
|
42
36
|
const { Option } = Select;
|
|
@@ -46,7 +40,10 @@ const { Option } = Select;
|
|
|
46
40
|
*/
|
|
47
41
|
interface XObjectTableProps {
|
|
48
42
|
/** XObject 实体对象的 API Key,用于标识要操作的数据对象 */
|
|
49
|
-
|
|
43
|
+
xObjectDataApi: {
|
|
44
|
+
xObjectApiKey: string;
|
|
45
|
+
fields: string[];
|
|
46
|
+
};
|
|
50
47
|
/** Neo 平台传递的数据,包含系统信息等 */
|
|
51
48
|
data?: any;
|
|
52
49
|
/** 是否显示新增按钮 */
|
|
@@ -87,6 +84,7 @@ interface FieldInfo {
|
|
|
87
84
|
interface XObjectTableState {
|
|
88
85
|
/** 表格标题 */
|
|
89
86
|
title?: string;
|
|
87
|
+
fieldList: FieldInfo[];
|
|
90
88
|
/** 表格数据源 */
|
|
91
89
|
dataSource: any[];
|
|
92
90
|
/** 加载状态 */
|
|
@@ -109,8 +107,6 @@ interface XObjectTableState {
|
|
|
109
107
|
form: any;
|
|
110
108
|
/** 业务类型列表 */
|
|
111
109
|
entityTypeList: any[];
|
|
112
|
-
/** 字段列表 */
|
|
113
|
-
fieldList: FieldInfo[];
|
|
114
110
|
}
|
|
115
111
|
|
|
116
112
|
/**
|
|
@@ -123,9 +119,12 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
123
119
|
> {
|
|
124
120
|
constructor(props: XObjectTableProps) {
|
|
125
121
|
super(props);
|
|
122
|
+
const { xObjectDataApi } = props;
|
|
123
|
+
const { xObjectApiKey, fields } = xObjectDataApi || {};
|
|
126
124
|
|
|
127
125
|
// 初始化组件状态
|
|
128
126
|
this.state = {
|
|
127
|
+
fieldList: [],
|
|
129
128
|
dataSource: [],
|
|
130
129
|
loading: false,
|
|
131
130
|
error: null,
|
|
@@ -138,21 +137,21 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
138
137
|
isEditMode: false,
|
|
139
138
|
editingRecord: null,
|
|
140
139
|
form: null,
|
|
141
|
-
fieldList: [],
|
|
142
140
|
entityTypeList: [],
|
|
143
141
|
};
|
|
144
142
|
|
|
145
|
-
if (
|
|
143
|
+
if (xObjectApiKey) {
|
|
146
144
|
// 初始化字段列表、加载数据和业务类型列表
|
|
147
|
-
this.
|
|
145
|
+
this.getEntityTypeList(xObjectApiKey);
|
|
146
|
+
this.loadFieldList(xObjectApiKey);
|
|
147
|
+
|
|
148
|
+
if (fields) {
|
|
148
149
|
this.loadData();
|
|
149
|
-
}
|
|
150
|
-
this.getEntityTypeList();
|
|
150
|
+
}
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
// 绑定方法上下文
|
|
154
154
|
this.loadData = this.loadData.bind(this);
|
|
155
|
-
this.loadFieldList = this.loadFieldList.bind(this);
|
|
156
155
|
this.handleAdd = this.handleAdd.bind(this);
|
|
157
156
|
this.handleEdit = this.handleEdit.bind(this);
|
|
158
157
|
this.handleDelete = this.handleDelete.bind(this);
|
|
@@ -161,52 +160,53 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
161
160
|
this.handleTableChange = this.handleTableChange.bind(this);
|
|
162
161
|
}
|
|
163
162
|
|
|
164
|
-
/**
|
|
165
|
-
* 获取业务类型列表
|
|
166
|
-
* 用于下拉选择框的选项数据
|
|
167
|
-
*/
|
|
168
|
-
getEntityTypeList() {
|
|
169
|
-
getEntityTypeList(this.props.xObjectApiKey).then((res: any) => {
|
|
170
|
-
if (res && res.code === '200') {
|
|
171
|
-
const result = res.data || {};
|
|
172
|
-
this.setState({
|
|
173
|
-
entityTypeList: result.records || [],
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
|
|
179
163
|
/**
|
|
180
164
|
* 组件更新后执行
|
|
181
165
|
* 当 xObjectApiKey 发生变化时重新加载数据
|
|
182
166
|
*/
|
|
183
167
|
async componentDidUpdate(prevProps: XObjectTableProps) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
168
|
+
const { xObjectApiKey } = this.props.xObjectDataApi || {};
|
|
169
|
+
const { xObjectApiKey: prevXObjectApiKey } = prevProps.xObjectDataApi || {};
|
|
170
|
+
if (xObjectApiKey !== prevXObjectApiKey) {
|
|
171
|
+
if (xObjectApiKey) {
|
|
187
172
|
this.loadData();
|
|
188
|
-
this.getEntityTypeList();
|
|
173
|
+
this.getEntityTypeList(xObjectApiKey);
|
|
174
|
+
this.loadFieldList(xObjectApiKey);
|
|
189
175
|
} else {
|
|
190
176
|
this.setState({
|
|
191
177
|
dataSource: [],
|
|
192
|
-
fieldList: [],
|
|
193
178
|
});
|
|
194
179
|
}
|
|
195
180
|
}
|
|
196
181
|
}
|
|
197
182
|
|
|
183
|
+
/**
|
|
184
|
+
* 获取业务类型列表
|
|
185
|
+
* 用于下拉选择框的选项数据
|
|
186
|
+
*/
|
|
187
|
+
async getEntityTypeList(xObjectApiKey?: string) {
|
|
188
|
+
const { xObjectDataApi } = this.props;
|
|
189
|
+
const curXObjectApiKey = xObjectApiKey || xObjectDataApi?.xObjectApiKey;
|
|
190
|
+
const result = await xObject.getEntityTypeList(curXObjectApiKey);
|
|
191
|
+
if (result && result.status) {
|
|
192
|
+
const records = result.data || [];
|
|
193
|
+
this.setState({
|
|
194
|
+
entityTypeList: records,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
198
199
|
/**
|
|
199
200
|
* 加载字段列表
|
|
200
201
|
* 从 Neo 平台获取 XObject 的字段描述信息
|
|
201
202
|
*/
|
|
202
|
-
async loadFieldList() {
|
|
203
|
-
const { xObjectApiKey } = this.props;
|
|
203
|
+
async loadFieldList(xObjectApiKey?: string) {
|
|
204
204
|
if (!xObjectApiKey) return;
|
|
205
205
|
|
|
206
206
|
try {
|
|
207
|
-
const
|
|
208
|
-
if (
|
|
209
|
-
const result =
|
|
207
|
+
const resultData = await xObject.getDesc(xObjectApiKey);
|
|
208
|
+
if (resultData && resultData.status) {
|
|
209
|
+
const result = resultData.data || {};
|
|
210
210
|
const fieldList = result.fields || [];
|
|
211
211
|
this.setState({ fieldList, title: result.label });
|
|
212
212
|
}
|
|
@@ -218,13 +218,20 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
218
218
|
|
|
219
219
|
/**
|
|
220
220
|
* 生成表格列配置
|
|
221
|
-
* @param _fieldList 字段列表,可选参数
|
|
222
221
|
* @returns 表格列配置数组
|
|
223
222
|
*/
|
|
224
|
-
generateColumns(
|
|
225
|
-
const { showEditButton, showDeleteButton } = this.props;
|
|
223
|
+
generateColumns() {
|
|
224
|
+
const { showEditButton, showDeleteButton, xObjectDataApi } = this.props;
|
|
226
225
|
const { fieldList } = this.state;
|
|
227
|
-
const
|
|
226
|
+
const { fields } = xObjectDataApi || {};
|
|
227
|
+
let curFieldList = fieldList;
|
|
228
|
+
|
|
229
|
+
if (fields && fields.length > 0) {
|
|
230
|
+
// 如果 fields 存在,则过滤掉 fieldList 中不存在的字段
|
|
231
|
+
curFieldList = curFieldList.filter((field) =>
|
|
232
|
+
fields.includes(field.apiKey),
|
|
233
|
+
);
|
|
234
|
+
}
|
|
228
235
|
|
|
229
236
|
// 根据字段列表生成基础列配置
|
|
230
237
|
const columns: any[] = curFieldList.map((field) => ({
|
|
@@ -285,15 +292,14 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
285
292
|
* @param pageSize 每页条数,默认为 10
|
|
286
293
|
*/
|
|
287
294
|
async loadData(page = 1, pageSize = 10) {
|
|
288
|
-
const { xObjectApiKey } = this.props;
|
|
295
|
+
const { xObjectApiKey, fields } = this.props.xObjectDataApi || {};
|
|
289
296
|
if (!xObjectApiKey) return;
|
|
290
297
|
|
|
291
298
|
this.setState({ loading: true, error: null });
|
|
292
299
|
|
|
293
300
|
try {
|
|
294
|
-
// 获取所有字段的 API Key
|
|
295
|
-
const
|
|
296
|
-
const result = await queryXObjectData({
|
|
301
|
+
// 获取所有字段的 API Key=
|
|
302
|
+
const result = await xObject.query({
|
|
297
303
|
xObjectApiKey,
|
|
298
304
|
fields,
|
|
299
305
|
page,
|
|
@@ -356,11 +362,11 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
356
362
|
* @param id 要删除的记录 ID
|
|
357
363
|
*/
|
|
358
364
|
async handleDelete(id: string) {
|
|
359
|
-
const { xObjectApiKey } = this.props;
|
|
365
|
+
const { xObjectApiKey } = this.props.xObjectDataApi || {};
|
|
360
366
|
if (!xObjectApiKey) return;
|
|
361
367
|
|
|
362
368
|
try {
|
|
363
|
-
const response = await
|
|
369
|
+
const response = await xObject.delete(xObjectApiKey, id);
|
|
364
370
|
if (response && (response.code === 200 || response.code === '200')) {
|
|
365
371
|
message.success('删除成功');
|
|
366
372
|
// 删除成功后重新加载当前页数据
|
|
@@ -383,7 +389,8 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
383
389
|
*/
|
|
384
390
|
handleModalOk() {
|
|
385
391
|
this.state.form?.validateFields().then(async (values: any) => {
|
|
386
|
-
const { xObjectApiKey } =
|
|
392
|
+
const { xObjectApiKey, fields: fieldList } =
|
|
393
|
+
this.props.xObjectDataApi || {};
|
|
387
394
|
const { isEditMode, editingRecord } = this.state;
|
|
388
395
|
|
|
389
396
|
try {
|
|
@@ -405,13 +412,13 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
405
412
|
values[fieldKey] = new Date(values[fieldKey]).getTime();
|
|
406
413
|
}
|
|
407
414
|
});
|
|
408
|
-
response = await
|
|
415
|
+
response = await xObject.update(xObjectApiKey, editingRecord.id, {
|
|
409
416
|
data: values,
|
|
410
417
|
method: 'PATCH',
|
|
411
418
|
});
|
|
412
419
|
} else {
|
|
413
420
|
// 新增模式:创建新记录
|
|
414
|
-
response = await
|
|
421
|
+
response = await xObject.create(xObjectApiKey, {
|
|
415
422
|
data: values,
|
|
416
423
|
method: 'POST',
|
|
417
424
|
});
|
|
@@ -463,8 +470,18 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
463
470
|
* @returns 表单 JSX 元素
|
|
464
471
|
*/
|
|
465
472
|
renderForm() {
|
|
466
|
-
const {
|
|
467
|
-
|
|
473
|
+
const {
|
|
474
|
+
fieldList: _fieldList,
|
|
475
|
+
isEditMode,
|
|
476
|
+
editingRecord,
|
|
477
|
+
entityTypeList,
|
|
478
|
+
} = this.state;
|
|
479
|
+
const { xObjectApiKey, fields } = this.props.xObjectDataApi || {};
|
|
480
|
+
let fieldList = _fieldList;
|
|
481
|
+
|
|
482
|
+
if (fields && fields.length > 0) {
|
|
483
|
+
fieldList = fieldList.filter((field) => fields.includes(field.apiKey));
|
|
484
|
+
}
|
|
468
485
|
|
|
469
486
|
// 如果没有选择对象,显示提示信息
|
|
470
487
|
if (!xObjectApiKey) {
|
|
@@ -642,6 +659,7 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
642
659
|
} = this.state;
|
|
643
660
|
const curAmisData = this.props.data || {};
|
|
644
661
|
const systemInfo = curAmisData.__NeoSystemInfo || {};
|
|
662
|
+
const { xObjectApiKey } = this.props.xObjectDataApi || {};
|
|
645
663
|
const columns = this.generateColumns();
|
|
646
664
|
|
|
647
665
|
return (
|
|
@@ -659,7 +677,7 @@ export default class XObjectTable extends React.PureComponent<
|
|
|
659
677
|
type="primary"
|
|
660
678
|
icon={<PlusOutlined />}
|
|
661
679
|
onClick={this.handleAdd}
|
|
662
|
-
disabled={!
|
|
680
|
+
disabled={!xObjectApiKey}
|
|
663
681
|
>
|
|
664
682
|
新增
|
|
665
683
|
</Button>
|
|
@@ -27,17 +27,22 @@ export class XObjectTableModel {
|
|
|
27
27
|
/** 初次插入页面的默认属性数据 */
|
|
28
28
|
defaultComProps = {
|
|
29
29
|
title: '实体数据表格',
|
|
30
|
-
xObjectApiKey: 'account',
|
|
31
30
|
showAddButton: true,
|
|
32
31
|
showEditButton: true,
|
|
33
32
|
showDeleteButton: true,
|
|
34
|
-
|
|
33
|
+
xObjectDataApi: {
|
|
34
|
+
xObjectApiKey: 'customContact__c',
|
|
35
|
+
fields: ['id', 'name', 'phone__c'],
|
|
36
|
+
},
|
|
35
37
|
};
|
|
36
38
|
|
|
37
39
|
/** 设计器端预览时展示的默认数据 */
|
|
38
40
|
previewComProps = {
|
|
39
41
|
title: '实体数据表格',
|
|
40
|
-
|
|
42
|
+
xObjectDataApi: {
|
|
43
|
+
xObjectApiKey: 'customContact__c',
|
|
44
|
+
fields: ['id', 'name', 'phone__c'],
|
|
45
|
+
},
|
|
41
46
|
};
|
|
42
47
|
|
|
43
48
|
/**
|
|
@@ -46,6 +51,7 @@ export class XObjectTableModel {
|
|
|
46
51
|
* 定义组件在编辑器中可配置的属性
|
|
47
52
|
*/
|
|
48
53
|
propsSchema = [
|
|
54
|
+
/*
|
|
49
55
|
{
|
|
50
56
|
type: 'select',
|
|
51
57
|
name: 'custom',
|
|
@@ -87,6 +93,18 @@ export class XObjectTableModel {
|
|
|
87
93
|
value: 'account',
|
|
88
94
|
placeholder: '请选择要操作的实体对象',
|
|
89
95
|
},
|
|
96
|
+
*/
|
|
97
|
+
{
|
|
98
|
+
type: 'xObjectDataApi', // 用于获取实体业务数据列表的配置项
|
|
99
|
+
name: 'xObjectDataApi',
|
|
100
|
+
label: '实体数据源',
|
|
101
|
+
value: {
|
|
102
|
+
xObjectApiKey: 'customContact__c',
|
|
103
|
+
fields: ['id', 'name', 'phone__c'],
|
|
104
|
+
},
|
|
105
|
+
placeholder: '请选择实体数据源',
|
|
106
|
+
custom: true,
|
|
107
|
+
},
|
|
90
108
|
{
|
|
91
109
|
type: 'switch',
|
|
92
110
|
name: 'showAddButton',
|