169 lines
6.7 KiB
Python
169 lines
6.7 KiB
Python
|
|
"""通知告警配置服务。"""
|
||
|
|
import json
|
||
|
|
from insurance.db.compat import db
|
||
|
|
from insurance.models.notification import NotificationChannel, AlertRule
|
||
|
|
|
||
|
|
|
||
|
|
class NotificationService:
|
||
|
|
"""通知告警配置业务逻辑。"""
|
||
|
|
|
||
|
|
# ---- 通知渠道管理 ----
|
||
|
|
|
||
|
|
def list_channels(self) -> dict:
|
||
|
|
"""获取通知渠道列表。"""
|
||
|
|
channels = db.session.query(NotificationChannel).all()
|
||
|
|
return {"code": 0, "data": [c.to_dict() for c in channels]}
|
||
|
|
|
||
|
|
def create_channel(self, data: dict) -> dict:
|
||
|
|
"""创建通知渠道。"""
|
||
|
|
channel = NotificationChannel(
|
||
|
|
name=data.get("name", ""),
|
||
|
|
type=data.get("type", ""),
|
||
|
|
config=json.dumps(data.get("config", {})),
|
||
|
|
enabled=data.get("enabled", True),
|
||
|
|
)
|
||
|
|
db.session.add(channel)
|
||
|
|
db.session.commit()
|
||
|
|
|
||
|
|
from insurance.utils.audit import log_operation
|
||
|
|
log_operation("system", "create", "notification_channel", str(channel.id), {"name": channel.name})
|
||
|
|
|
||
|
|
return {"code": 0, "data": {"id": f"channel-{channel.id}"}}
|
||
|
|
|
||
|
|
def update_channel(self, channel_id: str, data: dict) -> dict:
|
||
|
|
"""更新通知渠道。"""
|
||
|
|
channel_id_int = int(channel_id.replace("channel-", ""))
|
||
|
|
channel = db.session.query(NotificationChannel).filter_by(id=channel_id_int).first()
|
||
|
|
if not channel:
|
||
|
|
return {"code": 1005, "message": "渠道不存在", "data": None}
|
||
|
|
|
||
|
|
for key in ("name", "type", "enabled"):
|
||
|
|
if key in data:
|
||
|
|
setattr(channel, key, data[key])
|
||
|
|
if "config" in data:
|
||
|
|
channel.config = json.dumps(data["config"])
|
||
|
|
|
||
|
|
db.session.commit()
|
||
|
|
|
||
|
|
from insurance.utils.audit import log_operation
|
||
|
|
log_operation("system", "update", "notification_channel", channel_id, {"name": channel.name})
|
||
|
|
|
||
|
|
return {"code": 0, "message": "success", "data": None}
|
||
|
|
|
||
|
|
def delete_channel(self, channel_id: str) -> dict:
|
||
|
|
"""删除通知渠道。"""
|
||
|
|
channel_id_int = int(channel_id.replace("channel-", ""))
|
||
|
|
channel = db.session.query(NotificationChannel).filter_by(id=channel_id_int).first()
|
||
|
|
if not channel:
|
||
|
|
return {"code": 1005, "message": "渠道不存在", "data": None}
|
||
|
|
|
||
|
|
# 检查是否有规则引用
|
||
|
|
rules_count = db.session.query(AlertRule).filter_by(channel_id=channel.id).count()
|
||
|
|
if rules_count > 0:
|
||
|
|
return {"code": 1009, "message": "该渠道正在被告警规则使用,无法删除", "data": None}
|
||
|
|
|
||
|
|
db.session.delete(channel)
|
||
|
|
db.session.commit()
|
||
|
|
|
||
|
|
from insurance.utils.audit import log_operation
|
||
|
|
log_operation("system", "delete", "notification_channel", channel_id, {"name": channel.name})
|
||
|
|
|
||
|
|
return {"code": 0, "message": "success", "data": None}
|
||
|
|
|
||
|
|
def test_channel(self, channel_id: str) -> dict:
|
||
|
|
"""测试通知渠道。"""
|
||
|
|
channel_id_int = int(channel_id.replace("channel-", ""))
|
||
|
|
channel = db.session.query(NotificationChannel).filter_by(id=channel_id_int).first()
|
||
|
|
if not channel:
|
||
|
|
return {"code": 1005, "message": "渠道不存在", "data": None}
|
||
|
|
|
||
|
|
config = json.loads(channel.config) if channel.config else {}
|
||
|
|
|
||
|
|
if channel.type == "wecom_webhook":
|
||
|
|
webhook_url = config.get("webhook_url", "")
|
||
|
|
if not webhook_url:
|
||
|
|
return {"code": 1010, "message": "Webhook URL 未配置", "data": None}
|
||
|
|
|
||
|
|
# 发送测试消息
|
||
|
|
import requests
|
||
|
|
try:
|
||
|
|
resp = requests.post(webhook_url, json={
|
||
|
|
"msgtype": "markdown",
|
||
|
|
"markdown": {
|
||
|
|
"content": "## 测试通知\n\n这是一条测试消息\n> 来自保险智能客服系统"
|
||
|
|
}
|
||
|
|
}, timeout=10)
|
||
|
|
result = resp.json()
|
||
|
|
if result.get("errcode") == 0:
|
||
|
|
return {"code": 0, "message": "测试成功", "data": None}
|
||
|
|
else:
|
||
|
|
return {"code": 1011, "message": f"发送失败: {result.get('errmsg')}", "data": None}
|
||
|
|
except Exception as e:
|
||
|
|
return {"code": 1011, "message": f"发送失败: {str(e)}", "data": None}
|
||
|
|
|
||
|
|
elif channel.type == "email":
|
||
|
|
# 邮件测试(简化实现)
|
||
|
|
return {"code": 0, "message": "邮件测试功能开发中", "data": None}
|
||
|
|
|
||
|
|
return {"code": 1010, "message": "不支持的渠道类型", "data": None}
|
||
|
|
|
||
|
|
# ---- 告警规则管理 ----
|
||
|
|
|
||
|
|
def list_rules(self) -> dict:
|
||
|
|
"""获取告警规则列表。"""
|
||
|
|
rules = db.session.query(AlertRule).all()
|
||
|
|
return {"code": 0, "data": [r.to_dict() for r in rules]}
|
||
|
|
|
||
|
|
def create_rule(self, data: dict) -> dict:
|
||
|
|
"""创建告警规则。"""
|
||
|
|
rule = AlertRule(
|
||
|
|
name=data.get("name", ""),
|
||
|
|
description=data.get("description", ""),
|
||
|
|
condition_type=data.get("condition_type", ""),
|
||
|
|
condition_config=json.dumps(data.get("condition_config", {})),
|
||
|
|
channel_id=data.get("channel_id"),
|
||
|
|
enabled=data.get("enabled", True),
|
||
|
|
)
|
||
|
|
db.session.add(rule)
|
||
|
|
db.session.commit()
|
||
|
|
|
||
|
|
from insurance.utils.audit import log_operation
|
||
|
|
log_operation("system", "create", "alert_rule", str(rule.id), {"name": rule.name})
|
||
|
|
|
||
|
|
return {"code": 0, "data": {"id": f"rule-{rule.id}"}}
|
||
|
|
|
||
|
|
def update_rule(self, rule_id: str, data: dict) -> dict:
|
||
|
|
"""更新告警规则。"""
|
||
|
|
rule_id_int = int(rule_id.replace("rule-", ""))
|
||
|
|
rule = db.session.query(AlertRule).filter_by(id=rule_id_int).first()
|
||
|
|
if not rule:
|
||
|
|
return {"code": 1005, "message": "规则不存在", "data": None}
|
||
|
|
|
||
|
|
for key in ("name", "description", "condition_type", "channel_id", "enabled"):
|
||
|
|
if key in data:
|
||
|
|
setattr(rule, key, data[key])
|
||
|
|
if "condition_config" in data:
|
||
|
|
rule.condition_config = json.dumps(data["condition_config"])
|
||
|
|
|
||
|
|
db.session.commit()
|
||
|
|
|
||
|
|
from insurance.utils.audit import log_operation
|
||
|
|
log_operation("system", "update", "alert_rule", rule_id, {"name": rule.name})
|
||
|
|
|
||
|
|
return {"code": 0, "message": "success", "data": None}
|
||
|
|
|
||
|
|
def delete_rule(self, rule_id: str) -> dict:
|
||
|
|
"""删除告警规则。"""
|
||
|
|
rule_id_int = int(rule_id.replace("rule-", ""))
|
||
|
|
rule = db.session.query(AlertRule).filter_by(id=rule_id_int).first()
|
||
|
|
if not rule:
|
||
|
|
return {"code": 1005, "message": "规则不存在", "data": None}
|
||
|
|
|
||
|
|
db.session.delete(rule)
|
||
|
|
db.session.commit()
|
||
|
|
|
||
|
|
from insurance.utils.audit import log_operation
|
||
|
|
log_operation("system", "delete", "alert_rule", rule_id, {"name": rule.name})
|
||
|
|
|
||
|
|
return {"code": 0, "message": "success", "data": None}
|