210 lines
5.6 KiB
JavaScript
210 lines
5.6 KiB
JavaScript
import React from "react";
|
||
import {fileGetQiniuToken} from "../../services/admin";
|
||
import uuid from "js-uuid";
|
||
import * as qiniu from "qiniu-js";
|
||
import {Icon, Modal, Upload} from "antd";
|
||
|
||
import styles from './PicturesWall.less';
|
||
|
||
/**
|
||
* 照片墙,带有上传图片到七牛。
|
||
*/
|
||
class PicturesWall extends React.Component {
|
||
state = {
|
||
token: undefined, // 七牛 token
|
||
|
||
|
||
previewVisible: false,
|
||
previewImage: '',
|
||
|
||
fileList: [
|
||
// { // 目前图片
|
||
// uid: -1,
|
||
// name: 'xxx.png',
|
||
// status: 'done',
|
||
// url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
|
||
// }
|
||
],
|
||
};
|
||
|
||
componentDidMount() {
|
||
if (this.props.urls) {
|
||
this.setUrls(this.props.urls);
|
||
}
|
||
}
|
||
|
||
handleCancel = () => this.setState({ previewVisible: false })
|
||
|
||
handlePreview = (file) => {
|
||
this.setState({
|
||
previewImage: file.url || file.thumbUrl,
|
||
previewVisible: true,
|
||
});
|
||
}
|
||
|
||
beforeUpload = async () => {
|
||
const tokenResult = await fileGetQiniuToken();
|
||
if (tokenResult.code !== 0) {
|
||
alert('获得七牛上传 Token 失败');
|
||
return false;
|
||
}
|
||
this.setState({
|
||
token: tokenResult.data,
|
||
});
|
||
return true;
|
||
};
|
||
|
||
customRequest = ({action,
|
||
file,
|
||
headers,
|
||
onError,
|
||
onProgress,
|
||
onSuccess,
|
||
withCredentials,}) => {
|
||
// fs.readFile(path, function(err, data) {
|
||
// if (err) return;
|
||
// let md5Value= crypto.createHash('md5').update(data, 'utf8').digest('hex');
|
||
// let observable = qiniu.upload(file, md5Value, this.state.token);
|
||
// observable.subscribe(function () {
|
||
// // next
|
||
// }, function () {
|
||
// // error
|
||
// }, function (response) {
|
||
// // complete
|
||
// debugger;
|
||
// onSuccess(response, file);
|
||
// });
|
||
// });
|
||
|
||
// 使用 FileReader 将上传的文件转换成二进制流,满足 'application/octet-stream' 格式的要求
|
||
const reader = new FileReader();
|
||
reader.readAsArrayBuffer(file);
|
||
let fileData = null;
|
||
reader.onload = (e) => {
|
||
// 在文件读取结束后执行的操作
|
||
fileData = e.target.result;
|
||
// debugger;
|
||
// let md5Value= crypto.createHash('md5').update(fileData, 'utf8').digest('hex');
|
||
// 上传文件
|
||
// fileUploadQiniu(fileData);
|
||
// debugger;
|
||
// 使用 axios 进行文件上传的请求
|
||
// axios.put(action, fileData, {
|
||
// withCredentials,
|
||
// headers,
|
||
// onUploadProgress: ({ total, loaded }) => {
|
||
// // 进行上传进度输出,更加直观
|
||
// onProgress({ percent: Math.round(loaded / total * 100).toFixed(2) }, file);
|
||
// },
|
||
// }).then(response => {
|
||
// onSuccess(response, file);
|
||
// })
|
||
// .catch(onError);
|
||
let key = uuid.v4(); // TODO 芋艿,可能后面要优化。MD5?
|
||
let observable = qiniu.upload(file, key, this.state.token); // TODO 芋艿,最后后面去掉 qiniu 的库依赖,直接 http 请求,这样更轻量
|
||
observable.subscribe(function () {
|
||
// next
|
||
}, function () {
|
||
// error
|
||
// TODO 芋艿,后续补充
|
||
debugger;
|
||
}, function (response) {
|
||
debugger;
|
||
// complete
|
||
// debugger;
|
||
response.url = 'http://static.shop.iocoder.cn/' + response.key; // 需要设置,用于后续 onSuccess ,合并到 file 中,从而设置到 fileList
|
||
onSuccess(response, file);
|
||
});
|
||
};
|
||
return {
|
||
abort() {
|
||
console.log('upload progress is aborted.');
|
||
},
|
||
};
|
||
};
|
||
|
||
handleChange = ({ file, fileList }) => {
|
||
if (file.response && file.response.url) {
|
||
// debugger
|
||
// file.url =
|
||
for (let i in fileList) {
|
||
if (fileList[i].uid === file.uid) {
|
||
fileList[i].url = file.response.url;
|
||
}
|
||
}
|
||
}
|
||
this.setState({ fileList });
|
||
}
|
||
|
||
getUrls = () => {
|
||
let urls = [];
|
||
for (let i in this.state.fileList) {
|
||
urls.push(this.state.fileList[i].url);
|
||
}
|
||
return urls;
|
||
};
|
||
|
||
getUrl = () => {
|
||
let urls = this.getUrls();
|
||
if (urls && urls.length > 0) {
|
||
return urls[0];
|
||
}
|
||
return undefined;
|
||
};
|
||
|
||
setUrls = (urls) => {
|
||
// let urls = this.props.urls;
|
||
if (urls) {
|
||
let fileList = [];
|
||
for (let i in urls) {
|
||
let url = urls[i];
|
||
fileList.push({
|
||
uid: -i,
|
||
name: url,
|
||
status: 'done',
|
||
url,
|
||
});
|
||
}
|
||
this.setState({
|
||
fileList: fileList,
|
||
})
|
||
}
|
||
};
|
||
|
||
render() {
|
||
const { previewVisible, previewImage, fileList } = this.state;
|
||
const uploadButton = (
|
||
<div>
|
||
<Icon type="plus" />
|
||
<div className="ant-upload-text">Upload</div>
|
||
</div>
|
||
);
|
||
return (
|
||
<div className="clearfix">
|
||
<Upload
|
||
// action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
|
||
// action="https://up-z2.qiniu.com"
|
||
listType="picture-card"
|
||
fileList={fileList}
|
||
onPreview={this.handlePreview}
|
||
onChange={this.handleChange}
|
||
beforeUpload={this.beforeUpload}
|
||
customRequest={this.customRequest}
|
||
>
|
||
{fileList.length >= this.props.maxLength ? null : uploadButton}
|
||
</Upload>
|
||
<Modal visible={previewVisible} footer={null} onCancel={this.handleCancel}>
|
||
<img alt="example" style={{ width: '100%' }} src={previewImage} />
|
||
</Modal>
|
||
</div>
|
||
);
|
||
}
|
||
};
|
||
|
||
PicturesWall.propTypes = {
|
||
maxLength: Number, // 最大照片墙图片数量
|
||
urls: Array, // 初始图片列表
|
||
};
|
||
|
||
export default PicturesWall;
|