package business import ( "context" "encoding/json" "strconv" "strings" "kra/internal/biz/business" "kra/internal/service/dto" ) type AlertRecordUsecase interface { Platforms(context.Context) ([]string, error) Ignore(context.Context, []uint64) error List(context.Context, business.AlertRecordFilter, ...business.ListOption) (*business.AlertRecordPage, error) Detail(context.Context, uint64) (*business.AlertRecordDetail, error) Process(context.Context, uint64, business.AlertAction, string) error AddNote(context.Context, uint64, string, []string) error } func (s *AlertRecordService) Platforms(ctx context.Context) ([]string, error) { return s.uc.Platforms(ctx) } type AlertRecordService struct{ uc AlertRecordUsecase } func NewAlertRecordService(uc *business.AlertRecordUsecase) *AlertRecordService { return &AlertRecordService{uc: uc} } func alertRecordResponse(r *business.AlertRecord) *dto.AlertRecordResponse { metricLabel := "" if r.MonitorMetric != nil { metricLabel = business.AlertMetricLabel(*r.MonitorMetric) } return &dto.AlertRecordResponse{ID: r.ID, TotalPlayers: r.TotalPlayers, TotalPay: r.TotalPay, WarningColor: r.WarningColor, Lost: r.Lost, RuleID: r.RuleID, PlatformCode: r.PlatformCode, PlatformName: r.PlatformName, RuleName: r.RuleName, RuleType: r.RuleType, RuleTypeLabel: business.AlertRuleTypeLabel(r.RuleType), MonitorMetric: r.MonitorMetric, MonitorMetricLabel: metricLabel, TargetPromoteID: r.TargetPromoteID, TargetPromoteName: r.TargetPromoteName, BusinessID: r.BusinessID, BusinessName: r.BusinessName, AlertContent: r.AlertContent, Status: r.Status, StatusLabel: business.AlertStatusLabel(r.Status), CreatedAt: localTime(&r.CreatedAt), UpdatedAt: localTime(&r.UpdatedAt)} } func (s *AlertRecordService) List(ctx context.Context, req *dto.AlertRecordQuery) (*dto.AlertRecordPage, error) { if req == nil { return nil, business.ErrAlertRecordInput } if req.PlatformBusierID != nil && *req.PlatformBusierID == 0 { return nil, business.ErrAlertRecordInput } if req.MonitorMetric != nil && (*req.MonitorMetric < 1 || *req.MonitorMetric > 3) { return nil, business.ErrAlertRecordInput } if req.Status != nil && (*req.Status < 1 || *req.Status > 6) { return nil, business.ErrAlertRecordInput } page, size := req.Page, req.PageSize if page < 1 { page = 1 } if size < 1 { size = 10 } if size > 500 { size = 500 } if page > int(^uint(0)>>1)/size { return nil, business.ErrAlertRecordInput } filter := business.AlertRecordFilter{AlertContent: strings.TrimSpace(req.AlertContent), Lost: req.Lost, TargetPromoteID: req.TargetPromoteID, BusinessID: req.BusinessID, TargetPromoteName: strings.TrimSpace(req.TargetPromoteName), RuleName: strings.TrimSpace(req.RuleName), RuleType: strings.TrimSpace(req.RuleType), BusinessName: strings.TrimSpace(req.BusinessName), MonitorMetric: req.MonitorMetric, Status: req.Status} seen := map[string]bool{} filter.PlatformBusierID = req.PlatformBusierID for _, code := range strings.Split(req.PlatformCodes, ",") { code = strings.TrimSpace(code) if code != "" && !seen[code] { filter.PlatformCodes = append(filter.PlatformCodes, code) seen[code] = true } } result, err := s.uc.List(ctx, filter, business.ListOffset((page-1)*size), business.ListLimit(size)) if err != nil { return nil, err } out := &dto.AlertRecordPage{PageData: dto.AlertRecordRows{Rows: []*dto.AlertRecordResponse{}, Total: result.Total}, StatusCount: result.StatusCount, Available: result.Available} for _, row := range result.Rows { out.PageData.Rows = append(out.PageData.Rows, alertRecordResponse(row)) } return out, nil } func (s *AlertRecordService) Detail(ctx context.Context, id uint64) (*dto.AlertRecordDetail, error) { if id == 0 { return nil, business.ErrAlertRecordInput } detail, err := s.uc.Detail(ctx, id) if err != nil { return nil, err } out := &dto.AlertRecordDetail{AlertRecord: alertRecordResponse(detail.Record), OperationLogs: []*dto.AlertLogResponse{}, CanAudit: detail.CanAudit} for _, l := range detail.Logs { out.OperationLogs = append(out.OperationLogs, &dto.AlertLogResponse{ID: l.ID, AlertID: l.AlertID, OperatorID: l.OperatorID, OperatorName: l.OperatorName, LogType: l.LogType, LogTypeLabel: business.AlertLogTypeLabel(l.LogType), ActionDetail: l.ActionDetail, NoteContent: l.NoteContent, Attachments: l.Attachments, CreatedAt: localTime(&l.CreatedAt)}) } return out, nil } func (s *AlertRecordService) Process(ctx context.Context, req *dto.AlertProcessRequest, action business.AlertAction) error { if req == nil || len(req.Note) > 65535 { return business.ErrAlertRecordInput } id, err := strconv.ParseUint(req.AlertID.String(), 10, 64) if err != nil || id == 0 { return business.ErrAlertRecordInput } return s.uc.Process(ctx, id, action, req.Note) } func (s *AlertRecordService) AddNote(ctx context.Context, req *dto.AlertNoteRequest) error { if req == nil || len(req.NoteContent) > 65535 { return business.ErrAlertRecordInput } id, err := strconv.ParseUint(req.AlertID.String(), 10, 64) if err != nil || id == 0 { return business.ErrAlertRecordInput } if strings.TrimSpace(req.NoteContent) == "" { return business.ErrAlertNoteEmpty } values := make([]string, 0, len(req.AttachmentIDs)) for _, raw := range req.AttachmentIDs { var value string if json.Unmarshal(raw, &value) != nil { var number json.Number if json.Unmarshal(raw, &number) != nil { return business.ErrAlertRecordInput } if _, err := number.Int64(); err != nil { return business.ErrAlertRecordInput } value = number.String() } if value == "" { return business.ErrAlertRecordInput } values = append(values, value) } return s.uc.AddNote(ctx, id, req.NoteContent, values) }