perf: 同步近期修改
This commit is contained in:
@@ -147,18 +147,18 @@ class Log:
|
||||
# if request_from_swagger or request_from_redoc:
|
||||
# pass
|
||||
# else:
|
||||
if status == 1:
|
||||
session_id = request.app.state.session_id
|
||||
current_user = await User.get_or_none(username=payload.get("username"))
|
||||
await LoginLog.create(
|
||||
user_id=current_user.id,
|
||||
login_ip=host,
|
||||
login_location=location,
|
||||
browser=browser,
|
||||
os=system_os,
|
||||
status=status,
|
||||
session_id=session_id
|
||||
)
|
||||
session_id = request.app.state.session_id
|
||||
status = 1 if request.app.state.login_status else 0
|
||||
current_user = await User.get_or_none(username=payload.get("username"))
|
||||
await LoginLog.create(
|
||||
user_id=current_user.id,
|
||||
login_ip=host,
|
||||
login_location=location,
|
||||
browser=browser,
|
||||
os=system_os,
|
||||
status=status,
|
||||
session_id=session_id
|
||||
)
|
||||
else:
|
||||
if "image" in request.headers.get("Accept", ""):
|
||||
pass
|
||||
|
||||
@@ -74,7 +74,7 @@ async def delete_department_recursive(department_id: str):
|
||||
:return:
|
||||
"""
|
||||
await Department.filter(id=department_id).delete()
|
||||
sub_departments = await Department.filter(parentId=department_id).all()
|
||||
sub_departments = await Department.filter(parent_id=department_id).all()
|
||||
for sub_department in sub_departments:
|
||||
await delete_department_recursive(sub_department.id)
|
||||
return True
|
||||
|
||||
@@ -33,7 +33,7 @@ async def get_login_log(request: Request,
|
||||
):
|
||||
online_user_list = await LoginController.get_online_user(request)
|
||||
online_user_list = list(
|
||||
filter(lambda x: x["user_id"] == current_user.get("id"), jsonable_encoder(online_user_list, )))
|
||||
filter(lambda x: x["user_id"] == current_user.get("id"), jsonable_encoder(online_user_list)))
|
||||
user_id = current_user.get("id")
|
||||
result = await LoginLog.filter(user_id=user_id, del_flag=1).offset((page - 1) * pageSize).limit(pageSize).values(
|
||||
id="id",
|
||||
|
||||
@@ -38,6 +38,8 @@ async def login(
|
||||
request: Request,
|
||||
params: CustomOAuth2PasswordRequestForm = Depends()
|
||||
):
|
||||
request.app.state.session_id = None
|
||||
request.app.state.login_status = False
|
||||
user = LoginParams(
|
||||
username=params.username,
|
||||
password=params.password,
|
||||
@@ -47,7 +49,7 @@ async def login(
|
||||
)
|
||||
captcha_enabled = (
|
||||
True
|
||||
if await request.app.state.redis.get(f'{RedisKeyConfig.SYSTEM_CONFIG.key}:account.captcha_enabled')
|
||||
if await request.app.state.redis.get(f'{RedisKeyConfig.SYSTEM_CONFIG.key}:account_captcha_enabled')
|
||||
== 'true'
|
||||
else False
|
||||
)
|
||||
@@ -75,6 +77,7 @@ async def login(
|
||||
ex=timedelta(minutes=5),
|
||||
)
|
||||
request.app.state.session_id = result["session_id"]
|
||||
request.app.state.login_status = True
|
||||
if request_from_swagger or request_from_redoc:
|
||||
return {'access_token': result["accessToken"], 'token_type': 'Bearer',
|
||||
"expires_in": result["expiresIn"] * 60}
|
||||
@@ -83,6 +86,7 @@ async def login(
|
||||
result.pop("session_id")
|
||||
result.pop("userInfo")
|
||||
return Response.success(data=result)
|
||||
request.app.state.login_status = False
|
||||
return Response.failure(msg="登录失败,账号或密码错误!")
|
||||
|
||||
|
||||
@@ -90,7 +94,7 @@ async def login(
|
||||
async def register(request: Request, params: RegisterUserParams):
|
||||
register_enabled = (
|
||||
True
|
||||
if await request.app.state.redis.get(f'{RedisKeyConfig.SYSTEM_CONFIG.key}:account_register_enabled')
|
||||
if await request.app.state.redis.get(f'{RedisKeyConfig.SYSTEM_CONFIG.key}:register_enabled')
|
||||
== 'true'
|
||||
else False
|
||||
)
|
||||
|
||||
104
api/user.py
104
api/user.py
@@ -5,8 +5,9 @@
|
||||
# @File : user.py
|
||||
# @Software : PyCharm
|
||||
# @Comment : 本程序
|
||||
import calendar
|
||||
import os
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, Depends, Path, Query, UploadFile, File, Request
|
||||
@@ -20,13 +21,14 @@ from controller.login import LoginController
|
||||
from controller.query import QueryController
|
||||
from exceptions.exception import ModelValidatorException
|
||||
from models import File as FileModel
|
||||
from models import Role, Department
|
||||
from models import Role, Department, QueryCode
|
||||
from models.user import User, UserRole
|
||||
from schemas.common import BaseResponse
|
||||
from schemas.department import GetDepartmentListResponse
|
||||
from schemas.file import UploadFileResponse
|
||||
from schemas.user import AddUserParams, GetUserListResponse, GetUserInfoResponse, UpdateUserParams, \
|
||||
AddUserRoleParams, GetUserRoleInfoResponse, UpdateUserRoleParams, GetUserPermissionListResponse, ResetPasswordParams
|
||||
AddUserRoleParams, GetUserRoleInfoResponse, UpdateUserRoleParams, GetUserPermissionListResponse, \
|
||||
ResetPasswordParams, GetUserStatisticsResponse
|
||||
from utils.common import filterKeyValues
|
||||
from utils.password import Password
|
||||
from utils.response import Response
|
||||
@@ -347,3 +349,99 @@ async def reset_user_password(request: Request, params: ResetPasswordParams, id:
|
||||
await user.save()
|
||||
return Response.success(msg="重置密码成功!")
|
||||
return Response.failure(msg="用户不存在!")
|
||||
|
||||
|
||||
@userAPI.get("/statistics", response_model=GetUserStatisticsResponse, response_class=JSONResponse,
|
||||
summary="获取用户查询统计")
|
||||
@Log(title="获取用户查询统计", business_type=BusinessType.SELECT)
|
||||
async def get_user_statistics(request: Request, current_user: dict = Depends(LoginController.get_current_user)):
|
||||
user_id = current_user.get("id")
|
||||
# 获取当前时间
|
||||
now = datetime.now()
|
||||
|
||||
# 今日开始时间
|
||||
today_start_time = now.replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
|
||||
# 今日结束时间
|
||||
today_end_time = now.replace(hour=23, minute=59, second=59, microsecond=999999)
|
||||
|
||||
# 当月开始时间
|
||||
this_month_start_time = now.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
|
||||
|
||||
# 计算当月的最后一天
|
||||
this_month_last_day = calendar.monthrange(now.year, now.month)[1]
|
||||
|
||||
# 当月结束时间
|
||||
this_month_end_time = now.replace(
|
||||
day=this_month_last_day, hour=23, minute=59, second=59, microsecond=999999
|
||||
)
|
||||
|
||||
# 计算上个月的年和月
|
||||
if now.month == 1: # 处理1月(上月是去年的12月)
|
||||
last_month_year = now.year - 1
|
||||
last_month = 12
|
||||
else:
|
||||
last_month_year = now.year
|
||||
last_month = now.month - 1
|
||||
|
||||
# 上月开始时间
|
||||
last_month_start_time = datetime(last_month_year, last_month, 1, 0, 0, 0, 0)
|
||||
|
||||
# 计算上个月最后一天
|
||||
last_month_last_day = calendar.monthrange(last_month_year, last_month)[1]
|
||||
|
||||
# 上月结束时间
|
||||
last_month_end_time = datetime(last_month_year, last_month, last_month_last_day, 23, 59, 59, 999999)
|
||||
|
||||
# 计算今日查询数量
|
||||
today_count = await QueryCode.filter(create_time__gte=today_start_time, create_time__lte=today_end_time,
|
||||
session__operator__id=user_id).count()
|
||||
# 计算当月查询数量
|
||||
this_month_count = await QueryCode.filter(create_time__gte=this_month_start_time,
|
||||
create_time__lte=this_month_end_time,
|
||||
session__operator__id=user_id).count()
|
||||
# 计算上月查询数量
|
||||
last_month_count = await QueryCode.filter(create_time__gte=last_month_start_time,
|
||||
create_time__lte=last_month_end_time,
|
||||
session__operator__id=user_id).count()
|
||||
|
||||
async def get_last_14_days_count(status: int = 1):
|
||||
today = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
|
||||
# 保存结果的列表
|
||||
result = []
|
||||
|
||||
# 遍历最近7天(包括今天)
|
||||
for i in range(14):
|
||||
day = today - timedelta(days=i)
|
||||
|
||||
# 当天的开始时间和结束时间
|
||||
day_start = day # 00:00:00
|
||||
day_end = (day + timedelta(days=1)) # 23:59:59
|
||||
|
||||
# 统计当天查询数量
|
||||
count = await QueryCode.filter(
|
||||
create_time__gte=day_start,
|
||||
create_time__lte=day_end,
|
||||
session__operator__id=user_id,
|
||||
status=status
|
||||
).count()
|
||||
|
||||
# 添加到结果列表(格式化日期为 YYYY-MM-DD)
|
||||
result.append({"date": day.strftime("%Y-%m-%d"), "count": count})
|
||||
|
||||
# 结果按日期升序排列(可选,确保从过去到现在排序)
|
||||
result.sort(key=lambda x: x["date"])
|
||||
return result
|
||||
|
||||
# 过去14天内的查询数量
|
||||
before_14day_count_success = await get_last_14_days_count(1)
|
||||
before_14day_count_fail = await get_last_14_days_count(0)
|
||||
|
||||
return Response.success(data={
|
||||
"today_count": today_count,
|
||||
"this_month_count": this_month_count,
|
||||
"last_month_count": last_month_count,
|
||||
"before_14day_count_success": before_14day_count_success,
|
||||
"before_14day_count_fail": before_14day_count_fail,
|
||||
})
|
||||
|
||||
@@ -66,5 +66,5 @@ class Config(BaseModel):
|
||||
"""
|
||||
|
||||
class Meta:
|
||||
table = "sys_config"
|
||||
table = "config"
|
||||
table_description = "系统配置表"
|
||||
|
||||
@@ -117,15 +117,13 @@ class GetCaptchaResult(BaseModel):
|
||||
uuid: Optional[str] = Field(default=None, description="验证码UUID")
|
||||
captcha: Optional[str] = Field(default=None, description="验证码图片")
|
||||
captcha_enabled: Optional[bool] = Field(default=False, description="是否开启验证码")
|
||||
register_enabled: Optional[bool] = Field(default=False, description="是否开启注册")
|
||||
|
||||
class Config:
|
||||
json_schema_extra = {
|
||||
"example": {
|
||||
"uuid": "1234567890",
|
||||
"captcha": "base64编码的图片",
|
||||
"captcha_enabled": True,
|
||||
"register_enabled": True
|
||||
"captcha_enabled": True
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -348,3 +348,42 @@ class ResetPasswordParams(BaseModel):
|
||||
"password": "123456"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GetUserStatisticsResult(BaseModel):
|
||||
"""
|
||||
用户统计信息模型。
|
||||
"""
|
||||
today_count: int = Field(default=0, description="今日查询次数")
|
||||
this_month_count: int = Field(default=0, description="本月查询次数")
|
||||
last_month_count: int = Field(default=0, description="上月查询次数")
|
||||
before_14day_count_success: List[dict] = Field(default=[], description="最近14天成功查询次数")
|
||||
before_14day_count_fail: List[dict] = Field(default=[], description="最近14天失败查询次数")
|
||||
|
||||
class Config:
|
||||
json_schema_extra = {
|
||||
"example": {
|
||||
"today_count": 0,
|
||||
"this_month_count": 0,
|
||||
"last_month_count": 0,
|
||||
"before_14day_count_success": [
|
||||
{
|
||||
"date": "2023-10-01",
|
||||
"count": 0
|
||||
}
|
||||
],
|
||||
"before_14day_count_fail": [
|
||||
{
|
||||
"date": "2023-10-01",
|
||||
"count": 0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class GetUserStatisticsResponse(BaseResponse):
|
||||
"""
|
||||
获取用户统计信息响应模型。
|
||||
"""
|
||||
data: GetUserStatisticsResult = Field(default=None, description="响应数据")
|
||||
|
||||
Reference in New Issue
Block a user