add backend source code
This commit is contained in:
271
backend/app/api/v1/templates.py
Normal file
271
backend/app/api/v1/templates.py
Normal file
@@ -0,0 +1,271 @@
|
||||
"""
|
||||
API路由 - 指标模板管理
|
||||
"""
|
||||
from typing import Annotated, Optional, List
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
from app.core.database import get_db
|
||||
from app.core.security import get_current_active_user, get_current_manager_user
|
||||
from app.schemas.schemas import (
|
||||
IndicatorTemplateCreate, IndicatorTemplateUpdate,
|
||||
IndicatorTemplateResponse, IndicatorTemplateListResponse,
|
||||
TemplateIndicatorCreate, TemplateIndicatorUpdate, TemplateIndicatorResponse,
|
||||
ResponseBase
|
||||
)
|
||||
from app.services.template_service import TemplateService
|
||||
from app.models.models import User
|
||||
|
||||
router = APIRouter(prefix="/templates", tags=["指标模板"])
|
||||
|
||||
|
||||
@router.get("", summary="获取模板列表")
|
||||
async def get_templates(
|
||||
template_type: Optional[str] = Query(None, description="模板类型"),
|
||||
is_active: Optional[bool] = Query(None, description="是否启用"),
|
||||
page: int = Query(1, ge=1, description="页码"),
|
||||
page_size: int = Query(20, ge=1, le=100, description="每页数量"),
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_active_user)
|
||||
):
|
||||
"""获取模板列表"""
|
||||
templates, total = await TemplateService.get_list(
|
||||
db, template_type, is_active, page, page_size
|
||||
)
|
||||
return {
|
||||
"code": 200,
|
||||
"message": "success",
|
||||
"data": templates,
|
||||
"total": total,
|
||||
"page": page,
|
||||
"page_size": page_size
|
||||
}
|
||||
|
||||
|
||||
@router.get("/types", summary="获取模板类型列表")
|
||||
async def get_template_types(
|
||||
current_user: User = Depends(get_current_active_user)
|
||||
):
|
||||
"""获取模板类型列表"""
|
||||
types = [
|
||||
{"value": "general", "label": "通用模板"},
|
||||
{"value": "surgical", "label": "手术临床科室"},
|
||||
{"value": "nonsurgical_ward", "label": "非手术有病房科室"},
|
||||
{"value": "nonsurgical_noward", "label": "非手术无病房科室"},
|
||||
{"value": "medical_tech", "label": "医技科室"},
|
||||
{"value": "nursing", "label": "护理单元"},
|
||||
{"value": "admin", "label": "行政科室"},
|
||||
{"value": "logistics", "label": "后勤科室"}
|
||||
]
|
||||
return {"code": 200, "message": "success", "data": types}
|
||||
|
||||
|
||||
@router.get("/dimensions", summary="获取BSC维度列表")
|
||||
async def get_dimensions(
|
||||
current_user: User = Depends(get_current_active_user)
|
||||
):
|
||||
"""获取BSC维度列表"""
|
||||
dimensions = [
|
||||
{"value": "financial", "label": "财务管理", "weight_range": "30%-40%"},
|
||||
{"value": "customer", "label": "顾客服务", "weight_range": "25%-35%"},
|
||||
{"value": "internal_process", "label": "内部流程", "weight_range": "20%-30%"},
|
||||
{"value": "learning_growth", "label": "学习与成长", "weight_range": "5%-15%"}
|
||||
]
|
||||
return {"code": 200, "message": "success", "data": dimensions}
|
||||
|
||||
|
||||
@router.get("/{template_id}", summary="获取模板详情")
|
||||
async def get_template(
|
||||
template_id: int,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_active_user)
|
||||
):
|
||||
"""获取模板详情"""
|
||||
template = await TemplateService.get_by_id(db, template_id)
|
||||
if not template:
|
||||
raise HTTPException(status_code=404, detail="模板不存在")
|
||||
|
||||
# 构建响应数据
|
||||
indicators = []
|
||||
for ti in template.indicators:
|
||||
ind_dict = {
|
||||
"id": ti.id,
|
||||
"template_id": ti.template_id,
|
||||
"indicator_id": ti.indicator_id,
|
||||
"indicator_name": ti.indicator.name if ti.indicator else None,
|
||||
"indicator_code": ti.indicator.code if ti.indicator else None,
|
||||
"indicator_type": ti.indicator.indicator_type.value if ti.indicator else None,
|
||||
"bs_dimension": ti.indicator.bs_dimension.value if ti.indicator else None,
|
||||
"category": ti.category,
|
||||
"target_value": float(ti.target_value) if ti.target_value else None,
|
||||
"target_unit": ti.target_unit,
|
||||
"weight": float(ti.weight),
|
||||
"scoring_method": ti.scoring_method,
|
||||
"scoring_params": ti.scoring_params,
|
||||
"sort_order": ti.sort_order,
|
||||
"remark": ti.remark,
|
||||
"created_at": ti.created_at,
|
||||
"updated_at": ti.updated_at
|
||||
}
|
||||
indicators.append(ind_dict)
|
||||
|
||||
response_data = {
|
||||
"id": template.id,
|
||||
"template_name": template.template_name,
|
||||
"template_code": template.template_code,
|
||||
"template_type": template.template_type.value,
|
||||
"description": template.description,
|
||||
"dimension_weights": template.dimension_weights,
|
||||
"assessment_cycle": template.assessment_cycle,
|
||||
"is_active": template.is_active,
|
||||
"created_at": template.created_at,
|
||||
"updated_at": template.updated_at,
|
||||
"indicators": indicators
|
||||
}
|
||||
|
||||
return {"code": 200, "message": "success", "data": response_data}
|
||||
|
||||
|
||||
@router.post("", summary="创建模板")
|
||||
async def create_template(
|
||||
template_data: IndicatorTemplateCreate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
||||
):
|
||||
"""创建模板(需要管理员或经理权限)"""
|
||||
# 检查编码是否已存在
|
||||
existing = await TemplateService.get_by_code(db, template_data.template_code)
|
||||
if existing:
|
||||
raise HTTPException(status_code=400, detail="模板编码已存在")
|
||||
|
||||
template = await TemplateService.create(db, template_data)
|
||||
return {"code": 200, "message": "创建成功", "data": {"id": template.id}}
|
||||
|
||||
|
||||
@router.put("/{template_id}", summary="更新模板")
|
||||
async def update_template(
|
||||
template_id: int,
|
||||
template_data: IndicatorTemplateUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
||||
):
|
||||
"""更新模板(需要管理员或经理权限)"""
|
||||
template = await TemplateService.update(db, template_id, template_data)
|
||||
if not template:
|
||||
raise HTTPException(status_code=404, detail="模板不存在")
|
||||
return {"code": 200, "message": "更新成功"}
|
||||
|
||||
|
||||
@router.delete("/{template_id}", summary="删除模板")
|
||||
async def delete_template(
|
||||
template_id: int,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
||||
):
|
||||
"""删除模板(需要管理员或经理权限)"""
|
||||
success = await TemplateService.delete(db, template_id)
|
||||
if not success:
|
||||
raise HTTPException(status_code=404, detail="模板不存在")
|
||||
return {"code": 200, "message": "删除成功"}
|
||||
|
||||
|
||||
# ==================== 模板指标管理 ====================
|
||||
|
||||
@router.get("/{template_id}/indicators", summary="获取模板指标列表")
|
||||
async def get_template_indicators(
|
||||
template_id: int,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: User = Depends(get_current_active_user)
|
||||
):
|
||||
"""获取模板指标列表"""
|
||||
indicators = await TemplateService.get_template_indicators(db, template_id)
|
||||
|
||||
result = []
|
||||
for ti in indicators:
|
||||
ind_dict = {
|
||||
"id": ti.id,
|
||||
"template_id": ti.template_id,
|
||||
"indicator_id": ti.indicator_id,
|
||||
"indicator_name": ti.indicator.name if ti.indicator else None,
|
||||
"indicator_code": ti.indicator.code if ti.indicator else None,
|
||||
"indicator_type": ti.indicator.indicator_type.value if ti.indicator else None,
|
||||
"bs_dimension": ti.indicator.bs_dimension.value if ti.indicator else None,
|
||||
"category": ti.category,
|
||||
"target_value": float(ti.target_value) if ti.target_value else None,
|
||||
"target_unit": ti.target_unit,
|
||||
"weight": float(ti.weight),
|
||||
"scoring_method": ti.scoring_method,
|
||||
"scoring_params": ti.scoring_params,
|
||||
"sort_order": ti.sort_order,
|
||||
"remark": ti.remark,
|
||||
"created_at": ti.created_at,
|
||||
"updated_at": ti.updated_at
|
||||
}
|
||||
result.append(ind_dict)
|
||||
|
||||
return {"code": 200, "message": "success", "data": result}
|
||||
|
||||
|
||||
@router.post("/{template_id}/indicators", summary="添加模板指标")
|
||||
async def add_template_indicator(
|
||||
template_id: int,
|
||||
indicator_data: TemplateIndicatorCreate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
||||
):
|
||||
"""添加模板指标"""
|
||||
ti = await TemplateService.add_indicator(db, template_id, indicator_data)
|
||||
if not ti:
|
||||
raise HTTPException(status_code=400, detail="添加失败,模板不存在或指标已存在")
|
||||
return {"code": 200, "message": "添加成功", "data": {"id": ti.id}}
|
||||
|
||||
|
||||
@router.put("/{template_id}/indicators/{indicator_id}", summary="更新模板指标")
|
||||
async def update_template_indicator(
|
||||
template_id: int,
|
||||
indicator_id: int,
|
||||
indicator_data: TemplateIndicatorUpdate,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
||||
):
|
||||
"""更新模板指标"""
|
||||
ti = await TemplateService.update_indicator(db, template_id, indicator_id, indicator_data)
|
||||
if not ti:
|
||||
raise HTTPException(status_code=404, detail="模板指标不存在")
|
||||
return {"code": 200, "message": "更新成功"}
|
||||
|
||||
|
||||
@router.delete("/{template_id}/indicators/{indicator_id}", summary="移除模板指标")
|
||||
async def remove_template_indicator(
|
||||
template_id: int,
|
||||
indicator_id: int,
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
||||
):
|
||||
"""移除模板指标"""
|
||||
success = await TemplateService.remove_indicator(db, template_id, indicator_id)
|
||||
if not success:
|
||||
raise HTTPException(status_code=404, detail="模板指标不存在")
|
||||
return {"code": 200, "message": "移除成功"}
|
||||
|
||||
|
||||
@router.post("/{template_id}/indicators/batch", summary="批量添加模板指标")
|
||||
async def batch_add_template_indicators(
|
||||
template_id: int,
|
||||
indicators_data: List[TemplateIndicatorCreate],
|
||||
db: AsyncSession = Depends(get_db),
|
||||
current_user: Annotated[User, Depends(get_current_manager_user)] = None
|
||||
):
|
||||
"""批量添加模板指标"""
|
||||
added_count = 0
|
||||
for idx, ind_data in enumerate(indicators_data):
|
||||
ind_data.sort_order = ind_data.sort_order or idx
|
||||
ti = await TemplateService.add_indicator(db, template_id, ind_data)
|
||||
if ti:
|
||||
added_count += 1
|
||||
|
||||
return {
|
||||
"code": 200,
|
||||
"message": f"成功添加 {added_count} 个指标",
|
||||
"data": {"added_count": added_count}
|
||||
}
|
||||
Reference in New Issue
Block a user