Skip to content

Commit 8adcb49

Browse files
committed
Optimize more
1 parent 233241c commit 8adcb49

File tree

8 files changed

+161
-115
lines changed

8 files changed

+161
-115
lines changed

backend/app/admin/crud/crud_user.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,7 @@ async def get_list(
193193
)
194194
.order_by(desc(self.model.join_time))
195195
)
196-
197-
# 构建过滤条件
196+
198197
filters = []
199198
if dept:
200199
filters.append(self.model.dept_id == dept)
@@ -204,8 +203,7 @@ async def get_list(
204203
filters.append(self.model.phone.like(f'%{phone}%'))
205204
if status is not None:
206205
filters.append(self.model.status == status)
207-
208-
# 应用过滤条件
206+
209207
if filters:
210208
stmt = stmt.where(and_(*filters))
211209

@@ -257,44 +255,44 @@ async def get_multi_login(self, db: AsyncSession, user_id: int) -> bool:
257255

258256
async def set_super(self, db: AsyncSession, user_id: int, is_super: bool) -> int:
259257
"""
260-
设置用户的超级管理员状态
258+
设置用户超级管理员状态
261259
262260
:param db: 数据库会话
263261
:param user_id: 用户 ID
264-
:param is_super: 是否为超级管理员
262+
:param is_super: 是否超级管理员
265263
:return:
266264
"""
267265
return await self.update_model(db, user_id, {'is_superuser': is_super})
268266

269267
async def set_staff(self, db: AsyncSession, user_id: int, is_staff: bool) -> int:
270268
"""
271-
设置用户的后台登录权限
269+
设置用户后台登录状态
272270
273271
:param db: 数据库会话
274272
:param user_id: 用户 ID
275-
:param is_staff: 是否允许登录后台
273+
:param is_staff: 是否可登录后台
276274
:return:
277275
"""
278276
return await self.update_model(db, user_id, {'is_staff': is_staff})
279277

280-
async def set_status(self, db: AsyncSession, user_id: int, status: bool) -> int:
278+
async def set_status(self, db: AsyncSession, user_id: int, status: int) -> int:
281279
"""
282-
设置用户的启用状态
280+
设置用户状态
283281
284282
:param db: 数据库会话
285283
:param user_id: 用户 ID
286-
:param status: 是否启用用户
284+
:param status: 状态
287285
:return:
288286
"""
289287
return await self.update_model(db, user_id, {'status': status})
290288

291289
async def set_multi_login(self, db: AsyncSession, user_id: int, multi_login: bool) -> int:
292290
"""
293-
设置用户的多点登录权限
291+
设置用户多端登录状态
294292
295293
:param db: 数据库会话
296294
:param user_id: 用户 ID
297-
:param multi_login: 是否允许多点登录
295+
:param multi_login: 是否允许多端登录
298296
:return:
299297
"""
300298
return await self.update_model(db, user_id, {'is_multi_login': multi_login})
@@ -303,7 +301,7 @@ async def get_with_relation(
303301
self, db: AsyncSession, *, user_id: int | None = None, username: str | None = None
304302
) -> User | None:
305303
"""
306-
获取用户及关联数据
304+
获取用户关联信息
307305
308306
:param db: 数据库会话
309307
:param user_id: 用户 ID
@@ -317,12 +315,18 @@ async def get_with_relation(
317315
selectinload(Role.rules),
318316
),
319317
)
318+
320319
filters = []
321320
if user_id:
322321
filters.append(self.model.id == user_id)
323322
if username:
324323
filters.append(self.model.username == username)
325-
user = await db.execute(stmt.where(*filters))
324+
325+
if filters:
326+
stmt = stmt.where(and_(*filters))
327+
328+
user = await db.execute(stmt)
329+
326330
return user.scalars().first()
327331

328332

backend/app/admin/model/user.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from datetime import datetime
66
from typing import TYPE_CHECKING
77

8-
from sqlalchemy import VARBINARY, Boolean, DateTime, ForeignKey, String
8+
from sqlalchemy import VARBINARY, Boolean, DateTime, ForeignKey, String, Index
99
from sqlalchemy.dialects.postgresql import BYTEA, INTEGER
1010
from sqlalchemy.orm import Mapped, mapped_column, relationship
1111

@@ -38,7 +38,7 @@ class User(Base):
3838
is_staff: Mapped[bool] = mapped_column(
3939
Boolean().with_variant(INTEGER, 'postgresql'), default=False, comment='后台管理登陆(0否 1是)'
4040
)
41-
status: Mapped[int] = mapped_column(default=1, comment='用户账号状态(0停用 1正常)')
41+
status: Mapped[int] = mapped_column(default=1, index=True, comment='用户账号状态(0停用 1正常)')
4242
is_multi_login: Mapped[bool] = mapped_column(
4343
Boolean().with_variant(INTEGER, 'postgresql'), default=False, comment='是否重复登陆(0否 1是)'
4444
)

backend/app/admin/service/user_service.py

Lines changed: 68 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,11 @@ async def pwd_reset(*, request: Request, obj: ResetPasswordParam) -> int:
9393
"""
9494
async with async_db_session.begin() as db:
9595
user = await user_dao.get(db, request.user.id)
96+
if not user:
97+
raise errors.NotFoundError(msg='用户不存在')
9698
if not password_verify(obj.old_password, user.password):
9799
raise errors.ForbiddenError(msg='原密码错误')
98-
np1 = obj.new_password
99-
np2 = obj.confirm_password
100-
if np1 != np2:
100+
if obj.new_password != obj.confirm_password:
101101
raise errors.ForbiddenError(msg='密码输入不一致')
102102
new_pwd = get_hash_password(obj.new_password, user.salt)
103103
count = await user_dao.reset_password(db, request.user.id, new_pwd)
@@ -135,9 +135,8 @@ async def update(*, request: Request, username: str, obj: UpdateUserParam) -> in
135135
:return:
136136
"""
137137
async with async_db_session.begin() as db:
138-
if not request.user.is_superuser:
139-
if request.user.username != username:
140-
raise errors.ForbiddenError(msg='你只能修改自己的信息')
138+
if not request.user.is_superuser and request.user.username != username:
139+
raise errors.ForbiddenError(msg='你只能修改自己的信息')
141140
input_user = await user_dao.get_with_relation(db, username=username)
142141
if not input_user:
143142
raise errors.NotFoundError(msg='用户不存在')
@@ -168,9 +167,8 @@ async def update_roles(*, request: Request, username: str, obj: UpdateUserRolePa
168167
:return:
169168
"""
170169
async with async_db_session.begin() as db:
171-
if not request.user.is_superuser:
172-
if request.user.username != username:
173-
raise errors.AuthorizationError
170+
if not request.user.is_superuser and request.user.username != username:
171+
raise errors.AuthorizationError
174172
input_user = await user_dao.get_with_relation(db, username=username)
175173
if not input_user:
176174
raise errors.NotFoundError(msg='用户不存在')
@@ -192,9 +190,8 @@ async def update_avatar(*, request: Request, username: str, avatar: AvatarParam)
192190
:return:
193191
"""
194192
async with async_db_session.begin() as db:
195-
if not request.user.is_superuser:
196-
if request.user.username != username:
197-
raise errors.AuthorizationError
193+
if not request.user.is_superuser and request.user.username != username:
194+
raise errors.AuthorizationError
198195
input_user = await user_dao.get_by_username(db, username)
199196
if not input_user:
200197
raise errors.NotFoundError(msg='用户不存在')
@@ -226,15 +223,15 @@ async def update_permission(*, request: Request, pk: int) -> int:
226223
"""
227224
async with async_db_session.begin() as db:
228225
superuser_verify(request)
229-
if not await user_dao.get(db, pk):
226+
user = await user_dao.get(db, pk)
227+
if not user:
230228
raise errors.NotFoundError(msg='用户不存在')
231-
else:
232-
if pk == request.user.id:
233-
raise errors.ForbiddenError(msg='非法操作')
234-
super_status = await user_dao.get_super(db, pk)
235-
count = await user_dao.set_super(db, pk, False if super_status else True)
236-
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
237-
return count
229+
if pk == request.user.id:
230+
raise errors.ForbiddenError(msg='非法操作')
231+
super_status = await user_dao.get_super(db, pk)
232+
count = await user_dao.set_super(db, pk, not super_status)
233+
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
234+
return count
238235

239236
@staticmethod
240237
async def update_staff(*, request: Request, pk: int) -> int:
@@ -247,15 +244,15 @@ async def update_staff(*, request: Request, pk: int) -> int:
247244
"""
248245
async with async_db_session.begin() as db:
249246
superuser_verify(request)
250-
if not await user_dao.get(db, pk):
247+
user = await user_dao.get(db, pk)
248+
if not user:
251249
raise errors.NotFoundError(msg='用户不存在')
252-
else:
253-
if pk == request.user.id:
254-
raise errors.ForbiddenError(msg='非法操作')
255-
staff_status = await user_dao.get_staff(db, pk)
256-
count = await user_dao.set_staff(db, pk, False if staff_status else True)
257-
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
258-
return count
250+
if pk == request.user.id:
251+
raise errors.ForbiddenError(msg='非法操作')
252+
staff_status = await user_dao.get_staff(db, pk)
253+
count = await user_dao.set_staff(db, pk, not staff_status)
254+
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
255+
return count
259256

260257
@staticmethod
261258
async def update_status(*, request: Request, pk: int) -> int:
@@ -268,15 +265,15 @@ async def update_status(*, request: Request, pk: int) -> int:
268265
"""
269266
async with async_db_session.begin() as db:
270267
superuser_verify(request)
271-
if not await user_dao.get(db, pk):
268+
user = await user_dao.get(db, pk)
269+
if not user:
272270
raise errors.NotFoundError(msg='用户不存在')
273-
else:
274-
if pk == request.user.id:
275-
raise errors.ForbiddenError(msg='非法操作')
276-
status = await user_dao.get_status(db, pk)
277-
count = await user_dao.set_status(db, pk, False if status else True)
278-
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
279-
return count
271+
if pk == request.user.id:
272+
raise errors.ForbiddenError(msg='非法操作')
273+
status = await user_dao.get_status(db, pk)
274+
count = await user_dao.set_status(db, pk, 0 if status == 1 else 1)
275+
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
276+
return count
280277

281278
@staticmethod
282279
async def update_multi_login(*, request: Request, pk: int) -> int:
@@ -289,37 +286,38 @@ async def update_multi_login(*, request: Request, pk: int) -> int:
289286
"""
290287
async with async_db_session.begin() as db:
291288
superuser_verify(request)
292-
if not await user_dao.get(db, pk):
289+
user = await user_dao.get(db, pk)
290+
if not user:
293291
raise errors.NotFoundError(msg='用户不存在')
292+
user_id = request.user.id
293+
multi_login = await user_dao.get_multi_login(db, pk) if pk != user_id else request.user.is_multi_login
294+
count = await user_dao.set_multi_login(db, pk, not multi_login)
295+
# 删除当前用户缓存
296+
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
297+
token = get_token(request)
298+
token_payload = jwt_decode(token)
299+
latest_multi_login = await user_dao.get_multi_login(db, pk)
300+
# 超级用户修改自身时,除当前 token 外,其他 token 失效
301+
if pk == user_id:
302+
if not latest_multi_login:
303+
key_prefix = f'{settings.TOKEN_REDIS_PREFIX}:{pk}'
304+
await redis_client.delete_prefix(
305+
key_prefix, exclude=f'{key_prefix}:{token_payload.session_uuid}'
306+
)
307+
refresh_token = request.cookies.get(settings.COOKIE_REFRESH_TOKEN_KEY)
308+
if refresh_token:
309+
key_prefix = f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{pk}'
310+
await redis_client.delete_prefix(key_prefix, exclude=f'{key_prefix}:{refresh_token}')
311+
# 超级用户修改他人时,其他 token 将全部失效
294312
else:
295-
user_id = request.user.id
296-
multi_login = await user_dao.get_multi_login(db, pk) if pk != user_id else request.user.is_multi_login
297-
count = await user_dao.set_multi_login(db, pk, False if multi_login else True)
298-
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
299-
token = get_token(request)
300-
token_payload = jwt_decode(token)
301-
latest_multi_login = await user_dao.get_multi_login(db, pk)
302-
# 超级用户修改自身时,除当前token外,其他token失效
303-
if pk == user_id:
304-
if not latest_multi_login:
305-
key_prefix = f'{settings.TOKEN_REDIS_PREFIX}:{pk}'
306-
await redis_client.delete_prefix(
307-
key_prefix, exclude=f'{key_prefix}:{token_payload.session_uuid}'
308-
)
309-
refresh_token = request.cookies.get(settings.COOKIE_REFRESH_TOKEN_KEY)
310-
if refresh_token:
311-
key_prefix = f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{pk}'
312-
await redis_client.delete_prefix(key_prefix, exclude=f'{key_prefix}:{refresh_token}')
313-
# 超级用户修改他人时,其他token将全部失效
314-
else:
315-
if not latest_multi_login:
316-
key_prefix = [f'{settings.TOKEN_REDIS_PREFIX}:{pk}']
317-
refresh_token = request.cookies.get(settings.COOKIE_REFRESH_TOKEN_KEY)
318-
if refresh_token:
319-
key_prefix.append(f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{pk}')
320-
for prefix in key_prefix:
321-
await redis_client.delete_prefix(prefix)
322-
return count
313+
if not latest_multi_login:
314+
key_prefix = [f'{settings.TOKEN_REDIS_PREFIX}:{pk}']
315+
refresh_token = request.cookies.get(settings.COOKIE_REFRESH_TOKEN_KEY)
316+
if refresh_token:
317+
key_prefix.append(f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{pk}')
318+
for prefix in key_prefix:
319+
await redis_client.delete_prefix(prefix)
320+
return count
323321

324322
@staticmethod
325323
async def delete(*, username: str) -> int:
@@ -330,13 +328,13 @@ async def delete(*, username: str) -> int:
330328
:return:
331329
"""
332330
async with async_db_session.begin() as db:
333-
input_user = await user_dao.get_by_username(db, username)
334-
if not input_user:
331+
user = await user_dao.get_by_username(db, username)
332+
if not user:
335333
raise errors.NotFoundError(msg='用户不存在')
336-
count = await user_dao.delete(db, input_user.id)
334+
count = await user_dao.delete(db, user.id)
337335
key_prefix = [
338-
f'{settings.TOKEN_REDIS_PREFIX}:{input_user.id}',
339-
f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{input_user.id}',
336+
f'{settings.TOKEN_REDIS_PREFIX}:{user.id}',
337+
f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{user.id}',
340338
]
341339
for key in key_prefix:
342340
await redis_client.delete_prefix(key)

0 commit comments

Comments
 (0)