package cardpackage import ( "context" "sort" "strings" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/do" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gerror" ) const cardPackageBindInsertBatchSize = 500 type Repository struct{} func NewRepository() *Repository { return &Repository{} } func (r *Repository) LockCardsByIccids(ctx context.Context, tx gdb.TX, iccids []string) (map[string]*entity.TSimCardInfo, error) { result := make(map[string]*entity.TSimCardInfo) uniqueIccids := uniqueStrings(iccids) if len(uniqueIccids) == 0 { return result, nil } var list []*entity.TSimCardInfo if err := tx.Ctx(ctx).Model(dao.TSimCardInfo.Table()). WhereIn(dao.TSimCardInfo.Columns().Iccid, uniqueIccids). LockUpdate(). Scan(&list); err != nil { return nil, err } for _, item := range list { if item != nil && item.Iccid != "" { result[item.Iccid] = item } } return result, nil } func (r *Repository) LockCurrentActiveBindsByIccids(ctx context.Context, tx gdb.TX, iccids []string) (map[string]*entity.TSimCardBindPkg, error) { result := make(map[string]*entity.TSimCardBindPkg) priorities := make(map[string]int) uniqueIccids := uniqueStrings(iccids) if len(uniqueIccids) == 0 { return result, nil } var list []*entity.TSimCardBindPkg if err := tx.Ctx(ctx).Model(dao.TSimCardBindPkg.Table()). WhereIn(dao.TSimCardBindPkg.Columns().Iccid, uniqueIccids). WhereIn(dao.TSimCardBindPkg.Columns().EffectiveStatus, []int{consts.EffectiveStatusPending, consts.EffectiveStatusEffective}). OrderDesc(dao.TSimCardBindPkg.Columns().EffectiveStatus). OrderAsc(dao.TSimCardBindPkg.Columns().EffectiveTime). OrderAsc(dao.TSimCardBindPkg.Columns().Id). LockUpdate(). Scan(&list); err != nil { return nil, err } for _, item := range list { if item == nil || item.Iccid == "" { continue } priority := bindPriority(item.EffectiveStatus) currentPriority, exists := priorities[item.Iccid] if exists && priority < currentPriority { continue } if exists && priority == currentPriority { result[item.Iccid] = nil continue } priorities[item.Iccid] = priority result[item.Iccid] = item } return result, nil } func (r *Repository) LockLatestBindsByIccids(ctx context.Context, tx gdb.TX, iccids []string) (map[string]*entity.TSimCardBindPkg, error) { result := make(map[string]*entity.TSimCardBindPkg) uniqueIccids := uniqueStrings(iccids) if len(uniqueIccids) == 0 { return result, nil } var list []*entity.TSimCardBindPkg if err := tx.Ctx(ctx).Model(dao.TSimCardBindPkg.Table()). WhereIn(dao.TSimCardBindPkg.Columns().Iccid, uniqueIccids). WhereIn(dao.TSimCardBindPkg.Columns().PackageType, []int{101, 102}). WhereIn(dao.TSimCardBindPkg.Columns().EffectiveStatus, []int{ consts.EffectiveStatusPending, consts.EffectiveStatusEffective, consts.EffectiveStatusExpired, }). OrderDesc(dao.TSimCardBindPkg.Columns().ExpectedExpireTime). OrderDesc(dao.TSimCardBindPkg.Columns().Id). LockUpdate(). Scan(&list); err != nil { return nil, err } effectiveCount := make(map[string]int) for _, item := range list { if item == nil || item.Iccid == "" { continue } iccid := strings.TrimSpace(item.Iccid) if item.EffectiveStatus == consts.EffectiveStatusEffective { effectiveCount[iccid]++ if effectiveCount[iccid] > 1 { return nil, gerror.Newf("同一张卡存在多个生效中的套餐订购记录:%s", iccid) } } if _, exists := result[iccid]; exists { continue } result[iccid] = item } return result, nil } func (r *Repository) ActiveBindCountsByOrderCodes(ctx context.Context, tx gdb.TX, orderCodes []string) (map[string]int, error) { result := make(map[string]int) uniqueOrderCodes := uniqueStrings(orderCodes) if len(uniqueOrderCodes) == 0 { return result, nil } var list []struct { OrderCode string `orm:"order_code"` Count int `orm:"count"` } err := tx.Ctx(ctx).Model(dao.TSimCardBindPkg.Table()). Fields(dao.TSimCardBindPkg.Columns().OrderCode, "COUNT(1) AS count"). WhereIn(dao.TSimCardBindPkg.Columns().OrderCode, uniqueOrderCodes). Group(dao.TSimCardBindPkg.Columns().OrderCode). Scan(&list) if err != nil { return nil, err } for _, item := range list { result[item.OrderCode] = item.Count } return result, nil } func (r *Repository) LoadTargetDept(ctx context.Context, tx gdb.TX, deptId int64, tenantId string) (*entity.SysDept, error) { var customer *entity.SysDept mod := tx.Ctx(ctx).Model(dao.SysDept.Table()). Where(dao.SysDept.Columns().DeptId, deptId) if tenantId != "" { mod = mod.Where(dao.SysDept.Columns().TenantId, tenantId) } if err := mod.Scan(&customer); err != nil { return nil, err } return customer, nil } func (r *Repository) LoadPackage(ctx context.Context, tx gdb.TX, packageCode string) (*entity.TSimFlowPackageInfo, error) { var pkg *entity.TSimFlowPackageInfo err := tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()). Where(dao.TSimFlowPackageInfo.Columns().PackageCode, strings.TrimSpace(packageCode)). Scan(&pkg) if err != nil { return nil, err } return pkg, nil } func (r *Repository) InsertOrder(ctx context.Context, tx gdb.TX, data do.TOrder) (int64, error) { return tx.Ctx(ctx).Model(dao.TOrder.Table()).Data(data).InsertAndGetId() } func (r *Repository) InsertOrderItem(ctx context.Context, tx gdb.TX, data do.TOrderItem) error { _, err := tx.Ctx(ctx).Model(dao.TOrderItem.Table()).Data(data).Insert() return err } func (r *Repository) InsertCardPackageBinds(ctx context.Context, tx gdb.TX, rows []do.TSimCardBindPkg) error { if len(rows) == 0 { return nil } for start := 0; start < len(rows); start += cardPackageBindInsertBatchSize { end := start + cardPackageBindInsertBatchSize if end > len(rows) { end = len(rows) } if _, err := tx.Ctx(ctx).Model(dao.TSimCardBindPkg.Table()).Data(rows[start:end]).Insert(); err != nil { return err } } return nil } func (r *Repository) DeleteBindsBySubscriptionNos(ctx context.Context, tx gdb.TX, subscriptionNos []string) (int64, error) { uniqueNos := uniqueStrings(subscriptionNos) if len(uniqueNos) == 0 { return 0, nil } result, err := tx.Ctx(ctx).Model(dao.TSimCardBindPkg.Table()). WhereIn(dao.TSimCardBindPkg.Columns().SubscriptionNo, uniqueNos). Delete() if err != nil { return 0, err } return result.RowsAffected() } func uniqueStrings(list []string) []string { if len(list) == 0 { return nil } seen := make(map[string]struct{}, len(list)) result := make([]string, 0, len(list)) for _, item := range list { item = strings.TrimSpace(item) if item == "" { continue } if _, ok := seen[item]; ok { continue } seen[item] = struct{}{} result = append(result, item) } sort.Strings(result) return result } func bindPriority(status int) int { switch status { case consts.EffectiveStatusEffective: return 2 case consts.EffectiveStatusPending: return 1 default: return 0 } }