package service import ( "electricity_bill_calc/cache" "electricity_bill_calc/global" "electricity_bill_calc/logger" "electricity_bill_calc/model" "fmt" "time" "github.com/samber/lo" "go.uber.org/zap" ) type _RegionService struct { l *zap.Logger } var RegionService = _RegionService{ l: logger.Named("Service", "Region"), } func (_RegionService) FetchSubRegions(parent string) ([]model.Region, error) { ctx, cancel := global.TimeoutContext(30 * time.Second) defer cancel() if regions, _ := cache.RetreiveSearch[[]model.Region]("region", "parent", parent); regions != nil { return *regions, nil } regions := make([]model.Region, 0) err := global.DB.NewSelect().Model(®ions).Where("parent = ?", parent).Order("code asc").Scan(ctx) if err != nil { return make([]model.Region, 0), err } relationNames := lo.Map(regions, func(r model.Region, index int) string { return fmt.Sprintf("region:%s", r.Code) }) cache.CacheSearch(regions, relationNames, "region", "parent", parent) return regions, err } func (r _RegionService) FetchAllParentRegions(code string) ([]model.Region, error) { regions := make([]model.Region, 0) region, err := r.fetchRegion(code) if err != nil { return regions, err } regions = append(regions, *region) for region.Level > 1 { region, err = r.fetchRegion(region.Parent) if err != nil { return make([]model.Region, 0), nil } regions = append(regions, *region) } return regions, nil } func (_RegionService) fetchRegion(code string) (*model.Region, error) { ctx, cancel := global.TimeoutContext(30 * time.Second) defer cancel() if cachedRegion, _ := cache.RetreiveSearch[model.Region]("region", code); cachedRegion != nil { return cachedRegion, nil } region := new(model.Region) err := global.DB.NewSelect().Model(®ion).WherePK(code).Scan(ctx) if err != nil && region != nil { relationName := fmt.Sprintf("region:%s", code) cache.CacheSearch(region, []string{relationName}, "region", code) } return region, err }