Files
bj_power/bj_power_mes/internal/logic/alert.go
T
SunYF 5c3b747a20 feat: 新增预警与附件模块,优化工位派工功能
1. 新增预警规则、预警消息、业务附件数据库表与CRUD逻辑
2. 为拧紧记录添加审核人、审核时间字段及审核留痕功能
3. 优化产线点位类型与编号描述,更新工位组合下发菜单名称为工艺路线派工
4. 新增上传文件获取原文件名与大小的工具方法
5. 在系统管理菜单新增预警中心与附件中心入口
2026-09-14 16:31:08 +08:00

107 lines
3.5 KiB
Go

package logic
import (
"context"
"errors"
"bj_power_mes/ent"
"bj_power_mes/ent/alert"
"bj_power_mes/ent/alertrule"
)
// CreateAlertRule 新增预警规则
func (s *Service) CreateAlertRule(ctx context.Context, name, typ string, threshold float64, receiver string, enabled bool, createdBy string) error {
if name == "" || typ == "" {
return errors.New("规则名称与类型必填")
}
_, err := s.ctx.EntClient.AlertRule.Create().
SetName(name).SetType(typ).SetThreshold(threshold).
SetReceiver(receiver).SetEnabled(enabled).SetCreatedBy(createdBy).Save(ctx)
return err
}
// UpdateAlertRule 修改预警规则
func (s *Service) UpdateAlertRule(ctx context.Context, id int, name, typ string, threshold float64, receiver string, enabled bool) error {
if id <= 0 {
return errors.New("规则ID无效")
}
if name == "" || typ == "" {
return errors.New("规则名称与类型必填")
}
_, err := s.ctx.EntClient.AlertRule.UpdateOneID(id).
SetName(name).SetType(typ).SetThreshold(threshold).
SetReceiver(receiver).SetEnabled(enabled).Save(ctx)
return err
}
// DeleteAlertRule 删除预警规则
func (s *Service) DeleteAlertRule(ctx context.Context, id int) error {
if id <= 0 {
return errors.New("规则ID无效")
}
return s.ctx.EntClient.AlertRule.DeleteOneID(id).Exec(ctx)
}
// ListAlertRules 查询全部预警规则
func (s *Service) ListAlertRules(ctx context.Context) ([]*ent.AlertRule, error) {
return s.ctx.EntClient.AlertRule.Query().
Order(ent.Desc(alertrule.FieldCreatedAt), ent.Desc(alertrule.FieldID)).All(ctx)
}
// ListAlerts 查询预警消息(status 空=全部)
func (s *Service) ListAlerts(ctx context.Context, status string) ([]*ent.Alert, error) {
q := s.ctx.EntClient.Alert.Query()
if status != "" {
q = q.Where(alert.Status(status))
}
return q.Order(ent.Desc(alert.FieldCreatedAt), ent.Desc(alert.FieldID)).All(ctx)
}
// UnreadAlertCount 未读预警数
func (s *Service) UnreadAlertCount(ctx context.Context) (int, error) {
return s.ctx.EntClient.Alert.Query().Where(alert.Status("UNREAD")).Count(ctx)
}
// MarkAlertRead 标记预警已读
func (s *Service) MarkAlertRead(ctx context.Context, id int) error {
if id <= 0 {
return errors.New("预警ID无效")
}
_, err := s.ctx.EntClient.Alert.UpdateOneID(id).SetStatus("READ").Save(ctx)
return err
}
// alertDirection 阈值比较方向:inventory_low 为 <=,其余为 >=
func alertDirection(typ string) int {
if typ == "inventory_low" {
return -1
}
return 1
}
// Evaluate 预警规则评估:遍历启用且类型匹配的规则,命中阈值则写 alert 消息。
// 由业务事件触发(如拧紧不合格),也可手动调用。
func (s *Service) Evaluate(ctx context.Context, typ string, value float64, title, content, refType, refId string) {
rules, err := s.ctx.EntClient.AlertRule.Query().
Where(alertrule.Type(typ), alertrule.Enabled(true)).All(ctx)
if err != nil || len(rules) == 0 {
return
}
dir := alertDirection(typ)
for _, r := range rules {
hit := (dir == 1 && value >= r.Threshold) || (dir == -1 && value <= r.Threshold)
if !hit {
continue
}
_ = s.createAlert(ctx, r.ID, typ, title, content, refType, refId, r.Receiver)
}
}
func (s *Service) createAlert(ctx context.Context, ruleId int, typ, title, content, refType, refId, receiver string) error {
_, err := s.ctx.EntClient.Alert.Create().
SetRuleId(ruleId).SetType(typ).SetTitle(title).
SetContent(content).SetRefType(refType).SetRefId(refId).
SetReceiver(receiver).SetStatus("UNREAD").Save(ctx)
return err
}