Files
kenaito-media-picker/internal/api/config_controller.go
T
2025-09-24 21:19:55 +08:00

180 lines
5.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package api 配置相关接口。
package api
import (
"net/http"
"strconv"
"github.com/gin-gonic/gin"
"kenaito-media-picker/internal/store"
"kenaito-media-picker/internal/sysinfo"
)
// 配置键名(存储在 AppConfig 表中)
const (
ConfigKeyNsfwType = "nsfw.type" // 检测类型:"" / "human" / "anime"
ConfigKeyNsfwWorkers = "nsfw.workers" // 人类检测 worker 数量
ConfigKeyAnimeNsfwWorkers = "anime.workers" // 二次元检测 worker 数量
ConfigKeyOrganizeWorkers = "organize.workers" // Go 端探测/MIME/移动 worker 数量
ConfigKeyScanDir = "scan.scanDir" // 扫描目录
ConfigKeyDestDir = "scan.destDir" // 存放目录
)
// ConfigController 配置相关接口。
type ConfigController struct {
store *store.Store
}
// NewConfigController 创建配置控制器。
func NewConfigController(st *store.Store) *ConfigController {
return &ConfigController{store: st}
}
// NsfwConfig NSFW 配置响应。
type NsfwConfig struct {
Type string `json:"type"` // 检测类型:"" / "human" / "anime"
HumanWorkers int `json:"humanWorkers"` // 人类检测 worker 数量
AnimeWorkers int `json:"animeWorkers"` // 二次元检测 worker 数量
GoWorkers int `json:"goWorkers"` // Go 端 worker 数量
}
// GetNsfwConfig 处理 GET /api/config/nsfw:获取 NSFW 配置。
func (c *ConfigController) GetNsfwConfig(ctx *gin.Context) {
nsfwType := c.store.GetConfig(ConfigKeyNsfwType)
humanWorkers := 4
if v := c.store.GetConfig(ConfigKeyNsfwWorkers); v != "" {
if w, err := strconv.Atoi(v); err == nil && w > 0 {
humanWorkers = w
}
}
animeWorkers := 2
if v := c.store.GetConfig(ConfigKeyAnimeNsfwWorkers); v != "" {
if w, err := strconv.Atoi(v); err == nil && w > 0 {
animeWorkers = w
}
}
goWorkers := 0 // 0 表示使用文件配置或自动计算
if v := c.store.GetConfig(ConfigKeyOrganizeWorkers); v != "" {
if w, err := strconv.Atoi(v); err == nil && w >= 0 {
goWorkers = w
}
}
Success(ctx, NsfwConfig{
Type: nsfwType,
HumanWorkers: humanWorkers,
AnimeWorkers: animeWorkers,
GoWorkers: goWorkers,
})
}
// UpdateNsfwConfigReq 更新 NSFW 配置请求。
type UpdateNsfwConfigReq struct {
Type string `json:"type"` // 检测类型:"" / "human" / "anime"
HumanWorkers int `json:"humanWorkers"` // 人类检测 worker 数量
AnimeWorkers int `json:"animeWorkers"` // 二次元检测 worker 数量
GoWorkers int `json:"goWorkers"` // Go 端 worker 数量(0 表示使用文件配置)
}
// UpdateNsfwConfig 处理 PUT /api/config/nsfw:更新 NSFW 配置。
func (c *ConfigController) UpdateNsfwConfig(ctx *gin.Context) {
var req UpdateNsfwConfigReq
if err := ctx.ShouldBindJSON(&req); err != nil {
Error(ctx, http.StatusBadRequest, "请求参数错误:"+err.Error())
return
}
// 校验检测类型
if req.Type != "" && req.Type != "human" && req.Type != "anime" {
Error(ctx, http.StatusBadRequest, "检测类型必须是空、human 或 anime")
return
}
// 校验 worker 数量
if req.HumanWorkers <= 0 {
req.HumanWorkers = 4
}
if req.AnimeWorkers <= 0 {
req.AnimeWorkers = 2
}
if req.GoWorkers < 0 {
req.GoWorkers = 0
}
// 保存配置
if err := c.store.SaveConfig(ConfigKeyNsfwType, req.Type); err != nil {
Error(ctx, http.StatusInternalServerError, "保存配置失败:"+err.Error())
return
}
if err := c.store.SaveConfig(ConfigKeyNsfwWorkers, strconv.Itoa(req.HumanWorkers)); err != nil {
Error(ctx, http.StatusInternalServerError, "保存配置失败:"+err.Error())
return
}
if err := c.store.SaveConfig(ConfigKeyAnimeNsfwWorkers, strconv.Itoa(req.AnimeWorkers)); err != nil {
Error(ctx, http.StatusInternalServerError, "保存配置失败:"+err.Error())
return
}
if err := c.store.SaveConfig(ConfigKeyOrganizeWorkers, strconv.Itoa(req.GoWorkers)); err != nil {
Error(ctx, http.StatusInternalServerError, "保存配置失败:"+err.Error())
return
}
Success(ctx, nil)
}
// SystemInfo 系统信息响应。
type SystemInfo struct {
CPUCores int `json:"cpuCores"` // CPU 逻辑核心数
MemoryGB float64 `json:"memoryGB"` // 内存大小(GB)
RecommendedGo int `json:"recommendedGo"` // 推荐的 Go 端 worker 数
RecommendedNsfw int `json:"recommendedNsfw"` // 推荐的人类检测 worker 数
RecommendedAnime int `json:"recommendedAnime"` // 推荐的二次元检测 worker 数
}
// GetSystemInfo 处理 GET /api/config/system:获取系统信息和推荐配置。
func (c *ConfigController) GetSystemInfo(ctx *gin.Context) {
info := sysinfo.GetSystemInfo()
workers := sysinfo.CalculateWorkerConfig(info)
Success(ctx, SystemInfo{
CPUCores: info.CPUCores,
MemoryGB: info.MemoryGB,
RecommendedGo: workers.GoWorkers,
RecommendedNsfw: workers.NsfwWorkers,
RecommendedAnime: workers.AnimeNsfwWorkers,
})
}
// UpdateScanDirReq 更新扫描目录配置请求。
type UpdateScanDirReq struct {
ScanDir string `json:"scanDir"` // 扫描目录
DestDir string `json:"destDir"` // 存放目录
}
// UpdateScanDir 处理 PUT /api/config/scan-dir:更新扫描目录配置。
func (c *ConfigController) UpdateScanDir(ctx *gin.Context) {
var req UpdateScanDirReq
if err := ctx.ShouldBindJSON(&req); err != nil {
Error(ctx, http.StatusBadRequest, "请求参数错误:"+err.Error())
return
}
// 保存扫描目录
if err := c.store.SaveConfig(ConfigKeyScanDir, req.ScanDir); err != nil {
Error(ctx, http.StatusInternalServerError, "保存扫描目录失败:"+err.Error())
return
}
// 保存存放目录
if err := c.store.SaveConfig(ConfigKeyDestDir, req.DestDir); err != nil {
Error(ctx, http.StatusInternalServerError, "保存存放目录失败:"+err.Error())
return
}
Success(ctx, nil)
}