From 226a15573a53fa4d4a88bbf87bde9d1388228fbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=82=B9=E8=BF=9B?= Date: Sat, 7 Nov 2026 17:39:46 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=82=E6=B5=8B=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E4=B8=8E=E6=8B=92=E7=BB=9D=E5=81=9C=E6=9C=BA=E5=91=8A=E8=AD=A6?= =?UTF-8?q?=E8=AF=BB=E5=8F=96=20ICCID=20=E6=97=B6=E6=98=BE=E5=BC=8F?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E5=88=97=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GORM 默认把字段 ICCID 映射成 icc_id: - 观测序列设备换卡的本地预期判定读不到当前卡 ICCID,永远判不成立,只能靠调网关重试到上限 - 拒绝停机告警列表 ICCID 一直为空 补列名测试防回归。 --- .../cardobservation/series_runner.go | 7 +++-- internal/query/pollingalert/stop_refused.go | 2 +- .../pollingalert/stop_refused_columns_test.go | 20 +++++++++++++ internal/query/recorddisplay/columns_test.go | 29 +++++++++++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 internal/query/pollingalert/stop_refused_columns_test.go create mode 100644 internal/query/recorddisplay/columns_test.go diff --git a/internal/infrastructure/cardobservation/series_runner.go b/internal/infrastructure/cardobservation/series_runner.go index 0ee473aa..d3fffb64 100644 --- a/internal/infrastructure/cardobservation/series_runner.go +++ b/internal/infrastructure/cardobservation/series_runner.go @@ -475,10 +475,11 @@ func (r *SeriesRunner) loadCurrentICCIDs(ctx context.Context, payload cardapp.Se if err != nil { return nil, err } + // 显式列名:GORM 默认把 ICCID 映射成 icc_id,不写 tag 时三个值都读不到,本地预期判定永远不成立。 var current struct { - ICCID string - ICCID19 string - ICCID20 *string + ICCID string `gorm:"column:iccid"` + ICCID19 string `gorm:"column:iccid_19"` + ICCID20 *string `gorm:"column:iccid_20"` } err = r.db.WithContext(ctx).Table("tb_device_sim_binding AS binding"). Select("card.iccid, card.iccid_19, card.iccid_20"). diff --git a/internal/query/pollingalert/stop_refused.go b/internal/query/pollingalert/stop_refused.go index 80ec4963..b7309cd4 100644 --- a/internal/query/pollingalert/stop_refused.go +++ b/internal/query/pollingalert/stop_refused.go @@ -24,7 +24,7 @@ type StopRefusedFilter struct { type StopRefusedRow struct { ID uint CardID uint - ICCID string + ICCID string `gorm:"column:iccid"` // 显式列名:GORM 默认映射成 icc_id CarrierID uint CarrierName string DeviceID uint diff --git a/internal/query/pollingalert/stop_refused_columns_test.go b/internal/query/pollingalert/stop_refused_columns_test.go new file mode 100644 index 00000000..d2775199 --- /dev/null +++ b/internal/query/pollingalert/stop_refused_columns_test.go @@ -0,0 +1,20 @@ +package pollingalert + +import ( + "sync" + "testing" + + "gorm.io/gorm/schema" +) + +// GORM 默认把字段 ICCID 映射成 icc_id;查询选的是 a.iccid,必须显式指定列名,否则列表 ICCID 一直为空。 +func TestStopRefusedRowICCIDColumn(t *testing.T) { + s, err := schema.Parse(&StopRefusedRow{}, &sync.Map{}, schema.NamingStrategy{}) + if err != nil { + t.Fatalf("parse StopRefusedRow: %v", err) + } + field := s.LookUpField("ICCID") + if field == nil || field.DBName != "iccid" { + t.Fatalf("StopRefusedRow.ICCID column = %v, want iccid", field) + } +} diff --git a/internal/query/recorddisplay/columns_test.go b/internal/query/recorddisplay/columns_test.go new file mode 100644 index 00000000..7fc7df36 --- /dev/null +++ b/internal/query/recorddisplay/columns_test.go @@ -0,0 +1,29 @@ +package recorddisplay + +import ( + "sync" + "testing" + + "gorm.io/gorm/schema" +) + +// 防回归:不带 column tag 时 GORM 会把 ICCID 读成 icc_id 列。 +func TestDefaultNamingSplitsICCID(t *testing.T) { + type untagged struct{ ICCID string } + type tagged struct { + ICCID string `gorm:"column:iccid"` + } + for _, tc := range []struct { + name string + v any + want string + }{{"untagged", &untagged{}, "icc_id"}, {"tagged", &tagged{}, "iccid"}} { + s, err := schema.Parse(tc.v, &sync.Map{}, schema.NamingStrategy{}) + if err != nil { + t.Fatal(err) + } + if got := s.LookUpField("ICCID").DBName; got != tc.want { + t.Fatalf("%s: DBName = %q, want %q", tc.name, got, tc.want) + } + } +}