feat: 添加用户注销,用户更新手机号,更新邮箱,更新密码功能

This commit is contained in:
皓月归尘 2025-02-26 17:07:16 +08:00
parent 8edb6badc4
commit f6af4eace8
4 changed files with 138 additions and 5 deletions

View File

@ -149,7 +149,7 @@ class Log:
# else: # else:
session_id = request.app.state.session_id session_id = request.app.state.session_id
status = 1 if request.app.state.login_status else 0 status = 1 if request.app.state.login_status else 0
current_user = await User.get_or_none(username=payload.get("username"),del_flag=1) current_user = await User.get_or_none(username=payload.get("username"), del_flag=1)
await LoginLog.create( await LoginLog.create(
user_id=current_user.id, user_id=current_user.id,
login_ip=host, login_ip=host,

View File

@ -18,7 +18,7 @@ from config.constant import BusinessType
from config.constant import RedisKeyConfig from config.constant import RedisKeyConfig
from controller.login import CustomOAuth2PasswordRequestForm, LoginController from controller.login import CustomOAuth2PasswordRequestForm, LoginController
from controller.query import QueryController from controller.query import QueryController
from models import Department, User, Role, UserRole from models import Department, User, Role, UserRole, LoginLog, OperationLog, QueryCodeLog, QueryCode
from schemas.common import BaseResponse from schemas.common import BaseResponse
from schemas.login import LoginParams, GetUserInfoResponse, LoginResponse, GetCaptchaResponse, GetEmailCodeParams, \ from schemas.login import LoginParams, GetUserInfoResponse, LoginResponse, GetCaptchaResponse, GetEmailCodeParams, \
ResetPasswordParams ResetPasswordParams
@ -271,3 +271,36 @@ async def logout(request: Request, status: bool = Depends(LoginController.logout
if status: if status:
return Response.success(data="退出成功!") return Response.success(data="退出成功!")
return Response.error(data="登出失败!") return Response.error(data="登出失败!")
@loginAPI.post("/unsubscribe", response_class=JSONResponse, response_model=BaseResponse, summary="用户注销")
@Log(title="用户注销", business_type=BusinessType.FORCE)
async def unsubscribe(request: Request, current_user: dict = Depends(LoginController.get_current_user)):
id = current_user.get("id")
session_id = current_user.get("session_id")
if user := await User.get_or_none(id=id, del_flag=1):
user.del_flag = 0
await user.save()
redis_token = await request.app.state.redis.get(f'{RedisKeyConfig.ACCESS_TOKEN.key}:{session_id}')
if redis_token:
await request.app.state.redis.delete(f'{RedisKeyConfig.ACCESS_TOKEN.key}:{session_id}')
# 移除用户角色
await UserRole.filter(user_id=user.id, del_flag=1).update(del_flag=0)
# 移除用户登录日志
await LoginLog.filter(user_id=user.id, del_flag=1).update(del_flag=0)
# 移除用户操作日志
await OperationLog.filter(user_id=user.id, del_flag=1).update(del_flag=0)
# 移除编码查询日志
logs = await QueryCodeLog.filter(operator__id=user.id, del_flag=1).values("id")
for log in logs:
await QueryCode.filter(session_id=log["id"], del_flag=1).update(del_flag=0)
await QueryCodeLog.filter(id=log["id"], del_flag=1).update(del_flag=0)
# 更新用户信息缓存
if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:{id}'):
await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:{id}')
# 更新用户路由缓存
if await request.app.state.redis.get(f'{RedisKeyConfig.USER_ROUTES.key}:{id}'):
await request.app.state.redis.delete(f'{RedisKeyConfig.USER_ROUTES.key}:{id}')
return Response.success(data="注销成功!")
else:
return Response.error(data="注销失败!")

View File

@ -10,7 +10,7 @@ import os
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Optional from typing import Optional
from fastapi import APIRouter, Depends, Path, Query, UploadFile, File, Request from fastapi import APIRouter, Depends, Path, Query, UploadFile, File, Request, Form
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from annotation.auth import Auth from annotation.auth import Auth
@ -29,7 +29,7 @@ from schemas.department import GetDepartmentListResponse
from schemas.file import UploadFileResponse from schemas.file import UploadFileResponse
from schemas.user import AddUserParams, GetUserListResponse, GetUserInfoResponse, UpdateUserParams, \ from schemas.user import AddUserParams, GetUserListResponse, GetUserInfoResponse, UpdateUserParams, \
AddUserRoleParams, GetUserRoleInfoResponse, UpdateUserRoleParams, GetUserPermissionListResponse, \ AddUserRoleParams, GetUserRoleInfoResponse, UpdateUserRoleParams, GetUserPermissionListResponse, \
ResetPasswordParams, GetUserStatisticsResponse ResetPasswordParams, GetUserStatisticsResponse, UpdateBaseUserInfoParams
from utils.common import filterKeyValues from utils.common import filterKeyValues
from utils.password import Password from utils.password import Password
from utils.response import Response from utils.response import Response
@ -438,6 +438,84 @@ async def reset_user_password(request: Request, params: ResetPasswordParams, id:
return Response.failure(msg="用户不存在!") return Response.failure(msg="用户不存在!")
@userAPI.put("/updateBaseUserInfo", response_model=BaseResponse, response_class=JSONResponse,
summary="更新基础个人信息")
@userAPI.post("/updateBaseUserInfo", response_model=BaseResponse, response_class=JSONResponse,
summary="更新基础个人信息")
@Log(title="更新基础个人信息", business_type=BusinessType.UPDATE)
async def update_base_userinfo(params: UpdateBaseUserInfoParams, request: Request,
current_user: dict = Depends(LoginController.get_current_user)):
user = await User.get_or_none(id=current_user.get("id"), del_flag=1)
if user:
user.nickname = params.name
user.gender = params.gender
await user.save()
if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:{user.id}'):
await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:{user.id}')
return Response.success(msg="更新成功!")
return Response.error(msg="更新失败!")
@userAPI.put("/updatePassword", response_class=JSONResponse, response_model=BaseResponse, summary="用户更新密码")
@userAPI.post("/updatePassword", response_class=JSONResponse, response_model=BaseResponse, summary="用户更新密码")
@Log(title="用户更新密码", business_type=BusinessType.UPDATE)
async def update_user_password(request: Request, oldPassword: str = Form(description="用户旧密码"),
newPassword: str = Form(description="用户新密码"),
current_user: dict = Depends(LoginController.get_current_user)):
if user := await User.get_or_none(id=current_user.get("id"), del_flag=1):
password = await Password.get_password_hash(oldPassword)
if user.password != password:
return Response.error(msg="旧密码错误!")
newPassword = await Password.get_password_hash(newPassword)
user.password = newPassword
await user.save()
if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:{user.id}'):
await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:{user.id}')
return Response.success(msg="更新成功!")
return Response.error(msg="更新失败!")
@userAPI.put("/updatePhone", response_class=JSONResponse, response_model=BaseResponse, summary="用户更新手机号")
@userAPI.post("/updatePhone", response_class=JSONResponse, response_model=BaseResponse, summary="用户更新手机号")
@Log(title="用户更新手机号", business_type=BusinessType.UPDATE)
async def update_user_phone(request: Request, password: str = Form(description="用户密码"),
phone: str = Form(description="用户手机号"),
current_user: dict = Depends(LoginController.get_current_user)):
if user := await User.get_or_none(id=current_user.get("id"), del_flag=1):
password = await Password.get_password_hash(password)
if user.password != password:
return Response.error("更改失败,请正确输入旧密码")
phoneStatus = await User.filter(phone=phone,del_flag=1).count()
if phoneStatus:
return Response.error( f"更改失败,手机号:{phone}已绑定其他账号!")
user.phone=phone
await user.save()
if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:{user.id}'):
await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:{user.id}')
return Response.success(msg="更新成功!")
return Response.error(msg="更新失败!")
@userAPI.put("/updateEmail", response_class=JSONResponse, response_model=BaseResponse, summary="用户更新邮箱")
@userAPI.post("/updateEmail", response_class=JSONResponse, response_model=BaseResponse, summary="用户更新邮箱")
@Log(title="用户更新邮箱", business_type=BusinessType.UPDATE)
async def update_user_email(request: Request, password: str = Form(description="用户密码"),
email: str = Form(description="用户邮箱"),current_user: dict = Depends(LoginController.get_current_user)):
if user:=await User.get_or_none(id=current_user.get("id"),del_flag=1):
password = await Password.get_password_hash(password)
if user.password != password:
return Response.error("更改失败,请正确输入旧密码")
emailStatus = await User.filter(email=email,del_flag=1).count()
if emailStatus:
return Response.error(f"更改失败,邮箱:{email}已绑定其他账号!")
user.email=email
await user.save()
if await request.app.state.redis.get(f'{RedisKeyConfig.USER_INFO.key}:{user.id}'):
await request.app.state.redis.delete(f'{RedisKeyConfig.USER_INFO.key}:{user.id}')
return Response.success(msg="更新成功!")
return Response.error(msg="更新失败!")
@userAPI.get("/statistics", response_model=GetUserStatisticsResponse, response_class=JSONResponse, @userAPI.get("/statistics", response_model=GetUserStatisticsResponse, response_class=JSONResponse,
summary="获取用户查询统计") summary="获取用户查询统计")
@Log(title="获取用户查询统计", business_type=BusinessType.SELECT) @Log(title="获取用户查询统计", business_type=BusinessType.SELECT)

View File

@ -6,6 +6,7 @@
# @Software : PyCharm # @Software : PyCharm
# @Comment : 本程序 # @Comment : 本程序
from datetime import datetime from datetime import datetime
from enum import IntEnum
from typing import Optional, List from typing import Optional, List
from uuid import UUID from uuid import UUID
@ -15,6 +16,11 @@ from pydantic_validation_decorator import Xss, NotBlank, Size, Network
from schemas.common import BaseResponse, ListQueryResult from schemas.common import BaseResponse, ListQueryResult
class Gender(IntEnum):
MAN = 0
WOMAN = 1
class UserBase(BaseModel): class UserBase(BaseModel):
""" """
用户表基础模型 用户表基础模型
@ -387,3 +393,19 @@ class GetUserStatisticsResponse(BaseResponse):
获取用户统计信息响应模型 获取用户统计信息响应模型
""" """
data: GetUserStatisticsResult = Field(default=None, description="响应数据") data: GetUserStatisticsResult = Field(default=None, description="响应数据")
class UpdateBaseUserInfoParams(BaseModel):
"""修改基础信息参数"""
name: str
"""姓名"""
gender: Gender
"""性别"""
class Config:
json_schema_extra = {
"example": {
"name": "张三",
"gender": 1,
}
}