neo-cmp-cli 1.8.3 → 1.8.6

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 (189) hide show
  1. package/package.json +3 -3
  2. package/src/utils/cmpUtils/createCmpByTemplate.js +1 -1
  3. package/src/utils/projectUtils/createCmpProjectByTemplate.js +1 -1
  4. package/template/antd-custom-cmp-template/.prettierrc.js +12 -0
  5. package/template/antd-custom-cmp-template/README.md +153 -0
  6. package/template/antd-custom-cmp-template/commitlint.config.js +59 -0
  7. package/template/antd-custom-cmp-template/neo.config.js +144 -0
  8. package/template/antd-custom-cmp-template/package.json +60 -0
  9. package/template/antd-custom-cmp-template/public/css/base.css +283 -0
  10. package/template/antd-custom-cmp-template/public/scripts/app/bluebird.js +6679 -0
  11. package/template/antd-custom-cmp-template/public/template.html +13 -0
  12. package/template/antd-custom-cmp-template/src/assets/css/common.scss +127 -0
  13. package/template/antd-custom-cmp-template/src/assets/css/mixin.scss +47 -0
  14. package/template/antd-custom-cmp-template/src/assets/img/NeoCRM.jpg +0 -0
  15. package/template/antd-custom-cmp-template/src/assets/img/custom-widget.svg +1 -0
  16. package/template/antd-custom-cmp-template/src/assets/img/favicon.png +0 -0
  17. package/template/antd-custom-cmp-template/src/components/dataDashboard/README.md +39 -0
  18. package/template/antd-custom-cmp-template/src/components/dataDashboard/index.tsx +462 -0
  19. package/template/antd-custom-cmp-template/src/components/dataDashboard/model.ts +75 -0
  20. package/template/antd-custom-cmp-template/src/components/dataDashboard/style.scss +1667 -0
  21. package/template/antd-custom-cmp-template/src/components/infoCard/index.tsx +87 -0
  22. package/template/antd-custom-cmp-template/src/components/infoCard/model.ts +80 -0
  23. package/template/antd-custom-cmp-template/src/components/infoCard/style.scss +105 -0
  24. package/template/antd-custom-cmp-template/tsconfig.json +68 -0
  25. package/template/develop/neo-custom-cmp-template/.prettierrc.js +12 -0
  26. package/template/develop/neo-custom-cmp-template/README.md +48 -0
  27. package/template/develop/neo-custom-cmp-template/commitlint.config.js +59 -0
  28. package/template/develop/neo-custom-cmp-template/docs/README.md +13 -0
  29. package/template/develop/neo-custom-cmp-template/neo.config.js +121 -0
  30. package/template/develop/neo-custom-cmp-template/package.json +63 -0
  31. package/template/develop/neo-custom-cmp-template/public/css/base.css +283 -0
  32. package/template/develop/neo-custom-cmp-template/public/scripts/app/bluebird.js +6679 -0
  33. package/template/develop/neo-custom-cmp-template/public/template.html +13 -0
  34. package/template/develop/neo-custom-cmp-template/src/assets/css/common.scss +127 -0
  35. package/template/develop/neo-custom-cmp-template/src/assets/css/mixin.scss +47 -0
  36. package/template/develop/neo-custom-cmp-template/src/assets/img/NeoCRM.jpg +0 -0
  37. package/template/develop/neo-custom-cmp-template/src/assets/img/custom-widget.svg +1 -0
  38. package/template/develop/neo-custom-cmp-template/src/assets/img/favicon.png +0 -0
  39. package/template/develop/neo-custom-cmp-template/src/assets/img/table.svg +1 -0
  40. package/template/develop/neo-custom-cmp-template/src/components/contactCardList/README.md +65 -0
  41. package/template/develop/neo-custom-cmp-template/src/components/contactCardList/index.tsx +180 -0
  42. package/template/develop/neo-custom-cmp-template/src/components/contactCardList/model.ts +50 -0
  43. package/template/develop/neo-custom-cmp-template/src/components/contactCardList/style.scss +260 -0
  44. package/template/develop/neo-custom-cmp-template/src/components/contactForm/README.md +94 -0
  45. package/template/develop/neo-custom-cmp-template/src/components/contactForm/index.tsx +251 -0
  46. package/template/develop/neo-custom-cmp-template/src/components/contactForm/model.ts +56 -0
  47. package/template/develop/neo-custom-cmp-template/src/components/contactForm/style.scss +120 -0
  48. package/template/develop/neo-custom-cmp-template/src/components/neoEntityGrid/README.md +115 -0
  49. package/template/develop/neo-custom-cmp-template/src/components/neoEntityGrid/index.tsx +304 -0
  50. package/template/develop/neo-custom-cmp-template/src/components/neoEntityGrid/model.ts +87 -0
  51. package/template/develop/neo-custom-cmp-template/src/components/neoEntityGrid/style.scss +127 -0
  52. package/template/develop/neo-custom-cmp-template/src/utils/axiosFetcher.ts +29 -0
  53. package/template/develop/neo-custom-cmp-template/src/utils/queryObjectData.ts +39 -0
  54. package/template/develop/neo-custom-cmp-template/src/utils/xobjects.ts +203 -0
  55. package/template/develop/neo-custom-cmp-template/tsconfig.json +68 -0
  56. package/template/echarts-custom-cmp-template/.prettierrc.js +12 -0
  57. package/template/echarts-custom-cmp-template/README.md +198 -0
  58. package/template/echarts-custom-cmp-template/commitlint.config.js +59 -0
  59. package/template/echarts-custom-cmp-template/neo.config.js +140 -0
  60. package/template/echarts-custom-cmp-template/package.json +61 -0
  61. package/template/echarts-custom-cmp-template/public/css/base.css +283 -0
  62. package/template/echarts-custom-cmp-template/public/scripts/app/bluebird.js +6679 -0
  63. package/template/echarts-custom-cmp-template/public/template.html +13 -0
  64. package/template/echarts-custom-cmp-template/src/assets/css/common.scss +127 -0
  65. package/template/echarts-custom-cmp-template/src/assets/css/mixin.scss +47 -0
  66. package/template/echarts-custom-cmp-template/src/assets/img/NeoCRM.jpg +0 -0
  67. package/template/echarts-custom-cmp-template/src/assets/img/chart.svg +1 -0
  68. package/template/echarts-custom-cmp-template/src/assets/img/custom-widget.svg +1 -0
  69. package/template/echarts-custom-cmp-template/src/assets/img/favicon.png +0 -0
  70. package/template/echarts-custom-cmp-template/src/components/chartWidget/README.md +186 -0
  71. package/template/echarts-custom-cmp-template/src/components/chartWidget/index.tsx +724 -0
  72. package/template/echarts-custom-cmp-template/src/components/chartWidget/model.ts +151 -0
  73. package/template/echarts-custom-cmp-template/src/components/chartWidget/style.scss +209 -0
  74. package/template/echarts-custom-cmp-template/src/components/mapWidget/README.md +125 -0
  75. package/template/echarts-custom-cmp-template/src/components/mapWidget/USAGE.md +190 -0
  76. package/template/echarts-custom-cmp-template/src/components/mapWidget/index.tsx +385 -0
  77. package/template/echarts-custom-cmp-template/src/components/mapWidget/model.ts +107 -0
  78. package/template/echarts-custom-cmp-template/src/components/mapWidget/style.scss +192 -0
  79. package/template/echarts-custom-cmp-template/src/utils/url.ts +82 -0
  80. package/template/echarts-custom-cmp-template/tsconfig.json +68 -0
  81. package/template/empty-cmp/index.tsx +58 -0
  82. package/template/empty-cmp/model.ts +79 -0
  83. package/template/empty-cmp/style.scss +72 -0
  84. package/template/empty-custom-cmp-template/.prettierrc.js +12 -0
  85. package/template/empty-custom-cmp-template/README.md +154 -0
  86. package/template/empty-custom-cmp-template/commitlint.config.js +59 -0
  87. package/template/empty-custom-cmp-template/neo.config.js +138 -0
  88. package/template/empty-custom-cmp-template/package.json +58 -0
  89. package/template/empty-custom-cmp-template/public/css/base.css +283 -0
  90. package/template/empty-custom-cmp-template/public/scripts/app/bluebird.js +6679 -0
  91. package/template/empty-custom-cmp-template/public/template.html +13 -0
  92. package/template/empty-custom-cmp-template/src/assets/css/common.scss +127 -0
  93. package/template/empty-custom-cmp-template/src/assets/css/mixin.scss +47 -0
  94. package/template/empty-custom-cmp-template/src/assets/img/NeoCRM.jpg +0 -0
  95. package/template/empty-custom-cmp-template/src/assets/img/custom-widget.svg +1 -0
  96. package/template/empty-custom-cmp-template/src/assets/img/favicon.png +0 -0
  97. package/template/empty-custom-cmp-template/src/assets/img/map.svg +1 -0
  98. package/template/empty-custom-cmp-template/src/components/README.md +3 -0
  99. package/template/empty-custom-cmp-template/tsconfig.json +68 -0
  100. package/template/neo-custom-cmp-template/.prettierrc.js +12 -0
  101. package/template/neo-custom-cmp-template/README.md +155 -0
  102. package/template/neo-custom-cmp-template/commitlint.config.js +59 -0
  103. package/template/neo-custom-cmp-template/docs/README.md +244 -0
  104. package/template/neo-custom-cmp-template/neo.config.js +140 -0
  105. package/template/neo-custom-cmp-template/package.json +66 -0
  106. package/template/neo-custom-cmp-template/public/css/base.css +283 -0
  107. package/template/neo-custom-cmp-template/public/scripts/app/bluebird.js +6679 -0
  108. package/template/neo-custom-cmp-template/public/template.html +13 -0
  109. package/template/neo-custom-cmp-template/src/assets/css/common.scss +127 -0
  110. package/template/neo-custom-cmp-template/src/assets/css/mixin.scss +47 -0
  111. package/template/neo-custom-cmp-template/src/assets/img/NeoCRM.jpg +0 -0
  112. package/template/neo-custom-cmp-template/src/assets/img/card-list.svg +1 -0
  113. package/template/neo-custom-cmp-template/src/assets/img/contact-form.svg +1 -0
  114. package/template/neo-custom-cmp-template/src/assets/img/custom-form.svg +1 -0
  115. package/template/neo-custom-cmp-template/src/assets/img/custom-widget.svg +1 -0
  116. package/template/neo-custom-cmp-template/src/assets/img/data-list.svg +1 -0
  117. package/template/neo-custom-cmp-template/src/assets/img/detail.svg +1 -0
  118. package/template/neo-custom-cmp-template/src/assets/img/table.svg +1 -0
  119. package/template/neo-custom-cmp-template/src/components/entityCardList/README.md +61 -0
  120. package/template/neo-custom-cmp-template/src/components/entityCardList/index.tsx +202 -0
  121. package/template/neo-custom-cmp-template/src/components/entityCardList/model.ts +74 -0
  122. package/template/neo-custom-cmp-template/src/components/entityCardList/style.scss +260 -0
  123. package/template/neo-custom-cmp-template/src/components/entityDetail/README.md +176 -0
  124. package/template/neo-custom-cmp-template/src/components/entityDetail/index.tsx +334 -0
  125. package/template/neo-custom-cmp-template/src/components/entityDetail/model.ts +123 -0
  126. package/template/neo-custom-cmp-template/src/components/entityDetail/style.scss +292 -0
  127. package/template/neo-custom-cmp-template/src/components/entityForm/README.md +176 -0
  128. package/template/neo-custom-cmp-template/src/components/entityForm/index.tsx +615 -0
  129. package/template/neo-custom-cmp-template/src/components/entityForm/model.ts +107 -0
  130. package/template/neo-custom-cmp-template/src/components/entityForm/style.scss +370 -0
  131. package/template/neo-custom-cmp-template/src/components/entityTable/README.md +92 -0
  132. package/template/neo-custom-cmp-template/src/components/entityTable/index.tsx +784 -0
  133. package/template/neo-custom-cmp-template/src/components/entityTable/model.ts +134 -0
  134. package/template/neo-custom-cmp-template/src/components/entityTable/style.scss +304 -0
  135. package/template/neo-custom-cmp-template/src/utils/axiosFetcher.ts +37 -0
  136. package/template/neo-custom-cmp-template/src/utils/queryObjectData.ts +76 -0
  137. package/template/neo-custom-cmp-template/src/utils/xobjects.ts +162 -0
  138. package/template/neo-custom-cmp-template/tsconfig.json +49 -0
  139. package/template/react-custom-cmp-template/.prettierrc.js +12 -0
  140. package/template/react-custom-cmp-template/README.md +154 -0
  141. package/template/react-custom-cmp-template/commitlint.config.js +59 -0
  142. package/template/react-custom-cmp-template/neo.config.js +137 -0
  143. package/template/react-custom-cmp-template/package.json +57 -0
  144. package/template/react-custom-cmp-template/public/css/base.css +283 -0
  145. package/template/react-custom-cmp-template/public/scripts/app/bluebird.js +6679 -0
  146. package/template/react-custom-cmp-template/public/template.html +13 -0
  147. package/template/react-custom-cmp-template/src/assets/css/common.scss +127 -0
  148. package/template/react-custom-cmp-template/src/assets/css/mixin.scss +47 -0
  149. package/template/react-custom-cmp-template/src/assets/img/NeoCRM.jpg +0 -0
  150. package/template/react-custom-cmp-template/src/assets/img/custom-widget.svg +1 -0
  151. package/template/react-custom-cmp-template/src/assets/img/favicon.png +0 -0
  152. package/template/react-custom-cmp-template/src/components/infoCard/index.jsx +45 -0
  153. package/template/react-custom-cmp-template/src/components/infoCard/model.js +81 -0
  154. package/template/react-custom-cmp-template/src/components/infoCard/style.scss +67 -0
  155. package/template/react-ts-custom-cmp-template/.prettierrc.js +12 -0
  156. package/template/react-ts-custom-cmp-template/README.md +154 -0
  157. package/template/react-ts-custom-cmp-template/commitlint.config.js +59 -0
  158. package/template/react-ts-custom-cmp-template/neo.config.js +138 -0
  159. package/template/react-ts-custom-cmp-template/package.json +59 -0
  160. package/template/react-ts-custom-cmp-template/public/css/base.css +283 -0
  161. package/template/react-ts-custom-cmp-template/public/scripts/app/bluebird.js +6679 -0
  162. package/template/react-ts-custom-cmp-template/public/template.html +13 -0
  163. package/template/react-ts-custom-cmp-template/src/assets/css/common.scss +127 -0
  164. package/template/react-ts-custom-cmp-template/src/assets/css/mixin.scss +47 -0
  165. package/template/react-ts-custom-cmp-template/src/assets/img/NeoCRM.jpg +0 -0
  166. package/template/react-ts-custom-cmp-template/src/assets/img/custom-widget.svg +1 -0
  167. package/template/react-ts-custom-cmp-template/src/assets/img/favicon.png +0 -0
  168. package/template/react-ts-custom-cmp-template/src/assets/img/map.svg +1 -0
  169. package/template/react-ts-custom-cmp-template/src/components/listWidget/README.md +2 -0
  170. package/template/react-ts-custom-cmp-template/src/components/listWidget/index.tsx +208 -0
  171. package/template/react-ts-custom-cmp-template/src/components/listWidget/model.ts +92 -0
  172. package/template/react-ts-custom-cmp-template/src/components/listWidget/style.scss +350 -0
  173. package/template/react-ts-custom-cmp-template/tsconfig.json +68 -0
  174. package/template/vue2-custom-cmp-template/.prettierrc.js +12 -0
  175. package/template/vue2-custom-cmp-template/README.md +154 -0
  176. package/template/vue2-custom-cmp-template/commitlint.config.js +59 -0
  177. package/template/vue2-custom-cmp-template/neo.config.js +146 -0
  178. package/template/vue2-custom-cmp-template/package.json +59 -0
  179. package/template/vue2-custom-cmp-template/public/css/base.css +283 -0
  180. package/template/vue2-custom-cmp-template/public/scripts/app/bluebird.js +6679 -0
  181. package/template/vue2-custom-cmp-template/public/template.html +13 -0
  182. package/template/vue2-custom-cmp-template/src/assets/css/common.scss +126 -0
  183. package/template/vue2-custom-cmp-template/src/assets/css/mixin.scss +47 -0
  184. package/template/vue2-custom-cmp-template/src/assets/img/NeoCRM.jpg +0 -0
  185. package/template/vue2-custom-cmp-template/src/assets/img/custom-widget.svg +1 -0
  186. package/template/vue2-custom-cmp-template/src/assets/img/favicon.png +0 -0
  187. package/template/vue2-custom-cmp-template/src/components/vueInfoCard/index.vue +131 -0
  188. package/template/vue2-custom-cmp-template/src/components/vueInfoCard/model.js +81 -0
  189. package/test/deprecate-versions.js +1 -1
