mock平台

Profile.js 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. import React, { PureComponent as Component } from 'react';
  2. import { Row, Col, Input, Button, Select, message, Upload, Tooltip } from 'antd';
  3. import axios from 'axios';
  4. import { formatTime } from '../../common.js';
  5. import PropTypes from 'prop-types';
  6. import { setBreadcrumb, setImageUrl } from '../../reducer/modules/user';
  7. import { connect } from 'react-redux';
  8. const EditButton = props => {
  9. const { isAdmin, isOwner, onClick, name, admin } = props;
  10. if (isOwner) {
  11. // 本人
  12. if (admin) {
  13. return null;
  14. }
  15. return (
  16. <Button
  17. icon="edit"
  18. onClick={() => {
  19. onClick(name, true);
  20. }}
  21. >
  22. 修改
  23. </Button>
  24. );
  25. } else if (isAdmin) {
  26. // 管理员
  27. return (
  28. <Button
  29. icon="edit"
  30. onClick={() => {
  31. onClick(name, true);
  32. }}
  33. >
  34. 修改
  35. </Button>
  36. );
  37. } else {
  38. return null;
  39. }
  40. };
  41. EditButton.propTypes = {
  42. isAdmin: PropTypes.bool,
  43. isOwner: PropTypes.bool,
  44. onClick: PropTypes.func,
  45. name: PropTypes.string,
  46. admin: PropTypes.bool
  47. };
  48. @connect(
  49. state => {
  50. return {
  51. curUid: state.user.uid,
  52. userType: state.user.type,
  53. curRole: state.user.role
  54. };
  55. },
  56. {
  57. setBreadcrumb
  58. }
  59. )
  60. class Profile extends Component {
  61. static propTypes = {
  62. match: PropTypes.object,
  63. curUid: PropTypes.number,
  64. userType: PropTypes.string,
  65. setBreadcrumb: PropTypes.func,
  66. curRole: PropTypes.string,
  67. upload: PropTypes.bool
  68. };
  69. constructor(props) {
  70. super(props);
  71. this.state = {
  72. usernameEdit: false,
  73. emailEdit: false,
  74. secureEdit: false,
  75. roleEdit: false,
  76. userinfo: {}
  77. };
  78. }
  79. componentDidMount() {
  80. this._uid = this.props.match.params.uid;
  81. this.handleUserinfo(this.props);
  82. }
  83. componentWillReceiveProps(nextProps) {
  84. if (!nextProps.match.params.uid) {
  85. return;
  86. }
  87. if (this._uid !== nextProps.match.params.uid) {
  88. this.handleUserinfo(nextProps);
  89. }
  90. }
  91. handleUserinfo(props) {
  92. const uid = props.match.params.uid;
  93. this.getUserInfo(uid);
  94. }
  95. handleEdit = (key, val) => {
  96. var s = {};
  97. s[key] = val;
  98. this.setState(s);
  99. };
  100. getUserInfo = id => {
  101. var _this = this;
  102. const { curUid } = this.props;
  103. axios.get('/api/user/find?id=' + id).then(res => {
  104. _this.setState({
  105. userinfo: res.data.data,
  106. _userinfo: res.data.data
  107. });
  108. if (curUid === +id) {
  109. this.props.setBreadcrumb([{ name: res.data.data.username }]);
  110. } else {
  111. this.props.setBreadcrumb([{ name: '管理: ' + res.data.data.username }]);
  112. }
  113. });
  114. };
  115. updateUserinfo = name => {
  116. var state = this.state;
  117. let value = this.state._userinfo[name];
  118. let params = { uid: state.userinfo.uid };
  119. params[name] = value;
  120. axios.post('/api/user/update', params).then(
  121. res => {
  122. let data = res.data;
  123. if (data.errcode === 0) {
  124. let userinfo = this.state.userinfo;
  125. userinfo[name] = value;
  126. this.setState({
  127. userinfo: userinfo
  128. });
  129. this.handleEdit(name + 'Edit', false);
  130. message.success('更新用户信息成功');
  131. } else {
  132. message.error(data.errmsg);
  133. }
  134. },
  135. err => {
  136. message.error(err.message);
  137. }
  138. );
  139. };
  140. changeUserinfo = e => {
  141. let dom = e.target;
  142. let name = dom.getAttribute('name');
  143. let value = dom.value;
  144. this.setState({
  145. _userinfo: {
  146. ...this.state._userinfo,
  147. [name]: value
  148. }
  149. });
  150. };
  151. changeRole = val => {
  152. let userinfo = this.state.userinfo;
  153. userinfo.role = val;
  154. this.setState({
  155. _userinfo: userinfo
  156. });
  157. this.updateUserinfo('role');
  158. };
  159. updatePassword = () => {
  160. let old_password = document.getElementById('old_password').value;
  161. let password = document.getElementById('password').value;
  162. let verify_pass = document.getElementById('verify_pass').value;
  163. if (password != verify_pass) {
  164. return message.error('两次输入的密码不一样');
  165. }
  166. let params = {
  167. uid: this.state.userinfo.uid,
  168. password: password,
  169. old_password: old_password
  170. };
  171. axios.post('/api/user/change_password', params).then(
  172. res => {
  173. let data = res.data;
  174. if (data.errcode === 0) {
  175. this.handleEdit('secureEdit', false);
  176. message.success('修改密码成功');
  177. if (this.props.curUid === this.state.userinfo.uid) {
  178. location.reload();
  179. }
  180. } else {
  181. message.error(data.errmsg);
  182. }
  183. },
  184. err => {
  185. message.error(err.message);
  186. }
  187. );
  188. };
  189. render() {
  190. let ButtonGroup = Button.Group;
  191. let userNameEditHtml, emailEditHtml, secureEditHtml, roleEditHtml;
  192. const Option = Select.Option;
  193. let userinfo = this.state.userinfo;
  194. let _userinfo = this.state._userinfo;
  195. let roles = { admin: '管理员', member: '会员' };
  196. let userType = '';
  197. if (this.props.userType === 'third') {
  198. userType = false;
  199. } else if (this.props.userType === 'site') {
  200. userType = true;
  201. } else {
  202. userType = false;
  203. }
  204. // 用户名信息修改
  205. if (this.state.usernameEdit === false) {
  206. userNameEditHtml = (
  207. <div>
  208. <span className="text">{userinfo.username}</span>&nbsp;&nbsp;
  209. {/*<span className="text-button" onClick={() => { this.handleEdit('usernameEdit', true) }}><Icon type="edit" />修改</span>*/}
  210. {/* {btn} */}
  211. {/* 站点登陆才能编辑 */}
  212. {userType && (
  213. <EditButton
  214. userType={userType}
  215. isOwner={userinfo.uid === this.props.curUid}
  216. isAdmin={this.props.curRole === 'admin'}
  217. onClick={this.handleEdit}
  218. name="usernameEdit"
  219. />
  220. )}
  221. </div>
  222. );
  223. } else {
  224. userNameEditHtml = (
  225. <div>
  226. <Input
  227. value={_userinfo.username}
  228. name="username"
  229. onChange={this.changeUserinfo}
  230. placeholder="用户名"
  231. />
  232. <ButtonGroup className="edit-buttons">
  233. <Button
  234. className="edit-button"
  235. onClick={() => {
  236. this.handleEdit('usernameEdit', false);
  237. }}
  238. >
  239. 取消
  240. </Button>
  241. <Button
  242. className="edit-button"
  243. onClick={() => {
  244. this.updateUserinfo('username');
  245. }}
  246. type="primary"
  247. >
  248. 确定
  249. </Button>
  250. </ButtonGroup>
  251. </div>
  252. );
  253. }
  254. // 邮箱信息修改
  255. if (this.state.emailEdit === false) {
  256. emailEditHtml = (
  257. <div>
  258. <span className="text">{userinfo.email}</span>&nbsp;&nbsp;
  259. {/*<span className="text-button" onClick={() => { this.handleEdit('emailEdit', true) }} ><Icon type="edit" />修改</span>*/}
  260. {/* {btn} */}
  261. {/* 站点登陆才能编辑 */}
  262. {userType && (
  263. <EditButton
  264. admin={userinfo.role === 'admin'}
  265. isOwner={userinfo.uid === this.props.curUid}
  266. isAdmin={this.props.curRole === 'admin'}
  267. onClick={this.handleEdit}
  268. name="emailEdit"
  269. />
  270. )}
  271. </div>
  272. );
  273. } else {
  274. emailEditHtml = (
  275. <div>
  276. <Input
  277. placeholder="Email"
  278. value={_userinfo.email}
  279. name="email"
  280. onChange={this.changeUserinfo}
  281. />
  282. <ButtonGroup className="edit-buttons">
  283. <Button
  284. className="edit-button"
  285. onClick={() => {
  286. this.handleEdit('emailEdit', false);
  287. }}
  288. >
  289. 取消
  290. </Button>
  291. <Button
  292. className="edit-button"
  293. type="primary"
  294. onClick={() => {
  295. this.updateUserinfo('email');
  296. }}
  297. >
  298. 确定
  299. </Button>
  300. </ButtonGroup>
  301. </div>
  302. );
  303. }
  304. if (this.state.roleEdit === false) {
  305. roleEditHtml = (
  306. <div>
  307. <span className="text">{roles[userinfo.role]}</span>&nbsp;&nbsp;
  308. </div>
  309. );
  310. } else {
  311. roleEditHtml = (
  312. <Select defaultValue={_userinfo.role} onChange={this.changeRole} style={{ width: 150 }}>
  313. <Option value="admin">管理员</Option>
  314. <Option value="member">会员</Option>
  315. </Select>
  316. );
  317. }
  318. if (this.state.secureEdit === false) {
  319. let btn = '';
  320. if (userType) {
  321. btn = (
  322. <Button
  323. icon="edit"
  324. onClick={() => {
  325. this.handleEdit('secureEdit', true);
  326. }}
  327. >
  328. 修改
  329. </Button>
  330. );
  331. }
  332. secureEditHtml = btn;
  333. } else {
  334. secureEditHtml = (
  335. <div>
  336. <Input
  337. style={{
  338. display: this.props.curRole === 'admin' && userinfo.role != 'admin' ? 'none' : ''
  339. }}
  340. placeholder="旧的密码"
  341. type="password"
  342. name="old_password"
  343. id="old_password"
  344. />
  345. <Input placeholder="新的密码" type="password" name="password" id="password" />
  346. <Input placeholder="确认密码" type="password" name="verify_pass" id="verify_pass" />
  347. <ButtonGroup className="edit-buttons">
  348. <Button
  349. className="edit-button"
  350. onClick={() => {
  351. this.handleEdit('secureEdit', false);
  352. }}
  353. >
  354. 取消
  355. </Button>
  356. <Button className="edit-button" onClick={this.updatePassword} type="primary">
  357. 确定
  358. </Button>
  359. </ButtonGroup>
  360. </div>
  361. );
  362. }
  363. return (
  364. <div className="user-profile">
  365. <div className="user-item-body">
  366. {userinfo.uid === this.props.curUid ? (
  367. <h3>个人设置</h3>
  368. ) : (
  369. <h3>{userinfo.username} 资料设置</h3>
  370. )}
  371. <Row className="avatarCon" type="flex" justify="start">
  372. <Col span={24}>
  373. {userinfo.uid === this.props.curUid ? (
  374. <AvatarUpload uid={userinfo.uid}>点击上传头像</AvatarUpload>
  375. ) : (
  376. <div className="avatarImg">
  377. <img src={`/api/user/avatar?uid=${userinfo.uid}`} />
  378. </div>
  379. )}
  380. </Col>
  381. </Row>
  382. <Row className="user-item" type="flex" justify="start">
  383. <div className="maoboli" />
  384. <Col span={4}>用户id</Col>
  385. <Col span={12}>{userinfo.uid}</Col>
  386. </Row>
  387. <Row className="user-item" type="flex" justify="start">
  388. <div className="maoboli" />
  389. <Col span={4}>用户名</Col>
  390. <Col span={12}>{userNameEditHtml}</Col>
  391. </Row>
  392. <Row className="user-item" type="flex" justify="start">
  393. <div className="maoboli" />
  394. <Col span={4}>Email</Col>
  395. <Col span={12}>{emailEditHtml}</Col>
  396. </Row>
  397. <Row
  398. className="user-item"
  399. style={{ display: this.props.curRole === 'admin' ? '' : 'none' }}
  400. type="flex"
  401. justify="start"
  402. >
  403. <div className="maoboli" />
  404. <Col span={4}>角色</Col>
  405. <Col span={12}>{roleEditHtml}</Col>
  406. </Row>
  407. <Row
  408. className="user-item"
  409. style={{ display: this.props.curRole === 'admin' ? '' : 'none' }}
  410. type="flex"
  411. justify="start"
  412. >
  413. <div className="maoboli" />
  414. <Col span={4}>登陆方式</Col>
  415. <Col span={12}>{userinfo.type === 'site' ? '站点登陆' : '第三方登陆'}</Col>
  416. </Row>
  417. <Row className="user-item" type="flex" justify="start">
  418. <div className="maoboli" />
  419. <Col span={4}>创建账号时间</Col>
  420. <Col span={12}>{formatTime(userinfo.add_time)}</Col>
  421. </Row>
  422. <Row className="user-item" type="flex" justify="start">
  423. <div className="maoboli" />
  424. <Col span={4}>更新账号时间</Col>
  425. <Col span={12}>{formatTime(userinfo.up_time)}</Col>
  426. </Row>
  427. {userType ? (
  428. <Row className="user-item" type="flex" justify="start">
  429. <div className="maoboli" />
  430. <Col span={4}>密码</Col>
  431. <Col span={12}>{secureEditHtml}</Col>
  432. </Row>
  433. ) : (
  434. ''
  435. )}
  436. </div>
  437. </div>
  438. );
  439. }
  440. }
  441. @connect(
  442. state => {
  443. return {
  444. url: state.user.imageUrl
  445. };
  446. },
  447. {
  448. setImageUrl
  449. }
  450. )
  451. class AvatarUpload extends Component {
  452. constructor(props) {
  453. super(props);
  454. }
  455. static propTypes = {
  456. uid: PropTypes.number,
  457. setImageUrl: PropTypes.func,
  458. url: PropTypes.any
  459. };
  460. uploadAvatar(basecode) {
  461. axios
  462. .post('/api/user/upload_avatar', { basecode: basecode })
  463. .then(() => {
  464. // this.setState({ imageUrl: basecode });
  465. this.props.setImageUrl(basecode);
  466. })
  467. .catch(e => {
  468. console.log(e);
  469. });
  470. }
  471. handleChange(info) {
  472. if (info.file.status === 'done') {
  473. // Get this url from response in real world.
  474. getBase64(info.file.originFileObj, basecode => {
  475. this.uploadAvatar(basecode);
  476. });
  477. }
  478. }
  479. render() {
  480. const { url } = this.props;
  481. let imageUrl = url ? url : `/api/user/avatar?uid=${this.props.uid}`;
  482. // let imageUrl = this.state.imageUrl ? this.state.imageUrl : `/api/user/avatar?uid=${this.props.uid}`;
  483. // console.log(this.props.uid);
  484. return (
  485. <div className="avatar-box">
  486. <Tooltip
  487. placement="right"
  488. title={<div>点击头像更换 (只支持jpg、png格式且大小不超过200kb的图片)</div>}
  489. >
  490. <div>
  491. <Upload
  492. className="avatar-uploader"
  493. name="basecode"
  494. showUploadList={false}
  495. action="/api/user/upload_avatar"
  496. beforeUpload={beforeUpload}
  497. onChange={this.handleChange.bind(this)}
  498. >
  499. {/*<Avatar size="large" src={imageUrl} />*/}
  500. <div style={{ width: 100, height: 100 }}>
  501. <img className="avatar" src={imageUrl} />
  502. </div>
  503. </Upload>
  504. </div>
  505. </Tooltip>
  506. <span className="avatarChange" />
  507. </div>
  508. );
  509. }
  510. }
  511. function beforeUpload(file) {
  512. const isJPG = file.type === 'image/jpeg';
  513. const isPNG = file.type === 'image/png';
  514. if (!isJPG && !isPNG) {
  515. message.error('图片的格式只能为 jpg、png!');
  516. }
  517. const isLt2M = file.size / 1024 / 1024 < 0.2;
  518. if (!isLt2M) {
  519. message.error('图片必须小于 200kb!');
  520. }
  521. return (isPNG || isJPG) && isLt2M;
  522. }
  523. function getBase64(img, callback) {
  524. const reader = new FileReader();
  525. reader.addEventListener('load', () => callback(reader.result));
  526. reader.readAsDataURL(img);
  527. }
  528. export default Profile;