Files
iotlcm/server/internal/logic/iot/simcardbatch/renew/identity.go
T
MiFaZhan 59eb34976a chore: 初始开源发布
iotlcm-admin-svr:管理后台服务。

- Go module:iotlcm → git.5iot.com/iotlcm-public/iotlcm-admin-svr(729 文件)
- 凭据与地址脱敏:JWT signingKey(含代码里的 MustGet 默认值)、
  MySQL DSN、Redis 口令、告警邮件发件人邮箱全部改为占位;
  私网 IP → 文档地址段;库名 xiujie_admin → iotlcm
- 真实手机号/邮箱 → 合法 11 位编造号 / example.com
- 移除内部资产:CI 触发器、过时 DDL(sql/db_iotlcm.sql)、
  私有依赖 go get 行、明文 registry 登录口令
- 启动 banner 统一 IOTLCM 方块字 + 社区惯例署名
- Dockerfile 改用公共基础镜像
- 拼错的 RADEME.md → README.md,README 重写
- 需要真实数据库的用例改为可用 IOTLCM_TEST_WITH_DB=1 显式启用
- 补 Apache-2.0 LICENSE,LF 行尾 + .gitattributes

数据库 schema 不随本仓发布(生产 DDL 已过时),README 已说明。
2026-10-23 14:48:30 +08:00

190 lines
4.6 KiB
Go

package renew
import (
"context"
"strings"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity"
"git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/service"
"github.com/gogf/gf/v2/errors/gerror"
)
type renewIdentityResolver struct {
byValue map[string]map[int64]*entity.TSimCardInfo
}
var renewIdentityResolverLoader = loadRenewIdentityResolver
func newRenewIdentityResolverFromCards(cards []*entity.TSimCardInfo) *renewIdentityResolver {
resolver := &renewIdentityResolver{
byValue: make(map[string]map[int64]*entity.TSimCardInfo),
}
for _, card := range cards {
resolver.addCard(card)
}
return resolver
}
func loadRenewIdentityResolver(ctx context.Context, rows []*Row) (*renewIdentityResolver, error) {
keys := collectRenewIdentityKeys(rows)
resolver := newRenewIdentityResolverFromCards(nil)
if len(keys) == 0 {
return resolver, nil
}
for _, column := range []string{
dao.TSimCardInfo.Columns().Iccid,
dao.TSimCardInfo.Columns().Msisdn,
dao.TSimCardInfo.Columns().Imsi,
} {
cards, err := queryRenewIdentityCardsByColumn(ctx, column, keys)
if err != nil {
return nil, err
}
for _, card := range cards {
resolver.addCard(card)
}
}
return resolver, nil
}
func queryRenewIdentityCardsByColumn(ctx context.Context, column string, values []string) ([]*entity.TSimCardInfo, error) {
if len(values) == 0 {
return nil, nil
}
var cards []*entity.TSimCardInfo
if err := service.IotTSimCardInfo().Model(ctx).
Fields(
dao.TSimCardInfo.Columns().Id,
dao.TSimCardInfo.Columns().Iccid,
dao.TSimCardInfo.Columns().Msisdn,
dao.TSimCardInfo.Columns().Imsi,
).
WhereIn(column, values).
Scan(&cards); err != nil {
return nil, gerror.Wrap(err, "查询续费卡信息失败")
}
return cards, nil
}
func collectRenewIdentityKeys(rows []*Row) []string {
keys := make([]string, 0, len(rows)*3)
for _, row := range rows {
if row == nil {
continue
}
keys = append(keys,
strings.TrimSpace(row.Iccid),
strings.TrimSpace(row.Msisdn),
strings.TrimSpace(row.Imsi),
)
}
return uniqueStrings(keys)
}
func (r *renewIdentityResolver) addCard(card *entity.TSimCardInfo) {
if r == nil || card == nil || card.Id <= 0 {
return
}
r.addValue(strings.TrimSpace(card.Iccid), card)
r.addValue(strings.TrimSpace(card.Msisdn), card)
r.addValue(strings.TrimSpace(card.Imsi), card)
}
func (r *renewIdentityResolver) addValue(value string, card *entity.TSimCardInfo) {
if r == nil || card == nil || card.Id <= 0 || value == "" {
return
}
if r.byValue == nil {
r.byValue = make(map[string]map[int64]*entity.TSimCardInfo)
}
cards := r.byValue[value]
if cards == nil {
cards = make(map[int64]*entity.TSimCardInfo)
r.byValue[value] = cards
}
cards[card.Id] = card
}
func (r *renewIdentityResolver) resolveRow(row *Row) {
if r == nil || row == nil {
return
}
identities := uniqueStrings([]string{
strings.TrimSpace(row.Iccid),
strings.TrimSpace(row.Msisdn),
strings.TrimSpace(row.Imsi),
})
if len(identities) == 0 {
row.AddReason("ICCID/MSISDN/IMSI不能为空")
return
}
card, err := r.resolve(identities)
if err != nil {
row.AddReason(err.Error())
return
}
if card == nil {
row.AddReason("卡号不存在或无权限访问")
return
}
for _, value := range identities {
if !cardIdentityMatches(card, value) {
row.AddReason("ICCID/MSISDN/IMSI与卡信息不一致")
return
}
}
row.Iccid = strings.TrimSpace(card.Iccid)
row.Msisdn = strings.TrimSpace(card.Msisdn)
row.Imsi = strings.TrimSpace(card.Imsi)
}
func (r *renewIdentityResolver) resolve(values []string) (*entity.TSimCardInfo, error) {
if r == nil || len(values) == 0 {
return nil, nil
}
matches := make(map[int64]*entity.TSimCardInfo)
for _, value := range uniqueStrings(values) {
for id, card := range r.byValue[strings.TrimSpace(value)] {
matches[id] = card
}
}
switch len(matches) {
case 0:
return nil, nil
case 1:
for _, card := range matches {
return card, nil
}
}
return nil, gerror.New("卡号对应多条卡记录,请输入 ICCID")
}
func cardIdentityMatches(card *entity.TSimCardInfo, value string) bool {
if card == nil {
return false
}
value = strings.TrimSpace(value)
if value == "" {
return false
}
return value == strings.TrimSpace(card.Iccid) ||
value == strings.TrimSpace(card.Msisdn) ||
value == strings.TrimSpace(card.Imsi)
}
func normalizeRenewIdentityRows(ctx context.Context, rows []*Row) error {
resolver, err := renewIdentityResolverLoader(ctx, rows)
if err != nil {
return err
}
for _, row := range rows {
resolver.resolveRow(row)
}
return nil
}