From 40b007698f478c7bc5d14a608c7ff546bc04a8e3 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sun, 25 Jun 2023 09:43:18 +0800 Subject: [PATCH] feat: add nickname edit in register view --- .../shared/i18n/langs/en-US/translation.json | 1 + .../shared/i18n/langs/zh-CN/translation.json | 1 + client/shared/model/user.ts | 17 ++++--- client/web/src/components/TipIcon.tsx | 2 +- client/web/src/routes/Entry/RegisterView.tsx | 45 ++++++++++++++++++- server/services/core/user/user.service.ts | 5 ++- 6 files changed, 62 insertions(+), 9 deletions(-) diff --git a/client/shared/i18n/langs/en-US/translation.json b/client/shared/i18n/langs/en-US/translation.json index 4075ba99..d97a871c 100644 --- a/client/shared/i18n/langs/en-US/translation.json +++ b/client/shared/i18n/langs/en-US/translation.json @@ -381,6 +381,7 @@ "kfaddd61d": "Chat Service", "kfbecf2a7": "Are you sure you want to delete the panel group [{{name}}] and all subordinate panels", "kfc07c0a4": "Here is the beginning of all messages, please feel free to speak up.", + "kfc0ccc0e": "It can be modified at any time in the user settings later", "kfd340bbc": "Manage members", "kfe731dfc": "Action" } diff --git a/client/shared/i18n/langs/zh-CN/translation.json b/client/shared/i18n/langs/zh-CN/translation.json index 55b4aca2..ce963164 100644 --- a/client/shared/i18n/langs/zh-CN/translation.json +++ b/client/shared/i18n/langs/zh-CN/translation.json @@ -381,6 +381,7 @@ "kfaddd61d": "聊天服务", "kfbecf2a7": "确定要删除面板组 【{{name}}】 以及下级的所有面板么", "kfc07c0a4": "这里是所有消息的开始,请畅所欲言。", + "kfc0ccc0e": "后续在用户设置中可以随时修改", "kfd340bbc": "管理成员", "kfe731dfc": "操作" } diff --git a/client/shared/model/user.ts b/client/shared/model/user.ts index c1a1f421..3e86077b 100644 --- a/client/shared/model/user.ts +++ b/client/shared/model/user.ts @@ -142,13 +142,20 @@ export async function verifyEmailWithOTP( * @param email 邮箱 * @param password 密码 */ -export async function registerWithEmail( - email: string, - password: string, - emailOTP?: string -): Promise { +export async function registerWithEmail({ + email, + password, + nickname, + emailOTP, +}: { + email: string; + password: string; + nickname?: string; + emailOTP?: string; +}): Promise { const { data } = await request.post('/api/user/register', { email, + nickname, password, emailOTP, }); diff --git a/client/web/src/components/TipIcon.tsx b/client/web/src/components/TipIcon.tsx index ee201fbe..25b6804f 100644 --- a/client/web/src/components/TipIcon.tsx +++ b/client/web/src/components/TipIcon.tsx @@ -7,7 +7,7 @@ export const TipIcon: React.FC<{ }> = React.memo(({ content }) => { return ( - + ); }); diff --git a/client/web/src/routes/Entry/RegisterView.tsx b/client/web/src/routes/Entry/RegisterView.tsx index c13c900e..b1f1a8d5 100644 --- a/client/web/src/routes/Entry/RegisterView.tsx +++ b/client/web/src/routes/Entry/RegisterView.tsx @@ -7,6 +7,7 @@ import { useAsyncFn, useAsyncRequest, getGlobalConfig, + useWatch, } from 'tailchat-shared'; import React, { useState } from 'react'; import { string } from 'yup'; @@ -19,15 +20,18 @@ import { useNavToView } from './utils'; import { EntryInput } from './components/Input'; import { SecondaryBtn } from './components/SecondaryBtn'; import { PrimaryBtn } from './components/PrimaryBtn'; +import { TipIcon } from '@/components/TipIcon'; /** * 注册视图 */ export const RegisterView: React.FC = React.memo(() => { const [email, setEmail] = useState(''); + const [nickname, setNickname] = useState(''); const [password, setPassword] = useState(''); const [emailOTP, setEmailOTP] = useState(''); const [sendedEmail, setSendedEmail] = useState(false); + const [customNickname, setCustomNickname] = useState(false); const navigate = useNavigate(); const navRedirect = useSearchParam('redirect'); @@ -44,7 +48,12 @@ export const RegisterView: React.FC = React.memo(() => { .max(40, t('密码最长限制40个字符')) .validate(password); - const data = await registerWithEmail(email, password, emailOTP); + const data = await registerWithEmail({ + email, + password, + nickname, + emailOTP, + }); setGlobalUserLoginInfo(data); await setUserJWT(data.token); @@ -54,7 +63,7 @@ export const RegisterView: React.FC = React.memo(() => { } else { navigate('/main'); } - }, [email, password, emailOTP, navRedirect]); + }, [email, nickname, password, emailOTP, navRedirect]); const [{ loading: sendEmailLoading }, handleSendEmail] = useAsyncRequest(async () => { @@ -63,6 +72,12 @@ export const RegisterView: React.FC = React.memo(() => { setSendedEmail(true); }, [email]); + useWatch([email, customNickname], () => { + if (!customNickname) { + setNickname(getEmailAddress(email)); + } + }); + const navToView = useNavToView(); return ( @@ -102,6 +117,28 @@ export const RegisterView: React.FC = React.memo(() => { )} +
+
+ {t('昵称')} + +
+ setNickname(e.target.value)} + /> + + + setCustomNickname((customNickname) => !customNickname) + } + /> +
+
{t('密码')}
{ ); }); RegisterView.displayName = 'RegisterView'; + +function getEmailAddress(email: string) { + return email.split('@')[0]; +} diff --git a/server/services/core/user/user.service.ts b/server/services/core/user/user.service.ts index 534117a9..f50be669 100644 --- a/server/services/core/user/user.service.ts +++ b/server/services/core/user/user.service.ts @@ -84,6 +84,7 @@ class UserService extends TcService { params: { username: { type: 'string', optional: true, max: 40 }, email: { type: 'email', optional: true, max: 40 }, + nickname: { type: 'string', optional: true, max: 40 }, password: { type: 'string', max: 40 }, emailOTP: { type: 'string', optional: true }, }, @@ -395,6 +396,7 @@ class UserService extends TcService { { username?: string; email?: string; + nickname?: string; password: string; emailOTP?: string; }, @@ -411,7 +413,8 @@ class UserService extends TcService { throw new Error(t('服务器不允许新用户注册')); } - const nickname = params.username ?? getEmailAddress(params.email); + const nickname = + params.nickname || (params.username ?? getEmailAddress(params.email)); const discriminator = await this.adapter.model.generateDiscriminator( nickname );