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,260 @@
1
+ .contact-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
+ .contact-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
+ .contact-card-content {
114
+ display: flex;
115
+ align-items: center;
116
+ width: 100%;
117
+ gap: 12px;
118
+
119
+ .contact-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
+ .contact-info {
130
+ flex: 1;
131
+ min-width: 0;
132
+
133
+ .contact-name,
134
+ .contact-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
+ .contact-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
+ .contact-card {
207
+ .ant-card-body {
208
+ padding: 12px;
209
+ }
210
+
211
+ .contact-card-content {
212
+ gap: 8px;
213
+
214
+ .contact-avatar {
215
+ .avatar-icon {
216
+ width: 40px !important;
217
+ height: 40px !important;
218
+ line-height: 40px !important;
219
+ }
220
+ }
221
+
222
+ .contact-info {
223
+ .contact-name,
224
+ .contact-phone {
225
+ .name-text,
226
+ .phone-text {
227
+ font-size: 13px;
228
+ }
229
+ }
230
+ }
231
+ }
232
+ }
233
+ }
234
+
235
+ @media (max-width: 480px) {
236
+ .contact-card {
237
+ .contact-card-content {
238
+ flex-direction: column;
239
+ text-align: center;
240
+ gap: 8px;
241
+
242
+ .contact-info {
243
+ .contact-name,
244
+ .contact-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
+ }
@@ -0,0 +1,94 @@
1
+ # 联系人表单组件
2
+
3
+ 基于 Ant Design 的联系人表单组件,支持姓名、所有人、业务类型、所属部门、手机号等字段的输入和提交。
4
+
5
+ ## 功能特性
6
+
7
+ - ✅ 基于 Ant Design 4.x 组件库
8
+ - ✅ 表单字段验证(姓名和手机号为必填项)
9
+ - ✅ 手机号格式验证
10
+ - ✅ 数据提交到 Neo 平台 API
11
+ - ✅ 加载状态显示
12
+ - ✅ 成功/错误消息提示
13
+ - ✅ 响应式设计
14
+ - ✅ 使用 React state 管理表单数据
15
+
16
+ ## 表单字段
17
+
18
+ | 字段名 | 类型 | 必填 | 说明 |
19
+ |--------|------|------|------|
20
+ | 姓名 | text | ✅ | 联系人姓名 |
21
+ | 所有人 | number | ❌ | 联系人用户ID (userId) |
22
+ | 业务类型 | select | ❌ | 销售/市场/客服/技术/其他 (entityType) |
23
+ | 所属部门 | number | ❌ | 联系人所属部门ID (dimDepart) |
24
+ | 手机号 | number | ✅ | 联系人手机号(格式验证)(phone__c) |
25
+
26
+ ## API 接口
27
+
28
+ 组件会将表单数据提交到以下接口:
29
+
30
+ ```
31
+ POST /rest/data/v2.0/xobjects/customContact__c
32
+ ```
33
+
34
+ ### 请求数据格式
35
+
36
+ ```json
37
+ {
38
+ "name": "张三",
39
+ "userId": 12345,
40
+ "entityType": 3998003734470119,
41
+ "dimDepart": 67890,
42
+ "phone__c": "13800138000"
43
+ }
44
+ ```
45
+
46
+ ## 组件属性
47
+
48
+ | 属性名 | 类型 | 默认值 | 说明 |
49
+ |--------|------|--------|------|
50
+ | title | string | '创建联系人' | 表单标题 |
51
+ | data | object | {} | Neo 平台数据(包含用户信息和系统信息) |
52
+
53
+ ## 使用示例
54
+
55
+ ```tsx
56
+ import ContactForm from './components/contact-form';
57
+
58
+ // 在页面中使用
59
+ <ContactForm
60
+ title="创建新联系人"
61
+ data={amisData}
62
+ />
63
+ ```
64
+
65
+ ## 技术栈
66
+
67
+ - React 16.9.0
68
+ - TypeScript
69
+ - Ant Design 4.x
70
+ - SCSS
71
+
72
+ ## 样式定制
73
+
74
+ 组件基于 Ant Design 设计规范,支持通过 SCSS 进行样式定制:
75
+
76
+ ```scss
77
+ .contact-form-container {
78
+ .contact-form-card {
79
+ // 卡片样式定制
80
+ }
81
+
82
+ .contact-form {
83
+ // 表单样式定制
84
+ }
85
+ }
86
+ ```
87
+
88
+ ## 注意事项
89
+
90
+ 1. 确保 Neo 平台已正确配置 `customContact__c` 对象
91
+ 2. 组件依赖 `antd` 和 `axios` 进行 UI 渲染和 API 调用
92
+ 3. 需要确保用户有创建联系人的权限
93
+ 4. 手机号格式验证仅支持中国大陆手机号(1开头的11位数字)
94
+ 5. 组件使用 React state 管理表单数据,无需手动处理 ref
@@ -0,0 +1,251 @@
1
+ import * as React from 'react';
2
+ import { Form, Input, Select, Button, message, Card } from 'antd';
3
+ import { getEntityTypeList, createXObject } from '../../utils/xobjects';
4
+ const { Option } = Select;
5
+
6
+ import './style.scss';
7
+
8
+ interface ContactFormProps {
9
+ title: string;
10
+ data?: any;
11
+ }
12
+
13
+ interface ContactFormState {
14
+ formData: {
15
+ name: string;
16
+ entityType?: number;
17
+ phone__c: string;
18
+ };
19
+ entityTypeList: any[];
20
+ loading: boolean;
21
+ }
22
+
23
+ export default class ContactForm extends React.PureComponent<
24
+ ContactFormProps,
25
+ ContactFormState
26
+ > {
27
+ private formRef: any;
28
+
29
+ constructor(props: ContactFormProps) {
30
+ super(props);
31
+
32
+ this.state = {
33
+ formData: {
34
+ name: 'wibetter',
35
+ phone__c: '15900000003',
36
+ },
37
+ entityTypeList: [],
38
+ loading: false,
39
+ };
40
+
41
+ // 获取业务类型列表
42
+ getEntityTypeList('customContact__c').then((res: any) => {
43
+ if (res && res.code === '200') {
44
+ const result = res.data || {};
45
+ this.setState({
46
+ entityTypeList: result.records || [],
47
+ });
48
+ }
49
+ });
50
+
51
+ this.handleInputChange = this.handleInputChange.bind(this);
52
+ this.handleSubmit = this.handleSubmit.bind(this);
53
+ this.resetForm = this.resetForm.bind(this);
54
+ }
55
+
56
+ handleInputChange(
57
+ field: keyof ContactFormState['formData'],
58
+ value: string | number,
59
+ ) {
60
+ this.setState((prevState) => ({
61
+ formData: {
62
+ ...prevState.formData,
63
+ [field]: value,
64
+ },
65
+ }));
66
+ }
67
+
68
+ validateForm() {
69
+ const { formData } = this.state;
70
+
71
+ if (!formData.name.trim()) {
72
+ message.error('请输入联系人姓名');
73
+ return false;
74
+ }
75
+
76
+ if (!formData.phone__c.trim()) {
77
+ message.error('请输入手机号');
78
+ return false;
79
+ }
80
+
81
+ // 手机号格式验证
82
+ const phoneRegex = /^1[3-9]\d{9}$/;
83
+ if (!phoneRegex.test(formData.phone__c)) {
84
+ message.error('请输入正确的手机号格式');
85
+ return false;
86
+ }
87
+
88
+ return true;
89
+ }
90
+
91
+ async handleSubmit() {
92
+ if (!this.validateForm()) {
93
+ return;
94
+ }
95
+ this.setState({ loading: true });
96
+
97
+ try {
98
+ const { formData } = this.state;
99
+ // 获取当前用户信息
100
+ const curAmisData = this.props.data || {};
101
+ const userInfo = curAmisData.__NeoCurrentUser;
102
+
103
+ // 准备提交的数据
104
+ let submitData = {
105
+ name: formData.name.trim(),
106
+ phone__c: formData.phone__c.trim(),
107
+ entityType: formData.entityType
108
+ };
109
+
110
+ if (userInfo && userInfo.id) {
111
+ submitData = Object.assign(submitData, {
112
+ userId: userInfo.id,
113
+ dimDepart: userInfo.departId,
114
+ });
115
+ }
116
+
117
+ console.log('提交联系人数据:', submitData);
118
+
119
+ // 调用 API 提交数据
120
+ const response: any = await createXObject('customContact__c', {
121
+ method: 'POST',
122
+ data: submitData,
123
+ });
124
+
125
+ if (response && response.code === '200') {
126
+ console.log('联系人创建成功:', response.data);
127
+
128
+ message.success('联系人创建成功!');
129
+ // 成功后重置表单
130
+ setTimeout(() => {
131
+ this.resetForm();
132
+ }, 1000);
133
+ } else {
134
+ message.error('创建联系人失败:', response.message);
135
+ }
136
+ } catch (error: any) {
137
+ message.error('创建联系人失败:', error);
138
+ } finally {
139
+ this.setState({ loading: false });
140
+ }
141
+ }
142
+
143
+ resetForm() {
144
+ this.setState({
145
+ formData: {
146
+ name: '',
147
+ phone__c: '',
148
+ },
149
+ });
150
+
151
+ // 重置 Ant Design 表单
152
+ if (this.formRef) {
153
+ this.formRef.resetFields();
154
+ }
155
+ }
156
+
157
+ render() {
158
+ const { title } = this.props;
159
+ const { formData, loading, entityTypeList } = this.state;
160
+ const curAmisData = this.props.data || {};
161
+ const systemInfo = curAmisData.__NeoSystemInfo || {};
162
+
163
+ return (
164
+ <div className="contact-form-container">
165
+ <Card
166
+ title={title || '创建联系人'}
167
+ extra={systemInfo.tenantName ? `【${systemInfo.tenantName}】` : ''}
168
+ className="contact-form-card"
169
+ >
170
+ <Form
171
+ ref={(ref) => {
172
+ this.formRef = ref;
173
+ }}
174
+ layout="vertical"
175
+ className="contact-form"
176
+ initialValues={formData}
177
+ >
178
+ <Form.Item
179
+ label="姓名"
180
+ required
181
+ rules={[{ required: true, message: '请输入联系人姓名' }]}
182
+ >
183
+ <Input
184
+ value={formData.name}
185
+ onChange={(e) => this.handleInputChange('name', e.target.value)}
186
+ placeholder="请输入联系人姓名"
187
+ disabled={loading}
188
+ />
189
+ </Form.Item>
190
+
191
+ <Form.Item
192
+ label="手机号"
193
+ required
194
+ rules={[
195
+ { required: true, message: '请输入手机号' },
196
+ { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式' },
197
+ ]}
198
+ >
199
+ <Input
200
+ value={formData.phone__c}
201
+ onChange={(e) =>
202
+ this.handleInputChange('phone__c', e.target.value)
203
+ }
204
+ placeholder="请输入手机号"
205
+ disabled={loading}
206
+ />
207
+ </Form.Item>
208
+
209
+ <Form.Item label="业务类型">
210
+ <Select
211
+ value={formData.entityType}
212
+ onChange={(value) =>
213
+ this.handleInputChange('entityType', value)
214
+ }
215
+ placeholder="请选择业务类型"
216
+ disabled={loading}
217
+ >
218
+ {entityTypeList.map((item) => (
219
+ <Option
220
+ key={item.apiKey}
221
+ value={item.id}
222
+ disabled={!item.active}
223
+ >
224
+ {item.label}
225
+ </Option>
226
+ ))}
227
+ </Select>
228
+ </Form.Item>
229
+
230
+ <Form.Item className="form-actions">
231
+ <Button
232
+ onClick={this.resetForm}
233
+ disabled={loading}
234
+ style={{ marginRight: 8 }}
235
+ >
236
+ 重置
237
+ </Button>
238
+ <Button
239
+ type="primary"
240
+ onClick={this.handleSubmit}
241
+ loading={loading}
242
+ >
243
+ 保存联系人
244
+ </Button>
245
+ </Form.Item>
246
+ </Form>
247
+ </Card>
248
+ </div>
249
+ );
250
+ }
251
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * @file 自定义组件对接编辑器的描述文件
3
+ */
4
+ export class ContactFormModel {
5
+ /**
6
+ * cmpType 为自定义组件名称,用于标识组件的唯一性
7
+ * 在构建时根据当前组件目录名称自动生成
8
+ */
9
+ // cmpType: string = 'contact-form';
10
+
11
+ // 组件名称,用于设置在编辑器左侧组件面板中展示的名称
12
+ label: string = '联系人表单';
13
+
14
+ // 组件描述,用于设置在编辑器左侧组件面板中展示的描述
15
+ description: string =
16
+ '基于 Ant Design 的联系人表单组件,支持姓名、所有人、业务类型、所属部门、手机号等字段';
17
+
18
+ // 分类标签,用于设置在编辑器左侧组件面板哪个分类中展示(可设置多个分类标签)
19
+ // tags: string[] = ['自定义组件'];
20
+
21
+ // 组件图标,用于设置在编辑器左侧组件面板中展示的图标
22
+ iconSrc: string = 'https://custom-widgets.bj.bcebos.com/contact-form.svg';
23
+
24
+ // 初次插入页面的默认属性数据
25
+ defaultComProps = {
26
+ title: '创建联系人',
27
+ label: '联系人表单',
28
+ };
29
+
30
+ // 设计器端预览时展示的默认数据
31
+ previewComProps = {
32
+ label: '联系人表单',
33
+ };
34
+
35
+ /**
36
+ * 组件面板配置,用于生成编辑器右侧属性配置面板内容
37
+ */
38
+ propsSchema = [
39
+ {
40
+ type: 'textarea',
41
+ name: 'title',
42
+ label: '表单标题',
43
+ value: '创建联系人',
44
+ placeholder: '请输入表单标题',
45
+ },
46
+ ];
47
+
48
+ // 支持 函数式写法:propsSchemaCreator,com 为组件实例。优先级比 propsSchema 高
49
+ /*
50
+ propsSchemaCreator = (com: any) => {
51
+ return [];
52
+ };
53
+ */
54
+ }
55
+
56
+ export default ContactFormModel;