From c82fee6162c0ff34a5260d4bcd77843901889dcc Mon Sep 17 00:00:00 2001 From: chenos Date: Mon, 23 Aug 2021 21:49:44 +0800 Subject: [PATCH] feat: user register & profile --- packages/api/src/migrations/init.ts | 1 + .../api/src/migrations/ui-schema/login.ts | 2 +- .../api/src/migrations/ui-schema/register.ts | 32 +++++++++-- .../src/components/admin-layout/Auth.tsx | 14 ++++- .../src/components/admin-layout/UserInfo.tsx | 56 ++++++++++++++++++- .../route-schema-renderer/index.tsx | 19 ++++++- packages/plugin-users/src/actions/users.ts | 10 ++++ 7 files changed, 121 insertions(+), 13 deletions(-) diff --git a/packages/api/src/migrations/init.ts b/packages/api/src/migrations/init.ts index 1b78e4604..117ed52ec 100644 --- a/packages/api/src/migrations/init.ts +++ b/packages/api/src/migrations/init.ts @@ -115,6 +115,7 @@ import * as uiSchema from './ui-schema'; const User = database.getModel('users'); const user = await User.create({ + nickname: '超级管理员', email: process.env.ADMIN_EMAIL, password: process.env.ADMIN_PASSWORD, }); diff --git a/packages/api/src/migrations/ui-schema/login.ts b/packages/api/src/migrations/ui-schema/login.ts index 633a71181..d6eaf0c40 100644 --- a/packages/api/src/migrations/ui-schema/login.ts +++ b/packages/api/src/migrations/ui-schema/login.ts @@ -8,7 +8,7 @@ export const login = { 'x-decorator': 'FormItem', 'x-component': 'Input', 'x-component-props': { - placeholder: '邮箱或用户名', + placeholder: '电子邮箱', style: { // width: 240, }, diff --git a/packages/api/src/migrations/ui-schema/register.ts b/packages/api/src/migrations/ui-schema/register.ts index 993d56a2f..39dbb2e31 100644 --- a/packages/api/src/migrations/ui-schema/register.ts +++ b/packages/api/src/migrations/ui-schema/register.ts @@ -2,19 +2,19 @@ export const register = { key: '46qlxqam3xk', type: 'object', properties: { - username: { + email: { type: 'string', required: true, 'x-decorator': 'FormItem', 'x-component': 'Input', 'x-component-props': { - placeholder: '用户名', + placeholder: '电子邮箱', style: { // width: 240, }, }, }, - pwd1: { + password: { type: 'string', required: true, 'x-decorator': 'FormItem', @@ -26,19 +26,41 @@ export const register = { // width: 240, }, }, + 'x-reactions': [ + { + dependencies: ['.confirm_password'], + fulfill: { + state: { + errors: + '{{$deps[0] && $self.value && $self.value !== $deps[0] ? "确认密码不匹配" : ""}}', + }, + }, + }, + ], }, - pwd2: { + confirm_password: { type: 'string', required: true, 'x-decorator': 'FormItem', 'x-component': 'Password', 'x-component-props': { - placeholder: '密码', + placeholder: '确认密码', checkStrength: true, style: { // width: 240, }, }, + 'x-reactions': [ + { + dependencies: ['.password'], + fulfill: { + state: { + errors: + '{{$deps[0] && $self.value && $self.value !== $deps[0] ? "确认密码不匹配" : ""}}', + }, + }, + }, + ], }, actions: { type: 'void', diff --git a/packages/client/src/components/admin-layout/Auth.tsx b/packages/client/src/components/admin-layout/Auth.tsx index a76e65d38..2e4286ab0 100644 --- a/packages/client/src/components/admin-layout/Auth.tsx +++ b/packages/client/src/components/admin-layout/Auth.tsx @@ -1,10 +1,22 @@ import { useRequest } from 'ahooks'; import { Spin } from 'antd'; import React, { createContext } from 'react'; +import { useContext } from 'react'; import { Redirect } from 'react-router'; 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; +} + +export const AuthContext = createContext({}); + +export const useCurrentUser = () => { + const { currentUser } = useContext(AuthContext); + return currentUser; +} export function AuthProvider(props) { const service = useRequest('users:check', { diff --git a/packages/client/src/components/admin-layout/UserInfo.tsx b/packages/client/src/components/admin-layout/UserInfo.tsx index 8ada7c08f..010d7284f 100644 --- a/packages/client/src/components/admin-layout/UserInfo.tsx +++ b/packages/client/src/components/admin-layout/UserInfo.tsx @@ -1,15 +1,63 @@ import React, { useContext, useEffect } from 'react'; import { Button, Dropdown, Menu } from 'antd'; 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 = () => { const history = useHistory(); + const { service, currentUser } = useContext(AuthContext); return ( - 个人资料 + { + const values = await FormDrawer('个人资料', () => { + return ( + + + + + { + }}> + 保存 + + + + + ); + }).open({ + initialValues: currentUser || {}, + }); + const { data } = await request('users:updateProfile', { + method: 'post', + data: values, + }); + service.mutate(data); + }} + > + 个人资料 + { @@ -23,7 +71,9 @@ export const UserInfo = () => { } > - + ); }; diff --git a/packages/client/src/components/route-schema-renderer/index.tsx b/packages/client/src/components/route-schema-renderer/index.tsx index e5bea6df3..a9a064845 100644 --- a/packages/client/src/components/route-schema-renderer/index.tsx +++ b/packages/client/src/components/route-schema-renderer/index.tsx @@ -1,5 +1,5 @@ import React, { useContext, useEffect, useState } from 'react'; -import { Spin } from 'antd'; +import { message, Spin } from 'antd'; import { Helmet } from 'react-helmet'; import { useRequest } from 'ahooks'; import { request, SchemaRenderer } from '../../schemas'; @@ -7,7 +7,7 @@ import { useForm } from '@formily/react'; import { useHistory } from 'react-router-dom'; function Div(props) { - return
+ return
; } export function useLogin() { @@ -29,9 +29,18 @@ export function useLogin() { export function useRegister() { const form = useForm(); + const history = useHistory(); return { async run() { 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); }, }; @@ -50,7 +59,11 @@ export function RouteSchemaRenderer({ route }) { } return (
- +
); } diff --git a/packages/plugin-users/src/actions/users.ts b/packages/plugin-users/src/actions/users.ts index 9665c76f7..6451d91f9 100644 --- a/packages/plugin-users/src/actions/users.ts +++ b/packages/plugin-users/src/actions/users.ts @@ -120,3 +120,13 @@ export async function getUserByResetToken(ctx: actions.Context, next: actions.Ne ctx.body = user; 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(); +}