package cache import ( "context" "strings" "sync" "chis_osi/osi" ) type DictionarySnapshot struct { regionByName map[string]string doctorByName map[string]string orgByName map[string]string doctorIDs map[string]struct{} orgIDs map[string]struct{} } type PublicClient interface { QueryGridAddress(context.Context, osi.GridAddressQuery) ([]osi.GridAddress, osi.Result, error) QueryDoctors(context.Context, osi.DoctorQuery) ([]osi.Doctor, osi.Result, error) QueryOrgs(context.Context, osi.OrgQuery) ([]osi.Org, osi.Result, error) } type PersistentStore interface { SaveDictionarySnapshot(context.Context, DictionarySnapshot) error } type RefreshParams struct { Grid osi.GridAddressQuery Doctors osi.DoctorQuery Orgs osi.OrgQuery } type DictionaryService struct { client PublicClient store PersistentStore mu sync.RWMutex memory DictionarySnapshot } func NewDictionarySnapshot(grids []osi.GridAddress, doctors []osi.Doctor, orgs []osi.Org) DictionarySnapshot { snapshot := DictionarySnapshot{ regionByName: make(map[string]string, len(grids)), doctorByName: make(map[string]string, len(doctors)), orgByName: make(map[string]string, len(orgs)), doctorIDs: make(map[string]struct{}, len(doctors)), orgIDs: make(map[string]struct{}, len(orgs)), } for _, row := range grids { put(snapshot.regionByName, row.RegionName, row.RegionCode) } for _, row := range doctors { put(snapshot.doctorByName, row.PersonName, row.PersonID) putID(snapshot.doctorIDs, row.PersonID) } for _, row := range orgs { put(snapshot.orgByName, row.OrganizName, row.OrganizCode) putID(snapshot.orgIDs, row.OrganizCode) } return snapshot } func NewDictionaryService(client PublicClient, store PersistentStore) *DictionaryService { return &DictionaryService{client: client, store: store} } func (s *DictionaryService) Refresh(ctx context.Context, params RefreshParams) (DictionarySnapshot, error) { grids, _, err := s.client.QueryGridAddress(ctx, params.Grid) if err != nil { return DictionarySnapshot{}, err } doctors, _, err := s.client.QueryDoctors(ctx, params.Doctors) if err != nil { return DictionarySnapshot{}, err } orgs, _, err := s.client.QueryOrgs(ctx, params.Orgs) if err != nil { return DictionarySnapshot{}, err } snapshot := NewDictionarySnapshot(grids, doctors, orgs) s.mu.Lock() s.memory = snapshot s.mu.Unlock() if s.store != nil { _ = s.store.SaveDictionarySnapshot(ctx, snapshot) } return snapshot, nil } func (s *DictionaryService) Snapshot() DictionarySnapshot { s.mu.RLock() defer s.mu.RUnlock() return s.memory } func (s DictionarySnapshot) RegionCodeByName(name string) (string, bool) { return lookup(s.regionByName, name) } func (s DictionarySnapshot) DoctorIDByName(name string) (string, bool) { return lookup(s.doctorByName, name) } func (s DictionarySnapshot) ManaUnitIDByName(name string) (string, bool) { return lookup(s.orgByName, name) } func (s DictionarySnapshot) DoctorIDExists(id string) bool { _, ok := s.doctorIDs[strings.TrimSpace(id)] return ok } func (s DictionarySnapshot) ManaUnitIDExists(id string) bool { _, ok := s.orgIDs[strings.TrimSpace(id)] return ok } func put(index map[string]string, name string, code string) { name = strings.TrimSpace(name) code = strings.TrimSpace(code) if name == "" || code == "" { return } if _, exists := index[name]; !exists { index[name] = code } } func putID(index map[string]struct{}, id string) { id = strings.TrimSpace(id) if id != "" { index[id] = struct{}{} } } func lookup(index map[string]string, name string) (string, bool) { code, ok := index[strings.TrimSpace(name)] return code, ok }