Skip to content

Commit

Permalink
feat: 新增上传图片组件 (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
JavanCheng authored Jan 21, 2023
1 parent 493162c commit 7c3412e
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 1 deletion.
127 changes: 127 additions & 0 deletions src/components/UploadImagesFormItem/index.tsx
Original file line number Diff line number Diff line change
@@ -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<string> => {
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<boolean>(false);
const [previewImage, setPreviewImage] = useState<string>('');
const [previewTitle, setPreviewTitle] = useState<string>('');
const [fileList, setFileList] = useState<UploadFile[]>([]);
const [url, setUrl] = useState<string>('');
const [sessionToken, setSessionToken] = useState<string>('');
const [contentType, setContentType] = useState<string>('');
const [callbackUrl, setCallbackUrl] = useState<string[]>([]);

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<any> => {
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 = (
<div>
<PlusOutlined />
<div style={{ marginTop: 8 }}>上传图片</div>
</div>
);

return (
<>
<Upload
action={url}
listType="picture-card"
fileList={fileList}
onPreview={handlePreview}
onChange={handleChange}
beforeUpload={beforeUpload}
method="PUT"
customRequest={handleRequest}
>
{fileList.length >= 9 ? null : uploadButton}
</Upload>
<Modal open={previewOpen} title={previewTitle} footer={null} onCancel={handleCancel}>
<img alt="example" style={{ width: '100%' }} src={previewImage} />
</Modal>
</>
);
};

export default UploadImagesFormItem;
14 changes: 14 additions & 0 deletions src/pages/CatMessage/components/Create/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import UploadImagesFormItem from '@/components/UploadImagesFormItem';
import { createCatInfo } from '@/services/cat';
import {
DrawerForm,
Expand All @@ -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) => {
Expand Down Expand Up @@ -145,6 +147,18 @@ const Create = ({ open, setCreateVisible, actionRef }: any) => {
},
]}
/>
<Form.Item
name="avatars"
label="照片"
rules={[
{
required: true,
message: '此条必填',
},
]}
>
<UploadImagesFormItem></UploadImagesFormItem>
</Form.Item>
</DrawerForm>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/pages/News/components/Edit/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions src/pages/Welcome/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import UploadImagesFormItem from '@/components/UploadImagesFormItem';
import { PageContainer } from '@ant-design/pro-components';
import { Card } from 'antd';
import React from 'react';
Expand Down Expand Up @@ -33,6 +34,7 @@ const Welcome: React.FC = () => {
</div>
</div>
</Card>
<UploadImagesFormItem />
</PageContainer>
);
};
Expand Down
18 changes: 18 additions & 0 deletions src/services/cos.ts
Original file line number Diff line number Diff line change
@@ -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 || {}),
});
};

0 comments on commit 7c3412e

Please sign in to comment.