diff --git a/config-overrides.js b/config-overrides.js index aa0674a..0deaaac 100644 --- a/config-overrides.js +++ b/config-overrides.js @@ -50,6 +50,13 @@ module.exports = { '^/user/artist': '', }, }, + '/user/user': { + target: 'http://39.103.180.196:9012/user/user/', + changeOrigin: true, + pathRewrite: { + '^/user/user': '', + }, + }, }; return config; }), diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx index 84bc6f9..7ad1c1e 100644 --- a/src/components/Header/index.tsx +++ b/src/components/Header/index.tsx @@ -1,9 +1,11 @@ import React, { memo } from 'react'; +import { useSelector } from 'react-redux'; import cs from 'classnames'; import { Layout, Avatar } from '@arco-design/web-react'; import { IconUser } from '@arco-design/web-react/icon'; import Logo from '@/assets/logo.svg'; import LogoBlack from '@/assets/logo_black.svg'; +import { GlobalState } from '@/store'; import styles from './style/index.module.less'; interface HeaderProps { @@ -13,6 +15,7 @@ interface HeaderProps { const LayoutHeader = Layout.Header; function Header({ mode }: HeaderProps) { + const userInfo = useSelector((state: GlobalState) => state.userInfo); return ( : }
雀乐音乐人
-
-
登录
- - - -
+ {!userInfo && ( +
+
登录
+ + + +
+ )}
); diff --git a/src/components/LoginModal/index.tsx b/src/components/LoginModal/index.tsx new file mode 100644 index 0000000..277dd3a --- /dev/null +++ b/src/components/LoginModal/index.tsx @@ -0,0 +1,130 @@ +import React, { + memo, + useState, + useCallback, + forwardRef, + useImperativeHandle, +} from 'react'; +import cs from 'classnames'; +import { Modal, Form, Input, Button, Message } from '@arco-design/web-react'; +import { IconClose } from '@arco-design/web-react/icon'; +import request from '@/utils/request'; +import styles from './style/index.module.less'; + +export interface LoginModalProps { + onLoginSuccess?: (resData: any) => void; +} + +const { useForm, useWatch, Item: FormItem } = Form; +const InputPassword = Input.Password; + +function LoginModal(props: LoginModalProps, ref: React.Ref) { + const { onLoginSuccess } = props; + const [visible, setVisible] = useState(false); + const [form] = useForm(); + const userNameVal = useWatch('userName', form); + const passwordVal = useWatch('password', form); + const [submiting, setSubmiting] = useState(false); + + const open = useCallback(() => { + setVisible(true); + }, []); + + const close = useCallback(() => { + if (submiting) return; + setVisible(false); + form.resetFields(); + }, [form, submiting]); + + const handleLogin = () => { + form.validate().then(async (values) => { + setSubmiting(true); + const { userName, password } = values; + request + .post(`/user/user/login/${userName}/${password}`, values) + .then((res: any) => { + if (res?.code === 200 && res?.data?.token) { + Message.success('登录成功'); + localStorage.setItem('token', res?.data?.token); + onLoginSuccess?.(res); + } + }) + .finally(() => { + setSubmiting(false); + }); + }); + }; + + const handleProtocal = async () => { + // TODO: + }; + + useImperativeHandle(ref, () => ({ open }), [open]); + + return ( + setVisible(false)} + onCancel={() => setVisible(false)} + footer={null} + > +
+ +

登录

+

+ 输入您设置的账户名和密码,或系统默认的账户 +

+
+ + + + + + + + + +
+

+ 登录即代表同意 + + 《用户服务协议》 + +

+
+
+ ); +} + +export default memo(forwardRef(LoginModal)); diff --git a/src/components/LoginModal/style/index.module.less b/src/components/LoginModal/style/index.module.less new file mode 100644 index 0000000..1ff545f --- /dev/null +++ b/src/components/LoginModal/style/index.module.less @@ -0,0 +1,111 @@ +.loginModal { + width: 420px; + // height: 438px; + background: #f2f3f7; + border-radius: 18px; + padding: 24px; +} + +.loginModalCont { + width: 100%; + height: 100%; + padding-top: 24px; + padding-left: 16px; + padding-right: 16px; + padding-bottom: 4px; + box-sizing: border-box; +} + +.closeIcon { + position: absolute; + top: 0; + right: 0; + width: 24px; + height: 24px; + cursor: pointer; +} +.closeIcon:hover { + opacity: 0.8; +} + +.loginTitle { + margin-top: 0; + margin-bottom: 6px; + width: 48px; + height: 34px; + top: 334px; + left: 694px; + font-family: PingFang SC; + font-size: 24px; + font-weight: 600; + line-height: 33.6px; + text-align: left; + color: #1d2129; +} + +.loginTip { + height: 18px; + font-family: PingFang SC; + font-size: 13px; + font-weight: 400; + line-height: 18.2px; + color: #4e5969; + margin-top: 0; + margin-bottom: 30px; +} + +.pwdWrap { + padding-top: 4px; +} + +.formInp { + width: 340px; + height: 50px; + border-radius: 2px; + box-sizing: border-box; + + &.formInpUserName, + :global(.arco-input-inner-wrapper) { + background-color: #fff; + padding-left: 24px; + padding-right: 24px; + } + + :global(.arco-input-inner-wrapper svg) { + width: 24px; + height: 24px; + color: rgba(#4e5969, 0.5); + } +} + +.loginBtnWrap { + padding-top: 10px; + margin-bottom: 0; +} + +.loginBtn { + width: 340px; + height: 50px; + border-radius: 2px; +} + +.loginDesc { + line-height: 18px; + font-family: PingFang SC; + font-size: 13px; + font-weight: 400; + line-height: 18.2px; + text-align: center; + color: #00000066; + margin-top: 50px; + margin-bottom: 0; +} + +.protocal { + font-family: PingFang SC; + font-size: 13px; + font-weight: 400; + line-height: 18.2px; + text-align: center; + color: #000000f2; +} diff --git a/src/index.tsx b/src/index.tsx index ed42f4c..dd8c41e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,5 @@ import './style/global.less'; -import React, { useEffect } from 'react'; +import React, { useEffect, useMemo } from 'react'; import ReactDOM from 'react-dom'; import { createStore } from 'redux'; import { Provider } from 'react-redux'; @@ -13,7 +13,6 @@ import PageLayout from './layout'; import { GlobalContext } from './context'; import Login from './pages/login'; import Home from './pages/home'; -import SettleIn from './pages/settle-in'; import checkLogin from './utils/checkLogin'; import changeTheme from './utils/changeTheme'; import useStorage from './utils/useStorage'; @@ -24,6 +23,7 @@ const store = createStore(rootReducer); function Index() { const [lang, setLang] = useStorage('arco-lang', 'en-US'); const [theme, setTheme] = useStorage('arco-theme', 'light'); + const isLogin = useMemo(() => checkLogin(), []); function getArcoLocale() { switch (lang) { @@ -89,8 +89,7 @@ function Index() { {/* */} {/* */} - - + diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index cad872e..1990293 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -1,7 +1,8 @@ -import React from 'react'; +import React, { useRef } from 'react'; import { useHistory } from 'react-router-dom'; import { Layout, Typography, Button } from '@arco-design/web-react'; import Header from '@/components/Header'; +import LoginModal from '@/components/LoginModal'; import styles from './style/index.module.less'; const Content = Layout.Content; @@ -9,9 +10,14 @@ const { Title, Paragraph } = Typography; function Home() { const history = useHistory(); + const loginModalRef = useRef(null); const handleClick = () => { - history.push('/settle-in'); + loginModalRef?.current?.open(); + }; + + const handleLoginSuccess = () => { + window.location.reload(); }; return ( @@ -28,10 +34,11 @@ function Home() { className={styles.btn} onClick={handleClick} > - 成为雀乐音乐人 + 登录账户 + ); } diff --git a/src/utils/checkLogin.tsx b/src/utils/checkLogin.tsx index df76c68..668a5cf 100644 --- a/src/utils/checkLogin.tsx +++ b/src/utils/checkLogin.tsx @@ -1,3 +1,3 @@ export default function checkLogin() { - return localStorage.getItem('userStatus') === 'login'; + return !!localStorage.getItem('token'); } diff --git a/src/utils/request/index.ts b/src/utils/request/index.ts new file mode 100644 index 0000000..859ec6e --- /dev/null +++ b/src/utils/request/index.ts @@ -0,0 +1,61 @@ +import axios from 'axios'; + +// 创建axios实例 +const request = axios.create({ + // baseURL: process.env.APP_BASE_API, // api的base_url + baseURL: '', // api的base_url + timeout: 30000, // 请求超时时间 +}); + +// 请求拦截器 +request.interceptors.request.use( + (config) => { + const token = localStorage.getItem('token'); + if (token) { + config.headers['Authorization'] = `Bearer ${token}`; + } + return config; + }, + (error) => { + // 请求错误处理 + console.log(error); // for debug + Promise.reject(error); + } +); + +// 响应拦截器 +request.interceptors.response.use( + (response) => { + // 对响应数据做处理,例如只返回data部分 + const res = response.data; + // if (res.code !== 20000) { + // Message({ + // message: res.message, + // type: 'error', + // duration: 5 * 1000 + // }); + // // 50001: 非法的token; 50002: 其他客户端错误; 50003: 认证失败; 50004: 授权失败; 50005: 未找到用户 + // if (res.code === 50001 || res.code === 50002 || res.code === 50003 || res.code === 50004 || res.code === 50005) { + // // 移除token + // resetToken(); + // // 跳转到登录页面 + // location.reload(); + // } + // return Promise.reject('error'); + // } else { + // return res; + // } + return res; + }, + (error) => { + console.log('err' + error); // for debug + // Message({ + // message: error.message, + // type: 'error', + // duration: 5 * 1000 + // }); + return Promise.reject(error); + } +); + +export default request;