"""通知渠道配置 API""" from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from app.database import get_db from app.models import NotificationChannel, NotificationLog from app.auth_middleware import require_role from datetime import datetime router = APIRouter(prefix="/api/cma/notifications", tags=["通知配置"]) def ch_to_dict(c): return { "id": c.id, "name": c.name, "channel_type": c.channel_type, "config": c.config, "enabled": c.enabled, "created_at": c.created_at.isoformat() if c.created_at else None, } @router.get("/channels") def list_channels(db: Session = Depends(get_db)): """获取通知渠道列表""" channels = db.query(NotificationChannel).order_by(NotificationChannel.id).all() return {"data": [ch_to_dict(c) for c in channels]} @router.post("/channels") def create_channel(data: dict, db: Session = Depends(get_db)): """创建通知渠道""" ch = NotificationChannel( name=data["name"], channel_type=data["channel_type"], config=data.get("config", {}), enabled=data.get("enabled", True), ) db.add(ch) db.commit() db.refresh(ch) return ch_to_dict(ch) @router.put("/channels/{ch_id}") def update_channel(ch_id: int, data: dict, db: Session = Depends(get_db)): """更新通知渠道""" ch = db.query(NotificationChannel).filter(NotificationChannel.id == ch_id).first() if not ch: raise HTTPException(404, "渠道不存在") for k, v in data.items(): if hasattr(ch, k) and k not in ("id", "created_at"): setattr(ch, k, v) db.commit() db.refresh(ch) return ch_to_dict(ch) @router.delete("/channels/{ch_id}") def delete_channel(ch_id: int, db: Session = Depends(get_db)): """删除通知渠道""" ch = db.query(NotificationChannel).filter(NotificationChannel.id == ch_id).first() if not ch: raise HTTPException(404, "渠道不存在") db.delete(ch) db.commit() return {"message": "已删除"} @router.post("/channels/{ch_id}/test") def test_channel(ch_id: int, db: Session = Depends(get_db)): """测试推送""" from app.utils.notifier import push_alert ch = db.query(NotificationChannel).filter(NotificationChannel.id == ch_id).first() if not ch: raise HTTPException(404, "渠道不存在") config = ch.config or {} test_alert = { "alert_level": "yellow", "alert_message": "【测试通知】这是一条管理会计OS的测试预警", "kpi_name": "销售总额", "period": datetime.now().strftime("%Y-%m"), "actual_value": "800,000", "target_value": "1,000,000", } results = push_alert(test_alert, [{ "name": ch.name, "channel_type": ch.channel_type, "config": config, "enabled": True }]) return {"results": results} @router.get("/logs") def list_logs(page: int = 1, db: Session = Depends(get_db)): """通知历史""" total = db.query(NotificationLog).count() logs = db.query(NotificationLog).order_by( NotificationLog.created_at.desc() ).offset((page - 1) * 20).limit(20).all() return { "total": total, "data": [{ "id": l.id, "alert_id": l.alert_id, "channel": l.channel, "recipient": l.recipient, "title": l.title, "status": l.status, "error_msg": l.error_msg, "sent_at": l.sent_at.isoformat() if l.sent_at else None, "created_at": l.created_at.isoformat() if l.created_at else None, } for l in logs] }