diff --git a/config/proxy.ts b/config/proxy.ts index 10baf73..986f92e 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -1,13 +1,18 @@ export default { dev: { - // '/api/wfap/v1/audit/bill/find/by/procid': { - // target: 'http://10.242.37.148:8891/',//审批单 dev环境自动审批,暂时用不到 - // changeOrigin: true, - // pathRewrite: { '^': '' }, - // }, + '/api/v1': { + target: 'http://10.0.0.10:18030',// 茂 + // target: 'http://10.0.0.14:18030',// 李 + changeOrigin: true, + pathRewrite: { '^/api/v1': '/v1' }, + }, '/api': { - // target: 'http://10.0.0.125:18012',//测试环境 - target: 'http://10.0.0.10:18013',//连接天宫的ng + // target: 'http://10.242.37.148:18022',// + target: 'http://10.0.0.10:18013',// 茂 + // target: 'http://10.0.0.125:18012',// 测试 + // target: 'http://10.0.0.14:18012',// 李 + // target: 'http://10.0.0.14:18030',// 李 + // target: 'http://10.0.0.46:18013',// 袁 changeOrigin: true, pathRewrite: { '^/api': '' }, }, diff --git a/package.json b/package.json index 8b3f382..09e7ccf 100644 --- a/package.json +++ b/package.json @@ -70,9 +70,11 @@ "array-move": "3.0.1", "axios": "0.21.1", "classnames": "2.3.1", + "dayjs": "^1.11.13", "dva": "2.4.1", "echarts": "^5.2.2", "echarts-for-react": "^3.0.2", + "jsencrypt": "^3.3.2", "lodash": "4.17.21", "moment": "^2.29.4", "omit.js": "2.0.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 72ab334..026993d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,6 +50,9 @@ dependencies: classnames: specifier: 2.3.1 version: 2.3.1 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 dva: specifier: 2.4.1 version: 2.4.1(react-dom@16.14.0)(react@16.14.0) @@ -59,6 +62,9 @@ dependencies: echarts-for-react: specifier: ^3.0.2 version: 3.0.2(echarts@5.6.0)(react@16.14.0) + jsencrypt: + specifier: ^3.3.2 + version: 3.3.2 lodash: specifier: 4.17.21 version: 4.17.21 @@ -10263,6 +10269,10 @@ packages: - utf-8-validate dev: true + /jsencrypt@3.3.2: + resolution: {integrity: sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==} + dev: false + /jsesc@2.5.2: resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} engines: {node: '>=4'} diff --git a/src/layouts/Header.tsx b/src/layouts/Header.tsx index 0f8491d..11f3d24 100644 --- a/src/layouts/Header.tsx +++ b/src/layouts/Header.tsx @@ -1,18 +1,74 @@ -import React from 'react'; +import React, { useEffect } from 'react'; //导入logo图片 import LogoImg from '@/assets/img/logo.png'; // 引入样式文件 import './Header.less'; //导入菜单组件 import HeaderMenu from './HeaderMenu'; -const Header: React.FC = (props) => { +import { connect, history } from 'umi'; +import type { UserModelState } from '@/models/user'; +import type { ConnectProps, Dispatch } from 'umi'; +import { Button, Dropdown, message, Modal } from 'antd'; +import { DownOutlined, ExclamationCircleOutlined } from '@ant-design/icons'; +interface PageProps extends ConnectProps { + user: UserModelState; // dva model状态 + dispatch: Dispatch; // dva dispatch方法 +} +const Header: React.FC = ({ user, dispatch }) => { + useEffect(() => { + if (user.token) { + dispatch({ + type: 'user/fetchUserInfo', + }); + } + }, [user.token]); + const handleMenuClick = (e: any) => { + if (e.key === 'logout') { + Modal.confirm({ + title: '确定退出登录吗?', + icon: , + content: '退出登录后,您将需要重新登录', + onOk() { + dispatch({ + type: 'user/logout', + }).then(() => { + sessionStorage.clear(); + message.success('退出登录成功'); + history.push('/index'); + }); + }, + onCancel() { + return; + }, + }); + } + }; return (
logo + {user.userInfo?.fullName && ( + + + + )}
); }; -export default Header; +export default connect(({ user }: { user: UserModelState }) => ({ user }))(Header); diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts index 7f6f38f..c24f227 100644 --- a/src/locales/en-US.ts +++ b/src/locales/en-US.ts @@ -4,6 +4,7 @@ import help from './en-US/help'; import policy from './en-US/policy'; import register from './en-US/register'; import home from './en-US/home'; +import login from './en-US/login'; export default { 'menu.首页': 'Home', @@ -39,19 +40,6 @@ export default { "加载更多":"Load More", "登录/注册":"Login/Register", - // Login page - "login.title": "E-Bidding Platform", - "login.tab.supplier": "Supplier", - "login.tab.expert": "Expert", - "login.tab.agent": "Bidding Agent", - "login.username.placeholder": "Please enter username", - "login.password.placeholder": "Please enter password", - "login.remember": "Remember password", - "login.forgot": "Forgot password?", - "login.button": "Login", - "login.register.tip": "Don't have an account?", - "login.register.action": "Register Now", - "login.back.home": "Back to Home", // Help Center module ...help, @@ -70,4 +58,7 @@ export default { // Home module ...home, + + // Login page + ...login, }; diff --git a/src/locales/en-US/login.ts b/src/locales/en-US/login.ts new file mode 100644 index 0000000..34a7084 --- /dev/null +++ b/src/locales/en-US/login.ts @@ -0,0 +1,16 @@ +export default { + // Login page + "login.title": "E-Bidding Platform", + "login.tab.supplier": "Supplier", + "login.tab.expert": "Expert", + "login.tab.agent": "Bidding Agent", + "login.username.placeholder": "Please enter username", + "login.password.placeholder": "Please enter password", + "login.remember": "Remember me", + "login.forgot": "Forgot password?", + "login.button": "Login", + "login.register.tip": "Don't have an account?", + "login.register.action": "Register now", + "login.back.home": "Back to home", + "login.captcha.placeholder": "Please enter verification code", +}; diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index b4cf4ce..daf7168 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -4,6 +4,7 @@ import help from './zh-CN/help'; import policy from './zh-CN/policy'; import register from './zh-CN/register'; import home from './zh-CN/home'; +import login from './zh-CN/login'; export default { 'menu.首页': '首页', @@ -39,19 +40,6 @@ export default { "加载更多":"加载更多", "登录/注册":"登录/注册", - // 登录页文案 - "login.title": "电子招投标平台", - "login.tab.supplier": "供应商", - "login.tab.expert": "专家", - "login.tab.agent": "招标代理", - "login.username.placeholder": "请输入用户名", - "login.password.placeholder": "请输入密码", - "login.remember": "记住密码", - "login.forgot": "忘记密码?", - "login.button": "登录", - "login.register.tip": "还没有账号?", - "login.register.action": "立即注册", - "login.back.home": "返回首页", // 帮助中心模块 ...help, @@ -70,4 +58,7 @@ export default { // Home module ...home, + + // Login page + ...login, }; diff --git a/src/locales/zh-CN/login.ts b/src/locales/zh-CN/login.ts new file mode 100644 index 0000000..6521f8a --- /dev/null +++ b/src/locales/zh-CN/login.ts @@ -0,0 +1,16 @@ +export default { + // 登录页文案 + "login.title": "中远海运", + "login.tab.supplier": "供应商", + "login.tab.expert": "专家", + "login.tab.agent": "招标代理", + "login.username.placeholder": "请输入用户名", + "login.password.placeholder": "请输入密码", + "login.remember": "记住密码", + "login.forgot": "忘记密码?", + "login.button": "登录", + "login.register.tip": "还没有账号?", + "login.register.action": "立即注册", + "login.back.home": "返回首页", + "login.captcha.placeholder": "请输入验证码", +}; diff --git a/src/models/index.ts b/src/models/index.ts new file mode 100644 index 0000000..cd99190 --- /dev/null +++ b/src/models/index.ts @@ -0,0 +1,4 @@ +import user from './user'; +export default { + user, +}; diff --git a/src/models/user.ts b/src/models/user.ts new file mode 100644 index 0000000..428189b --- /dev/null +++ b/src/models/user.ts @@ -0,0 +1,103 @@ +import type { Effect, Reducer } from 'umi'; + +import { getUserinfo, Logout } from '@/servers/api/login'; + +export type SupplierUser = { + email?: string; + mobile?: string; + name?: string; + sex?: string; + status?: number; + userId?: string; + userName?: string; +}; + +export type User = { + userId: string; + userName: string; + userType: string; +}; + +export type UserInfo = { + userId: string; + fullName: string; + loginName: string; + userType: string; + authorityList: { roleId: string, roleName: string, roleCode: string, roleScope: string }[]; +}; + +export type UserModelState = { + supplierUser?: SupplierUser; + user?: User; + token?: string; + userInfo?: UserInfo; +}; + +export type UserModelType = { + namespace: 'user'; + state: UserModelState; + effects: { + fetchUserInfo: Effect; + logout: Effect; + }; + reducers: { + saveLoginUser: Reducer; + saveUserInfo: Reducer; + clearUserInfo: Reducer; + }; +}; + +const UserModel: UserModelType = { + namespace: 'user', + + state: { + supplierUser: {}, // 登录返回的供应商用户信息 + user: undefined, // 登录返回的用户信息 + token: sessionStorage.getItem('token') || '', // 登录返回的token + userInfo: undefined, // 请求userInfo返回的用户信息 + }, + + effects: { + *fetchUserInfo(_, { call, put }) { + const response = yield call(getUserinfo); + yield put({ + type: 'saveUserInfo', + payload: response, + }); + }, + *logout(_, { call, put }) { + yield call(Logout); + yield put({ + type: 'clearUserInfo' + }); + }, + }, + + reducers: { + clearUserInfo(state) { + return { + ...state, + userInfo: undefined, + token: '', + supplierUser: {}, + user: {}, + }; + }, + saveLoginUser(state, action) { + return { + ...state, + supplierUser: action.payload.supplierUser || {}, + user: action.payload.user || {}, + token: action.payload.token || '', + }; + }, + saveUserInfo(state, action) { + return { + ...state, + userInfo: action.payload || {}, + }; + }, + } +}; + +export default UserModel; diff --git a/src/pages/index/index.less b/src/pages/index/index.less index 48ee0e3..3a1a9fc 100644 --- a/src/pages/index/index.less +++ b/src/pages/index/index.less @@ -31,70 +31,43 @@ } .noticeList { padding: 10px 0; - .noticeTitle { - font-size: 22px; + display: flex; + gap: 20px; + align-items: center; + .noticeName { + font-size: 18px; font-weight: 600; - color: @main-color; - padding: 10px 7px; + color: @main-danger-color; + width: 50px; + line-height: 20px; + text-align: center; } .noticeItem { - background-color: #fff; - padding: 24px; - border-radius: 16px; - box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.05); - height: 249px; - .title { - margin: 14px 0; - font-size: 20px; - font-weight: 600; - // 超过两行显示省略号 - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; - text-overflow: ellipsis; - height: 63px; - } - .content{ - font-size: 16px; - color: @main-text-color-2; - // 超过两行显示省略号 - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; - text-overflow: ellipsis; - } - .button{ - color: @main-color; - font-size: 16px; - margin-top: 14px; - cursor: pointer; - } - .header { + margin-right: 20px; + flex: 1; + width: 0; + .cardTitle { display: flex; justify-content: space-between; - align-items: center; - .time { - font-size: 14px; + .cardTitleText { + font-size: 18px; + font-weight: 600; + color: @main-color; + cursor: pointer; + &:hover { + text-decoration: underline; + } + } + .cardTitleTime { color: @main-text-color-2; } - .type { - display: inline-block; - background-color: @main-color; - color: #fff; - font-size: 12px; - padding: 4px 8px; - border-radius: 20px; - &.primary { - background-color: rgba(59, 130, 246, 0.1); - color: #3b82f6; - } - &.danger { - background-color: rgba(255, 77, 77, 0.1); - color: #ff4d4d; - } - } + } + .cardContent { + color: @main-text-color-2; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + margin-bottom: 0; } } } @@ -163,7 +136,7 @@ } } } - .search { + .search{ height: 100%; } } diff --git a/src/pages/index/index.tsx b/src/pages/index/index.tsx index c62d360..c2c05a8 100644 --- a/src/pages/index/index.tsx +++ b/src/pages/index/index.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect } from 'react'; import { Card, Row, Col, Tabs, Table, Button, Space } from 'antd'; -import { useIntl, Link, history } from 'umi'; +import { useIntl, Link, history, connect } from 'umi'; import './index.less'; import IconFont from '@/components/IconFont/IconFont'; import Search from '../announce/Search'; @@ -12,7 +12,8 @@ import { getAboutUs } from '@/servers/api/about'; // 获取通知公告 import { getNoticeList } from '@/servers/api/notice'; import { filterHtmlTag } from '@/utils/utils'; -const IndexPage: React.FC = () => { +const IndexPage: React.FC = ({ user }) => { + const token = user.token; const intl = useIntl(); const [noticeLoading, setNoticeLoading] = useState(false); // 友情链接 @@ -186,7 +187,29 @@ const IndexPage: React.FC = () => { return (
- + {/* 通知列表 */} +
+
通知公告
+ {noticeList.map((item) => ( +
+
+ { + history.push({ + pathname: '/announce/announceInfo', + search: '?id=' + item.id, + }); + }} + > + {item.title} + + {item.publishTime} +
+

+

+ ))} +
@@ -242,49 +265,6 @@ const IndexPage: React.FC = () => {
- {/* 通知列表 */} -
-
-
- 通知公告 -
- - {noticeList.map((item) => ( - -
-
- {item.publishTime} - {item.columnType === 'notice' ? '公告' : '通知'} -
-
{item[intl.formatMessage({ id: 'notice.data.title' }) as keyof typeof item]}
-
{filterHtmlTag(item[intl.formatMessage({ id: 'notice.data.content' }) as keyof typeof item] || '')}
-
{ - history.push({ - pathname: '/announce/announceInfo', - search: '?id=' + item.id, - }); - }}>{intl.formatMessage({ id: 'notice.detail' })}>
- {/*
- { - history.push({ - pathname: '/announce/announceInfo', - search: '?id=' + item.id, - }); - }} - > - {item.title} - - {item.time} -
*/} - {/*

{item.content}

*/} -
- - ))} -
-
-
@@ -393,4 +373,6 @@ const IndexPage: React.FC = () => { ); }; -export default IndexPage; +export default connect(({ user }: any) => ({ + user, +}))(IndexPage); diff --git a/src/pages/login/login.tsx b/src/pages/login/login.tsx index abe595a..f35f2ec 100644 --- a/src/pages/login/login.tsx +++ b/src/pages/login/login.tsx @@ -1,26 +1,57 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { Form, Input, Button, Checkbox, Tabs, message } from 'antd'; -import { UserOutlined, LockOutlined, EyeInvisibleOutlined, EyeTwoTone, HomeOutlined } from '@ant-design/icons'; -import { history, useIntl } from 'umi'; +import { + UserOutlined, + LockOutlined, + EyeInvisibleOutlined, + EyeTwoTone, + HomeOutlined, +} from '@ant-design/icons'; +import { history, useIntl, connect } from 'umi'; +import type { ConnectProps, Dispatch } from 'umi'; import './login.less'; +import { getCaptcha, supplierLogin, getUserinfo, findMenuList } from '@/servers/api/login'; +import { encryptWithRsa } from '@/utils/encryptWithRsa'; +import type { UserModelState } from '@/models/user'; const { TabPane } = Tabs; - -const LoginPage: React.FC = () => { +interface PageProps extends ConnectProps { + user: UserModelState; // dva model状态 + dispatch: Dispatch; // dva dispatch方法 +} +const LoginPage: React.FC = ({ user, dispatch }) => { const [activeKey, setActiveKey] = useState('supplier'); const [form] = Form.useForm(); const [loading, setLoading] = useState(false); const intl = useIntl(); - - const onFinish = (values: any) => { + const [captchaImg, setCaptchaImg] = useState(''); + const [captchaKey, setCaptchaKey] = useState(''); + const onFinish = async (values: any) => { setLoading(true); - console.log('登录信息:', values); - // 这里添加登录逻辑 - setTimeout(() => { + try { + const params = { + ...values, + password: encryptWithRsa(values.password, false), + encryptValue: encryptWithRsa(values.identifying), + }; + const loginRes = await supplierLogin(params); + if (loginRes.code === 200) { + sessionStorage.setItem('token', loginRes.data.token); + //存入供应商用户id + sessionStorage.setItem('userId', loginRes.data.supplierUser.userId); + sessionStorage.setItem('currentUser', JSON.stringify(loginRes.data)); + dispatch({ + type: 'user/saveLoginUser', + payload: loginRes.data, + }) + message.success('登录成功'); + history.push('/index'); + } else { + message.error(loginRes.message || '登录失败'); + } + } finally { setLoading(false); - message.success('登录成功'); - history.push('/index'); - }, 1000); + } }; const handleTabChange = (key: string) => { @@ -30,7 +61,7 @@ const LoginPage: React.FC = () => { // 根据当前选中的Tab决定跳转到哪个注册页面 const handleRegister = () => { - switch(activeKey) { + switch (activeKey) { case 'supplier': history.push('/register/supplier'); break; @@ -52,42 +83,55 @@ const LoginPage: React.FC = () => { return ( ); }; - + // 获取验证码 + const fetchCaptcha = async () => { + const res = await getCaptcha(); + if (res.code === 200) { + setCaptchaImg(res.data.base64Image); + setCaptchaKey(res.data.code); + } + }; + useEffect(() => { + fetchCaptcha(); + }, [activeKey]); return ( -
-
-
+
+
+ -
{intl.formatMessage({ id: 'login.title' })}
+
{intl.formatMessage({ id: 'login.title' })}
-
+ {/*
-
+
*/}
} @@ -98,18 +142,48 @@ const LoginPage: React.FC = () => { } placeholder={intl.formatMessage({ id: 'login.password.placeholder' })} - iconRender={visible => (visible ? : )} + iconRender={(visible) => (visible ? : )} size="large" /> + + + } + /> + -
+
{intl.formatMessage({ id: 'login.remember' })} @@ -120,7 +194,13 @@ const LoginPage: React.FC = () => { - {renderRegisterLink()} @@ -131,4 +211,4 @@ const LoginPage: React.FC = () => { ); }; -export default LoginPage; +export default connect(({ user }: { user: UserModelState }) => ({ user }))(LoginPage); diff --git a/src/servers/api/login.ts b/src/servers/api/login.ts new file mode 100644 index 0000000..90a63e7 --- /dev/null +++ b/src/servers/api/login.ts @@ -0,0 +1,73 @@ +import request from '@/utils/request'; + +/** + * 验证码 + */ +export async function getCaptcha() { + return request('/v1/login/getCaptcha', { + method: 'GET' + }); +} + +/** + * 招标代理 + */ +export async function accountLogin (data: API.LoginSupplier) { + return request('/v1/login/accountLogin', { + method: 'POST', + data + }); +} +/** + * 专家 + */ +export async function expertLogin (data: API.LoginSupplier) { + return request('/v1/login/expertLogin', { + method: 'POST', + data + }); +} + +/** + * 供应商 + */ +export async function supplierLogin (data: API.LoginSupplier) { + return request('/v1/login/accountLogin/supplier', { + method: 'POST', + data + }); +} +/** + * 用户信息 + */ +export async function getUserinfo() { + return request('/v1/userinfo/get', { + method: 'GET' + }); +} + +/** + * 退出 + */ +export async function Logout() { + return request('/v1/login/logout', { + method: 'POST' + }); +} +/** + * 路由 + */ +export async function findMenuList(data: any) { + return request('/v1/menu/findMenuList', { + method: 'POST', + data + }); +} +/** +* 部门 +*/ +export async function queryUserOrgAll() { + return request('/org/queryUserOrgAll', { + method: 'GET' + }); +} \ No newline at end of file diff --git a/src/servers/api/typings.d.ts b/src/servers/api/typings.d.ts index 9847e44..25383f6 100644 --- a/src/servers/api/typings.d.ts +++ b/src/servers/api/typings.d.ts @@ -368,4 +368,11 @@ declare namespace API { thumbnail: string; url: string; } + //登录 + interface LoginSupplier { + account: string; + password: string; + identifying: string; + encryptValue: string; + } } diff --git a/src/utils/encryptWithRsa.ts b/src/utils/encryptWithRsa.ts new file mode 100644 index 0000000..caa1162 --- /dev/null +++ b/src/utils/encryptWithRsa.ts @@ -0,0 +1,21 @@ +import JSEncrypt from 'jsencrypt'; +import dayjs from 'dayjs'; + +const PUBLIC_KEY = `-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvLBkALIYR/x9Rv5TiXQGWAXTzraN/He80r9gQovSQ5oTP8qllL9+Oc1LdTijPFRsddHWg37umvFliwhmukU1NT+o2loGcKpyMHFkc/UPNjQLvd+YFR4nYhgP8l+dmRNOtQWawOt5dbksRKTghMjA+FKT2+itMsawSs1+Ic+zoIwIDAQAB +-----END PUBLIC KEY-----`; + +export function encryptWithRsa(value: string, type: boolean = true, publicKey: string = PUBLIC_KEY): string { + const nowStr = dayjs().format('YYYY-MM-DD HH:mm:ss'); + + const content = type? `${value}_${nowStr}`: value; + const encryptor = new JSEncrypt(); + encryptor.setPublicKey(publicKey); + const encrypted = encryptor.encrypt(content); + if (!encrypted) { + throw new Error('RSA 加密失败'); + } + return encrypted; +} + + diff --git a/src/utils/request.ts b/src/utils/request.ts index fa9def3..6617bb8 100644 --- a/src/utils/request.ts +++ b/src/utils/request.ts @@ -57,24 +57,20 @@ const request = extend({ credentials: 'include' // 默认请求是否带上cookie }); // request拦截器, 改变url 或 options. -request.interceptors.request.use(async (url, options) => { - if ( - options.method === 'post' || - options.method === 'put' || - options.method === 'delete' || - options.method === 'get' - ) { - //如果是获取token的url,则不加token - // headers = { - // Authorization: getUserToken() == null ? null : getUserToken(), - // JwtToken: getSessionUserData() == null ? null : getSessionUserData().userId, - // ...options.headers - // } - // options.headers = headers; - } +request.interceptors.request.use((url: string, options: any) => { + // 获取 token + const token = sessionStorage.getItem('token'); + const userId = sessionStorage.getItem('userId'); return { url, - options: { ...options }, + options: { + ...options, + headers: { + ...(options.headers || {}), + ...(token ? { Authorization: `Bearer ${token}` } : {}), + ...(userId ? { Mall3Check: `${userId}` } : {}), + }, + }, }; }); //response拦截 diff --git a/src/wrappers/auth.tsx b/src/wrappers/auth.tsx index cd46ca5..d6f3951 100644 --- a/src/wrappers/auth.tsx +++ b/src/wrappers/auth.tsx @@ -1,13 +1,15 @@ import React from 'react'; -import { Redirect } from 'umi'; -import { message } from 'antd'; +import { connect, Redirect, history } from 'umi'; +import { message, Modal } from 'antd'; // 权限校验 -export default (props: any) => { - if (localStorage.getItem('token')) { - return
{props.children}
; +const AuthWrapper = ({ user, children }: any) => { + if (user.token) { + return
{children}
; } else { - // 提示后跳转 - message.error('请先登录'); return ; } }; + +export default connect(({ user }: any) => ({ + user, +}))(AuthWrapper);