@@ -0,0 +1,784 @@
1
+ /**
2
+ * @file XObject 数据表格组件
3
+ * @description 基于 Neo 平台的 XObject 实体对象数据表格组件,支持增删改查操作
4
+ */
5
+ import * as React from 'react';
6
+ import {
7
+ Table,
8
+ Button,
9
+ Space,
10
+ Modal,
11
+ Form,
12
+ Input,
13
+ Select,
14
+ message,
15
+ Popconfirm,
16
+ Spin,
17
+ Empty,
18
+ Card,
19
+ DatePicker,
20
+ InputNumber,
21
+ Checkbox,
22
+ Row,
23
+ Col,
24
+ } from 'antd';
25
+ import {
26
+ PlusOutlined,
27
+ EditOutlined,
28
+ DeleteOutlined,
29
+ ReloadOutlined,
30
+ } from '@ant-design/icons';
31
+ import moment from 'moment';
32
+ // @ts-ignore
33
+ import { xObject } from 'neo-open-api'; // Neo Open API
34
+ // @ts-ignore
35
+ import isEqual from 'lodash/isEqual';
36
+ import './style.scss';
37
+
38
+ const { Option } = Select;
39
+
40
+ /**
41
+ * 组件属性接口
42
+ */
43
+ interface EntityTableProps {
44
+ /** XObject 实体对象的 API Key,用于标识要操作的数据对象 */
45
+ xObjectDataApi: {
46
+ xObjectApiKey: string;
47
+ fields: string[];
48
+ fieldDescList?: any[];
49
+ pageSize?: number;
50
+ page?: number;
51
+ autoFetchData?: boolean;
52
+ };
53
+ /** Neo 平台传递的数据,包含系统信息等 */
54
+ data?: any;
55
+ entityData?: any; // Neo 平台自动获取的实体数据
56
+ /** 是否显示新增按钮 */
57
+ showAddButton?: boolean;
58
+ /** 是否显示编辑按钮 */
59
+ showEditButton?: boolean;
60
+ /** 是否显示删除按钮 */
61
+ showDeleteButton?: boolean;
62
+ /** 是否为自定义实体对象 */
63
+ custom?: boolean;
64
+ }
65
+
66
+ /**
67
+ * 字段信息接口
68
+ */
69
+ interface FieldInfo {
70
+ /** 字段名称 */
71
+ name: string;
72
+ /** 字段显示标签 */
73
+ label: string;
74
+ /** 字段 API Key */
75
+ apiKey: string;
76
+ /** 字段类型 */
77
+ type: string;
78
+ /** 字段项类型 */
79
+ itemType: string;
80
+ /** 复选框选项列表 */
81
+ checkitem: any[];
82
+ /** 下拉选择选项列表 */
83
+ selectitem?: any[];
84
+ /** 是否必填 */
85
+ required: boolean;
86
+ }
87
+
88
+ /**
89
+ * 组件状态接口
90
+ */
91
+ interface EntityTableState {
92
+ /** 表格标题 */
93
+ title?: string;
94
+ fieldList: FieldInfo[];
95
+ /** 表格数据源 */
96
+ dataSource: any[];
97
+ /** 加载状态 */
98
+ loading: boolean;
99
+ /** 错误信息 */
100
+ error: string | null;
101
+ /** 分页信息 */
102
+ pagination: {
103
+ current: number;
104
+ pageSize: number;
105
+ total: number;
106
+ };
107
+ /** 模态框是否可见 */
108
+ isModalVisible: boolean;
109
+ /** 是否为编辑模式 */
110
+ isEditMode: boolean;
111
+ /** 正在编辑的记录 */
112
+ editingRecord: any;
113
+ /** 表单实例 */
114
+ form: any;
115
+ /** 业务类型列表 */
116
+ entityTypeList: any[];
117
+ }
118
+
119
+ /**
120
+ * XObject 数据表格组件
121
+ * 支持对 Neo 平台的 XObject 实体对象进行增删改查操作
122
+ */
123
+ export default class EntityTable extends React.PureComponent<
124
+ EntityTableProps,
125
+ EntityTableState
126
+ > {
127
+ constructor(props: EntityTableProps) {
128
+ super(props);
129
+ const { xObjectDataApi } = this.props;
130
+ const { page, pageSize } = xObjectDataApi || {};
131
+
132
+ // 初始化组件状态
133
+ this.state = {
134
+ fieldList: [],
135
+ dataSource: [],
136
+ loading: false,
137
+ error: null,
138
+ pagination: {
139
+ current: page || 1,
140
+ pageSize: pageSize || 10,
141
+ total: 0,
142
+ },
143
+ isModalVisible: false,
144
+ isEditMode: false,
145
+ editingRecord: null,
146
+ form: null,
147
+ entityTypeList: [],
148
+ };
149
+
150
+ // 绑定方法上下文
151
+ this.loadData = this.loadData.bind(this);
152
+ this.handleAdd = this.handleAdd.bind(this);
153
+ this.handleEdit = this.handleEdit.bind(this);
154
+ this.handleDelete = this.handleDelete.bind(this);
155
+ this.handleModalOk = this.handleModalOk.bind(this);
156
+ this.handleModalCancel = this.handleModalCancel.bind(this);
157
+ this.handleTableChange = this.handleTableChange.bind(this);
158
+ }
159
+
160
+ componentDidMount() {
161
+ const { xObjectDataApi } = this.props;
162
+ const { xObjectApiKey, fields, page, pageSize } = xObjectDataApi || {};
163
+
164
+ if (xObjectApiKey) {
165
+ // 初始化字段列表、加载数据和业务类型列表
166
+ this.getEntityTypeList(xObjectApiKey);
167
+ this.loadFieldList();
168
+
169
+ if (fields) {
170
+ this.loadData(page, pageSize);
171
+ }
172
+ }
173
+ }
174
+
175
+ /**
176
+ * 组件更新后执行
177
+ * 当 xObjectApiKey 发生变化时重新加载数据
178
+ */
179
+ async componentDidUpdate(prevProps: EntityTableProps) {
180
+ const { xObjectApiKey, fields, page, pageSize } =
181
+ this.props.xObjectDataApi || {};
182
+ const {
183
+ xObjectApiKey: prevXObjectApiKey,
184
+ fields: prevFields,
185
+ page: prevPage,
186
+ pageSize: prevPageSize,
187
+ } = prevProps.xObjectDataApi || {};
188
+ if (
189
+ xObjectApiKey !== prevXObjectApiKey ||
190
+ !isEqual(fields, prevFields) ||
191
+ page !== prevPage ||
192
+ pageSize !== prevPageSize
193
+ ) {
194
+ if (xObjectApiKey) {
195
+ // 先加载字段列表,等待完成后再加载数据,确保字段信息已更新
196
+ await this.loadFieldList();
197
+ await this.getEntityTypeList(xObjectApiKey);
198
+ this.loadData(page, pageSize);
199
+ } else {
200
+ this.setState({
201
+ dataSource: [],
202
+ fieldList: [],
203
+ });
204
+ }
205
+ }
206
+ }
207
+
208
+ /**
209
+ * 获取业务类型列表
210
+ * 用于下拉选择框的选项数据
211
+ */
212
+ async getEntityTypeList(xObjectApiKey?: string) {
213
+ const { xObjectDataApi } = this.props;
214
+ const curXObjectApiKey = xObjectApiKey || xObjectDataApi?.xObjectApiKey;
215
+ const result = await xObject.getEntityTypeList(curXObjectApiKey);
216
+ if (result && result.status) {
217
+ const records = result.data || [];
218
+ this.setState({
219
+ entityTypeList: records,
220
+ });
221
+ }
222
+ }
223
+
224
+ /**
225
+ * 加载字段列表
226
+ * 从 Neo 平台获取 XObject 的字段描述信息
227
+ */
228
+ async loadFieldList() {
229
+ const { xObjectDataApi } = this.props || {};
230
+
231
+ // 方式一:直接从 props.xObjectDetailApi 中获取字段描述
232
+ if (xObjectDataApi && xObjectDataApi.fieldDescList) {
233
+ this.setState({ fieldList: xObjectDataApi.fieldDescList });
234
+ } else {
235
+ // 方式二:自行通过 OpenAPI SDK 获取字段描述
236
+ if (!xObjectDataApi.xObjectApiKey) return;
237
+ try {
238
+ const resultData = await xObject.getDesc(xObjectDataApi.xObjectApiKey);
239
+ if (resultData && resultData.status) {
240
+ const result = resultData.data || {};
241
+ const fieldList = result.fields || [];
242
+ this.setState({ fieldList, title: result.label });
243
+ }
244
+ } catch (error) {
245
+ console.error('获取字段列表失败:', error);
246
+ message.error('获取字段列表失败');
247
+ }
248
+ }
249
+ }
250
+
251
+ /**
252
+ * 生成表格列配置
253
+ * @returns 表格列配置数组
254
+ */
255
+ generateColumns() {
256
+ const { showEditButton, showDeleteButton, xObjectDataApi } = this.props;
257
+ const { fieldList } = this.state;
258
+ const { fields, fieldDescList } = xObjectDataApi || {};
259
+ let curFieldList =
260
+ fieldDescList && fieldDescList.length > 0 ? fieldDescList : fieldList;
261
+
262
+ if (fields && fields.length > 0) {
263
+ // 如果 fields 存在,则过滤掉 fieldList 中不存在的字段
264
+ curFieldList = curFieldList.filter((field) =>
265
+ fields.includes(field.apiKey),
266
+ );
267
+ }
268
+
269
+ // 根据字段列表生成基础列配置
270
+ const columns: any[] = curFieldList.map((field) => ({
271
+ title: field.label,
272
+ dataIndex: field.apiKey,
273
+ key: field.apiKey,
274
+ ellipsis: true,
275
+ }));
276
+
277
+ // 添加操作列(编辑和删除按钮)
278
+ if (showEditButton || showDeleteButton) {
279
+ columns.push({
280
+ title: '操作',
281
+ key: 'action',
282
+ dataIndex: 'action',
283
+ ellipsis: false,
284
+ width: 150,
285
+ render: (text: any, record: any) => (
286
+ <Space size="middle">
287
+ {showEditButton && (
288
+ <Button
289
+ type="link"
290
+ icon={<EditOutlined />}
291
+ onClick={() => this.handleEdit(record)}
292
+ size="small"
293
+ >
294
+ 编辑
295
+ </Button>
296
+ )}
297
+ {showDeleteButton && (
298
+ <Popconfirm
299
+ title="确定要删除这条记录吗?"
300
+ onConfirm={() => this.handleDelete(record.id)}
301
+ okText="确定"
302
+ cancelText="取消"
303
+ >
304
+ <Button
305
+ type="link"
306
+ danger
307
+ icon={<DeleteOutlined />}
308
+ size="small"
309
+ >
310
+ 删除
311
+ </Button>
312
+ </Popconfirm>
313
+ )}
314
+ </Space>
315
+ ),
316
+ });
317
+ }
318
+
319
+ return columns;
320
+ }
321
+
322
+ /**
323
+ * 加载表格数据
324
+ * @param page 页码,默认为 1
325
+ * @param pageSize 每页条数,默认为 10
326
+ */
327
+ async loadData(page = 1, pageSize = 10) {
328
+ const { xObjectApiKey, autoFetchData } = this.props.xObjectDataApi || {};
329
+ if (!xObjectApiKey) return;
330
+
331
+ this.setState({ loading: true, error: null });
332
+
333
+ try {
334
+ // 获取所有字段的 API Key=
335
+ const result = await xObject.query(this.props.xObjectDataApi);
336
+
337
+ if (result && result.status) {
338
+ const records = result.data || [];
339
+ const totalSize = result.totalSize || 0;
340
+
341
+ this.setState({
342
+ dataSource: records,
343
+ pagination: {
344
+ current: page,
345
+ pageSize,
346
+ total: totalSize,
347
+ },
348
+ loading: false,
349
+ });
350
+ } else {
351
+ this.setState({
352
+ error: result?.msg || '获取数据失败',
353
+ loading: false,
354
+ });
355
+ }
356
+ } catch (error: any) {
357
+ this.setState({
358
+ error: error.message || '获取数据失败',
359
+ loading: false,
360
+ });
361
+ }
362
+ }
363
+
364
+ /**
365
+ * 处理新增按钮点击
366
+ * 打开新增模态框
367
+ */
368
+ handleAdd() {
369
+ this.setState({
370
+ isModalVisible: true,
371
+ isEditMode: false,
372
+ editingRecord: null,
373
+ });
374
+ }
375
+
376
+ /**
377
+ * 处理编辑按钮点击
378
+ * @param record 要编辑的记录
379
+ */
380
+ handleEdit(record: any) {
381
+ this.setState({
382
+ isModalVisible: true,
383
+ isEditMode: true,
384
+ editingRecord: record,
385
+ });
386
+ }
387
+
388
+ /**
389
+ * 处理删除操作
390
+ * @param id 要删除的记录 ID
391
+ */
392
+ async handleDelete(id: string) {
393
+ const { xObjectApiKey } = this.props.xObjectDataApi || {};
394
+ if (!xObjectApiKey) return;
395
+
396
+ try {
397
+ const response = await xObject.delete(xObjectApiKey, id);
398
+ if (response && (response.code === 200 || response.code === '200')) {
399
+ message.success('删除成功');
400
+ // 删除成功后重新加载当前页数据
401
+ this.loadData(
402
+ this.state.pagination.current,
403
+ this.state.pagination.pageSize,
404
+ );
405
+ } else {
406
+ message.error(response?.message || '删除失败');
407
+ }
408
+ } catch (error) {
409
+ console.error('删除失败:', error);
410
+ message.error('删除失败');
411
+ }
412
+ }
413
+
414
+ /**
415
+ * 处理模态框确定按钮点击
416
+ * 执行新增或编辑操作
417
+ */
418
+ handleModalOk() {
419
+ this.state.form?.validateFields().then(async (values: any) => {
420
+ const { xObjectApiKey, fields: fieldList } =
421
+ this.props.xObjectDataApi || {};
422
+ const { isEditMode, editingRecord } = this.state;
423
+
424
+ try {
425
+ let response;
426
+ if (isEditMode) {
427
+ // 编辑模式:更新现有记录
428
+ const { fieldList } = this.state;
429
+ // 处理日期格式的字段,转换为时间戳
430
+ Object.keys(values).forEach((fieldKey: any) => {
431
+ const field = fieldList.find(
432
+ (field: any) => field.apiKey === fieldKey,
433
+ );
434
+ if (
435
+ field &&
436
+ (field.type === 'date' ||
437
+ field.type === 'datetime' ||
438
+ field.type === 'time')
439
+ ) {
440
+ values[fieldKey] = new Date(values[fieldKey]).getTime();
441
+ }
442
+ });
443
+ response = await xObject.update(xObjectApiKey, editingRecord.id, {
444
+ data: values,
445
+ method: 'PATCH',
446
+ });
447
+ } else {
448
+ // 新增模式:创建新记录
449
+ response = await xObject.create(xObjectApiKey, {
450
+ data: values,
451
+ method: 'POST',
452
+ });
453
+ }
454
+
455
+ if (response && (response.code === 200 || response.code === '200')) {
456
+ message.success(isEditMode ? '更新成功' : '创建成功');
457
+ this.setState({ isModalVisible: false });
458
+ // 操作成功后重新加载当前页数据
459
+ this.loadData(
460
+ this.state.pagination.current,
461
+ this.state.pagination.pageSize,
462
+ );
463
+ } else {
464
+ message.error(
465
+ response?.message || (isEditMode ? '更新失败' : '创建失败'),
466
+ );
467
+ }
468
+ } catch (error) {
469
+ console.error(isEditMode ? '更新失败:' : '创建失败:', error);
470
+ message.error(isEditMode ? '更新失败' : '创建失败');
471
+ }
472
+ });
473
+ }
474
+
475
+ /**
476
+ * 处理模态框取消按钮点击
477
+ * 关闭模态框并重置状态
478
+ */
479
+ handleModalCancel() {
480
+ this.setState({
481
+ isModalVisible: false,
482
+ isEditMode: false,
483
+ editingRecord: null,
484
+ });
485
+ }
486
+
487
+ /**
488
+ * 处理表格分页变化
489
+ * @param pagination 分页信息
490
+ */
491
+ handleTableChange(pagination: any) {
492
+ this.loadData(pagination.current, pagination.pageSize);
493
+ }
494
+
495
+ /**
496
+ * 渲染表单内容
497
+ * 根据字段类型动态生成对应的输入组件
498
+ * @returns 表单 JSX 元素
499
+ */
500
+ renderForm() {
501
+ const {
502
+ fieldList: _fieldList,
503
+ isEditMode,
504
+ editingRecord,
505
+ entityTypeList,
506
+ } = this.state;
507
+ const { xObjectApiKey, fields } = this.props.xObjectDataApi || {};
508
+ let fieldList = _fieldList;
509
+
510
+ if (fields && fields.length > 0) {
511
+ fieldList = fieldList.filter((field) => fields.includes(field.apiKey));
512
+ }
513
+
514
+ // 如果没有选择对象,显示提示信息
515
+ if (!xObjectApiKey) {
516
+ return (
517
+ <Empty
518
+ description="请先选择要操作的对象"
519
+ image={Empty.PRESENTED_IMAGE_SIMPLE}
520
+ />
521
+ );
522
+ }
523
+
524
+ // 处理编辑模式下的日期格式字段
525
+ const curEditingRecord = editingRecord || {};
526
+ if (editingRecord) {
527
+ Object.keys(editingRecord).forEach((fieldKey: any) => {
528
+ const field = fieldList.find((field: any) => field.apiKey === fieldKey);
529
+ if (
530
+ field &&
531
+ editingRecord[fieldKey] &&
532
+ (field.type === 'date' ||
533
+ field.type === 'datetime' ||
534
+ field.type === 'time')
535
+ ) {
536
+ // 将时间戳转换为 moment 对象,用于日期选择器
537
+ curEditingRecord[fieldKey] = moment(
538
+ new Date(editingRecord[fieldKey]),
539
+ field.type === 'date'
540
+ ? 'YYYY/MM/DD'
541
+ : field.type === 'datetime'
542
+ ? 'YYYY/MM/DD HH:mm:ss'
543
+ : 'HH:mm:ss',
544
+ );
545
+ }
546
+ });
547
+ }
548
+
549
+ return (
550
+ <Form
551
+ ref={(form) => this.setState({ form })}
552
+ layout="vertical"
553
+ initialValues={isEditMode ? curEditingRecord : {}}
554
+ >
555
+ {fieldList.map((field) => {
556
+ // 跳过 ID 字段,不需要在表单中显示
557
+ if (field.apiKey === 'id') return null;
558
+
559
+ let inputComponent;
560
+ const selectitem = field.selectitem || [];
561
+ const checkitem = field.checkitem || [];
562
+
563
+ // 根据字段类型生成对应的输入组件
564
+ switch (field.type) {
565
+ case 'entityType':
566
+ case 'entitytype':
567
+ // 业务类型选择器
568
+ inputComponent = (
569
+ <Select placeholder="请选择业务类型">
570
+ {entityTypeList.map((item) => (
571
+ <Option
572
+ key={item.apiKey}
573
+ value={item.id}
574
+ disabled={!item.active}
575
+ >
576
+ {item.label}
577
+ </Option>
578
+ ))}
579
+ </Select>
580
+ );
581
+ break;
582
+ case 'picklist':
583
+ // 单选下拉框
584
+ inputComponent = (
585
+ <Select placeholder={`请选择${field.label}`}>
586
+ {selectitem.map((item) => (
587
+ <Option key={item.apiKey} value={item.id}>
588
+ {item.label}
589
+ </Option>
590
+ ))}
591
+ </Select>
592
+ );
593
+ break;
594
+ case 'textarea':
595
+ // 多行文本输入框
596
+ inputComponent = (
597
+ <Input.TextArea placeholder={`请输入${field.label}`} rows={3} />
598
+ );
599
+ break;
600
+ case 'multipicklist':
601
+ // 多选下拉框
602
+ inputComponent = (
603
+ <Select placeholder={`请选择${field.label}`} mode="multiple">
604
+ {checkitem.map((item) => (
605
+ <Option key={item.apiKey} value={item.id}>
606
+ {item.label}
607
+ </Option>
608
+ ))}
609
+ </Select>
610
+ );
611
+ break;
612
+ case 'datetime':
613
+ // 日期时间选择器
614
+ inputComponent = (
615
+ <DatePicker
616
+ placeholder={`请输入${field.label}`}
617
+ format={'YYYY/MM/DD HH:mm:ss'}
618
+ showTime={true}
619
+ />
620
+ );
621
+ break;
622
+ case 'date':
623
+ // 日期选择器
624
+ inputComponent = (
625
+ <DatePicker
626
+ placeholder={`请输入${field.label}`}
627
+ format={'YYYY/MM/DD'}
628
+ />
629
+ );
630
+ break;
631
+ case 'time':
632
+ // 时间选择器
633
+ inputComponent = (
634
+ <DatePicker
635
+ placeholder={`请输入${field.label}`}
636
+ format={'HH:mm:ss'}
637
+ showTime={true}
638
+ />
639
+ );
640
+ break;
641
+ case 'int':
642
+ case 'float':
643
+ // 数字输入框
644
+ inputComponent = (
645
+ <InputNumber placeholder={`请输入${field.label}`} />
646
+ );
647
+ break;
648
+ default:
649
+ // 默认文本输入框
650
+ inputComponent = <Input placeholder={`请输入${field.label}`} />;
651
+ }
652
+
653
+ return (
654
+ <Form.Item
655
+ key={field.apiKey}
656
+ name={field.apiKey}
657
+ label={field.label}
658
+ required={field.required ?? false}
659
+ rules={[
660
+ {
661
+ required: field.required,
662
+ message: `请输入${field.label}`,
663
+ },
664
+ ]}
665
+ >
666
+ {inputComponent}
667
+ </Form.Item>
668
+ );
669
+ })}
670
+ </Form>
671
+ );
672
+ }
673
+
674
+ /**
675
+ * 渲染组件
676
+ * @returns 组件 JSX 元素
677
+ */
678
+ render() {
679
+ const {
680
+ title,
681
+ dataSource,
682
+ loading,
683
+ error,
684
+ pagination,
685
+ isModalVisible,
686
+ isEditMode,
687
+ } = this.state;
688
+ const curAmisData = this.props.data || {};
689
+ const systemInfo = curAmisData.__NeoSystemInfo || {};
690
+ const { xObjectApiKey } = this.props.xObjectDataApi || {};
691
+ const columns = this.generateColumns();
692
+ console.log('this.props:', this.props, columns);
693
+
694
+ return (
695
+ <div className="entity-table-container">
696
+ <Card>
697
+ <div className="table-header">
698
+ <div className="header-content">
699
+ <h3 className="header-title">
700
+ {title || '数据表格'}
701
+ {systemInfo.tenantName ? `【${systemInfo.tenantName}】` : ''}
702
+ </h3>
703
+ <Space>
704
+ {this.props.showAddButton && (
705
+ <Button
706
+ type="primary"
707
+ icon={<PlusOutlined />}
708
+ onClick={this.handleAdd}
709
+ disabled={!xObjectApiKey}
710
+ >
711
+ 新增
712
+ </Button>
713
+ )}
714
+ <Button
715
+ icon={<ReloadOutlined />}
716
+ onClick={() =>
717
+ this.loadData(pagination.current, pagination.pageSize)
718
+ }
719
+ loading={loading}
720
+ >
721
+ 刷新
722
+ </Button>
723
+ </Space>
724
+ </div>
725
+ </div>
726
+
727
+ <div className="table-content">
728
+ <Spin spinning={loading} tip="加载数据中...">
729
+ {error ? (
730
+ <Empty
731
+ image={Empty.PRESENTED_IMAGE_SIMPLE}
732
+ description={
733
+ <div>
734
+ <div style={{ color: '#ff4d4f', marginBottom: 8 }}>
735
+ {error}
736
+ </div>
737
+ <Button
738
+ type="primary"
739
+ onClick={() =>
740
+ this.loadData(pagination.current, pagination.pageSize)
741
+ }
742
+ >
743
+ 重新加载
744
+ </Button>
745
+ </div>
746
+ }
747
+ />
748
+ ) : (
749
+ <Table
750
+ key={`${xObjectApiKey}-${columns.length}`}
751
+ columns={columns}
752
+ dataSource={dataSource}
753
+ rowKey="id"
754
+ pagination={{
755
+ ...pagination,
756
+ showSizeChanger: true,
757
+ showQuickJumper: true,
758
+ showTotal: (total, range) =>
759
+ `第 ${range[0]}-${range[1]} 条/共 ${total} 条`,
760
+ }}
761
+ onChange={this.handleTableChange}
762
+ scroll={{ x: 'max-content' }}
763
+ />
764
+ )}
765
+ </Spin>
766
+ </div>
767
+ </Card>
768
+
769
+ <Modal
770
+ title={isEditMode ? `编辑${title}` : `新增${title}`}
771
+ visible={isModalVisible}
772
+ onOk={this.handleModalOk}
773
+ onCancel={this.handleModalCancel}
774
+ cancelText="取消"
775
+ okText="确定"
776
+ width={600}
777
+ destroyOnClose
778
+ >
779
+ {this.renderForm()}
780
+ </Modal>
781
+ </div>
782
+ );
783
+ }
784
+ }