75 lines
2.7 KiB
Python
75 lines
2.7 KiB
Python
"""消息通知与智能预警模型:
|
|
1. Notification 站内消息/通知
|
|
2. AlertRule 业务预警规则(库存低限预警、应收账款逾期催收预警等)
|
|
"""
|
|
|
|
from django.conf import settings
|
|
from django.db import models
|
|
from apps.core.base_models import TenantScopedModel
|
|
|
|
|
|
class Notification(TenantScopedModel):
|
|
"""消息通知。"""
|
|
|
|
CATEGORY_CHOICES = [
|
|
("info", "系统通知"),
|
|
("warning", "业务预警"),
|
|
("error", "异常提醒"),
|
|
("audit", "审批待办"),
|
|
]
|
|
|
|
recipient = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
null=True,
|
|
blank=True,
|
|
on_delete=models.CASCADE,
|
|
related_name="notifications",
|
|
help_text="接收人(为空表示租户内广播)",
|
|
)
|
|
title = models.CharField(max_length=128)
|
|
content = models.TextField()
|
|
category = models.CharField(max_length=16, choices=CATEGORY_CHOICES, default="info")
|
|
link = models.CharField(max_length=255, blank=True, default="", help_text="跳转路由")
|
|
is_read = models.BooleanField(default=False)
|
|
read_at = models.DateTimeField(null=True, blank=True)
|
|
extra_data = models.JSONField(default=dict, blank=True)
|
|
|
|
class Meta:
|
|
db_table = "notify_notification"
|
|
indexes = [
|
|
models.Index(fields=["tenant", "recipient", "is_read"]),
|
|
models.Index(fields=["tenant", "-created_at"]),
|
|
]
|
|
ordering = ["-created_at"]
|
|
|
|
def __str__(self):
|
|
return f"[{self.get_category_display()}] {self.title} (已读: {self.is_read})"
|
|
|
|
|
|
class AlertRule(TenantScopedModel):
|
|
"""业务预警规则配置。"""
|
|
|
|
RULE_TYPE_CHOICES = [
|
|
("inventory_low", "库存缺货/下限预警"),
|
|
("receivable_overdue", "应收账款逾期催款预警"),
|
|
("stock_backlog", "商品呆滞积压预警"),
|
|
("batch_expiry", "批次近效期预警"),
|
|
("risk_score", "AI 应收风险预警(threshold=风险分数线)"),
|
|
]
|
|
|
|
code = models.CharField(max_length=64, help_text="规则代码")
|
|
name = models.CharField(max_length=128, help_text="预警规则名称")
|
|
rule_type = models.CharField(max_length=32, choices=RULE_TYPE_CHOICES)
|
|
threshold = models.DecimalField(max_digits=18, decimal_places=4, default=10, help_text="预警阈值(如天数或数量)")
|
|
is_enabled = models.BooleanField(default=True)
|
|
channels = models.JSONField(default=list, blank=True, help_text="通知渠道 ['in_app', 'webhook']")
|
|
|
|
class Meta:
|
|
db_table = "notify_alert_rule"
|
|
unique_together = [("tenant", "code")]
|
|
verbose_name_plural = "业务预警规则"
|
|
ordering = ["code"]
|
|
|
|
def __str__(self):
|
|
return f"{self.name} (阈值: {self.threshold}) [{ '启用' if self.is_enabled else '停用' }]"
|