mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-21 04:46:26 +00:00
refactor: 完成项目整体架构升级与依赖优化
此提交包含多项核心优化: 1. 依赖库升级:更新FastAPI、替换fastapi-limiter为slowapi,更换MySQL驱动为aiomysql,重构缓存系统使用fastapi-cache2-fork 2. 代码重构:移除自定义缓存工具,统一使用fastapi-cache2;重构请求限流逻辑,修复操作日志记录开关逻辑 3. 接口规范:统一将Depends分页/查询参数改为Query注解,补全File上传依赖注解 4. 前端优化:调整登录滑块进度条颜色、移除冗余demo页面样式类 5. 日志优化:重构日志配置,使用time.perf_counter替代time.time统计耗时 6. 测试优化:移除冗余的限流mock配置,改用官方限流方案 7. 模板优化:更新vue代码生成模板,移除冗余导入并优化组件使用 8. 导入功能优化:移除pandas依赖,使用Excel工具类重构文件导入逻辑
This commit is contained in:
@@ -2,22 +2,22 @@ import json
|
||||
import secrets
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, BackgroundTasks, Depends, Path, Query, Request
|
||||
from fastapi import APIRouter, BackgroundTasks, Depends, Path, Query, Body, Form, Request
|
||||
from fastapi.responses import JSONResponse, RedirectResponse
|
||||
from redis.asyncio.client import Redis
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.common.response import ErrorResponse, ResponseSchema, SuccessResponse
|
||||
from app.config.setting import settings
|
||||
from app.core import cache_util
|
||||
from app.core.base_schema import (
|
||||
AuthSchema,
|
||||
JWTOutSchema,
|
||||
LogoutPayloadSchema,
|
||||
RefreshTokenPayloadSchema,
|
||||
)
|
||||
from app.core.cache_util import cache
|
||||
from app.core.dependencies import db_getter, get_current_user, redis_getter
|
||||
from fastapi_cache import FastAPICache
|
||||
from fastapi_cache.decorator import cache
|
||||
from app.core.exceptions import CustomException
|
||||
from app.core.logger import logger
|
||||
from app.core.redis_crud import RedisCURD
|
||||
@@ -65,8 +65,8 @@ async def login_for_access_token_controller(
|
||||
request: Request,
|
||||
background_tasks: BackgroundTasks,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
login_form: Annotated[CustomOAuth2PasswordRequestForm, Depends()],
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
login_form: Annotated[CustomOAuth2PasswordRequestForm, Form(description="登录表单")],
|
||||
) -> JSONResponse | dict:
|
||||
login_result = await LoginService.authenticate_user(
|
||||
request=request, redis=redis, login_form=login_form, db=db, background_tasks=background_tasks
|
||||
@@ -85,9 +85,9 @@ async def login_for_access_token_controller(
|
||||
response_model=ResponseSchema[JWTOutSchema],
|
||||
)
|
||||
async def get_new_token_controller(
|
||||
payload: RefreshTokenPayloadSchema,
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
payload: Annotated[RefreshTokenPayloadSchema, Body(description="刷新token参数")],
|
||||
) -> JSONResponse:
|
||||
new_token = await LoginService.refresh_token(db=db, redis=redis, refresh_token=payload)
|
||||
return SuccessResponse(data=new_token, msg="刷新成功")
|
||||
@@ -112,8 +112,8 @@ async def get_captcha_for_login_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def logout_controller(
|
||||
payload: LogoutPayloadSchema,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
payload: Annotated[LogoutPayloadSchema, Body(description="退出登录参数")],
|
||||
) -> JSONResponse:
|
||||
if await LoginService.logout(redis=redis, token=payload):
|
||||
logger.info("退出成功")
|
||||
@@ -144,7 +144,7 @@ async def get_auto_login_token_controller(
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
user_id: int,
|
||||
user_id: Annotated[int, Body(description="用户ID")],
|
||||
) -> JSONResponse:
|
||||
tenant_id = None if auth.user.is_superuser else auth.user.tenant_id
|
||||
result = await AutoLoginService.create_auto_login_token(redis=redis, db=db, user_id=user_id, tenant_id=tenant_id)
|
||||
@@ -160,7 +160,7 @@ async def auto_login_controller(
|
||||
request: Request,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
token: str,
|
||||
token: Annotated[str, Body(description="免登录Token")],
|
||||
) -> JSONResponse:
|
||||
login_token = await AutoLoginService.auto_login(request=request, redis=redis, db=db, token=token)
|
||||
logger.info("用户免登录成功")
|
||||
@@ -175,12 +175,12 @@ async def auto_login_controller(
|
||||
)
|
||||
async def select_tenant_controller(
|
||||
request: Request,
|
||||
data: SelectTenantSchema,
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
data: Annotated[SelectTenantSchema, Body(description="租户选择参数")],
|
||||
) -> JSONResponse:
|
||||
result = await LoginService(auth).select_tenant(request=request, redis=redis, tenant_id=data.tenant_id)
|
||||
await cache_util.clear(namespace=_AUTH_TENANTS_NS)
|
||||
await FastAPICache.clear(namespace=_AUTH_TENANTS_NS)
|
||||
return SuccessResponse(data=result, msg="租户切换成功")
|
||||
|
||||
|
||||
@@ -193,7 +193,6 @@ async def select_tenant_controller(
|
||||
@cache(expire=120, namespace=_AUTH_TENANTS_NS)
|
||||
async def get_user_tenants_controller(
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
) -> JSONResponse:
|
||||
service = LoginService(auth)
|
||||
tenants = await service.get_user_tenants()
|
||||
@@ -208,10 +207,7 @@ async def oauth_login_redirect_controller(
|
||||
request: Request,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
provider: Annotated[str, Path(description="wechat | qq | github | gitee")],
|
||||
redirect_uri: Annotated[
|
||||
str | None,
|
||||
Query(description="OAuth 完成后浏览器回到的前端登录页完整 URL"),
|
||||
] = None,
|
||||
redirect_uri: Annotated[str | None, Query(description="OAuth 完成后浏览器回到的前端登录页完整 URL")] = None,
|
||||
) -> RedirectResponse:
|
||||
allowed = {"wechat", "qq", "github", "gitee"}
|
||||
fe = redirect_uri or settings.OAUTH_FRONTEND_FALLBACK
|
||||
@@ -252,9 +248,9 @@ async def oauth_callback_controller(
|
||||
request: Request,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
provider: Annotated[str, Path()],
|
||||
code: Annotated[str | None, Query()] = None,
|
||||
state: Annotated[str | None, Query()] = None,
|
||||
provider: Annotated[str, Path(description="wechat | qq | github | gitee")],
|
||||
code: Annotated[str | None, Query(description="OAuth 授权码")] = None,
|
||||
state: Annotated[str | None, Query(description="OAuth 状态参数")] = None,
|
||||
) -> RedirectResponse:
|
||||
fe_fallback = settings.OAUTH_FRONTEND_FALLBACK
|
||||
|
||||
@@ -300,8 +296,8 @@ async def oauth_callback_controller(
|
||||
response_model=ResponseSchema[TenantRegisterOutSchema],
|
||||
)
|
||||
async def tenant_register_controller(
|
||||
data: TenantRegisterSchema,
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
data: Annotated[TenantRegisterSchema, Body(description="租户注册参数")],
|
||||
) -> JSONResponse:
|
||||
result = await TenantRegisterService.register(
|
||||
db=db,
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path
|
||||
from fastapi import APIRouter, Body, Depends, Path, Query
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app.common.response import ResponseSchema, SuccessResponse
|
||||
from app.core import cache_util
|
||||
from app.core.base_schema import AuthSchema, BatchSetAvailable
|
||||
from app.core.cache_util import cache
|
||||
from app.core.dependencies import AuthPermission
|
||||
from app.core.router_class import OperationLogRoute
|
||||
from fastapi_cache import FastAPICache
|
||||
from fastapi_cache.decorator import cache
|
||||
|
||||
from .schema import DeptCreateSchema, DeptOutSchema, DeptQueryParam, DeptUpdateSchema
|
||||
from .service import DeptService
|
||||
@@ -24,8 +24,8 @@ _DEPT_NS = "dept"
|
||||
)
|
||||
@cache(expire=300, namespace=_DEPT_NS)
|
||||
async def get_dept_tree_controller(
|
||||
search: Annotated[DeptQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:query"]))],
|
||||
search: Annotated[DeptQueryParam, Query(description="部门查询参数")],
|
||||
) -> JSONResponse:
|
||||
order_by = [{"order": "asc"}]
|
||||
result_dict_tree = await DeptService(auth).tree(search=search, order_by=order_by)
|
||||
@@ -37,8 +37,8 @@ async def get_dept_tree_controller(
|
||||
response_model=ResponseSchema[DeptOutSchema],
|
||||
)
|
||||
async def get_obj_detail_controller(
|
||||
id: Annotated[int, Path(description="部门ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:detail"]))],
|
||||
id: Annotated[int, Path(description="部门ID")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DeptService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="查询部门详情成功")
|
||||
@@ -49,11 +49,11 @@ async def get_obj_detail_controller(
|
||||
response_model=ResponseSchema[DeptOutSchema],
|
||||
)
|
||||
async def create_obj_controller(
|
||||
data: DeptCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:create"]))],
|
||||
data: Annotated[DeptCreateSchema, Body(description="部门创建参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DeptService(auth).create(data=data)
|
||||
await cache_util.clear(namespace=_DEPT_NS)
|
||||
await FastAPICache.clear(namespace=_DEPT_NS)
|
||||
return SuccessResponse(data=result_dict, msg="创建部门成功")
|
||||
|
||||
@DeptRouter.put(
|
||||
@@ -62,12 +62,12 @@ async def create_obj_controller(
|
||||
response_model=ResponseSchema[DeptOutSchema],
|
||||
)
|
||||
async def update_obj_controller(
|
||||
data: DeptUpdateSchema,
|
||||
id: Annotated[int, Path(description="部门ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:update"]))],
|
||||
id: Annotated[int, Path(description="部门ID")],
|
||||
data: Annotated[DeptUpdateSchema, Body(description="部门修改参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DeptService(auth).update(id=id, data=data)
|
||||
await cache_util.clear(namespace=_DEPT_NS)
|
||||
await FastAPICache.clear(namespace=_DEPT_NS)
|
||||
return SuccessResponse(data=result_dict, msg="修改部门成功")
|
||||
|
||||
@DeptRouter.delete(
|
||||
@@ -76,11 +76,11 @@ async def update_obj_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def delete_obj_controller(
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
) -> JSONResponse:
|
||||
await DeptService(auth).delete(ids=ids)
|
||||
await cache_util.clear(namespace=_DEPT_NS)
|
||||
await FastAPICache.clear(namespace=_DEPT_NS)
|
||||
return SuccessResponse(msg="删除部门成功")
|
||||
|
||||
@DeptRouter.patch(
|
||||
@@ -89,9 +89,9 @@ async def delete_obj_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dept:patch"]))],
|
||||
data: Annotated[BatchSetAvailable, Body(description="批量修改部门状态参数")],
|
||||
) -> JSONResponse:
|
||||
await DeptService(auth).batch_set_available(data=data)
|
||||
await cache_util.clear(namespace=_DEPT_NS)
|
||||
await FastAPICache.clear(namespace=_DEPT_NS)
|
||||
return SuccessResponse(msg="批量修改部门状态成功")
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path
|
||||
from fastapi import APIRouter, Body, Depends, Path, Query
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from redis.asyncio.client import Redis
|
||||
|
||||
from app.common.response import ResponseSchema, StreamResponse, SuccessResponse
|
||||
from app.core import cache_util
|
||||
from app.core.base_params import PaginationQueryParam
|
||||
from app.core.base_schema import AuthSchema, BatchSetAvailable, PageResultSchema
|
||||
from app.core.cache_util import cache
|
||||
from app.core.dependencies import AuthPermission, redis_getter
|
||||
from fastapi_cache import FastAPICache
|
||||
from fastapi_cache.decorator import cache
|
||||
from app.core.router_class import OperationLogRoute
|
||||
from app.utils.common_util import bytes2file_response
|
||||
|
||||
@@ -35,8 +35,8 @@ _DICT_TYPE_NS = "dict_type"
|
||||
response_model=ResponseSchema[DictTypeOutSchema],
|
||||
)
|
||||
async def get_type_detail_controller(
|
||||
id: Annotated[int, Path(description="字典类型ID", ge=1)],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:detail"]))],
|
||||
id: Annotated[int, Path(description="字典类型ID", ge=1)],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictTypeService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取字典类型详情成功")
|
||||
@@ -47,9 +47,9 @@ async def get_type_detail_controller(
|
||||
response_model=ResponseSchema[PageResultSchema[DictTypeOutSchema]],
|
||||
)
|
||||
async def get_type_list_controller(
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[DictTypeQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:query"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页查询参数")],
|
||||
search: Annotated[DictTypeQueryParam, Query(description="字典类型查询参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictTypeService(auth).page(
|
||||
page_no=page.page_no,
|
||||
@@ -77,12 +77,12 @@ async def get_type_optionselect_controller(
|
||||
response_model=ResponseSchema[DictTypeOutSchema],
|
||||
)
|
||||
async def create_type_controller(
|
||||
data: DictTypeCreateSchema,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:create"]))],
|
||||
data: Annotated[DictTypeCreateSchema, Body(description="字典类型创建参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictTypeService(auth).create(redis=redis, data=data)
|
||||
await cache_util.clear(namespace=_DICT_TYPE_NS)
|
||||
await FastAPICache.clear(namespace=_DICT_TYPE_NS)
|
||||
return SuccessResponse(data=result_dict, msg="创建字典类型成功")
|
||||
|
||||
@DictRouter.put(
|
||||
@@ -91,13 +91,13 @@ async def create_type_controller(
|
||||
response_model=ResponseSchema[DictTypeOutSchema],
|
||||
)
|
||||
async def update_type_controller(
|
||||
data: DictTypeUpdateSchema,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
id: Annotated[int, Path(description="字典类型ID", ge=1)],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:update"]))],
|
||||
id: Annotated[int, Path(description="字典类型ID", ge=1)],
|
||||
data: Annotated[DictTypeUpdateSchema, Body(description="字典类型修改参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictTypeService(auth).update(redis=redis, id=id, data=data)
|
||||
await cache_util.clear(namespace=_DICT_TYPE_NS)
|
||||
await FastAPICache.clear(namespace=_DICT_TYPE_NS)
|
||||
return SuccessResponse(data=result_dict, msg="修改字典类型成功")
|
||||
|
||||
@DictRouter.delete(
|
||||
@@ -107,11 +107,11 @@ async def update_type_controller(
|
||||
)
|
||||
async def delete_type_controller(
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="字典类型ID列表")],
|
||||
) -> JSONResponse:
|
||||
await DictTypeService(auth).delete(redis=redis, ids=ids)
|
||||
await cache_util.clear(namespace=_DICT_TYPE_NS)
|
||||
await FastAPICache.clear(namespace=_DICT_TYPE_NS)
|
||||
return SuccessResponse(msg="删除字典类型成功")
|
||||
|
||||
@DictRouter.patch(
|
||||
@@ -120,11 +120,11 @@ async def delete_type_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def batch_set_available_dict_type_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:patch"]))],
|
||||
data: Annotated[BatchSetAvailable, Body(description="批量修改字典类型状态参数")],
|
||||
) -> JSONResponse:
|
||||
await DictTypeService(auth).set_available(data=data)
|
||||
await cache_util.clear(namespace=_DICT_TYPE_NS)
|
||||
await FastAPICache.clear(namespace=_DICT_TYPE_NS)
|
||||
return SuccessResponse(msg="批量修改字典类型状态成功")
|
||||
|
||||
@DictRouter.post(
|
||||
@@ -133,8 +133,8 @@ async def batch_set_available_dict_type_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def export_type_list_controller(
|
||||
search: Annotated[DictTypeQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:export"]))],
|
||||
search: Annotated[DictTypeQueryParam, Query(description="字典类型查询参数")],
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据并转为dict列表
|
||||
result_dict_list = await DictTypeService(auth).get_list(search=search)
|
||||
@@ -153,8 +153,8 @@ async def export_type_list_controller(
|
||||
response_model=ResponseSchema[DictDataOutSchema],
|
||||
)
|
||||
async def get_data_detail_controller(
|
||||
id: Annotated[int, Path(description="字典数据ID", ge=1)],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:detail"]))],
|
||||
id: Annotated[int, Path(description="字典数据ID", ge=1)],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictDataService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取字典数据详情成功")
|
||||
@@ -165,9 +165,9 @@ async def get_data_detail_controller(
|
||||
response_model=ResponseSchema[PageResultSchema[DictDataOutSchema]],
|
||||
)
|
||||
async def get_data_list_controller(
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[DictDataQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:query"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[DictDataQueryParam, Query(description="字典数据查询参数")],
|
||||
) -> JSONResponse:
|
||||
order_by = [{"order": "asc"}]
|
||||
if page.order_by:
|
||||
@@ -186,9 +186,9 @@ async def get_data_list_controller(
|
||||
response_model=ResponseSchema[DictDataOutSchema],
|
||||
)
|
||||
async def create_data_controller(
|
||||
data: DictDataCreateSchema,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:create"]))],
|
||||
data: Annotated[DictDataCreateSchema, Body(description="字典数据创建参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictDataService(auth).create(redis=redis, data=data)
|
||||
return SuccessResponse(data=result_dict, msg="创建字典数据成功")
|
||||
@@ -199,10 +199,10 @@ async def create_data_controller(
|
||||
response_model=ResponseSchema[DictDataOutSchema],
|
||||
)
|
||||
async def update_data_controller(
|
||||
data: DictDataUpdateSchema,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
id: Annotated[int, Path(description="字典数据ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:update"]))],
|
||||
id: Annotated[int, Path(description="字典数据ID")],
|
||||
data: Annotated[DictDataUpdateSchema, Body(description="字典数据修改参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictDataService(auth).update(redis=redis, id=id, data=data)
|
||||
return SuccessResponse(data=result_dict, msg="修改字典数据成功")
|
||||
@@ -214,8 +214,8 @@ async def update_data_controller(
|
||||
)
|
||||
async def delete_data_controller(
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
) -> JSONResponse:
|
||||
await DictDataService(auth).delete(redis=redis, ids=ids)
|
||||
return SuccessResponse(msg="删除字典数据成功")
|
||||
@@ -226,8 +226,8 @@ async def delete_data_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def batch_set_available_dict_data_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:patch"]))],
|
||||
data: Annotated[BatchSetAvailable, Body(description="批量修改字典数据状态参数")],
|
||||
) -> JSONResponse:
|
||||
await DictDataService(auth).set_available(data=data)
|
||||
return SuccessResponse(msg="批量修改字典数据状态成功")
|
||||
@@ -238,9 +238,9 @@ async def batch_set_available_dict_data_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def export_data_list_controller(
|
||||
search: Annotated[DictDataQueryParam, Depends()],
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:export"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[DictDataQueryParam, Query(description="字典数据查询参数")],
|
||||
) -> StreamingResponse:
|
||||
result_dict_list = await DictDataService(auth).get_list(search=search, order_by=page.order_by)
|
||||
export_data = [item.model_dump() for item in result_dict_list]
|
||||
@@ -257,7 +257,10 @@ async def export_data_list_controller(
|
||||
summary="根据字典类型获取数据",
|
||||
response_model=ResponseSchema[list[DictDataOutSchema]],
|
||||
)
|
||||
async def get_init_dict_data_controller(dict_type: str, redis: Annotated[Redis, Depends(redis_getter)]) -> JSONResponse:
|
||||
async def get_init_dict_data_controller(
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
dict_type: Annotated[str, Path(description="字典类型")],
|
||||
) -> JSONResponse:
|
||||
dict_data_query_result = await DictDataService.get_init_cache(redis=redis, dict_type=dict_type, tenant_id=1)
|
||||
|
||||
return SuccessResponse(data=dict_data_query_result, msg="获取初始化字典数据成功")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path
|
||||
from fastapi import APIRouter, Body, Depends, Path, Query
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app.common.response import ResponseSchema, SuccessResponse
|
||||
@@ -30,8 +30,8 @@ LogRouter = APIRouter(route_class=OperationLogRoute, prefix="/log", tags=["系
|
||||
response_model=ResponseSchema[LoginLogDetailOutSchema],
|
||||
)
|
||||
async def get_log_detail_controller(
|
||||
id: Annotated[int, Path(description="登录日志ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:login_log:query"]))],
|
||||
id: Annotated[int, Path(description="登录日志ID")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await LoginLogService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取登录日志详情成功")
|
||||
@@ -43,9 +43,9 @@ async def get_log_detail_controller(
|
||||
response_model=ResponseSchema[PageResultSchema[LoginLogOutSchema]],
|
||||
)
|
||||
async def get_log_list_controller(
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[LoginLogQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:login_log:query"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[LoginLogQueryParam, Query(description="登录日志查询参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await LoginLogService(auth).page(
|
||||
page_no=page.page_no,
|
||||
@@ -62,8 +62,8 @@ async def get_log_list_controller(
|
||||
response_model=ResponseSchema[LoginLogDetailOutSchema],
|
||||
)
|
||||
async def create_log_controller(
|
||||
data: LoginLogCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
data: Annotated[LoginLogCreateSchema, Body(description="登录日志创建参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await LoginLogService(auth).create(data=data)
|
||||
return SuccessResponse(data=result_dict, msg="创建登录日志成功")
|
||||
@@ -75,8 +75,8 @@ async def create_log_controller(
|
||||
response_model=ResponseSchema,
|
||||
)
|
||||
async def delete_log_controller(
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:login_log:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
) -> JSONResponse:
|
||||
await LoginLogService(auth).delete(ids=ids)
|
||||
return SuccessResponse(msg="删除登录日志成功")
|
||||
@@ -89,9 +89,8 @@ async def delete_log_controller(
|
||||
dependencies=[Depends(AuthPermission(["module_system:log:query"]))],
|
||||
)
|
||||
async def get_operation_log_detail_controller(
|
||||
*,
|
||||
id: Annotated[int, Path(gt=0)],
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
id: Annotated[int, Path(description="操作日志ID", gt=0)],
|
||||
):
|
||||
result_dict = await OperationLogService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取操作日志详情成功")
|
||||
@@ -103,11 +102,10 @@ async def get_operation_log_detail_controller(
|
||||
response_model=ResponseSchema[PageResultSchema[OperationLogOutSchema]],
|
||||
dependencies=[Depends(AuthPermission(["module_system:log:query"]))],
|
||||
)
|
||||
async def list(
|
||||
*,
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[OperationLogQueryParam, Depends()],
|
||||
async def get_operation_log_list_controller(
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[OperationLogQueryParam, Query(description="操作日志查询参数")],
|
||||
):
|
||||
result_dict = await OperationLogService(auth).page(
|
||||
page_no=page.page_no,
|
||||
@@ -124,9 +122,8 @@ async def list(
|
||||
response_model=ResponseSchema[OperationLogDetailOutSchema],
|
||||
)
|
||||
async def create_operation_log_controller(
|
||||
*,
|
||||
data: OperationLogCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
data: Annotated[OperationLogCreateSchema, Body(description="操作日志创建参数")],
|
||||
):
|
||||
result_dict = await OperationLogService(auth).create(data=data)
|
||||
return SuccessResponse(data=result_dict, msg="创建操作日志成功")
|
||||
@@ -139,9 +136,8 @@ async def create_operation_log_controller(
|
||||
dependencies=[Depends(AuthPermission(["module_system:log:delete"]))],
|
||||
)
|
||||
async def delete(
|
||||
*,
|
||||
data: BatchDelete,
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
data: Annotated[BatchDelete, Body(description="ID列表")],
|
||||
):
|
||||
await OperationLogService(auth).delete(ids=data.ids)
|
||||
return SuccessResponse(msg="删除操作日志成功")
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path
|
||||
from fastapi import APIRouter, Body, Depends, Path, Query
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
|
||||
from app.common.response import ResponseSchema, StreamResponse, SuccessResponse
|
||||
from app.core import cache_util
|
||||
from app.core.base_params import PaginationQueryParam
|
||||
from app.core.base_schema import AuthSchema, BatchSetAvailable, PageResultSchema
|
||||
from app.core.cache_util import cache
|
||||
from app.core.dependencies import AuthPermission, get_current_user
|
||||
from fastapi_cache import FastAPICache
|
||||
from fastapi_cache.decorator import cache
|
||||
from app.core.logger import logger
|
||||
from app.core.router_class import OperationLogRoute
|
||||
from app.utils.common_util import bytes2file_response
|
||||
@@ -32,8 +32,8 @@ _NOTICE_NS = "notice"
|
||||
response_model=ResponseSchema[NoticeOutSchema],
|
||||
)
|
||||
async def get_notice_detail_controller(
|
||||
id: Annotated[int, Path(description="公告ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:notice:detail"]))],
|
||||
id: Annotated[int, Path(description="公告ID")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await NoticeService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取公告详情成功")
|
||||
@@ -44,9 +44,9 @@ async def get_notice_detail_controller(
|
||||
response_model=ResponseSchema[PageResultSchema[NoticeOutSchema]],
|
||||
)
|
||||
async def get_notice_list_controller(
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[NoticeQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:notice:query"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[NoticeQueryParam, Query(description="公告查询参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await NoticeService(auth).page(
|
||||
page_no=page.page_no,
|
||||
@@ -62,11 +62,11 @@ async def get_notice_list_controller(
|
||||
response_model=ResponseSchema[NoticeOutSchema],
|
||||
)
|
||||
async def create_notice_controller(
|
||||
data: NoticeCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:notice:create"]))],
|
||||
data: Annotated[NoticeCreateSchema, Body(description="公告创建参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await NoticeService(auth).create(data=data)
|
||||
await cache_util.clear(namespace=_NOTICE_NS)
|
||||
await FastAPICache.clear(namespace=_NOTICE_NS)
|
||||
return SuccessResponse(data=result_dict, msg="创建公告成功")
|
||||
|
||||
@NoticeRouter.put(
|
||||
@@ -75,12 +75,12 @@ async def create_notice_controller(
|
||||
response_model=ResponseSchema[NoticeOutSchema],
|
||||
)
|
||||
async def update_notice_controller(
|
||||
data: NoticeUpdateSchema,
|
||||
id: Annotated[int, Path(description="公告ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:notice:update"]))],
|
||||
id: Annotated[int, Path(description="公告ID")],
|
||||
data: Annotated[NoticeUpdateSchema, Body(description="公告修改参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await NoticeService(auth).update(id=id, data=data)
|
||||
await cache_util.clear(namespace=_NOTICE_NS)
|
||||
await FastAPICache.clear(namespace=_NOTICE_NS)
|
||||
return SuccessResponse(data=result_dict, msg="修改公告成功")
|
||||
|
||||
@NoticeRouter.delete(
|
||||
@@ -89,11 +89,11 @@ async def update_notice_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def delete_notice_controller(
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:notice:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
) -> JSONResponse:
|
||||
await NoticeService(auth).delete(ids=ids)
|
||||
await cache_util.clear(namespace=_NOTICE_NS)
|
||||
await FastAPICache.clear(namespace=_NOTICE_NS)
|
||||
return SuccessResponse(msg="删除公告成功")
|
||||
|
||||
@NoticeRouter.patch(
|
||||
@@ -102,11 +102,11 @@ async def delete_notice_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def batch_set_available_notice_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:notice:patch"]))],
|
||||
data: Annotated[BatchSetAvailable, Body(description="批量修改公告状态参数")],
|
||||
) -> JSONResponse:
|
||||
await NoticeService(auth).set_available(data=data)
|
||||
await cache_util.clear(namespace=_NOTICE_NS)
|
||||
await FastAPICache.clear(namespace=_NOTICE_NS)
|
||||
return SuccessResponse(msg="批量修改公告状态成功")
|
||||
|
||||
@NoticeRouter.post(
|
||||
@@ -114,8 +114,8 @@ async def batch_set_available_notice_controller(
|
||||
summary="导出公告",
|
||||
)
|
||||
async def export_notice_list_controller(
|
||||
search: Annotated[NoticeQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:notice:export"]))],
|
||||
search: Annotated[NoticeQueryParam, Query(description="公告查询参数")],
|
||||
) -> StreamingResponse:
|
||||
result_dict_list = await NoticeService(auth).get_list(search=search)
|
||||
export_data = [item.model_dump() for item in result_dict_list]
|
||||
@@ -158,12 +158,12 @@ async def get_notification_panel_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def mark_read_controller(
|
||||
id: Annotated[int, Path(description="通知ID")],
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
id: Annotated[int, Path(description="通知ID")],
|
||||
) -> JSONResponse:
|
||||
"""标记已读。通过 `sys_notice_read` 表记录已读时间。"""
|
||||
await NoticeService(auth).mark_read(notice_id=id)
|
||||
await cache_util.clear(namespace=_NOTICE_NS)
|
||||
await FastAPICache.clear(namespace=_NOTICE_NS)
|
||||
logger.info(f"用户[{auth.user.id}]标记通知[{id}]已读")
|
||||
return SuccessResponse(msg="标记已读成功")
|
||||
|
||||
@@ -177,7 +177,7 @@ async def mark_all_read_controller(
|
||||
) -> JSONResponse:
|
||||
"""全部标记已读。返回本次操作标记的数量。"""
|
||||
count = await NoticeService(auth).mark_all_read()
|
||||
await cache_util.clear(namespace=_NOTICE_NS)
|
||||
await FastAPICache.clear(namespace=_NOTICE_NS)
|
||||
logger.info(f"用户[{auth.user.id}]全部已读, 数量={count}")
|
||||
return SuccessResponse(data=count, msg=f"全部标记已读成功,共标记 {count} 条")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path
|
||||
from fastapi import APIRouter, Body, Depends, Path, Query
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from redis.asyncio.client import Redis
|
||||
|
||||
@@ -22,8 +22,8 @@ ParamsRouter = APIRouter(route_class=OperationLogRoute, prefix="/param", tags=["
|
||||
response_model=ResponseSchema[ParamsOutSchema],
|
||||
)
|
||||
async def get_param_detail_controller(
|
||||
id: Annotated[int, Path(description="参数ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:detail"]))],
|
||||
id: Annotated[int, Path(description="参数ID")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取参数详情成功")
|
||||
@@ -34,8 +34,8 @@ async def get_param_detail_controller(
|
||||
response_model=ResponseSchema[ParamsOutSchema],
|
||||
)
|
||||
async def get_param_by_key_controller(
|
||||
config_key: Annotated[str, Path(description="配置键")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:query"]))],
|
||||
config_key: Annotated[str, Path(description="配置键")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService(auth).get_by_key(config_key=config_key)
|
||||
return SuccessResponse(data=result_dict, msg="根据配置键获取参数详情成功")
|
||||
@@ -46,8 +46,8 @@ async def get_param_by_key_controller(
|
||||
response_model=ResponseSchema[ParamsOutSchema],
|
||||
)
|
||||
async def get_config_value_by_key_controller(
|
||||
config_key: Annotated[str, Path(description="配置键")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:query"]))],
|
||||
config_key: Annotated[str, Path(description="配置键")],
|
||||
) -> JSONResponse:
|
||||
result_value = await ParamsService(auth).get_config_value_by_key(config_key=config_key)
|
||||
return SuccessResponse(data=result_value, msg="根据配置键获取参数值成功")
|
||||
@@ -59,8 +59,8 @@ async def get_config_value_by_key_controller(
|
||||
)
|
||||
async def get_param_list_controller(
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:query"]))],
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[ParamsQueryParam, Depends()],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[ParamsQueryParam, Query(description="参数查询参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService(auth).page(
|
||||
page_no=page.page_no,
|
||||
@@ -76,9 +76,9 @@ async def get_param_list_controller(
|
||||
response_model=ResponseSchema[ParamsOutSchema],
|
||||
)
|
||||
async def create_param_controller(
|
||||
data: ParamsCreateSchema,
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:create"]))],
|
||||
data: Annotated[ParamsCreateSchema, Body(description="参数创建参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService(auth).create(redis=redis, data=data)
|
||||
return SuccessResponse(data=result_dict, msg="创建参数成功")
|
||||
@@ -89,10 +89,10 @@ async def create_param_controller(
|
||||
response_model=ResponseSchema[ParamsOutSchema],
|
||||
)
|
||||
async def update_param_controller(
|
||||
data: ParamsUpdateSchema,
|
||||
id: Annotated[int, Path(description="参数ID")],
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:update"]))],
|
||||
id: Annotated[int, Path(description="参数ID")],
|
||||
data: Annotated[ParamsUpdateSchema, Body(description="参数修改参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService(auth).update(redis=redis, id=id, data=data)
|
||||
return SuccessResponse(data=result_dict, msg="更新参数成功")
|
||||
@@ -104,8 +104,8 @@ async def update_param_controller(
|
||||
)
|
||||
async def delete_param_controller(
|
||||
redis: Annotated[Redis, Depends(redis_getter)],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
) -> JSONResponse:
|
||||
await ParamsService(auth).delete(redis=redis, ids=ids)
|
||||
return SuccessResponse(msg="删除参数成功")
|
||||
@@ -116,9 +116,9 @@ async def delete_param_controller(
|
||||
response_model=ResponseSchema,
|
||||
)
|
||||
async def batch_set_status_controller(
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:patch"]))],
|
||||
ids: Annotated[list[int], Body(description="参数ID列表")],
|
||||
status: Annotated[int, Body(description="状态值")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:patch"]))],
|
||||
) -> JSONResponse:
|
||||
await ParamsService(auth).batch_set_status(ids=ids, status=status)
|
||||
return SuccessResponse(msg="批量设置参数状态成功")
|
||||
@@ -129,8 +129,8 @@ async def batch_set_status_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def export_param_list_controller(
|
||||
search: Annotated[ParamsQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:param:export"]))],
|
||||
search: Annotated[ParamsQueryParam, Query(description="参数查询参数")],
|
||||
) -> StreamingResponse:
|
||||
result_dict_list = await ParamsService(auth).get_list(search=search)
|
||||
export_data = [item.model_dump() for item in result_dict_list]
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path
|
||||
from fastapi import APIRouter, Body, Depends, Path, Query
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
|
||||
from app.common.response import ResponseSchema, StreamResponse, SuccessResponse
|
||||
from app.core import cache_util
|
||||
from app.core.base_params import PaginationQueryParam
|
||||
from app.core.base_schema import AuthSchema, BatchSetAvailable, PageResultSchema
|
||||
from app.core.cache_util import cache
|
||||
from app.core.dependencies import AuthPermission
|
||||
from app.core.router_class import OperationLogRoute
|
||||
from fastapi_cache import FastAPICache
|
||||
from fastapi_cache.decorator import cache
|
||||
from app.utils.common_util import bytes2file_response
|
||||
|
||||
from .schema import (
|
||||
@@ -31,9 +31,9 @@ _POS_NS = "position"
|
||||
)
|
||||
@cache(expire=300, namespace=_POS_NS)
|
||||
async def get_obj_list_controller(
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[PositionQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:position:query"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[PositionQueryParam, Query(description="岗位查询参数")],
|
||||
) -> JSONResponse:
|
||||
order_by = [{"order": "asc"}]
|
||||
if page.order_by:
|
||||
@@ -52,8 +52,8 @@ async def get_obj_list_controller(
|
||||
response_model=ResponseSchema[PositionOutSchema],
|
||||
)
|
||||
async def get_obj_detail_controller(
|
||||
id: Annotated[int, Path(description="岗位ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:position:detail"]))],
|
||||
id: Annotated[int, Path(description="岗位ID")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await PositionService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取岗位详情成功")
|
||||
@@ -64,11 +64,11 @@ async def get_obj_detail_controller(
|
||||
response_model=ResponseSchema[PositionOutSchema],
|
||||
)
|
||||
async def create_obj_controller(
|
||||
data: PositionCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:position:create"]))],
|
||||
data: Annotated[PositionCreateSchema, Body(description="岗位创建参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await PositionService(auth).create(data=data)
|
||||
await cache_util.clear(namespace=_POS_NS)
|
||||
await FastAPICache.clear(namespace=_POS_NS)
|
||||
return SuccessResponse(data=result_dict, msg="创建岗位成功")
|
||||
|
||||
@PositionRouter.put(
|
||||
@@ -77,12 +77,12 @@ async def create_obj_controller(
|
||||
response_model=ResponseSchema[PositionOutSchema],
|
||||
)
|
||||
async def update_obj_controller(
|
||||
data: PositionUpdateSchema,
|
||||
id: Annotated[int, Path(description="岗位ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:position:update"]))],
|
||||
id: Annotated[int, Path(description="岗位ID")],
|
||||
data: Annotated[PositionUpdateSchema, Body(description="岗位修改参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await PositionService(auth).update(id=id, data=data)
|
||||
await cache_util.clear(namespace=_POS_NS)
|
||||
await FastAPICache.clear(namespace=_POS_NS)
|
||||
return SuccessResponse(data=result_dict, msg="修改岗位成功")
|
||||
|
||||
@PositionRouter.delete(
|
||||
@@ -91,11 +91,11 @@ async def update_obj_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def delete_obj_controller(
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:position:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
) -> JSONResponse:
|
||||
await PositionService(auth).delete(ids=ids)
|
||||
await cache_util.clear(namespace=_POS_NS)
|
||||
await FastAPICache.clear(namespace=_POS_NS)
|
||||
return SuccessResponse(msg="删除岗位成功")
|
||||
|
||||
@PositionRouter.patch(
|
||||
@@ -104,11 +104,11 @@ async def delete_obj_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:position:patch"]))],
|
||||
data: Annotated[BatchSetAvailable, Body(description="批量修改岗位状态参数")],
|
||||
) -> JSONResponse:
|
||||
await PositionService(auth).set_available(data=data)
|
||||
await cache_util.clear(namespace=_POS_NS)
|
||||
await FastAPICache.clear(namespace=_POS_NS)
|
||||
return SuccessResponse(msg="批量修改岗位状态成功")
|
||||
|
||||
@PositionRouter.get(
|
||||
@@ -117,8 +117,8 @@ async def batch_set_available_obj_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def export_obj_list_controller(
|
||||
search: Annotated[PositionQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:position:export"]))],
|
||||
search: Annotated[PositionQueryParam, Query(description="岗位查询参数")],
|
||||
) -> StreamingResponse:
|
||||
position_query_result = await PositionService(auth).get_list(search=search)
|
||||
position_export_result = PositionService.export_list(position_list=position_query_result)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path
|
||||
from fastapi import APIRouter, Body, Depends, Path, Query
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
|
||||
from app.common.response import ResponseSchema, StreamResponse, SuccessResponse
|
||||
from app.core import cache_util
|
||||
from app.core.base_params import PaginationQueryParam
|
||||
from app.core.base_schema import AuthSchema, BatchSetAvailable, PageResultSchema
|
||||
from app.core.cache_util import cache
|
||||
from app.core.dependencies import AuthPermission
|
||||
from app.core.router_class import OperationLogRoute
|
||||
from fastapi_cache import FastAPICache
|
||||
from fastapi_cache.decorator import cache
|
||||
from app.utils.common_util import bytes2file_response
|
||||
|
||||
from .schema import (
|
||||
@@ -32,9 +32,9 @@ _ROLE_NS = "role"
|
||||
)
|
||||
@cache(expire=300, namespace=_ROLE_NS)
|
||||
async def get_role_list_controller(
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[RoleQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:role:query"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[RoleQueryParam, Query(description="角色查询参数")],
|
||||
) -> JSONResponse:
|
||||
order_by = [{"order": "asc"}]
|
||||
if page.order_by:
|
||||
@@ -53,8 +53,8 @@ async def get_role_list_controller(
|
||||
response_model=ResponseSchema[RoleOutSchema],
|
||||
)
|
||||
async def get_role_detail_controller(
|
||||
id: Annotated[int, Path(description="角色ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:role:detail"]))],
|
||||
id: Annotated[int, Path(description="角色ID")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await RoleService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取角色详情成功")
|
||||
@@ -65,11 +65,11 @@ async def get_role_detail_controller(
|
||||
response_model=ResponseSchema[RoleOutSchema],
|
||||
)
|
||||
async def create_role_controller(
|
||||
data: RoleCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:role:create"]))],
|
||||
data: Annotated[RoleCreateSchema, Body(description="角色创建参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await RoleService(auth).create(data=data)
|
||||
await cache_util.clear(namespace=_ROLE_NS)
|
||||
await FastAPICache.clear(namespace=_ROLE_NS)
|
||||
return SuccessResponse(data=result_dict, msg="创建角色成功")
|
||||
|
||||
@RoleRouter.put(
|
||||
@@ -78,12 +78,12 @@ async def create_role_controller(
|
||||
response_model=ResponseSchema[RoleOutSchema],
|
||||
)
|
||||
async def update_role_controller(
|
||||
data: RoleUpdateSchema,
|
||||
id: Annotated[int, Path(description="角色ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:role:update"]))],
|
||||
id: Annotated[int, Path(description="角色ID")],
|
||||
data: Annotated[RoleUpdateSchema, Body(description="角色修改参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await RoleService(auth).update(id=id, data=data)
|
||||
await cache_util.clear(namespace=_ROLE_NS)
|
||||
await FastAPICache.clear(namespace=_ROLE_NS)
|
||||
return SuccessResponse(data=result_dict, msg="修改角色成功")
|
||||
|
||||
@RoleRouter.delete(
|
||||
@@ -92,11 +92,11 @@ async def update_role_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def delete_role_controller(
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:role:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
) -> JSONResponse:
|
||||
await RoleService(auth).delete(ids=ids)
|
||||
await cache_util.clear(namespace=_ROLE_NS)
|
||||
await FastAPICache.clear(namespace=_ROLE_NS)
|
||||
return SuccessResponse(msg="删除角色成功")
|
||||
|
||||
@RoleRouter.patch(
|
||||
@@ -105,11 +105,11 @@ async def delete_role_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def batch_set_available_role_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:role:patch"]))],
|
||||
data: Annotated[BatchSetAvailable, Body(description="批量修改角色状态参数")],
|
||||
) -> JSONResponse:
|
||||
await RoleService(auth).set_available(data=data)
|
||||
await cache_util.clear(namespace=_ROLE_NS)
|
||||
await FastAPICache.clear(namespace=_ROLE_NS)
|
||||
return SuccessResponse(msg="批量修改角色状态成功")
|
||||
|
||||
@RoleRouter.put(
|
||||
@@ -118,11 +118,11 @@ async def batch_set_available_role_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def set_role_permission_controller(
|
||||
data: RolePermissionSettingSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:role:permission"]))],
|
||||
data: Annotated[RolePermissionSettingSchema, Body(description="角色授权参数")],
|
||||
) -> JSONResponse:
|
||||
await RoleService(auth).set_permission(data=data)
|
||||
await cache_util.clear(namespace=_ROLE_NS)
|
||||
await FastAPICache.clear(namespace=_ROLE_NS)
|
||||
return SuccessResponse(msg="授权角色成功")
|
||||
|
||||
@RoleRouter.get(
|
||||
@@ -131,8 +131,8 @@ async def set_role_permission_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def export_role_list_controller(
|
||||
search: Annotated[RoleQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:role:export"]))],
|
||||
search: Annotated[RoleQueryParam, Query(description="角色查询参数")],
|
||||
) -> StreamingResponse:
|
||||
role_query_result = await RoleService(auth).get_list(search=search)
|
||||
role_export_result = RoleService.export_list(role_list=role_query_result)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi import APIRouter, Depends, Query, Path, Body
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app.common.response import ResponseSchema, SuccessResponse
|
||||
@@ -22,9 +22,9 @@ TicketRouter = APIRouter(route_class=OperationLogRoute, prefix="/ticket", tags=[
|
||||
|
||||
@TicketRouter.get("/list", summary="工单列表", response_model=ResponseSchema[PageResultSchema[TicketOutSchema]])
|
||||
async def ticket_list_controller(
|
||||
search: Annotated[TicketQueryParam, Depends()],
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:ticket:list"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[TicketQueryParam, Query(description="工单查询参数")],
|
||||
) -> JSONResponse:
|
||||
result = await TicketService(auth).page(
|
||||
page_no=page.page_no,
|
||||
@@ -36,41 +36,41 @@ async def ticket_list_controller(
|
||||
|
||||
@TicketRouter.get("/detail/{id}", summary="获取工单详情", response_model=ResponseSchema[TicketOutSchema])
|
||||
async def ticket_detail_controller(
|
||||
id: int,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:ticket:detail"]))],
|
||||
id: Annotated[int, Path(description="工单ID")],
|
||||
) -> JSONResponse:
|
||||
result = await TicketService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result, msg="查询成功")
|
||||
|
||||
@TicketRouter.post("/create", summary="创建工单", response_model=ResponseSchema[TicketOutSchema])
|
||||
async def ticket_create_controller(
|
||||
data: TicketCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:ticket:create"]))],
|
||||
data: Annotated[TicketCreateSchema, Body(description="工单创建参数")],
|
||||
) -> JSONResponse:
|
||||
result = await TicketService(auth).create(data=data)
|
||||
return SuccessResponse(data=result, msg="创建成功")
|
||||
|
||||
@TicketRouter.put("/update/{id}", summary="更新工单", response_model=ResponseSchema[TicketOutSchema])
|
||||
async def ticket_update_controller(
|
||||
id: int,
|
||||
data: TicketUpdateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:ticket:update"]))],
|
||||
id: Annotated[int, Path(description="工单ID")],
|
||||
data: Annotated[TicketUpdateSchema, Body(description="工单更新参数")],
|
||||
) -> JSONResponse:
|
||||
result = await TicketService(auth).update(id=id, data=data)
|
||||
return SuccessResponse(data=result, msg="更新成功")
|
||||
|
||||
@TicketRouter.put("/batch", summary="批量更新工单", response_model=ResponseSchema)
|
||||
async def ticket_batch_update_controller(
|
||||
data: TicketBatchSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:ticket:update"]))],
|
||||
data: Annotated[TicketBatchSchema, Body(description="工单批量更新参数")],
|
||||
) -> JSONResponse:
|
||||
await TicketService(auth).batch(data=data)
|
||||
return SuccessResponse(msg="批量操作成功")
|
||||
|
||||
@TicketRouter.delete("/delete", summary="删除工单", response_model=ResponseSchema[None])
|
||||
async def ticket_delete_controller(
|
||||
ids: list[int],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:ticket:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="工单ID列表")],
|
||||
) -> JSONResponse:
|
||||
await TicketService(auth).delete(ids=ids)
|
||||
return SuccessResponse(msg="删除成功")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import urllib.parse
|
||||
from typing import Annotated
|
||||
|
||||
from fastapi import APIRouter, Body, Depends, Path, UploadFile
|
||||
from fastapi import APIRouter, Body, Depends, Path, Query, File, UploadFile
|
||||
from fastapi.responses import JSONResponse, StreamingResponse
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -45,8 +45,8 @@ async def get_current_user_info_controller(
|
||||
response_model=ResponseSchema[UserOutSchema],
|
||||
)
|
||||
async def update_current_user_info_controller(
|
||||
data: CurrentUserUpdateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
data: Annotated[CurrentUserUpdateSchema, Body(description="更新用户基本信息参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService(auth).update_current_info(data=data)
|
||||
return SuccessResponse(data=result_dict, msg="更新当前用户基本信息成功")
|
||||
@@ -57,8 +57,8 @@ async def update_current_user_info_controller(
|
||||
response_model=ResponseSchema[UserOutSchema],
|
||||
)
|
||||
async def change_current_user_password_controller(
|
||||
data: UserChangePasswordSchema,
|
||||
auth: Annotated[AuthSchema, Depends(get_current_user)],
|
||||
data: Annotated[UserChangePasswordSchema, Body(description="修改用户密码参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService(auth).change_password(data=data)
|
||||
return SuccessResponse(data=result_dict, msg="修改密码成功, 请重新登录")
|
||||
@@ -69,9 +69,9 @@ async def change_current_user_password_controller(
|
||||
response_model=ResponseSchema[UserOutSchema],
|
||||
)
|
||||
async def reset_password_controller(
|
||||
id: Annotated[int, Path(description="用户ID")],
|
||||
data: ResetPasswordSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:update"]))],
|
||||
id: Annotated[int, Path(description="用户ID")],
|
||||
data: Annotated[ResetPasswordSchema, Body(description="重置用户密码参数")],
|
||||
) -> JSONResponse:
|
||||
data.id = id
|
||||
result_dict = await UserService(auth).reset_password(data=data)
|
||||
@@ -83,8 +83,8 @@ async def reset_password_controller(
|
||||
response_model=ResponseSchema[UserOutSchema],
|
||||
)
|
||||
async def register_user_controller(
|
||||
data: UserRegisterSchema,
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
data: Annotated[UserRegisterSchema, Body(description="注册用户参数")],
|
||||
) -> JSONResponse:
|
||||
auth = AuthSchema(db=db, check_data_scope=False)
|
||||
user_register_result = await UserService(auth).register(data=data)
|
||||
@@ -97,8 +97,8 @@ async def register_user_controller(
|
||||
response_model=ResponseSchema[UserOutSchema],
|
||||
)
|
||||
async def forget_password_controller(
|
||||
data: UserForgetPasswordSchema,
|
||||
db: Annotated[AsyncSession, Depends(db_getter)],
|
||||
data: Annotated[UserForgetPasswordSchema, Body(description="忘记密码参数")],
|
||||
) -> JSONResponse:
|
||||
auth = AuthSchema(db=db, check_data_scope=False)
|
||||
user_forget_password_result = await UserService(auth).forget_password(data=data)
|
||||
@@ -111,9 +111,9 @@ async def forget_password_controller(
|
||||
response_model=ResponseSchema[PageResultSchema[UserOutSchema]],
|
||||
)
|
||||
async def get_user_list_controller(
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[UserQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:query"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[UserQueryParam, Query(description="用户查询参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService(auth).page(
|
||||
page_no=page.page_no,
|
||||
@@ -129,8 +129,8 @@ async def get_user_list_controller(
|
||||
response_model=ResponseSchema[UserOutSchema],
|
||||
)
|
||||
async def get_user_detail_controller(
|
||||
id: Annotated[int, Path(description="用户ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:detail"]))],
|
||||
id: Annotated[int, Path(description="用户ID")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService(auth).detail(id=id)
|
||||
return SuccessResponse(data=result_dict, msg="获取用户详情成功")
|
||||
@@ -141,8 +141,8 @@ async def get_user_detail_controller(
|
||||
response_model=ResponseSchema[UserOutSchema],
|
||||
)
|
||||
async def create_user_controller(
|
||||
data: UserCreateSchema,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:create"]))],
|
||||
data: Annotated[UserCreateSchema, Body(description="创建用户参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService(auth).create(data=data)
|
||||
return SuccessResponse(data=result_dict, msg="创建用户成功")
|
||||
@@ -153,9 +153,9 @@ async def create_user_controller(
|
||||
response_model=ResponseSchema[UserOutSchema],
|
||||
)
|
||||
async def update_user_controller(
|
||||
data: UserUpdateSchema,
|
||||
id: Annotated[int, Path(description="用户ID")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:update"]))],
|
||||
id: Annotated[int, Path(description="用户ID")],
|
||||
data: Annotated[UserUpdateSchema, Body(description="修改用户参数")],
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService(auth).update(id=id, data=data)
|
||||
return SuccessResponse(data=result_dict, msg="修改用户成功")
|
||||
@@ -166,8 +166,8 @@ async def update_user_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def delete_user_controller(
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:delete"]))],
|
||||
ids: Annotated[list[int], Body(description="ID列表")],
|
||||
) -> JSONResponse:
|
||||
await UserService(auth).delete(ids=ids)
|
||||
return SuccessResponse(msg="删除用户成功")
|
||||
@@ -178,8 +178,8 @@ async def delete_user_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def batch_set_available_user_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:patch"]))],
|
||||
data: Annotated[BatchSetAvailable, Body(description="批量修改用户状态参数")],
|
||||
) -> JSONResponse:
|
||||
await UserService(auth).set_available(data=data)
|
||||
return SuccessResponse(msg="批量修改用户状态成功")
|
||||
@@ -208,9 +208,9 @@ async def export_user_import_template_controller() -> StreamingResponse:
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def export_user_list_controller(
|
||||
page: Annotated[PaginationQueryParam, Depends()],
|
||||
search: Annotated[UserQueryParam, Depends()],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:export"]))],
|
||||
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
|
||||
search: Annotated[UserQueryParam, Query(description="用户查询参数")],
|
||||
) -> StreamingResponse:
|
||||
user_list = await UserService(auth).get_list(search=search, order_by=page.order_by)
|
||||
user_export_result = UserService.export_list(user_list=user_list)
|
||||
@@ -227,7 +227,7 @@ async def export_user_list_controller(
|
||||
response_model=ResponseSchema[None],
|
||||
)
|
||||
async def import_user_list_controller(
|
||||
file: UploadFile,
|
||||
file: Annotated[UploadFile, File(description="用户导入文件")],
|
||||
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:user:import"]))],
|
||||
) -> JSONResponse:
|
||||
batch_import_result = await UserService(auth).batch_import(file=file, update_support=True)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import io
|
||||
from typing import Any
|
||||
|
||||
import pandas as pd
|
||||
from fastapi import UploadFile
|
||||
|
||||
from app.api.v1.module_platform.menu.crud import MenuCRUD
|
||||
@@ -304,23 +303,26 @@ class UserService:
|
||||
|
||||
try:
|
||||
contents = await file.read()
|
||||
df = pd.read_excel(io.BytesIO(contents))
|
||||
rows = ExcelUtil.read_excel_to_dicts(contents)
|
||||
await file.close()
|
||||
|
||||
if df.empty:
|
||||
if not rows:
|
||||
raise CustomException(msg="导入文件为空")
|
||||
|
||||
missing_headers = [header for header in header_dict if header not in df.columns]
|
||||
missing_headers = [h for h in header_dict if h not in rows[0]]
|
||||
if missing_headers:
|
||||
raise CustomException(msg=f"导入文件缺少必要的列: {', '.join(missing_headers)}")
|
||||
|
||||
df.rename(columns=header_dict, inplace=True)
|
||||
# 将中文字段名映射为英文字段
|
||||
mapped_rows = []
|
||||
for row in rows:
|
||||
mapped_rows.append({en: row.get(ch) for ch, en in header_dict.items()})
|
||||
|
||||
required_fields = ["username", "name", "dept_id"]
|
||||
errors = []
|
||||
for field in required_fields:
|
||||
if df[field].isnull().any():
|
||||
missing_count = df[field].isnull().sum()
|
||||
missing_count = sum(1 for r in mapped_rows if r.get(field) is None)
|
||||
if missing_count:
|
||||
errors.append(f"字段'{field}'有{missing_count}行缺少数据")
|
||||
|
||||
if errors:
|
||||
@@ -329,10 +331,10 @@ class UserService:
|
||||
success_count = 0
|
||||
error_msgs = []
|
||||
|
||||
for i, (_, row) in enumerate(df.iterrows(), start=2):
|
||||
for i, row in enumerate(mapped_rows, start=2):
|
||||
try:
|
||||
username = str(row["username"]).strip() if pd.notna(row["username"]) else ""
|
||||
name = str(row["name"]).strip() if pd.notna(row["name"]) else ""
|
||||
username = (str(row["username"]) if row["username"] is not None else "").strip()
|
||||
name = (str(row["name"]) if row["name"] is not None else "").strip()
|
||||
if not username:
|
||||
error_msgs.append(f"第{i}行: 账号不能为空")
|
||||
continue
|
||||
@@ -343,9 +345,9 @@ class UserService:
|
||||
user_data = {
|
||||
"username": username,
|
||||
"name": name,
|
||||
"email": str(row["email"]).strip() if pd.notna(row["email"]) else None,
|
||||
"mobile": str(row["mobile"]).strip() if pd.notna(row["mobile"]) else None,
|
||||
"gender": str(row["gender"]).strip() if pd.notna(row["gender"]) else "1",
|
||||
"email": str(row["email"]).strip() if row.get("email") is not None else None,
|
||||
"mobile": str(row["mobile"]).strip() if row.get("mobile") is not None else None,
|
||||
"gender": str(row["gender"]).strip() if row.get("gender") is not None else "1",
|
||||
"status": 0 if str(row["status"]).strip() == "正常" else 1,
|
||||
"dept_id": int(row["dept_id"]),
|
||||
"password": PwdUtil.hash_password(password="123456"),
|
||||
|
||||
Reference in New Issue
Block a user