mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-20 20:39:55 +00:00
@@ -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
|
||||
@@ -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('初始化数据字典完成...')
|
||||
|
||||
Reference in New Issue
Block a user