package iot import ( "context" "math" "strings" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/contexts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/exportcenter" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/handler" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/xgorm/hook" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/iot/packageduration" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/packagecustomer" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/do" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/entity" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/service" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/utility/convert" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" "github.com/gogf/gf/v2/util/gconv" ) type sIotTSimFlowPackageInfo struct{} func NewIotTSimFlowPackageInfo() *sIotTSimFlowPackageInfo { return &sIotTSimFlowPackageInfo{} } func init() { service.RegisterIotTSimFlowPackageInfo(NewIotTSimFlowPackageInfo()) } func (s *sIotTSimFlowPackageInfo) Model(ctx context.Context, option ...*handler.Option) *gdb.Model { if len(option) == 0 { option = append(option, &handler.Option{ FilterTenant: true, FilterAuth: true, }) } return handler.Model(dao.TSimFlowPackageInfo.Ctx(ctx), option...) } func (s *sIotTSimFlowPackageInfo) packageListModel(ctx context.Context) (*gdb.Model, error) { mainTable := dao.TSimFlowPackageInfo.Table() pcTable := dao.TPackageCustomer.Table() pcColumns := dao.TPackageCustomer.Columns() mod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}) isTop, _, err := service.AgentDept().IsTopDept(ctx) if err != nil { return nil, err } if isTop { return mod, nil } return mod. InnerJoin(pcTable, pcTable+"."+pcColumns.PackageCode+" = "+mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode). Where(pcTable+"."+pcColumns.DeptId, contexts.GetDeptId(ctx)). Where(pcTable+"."+pcColumns.TenantId, contexts.GetTenantId(ctx)), nil } func (s *sIotTSimFlowPackageInfo) applyListFilter(mod *gdb.Model, mainTable string, in *model.TSimFlowPackageInfoListParam) *gdb.Model { if in.PackageCode != "" { mod = mod.WhereLike(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode, "%"+in.PackageCode+"%") } if in.CategoryCode != "" { mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().CategoryCode, in.CategoryCode) } if in.PackageType != "" { mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageType, in.PackageType) } if in.PackageName != "" { mod = mod.WhereLike(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageName, "%"+in.PackageName+"%") } if in.Enabled != nil { mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().Enabled, *in.Enabled) } if len(in.CreatedAt) == 2 { mod = mod.WhereBetween(mainTable+"."+dao.TSimFlowPackageInfo.Columns().CreatedAt, in.CreatedAt[0], in.CreatedAt[1].EndOfDay()) } return mod } func (s *sIotTSimFlowPackageInfo) buildPackageCustomer(ctx context.Context, dept *entity.SysDept, packageCode, packageName string, now *gtime.Time) do.TPackageCustomer { userId := contexts.GetUserId(ctx) return do.TPackageCustomer{ PackageCode: packageCode, PackageName: packageName, DeptId: dept.DeptId, DeptName: dept.DeptName, TenantId: contexts.GetTenantId(ctx), CreatedDept: contexts.GetDeptId(ctx), CreatedBy: userId, CreatedAt: now, UpdatedBy: userId, UpdatedAt: now, } } func (s *sIotTSimFlowPackageInfo) List(ctx context.Context, in *model.TSimFlowPackageInfoListParam) (list []*model.TSimFlowPackageInfoListModel, totalCount int, err error) { mainTable := dao.TSimFlowPackageInfo.Table() catTable := dao.TSimPackageCategory.Table() countBaseMod, err := s.packageListModel(ctx) if err != nil { return nil, 0, err } countMod := s.applyListFilter(countBaseMod, mainTable, in) totalCount, err = countMod.Count() if err != nil { err = gerror.Wrap(err, "获取SIM流量套餐管理列表失败,请稍后重试") return } mod, err := s.packageListModel(ctx) if err != nil { return nil, 0, err } mod = mod.LeftJoin(catTable, mainTable+"."+dao.TSimFlowPackageInfo.Columns().CategoryCode+" = "+catTable+"."+dao.TSimPackageCategory.Columns().CategoryCode) mod = s.applyListFilter(mod, mainTable, in) mod = mod.FieldsPrefix(mainTable, model.TSimFlowPackageInfoListModel{}) mod = mod.Fields(catTable + "." + dao.TSimPackageCategory.Columns().CategoryName + " as categoryName") mod = mod.Page(in.Page, in.PageSize) mod = mod.OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().SortNo) mod = mod.Hook(hook.MemberSummary) if err = mod.Scan(&list); err != nil { err = gerror.Wrap(err, "获取SIM流量套餐管理列表失败,请稍后重试") return } if err = s.fillPackageListPrices(ctx, list); err != nil { return nil, 0, err } normalizePackageListRows(list) return } // 可配置池列表(PackageType=102) func (s *sIotTSimFlowPackageInfo) FlowPackageList(ctx context.Context, in *model.TSimFlowPackageInfoFlowPackageListParam) (list []*model.TSimFlowPackageInfoListModel, err error) { mainTable := dao.TSimFlowPackageInfo.Table() mod := dao.TSimFlowPackageInfo.Ctx(ctx) // 该接口只供流量池套餐配置弹窗使用,返回套餐编码和名称即可。 // pool_package_code 是字符串编码,旧列表模型仍为整数类型,这里不查询该字段, // 避免编辑已有池配置时发生字符串转整数的扫描错误。 mod = mod.Fields( mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode, mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageName, mainTable+"."+dao.TSimFlowPackageInfo.Columns().SortNo, ) currentPoolPackageCode := "" if in != nil { currentPoolPackageCode = strings.TrimSpace(in.PoolPackageCode) } mod = applyPoolFlowPackageBaseFilter(mod, mainTable, currentPoolPackageCode) // 根据流量套餐过滤(格式:100.000,102400.000,前边是GB后边是MB) if in != nil && in.Flow != "" { flow := strings.Trim(in.Flow, "\"") parts := strings.Split(flow, ",") if len(parts) == 2 { flowGb := strings.TrimSpace(parts[0]) flowMb := strings.TrimSpace(parts[1]) if flowGb == "" { mod = mod.Where(mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowGb + " IS NULL") } else { mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().FlowGb+" = ?", flowGb) } mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().FlowMb+" = ?", flowMb) } } mod = mod.OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().SortNo) mod = mod.Hook(hook.MemberSummary) if err = mod.Scan(&list); err != nil { err = gerror.Wrap(err, "获取SIM流量套餐管理列表失败,请稍后重试") return } normalizePackageListRows(list) return } // 可配置池加油包列表(PackageType=104) func (s *sIotTSimFlowPackageInfo) FlowPackageAddList(ctx context.Context) (list []*model.TSimFlowPackageInfoListModel, err error) { mainTable := dao.TSimFlowPackageInfo.Table() mod := dao.TSimFlowPackageInfo.Ctx(ctx) // 弹窗只使用套餐编码和名称,不查询字符串类型的池编码字段。 mod = mod.Fields( mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageCode, mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageName, mainTable+"."+dao.TSimFlowPackageInfo.Columns().SortNo, ) mod = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageType, "104") mod = mod.OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().SortNo) mod = mod.Hook(hook.MemberSummary) if err = mod.Scan(&list); err != nil { err = gerror.Wrap(err, "获取SIM流量套餐管理列表失败,请稍后重试") return } normalizePackageListRows(list) return } // GetFlowPackageOptions 获取流量套餐GB+MB组合选项 func (s *sIotTSimFlowPackageInfo) RenewablePackageOptions(ctx context.Context, in *model.TSimFlowPackageInfoRenewablePackageOptionsParam) (list []*model.TSimFlowPackageInfoListModel, err error) { if in == nil { in = &model.TSimFlowPackageInfoRenewablePackageOptionsParam{} } mainTable := dao.TSimFlowPackageInfo.Table() columns := dao.TSimFlowPackageInfo.Columns() mod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}). Fields(model.TSimFlowPackageInfoListModel{}). Where(mainTable+"."+columns.Enabled, 1) if packageType := strings.TrimSpace(in.PackageType); packageType != "" { mod = mod.Where(mainTable+"."+columns.PackageType, packageType) } if packageCode := strings.TrimSpace(in.ExcludePackageCode); packageCode != "" { mod = mod.WhereNot(mainTable+"."+columns.PackageCode, packageCode) } mod = mod.OrderAsc(mainTable + "." + columns.SortNo) if err = mod.Scan(&list); err != nil { return nil, gerror.Wrap(err, "获取可续费套餐候选列表失败,请稍后重试") } normalizePackageListRows(list) return list, nil } func (s *sIotTSimFlowPackageInfo) GetFlowPackageOptions(ctx context.Context, in *model.TSimFlowPackageInfoFlowPackageOptionsParam) ([]string, error) { var results []string mainTable := dao.TSimFlowPackageInfo.Table() currentPoolPackageCode := "" if in != nil { currentPoolPackageCode = strings.TrimSpace(in.PoolPackageCode) } var rows []*struct { FlowGb string FlowMb string } g.Log().Info(ctx, "获取流量套餐选项") mod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}). Fields(mainTable+"."+dao.TSimFlowPackageInfo.Columns().FlowGb, mainTable+"."+dao.TSimFlowPackageInfo.Columns().FlowMb). Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().PackageType, "102"). Distinct(). Where("(" + mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowGb + " <> '' OR " + mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowMb + " <> '')"). OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowGb). OrderAsc(mainTable + "." + dao.TSimFlowPackageInfo.Columns().FlowMb) if currentPoolPackageCode == "" { mod = mod.Where("(" + mainTable + "." + dao.TSimFlowPackageInfo.Columns().PoolPackageCode + " IS NULL OR " + mainTable + "." + dao.TSimFlowPackageInfo.Columns().PoolPackageCode + " = '')") } else { mod = mod.Where("("+mainTable+"."+dao.TSimFlowPackageInfo.Columns().PoolPackageCode+" IS NULL OR "+mainTable+"."+dao.TSimFlowPackageInfo.Columns().PoolPackageCode+" = '' OR "+mainTable+"."+dao.TSimFlowPackageInfo.Columns().PoolPackageCode+" = ?)", currentPoolPackageCode) } if err := mod.Scan(&rows); err != nil { return nil, gerror.Wrap(err, "获取流量套餐选项失败") } for _, row := range rows { results = append(results, row.FlowGb+","+row.FlowMb) } return results, nil } func normalizePackageListRows(list []*model.TSimFlowPackageInfoListModel) { for _, item := range list { if item == nil { continue } if item.RenewableDurationConfig == nil { continue } if normalized, normalizeErr := packageduration.NormalizeRenewableDurationConfig(item.RenewableDurationConfig); normalizeErr == nil { item.RenewableDurationConfig = normalized } } } func (s *sIotTSimFlowPackageInfo) fillPackageListPrices(ctx context.Context, list []*model.TSimFlowPackageInfoListModel) error { if len(list) == 0 { return nil } tenantID := contexts.GetTenantId(ctx) currentDeptID := contexts.GetDeptId(ctx) ownerDeptID, err := loadPackagePriceParentDeptID(ctx, nil, tenantID, currentDeptID) if err != nil { return gerror.Wrap(err, "get package price owner department failed") } for _, item := range list { if item == nil { continue } salePrice, err := resolvePackageEffectiveSalePrice( ctx, nil, tenantID, ownerDeptID, currentDeptID, packagePriceSourceFromListModel(item), ) if err != nil { return gerror.Wrapf(err, "calculate effective price for package %s failed", item.PackageCode) } item.AgentShipmentPrice = salePrice.AgentShipmentPrice item.TerminalSalePrice = salePrice.TerminalSalePrice } return nil } func packagePriceSourceFromListModel(pkg *model.TSimFlowPackageInfoListModel) packagePriceSource { if pkg == nil { return packagePriceSource{} } return packagePriceSource{ PackageCode: strings.TrimSpace(pkg.PackageCode), CostPrice: pkg.CostPrice, TerminalCost: pkg.TerminalCost, SysDefaultRatio: pkg.SysDefaultRatio, SysDefaultProfit: pkg.SysDefaultProfit, SysDefaultTerminalRatio: pkg.SysDefaultTerminalRatio, SysDefaultTerminalProfit: pkg.SysDefaultTerminalProfit, } } func applyPoolFlowPackageBaseFilter(mod *gdb.Model, mainTable, currentPoolPackageCode string) *gdb.Model { columns := dao.TSimFlowPackageInfo.Columns() poolPackageColumn := mainTable + "." + columns.PoolPackageCode if currentPoolPackageCode == "" { return mod. Where("("+poolPackageColumn+" IS NULL OR "+poolPackageColumn+" = '')"). Where(mainTable+"."+columns.PackageType, "102") } return mod. Where("("+poolPackageColumn+" IS NULL OR "+poolPackageColumn+" = '' OR "+poolPackageColumn+" = ?)", currentPoolPackageCode). Where(mainTable+"."+columns.PackageType, "102") } // Export 导出SIM流量套餐(异步:提交任务后到下载中心取文件) func (s *sIotTSimFlowPackageInfo) Export(ctx context.Context, in *model.TSimFlowPackageInfoListParam) (err error) { _, err = exportcenter.Submit(ctx, &exportcenter.Request{ BizKey: "tSimFlowPackageInfo", BizName: "SIM流量套餐", PermCode: "cpm:iot:tSimFlowPackageInfo:export", QueryParam: in, Tags: func() ([]string, error) { return convert.GetEntityDescTags(model.TSimFlowPackageInfoListModel{}) }, Fetch: func(ctx context.Context, page, pageSize int) (rows []interface{}, total int, err error) { query := *in query.Page = page query.PageSize = pageSize list, count, err := s.List(ctx, &query) if err != nil { return nil, 0, err } rows = make([]interface{}, 0, len(list)) for _, item := range list { rows = append(rows, item) } return rows, count, nil }, }) return err } func (s *sIotTSimFlowPackageInfo) Edit(ctx context.Context, in *model.TSimFlowPackageInfoEditParam) (err error) { if in == nil { return gerror.New("package information cannot be empty") } if err = validateFlowMb(in); err != nil { return err } if in.BillingMethod == nil || strings.TrimSpace(*in.BillingMethod) == "" { billingMethod := packageduration.MonthBillingMethodValue() in.BillingMethod = &billingMethod } if in.RenewableDurationConfig != nil { in.RenewableDurationConfig, err = packageduration.NormalizeRenewableDurationConfig(in.RenewableDurationConfig) if err != nil { return err } } packageCode := gconv.String(in.PackageCode) normalizeFlowPackageRenewableCodes(in, packageCode) if packageCode != "" { uniqueMod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}). Where(dao.TSimFlowPackageInfo.Columns().PackageCode, packageCode) if in.Id > 0 { uniqueMod = uniqueMod.WhereNot(dao.TSimFlowPackageInfo.Columns().Id, in.Id) } count, countErr := uniqueMod.Count() if countErr != nil { return countErr } if count > 0 { return gerror.New("套餐编码已存在") } } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { now := gtime.Now() userId := contexts.GetUserId(ctx) if in.Id > 0 { var oldPackage entity.TSimFlowPackageInfo if err = s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).WherePri(in.Id).Scan(&oldPackage); err != nil { return gerror.Wrap(err, "获取套餐信息失败,请稍后重试") } if oldPackage.Id == 0 { return gerror.New("套餐不存在") } in.UpdatedBy = &userId in.UpdatedAt = now if _, err = tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()). Fields(model.TSimFlowPackageInfoUpdateFields{}). WherePri(in.Id). Where(dao.TSimFlowPackageInfo.Columns().TenantId, contexts.GetTenantId(ctx)). Data(in).Update(); err != nil { return gerror.Wrap(err, "修改SIM流量套餐管理失败,请稍后重试") } newPackageCode := oldPackage.PackageCode if in.PackageCode != nil { newPackageCode = *in.PackageCode } newPackageName := oldPackage.PackageName if in.PackageName != nil { newPackageName = *in.PackageName } if newPackageCode != oldPackage.PackageCode || newPackageName != oldPackage.PackageName { updateCustomer := do.TPackageCustomer{ PackageCode: newPackageCode, PackageName: newPackageName, UpdatedBy: userId, UpdatedAt: now, } if _, err = tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()). Where(dao.TPackageCustomer.Columns().TenantId, contexts.GetTenantId(ctx)). Where(dao.TPackageCustomer.Columns().PackageCode, oldPackage.PackageCode). Data(updateCustomer).Update(); err != nil { return gerror.Wrap(err, "同步套餐客户关联失败,请稍后重试") } } return nil } // 新增套餐 tenantId := contexts.GetTenantId(ctx) in.TenantId = &tenantId createdDept := contexts.GetDeptId(ctx) in.CreatedDept = &createdDept in.CreatedBy = &userId in.CreatedAt = now if _, err = tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()). Fields(model.TSimFlowPackageInfoInsertFields{}). Data(in).Insert(); err != nil { return gerror.Wrap(err, "新增SIM流量套餐管理失败,请稍后重试") } _, dept, err := service.AgentDept().IsTopDept(ctx) if err != nil { return err } packageName := gconv.String(in.PackageName) customer := s.buildPackageCustomer(ctx, dept, packageCode, packageName, now) if _, err = tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()).Data(customer).Insert(); err != nil { return gerror.Wrap(err, "新增套餐客户关联失败,请稍后重试") } return nil }) } func validateFlowMb(in *model.TSimFlowPackageInfoEditParam) error { if in == nil { return gerror.New("package information cannot be empty") } if in.Id <= 0 && in.FlowMb == nil { return gerror.New("套餐流量(MB)不能为空") } if in.FlowMb != nil && (*in.FlowMb <= 0 || math.IsNaN(*in.FlowMb) || math.IsInf(*in.FlowMb, 0)) { return gerror.New("套餐流量(MB)必须大于0") } return nil } func normalizeFlowPackageRenewableCodes(in *model.TSimFlowPackageInfoEditParam, packageCode string) { if in == nil || in.RenewablePackageCodes == nil { return } codes := make([]string, 0) _ = in.RenewablePackageCodes.Scan(&codes) in.RenewablePackageCodes = gjson.New(uniquePackageCodes(codes)) } func uniquePackageCodes(codes []string) []string { result := make([]string, 0, len(codes)) seen := make(map[string]struct{}, len(codes)) for _, code := range codes { code = strings.TrimSpace(code) if code == "" { continue } if _, ok := seen[code]; ok { continue } seen[code] = struct{}{} result = append(result, code) } return result } func (s *sIotTSimFlowPackageInfo) Delete(ctx context.Context, in *model.TSimFlowPackageInfoDeleteParam) (err error) { var packageInfo entity.TSimFlowPackageInfo if err = s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}).WherePri(in.Id).Scan(&packageInfo); err != nil { return gerror.Wrap(err, "获取套餐信息失败,请稍后重试") } if packageInfo.Id == 0 { return gerror.New("套餐不存在") } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) (err error) { if _, err = tx.Ctx(ctx).Model(dao.TSimFlowPackageInfo.Table()). WherePri(in.Id). Where(dao.TSimFlowPackageInfo.Columns().TenantId, contexts.GetTenantId(ctx)). Unscoped().Delete(); err != nil { return gerror.Wrap(err, "删除SIM流量套餐管理失败,请稍后重试") } if _, err = tx.Ctx(ctx).Model(dao.TPackageCustomer.Table()). Where(dao.TPackageCustomer.Columns().TenantId, contexts.GetTenantId(ctx)). Where(dao.TPackageCustomer.Columns().PackageCode, packageInfo.PackageCode). Delete(); err != nil { return gerror.Wrap(err, "清理套餐客户关联失败,请稍后重试") } return nil }) } func (s *sIotTSimFlowPackageInfo) View(ctx context.Context, in *model.TSimFlowPackageInfoViewParam) (res *model.TSimFlowPackageInfoViewModel, err error) { mainTable := dao.TSimFlowPackageInfo.Table() catTable := dao.TSimPackageCategory.Table() mod, err := s.packageListModel(ctx) if err != nil { return nil, err } mod = mod.LeftJoin(catTable, mainTable+"."+dao.TSimFlowPackageInfo.Columns().CategoryCode+" = "+catTable+"."+dao.TSimPackageCategory.Columns().CategoryCode) mod = mod.Fields( mainTable+".*", catTable+"."+dao.TSimPackageCategory.Columns().CategoryName+" as categoryName", ) if err = mod.Where(mainTable+"."+dao.TSimFlowPackageInfo.Columns().Id, in.Id).Hook(hook.MemberSummary).Scan(&res); err != nil { return nil, gerror.Wrap(err, "获取SIM流量套餐管理信息失败,请稍后重试") } if res == nil || res.Id == 0 { return nil, gerror.New("套餐不存在或无权限") } if res.RenewableDurationConfig != nil { if normalized, normalizeErr := packageduration.NormalizeRenewableDurationConfig(res.RenewableDurationConfig); normalizeErr == nil { res.RenewableDurationConfig = normalized } } if err = s.fillPackageRelationNames(ctx, res); err != nil { return nil, err } return } func (s *sIotTSimFlowPackageInfo) fillPackageRelationNames(ctx context.Context, res *model.TSimFlowPackageInfoViewModel) error { if res == nil { return nil } renewableCodes := packageCodesFromJSON(res.RenewablePackageCodes) changeableCodes := packageCodesFromJSON(res.ChangeablePackageCodes) topupCodes := packageCodesFromJSON(res.TopupPackageCodes) allCodes := uniquePackageCodes(append(append(renewableCodes, changeableCodes...), topupCodes...)) if len(allCodes) == 0 { return nil } nameMap, err := s.packageNamesByCode(ctx, res.TenantId, allCodes) if err != nil { return err } res.RenewablePackageNames = gjson.New(packageNamesForCodes(renewableCodes, nameMap)) res.ChangeablePackageNames = gjson.New(packageNamesForCodes(changeableCodes, nameMap)) res.TopupPackageNames = gjson.New(packageNamesForCodes(topupCodes, nameMap)) return nil } func packageCodesFromJSON(value *gjson.Json) []string { if value == nil { return nil } var codes []string _ = value.Scan(&codes) return uniquePackageCodes(codes) } func (s *sIotTSimFlowPackageInfo) packageNamesByCode(ctx context.Context, tenantId string, codes []string) (map[string]string, error) { result := make(map[string]string, len(codes)) if len(codes) == 0 { return result, nil } columns := dao.TSimFlowPackageInfo.Columns() var packages []struct { PackageCode string `orm:"package_code"` PackageName string `orm:"package_name"` } mod := s.Model(ctx, &handler.Option{FilterTenant: true, FilterAuth: false}). Fields(columns.PackageCode, columns.PackageName). WhereIn(columns.PackageCode, codes) if tenantId != "" { mod = mod.Where(columns.TenantId, tenantId) } if err := mod.Scan(&packages); err != nil { return nil, gerror.Wrap(err, "查询套餐名称失败") } for _, pkg := range packages { code := strings.TrimSpace(pkg.PackageCode) name := strings.TrimSpace(pkg.PackageName) if code == "" || name == "" { continue } result[code] = name } return result, nil } func packageNamesForCodes(codes []string, nameMap map[string]string) []string { names := make([]string, 0, len(codes)) for _, code := range codes { if name := strings.TrimSpace(nameMap[code]); name != "" { names = append(names, name) } } return names } // GetPoolPackagesByCardPackages 根据卡套餐编码列表获取对应的池套餐编码列表 func (s *sIotTSimFlowPackageInfo) GetPoolPackagesByCardPackages(ctx context.Context, cardPackageCodes []string) (poolPackageMap102 map[string]int64, poolPackageMap104 map[string]int64, err error) { poolPackageMap102 = make(map[string]int64) poolPackageMap104 = make(map[string]int64) if len(cardPackageCodes) == 0 { return } g.Log().Info(ctx, "GetPoolPackagesByCardPackages cardPackageCodes:", cardPackageCodes) //这些不存在 104 mod := s.Model(ctx) mod = mod.Where(dao.TSimFlowPackageInfo.Columns().PackageCode+" IN (?)", cardPackageCodes) // 查询 102 池套餐 mod102 := mod.Where(dao.TSimFlowPackageInfo.Columns().PackageType, 102) var packages102 []*model.TSimFlowPackageInfoListModel var poolPackageCodes []int64 if err = mod102.Scan(&packages102); err != nil { return nil, nil, gerror.Wrap(err, "获取102池套餐列表失败,请稍后重试!") } g.Log().Info(ctx, "获取102池套餐列表:%v", packages102) for _, pkg := range packages102 { poolPackageMap102[pkg.PackageCode] = pkg.PoolPackageCode poolPackageCodes = append(poolPackageCodes, pkg.PoolPackageCode) } // 查询 104 池套餐 mod104 := s.Model(ctx).Where(dao.TSimFlowPackageInfo.Columns().PackageType, 104).Where(dao.TSimFlowPackageInfo.Columns().PoolPackageCode+" IN (?)", poolPackageCodes) var packages104 []*model.TSimFlowPackageInfoListModel if err = mod104.Scan(&packages104); err != nil { return nil, nil, gerror.Wrap(err, "获取104池套餐列表失败,请稍后重试!") } g.Log().Info(ctx, "GetPoolPackagesByCardPackages packages104:", packages104) for _, pkg := range packages104 { poolPackageMap104[pkg.PackageCode] = pkg.PoolPackageCode } g.Log().Info(ctx, "GetPoolPackagesByCardPackages poolPackageMap102:", poolPackageMap102) g.Log().Info(ctx, "GetPoolPackagesByCardPackages poolPackageMap104:", poolPackageMap104) return poolPackageMap102, poolPackageMap104, nil } func (s *sIotTSimFlowPackageInfo) SyncDeptPackages(ctx context.Context) (err error) { _, dept, err := service.AgentDept().IsTopDept(ctx) if err != nil { return } return packagecustomer.PublishSync(ctx, model.PackageCustomerSyncMessage{ TenantId: contexts.GetTenantId(ctx), DeptId: dept.DeptId, UserId: contexts.GetUserId(ctx), Trigger: "manual_sync", }) } func (s *sIotTSimFlowPackageInfo) SyncDeptPackagesByDept(ctx context.Context, tenantId string, deptId int64, userId int64) error { return packagecustomer.SyncDeptPackagesByDept(ctx, tenantId, deptId, userId) }