141 lines
2.9 KiB
Go
141 lines
2.9 KiB
Go
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
|
|
}
|