| @@ -27,6 +27,16 @@ export default [ | |||||
| }, | }, | ||||
| ], | ], | ||||
| }, | }, | ||||
| { | |||||
| path: '/authorize', | |||||
| layout: false, | |||||
| component: './Authorize/index', | |||||
| }, | |||||
| { | |||||
| path: '/gitlink', | |||||
| layout: true, | |||||
| component: './GitLink/index', | |||||
| }, | |||||
| { | { | ||||
| path: '/user', | path: '/user', | ||||
| layout: false, | layout: false, | ||||
| @@ -7,7 +7,6 @@ import defaultSettings from '../config/defaultSettings'; | |||||
| import '../public/fonts/font.css'; | import '../public/fonts/font.css'; | ||||
| import { getAccessToken } from './access'; | import { getAccessToken } from './access'; | ||||
| import './dayjsConfig'; | import './dayjsConfig'; | ||||
| import { PageEnum } from './enums/pagesEnums'; | |||||
| import './global.less'; | import './global.less'; | ||||
| import { removeAllPageCacheState } from './hooks/pageCacheState'; | import { removeAllPageCacheState } from './hooks/pageCacheState'; | ||||
| import { | import { | ||||
| @@ -23,6 +22,7 @@ export { requestConfig as request } from './requestConfig'; | |||||
| import { type GlobalInitialState } from '@/types'; | import { type GlobalInitialState } from '@/types'; | ||||
| import { menuItemRender } from '@/utils/menuRender'; | import { menuItemRender } from '@/utils/menuRender'; | ||||
| import ErrorBoundary from './components/ErrorBoundary'; | import ErrorBoundary from './components/ErrorBoundary'; | ||||
| import { needAuth } from './utils'; | |||||
| import { gotoLoginPage } from './utils/ui'; | import { gotoLoginPage } from './utils/ui'; | ||||
| /** | /** | ||||
| @@ -40,14 +40,17 @@ export async function getInitialState(): Promise<GlobalInitialState> { | |||||
| roleNames: response.user.roles, | roleNames: response.user.roles, | ||||
| } as API.CurrentUser; | } as API.CurrentUser; | ||||
| } catch (error) { | } catch (error) { | ||||
| console.error(error); | |||||
| console.error('1111', error); | |||||
| gotoLoginPage(); | gotoLoginPage(); | ||||
| } | } | ||||
| return undefined; | return undefined; | ||||
| }; | }; | ||||
| // 如果不是登录页面,执行 | // 如果不是登录页面,执行 | ||||
| const { location } = history; | const { location } = history; | ||||
| if (location.pathname !== PageEnum.LOGIN) { | |||||
| console.log('getInitialState', needAuth(location.pathname)); | |||||
| if (needAuth(location.pathname)) { | |||||
| const currentUser = await fetchUserInfo(); | const currentUser = await fetchUserInfo(); | ||||
| return { | return { | ||||
| fetchUserInfo, | fetchUserInfo, | ||||
| @@ -94,7 +97,7 @@ export const layout: RuntimeConfig['layout'] = ({ initialState }) => { | |||||
| onPageChange: () => { | onPageChange: () => { | ||||
| const { location } = history; | const { location } = history; | ||||
| // 如果没有登录,重定向到 login | // 如果没有登录,重定向到 login | ||||
| if (!initialState?.currentUser && location.pathname !== PageEnum.LOGIN) { | |||||
| if (!initialState?.currentUser && needAuth(location.pathname)) { | |||||
| gotoLoginPage(); | gotoLoginPage(); | ||||
| } | } | ||||
| }, | }, | ||||
| @@ -159,8 +162,8 @@ export const layout: RuntimeConfig['layout'] = ({ initialState }) => { | |||||
| export const onRouteChange: RuntimeConfig['onRouteChange'] = async (e) => { | export const onRouteChange: RuntimeConfig['onRouteChange'] = async (e) => { | ||||
| const { location } = e; | const { location } = e; | ||||
| const menus = getRemoteMenu(); | const menus = getRemoteMenu(); | ||||
| // console.log('onRouteChange', e); | |||||
| if (menus === null && location.pathname !== PageEnum.LOGIN) { | |||||
| console.log('onRouteChange', menus); | |||||
| if (menus === null && needAuth(location.pathname)) { | |||||
| history.go(0); | history.go(0); | ||||
| } | } | ||||
| }; | }; | ||||
| @@ -170,12 +173,12 @@ export const patchRoutes: RuntimeConfig['patchRoutes'] = (e) => { | |||||
| }; | }; | ||||
| export const patchClientRoutes: RuntimeConfig['patchClientRoutes'] = (e) => { | export const patchClientRoutes: RuntimeConfig['patchClientRoutes'] = (e) => { | ||||
| //console.log('patchClientRoutes', e); | |||||
| console.log('patchClientRoutes', e); | |||||
| patchRouteWithRemoteMenus(e.routes); | patchRouteWithRemoteMenus(e.routes); | ||||
| }; | }; | ||||
| export function render(oldRender: () => void) { | export function render(oldRender: () => void) { | ||||
| // console.log('render'); | |||||
| console.log('render'); | |||||
| const token = getAccessToken(); | const token = getAccessToken(); | ||||
| if (!token || token?.length === 0) { | if (!token || token?.length === 0) { | ||||
| oldRender(); | oldRender(); | ||||
| @@ -12,6 +12,7 @@ export enum IframePageType { | |||||
| DatasetAnnotation = 'DatasetAnnotation', // 数据标注 | DatasetAnnotation = 'DatasetAnnotation', // 数据标注 | ||||
| AppDevelopment = 'AppDevelopment', // 应用开发 | AppDevelopment = 'AppDevelopment', // 应用开发 | ||||
| DevEnv = 'DevEnv', // 开发环境 | DevEnv = 'DevEnv', // 开发环境 | ||||
| GitLink = 'GitLink', | |||||
| } | } | ||||
| const getRequestAPI = (type: IframePageType): (() => Promise<any>) => { | const getRequestAPI = (type: IframePageType): (() => Promise<any>) => { | ||||
| @@ -26,6 +27,8 @@ const getRequestAPI = (type: IframePageType): (() => Promise<any>) => { | |||||
| code: 200, | code: 200, | ||||
| data: SessionStorage.getItem(SessionStorage.editorUrlKey) || '', | data: SessionStorage.getItem(SessionStorage.editorUrlKey) || '', | ||||
| }); | }); | ||||
| case IframePageType.GitLink: | |||||
| return () => Promise.resolve({ code: 200, data: 'http://172.20.32.201:4000' }); | |||||
| } | } | ||||
| }; | }; | ||||
| @@ -1,6 +1,8 @@ | |||||
| import { clearSessionToken } from '@/access'; | import { clearSessionToken } from '@/access'; | ||||
| import { setRemoteMenu } from '@/services/session'; | import { setRemoteMenu } from '@/services/session'; | ||||
| import { logout } from '@/services/system/auth'; | import { logout } from '@/services/system/auth'; | ||||
| import { ClientInfo } from '@/types'; | |||||
| import SessionStorage from '@/utils/sessionStorage'; | |||||
| import { gotoLoginPage } from '@/utils/ui'; | import { gotoLoginPage } from '@/utils/ui'; | ||||
| import { LogoutOutlined, UserOutlined } from '@ant-design/icons'; | import { LogoutOutlined, UserOutlined } from '@ant-design/icons'; | ||||
| import { setAlpha } from '@ant-design/pro-components'; | import { setAlpha } from '@ant-design/pro-components'; | ||||
| @@ -64,6 +66,11 @@ const AvatarDropdown: React.FC<GlobalHeaderRightProps> = ({ menu }) => { | |||||
| clearSessionToken(); | clearSessionToken(); | ||||
| setRemoteMenu(null); | setRemoteMenu(null); | ||||
| gotoLoginPage(); | gotoLoginPage(); | ||||
| const clientInfo: ClientInfo = SessionStorage.getItem(SessionStorage.clientInfoKey, true); | |||||
| if (clientInfo) { | |||||
| const { logoutUri } = clientInfo; | |||||
| location.replace(logoutUri); | |||||
| } | |||||
| }; | }; | ||||
| const actionClassName = useEmotionCss(({ token }) => { | const actionClassName = useEmotionCss(({ token }) => { | ||||
| return { | return { | ||||
| @@ -0,0 +1,50 @@ | |||||
| import { setSessionToken } from '@/access'; | |||||
| import { loginByOauth2Req } from '@/services/auth'; | |||||
| import { to } from '@/utils/promise'; | |||||
| import { history, useModel, useSearchParams } from '@umijs/max'; | |||||
| import { message } from 'antd'; | |||||
| import { useEffect } from 'react'; | |||||
| import { flushSync } from 'react-dom'; | |||||
| import styles from './index.less'; | |||||
| function Authorize() { | |||||
| const { initialState, setInitialState } = useModel('@@initialState'); | |||||
| const [searchParams] = useSearchParams(); | |||||
| const code = searchParams.get('code'); | |||||
| const redirect = searchParams.get('redirect'); | |||||
| useEffect(() => { | |||||
| loginByOauth2(); | |||||
| }, []); | |||||
| // 登录 | |||||
| const loginByOauth2 = async () => { | |||||
| const params = { | |||||
| code, | |||||
| }; | |||||
| const [res] = await to(loginByOauth2Req(params)); | |||||
| debugger; | |||||
| if (res && res.data) { | |||||
| const { access_token, expires_in } = res.data; | |||||
| setSessionToken(access_token, access_token, expires_in); | |||||
| message.success('登录成功!'); | |||||
| await fetchUserInfo(); | |||||
| history.push(redirect || '/'); | |||||
| } | |||||
| }; | |||||
| const fetchUserInfo = async () => { | |||||
| const userInfo = await initialState?.fetchUserInfo?.(); | |||||
| if (userInfo) { | |||||
| flushSync(() => { | |||||
| setInitialState((s) => ({ | |||||
| ...s, | |||||
| currentUser: userInfo, | |||||
| })); | |||||
| }); | |||||
| } | |||||
| }; | |||||
| return <div className={styles.container}></div>; | |||||
| } | |||||
| export default Authorize; | |||||
| @@ -0,0 +1,7 @@ | |||||
| import IframePage, { IframePageType } from '@/components/IFramePage'; | |||||
| function GitLink() { | |||||
| return <IframePage type={IframePageType.GitLink}></IframePage>; | |||||
| } | |||||
| export default GitLink; | |||||
| @@ -1,11 +1,12 @@ | |||||
| import { clearSessionToken, setSessionToken } from '@/access'; | import { clearSessionToken, setSessionToken } from '@/access'; | ||||
| import { getClientInfoReq } from '@/services/auth'; | |||||
| import { getCaptchaImg, login } from '@/services/system/auth'; | import { getCaptchaImg, login } from '@/services/system/auth'; | ||||
| import { parseJsonText } from '@/utils'; | |||||
| import { safeInvoke } from '@/utils/functional'; | |||||
| import LocalStorage from '@/utils/localStorage'; | import LocalStorage from '@/utils/localStorage'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | |||||
| import { gotoOAuth2 } from '@/utils/ui'; | |||||
| import { history, useModel } from '@umijs/max'; | import { history, useModel } from '@umijs/max'; | ||||
| import { Button, Checkbox, Flex, Form, Image, Input, message, type InputRef } from 'antd'; | |||||
| import { Form, message, type InputRef } from 'antd'; | |||||
| import CryptoJS from 'crypto-js'; | import CryptoJS from 'crypto-js'; | ||||
| import { useEffect, useRef, useState } from 'react'; | import { useEffect, useRef, useState } from 'react'; | ||||
| import { flushSync } from 'react-dom'; | import { flushSync } from 'react-dom'; | ||||
| @@ -31,25 +32,35 @@ const Login = () => { | |||||
| const captchaInputRef = useRef<InputRef>(null); | const captchaInputRef = useRef<InputRef>(null); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| getCaptchaCode(); | |||||
| const autoLogin = LocalStorage.getItem(LocalStorage.rememberPasswordKey) ?? 'false'; | |||||
| if (autoLogin === 'true') { | |||||
| const userStorage = LocalStorage.getItem(LocalStorage.loginUserKey); | |||||
| const userJson = safeInvoke((text: string) => | |||||
| CryptoJS.AES.decrypt(text, AESKEY).toString(CryptoJS.enc.Utf8), | |||||
| )(userStorage); | |||||
| const user = safeInvoke(parseJsonText)(userJson); | |||||
| if (user && typeof user === 'object' && user.version === VERSION) { | |||||
| const { username, password } = user; | |||||
| form.setFieldsValue({ username: username, password: password, autoLogin: true }); | |||||
| } else { | |||||
| form.setFieldsValue({ username: '', password: '', autoLogin: true }); | |||||
| LocalStorage.removeItem(LocalStorage.loginUserKey); | |||||
| } | |||||
| } else { | |||||
| form.setFieldsValue({ username: '', password: '', autoLogin: false }); | |||||
| } | |||||
| // getCaptchaCode(); | |||||
| // const autoLogin = LocalStorage.getItem(LocalStorage.rememberPasswordKey) ?? 'false'; | |||||
| // if (autoLogin === 'true') { | |||||
| // const userStorage = LocalStorage.getItem(LocalStorage.loginUserKey); | |||||
| // const userJson = safeInvoke((text: string) => | |||||
| // CryptoJS.AES.decrypt(text, AESKEY).toString(CryptoJS.enc.Utf8), | |||||
| // )(userStorage); | |||||
| // const user = safeInvoke(parseJsonText)(userJson); | |||||
| // if (user && typeof user === 'object' && user.version === VERSION) { | |||||
| // const { username, password } = user; | |||||
| // form.setFieldsValue({ username: username, password: password, autoLogin: true }); | |||||
| // } else { | |||||
| // form.setFieldsValue({ username: '', password: '', autoLogin: true }); | |||||
| // LocalStorage.removeItem(LocalStorage.loginUserKey); | |||||
| // } | |||||
| // } else { | |||||
| // form.setFieldsValue({ username: '', password: '', autoLogin: false }); | |||||
| // } | |||||
| getClientInfo(); | |||||
| }, []); | }, []); | ||||
| const getClientInfo = async () => { | |||||
| const [res] = await to(getClientInfoReq()); | |||||
| if (res && res.data) { | |||||
| const clientInfo = res.data; | |||||
| SessionStorage.setItem(SessionStorage.clientInfoKey, clientInfo, true); | |||||
| gotoOAuth2(); | |||||
| } | |||||
| }; | |||||
| const getCaptchaCode = async () => { | const getCaptchaCode = async () => { | ||||
| const [res] = await to(getCaptchaImg()); | const [res] = await to(getCaptchaImg()); | ||||
| if (res) { | if (res) { | ||||
| @@ -71,6 +82,12 @@ const Login = () => { | |||||
| } | } | ||||
| }; | }; | ||||
| const handleSubmit2 = async (values: API.LoginParams) => { | |||||
| const url = | |||||
| 'http://172.20.32.106:8080/oauth/authorize?client_id=ci4s&response_type=code&grant_type=authorization_code'; | |||||
| window.location.href = url; | |||||
| }; | |||||
| // 登录 | // 登录 | ||||
| const handleSubmit = async (values: API.LoginParams) => { | const handleSubmit = async (values: API.LoginParams) => { | ||||
| const [res, error] = await to(login({ ...values, uuid })); | const [res, error] = await to(login({ ...values, uuid })); | ||||
| @@ -109,113 +126,115 @@ const Login = () => { | |||||
| } | } | ||||
| }; | }; | ||||
| return ( | |||||
| <div className={styles['user-login']}> | |||||
| <div className={styles['user-login__left']}> | |||||
| <div className={styles['user-login__left__top']}> | |||||
| <img | |||||
| src={require('@/assets/img/logo.png')} | |||||
| style={{ width: '32px', marginRight: '12px' }} | |||||
| draggable={false} | |||||
| alt="" | |||||
| /> | |||||
| 智能材料科研平台 | |||||
| </div> | |||||
| <div className={styles['user-login__left__title']}> | |||||
| <span>智能材料科研平台</span> | |||||
| <img | |||||
| src={require('@/assets/img/login-ai-logo.png')} | |||||
| className={styles['user-login__left__title__img']} | |||||
| draggable={false} | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| <div className={styles['user-login__left__message']}> | |||||
| <span>大语言模型运维 统一管理平台</span> | |||||
| </div> | |||||
| <img | |||||
| className={styles['user-login__left__bottom-img']} | |||||
| src={require('@/assets/img/login-left-image.png')} | |||||
| draggable={false} | |||||
| alt="" | |||||
| /> | |||||
| </div> | |||||
| <div className={styles['user-login__right']}> | |||||
| <div> | |||||
| <div className={styles['user-login__right__title']}> | |||||
| <span style={{ color: '#111111' }}>欢迎登录</span> | |||||
| <span>智能材料科研平台</span> | |||||
| </div> | |||||
| <div className={styles['user-login__right__content']}> | |||||
| <div className={styles['user-login__right__content__title']}>账号登录</div> | |||||
| <div className={styles['user-login__right__content__form']}> | |||||
| <Form | |||||
| labelCol={{ span: 0 }} | |||||
| wrapperCol={{ span: 24 }} | |||||
| initialValues={{ autoLogin: true }} | |||||
| onFinish={handleSubmit} | |||||
| autoComplete="off" | |||||
| form={form} | |||||
| > | |||||
| <Form.Item name="username" rules={[{ required: true, message: '请输入用户名' }]}> | |||||
| <Input | |||||
| placeholder="请输入用户名" | |||||
| prefix={<LoginInputPrefix icon={require('@/assets/img/login-user.png')} />} | |||||
| allowClear | |||||
| /> | |||||
| </Form.Item> | |||||
| <Form.Item name="password" rules={[{ required: true, message: '请输入密码' }]}> | |||||
| <Input.Password | |||||
| placeholder="请输入密码" | |||||
| prefix={<LoginInputPrefix icon={require('@/assets/img/login-password.png')} />} | |||||
| allowClear | |||||
| /> | |||||
| </Form.Item> | |||||
| <Flex align="start" style={{ height: '98px' }}> | |||||
| <div style={{ flex: 1 }}> | |||||
| <Form.Item name="code" rules={[{ required: true, message: '请输入验证码' }]}> | |||||
| <Input | |||||
| placeholder="请输入验证码" | |||||
| prefix={ | |||||
| <LoginInputPrefix icon={require('@/assets/img/login-captcha.png')} /> | |||||
| } | |||||
| ref={captchaInputRef} | |||||
| allowClear | |||||
| /> | |||||
| </Form.Item> | |||||
| </div> | |||||
| <Image | |||||
| className={styles['user-login__right__content__form__captcha']} | |||||
| src={captchaCode} | |||||
| alt="验证码" | |||||
| preview={false} | |||||
| onClick={() => getCaptchaCode()} | |||||
| /> | |||||
| </Flex> | |||||
| <Form.Item | |||||
| name="autoLogin" | |||||
| valuePropName="checked" | |||||
| labelCol={{ span: 0 }} | |||||
| wrapperCol={{ span: 16 }} | |||||
| > | |||||
| <Checkbox>记住密码</Checkbox> | |||||
| </Form.Item> | |||||
| <Form.Item labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}> | |||||
| <Button type="primary" htmlType="submit"> | |||||
| 登录 | |||||
| </Button> | |||||
| </Form.Item> | |||||
| </Form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| ); | |||||
| return <div className={styles['user-login']}></div>; | |||||
| // return ( | |||||
| // <div className={styles['user-login']}> | |||||
| // <div className={styles['user-login__left']}> | |||||
| // <div className={styles['user-login__left__top']}> | |||||
| // <img | |||||
| // src={require('@/assets/img/logo.png')} | |||||
| // style={{ width: '32px', marginRight: '12px' }} | |||||
| // draggable={false} | |||||
| // alt="" | |||||
| // /> | |||||
| // 智能材料科研平台 | |||||
| // </div> | |||||
| // <div className={styles['user-login__left__title']}> | |||||
| // <span>智能材料科研平台</span> | |||||
| // <img | |||||
| // src={require('@/assets/img/login-ai-logo.png')} | |||||
| // className={styles['user-login__left__title__img']} | |||||
| // draggable={false} | |||||
| // alt="" | |||||
| // /> | |||||
| // </div> | |||||
| // <div className={styles['user-login__left__message']}> | |||||
| // <span>大语言模型运维 统一管理平台</span> | |||||
| // </div> | |||||
| // <img | |||||
| // className={styles['user-login__left__bottom-img']} | |||||
| // src={require('@/assets/img/login-left-image.png')} | |||||
| // draggable={false} | |||||
| // alt="" | |||||
| // /> | |||||
| // </div> | |||||
| // <div className={styles['user-login__right']}> | |||||
| // <div> | |||||
| // <div className={styles['user-login__right__title']}> | |||||
| // <span style={{ color: '#111111' }}>欢迎登录</span> | |||||
| // <span>智能材料科研平台</span> | |||||
| // </div> | |||||
| // <div className={styles['user-login__right__content']}> | |||||
| // <div className={styles['user-login__right__content__title']}>账号登录</div> | |||||
| // <div className={styles['user-login__right__content__form']}> | |||||
| // <Form | |||||
| // labelCol={{ span: 0 }} | |||||
| // wrapperCol={{ span: 24 }} | |||||
| // initialValues={{ autoLogin: true }} | |||||
| // onFinish={handleSubmit2} | |||||
| // autoComplete="off" | |||||
| // form={form} | |||||
| // > | |||||
| // <Form.Item name="username" rules={[{ required: false, message: '请输入用户名' }]}> | |||||
| // <Input | |||||
| // placeholder="请输入用户名" | |||||
| // prefix={<LoginInputPrefix icon={require('@/assets/img/login-user.png')} />} | |||||
| // allowClear | |||||
| // /> | |||||
| // </Form.Item> | |||||
| // <Form.Item name="password" rules={[{ required: false, message: '请输入密码' }]}> | |||||
| // <Input.Password | |||||
| // placeholder="请输入密码" | |||||
| // prefix={<LoginInputPrefix icon={require('@/assets/img/login-password.png')} />} | |||||
| // allowClear | |||||
| // /> | |||||
| // </Form.Item> | |||||
| // <Flex align="start" style={{ height: '98px' }}> | |||||
| // <div style={{ flex: 1 }}> | |||||
| // <Form.Item name="code" rules={[{ required: false, message: '请输入验证码' }]}> | |||||
| // <Input | |||||
| // placeholder="请输入验证码" | |||||
| // prefix={ | |||||
| // <LoginInputPrefix icon={require('@/assets/img/login-captcha.png')} /> | |||||
| // } | |||||
| // ref={captchaInputRef} | |||||
| // allowClear | |||||
| // /> | |||||
| // </Form.Item> | |||||
| // </div> | |||||
| // <Image | |||||
| // className={styles['user-login__right__content__form__captcha']} | |||||
| // src={captchaCode} | |||||
| // alt="验证码" | |||||
| // preview={false} | |||||
| // onClick={() => getCaptchaCode()} | |||||
| // /> | |||||
| // </Flex> | |||||
| // <Form.Item | |||||
| // name="autoLogin" | |||||
| // valuePropName="checked" | |||||
| // labelCol={{ span: 0 }} | |||||
| // wrapperCol={{ span: 16 }} | |||||
| // > | |||||
| // <Checkbox>记住密码</Checkbox> | |||||
| // </Form.Item> | |||||
| // <Form.Item labelCol={{ span: 0 }} wrapperCol={{ span: 24 }}> | |||||
| // <Button type="primary" htmlType="submit"> | |||||
| // 登录 | |||||
| // </Button> | |||||
| // </Form.Item> | |||||
| // </Form> | |||||
| // </div> | |||||
| // </div> | |||||
| // </div> | |||||
| // </div> | |||||
| // </div> | |||||
| // ); | |||||
| }; | }; | ||||
| export default Login; | export default Login; | ||||
| @@ -0,0 +1,16 @@ | |||||
| import { request } from '@umijs/max'; | |||||
| // 单点登录 | |||||
| export function loginByOauth2Req(data) { | |||||
| return request(`/api/auth/loginByOauth2`, { | |||||
| method: 'POST', | |||||
| data, | |||||
| }); | |||||
| } | |||||
| // 登录获取客户端信息 | |||||
| export function getClientInfoReq() { | |||||
| return request(`/api/auth/oauth2ClientInfo`, { | |||||
| method: 'GET', | |||||
| }); | |||||
| } | |||||
| @@ -7,6 +7,17 @@ | |||||
| import { ExperimentStatus, TensorBoardStatus } from '@/enums'; | import { ExperimentStatus, TensorBoardStatus } from '@/enums'; | ||||
| import type { Settings as LayoutSettings } from '@ant-design/pro-components'; | import type { Settings as LayoutSettings } from '@ant-design/pro-components'; | ||||
| export type ClientInfo = { | |||||
| accessTokenUri: string; | |||||
| checkTokenUri: string; | |||||
| clientId: string; | |||||
| clientSecret: string; | |||||
| loginPage: string; | |||||
| logoutUri: string; | |||||
| redirectUri: string; | |||||
| userAuthorizationUri: string; | |||||
| }; | |||||
| // 全局初始状态类型 | // 全局初始状态类型 | ||||
| export type GlobalInitialState = { | export type GlobalInitialState = { | ||||
| settings?: Partial<LayoutSettings>; | settings?: Partial<LayoutSettings>; | ||||
| @@ -14,6 +25,7 @@ export type GlobalInitialState = { | |||||
| fetchUserInfo?: () => Promise<API.CurrentUser | undefined>; | fetchUserInfo?: () => Promise<API.CurrentUser | undefined>; | ||||
| loading?: boolean; | loading?: boolean; | ||||
| collapsed?: boolean; | collapsed?: boolean; | ||||
| clientInfo?: ClientInfo; | |||||
| }; | }; | ||||
| // 流水线全局参数 | // 流水线全局参数 | ||||
| @@ -9,6 +9,8 @@ export default class SessionStorage { | |||||
| static readonly serviceVersionInfoKey = 'service-version-info'; | static readonly serviceVersionInfoKey = 'service-version-info'; | ||||
| // 编辑器 url | // 编辑器 url | ||||
| static readonly editorUrlKey = 'editor-url'; | static readonly editorUrlKey = 'editor-url'; | ||||
| // 客户端信息 | |||||
| static readonly clientInfoKey = 'client-info'; | |||||
| static getItem(key: string, isObject: boolean = false) { | static getItem(key: string, isObject: boolean = false) { | ||||
| const jsonStr = sessionStorage.getItem(key); | const jsonStr = sessionStorage.getItem(key); | ||||
| @@ -6,9 +6,11 @@ | |||||
| import { PageEnum } from '@/enums/pagesEnums'; | import { PageEnum } from '@/enums/pagesEnums'; | ||||
| import { removeAllPageCacheState } from '@/hooks/pageCacheState'; | import { removeAllPageCacheState } from '@/hooks/pageCacheState'; | ||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { type ClientInfo } from '@/types'; | |||||
| import { history } from '@umijs/max'; | import { history } from '@umijs/max'; | ||||
| import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd'; | import { Modal, message, type ModalFuncProps, type UploadFile } from 'antd'; | ||||
| import { closeAllModals } from './modal'; | import { closeAllModals } from './modal'; | ||||
| import SessionStorage from './sessionStorage'; | |||||
| type ModalConfirmProps = ModalFuncProps & { | type ModalConfirmProps = ModalFuncProps & { | ||||
| isDelete?: boolean; | isDelete?: boolean; | ||||
| @@ -75,7 +77,7 @@ export const gotoLoginPage = (toHome: boolean = true) => { | |||||
| const { pathname, search } = location; | const { pathname, search } = location; | ||||
| const urlParams = new URLSearchParams(); | const urlParams = new URLSearchParams(); | ||||
| urlParams.append('redirect', pathname + search); | urlParams.append('redirect', pathname + search); | ||||
| const newSearch = toHome && pathname !== '/' ? '' : urlParams.toString(); | |||||
| const newSearch = toHome || pathname === '/' ? '' : urlParams.toString(); | |||||
| // console.log('pathname', pathname); | // console.log('pathname', pathname); | ||||
| // console.log('search', search); | // console.log('search', search); | ||||
| if (pathname !== PageEnum.LOGIN) { | if (pathname !== PageEnum.LOGIN) { | ||||
| @@ -88,6 +90,15 @@ export const gotoLoginPage = (toHome: boolean = true) => { | |||||
| } | } | ||||
| }; | }; | ||||
| export const gotoOAuth2 = () => { | |||||
| const clientInfo = SessionStorage.getItem(SessionStorage.clientInfoKey, true) as ClientInfo; | |||||
| if (clientInfo) { | |||||
| const { clientId, userAuthorizationUri } = clientInfo; | |||||
| const url = `${userAuthorizationUri}?client_id=${clientId}&response_type=code&grant_type=authorization_code`; | |||||
| location.replace(url); | |||||
| } | |||||
| }; | |||||
| /** | /** | ||||
| * 验证文件上传 | * 验证文件上传 | ||||
| * | * | ||||