feat: 头像上传

This commit is contained in:
qitmac000249 2017-08-10 21:20:23 +08:00
parent 8054a95cd5
commit 0f17d0b625
5 changed files with 109 additions and 70 deletions

View File

@ -69,7 +69,7 @@ const ToolUser = (props)=> (
/>
}>
<a className="dropdown-link">
<img style={{width:24,height:24}} src="/user/avatar" /><span className="name">{props.user}</span>
<img style={{width:24,height:24}} src={`/user/avatar?uid=${props.uid}`} /><span className="name">{props.user}</span>
</a>
</Dropdown>
</li>
@ -89,6 +89,7 @@ ToolUser.propTypes={
@connect(
(state) => {
return{
avatar: state.login.avatar,
user: state.login.userName,
uid: state.login.uid,
msg: null,
@ -163,6 +164,9 @@ export default class HeaderCom extends Component {
console.log(err);
})
}
render () {
const { login, user, msg, uid } = this.props;
return (

View File

@ -1,56 +0,0 @@
import './index.scss'
import React, { Component } from 'react'
// import PropTypes from 'prop-types'
import { Upload, Icon, message } from 'antd'
class Avatar extends Component {
constructor(props) {
super(props);
this.state = {
imageUrl:""
}
}
handleChange(info){
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => this.setState({ imageUrl }));
}
}
render() {
const imageUrl = this.state.imageUrl;
return <div className="avatar-box">
<Upload
className="avatar-uploader"
name="avatar"
showUploadList={true}
action="//jsonplaceholder.typicode.com/posts/"
beforeUpload={beforeUpload}
onChange={this.handleChange.bind(this)} >
{
imageUrl ?
<img src={imageUrl} alt="" className="avatar" /> :
<Icon type="plus" className="avatar-uploader-trigger" />
}
</Upload>
</div>
}
}
function beforeUpload(file) {
const isJPG = file.type === 'image/jpeg';
if (!isJPG) {
message.error('You can only upload JPG file!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('Image must smaller than 2MB!');
}
return isJPG && isLt2M;
}
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default Avatar;

View File

@ -1,10 +1,9 @@
import React, { Component } from 'react'
import { Row, Col, Input, Button, Select, message } from 'antd'
import { Row, Col, Input, Button, Select, message, Upload, Icon } from 'antd'
import axios from 'axios';
import {formatTime} from '../../common.js'
import PropTypes from 'prop-types'
class Profile extends Component {
static propTypes = {
@ -191,6 +190,7 @@ class Profile extends Component {
return <div className="user-profile">
<Row className="user-item" type="flex" justify="start">
<Col span={24}><Avatar uid={userinfo.uid}>点击上传头像</Avatar></Col>
<Col span={4}>用户id</Col>
<Col span={12}>
{userinfo.uid}
@ -237,4 +237,76 @@ class Profile extends Component {
}
}
class Avatar extends Component {
constructor(props) {
super(props);
this.state = {
imageUrl:""
}
}
static propTypes = {
uid: PropTypes.number
}
uploadAvatar(basecode){
axios.post("/user/upload_avatar",{basecode: basecode}).then(()=>{
this.setState({ imageUrl: basecode })
}).catch((e)=>{
console.log(e);
})
}
handleChange(info){
if (info.file.status === 'done') {
// Get this url from response in real world.
getBase64(info.file.originFileObj, basecode=>{this.uploadAvatar(basecode)});
}
}
render() {
let imageUrl = "";
if(this.props.uid && !this.state.imageUrl){
imageUrl = `/user/avatar?uid=${this.props.uid}`;
}else{
imageUrl = this.state.imageUrl;
}
return <div className="avatar-box">
<Upload
className="avatar-uploader"
name="basecode"
showUploadList={true}
action="/user/upload_avatar"
beforeUpload={beforeUpload}
onChange={this.handleChange.bind(this)} >
{
imageUrl ?
<img src={imageUrl} alt="" className="avatar" /> :
<Icon type="plus" className="avatar-uploader-trigger" />
}
</Upload>
</div>
}
}
function beforeUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isPNG = file.type === 'image/png';
if (!isJPG && !isPNG) {
message.error('图片的格式只能为 jpg、png');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片必须小于 200kb!');
}
return (isPNG||isJPG) && isLt2M;
}
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img);
}
export default Profile

View File

@ -2,12 +2,12 @@ import './index.scss'
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { Route } from 'react-router-dom'
import LeftMenu from './LeftMenu.js'
// import LeftMenu from './LeftMenu.js'
import List from './List.js'
import PropTypes from 'prop-types'
import Profile from './Profile.js'
import { Row, Col } from 'antd';
import { Row } from 'antd';
import Subnav from '../../components/Subnav/Subnav.js';
@connect()
class User extends Component {
static propTypes = {
@ -26,16 +26,22 @@ class User extends Component {
return (
<div className="g-doc">
<Row gutter={16} className="user-box">
<Col span={6}>
<LeftMenu />
</Col>
<Col span={18}>
<div>
<Subnav
default={'我的关注'}
data={[{
name: '项目广场',
path: '/group'
}, {
name: '我的关注',
path: '/follow'
}]}/>
<div className="g-doc">
<Row gutter={16} className="user-box">
<Route path={this.props.match.path + '/list'} component={List} />
<Route path={this.props.match.path + '/profile/:uid'} component={Profile} />
</Col>
</Row>
</Row>
</div>
</div>
)
}

View File

@ -6,6 +6,7 @@ const LOGIN_OUT = 'yapi/login/LOGIN_OUT';
const LOGIN_TYPE = 'yapi/login/LOGIN_TYPE';
const GET_LOGIN_STATE = 'yapi/login/GET_LOGIN_STATE';
const REGISTER = 'yapi/login/REGISTER';
const GET_AVATAR = 'yapi/login/AVATAR';
// Reducer
const LOADING_STATUS = 0;
@ -72,6 +73,11 @@ export default (state = initialState, action) => {
userName: action.payload.data.data.username
};
}
case GET_AVATAR: {
return {
...state
}
}
default:
return state;
}
@ -124,3 +130,10 @@ export function loginTypeAction(index) {
index
}
}
export function getAvatar(){
return {
type: GET_AVATAR,
payload: axios.get("/user/avatar")
}
}