refactor: 重构项目模块结构与代码细节优化

1.  调整后端模块路由与插件文件结构,迁移部分模块代码至api/v1目录
2.  优化代码注释格式与文档字符串,简化冗余代码
3.  添加监控仪表盘、工单评论等新模块功能
4.  修复前端部分组件交互逻辑与类型定义
5.  清理冗余的初始化数据与废弃配置文件
6.  新增租户注册表单字段与国际化支持
7.  优化HTTP请求拦截器与快捷键功能
This commit is contained in:
zhangtao
2026-07-10 00:18:11 +08:00
parent 349ab7b525
commit 5ff72b086f
323 changed files with 7633 additions and 15306 deletions
@@ -0,0 +1,94 @@
from typing import Annotated
from fastapi import APIRouter, Body, Depends, Path, Query, Security, status
from fastapi.responses import JSONResponse
from sqlalchemy.ext.asyncio import AsyncSession
from app.common.response import ResponseSchema, SuccessResponse
from app.core.base_schema import AuthSchema, PageResultSchema, PaginationQueryParam
from app.core.dependencies import AuthPermission, db_getter
from app.core.router_class import OperationLogRoute
from .schema import (
VersionCreateSchema,
VersionOutSchema,
VersionQueryParam,
VersionStatusSchema,
VersionUpdateSchema,
)
from .service import VersionService
VersionRouter = APIRouter(route_class=OperationLogRoute, prefix="/versions", tags=["版本管理"])
@VersionRouter.get("/list", summary="分页查询版本", response_model=ResponseSchema[PageResultSchema[VersionOutSchema]])
async def get_version_list_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_system:version:query"]))],
page: Annotated[PaginationQueryParam, Query(description="分页参数")],
search: Annotated[VersionQueryParam, Query(description="查询参数")],
) -> JSONResponse:
service = VersionService(auth)
result = await service.page(page_no=page.page_no, page_size=page.page_size, search=search)
return SuccessResponse(data=result, msg="查询版本列表成功")
@VersionRouter.get("/published", summary="已发布版本列表", response_model=ResponseSchema[list[VersionOutSchema]])
async def get_published_versions_controller(
db: Annotated[AsyncSession, Depends(db_getter)],
) -> JSONResponse:
auth = AuthSchema.anonymous(db=db)
service = VersionService(auth)
result = await service.get_published()
return SuccessResponse(data=result, msg="查询成功")
@VersionRouter.get("/detail/{id}", summary="获取版本详情", response_model=ResponseSchema[VersionOutSchema])
async def get_version_detail_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_system:version:detail"]))],
id: Annotated[int, Path(description="版本ID")],
) -> JSONResponse:
service = VersionService(auth)
result = await service.detail(id=id)
return SuccessResponse(data=result, msg="获取版本详情成功")
@VersionRouter.post("/create", status_code=status.HTTP_201_CREATED, summary="创建版本", response_model=ResponseSchema[VersionOutSchema])
async def create_version_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_system:version:create"]))],
data: Annotated[VersionCreateSchema, Body(description="创建参数")],
) -> JSONResponse:
service = VersionService(auth)
result = await service.create(data=data)
return SuccessResponse(data=result, msg="创建版本成功")
@VersionRouter.put("/update/{id}", summary="修改版本", response_model=ResponseSchema[VersionOutSchema])
async def update_version_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_system:version:update"]))],
id: Annotated[int, Path(description="版本ID")],
data: Annotated[VersionUpdateSchema, Body(description="修改参数")],
) -> JSONResponse:
service = VersionService(auth)
result = await service.update(id=id, data=data)
return SuccessResponse(data=result, msg="修改版本成功")
@VersionRouter.delete("/delete", summary="删除版本", response_model=ResponseSchema[None])
async def delete_version_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_system:version:delete"]))],
ids: Annotated[list[int], Body(description="ID列表")],
) -> JSONResponse:
service = VersionService(auth)
await service.delete(ids=ids)
return SuccessResponse(msg="删除版本成功")
@VersionRouter.put("/{id}/status", summary="变更版本状态", response_model=ResponseSchema[VersionOutSchema])
async def set_version_status_controller(
auth: Annotated[AuthSchema, Security(AuthPermission(["module_system:version:update"]))],
id: Annotated[int, Path(description="版本ID")],
data: Annotated[VersionStatusSchema, Body(description="状态参数")],
) -> JSONResponse:
service = VersionService(auth)
result = await service.set_status(id=id, data=data)
return SuccessResponse(data=result, msg="状态变更成功")
@@ -0,0 +1,23 @@
from app.core.base_crud import CRUDBase
from app.core.base_schema import AuthSchema
from app.core.exceptions import CustomException
from .model import VersionModel
from .schema import VersionCreateSchema, VersionUpdateSchema
class VersionCRUD(CRUDBase[VersionModel, VersionCreateSchema, VersionUpdateSchema]):
"""版本数据层"""
def __init__(self, auth: AuthSchema) -> None:
super().__init__(model=VersionModel, auth=auth)
async def set_status(self, id: int, status: int) -> VersionModel:
"""更新版本状态"""
obj = await self.get(id=id)
if not obj:
raise CustomException(msg="版本不存在")
obj.status = status
await self.db.flush()
await self.db.refresh(obj)
return obj
@@ -0,0 +1,25 @@
from sqlalchemy import Boolean, Integer, String, Text
from sqlalchemy.orm import Mapped, mapped_column
from app.core.base_model import ModelMixin, UserMixin
class VersionModel(ModelMixin, UserMixin):
"""版本管理(平台级)"""
__tablename__: str = "sys_version"
__table_args__: dict[str, str] = {"comment": "版本管理表"}
__loader_options__: list[str] = [
"created_by",
"updated_by",
"deleted_by",
]
version: Mapped[str] = mapped_column(String(50), nullable=False, comment="版本号")
title: Mapped[str] = mapped_column(String(200), nullable=False, comment="版本标题")
date: Mapped[str] = mapped_column(String(50), nullable=False, comment="发布日期")
content: Mapped[str | None] = mapped_column(Text, nullable=True, default=None, comment="版本富文本内容")
description: Mapped[str | None] = mapped_column(String(500), nullable=True, default=None, comment="备注")
sort: Mapped[int] = mapped_column(Integer, default=0, nullable=False, comment="排序")
status: Mapped[int] = mapped_column(Integer, default=0, nullable=False, comment="状态: 0=草稿,1=已发布,2=已回滚")
require_re_login: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False, comment="是否需要重新登录")
@@ -0,0 +1,49 @@
from pydantic import BaseModel, ConfigDict, Field, field_validator
from app.core.base_schema import BaseQueryParam
class VersionCreateSchema(BaseModel):
"""版本创建模型"""
version: str = Field(..., description="版本号")
title: str = Field(..., description="更新标题")
date: str = Field(..., description="发布日期")
content: str | None = Field(default=None, description="更新内容(富文本HTML)")
description: str | None = Field(default=None, description="备注")
sort: int = Field(default=0, description="排序")
status: int = Field(default=0, description="状态: 0=草稿,1=已发布,2=已回滚")
require_re_login: bool = Field(default=False, description="是否需要重新登录")
class VersionUpdateSchema(VersionCreateSchema):
"""版本更新模型"""
class VersionOutSchema(VersionCreateSchema):
"""版本响应模型"""
model_config = ConfigDict(from_attributes=True)
id: int = Field(description="主键ID")
created_time: str | None = Field(default=None, description="创建时间")
updated_time: str | None = Field(default=None, description="更新时间")
class VersionStatusSchema(BaseModel):
"""版本状态更新模型"""
status: int = Field(..., description="状态: 0=草稿,1=已发布,2=已回滚")
@field_validator("status")
@classmethod
def validate_status(cls, v: int) -> int:
if v not in (0, 1, 2):
raise ValueError("status must be 0, 1, or 2")
return v
class VersionQueryParam(BaseQueryParam):
"""版本查询参数"""
status: int | None = Field(default=None, description="状态: 0=草稿,1=已发布,2=已回滚")
@@ -0,0 +1,72 @@
from app.core.base_schema import AuthSchema, PageResultSchema
from app.core.exceptions import CustomException
from .crud import VersionCRUD
from .schema import (
VersionCreateSchema,
VersionOutSchema,
VersionQueryParam,
VersionStatusSchema,
VersionUpdateSchema,
)
class VersionService:
"""版本管理模块服务层"""
def __init__(self, auth: AuthSchema) -> None:
self.auth = auth
async def detail(self, id: int) -> VersionOutSchema:
obj = await VersionCRUD(self.auth).get(id=id)
if not obj:
raise CustomException(msg="该数据不存在")
return VersionOutSchema.model_validate(obj)
async def page(
self,
page_no: int,
page_size: int,
search: VersionQueryParam | None = None,
order_by: list[dict[str, str]] | None = None,
) -> PageResultSchema[VersionOutSchema]:
offset = (page_no - 1) * page_size
return await VersionCRUD(self.auth).page(
offset=offset,
limit=page_size,
order_by=order_by or [{"sort": "asc"}, {"id": "desc"}],
search=vars(search) if search else {},
out_schema=VersionOutSchema,
)
async def create(self, data: VersionCreateSchema) -> VersionOutSchema:
obj = await VersionCRUD(self.auth).create(data=data)
return VersionOutSchema.model_validate(obj)
async def update(self, id: int, data: VersionUpdateSchema) -> VersionOutSchema:
obj = await VersionCRUD(self.auth).get(id=id)
if not obj:
raise CustomException(msg="更新失败,该数据不存在")
obj = await VersionCRUD(self.auth).update(id=id, data=data)
return VersionOutSchema.model_validate(obj)
async def delete(self, ids: list[int]) -> None:
if len(ids) < 1:
raise CustomException(msg="删除失败,删除对象不能为空")
objs = await VersionCRUD(self.auth).get_list(search={"id": ("in", ids)})
obj_map = {o.id: o for o in objs}
for id_ in ids:
if id_ not in obj_map:
raise CustomException(msg="删除失败,该数据不存在")
await VersionCRUD(self.auth).delete(ids=ids)
async def set_status(self, id: int, data: VersionStatusSchema) -> VersionOutSchema:
obj = await VersionCRUD(self.auth).set_status(id=id, status=data.status)
return VersionOutSchema.model_validate(obj)
async def get_published(self) -> list[VersionOutSchema]:
objs = await VersionCRUD(self.auth).get_list(
search={"status": ("eq", 1)},
order_by=[{"sort": "asc"}],
)
return [VersionOutSchema.model_validate(obj) for obj in objs]