refactor: 统一项目代码风格并修复多处类型与调用问题

本次提交包含多项优化:
1.  移除大量冗余的文件头注释与过时的from __future__导入
2.  将CRUD的list方法统一重命名为get_list保持接口一致
3.  修复前后端状态字段类型不匹配问题,将string类型status改为number
4.  修正前端文案错别字,将"代办事项"修正为标准写法
5.  更新sqlalchemy版本并调整依赖配置
6.  新增缓存工具类替代fastapi-cache2,重构缓存调用逻辑
7.  新增开源授权函生成相关工具与数据库字段支持
8.  为多个业务模块添加防重复提交loading状态
9.  修复邮件模型的外键关联缺失问题
10. 优化pdf生成工具的导入时机与文档注释
This commit is contained in:
zhangtao
2026-06-21 17:34:11 +08:00
parent 3169ef2355
commit 7d2367e34e
106 changed files with 1968 additions and 966 deletions
@@ -2,13 +2,13 @@ from typing import Annotated
from fastapi import APIRouter, Body, Depends, Path
from fastapi.responses import JSONResponse, StreamingResponse
from fastapi_cache import FastAPICache
from fastapi_cache.decorator import cache
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 app.core.router_class import OperationLogRoute
from app.utils.common_util import bytes2file_response
@@ -68,7 +68,7 @@ async def get_type_list_controller(
async def get_type_optionselect_controller(
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:query"]))],
) -> JSONResponse:
result_dict_list = await DictTypeService(auth).list()
result_dict_list = await DictTypeService(auth).get_list()
return SuccessResponse(data=result_dict_list, msg="获取字典类型列表成功")
@DictRouter.post(
@@ -82,7 +82,7 @@ async def create_type_controller(
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:create"]))],
) -> JSONResponse:
result_dict = await DictTypeService(auth).create(redis=redis, data=data)
await FastAPICache.clear(namespace=_DICT_TYPE_NS)
await cache_util.clear(namespace=_DICT_TYPE_NS)
return SuccessResponse(data=result_dict, msg="创建字典类型成功")
@DictRouter.put(
@@ -97,7 +97,7 @@ async def update_type_controller(
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:update"]))],
) -> JSONResponse:
result_dict = await DictTypeService(auth).update(redis=redis, id=id, data=data)
await FastAPICache.clear(namespace=_DICT_TYPE_NS)
await cache_util.clear(namespace=_DICT_TYPE_NS)
return SuccessResponse(data=result_dict, msg="修改字典类型成功")
@DictRouter.delete(
@@ -111,7 +111,7 @@ async def delete_type_controller(
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:delete"]))],
) -> JSONResponse:
await DictTypeService(auth).delete(redis=redis, ids=ids)
await FastAPICache.clear(namespace=_DICT_TYPE_NS)
await cache_util.clear(namespace=_DICT_TYPE_NS)
return SuccessResponse(msg="删除字典类型成功")
@DictRouter.patch(
@@ -124,7 +124,7 @@ async def batch_set_available_dict_type_controller(
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:patch"]))],
) -> JSONResponse:
await DictTypeService(auth).set_available(data=data)
await FastAPICache.clear(namespace=_DICT_TYPE_NS)
await cache_util.clear(namespace=_DICT_TYPE_NS)
return SuccessResponse(msg="批量修改字典类型状态成功")
@DictRouter.post(
@@ -137,7 +137,7 @@ async def export_type_list_controller(
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_type:export"]))],
) -> StreamingResponse:
# 获取全量数据并转为dict列表
result_dict_list = await DictTypeService(auth).list(search=search)
result_dict_list = await DictTypeService(auth).get_list(search=search)
export_data = [item.model_dump() for item in result_dict_list]
export_result = DictTypeService.export(data_list=export_data)
@@ -242,7 +242,7 @@ async def export_data_list_controller(
page: Annotated[PaginationQueryParam, Depends()],
auth: Annotated[AuthSchema, Depends(AuthPermission(["module_system:dict_data:export"]))],
) -> StreamingResponse:
result_dict_list = await DictDataService(auth).list(search=search, order_by=page.order_by)
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]
export_result = DictDataService.export(data_list=export_data)
@@ -54,7 +54,7 @@ class DictDataCRUD(CRUDBase[DictDataModel, DictDataCreateSchema, DictDataUpdateS
- int: 删除的记录数量
"""
if exclude_system:
system_data = await self.list(
system_data = await self.get_list(
search={
"id__in": ids,
"remark__contains": "系统默认",
@@ -81,4 +81,4 @@ class DictDataCRUD(CRUDBase[DictDataModel, DictDataCreateSchema, DictDataUpdateS
search = {"dict_type": dict_type}
if status is not None:
search["status"] = status
return await self.list(search=search, order_by=[{"id": "asc"}])
return await self.get_list(search=search, order_by=[{"id": "asc"}])
@@ -47,7 +47,7 @@ class DictTypeService:
"""
return await DictTypeCRUD(self.auth).get_or_404(id=id, out_schema=DictTypeOutSchema)
async def list(
async def get_list(
self,
search: DictTypeQueryParam | None = None,
order_by: list[dict] | None = None,
@@ -62,7 +62,7 @@ class DictTypeService:
返回:
- list[DictTypeOutSchema]: 字典类型响应模型列表
"""
obj_list = await DictTypeCRUD(self.auth).list(search=vars(search) if search else None, order_by=order_by)
obj_list = await DictTypeCRUD(self.auth).get_list(search=vars(search) if search else None, order_by=order_by)
return [DictTypeOutSchema.model_validate(obj) for obj in obj_list]
async def page(
@@ -149,7 +149,7 @@ class DictTypeService:
# 如果字典类型修改或状态变更,则修改对应字典数据的类型和状态
if exist_obj.dict_type != data.dict_type or exist_obj.status != data.status:
exist_obj_type_list = await DictDataCRUD(self.auth).list(search={"dict_type": exist_obj.dict_type})
exist_obj_type_list = await DictDataCRUD(self.auth).get_list(search={"dict_type": exist_obj.dict_type})
if exist_obj_type_list:
for item in exist_obj_type_list:
item.dict_type = data.dict_type
@@ -174,7 +174,7 @@ class DictTypeService:
redis_key = f"{RedisInitKeyConfig.SYSTEM_DICT.key}:{self.auth.user.tenant_id}:{data.dict_type}"
try:
# 获取当前字典类型的所有字典数据,确保包含最新状态
dict_data_list = await DictDataCRUD(self.auth).list(search={"dict_type": data.dict_type})
dict_data_list = await DictDataCRUD(self.auth).get_list(search={"dict_type": data.dict_type})
dict_data = [DictDataOutSchema.model_validate(row).model_dump(mode="json") for row in dict_data_list if row]
value = json.dumps(dict_data, ensure_ascii=False)
@@ -203,14 +203,14 @@ class DictTypeService:
"""
if len(ids) < 1:
raise CustomException(msg="删除失败,删除对象不能为空")
existing = await DictTypeCRUD(self.auth).list(search={"id": ("in", ids)})
existing = await DictTypeCRUD(self.auth).get_list(search={"id": ("in", ids)})
existing_map = {obj.id: obj for obj in existing}
for nid in ids:
if nid not in existing_map:
raise CustomException(msg="删除失败,该数据不存在")
exist_obj = existing_map[nid]
# 检查是否有字典数据
exist_obj_type_list = await DictDataCRUD(self.auth).list(search={"dict_type": exist_obj.dict_type})
exist_obj_type_list = await DictDataCRUD(self.auth).get_list(search={"dict_type": exist_obj.dict_type})
if len(exist_obj_type_list) > 0:
# 如果有字典数据,不能删除
raise CustomException(msg="删除失败,该数据字典类型下存在字典数据")
@@ -290,7 +290,7 @@ class DictDataService:
"""
return await DictDataCRUD(self.auth).get_or_404(id=id, out_schema=DictDataOutSchema)
async def list(
async def get_list(
self,
search: DictDataQueryParam | None = None,
order_by: list[dict] | None = None,
@@ -305,7 +305,7 @@ class DictDataService:
返回:
- list[DictDataOutSchema]: 字典数据响应模型列表
"""
obj_list = await DictDataCRUD(self.auth).list(search=vars(search) if search else None, order_by=order_by)
obj_list = await DictDataCRUD(self.auth).get_list(search=vars(search) if search else None, order_by=order_by)
return [DictDataOutSchema.model_validate(obj) for obj in obj_list]
async def page(
@@ -351,7 +351,7 @@ class DictDataService:
async with async_db_session() as session:
async with session.begin():
init_auth = AuthSchema(db=session, check_data_scope=False)
obj_list = await DictTypeCRUD(init_auth).list()
obj_list = await DictTypeCRUD(init_auth).get_list()
if not obj_list:
logger.warning("未找到任何字典类型数据")
return
@@ -360,7 +360,7 @@ class DictDataService:
dict_type = obj.dict_type
tenant_id = obj.tenant_id
try:
dict_data_list = await DictDataCRUD(init_auth).list(
dict_data_list = await DictDataCRUD(init_auth).get_list(
search={"dict_type": dict_type, "tenant_id": tenant_id}
)
dict_data = [
@@ -452,7 +452,7 @@ class DictDataService:
redis_key = f"{RedisInitKeyConfig.SYSTEM_DICT.key}:{self.auth.user.tenant_id}:{data.dict_type}"
try:
# 获取当前字典类型的所有字典数据
dict_data_list = await DictDataCRUD(self.auth).list(search={"dict_type": data.dict_type})
dict_data_list = await DictDataCRUD(self.auth).get_list(search={"dict_type": data.dict_type})
dict_data = [DictDataOutSchema.model_validate(row).model_dump(mode="json") for row in dict_data_list if row]
value = json.dumps(dict_data, ensure_ascii=False)
@@ -505,7 +505,7 @@ class DictDataService:
if dict_type:
redis_key = f"{RedisInitKeyConfig.SYSTEM_DICT.key}:{self.auth.user.tenant_id}:{dict_type.dict_type}"
try:
dict_data_list = await DictDataCRUD(self.auth).list(search={"dict_type": dict_type.dict_type})
dict_data_list = await DictDataCRUD(self.auth).get_list(search={"dict_type": dict_type.dict_type})
dict_data = [DictDataOutSchema.model_validate(row).model_dump(mode="json") for row in dict_data_list if row]
value = json.dumps(dict_data, ensure_ascii=False)
await RedisCURD(redis).set(
@@ -522,7 +522,7 @@ class DictDataService:
# 刷新新字典类型缓存
redis_key = f"{RedisInitKeyConfig.SYSTEM_DICT.key}:{self.auth.user.tenant_id}:{data.dict_type}"
try:
dict_data_list = await DictDataCRUD(self.auth).list(search={"dict_type": data.dict_type})
dict_data_list = await DictDataCRUD(self.auth).get_list(search={"dict_type": data.dict_type})
dict_data = [DictDataOutSchema.model_validate(row).model_dump(mode="json") for row in dict_data_list if row]
value = json.dumps(dict_data, ensure_ascii=False)
await RedisCURD(redis).set(
@@ -550,7 +550,7 @@ class DictDataService:
"""
if len(ids) < 1:
raise CustomException(msg="删除失败,删除对象不能为空")
existing = await DictDataCRUD(self.auth).list(search={"id": ("in", ids)})
existing = await DictDataCRUD(self.auth).get_list(search={"id": ("in", ids)})
existing_map = {obj.id: obj for obj in existing}
for nid in ids:
if nid not in existing_map:
@@ -560,7 +560,7 @@ class DictDataService:
redis_key = f"{RedisInitKeyConfig.SYSTEM_DICT.key}:{self.auth.user.tenant_id}:{exist_obj.dict_type}"
try:
# 重新拉取该类型所有字典数据并写回缓存(保持一致)
dict_data_list = await DictDataCRUD(self.auth).list(search={"dict_type": exist_obj.dict_type})
dict_data_list = await DictDataCRUD(self.auth).get_list(search={"dict_type": exist_obj.dict_type})
dict_data = [DictDataOutSchema.model_validate(row).model_dump(mode="json") for row in dict_data_list if row]
value = json.dumps(dict_data, ensure_ascii=False)
await RedisCURD(redis).set(