[ISSUE#11957] Console support init password for nacos username (#12148)
* feat:add register pagg * fix:i18n * console-ui build * fix * fix
This commit is contained in:
parent
bc039bc125
commit
0a797223c0
@ -27,6 +27,23 @@ function goLogin() {
|
||||
window.location = `${base_url}#/login`;
|
||||
}
|
||||
|
||||
function goRegister() {
|
||||
const url = window.location.href;
|
||||
localStorage.removeItem('token');
|
||||
const base_url = url.split('#')[0];
|
||||
window.location = `${base_url}#/register`;
|
||||
}
|
||||
|
||||
function generateRandomPassword(length) {
|
||||
const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
let password = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * charset.length);
|
||||
password += charset[randomIndex];
|
||||
}
|
||||
return password;
|
||||
}
|
||||
|
||||
const global = window;
|
||||
|
||||
/**
|
||||
@ -564,5 +581,7 @@ export {
|
||||
setParam,
|
||||
setParams,
|
||||
goLogin,
|
||||
goRegister,
|
||||
generateRandomPassword,
|
||||
request,
|
||||
};
|
||||
|
@ -32,6 +32,7 @@ import Layout from './layouts/MainLayout';
|
||||
import { LANGUAGE_KEY, REDUX_DEVTOOLS, THEME } from './constants';
|
||||
|
||||
import Login from './pages/Login';
|
||||
import Register from './pages/Register';
|
||||
import Namespace from './pages/NameSpace';
|
||||
import Newconfig from './pages/ConfigurationManagement/NewConfig';
|
||||
import Configsync from './pages/ConfigurationManagement/ConfigSync';
|
||||
@ -136,6 +137,7 @@ class App extends React.Component {
|
||||
{loginPageEnabled && loginPageEnabled === 'false' ? null : (
|
||||
<Route path="/login" component={Login} />
|
||||
)}
|
||||
<Route path="/register" component={Register} />
|
||||
{/* <Route path="/login" component={Login} /> */}
|
||||
<Layout>
|
||||
{consoleUiEnable &&
|
||||
|
@ -27,10 +27,12 @@ const I18N_CONF = {
|
||||
},
|
||||
Login: {
|
||||
login: '登录',
|
||||
initPassword: '初始化密码',
|
||||
internalSysTip1: '内部系统,不可暴露到公网',
|
||||
submit: '提交',
|
||||
pleaseInputUsername: '请输入用户名',
|
||||
pleaseInputPassword: '请输入密码',
|
||||
pleaseInputPasswordTips: '请输入密码(若密码为空,将使用随机密码)',
|
||||
invalidUsernameOrPassword: '用户名或密码错误',
|
||||
passwordRequired: '密码不能为空',
|
||||
usernameRequired: '用户名不能为空',
|
||||
|
160
console-ui/src/pages/Register/Register.jsx
Normal file
160
console-ui/src/pages/Register/Register.jsx
Normal file
@ -0,0 +1,160 @@
|
||||
import React from 'react';
|
||||
import { Card, Form, Input, Message, ConfigProvider, Field, Dialog } from '@alifd/next';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
import './index.scss';
|
||||
import Header from '../../layouts/Header';
|
||||
import PropTypes from 'prop-types';
|
||||
import { admin, guide, state } from '../../reducers/base';
|
||||
import { connect } from 'react-redux';
|
||||
import { generateRandomPassword } from '../../globalLib';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
@withRouter
|
||||
@ConfigProvider.config
|
||||
@connect(state => ({ ...state.locale }))
|
||||
class Register extends React.Component {
|
||||
static displayName = 'Register';
|
||||
|
||||
static propTypes = {
|
||||
locale: PropTypes.object,
|
||||
history: PropTypes.object,
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
consoleUiEnable: true,
|
||||
guideMsg: '',
|
||||
};
|
||||
this.field = new Field(this);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (localStorage.getItem('token')) {
|
||||
const [baseUrl] = location.href.split('#');
|
||||
location.href = `${baseUrl}#/`;
|
||||
}
|
||||
this.handleSearch();
|
||||
}
|
||||
|
||||
handleSearch = () => {
|
||||
state().then(res => {
|
||||
if (res?.console_ui_enabled === 'false') {
|
||||
this.setState({ consoleUiEnable: true });
|
||||
guide().then(res => {
|
||||
this.setState({ guideMsg: res?.data });
|
||||
});
|
||||
} else {
|
||||
this.setState({ consoleUiEnable: false });
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
handleSubmit = () => {
|
||||
const { locale = {} } = this.props;
|
||||
this.field.validate((errors, values) => {
|
||||
if (errors) {
|
||||
return;
|
||||
}
|
||||
|
||||
const data = {
|
||||
password: generateRandomPassword(10),
|
||||
...values
|
||||
};
|
||||
|
||||
admin(data)
|
||||
.then(res => {
|
||||
if (res.username && res.password) {
|
||||
localStorage.setItem('token', JSON.stringify(res));
|
||||
Dialog.alert({
|
||||
title: locale.Login.initPassword + locale.ListeningToQuery.success,
|
||||
content: locale.Password.newPassword + ':' + res.password,
|
||||
onOk: () => {
|
||||
this.props.history.push('/');
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
Message.error({
|
||||
content: locale.Login.invalidUsernameOrPassword,
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
onKeyDown = event => {
|
||||
// 'keypress' event misbehaves on mobile so we track 'Enter' key via 'keydown' event
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this.handleSubmit();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { locale = {} } = this.props;
|
||||
const { consoleUiEnable, guideMsg } = this.state;
|
||||
|
||||
return (
|
||||
<div className="home-page">
|
||||
<Header />
|
||||
<section
|
||||
className="top-section"
|
||||
style={{
|
||||
background: 'url(img/black_dot.png) repeat',
|
||||
backgroundSize: '14px 14px',
|
||||
}}
|
||||
>
|
||||
<div className="vertical-middle product-area">
|
||||
<img className="product-logo" src="img/nacos.png" />
|
||||
<p className="product-desc">{locale.Login.productDesc}</p>
|
||||
</div>
|
||||
<div className="animation animation1" />
|
||||
<div className="animation animation2" />
|
||||
<div className="animation animation3" />
|
||||
<div className="animation animation4" />
|
||||
<div className="animation animation5" />
|
||||
<Card className="login-panel" contentHeight="auto">
|
||||
<div className="login-header">{locale.Login.initPassword}</div>
|
||||
<div className="internal-sys-tip">
|
||||
<div>{locale.Login.internalSysTip1}</div>
|
||||
<div>{locale.Login.internalSysTip2}</div>
|
||||
</div>
|
||||
{!consoleUiEnable && (
|
||||
<Form className="login-form" field={this.field}>
|
||||
<FormItem>
|
||||
<Input
|
||||
value="nacos"
|
||||
readOnly
|
||||
placeholder={locale.Login.pleaseInputUsername}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Input
|
||||
htmlType="password"
|
||||
placeholder={locale.Login.pleaseInputPasswordTips}
|
||||
{...this.field.init('password', {})}
|
||||
onKeyDown={this.onKeyDown}
|
||||
/>
|
||||
</FormItem>
|
||||
<FormItem label=" ">
|
||||
<Form.Submit onClick={this.handleSubmit}>{locale.Login.submit}</Form.Submit>
|
||||
</FormItem>
|
||||
</Form>
|
||||
)}
|
||||
{consoleUiEnable && (
|
||||
<Message type="notice" style={{ marginTop: 30 }}>
|
||||
<div dangerouslySetInnerHTML={{ __html: guideMsg }} />
|
||||
</Message>
|
||||
)}
|
||||
</Card>
|
||||
</section>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Register;
|
4
console-ui/src/pages/Register/index.jsx
Normal file
4
console-ui/src/pages/Register/index.jsx
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
import Register from './Register';
|
||||
|
||||
export default Register;
|
142
console-ui/src/pages/Register/index.scss
Normal file
142
console-ui/src/pages/Register/index.scss
Normal file
@ -0,0 +1,142 @@
|
||||
/*!
|
||||
* Copyright 1999-2018 Alibaba Group Holding Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
$animationDuration: 2s;
|
||||
|
||||
// 品牌色
|
||||
$brandColor: #2e3034;
|
||||
$mobileWidth: 640px;
|
||||
// 页面主体最大宽度
|
||||
$contentWidth: 1280px;
|
||||
|
||||
@keyframes slashStar {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.home-page {
|
||||
.top-section {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
.login-panel {
|
||||
position: absolute;
|
||||
right: 40px;
|
||||
width: 480px;
|
||||
height: 540px;
|
||||
top: 90px;
|
||||
border: 0px;
|
||||
input,
|
||||
input::-webkit-input-placeholder {
|
||||
font-size: 16px;
|
||||
}
|
||||
.login-header {
|
||||
width: 100%;
|
||||
line-height: 45px;
|
||||
font-size: 32px;
|
||||
margin-top: 58px;
|
||||
text-align: center;
|
||||
}
|
||||
.internal-sys-tip {
|
||||
width: 100%;
|
||||
line-height: 25px;
|
||||
font-size: 20px;
|
||||
margin-top: 25px;
|
||||
text-align: center;
|
||||
font-weight: 800;
|
||||
color: #ff0000cc;
|
||||
}
|
||||
.login-form {
|
||||
width: 360px;
|
||||
margin: 40px auto auto auto;
|
||||
input {
|
||||
height: 60px;
|
||||
}
|
||||
button {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
font-size: 16px;
|
||||
background: #4190ff 100%;
|
||||
color: white;
|
||||
border: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.animation {
|
||||
position: absolute;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background-color: #1be1f6;
|
||||
&1 {
|
||||
left: 15%;
|
||||
top: 70%;
|
||||
animation: slashStar $animationDuration ease-in-out 0.3s infinite;
|
||||
}
|
||||
&2 {
|
||||
left: 34%;
|
||||
top: 35%;
|
||||
animation: slashStar $animationDuration ease-in-out 1.2s infinite;
|
||||
}
|
||||
&3 {
|
||||
left: 53%;
|
||||
top: 20%;
|
||||
animation: slashStar $animationDuration ease-in-out 0.5s infinite;
|
||||
}
|
||||
&4 {
|
||||
left: 72%;
|
||||
top: 64%;
|
||||
animation: slashStar $animationDuration ease-in-out 0.8s infinite;
|
||||
}
|
||||
&5 {
|
||||
left: 87%;
|
||||
top: 30%;
|
||||
animation: slashStar $animationDuration ease-in-out 1.5s infinite;
|
||||
}
|
||||
}
|
||||
.vertical-middle {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
margin-top: -47px;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.product-area {
|
||||
width: 600px;
|
||||
margin-left: 40px;
|
||||
}
|
||||
.product-logo {
|
||||
display: block;
|
||||
width: 257px;
|
||||
height: 50px;
|
||||
margin: 0;
|
||||
}
|
||||
.product-desc {
|
||||
opacity: 0.8;
|
||||
font-family: Avenir-Medium;
|
||||
font-size: 24px;
|
||||
color: #fff;
|
||||
max-width: 780px;
|
||||
margin: 12px auto 30px;
|
||||
text-align: left;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
@ -23,10 +23,18 @@ import { Redirect } from 'react-router-dom';
|
||||
class Welcome extends React.Component {
|
||||
static propTypes = {
|
||||
functionMode: PropTypes.string,
|
||||
authAdminRequest: PropTypes.string,
|
||||
};
|
||||
|
||||
render() {
|
||||
const { functionMode } = this.props;
|
||||
const { functionMode, authAdminRequest } = this.props;
|
||||
if (authAdminRequest && authAdminRequest === 'true') {
|
||||
return (
|
||||
<>
|
||||
<Redirect to="/register" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
const path = functionMode === 'naming' ? 'serviceManagement' : 'configurationManagement';
|
||||
return <>{functionMode !== '' && <Redirect to={`/${path}`} />}</>;
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ const initialState = {
|
||||
authEnabled: '',
|
||||
notice: '',
|
||||
consoleUiEnable: '',
|
||||
authAdminRequest: '',
|
||||
guideMsg: '',
|
||||
};
|
||||
|
||||
@ -33,6 +34,7 @@ const initialState = {
|
||||
* @param {*} param0
|
||||
*/
|
||||
const login = user => request.post('v1/auth/users/login', user);
|
||||
const admin = user => request.post('v1/auth/users/admin', user);
|
||||
|
||||
/**
|
||||
* 单独在login处调用 获取提示信息
|
||||
@ -57,6 +59,7 @@ const getState = () => dispatch =>
|
||||
functionMode: res.function_mode,
|
||||
loginPageEnabled: res.login_page_enabled,
|
||||
authEnabled: res.auth_enabled,
|
||||
authAdminRequest: res.auth_admin_request,
|
||||
consoleUiEnable: res.console_ui_enabled,
|
||||
startupMode: res.startup_mode,
|
||||
},
|
||||
@ -72,6 +75,7 @@ const getState = () => dispatch =>
|
||||
loginPageEnabled: null,
|
||||
authEnabled: null,
|
||||
consoleUiEnable: null,
|
||||
authAdminRequest: null,
|
||||
},
|
||||
});
|
||||
});
|
||||
@ -129,4 +133,4 @@ export default (state = initialState, action) => {
|
||||
}
|
||||
};
|
||||
|
||||
export { getState, login, getNotice, getGuide, guide, state };
|
||||
export { getState, login, getNotice, getGuide, guide, state, admin };
|
||||
|
File diff suppressed because one or more lines are too long
@ -35,7 +35,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="console-ui/public/css/icon.css">
|
||||
<link rel="stylesheet" type="text/css" href="console-ui/public/css/font-awesome.css">
|
||||
<!-- 第三方css结束 -->
|
||||
<link href="./css/main.css?c02a3284f12026e72980" rel="stylesheet"></head>
|
||||
<link href="./css/main.css?42101e8cf76887c3acb3" rel="stylesheet"></head>
|
||||
|
||||
<body>
|
||||
<div id="root" style="overflow:hidden"></div>
|
||||
@ -56,6 +56,6 @@
|
||||
<script src="console-ui/public/js/merge.js"></script>
|
||||
<script src="console-ui/public/js/loader.js"></script>
|
||||
<!-- 第三方js结束 -->
|
||||
<script type="text/javascript" src="./js/main.js?c02a3284f12026e72980"></script></body>
|
||||
<script type="text/javascript" src="./js/main.js?42101e8cf76887c3acb3"></script></body>
|
||||
|
||||
</html>
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user