@hzab/form-render 1.6.6 → 1.6.8-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,4 +1,12 @@
1
- # @hzab/form-render@1.6.6
1
+ # @hzab/form-render@1.6.9
2
+
3
+ feat: 添加主题色配置
4
+
5
+ # @hzab/form-render@1.6.8
6
+
7
+ feat:富文本组件添加私有化部署文件上传与oss上传的区分
8
+
9
+ # @hzab/form-render@1.6.7
2
10
 
3
11
  fix: 修复 LocationListPicker 组件在编辑时第一次无法正确渲染的 bug。
4
12
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/form-render",
3
- "version": "1.6.6",
3
+ "version": "1.6.8-beta",
4
4
  "description": "",
5
5
  "main": "src",
6
6
  "scripts": {
@@ -21,6 +21,7 @@
21
21
  "@hzab/data-model": "^1.2.0",
22
22
  "@hzab/permissions": "^0.1.1",
23
23
  "@hzab/webpack-config": "0.0.12",
24
+ "@hzab/theme-tools": "^0.0.2",
24
25
  "@types/react": "^17.0.62",
25
26
  "@types/react-dom": "^17.0.20",
26
27
  "antd": "^4.24.12",
@@ -38,6 +38,8 @@ export const arrayList = ["ArrayTable", "ArrayCards"];
38
38
  export const skipBindList = ["FormCollapse", "FormCollapse.CollapsePanel"];
39
39
  /** change 回调返回 parent 数据的组件 */
40
40
  export const returnParentValue = ["ArrayTable", "ArrayCards"];
41
+ /** 自定义样式中需要为下拉窗口或弹窗添加popupClassName的组件 */
42
+ export const addPopupClassName = ["Cascader", "TreeSelect", "Select", "TimePicker", "DatePicker", "DatePicker.RangePicker", "TimePicker.RangePicker", "UserSelect"]
41
43
 
42
44
  /**
43
45
  * schema 每项添加 onChange,解决无全局 onChange 问题
@@ -64,6 +66,12 @@ export const bindOnChange = (schema, opt) => {
64
66
  } else if (isScopeKey(comProps, schemaScope)) {
65
67
  item["x-component-props"] = getScopeKeyVal(comProps, schemaScope) || {};
66
68
  }
69
+ // 为自定义主题时存在弹窗或下拉框的组件添加类名
70
+ if (opt?.customTheme) {
71
+ if (addPopupClassName.includes(item["x-component"])) {
72
+ item["x-component-props"].popupClassName = typeof opt.customTheme === 'string' ? `form-dialog-custom-theme-${opt.customTheme}` : 'form-dialog-custom-theme';
73
+ }
74
+ }
67
75
 
68
76
  const bindParams = {
69
77
  componentName,
@@ -60,8 +60,7 @@ export const LocationListPicker = observer((props) => {
60
60
  }, []);
61
61
 
62
62
  useEffect(() => {
63
- listRef.current = value || [];
64
- if (!Array.isArray(value) || value?.length == 0 || !mapUtilsRef.current) {
63
+ if (!Array.isArray(value) || value?.length == 0) {
65
64
  return;
66
65
  }
67
66
  // 处理 id
@@ -70,6 +69,10 @@ export const LocationListPicker = observer((props) => {
70
69
  it.id = nanoid();
71
70
  }
72
71
  });
72
+ listRef.current = value || [];
73
+ if (!mapUtilsRef.current) {
74
+ return;
75
+ }
73
76
  renderMarker();
74
77
  }, [value]);
75
78
 
@@ -89,6 +92,7 @@ export const LocationListPicker = observer((props) => {
89
92
  mapUtilsRef.current.setCircle(item.longitude, item.latitude, item.range, { ...item });
90
93
  }
91
94
  });
95
+ mapUtilsRef.current.setFitView();
92
96
  clearActive();
93
97
  }
94
98
 
@@ -106,7 +110,6 @@ export const LocationListPicker = observer((props) => {
106
110
  });
107
111
 
108
112
  renderMarker();
109
- mapUtilsRef.current.setFitView();
110
113
  }
111
114
 
112
115
  function onAddClick() {
@@ -2,7 +2,8 @@ import "@wangeditor/editor/dist/css/style.css"; // 引入 css
2
2
  import React, { useState, useEffect, useImperativeHandle, forwardRef } from "react";
3
3
  import { Editor as WangEditor, Toolbar } from "@wangeditor/editor-for-react";
4
4
  import { IDomEditor, IEditorConfig, IToolbarConfig } from "@wangeditor/editor";
5
- import UploadOss from "./common/ossUpload";
5
+ import { getOssUploadRequest, getOfflineUploadRequest } from "../Upload/common/customRequest";
6
+ import { handlePreviewUrls } from "../Upload/common/OfflineUpload";
6
7
  import "./index.less";
7
8
  import { Spin, message } from 'antd';
8
9
  import { connect, mapProps, observer } from "@formily/react";
@@ -15,11 +16,16 @@ interface PropsType {
15
16
  toolbarConfig?: Partial<IToolbarConfig>;
16
17
  editorConfig?: Partial<IEditorConfig>;
17
18
  ossOpt: AnyObject,
18
- params: AnyObject,
19
+ uploadParams: AnyObject,
19
20
  height: string,
21
+ ossServerUrl: string,
20
22
  ossUrl: string,
23
+ offlinePreviewUrl: string,
24
+ offlineServerUrl: string,
21
25
  value: string,
22
26
  onChange: any,
27
+ customRequest: any,
28
+ uploadMode: string,
23
29
  zIndex: number
24
30
  }
25
31
 
@@ -31,10 +37,18 @@ export const RichEditor = observer(function (props: PropsType, parentRef) {
31
37
  onChange,
32
38
  value,
33
39
  ossOpt,
40
+ uploadMode = "oss",
41
+ offlinePreviewUrl = "",
42
+ offlineServerUrl = "",
43
+ uploadParams = {},
34
44
  // ossUrl = "https://test-abt.hzabjt.com:18091/api/v1/user/oss/getWebOssConfig",
45
+ ossServerUrl = "/api/v1/user/oss/getWebOssConfig",
35
46
  ossUrl = "/api/v1/user/oss/getWebOssConfig",
36
47
  zIndex = 9999
37
48
  } = props;
49
+ const isPrivateStore =
50
+ props.uploadParams?.fileAcl === "private" || props.ossOpt?.signatureParams?.fileAcl === "private";
51
+
38
52
  useImperativeHandle(parentRef, () => ({
39
53
  setEditorContent,
40
54
  getEditorContent,
@@ -57,6 +71,40 @@ export const RichEditor = observer(function (props: PropsType, parentRef) {
57
71
  return html;
58
72
  };
59
73
 
74
+
75
+ const customUpload = async (file: File, insertFn) => {
76
+ let customRequest = props.customRequest;
77
+ if (uploadMode === "oss") {
78
+ customRequest = getOssUploadRequest({
79
+ ...props,
80
+ isPrivateStore,
81
+ params: uploadParams,
82
+ ossServerUrl: ossServerUrl || ossUrl,
83
+ });
84
+ } else if (uploadMode === "offline") {
85
+ customRequest = getOfflineUploadRequest({
86
+ ...props,
87
+ isPrivateStore,
88
+ params: uploadParams,
89
+ offlineServerUrl: offlineServerUrl || ossUrl,
90
+ offlinePreviewUrl: offlinePreviewUrl,
91
+ });
92
+ }
93
+ setIsLoading(true);
94
+ customRequest({
95
+ file,
96
+ onSuccess: (res) => {
97
+ setIsLoading(false);
98
+ console.log(res)
99
+ insertFn(res.url, '', '');
100
+ },
101
+ onError: () => {
102
+ setIsLoading(false);
103
+ message.error(`${file.name} 上传失败`);
104
+ }
105
+ })
106
+ }
107
+
60
108
  const config: Partial<IEditorConfig> = {
61
109
  // TS 语法
62
110
  placeholder: "请输入内容...",
@@ -74,19 +122,7 @@ export const RichEditor = observer(function (props: PropsType, parentRef) {
74
122
  withCredentials: false,
75
123
  // 超时时间,默认为 10 秒
76
124
  timeout: 5 * 1000, // 5 秒
77
- async customUpload(file: File, insertFn) {
78
- const ossUpload = new UploadOss({
79
- serverUrl: ossUrl,
80
- ...ossOpt,
81
- });
82
- const res = await ossUpload.upload(file, {
83
- params: {
84
- isPublic: 1,
85
- ...(props.params || {}),
86
- },
87
- })
88
- insertFn(res?.data?.data?.fileUrl, '', '')
89
- },
125
+ customUpload,
90
126
  },
91
127
  uploadVideo: {
92
128
  // form-data fieldName ,默认值 'wangeditor-uploaded-image'
@@ -97,30 +133,13 @@ export const RichEditor = observer(function (props: PropsType, parentRef) {
97
133
  allowedFileTypes: ['video/*'],
98
134
  // 跨域是否传递 cookie ,默认为 false
99
135
  withCredentials: false,
100
- customUpload(file: File, insertFn) {
101
- setIsLoading(true)
102
- const ossUpload = new UploadOss({
103
- serverUrl: ossUrl,
104
- ...ossOpt,
105
- });
106
- ossUpload.upload(file, {
107
- params: {
108
- isPublic: 1,
109
- ...(props.params || {}),
110
- },
111
- }).then((res) => {
112
- setIsLoading(false)
113
- insertFn(res?.data?.data?.fileUrl, '', '')
114
- }).catch(() => {
115
- setIsLoading(false)
116
- message.error(`${file.name} 上传失败`);
117
- })
118
- },
136
+ customUpload,
119
137
  },
120
138
  },
121
139
  ...editorConfig,
122
140
  };
123
141
 
142
+
124
143
  const onEditorChange = (e) => {
125
144
  const content = e.getHtml();
126
145
  setHtml(content);
@@ -0,0 +1,488 @@
1
+ @primaryColor: var(--form-render-primary-color); // 主题色
2
+ @textColor: var(--form-render-color); // 字体颜色
3
+ @bgColor: var(--form-render-bg-color); // 背景颜色
4
+ @tableBgColor: var(--form-render-table-bg-color); // 表格背景颜色
5
+ @tableColor: var(--form-render-table-color); // 表格字体颜色
6
+ @talbeBorderColor: var(--form-render-table-border-color); // 表格边框颜色
7
+ @tableWrapperBorderColor: var(--form-render-table-wrapper-border-color); // 表格表头下边框颜色
8
+ @tableCellHoverBgColor: var(--form-render-table-cell-hover-bg-color); // 表格单元格滑过背景颜色
9
+ @tableCellHoverColor: var(--form-render-table-cell-hover-color); // 表格单元格滑过字体颜色
10
+ @btnOkColor: var(--form-render-btn-ok-color); // 确认按钮字体颜色
11
+ @btnOkBgColor: var(--form-render-btn-ok-bg-color); // 确认按钮背景颜色
12
+ @btnOkBgHoverColor: var(--form-render-btn-ok-bg-hover-color); // 确认按钮滑过字体颜色
13
+ @btnOkBorderColor: var(--form-render-btn-ok-border-color); // 确认按钮边框颜色
14
+ @btnDefaultColor: var(--form-render-btn-default-color); // 默认按钮字体颜色
15
+ @btnDefaultBgColor: var(--form-render-btn-default-bg-color); // 默认按钮背景颜色
16
+ @btnDefaultBorderColor: var(--form-render-btn-default-border-color); // 默认按钮边框颜色
17
+ @btnDefaultBgHoverColor: var(--form-render-btn-default-bg-hover-color); // 默认按钮滑过背景颜色
18
+ @inputColor: var(--form-render-input-color); // 输入框字体颜色
19
+ @formLabelColor: var(--form-render-form-label-color); // 表单项label字体颜色
20
+ @formReqiredColor: var(--form-render-form-required-color); // 表单项必填字体颜色
21
+ @inputHoverColor: var(--form-render-input-hover-color); // 输入框滑过字体颜色
22
+ @inputBgColor: var(--form-render-input-bg-color); // 输入框背景颜色
23
+ @inputBorderColor: var(--form-render-input-border-color); // 输入框边框颜色
24
+ @inputBorderHoverColor: var(--form-render-input-border-hover-color); // 输入框滑过边框颜色
25
+ @selectColor: var(--form-render-select-color); // 选择器字体颜色
26
+ @selectHoverColor: var(--form-render-select-hover-color); // 选择器滑过字体颜色
27
+ @selectBgColor: var(--form-render-select-bg-color); // 选择器背景颜色
28
+ @selectBgHoverColor: var(--form-render-select-bg-hover-color); // 选择器滑过背景颜色
29
+ @selectBorderColor: var(--form-render-select-border-color); // 选择器边框颜色
30
+ @iconColor: var(--form-render-icon-color); // 图标颜色
31
+ @iconHoverColor: var(--form-render-icon-hover-color); // 图标滑过颜色
32
+ @iconBgColor: var(--form-render-icon-bg-color); // 图标背景颜色
33
+ @iconBgHoverColor: var(--form-render-icon-bg-hover-color); // 图标滑过背景颜色
34
+ @pickerCellDisabled: var(--form-render-picker-cell-disabled); // 时间选择器禁用项字体颜色
35
+ @pickerRangeStartAEndBgColor: var(--form-render-picker-range-start-or-end-bg-color); // 时间选择器起止项背景颜色
36
+ @pickerRangeBgStartHoverColor: var(--form-render-picker-range-bg-start-hover-color); // 时间选择器滑过起始项字体颜色
37
+ @pickerRangeBgHoverColor: var(--form-render-picker-range-bg-hover-color); // 时间选择器选择区间背景颜色
38
+ @radioCheckedColor: var(--form-render-radio-checked-color); // 单选框选中状态颜色
39
+ @radioBgColor: var(--form-render-radio-bg-color); // 单选框背景颜色
40
+ @radioColor: var(--form-render-radio-color); // 单选框字体颜色
41
+ @checkboxCheckedColor: var(--form-render-checkbox-checked-color); // 复选框选中状态颜色
42
+ @checkboxBgColor: var(--form-render-checkbox-bg-color); // 复选框背景颜色
43
+ @checkboxColor: var(--form-render-checkbox-color); // 复选框字体颜色
44
+
45
+ // 表单项集合
46
+ .mixinColor() {
47
+ .ant-select:not(.ant-select-disabled) {
48
+ color: @selectColor;
49
+
50
+ &:hover {
51
+ color: @inputHoverColor;
52
+ }
53
+
54
+ .ant-select-selector {
55
+ background-color: @selectBgColor;
56
+
57
+ .ant-btn-icon-only {
58
+ color: @iconColor;
59
+ background-color: @selectBgColor;
60
+
61
+ &:hover {
62
+ color: @iconHoverColor;
63
+ background-color: @inputBgColor;
64
+ border-color: @inputBorderHoverColor;
65
+ }
66
+ }
67
+ }
68
+ }
69
+
70
+ .ant-select-tree {
71
+ color: @selectColor;
72
+ background-color: @selectBgColor;
73
+
74
+ .ant-select-tree-node-content-wrapper:hover,
75
+ .ant-select-tree-node-content-wrapper.ant-select-tree-node-selected {
76
+ color: @selectHoverColor;
77
+ background-color: @selectBgHoverColor;
78
+ }
79
+ }
80
+
81
+ .ant-select-item {
82
+ color: @selectColor;
83
+
84
+ .ant-select-item-option-content {
85
+ &>div {
86
+
87
+ >div,
88
+ >span {
89
+ color: @selectColor;
90
+ }
91
+ }
92
+
93
+ &:hover {
94
+ >div {
95
+
96
+ >div,
97
+ >span {
98
+ color: @selectHoverColor;
99
+ }
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ .ant-select-item.ant-select-item-option-selected,
106
+ .ant-select-item.ant-select-item-option-active {
107
+ color: @selectHoverColor;
108
+ background-color: @selectBgHoverColor;
109
+ }
110
+
111
+ .ant-select-arrow,
112
+ .ant-select-clear,
113
+ .ant-picker-suffix,
114
+ .ant-picker-clear,
115
+ .ant-collapse-expand-icon,
116
+ .ant-btn-icon-only,
117
+ .ant-table-cell button.ant-table-row-expand-icon {
118
+ color: @iconColor;
119
+ background-color: @iconBgColor;
120
+
121
+ &:hover {
122
+ color: @iconHoverColor;
123
+ background-color: @iconBgHoverColor;
124
+ }
125
+ }
126
+
127
+ .ant-formily-item-label {
128
+ color: @formLabelColor;
129
+
130
+ .ant-formily-item-asterisk {
131
+ color: @formReqiredColor;
132
+ }
133
+ }
134
+
135
+ .ant-input-affix-wrapper,
136
+ .ant-select:not(.ant-select-disabled) .ant-select-selector,
137
+ .ant-input-number,
138
+ .ant-upload,
139
+ .ant-collapse-item,
140
+ .ant-collapse-content,
141
+ .ant-card-head,
142
+ .ant-collapse-header-text,
143
+ .ant-picker-header,
144
+ .ant-picker-header button,
145
+ .ant-input {
146
+ color: @inputColor;
147
+ background-color: @inputBgColor;
148
+ border-color: @inputBorderColor;
149
+
150
+ &:not(.ant-card-head):hover {
151
+ color: @inputHoverColor;
152
+ border-color: @inputBorderHoverColor;
153
+ }
154
+ }
155
+
156
+ .ant-picker {
157
+ color: @inputColor;
158
+ background-color: @inputBgColor;
159
+ border-color: @inputBorderColor;
160
+
161
+ .ant-picker-input>input {
162
+ color: @inputColor;
163
+
164
+ &:hover {
165
+ color: @inputHoverColor;
166
+ }
167
+ }
168
+
169
+ .ant-picker-separator {
170
+ color: @inputColor;
171
+
172
+ &:hover {
173
+ color: @inputHoverColor;
174
+ }
175
+ }
176
+ }
177
+
178
+ .ant-picker-panel {
179
+ .ant-picker-body {
180
+ .ant-picker-content {
181
+ .ant-picker-cell {
182
+ color: @selectColor;
183
+
184
+ &:hover:not(.ant-picker-cell-selected):not(.ant-picker-cell-range-start):not(.ant-picker-cell-range-end):not(.ant-picker-cell-range-hover-start):not(.ant-picker-cell-range-hover-end) {
185
+ .ant-picker-cell-inner {
186
+ background-color: @selectBgHoverColor;
187
+ color: @selectHoverColor;
188
+ }
189
+ }
190
+
191
+ &:hover:not(.ant-picker-cell-in-view) {
192
+ .ant-picker-cell-inner {
193
+ background-color: @selectBgHoverColor;
194
+ }
195
+ }
196
+
197
+ &.ant-picker-cell-in-view.ant-picker-cell-range-end:not(.ant-picker-cell-range-end-single) {
198
+ &::before {
199
+ background-color: @selectBgHoverColor;
200
+ }
201
+ }
202
+
203
+ &.ant-picker-cell-in-view.ant-picker-cell-in-range {
204
+ &::before {
205
+ background-color: @selectBgHoverColor;
206
+ }
207
+
208
+ &.ant-picker-cell-range-hover-start,
209
+ &.ant-picker-cell-range-hover-end {
210
+ &::before {
211
+ background-color: @pickerRangeBgStartHoverColor;
212
+ }
213
+
214
+ .ant-picker-cell-inner {
215
+ &::after {
216
+ background-color: @pickerRangeBgStartHoverColor;
217
+ }
218
+ }
219
+ }
220
+
221
+ &.ant-picker-cell-range-hover {
222
+ &::before {
223
+ background-color: @pickerRangeBgHoverColor;
224
+ }
225
+ }
226
+
227
+ .ant-picker-cell-inner {
228
+ color: @selectHoverColor;
229
+
230
+ &::after {
231
+ background-color: @selectBgHoverColor;
232
+ }
233
+ }
234
+ }
235
+
236
+ &.ant-picker-cell-in-view {
237
+ color: @selectHoverColor;
238
+
239
+ &.ant-picker-cell-range-start:not(.ant-picker-cell-range-start-single),
240
+ &.ant-picker-cell-range-end {
241
+ &::before {
242
+ background-color: @pickerRangeStartAEndBgColor;
243
+ }
244
+ }
245
+
246
+ &.ant-picker-cell-selected {
247
+ .ant-picker-cell-inner {
248
+ background-color: @pickerRangeStartAEndBgColor;
249
+ ;
250
+ }
251
+ }
252
+
253
+ &.ant-picker-cell-disabled {
254
+ color: @pickerCellDisabled;
255
+ }
256
+ }
257
+ }
258
+ }
259
+ }
260
+ }
261
+
262
+ .ant-radio-group {
263
+ .ant-radio-wrapper {
264
+ .ant-radio+span {
265
+ color: @radioColor;
266
+ }
267
+
268
+ &.ant-radio-wrapper-checked {
269
+ .ant-radio.ant-radio-checked {
270
+ .ant-radio-inner {
271
+ background-color: @radioBgColor;
272
+
273
+ &::after {
274
+ background-color: @radioCheckedColor;
275
+ }
276
+ }
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ .ant-checkbox-group {
283
+ .ant-checkbox-wrapper {
284
+ .ant-checkbox+span {
285
+ color: @checkboxColor;
286
+ }
287
+
288
+ &.ant-checkbox-wrapper-checked {
289
+ .ant-checkbox.ant-checkbox-checked {
290
+ .ant-checkbox-inner {
291
+ background-color: @checkboxBgColor;
292
+
293
+ &::after {
294
+ border-color: @checkboxCheckedColor;
295
+ }
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+
302
+ .ant-upload-list-item-actions {
303
+ a {
304
+ color: @iconColor;
305
+ }
306
+ }
307
+
308
+ .ant-upload-span {
309
+ color: @inputColor;
310
+ fill: @inputColor;
311
+ }
312
+
313
+ .ant-switch {
314
+ background-color: @inputColor;
315
+
316
+ &.ant-switch-checked {
317
+ background-color: @primaryColor;
318
+
319
+ &:focus {
320
+ box-shadow: none;
321
+ }
322
+ }
323
+ }
324
+
325
+
326
+ .ant-cascader-menu-item {
327
+ &:hover {
328
+ background-color: @selectBgHoverColor;
329
+ }
330
+
331
+ &.ant-cascader-menu-item-active:not(.ant-cascader-menu-item-disabled) {
332
+ background-color: @selectBgHoverColor;
333
+ color: @selectHoverColor;
334
+ }
335
+ }
336
+
337
+ .ant-btn.ant-btn-primary {
338
+ color: @btnOkColor;
339
+ background-color: @btnOkBgColor;
340
+ border-color: @btnOkBorderColor;
341
+
342
+ &:hover,
343
+ &:focus {
344
+ border-color: @primaryColor;
345
+ background-color: @btnOkBgHoverColor;
346
+ }
347
+ }
348
+
349
+ .ant-btn.ant-btn-default {
350
+ color: @btnDefaultColor;
351
+ background-color: @btnDefaultBgColor;
352
+ border-color: @btnDefaultBorderColor;
353
+
354
+ &:hover,
355
+ &:focus {
356
+ color: @primaryColor;
357
+ border-color: @primaryColor;
358
+ background-color: @btnDefaultBgHoverColor;
359
+ }
360
+ }
361
+
362
+ .ant-btn.ant-btn-dashed {
363
+ color: @btnDefaultColor;
364
+ background-color: @btnDefaultBgColor;
365
+ border-color: @btnDefaultBorderColor;
366
+
367
+ &:hover,
368
+ &:focus {
369
+ color: @primaryColor;
370
+ border-color: @primaryColor;
371
+ }
372
+ }
373
+ }
374
+
375
+ .form-render-custom-theme {
376
+ background-color: @bgColor;
377
+ color: @textColor;
378
+
379
+ .ant-formily-item,
380
+ .ant-collapse,
381
+ .ant-card,
382
+ .ant-formily-array-table .ant-formily-array-table-sort-helper {
383
+ background-color: @bgColor;
384
+ color: @textColor;
385
+ .mixinColor();
386
+
387
+ .ant-table-cell {
388
+ .ant-empty-normal {
389
+ color: @tableColor;
390
+ }
391
+
392
+ &:hover {
393
+ background-color: @tableCellHoverBgColor;
394
+
395
+ .ant-empty-normal {
396
+ color: @tableCellHoverColor;
397
+ }
398
+ }
399
+ }
400
+ }
401
+
402
+ .ant-formily-item-control {
403
+ .ant-table {
404
+ background-color: @tableBgColor;
405
+ color: @tableColor;
406
+
407
+ .ant-formily-array-table .ant-formily-array-table-sort-helper {
408
+ background-color: @tableBgColor;
409
+ }
410
+
411
+ .ant-table-thead>tr>th {
412
+ background-color: @tableBgColor;
413
+ color: @tableColor;
414
+ }
415
+
416
+ .ant-table-row {
417
+
418
+ // 此处原因:会出现弹窗关闭后,鼠标刚好停留在外表格的某一行,导致ant-table-cell-row-hover类名未正常出现,渲染颜色错误
419
+ &:hover {
420
+ td {
421
+ background-color: @tableCellHoverBgColor;
422
+ color: @tableCellHoverColor;
423
+ }
424
+ }
425
+
426
+ & .ant-table-cell-row-hover {
427
+ background-color: @tableCellHoverBgColor;
428
+ color: @tableCellHoverColor;
429
+ }
430
+ }
431
+ }
432
+ }
433
+ }
434
+
435
+ .form-dialog-custom-theme {
436
+ background-color: @selectBgColor;
437
+ color: @selectColor;
438
+ .mixinColor();
439
+
440
+ .ant-table {
441
+ background-color: @tableBgColor;
442
+ color: @tableColor;
443
+
444
+ .ant-formily-array-table .ant-formily-array-table-sort-helper {
445
+ background-color: @tableBgColor;
446
+ }
447
+
448
+ .ant-table-thead>tr>th {
449
+ background-color: @tableBgColor;
450
+ color: @tableColor;
451
+ }
452
+
453
+ .ant-table-row {
454
+
455
+ // 此处原因:会出现弹窗关闭后,鼠标刚好停留在外表格的某一行,导致ant-table-cell-row-hover类名未正常出现,渲染颜色错误
456
+ &:hover {
457
+ td {
458
+ background-color: @tableCellHoverBgColor;
459
+ color: @tableCellHoverColor;
460
+ }
461
+ }
462
+ }
463
+ }
464
+
465
+ .ant-picker-panel-container {
466
+ color: @selectColor;
467
+ background-color: @selectBgColor;
468
+
469
+ .ant-picker-time-panel-cell .ant-picker-time-panel-cell-inner {
470
+ color: @selectColor;
471
+
472
+ &:hover {
473
+ background-color: @selectBgHoverColor;
474
+ color: @selectHoverColor;
475
+ }
476
+ }
477
+
478
+ .ant-picker-time-panel-cell-selected .ant-picker-time-panel-cell-inner {
479
+ background-color: @selectBgHoverColor;
480
+ color: @selectHoverColor;
481
+ }
482
+
483
+ }
484
+
485
+ .ant-empty-small {
486
+ color: @selectColor;
487
+ }
488
+ }
package/src/index.less CHANGED
@@ -1,18 +1,22 @@
1
1
  .form-render {
2
+
2
3
  &.ant-form-inline,
3
- &.ant-form-inline > form,
4
- &.ant-form-inline > form > .ant-formily-layout {
4
+ &.ant-form-inline>form,
5
+ &.ant-form-inline>form>.ant-formily-layout {
5
6
  display: inline-flex;
6
7
  flex-wrap: wrap;
8
+
7
9
  .ant-formily-item-control {
8
10
  min-width: 120px;
9
11
  }
12
+
10
13
  .ant-picker-range {
11
14
  min-width: 340px;
12
15
  }
16
+
13
17
  .ant-formily-item-layout-inline {
14
18
  margin-right: 12px;
15
19
  margin-bottom: 12px;
16
20
  }
17
21
  }
18
- }
22
+ }
package/src/index.tsx CHANGED
@@ -37,6 +37,7 @@ import { GlobalPropsContext } from "./common/global-props-context";
37
37
  import { bindOnChange } from "./common/schema-handler";
38
38
 
39
39
  import "./index.less";
40
+ import "./custom-theme.less";
40
41
 
41
42
  const antdComponents = {
42
43
  Form,
@@ -163,13 +164,16 @@ const FormRender = forwardRef((props: any, parentRef) => {
163
164
  schemaScope: schemaScopeRef.current,
164
165
  onChange: props.onChange,
165
166
  formRender,
167
+ customTheme: props.customTheme
166
168
  });
167
169
  }, []);
168
170
 
171
+ const className = props.customTheme === true ? 'form-render-custom-theme' : typeof props.customTheme === 'string' ? `form-render-${props.customTheme}` : '';
172
+
169
173
  return (
170
174
  <GlobalPropsContext.Provider value={props}>
171
175
  <Form
172
- className={`form-render ${props.className}`}
176
+ className={`form-render ${props.className} ${className}`}
173
177
  layout={props.layout}
174
178
  form={formRender}
175
179
  labelCol={props.schema.form.labelCol}
@@ -1,155 +0,0 @@
1
- import { axios } from "@hzab/data-model";
2
- import { nanoid } from "nanoid";
3
-
4
- export function getSignature(opt = {}) {
5
- const { serverUrl = "/api/v1/user/oss/getWebOssConfig" } = opt;
6
- // 减 10 秒,避免发起请求时 刚好过期的情况
7
- if (
8
- window.__ossSignatureRes &&
9
- serverUrl === window.__ossSignatureRes.serverUrl &&
10
- Date.now() - window.__ossSignatureRes.__saveTime < window.__ossSignatureRes.expireTimeMillis - 10000
11
- ) {
12
- return Promise.resolve(window.__ossSignatureRes);
13
- }
14
- const { axios: _ax = axios, params = {}, axiosConf } = opt;
15
- return _ax
16
- .get(serverUrl, {
17
- ...axiosConf,
18
- params: {
19
- isPublic: 1,
20
- ...params,
21
- },
22
- })
23
- .then((res) => {
24
- window.__ossSignatureRes = res?.data?.data;
25
- if (window.__ossSignatureRes) {
26
- window.__ossSignatureRes.__saveTime = Date.now();
27
- window.__ossSignatureRes.serverUrl = serverUrl;
28
- }
29
- return window.__ossSignatureRes;
30
- });
31
- }
32
-
33
- class OssUpload {
34
- constructor(props = {}) {
35
- this.axios = props.axios || axios;
36
- this.axiosConf = props.axiosConf || {};
37
- this.serverUrl = props.serverUrl || "/api/v1/user/oss/getWebOssConfig";
38
- this.signatureParams = props.signatureParams || {};
39
- }
40
-
41
- getSignature(serverUrl = this.serverUrl, opt) {
42
- return getSignature({
43
- ...opt,
44
- serverUrl,
45
- axios: opt?.axios || this.axios,
46
- axiosConf: { ...this.axiosConf, ...opt?.axiosConf },
47
- });
48
- }
49
-
50
- upload(file, opt = {}) {
51
- return new Promise(async (resolve, reject) => {
52
- const ossParams = await this.getSignature(opt.serverUrl || this.serverUrl, {
53
- ...opt,
54
- params: { ...this.signatureParams, ...opt.signatureParams },
55
- });
56
-
57
- const { ossParams: propOssParams } = opt || {};
58
- const formData = new FormData();
59
- // key 表示上传到 Bucket 内的 Object 的完整路径,例如 exampledir/exampleobject.txtObject,完整路径中不能包含 Bucket 名称。
60
- // filename 表示待上传的本地文件名称。
61
- let filename = file?.name;
62
- if (file?.name) {
63
- const nameArr = file?.name.match(/^(.+)\.(.+)$/);
64
- if (nameArr && nameArr.length > 2) {
65
- filename = `${nameArr[1]}_${Date.now()}_${nanoid()}.${nameArr[2]}`;
66
- }
67
- }
68
- if (!filename) {
69
- filename = `${Date.now()}_${nanoid()}.${file.type?.replace(/\w+\/, ''/)}`;
70
- }
71
- const key = `${ossParams?.dir}${filename}`;
72
- formData.set("key", key);
73
- formData.set("OSSAccessKeyId", ossParams.accessid);
74
- formData.set("policy", ossParams.policy);
75
- formData.set("Signature", ossParams.signature);
76
- if (ossParams.callback) {
77
- formData.set("callback", ossParams.callback);
78
- }
79
- formData.set("success_action_status", 200);
80
- formData.set("file", file);
81
-
82
- if (propOssParams) {
83
- for (const key in propOssParams) {
84
- if (Object.hasOwnProperty.call(propOssParams, key)) {
85
- formData.set(key, propOssParams[key]);
86
- }
87
- }
88
- }
89
-
90
- const _axios = opt?.axios || this.axios;
91
-
92
- return _axios
93
- .post(ossParams.host, formData, { ...this.axiosConf, ...opt?.axiosConf })
94
- .then((res) => {
95
- resolve(res);
96
- return res;
97
- })
98
- .catch((err) => {
99
- console.error("oss upload err", err);
100
- reject(err);
101
- return Promise.reject(err);
102
- });
103
- });
104
- }
105
- }
106
-
107
- /**
108
- * 处理文件上传逻辑
109
- * @param {Array} files
110
- * @param {Object} opt
111
- * @returns
112
- */
113
- export async function handleOssUpload(files, opt) {
114
- const _files = files;
115
- const { ossUrl, signatureParams, ossParams, axiosConf } = opt || {};
116
- const ossUpload = new OssUpload({
117
- axios: opt.axios,
118
- axiosConf: axiosConf,
119
- serverUrl: ossUrl || "/api/v1/user/oss/getWebOssConfig",
120
- });
121
-
122
- const promise = [];
123
- _files?.forEach((file) => {
124
- // 数据已经是 url 的情况
125
- if (typeof file === "string" || file.ossUrl) {
126
- promise.push(Promise.resolve(file));
127
- } else {
128
- promise.push(
129
- ossUpload
130
- .upload(file, {
131
- signatureParams: {
132
- isPublic: 1,
133
- ...(signatureParams || {}),
134
- },
135
- ossParams,
136
- axiosConf,
137
- })
138
- .then((res) => {
139
- return Promise.resolve(res?.data?.data?.fileUrl);
140
- }),
141
- );
142
- }
143
- });
144
-
145
- return Promise.all(promise).then((filePromises) => {
146
- filePromises?.forEach((fileUrl, idx) => {
147
- _files[idx].ossUrl = fileUrl;
148
- });
149
- return Promise.resolve(_files);
150
- });
151
- }
152
-
153
- export { axios };
154
-
155
- export default OssUpload;