refactor: 移除二次元识别功能,增强 NSFW 检测

This commit is contained in:
2025-07-12 21:04:52 +08:00
parent 2778393e9d
commit f589592535
17 changed files with 43 additions and 12217 deletions
-121
View File
@@ -1,121 +0,0 @@
package api
import (
"encoding/json"
"net/http"
"os"
"strings"
"github.com/gin-gonic/gin"
"kenaito-media-picker/internal/config"
"kenaito-media-picker/internal/store"
)
// hentaiDetectorReadyKey 记录最近一次扫描时二次元检测服务是否真的起来了。
const hentaiDetectorReadyKey = "hentai.detectorReady"
// HentaiController 二次元识别相关接口的控制器。
type HentaiController struct {
store *store.Store
}
// NewHentaiController 创建二次元识别控制器。
func NewHentaiController(st *store.Store) *HentaiController {
return &HentaiController{store: st}
}
// hentaiView 列表里展示的一条记录。
type hentaiView struct {
Id int64 `json:"id"`
FileName string `json:"fileName"`
Score float64 `json:"score"`
Rating string `json:"rating"`
Threshold float64 `json:"threshold"`
Path string `json:"path"`
TopTags string `json:"topTags"`
CreatedAt string `json:"createdAt"`
}
// List 处理 GET /api/hentai/list:查全部二次元识别记录(按检测分从高到低)。
func (c *HentaiController) List(ctx *gin.Context) {
list, err := c.store.ListHentai()
if err != nil {
Error(ctx, http.StatusInternalServerError, "查询二次元识别记录失败:"+err.Error())
return
}
views := make([]hentaiView, 0, len(list))
for _, r := range list {
path := r.MovedPath
if path == "" {
path = r.FilePath
}
views = append(views, hentaiView{
Id: r.Id,
FileName: r.FileName,
Score: r.Score,
Rating: r.Rating,
Threshold: r.Threshold,
Path: path,
TopTags: r.TopTags,
CreatedAt: r.CreatedAt.Format("2006-01-02 15:04:05"),
})
}
Success(ctx, map[string]interface{}{
"list": views,
"total": len(views),
"hentaiEnabled": config.GetAppConfig().HentaiEnabled,
"hentaiDetector": c.store == nil || c.store.GetConfig(hentaiDetectorReadyKey) != "0",
})
}
// Preview 处理 GET /api/hentai/preview?path=xxx:把指定图片文件返回给浏览器做预览。
func (c *HentaiController) Preview(ctx *gin.Context) {
path := strings.TrimSpace(ctx.Query("path"))
if path == "" {
Error(ctx, http.StatusBadRequest, "缺少 path 参数")
return
}
if _, err := os.Stat(path); err != nil {
Error(ctx, http.StatusNotFound, "图片不存在或已被移动: "+path)
return
}
ctx.File(path)
}
// Tags 处理 GET /api/hentai/tags?id=xxx:查某条记录的标签详情。
func (c *HentaiController) Tags(ctx *gin.Context) {
id := ctx.Query("id")
if id == "" {
Error(ctx, http.StatusBadRequest, "缺少 id 参数")
return
}
var idInt int64
if _, err := json.Number(id).Int64(); err != nil {
Error(ctx, http.StatusBadRequest, "id 格式错误")
return
}
idInt, _ = json.Number(id).Int64()
record, err := c.store.GetHentaiById(idInt)
if err != nil {
Error(ctx, http.StatusInternalServerError, "查询记录失败:"+err.Error())
return
}
if record == nil {
Error(ctx, http.StatusNotFound, "记录不存在")
return
}
var tags []map[string]interface{}
if record.TopTags != "" {
if err := json.Unmarshal([]byte(record.TopTags), &tags); err != nil {
tags = nil
}
}
Success(ctx, map[string]interface{}{
"id": record.Id,
"topTags": tags,
})
}
-6
View File
@@ -38,12 +38,6 @@ func NewRouter(st *store.Store) *gin.Engine {
apiGroup.GET("/nsfw/list", nc.List)
apiGroup.GET("/nsfw/preview", nc.Preview)
// 二次元识别(查看分级结果 + 图片预览 + 标签详情)
hc := NewHentaiController(st)
apiGroup.GET("/hentai/list", hc.List)
apiGroup.GET("/hentai/preview", hc.Preview)
apiGroup.GET("/hentai/tags", hc.Tags)
// 扫描整理(开始 / 中止 / 查进度 / 实时进度)
sc := NewScanController(service.NewScanService(st))
apiGroup.POST("/scan/start", sc.Start)