Files
junhong_cmp_fiber/internal/query/recorddisplay/lookup.go
邹进 3f593b912d
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 4m7s
feat: 记录查询列表补齐 ICCID、设备号、套餐名称、运营商名称与操作人
分页后按当前页 ID 批量查主键补齐展示字段,不在分页查询中关联,也不在记录表冗余:
- 采集成功记录补 ICCID、运营商名称;采集失败、卡日流量补运营商名称
- 套餐日流量详单、冲正流水补套餐名称、ICCID、设备号与 IMEI
- 冲正流水(含资产详情)补操作人用户名;退款后处理尝试记录补设备号与 IMEI
2026-11-07 17:07:27 +09:00

143 lines
4.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 recorddisplay 为记录查询列表补齐展示字段(ICCID、设备号、运营商名称、操作人)。
//
// 记录表只存内部 ID;列表先分页,再按当前页出现的 ID 批量查主键补齐,
// 不在分页查询里关联,也不在记录表里冗余这些字段。查到的是当前值。
package recorddisplay
import (
"context"
"gorm.io/gorm"
"github.com/break/junhong_cmp_fiber/internal/model"
"github.com/break/junhong_cmp_fiber/pkg/errors"
)
// Device 是设备展示字段。
type Device struct {
VirtualNo string
IMEI string
}
// Lookup 是当前页的展示字段字典;未找到的 ID 返回零值。
type Lookup struct {
iccids map[uint]string
devices map[uint]Device
carriers map[uint]string
operators map[uint]string
packages map[uint]string
}
// Request 是需要补齐的 ID 集合(可重复、可含 0,内部去重并忽略 0)。
type Request struct {
CardIDs []uint
DeviceIDs []uint
CarrierIDs []uint
OperatorIDs []uint
// PackageUsageIDs 用于取套餐使用记录上的套餐名称快照。
PackageUsageIDs []uint
}
// Load 按 ID 批量查询展示字段:每类最多一条主键查询,已删除的资产同样返回(历史记录仍需显示)。
func Load(ctx context.Context, db *gorm.DB, req Request) (*Lookup, error) {
lookup := &Lookup{
iccids: map[uint]string{}, devices: map[uint]Device{}, carriers: map[uint]string{}, operators: map[uint]string{},
packages: map[uint]string{},
}
session := db.WithContext(ctx).Unscoped()
if ids := distinct(req.CardIDs); len(ids) > 0 {
var rows []struct {
ID uint
ICCID string
}
if err := session.Model(&model.IotCard{}).Select("id, iccid").Where("id IN ?", ids).Scan(&rows).Error; err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询卡展示信息失败")
}
for _, row := range rows {
lookup.iccids[row.ID] = row.ICCID
}
}
if ids := distinct(req.DeviceIDs); len(ids) > 0 {
var rows []struct {
ID uint
VirtualNo string
IMEI string
}
if err := session.Model(&model.Device{}).Select("id, virtual_no, imei").Where("id IN ?", ids).Scan(&rows).Error; err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询设备展示信息失败")
}
for _, row := range rows {
lookup.devices[row.ID] = Device{VirtualNo: row.VirtualNo, IMEI: row.IMEI}
}
}
if ids := distinct(req.CarrierIDs); len(ids) > 0 {
var rows []struct {
ID uint
CarrierName string
}
if err := session.Model(&model.Carrier{}).Select("id, carrier_name").Where("id IN ?", ids).Scan(&rows).Error; err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询运营商账户展示信息失败")
}
for _, row := range rows {
lookup.carriers[row.ID] = row.CarrierName
}
}
if ids := distinct(req.OperatorIDs); len(ids) > 0 {
var rows []struct {
ID uint
Username string
}
if err := session.Model(&model.Account{}).Select("id, username").Where("id IN ?", ids).Scan(&rows).Error; err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询操作人展示信息失败")
}
for _, row := range rows {
lookup.operators[row.ID] = row.Username
}
}
if ids := distinct(req.PackageUsageIDs); len(ids) > 0 {
var rows []struct {
ID uint
PackageName string
}
if err := session.Model(&model.PackageUsage{}).Select("id, package_name").Where("id IN ?", ids).Scan(&rows).Error; err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询套餐名称失败")
}
for _, row := range rows {
lookup.packages[row.ID] = row.PackageName
}
}
return lookup, nil
}
// ICCID 返回卡 ICCID。
func (l *Lookup) ICCID(cardID uint) string { return l.iccids[cardID] }
// Device 返回设备号与 IMEI。
func (l *Lookup) Device(deviceID uint) Device { return l.devices[deviceID] }
// CarrierName 返回运营商账户名称。
func (l *Lookup) CarrierName(carrierID uint) string { return l.carriers[carrierID] }
// PackageName 返回套餐使用记录上的套餐名称快照。
func (l *Lookup) PackageName(packageUsageID uint) string { return l.packages[packageUsageID] }
// OperatorName 返回操作人账号用户名。
func (l *Lookup) OperatorName(accountID uint) string { return l.operators[accountID] }
func distinct(ids []uint) []uint {
seen := make(map[uint]struct{}, len(ids))
result := make([]uint, 0, len(ids))
for _, id := range ids {
if id == 0 {
continue
}
if _, ok := seen[id]; ok {
continue
}
seen[id] = struct{}{}
result = append(result, id)
}
return result
}