init: 管理会计OS初始代码
包含前后端完整代码: - 前端:Vue3+Vite+ElementPlus - 后端:FastAPI+SQLAlchemy - 模块:驾驶舱/KPI/战略地图/预警/预算/成本/预测/改善行动 - 当前版本:v1.0.0
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
"""通知渠道配置 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]
|
||||
}
|
||||
Reference in New Issue
Block a user