Merge pull request #169 from 1014TaoTao/v2.0.0

V2.0.0
This commit is contained in:
fastapiadmin
2025-09-16 00:43:30 +08:00
committed by GitHub
18 changed files with 328 additions and 9 deletions
+4 -2
View File
@@ -12,6 +12,8 @@ from .module_system.position.controller import PositionRouter
from .module_system.notice.controller import NoticeRouter
from .module_system.params.controller import ParamsRouter
from .module_system.dict.controller import DictRouter
from .module_system.ticket.controller import router as TicketRouter
from .module_system.version.controller import router as VersionRouter
from .module_monitor.cache.controller import CacheRouter
from .module_monitor.job.controller import JobRouter
@@ -28,8 +30,6 @@ from .module_application.myapp.controller import MyAppRouter
from .module_ai.mcp.controller import MCPRouter
from .module_resource.resource.controller import ResourceRouter
# 定义路由模块映射,按模块分组
SYSTEM_MODULES = [
@@ -43,6 +43,8 @@ SYSTEM_MODULES = [
{"router": NoticeRouter},
{"router": ParamsRouter},
{"router": DictRouter},
{"router": TicketRouter},
{"router": VersionRouter},
]
MONITOR_MODULES = [
@@ -25,5 +25,4 @@ class PositionModel(CreatorMixin):
# 用户关联关系
users: Mapped[List["UserModel"]] = relationship(secondary="system_user_positions", back_populates="positions", lazy="selectin")
# users: Mapped[List["UserModel"]] = relationship(secondary="system_user_positions", back_populates="positions", lazy="select")
@@ -23,10 +23,6 @@ class PositionOutSchema(PositionCreateSchema, BaseSchema):
"""岗位信息响应模型"""
model_config = ConfigDict(from_attributes=True)
class PositionOptionsOut(PositionCreateSchema):
model_config = ConfigDict(from_attributes=True)
id: int = Field(..., description="主键ID")
created_at: DateTimeStr = Field(..., description="创建时间")
updated_at: DateTimeStr = Field(..., description="更新时间")
@@ -0,0 +1 @@
# 工单管理模块
@@ -0,0 +1,4 @@
from fastapi import APIRouter
router = APIRouter(prefix="/tickets", tags=["工单管理"])
@@ -0,0 +1,16 @@
from sqlalchemy.orm import Session
from typing import List
from app.api.v1.module_system.ticket.model import Ticket
from app.api.v1.module_system.ticket.schema import TicketCreate, TicketUpdate
from app.core.base_crud import CRUDBase
from ..auth.schema import AuthSchema
class CRUDTicket(CRUDBase[Ticket, TicketCreate, TicketUpdate]):
"""工单 CRUD 操作"""
def __init__(self, auth: AuthSchema) -> None:
"""初始化工单CRUD"""
self.auth = auth
super().__init__(model=Ticket, auth=auth)
pass
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey
from sqlalchemy.orm import relationship
from datetime import datetime
from app.core.base_model import MappedBase, CreatorMixin
class Ticket(CreatorMixin):
"""工单模型"""
__tablename__ = "ticket"
title = Column(String(255), nullable=False, comment="工单标题")
status = Column(String(50), default="1", comment="工单状态(1:待处理 2:处理中 3:已解决 4:已关闭)")
priority = Column(String(50), default="medium", comment="优先级(low, medium, high, urgent)")
type = Column(String(50), comment="工单类型(bug, feature, task)")
assignee_id = Column(Integer, ForeignKey("system_user.id"), comment="指派给用户ID")
reporter_id = Column(Integer, ForeignKey("system_user.id"), comment="报告人ID")
project = Column(String(100), comment="所属项目")
version = Column(String(50), comment="版本号")
# 关系
assignee = relationship("UserModel", foreign_keys=[assignee_id])
reporter = relationship("UserModel", foreign_keys=[reporter_id])
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from typing import Optional
from fastapi import Query
from app.core.validator import DateTimeStr
class TicketQueryParams:
"""工单管理查询参数"""
def __init__(
self,
title: Optional[str] = Query(None, description="工单标题"),
status: Optional[bool] = Query(None, description="是否可用"),
creator: Optional[int] = Query(None, description="创建人"),
start_time: Optional[DateTimeStr] = Query(None, description="开始时间", example="2023-01-01 00:00:00"),
end_time: Optional[DateTimeStr] = Query(None, description="结束时间", example="2023-12-31 23:59:59"),
) -> None:
super().__init__()
# 模糊查询字段
self.title = ("like", title)
# 精确查询字段
self.creator_id = creator
self.status = status
# 时间范围查询
if start_time and end_time:
start_datetime = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')
end_datetime = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
self.created_at = ("between", (start_datetime, end_datetime))
@@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
from pydantic import BaseModel
from typing import Optional, List
from datetime import datetime
class TicketCreate(BaseModel):
"""创建工单"""
title: str
description: Optional[str] = None
status: Optional[str] = "open"
priority: Optional[str] = "medium"
type: Optional[str] = "bug"
assignee_id: Optional[int] = None
reporter_id: int
project: Optional[str] = None
version: Optional[str] = None
class TicketUpdate(BaseModel):
"""更新工单"""
title: Optional[str] = None
description: Optional[str] = None
status: Optional[str] = None
priority: Optional[str] = None
type: Optional[str] = None
assignee_id: Optional[int] = None
project: Optional[str] = None
version: Optional[str] = None
class TicketOut(BaseModel):
"""工单输出"""
id: int
title: str
description: Optional[str] = None
status: str
priority: str
type: str
assignee_id: Optional[int] = None
reporter_id: int
project: Optional[str] = None
version: Optional[str] = None
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
from typing import Dict, List, Optional, Sequence
from app.api.v1.module_system.auth.schema import AuthSchema
from app.api.v1.module_system.ticket.crud import TicketCRUD
from app.api.v1.module_system.ticket.schema import TicketCreate, TicketUpdate
class TicketService:
"""工单模块服务层"""
pass
@@ -0,0 +1 @@
# 版本管理模块
@@ -0,0 +1,4 @@
from fastapi import APIRouter
router = APIRouter(prefix="/versions", tags=["版本管理"])
@@ -0,0 +1,85 @@
# -*- coding: utf-8 -*-
from typing import Dict, List, Optional, Sequence
from app.core.base_crud import CRUDBase
from app.api.v1.module_system.auth.schema import AuthSchema
from app.api.v1.module_system.version.model import Version
from app.api.v1.module_system.version.schema import VersionCreate, VersionUpdate
class VersionCRUD(CRUDBase[Version, VersionCreate, VersionUpdate]):
"""版本模块数据层"""
def __init__(self, auth: AuthSchema) -> None:
"""初始化版本CRUD"""
self.auth = auth
super().__init__(model=Version, auth=auth)
async def get_by_id_crud(self, id: int) -> Optional[Version]:
"""
根据id获取版本信息
:param id: 版本ID
:return: 版本信息
"""
return await self.get(id=id)
async def get_list_crud(self, search: Dict = None, order_by: List[Dict[str, str]] = None) -> Sequence[Version]:
"""
获取版本列表
:param search: 搜索条件
:param order_by: 排序字段
:return: 版本列表
"""
return await self.list(search=search, order_by=order_by)
async def create_crud(self, data: VersionCreate) -> Optional[Version]:
"""
创建版本
:param data: 版本创建数据
:return: 创建的版本
"""
return await self.create(data=data)
async def update_crud(self, id: int, data: VersionUpdate) -> Optional[Version]:
"""
更新版本
:param id: 版本ID
:param data: 版本更新数据
:return: 更新的版本
"""
return await self.update(id=id, data=data)
async def delete_crud(self, ids: List[int]) -> None:
"""
批量删除版本
:param ids: 版本ID列表
"""
return await self.delete(ids=ids)
async def get_by_number_crud(self, version_number: str) -> Optional[Version]:
"""
根据版本号获取版本
:param version_number: 版本号
:return: 版本信息
"""
return await self.get(version_number=version_number)
async def get_by_status_crud(self, status: str, search: Dict = None, order_by: List[Dict[str, str]] = None) -> Sequence[Version]:
"""
根据状态获取版本列表
:param status: 版本状态
:param search: 搜索条件
:param order_by: 排序字段
:return: 版本列表
"""
if search is None:
search = {}
search['status'] = status
return await self.list(search=search, order_by=order_by)
@@ -0,0 +1,15 @@
from sqlalchemy import Column, Integer, String, Text, DateTime
from app.core.base_model import BaseModel
from datetime import datetime
class Version(BaseModel):
"""版本模型"""
__tablename__ = "version"
version_number = Column(String(50), nullable=False, comment="版本号")
title = Column(String(255), nullable=False, comment="版本标题")
release_notes = Column(Text, comment="发布说明")
status = Column(String(50), default="draft", comment="版本状态(draft, released, archived)")
project = Column(String(100), comment="所属项目")
released_at = Column(DateTime, comment="发布时间")
@@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from typing import Optional
from fastapi import Query
from app.core.validator import DateTimeStr
class VersionQueryParams:
"""版本管理查询参数"""
def __init__(
self,
title: Optional[str] = Query(None, description="版本标题"),
status: Optional[bool] = Query(None, description="是否可用"),
creator: Optional[int] = Query(None, description="创建人"),
start_time: Optional[DateTimeStr] = Query(None, description="开始时间", example="2023-01-01 00:00:00"),
end_time: Optional[DateTimeStr] = Query(None, description="结束时间", example="2023-12-31 23:59:59"),
) -> None:
super().__init__()
# 模糊查询字段
self.title = ("like", title)
# 精确查询字段
self.creator_id = creator
self.status = status
# 时间范围查询
if start_time and end_time:
start_datetime = datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')
end_datetime = datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
self.created_at = ("between", (start_datetime, end_datetime))
@@ -0,0 +1,42 @@
from pydantic import BaseModel
from typing import Optional
from datetime import datetime
class VersionCreate(BaseModel):
"""创建版本"""
version_number: str
title: str
description: Optional[str] = None
release_notes: Optional[str] = None
status: Optional[str] = "draft"
project: Optional[str] = None
released_at: Optional[datetime] = None
class VersionUpdate(BaseModel):
"""更新版本"""
version_number: Optional[str] = None
title: Optional[str] = None
description: Optional[str] = None
release_notes: Optional[str] = None
status: Optional[str] = None
project: Optional[str] = None
released_at: Optional[datetime] = None
class VersionOut(BaseModel):
"""版本输出"""
id: int
version_number: str
title: str
description: Optional[str] = None
release_notes: Optional[str] = None
status: str
project: Optional[str] = None
released_at: Optional[datetime] = None
created_at: datetime
updated_at: datetime
class Config:
from_attributes = True
@@ -0,0 +1,6 @@
class VersionService:
"""版本服务类"""
pass
+2 -2
View File
@@ -33,7 +33,7 @@ from app.core.exceptions import (
)
from app.core.database import session_connect, init_create_table
from app.scripts.initialize import InitializeData
from app.api.v1.module_system.config.service import ConfigService
from app.api.v1.module_system.params.service import ParamsService
from app.api.v1.module_system.dict.service import DictDataService
from app.api.v1 import router
@@ -52,7 +52,7 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[Any, Any]:
logger.info("初始化数据完成...")
await import_modules_async(modules=settings.EVENT_LIST, desc="全局事件", app=app, status=True)
logger.info("初始化全局事件完成...")
await ConfigService().init_config_service(redis=app.state.redis)
await ParamsService().init_config_service(redis=app.state.redis)
logger.info("初始化系统配置完成...")
await DictDataService().init_dict_service(redis=app.state.redis)
logger.info('初始化数据字典完成...')