diff --git a/src/components/UploadImagesFormItem/index.tsx b/src/components/UploadImagesFormItem/index.tsx new file mode 100644 index 0000000..7be23c5 --- /dev/null +++ b/src/components/UploadImagesFormItem/index.tsx @@ -0,0 +1,127 @@ +import { PlusOutlined } from '@ant-design/icons'; +import type { RcFile, UploadProps } from 'antd/es/upload'; +import type { UploadFile } from 'antd/es/upload/interface'; +import { Modal, Upload } from 'antd'; +import { useState } from 'react'; +import { applySignedUrl } from '@/services/cos'; +import { request } from '@umijs/max'; + +const CDN = 'static.xhpolaris.com'; + +const getBase64 = (file: RcFile): Promise => { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => resolve(reader.result as string); + reader.onerror = (error) => reject(error); + }); +}; + +const UploadImagesFormItem = ({ value = [], onChange }: any) => { + const [previewOpen, setPreviewOpen] = useState(false); + const [previewImage, setPreviewImage] = useState(''); + const [previewTitle, setPreviewTitle] = useState(''); + const [fileList, setFileList] = useState([]); + const [url, setUrl] = useState(''); + const [sessionToken, setSessionToken] = useState(''); + const [contentType, setContentType] = useState(''); + const [callbackUrl, setCallbackUrl] = useState([]); + + const handleCancel = () => setPreviewOpen(false); + + const handlePreview = async (file: UploadFile) => { + if (!file.url && !file.preview) { + file.preview = await getBase64(file.originFileObj as RcFile); + } + setPreviewImage(file.url || (file.preview as string)); + setPreviewOpen(true); + setPreviewTitle(file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1)); + }; + + const handleChange: UploadProps['onChange'] = ({ fileList: newFileList }) => { + setFileList(newFileList); + if (newFileList[newFileList.length - 1]?.status === 'done') { + // 去除url内的param + let newUrl = url.substring(0, url.lastIndexOf('?')); + // 将url的host替换为CDN域名 + newUrl = newUrl.replace(/(https:\/\/|http:\/\/)(.*?)(\/.*)/, `$1${CDN}$3`); + setCallbackUrl([...callbackUrl, newUrl]); + onChange?.([...value, newUrl]); + } + }; + + // 打印图片在线 url + console.log('callbackUrl: ', callbackUrl); + + const beforeUpload = async (file: any): Promise => { + const { name, type } = file; + const suffix = name.substring(name.lastIndexOf('.')); + const resp = await applySignedUrl({ + suffix: suffix, + }); + if (resp.url) { + setUrl(resp.url); + } + if (resp.sessionToken) { + setSessionToken(resp.sessionToken); + } + if (type) { + setContentType(type); + } + }; + + const handleRequest = async (options: any) => { + const { onSuccess, onError, file } = options; + const binaryString: string = await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.readAsBinaryString(file); + reader.onload = () => resolve(reader.result as string); + reader.onerror = (error) => reject(error); + }); + const config = { + headers: { + 'x-cos-security-token': sessionToken, + 'Content-Type': contentType, + }, + }; + try { + const res = await request(url, { + method: 'PUT', + data: binaryString, + ...config, + }); + onSuccess(res); + } catch (e) { + onError({ e }); + } + }; + + const uploadButton = ( +
+ +
上传图片
+
+ ); + + return ( + <> + + {fileList.length >= 9 ? null : uploadButton} + + + example + + + ); +}; + +export default UploadImagesFormItem; diff --git a/src/pages/CatMessage/components/Create/index.tsx b/src/pages/CatMessage/components/Create/index.tsx index 77d0119..946cc92 100644 --- a/src/pages/CatMessage/components/Create/index.tsx +++ b/src/pages/CatMessage/components/Create/index.tsx @@ -1,3 +1,4 @@ +import UploadImagesFormItem from '@/components/UploadImagesFormItem'; import { createCatInfo } from '@/services/cat'; import { DrawerForm, @@ -7,6 +8,7 @@ import { ProFormText, ProFormTextArea, } from '@ant-design/pro-components'; +import { Form } from 'antd'; const Create = ({ open, setCreateVisible, actionRef }: any) => { const handleCreate = async (value: any) => { @@ -145,6 +147,18 @@ const Create = ({ open, setCreateVisible, actionRef }: any) => { }, ]} /> + + + ); }; diff --git a/src/pages/News/components/Edit/index.tsx b/src/pages/News/components/Edit/index.tsx index fcf8d10..aa3ae71 100644 --- a/src/pages/News/components/Edit/index.tsx +++ b/src/pages/News/components/Edit/index.tsx @@ -11,7 +11,7 @@ const Edit = ({ open, setEditVisible, actionRef, currentNew }: any) => { ...value, id: currentNew, communityId: '637ce159b15d9764c31f9c84', - avatars: ['https://static.xhpolaris.com/cat_world.jpg'], + photos: ['https://static.xhpolaris.com/cat_world.jpg'], }; const success = await editNewInfo(data); if (success) { diff --git a/src/pages/Welcome/index.tsx b/src/pages/Welcome/index.tsx index d05c982..5adf4f4 100644 --- a/src/pages/Welcome/index.tsx +++ b/src/pages/Welcome/index.tsx @@ -1,3 +1,4 @@ +import UploadImagesFormItem from '@/components/UploadImagesFormItem'; import { PageContainer } from '@ant-design/pro-components'; import { Card } from 'antd'; import React from 'react'; @@ -33,6 +34,7 @@ const Welcome: React.FC = () => { + ); }; diff --git a/src/services/cos.ts b/src/services/cos.ts new file mode 100644 index 0000000..0371fff --- /dev/null +++ b/src/services/cos.ts @@ -0,0 +1,18 @@ +import { request } from '@umijs/max'; + +const DEFAULT_URL = 'https://meowchat.xhpolaris.com'; + +/** + * 获取预签名 url + * @param params + * @returns + */ +export const applySignedUrl = async (data: any, options?: { [key: string]: any }) => { + return request(`${DEFAULT_URL}/sts/apply_signed_url`, { + method: 'POST', + data: { + ...data, + }, + ...(options || {}), + }); +};