@hzab/form-render 1.6.21-beta → 1.7.0

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,6 +1,7 @@
1
- # @hzab/form-render@1.6.21
1
+ # @hzab/form-render@1.7.0
2
2
 
3
- refactor: upload 接入 utils upload utils
3
+ refactor: upload 接入 @hzab/utils upload utils
4
+ feat: components 支持通过项目初始化时全局进行挂载 setFormilyGlobalComponents。便于对 formRender 进行组件拆分
4
5
 
5
6
  # @hzab/form-render@1.6.20
6
7
 
package/README.md CHANGED
@@ -10,6 +10,29 @@ formily schema 表单渲染组件
10
10
 
11
11
  ## 示例
12
12
 
13
+ #### 项目初始化时挂载全局组件
14
+
15
+ ```jsx
16
+ import { setFormilyGlobalComponents } from "@hzab/utils/src/formily/global-components";
17
+
18
+ // 挂载 Test1 组件到 formRender 组件
19
+ setFormilyGlobalComponents({
20
+ Test1() {
21
+ return <div>Test1</div>;
22
+ },
23
+ });
24
+
25
+ // 挂载 Test2 组件到 formRender 组件
26
+ setFormilyGlobalComponents({
27
+ Test2() {
28
+ return <div>Test2</div>;
29
+ },
30
+ Test3() {
31
+ return <div>Test3</div>;
32
+ },
33
+ });
34
+ ```
35
+
13
36
  ```jsx
14
37
  import FormRender from "@hzab/form-render";
15
38
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hzab/form-render",
3
- "version": "1.6.21-beta",
3
+ "version": "1.7.0",
4
4
  "description": "",
5
5
  "main": "src",
6
6
  "scripts": {
@@ -21,6 +21,7 @@
21
21
  "devDependencies": {
22
22
  "@hzab/data-model": "^1.8.8",
23
23
  "@hzab/permissions": "^0.1.1",
24
+ "@hzab/utils": "^1.0.6",
24
25
  "@hzab/webpack-config": "0.0.12",
25
26
  "@types/react": "^17.0.62",
26
27
  "@types/react-dom": "^17.0.20",
@@ -34,6 +35,7 @@
34
35
  "typescript": "^4.9.4"
35
36
  },
36
37
  "peerDependencies": {
38
+ "@hzab/utils": ">=1.0.6",
37
39
  "antd": "4.x",
38
40
  "axios": ">=1.6.2",
39
41
  "react": ">=16.8.0",
@@ -44,7 +46,6 @@
44
46
  "@formily/core": "2.3.1",
45
47
  "@formily/react": "2.3.1",
46
48
  "@formily/reactive-react": "2.3.1",
47
- "@hzab/utils": "^1.0.4",
48
49
  "@turf/turf": "^6.5.0",
49
50
  "@wangeditor/editor": "^5.1.23",
50
51
  "@wangeditor/editor-for-react": "^1.0.6",
@@ -95,7 +95,6 @@ export const RichEditor = observer(function (props: PropsType, parentRef) {
95
95
  file,
96
96
  onSuccess: (res) => {
97
97
  setIsLoading(false);
98
- console.log(res);
99
98
  insertFn(res.url, "", "");
100
99
  },
101
100
  onError: () => {
@@ -1,39 +1,4 @@
1
- import { checkImageUrl, checkVideoUrl, checkAudioUrl } from "./utils";
2
-
3
- export const TYPE_VIDEO = "video";
4
- export const TYPE_IMG = "image";
5
- export const TYPE_AUDIO = "audio";
6
-
7
- export function checkFileType(file) {
8
- const { type, url = file?.ossUrl } = file || {};
9
- let fileType = "";
10
- // 判断文件类型,获取对应展示的数据
11
- if (url) {
12
- // 图片
13
- if (url.startsWith("data:image/") || checkImageUrl(url)) {
14
- fileType = TYPE_IMG;
15
- } else if (checkVideoUrl(url)) {
16
- // 视频
17
- fileType = TYPE_VIDEO;
18
- } else if (checkAudioUrl(url)) {
19
- // 音频
20
- fileType = TYPE_AUDIO;
21
- }
22
- } else if (type) {
23
- // 图片
24
- if (type?.startsWith("image/")) {
25
- fileType = TYPE_IMG;
26
- }
27
-
28
- // 视频
29
- if (type?.startsWith("video/")) {
30
- fileType = TYPE_VIDEO;
31
- }
32
-
33
- // 音频
34
- if (type?.startsWith("audio/")) {
35
- fileType = TYPE_AUDIO;
36
- }
37
- }
38
- return fileType || type;
39
- }
1
+ export * from "@hzab/utils/src/file/fileType";
2
+ import { getFileTypeStr } from "@hzab/utils/src/file/fileType";
3
+
4
+ export const checkFileType = getFileTypeStr;
@@ -1,142 +1,5 @@
1
- import { nanoidNumALetters } from "./nanoid";
1
+ export * from "@hzab/utils/src/file/fileName";
2
2
 
3
- /**
4
- * 获取文件后缀
5
- * @param fileUrl
6
- * @returns
7
- */
8
- export function getFileExt(fileUrl) {
9
- if (typeof fileUrl !== "string") {
10
- return;
11
- }
12
- const res = fileUrl?.match(/([^\/]+?)\.([^\/\.]+)$/);
13
- if (res && res.length > 2) {
14
- return res[2];
15
- }
16
- return fileUrl;
17
- }
3
+ import { getFileNameByFileObj, getFileNameObj, setFileNameObj, getValByKey } from "@hzab/utils/src/upload/uploadUtils";
18
4
 
19
- /**
20
- * 从 url 获取文件名称,不包含后缀
21
- * @param {*} fileName
22
- * @param {*} str
23
- * @returns
24
- */
25
- export function getFileName(fileUrl) {
26
- if (typeof fileUrl !== "string") {
27
- return;
28
- }
29
- const res = fileUrl?.match(/([^\/]+?)\.[^\/\.]+$/);
30
- if (res && res.length > 0) {
31
- return res?.[1] || res?.[0];
32
- }
33
- return fileUrl;
34
- }
35
-
36
- /**
37
- * 从 url 获取文件名称,包含后缀
38
- * @param {*} fileName
39
- * @param {*} str
40
- * @returns
41
- */
42
- export function getFullFileName(fileUrl) {
43
- if (typeof fileUrl !== "string") {
44
- return;
45
- }
46
- const res = fileUrl?.match(/[^\/]+?\.[^\/\.]+$/);
47
- if (res && res.length > 0) {
48
- return res[0];
49
- }
50
- return fileUrl;
51
- }
52
-
53
- /**
54
- * 合并文件名称,自动处理后缀
55
- * @param {*} fileName
56
- * @param {*} str
57
- * @returns
58
- */
59
- export const mergeFileName = function (fileName, str = "") {
60
- if (typeof fileName !== "string") {
61
- return "";
62
- }
63
-
64
- const suffix = fileName?.match(/\.([^\/.]+)$/)?.[1] || "";
65
- const name = fileName?.match(/([^\/]+)\.[^.]+$/)?.[1] || "";
66
- return `${name}${str ?? ""}.${suffix}`;
67
- };
68
-
69
- /**
70
- * 获取唯一的文件名
71
- * @param {*} fileName
72
- * @returns
73
- */
74
- export const getUFileName = function (fileName) {
75
- return mergeFileName(getFileName(fileName) || "rc-upload", "-" + `~kid-${nanoidNumALetters()}~` + `${Date.now()}`);
76
- };
77
-
78
- /**
79
- * 根据 file 对象获取文件名称,文件名称包含:初始名称、类型
80
- * 数据存储格式 ~k[key]-[data]~ 如: ~ktime-1743649562530~
81
- * key、data 中的 ~ 转为 _
82
- * @param file
83
- */
84
- export const getFileNameByFileObj = (file, opt: any) => {
85
- const { useHashName = true } = opt || {};
86
- const _fileName = file.name || getFullFileName(file.url);
87
- if (_fileName.indexOf("~kid-") >= 0 || !useHashName) {
88
- return _fileName;
89
- }
90
- // id、时间、文件类型
91
- const id = file.id || file.uid || nanoidNumALetters();
92
- return mergeFileName(
93
- _fileName,
94
- "-" +
95
- setFileNameObj({
96
- id,
97
- time: file.createTime ?? Date.now(),
98
- type: (file.type || file.contentType)?.replace("/", "_"),
99
- }),
100
- );
101
- };
102
-
103
- /**
104
- * 解析
105
- * @param url
106
- * @returns
107
- */
108
- export const getFileNameObj = function (url): any {
109
- const list = url.match(/~k([^-~]+)-([^~]*)~/g);
110
- const res = {};
111
- list?.forEach((it) => {
112
- const arr = it?.match(/~k([^-~]+)-([^~]*)~/);
113
- if (arr?.length >= 3) {
114
- res[arr[1]] = arr[2];
115
- }
116
- });
117
- return res;
118
- };
119
-
120
- /**
121
- * 解析
122
- * @param url
123
- * @returns
124
- */
125
- export function setFileNameObj(obj) {
126
- return Object.keys(obj)
127
- .map((key) => {
128
- return `~k${key?.replace(/~/g, "_")}-${obj[key]?.toString()?.replace(/~/g, "_")}~`;
129
- })
130
- .join("");
131
- }
132
-
133
- /**
134
- * 通过 key 获取对应的值
135
- * @param url
136
- * @param key
137
- * @returns
138
- */
139
- export const getValByKey = function (url, key) {
140
- const reg = new RegExp(`~k${key?.replace(/~/g, "_")}-\([^~]*\)~`);
141
- return url.match(reg)?.[1];
142
- };
5
+ export { getFileNameByFileObj, getFileNameObj, setFileNameObj, getValByKey };
@@ -1,6 +1,9 @@
1
- import { getFileURL, getFileType, isBase64Str } from "./utils";
2
- import { getUFileName, getFileName, getFullFileName, getFileExt, getFileNameObj } from "./fileName";
3
- import { nanoidNumALetters } from "./nanoid";
1
+ import { getFileURL } from "@hzab/utils/src/file/file";
2
+ import { getFileType } from "@hzab/utils/src/file/fileType";
3
+ import { isBase64Str } from "@hzab/utils/src/base64Str";
4
+ import { getUFileName, getFileName, getFullFileName, getFileExt } from "@hzab/utils/src/file/fileName";
5
+ import { getFileNameObj } from "@hzab/utils/src/upload/uploadUtils";
6
+ import { nanoidNumALetters } from "@hzab/utils/src/nanoid";
4
7
 
5
8
  /**
6
9
  * 出入参归一化
@@ -218,7 +221,8 @@ export const handleInputItem = (data, opt: IHandlerOpt) => {
218
221
  }
219
222
  if (!file.id) {
220
223
  file.id =
221
- file.uid || `${getFileName(file.url || file.name || file.filename) || "rc-upload"}-${Date.now()}-${nanoidNumALetters()}`;
224
+ file.uid ||
225
+ `${getFileName(file.url || file.name || file.filename) || "rc-upload"}-${Date.now()}-${nanoidNumALetters()}`;
222
226
  }
223
227
  if (!file.name) {
224
228
  file.name = file.id;
@@ -1,5 +1,4 @@
1
- import { axios, getSignature, OssUploadUtil } from "@hzab/utils/src/upload/OssUploadUtil";
2
- console.log('OssUploadUtil', OssUploadUtil);
1
+ import OssUploadUtil, { axios, getSignature } from "@hzab/utils/src/upload/OssUploadUtil";
3
2
 
4
3
  /**
5
4
  * 处理文件上传逻辑
@@ -1,195 +1,27 @@
1
-
2
-
3
-
4
- /**
5
- * 格式化 dir 字符串,必须为非 / 开头, / 结尾。如: test/
6
- * @param {*} dir
7
- * @returns
8
- */
9
- export const formatDirStr = function (dir) {
10
- return dir?.replace(/^\/(.*)\/*$/, "$1").replace(/(.?=*)\/*$/, "$1/");
11
- };
12
-
13
- /**
14
- * 合并 dir 字符串
15
- * @param {*} dir
16
- */
17
- export const mergeDirStr = function (dir1, dir2) {
18
- return `${formatDirStr(dir1 || "")}${formatDirStr(dir2 || "")}`;
19
- };
20
-
21
- /**
22
- * 建立一个可以存取该 file 的 url
23
- * @param {Object} file 文件
24
- * @returns {string} url
25
- * blob:http://localhost:8000/c9950644-5118-4231-9be7-8183bde1fdc7
26
- */
27
- export function getFileURL(file) {
28
- const _file = file?.file || file;
29
- if (!(_file instanceof File)) {
30
- return;
31
- }
32
-
33
- let url = _file.url || null;
34
-
35
- try {
36
- // 下面函数执行的效果是一样的,只是需要针对不同的浏览器执行不同的 js 函数而已
37
- if (window.createObjectURL != undefined) {
38
- // basic
39
- return window.createObjectURL(_file);
40
- } else if (window.URL != undefined) {
41
- // mozilla(firefox)
42
- return window.URL.createObjectURL(_file);
43
- } else if (window.webkitURL != undefined) {
44
- // webkit or chrome
45
- return window.webkitURL.createObjectURL(_file);
46
- }
47
- } catch (error) {
48
- console.warn("getFileURL Error: ", error);
49
- }
50
-
51
- return url;
52
- }
53
-
54
- /**
55
- * 是否是 base64 字符串
56
- * @param {*} str
57
- * @returns
58
- */
59
- export const isBase64Str = function (str) {
60
- return /^data:\w+\/\w+;base64/i.test(str);
1
+ import { formatDirStr, mergeDirStr, handleMaxCount, mergePreviewConfig } from "@hzab/utils/upload/uploadUtils";
2
+ import { getFileURL } from "@hzab/utils/file/file";
3
+ import { isBase64Str } from "@hzab/utils/src/base64Str";
4
+ import {
5
+ checkImageUrl,
6
+ checkVideoUrl,
7
+ checkAudioUrl,
8
+ isValidMediaType,
9
+ checkUrlSuffix,
10
+ } from "@hzab/utils/src/file/fileType";
11
+ import { getArr } from "@hzab/utils/src/array";
12
+
13
+ export {
14
+ formatDirStr,
15
+ mergeDirStr,
16
+ getFileURL,
17
+ isBase64Str,
18
+ checkImageUrl,
19
+ checkVideoUrl,
20
+ checkAudioUrl,
21
+ isValidMediaType,
22
+ checkUrlSuffix,
23
+ getFileType,
24
+ getArr,
25
+ handleMaxCount,
26
+ mergePreviewConfig,
61
27
  };
62
-
63
- /**
64
- * 判断 url 是否带有指定图片后缀
65
- * @param {string} url
66
- * @returns
67
- */
68
- export function checkImageUrl(url) {
69
- // base64
70
- if (/^data:image\/\w+;base64/i.test(url)) {
71
- return true;
72
- }
73
- const imgTypes = [
74
- "apng",
75
- "avif",
76
- "bmp",
77
- "gif",
78
- "ico",
79
- "cur",
80
- "jpg",
81
- "jpeg",
82
- "jfif",
83
- "pjpeg",
84
- "pjp",
85
- "png",
86
- "svg",
87
- "tif",
88
- "tiff",
89
- "webp",
90
- ];
91
- return checkUrlSuffix(url, imgTypes);
92
- }
93
-
94
- /**
95
- * 判断是否是合法的媒体类型
96
- * @param {String} input
97
- * @returns
98
- */
99
- export function isValidMediaType(input) {
100
- const validPrefixes = ["image/", "video/", "audio/"];
101
- return validPrefixes.some((prefix) => input?.startsWith(prefix));
102
- }
103
-
104
- /**
105
- * 判断 url 是否带有指定视频后缀
106
- * @param {string} url
107
- * @returns
108
- */
109
- export function checkVideoUrl(url) {
110
- const imgTypes = ["3gp", "mpg", "mpeg", "mp4", "m4v", "m4p", "ogv", "ogg", "mov", "webm"];
111
- return checkUrlSuffix(url, imgTypes);
112
- }
113
-
114
- /**
115
- * 判断 url 是否带有指定音频后缀
116
- * @param {string} url
117
- * @returns
118
- */
119
- export function checkAudioUrl(url) {
120
- const imgTypes = ["3gp", "adts", "mpeg", "mp3", "mp4", "ogg", "mov", "webm", "rtp", "amr", "wav"];
121
- return checkUrlSuffix(url, imgTypes);
122
- }
123
-
124
- /**
125
- * 检查 url 是否带有指定后缀
126
- * @param {string} url url 地址
127
- * @param {Array} types 后缀数组
128
- * @returns
129
- */
130
- export function checkUrlSuffix(url, types = [], caseSensitive) {
131
- if (!url) {
132
- return false;
133
- }
134
- let _url = url?.replace(/\?.+/, "");
135
- const reg = new RegExp(`\.(${types.join("|")})$`, caseSensitive ? undefined : "i");
136
- if (reg.test(_url)) {
137
- return true;
138
- }
139
- }
140
-
141
- export function getFileType(file) {
142
- if (typeof file === "object" && file?.type) {
143
- return file?.type;
144
- }
145
- if (typeof file === "string") {
146
- let type = null;
147
- if (checkVideoUrl(file)) {
148
- type = "video/mp4";
149
- } else if (checkImageUrl(file)) {
150
- type = "image/jpeg";
151
- } else if (checkAudioUrl(file)) {
152
- type = "audio/3gpp";
153
- } else if (checkUrlSuffix(file, ["pdf"])) {
154
- type = "application/pdf";
155
- } else if (checkUrlSuffix(file, ["pdf"])) {
156
- type = "application/pdf";
157
- } else if (checkUrlSuffix(file, ["xlsx", "xls", "csv", "xlsm", "xlsb"])) {
158
- type = "application/vnd.ms-excel";
159
- } else if (checkUrlSuffix(file, ["doc", "docx"])) {
160
- type = "application/msword";
161
- } else if (checkUrlSuffix(file, ["ppt", "pptx"])) {
162
- type = "application/vnd.ms-powerpoint";
163
- }
164
- return type;
165
- }
166
- }
167
-
168
- function getArr(value) {
169
- return Array.isArray(value) ? value : (value && [value]) || [];
170
- }
171
-
172
- export function handleMaxCount(fileList, maxCount) {
173
- let list = getArr(fileList);
174
- if (maxCount > 0 && list.length > maxCount) {
175
- list = list.slice(0, maxCount);
176
- }
177
- return list;
178
- }
179
-
180
- /**
181
- * 预览 url 添加前缀
182
- * @param {*} uri
183
- * @param {*} previewConfig
184
- * @returns
185
- */
186
- export function mergePreviewConfig(uri, previewConfig) {
187
- const isUriPattern = /http[s]?:\/\/[^\s]+/.test(uri);
188
- const query = previewConfig?.query ? "?" + previewConfig?.query : "";
189
-
190
- if (isUriPattern) return `${uri}${query}`?.trim();
191
-
192
- if (previewConfig) return `${previewConfig?.url}/${uri}${query}`?.trim();
193
-
194
- return uri;
195
- }
@@ -1,6 +1,5 @@
1
- import { getFileURL } from "../../common/utils";
2
-
3
- import { TYPE_VIDEO, TYPE_IMG, TYPE_AUDIO, checkFileType } from "../../common/checkFileType";
1
+ import { getFileURL } from "@hzab/utils/src/file/file";
2
+ import { TYPE_VIDEO, TYPE_IMG, TYPE_AUDIO, getFileTypeStr } from "@hzab/utils/src/file/fileType";
4
3
 
5
4
  import Video from "../video";
6
5
  import Image from "../Image";
@@ -28,7 +27,7 @@ export const ItemList = (props) => {
28
27
  </div>
29
28
  );
30
29
 
31
- const fileType = checkFileType(it);
30
+ const fileType = getFileTypeStr(it);
32
31
  if (fileType === TYPE_IMG) {
33
32
  content = <Image src={src} alt={name} />;
34
33
  }
@@ -1,5 +1,13 @@
1
- import { checkFileType, TYPE_VIDEO, TYPE_IMG, TYPE_AUDIO } from "../../common/checkFileType";
2
- import { checkImageUrl, checkVideoUrl, checkAudioUrl, isValidMediaType } from "../../common/utils";
1
+ import {
2
+ TYPE_VIDEO,
3
+ TYPE_IMG,
4
+ TYPE_AUDIO,
5
+ getFileTypeStr,
6
+ checkImageUrl,
7
+ checkVideoUrl,
8
+ checkAudioUrl,
9
+ isValidMediaType,
10
+ } from "@hzab/utils/src/file/fileType";
3
11
 
4
12
  export const previewRenderEnum = {
5
13
  [TYPE_VIDEO]: videoRender,
@@ -8,7 +16,7 @@ export const previewRenderEnum = {
8
16
  };
9
17
 
10
18
  export function hasPreviewRender(file) {
11
- return !!previewRenderEnum[checkFileType(file)];
19
+ return !!previewRenderEnum[getFileTypeStr(file)];
12
20
  }
13
21
 
14
22
  function getFirstAcceptRule(accept: string): string {
@@ -31,11 +39,11 @@ export function hasPreviewMedium(accept: string): boolean {
31
39
  }
32
40
 
33
41
  export function getPreviewRender(file, accept) {
34
- const fileType = checkFileType(file);
42
+ const fileType = getFileTypeStr(file);
35
43
  let render = null;
36
44
 
37
45
  if (fileType) {
38
- render = previewRenderEnum[checkFileType(file)];
46
+ render = previewRenderEnum[getFileTypeStr(file)];
39
47
  }
40
48
 
41
49
  if (accept) {
@@ -50,8 +58,6 @@ export function getPreviewRender(file, accept) {
50
58
  return render;
51
59
  }
52
60
 
53
-
54
-
55
61
  export function getPreviewContent(file, accept) {
56
62
  let render = getPreviewRender(file, accept);
57
63
  if (!render) {
@@ -3,7 +3,7 @@ import { Button, Modal, message } from "antd";
3
3
 
4
4
  import ItemList from "./components/ItemList";
5
5
 
6
- import { handleMaxCount } from "./common/utils";
6
+ import { handleMaxCount } from "@hzab/utils/upload/uploadUtils";
7
7
  import { handleInputFileList, handleOutputFileList } from "./common/handleIOFileList";
8
8
  import { handleOssUpload } from "./common/ossUpload";
9
9
 
package/src/index.tsx CHANGED
@@ -30,6 +30,7 @@ import {
30
30
  ArrayCards,
31
31
  } from "c-formily-antd";
32
32
  import { Card, Slider, Rate } from "antd";
33
+ import { getFormilyGlobalComponents } from "@hzab/utils/src/formily/global-components";
33
34
 
34
35
  // 自定义组件
35
36
  import * as customComponents from "./components/index";
@@ -67,8 +68,6 @@ const antdComponents = {
67
68
  ArrayCards,
68
69
  };
69
70
 
70
- const noop = () => {};
71
-
72
71
  const FormRender = forwardRef((props: any, parentRef) => {
73
72
  /** schema scope 解决父级无 schema Scope 导致 scope 对象刷新的问题 */
74
73
  const schemaScopeRef = useRef<{ _$tempData: Object }>();
@@ -112,6 +111,7 @@ const FormRender = forwardRef((props: any, parentRef) => {
112
111
  Slider,
113
112
  Rate,
114
113
  ...customComponents,
114
+ ...getFormilyGlobalComponents(),
115
115
  ...props.components,
116
116
  },
117
117
  scope: schemaScopeRef.current,