Files
mengyastore/mengyastore-backend/internal/storage/sitestore.go

136 lines
3.1 KiB
Go

package storage
import (
"strconv"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"mengyastore-backend/internal/database"
)
type SiteStore struct {
db *gorm.DB
}
func NewSiteStore(db *gorm.DB) (*SiteStore, error) {
return &SiteStore{db: db}, nil
}
func (s *SiteStore) get(key string) (string, error) {
var row database.SiteSettingRow
if err := s.db.First(&row, "key = ?", key).Error; err != nil {
return "", nil // key not found → return zero value
}
return row.Value, nil
}
func (s *SiteStore) set(key, value string) error {
return s.db.Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "key"}},
DoUpdates: clause.AssignmentColumns([]string{"value"}),
}).Create(&database.SiteSettingRow{Key: key, Value: value}).Error
}
func (s *SiteStore) GetTotalVisits() (int, error) {
v, err := s.get("totalVisits")
if err != nil || v == "" {
return 0, err
}
n, _ := strconv.Atoi(v)
return n, nil
}
func (s *SiteStore) IncrementVisits() (int, error) {
current, err := s.GetTotalVisits()
if err != nil {
return 0, err
}
current++
if err := s.set("totalVisits", strconv.Itoa(current)); err != nil {
return 0, err
}
return current, nil
}
func (s *SiteStore) GetMaintenance() (enabled bool, reason string, err error) {
v, err := s.get("maintenance")
if err != nil {
return false, "", err
}
enabled = v == "true"
reason, err = s.get("maintenanceReason")
return enabled, reason, err
}
func (s *SiteStore) SetMaintenance(enabled bool, reason string) error {
v := "false"
if enabled {
v = "true"
}
if err := s.set("maintenance", v); err != nil {
return err
}
return s.set("maintenanceReason", reason)
}
// RecordVisit increments the visit counter. Returns (totalVisits, counted, error).
// For simplicity, every call increments (fingerprint dedup is handled in-memory by the handler layer).
func (s *SiteStore) RecordVisit(_ string) (int, bool, error) {
total, err := s.IncrementVisits()
return total, true, err
}
// SMTPConfig holds the mail sender configuration stored in the DB.
type SMTPConfig struct {
Email string `json:"email"`
Password string `json:"password"`
FromName string `json:"fromName"`
Host string `json:"host"`
Port string `json:"port"`
}
// IsConfiguredEmail returns true if the SMTP config is ready to send mail.
func (c SMTPConfig) IsConfiguredEmail() bool {
return c.Email != "" && c.Password != "" && c.Host != ""
}
func (s *SiteStore) GetSMTPConfig() (SMTPConfig, error) {
cfg := SMTPConfig{
Host: "smtp.qq.com",
Port: "465",
}
if v, _ := s.get("smtpEmail"); v != "" {
cfg.Email = v
}
if v, _ := s.get("smtpPassword"); v != "" {
cfg.Password = v
}
if v, _ := s.get("smtpFromName"); v != "" {
cfg.FromName = v
}
if v, _ := s.get("smtpHost"); v != "" {
cfg.Host = v
}
if v, _ := s.get("smtpPort"); v != "" {
cfg.Port = v
}
return cfg, nil
}
func (s *SiteStore) SetSMTPConfig(cfg SMTPConfig) error {
pairs := [][2]string{
{"smtpEmail", cfg.Email},
{"smtpPassword", cfg.Password},
{"smtpFromName", cfg.FromName},
{"smtpHost", cfg.Host},
{"smtpPort", cfg.Port},
}
for _, p := range pairs {
if err := s.set(p[0], p[1]); err != nil {
return err
}
}
return nil
}