mirror of
https://github.com/ctwj/urldb.git
synced 2025-11-25 03:15:04 +08:00
update: 系统配置重构
This commit is contained in:
@@ -3,7 +3,6 @@ package converter
|
||||
import (
|
||||
"github.com/ctwj/urldb/db/dto"
|
||||
"github.com/ctwj/urldb/db/entity"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// ToResourceResponse 将Resource实体转换为ResourceResponse
|
||||
@@ -214,25 +213,3 @@ func ToReadyResourceResponseList(resources []entity.ReadyResource) []dto.ReadyRe
|
||||
// Key: req.Key,
|
||||
// }
|
||||
// }
|
||||
|
||||
// SystemConfigToPublicResponse 返回不含 api_token 的系统配置响应
|
||||
func SystemConfigToPublicResponse(config *entity.SystemConfig) gin.H {
|
||||
return gin.H{
|
||||
"id": config.ID,
|
||||
"created_at": config.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
"updated_at": config.UpdatedAt.Format("2006-01-02 15:04:05"),
|
||||
"site_title": config.SiteTitle,
|
||||
"site_description": config.SiteDescription,
|
||||
"keywords": config.Keywords,
|
||||
"author": config.Author,
|
||||
"copyright": config.Copyright,
|
||||
"auto_process_ready_resources": config.AutoProcessReadyResources,
|
||||
"auto_process_interval": config.AutoProcessInterval,
|
||||
"auto_transfer_enabled": config.AutoTransferEnabled,
|
||||
"auto_transfer_limit_days": config.AutoTransferLimitDays,
|
||||
"auto_transfer_min_space": config.AutoTransferMinSpace,
|
||||
"auto_fetch_hot_drama_enabled": config.AutoFetchHotDramaEnabled,
|
||||
"page_size": config.PageSize,
|
||||
"maintenance_mode": config.MaintenanceMode,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,74 +1,200 @@
|
||||
package converter
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/ctwj/urldb/db/dto"
|
||||
"github.com/ctwj/urldb/db/entity"
|
||||
)
|
||||
|
||||
// SystemConfigToResponse 将系统配置实体转换为响应DTO
|
||||
func SystemConfigToResponse(config *entity.SystemConfig) *dto.SystemConfigResponse {
|
||||
if config == nil {
|
||||
return nil
|
||||
// SystemConfigToResponse 将系统配置实体列表转换为响应DTO
|
||||
func SystemConfigToResponse(configs []entity.SystemConfig) *dto.SystemConfigResponse {
|
||||
if len(configs) == 0 {
|
||||
return getDefaultConfigResponse()
|
||||
}
|
||||
|
||||
return &dto.SystemConfigResponse{
|
||||
ID: config.ID,
|
||||
CreatedAt: config.CreatedAt.Format(time.RFC3339),
|
||||
UpdatedAt: config.UpdatedAt.Format(time.RFC3339),
|
||||
response := getDefaultConfigResponse()
|
||||
|
||||
// SEO 配置
|
||||
SiteTitle: config.SiteTitle,
|
||||
SiteDescription: config.SiteDescription,
|
||||
Keywords: config.Keywords,
|
||||
Author: config.Author,
|
||||
Copyright: config.Copyright,
|
||||
|
||||
// 自动处理配置组
|
||||
AutoProcessReadyResources: config.AutoProcessReadyResources,
|
||||
AutoProcessInterval: config.AutoProcessInterval,
|
||||
AutoTransferEnabled: config.AutoTransferEnabled,
|
||||
AutoTransferLimitDays: config.AutoTransferLimitDays,
|
||||
AutoTransferMinSpace: config.AutoTransferMinSpace,
|
||||
AutoFetchHotDramaEnabled: config.AutoFetchHotDramaEnabled,
|
||||
|
||||
// API配置
|
||||
ApiToken: config.ApiToken,
|
||||
|
||||
// 其他配置
|
||||
PageSize: config.PageSize,
|
||||
MaintenanceMode: config.MaintenanceMode,
|
||||
// 将键值对转换为结构体
|
||||
for _, config := range configs {
|
||||
switch config.Key {
|
||||
case entity.ConfigKeySiteTitle:
|
||||
response.SiteTitle = config.Value
|
||||
case entity.ConfigKeySiteDescription:
|
||||
response.SiteDescription = config.Value
|
||||
case entity.ConfigKeyKeywords:
|
||||
response.Keywords = config.Value
|
||||
case entity.ConfigKeyAuthor:
|
||||
response.Author = config.Value
|
||||
case entity.ConfigKeyCopyright:
|
||||
response.Copyright = config.Value
|
||||
case entity.ConfigKeyAutoProcessReadyResources:
|
||||
if val, err := strconv.ParseBool(config.Value); err == nil {
|
||||
response.AutoProcessReadyResources = val
|
||||
}
|
||||
case entity.ConfigKeyAutoProcessInterval:
|
||||
if val, err := strconv.Atoi(config.Value); err == nil {
|
||||
response.AutoProcessInterval = val
|
||||
}
|
||||
case entity.ConfigKeyAutoTransferEnabled:
|
||||
if val, err := strconv.ParseBool(config.Value); err == nil {
|
||||
response.AutoTransferEnabled = val
|
||||
}
|
||||
case entity.ConfigKeyAutoTransferLimitDays:
|
||||
if val, err := strconv.Atoi(config.Value); err == nil {
|
||||
response.AutoTransferLimitDays = val
|
||||
}
|
||||
case entity.ConfigKeyAutoTransferMinSpace:
|
||||
if val, err := strconv.Atoi(config.Value); err == nil {
|
||||
response.AutoTransferMinSpace = val
|
||||
}
|
||||
case entity.ConfigKeyAutoFetchHotDramaEnabled:
|
||||
if val, err := strconv.ParseBool(config.Value); err == nil {
|
||||
response.AutoFetchHotDramaEnabled = val
|
||||
}
|
||||
case entity.ConfigKeyApiToken:
|
||||
response.ApiToken = config.Value
|
||||
case entity.ConfigKeyPageSize:
|
||||
if val, err := strconv.Atoi(config.Value); err == nil {
|
||||
response.PageSize = val
|
||||
}
|
||||
case entity.ConfigKeyMaintenanceMode:
|
||||
if val, err := strconv.ParseBool(config.Value); err == nil {
|
||||
response.MaintenanceMode = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置时间戳(使用第一个配置的时间)
|
||||
if len(configs) > 0 {
|
||||
response.CreatedAt = configs[0].CreatedAt.Format(time.RFC3339)
|
||||
response.UpdatedAt = configs[0].UpdatedAt.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
// RequestToSystemConfig 将请求DTO转换为系统配置实体
|
||||
func RequestToSystemConfig(req *dto.SystemConfigRequest) *entity.SystemConfig {
|
||||
// RequestToSystemConfig 将请求DTO转换为系统配置实体列表
|
||||
func RequestToSystemConfig(req *dto.SystemConfigRequest) []entity.SystemConfig {
|
||||
if req == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &entity.SystemConfig{
|
||||
// SEO 配置
|
||||
SiteTitle: req.SiteTitle,
|
||||
SiteDescription: req.SiteDescription,
|
||||
Keywords: req.Keywords,
|
||||
Author: req.Author,
|
||||
Copyright: req.Copyright,
|
||||
configs := []entity.SystemConfig{
|
||||
{Key: entity.ConfigKeySiteTitle, Value: req.SiteTitle, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeySiteDescription, Value: req.SiteDescription, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyKeywords, Value: req.Keywords, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyAuthor, Value: req.Author, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyCopyright, Value: req.Copyright, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyAutoProcessReadyResources, Value: strconv.FormatBool(req.AutoProcessReadyResources), Type: entity.ConfigTypeBool},
|
||||
{Key: entity.ConfigKeyAutoProcessInterval, Value: strconv.Itoa(req.AutoProcessInterval), Type: entity.ConfigTypeInt},
|
||||
{Key: entity.ConfigKeyAutoTransferEnabled, Value: strconv.FormatBool(req.AutoTransferEnabled), Type: entity.ConfigTypeBool},
|
||||
{Key: entity.ConfigKeyAutoTransferLimitDays, Value: strconv.Itoa(req.AutoTransferLimitDays), Type: entity.ConfigTypeInt},
|
||||
{Key: entity.ConfigKeyAutoTransferMinSpace, Value: strconv.Itoa(req.AutoTransferMinSpace), Type: entity.ConfigTypeInt},
|
||||
{Key: entity.ConfigKeyAutoFetchHotDramaEnabled, Value: strconv.FormatBool(req.AutoFetchHotDramaEnabled), Type: entity.ConfigTypeBool},
|
||||
{Key: entity.ConfigKeyApiToken, Value: req.ApiToken, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyPageSize, Value: strconv.Itoa(req.PageSize), Type: entity.ConfigTypeInt},
|
||||
{Key: entity.ConfigKeyMaintenanceMode, Value: strconv.FormatBool(req.MaintenanceMode), Type: entity.ConfigTypeBool},
|
||||
}
|
||||
|
||||
// 自动处理配置组
|
||||
AutoProcessReadyResources: req.AutoProcessReadyResources,
|
||||
AutoProcessInterval: req.AutoProcessInterval,
|
||||
AutoTransferEnabled: req.AutoTransferEnabled,
|
||||
AutoTransferLimitDays: req.AutoTransferLimitDays,
|
||||
AutoTransferMinSpace: req.AutoTransferMinSpace,
|
||||
AutoFetchHotDramaEnabled: req.AutoFetchHotDramaEnabled,
|
||||
return configs
|
||||
}
|
||||
|
||||
// API配置
|
||||
ApiToken: req.ApiToken,
|
||||
// SystemConfigToPublicResponse 返回不含 api_token 的系统配置响应
|
||||
func SystemConfigToPublicResponse(configs []entity.SystemConfig) map[string]interface{} {
|
||||
response := map[string]interface{}{
|
||||
entity.ConfigResponseFieldID: 0,
|
||||
entity.ConfigResponseFieldCreatedAt: time.Now().Format("2006-01-02 15:04:05"),
|
||||
entity.ConfigResponseFieldUpdatedAt: time.Now().Format("2006-01-02 15:04:05"),
|
||||
entity.ConfigResponseFieldSiteTitle: entity.ConfigDefaultSiteTitle,
|
||||
entity.ConfigResponseFieldSiteDescription: entity.ConfigDefaultSiteDescription,
|
||||
entity.ConfigResponseFieldKeywords: entity.ConfigDefaultKeywords,
|
||||
entity.ConfigResponseFieldAuthor: entity.ConfigDefaultAuthor,
|
||||
entity.ConfigResponseFieldCopyright: entity.ConfigDefaultCopyright,
|
||||
entity.ConfigResponseFieldAutoProcessReadyResources: false,
|
||||
entity.ConfigResponseFieldAutoProcessInterval: 30,
|
||||
entity.ConfigResponseFieldAutoTransferEnabled: false,
|
||||
entity.ConfigResponseFieldAutoTransferLimitDays: 0,
|
||||
entity.ConfigResponseFieldAutoTransferMinSpace: 100,
|
||||
entity.ConfigResponseFieldAutoFetchHotDramaEnabled: false,
|
||||
entity.ConfigResponseFieldPageSize: 100,
|
||||
entity.ConfigResponseFieldMaintenanceMode: false,
|
||||
}
|
||||
|
||||
// 其他配置
|
||||
PageSize: req.PageSize,
|
||||
MaintenanceMode: req.MaintenanceMode,
|
||||
// 将键值对转换为map
|
||||
for _, config := range configs {
|
||||
switch config.Key {
|
||||
case entity.ConfigKeySiteTitle:
|
||||
response[entity.ConfigResponseFieldSiteTitle] = config.Value
|
||||
case entity.ConfigKeySiteDescription:
|
||||
response[entity.ConfigResponseFieldSiteDescription] = config.Value
|
||||
case entity.ConfigKeyKeywords:
|
||||
response[entity.ConfigResponseFieldKeywords] = config.Value
|
||||
case entity.ConfigKeyAuthor:
|
||||
response[entity.ConfigResponseFieldAuthor] = config.Value
|
||||
case entity.ConfigKeyCopyright:
|
||||
response[entity.ConfigResponseFieldCopyright] = config.Value
|
||||
case entity.ConfigKeyAutoProcessReadyResources:
|
||||
if val, err := strconv.ParseBool(config.Value); err == nil {
|
||||
response[entity.ConfigResponseFieldAutoProcessReadyResources] = val
|
||||
}
|
||||
case entity.ConfigKeyAutoProcessInterval:
|
||||
if val, err := strconv.Atoi(config.Value); err == nil {
|
||||
response[entity.ConfigResponseFieldAutoProcessInterval] = val
|
||||
}
|
||||
case entity.ConfigKeyAutoTransferEnabled:
|
||||
if val, err := strconv.ParseBool(config.Value); err == nil {
|
||||
response[entity.ConfigResponseFieldAutoTransferEnabled] = val
|
||||
}
|
||||
case entity.ConfigKeyAutoTransferLimitDays:
|
||||
if val, err := strconv.Atoi(config.Value); err == nil {
|
||||
response[entity.ConfigResponseFieldAutoTransferLimitDays] = val
|
||||
}
|
||||
case entity.ConfigKeyAutoTransferMinSpace:
|
||||
if val, err := strconv.Atoi(config.Value); err == nil {
|
||||
response[entity.ConfigResponseFieldAutoTransferMinSpace] = val
|
||||
}
|
||||
case entity.ConfigKeyAutoFetchHotDramaEnabled:
|
||||
if val, err := strconv.ParseBool(config.Value); err == nil {
|
||||
response[entity.ConfigResponseFieldAutoFetchHotDramaEnabled] = val
|
||||
}
|
||||
case entity.ConfigKeyPageSize:
|
||||
if val, err := strconv.Atoi(config.Value); err == nil {
|
||||
response[entity.ConfigResponseFieldPageSize] = val
|
||||
}
|
||||
case entity.ConfigKeyMaintenanceMode:
|
||||
if val, err := strconv.ParseBool(config.Value); err == nil {
|
||||
response[entity.ConfigResponseFieldMaintenanceMode] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 设置时间戳(使用第一个配置的时间)
|
||||
if len(configs) > 0 {
|
||||
response[entity.ConfigResponseFieldCreatedAt] = configs[0].CreatedAt.Format("2006-01-02 15:04:05")
|
||||
response[entity.ConfigResponseFieldUpdatedAt] = configs[0].UpdatedAt.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
|
||||
// getDefaultConfigResponse 获取默认配置响应
|
||||
func getDefaultConfigResponse() *dto.SystemConfigResponse {
|
||||
return &dto.SystemConfigResponse{
|
||||
SiteTitle: entity.ConfigDefaultSiteTitle,
|
||||
SiteDescription: entity.ConfigDefaultSiteDescription,
|
||||
Keywords: entity.ConfigDefaultKeywords,
|
||||
Author: entity.ConfigDefaultAuthor,
|
||||
Copyright: entity.ConfigDefaultCopyright,
|
||||
AutoProcessReadyResources: false,
|
||||
AutoProcessInterval: 30,
|
||||
AutoTransferEnabled: false,
|
||||
AutoTransferLimitDays: 0,
|
||||
AutoTransferMinSpace: 100,
|
||||
AutoFetchHotDramaEnabled: false,
|
||||
ApiToken: entity.ConfigDefaultApiToken,
|
||||
PageSize: 100,
|
||||
MaintenanceMode: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,3 +53,15 @@ type SystemConfigResponse struct {
|
||||
PageSize int `json:"page_size"`
|
||||
MaintenanceMode bool `json:"maintenance_mode"`
|
||||
}
|
||||
|
||||
// SystemConfigItem 单个配置项
|
||||
type SystemConfigItem struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
// SystemConfigListResponse 配置列表响应
|
||||
type SystemConfigListResponse struct {
|
||||
Configs []SystemConfigItem `json:"configs"`
|
||||
}
|
||||
|
||||
@@ -4,33 +4,16 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// SystemConfig 系统配置实体
|
||||
// SystemConfig 系统配置实体(键值对形式)
|
||||
type SystemConfig struct {
|
||||
ID uint `json:"id" gorm:"primaryKey"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
// SEO 配置
|
||||
SiteTitle string `json:"site_title" gorm:"size:200;not null;default:'老九网盘资源数据库'"`
|
||||
SiteDescription string `json:"site_description" gorm:"size:500"`
|
||||
Keywords string `json:"keywords" gorm:"size:500"`
|
||||
Author string `json:"author" gorm:"size:100"`
|
||||
Copyright string `json:"copyright" gorm:"size:200"`
|
||||
|
||||
// 自动处理配置组
|
||||
AutoProcessReadyResources bool `json:"auto_process_ready_resources" gorm:"default:false"` // 自动处理待处理资源
|
||||
AutoProcessInterval int `json:"auto_process_interval" gorm:"default:30"` // 自动处理间隔(分钟)
|
||||
AutoTransferEnabled bool `json:"auto_transfer_enabled" gorm:"default:false"` // 开启自动转存
|
||||
AutoTransferLimitDays int `json:"auto_transfer_limit_days" gorm:"default:0"` // 自动转存限制天数(0表示不限制)
|
||||
AutoTransferMinSpace int `json:"auto_transfer_min_space" gorm:"default:100"` // 最小存储空间(GB)
|
||||
AutoFetchHotDramaEnabled bool `json:"auto_fetch_hot_drama_enabled" gorm:"default:false"` // 自动拉取热播剧名字
|
||||
|
||||
// API配置
|
||||
ApiToken string `json:"api_token" gorm:"size:100;uniqueIndex"` // 公开API访问令牌
|
||||
|
||||
// 其他配置
|
||||
PageSize int `json:"page_size" gorm:"default:100"`
|
||||
MaintenanceMode bool `json:"maintenance_mode" gorm:"default:false"`
|
||||
// 键值对配置
|
||||
Key string `json:"key" gorm:"size:100;not null;uniqueIndex"`
|
||||
Value string `json:"value" gorm:"size:1000"`
|
||||
Type string `json:"type" gorm:"size:20;default:'string'"` // string, int, bool, json
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
89
db/entity/system_config_constants.go
Normal file
89
db/entity/system_config_constants.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package entity
|
||||
|
||||
// ConfigKey 配置键常量
|
||||
const (
|
||||
// SEO 配置
|
||||
ConfigKeySiteTitle = "site_title"
|
||||
ConfigKeySiteDescription = "site_description"
|
||||
ConfigKeyKeywords = "keywords"
|
||||
ConfigKeyAuthor = "author"
|
||||
ConfigKeyCopyright = "copyright"
|
||||
|
||||
// 自动处理配置组
|
||||
ConfigKeyAutoProcessReadyResources = "auto_process_ready_resources"
|
||||
ConfigKeyAutoProcessInterval = "auto_process_interval"
|
||||
ConfigKeyAutoTransferEnabled = "auto_transfer_enabled"
|
||||
ConfigKeyAutoTransferLimitDays = "auto_transfer_limit_days"
|
||||
ConfigKeyAutoTransferMinSpace = "auto_transfer_min_space"
|
||||
ConfigKeyAutoFetchHotDramaEnabled = "auto_fetch_hot_drama_enabled"
|
||||
|
||||
// API配置
|
||||
ConfigKeyApiToken = "api_token"
|
||||
|
||||
// 其他配置
|
||||
ConfigKeyPageSize = "page_size"
|
||||
ConfigKeyMaintenanceMode = "maintenance_mode"
|
||||
)
|
||||
|
||||
// ConfigType 配置类型常量
|
||||
const (
|
||||
ConfigTypeString = "string"
|
||||
ConfigTypeInt = "int"
|
||||
ConfigTypeBool = "bool"
|
||||
ConfigTypeJSON = "json"
|
||||
)
|
||||
|
||||
// ConfigResponseField API响应字段名常量
|
||||
const (
|
||||
// 基础字段
|
||||
ConfigResponseFieldID = "id"
|
||||
ConfigResponseFieldCreatedAt = "created_at"
|
||||
ConfigResponseFieldUpdatedAt = "updated_at"
|
||||
|
||||
// SEO 配置字段
|
||||
ConfigResponseFieldSiteTitle = "site_title"
|
||||
ConfigResponseFieldSiteDescription = "site_description"
|
||||
ConfigResponseFieldKeywords = "keywords"
|
||||
ConfigResponseFieldAuthor = "author"
|
||||
ConfigResponseFieldCopyright = "copyright"
|
||||
|
||||
// 自动处理配置字段
|
||||
ConfigResponseFieldAutoProcessReadyResources = "auto_process_ready_resources"
|
||||
ConfigResponseFieldAutoProcessInterval = "auto_process_interval"
|
||||
ConfigResponseFieldAutoTransferEnabled = "auto_transfer_enabled"
|
||||
ConfigResponseFieldAutoTransferLimitDays = "auto_transfer_limit_days"
|
||||
ConfigResponseFieldAutoTransferMinSpace = "auto_transfer_min_space"
|
||||
ConfigResponseFieldAutoFetchHotDramaEnabled = "auto_fetch_hot_drama_enabled"
|
||||
|
||||
// API配置字段
|
||||
ConfigResponseFieldApiToken = "api_token"
|
||||
|
||||
// 其他配置字段
|
||||
ConfigResponseFieldPageSize = "page_size"
|
||||
ConfigResponseFieldMaintenanceMode = "maintenance_mode"
|
||||
)
|
||||
|
||||
// ConfigDefaultValue 配置默认值常量
|
||||
const (
|
||||
// SEO 配置默认值
|
||||
ConfigDefaultSiteTitle = "老九网盘资源数据库"
|
||||
ConfigDefaultSiteDescription = "专业的老九网盘资源数据库"
|
||||
ConfigDefaultKeywords = "网盘,资源管理,文件分享"
|
||||
ConfigDefaultAuthor = "系统管理员"
|
||||
ConfigDefaultCopyright = "© 2024 老九网盘资源数据库"
|
||||
|
||||
// 自动处理配置默认值
|
||||
ConfigDefaultAutoProcessReadyResources = "false"
|
||||
ConfigDefaultAutoProcessInterval = "30"
|
||||
ConfigDefaultAutoTransferEnabled = "false"
|
||||
ConfigDefaultAutoTransferLimitDays = "0"
|
||||
ConfigDefaultAutoTransferMinSpace = "100"
|
||||
ConfigDefaultAutoFetchHotDramaEnabled = "false"
|
||||
|
||||
// API配置默认值
|
||||
ConfigDefaultApiToken = ""
|
||||
|
||||
// 其他配置默认值
|
||||
ConfigDefaultPageSize = "100"
|
||||
ConfigDefaultMaintenanceMode = "false"
|
||||
)
|
||||
@@ -1,6 +1,8 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ctwj/urldb/db/entity"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -9,9 +11,13 @@ import (
|
||||
// SystemConfigRepository 系统配置Repository接口
|
||||
type SystemConfigRepository interface {
|
||||
BaseRepository[entity.SystemConfig]
|
||||
FindFirst() (*entity.SystemConfig, error)
|
||||
GetOrCreateDefault() (*entity.SystemConfig, error)
|
||||
Upsert(config *entity.SystemConfig) error
|
||||
FindAll() ([]entity.SystemConfig, error)
|
||||
FindByKey(key string) (*entity.SystemConfig, error)
|
||||
GetOrCreateDefault() ([]entity.SystemConfig, error)
|
||||
UpsertConfigs(configs []entity.SystemConfig) error
|
||||
GetConfigValue(key string) (string, error)
|
||||
GetConfigBool(key string) (bool, error)
|
||||
GetConfigInt(key string) (int, error)
|
||||
}
|
||||
|
||||
// SystemConfigRepositoryImpl 系统配置Repository实现
|
||||
@@ -26,55 +32,117 @@ func NewSystemConfigRepository(db *gorm.DB) SystemConfigRepository {
|
||||
}
|
||||
}
|
||||
|
||||
// FindFirst 获取第一个配置(通常只有一个配置)
|
||||
func (r *SystemConfigRepositoryImpl) FindFirst() (*entity.SystemConfig, error) {
|
||||
// FindAll 获取所有配置
|
||||
func (r *SystemConfigRepositoryImpl) FindAll() ([]entity.SystemConfig, error) {
|
||||
var configs []entity.SystemConfig
|
||||
err := r.db.Find(&configs).Error
|
||||
return configs, err
|
||||
}
|
||||
|
||||
// FindByKey 根据键查找配置
|
||||
func (r *SystemConfigRepositoryImpl) FindByKey(key string) (*entity.SystemConfig, error) {
|
||||
var config entity.SystemConfig
|
||||
err := r.db.First(&config).Error
|
||||
err := r.db.Where("key = ?", key).First(&config).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// Upsert 创建或更新系统配置
|
||||
func (r *SystemConfigRepositoryImpl) Upsert(config *entity.SystemConfig) error {
|
||||
var existingConfig entity.SystemConfig
|
||||
err := r.db.First(&existingConfig).Error
|
||||
// UpsertConfigs 批量创建或更新配置
|
||||
func (r *SystemConfigRepositoryImpl) UpsertConfigs(configs []entity.SystemConfig) error {
|
||||
for _, config := range configs {
|
||||
var existingConfig entity.SystemConfig
|
||||
err := r.db.Where("key = ?", config.Key).First(&existingConfig).Error
|
||||
|
||||
if err != nil {
|
||||
// 如果不存在,则创建
|
||||
return r.db.Create(config).Error
|
||||
} else {
|
||||
// 如果存在,则更新
|
||||
config.ID = existingConfig.ID
|
||||
return r.db.Save(config).Error
|
||||
if err != nil {
|
||||
// 如果不存在,则创建
|
||||
if err := r.db.Create(&config).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// 如果存在,则更新
|
||||
config.ID = existingConfig.ID
|
||||
if err := r.db.Save(&config).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetOrCreateDefault 获取配置或创建默认配置
|
||||
func (r *SystemConfigRepositoryImpl) GetOrCreateDefault() (*entity.SystemConfig, error) {
|
||||
config, err := r.FindFirst()
|
||||
func (r *SystemConfigRepositoryImpl) GetOrCreateDefault() ([]entity.SystemConfig, error) {
|
||||
configs, err := r.FindAll()
|
||||
if err != nil {
|
||||
// 创建默认配置
|
||||
defaultConfig := &entity.SystemConfig{
|
||||
SiteTitle: "老九网盘资源数据库",
|
||||
SiteDescription: "专业的老九网盘资源数据库",
|
||||
Keywords: "网盘,资源管理,文件分享",
|
||||
Author: "系统管理员",
|
||||
Copyright: "© 2024 老九网盘资源数据库",
|
||||
AutoProcessReadyResources: false,
|
||||
AutoProcessInterval: 30,
|
||||
PageSize: 100,
|
||||
MaintenanceMode: false,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 如果没有配置,创建默认配置
|
||||
if len(configs) == 0 {
|
||||
defaultConfigs := []entity.SystemConfig{
|
||||
{Key: entity.ConfigKeySiteTitle, Value: entity.ConfigDefaultSiteTitle, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeySiteDescription, Value: entity.ConfigDefaultSiteDescription, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyKeywords, Value: entity.ConfigDefaultKeywords, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyAuthor, Value: entity.ConfigDefaultAuthor, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyCopyright, Value: entity.ConfigDefaultCopyright, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyAutoProcessReadyResources, Value: entity.ConfigDefaultAutoProcessReadyResources, Type: entity.ConfigTypeBool},
|
||||
{Key: entity.ConfigKeyAutoProcessInterval, Value: entity.ConfigDefaultAutoProcessInterval, Type: entity.ConfigTypeInt},
|
||||
{Key: entity.ConfigKeyAutoTransferEnabled, Value: entity.ConfigDefaultAutoTransferEnabled, Type: entity.ConfigTypeBool},
|
||||
{Key: entity.ConfigKeyAutoTransferLimitDays, Value: entity.ConfigDefaultAutoTransferLimitDays, Type: entity.ConfigTypeInt},
|
||||
{Key: entity.ConfigKeyAutoTransferMinSpace, Value: entity.ConfigDefaultAutoTransferMinSpace, Type: entity.ConfigTypeInt},
|
||||
{Key: entity.ConfigKeyAutoFetchHotDramaEnabled, Value: entity.ConfigDefaultAutoFetchHotDramaEnabled, Type: entity.ConfigTypeBool},
|
||||
{Key: entity.ConfigKeyApiToken, Value: entity.ConfigDefaultApiToken, Type: entity.ConfigTypeString},
|
||||
{Key: entity.ConfigKeyPageSize, Value: entity.ConfigDefaultPageSize, Type: entity.ConfigTypeInt},
|
||||
{Key: entity.ConfigKeyMaintenanceMode, Value: entity.ConfigDefaultMaintenanceMode, Type: entity.ConfigTypeBool},
|
||||
}
|
||||
|
||||
err = r.db.Create(defaultConfig).Error
|
||||
err = r.UpsertConfigs(defaultConfigs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return defaultConfig, nil
|
||||
return defaultConfigs, nil
|
||||
}
|
||||
|
||||
return config, nil
|
||||
return configs, nil
|
||||
}
|
||||
|
||||
// GetConfigValue 获取配置值(字符串)
|
||||
func (r *SystemConfigRepositoryImpl) GetConfigValue(key string) (string, error) {
|
||||
config, err := r.FindByKey(key)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return config.Value, nil
|
||||
}
|
||||
|
||||
// GetConfigBool 获取配置值(布尔)
|
||||
func (r *SystemConfigRepositoryImpl) GetConfigBool(key string) (bool, error) {
|
||||
value, err := r.GetConfigValue(key)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
switch value {
|
||||
case "true", "1", "yes":
|
||||
return true, nil
|
||||
case "false", "0", "no":
|
||||
return false, nil
|
||||
default:
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
// GetConfigInt 获取配置值(整数)
|
||||
func (r *SystemConfigRepositoryImpl) GetConfigInt(key string) (int, error) {
|
||||
value, err := r.GetConfigValue(key)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 这里需要导入 strconv 包,但为了避免循环导入,我们使用简单的转换
|
||||
var result int
|
||||
_, err = fmt.Sscanf(value, "%d", &result)
|
||||
return result, err
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
|
||||
"github.com/ctwj/urldb/db/converter"
|
||||
"github.com/ctwj/urldb/db/dto"
|
||||
"github.com/ctwj/urldb/db/entity"
|
||||
"github.com/ctwj/urldb/db/repo"
|
||||
"github.com/ctwj/urldb/utils"
|
||||
|
||||
@@ -25,13 +26,13 @@ func NewSystemConfigHandler(systemConfigRepo repo.SystemConfigRepository) *Syste
|
||||
|
||||
// GetConfig 获取系统配置
|
||||
func (h *SystemConfigHandler) GetConfig(c *gin.Context) {
|
||||
config, err := h.systemConfigRepo.GetOrCreateDefault()
|
||||
configs, err := h.systemConfigRepo.GetOrCreateDefault()
|
||||
if err != nil {
|
||||
ErrorResponse(c, "获取系统配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
configResponse := converter.SystemConfigToResponse(config)
|
||||
configResponse := converter.SystemConfigToResponse(configs)
|
||||
SuccessResponse(c, configResponse)
|
||||
}
|
||||
|
||||
@@ -71,39 +72,39 @@ func (h *SystemConfigHandler) UpdateConfig(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 转换为实体
|
||||
config := converter.RequestToSystemConfig(&req)
|
||||
if config == nil {
|
||||
configs := converter.RequestToSystemConfig(&req)
|
||||
if configs == nil {
|
||||
ErrorResponse(c, "数据转换失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
err := h.systemConfigRepo.Upsert(config)
|
||||
err := h.systemConfigRepo.UpsertConfigs(configs)
|
||||
if err != nil {
|
||||
ErrorResponse(c, "保存系统配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 返回更新后的配置
|
||||
updatedConfig, err := h.systemConfigRepo.FindFirst()
|
||||
updatedConfigs, err := h.systemConfigRepo.FindAll()
|
||||
if err != nil {
|
||||
ErrorResponse(c, "获取更新后的配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
configResponse := converter.SystemConfigToResponse(updatedConfig)
|
||||
configResponse := converter.SystemConfigToResponse(updatedConfigs)
|
||||
SuccessResponse(c, configResponse)
|
||||
}
|
||||
|
||||
// GetSystemConfig 获取系统配置(使用全局repoManager)
|
||||
func GetSystemConfig(c *gin.Context) {
|
||||
config, err := repoManager.SystemConfigRepository.GetOrCreateDefault()
|
||||
configs, err := repoManager.SystemConfigRepository.GetOrCreateDefault()
|
||||
if err != nil {
|
||||
ErrorResponse(c, "获取系统配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
configResponse := converter.SystemConfigToResponse(config)
|
||||
configResponse := converter.SystemConfigToResponse(configs)
|
||||
SuccessResponse(c, configResponse)
|
||||
}
|
||||
|
||||
@@ -143,14 +144,14 @@ func UpdateSystemConfig(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 转换为实体
|
||||
config := converter.RequestToSystemConfig(&req)
|
||||
if config == nil {
|
||||
configs := converter.RequestToSystemConfig(&req)
|
||||
if configs == nil {
|
||||
ErrorResponse(c, "数据转换失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
err := repoManager.SystemConfigRepository.Upsert(config)
|
||||
err := repoManager.SystemConfigRepository.UpsertConfigs(configs)
|
||||
if err != nil {
|
||||
ErrorResponse(c, "保存系统配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -172,24 +173,24 @@ func UpdateSystemConfig(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 返回更新后的配置
|
||||
updatedConfig, err := repoManager.SystemConfigRepository.FindFirst()
|
||||
updatedConfigs, err := repoManager.SystemConfigRepository.FindAll()
|
||||
if err != nil {
|
||||
ErrorResponse(c, "获取更新后的配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
configResponse := converter.SystemConfigToResponse(updatedConfig)
|
||||
configResponse := converter.SystemConfigToResponse(updatedConfigs)
|
||||
SuccessResponse(c, configResponse)
|
||||
}
|
||||
|
||||
// 新增:公开获取系统配置(不含api_token)
|
||||
func GetPublicSystemConfig(c *gin.Context) {
|
||||
config, err := repoManager.SystemConfigRepository.GetOrCreateDefault()
|
||||
configs, err := repoManager.SystemConfigRepository.GetOrCreateDefault()
|
||||
if err != nil {
|
||||
ErrorResponse(c, "获取系统配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
configResponse := converter.SystemConfigToPublicResponse(config)
|
||||
configResponse := converter.SystemConfigToPublicResponse(configs)
|
||||
SuccessResponse(c, configResponse)
|
||||
}
|
||||
|
||||
@@ -204,17 +205,25 @@ func ToggleAutoProcess(c *gin.Context) {
|
||||
}
|
||||
|
||||
// 获取当前配置
|
||||
config, err := repoManager.SystemConfigRepository.GetOrCreateDefault()
|
||||
configs, err := repoManager.SystemConfigRepository.GetOrCreateDefault()
|
||||
if err != nil {
|
||||
ErrorResponse(c, "获取系统配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// 只更新自动处理配置
|
||||
config.AutoProcessReadyResources = req.AutoProcessReadyResources
|
||||
// 更新自动处理配置
|
||||
for i, config := range configs {
|
||||
if config.Key == entity.ConfigKeyAutoProcessReadyResources {
|
||||
configs[i].Value = "true"
|
||||
if !req.AutoProcessReadyResources {
|
||||
configs[i].Value = "false"
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 保存配置
|
||||
err = repoManager.SystemConfigRepository.Upsert(config)
|
||||
err = repoManager.SystemConfigRepository.UpsertConfigs(configs)
|
||||
if err != nil {
|
||||
ErrorResponse(c, "保存系统配置失败", http.StatusInternalServerError)
|
||||
return
|
||||
@@ -232,14 +241,18 @@ func ToggleAutoProcess(c *gin.Context) {
|
||||
repoManager.CategoryRepository,
|
||||
)
|
||||
if scheduler != nil {
|
||||
// 获取其他配置值
|
||||
autoFetchHotDrama, _ := repoManager.SystemConfigRepository.GetConfigBool(entity.ConfigKeyAutoFetchHotDramaEnabled)
|
||||
autoTransfer, _ := repoManager.SystemConfigRepository.GetConfigBool(entity.ConfigKeyAutoTransferEnabled)
|
||||
|
||||
scheduler.UpdateSchedulerStatusWithAutoTransfer(
|
||||
config.AutoFetchHotDramaEnabled,
|
||||
config.AutoProcessReadyResources,
|
||||
config.AutoTransferEnabled,
|
||||
autoFetchHotDrama,
|
||||
req.AutoProcessReadyResources,
|
||||
autoTransfer,
|
||||
)
|
||||
}
|
||||
|
||||
// 返回更新后的配置
|
||||
configResponse := converter.SystemConfigToResponse(config)
|
||||
configResponse := converter.SystemConfigToResponse(configs)
|
||||
SuccessResponse(c, configResponse)
|
||||
}
|
||||
|
||||
48
main.go
48
main.go
@@ -7,6 +7,7 @@ import (
|
||||
"github.com/ctwj/urldb/utils"
|
||||
|
||||
"github.com/ctwj/urldb/db"
|
||||
"github.com/ctwj/urldb/db/entity"
|
||||
"github.com/ctwj/urldb/db/repo"
|
||||
"github.com/ctwj/urldb/handlers"
|
||||
"github.com/ctwj/urldb/middleware"
|
||||
@@ -81,33 +82,34 @@ func main() {
|
||||
)
|
||||
|
||||
// 检查系统配置,决定是否启动各种自动任务
|
||||
systemConfig, err := repoManager.SystemConfigRepository.GetOrCreateDefault()
|
||||
autoProcessReadyResources, err := repoManager.SystemConfigRepository.GetConfigBool(entity.ConfigKeyAutoProcessReadyResources)
|
||||
if err != nil {
|
||||
utils.Error("获取系统配置失败: %v", err)
|
||||
utils.Error("获取自动处理待处理资源配置失败: %v", err)
|
||||
} else if autoProcessReadyResources {
|
||||
scheduler.StartReadyResourceScheduler()
|
||||
utils.Info("已启动待处理资源自动处理任务")
|
||||
} else {
|
||||
// 检查是否启动待处理资源自动处理任务
|
||||
if systemConfig.AutoProcessReadyResources {
|
||||
scheduler.StartReadyResourceScheduler()
|
||||
utils.Info("已启动待处理资源自动处理任务")
|
||||
} else {
|
||||
utils.Info("系统配置中自动处理待处理资源功能已禁用,跳过启动定时任务")
|
||||
}
|
||||
utils.Info("系统配置中自动处理待处理资源功能已禁用,跳过启动定时任务")
|
||||
}
|
||||
|
||||
// 检查是否启动热播剧自动拉取任务
|
||||
if systemConfig.AutoFetchHotDramaEnabled {
|
||||
scheduler.StartHotDramaScheduler()
|
||||
utils.Info("已启动热播剧自动拉取任务")
|
||||
} else {
|
||||
utils.Info("系统配置中自动拉取热播剧功能已禁用,跳过启动定时任务")
|
||||
}
|
||||
autoFetchHotDramaEnabled, err := repoManager.SystemConfigRepository.GetConfigBool(entity.ConfigKeyAutoFetchHotDramaEnabled)
|
||||
if err != nil {
|
||||
utils.Error("获取自动拉取热播剧配置失败: %v", err)
|
||||
} else if autoFetchHotDramaEnabled {
|
||||
scheduler.StartHotDramaScheduler()
|
||||
utils.Info("已启动热播剧自动拉取任务")
|
||||
} else {
|
||||
utils.Info("系统配置中自动拉取热播剧功能已禁用,跳过启动定时任务")
|
||||
}
|
||||
|
||||
// 检查是否启动自动转存任务
|
||||
if systemConfig.AutoTransferEnabled {
|
||||
scheduler.StartAutoTransferScheduler()
|
||||
utils.Info("已启动自动转存任务")
|
||||
} else {
|
||||
utils.Info("系统配置中自动转存功能已禁用,跳过启动定时任务")
|
||||
}
|
||||
autoTransferEnabled, err := repoManager.SystemConfigRepository.GetConfigBool(entity.ConfigKeyAutoTransferEnabled)
|
||||
if err != nil {
|
||||
utils.Error("获取自动转存配置失败: %v", err)
|
||||
} else if autoTransferEnabled {
|
||||
scheduler.StartAutoTransferScheduler()
|
||||
utils.Info("已启动自动转存任务")
|
||||
} else {
|
||||
utils.Info("系统配置中自动转存功能已禁用,跳过启动定时任务")
|
||||
}
|
||||
|
||||
// 创建Gin实例
|
||||
|
||||
@@ -3,6 +3,7 @@ package middleware
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/ctwj/urldb/db/entity"
|
||||
"github.com/ctwj/urldb/db/repo"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -45,7 +46,8 @@ func PublicAPIAuth() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
config, err := repoManager.SystemConfigRepository.FindFirst()
|
||||
// 验证API Token
|
||||
apiTokenConfig, err := repoManager.SystemConfigRepository.GetConfigValue(entity.ConfigKeyApiToken)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"success": false,
|
||||
@@ -56,7 +58,7 @@ func PublicAPIAuth() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
if config.ApiToken == "" {
|
||||
if apiTokenConfig == "" {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{
|
||||
"success": false,
|
||||
"message": "API Token未配置",
|
||||
@@ -66,7 +68,7 @@ func PublicAPIAuth() gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
if config.ApiToken != apiToken {
|
||||
if apiTokenConfig != apiToken {
|
||||
c.JSON(http.StatusUnauthorized, gin.H{
|
||||
"success": false,
|
||||
"message": "API Token无效",
|
||||
@@ -77,7 +79,18 @@ func PublicAPIAuth() gin.HandlerFunc {
|
||||
}
|
||||
|
||||
// 检查维护模式
|
||||
if config.MaintenanceMode {
|
||||
maintenanceMode, err := repoManager.SystemConfigRepository.GetConfigBool(entity.ConfigKeyMaintenanceMode)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"success": false,
|
||||
"message": "系统配置获取失败",
|
||||
"code": 500,
|
||||
})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
if maintenanceMode {
|
||||
c.JSON(http.StatusServiceUnavailable, gin.H{
|
||||
"success": false,
|
||||
"message": "系统维护中,请稍后再试",
|
||||
|
||||
@@ -290,10 +290,9 @@ func (s *Scheduler) StartReadyResourceScheduler() {
|
||||
|
||||
go func() {
|
||||
// 获取系统配置中的间隔时间
|
||||
config, err := s.systemConfigRepo.GetOrCreateDefault()
|
||||
interval := 3 * time.Minute // 默认5分钟
|
||||
if err == nil && config.AutoProcessInterval > 0 {
|
||||
interval = time.Duration(config.AutoProcessInterval) * time.Minute
|
||||
interval := 3 * time.Minute // 默认3分钟
|
||||
if autoProcessInterval, err := s.systemConfigRepo.GetConfigInt(entity.ConfigKeyAutoProcessInterval); err == nil && autoProcessInterval > 0 {
|
||||
interval = time.Duration(autoProcessInterval) * time.Minute
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(interval)
|
||||
@@ -341,13 +340,13 @@ func (s *Scheduler) processReadyResources() {
|
||||
Info("开始处理待处理资源...")
|
||||
|
||||
// 检查系统配置,确认是否启用自动处理
|
||||
config, err := s.systemConfigRepo.GetOrCreateDefault()
|
||||
autoProcess, err := s.systemConfigRepo.GetConfigBool(entity.ConfigKeyAutoProcessReadyResources)
|
||||
if err != nil {
|
||||
Error("获取系统配置失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !config.AutoProcessReadyResources {
|
||||
if !autoProcess {
|
||||
Info("自动处理待处理资源功能已禁用")
|
||||
return
|
||||
}
|
||||
@@ -641,10 +640,9 @@ func (s *Scheduler) StartAutoTransferScheduler() {
|
||||
|
||||
go func() {
|
||||
// 获取系统配置中的间隔时间
|
||||
config, err := s.systemConfigRepo.GetOrCreateDefault()
|
||||
interval := 5 * time.Minute // 默认5分钟
|
||||
if err == nil && config.AutoProcessInterval > 0 {
|
||||
interval = time.Duration(config.AutoProcessInterval) * time.Minute
|
||||
if autoProcessInterval, err := s.systemConfigRepo.GetConfigInt(entity.ConfigKeyAutoProcessInterval); err == nil && autoProcessInterval > 0 {
|
||||
interval = time.Duration(autoProcessInterval) * time.Minute
|
||||
}
|
||||
|
||||
ticker := time.NewTicker(interval)
|
||||
@@ -697,13 +695,13 @@ func (s *Scheduler) processAutoTransfer() {
|
||||
Info("开始处理自动转存...")
|
||||
|
||||
// 检查系统配置,确认是否启用自动转存
|
||||
config, err := s.systemConfigRepo.GetOrCreateDefault()
|
||||
autoTransferEnabled, err := s.systemConfigRepo.GetConfigBool(entity.ConfigKeyAutoTransferEnabled)
|
||||
if err != nil {
|
||||
Error("获取系统配置失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
if !config.AutoTransferEnabled {
|
||||
if !autoTransferEnabled {
|
||||
Info("自动转存功能已禁用")
|
||||
return
|
||||
}
|
||||
@@ -729,8 +727,15 @@ func (s *Scheduler) processAutoTransfer() {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取最小存储空间配置
|
||||
autoTransferMinSpace, err := s.systemConfigRepo.GetConfigInt(entity.ConfigKeyAutoTransferMinSpace)
|
||||
if err != nil {
|
||||
Error("获取最小存储空间配置失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 过滤:只保留已激活、quark平台、剩余空间足够的账号
|
||||
minSpaceBytes := int64(config.AutoTransferMinSpace) * 1024 * 1024 * 1024
|
||||
minSpaceBytes := int64(autoTransferMinSpace) * 1024 * 1024 * 1024
|
||||
var validAccounts []entity.Cks
|
||||
for _, acc := range accounts {
|
||||
if acc.IsValid && acc.PanID == quarkPanID && acc.LeftSpace >= minSpaceBytes {
|
||||
@@ -746,7 +751,7 @@ func (s *Scheduler) processAutoTransfer() {
|
||||
Info("找到 %d 个可用quark网盘账号,开始自动转存处理...", len(validAccounts))
|
||||
|
||||
// 获取需要转存的资源
|
||||
resources, err := s.getResourcesForTransfer(config, quarkPanID)
|
||||
resources, err := s.getResourcesForTransfer(quarkPanID)
|
||||
if err != nil {
|
||||
Error("获取需要转存的资源失败: %v", err)
|
||||
return
|
||||
@@ -773,7 +778,7 @@ func (s *Scheduler) processAutoTransfer() {
|
||||
defer wg.Done()
|
||||
factory := panutils.GetInstance() // 使用单例模式
|
||||
for res := range resourceCh {
|
||||
if err := s.transferResource(res, []entity.Cks{acc}, config, factory); err != nil {
|
||||
if err := s.transferResource(res, []entity.Cks{acc}, factory); err != nil {
|
||||
Error("转存资源失败 (ID: %d): %v", res.ID, err)
|
||||
} else {
|
||||
Info("成功转存资源: %s", res.Title)
|
||||
@@ -789,8 +794,15 @@ func (s *Scheduler) processAutoTransfer() {
|
||||
}
|
||||
|
||||
// getResourcesForTransfer 获取需要转存的资源
|
||||
func (s *Scheduler) getResourcesForTransfer(config *entity.SystemConfig, quarkPanID uint) ([]*entity.Resource, error) {
|
||||
days := config.AutoTransferLimitDays
|
||||
func (s *Scheduler) getResourcesForTransfer(quarkPanID uint) ([]*entity.Resource, error) {
|
||||
// 获取自动转存限制天数配置
|
||||
autoTransferLimitDays, err := s.systemConfigRepo.GetConfigInt(entity.ConfigKeyAutoTransferLimitDays)
|
||||
if err != nil {
|
||||
Error("获取自动转存限制天数配置失败: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
days := autoTransferLimitDays
|
||||
var sinceTime time.Time
|
||||
if days > 0 {
|
||||
sinceTime = GetCurrentTime().AddDate(0, 0, -days)
|
||||
@@ -808,7 +820,7 @@ func (s *Scheduler) getResourcesForTransfer(config *entity.SystemConfig, quarkPa
|
||||
var resourceUpdateMutex sync.Mutex // 全局互斥锁,保证多协程安全
|
||||
|
||||
// transferResource 转存单个资源
|
||||
func (s *Scheduler) transferResource(resource *entity.Resource, accounts []entity.Cks, config *entity.SystemConfig, factory *panutils.PanFactory) error {
|
||||
func (s *Scheduler) transferResource(resource *entity.Resource, accounts []entity.Cks, factory *panutils.PanFactory) error {
|
||||
if len(accounts) == 0 {
|
||||
return fmt.Errorf("没有可用的网盘账号")
|
||||
}
|
||||
@@ -824,7 +836,23 @@ func (s *Scheduler) transferResource(resource *entity.Resource, accounts []entit
|
||||
return fmt.Errorf("创建网盘服务失败: %v", err)
|
||||
}
|
||||
|
||||
// 获取最小存储空间配置
|
||||
autoTransferMinSpace, err := s.systemConfigRepo.GetConfigInt(entity.ConfigKeyAutoTransferMinSpace)
|
||||
if err != nil {
|
||||
Error("获取最小存储空间配置失败: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// 检查账号剩余空间
|
||||
minSpaceBytes := int64(autoTransferMinSpace) * 1024 * 1024 * 1024
|
||||
if account.LeftSpace < minSpaceBytes {
|
||||
return fmt.Errorf("账号剩余空间不足,需要 %d GB,当前剩余 %d GB", autoTransferMinSpace, account.LeftSpace/1024/1024/1024)
|
||||
}
|
||||
|
||||
// 提取分享ID
|
||||
shareID, _ := commonutils.ExtractShareIdString(resource.URL)
|
||||
|
||||
// 转存资源
|
||||
result, err := service.Transfer(shareID)
|
||||
if err != nil {
|
||||
resourceUpdateMutex.Lock()
|
||||
@@ -880,35 +908,34 @@ func (s *Scheduler) transferResource(resource *entity.Resource, accounts []entit
|
||||
return nil
|
||||
}
|
||||
|
||||
// selectBestAccount 选择最佳网盘账号
|
||||
func (s *Scheduler) selectBestAccount(accounts []entity.Cks, config *entity.SystemConfig) *entity.Cks {
|
||||
// TODO: 实现账号选择逻辑
|
||||
// 1. 过滤出有效的账号
|
||||
// 2. 检查剩余空间是否满足最小要求
|
||||
// 3. 优先选择VIP账号
|
||||
// 4. 优先选择剩余空间大的账号
|
||||
// 5. 考虑账号的使用频率(避免单个账号过度使用)
|
||||
// selectBestAccount 选择最佳账号
|
||||
func (s *Scheduler) selectBestAccount(accounts []entity.Cks) *entity.Cks {
|
||||
if len(accounts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
minSpaceBytes := int64(config.AutoTransferMinSpace) * 1024 * 1024 * 1024 // 转换为字节
|
||||
// 获取最小存储空间配置
|
||||
autoTransferMinSpace, err := s.systemConfigRepo.GetConfigInt(entity.ConfigKeyAutoTransferMinSpace)
|
||||
if err != nil {
|
||||
Error("获取最小存储空间配置失败: %v", err)
|
||||
return &accounts[0] // 返回第一个账号
|
||||
}
|
||||
|
||||
minSpaceBytes := int64(autoTransferMinSpace) * 1024 * 1024 * 1024
|
||||
|
||||
var bestAccount *entity.Cks
|
||||
var maxScore int64 = -1
|
||||
var bestScore int64 = -1
|
||||
|
||||
for _, account := range accounts {
|
||||
if !account.IsValid {
|
||||
continue
|
||||
}
|
||||
|
||||
// 检查剩余空间
|
||||
for i := range accounts {
|
||||
account := &accounts[i]
|
||||
if account.LeftSpace < minSpaceBytes {
|
||||
continue
|
||||
continue // 跳过空间不足的账号
|
||||
}
|
||||
|
||||
// 计算账号评分
|
||||
score := s.calculateAccountScore(&account)
|
||||
if score > maxScore {
|
||||
maxScore = score
|
||||
bestAccount = &account
|
||||
score := s.calculateAccountScore(account)
|
||||
if score > bestScore {
|
||||
bestScore = score
|
||||
bestAccount = account
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user