From b32c50e8f5d69af9c0bb5136e27abfb1cd76a093 Mon Sep 17 00:00:00 2001 From: fanxb Date: Wed, 10 Jul 2019 16:58:51 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Feat:=20[=E5=89=8D=E5=8F=B0]:?= =?UTF-8?q?=E7=99=BB=E9=99=86=EF=BC=8C=E6=B3=A8=E5=86=8C=E9=87=8D=E7=BD=AE?= =?UTF-8?q?=E5=AF=86=E7=A0=81=E5=AE=8C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- front/package.json | 6 +- front/public/img/bookmarkLogo.png | Bin 0 -> 5386 bytes front/src/App.jsx | 8 +- front/src/components/IconFont.jsx | 2 +- front/src/layout/LoginLayout/index.jsx | 7 +- .../src/layout/LoginLayout/index.module.less | 7 +- front/src/layout/MainLayout/index.jsx | 0 front/src/layout/MainLayout/index.module.less | 0 front/src/pages/manage/OverView/index.jsx | 12 ++ .../pages/manage/OverView/index.module.less | 0 front/src/pages/public/Login/index.jsx | 57 ++++++--- .../pages/public/RegisterOrReset/index.jsx | 117 ++++++++++++++++-- front/src/util/httpUtil.js | 60 +++++---- 13 files changed, 212 insertions(+), 64 deletions(-) create mode 100644 front/public/img/bookmarkLogo.png create mode 100644 front/src/layout/MainLayout/index.jsx create mode 100644 front/src/layout/MainLayout/index.module.less create mode 100644 front/src/pages/manage/OverView/index.jsx create mode 100644 front/src/pages/manage/OverView/index.module.less diff --git a/front/package.json b/front/package.json index 7626ab0..7a6e6dc 100644 --- a/front/package.json +++ b/front/package.json @@ -1,9 +1,9 @@ { - "name": "chat-room", + "name": "bookmark-world", "version": "0.1.0", "private": true, "homepage": ".", - "proxy": "http://ali.tapme.top:8081/mock/16/chat/api/", + "proxy": "http://10.82.17.56:8088/bookmark/api", "dependencies": { "antd": "^3.19.8", "axios": "^0.19.0", @@ -43,4 +43,4 @@ "devDependencies": { "less-loader": "^5.0.0" } -} +} \ No newline at end of file diff --git a/front/public/img/bookmarkLogo.png b/front/public/img/bookmarkLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..d77cc9aa74ca7b72da78c01795e58df0de30119d GIT binary patch literal 5386 zcmV+l74_Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf03mcmSad^jWnpw_ zZ*Cw|X>DZyGB7bYIxsgnF)$!8HaapmIx;q#STEZE02FdbL_t(|UhSO;?0v@+$N$y} zsz zJ)hrw(~ikG_sz_md*8k9olo-3yT9%J?wfb-%$ak}oZ06%j^j9v<2a7vI8F(dTD>lX zD~nDM-CuNw=xos+L{2^4rjFByTZvvEy58Pb)A1V7e-nLD#KXOGyiFZv!CX@GZBclL zzAQRSG&Wc>e;36MF#4&8Yg#hirjE04juE8~68f;{(xS0=uSom9PY^8~Z&PPmxw`14 zqHBw;$Tyb2C04JwTvPND(UtbT`hPwydSG|hoLh*ns8TEDH=;vD7w&zvOuS8K$(>5$=lX$2vtTf7?U$}d75$?-oDCQpU+WHSaymv*I=ImDb zCwfcK;F%1KpgA>%>RY09Fgj^}`&tnZr+bP>10dIr>819&x%!T1D!fgnfm}@5n!#Yq zT+m(Om!kA@=02GkQroUCy1fWr`J+Y85aF77i|8Yw^g4scsT>416V`=x@?VMYk)0@F zO89S)_IsAzF6x6s&_9dPzaz?o`K^J;PHrBNR37ekiHNXreXRZMyGDL@3cO9Hf%h6; z3w|#As>^lc+UK1!AZzd};O}PU^dJ$P96rewq@RDR!6|S&2-=C! z{X{V|8a;8ifv`-lI(UePyb?0!p(H{@<33K*2Yw9g|Gr053sXhRa;}qf6_(s#A@N?a zLii2vHk}4;e(k+7DAho_$LC=Xdy{CF;4_ZfAc%a}8mJ49p6f-T7BJmT&mDxNSq(Qk ziIm!jNk|?W9{lwG^6=k8v{bxJr^Ct*{fejt0$Z)l6<~I7oajj+1`@0%?vc5IRhPB_ zVp(YowWX+DUu-4EreWEuW6Q*w3|Nexi53ChdZSYXcu`-Oe>2y3w zq`hB!Pc>+THgI_i;n$+{oVYdS3JL$|^`h5_YQVLTo(s#o1z3gYxr3_jW2Qu!F9G4? zOrcB`QwyA)IJ<{By0tP`2p>crsl%0JLs()s;Yp9#B;KaeLT4UdcM$DaiuI7yb_jqA zLc1SukIWVPv+4CBEZ-V5e>YX7TEHwQJ$F!b_61V}?S!nB(0G+7{yp9>))5bM%|*~5 z#OFi!)%w6`tBvZh@GoJiYsDJI#@lpStcRGXYbgX=v~vwvQ_i5Gos*?&bH$4E;tD8* zdssVHtM`vvLOVaMtSYRV;P)bHy{s0(4`KwwTFC{=h!Kdti_gPUu8+R8zp)slr%EIZ zc$-d78Y~HVil`K;BplQATJ9*)&dGY-x$4PdT+BpeG z%oT0c5w4jCGd@T%A8@lUXwcT&Z+8(f$daW%-~%6@HPvmkr3RTC+W84U4uU8d4<9G% zdx-FbS>>yOco3(6DlpW3)1t3In@q9rHk}U3;^rYOh1DL~xrU@8S%C}^?dJ-CA?=!5 zivPiEi1xwv&TNZmF&!!cdoEV+jRCU>eE2z4clkXYR_%tYxq;{$a{jLcX%CMOG1}wb z`<;kJpJKa!b$FYO4+-6Ao7J`(7O{4&A%0cM2RheUn0)ry^-ir&i;)hFj0zStXu%&` zCfeU;=UkRn@XmomP=W+^5V5fQk)j+J5tv>+QN%QbsvY-Tz3w{RrWeCtfe(ptY^?E4 z1tghkd{9K;4gQvP46k(X@z?Py4_}%Uz|U?iqM}SJem@5S8JchIv7&c(hqGdgicGDb z4BmCS!;7G^)GAkfNc7O|aQ@(LAoYP@MB2mSEXC4s%Gl;MWuvb2Jtii>( zZ#l_hF;Wf9%u3pl1fedFJ=o=^I_J5kDHCNG#?}R!P@zGAG3j}0Di8T zO>wB=!ka0HNbLf<+@?%dwfD6v+C;}_MbT?ls<7fpJ0F943qtlsstiMQ##eP^v+cNGFZQ*)KoYYN+$)jc!dI+BV>AdNJJexDT*8$a5oE8s91_RG3y-IgI$dn1V6=veJ2$ zpjL$zN+4HNyO!EuhP8-+pi~R2=Onw9X3KOPte0a&R;olR*kp+hinIo81DnSr5joW3G*DOnPjf+d_& za-WXzo!#MNu)2jD)|8isUfdlP!Qh6EFon(D4($%B;q#iF`H(Wj^d2`tQ6SBbRKWhdU)Wp_eQ&vKnH16L}I&yTAnG=&N;^wL;(f}?V7cX zv2vjE(#}^~NI1qSQml2v&0z#&`eK#o?-LK{a`W=R5%pR!-loIh z{ac-xX7Thv=ck=R_=T#mX25j{O49=;mwpIhQ) zCErM!LZo13lN(iX*+nI+Iv8y?g-o%+IdKtAA*%*r`6@03)XsZ ze7v=2iw{_8I+VwV((@t)`sOgLVBZmInqr9uk%Uy7t)&owB_Xr)evBF~rmhZTx zz{OOMXsumyDrPYZpmcCVthrxF=;m|5?~O&z{SPdaO#i+`#GUMo^t`BOL4y^QX4=Gv z`9e{NBYwY#p85Tv+y(U|kf8Z&QE7?^c~fr{F`cZG<#vvKCo`h-69o@qlS7 zC5T8rwL7eWrG46lOb3b1>kelJofswPT0!Om9V7#E3{mNmMHj3@USlZcK_HP=6bgof z;{eBeHrnjq-lETRhjrjvDP5?~2r=bUfJOGyG%Q^=%kMJ{9kf$e1>UC9U`2e1wwGen z#Ka03g4VvRR(y;F?t}E2m!=_^1bbMe_*2n?<48_(#;}G6ne)o@g((+x0MpT-1+3uU zMzxZ9E#deLCjAt6n@$7Pt9ETQX&~B`sR*mI7IGrBbK=sNGepe$iWSdYO!15EO=~KR zAH`Z%c&_LK5osXW@+^D|eN)9?9tXuHGt)Ds6X7)+vuYvzUVO}TaJ@&1u+G*+P_<;= zvGFz?A1q!iy8Bhpox8(qurf7&?%^V)do^ISFmp)xg6JOI;jCdmX2lU(72I6J08S8a z(*xo}oa6?e%Ebetl9$puf#EP-<$i`HhSH{gpu9#Kx4ohegkyUTg@v+iMN>ep> zFWPxfO*TNl+61d_tBbiqr^sxESrGva?h{tZP+$T}y(UGhwTcUG^eqWwbRbH^O@j0P zqoQ@oX*N;m7Y8hk^%N`|ES|@U*p!D4kl$rwt{w4*;%z!E_`)c0m4Y>XRCkyK54tt| zK0t&eUIP`8v`+e^B7$<;3WF>WY1}kC1EGisqCf?&xEU}4c;)%vnAafA(Kl=1K4hkY zsM3Cph@ugvi5M`MHEfK&bcwN)v+x|h993zwDC6AmHqFPfXh|2 z4`%JWta#c6aJgWewTxiLFc62%GjyC|_}QDo8ei>$A5(MQi?;>drukU48cWyovV2fG zPb~5|u~4x9DZEOuKA#nx0!uM9>xOMcwR26GeJ}?29pfZ$77&!?jkW^ob1rl#n4Ve7^&T!_BdlB~%u0lN2u$q= zV4W#qO2;cf3vCJKjYOw*hl_%ILH4P^t&;L75gV^f3C{{Sm$;`01ab|Iv(vD0B(}n0 zF~utZ|F3qQvBU$tB(MhGAzBv{oZ1pjSG`bNrS!AkTCjYawk)Adt%xs5^Fr4_9;fB6 zY%QjpOMwoYoW|TpGXu<25Tw+u0kH)L)BT-=h$Q)ERGq<3#B|ab#!}jpXu0-KAR?kQ z;KCr1%pS!=Ht{QJ=N}^0PA>sUjO8Z%({WM{U`p74U%QrAWP}_d8lBo34)A{w)jV1GKGvP98y*Ul68qDac7pmU_n za~DHU%%kQxGa($#haLU_7gADWlX6b!#q;$LCnn)*&JcqA|ljBh)5=%8~EdLOVV+lVL3NRlW71|qDrdZ6QE%b7zEP@ZE-z~LuvgSta@oU zp=+jRST3=p6bs)NBl(>1Hf;kBr*^$9szUDybPz1*O9xp?bSm0PqcI>qltg%DRow6F zaEV_LOEHD-;Zn*85)qgg4AV8M(U=0}SSa|=m{w@#C|=VjkX);s3sHt@?s%KFfd@sq zUV=u>dWh;;6@^k!)I^(xGGO9HUB~ugn z9-6RZY8{q82$lFLNHDclJ1`Z{Mw2<>Z8{t)Kv28)@vgyoe69UrF1 zJWk}Sr*BO@78f1Mx_i(%2StB}V!4a()8>MU2;V)^XP&9rHSZ=^Fn#m)oVB(%ovm#> z$*NxmR*?3$XznQx8s4VEV0x!rcj-FmT_)Yyl@5^_p}Fgx$@z@`KIkOTP||A)sx2Hm z+RSHNaf6)5CC*gsZ}GX|d$XYDw{pj@j#~IMHi5TkJ(iCZE1HKJXFLxPK3kR#&OIo% zDHuTM5D8|L2JUEI?K2pNIqqA=#q=oso1olC z?p*OUEr&Fi+(>FHtZUkZ$Tb!*d)F}dFt|_{fq(>^!%}?Jt*BjOV3k#Cv8S_jZY;@J zVlB95)XACu<6n#YLqr$*Msv)1YszWu5VthEP0PTV)vmpz2t1Gjzjct7qn&%|Z9l4@SD)IcjU#=VOA2|L zmP6qKI(htsOyk)4)5^`9Lc3xyTFWvC7@Q~a~P=K8q zt%!Cj<*Z)X2C$5^_ur~e1}jz4bMx6Xr}fqbbAxClj__FLi`aMBsbgE)lmvM8?#9~0 zIyqQGbT(CKQZVhpPI$X;&#@f@?w^!ayCCATO}DRQ8v}Nv%-W|>cZ`0*K+tNW23CG1jM;Sz*iq`|9 zui5Wqo3}=d!7|kH3Xc`NvO63E>!peQr(8{RZg)5>VdLyg`e|CJ#k$QFc$+%ghPCFO zG@cf)Nt<^5)QTJomP!s`B(yAsCBgfc1Ky_2wqf-rY=Yl{GghxDxpe@t$?X`o$v?uj zmUF<{)Y&%1?ij5Ibn_y)xgF!#tJiJdyw&Tb@iujKg~eHnxxp9Kk+xbdOY{f}Bj`fq znAcokc_Eg|g<}-|EEdjitAVG)+tk@Mtf=(iqLaJBL9itRiycyq5}nW;wjsA;B#nV6 zTzCL^4YIzDUwNQ-MNWsesk3e1FAvp=IL1;uT|}qI06G*hBd82cdKiJrvqWc#_KP+W om3AD*aU92S9LI4SN7%RTf9lP5rPOX
- + + + + {/* 公共页面 */} diff --git a/front/src/components/IconFont.jsx b/front/src/components/IconFont.jsx index c3c44af..03e1bb2 100644 --- a/front/src/components/IconFont.jsx +++ b/front/src/components/IconFont.jsx @@ -1,7 +1,7 @@ import { Icon } from "antd"; const IconFont = Icon.createFromIconfontCN({ - scriptUrl: "//at.alicdn.com/t/font_1261825_09wguqxg78th.js" + scriptUrl: "//at.alicdn.com/t/font_1261825_snxc2hrpa4o.js" }); diff --git a/front/src/layout/LoginLayout/index.jsx b/front/src/layout/LoginLayout/index.jsx index eac9810..3475552 100644 --- a/front/src/layout/LoginLayout/index.jsx +++ b/front/src/layout/LoginLayout/index.jsx @@ -1,3 +1,6 @@ +/** + * 登陆/注册/重置密码 通用布局 + */ import React from "react"; import styles from "./index.module.less"; import { Link } from "react-router-dom"; @@ -29,7 +32,9 @@ const LoginOrRegister = ({ type }) => { export function LoginLayout({ type, children }) { return (
-
CR
+
+ logo +
{type === RESET_PASSWORD_TYPE ?
重置密码
: } {children} diff --git a/front/src/layout/LoginLayout/index.module.less b/front/src/layout/LoginLayout/index.module.less index ef1fbd6..150bb96 100644 --- a/front/src/layout/LoginLayout/index.module.less +++ b/front/src/layout/LoginLayout/index.module.less @@ -13,9 +13,10 @@ position: absolute; left: 5%; top: 5%; - font-size: 4em; - font-weight: 700; - color: #1890ff; + + img { + width: 2rem; + } } .content { diff --git a/front/src/layout/MainLayout/index.jsx b/front/src/layout/MainLayout/index.jsx new file mode 100644 index 0000000..e69de29 diff --git a/front/src/layout/MainLayout/index.module.less b/front/src/layout/MainLayout/index.module.less new file mode 100644 index 0000000..e69de29 diff --git a/front/src/pages/manage/OverView/index.jsx b/front/src/pages/manage/OverView/index.jsx new file mode 100644 index 0000000..c9f8c24 --- /dev/null +++ b/front/src/pages/manage/OverView/index.jsx @@ -0,0 +1,12 @@ +import React from "react"; + +export default class OverView extends React.Component { + constructor(props) { + super(props); + this.state = {}; + } + + render() { + return
主界面
; + } +} diff --git a/front/src/pages/manage/OverView/index.module.less b/front/src/pages/manage/OverView/index.module.less new file mode 100644 index 0000000..e69de29 diff --git a/front/src/pages/public/Login/index.jsx b/front/src/pages/public/Login/index.jsx index e4c304e..20f7711 100644 --- a/front/src/pages/public/Login/index.jsx +++ b/front/src/pages/public/Login/index.jsx @@ -23,7 +23,7 @@ class Login extends Component { constructor(props) { super(props); this.state = { - email: "", + str: "", password: "", rememberMe: false }; @@ -35,28 +35,51 @@ class Login extends Component { }; submit = () => { - axios.post("/public/login", this.state).then(res => { - localStorage.setItem("token", res.token); - localStorage.setItem("userInfo", JSON.stringify(res.userInfo)); - window.token = res.token; - window.userInfo = res.userInfo; - message.success("登录成功"); - this.props.updateLoginInfo(res.token, res.userInfo); - if (this.query.redirect) { - this.props.history.replace(decodeURIComponent(this.query.redirect)); - } else { - this.props.history.replace("/"); - } - }); + axios + .post("/user/login", this.state) + .then(res => { + const token = res.token; + delete res.token; + localStorage.setItem("token", token); + localStorage.setItem("userInfo", JSON.stringify(res)); + window.token = token; + window.userInfo = res; + message.success("登录成功"); + this.props.updateLoginInfo(token, res); + if (this.query.redirect) { + this.props.history.replace(decodeURIComponent(this.query.redirect)); + } else { + this.props.history.replace("/"); + } + }) + .catch(error => { + message.error(error); + }); }; render() { - const { email, password, rememberMe } = this.state; + const { str, password, rememberMe } = this.state; return (
- } placeholder="邮箱" /> - } placeholder="密码" /> + } + placeholder="邮箱或者用户名" + /> + } + placeholder="密码" + />
记住我 diff --git a/front/src/pages/public/RegisterOrReset/index.jsx b/front/src/pages/public/RegisterOrReset/index.jsx index 4cd6ac5..f7cdc4b 100644 --- a/front/src/pages/public/RegisterOrReset/index.jsx +++ b/front/src/pages/public/RegisterOrReset/index.jsx @@ -1,53 +1,144 @@ import React from "react"; import IconFont from "../../../components/IconFont"; -import { Button, Input, Checkbox } from "antd"; +import { Button, Input, message } from "antd"; import { LoginLayout, REGISTER_TYPE, RESET_PASSWORD_TYPE } from "../../../layout/LoginLayout"; import styles from "./index.module.less"; -import { Link } from "react-router-dom"; import axios from "../../../util/httpUtil"; export default class Register extends React.Component { constructor(props) { super(props); + console.log(props); let type = props.location.pathname.split("/").reverse()[0]; this.state = { current: type === "register" ? REGISTER_TYPE : RESET_PASSWORD_TYPE, + username: "", email: "", password: "", repassword: "", - code: "" + authCode: "", + authCodeText: "获取验证码", + isCountDown: false }; } + componentWillUnmount() { + if (this.timer != null) { + clearInterval(this.timer); + } + } + /** * 获取验证码 */ - getCode = () => {}; + getCode = () => { + if (this.state.isCountDown) { + return; + } + axios.get("/user/authCode?email=" + this.state.email).then(() => { + message.success("发送成功,请注意查收(检查垃圾箱)"); + let count = 60; + this.setState({ authCodeText: `${count}s后重试`, isCountDown: true }); + this.timer = setInterval(() => { + count--; + if (count === 0) { + this.setState({ isCountDown: false, authCodeText: "获取验证码" }); + clearInterval(this.timer); + return; + } + this.setState({ authCodeText: `${count}s后重试` }); + }, 1000); + }); + }; changeData = e => { this.setState({ [e.target.name]: e.target.value }); }; - submit = () => {}; + /** + * 提交表单 + */ + submit = () => { + const { current, username, email, password, repassword, authCode } = this.state; + if (password !== repassword) { + message.error("两次密码不一致"); + return; + } + let form = { username, email, password, authCode }; + if (current === REGISTER_TYPE) { + axios + .put("/user", form) + .then(() => { + message.success("注册成功"); + setTimeout(() => this.props.history.replace("/public/login"), 500); + }) + .catch(error => message.error(error)); + } else { + delete form.username; + axios + .post("/user/resetPassword", form) + .then(() => { + message.success("操作成功"); + console.log(this.location); + setTimeout(() => this.props.history.replace("/public/login"), 500); + }) + .catch(error => message.error(error)); + } + }; render() { - const { current, email, password, repassword, code } = this.state; + const { current, username, email, password, repassword, authCode, authCodeText, isCountDown } = this.state; return (
- } placeholder="邮箱" /> - } placeholder="密码" /> - } placeholder="重复密码" /> + {current === REGISTER_TYPE ? ( + } + placeholder="用户名" + /> + ) : null} + } + placeholder="邮箱" + /> + } + placeholder="密码" + /> + } + placeholder="重复密码" + /> } addonAfter={ - - 获取验证码 + + {authCodeText} } placeholder="验证码" diff --git a/front/src/util/httpUtil.js b/front/src/util/httpUtil.js index 95d399a..cc6ea7e 100644 --- a/front/src/util/httpUtil.js +++ b/front/src/util/httpUtil.js @@ -1,43 +1,55 @@ import { notification } from "antd"; +import { createBrowserHistory } from "history"; import axios from "axios"; +const history = createBrowserHistory(); + //定义http实例 const instance = axios.create({ // baseURL: "http://ali.tapme.top:8081/mock/16/chat/api/", headers: { - token: window.token + "jwt-token": window.token } }); //实例添加拦截器 instance.interceptors.response.use( function(res) { - return res.data; + console.log(res); + const data = res.data; + if (data.code === 1) { + return data.data; + } else if (data.code === -2) { + return Promise.reject(data.message); + } else { + showError(data); + return Promise.reject(data.message); + } }, function(error) { - console.log(error); - let message, description; - if (error.response === undefined) { - message = "出问题啦"; - description = "你的网络有问题"; - } else { - message = "出问题啦:" + error.response.status; - description = JSON.stringify(error.response.data); - //401跳转到登录页面 - } - notification.open({ - message, - description, - duration: 2 - }); - setTimeout(() => { - if (error.response && error.response.status === 401) { - let redirect = encodeURIComponent(window.location.pathname + window.location.search); - window.location.replace("/public/login?redirect=" + redirect); - } - }, 1000); - return Promise.reject(error); + showError(error.response); } ); +function showError(response) { + let description, + message = "出问题啦"; + if (response) { + description = response.message; + if (response.code === -1) { + setTimeout(() => { + let redirect = encodeURIComponent(window.location.pathname + window.location.search); + history.replace("/public/login?redirect=" + redirect); + }, 1000); + } + } else { + description = "无网络连接"; + } + notification.open({ + message, + description, + duration: 2 + }); +} + export default instance;