feat: 记录查询列表补齐 ICCID、设备号、套餐名称、运营商名称与操作人
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 4m7s
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 4m7s
分页后按当前页 ID 批量查主键补齐展示字段,不在分页查询中关联,也不在记录表冗余: - 采集成功记录补 ICCID、运营商名称;采集失败、卡日流量补运营商名称 - 套餐日流量详单、冲正流水补套餐名称、ICCID、设备号与 IMEI - 冲正流水(含资产详情)补操作人用户名;退款后处理尝试记录补设备号与 IMEI
This commit is contained in:
@@ -298,6 +298,7 @@ type PackageTrafficAdjustmentItem struct {
|
||||
RefObservationID string `json:"ref_observation_id" description:"关联的采集 ID"`
|
||||
RefEventID string `json:"ref_event_id" description:"关联的流量事件 ID"`
|
||||
OperatorID uint `json:"operator_id" description:"操作人账号ID"`
|
||||
OperatorName string `json:"operator_name" description:"操作人账号用户名"`
|
||||
CreatedAt time.Time `json:"created_at" description:"冲正时间"`
|
||||
}
|
||||
|
||||
|
||||
@@ -50,8 +50,10 @@ type TrafficCollectionListRequest struct {
|
||||
// TrafficCollectionRecordItem 采集成功记录。
|
||||
type TrafficCollectionRecordItem struct {
|
||||
CardTrafficCollectionItem
|
||||
IotCardID uint `json:"iot_card_id" description:"卡ID"`
|
||||
CarrierID uint `json:"carrier_id" description:"运营商账户ID(历史记录为 0)"`
|
||||
IotCardID uint `json:"iot_card_id" description:"卡ID"`
|
||||
ICCID string `json:"iccid" description:"ICCID"`
|
||||
CarrierID uint `json:"carrier_id" description:"运营商账户ID(历史记录为 0)"`
|
||||
CarrierName string `json:"carrier_name" description:"运营商账户名称"`
|
||||
}
|
||||
|
||||
// TrafficCollectionRecordListResponse 采集成功记录分页结果。
|
||||
@@ -79,6 +81,7 @@ type TrafficCollectionFailureItem struct {
|
||||
IotCardID uint `json:"iot_card_id" description:"卡ID"`
|
||||
ICCID string `json:"iccid" description:"ICCID"`
|
||||
CarrierID uint `json:"carrier_id" description:"运营商账户ID"`
|
||||
CarrierName string `json:"carrier_name" description:"运营商账户名称"`
|
||||
ObservedAt time.Time `json:"observed_at" description:"采集时间"`
|
||||
ObservationID string `json:"observation_id" description:"采集 ID(等于对接日志 integration_id)"`
|
||||
Source string `json:"source" description:"来源"`
|
||||
@@ -112,6 +115,7 @@ type CardDailyUsageItem struct {
|
||||
IotCardID uint `json:"iot_card_id" description:"卡ID"`
|
||||
ICCID string `json:"iccid" description:"ICCID"`
|
||||
CarrierID uint `json:"carrier_id" description:"运营商账户ID"`
|
||||
CarrierName string `json:"carrier_name" description:"运营商账户名称"`
|
||||
Date string `json:"date" description:"日期(上海)"`
|
||||
SettledMB float64 `json:"settled_mb" description:"当日已结算增量合计(MB),即当日用量"`
|
||||
MonthUsedMB float64 `json:"month_used_mb" description:"当日结束时的本月自然月累计(MB)"`
|
||||
@@ -142,8 +146,12 @@ type PackageUsageDailyRecordItem struct {
|
||||
ID uint `json:"id" description:"记录ID"`
|
||||
PackageUsageID uint `json:"package_usage_id" description:"套餐使用记录ID"`
|
||||
PackageID uint `json:"package_id" description:"套餐ID"`
|
||||
PackageName string `json:"package_name" description:"套餐名称(套餐使用记录快照)"`
|
||||
IotCardID uint `json:"iot_card_id" description:"卡ID,设备套餐为 0"`
|
||||
ICCID string `json:"iccid" description:"ICCID(卡套餐)"`
|
||||
DeviceID uint `json:"device_id" description:"设备ID,卡套餐为 0"`
|
||||
DeviceVirtualNo string `json:"device_virtual_no" description:"设备号(设备套餐)"`
|
||||
DeviceIMEI string `json:"device_imei" description:"设备 IMEI(设备套餐)"`
|
||||
Date string `json:"date" description:"日期"`
|
||||
DailyUsageMB int `json:"daily_usage_mb" description:"当日流量(MB)"`
|
||||
CumulativeUsageMB int64 `json:"cumulative_usage_mb" description:"截止当日累计(MB)"`
|
||||
@@ -169,8 +177,12 @@ type PackageTrafficAdjustmentQueryRequest struct {
|
||||
// PackageTrafficAdjustmentRecordItem 冲正流水(跨卡列表)。
|
||||
type PackageTrafficAdjustmentRecordItem struct {
|
||||
PackageTrafficAdjustmentItem
|
||||
IotCardID uint `json:"iot_card_id" description:"卡ID"`
|
||||
DeviceID uint `json:"device_id" description:"设备ID"`
|
||||
PackageName string `json:"package_name" description:"套餐名称(套餐使用记录快照)"`
|
||||
IotCardID uint `json:"iot_card_id" description:"卡ID"`
|
||||
ICCID string `json:"iccid" description:"ICCID(卡套餐)"`
|
||||
DeviceID uint `json:"device_id" description:"设备ID"`
|
||||
DeviceVirtualNo string `json:"device_virtual_no" description:"设备号(设备套餐)"`
|
||||
DeviceIMEI string `json:"device_imei" description:"设备 IMEI(设备套餐)"`
|
||||
}
|
||||
|
||||
// PackageTrafficAdjustmentRecordListResponse 冲正流水分页结果(跨卡列表)。
|
||||
@@ -194,20 +206,22 @@ type RefundPostProcessAttemptListRequest struct {
|
||||
|
||||
// RefundPostProcessAttemptItem 退款资产后处理尝试记录。
|
||||
type RefundPostProcessAttemptItem struct {
|
||||
ID uint `json:"id" description:"记录ID"`
|
||||
RefundID uint `json:"refund_id" description:"退款单ID"`
|
||||
RefundNo string `json:"refund_no" description:"退款单号"`
|
||||
Step string `json:"step" description:"处理步骤(失败时为失败步骤,成功为 done)"`
|
||||
AssetType string `json:"asset_type" description:"资产类型"`
|
||||
AssetID uint `json:"asset_id" description:"资产ID"`
|
||||
ICCID string `json:"iccid" description:"ICCID(单卡资产)"`
|
||||
Attempt int `json:"attempt" description:"尝试序号"`
|
||||
Trigger string `json:"trigger" description:"触发方式"`
|
||||
Result string `json:"result" description:"结果"`
|
||||
ErrorCode string `json:"error_code" description:"错误码"`
|
||||
ErrorMessage string `json:"error_message" description:"错误信息"`
|
||||
DurationMS int `json:"duration_ms" description:"耗时(毫秒)"`
|
||||
CreatedAt time.Time `json:"created_at" description:"记录时间"`
|
||||
ID uint `json:"id" description:"记录ID"`
|
||||
RefundID uint `json:"refund_id" description:"退款单ID"`
|
||||
RefundNo string `json:"refund_no" description:"退款单号"`
|
||||
Step string `json:"step" description:"处理步骤(失败时为失败步骤,成功为 done)"`
|
||||
AssetType string `json:"asset_type" description:"资产类型"`
|
||||
AssetID uint `json:"asset_id" description:"资产ID"`
|
||||
ICCID string `json:"iccid" description:"ICCID(单卡资产)"`
|
||||
DeviceVirtualNo string `json:"device_virtual_no" description:"设备号(设备资产)"`
|
||||
DeviceIMEI string `json:"device_imei" description:"设备 IMEI(设备资产)"`
|
||||
Attempt int `json:"attempt" description:"尝试序号"`
|
||||
Trigger string `json:"trigger" description:"触发方式"`
|
||||
Result string `json:"result" description:"结果"`
|
||||
ErrorCode string `json:"error_code" description:"错误码"`
|
||||
ErrorMessage string `json:"error_message" description:"错误信息"`
|
||||
DurationMS int `json:"duration_ms" description:"耗时(毫秒)"`
|
||||
CreatedAt time.Time `json:"created_at" description:"记录时间"`
|
||||
}
|
||||
|
||||
// RefundPostProcessAttemptListResponse 退款资产后处理尝试记录分页结果。
|
||||
|
||||
142
internal/query/recorddisplay/lookup.go
Normal file
142
internal/query/recorddisplay/lookup.go
Normal file
@@ -0,0 +1,142 @@
|
||||
// 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
|
||||
}
|
||||
50
internal/query/recorddisplay/lookup_test.go
Normal file
50
internal/query/recorddisplay/lookup_test.go
Normal file
@@ -0,0 +1,50 @@
|
||||
package recorddisplay
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDistinctSkipsZeroAndDuplicates(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in []uint
|
||||
want []uint
|
||||
}{
|
||||
{name: "空", in: nil, want: []uint{}},
|
||||
{name: "只有 0", in: []uint{0, 0}, want: []uint{}},
|
||||
{name: "去重并保持顺序", in: []uint{3, 0, 1, 3, 2, 1}, want: []uint{3, 1, 2}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := distinct(tt.in); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Fatalf("distinct(%v) = %v, want %v", tt.in, got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLookupMissingIDsReturnZeroValues(t *testing.T) {
|
||||
lookup := &Lookup{
|
||||
iccids: map[uint]string{1: "8986001"},
|
||||
devices: map[uint]Device{2: {VirtualNo: "60003081372", IMEI: "869555083099518"}},
|
||||
carriers: map[uint]string{},
|
||||
operators: map[uint]string{},
|
||||
packages: map[uint]string{},
|
||||
}
|
||||
if got := lookup.ICCID(1); got != "8986001" {
|
||||
t.Fatalf("ICCID(1) = %q", got)
|
||||
}
|
||||
if got := lookup.ICCID(9); got != "" {
|
||||
t.Fatalf("ICCID(9) = %q, want empty", got)
|
||||
}
|
||||
if got := lookup.Device(2); got.VirtualNo != "60003081372" || got.IMEI != "869555083099518" {
|
||||
t.Fatalf("Device(2) = %+v", got)
|
||||
}
|
||||
if got := lookup.Device(0); got != (Device{}) {
|
||||
t.Fatalf("Device(0) = %+v, want zero", got)
|
||||
}
|
||||
if lookup.CarrierName(5) != "" || lookup.OperatorName(5) != "" || lookup.PackageName(5) != "" {
|
||||
t.Fatal("missing IDs must return empty strings")
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/break/junhong_cmp_fiber/internal/domain/cardflow"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
"github.com/break/junhong_cmp_fiber/internal/query/recorddisplay"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/middleware"
|
||||
@@ -182,9 +183,19 @@ func (s *Service) ListTrafficCollectionRecords(ctx context.Context, req *dto.Tra
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询采集成功记录失败")
|
||||
}
|
||||
successReq := recorddisplay.Request{}
|
||||
for _, row := range rows {
|
||||
successReq.CardIDs = append(successReq.CardIDs, row.IotCardID)
|
||||
successReq.CarrierIDs = append(successReq.CarrierIDs, row.CarrierID)
|
||||
}
|
||||
display, err := recorddisplay.Load(ctx, s.db, successReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range rows {
|
||||
resp.Items = append(resp.Items, dto.TrafficCollectionRecordItem{
|
||||
CardTrafficCollectionItem: collectionSuccessItem(row), IotCardID: row.IotCardID, CarrierID: row.CarrierID,
|
||||
CardTrafficCollectionItem: collectionSuccessItem(row), IotCardID: row.IotCardID, ICCID: display.ICCID(row.IotCardID),
|
||||
CarrierID: row.CarrierID, CarrierName: display.CarrierName(row.CarrierID),
|
||||
})
|
||||
}
|
||||
resp.Total = total
|
||||
@@ -217,8 +228,18 @@ func (s *Service) ListTrafficCollectionFailures(ctx context.Context, req *dto.Tr
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询采集失败记录失败")
|
||||
}
|
||||
carrierIDs := make([]uint, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
resp.Items = append(resp.Items, collectionFailureItem(row))
|
||||
carrierIDs = append(carrierIDs, row.CarrierID)
|
||||
}
|
||||
display, err := recorddisplay.Load(ctx, s.db, recorddisplay.Request{CarrierIDs: carrierIDs})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range rows {
|
||||
item := collectionFailureItem(row)
|
||||
item.CarrierName = display.CarrierName(row.CarrierID)
|
||||
resp.Items = append(resp.Items, item)
|
||||
}
|
||||
resp.Total = total
|
||||
return resp, nil
|
||||
@@ -257,10 +278,19 @@ func (s *Service) ListCardDailyUsages(ctx context.Context, req *dto.CardDailyUsa
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询卡日流量失败")
|
||||
}
|
||||
carrierIDs := make([]uint, 0, len(rows))
|
||||
for _, item := range rows {
|
||||
carrierIDs = append(carrierIDs, item.CarrierID)
|
||||
}
|
||||
display, err := recorddisplay.Load(ctx, s.db, recorddisplay.Request{CarrierIDs: carrierIDs})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range rows {
|
||||
resp.Items = append(resp.Items, dto.CardDailyUsageItem{
|
||||
ID: item.ID, IotCardID: item.IotCardID, ICCID: item.ICCID, CarrierID: item.CarrierID,
|
||||
Date: item.FlowDate.Format(recordDateLayout), SettledMB: item.SettledMB, MonthUsedMB: item.MonthUsedMB,
|
||||
CarrierName: display.CarrierName(item.CarrierID),
|
||||
Date: item.FlowDate.Format(recordDateLayout), SettledMB: item.SettledMB, MonthUsedMB: item.MonthUsedMB,
|
||||
VendorUsedMB: item.VendorUsedMB, StaleGuarded: item.StaleGuarded, ObsCount: item.ObsCount, UpdatedAt: item.UpdatedAt,
|
||||
})
|
||||
}
|
||||
@@ -282,12 +312,13 @@ func (s *Service) ListPackageUsageDailyRecords(ctx context.Context, req *dto.Pac
|
||||
}
|
||||
type row struct {
|
||||
model.PackageUsageDailyRecord
|
||||
PackageID uint
|
||||
IotCardID uint
|
||||
DeviceID uint
|
||||
PackageID uint
|
||||
PackageName string
|
||||
IotCardID uint
|
||||
DeviceID uint
|
||||
}
|
||||
query := s.db.WithContext(ctx).Table("tb_package_usage_daily_record AS r").
|
||||
Select("r.*, pu.package_id, COALESCE(pu.iot_card_id, 0) AS iot_card_id, COALESCE(pu.device_id, 0) AS device_id").
|
||||
Select("r.*, pu.package_id, pu.package_name, COALESCE(pu.iot_card_id, 0) AS iot_card_id, COALESCE(pu.device_id, 0) AS device_id").
|
||||
Joins("JOIN tb_package_usage pu ON pu.id = r.package_usage_id").
|
||||
Where("r.date >= ? AND r.date <= ?", from.Format(recordDateLayout), to.Format(recordDateLayout))
|
||||
if !scope.all {
|
||||
@@ -310,10 +341,21 @@ func (s *Service) ListPackageUsageDailyRecords(ctx context.Context, req *dto.Pac
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询套餐日流量详单失败")
|
||||
}
|
||||
dailyReq := recorddisplay.Request{}
|
||||
for _, item := range rows {
|
||||
dailyReq.CardIDs = append(dailyReq.CardIDs, item.IotCardID)
|
||||
dailyReq.DeviceIDs = append(dailyReq.DeviceIDs, item.DeviceID)
|
||||
}
|
||||
display, err := recorddisplay.Load(ctx, s.db, dailyReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, item := range rows {
|
||||
device := display.Device(item.DeviceID)
|
||||
resp.Items = append(resp.Items, dto.PackageUsageDailyRecordItem{
|
||||
ID: item.ID, PackageUsageID: item.PackageUsageID, PackageID: item.PackageID, IotCardID: item.IotCardID,
|
||||
DeviceID: item.DeviceID, Date: item.Date.Format(recordDateLayout), DailyUsageMB: item.DailyUsageMB,
|
||||
ID: item.ID, PackageUsageID: item.PackageUsageID, PackageID: item.PackageID, PackageName: item.PackageName,
|
||||
IotCardID: item.IotCardID, ICCID: display.ICCID(item.IotCardID),
|
||||
DeviceID: item.DeviceID, DeviceVirtualNo: device.VirtualNo, DeviceIMEI: device.IMEI, Date: item.Date.Format(recordDateLayout), DailyUsageMB: item.DailyUsageMB,
|
||||
CumulativeUsageMB: item.CumulativeUsageMB, UpdatedAt: item.UpdatedAt,
|
||||
})
|
||||
}
|
||||
@@ -357,9 +399,25 @@ func (s *Service) ListPackageTrafficAdjustmentRecords(ctx context.Context, req *
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询套餐流量冲正流水失败")
|
||||
}
|
||||
adjReq := recorddisplay.Request{}
|
||||
for _, row := range rows {
|
||||
adjReq.CardIDs = append(adjReq.CardIDs, row.IotCardID)
|
||||
adjReq.DeviceIDs = append(adjReq.DeviceIDs, row.DeviceID)
|
||||
adjReq.OperatorIDs = append(adjReq.OperatorIDs, row.OperatorID)
|
||||
adjReq.PackageUsageIDs = append(adjReq.PackageUsageIDs, row.PackageUsageID)
|
||||
}
|
||||
display, err := recorddisplay.Load(ctx, s.db, adjReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range rows {
|
||||
item := toTrafficAdjustmentItem(row)
|
||||
item.OperatorName = display.OperatorName(row.OperatorID)
|
||||
device := display.Device(row.DeviceID)
|
||||
resp.Items = append(resp.Items, dto.PackageTrafficAdjustmentRecordItem{
|
||||
PackageTrafficAdjustmentItem: toTrafficAdjustmentItem(row), IotCardID: row.IotCardID, DeviceID: row.DeviceID,
|
||||
PackageTrafficAdjustmentItem: item, PackageName: display.PackageName(row.PackageUsageID),
|
||||
IotCardID: row.IotCardID, ICCID: display.ICCID(row.IotCardID),
|
||||
DeviceID: row.DeviceID, DeviceVirtualNo: device.VirtualNo, DeviceIMEI: device.IMEI,
|
||||
})
|
||||
}
|
||||
resp.Total = total
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
stopresumedomain "github.com/break/junhong_cmp_fiber/internal/domain/stopresume"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
"github.com/break/junhong_cmp_fiber/internal/query/recorddisplay"
|
||||
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
@@ -190,9 +191,19 @@ func (s *Service) ListPackageTrafficAdjustments(ctx context.Context, assetType s
|
||||
if err := query.Order("created_at DESC, id DESC").Offset((page - 1) * size).Limit(size).Find(&rows).Error; err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询冲正流水失败")
|
||||
}
|
||||
operatorIDs := make([]uint, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
operatorIDs = append(operatorIDs, row.OperatorID)
|
||||
}
|
||||
display, err := recorddisplay.Load(ctx, s.db, recorddisplay.Request{OperatorIDs: operatorIDs})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items := make([]dto.PackageTrafficAdjustmentItem, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
items = append(items, toTrafficAdjustmentItem(row))
|
||||
item := toTrafficAdjustmentItem(row)
|
||||
item.OperatorName = display.OperatorName(row.OperatorID)
|
||||
items = append(items, item)
|
||||
}
|
||||
return &dto.PackageTrafficAdjustmentListResponse{Items: items, Total: total}, nil
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/break/junhong_cmp_fiber/internal/domain/cardflow"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
"github.com/break/junhong_cmp_fiber/internal/query/recorddisplay"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/middleware"
|
||||
@@ -72,10 +73,24 @@ func (s *Service) ListAssetPostProcessAttempts(ctx context.Context, req *dto.Ref
|
||||
if err := query.Order("created_at DESC, id DESC").Offset((page - 1) * size).Limit(size).Find(&rows).Error; err != nil {
|
||||
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询退款资产后处理尝试记录失败")
|
||||
}
|
||||
displayReq := recorddisplay.Request{}
|
||||
for _, row := range rows {
|
||||
if row.AssetType == constants.AssetTypeDevice {
|
||||
displayReq.DeviceIDs = append(displayReq.DeviceIDs, row.AssetID)
|
||||
}
|
||||
}
|
||||
display, err := recorddisplay.Load(ctx, s.db, displayReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, row := range rows {
|
||||
var device recorddisplay.Device
|
||||
if row.AssetType == constants.AssetTypeDevice {
|
||||
device = display.Device(row.AssetID)
|
||||
}
|
||||
resp.Items = append(resp.Items, dto.RefundPostProcessAttemptItem{
|
||||
ID: row.ID, RefundID: row.RefundID, RefundNo: row.RefundNo, Step: row.Step, AssetType: row.AssetType,
|
||||
AssetID: row.AssetID, ICCID: row.ICCID, Attempt: row.Attempt, Trigger: row.Trigger, Result: row.Result,
|
||||
AssetID: row.AssetID, ICCID: row.ICCID, DeviceVirtualNo: device.VirtualNo, DeviceIMEI: device.IMEI, Attempt: row.Attempt, Trigger: row.Trigger, Result: row.Result,
|
||||
ErrorCode: row.ErrorCode, ErrorMessage: row.ErrorMessage, DurationMS: row.DurationMS, CreatedAt: row.CreatedAt,
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user