mirror of https://github.com/openspug/spug
A 添加个人中心
parent
3f5e8c0dd9
commit
86f9a86aeb
|
@ -10,4 +10,5 @@ urlpatterns = [
|
||||||
url(r'^logout/', logout),
|
url(r'^logout/', logout),
|
||||||
url(r'^user/$', UserView.as_view()),
|
url(r'^user/$', UserView.as_view()),
|
||||||
url(r'^role/$', RoleView.as_view()),
|
url(r'^role/$', RoleView.as_view()),
|
||||||
|
url(r'^self/$', SelfView.as_view()),
|
||||||
]
|
]
|
||||||
|
|
|
@ -108,6 +108,29 @@ class RoleView(View):
|
||||||
return json_response(error=error)
|
return json_response(error=error)
|
||||||
|
|
||||||
|
|
||||||
|
class SelfView(View):
|
||||||
|
def patch(self, request):
|
||||||
|
form, error = JsonParser(
|
||||||
|
Argument('old_password', required=False),
|
||||||
|
Argument('new_password', required=False),
|
||||||
|
Argument('nickname', required=False),
|
||||||
|
).parse(request.body, True)
|
||||||
|
if error is None:
|
||||||
|
if form.get('old_password') and form.get('new_password'):
|
||||||
|
if len(form.new_password) < 6:
|
||||||
|
return json_response(error='请设置至少6位的新密码')
|
||||||
|
if request.user.verify_password(form.old_password):
|
||||||
|
request.user.password_hash = User.make_password(form.new_password)
|
||||||
|
request.user.token_expired = 0
|
||||||
|
request.user.save()
|
||||||
|
else:
|
||||||
|
return json_response(error='原密码错误,请重新输入')
|
||||||
|
if form.get('nickname'):
|
||||||
|
request.user.nickname = form.nickname
|
||||||
|
request.user.save()
|
||||||
|
return json_response(error=error)
|
||||||
|
|
||||||
|
|
||||||
def login(request):
|
def login(request):
|
||||||
form, error = JsonParser(
|
form, error = JsonParser(
|
||||||
Argument('username', help='请输入用户名'),
|
Argument('username', help='请输入用户名'),
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* Released under the MIT License.
|
* Released under the MIT License.
|
||||||
*/
|
*/
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
import { Layout, Dropdown, Menu, List, Icon, Badge, Avatar } from 'antd';
|
import { Layout, Dropdown, Menu, List, Icon, Badge, Avatar } from 'antd';
|
||||||
import styles from './layout.module.css';
|
import styles from './layout.module.css';
|
||||||
import http from '../libs/http';
|
import http from '../libs/http';
|
||||||
|
@ -57,8 +58,10 @@ export default class extends React.Component {
|
||||||
};
|
};
|
||||||
menu = (
|
menu = (
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item disabled>
|
<Menu.Item>
|
||||||
<Icon type="user" style={{marginRight: 10}}/>个人中心
|
<Link to="/welcome/info">
|
||||||
|
<Icon type="user" style={{marginRight: 10}}/>个人中心
|
||||||
|
</Link>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
<Menu.Divider/>
|
<Menu.Divider/>
|
||||||
<Menu.Item onClick={this.handleLogout}>
|
<Menu.Item onClick={this.handleLogout}>
|
||||||
|
|
|
@ -52,7 +52,7 @@ class LoginIndex extends React.Component {
|
||||||
if (history.location.state && history.location.state['from']) {
|
if (history.location.state && history.location.state['from']) {
|
||||||
history.push(history.location.state['from'])
|
history.push(history.location.state['from'])
|
||||||
} else {
|
} else {
|
||||||
history.push('/welcome')
|
history.push('/welcome/index')
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ class LoginIndex extends React.Component {
|
||||||
<div className={styles.formContainer}>
|
<div className={styles.formContainer}>
|
||||||
<Tabs classNam={styles.tabs} onTabClick={e => this.setState({loginType: e})}>
|
<Tabs classNam={styles.tabs} onTabClick={e => this.setState({loginType: e})}>
|
||||||
<Tabs.TabPane tab="普通登录" key="default"/>
|
<Tabs.TabPane tab="普通登录" key="default"/>
|
||||||
<Tabs.TabPane tab="LDAP登录" key="ldap"/>
|
<Tabs.TabPane disabled tab="LDAP登录" key="ldap"/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<Form>
|
<Form>
|
||||||
<Form.Item className={styles.formItem}>
|
<Form.Item className={styles.formItem}>
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
|
* Released under the MIT License.
|
||||||
|
*/
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Button, Form, Input, message } from 'antd';
|
||||||
|
import styles from './index.module.css';
|
||||||
|
import { http } from 'libs';
|
||||||
|
import store from './store';
|
||||||
|
|
||||||
|
|
||||||
|
export default function Basic(props) {
|
||||||
|
const [nickname, setNickname] = useState(localStorage.getItem('nickname'));
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
store.loading = true;
|
||||||
|
http.patch('/api/account/self/', {nickname})
|
||||||
|
.then(() => {
|
||||||
|
message.success('设置成功,重新登录或刷新页面后生效');
|
||||||
|
localStorage.setItem('nickname', nickname)
|
||||||
|
})
|
||||||
|
.finally(() => store.loading = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div className={styles.title}>基本设置</div>
|
||||||
|
<Form style={{maxWidth: 320}}>
|
||||||
|
<Form.Item colon={false} label="昵称">
|
||||||
|
<Input value={nickname} placeholder="请输入" onChange={e => setNickname(e.target.value)}/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
<Button type="primary" loading={store.loading} onClick={handleSubmit}>保存设置</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
|
* Released under the MIT License.
|
||||||
|
*/
|
||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Button, Form, Input, message } from 'antd';
|
||||||
|
import styles from './index.module.css';
|
||||||
|
import { http } from 'libs';
|
||||||
|
import store from './store';
|
||||||
|
import history from 'libs/history';
|
||||||
|
|
||||||
|
|
||||||
|
export default function Reset(props) {
|
||||||
|
const [old_password, setOldPassword] = useState();
|
||||||
|
const [new_password, setNewPassword] = useState();
|
||||||
|
const [new2_password, setNew2Password] = useState();
|
||||||
|
|
||||||
|
function handleSubmit() {
|
||||||
|
if (!old_password) {
|
||||||
|
return message.error('请输入原密码')
|
||||||
|
} else if (!new_password) {
|
||||||
|
return message.error('请输入新密码')
|
||||||
|
} else if (new_password !== new2_password) {
|
||||||
|
return message.error('两次输入密码不一致')
|
||||||
|
}
|
||||||
|
store.loading = true;
|
||||||
|
http.patch('/api/account/self/', {old_password, new_password})
|
||||||
|
.then(() => {
|
||||||
|
message.success('密码修改成功');
|
||||||
|
history.push('/');
|
||||||
|
http.get('/api/account/logout/')
|
||||||
|
})
|
||||||
|
.finally(() => store.loading = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<div className={styles.title}>修改密码</div>
|
||||||
|
<Form style={{maxWidth: 320}} labelCol={{span: 6}} wrapperCol={{span: 18}}>
|
||||||
|
<Form.Item label="原密码">
|
||||||
|
<Input.Password value={old_password} placeholder="请输入" onChange={e => setOldPassword(e.target.value)}/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="新密码">
|
||||||
|
<Input.Password value={new_password} placeholder="请输入" onChange={e => setNewPassword(e.target.value)}/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item label="再次确认">
|
||||||
|
<Input.Password value={new2_password} placeholder="请输入" onChange={e => setNew2Password(e.target.value)}/>
|
||||||
|
</Form.Item>
|
||||||
|
<Form.Item>
|
||||||
|
<Button type="primary" loading={store.loading} onClick={handleSubmit}>保存设置</Button>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</React.Fragment>
|
||||||
|
)
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
|
* Released under the MIT License.
|
||||||
|
*/
|
||||||
|
import React from 'react';
|
||||||
|
import { Menu } from 'antd';
|
||||||
|
import Basic from './Basic';
|
||||||
|
import Reset from './Reset';
|
||||||
|
import styles from './index.module.css';
|
||||||
|
|
||||||
|
class Index extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
selectedKeys: ['basic']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {selectedKeys} = this.state;
|
||||||
|
return (
|
||||||
|
<div className={styles.container}>
|
||||||
|
<div className={styles.left}>
|
||||||
|
<Menu
|
||||||
|
mode="inline"
|
||||||
|
selectedKeys={selectedKeys}
|
||||||
|
style={{border: 'none'}}
|
||||||
|
onSelect={({selectedKeys}) => this.setState({selectedKeys})}>
|
||||||
|
<Menu.Item key="basic">基本设置</Menu.Item>
|
||||||
|
<Menu.Item key="reset">修改密码</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
</div>
|
||||||
|
<div className={styles.right}>
|
||||||
|
{selectedKeys[0] === 'basic' && <Basic />}
|
||||||
|
{selectedKeys[0] === 'reset' && <Reset />}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Index
|
|
@ -0,0 +1,25 @@
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 16px 0;
|
||||||
|
}
|
||||||
|
.left {
|
||||||
|
flex: 2;
|
||||||
|
border-right: 1px solid #e8e8e8;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
flex: 7;
|
||||||
|
padding: 8px 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
color: rgba(0, 0, 0, .85);
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form {
|
||||||
|
max-width: 320px;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
|
||||||
|
* Copyright (c) <spug.dev@gmail.com>
|
||||||
|
* Released under the MIT License.
|
||||||
|
*/
|
||||||
|
import { observable } from "mobx";
|
||||||
|
|
||||||
|
class Store {
|
||||||
|
@observable loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new Store()
|
|
@ -5,7 +5,9 @@
|
||||||
*/
|
*/
|
||||||
import { makeRoute } from 'libs/router';
|
import { makeRoute } from 'libs/router';
|
||||||
import Index from './index';
|
import Index from './index';
|
||||||
|
import Info from './info';
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
makeRoute('', Index),
|
makeRoute('/index', Index),
|
||||||
|
makeRoute('/info', Info),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue