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