Files
junhong_cmp_fiber/internal/service/polling/audit.go
邹进 79b7580554
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m30s
feat: 下线设备保护期
- 后台设备停复机不再设置 1 小时保护期,也不再因保护期拒绝相反操作;单卡手动停复机去掉保护期检查
- 删除保护期一致性轮询(polling:protect)及其强制停复机方法;调度、初始化、监控、匹配预览不再包含保护期;已入队的旧任务由空处理函数直接确认,下一次发布移除
- 轮询配置接口不再接受与返回 protect_check_interval;并发配置不再返回 protect,查询、更新、重置该类型时拒绝
- 资产详情 device_protect_status 固定返回 none 并标记废弃,兼容老版本客户端
- 删除保护期 Redis key 与时长常量;停机原因 protect_period 保留供历史数据与开放接口映射
- 迁移 000249 只把 protect_check_interval、last_protect_check_at 列注释标记为已废弃,不删列不改数据
2026-10-25 17:19:10 +09:00

124 lines
4.7 KiB
Go

package polling
import (
"context"
stderrors "errors"
"strconv"
"gorm.io/gorm"
auditinfra "github.com/break/junhong_cmp_fiber/internal/infrastructure/audit"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/pkg/auditcontext"
"github.com/break/junhong_cmp_fiber/pkg/auditfailure"
"github.com/break/junhong_cmp_fiber/pkg/constants"
pkgerrors "github.com/break/junhong_cmp_fiber/pkg/errors"
)
func runPollingTransaction(ctx context.Context, db *gorm.DB, writer *auditinfra.Writer, fn func(*gorm.DB) error) error {
if db == nil || writer == nil {
return pkgerrors.New(pkgerrors.CodeInvalidStatus, "统一轮询审计接缝未配置")
}
return db.WithContext(ctx).Transaction(fn)
}
func writePollingAudit(ctx context.Context, tx *gorm.DB, writer *auditinfra.Writer, input auditinfra.PollingInput) error {
return writer.WritePolling(ctx, tx, input)
}
func recordPollingFailure(ctx context.Context, db *gorm.DB, writer *auditinfra.Writer, input auditinfra.PollingInput, originalErr error) {
if input.OperatorID == 0 || input.ResourceType == "" || input.ResourceKey == "" {
return
}
var appErr *pkgerrors.AppError
if !stderrors.As(originalErr, &appErr) {
appErr = pkgerrors.New(pkgerrors.CodeInternalError, "轮询操作失败")
}
if input.Result == "" {
input.Result = constants.AuditResultFailed
}
if input.ErrorCode == "" {
input.ErrorCode = strconv.Itoa(appErr.Code)
}
if input.ErrorSummary == "" {
input.ErrorSummary = appErr.Message
}
if db != nil && writer != nil {
if err := db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
return writePollingAudit(ctx, tx, writer, input)
}); err == nil {
return
} else {
originalErr = err
}
}
linkage := auditcontext.From(ctx)
auditfailure.RecordSecondaryWriteFailure(
input.ActionCode, input.ResourceKey, linkage.RequestID, linkage.CorrelationID, input.ErrorCode, originalErr,
)
}
func pollingConfigIdentity(config *model.PollingConfig) map[string]any {
return map[string]any{
"id": config.ID, "config_name": config.ConfigName, "card_condition": config.CardCondition,
"card_category": config.CardCategory, "carrier_id": config.CarrierID, "priority": config.Priority,
"status": config.Status,
}
}
func pollingConfigState(config *model.PollingConfig) map[string]any {
return map[string]any{
"config_name": config.ConfigName, "card_condition": config.CardCondition,
"card_category": config.CardCategory, "carrier_id": config.CarrierID, "priority": config.Priority,
"realname_check_interval": config.RealnameCheckInterval, "carddata_check_interval": config.CarddataCheckInterval,
"package_check_interval": config.PackageCheckInterval,
"card_status_check_interval": config.CardStatusCheckInterval, "status": config.Status,
"package_state": config.PackageState, "asset_status": config.AssetStatus,
"pre_reset_window": config.PreResetWindow, "pre_reset_carddata_interval": config.PreResetCarddataInterval,
"description": config.Description,
}
}
func pollingConcurrencyIdentity(config *model.PollingConcurrencyConfig) map[string]any {
return map[string]any{"id": config.ID, "task_type": config.TaskType, "max_concurrency": config.MaxConcurrency}
}
func pollingAlertRuleIdentity(rule *model.PollingAlertRule) map[string]any {
return map[string]any{
"id": rule.ID, "rule_name": rule.RuleName, "task_type": rule.TaskType,
"metric_type": rule.MetricType, "operator": rule.Operator, "threshold": rule.Threshold,
"alert_level": rule.AlertLevel, "status": rule.Status,
}
}
func pollingAlertRuleState(rule *model.PollingAlertRule) map[string]any {
return map[string]any{
"rule_name": rule.RuleName, "task_type": rule.TaskType, "metric_type": rule.MetricType,
"operator": rule.Operator, "threshold": rule.Threshold, "duration_minutes": rule.DurationMinutes,
"alert_level": rule.AlertLevel, "status": rule.Status, "cooldown_minutes": rule.CooldownMinutes,
"notification_channels_configured": rule.NotificationChannels != "", "description": rule.Description,
}
}
func pollingManualTriggerIdentity(log *model.PollingManualTriggerLog) map[string]any {
return map[string]any{
"id": log.ID, "task_type": log.TaskType, "trigger_type": log.TriggerType,
"total_count": log.TotalCount, "status": log.Status, "triggered_by": log.TriggeredBy,
}
}
func pollingManualTriggerKey(id uint) string {
return strconv.FormatUint(uint64(id), 10)
}
func pollingManualAttemptKey(taskType, triggerType string, operatorID uint) string {
return triggerType + ":" + taskType + ":" + strconv.FormatUint(uint64(operatorID), 10)
}
func pollingManualAttemptIdentity(taskType, triggerType string, totalCount int, operatorID uint) map[string]any {
return map[string]any{
"task_type": taskType, "trigger_type": triggerType,
"total_count": totalCount, "triggered_by": operatorID,
}
}