@cloudbase/weda-ui 3.16.0 → 3.17.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.
Files changed (58) hide show
  1. package/dist/configs/components/container.js +0 -3
  2. package/dist/configs/components/wd-ad.d.ts +4 -0
  3. package/dist/configs/components/wd-ad.js +23 -0
  4. package/dist/configs/components/wd-cascader.d.ts +4 -0
  5. package/dist/configs/components/wd-checkbox.d.ts +4 -0
  6. package/dist/configs/components/wd-code-editor.d.ts +4 -0
  7. package/dist/configs/components/wd-date-range.d.ts +4 -0
  8. package/dist/configs/components/wd-date.d.ts +4 -0
  9. package/dist/configs/components/wd-department.d.ts +6 -0
  10. package/dist/configs/components/wd-department.js +1 -1
  11. package/dist/configs/components/wd-form-arr.d.ts +4 -0
  12. package/dist/configs/components/wd-form-detail.d.ts +4 -0
  13. package/dist/configs/components/wd-form-obj.d.ts +4 -0
  14. package/dist/configs/components/wd-input-email.d.ts +4 -0
  15. package/dist/configs/components/wd-input-number.d.ts +4 -0
  16. package/dist/configs/components/wd-input-phone.d.ts +4 -0
  17. package/dist/configs/components/wd-input-url.d.ts +4 -0
  18. package/dist/configs/components/wd-input.d.ts +4 -0
  19. package/dist/configs/components/wd-location.d.ts +4 -0
  20. package/dist/configs/components/wd-member.d.ts +4 -0
  21. package/dist/configs/components/wd-radio.d.ts +4 -0
  22. package/dist/configs/components/wd-rating.d.ts +4 -0
  23. package/dist/configs/components/wd-region.d.ts +4 -0
  24. package/dist/configs/components/wd-rich-text.d.ts +4 -0
  25. package/dist/configs/components/wd-select-multiple.d.ts +4 -0
  26. package/dist/configs/components/wd-select.d.ts +4 -0
  27. package/dist/configs/components/wd-switch.d.ts +4 -0
  28. package/dist/configs/components/wd-tag-select.d.ts +4 -0
  29. package/dist/configs/components/wd-tag.d.ts +4 -0
  30. package/dist/configs/components/wd-textarea.d.ts +4 -0
  31. package/dist/configs/components/wd-time.d.ts +4 -0
  32. package/dist/configs/components/wd-upload-file.d.ts +4 -0
  33. package/dist/configs/components/wd-upload-image.d.ts +195 -15
  34. package/dist/configs/components/wd-upload-image.js +125 -6
  35. package/dist/configs/index.d.ts +492 -4
  36. package/dist/configs/type-utils/type-form.d.ts +4 -0
  37. package/dist/configs/type-utils/type-form.js +4 -0
  38. package/dist/configs/type-utils/x-runtime-default.d.ts +2 -0
  39. package/dist/configs/type-utils/x-runtime-default.js +2 -0
  40. package/dist/configs/utils/field.d.ts +1 -0
  41. package/dist/configs/utils/field.js +95 -0
  42. package/dist/style/weda-ui.min.css +1 -1
  43. package/dist/web/components/form/uploader/index.d.ts +1 -0
  44. package/dist/web/components/form/uploader/index.js +7 -4
  45. package/dist/web/components/form/uploader/upload/index.d.ts +26 -0
  46. package/dist/web/components/form/uploader/upload/index.js +200 -0
  47. package/dist/web/components/form/uploader/uploader.h5.d.ts +6 -1
  48. package/dist/web/components/form/uploader/uploader.h5.js +26 -94
  49. package/dist/web/components/form/uploader/uploader.pc.d.ts +1 -1
  50. package/dist/web/components/form/uploader/uploader.pc.js +30 -100
  51. package/dist/web/components/form/uploader/util.d.ts +16 -0
  52. package/dist/web/components/form/uploader/util.js +106 -5
  53. package/dist/web/components/uploaderView/index.js +1 -1
  54. package/dist/web/components/wd-ad/wd-ad.js +2 -4
  55. package/dist/web/components/wd-upload-image/wd-upload-image.js +14 -4
  56. package/package.json +4 -4
  57. package/dist/web/components/form/uploader/useUploadFile.d.ts +0 -16
  58. package/dist/web/components/form/uploader/useUploadFile.js +0 -99
@@ -5,7 +5,7 @@ export declare const IMAGE_TYPES: string[];
5
5
  interface TempFileProps {
6
6
  progress?: number;
7
7
  loading?: boolean;
8
- realUrl?: string;
8
+ cloudId?: string;
9
9
  tempUrl?: string;
10
10
  key?: string;
11
11
  }
@@ -1,14 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
- import { Upload, Icon, ErrorTip, ConfigProvider } from 'tea-component';
3
+ import { Icon, ErrorTip, ConfigProvider } from 'tea-component';
4
4
  import { useTempUrl } from '../../../utils/hooks/use-cloud-id-temp-url';
5
- import { toBase64Uri } from '../../../utils/file2base64';
6
- import { isNil } from '../../../utils/lodash';
7
5
  import { errorHandler } from '../../../utils/error';
8
- import { alertErrorMessage } from '../../../utils/platform';
9
6
  import { WdIcon } from '../../wd-icon';
