""" 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} }