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,615 @@
1
+ /**
2
+ * @file Object Form 对象表单组件
3
+ * @description 基于 Neo 平台的 XObject 实体对象数据表单组件,用于新增数据
4
+ */
5
+ import * as React from 'react';
6
+ import {
7
+ Form,
8
+ Input,
9
+ Select,
10
+ Button,
11
+ message,
12
+ Card,
13
+ DatePicker,
14
+ InputNumber,
15
+ Space,
16
+ Spin,
17
+ Empty,
18
+ Row,
19
+ Col,
20
+ } from 'antd';
21
+ import {
22
+ SaveOutlined,
23
+ ReloadOutlined,
24
+ CheckCircleOutlined,
25
+ } from '@ant-design/icons';
26
+ import moment from 'moment';
27
+ // @ts-ignore
28
+ import { xObject } from 'neo-open-api'; // Neo Open API
29
+ // @ts-ignore
30
+ import isEqual from 'lodash/isEqual';
31
+ import './style.scss';
32
+
33
+ const { Option } = Select;
34
+
35
+ /**
36
+ * 组件属性接口
37
+ */
38
+ interface EntityFormProps {
39
+ /** XObject 实体对象的 API Key,用于标识要操作的数据对象 */
40
+ xObjectDataApi: {
41
+ xObjectApiKey: string;
42
+ fields?: string[];
43
+ fieldDescList?: any[];
44
+ };
45
+ /** Neo 平台传递的数据,包含系统信息等 */
46
+ data?: any;
47
+ /** 表单标题 */
48
+ formTitle?: string;
49
+ /** 是否显示重置按钮 */
50
+ showResetButton?: boolean;
51
+ /** 表单列数(1列或2列) */
52
+ columnCount?: 1 | 2;
53
+ /** 提交成功后的回调 */
54
+ onSuccess?: (data: any) => void;
55
+ /** 是否为自定义实体对象 */
56
+ custom?: boolean;
57
+ }
58
+
59
+ /**
60
+ * 字段信息接口
61
+ */
62
+ interface FieldInfo {
63
+ /** 字段名称 */
64
+ name: string;
65
+ /** 字段显示标签 */
66
+ label: string;
67
+ /** 字段 API Key */
68
+ apiKey: string;
69
+ /** 字段类型 */
70
+ type: string;
71
+ /** 字段项类型 */
72
+ itemType: string;
73
+ /** 复选框选项列表 */
74
+ checkitem: any[];
75
+ /** 下拉选择选项列表 */
76
+ selectitem?: any[];
77
+ /** 是否必填 */
78
+ required: boolean;
79
+ }
80
+
81
+ /**
82
+ * 组件状态接口
83
+ */
84
+ interface EntityFormState {
85
+ /** 表单标题 */
86
+ title?: string;
87
+ /** 字段列表 */
88
+ fieldList: FieldInfo[];
89
+ /** 加载状态 */
90
+ loading: boolean;
91
+ /** 提交中状态 */
92
+ submitting: boolean;
93
+ /** 错误信息 */
94
+ error: string | null;
95
+ /** 表单实例 */
96
+ form: any;
97
+ /** 业务类型列表 */
98
+ entityTypeList: any[];
99
+ /** 提交成功状态 */
100
+ submitSuccess: boolean;
101
+ }
102
+
103
+ /**
104
+ * Object Form 对象表单组件
105
+ * 支持对 Neo 平台的 XObject 实体对象进行新增操作
106
+ */
107
+ export default class EntityForm extends React.PureComponent<
108
+ EntityFormProps,
109
+ EntityFormState
110
+ > {
111
+ constructor(props: EntityFormProps) {
112
+ super(props);
113
+
114
+ // 初始化组件状态
115
+ this.state = {
116
+ fieldList: [],
117
+ loading: false,
118
+ submitting: false,
119
+ error: null,
120
+ form: null,
121
+ entityTypeList: [],
122
+ submitSuccess: false,
123
+ };
124
+
125
+ // 绑定方法上下文
126
+ this.loadFieldList = this.loadFieldList.bind(this);
127
+ this.handleSubmit = this.handleSubmit.bind(this);
128
+ this.handleReset = this.handleReset.bind(this);
129
+ }
130
+
131
+ componentDidMount() {
132
+ const { xObjectDataApi } = this.props;
133
+ const { xObjectApiKey } = xObjectDataApi || {};
134
+
135
+ if (xObjectApiKey) {
136
+ // 初始化字段列表和业务类型列表
137
+ this.getEntityTypeList(xObjectApiKey);
138
+ this.loadFieldList();
139
+ }
140
+ }
141
+
142
+ /**
143
+ * 组件更新后执行
144
+ * 当 xObjectApiKey 发生变化时重新加载字段列表
145
+ */
146
+ async componentDidUpdate(prevProps: EntityFormProps) {
147
+ const { xObjectApiKey, fields } = this.props.xObjectDataApi || {};
148
+ const { xObjectApiKey: prevXObjectApiKey, fields: prevFields } =
149
+ prevProps.xObjectDataApi || {};
150
+
151
+ if (xObjectApiKey !== prevXObjectApiKey || !isEqual(fields, prevFields)) {
152
+ if (xObjectApiKey) {
153
+ await this.loadFieldList();
154
+ await this.getEntityTypeList(xObjectApiKey);
155
+ } else {
156
+ this.setState({
157
+ fieldList: [],
158
+ });
159
+ }
160
+ }
161
+ }
162
+
163
+ /**
164
+ * 获取业务类型列表
165
+ * 用于下拉选择框的选项数据
166
+ */
167
+ async getEntityTypeList(xObjectApiKey?: string) {
168
+ const { xObjectDataApi } = this.props;
169
+ const curXObjectApiKey = xObjectApiKey || xObjectDataApi?.xObjectApiKey;
170
+ try {
171
+ const result = await xObject.getEntityTypeList(curXObjectApiKey);
172
+ if (result && result.status) {
173
+ const records = result.data || [];
174
+ this.setState({
175
+ entityTypeList: records,
176
+ });
177
+ }
178
+ } catch (error) {
179
+ console.error('获取业务类型列表失败:', error);
180
+ }
181
+ }
182
+
183
+ /**
184
+ * 加载字段列表
185
+ * 从 Neo 平台获取 XObject 的字段描述信息
186
+ */
187
+ async loadFieldList() {
188
+ const { xObjectDataApi } = this.props || {};
189
+
190
+ this.setState({ loading: true });
191
+
192
+ try {
193
+ // 方式一:直接从 props.xObjectDataApi 中获取字段描述
194
+ if (xObjectDataApi && xObjectDataApi.fieldDescList) {
195
+ this.setState({
196
+ fieldList: xObjectDataApi.fieldDescList,
197
+ loading: false,
198
+ });
199
+ } else {
200
+ // 方式二:自行通过 OpenAPI SDK 获取字段描述
201
+ if (!xObjectDataApi.xObjectApiKey) {
202
+ this.setState({ loading: false });
203
+ return;
204
+ }
205
+ const resultData = await xObject.getDesc(xObjectDataApi.xObjectApiKey);
206
+ if (resultData && resultData.status) {
207
+ const result = resultData.data || {};
208
+ const fieldList = result.fields || [];
209
+ this.setState({
210
+ fieldList,
211
+ title: result.label,
212
+ loading: false,
213
+ });
214
+ } else {
215
+ this.setState({
216
+ error: '获取字段列表失败',
217
+ loading: false,
218
+ });
219
+ }
220
+ }
221
+ } catch (error) {
222
+ console.error('获取字段列表失败:', error);
223
+ message.error('获取字段列表失败');
224
+ this.setState({
225
+ error: '获取字段列表失败',
226
+ loading: false,
227
+ });
228
+ }
229
+ }
230
+
231
+ /**
232
+ * 处理表单提交
233
+ * 执行新增操作
234
+ */
235
+ handleSubmit() {
236
+ this.state.form?.validateFields().then(async (values: any) => {
237
+ const { xObjectApiKey } = this.props.xObjectDataApi || {};
238
+ const { fieldList } = this.state;
239
+
240
+ if (!xObjectApiKey) {
241
+ message.error('请先选择要操作的对象');
242
+ return;
243
+ }
244
+
245
+ this.setState({ submitting: true });
246
+
247
+ try {
248
+ // 处理日期格式的字段,转换为时间戳
249
+ Object.keys(values).forEach((fieldKey: any) => {
250
+ const field = fieldList.find(
251
+ (field: any) => field.apiKey === fieldKey,
252
+ );
253
+ if (
254
+ field &&
255
+ values[fieldKey] &&
256
+ (field.type === 'date' ||
257
+ field.type === 'datetime' ||
258
+ field.type === 'time')
259
+ ) {
260
+ values[fieldKey] = new Date(values[fieldKey]).getTime();
261
+ }
262
+ });
263
+
264
+ // 调用新增接口
265
+ const response = await xObject.create(xObjectApiKey, {
266
+ data: values,
267
+ method: 'POST',
268
+ });
269
+
270
+ if (response && (response.code === 200 || response.code === '200')) {
271
+ message.success('创建成功');
272
+ this.setState({
273
+ submitting: false,
274
+ submitSuccess: true,
275
+ });
276
+
277
+ // 重置表单
278
+ this.state.form?.resetFields();
279
+
280
+ // 1秒后隐藏成功提示
281
+ setTimeout(() => {
282
+ this.setState({ submitSuccess: false });
283
+ }, 2000);
284
+
285
+ // 调用成功回调
286
+ if (this.props.onSuccess) {
287
+ this.props.onSuccess(response.data);
288
+ }
289
+ } else {
290
+ message.error(response?.message || '创建失败');
291
+ this.setState({ submitting: false });
292
+ }
293
+ } catch (error) {
294
+ console.error('创建失败:', error);
295
+ message.error('创建失败');
296
+ this.setState({ submitting: false });
297
+ }
298
+ });
299
+ }
300
+
301
+ /**
302
+ * 处理表单重置
303
+ */
304
+ handleReset() {
305
+ this.state.form?.resetFields();
306
+ this.setState({ submitSuccess: false });
307
+ message.info('表单已重置');
308
+ }
309
+
310
+ /**
311
+ * 渲染表单内容
312
+ * 根据字段类型动态生成对应的输入组件
313
+ * @returns 表单 JSX 元素
314
+ */
315
+ renderForm() {
316
+ const { fieldList, entityTypeList, submitSuccess } = this.state;
317
+ const { xObjectApiKey, fields } = this.props.xObjectDataApi || {};
318
+ const { columnCount = 1 } = this.props;
319
+
320
+ let curFieldList = fieldList;
321
+
322
+ // 如果指定了 fields,则只显示指定的字段
323
+ if (fields && fields.length > 0) {
324
+ curFieldList = fieldList.filter((field) => fields.includes(field.apiKey));
325
+ }
326
+
327
+ // 如果没有选择对象,显示提示信息
328
+ if (!xObjectApiKey) {
329
+ return (
330
+ <Empty
331
+ description="请先选择要操作的对象"
332
+ image={Empty.PRESENTED_IMAGE_SIMPLE}
333
+ />
334
+ );
335
+ }
336
+
337
+ // 如果字段列表为空,显示提示信息
338
+ if (curFieldList.length === 0) {
339
+ return (
340
+ <Empty
341
+ description="暂无可用字段"
342
+ image={Empty.PRESENTED_IMAGE_SIMPLE}
343
+ />
344
+ );
345
+ }
346
+
347
+ const formItemLayout =
348
+ columnCount === 2
349
+ ? {
350
+ labelCol: { span: 8 },
351
+ wrapperCol: { span: 16 },
352
+ }
353
+ : {
354
+ labelCol: { span: 4 },
355
+ wrapperCol: { span: 20 },
356
+ };
357
+
358
+ return (
359
+ <Form
360
+ ref={(form) => this.setState({ form })}
361
+ layout="horizontal"
362
+ {...formItemLayout}
363
+ >
364
+ <Row gutter={16}>
365
+ {curFieldList.map((field) => {
366
+ // 跳过 ID 字段,不需要在表单中显示
367
+ if (field.apiKey === 'id') return null;
368
+
369
+ let inputComponent;
370
+ const selectitem = field.selectitem || [];
371
+ const checkitem = field.checkitem || [];
372
+
373
+ // 根据字段类型生成对应的输入组件
374
+ switch (field.type) {
375
+ case 'entityType':
376
+ case 'entitytype':
377
+ // 业务类型选择器
378
+ inputComponent = (
379
+ <Select placeholder="请选择业务类型" allowClear>
380
+ {entityTypeList.map((item) => (
381
+ <Option
382
+ key={item.apiKey}
383
+ value={item.id}
384
+ disabled={!item.active}
385
+ >
386
+ {item.label}
387
+ </Option>
388
+ ))}
389
+ </Select>
390
+ );
391
+ break;
392
+ case 'picklist':
393
+ // 单选下拉框
394
+ inputComponent = (
395
+ <Select placeholder={`请选择${field.label}`} allowClear>
396
+ {selectitem.map((item) => (
397
+ <Option key={item.apiKey} value={item.id}>
398
+ {item.label}
399
+ </Option>
400
+ ))}
401
+ </Select>
402
+ );
403
+ break;
404
+ case 'textarea':
405
+ // 多行文本输入框
406
+ inputComponent = (
407
+ <Input.TextArea
408
+ placeholder={`请输入${field.label}`}
409
+ rows={3}
410
+ showCount
411
+ maxLength={500}
412
+ />
413
+ );
414
+ break;
415
+ case 'multipicklist':
416
+ // 多选下拉框
417
+ inputComponent = (
418
+ <Select
419
+ placeholder={`请选择${field.label}`}
420
+ mode="multiple"
421
+ allowClear
422
+ >
423
+ {checkitem.map((item) => (
424
+ <Option key={item.apiKey} value={item.id}>
425
+ {item.label}
426
+ </Option>
427
+ ))}
428
+ </Select>
429
+ );
430
+ break;
431
+ case 'datetime':
432
+ // 日期时间选择器
433
+ inputComponent = (
434
+ <DatePicker
435
+ placeholder={`请选择${field.label}`}
436
+ format={'YYYY/MM/DD HH:mm:ss'}
437
+ showTime={true}
438
+ style={{ width: '100%' }}
439
+ />
440
+ );
441
+ break;
442
+ case 'date':
443
+ // 日期选择器
444
+ inputComponent = (
445
+ <DatePicker
446
+ placeholder={`请选择${field.label}`}
447
+ format={'YYYY/MM/DD'}
448
+ style={{ width: '100%' }}
449
+ />
450
+ );
451
+ break;
452
+ case 'time':
453
+ // 时间选择器
454
+ inputComponent = (
455
+ <DatePicker
456
+ placeholder={`请选择${field.label}`}
457
+ format={'HH:mm:ss'}
458
+ showTime={true}
459
+ style={{ width: '100%' }}
460
+ />
461
+ );
462
+ break;
463
+ case 'int':
464
+ case 'float':
465
+ // 数字输入框
466
+ inputComponent = (
467
+ <InputNumber
468
+ placeholder={`请输入${field.label}`}
469
+ style={{ width: '100%' }}
470
+ />
471
+ );
472
+ break;
473
+ case 'email':
474
+ // 邮箱输入框
475
+ inputComponent = (
476
+ <Input placeholder={`请输入${field.label}`} type="email" />
477
+ );
478
+ break;
479
+ case 'url':
480
+ // URL 输入框
481
+ inputComponent = (
482
+ <Input placeholder={`请输入${field.label}`} type="url" />
483
+ );
484
+ break;
485
+ case 'phone':
486
+ // 电话号码输入框
487
+ inputComponent = (
488
+ <Input placeholder={`请输入${field.label}`} type="tel" />
489
+ );
490
+ break;
491
+ default:
492
+ // 默认文本输入框
493
+ inputComponent = (
494
+ <Input placeholder={`请输入${field.label}`} maxLength={200} />
495
+ );
496
+ }
497
+
498
+ const colSpan = columnCount === 2 ? 12 : 24;
499
+
500
+ return (
501
+ <Col span={colSpan} key={field.apiKey}>
502
+ <Form.Item
503
+ name={field.apiKey}
504
+ label={field.label}
505
+ required={field.required ?? false}
506
+ rules={[
507
+ {
508
+ required: field.required,
509
+ message: `请${
510
+ field.type === 'picklist' ||
511
+ field.type === 'multipicklist' ||
512
+ field.type === 'entityType' ||
513
+ field.type === 'entitytype' ||
514
+ field.type === 'date' ||
515
+ field.type === 'datetime' ||
516
+ field.type === 'time'
517
+ ? '选择'
518
+ : '输入'
519
+ }${field.label}`,
520
+ },
521
+ ]}
522
+ >
523
+ {inputComponent}
524
+ </Form.Item>
525
+ </Col>
526
+ );
527
+ })}
528
+ </Row>
529
+
530
+ {submitSuccess && (
531
+ <div className="submit-success-message">
532
+ <CheckCircleOutlined /> 数据已成功提交
533
+ </div>
534
+ )}
535
+ </Form>
536
+ );
537
+ }
538
+
539
+ /**
540
+ * 渲染组件
541
+ * @returns 组件 JSX 元素
542
+ */
543
+ render() {
544
+ const { title, loading, submitting, error } = this.state;
545
+ const { formTitle, showResetButton = true, data } = this.props;
546
+
547
+ // 测试输出
548
+ console.log('this.props:', this.props);
549
+
550
+ const curAmisData = data || {};
551
+ const systemInfo = curAmisData.__NeoSystemInfo || {};
552
+ const { xObjectApiKey } = this.props.xObjectDataApi || {};
553
+
554
+ const displayTitle = formTitle || title || '新增数据';
555
+
556
+ return (
557
+ <div className="entity-form-container">
558
+ <Card>
559
+ <div className="form-header">
560
+ <h3 className="form-title">
561
+ {displayTitle}
562
+ {systemInfo.tenantName ? `【${systemInfo.tenantName}】` : ''}
563
+ </h3>
564
+ </div>
565
+
566
+ <div className="form-content">
567
+ <Spin spinning={loading} tip="加载字段信息...">
568
+ {error ? (
569
+ <Empty
570
+ image={Empty.PRESENTED_IMAGE_SIMPLE}
571
+ description={
572
+ <div>
573
+ <div style={{ color: '#ff4d4f', marginBottom: 8 }}>
574
+ {error}
575
+ </div>
576
+ <Button type="primary" onClick={this.loadFieldList}>
577
+ 重新加载
578
+ </Button>
579
+ </div>
580
+ }
581
+ />
582
+ ) : (
583
+ <>
584
+ {this.renderForm()}
585
+ <div className="form-actions">
586
+ <Space size="middle">
587
+ <Button
588
+ type="primary"
589
+ icon={<SaveOutlined />}
590
+ onClick={this.handleSubmit}
591
+ loading={submitting}
592
+ disabled={!xObjectApiKey}
593
+ >
594
+ {submitting ? '提交中...' : '提交'}
595
+ </Button>
596
+ {showResetButton && (
597
+ <Button
598
+ icon={<ReloadOutlined />}
599
+ onClick={this.handleReset}
600
+ disabled={submitting}
601
+ >
602
+ 重置
603
+ </Button>
604
+ )}
605
+ </Space>
606
+ </div>
607
+ </>
608
+ )}
609
+ </Spin>
610
+ </div>
611
+ </Card>
612
+ </div>
613
+ );
614
+ }
615
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @file Object Form 表单组件对接编辑器的描述文件
3
+ * @description 定义组件在 Neo 平台编辑器中的配置信息
4
+ * @author Neo Custom Widget CLI
5
+ * @version 1.0.0
6
+ */
7
+ export class EntityFormModel {
8
+ /**
9
+ * 组件类型标识
10
+ * 用于标识组件的唯一性,在构建时根据当前组件目录名称自动生成
11
+ * 注意:此字段在构建时会被自动替换,不需要手动设置
12
+ */
13
+ // cmpType: string = 'entityForm';
14
+
15
+ /** 组件名称,用于设置在编辑器左侧组件面板中展示的名称 */
16
+ label: string = '实体对象表单';
17
+
18
+ /** 组件描述,用于设置在编辑器左侧组件面板中展示的描述 */
19
+ description: string = '基于 XObject 的对象表单组件,用于新增数据';
20
+
21
+ /** 分类标签,用于设置在编辑器左侧组件面板哪个分类中展示(可设置多个分类标签) */
22
+ // tags: string[] = ['自定义组件'];
23
+
24
+ /**
25
+ * 用于设置组件支持的页面类型
26
+ *
27
+ * 当前 NeoCRM 平台存在的页面类型:
28
+ * all: 1 全页面
29
+ * indexPage: 2 首页
30
+ * entityListPage: 3 实体列表页
31
+ * entityFormPage: 4 实体表单页
32
+ * entityDetailPage: 5 实体详情页
33
+ * customPage: 6 自定义页面
34
+ * bizPage: 7 业务页面
35
+ */
36
+ // targetPage: string[] = ['customPage'];
37
+
38
+ /** 组件图标,用于设置在编辑器左侧组件面板中展示的图标 */
39
+ iconSrc: string = 'https://custom-widgets.bj.bcebos.com/custom-form.svg';
40
+
41
+ /** 初次插入页面的默认属性数据 */
42
+ defaultComProps = {
43
+ formTitle: '新增数据表单',
44
+ showResetButton: true,
45
+ columnCount: 1,
46
+ xObjectDataApi: {
47
+ xObjectApiKey: 'customContact__c',
48
+ fields: ['name', 'entityType', 'phone__c'],
49
+ },
50
+ };
51
+
52
+ /**
53
+ * 组件属性配置模式
54
+ * 支持静态配置:propsSchema,优先级比 propsSchemaCreator 低
55
+ * 定义组件在编辑器中可配置的属性
56
+ */
57
+ propsSchema = [
58
+ {
59
+ type: 'text',
60
+ name: 'formTitle',
61
+ label: '表单标题',
62
+ value: '新增数据表单',
63
+ placeholder: '请输入表单标题',
64
+ },
65
+ {
66
+ type: 'xObjectDataApi', // 用于获取实体业务数据列表的配置项
67
+ name: 'xObjectDataApi',
68
+ label: '实体数据源',
69
+ /*
70
+ value: {
71
+ xObjectApiKey: 'customContact__c',
72
+ fields: ['name', 'entityType', 'phone__c'],
73
+ },
74
+ */
75
+ placeholder: '请选择实体数据源',
76
+ custom: true,
77
+ showPage: false,
78
+ showPageSize: false,
79
+ showAutoFetchData: false,
80
+ },
81
+ {
82
+ type: 'select',
83
+ name: 'columnCount',
84
+ label: '表单列数',
85
+ value: 1,
86
+ placeholder: '请选择表单列数',
87
+ options: [
88
+ {
89
+ label: '单列',
90
+ value: 1,
91
+ },
92
+ {
93
+ label: '双列',
94
+ value: 2,
95
+ },
96
+ ],
97
+ },
98
+ {
99
+ type: 'switch',
100
+ name: 'showResetButton',
101
+ label: '显示重置按钮',
102
+ value: true,
103
+ },
104
+ ];
105
+ }
106
+
107
+ export default EntityFormModel;