package storage import ( "encoding/json" "fmt" "os" "path/filepath" "sync" "time" "github.com/google/uuid" "mengyastore-backend/internal/models" ) type OrderStore struct { path string mu sync.Mutex } func NewOrderStore(path string) (*OrderStore, error) { if err := ensureOrdersFile(path); err != nil { return nil, err } return &OrderStore{path: path}, nil } func (s *OrderStore) Count() (int, error) { s.mu.Lock() defer s.mu.Unlock() items, err := s.readAll() if err != nil { return 0, err } return len(items), nil } func (s *OrderStore) ListByAccount(account string) ([]models.Order, error) { s.mu.Lock() defer s.mu.Unlock() items, err := s.readAll() if err != nil { return nil, err } matched := make([]models.Order, 0) for i := len(items) - 1; i >= 0; i-- { if items[i].UserAccount == account { matched = append(matched, items[i]) } } return matched, nil } func (s *OrderStore) Confirm(id string) (models.Order, error) { s.mu.Lock() defer s.mu.Unlock() items, err := s.readAll() if err != nil { return models.Order{}, err } for i, item := range items { if item.ID == id { if item.Status == "completed" { return item, nil } items[i].Status = "completed" if err := s.writeAll(items); err != nil { return models.Order{}, err } return items[i], nil } } return models.Order{}, fmt.Errorf("order not found") } func (s *OrderStore) Create(order models.Order) (models.Order, error) { s.mu.Lock() defer s.mu.Unlock() items, err := s.readAll() if err != nil { return models.Order{}, err } order.ID = uuid.NewString() order.CreatedAt = time.Now() items = append(items, order) if err := s.writeAll(items); err != nil { return models.Order{}, err } return order, nil } func (s *OrderStore) readAll() ([]models.Order, error) { bytes, err := os.ReadFile(s.path) if err != nil { return nil, fmt.Errorf("read orders: %w", err) } var items []models.Order if err := json.Unmarshal(bytes, &items); err != nil { return nil, fmt.Errorf("parse orders: %w", err) } return items, nil } func (s *OrderStore) writeAll(items []models.Order) error { bytes, err := json.MarshalIndent(items, "", " ") if err != nil { return fmt.Errorf("encode orders: %w", err) } if err := os.WriteFile(s.path, bytes, 0o644); err != nil { return fmt.Errorf("write orders: %w", err) } return nil } func ensureOrdersFile(path string) error { dir := filepath.Dir(path) if err := os.MkdirAll(dir, 0o755); err != nil { return fmt.Errorf("mkdir data dir: %w", err) } if _, err := os.Stat(path); err == nil { return nil } else if !os.IsNotExist(err) { return fmt.Errorf("stat data file: %w", err) } initial := []models.Order{} bytes, err := json.MarshalIndent(initial, "", " ") if err != nil { return fmt.Errorf("init json: %w", err) } if err := os.WriteFile(path, bytes, 0o644); err != nil { return fmt.Errorf("write init json: %w", err) } return nil }