From 7b3233396fecc93ccba28a17f7b12a93511de599 Mon Sep 17 00:00:00 2001 From: helihui Date: Sun, 13 Aug 2023 01:30:11 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat(upload):=20=E6=96=B0=E5=A2=9E=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E7=BB=84=E4=BB=B6=E5=88=9D=E7=89=88=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + .../components/Upload/components/Upload.tsx | 168 ++++++++++++++++++ .../src/components/Upload/constants/index.ts | 3 + .../src/components/Upload/index.tsx | 3 + .../src/components/Upload/style/Upload.scss | 3 + .../src/components/Upload/style/index.scss | 3 + .../src/components/Upload/types/types.ts | 33 ++++ packages/yike-design/src/index.ts | 1 + 8 files changed, 216 insertions(+) create mode 100644 packages/yike-design/src/components/Upload/components/Upload.tsx create mode 100644 packages/yike-design/src/components/Upload/constants/index.ts create mode 100644 packages/yike-design/src/components/Upload/index.tsx create mode 100644 packages/yike-design/src/components/Upload/style/Upload.scss create mode 100644 packages/yike-design/src/components/Upload/style/index.scss create mode 100644 packages/yike-design/src/components/Upload/types/types.ts diff --git a/package.json b/package.json index 5b6c8f7b..d25c598c 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,8 @@ ] }, "dependencies": { + "axios": "^1.4.0", + "classnames": "^2.3.2", "react": "^18.2.0", "react-dom": "^18.2.0" } diff --git a/packages/yike-design/src/components/Upload/components/Upload.tsx b/packages/yike-design/src/components/Upload/components/Upload.tsx new file mode 100644 index 00000000..f0ecd02e --- /dev/null +++ b/packages/yike-design/src/components/Upload/components/Upload.tsx @@ -0,0 +1,168 @@ +import type React from 'react'; +import { useRef, type ChangeEvent, useState } from 'react'; +import type { UploadFile, UploadProps } from '../types/types'; +import { uploadClsPrefix } from '../constants'; +// import classnames from 'classnames'; +import axios, { type AxiosProgressEvent } from 'axios'; +const Upload: React.FC = props => { + const { + action, + defaultFileList, + header, + name, + data, + withCredentials, + accept, + multiple, + // drag, + onProgress, + onSuccess, + onError, + beforeUpload, + // onRemove, + onChange, + } = props; + + const uploadInputRef = useRef(null); + const [fileList, setFileList] = useState(defaultFileList || []); + + const updateFileList = (updateFile: UploadFile, updateObj: Partial) => { + setFileList(prevList => { + return prevList.map(file => { + if (file.uid === updateFile.uid) { + return { ...file, ...updateObj }; + } else { + return file; + } + }); + }); + }; + + const handleClick = () => { + if (uploadInputRef.current) { + uploadInputRef.current.click(); + } + }; + const handleFileChange = (e: ChangeEvent) => { + const files = e.target.files; + if (!files) { + return; + } + uploadFile(files); + if (uploadInputRef.current) { + uploadInputRef.current.value = ''; + } + }; + + const uploadFile = (file: FileList) => { + const files = Array.from(file); + files.forEach(file => { + if (!beforeUpload) { + postFile(file); + } else { + const result = beforeUpload(file); + if (result && result instanceof Promise) { + result.then(processedFile => { + postFile(processedFile); + }); + } else if (result != false) { + postFile(file); + } + } + }); + }; + + const postFile = (file: File) => { + const _file: UploadFile = { + uid: Date.now() + 'upload', + size: file.size, + name: file.name, + status: 'ready', + percent: 0, + raw: file, + }; + setFileList(prev => { + return [_file, ...prev]; + }); + const formData = new FormData(); + formData.append(name || 'file', file); + if (data) { + Object.keys(data).forEach(key => { + formData.append(key, data[key]); + }); + } + axios + .post(action, formData, { + headers: { + ...header, + 'Content-Type': 'multipart/form-data', + }, + withCredentials, + onUploadProgress: (e: AxiosProgressEvent) => { + if (e.total) { + const persent = Math.round((e.loaded * 100) / e.total) || 0; + if (persent < 100) { + updateFileList(_file, { percent: persent, status: 'uploading' }); + if (onProgress) { + onProgress(persent, file); + } + } + } + }, + }) + .then(response => { + updateFileList(_file, { percent: 100, status: 'success', response: response.data }); + if (onSuccess) { + onSuccess(response, file); + } + if (onChange) { + onChange(file); + } + }) + .catch(err => { + updateFileList(_file, { status: 'error', error: err }); + if (onError) { + onError(err, file); + } + if (onChange) { + onChange(file); + } + }); + }; + + // const handleRemove = (file: UploadFile) => { + // setFileList(prevList => { + // return prevList.filter(item => item.uid !== file.uid); + // }); + // if (onRemove) { + // onRemove(file); + // } + // }; + + return ( +
+
+ +
+
+ {fileList.map((item, index) => { + return
{item.name}
; + })} +
+
+ ); +}; + +export default Upload; diff --git a/packages/yike-design/src/components/Upload/constants/index.ts b/packages/yike-design/src/components/Upload/constants/index.ts new file mode 100644 index 00000000..ad5300c7 --- /dev/null +++ b/packages/yike-design/src/components/Upload/constants/index.ts @@ -0,0 +1,3 @@ +export const uiClsPrefix = 'yike'; + +export const uploadClsPrefix = `${uiClsPrefix}-upload`; diff --git a/packages/yike-design/src/components/Upload/index.tsx b/packages/yike-design/src/components/Upload/index.tsx new file mode 100644 index 00000000..c3d04682 --- /dev/null +++ b/packages/yike-design/src/components/Upload/index.tsx @@ -0,0 +1,3 @@ +import Upload from './components/Upload'; + +export { Upload }; diff --git a/packages/yike-design/src/components/Upload/style/Upload.scss b/packages/yike-design/src/components/Upload/style/Upload.scss new file mode 100644 index 00000000..8c0da8e3 --- /dev/null +++ b/packages/yike-design/src/components/Upload/style/Upload.scss @@ -0,0 +1,3 @@ +/* stylelint-disable-next-line block-no-empty */ +.yike-upload { +} diff --git a/packages/yike-design/src/components/Upload/style/index.scss b/packages/yike-design/src/components/Upload/style/index.scss new file mode 100644 index 00000000..8c0da8e3 --- /dev/null +++ b/packages/yike-design/src/components/Upload/style/index.scss @@ -0,0 +1,3 @@ +/* stylelint-disable-next-line block-no-empty */ +.yike-upload { +} diff --git a/packages/yike-design/src/components/Upload/types/types.ts b/packages/yike-design/src/components/Upload/types/types.ts new file mode 100644 index 00000000..a42e4d7a --- /dev/null +++ b/packages/yike-design/src/components/Upload/types/types.ts @@ -0,0 +1,33 @@ +import { type AxiosResponse } from 'axios'; + +export interface UploadProps { + //attr + action: string; + defaultFileList?: Array; + header?: { [key: string]: any }; + name?: string; + data?: { [key: string]: any }; + withCredentials?: boolean; + accept?: string; + multiple?: boolean; + drag?: boolean; + // function + onProgress?: (presentNumber: number, file: File) => void; + onSuccess?: (data: AxiosResponse, file: File) => void; + onError?: (err: any, file: File) => void; + beforeUpload?: (file: File) => boolean | Promise; + onChange?: (file: File) => void; + onRemove?: (file: UploadFile) => void; +} +type FileStatus = 'ready' | 'success' | 'uploading' | 'error'; + +export interface UploadFile extends Partial { + uid: string; + size: number; + name: string; + status?: FileStatus; + percent?: number; + raw?: File; + response?: any; + error?: any; +} diff --git a/packages/yike-design/src/index.ts b/packages/yike-design/src/index.ts index 28a6ee3b..f7c62b5d 100644 --- a/packages/yike-design/src/index.ts +++ b/packages/yike-design/src/index.ts @@ -1,2 +1,3 @@ export * from './components/Button'; export * from './components/Space'; +export * from './components/Upload'; From d9ec02c821c02f147745e8caadd244dd197cc31b Mon Sep 17 00:00:00 2001 From: xiefeng <1294699027@qq.com> Date: Sun, 13 Aug 2023 10:47:26 +0800 Subject: [PATCH 2/2] fix: fix package install position --- package.json | 2 -- packages/yike-design/package.json | 4 ++- .../components/Upload/components/Upload.tsx | 30 +++++++++++-------- .../src/components/Upload/style/index.ts | 1 + 4 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 packages/yike-design/src/components/Upload/style/index.ts diff --git a/package.json b/package.json index d25c598c..5b6c8f7b 100644 --- a/package.json +++ b/package.json @@ -60,8 +60,6 @@ ] }, "dependencies": { - "axios": "^1.4.0", - "classnames": "^2.3.2", "react": "^18.2.0", "react-dom": "^18.2.0" } diff --git a/packages/yike-design/package.json b/packages/yike-design/package.json index 5dc85aa1..1ce1a794 100644 --- a/packages/yike-design/package.json +++ b/packages/yike-design/package.json @@ -24,7 +24,9 @@ "react-dom": ">=16.8.0" }, "dependencies": { - "@babel/runtime": "^7.22.6" + "@babel/runtime": "^7.22.6", + "axios": "^1.4.0", + "clsx": "^2.0.0" }, "devDependencies": { "clean-package": "^2.2.0" diff --git a/packages/yike-design/src/components/Upload/components/Upload.tsx b/packages/yike-design/src/components/Upload/components/Upload.tsx index f0ecd02e..a7016935 100644 --- a/packages/yike-design/src/components/Upload/components/Upload.tsx +++ b/packages/yike-design/src/components/Upload/components/Upload.tsx @@ -1,10 +1,12 @@ +import clsx from 'clsx'; import type React from 'react'; -import { useRef, type ChangeEvent, useState } from 'react'; -import type { UploadFile, UploadProps } from '../types/types'; -import { uploadClsPrefix } from '../constants'; -// import classnames from 'classnames'; +import { useRef, useState } from 'react'; import axios, { type AxiosProgressEvent } from 'axios'; -const Upload: React.FC = props => { + +import { uploadClsPrefix } from '../constants'; +import type { UploadFile, UploadProps } from '../types/types'; + +const Upload: React.FC> = props => { const { action, defaultFileList, @@ -21,6 +23,8 @@ const Upload: React.FC = props => { beforeUpload, // onRemove, onChange, + + children, } = props; const uploadInputRef = useRef(null); @@ -43,7 +47,8 @@ const Upload: React.FC = props => { uploadInputRef.current.click(); } }; - const handleFileChange = (e: ChangeEvent) => { + + const handleFileChange = (e: React.ChangeEvent) => { const files = e.target.files; if (!files) { return; @@ -100,11 +105,11 @@ const Upload: React.FC = props => { withCredentials, onUploadProgress: (e: AxiosProgressEvent) => { if (e.total) { - const persent = Math.round((e.loaded * 100) / e.total) || 0; - if (persent < 100) { - updateFileList(_file, { percent: persent, status: 'uploading' }); + const percent = Math.round((e.loaded * 100) / e.total) || 0; + if (percent < 100) { + updateFileList(_file, { percent: percent, status: 'uploading' }); if (onProgress) { - onProgress(persent, file); + onProgress(percent, file); } } } @@ -140,9 +145,9 @@ const Upload: React.FC = props => { // }; return ( -
+
@@ -155,6 +160,7 @@ const Upload: React.FC = props => { accept={accept} multiple={multiple} /> + {children}
{fileList.map((item, index) => { diff --git a/packages/yike-design/src/components/Upload/style/index.ts b/packages/yike-design/src/components/Upload/style/index.ts new file mode 100644 index 00000000..67aac616 --- /dev/null +++ b/packages/yike-design/src/components/Upload/style/index.ts @@ -0,0 +1 @@ +import './index.scss';