A 微信token普通用户可以通过个人中心设置

pull/462/head
vapao 2022-02-18 15:37:52 +08:00
parent eae6f0b818
commit 02d9563367
7 changed files with 100 additions and 64 deletions

View File

@ -142,14 +142,20 @@ class RoleView(AdminView):
class SelfView(View):
def get(self, request):
data = request.user.to_dict(selects=('nickname', 'wx_token'))
return json_response(data)
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)
Argument('nickname', required=False, help='请输入昵称'),
Argument('wx_token', required=False),
).parse(request.body)
if error is None:
if form.get('old_password') and form.get('new_password'):
print(form)
if form.old_password and form.new_password:
if request.user.type == 'ldap':
return json_response(error='LDAP账户无法修改密码')
if len(form.new_password) < 6:
@ -158,10 +164,13 @@ class SelfView(View):
request.user.password_hash = User.make_password(form.new_password)
request.user.token_expired = 0
request.user.save()
return json_response()
else:
return json_response(error='原密码错误,请重新输入')
if form.get('nickname'):
if form.nickname is not None:
request.user.nickname = form.nickname
if form.wx_token is not None:
request.user.wx_token = form.wx_token
request.user.save()
return json_response(error=error)

View File

@ -20,13 +20,11 @@ class Argument(object):
:param bool required: is required
"""
def __init__(self, name, default=None, handler=None, required=True, type=str, filter=None, help=None,
nullable=False):
def __init__(self, name, default=None, handler=None, required=True, type=str, filter=None, help=None):
self.name = name
self.default = default
self.type = type
self.required = required
self.nullable = nullable
self.filter = filter
self.help = help
self.handler = handler
@ -45,11 +43,12 @@ class Argument(object):
elif value in [u'', '', None]:
if self.default is not None:
return self.default
elif not self.nullable and self.required:
raise ParseError(
self.help or 'Value Error: %s must not be null' % self.name)
elif self.required:
raise ParseError(self.help or 'Value Error: %s must not be null' % self.name)
elif self.help:
raise ParseError(self.help)
else:
return None
return value
try:
if self.type:
if self.type in (list, dict) and isinstance(value, str):

View File

@ -3,37 +3,55 @@
* Copyright (c) <spug.dev@gmail.com>
* Released under the AGPL-3.0 License.
*/
import React, { useState } from 'react';
import { Button, Form, Input, message } from 'antd';
import React, { useState, useEffect } from 'react';
import { observer } from 'mobx-react';
import { Button, Form, Input, Spin, 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'));
const [loading, setLoading] = useState(false);
export default observer(function Basic(props) {
const [form] = Form.useForm()
const [fetching, setFetching] = useState(false)
const [loading, setLoading] = useState(false)
useEffect(() => {
if (!store.user.nickname) {
setFetching(true)
store.fetchUser()
.then(() => form.setFieldsValue(store.user))
.finally(() => setFetching(false))
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
function handleSubmit() {
setLoading(true);
http.patch('/api/account/self/', {nickname})
const formData = form.getFieldsValue();
http.patch('/api/account/self/', formData)
.then(() => {
message.success('设置成功,重新登录或刷新页面后生效');
localStorage.setItem('nickname', nickname)
message.success('保存成功,昵称将在重新登录或刷新页面后生效');
localStorage.setItem('nickname', formData.nickname);
store.fetchUser()
})
.finally(() => setLoading(false))
}
return (
<React.Fragment>
<Spin spinning={fetching}>
<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 form={form} layout="vertical" style={{maxWidth: 320}} initialValues={store.user}>
<Form.Item required name="nickname" label="昵称">
<Input placeholder="请输入"/>
</Form.Item>
<Form.Item name="wx_token" label="微信Token" extra={<a target="_blank" rel="noopener noreferrer" href="https://spug.cc/docs/wx-token/">什么是微信Token</a>}>
<Input placeholder="请输入"/>
</Form.Item>
<Form.Item>
<Button type="primary" loading={loading} onClick={handleSubmit}>保存设置</Button>
</Form.Item>
</Form>
</React.Fragment>
</Spin>
)
}
})

View File

@ -38,13 +38,13 @@ export default function Reset(props) {
<React.Fragment>
<div className={styles.title}>修改密码</div>
<Form style={{maxWidth: 320}} labelCol={{span: 6}} wrapperCol={{span: 18}}>
<Form.Item label="原密码">
<Form.Item required label="原密码">
<Input.Password value={old_password} placeholder="请输入" onChange={e => setOldPassword(e.target.value)}/>
</Form.Item>
<Form.Item label="新密码">
<Form.Item required label="新密码">
<Input.Password value={new_password} placeholder="请输入" onChange={e => setNewPassword(e.target.value)}/>
</Form.Item>
<Form.Item label="再次确认">
<Form.Item required label="再次确认">
<Input.Password value={new2_password} placeholder="请输入" onChange={e => setNew2Password(e.target.value)}/>
</Form.Item>
<Form.Item>

View File

@ -3,23 +3,16 @@
* Copyright (c) <spug.dev@gmail.com>
* Released under the AGPL-3.0 License.
*/
import React from 'react';
import React, { useState } from 'react';
import { Menu } from 'antd';
import { Breadcrumb } from 'components';
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']
}
}
function Index() {
const [selectedKeys, setSelectedKeys] = useState(['basic'])
render() {
const {selectedKeys} = this.state;
return (
<div>
<Breadcrumb>
@ -32,7 +25,7 @@ class Index extends React.Component {
mode="inline"
selectedKeys={selectedKeys}
style={{border: 'none'}}
onSelect={({selectedKeys}) => this.setState({selectedKeys})}>
onSelect={({selectedKeys}) => setSelectedKeys(selectedKeys)}>
<Menu.Item key="basic">基本设置</Menu.Item>
<Menu.Item key="reset">修改密码</Menu.Item>
</Menu>
@ -45,6 +38,5 @@ class Index extends React.Component {
</div>
)
}
}
export default Index

View File

@ -13,7 +13,7 @@
}
.title {
margin-bottom: 12px;
margin-bottom: 24px;
color: rgba(0, 0, 0, .85);
font-weight: 500;
font-size: 20px;

View File

@ -0,0 +1,18 @@
/**
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
* Copyright (c) <spug.dev@gmail.com>
* Released under the AGPL-3.0 License.
*/
import { observable } from 'mobx';
import http from 'libs/http';
class Store {
@observable user = {};
fetchUser = () => {
return http.get('/api/account/self/')
.then(res => this.user = res)
}
}
export default new Store()