10
- import { useUploader } from './useUploadFile';
11
7
  import { ImagePreview } from '../../wd-image/ImagePreview';
8
+ import { Upload } from './upload';
12
9
  // 默认组件类前缀
13
10
  export const CLASS_PREFIX = 'weda-uploader-pc';
14
11
  // 默认图片类型
@@ -22,117 +19,50 @@ export const IMAGE_TYPES = [
22
19
  'image/gif',
23
20
  ];
24
21
  export function UploaderPCInner(props) {
25
- const { tips = '', btnTitle = '上传图片', maxUploadCount = 9, maxSize = 10, acceptTypes = IMAGE_TYPES, events, single = false, disabled = false, onChange, imgTypeCls, readOnly, sourceType, callbacks, popupContainer: portalContainer, } = props;
26
- const { tempFile, uploading, upload, getTempFile } = useUploader(props);
27
- const handleChange = (allFile = [], isDelete = false) => {
28
- var _a;
29
- const value = getTempFile(allFile);
30
- onChange === null || onChange === void 0 ? void 0 : onChange(value);
31
- (_a = events === null || events === void 0 ? void 0 : events.change) === null || _a === void 0 ? void 0 : _a.call(events, { value, isDelete });
32
- };
33
- // 方法:上传前,判断图片大小、数量是否满足,取消默认组件的上传事件,用自定义的 tcb 上传方法
34
- const beforeHandle = async (file, fileList, isAccepted, error) => {
35
- const finalMaxImgCount = single ? 1 : maxUploadCount;
36
- if (!isAccepted) {
37
- try {
38
- const errorList = [];
39
- if (error.find((item) => (item === null || item === void 0 ? void 0 : item.code) === 'file-invalid-type')) {
40
- errorList.push('上传图片类型错误');
41
- }
42
- if (error.find((item) => (item === null || item === void 0 ? void 0 : item.code) === 'file-too-large')) {
43
- errorList.push(`上传图片大小不能超过${maxSize}M`);
44
- }
45
- alertErrorMessage({
46
- message: errorList.join(', '),
47
- icon: 'error',
48
- });
49
- }
50
- catch (e) {
51
- errorHandler({
52
- code: 'BEFORE_UPLOAD_ERROR',
53
- error: e,
54
- });
55
- }
56
- return Promise.reject(false);
57
- }
58
- const ids = fileList.filter((f) => !!f.id);
59
- if (ids.length < fileList.length)
60
- return Promise.reject(false);
61
- if (fileList.length > finalMaxImgCount) {
62
- // 防止一下子选择过多文件
63
- alertErrorMessage({
64
- message: `最多只能上传${finalMaxImgCount}张图片,请重新选择`,
65
- icon: 'error',
66
- });
67
- return Promise.reject(false);
68
- }
69
- if (tempFile.length + fileList.length > finalMaxImgCount) {
70
- alertErrorMessage({
71
- message: `最多只能上传${finalMaxImgCount}张图片`,
72
- icon: 'error',
73
- });
74
- return Promise.reject(false);
75
- }
76
- let shouldUploadToCos = true;
77
- if (typeof (callbacks === null || callbacks === void 0 ? void 0 : callbacks.beforeUpload) === 'function') {
78
- try {
79
- const base64Uri = await Promise.all(fileList.map((file) => toBase64Uri(file)));
80
- const ret = await callbacks.beforeUpload({
81
- files: fileList,
82
- base64Uri,
83
- });
84
- if (typeof ret === 'boolean') {
85
- shouldUploadToCos = ret;
86
- }
87
- else if (Array.isArray(ret) && ret.every((item) => item instanceof File)) {
88
- fileList = ret;
89
- }
90
- else if (!isNil(ret)) {
91
- throw new TypeError('web端返回值接受布尔值 / File对象数组');
92
- }
93
- }
94
- catch (err) {
95
- errorHandler({
96
- code: 'BEFORE_UPLOAD_ERROR',
97
- error: err,
98
- });
99
- shouldUploadToCos = false;
100
- }
101
- }
102
- if (shouldUploadToCos === false) {
103
- return Promise.reject(false);
22
+ const { tips = '', btnTitle = '上传图片', maxUploadCount = 9, maxSize = 10, acceptTypes = IMAGE_TYPES, single = false, disabled = false, imgTypeCls, readOnly, sourceType, popupContainer: portalContainer, defaultValue, setUploadHandle: outSetUploadHandle, } = props;
23
+ const uploadRef = React.useRef(null);
24
+ const [uploadHandle, setUploadHandle] = React.useState({});
25
+ const tempFile = React.useMemo(() => (uploadHandle === null || uploadHandle === void 0 ? void 0 : uploadHandle.previewFile) || [], [uploadHandle === null || uploadHandle === void 0 ? void 0 : uploadHandle.previewFile]);
26
+ const uploading = tempFile === null || tempFile === void 0 ? void 0 : tempFile.some((i) => i.loading);
27
+ const setUploadRef = React.useCallback((uploadHandle) => {
28
+ setUploadHandle(uploadHandle);
29
+ // 设置最外层组件方法
30
+ // 兼容云后台数据库中使用uploader组件,未传outSetUploadHandle
31
+ if (outSetUploadHandle) {
32
+ outSetUploadHandle(uploadHandle);
104
33
  }
105
- const allFile = await upload(fileList);
106
- handleChange(allFile);
107
- };
34
+ }, [outSetUploadHandle]);
108
35
  // 删除图片
109
- const deleteHandle = (fileItem) => {
110
- const fileList = tempFile.filter((d) => d.key !== fileItem.key);
111
- handleChange(fileList, true);
36
+ const deleteHandle = (file) => {
37
+ var _a;
38
+ (_a = uploadRef === null || uploadRef === void 0 ? void 0 : uploadRef.current) === null || _a === void 0 ? void 0 : _a.delete({ cloudId: file.cloudId });
112
39
  };
113
40
  // 转换后的属性
114
- const extraProps = {};
41
+ const extraProps = { ...props };
115
42
  //是否支持多选
116
43
  extraProps['multiple'] = !single;
117
44
  extraProps['accept'] = acceptTypes.length === 0 ? IMAGE_TYPES : Array.from(new Set(acceptTypes));
118
45
  tips && (extraProps['title'] = tips);
119
46
  maxSize && (extraProps['maxSize'] = maxSize * 1024 * 1024);
120
47
  const hasActions = !uploading && !readOnly && !(disabled || sourceType === 'camera');
121
- return (_jsx(ConfigProvider, { classPrefix: "wedatea2td", children: _jsxs("div", { className: "_weda-fn-upload-result", children: [tempFile === null || tempFile === void 0 ? void 0 : tempFile.map((d, index) => (_jsx("div", { className: `_weda-fn-upload-result__item ${imgTypeCls}`, children: _jsx(TcbImage, { index: index, allFile: tempFile, tempFile: d, imgTypeCls: imgTypeCls, isZoom: true, previewIcon: "td:browse", portalContainer: portalContainer, actions: hasActions && (_jsx(WdIcon, { className: `${CLASS_PREFIX}__image-actions-delete`, name: "td:delete", onClick: () => deleteHandle(d), size: "sm" })) }) }, d.key))), _jsxs("div", { className: `${CLASS_PREFIX}__input-box`, children: [readOnly && tempFile.length < 1 && _jsx("div", { children: "-" }), sourceType === 'camera' || (disabled && !readOnly) ? (_jsx("div", { className: `_weda-fn-upload-result__item wedatea2td-disabled weda-uploader-btn__box ${imgTypeCls}`, children: _jsxs("div", { className: "_weda-fn-upload-result__status", children: [_jsx("i", { className: "wedatea2td-icon wedatea2td-icon-plus", role: "img", "aria-label": "plus" }), _jsx("span", { className: "wedatea2td-mt-1n wedatea2td-text-label wedatea2td-fz-reset", children: btnTitle })] }) })) : (((!single && tempFile.length < maxUploadCount) || (single && tempFile.length < 1 && !uploading)) &&
122
- !readOnly && (
123
- // single 模式时,当数组为空且不在上传文件过程中时显示
124
- _jsx(Upload, { ...extraProps, beforeUpload: beforeHandle, children: _jsxs("div", {
48
+ return (_jsx(ConfigProvider, { classPrefix: "wedatea2td", children: _jsx(Upload, { ...extraProps, ref: uploadRef, value: defaultValue, setUploadHandle: setUploadRef, children: _jsxs("div", { className: "_weda-fn-upload-result", children: [tempFile === null || tempFile === void 0 ? void 0 : tempFile.map((d, index) => (_jsx("div", { className: `_weda-fn-upload-result__item ${imgTypeCls}`, children: _jsx(TcbImage, { index: index, allFile: tempFile, tempFile: d, imgTypeCls: imgTypeCls, isZoom: true, previewIcon: "td:browse", portalContainer: portalContainer, actions: hasActions && (_jsx(WdIcon, { className: `${CLASS_PREFIX}__image-actions-delete`, name: "td:delete", onClick: () => deleteHandle(d), size: "sm" })) }) }, d.cloudId))), _jsxs("div", { className: `${CLASS_PREFIX}__input-box`, children: [readOnly && tempFile.length < 1 && _jsx("div", { children: "-" }), sourceType === 'camera' || (disabled && !readOnly) ? (_jsx("div", { className: `_weda-fn-upload-result__item wedatea2td-disabled weda-uploader-btn__box ${imgTypeCls}`, children: _jsxs("div", { className: "_weda-fn-upload-result__status", children: [_jsx("i", { className: "wedatea2td-icon wedatea2td-icon-plus", role: "img", "aria-label": "plus" }), _jsx("span", { className: "wedatea2td-mt-1n wedatea2td-text-label wedatea2td-fz-reset", children: btnTitle })] }) })) : (((!single && tempFile.length < maxUploadCount) || (single && tempFile.length < 1 && !uploading)) &&
49
+ !readOnly && (
50
+ // single 模式时,当数组为空且不在上传文件过程中时显示
51
+ _jsxs("div", {
125
52
  // className={"_weda-fn-upload-result__item _weda-fn-upload-result__item--upload" imgTypeCls}
126
53
  // className={classNames(
127
54
  // `_weda-fn-upload-result__item _weda-fn-upload-result__item--upload`,
128
55
  // imgTypeCls
129
56
  // )}
130
- className: `_weda-fn-upload-result__item weda-uploader-btn__box _weda-fn-upload-result__item--upload ${imgTypeCls}`, children: [imgTypeCls, _jsxs("div", { className: "_weda-fn-upload-result__status", children: [_jsx("i", { className: "wedatea2td-icon wedatea2td-icon-plus", role: "img", "aria-label": "plus" }), _jsx("span", { className: "wedatea2td-mt-1n wedatea2td-text-label wedatea2td-fz-reset", children: btnTitle })] })] }) })))] })] }) }));
57
+ className: `_weda-fn-upload-result__item weda-uploader-btn__box _weda-fn-upload-result__item--upload ${imgTypeCls}`, onClick: () => {
58
+ var _a;
59
+ (_a = uploadRef === null || uploadRef === void 0 ? void 0 : uploadRef.current) === null || _a === void 0 ? void 0 : _a.upload();
60
+ }, children: [imgTypeCls, _jsxs("div", { className: "_weda-fn-upload-result__status", children: [_jsx("i", { className: "wedatea2td-icon wedatea2td-icon-plus", role: "img", "aria-label": "plus" }), _jsx("span", { className: "wedatea2td-mt-1n wedatea2td-text-label wedatea2td-fz-reset", children: btnTitle })] })] })))] })] }) }) }));
131
61
  }
132
62
  export const TcbImage = (props) => {
133
- const { fileID, tempFile = { progress: 100, loading: false, realUrl: null, tempUrl: null }, isZoom, imgTypeCls, previewIcon, actions, allFile = [], index, portalContainer, ...rest } = props;
134
- const { progress, loading, realUrl, tempUrl } = tempFile;
135
- const fileCloudID = (realUrl !== null && realUrl !== void 0 ? realUrl : tempUrl) || fileID;
63
+ const { fileID, tempFile = { progress: 100, loading: false, cloudId: null, tempUrl: null }, isZoom, imgTypeCls, previewIcon, actions, allFile = [], index, portalContainer, ...rest } = props;
64
+ const { progress, loading, cloudId, tempUrl } = tempFile;
65
+ const fileCloudID = (cloudId !== null && cloudId !== void 0 ? cloudId : tempUrl) || fileID;
136
66
  const [isError, setIsError] = React.useState(false);
137
67
  const { data: src, error: requestError } = useTempUrl(fileCloudID);
138
68
  const encodeSrc = encodeConvert(src);
@@ -152,7 +82,7 @@ export const TcbImage = (props) => {
152
82
  };
153
83
  if (!isZoom)
154
84
  return renderImg();
155
- const previewImageList = allFile.map((i) => i.realUrl || i.tempUrl);
85
+ const previewImageList = allFile.map((i) => i.cloudId || i.tempUrl);
156
86
  const previewProps = {
157
87
  index,
158
88
  'data-testid': 'uploaderpc_imgStyle',
@@ -1,4 +1,20 @@
1
+ import { TempFileProps } from './upload/index';
2
+ export declare const DEFAULT_UPLOAD_PATH = "weda-uploader";
1
3
  export declare const getBase64: (files: any) => Promise<any[]>;
2
4
  export declare const uploadTcbMulti: (files: any, props: any) => Promise<any[]>;
3
5
  export declare const filenameRegex: RegExp;
4
6
  export declare const checkAcceptedFiles: (file: any, acceptedFiles: any) => any;
7
+ export declare const checkBeforeUpload: ({ tempFile, files, accepts, maxSize, maxUploadCount }: {
8
+ tempFile: any;
9
+ files: any;
10
+ accepts: any;
11
+ maxSize: any;
12
+ maxUploadCount: any;
13
+ }) => boolean;
14
+ export declare const getPreviewFileMap: (previewFile: any) => any;
15
+ export declare const getInitTempFile: ({ value }: {
16
+ value?: any;
17
+ }) => TempFileProps[];
18
+ export declare const CLASS_PREFIX = "weda-uploader-pc";
19
+ export declare const IMAGE_TYPES: string[];
20
+ export declare const upload: (fileList: any, uploadInstance: any, allTempFile: any) => Promise<void>;
@@ -1,8 +1,9 @@
1
1
  import { compressImage } from './compress';
2
2
  import { getCloudInstance, getDefaultUploadPath } from '../../../utils/tcb';
3
3
  import { toBase64Uri } from '../../../utils/file2base64';
4
- import { randomStr } from '../../../utils/platform';
4
+ import { randomStr, alertErrorMessage } from '../../../utils/platform';
5
5
  import { errorHandler } from '../../../utils/error';
6
+ export const DEFAULT_UPLOAD_PATH = 'weda-uploader';
6
7
  export const getBase64 = (files) => {
7
8
  return Promise.all(files.map(async (item) => {
8
9
  let tempUrl = '';
@@ -35,13 +36,29 @@ export const uploadTcbMulti = async (files, props) => {
35
36
  return result;
36
37
  };
37
38
  export const filenameRegex = /[^a-zA-Z0-9\u4e00-\u9fff-*!_.]/g;
39
+ const sanitizeFilename = (filename, replacement = '') => {
40
+ return (filename
41
+ // 移除非法字符
42
+ // eslint-disable-next-line no-control-regex
43
+ .replace(/[<>.:"\\|?*\x00-\x1F]/g, replacement)
44
+ // 处理Windows保留文件名(CON, PRN等)
45
+ .replace(/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\..*)?$/i, replacement)
46
+ // 移除开头和结尾的点,空格,反斜杠(Windows不允许)
47
+ .replace(/^[. /]+/, '')
48
+ .replace(/[. /]+$/, '')
49
+ // 可选:限制长度
50
+ .slice(0, 255));
51
+ };
38
52
  const uploadToTcb = async (item, props) => {
39
53
  var _a;
40
- const { onUploadProgress, onUploadFinish, onUploadError } = props;
41
- const { file, uploadPath } = item;
54
+ const { onUploadProgress, onUploadFinish, onUploadError, uploadPath, customUploadPath } = props;
55
+ const { file } = item;
42
56
  try {
43
57
  const tcb = await getCloudInstance();
44
- const _uploadPath = getDefaultUploadPath(uploadPath);
58
+ let _uploadPath = getDefaultUploadPath(uploadPath);
59
+ if (customUploadPath) {
60
+ _uploadPath = `${_uploadPath}/${sanitizeFilename(customUploadPath, '')}}`;
61
+ }
45
62
  const cloudPath = `${_uploadPath}/${randomStr()}-${(_a = file === null || file === void 0 ? void 0 : file.name) === null || _a === void 0 ? void 0 : _a.replace(filenameRegex, '-')}`;
46
63
  const { fileID } = await tcb.uploadFile({
47
64
  cloudPath,
@@ -67,7 +84,7 @@ const uploadToTcb = async (item, props) => {
67
84
  ...item,
68
85
  progress: 100,
69
86
  loading: false,
70
- realUrl: fileID,
87
+ cloudId: fileID,
71
88
  };
72
89
  if (onUploadFinish) {
73
90
  onUploadFinish(fileItem);
@@ -109,3 +126,87 @@ export const checkAcceptedFiles = (file, acceptedFiles) => {
109
126
  }
110
127
  return true;
111
128
  };
129
+ export const checkBeforeUpload = ({ tempFile, files, accepts, maxSize, maxUploadCount }) => {
130
+ const isAccepted = files.every((i) => checkAcceptedFiles(i, accepts));
131
+ if (!isAccepted) {
132
+ alertErrorMessage({
133
+ message: `上传图片类型错误`,
134
+ icon: 'error',
135
+ });
136
+ return false;
137
+ }
138
+ if (files.some((f) => f.size > maxSize * 1024 * 1024)) {
139
+ alertErrorMessage({
140
+ message: `请上传不超过 ${maxSize}M 的图片`,
141
+ icon: 'error',
142
+ });
143
+ return false;
144
+ }
145
+ if (files.length > maxUploadCount) {
146
+ // 防止一下子选择过多文件
147
+ alertErrorMessage({
148
+ message: `最多只能上传${maxUploadCount}张图片,请重新选择`,
149
+ icon: 'error',
150
+ });
151
+ return false;
152
+ }
153
+ if ((tempFile === null || tempFile === void 0 ? void 0 : tempFile.length) + (files === null || files === void 0 ? void 0 : files.length) > maxUploadCount) {
154
+ alertErrorMessage({
155
+ message: `最多只能上传${maxUploadCount}张图片`,
156
+ icon: 'error',
157
+ });
158
+ return false;
159
+ }
160
+ return true;
161
+ };
162
+ export const getPreviewFileMap = (previewFile) => {
163
+ return previewFile.reduce((acc, obj) => {
164
+ acc[obj === null || obj === void 0 ? void 0 : obj.cloudId] = obj; // 使用 cloudId 作为新对象的 key
165
+ return acc;
166
+ }, {});
167
+ };
168
+ export const getInitTempFile = ({ value }) => {
169
+ const tempFile = value.map((i) => ({
170
+ key: randomStr(),
171
+ cloudId: i,
172
+ tempUrl: '',
173
+ progress: 100,
174
+ loading: false,
175
+ }));
176
+ return tempFile;
177
+ };
178
+ // 默认组件类前缀
179
+ export const CLASS_PREFIX = 'weda-uploader-pc';
180
+ // 默认图片类型
181
+ export const IMAGE_TYPES = [
182
+ 'image/jpg',
183
+ 'image/png',
184
+ 'image/tif',
185
+ 'image/bmp',
186
+ 'image/jpeg',
187
+ 'image/tiff',
188
+ 'image/gif',
189
+ ];
190
+ export const upload = async (fileList, uploadInstance, allTempFile) => {
191
+ const { config = {}, onComplete, onSuccess, onFail, onUploadProgress } = uploadInstance;
192
+ const { isCompressBeforeUpload, compressQuality, compressedHeight, compressedWidth } = config;
193
+ const result = await uploadTcbMulti(fileList, {
194
+ isCompressBeforeUpload,
195
+ compressedHeight,
196
+ compressedWidth,
197
+ compressQuality,
198
+ customUploadPath: config.customUploadPath,
199
+ uploadPath: DEFAULT_UPLOAD_PATH,
200
+ onUploadProgress: (item) => {
201
+ onUploadProgress(item);
202
+ },
203
+ onUploadFinish: (item) => {
204
+ onSuccess(item);
205
+ },
206
+ onUploadError: (err) => {
207
+ onFail(err);
208
+ },
209
+ });
210
+ const allFile = allTempFile.map((i) => result.find((j) => (j === null || j === void 0 ? void 0 : j.key) === (i === null || i === void 0 ? void 0 : i.key)) || i);
211
+ onComplete(allFile);
212
+ };
@@ -38,7 +38,7 @@ alt = '[加载失败]', gutter = 8, height = 100, width = 100, events = emptyObj
38
38
  onLoad: () => setSuccessList((list) => [...list, d]),
39
39
  onError: () => setErrorList((list) => [...list, d]),
40
40
  portalContainer,
41
- allFile: values === null || values === void 0 ? void 0 : values.map((d) => ({ realUrl: d })),
41
+ allFile: values === null || values === void 0 ? void 0 : values.map((d) => ({ cloudId: d })),
42
42
  index: i,
43
43
  };
44
44
  return (_jsx("div", { className: `${CLASS_PREFIX}__image-box`, style: boxStyle, title: d, children: _jsx(TcbImage, { ...imgProps }) }, `${d}-${i}`));
@@ -9,13 +9,11 @@ import { X_RUNTIME_DEFAULT } from '../../../configs/type-utils/x-runtime-default
9
9
  */
10
10
  export function WdAd(props) {
11
11
  const { className, id, style, adType: _adType = X_RUNTIME_DEFAULT.adType, gridCount: _gridCount = X_RUNTIME_DEFAULT.gridCount, } = props;
12
- const adType = ['banner', 'video', 'grid'].includes(_adType)
13
- ? _adType
14
- : 'banner';
12
+ const adType = ['banner', 'video', 'grid', 'rewardedVideoAd'].includes(_adType) ? _adType : 'banner';
15
13
  const gridCount = _gridCount == 8 ? 8 : 5;
16
14
  const { classPrefix } = useConfig();
17
15
  const canPreview = useCanPreview();
18
16
  if (!canPreview)
19
17
  return null;
20
- return (_jsx(ConfigProvider, { classPrefix: "wedatea2td", children: _jsx(Bubble, { placement: "auto", openDelay: 300, content: _jsxs(_Fragment, { children: ["\u8BE5\u7EC4\u4EF6\u5FC5\u987B\u5728\u5C0F\u7A0B\u5E8F\u771F\u5B9E\u73AF\u5883\u4F7F\u7528\u624D\u80FD\u591F\u770B\u5230\u5B9E\u9645\u6548\u679C\u3002", _jsx("br", {}), "\u8BF7\u9075\u5FAA\u5FAE\u4FE1\u5E7F\u544A\u7EC4\u4EF6\u5E94\u7528\u89C4\u8303\uFF0C\u5426\u5219\u53EF\u80FD\u5BFC\u81F4\u5C0F\u7A0B\u5E8F\u5BA1\u6838\u5931\u8D25\u3002"] }), children: _jsxs("div", { className: `${classPrefix}-ad ${classPrefix}-ad--${adType} ${className}`, id: id, style: style, children: [adType === 'banner' && _jsx(BannerAd, {}), adType === 'video' && _jsx(VideoAd, {}), adType === 'grid' && _jsx(GridAd, { gridCount: gridCount })] }) }) }));
18
+ return (_jsx(ConfigProvider, { classPrefix: "wedatea2td", children: _jsx(Bubble, { placement: "auto", openDelay: 300, content: _jsxs(_Fragment, { children: ["\u8BE5\u7EC4\u4EF6\u5FC5\u987B\u5728\u5C0F\u7A0B\u5E8F\u771F\u5B9E\u73AF\u5883\u4F7F\u7528\u624D\u80FD\u591F\u770B\u5230\u5B9E\u9645\u6548\u679C\u3002", _jsx("br", {}), "\u8BF7\u9075\u5FAA\u5FAE\u4FE1\u5E7F\u544A\u7EC4\u4EF6\u5E94\u7528\u89C4\u8303\uFF0C\u5426\u5219\u53EF\u80FD\u5BFC\u81F4\u5C0F\u7A0B\u5E8F\u5BA1\u6838\u5931\u8D25\u3002"] }), children: _jsxs("div", { className: `${classPrefix}-ad ${classPrefix}-ad--${adType} ${className}`, id: id, style: style, children: [adType === 'banner' && _jsx(BannerAd, {}), ['rewardedVideoAd', 'video'].includes(adType) && _jsx(VideoAd, {}), adType === 'grid' && _jsx(GridAd, { gridCount: gridCount })] }) }) }));
21
19
  }
@@ -1,28 +1,33 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { forwardRef, useMemo, useRef } from 'react';
2
+ import { forwardRef, useMemo, useRef, useState } from 'react';
3
3
  import { useFormInputTrait } from '../../components/form-input-hooks';
4
4
  import { WdFormItem } from '../wd-form-item';
5
5
  import Uploader from '../form/uploader';
6
6
  import { emptyObject } from '../../utils/constant';
7
7
  import { convertSingleValue } from '../../utils/tool';
8
+ import { useSetWidgetApi } from '../../utils/widget-api/use-set-widget-api';
8
9
  import { X_RUNTIME_DEFAULT } from '../../../configs/type-utils/x-runtime-default';
9
10
  import './style';
11
+ import { Upload } from '../form/uploader/upload/index';
10
12
  /**
11
13
  * 图片上传-标准化
12
14
  */
13
15
  export const WdUploadImage = forwardRef(function WdUploadImage(props, ref) {
14
16
  const { classRoot = 'upload-image', showShape = X_RUNTIME_DEFAULT.showShape, acceptTypes = X_RUNTIME_DEFAULT.acceptTypes, maxSize = X_RUNTIME_DEFAULT.maxSize, single = X_RUNTIME_DEFAULT.single, maxUploadCount = X_RUNTIME_DEFAULT.maxUploadCount, events = emptyObject, isCompressBeforeUpload = false,
15
17
  // eslint-disable-next-line @typescript-eslint/no-magic-numbers
16
- compressQuality = 70, compressedHeight = 0, compressedWidth = 0, sourceType = 'both', tips, callbacks, } = props;
18
+ compressQuality = 70, compressedHeight = 0, compressedWidth = 0, sourceType = 'both', tips, callbacks, template = 'normal', children, } = props;
17
19
  // 强制转换初始值
18
20
  const initRef = useRef(false);
21
+ const uploadRef = useRef(null);
19
22
  const formValue = useMemo(() => {
20
23
  if (initRef.current)
21
24
  return props.value;
22
25
  initRef.current = true;
23
26
  return convertSingleValue(props.value, single);
24
27
  }, [props.value, single]);
25
- const traitProps = { ...props, value: formValue, inputRef: ref };
28
+ const [innerHandle, setInnerHandle] = useState({});
29
+ const [uploadHandle, setUploadHandle] = useState({});
30
+ const traitProps = { ...props, value: formValue, inputRef: ref, setInnerHandle };
26
31
  const trait = useFormInputTrait(traitProps);
27
32
  const { value, onChange, disabled, readOnly, visible } = trait;
28
33
  const formItemProps = {
@@ -32,7 +37,12 @@ export const WdUploadImage = forwardRef(function WdUploadImage(props, ref) {
32
37
  readOnly: false,
33
38
  size: 'md',
34
39
  };
40
+ useSetWidgetApi(() => ({
41
+ ...innerHandle,
42
+ ...uploadHandle,
43
+ }), [innerHandle, uploadHandle], ref);
44
+ const multiple = !single;
35
45
  if (!visible)
36
46
  return null;
37
- return (_jsx(WdFormItem, { ...formItemProps, children: _jsx(Uploader, { events: events, labelVisible: false, acceptTypes: acceptTypes, defaultValue: value, maxSize: maxSize, maxUploadCount: maxUploadCount, single: single, tips: tips, showShape: showShape, readOnly: readOnly, disabled: disabled, decorator: null, onChange: onChange, isCompressBeforeUpload: isCompressBeforeUpload, compressQuality: compressQuality, compressedHeight: compressedHeight, compressedWidth: compressedWidth, sourceType: sourceType, callbacks: callbacks }) }));
47
+ return (_jsx(WdFormItem, { ...formItemProps, children: template === 'custom' ? (_jsx(Upload, { events: events, acceptTypes: acceptTypes, maxSize: maxSize, maxUploadCount: maxUploadCount, readOnly: readOnly, disabled: disabled, isCompressBeforeUpload: isCompressBeforeUpload, compressQuality: compressQuality, compressedHeight: compressedHeight, compressedWidth: compressedWidth, callbacks: callbacks, value: value, multiple: multiple, capture: sourceType === 'camera' ? 'capture' : null, onChange: onChange, ref: uploadRef, setUploadHandle: setUploadHandle, children: children })) : (_jsx(Uploader, { events: events, labelVisible: false, acceptTypes: acceptTypes, defaultValue: value, maxSize: maxSize, maxUploadCount: maxUploadCount, single: single, tips: tips, showShape: showShape, readOnly: readOnly, disabled: disabled, decorator: null, onChange: onChange, isCompressBeforeUpload: isCompressBeforeUpload, compressQuality: compressQuality, compressedHeight: compressedHeight, compressedWidth: compressedWidth, sourceType: sourceType, callbacks: callbacks, setUploadHandle: setUploadHandle })) }));
38
48
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/weda-ui",
3
- "version": "3.16.0",
3
+ "version": "3.17.0",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index",
6
6
  "miniprogram": "mpdist",
@@ -85,7 +85,7 @@
85
85
  "description": "腾讯云微搭低代码组件库模板",
86
86
  "dependencies": {
87
87
  "@antv/g6": "^4.8.5",
88
- "@cloudbase/weda-client": "^1.1.26",
88
+ "@cloudbase/weda-client": "^1.1.27",
89
89
  "@codemirror/autocomplete": "^6.16.0",
90
90
  "@codemirror/lang-javascript": "^6.2.2",
91
91
  "@codemirror/lang-json": "^6.0.1",
@@ -148,8 +148,8 @@
148
148
  "@babel/preset-react": "^7.22.15",
149
149
  "@babel/preset-typescript": "^7.22.15",
150
150
  "@cloudbase/cals": "^1.2.13",
151
- "@cloudbase/lowcode-cli": "^0.22.1",
152
- "@cloudbase/weda-cloud-sdk": "^1.0.97",
151
+ "@cloudbase/lowcode-cli": "^0.22.2",
152
+ "@cloudbase/weda-cloud-sdk": "^1.0.99",
153
153
  "@commitlint/cli": "^16.0.2",
154
154
  "@commitlint/config-conventional": "^17.7.0",
155
155
  "@craco/craco": "^7.1.0",
@@ -1,16 +0,0 @@
1
- export declare const CLASS_PREFIX = "weda-uploader-pc";
2
- export declare const IMAGE_TYPES: string[];
3
- interface TempFileProps {
4
- progress?: number;
5
- loading?: boolean;
6
- realUrl?: string;
7
- tempUrl?: string;
8
- key?: string;
9
- }
10
- export declare function useUploader(props: any): {
11
- tempFile: TempFileProps[];
12
- uploading: boolean;
13
- upload: (fileList: any) => Promise<any[]>;
14
- getTempFile: (allFile?: any[]) => any[];
15
- };
16
- export {};
@@ -1,99 +0,0 @@
1
- import * as React from 'react';
2
- import { randomStr } from '../../../utils/platform';
3
- import isObjectEqual from '../../../utils/isObjectEqual';
4
- import { getBase64, uploadTcbMulti } from './util';
5
- // 默认组件类前缀
6
- export const CLASS_PREFIX = 'weda-uploader-pc';
7
- // 默认图片类型
8
- export const IMAGE_TYPES = [
9
- 'image/jpg',
10
- 'image/png',
11
- 'image/tif',
12
- 'image/bmp',
13
- 'image/jpeg',
14
- 'image/tiff',
15
- 'image/gif',
16
- ];
17
- const getInitTempFile = ({ single, value, defaultValue, uploadPath }) => {
18
- let initialValue = []
19
- .concat(value ? value : defaultValue)
20
- .filter((d) => typeof d === 'string' && d !== '');
21
- if (single) {
22
- initialValue = initialValue[0] ? [initialValue[0]] : [];
23
- }
24
- const tempFile = initialValue.map((i) => ({
25
- key: randomStr(),
26
- uploadPath,
27
- realUrl: i,
28
- tempUrl: '',
29
- progress: 100,
30
- loading: false,
31
- }));
32
- return tempFile;
33
- };
34
- export function useUploader(props) {
35
- const { defaultValue, // 需要兼容 cloud:和https: 协议,需要兼容 字符串和字符串数组
36
- uploadPath = 'weda-uploader', events, single = false, value, // 数据管理后台中,formily使用此字段传默认值
37
- isCompressBeforeUpload, compressQuality, compressedHeight, compressedWidth, } = props;
38
- // 上传中
39
- const [uploading, setUploading] = React.useState(false);
40
- // 文件列表
41
- const [tempFile, setTempFile] = React.useState(() => {
42
- return getInitTempFile(props);
43
- });
44
- const defaultValueRef = React.useRef(null);
45
- React.useEffect(() => {
46
- if (isObjectEqual(defaultValueRef.current, defaultValue))
47
- return;
48
- const tempFile = getInitTempFile({
49
- single,
50
- value,
51
- defaultValue,
52
- uploadPath,
53
- });
54
- defaultValueRef.current = defaultValue;
55
- setTempFile(tempFile);
56
- }, [defaultValue, single, uploadPath, value]);
57
- // 方法:上传前,判断图片大小、数量是否满足,取消默认组件的上传事件,用自定义的 tcb 上传方法
58
- const upload = async (fileList) => {
59
- let tempFiles = fileList.map((i) => ({
60
- file: i,
61
- key: randomStr(),
62
- uploadPath,
63
- progress: 0,
64
- loading: true,
65
- }));
66
- tempFiles = await getBase64(tempFiles);
67
- const allTempFile = [...tempFile, ...tempFiles];
68
- setTempFile(allTempFile);
69
- setUploading(true);
70
- const result = await uploadTcbMulti(tempFiles, {
71
- isCompressBeforeUpload,
72
- compressedHeight,
73
- compressedWidth,
74
- compressQuality,
75
- onUploadProgress: (item) => {
76
- setTempFile((allTempFile) => allTempFile.map((i) => (i.key === item.key ? { ...i, ...item } : i)));
77
- },
78
- onUploadFinish: (item) => {
79
- var _a;
80
- (_a = events === null || events === void 0 ? void 0 : events.success) === null || _a === void 0 ? void 0 : _a.call(events, { value: item.realUrl, file: item.file });
81
- setUploading(false);
82
- setTempFile((allTempFile) => allTempFile.map((i) => (i.key === item.key ? { ...i, ...item } : i)));
83
- },
84
- onUploadError: (err) => {
85
- events.error && events.error(err);
86
- setUploading(false);
87
- },
88
- });
89
- const allFile = allTempFile.map((i) => result.find((j) => (j === null || j === void 0 ? void 0 : j.key) === (i === null || i === void 0 ? void 0 : i.key)) || i);
90
- return allFile;
91
- };
92
- const getTempFile = (allFile = []) => {
93
- setTempFile(allFile);
94
- let value = allFile.map((i) => i === null || i === void 0 ? void 0 : i.realUrl).filter((j) => !!j);
95
- value = single ? value[0] || '' : value;
96
- return value;
97
- };
98
- return { tempFile, uploading, upload, getTempFile };
99
- }