Skip to content

Commit b41aca5

Browse files
authored
Update roles and nickname fields to be optiona (#190)
* Update roles and nickname fields to be optional * Update the department and role fields is optional * fix role judgment * New add user interface * update interface permissions * fix nickname judgment
1 parent eb662e4 commit b41aca5

File tree

5 files changed

+70
-20
lines changed

5 files changed

+70
-20
lines changed

backend/app/api/v1/user.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010
from backend.app.common.response.response_schema import response_base
1111
from backend.app.database.db_mysql import CurrentSession
1212
from backend.app.schemas.user import (
13-
CreateUser,
13+
RegisterUser,
1414
GetAllUserInfo,
1515
ResetPassword,
1616
UpdateUser,
1717
Avatar,
1818
GetCurrentUserInfo,
1919
UpdateUserRole,
20+
AddUser,
2021
)
2122
from backend.app.services.user_service import UserService
2223
from backend.app.utils.serializers import select_to_json
@@ -25,11 +26,17 @@
2526

2627

2728
@router.post('/register', summary='用户注册')
28-
async def user_register(obj: CreateUser):
29+
async def user_register(obj: RegisterUser):
2930
await UserService.register(obj=obj)
3031
return await response_base.success()
3132

3233

34+
@router.post('/add', summary='添加用户', dependencies=[DependsRBAC])
35+
async def add_user(obj: AddUser):
36+
await UserService.add(obj=obj)
37+
return await response_base.success()
38+
39+
3340
@router.post('/password/reset', summary='密码重置', dependencies=[DependsJwtAuth])
3441
async def password_reset(request: Request, obj: ResetPassword):
3542
count = await UserService.pwd_reset(request=request, obj=obj)

backend/app/crud/crud_user.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,37 @@
1212
from backend.app.common import jwt
1313
from backend.app.crud.base import CRUDBase
1414
from backend.app.models import User, Role
15-
from backend.app.schemas.user import CreateUser, UpdateUser, Avatar, UpdateUserRole
15+
from backend.app.schemas.user import RegisterUser, UpdateUser, Avatar, UpdateUserRole, AddUser
1616

1717

18-
class CRUDUser(CRUDBase[User, CreateUser, UpdateUser]):
18+
class CRUDUser(CRUDBase[User, RegisterUser, UpdateUser]):
1919
async def get(self, db: AsyncSession, user_id: int) -> User | None:
2020
return await self.get_(db, pk=user_id)
2121

2222
async def get_by_username(self, db: AsyncSession, username: str) -> User | None:
2323
user = await db.execute(select(self.model).where(self.model.username == username))
2424
return user.scalars().first()
2525

26+
async def get_by_nickname(self, db: AsyncSession, nickname: str) -> User | None:
27+
user = await db.execute(select(self.model).where(self.model.nickname == nickname))
28+
return user.scalars().first()
29+
2630
async def update_login_time(self, db: AsyncSession, username: str, login_time: datetime) -> int:
2731
user = await db.execute(
2832
update(self.model).where(self.model.username == username).values(last_login_time=login_time)
2933
)
3034
await db.commit()
3135
return user.rowcount
3236

33-
async def create(self, db: AsyncSession, obj: CreateUser) -> NoReturn:
37+
async def create(self, db: AsyncSession, obj: RegisterUser) -> NoReturn:
38+
salt = text_captcha(5)
39+
obj.password = await jwt.get_hash_password(obj.password + salt)
40+
dict_obj = obj.dict()
41+
dict_obj.update({'salt': salt})
42+
new_user = self.model(**dict_obj)
43+
db.add(new_user)
44+
45+
async def add(self, db: AsyncSession, obj: AddUser) -> NoReturn:
3446
salt = text_captcha(5)
3547
obj.password = await jwt.get_hash_password(obj.password + salt)
3648
dict_obj = obj.dict(exclude={'roles'})

backend/app/schemas/user.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3+
import random
34
from datetime import datetime
45

56
from email_validator import validate_email, EmailNotValidError
@@ -20,10 +21,23 @@ class AuthLogin(Auth):
2021
captcha: str
2122

2223

23-
class CreateUser(Auth):
24-
dept_id: int | None = None
24+
class RegisterUser(Auth):
25+
nickname: str = Field(f'用户{random.randrange(10000, 99999)}')
26+
email: str = Field(..., example='user@example.com')
27+
28+
@validator('email')
29+
def email_validate(cls, v):
30+
try:
31+
validate_email(v, check_deliverability=False).email
32+
except EmailNotValidError:
33+
raise ValueError('邮箱格式错误')
34+
return v
35+
36+
37+
class AddUser(Auth):
38+
dept_id: int
2539
roles: list[int]
26-
nickname: str
40+
nickname: str = Field(f'用户{random.randrange(10000, 99999)}')
2741
email: str = Field(..., example='user@example.com')
2842

2943
@validator('email')

backend/app/services/menu_service.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ async def get_user_menu_tree(*, request: Request):
4141
async with async_db_session() as db:
4242
roles = request.user.roles
4343
menu_ids = []
44-
for role in roles:
45-
menu_ids.extend([menu.id for menu in role.menus])
44+
if roles:
45+
for role in roles:
46+
menu_ids.extend([menu.id for menu in role.menus])
4647
menu_select = await MenuDao.get_role_menus(db, request.user.is_superuser, menu_ids)
4748
menu_tree = await get_tree_data(menu_select)
4849
return menu_tree

backend/app/services/user_service.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3-
from typing import NoReturn
4-
53
from fastapi import Request
64
from sqlalchemy import Select
75

@@ -15,27 +13,44 @@
1513
from backend.app.crud.crud_user import UserDao
1614
from backend.app.database.db_mysql import async_db_session
1715
from backend.app.models import User
18-
from backend.app.schemas.user import CreateUser, ResetPassword, UpdateUser, Avatar, UpdateUserRole
16+
from backend.app.schemas.user import RegisterUser, ResetPassword, UpdateUser, Avatar, UpdateUserRole, AddUser
1917

2018

2119
class UserService:
2220
@staticmethod
23-
async def register(*, obj: CreateUser) -> NoReturn:
21+
async def register(*, obj: RegisterUser) -> None:
2422
async with async_db_session.begin() as db:
2523
username = await UserDao.get_by_username(db, obj.username)
2624
if username:
2725
raise errors.ForbiddenError(msg='该用户名已注册')
26+
nickname = await UserDao.get_by_nickname(db, obj.nickname)
27+
if nickname:
28+
raise errors.ForbiddenError(msg='该昵称已注册')
2829
email = await UserDao.check_email(db, obj.email)
2930
if email:
3031
raise errors.ForbiddenError(msg='该邮箱已注册')
32+
await UserDao.create(db, obj)
33+
34+
@staticmethod
35+
async def add(*, obj: AddUser) -> None:
36+
async with async_db_session.begin() as db:
37+
username = await UserDao.get_by_username(db, obj.username)
38+
if username:
39+
raise errors.ForbiddenError(msg='该用户名已注册')
40+
nickname = await UserDao.get_by_nickname(db, obj.nickname)
41+
if nickname:
42+
raise errors.ForbiddenError(msg='该昵称已注册')
3143
dept = await DeptDao.get(db, obj.dept_id)
3244
if not dept:
3345
raise errors.NotFoundError(msg='部门不存在')
3446
for role_id in obj.roles:
3547
role = await RoleDao.get(db, role_id)
3648
if not role:
3749
raise errors.NotFoundError(msg='角色不存在')
38-
await UserDao.create(db, obj)
50+
email = await UserDao.check_email(db, obj.email)
51+
if email:
52+
raise errors.ForbiddenError(msg='该邮箱已注册')
53+
await UserDao.add(db, obj)
3954

4055
@staticmethod
4156
async def pwd_reset(*, request: Request, obj: ResetPassword) -> int:
@@ -72,16 +87,17 @@ async def update(*, request: Request, username: str, obj: UpdateUser) -> int:
7287
if not input_user:
7388
raise errors.NotFoundError(msg='用户不存在')
7489
if input_user.username != obj.username:
75-
username = await UserDao.get_by_username(db, obj.username)
76-
if username:
90+
_username = await UserDao.get_by_username(db, obj.username)
91+
if _username:
7792
raise errors.ForbiddenError(msg='该用户名已存在')
93+
if input_user.nickname != obj.nickname:
94+
nickname = await UserDao.get_by_nickname(db, obj.nickname)
95+
if nickname:
96+
raise errors.ForbiddenError(msg='改昵称已存在')
7897
if input_user.email != obj.email:
7998
email = await UserDao.check_email(db, obj.email)
8099
if email:
81100
raise errors.ForbiddenError(msg='该邮箱已注册')
82-
dept = await DeptDao.get(db, obj.dept_id)
83-
if not dept:
84-
raise errors.NotFoundError(msg='部门不存在')
85101
count = await UserDao.update_userinfo(db, input_user, obj)
86102
return count
87103

0 commit comments

Comments
 (0)