From 0a334abede3c4bc697d1082c9220935296a2a6e0 Mon Sep 17 00:00:00 2001 From: caishi <1149225589@qq.com> Date: Wed, 5 Jan 2022 11:48:31 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A4=B4=E5=83=8F=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 13 ++++ package.json | 1 + src/forge/Head/Header.js | 65 +++++++++---------- src/forge/Order/MilepostDetail.js | 2 +- src/forge/Order/order.css | 3 + src/forge/Order/order.js | 2 +- src/forge/users/Avatar/Index.jsx | 101 ++++++++++++++++++++++++++++++ src/forge/users/Avatar/Index.scss | 66 +++++++++++++++++++ src/forge/users/Index.css | 4 +- src/forge/users/Index.scss | 28 ++++++++- src/forge/users/Infos.js | 63 +++++++++++++------ 11 files changed, 292 insertions(+), 56 deletions(-) create mode 100644 src/forge/users/Avatar/Index.jsx create mode 100644 src/forge/users/Avatar/Index.scss diff --git a/package-lock.json b/package-lock.json index 4a4f6a36..691afe35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3934,6 +3934,11 @@ "warning": "^4.0.3" } }, + "cropperjs": { + "version": "1.5.12", + "resolved": "https://registry.npmmirror.com/cropperjs/download/cropperjs-1.5.12.tgz", + "integrity": "sha1-2cDbK/uMDXadUXOej5FrvEThD1A=" + }, "cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -14227,6 +14232,14 @@ "countup.js": "^2.0.8" } }, + "react-cropper": { + "version": "2.1.8", + "resolved": "https://registry.npmmirror.com/react-cropper/download/react-cropper-2.1.8.tgz?cache=0&sync_timestamp=1634379691101&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-cropper%2Fdownload%2Freact-cropper-2.1.8.tgz", + "integrity": "sha1-vzWn3mV2n4rTV+iuiE55H+P+khI=", + "requires": { + "cropperjs": "^1.5.12" + } + }, "react-datepicker": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/react-datepicker/-/react-datepicker-2.14.1.tgz", diff --git a/package.json b/package.json index 00ef9788..01f6c282 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "react-content-loader": "^3.1.1", "react-cookies": "^0.1.1", "react-countup": "^6.1.0", + "react-cropper": "^2.1.8", "react-datepicker": "^2.14.1", "react-dev-utils": "^9.2.0-next.80", "react-dom": "^16.13.1", diff --git a/src/forge/Head/Header.js b/src/forge/Head/Header.js index acdf2dea..dd0710ec 100644 --- a/src/forge/Head/Header.js +++ b/src/forge/Head/Header.js @@ -42,8 +42,8 @@ class NewHeader extends Component { setevaluatinghides: false, occupation: 0, mydisplay: false, - headtypesonClickbool: false, - headtypess: "/", + // headtypesonClickbool: false, + // headtypess: "/", settings: null, visiblemyss: false, openSearch:false, @@ -137,12 +137,12 @@ class NewHeader extends Component { AccountProfiletype: false }) }; - headtypesonClick = (url, bool) => { - this.setState({ - headtypess: url, - headtypesonClickbool: bool, - }) - } + // headtypesonClick = (url, bool) => { + // this.setState({ + // headtypess: url, + // headtypesonClickbool: bool, + // }) + // } //获取数据为空的时候 gettablogourlnull = () => { this.setState({ @@ -295,12 +295,14 @@ class NewHeader extends Component { {...this.props} {...this.state} /> : ""} - { - publicNav && - - ccf - - } +
+ { + publicNav && + + ccf + + } +
{ settings && settings.nav_logo_url ? @@ -316,26 +318,26 @@ class NewHeader extends Component { { settings.navbar && settings.navbar.map((item, key) => { var new_link = item.link; - var user_login = current_user && current_user.login; - var is_hidden = item.hidden - if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) { - if (user_login) { - if (new_link.indexOf("courses") > -1) { - new_link = new_link.replace(/courses/g, user_login + "/courses") - } else if (new_link.indexOf("contests") > -1) { - new_link = new_link.replace(/contests/g, user_login + "/contests") - } - } else { - is_hidden = true - } - } - if (user_login && (new_link && new_link.indexOf("homes") > -1)) { - new_link = new_link.replace(/homes/g, user_login + "/user_activities") - } + // var user_login = current_user && current_user.login; + var is_hidden = item.hidden; + // if (new_link && (new_link.indexOf("courses") > -1 || new_link.indexOf("contests") > -1)) { + // if (user_login) { + // if (new_link.indexOf("courses") > -1) { + // new_link = new_link.replace(/courses/g, user_login + "/courses") + // } else if (new_link.indexOf("contests") > -1) { + // new_link = new_link.replace(/contests/g, user_login + "/contests") + // } + // } else { + // is_hidden = true + // } + // } + // if (user_login && (new_link && new_link.indexOf("homes") > -1)) { + // new_link = new_link.replace(/homes/g, user_login + "/user_activities") + // } var waiLian = (new_link && str.filter(item=>new_link.indexOf(item)>-1) ); var wl = waiLian && waiLian.length>0; return ( -
  • this.headtypesonClick(item.link, true)} className={`${this.matchpaths(new_link) === true ? 'pr active' : 'pr'}`} style={!is_hidden ? { display: 'flex' } : { display: 'none' }}> +
  • {item.name}
  • ) @@ -350,7 +352,6 @@ class NewHeader extends Component { { current_user && (current_user.main_site || current_user.login) && (settings && settings.add && settings.add.length>0)? - {/* */} :"" } diff --git a/src/forge/Order/MilepostDetail.js b/src/forge/Order/MilepostDetail.js index e67dac9b..66322ae1 100644 --- a/src/forge/Order/MilepostDetail.js +++ b/src/forge/Order/MilepostDetail.js @@ -321,7 +321,7 @@ class MilepostDetail extends Component { { search_count > limit? -
    +
    :"" } diff --git a/src/forge/Order/order.css b/src/forge/Order/order.css index 60bb5d2b..c35a1827 100644 --- a/src/forge/Order/order.css +++ b/src/forge/Order/order.css @@ -232,6 +232,9 @@ border-bottom: 1px solid #eee; padding: 16px 0px 16px 20px; } +.issueItem:last-child{ + border-bottom: none; +} .issueNo { padding: 0px 5px; border-radius: 4px; diff --git a/src/forge/Order/order.js b/src/forge/Order/order.js index 8a7bc928..17cee705 100644 --- a/src/forge/Order/order.js +++ b/src/forge/Order/order.js @@ -852,7 +852,7 @@ class order extends Component { )} { search_count > select_params.limit ? -
    +
    { + if(avatarImg){ + setAvatarPhoto(avatarImg); + } + },[avatarImg]) + + const cropper = useRef(); + + const saveAvatar = async () => { + const imgUrl = cropper.current.cropper.getCroppedCanvas().toDataURL("image/jpeg"); + if (!imgUrl) { + message.info('请先上传图片'); + } + const url = `/users/${login}/update_image.json`; + axios.put(url,{ + image:imgUrl + }).then(result=>{ + if(result){ + message.success("头像修改成功!"); + onCancel(true); + } + }).catch(error=>{}) + } + + function onChange(e){ + + let files; + if (e.dataTransfer) { + files = e.dataTransfer.files; + } else if (e.target) { + files = e.target.files; + } + + if (!files || (files && files.length===0)) { + return; + } + const file = files[0]; + if (!/^image\/\w+/.test(file.type)) { + message.info('请选择一个图片格式的文件'); + return; + } + + if (file.size > 2 * 1024 * 1024) { + message.info('仅支持文件大小小于2M的文件'); + return; + } + + const reader = new FileReader(); + reader.onload = () => { + setAvatarPhoto(reader.result); + }; + reader.readAsDataURL(files[0]); + } + + return( + onCancel(false)} + className="avatarBox" + > +
    +
    + + {/* 仅支持JPG、GIF、PNG,且文件小于2M */} +
    +
    +
    +
    + + 保存头像 +
    +
    +
    +
    + ) +} +export default Index; \ No newline at end of file diff --git a/src/forge/users/Avatar/Index.scss b/src/forge/users/Avatar/Index.scss new file mode 100644 index 00000000..8b7c1b17 --- /dev/null +++ b/src/forge/users/Avatar/Index.scss @@ -0,0 +1,66 @@ +.avatarBox{ + position: relative; + .ant-modal-header{ + background-color: rgba(242, 242, 255, 1); + .ant-modal-title{ + text-align: left; + } + } + + .ant-modal-body{ + position: relative; + } + .avatarDiv{ + display: flex; + .previewBox{ + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + margin-left: 30px; + .uploadBtn{ + margin-bottom: 30px; + display: flex; + a,label{ + cursor: pointer; + display: block; + height: 32px; + line-height: 30px; + margin:0px 10px; + width: 100px; + border:1px solid rgba(208, 208, 208, 1); + background-color: white; + border-radius:4px; + text-align: center; + color:#666666; + span{ + display: block; + .ant-upload.ant-upload-select { + width: 100%; + height: 32px; + } + .ant-upload-list{ + display: none; + } + } + } + a{ + background-color: rgba(65, 84, 241, 1); + color: white; + border-color: rgba(65, 84, 241, 1); + &:hover{ + color: white!important; + } + } + } + } + .previewImg{ + overflow: hidden; + background-color: #fff; + border-radius: 50%; + text-align: center; + width: 100px!important; + height: 100px!important; + } + } +} \ No newline at end of file diff --git a/src/forge/users/Index.css b/src/forge/users/Index.css index 280cce1b..8cad4168 100644 --- a/src/forge/users/Index.css +++ b/src/forge/users/Index.css @@ -137,7 +137,6 @@ .infoBox span { margin-left: 10px; } - .headimg { position: relative; display: block; @@ -150,8 +149,7 @@ .headimg span { position: absolute; bottom: -6px; - right: 0px; - left: 65px; + right: -16px; } .headimg span i { font-size: 25px !important; diff --git a/src/forge/users/Index.scss b/src/forge/users/Index.scss index 8139ebae..e523323d 100644 --- a/src/forge/users/Index.scss +++ b/src/forge/users/Index.scss @@ -133,6 +133,32 @@ $flex:flex; margin-left:10px ; } } + +.headimg-div{ + width: 110px; + height: 110px; + margin:0px auto; + position: relative; + .updateAvatar{ + cursor: pointer; + position: absolute; + width: 100%; + height: 100%; + border-radius: 50%; + content: ""; + left: 0px; + top:0px; + background-color: rgba(0,0,0,0.2); + display: none; + align-items: center; + justify-content: center; + color: white; + transition: 1s; + } + &:hover .updateAvatar{ + display: flex; + } +} .headimg{ position: relative; display: block; @@ -145,7 +171,7 @@ $flex:flex; position: absolute; bottom: -6px; right: 0px; - left: 65px; + z-index: 11; i{ font-size: 25px!important; border-radius: 50%; diff --git a/src/forge/users/Infos.js b/src/forge/users/Infos.js index 00b03310..ad339cf0 100644 --- a/src/forge/users/Infos.js +++ b/src/forge/users/Infos.js @@ -1,11 +1,12 @@ import React, { Component } from "react"; import { Link } from "react-router-dom"; -import { Button, Spin , Menu } from "antd"; +import { Spin , Menu } from "antd"; import FocusButton from "../UsersList/focus_button"; import axios from "axios"; import { getImageUrl } from "educoder"; import { Route, Switch } from "react-router-dom"; +import Avatar from './Avatar/Index'; import "./new_user.css"; import "../css/index.scss"; @@ -14,10 +15,10 @@ import './Index.scss'; import Loadable from "react-loadable"; import Loading from "../../Loading"; -const UpdateInfo = Loadable({ - loader: () => import("./Material/Index"), - loading: Loading, -}); +// const UpdateInfo = Loadable({ +// loader: () => import("./Material/Index"), +// loading: Loading, +// }); const InfosDevOps = Loadable({ loader: () => import("./devOpsCI"), loading: Loading, @@ -66,7 +67,8 @@ class Infos extends Component { project_type: undefined, route_type: undefined, undo_events:0, - menuKey:"0" + menuKey:"0", + avatarVisible:false }; } @@ -193,29 +195,54 @@ class Infos extends Component { }) } + onCancelAvatar=(reset)=>{ + this.setState({ + avatarVisible:false + }) + if(reset){ + this.fetchUser(); + const { resetUserInfo } = this.props; + resetUserInfo && resetUserInfo(); + } + } + render() { const { current_user } = this.props; const { username } = this.props.match.params; - const { user, isSpin, route_type , undo_events , menuKey } = this.state; + const { user, isSpin, route_type , undo_events , menuKey , avatarVisible } = this.state; return (
    + { + avatarVisible && + + }
    - - - - { - user && user.gender===1? - - : - - } +
    + + + + { + user && user.gender===1? + + : + + } + - - + { + current_user && current_user.login && current_user.login === username ? + {this.setState({avatarVisible:true})}}>修改头像 + :"" + } +
    {user && user.username}