mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 14:46:13 +00:00
feat: user register & profile
This commit is contained in:
parent
589fca05d0
commit
c82fee6162
@ -115,6 +115,7 @@ import * as uiSchema from './ui-schema';
|
|||||||
|
|
||||||
const User = database.getModel('users');
|
const User = database.getModel('users');
|
||||||
const user = await User.create({
|
const user = await User.create({
|
||||||
|
nickname: '超级管理员',
|
||||||
email: process.env.ADMIN_EMAIL,
|
email: process.env.ADMIN_EMAIL,
|
||||||
password: process.env.ADMIN_PASSWORD,
|
password: process.env.ADMIN_PASSWORD,
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,7 @@ export const login = {
|
|||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Input',
|
'x-component': 'Input',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
placeholder: '邮箱或用户名',
|
placeholder: '电子邮箱',
|
||||||
style: {
|
style: {
|
||||||
// width: 240,
|
// width: 240,
|
||||||
},
|
},
|
||||||
|
@ -2,19 +2,19 @@ export const register = {
|
|||||||
key: '46qlxqam3xk',
|
key: '46qlxqam3xk',
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
username: {
|
email: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Input',
|
'x-component': 'Input',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
placeholder: '用户名',
|
placeholder: '电子邮箱',
|
||||||
style: {
|
style: {
|
||||||
// width: 240,
|
// width: 240,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
pwd1: {
|
password: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
@ -26,19 +26,41 @@ export const register = {
|
|||||||
// width: 240,
|
// width: 240,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'x-reactions': [
|
||||||
|
{
|
||||||
|
dependencies: ['.confirm_password'],
|
||||||
|
fulfill: {
|
||||||
|
state: {
|
||||||
|
errors:
|
||||||
|
'{{$deps[0] && $self.value && $self.value !== $deps[0] ? "确认密码不匹配" : ""}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
pwd2: {
|
confirm_password: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
'x-decorator': 'FormItem',
|
'x-decorator': 'FormItem',
|
||||||
'x-component': 'Password',
|
'x-component': 'Password',
|
||||||
'x-component-props': {
|
'x-component-props': {
|
||||||
placeholder: '密码',
|
placeholder: '确认密码',
|
||||||
checkStrength: true,
|
checkStrength: true,
|
||||||
style: {
|
style: {
|
||||||
// width: 240,
|
// width: 240,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
'x-reactions': [
|
||||||
|
{
|
||||||
|
dependencies: ['.password'],
|
||||||
|
fulfill: {
|
||||||
|
state: {
|
||||||
|
errors:
|
||||||
|
'{{$deps[0] && $self.value && $self.value !== $deps[0] ? "确认密码不匹配" : ""}}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
type: 'void',
|
type: 'void',
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
import { useRequest } from 'ahooks';
|
import { useRequest } from 'ahooks';
|
||||||
import { Spin } from 'antd';
|
import { Spin } from 'antd';
|
||||||
import React, { createContext } from 'react';
|
import React, { createContext } from 'react';
|
||||||
|
import { useContext } from 'react';
|
||||||
import { Redirect } from 'react-router';
|
import { Redirect } from 'react-router';
|
||||||
import { useLocation } from 'react-router-dom';
|
import { useLocation } from 'react-router-dom';
|
||||||
|
import { BaseResult } from '@ahooksjs/use-request/lib/types';
|
||||||
|
|
||||||
export const AuthContext = createContext(null);
|
export interface AuthContextProps {
|
||||||
|
currentUser?: any;
|
||||||
|
service: BaseResult<any, any>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const AuthContext = createContext<AuthContextProps>({});
|
||||||
|
|
||||||
|
export const useCurrentUser = () => {
|
||||||
|
const { currentUser } = useContext(AuthContext);
|
||||||
|
return currentUser;
|
||||||
|
}
|
||||||
|
|
||||||
export function AuthProvider(props) {
|
export function AuthProvider(props) {
|
||||||
const service = useRequest('users:check', {
|
const service = useRequest('users:check', {
|
||||||
|
@ -1,15 +1,63 @@
|
|||||||
import React, { useContext, useEffect } from 'react';
|
import React, { useContext, useEffect } from 'react';
|
||||||
import { Button, Dropdown, Menu } from 'antd';
|
import { Button, Dropdown, Menu } from 'antd';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import { request } from '../../schemas';
|
import { request, SchemaField } from '../../schemas';
|
||||||
|
import { AuthContext, useCurrentUser } from './Auth';
|
||||||
|
import { FormButtonGroup, FormDrawer, FormLayout, Submit } from '@formily/antd';
|
||||||
|
|
||||||
export const UserInfo = () => {
|
export const UserInfo = () => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const { service, currentUser } = useContext(AuthContext);
|
||||||
return (
|
return (
|
||||||
<Dropdown
|
<Dropdown
|
||||||
overlay={
|
overlay={
|
||||||
<Menu>
|
<Menu>
|
||||||
<Menu.Item>个人资料</Menu.Item>
|
<Menu.Item
|
||||||
|
onClick={async () => {
|
||||||
|
const values = await FormDrawer('个人资料', () => {
|
||||||
|
return (
|
||||||
|
<FormLayout layout={'vertical'}>
|
||||||
|
<SchemaField
|
||||||
|
schema={{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
email: {
|
||||||
|
type: 'string',
|
||||||
|
title: '邮箱',
|
||||||
|
'x-component': 'Input',
|
||||||
|
'x-decorator': 'FormilyFormItem',
|
||||||
|
},
|
||||||
|
nickname: {
|
||||||
|
type: 'string',
|
||||||
|
title: '昵称',
|
||||||
|
'x-component': 'Input',
|
||||||
|
'x-decorator': 'FormilyFormItem',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<FormDrawer.Footer>
|
||||||
|
<FormButtonGroup align="right">
|
||||||
|
<Submit onSubmit={(values) => {
|
||||||
|
}}>
|
||||||
|
保存
|
||||||
|
</Submit>
|
||||||
|
</FormButtonGroup>
|
||||||
|
</FormDrawer.Footer>
|
||||||
|
</FormLayout>
|
||||||
|
);
|
||||||
|
}).open({
|
||||||
|
initialValues: currentUser || {},
|
||||||
|
});
|
||||||
|
const { data } = await request('users:updateProfile', {
|
||||||
|
method: 'post',
|
||||||
|
data: values,
|
||||||
|
});
|
||||||
|
service.mutate(data);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
个人资料
|
||||||
|
</Menu.Item>
|
||||||
<Menu.Divider />
|
<Menu.Divider />
|
||||||
<Menu.Item
|
<Menu.Item
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
@ -23,7 +71,9 @@ export const UserInfo = () => {
|
|||||||
</Menu>
|
</Menu>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Button type={'text'} className={'user-info'}>超级管理员</Button>
|
<Button type={'text'} className={'user-info'}>
|
||||||
|
{currentUser?.nickname || currentUser?.email}
|
||||||
|
</Button>
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useContext, useEffect, useState } from 'react';
|
import React, { useContext, useEffect, useState } from 'react';
|
||||||
import { Spin } from 'antd';
|
import { message, Spin } from 'antd';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
import { useRequest } from 'ahooks';
|
import { useRequest } from 'ahooks';
|
||||||
import { request, SchemaRenderer } from '../../schemas';
|
import { request, SchemaRenderer } from '../../schemas';
|
||||||
@ -7,7 +7,7 @@ import { useForm } from '@formily/react';
|
|||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
function Div(props) {
|
function Div(props) {
|
||||||
return <div {...props}></div>
|
return <div {...props}></div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useLogin() {
|
export function useLogin() {
|
||||||
@ -29,9 +29,18 @@ export function useLogin() {
|
|||||||
|
|
||||||
export function useRegister() {
|
export function useRegister() {
|
||||||
const form = useForm();
|
const form = useForm();
|
||||||
|
const history = useHistory();
|
||||||
return {
|
return {
|
||||||
async run() {
|
async run() {
|
||||||
await form.submit();
|
await form.submit();
|
||||||
|
const { data } = await request('users:register', {
|
||||||
|
method: 'post',
|
||||||
|
data: form.values,
|
||||||
|
});
|
||||||
|
message.success('注册成功,将跳转登录页');
|
||||||
|
setTimeout(() => {
|
||||||
|
history.push('/login');
|
||||||
|
}, 1000);
|
||||||
console.log(form.values);
|
console.log(form.values);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -50,7 +59,11 @@ export function RouteSchemaRenderer({ route }) {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<SchemaRenderer components={{ Div }} scope={{ useLogin, useRegister }} schema={data} />
|
<SchemaRenderer
|
||||||
|
components={{ Div }}
|
||||||
|
scope={{ useLogin, useRegister }}
|
||||||
|
schema={data}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -120,3 +120,13 @@ export async function getUserByResetToken(ctx: actions.Context, next: actions.Ne
|
|||||||
ctx.body = user;
|
ctx.body = user;
|
||||||
await next();
|
await next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function updateProfile(ctx: actions.Context, next: actions.Next) {
|
||||||
|
const { values } = ctx.action.params;
|
||||||
|
if (!ctx.state.currentUser) {
|
||||||
|
ctx.throw(401, 'Unauthorized');
|
||||||
|
}
|
||||||
|
await ctx.state.currentUser.update(values);
|
||||||
|
ctx.body = ctx.state.currentUser;
|
||||||
|
await next();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user