Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
GORM 默认把字段 ICCID 映射成 icc_id,卡日流量的 c.iccid 和展示字段批量查询都读不到值; 扫描用的匿名结构统一写 gorm column tag。
144 lines
4.9 KiB
Go
144 lines
4.9 KiB
Go
// 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 {
|
||
// 显式列名:GORM 默认把字段 ICCID 映射成 icc_id,不写 tag 会读不到值。
|
||
var rows []struct {
|
||
ID uint `gorm:"column:id"`
|
||
ICCID string `gorm:"column:iccid"`
|
||
}
|
||
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 `gorm:"column:id"`
|
||
VirtualNo string `gorm:"column:virtual_no"`
|
||
IMEI string `gorm:"column:imei"`
|
||
}
|
||
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 `gorm:"column:id"`
|
||
CarrierName string `gorm:"column:carrier_name"`
|
||
}
|
||
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 `gorm:"column:id"`
|
||
Username string `gorm:"column:username"`
|
||
}
|
||
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 `gorm:"column:id"`
|
||
PackageName string `gorm:"column:package_name"`
|
||
}
|
||
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
|
||
}
|