mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-21 12:52:26 +00:00
feat(api): 添加Ticket和Version模块路由
- 引入TicketRouter和VersionRouter - 将TicketRouter和VersionRouter加入SYSTEM_MODULES路由列表 - 移除未使用的ResourceRouter导入声明
This commit is contained in:
@@ -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 = [
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
# 工单管理模块
|
||||
@@ -0,0 +1,58 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from app.api.v1.module_system.ticket.schema import TicketCreate, TicketUpdate, TicketOut
|
||||
from app.api.v1.module_system.ticket.service import ticket_service
|
||||
from app.core.database import get_db
|
||||
|
||||
router = APIRouter(prefix="/tickets", tags=["工单管理"])
|
||||
|
||||
|
||||
@router.post("/", response_model=TicketOut)
|
||||
def create_ticket(ticket: TicketCreate, db: Session = Depends(get_db)):
|
||||
"""创建工单"""
|
||||
return ticket_service.create_ticket(db, ticket)
|
||||
|
||||
|
||||
@router.get("/{ticket_id}", response_model=TicketOut)
|
||||
def get_ticket(ticket_id: int, db: Session = Depends(get_db)):
|
||||
"""获取工单详情"""
|
||||
db_ticket = ticket_service.get_ticket(db, ticket_id)
|
||||
if db_ticket is None:
|
||||
raise HTTPException(status_code=404, detail="工单不存在")
|
||||
return db_ticket
|
||||
|
||||
|
||||
@router.get("/", response_model=list[TicketOut])
|
||||
def get_tickets(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
||||
"""获取工单列表"""
|
||||
return ticket_service.get_tickets(db, skip=skip, limit=limit)
|
||||
|
||||
|
||||
@router.put("/{ticket_id}", response_model=TicketOut)
|
||||
def update_ticket(ticket_id: int, ticket: TicketUpdate, db: Session = Depends(get_db)):
|
||||
"""更新工单"""
|
||||
db_ticket = ticket_service.update_ticket(db, ticket_id, ticket)
|
||||
if db_ticket is None:
|
||||
raise HTTPException(status_code=404, detail="工单不存在")
|
||||
return db_ticket
|
||||
|
||||
|
||||
@router.delete("/{ticket_id}", response_model=TicketOut)
|
||||
def delete_ticket(ticket_id: int, db: Session = Depends(get_db)):
|
||||
"""删除工单"""
|
||||
db_ticket = ticket_service.get_ticket(db, ticket_id)
|
||||
if db_ticket is None:
|
||||
raise HTTPException(status_code=404, detail="工单不存在")
|
||||
return ticket_service.delete_ticket(db, ticket_id)
|
||||
|
||||
|
||||
@router.get("/status/{status}", response_model=list[TicketOut])
|
||||
def get_tickets_by_status(status: str, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
||||
"""根据状态获取工单列表"""
|
||||
return ticket_service.get_tickets_by_status(db, status=status, skip=skip, limit=limit)
|
||||
|
||||
|
||||
@router.get("/assignee/{assignee_id}", response_model=list[TicketOut])
|
||||
def get_tickets_by_assignee(assignee_id: int, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
||||
"""根据指派用户获取工单列表"""
|
||||
return ticket_service.get_tickets_by_assignee(db, assignee_id=assignee_id, skip=skip, limit=limit)
|
||||
@@ -0,0 +1,28 @@
|
||||
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
|
||||
|
||||
|
||||
class CRUDTicket(CRUDBase[Ticket, TicketCreate, TicketUpdate]):
|
||||
"""工单 CRUD 操作"""
|
||||
|
||||
def get_ticket_by_id(self, db: Session, ticket_id: int) -> Ticket:
|
||||
"""根据ID获取工单"""
|
||||
return db.query(self.model).filter(self.model.id == ticket_id).first()
|
||||
|
||||
def get_tickets(self, db: Session, skip: int = 0, limit: int = 100) -> List[Ticket]:
|
||||
"""获取工单列表"""
|
||||
return db.query(self.model).offset(skip).limit(limit).all()
|
||||
|
||||
def get_tickets_by_status(self, db: Session, status: str, skip: int = 0, limit: int = 100) -> List[Ticket]:
|
||||
"""根据状态获取工单列表"""
|
||||
return db.query(self.model).filter(self.model.status == status).offset(skip).limit(limit).all()
|
||||
|
||||
def get_tickets_by_assignee(self, db: Session, assignee_id: int, skip: int = 0, limit: int = 100) -> List[Ticket]:
|
||||
"""根据指派用户获取工单列表"""
|
||||
return db.query(self.model).filter(self.model.assignee_id == assignee_id).offset(skip).limit(limit).all()
|
||||
|
||||
|
||||
ticket_crud = CRUDTicket(Ticket)
|
||||
@@ -0,0 +1,30 @@
|
||||
from sqlalchemy import Column, Integer, String, Text, DateTime, ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from app.core.base_model import BaseModel
|
||||
from app.api.v1.module_system.user.model import User
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Ticket(BaseModel):
|
||||
"""工单模型"""
|
||||
__tablename__ = "ticket"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True, comment="工单ID")
|
||||
|
||||
title = Column(String(255), nullable=False, comment="工单标题")
|
||||
|
||||
status = Column(String(50), default="open", comment="工单状态(open, in_progress, resolved, closed)")
|
||||
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="版本号")
|
||||
|
||||
description = Column(Text, comment="工单描述")
|
||||
created_at = Column(DateTime, default=datetime.now, comment="创建时间")
|
||||
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now, comment="更新时间")
|
||||
|
||||
# 关系
|
||||
assignee = relationship("User", foreign_keys=[assignee_id])
|
||||
reporter = relationship("User", foreign_keys=[reporter_id])
|
||||
@@ -0,0 +1,47 @@
|
||||
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,48 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from app.api.v1.module_system.ticket.crud import ticket_crud
|
||||
from app.api.v1.module_system.ticket.schema import TicketCreate, TicketUpdate
|
||||
|
||||
|
||||
class TicketService:
|
||||
"""工单服务类"""
|
||||
|
||||
@staticmethod
|
||||
def create_ticket(db: Session, ticket_create: TicketCreate):
|
||||
"""创建工单"""
|
||||
return ticket_crud.create(db, obj_in=ticket_create)
|
||||
|
||||
@staticmethod
|
||||
def get_ticket(db: Session, ticket_id: int):
|
||||
"""获取工单"""
|
||||
return ticket_crud.get(db, id=ticket_id)
|
||||
|
||||
@staticmethod
|
||||
def get_tickets(db: Session, skip: int = 0, limit: int = 100):
|
||||
"""获取工单列表"""
|
||||
return ticket_crud.get_multi(db, skip=skip, limit=limit)
|
||||
|
||||
@staticmethod
|
||||
def update_ticket(db: Session, ticket_id: int, ticket_update: TicketUpdate):
|
||||
"""更新工单"""
|
||||
db_ticket = ticket_crud.get(db, id=ticket_id)
|
||||
if db_ticket:
|
||||
return ticket_crud.update(db, db_obj=db_ticket, obj_in=ticket_update)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def delete_ticket(db: Session, ticket_id: int):
|
||||
"""删除工单"""
|
||||
return ticket_crud.remove(db, id=ticket_id)
|
||||
|
||||
@staticmethod
|
||||
def get_tickets_by_status(db: Session, status: str, skip: int = 0, limit: int = 100):
|
||||
"""根据状态获取工单列表"""
|
||||
return ticket_crud.get_tickets_by_status(db, status=status, skip=skip, limit=limit)
|
||||
|
||||
@staticmethod
|
||||
def get_tickets_by_assignee(db: Session, assignee_id: int, skip: int = 0, limit: int = 100):
|
||||
"""根据指派用户获取工单列表"""
|
||||
return ticket_crud.get_tickets_by_assignee(db, assignee_id=assignee_id, skip=skip, limit=limit)
|
||||
|
||||
|
||||
ticket_service = TicketService()
|
||||
@@ -0,0 +1 @@
|
||||
# 版本管理模块
|
||||
@@ -0,0 +1,61 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from sqlalchemy.orm import Session
|
||||
from app.api.v1.module_system.version.schema import VersionCreate, VersionUpdate, VersionOut
|
||||
from app.api.v1.module_system.version.service import version_service
|
||||
from app.core.database import get_db
|
||||
|
||||
router = APIRouter(prefix="/versions", tags=["版本管理"])
|
||||
|
||||
|
||||
@router.post("/", response_model=VersionOut)
|
||||
def create_version(version: VersionCreate, db: Session = Depends(get_db)):
|
||||
"""创建版本"""
|
||||
return version_service.create_version(db, version)
|
||||
|
||||
|
||||
@router.get("/{version_id}", response_model=VersionOut)
|
||||
def get_version(version_id: int, db: Session = Depends(get_db)):
|
||||
"""获取版本详情"""
|
||||
db_version = version_service.get_version(db, version_id)
|
||||
if db_version is None:
|
||||
raise HTTPException(status_code=404, detail="版本不存在")
|
||||
return db_version
|
||||
|
||||
|
||||
@router.get("/", response_model=list[VersionOut])
|
||||
def get_versions(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
||||
"""获取版本列表"""
|
||||
return version_service.get_versions(db, skip=skip, limit=limit)
|
||||
|
||||
|
||||
@router.put("/{version_id}", response_model=VersionOut)
|
||||
def update_version(version_id: int, version: VersionUpdate, db: Session = Depends(get_db)):
|
||||
"""更新版本"""
|
||||
db_version = version_service.update_version(db, version_id, version)
|
||||
if db_version is None:
|
||||
raise HTTPException(status_code=404, detail="版本不存在")
|
||||
return db_version
|
||||
|
||||
|
||||
@router.delete("/{version_id}", response_model=VersionOut)
|
||||
def delete_version(version_id: int, db: Session = Depends(get_db)):
|
||||
"""删除版本"""
|
||||
db_version = version_service.get_version(db, version_id)
|
||||
if db_version is None:
|
||||
raise HTTPException(status_code=404, detail="版本不存在")
|
||||
return version_service.delete_version(db, version_id)
|
||||
|
||||
|
||||
@router.get("/number/{version_number}", response_model=VersionOut)
|
||||
def get_version_by_number(version_number: str, db: Session = Depends(get_db)):
|
||||
"""根据版本号获取版本"""
|
||||
db_version = version_service.get_version_by_number(db, version_number)
|
||||
if db_version is None:
|
||||
raise HTTPException(status_code=404, detail="版本不存在")
|
||||
return db_version
|
||||
|
||||
|
||||
@router.get("/status/{status}", response_model=list[VersionOut])
|
||||
def get_versions_by_status(status: str, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
|
||||
"""根据状态获取版本列表"""
|
||||
return version_service.get_versions_by_status(db, status=status, skip=skip, limit=limit)
|
||||
@@ -0,0 +1,28 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import List
|
||||
from app.api.v1.module_system.version.model import Version
|
||||
from app.api.v1.module_system.version.schema import VersionCreate, VersionUpdate
|
||||
from app.core.base_crud import CRUDBase
|
||||
|
||||
|
||||
class CRUDVersion(CRUDBase[Version, VersionCreate, VersionUpdate]):
|
||||
"""版本 CRUD 操作"""
|
||||
|
||||
def get_version_by_id(self, db: Session, version_id: int) -> Version:
|
||||
"""根据ID获取版本"""
|
||||
return db.query(self.model).filter(self.model.id == version_id).first()
|
||||
|
||||
def get_versions(self, db: Session, skip: int = 0, limit: int = 100) -> List[Version]:
|
||||
"""获取版本列表"""
|
||||
return db.query(self.model).offset(skip).limit(limit).all()
|
||||
|
||||
def get_version_by_number(self, db: Session, version_number: str) -> Version:
|
||||
"""根据版本号获取版本"""
|
||||
return db.query(self.model).filter(self.model.version_number == version_number).first()
|
||||
|
||||
def get_versions_by_status(self, db: Session, status: str, skip: int = 0, limit: int = 100) -> List[Version]:
|
||||
"""根据状态获取版本列表"""
|
||||
return db.query(self.model).filter(self.model.status == status).offset(skip).limit(limit).all()
|
||||
|
||||
|
||||
version_crud = CRUDVersion(Version)
|
||||
@@ -0,0 +1,20 @@
|
||||
from sqlalchemy import Column, Integer, String, Text, DateTime
|
||||
from app.core.base_model import BaseModel
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
class Version(BaseModel):
|
||||
"""版本模型"""
|
||||
__tablename__ = "version"
|
||||
|
||||
id = Column(Integer, primary_key=True, index=True, comment="版本ID")
|
||||
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="发布时间")
|
||||
|
||||
description = Column(Text, comment="版本描述")
|
||||
created_at = Column(DateTime, default=datetime.now, comment="创建时间")
|
||||
updated_at = Column(DateTime, default=datetime.now, onupdate=datetime.now, comment="更新时间")
|
||||
@@ -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,48 @@
|
||||
from sqlalchemy.orm import Session
|
||||
from app.api.v1.module_system.version.crud import version_crud
|
||||
from app.api.v1.module_system.version.schema import VersionCreate, VersionUpdate
|
||||
|
||||
|
||||
class VersionService:
|
||||
"""版本服务类"""
|
||||
|
||||
@staticmethod
|
||||
def create_version(db: Session, version_create: VersionCreate):
|
||||
"""创建版本"""
|
||||
return version_crud.create(db, obj_in=version_create)
|
||||
|
||||
@staticmethod
|
||||
def get_version(db: Session, version_id: int):
|
||||
"""获取版本"""
|
||||
return version_crud.get(db, id=version_id)
|
||||
|
||||
@staticmethod
|
||||
def get_versions(db: Session, skip: int = 0, limit: int = 100):
|
||||
"""获取版本列表"""
|
||||
return version_crud.get_multi(db, skip=skip, limit=limit)
|
||||
|
||||
@staticmethod
|
||||
def update_version(db: Session, version_id: int, version_update: VersionUpdate):
|
||||
"""更新版本"""
|
||||
db_version = version_crud.get(db, id=version_id)
|
||||
if db_version:
|
||||
return version_crud.update(db, db_obj=db_version, obj_in=version_update)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def delete_version(db: Session, version_id: int):
|
||||
"""删除版本"""
|
||||
return version_crud.remove(db, id=version_id)
|
||||
|
||||
@staticmethod
|
||||
def get_version_by_number(db: Session, version_number: str):
|
||||
"""根据版本号获取版本"""
|
||||
return version_crud.get_version_by_number(db, version_number=version_number)
|
||||
|
||||
@staticmethod
|
||||
def get_versions_by_status(db: Session, status: str, skip: int = 0, limit: int = 100):
|
||||
"""根据状态获取版本列表"""
|
||||
return version_crud.get_versions_by_status(db, status=status, skip=skip, limit=limit)
|
||||
|
||||
|
||||
version_service = VersionService()
|
||||
Reference in New Issue
Block a user