Files
junhong_cmp_fiber/internal/query/pollingpause/query.go
邹进 7ddb9312e3
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m35s
feat: 不轮询清单与批量开关轮询
- 新增不轮询清单 tb_card_polling_pause(迁移 000256 补写存量),所有改 enable_polling 的入口同事务写清单
- 卡、设备勾选批量开关轮询(单次 500,逐项结果,开启跳过风险停机与已销户)与 CSV 文件导入
- 订单套餐生效、改有效期后自动恢复轮询并按规则评估复机
- 不轮询清单查询与导出;卡、设备列表与导出增加是否轮询
- 失败告警停机被拒视图、导出与批量关闭轮询;开关轮询影响说明

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 03:07:20 +09:00

112 lines
3.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package pollingpause 是不轮询清单的只读查询,供后台列表与导出共用(add-polling-pause-list-and-batch-toggle)。
package pollingpause
import (
"context"
"time"
"gorm.io/gorm"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/pkg/constants"
"github.com/break/junhong_cmp_fiber/pkg/errors"
)
// Filter 是不轮询清单筛选条件。
type Filter struct {
AssetType string
CarrierID *uint
Source string
Status *int
Identifier string
OperatorID *uint
StartTime *time.Time
EndTime *time.Time
}
// Row 是清单记录与资产当前状态、名称的投影。
type Row struct {
model.CardPollingPause
CarrierName string
EnablePolling bool
GatewayExtend string
ClosedByName string
RestoredByName string
}
// EnsureAllowed 不轮询清单仅超级管理员与平台账号可查看与导出。
func EnsureAllowed(userType int) error {
if userType == constants.UserTypeSuperAdmin || userType == constants.UserTypePlatform {
return nil
}
return errors.New(errors.CodeForbidden, "仅平台账号可查看不轮询清单")
}
// Query 不轮询清单只读查询。
type Query struct {
db *gorm.DB
}
// NewQuery 创建不轮询清单查询。
func NewQuery(db *gorm.DB) *Query {
return &Query{db: db}
}
func (q *Query) base(ctx context.Context, filter Filter) *gorm.DB {
query := q.db.WithContext(ctx).Table("tb_card_polling_pause AS p")
if filter.AssetType != "" {
query = query.Where("p.asset_type = ?", filter.AssetType)
}
if filter.CarrierID != nil {
query = query.Where("p.carrier_id = ?", *filter.CarrierID)
}
if filter.Source != "" {
query = query.Where("p.close_source = ?", filter.Source)
}
if filter.Status != nil {
query = query.Where("p.status = ?", *filter.Status)
}
if filter.Identifier != "" {
query = query.Where("p.identifier = ?", filter.Identifier)
}
if filter.OperatorID != nil {
query = query.Where("p.closed_by = ?", *filter.OperatorID)
}
if filter.StartTime != nil {
query = query.Where("p.closed_at >= ?", *filter.StartTime)
}
if filter.EndTime != nil {
query = query.Where("p.closed_at <= ?", *filter.EndTime)
}
return query
}
// Count 统计符合条件的记录数。
func (q *Query) Count(ctx context.Context, filter Filter) (int64, error) {
var total int64
if err := q.base(ctx, filter).Count(&total).Error; err != nil {
return 0, errors.Wrap(errors.CodeDatabaseError, err, "统计不轮询清单失败")
}
return total, nil
}
// Page 按关闭时间倒序返回一页记录,附带资产当前轮询开关、网关扩展状态、运营商账户与操作人名称。
func (q *Query) Page(ctx context.Context, filter Filter, offset, limit int) ([]Row, error) {
var rows []Row
err := q.base(ctx, filter).
Select(`p.*, COALESCE(ca.carrier_name, '') AS carrier_name,
COALESCE(c.enable_polling, d.enable_polling, FALSE) AS enable_polling,
COALESCE(c.gateway_extend, '') AS gateway_extend,
COALESCE(a1.username, '') AS closed_by_name, COALESCE(a2.username, '') AS restored_by_name`).
Joins("LEFT JOIN tb_iot_card c ON p.asset_type = 'iot_card' AND c.id = p.asset_id").
Joins("LEFT JOIN tb_device d ON p.asset_type = 'device' AND d.id = p.asset_id").
Joins("LEFT JOIN tb_carrier ca ON ca.id = p.carrier_id").
Joins("LEFT JOIN tb_account a1 ON a1.id = p.closed_by").
Joins("LEFT JOIN tb_account a2 ON a2.id = p.restored_by").
Order("p.closed_at DESC, p.id DESC").Offset(offset).Limit(limit).Scan(&rows).Error
if err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询不轮询清单失败")
}
return rows, nil
}