mirror of
https://github.com/woodchen-ink/random-api-go.git
synced 2025-07-18 05:42:01 +08:00
重构处理器逻辑,统一Handler命名为handler,更新相关引用;重命名模型为model,优化数据库迁移和配置获取逻辑,移除不再使用的处理器文件,简化代码结构。
This commit is contained in:
parent
bcc333b142
commit
5960444dc9
@ -7,7 +7,7 @@ import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"random-api-go/models"
|
||||
"random-api-go/model"
|
||||
|
||||
"github.com/glebarez/sqlite"
|
||||
"gorm.io/gorm"
|
||||
@ -59,11 +59,11 @@ func Initialize(dataDir string) error {
|
||||
// autoMigrate 自动迁移数据库结构
|
||||
func autoMigrate() error {
|
||||
return DB.AutoMigrate(
|
||||
&models.APIEndpoint{},
|
||||
&models.DataSource{},
|
||||
&models.URLReplaceRule{},
|
||||
&models.CachedURL{},
|
||||
&models.Config{},
|
||||
&model.APIEndpoint{},
|
||||
&model.DataSource{},
|
||||
&model.URLReplaceRule{},
|
||||
&model.CachedURL{},
|
||||
&model.Config{},
|
||||
)
|
||||
}
|
||||
|
||||
@ -81,12 +81,12 @@ func Close() error {
|
||||
|
||||
// CleanExpiredCache 清理过期缓存
|
||||
func CleanExpiredCache() error {
|
||||
return DB.Where("expires_at < ?", time.Now()).Delete(&models.CachedURL{}).Error
|
||||
return DB.Where("expires_at < ?", time.Now()).Delete(&model.CachedURL{}).Error
|
||||
}
|
||||
|
||||
// GetConfig 获取配置值
|
||||
func GetConfig(key string, defaultValue string) string {
|
||||
var config models.Config
|
||||
var config model.Config
|
||||
if err := DB.Where("key = ?", key).First(&config).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return defaultValue
|
||||
@ -99,12 +99,12 @@ func GetConfig(key string, defaultValue string) string {
|
||||
|
||||
// SetConfig 设置配置值
|
||||
func SetConfig(key, value, configType string) error {
|
||||
var config models.Config
|
||||
var config model.Config
|
||||
err := DB.Where("key = ?", key).First(&config).Error
|
||||
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
// 创建新配置
|
||||
config = models.Config{
|
||||
config = model.Config{
|
||||
Key: key,
|
||||
Value: value,
|
||||
Type: configType,
|
||||
@ -121,13 +121,13 @@ func SetConfig(key, value, configType string) error {
|
||||
}
|
||||
|
||||
// ListConfigs 列出所有配置
|
||||
func ListConfigs() ([]models.Config, error) {
|
||||
var configs []models.Config
|
||||
func ListConfigs() ([]model.Config, error) {
|
||||
var configs []model.Config
|
||||
err := DB.Order("key").Find(&configs).Error
|
||||
return configs, err
|
||||
}
|
||||
|
||||
// DeleteConfig 删除配置
|
||||
func DeleteConfig(key string) error {
|
||||
return DB.Where("key = ?", key).Delete(&models.Config{}).Error
|
||||
return DB.Where("key = ?", key).Delete(&model.Config{}).Error
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@ -9,8 +9,8 @@ import (
|
||||
"net/url"
|
||||
"random-api-go/config"
|
||||
"random-api-go/database"
|
||||
"random-api-go/models"
|
||||
"random-api-go/services"
|
||||
"random-api-go/model"
|
||||
"random-api-go/service"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@ -19,13 +19,13 @@ import (
|
||||
|
||||
// AdminHandler 管理后台处理器
|
||||
type AdminHandler struct {
|
||||
endpointService *services.EndpointService
|
||||
endpointService *service.EndpointService
|
||||
}
|
||||
|
||||
// NewAdminHandler 创建管理后台处理器
|
||||
func NewAdminHandler() *AdminHandler {
|
||||
return &AdminHandler{
|
||||
endpointService: services.GetEndpointService(),
|
||||
endpointService: service.GetEndpointService(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ func (h *AdminHandler) CreateEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var endpoint models.APIEndpoint
|
||||
var endpoint model.APIEndpoint
|
||||
if err := json.NewDecoder(r.Body).Decode(&endpoint); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
|
||||
return
|
||||
@ -121,7 +121,7 @@ func (h *AdminHandler) UpdateEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var endpoint models.APIEndpoint
|
||||
var endpoint model.APIEndpoint
|
||||
if err := json.NewDecoder(r.Body).Decode(&endpoint); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
|
||||
return
|
||||
@ -173,7 +173,7 @@ func (h *AdminHandler) CreateDataSource(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
var dataSource models.DataSource
|
||||
var dataSource model.DataSource
|
||||
if err := json.NewDecoder(r.Body).Decode(&dataSource); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
|
||||
return
|
||||
@ -228,7 +228,7 @@ func (h *AdminHandler) ListEndpointDataSources(w http.ResponseWriter, r *http.Re
|
||||
return
|
||||
}
|
||||
|
||||
var dataSources []models.DataSource
|
||||
var dataSources []model.DataSource
|
||||
if err := database.DB.Where("endpoint_id = ?", endpointID).Order("created_at DESC").Find(&dataSources).Error; err != nil {
|
||||
http.Error(w, fmt.Sprintf("Failed to query data sources: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
@ -259,7 +259,7 @@ func (h *AdminHandler) CreateEndpointDataSource(w http.ResponseWriter, r *http.R
|
||||
return
|
||||
}
|
||||
|
||||
var dataSource models.DataSource
|
||||
var dataSource model.DataSource
|
||||
if err := json.NewDecoder(r.Body).Decode(&dataSource); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
|
||||
return
|
||||
@ -275,7 +275,7 @@ func (h *AdminHandler) CreateEndpointDataSource(w http.ResponseWriter, r *http.R
|
||||
}
|
||||
|
||||
// 验证端点是否存在
|
||||
var endpoint models.APIEndpoint
|
||||
var endpoint model.APIEndpoint
|
||||
if err := database.DB.First(&endpoint, endpointID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "Endpoint not found", http.StatusNotFound)
|
||||
@ -330,7 +330,7 @@ func (h *AdminHandler) GetDataSource(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var dataSource models.DataSource
|
||||
var dataSource model.DataSource
|
||||
if err := database.DB.First(&dataSource, dataSourceID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "Data source not found", http.StatusNotFound)
|
||||
@ -365,7 +365,7 @@ func (h *AdminHandler) UpdateDataSource(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
var dataSource models.DataSource
|
||||
var dataSource model.DataSource
|
||||
if err := database.DB.First(&dataSource, dataSourceID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "Data source not found", http.StatusNotFound)
|
||||
@ -375,7 +375,7 @@ func (h *AdminHandler) UpdateDataSource(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
var updateData models.DataSource
|
||||
var updateData model.DataSource
|
||||
if err := json.NewDecoder(r.Body).Decode(&updateData); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
|
||||
return
|
||||
@ -463,7 +463,7 @@ func (h *AdminHandler) SyncDataSource(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
var dataSource models.DataSource
|
||||
var dataSource model.DataSource
|
||||
if err := database.DB.First(&dataSource, dataSourceID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "Data source not found", http.StatusNotFound)
|
||||
@ -500,7 +500,7 @@ func (h *AdminHandler) ListURLReplaceRules(w http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
var rules []models.URLReplaceRule
|
||||
var rules []model.URLReplaceRule
|
||||
if err := database.DB.Preload("Endpoint").Order("created_at DESC").Find(&rules).Error; err != nil {
|
||||
http.Error(w, fmt.Sprintf("Failed to query URL replace rules: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
@ -520,7 +520,7 @@ func (h *AdminHandler) CreateURLReplaceRule(w http.ResponseWriter, r *http.Reque
|
||||
return
|
||||
}
|
||||
|
||||
var rule models.URLReplaceRule
|
||||
var rule model.URLReplaceRule
|
||||
if err := json.NewDecoder(r.Body).Decode(&rule); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
|
||||
return
|
||||
@ -575,7 +575,7 @@ func (h *AdminHandler) HandleURLReplaceRuleByID(w http.ResponseWriter, r *http.R
|
||||
|
||||
// updateURLReplaceRule 更新URL替换规则
|
||||
func (h *AdminHandler) updateURLReplaceRule(w http.ResponseWriter, r *http.Request, ruleID uint) {
|
||||
var rule models.URLReplaceRule
|
||||
var rule model.URLReplaceRule
|
||||
if err := json.NewDecoder(r.Body).Decode(&rule); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Invalid JSON: %v", err), http.StatusBadRequest)
|
||||
return
|
||||
@ -588,7 +588,7 @@ func (h *AdminHandler) updateURLReplaceRule(w http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
|
||||
// 检查规则是否存在
|
||||
var existingRule models.URLReplaceRule
|
||||
var existingRule model.URLReplaceRule
|
||||
if err := database.DB.First(&existingRule, ruleID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "URL replace rule not found", http.StatusNotFound)
|
||||
@ -615,7 +615,7 @@ func (h *AdminHandler) updateURLReplaceRule(w http.ResponseWriter, r *http.Reque
|
||||
// deleteURLReplaceRule 删除URL替换规则
|
||||
func (h *AdminHandler) deleteURLReplaceRule(w http.ResponseWriter, r *http.Request, ruleID uint) {
|
||||
// 检查规则是否存在
|
||||
var rule models.URLReplaceRule
|
||||
var rule model.URLReplaceRule
|
||||
if err := database.DB.First(&rule, ruleID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
http.Error(w, "URL replace rule not found", http.StatusNotFound)
|
||||
@ -1013,7 +1013,7 @@ func (h *AdminHandler) UpdateEndpointSortOrder(w http.ResponseWriter, r *http.Re
|
||||
|
||||
// 批量更新排序
|
||||
for _, order := range request.EndpointOrders {
|
||||
if err := database.DB.Model(&models.APIEndpoint{}).
|
||||
if err := database.DB.Model(&model.APIEndpoint{}).
|
||||
Where("id = ?", order.ID).
|
||||
Update("sort_order", order.SortOrder).Error; err != nil {
|
||||
http.Error(w, fmt.Sprintf("Failed to update sort order: %v", err), http.StatusInternalServerError)
|
@ -1,4 +1,4 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -8,7 +8,7 @@ import (
|
||||
"net/http"
|
||||
"random-api-go/database"
|
||||
"random-api-go/monitoring"
|
||||
"random-api-go/services"
|
||||
"random-api-go/service"
|
||||
"random-api-go/stats"
|
||||
"random-api-go/utils"
|
||||
"strings"
|
||||
@ -22,7 +22,7 @@ type Router interface {
|
||||
|
||||
type Handlers struct {
|
||||
Stats *stats.StatsManager
|
||||
endpointService *services.EndpointService
|
||||
endpointService *service.EndpointService
|
||||
urlStatsCache map[string]struct {
|
||||
TotalURLs int `json:"total_urls"`
|
||||
}
|
||||
@ -57,7 +57,7 @@ func (h *Handlers) HandleAPIRequest(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 初始化端点服务
|
||||
if h.endpointService == nil {
|
||||
h.endpointService = services.GetEndpointService()
|
||||
h.endpointService = service.GetEndpointService()
|
||||
}
|
||||
|
||||
// 使用新的端点服务
|
||||
@ -140,7 +140,7 @@ func (h *Handlers) HandlePublicEndpoints(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
// 使用端点服务获取端点信息
|
||||
if h.endpointService == nil {
|
||||
h.endpointService = services.GetEndpointService()
|
||||
h.endpointService = service.GetEndpointService()
|
||||
}
|
||||
|
||||
endpoints, err := h.endpointService.ListEndpoints()
|
||||
@ -207,7 +207,7 @@ func (h *Handlers) HandleURLStats(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 缓存过期或不存在,重新计算
|
||||
if h.endpointService == nil {
|
||||
h.endpointService = services.GetEndpointService()
|
||||
h.endpointService = service.GetEndpointService()
|
||||
}
|
||||
|
||||
endpoints, err := h.endpointService.ListEndpoints()
|
@ -1,4 +1,4 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
@ -1,4 +1,4 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
@ -1,9 +1,9 @@
|
||||
package handlers
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"random-api-go/services"
|
||||
"random-api-go/service"
|
||||
)
|
||||
|
||||
func HandleURLStats(w http.ResponseWriter, r *http.Request) {
|
||||
@ -13,7 +13,7 @@ func HandleURLStats(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
stats := services.GetURLCounts()
|
||||
stats := service.GetURLCounts()
|
||||
|
||||
if err := json.NewEncoder(w).Encode(stats); err != nil {
|
||||
http.Error(w, "Error encoding response", http.StatusInternalServerError)
|
16
main.go
16
main.go
@ -11,10 +11,10 @@ import (
|
||||
"path/filepath"
|
||||
"random-api-go/config"
|
||||
"random-api-go/database"
|
||||
"random-api-go/handlers"
|
||||
"random-api-go/handler"
|
||||
"random-api-go/logging"
|
||||
"random-api-go/router"
|
||||
"random-api-go/services"
|
||||
"random-api-go/service"
|
||||
"random-api-go/stats"
|
||||
"syscall"
|
||||
"time"
|
||||
@ -24,8 +24,8 @@ type App struct {
|
||||
server *http.Server
|
||||
router *router.Router
|
||||
Stats *stats.StatsManager
|
||||
adminHandler *handlers.AdminHandler
|
||||
staticHandler *handlers.StaticHandler
|
||||
adminHandler *handler.AdminHandler
|
||||
staticHandler *handler.StaticHandler
|
||||
}
|
||||
|
||||
func NewApp() *App {
|
||||
@ -62,10 +62,10 @@ func (a *App) Initialize() error {
|
||||
a.Stats = stats.NewStatsManager(statsFile)
|
||||
|
||||
// 初始化端点服务
|
||||
services.GetEndpointService()
|
||||
service.GetEndpointService()
|
||||
|
||||
// 创建管理后台处理器
|
||||
a.adminHandler = handlers.NewAdminHandler()
|
||||
a.adminHandler = handler.NewAdminHandler()
|
||||
|
||||
// 创建静态文件处理器
|
||||
staticDir := "./web/out"
|
||||
@ -76,12 +76,12 @@ func (a *App) Initialize() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get absolute path for static directory: %w", err)
|
||||
}
|
||||
a.staticHandler = handlers.NewStaticHandler(absStaticDir)
|
||||
a.staticHandler = handler.NewStaticHandler(absStaticDir)
|
||||
log.Printf("Static file serving enabled from: %s", absStaticDir)
|
||||
}
|
||||
|
||||
// 创建 handlers
|
||||
handlers := handlers.NewHandlers(a.Stats)
|
||||
handlers := handler.NewHandlers(a.Stats)
|
||||
|
||||
// 统一设置所有路由
|
||||
a.router.SetupAllRoutes(handlers, a.adminHandler, a.staticHandler)
|
||||
|
@ -1,4 +1,4 @@
|
||||
package models
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
@ -1,4 +1,4 @@
|
||||
package models
|
||||
package model
|
||||
|
||||
import (
|
||||
"random-api-go/config"
|
@ -48,7 +48,7 @@
|
||||
service := GetEndpointService()
|
||||
|
||||
// 创建端点(会自动预加载)
|
||||
endpoint := &models.APIEndpoint{...}
|
||||
endpoint := &model.APIEndpoint{...}
|
||||
service.CreateEndpoint(endpoint)
|
||||
|
||||
// 获取随机URL(优先使用缓存)
|
@ -1,4 +1,4 @@
|
||||
package services
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"random-api-go/models"
|
||||
"random-api-go/model"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -26,7 +26,7 @@ func NewAPIFetcher() *APIFetcher {
|
||||
}
|
||||
|
||||
// FetchURLs 从API接口获取URL列表
|
||||
func (af *APIFetcher) FetchURLs(config *models.APIConfig) ([]string, error) {
|
||||
func (af *APIFetcher) FetchURLs(config *model.APIConfig) ([]string, error) {
|
||||
var allURLs []string
|
||||
|
||||
// 对于GET/POST接口,我们预获取多次以获得不同的URL
|
||||
@ -83,13 +83,13 @@ func (af *APIFetcher) FetchURLs(config *models.APIConfig) ([]string, error) {
|
||||
}
|
||||
|
||||
// FetchSingleURL 实时获取单个URL (用于GET/POST实时请求)
|
||||
func (af *APIFetcher) FetchSingleURL(config *models.APIConfig) ([]string, error) {
|
||||
func (af *APIFetcher) FetchSingleURL(config *model.APIConfig) ([]string, error) {
|
||||
log.Printf("实时请求 %s 接口: %s", config.Method, config.URL)
|
||||
return af.fetchSingleRequest(config)
|
||||
}
|
||||
|
||||
// fetchSingleRequest 执行单次API请求
|
||||
func (af *APIFetcher) fetchSingleRequest(config *models.APIConfig) ([]string, error) {
|
||||
func (af *APIFetcher) fetchSingleRequest(config *model.APIConfig) ([]string, error) {
|
||||
var req *http.Request
|
||||
var err error
|
||||
|
@ -1,9 +1,9 @@
|
||||
package services
|
||||
package service
|
||||
|
||||
import (
|
||||
"log"
|
||||
"random-api-go/database"
|
||||
"random-api-go/models"
|
||||
"random-api-go/model"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -61,7 +61,7 @@ func (cm *CacheManager) InvalidateMemoryCache(key string) {
|
||||
|
||||
// GetFromDBCache 从数据库缓存获取URL
|
||||
func (cm *CacheManager) GetFromDBCache(dataSourceID uint) ([]string, error) {
|
||||
var cachedURLs []models.CachedURL
|
||||
var cachedURLs []model.CachedURL
|
||||
if err := database.DB.Where("data_source_id = ? AND expires_at > ?", dataSourceID, time.Now()).
|
||||
Find(&cachedURLs).Error; err != nil {
|
||||
return nil, err
|
||||
@ -78,14 +78,14 @@ func (cm *CacheManager) GetFromDBCache(dataSourceID uint) ([]string, error) {
|
||||
// SetDBCache 设置数据库缓存
|
||||
func (cm *CacheManager) SetDBCache(dataSourceID uint, urls []string, duration time.Duration) error {
|
||||
// 先删除旧的缓存
|
||||
if err := database.DB.Where("data_source_id = ?", dataSourceID).Delete(&models.CachedURL{}).Error; err != nil {
|
||||
if err := database.DB.Where("data_source_id = ?", dataSourceID).Delete(&model.CachedURL{}).Error; err != nil {
|
||||
log.Printf("Failed to delete old cache for data source %d: %v", dataSourceID, err)
|
||||
}
|
||||
|
||||
// 插入新的缓存
|
||||
expiresAt := time.Now().Add(duration)
|
||||
for _, url := range urls {
|
||||
cachedURL := models.CachedURL{
|
||||
cachedURL := model.CachedURL{
|
||||
DataSourceID: dataSourceID,
|
||||
OriginalURL: url,
|
||||
FinalURL: url,
|
||||
@ -112,7 +112,7 @@ func (cm *CacheManager) UpdateDBCacheIfChanged(dataSourceID uint, newURLs []stri
|
||||
if cm.urlSlicesEqual(existingURLs, newURLs) {
|
||||
// 数据没有变化,只更新过期时间
|
||||
expiresAt := time.Now().Add(duration)
|
||||
if err := database.DB.Model(&models.CachedURL{}).
|
||||
if err := database.DB.Model(&model.CachedURL{}).
|
||||
Where("data_source_id = ?", dataSourceID).
|
||||
Update("expires_at", expiresAt).Error; err != nil {
|
||||
log.Printf("Failed to update cache expiry for data source %d: %v", dataSourceID, err)
|
||||
@ -127,7 +127,7 @@ func (cm *CacheManager) UpdateDBCacheIfChanged(dataSourceID uint, newURLs []stri
|
||||
// InvalidateMemoryCacheForDataSource 清理与数据源相关的内存缓存
|
||||
func (cm *CacheManager) InvalidateMemoryCacheForDataSource(dataSourceID uint) error {
|
||||
// 获取数据源信息
|
||||
var dataSource models.DataSource
|
||||
var dataSource model.DataSource
|
||||
if err := database.DB.Preload("Endpoint").First(&dataSource, dataSourceID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@ -169,7 +169,7 @@ func (cm *CacheManager) cleanupExpiredCache() {
|
||||
now := time.Now()
|
||||
|
||||
// 内存缓存不再自动过期,只清理数据库中的过期缓存
|
||||
if err := database.DB.Where("expires_at < ?", now).Delete(&models.CachedURL{}).Error; err != nil {
|
||||
if err := database.DB.Where("expires_at < ?", now).Delete(&model.CachedURL{}).Error; err != nil {
|
||||
log.Printf("Failed to cleanup expired cache: %v", err)
|
||||
}
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
package services
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"random-api-go/models"
|
||||
"random-api-go/model"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -26,7 +26,7 @@ func NewDataSourceFetcher(cacheManager *CacheManager) *DataSourceFetcher {
|
||||
}
|
||||
|
||||
// FetchURLs 从数据源获取URL列表
|
||||
func (dsf *DataSourceFetcher) FetchURLs(dataSource *models.DataSource) ([]string, error) {
|
||||
func (dsf *DataSourceFetcher) FetchURLs(dataSource *model.DataSource) ([]string, error) {
|
||||
// API类型的数据源直接实时请求,不使用缓存
|
||||
if dataSource.Type == "api_get" || dataSource.Type == "api_post" {
|
||||
log.Printf("实时请求API数据源 (类型: %s, ID: %d)", dataSource.Type, dataSource.ID)
|
||||
@ -90,8 +90,8 @@ func (dsf *DataSourceFetcher) FetchURLs(dataSource *models.DataSource) ([]string
|
||||
}
|
||||
|
||||
// fetchLankongURLs 获取兰空图床URL
|
||||
func (dsf *DataSourceFetcher) fetchLankongURLs(dataSource *models.DataSource) ([]string, error) {
|
||||
var config models.LankongConfig
|
||||
func (dsf *DataSourceFetcher) fetchLankongURLs(dataSource *model.DataSource) ([]string, error) {
|
||||
var config model.LankongConfig
|
||||
if err := json.Unmarshal([]byte(dataSource.Config), &config); err != nil {
|
||||
return nil, fmt.Errorf("invalid lankong config: %w", err)
|
||||
}
|
||||
@ -100,12 +100,12 @@ func (dsf *DataSourceFetcher) fetchLankongURLs(dataSource *models.DataSource) ([
|
||||
}
|
||||
|
||||
// fetchManualURLs 获取手动配置的URL
|
||||
func (dsf *DataSourceFetcher) fetchManualURLs(dataSource *models.DataSource) ([]string, error) {
|
||||
func (dsf *DataSourceFetcher) fetchManualURLs(dataSource *model.DataSource) ([]string, error) {
|
||||
// 手动配置可能是JSON格式或者纯文本格式
|
||||
config := strings.TrimSpace(dataSource.Config)
|
||||
|
||||
// 尝试解析为JSON格式
|
||||
var manualConfig models.ManualConfig
|
||||
var manualConfig model.ManualConfig
|
||||
if err := json.Unmarshal([]byte(config), &manualConfig); err == nil {
|
||||
return manualConfig.URLs, nil
|
||||
}
|
||||
@ -124,8 +124,8 @@ func (dsf *DataSourceFetcher) fetchManualURLs(dataSource *models.DataSource) ([]
|
||||
}
|
||||
|
||||
// fetchAPIURLs 获取API接口URL (实时请求,不缓存)
|
||||
func (dsf *DataSourceFetcher) fetchAPIURLs(dataSource *models.DataSource) ([]string, error) {
|
||||
var config models.APIConfig
|
||||
func (dsf *DataSourceFetcher) fetchAPIURLs(dataSource *model.DataSource) ([]string, error) {
|
||||
var config model.APIConfig
|
||||
if err := json.Unmarshal([]byte(dataSource.Config), &config); err != nil {
|
||||
return nil, fmt.Errorf("invalid API config: %w", err)
|
||||
}
|
||||
@ -135,8 +135,8 @@ func (dsf *DataSourceFetcher) fetchAPIURLs(dataSource *models.DataSource) ([]str
|
||||
}
|
||||
|
||||
// fetchEndpointURLs 获取端点URL (直接返回端点URL列表)
|
||||
func (dsf *DataSourceFetcher) fetchEndpointURLs(dataSource *models.DataSource) ([]string, error) {
|
||||
var config models.EndpointConfig
|
||||
func (dsf *DataSourceFetcher) fetchEndpointURLs(dataSource *model.DataSource) ([]string, error) {
|
||||
var config model.EndpointConfig
|
||||
if err := json.Unmarshal([]byte(dataSource.Config), &config); err != nil {
|
||||
return nil, fmt.Errorf("invalid endpoint config: %w", err)
|
||||
}
|
||||
@ -157,7 +157,7 @@ func (dsf *DataSourceFetcher) fetchEndpointURLs(dataSource *models.DataSource) (
|
||||
}
|
||||
|
||||
// updateDataSourceSyncTime 更新数据源的同步时间
|
||||
func (dsf *DataSourceFetcher) updateDataSourceSyncTime(dataSource *models.DataSource) error {
|
||||
func (dsf *DataSourceFetcher) updateDataSourceSyncTime(dataSource *model.DataSource) error {
|
||||
// 这里需要导入database包来更新数据库
|
||||
// 为了避免循环依赖,我们通过回调或者接口来处理
|
||||
// 暂时先记录日志,具体实现在主服务中处理
|
||||
@ -166,7 +166,7 @@ func (dsf *DataSourceFetcher) updateDataSourceSyncTime(dataSource *models.DataSo
|
||||
}
|
||||
|
||||
// PreloadDataSource 预加载数据源(在保存时调用)
|
||||
func (dsf *DataSourceFetcher) PreloadDataSource(dataSource *models.DataSource) error {
|
||||
func (dsf *DataSourceFetcher) PreloadDataSource(dataSource *model.DataSource) error {
|
||||
log.Printf("开始预加载数据源 (类型: %s, ID: %d)", dataSource.Type, dataSource.ID)
|
||||
|
||||
_, err := dsf.FetchURLs(dataSource)
|
@ -1,11 +1,11 @@
|
||||
package services
|
||||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"random-api-go/database"
|
||||
"random-api-go/models"
|
||||
"random-api-go/model"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -49,7 +49,7 @@ func GetEndpointService() *EndpointService {
|
||||
}
|
||||
|
||||
// CreateEndpoint 创建API端点
|
||||
func (s *EndpointService) CreateEndpoint(endpoint *models.APIEndpoint) error {
|
||||
func (s *EndpointService) CreateEndpoint(endpoint *model.APIEndpoint) error {
|
||||
if err := database.DB.Create(endpoint).Error; err != nil {
|
||||
return fmt.Errorf("failed to create endpoint: %w", err)
|
||||
}
|
||||
@ -64,8 +64,8 @@ func (s *EndpointService) CreateEndpoint(endpoint *models.APIEndpoint) error {
|
||||
}
|
||||
|
||||
// GetEndpoint 获取API端点
|
||||
func (s *EndpointService) GetEndpoint(id uint) (*models.APIEndpoint, error) {
|
||||
var endpoint models.APIEndpoint
|
||||
func (s *EndpointService) GetEndpoint(id uint) (*model.APIEndpoint, error) {
|
||||
var endpoint model.APIEndpoint
|
||||
if err := database.DB.Preload("DataSources").Preload("URLReplaceRules").First(&endpoint, id).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get endpoint: %w", err)
|
||||
}
|
||||
@ -73,8 +73,8 @@ func (s *EndpointService) GetEndpoint(id uint) (*models.APIEndpoint, error) {
|
||||
}
|
||||
|
||||
// GetEndpointByURL 根据URL获取端点
|
||||
func (s *EndpointService) GetEndpointByURL(url string) (*models.APIEndpoint, error) {
|
||||
var endpoint models.APIEndpoint
|
||||
func (s *EndpointService) GetEndpointByURL(url string) (*model.APIEndpoint, error) {
|
||||
var endpoint model.APIEndpoint
|
||||
if err := database.DB.Preload("DataSources").Preload("URLReplaceRules").
|
||||
Where("url = ? AND is_active = ?", url, true).First(&endpoint).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to get endpoint by URL: %w", err)
|
||||
@ -83,8 +83,8 @@ func (s *EndpointService) GetEndpointByURL(url string) (*models.APIEndpoint, err
|
||||
}
|
||||
|
||||
// ListEndpoints 列出所有端点
|
||||
func (s *EndpointService) ListEndpoints() ([]*models.APIEndpoint, error) {
|
||||
var endpoints []*models.APIEndpoint
|
||||
func (s *EndpointService) ListEndpoints() ([]*model.APIEndpoint, error) {
|
||||
var endpoints []*model.APIEndpoint
|
||||
if err := database.DB.Preload("DataSources").Preload("URLReplaceRules").
|
||||
Order("sort_order ASC, created_at DESC").Find(&endpoints).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to list endpoints: %w", err)
|
||||
@ -93,7 +93,7 @@ func (s *EndpointService) ListEndpoints() ([]*models.APIEndpoint, error) {
|
||||
}
|
||||
|
||||
// UpdateEndpoint 更新API端点
|
||||
func (s *EndpointService) UpdateEndpoint(endpoint *models.APIEndpoint) error {
|
||||
func (s *EndpointService) UpdateEndpoint(endpoint *model.APIEndpoint) error {
|
||||
// 只更新指定字段,避免覆盖 created_at 和 sort_order 等字段
|
||||
updates := map[string]interface{}{
|
||||
"name": endpoint.Name,
|
||||
@ -109,7 +109,7 @@ func (s *EndpointService) UpdateEndpoint(endpoint *models.APIEndpoint) error {
|
||||
updates["sort_order"] = endpoint.SortOrder
|
||||
}
|
||||
|
||||
if err := database.DB.Model(&models.APIEndpoint{}).Where("id = ?", endpoint.ID).Updates(updates).Error; err != nil {
|
||||
if err := database.DB.Model(&model.APIEndpoint{}).Where("id = ?", endpoint.ID).Updates(updates).Error; err != nil {
|
||||
return fmt.Errorf("failed to update endpoint: %w", err)
|
||||
}
|
||||
|
||||
@ -131,7 +131,7 @@ func (s *EndpointService) DeleteEndpoint(id uint) error {
|
||||
}
|
||||
|
||||
// 删除相关的数据源和URL替换规则
|
||||
if err := database.DB.Select("DataSources", "URLReplaceRules").Delete(&models.APIEndpoint{}, id).Error; err != nil {
|
||||
if err := database.DB.Select("DataSources", "URLReplaceRules").Delete(&model.APIEndpoint{}, id).Error; err != nil {
|
||||
return fmt.Errorf("failed to delete endpoint: %w", err)
|
||||
}
|
||||
|
||||
@ -169,9 +169,9 @@ func (s *EndpointService) GetRandomURL(url string) (string, error) {
|
||||
}
|
||||
|
||||
// getRandomURLRealtime 实时获取随机URL(用于包含API数据源的端点)
|
||||
func (s *EndpointService) getRandomURLRealtime(endpoint *models.APIEndpoint) (string, error) {
|
||||
func (s *EndpointService) getRandomURLRealtime(endpoint *model.APIEndpoint) (string, error) {
|
||||
// 收集所有激活的数据源
|
||||
var activeDataSources []models.DataSource
|
||||
var activeDataSources []model.DataSource
|
||||
for _, dataSource := range endpoint.DataSources {
|
||||
if dataSource.IsActive {
|
||||
activeDataSources = append(activeDataSources, dataSource)
|
||||
@ -221,9 +221,9 @@ func (s *EndpointService) getRandomURLRealtime(endpoint *models.APIEndpoint) (st
|
||||
}
|
||||
|
||||
// getRandomURLWithCache 使用缓存模式获取随机URL(先选择数据源)
|
||||
func (s *EndpointService) getRandomURLWithCache(endpoint *models.APIEndpoint) (string, error) {
|
||||
func (s *EndpointService) getRandomURLWithCache(endpoint *model.APIEndpoint) (string, error) {
|
||||
// 收集所有激活的数据源
|
||||
var activeDataSources []models.DataSource
|
||||
var activeDataSources []model.DataSource
|
||||
for _, dataSource := range endpoint.DataSources {
|
||||
if dataSource.IsActive {
|
||||
activeDataSources = append(activeDataSources, dataSource)
|
||||
@ -292,7 +292,7 @@ func (s *EndpointService) applyURLReplaceRules(url, endpointURL string) string {
|
||||
}
|
||||
|
||||
// CreateDataSource 创建数据源
|
||||
func (s *EndpointService) CreateDataSource(dataSource *models.DataSource) error {
|
||||
func (s *EndpointService) CreateDataSource(dataSource *model.DataSource) error {
|
||||
if err := database.DB.Create(dataSource).Error; err != nil {
|
||||
return fmt.Errorf("failed to create data source: %w", err)
|
||||
}
|
||||
@ -309,7 +309,7 @@ func (s *EndpointService) CreateDataSource(dataSource *models.DataSource) error
|
||||
}
|
||||
|
||||
// UpdateDataSource 更新数据源
|
||||
func (s *EndpointService) UpdateDataSource(dataSource *models.DataSource) error {
|
||||
func (s *EndpointService) UpdateDataSource(dataSource *model.DataSource) error {
|
||||
if err := database.DB.Save(dataSource).Error; err != nil {
|
||||
return fmt.Errorf("failed to update data source: %w", err)
|
||||
}
|
||||
@ -328,7 +328,7 @@ func (s *EndpointService) UpdateDataSource(dataSource *models.DataSource) error
|
||||
// DeleteDataSource 删除数据源
|
||||
func (s *EndpointService) DeleteDataSource(id uint) error {
|
||||
// 先获取数据源信息
|
||||
var dataSource models.DataSource
|
||||
var dataSource model.DataSource
|
||||
if err := database.DB.First(&dataSource, id).Error; err != nil {
|
||||
return fmt.Errorf("failed to get data source: %w", err)
|
||||
}
|
||||
@ -362,7 +362,7 @@ func (s *EndpointService) GetPreloader() *Preloader {
|
||||
}
|
||||
|
||||
// GetDataSourceURLCount 获取数据源的URL数量
|
||||
func (s *EndpointService) GetDataSourceURLCount(dataSource *models.DataSource) (int, error) {
|
||||
func (s *EndpointService) GetDataSourceURLCount(dataSource *model.DataSource) (int, error) {
|
||||
// 对于API类型和端点类型的数据源,返回1(因为每次都是实时请求)
|
||||
if dataSource.Type == "api_get" || dataSource.Type == "api_post" || dataSource.Type == "endpoint" {
|
||||
return 1, nil
|
@ -1,4 +1,4 @@
|
||||
package services
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"random-api-go/models"
|
||||
"random-api-go/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -40,7 +40,7 @@ type LankongResponse struct {
|
||||
}
|
||||
|
||||
// FetchURLs 从兰空图床获取URL列表
|
||||
func (lf *LankongFetcher) FetchURLs(config *models.LankongConfig) ([]string, error) {
|
||||
func (lf *LankongFetcher) FetchURLs(config *model.LankongConfig) ([]string, error) {
|
||||
var allURLs []string
|
||||
baseURL := config.BaseURL
|
||||
if baseURL == "" {
|
@ -1,9 +1,9 @@
|
||||
package services
|
||||
package service
|
||||
|
||||
import (
|
||||
"log"
|
||||
"random-api-go/database"
|
||||
"random-api-go/models"
|
||||
"random-api-go/model"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
@ -55,7 +55,7 @@ func (p *Preloader) Stop() {
|
||||
}
|
||||
|
||||
// PreloadDataSourceOnSave 在保存数据源时预加载数据
|
||||
func (p *Preloader) PreloadDataSourceOnSave(dataSource *models.DataSource) {
|
||||
func (p *Preloader) PreloadDataSourceOnSave(dataSource *model.DataSource) {
|
||||
// API类型的数据源不需要预加载,使用实时请求
|
||||
if dataSource.Type == "api_get" || dataSource.Type == "api_post" {
|
||||
log.Printf("API数据源 %d (%s) 使用实时请求,跳过预加载", dataSource.ID, dataSource.Type)
|
||||
@ -75,7 +75,7 @@ func (p *Preloader) PreloadDataSourceOnSave(dataSource *models.DataSource) {
|
||||
}
|
||||
|
||||
// PreloadEndpointOnSave 在保存端点时预加载所有相关数据源
|
||||
func (p *Preloader) PreloadEndpointOnSave(endpoint *models.APIEndpoint) {
|
||||
func (p *Preloader) PreloadEndpointOnSave(endpoint *model.APIEndpoint) {
|
||||
// 异步预加载,避免阻塞保存操作
|
||||
go func() {
|
||||
log.Printf("开始预加载端点 %d 的所有数据源", endpoint.ID)
|
||||
@ -93,7 +93,7 @@ func (p *Preloader) PreloadEndpointOnSave(endpoint *models.APIEndpoint) {
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func(ds models.DataSource) {
|
||||
go func(ds model.DataSource) {
|
||||
defer wg.Done()
|
||||
|
||||
if err := p.dataSourceFetcher.PreloadDataSource(&ds); err != nil {
|
||||
@ -112,7 +112,7 @@ func (p *Preloader) PreloadEndpointOnSave(endpoint *models.APIEndpoint) {
|
||||
|
||||
// RefreshDataSource 手动刷新指定数据源
|
||||
func (p *Preloader) RefreshDataSource(dataSourceID uint) error {
|
||||
var dataSource models.DataSource
|
||||
var dataSource model.DataSource
|
||||
if err := database.DB.First(&dataSource, dataSourceID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@ -123,7 +123,7 @@ func (p *Preloader) RefreshDataSource(dataSourceID uint) error {
|
||||
|
||||
// RefreshEndpoint 手动刷新指定端点的所有数据源
|
||||
func (p *Preloader) RefreshEndpoint(endpointID uint) error {
|
||||
var endpoint models.APIEndpoint
|
||||
var endpoint model.APIEndpoint
|
||||
if err := database.DB.Preload("DataSources").First(&endpoint, endpointID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
@ -145,7 +145,7 @@ func (p *Preloader) RefreshEndpoint(endpointID uint) error {
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func(ds models.DataSource) {
|
||||
go func(ds model.DataSource) {
|
||||
defer wg.Done()
|
||||
|
||||
if err := p.dataSourceFetcher.PreloadDataSource(&ds); err != nil {
|
||||
@ -187,7 +187,7 @@ func (p *Preloader) checkAndRefreshExpiredData() {
|
||||
log.Println("开始检查过期数据...")
|
||||
|
||||
// 获取所有活跃的数据源
|
||||
var dataSources []models.DataSource
|
||||
var dataSources []model.DataSource
|
||||
if err := database.DB.Where("is_active = ?", true).Find(&dataSources).Error; err != nil {
|
||||
log.Printf("获取数据源列表失败: %v", err)
|
||||
return
|
||||
@ -208,7 +208,7 @@ func (p *Preloader) checkAndRefreshExpiredData() {
|
||||
// 没有缓存数据,需要刷新
|
||||
refreshCount++
|
||||
wg.Add(1)
|
||||
go func(ds models.DataSource) {
|
||||
go func(ds model.DataSource) {
|
||||
defer wg.Done()
|
||||
p.refreshDataSourceAsync(&ds)
|
||||
}(dataSource)
|
||||
@ -219,7 +219,7 @@ func (p *Preloader) checkAndRefreshExpiredData() {
|
||||
if p.shouldPeriodicRefresh(&dataSource) {
|
||||
refreshCount++
|
||||
wg.Add(1)
|
||||
go func(ds models.DataSource) {
|
||||
go func(ds model.DataSource) {
|
||||
defer wg.Done()
|
||||
p.refreshDataSourceAsync(&ds)
|
||||
}(dataSource)
|
||||
@ -236,7 +236,7 @@ func (p *Preloader) checkAndRefreshExpiredData() {
|
||||
}
|
||||
|
||||
// shouldPeriodicRefresh 判断是否需要定期刷新
|
||||
func (p *Preloader) shouldPeriodicRefresh(dataSource *models.DataSource) bool {
|
||||
func (p *Preloader) shouldPeriodicRefresh(dataSource *model.DataSource) bool {
|
||||
// 手动数据、API数据和端点数据不需要定期刷新
|
||||
if dataSource.Type == "manual" || dataSource.Type == "api_get" || dataSource.Type == "api_post" || dataSource.Type == "endpoint" {
|
||||
return false
|
||||
@ -260,7 +260,7 @@ func (p *Preloader) shouldPeriodicRefresh(dataSource *models.DataSource) bool {
|
||||
}
|
||||
|
||||
// refreshDataSourceAsync 异步刷新数据源
|
||||
func (p *Preloader) refreshDataSourceAsync(dataSource *models.DataSource) {
|
||||
func (p *Preloader) refreshDataSourceAsync(dataSource *model.DataSource) {
|
||||
if err := p.dataSourceFetcher.PreloadDataSource(dataSource); err != nil {
|
||||
log.Printf("定期刷新数据源 %d 失败: %v", dataSource.ID, err)
|
||||
} else {
|
@ -1,4 +1,4 @@
|
||||
package services
|
||||
package service
|
||||
|
||||
import "sync"
|
||||
|
Loading…
x
Reference in New Issue
Block a user