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;