A 添加个人中心

pull/22/head
vapao 2020-01-16 18:36:56 +08:00
parent 3f5e8c0dd9
commit 86f9a86aeb
11 changed files with 209 additions and 5 deletions

View File

@ -10,4 +10,5 @@ urlpatterns = [
url(r'^logout/', logout),
url(r'^user/$', UserView.as_view()),
url(r'^role/$', RoleView.as_view()),
url(r'^self/$', SelfView.as_view()),
]

View File

@ -108,6 +108,29 @@ class RoleView(View):
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):
form, error = JsonParser(
Argument('username', help='请输入用户名'),

View File

@ -4,6 +4,7 @@
* Released under the MIT License.
*/
import React from 'react';
import { Link } from 'react-router-dom';
import { Layout, Dropdown, Menu, List, Icon, Badge, Avatar } from 'antd';
import styles from './layout.module.css';
import http from '../libs/http';
@ -57,8 +58,10 @@ export default class extends React.Component {
};
menu = (
<Menu>
<Menu.Item disabled>
<Icon type="user" style={{marginRight: 10}}/>个人中心
<Menu.Item>
<Link to="/welcome/info">
<Icon type="user" style={{marginRight: 10}}/>个人中心
</Link>
</Menu.Item>
<Menu.Divider/>
<Menu.Item onClick={this.handleLogout}>

View File

@ -52,7 +52,7 @@ class LoginIndex extends React.Component {
if (history.location.state && history.location.state['from']) {
history.push(history.location.state['from'])
} else {
history.push('/welcome')
history.push('/welcome/index')
}
};
@ -67,7 +67,7 @@ class LoginIndex extends React.Component {
<div className={styles.formContainer}>
<Tabs classNam={styles.tabs} onTabClick={e => this.setState({loginType: e})}>
<Tabs.TabPane tab="普通登录" key="default"/>
<Tabs.TabPane tab="LDAP登录" key="ldap"/>
<Tabs.TabPane disabled tab="LDAP登录" key="ldap"/>
</Tabs>
<Form>
<Form.Item className={styles.formItem}>

View File

@ -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>
)
}

View File

@ -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>
)
}

View File

@ -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

View File

@ -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;
}

View File

@ -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()

View File

@ -5,7 +5,9 @@
*/
import { makeRoute } from 'libs/router';
import Index from './index';
import Info from './info';
export default [
makeRoute('', Index),
makeRoute('/index', Index),
makeRoute('/info', Info),
]