🔧 chore: 初始化番茄小说 API 项目结构
新增项目基础框架,包含核心 API 实现、算法模块、HTTP 处理器等完整功能模块
This commit is contained in:
commit
6981148727
107 files changed
+12463
No files matched your search
@@ -0,0 +1,132 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fanqie/internal/fqapi"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// HandleAudio 音频处理
|
||||
func HandleAudio(w http.ResponseWriter, r *http.Request) {
|
||||
incrementTotal()
|
||||
incrementAudio()
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
itemIDs := r.URL.Query().Get("item_ids")
|
||||
toneID := r.URL.Query().Get("tone_id")
|
||||
output := r.URL.Query().Get("output")
|
||||
|
||||
result, err := fqapi.HandleAudio(itemIDs, toneID, output)
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, `{"code": -1, "msg": "获取音频失败: %s"}`, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprint(w, result)
|
||||
}
|
||||
|
||||
// HandleAudioProxy 音频代理处理
|
||||
func HandleAudioProxy(w http.ResponseWriter, r *http.Request) {
|
||||
incrementTotal()
|
||||
|
||||
// 从URL路径提取key: /audio/proxy/{key}
|
||||
path := r.URL.Path
|
||||
key := strings.TrimPrefix(path, "/audio/proxy/")
|
||||
if key == "" || key == path {
|
||||
http.Error(w, "缺少音频key", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 调用代理处理函数
|
||||
data, contentType, err := fqapi.HandleAudioProxy(key)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// 设置正确的Content-Type
|
||||
if contentType != "" {
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
} else {
|
||||
w.Header().Set("Content-Type", "audio/mpeg")
|
||||
}
|
||||
|
||||
// 直接播放,不强制下载
|
||||
// 浏览器会根据Content-Type决定是播放还是下载
|
||||
w.Write(data)
|
||||
}
|
||||
|
||||
// HandleVideo 视频处理
|
||||
func HandleVideo(w http.ResponseWriter, r *http.Request) {
|
||||
incrementTotal()
|
||||
incrementVideo()
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
|
||||
itemIDs := r.URL.Query().Get("item_ids")
|
||||
|
||||
result, err := fqapi.HandleVideo(itemIDs)
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, `{"code": -1, "msg": "获取视频失败: %s"}`, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprint(w, result)
|
||||
}
|
||||
|
||||
// HandleManga 漫画处理
|
||||
func HandleManga(w http.ResponseWriter, r *http.Request) {
|
||||
incrementTotal()
|
||||
incrementManga()
|
||||
itemID := r.URL.Query().Get("item_ids")
|
||||
if itemID == "" {
|
||||
itemID = r.URL.Query().Get("item_id")
|
||||
}
|
||||
|
||||
if itemID == "" {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
fmt.Fprint(w, `{"code": -1, "msg": "缺少item_ids参数"}`)
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否要返回HTML格式
|
||||
showHTML := r.URL.Query().Get("show_html") == "1"
|
||||
|
||||
// 检查输出模式参数(优先级高于配置文件)
|
||||
// 支持:output=url / output=proxy / output=data_uri
|
||||
outputMode := r.URL.Query().Get("output")
|
||||
|
||||
result, err := fqapi.HandleGetManga(itemID, showHTML, outputMode)
|
||||
if err != nil {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
fmt.Fprintf(w, `{"code": -1, "msg": "获取漫画失败: %s"}`, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if showHTML {
|
||||
// 返回HTML格式
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
if contentMap, ok := result.(map[string]interface{}); ok {
|
||||
if content, ok := contentMap["content"].(string); ok {
|
||||
fmt.Fprint(w, content)
|
||||
return
|
||||
}
|
||||
}
|
||||
fmt.Fprint(w, `<p>未找到漫画内容</p>`)
|
||||
} else {
|
||||
// 返回JSON格式
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
jsonData, err := json.Marshal(map[string]interface{}{
|
||||
"code": 0,
|
||||
"msg": "success",
|
||||
"data": result,
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Fprintf(w, `{"code": -1, "msg": "JSON编码失败: %s"}`, err.Error())
|
||||
return
|
||||
}
|
||||
fmt.Fprint(w, string(jsonData))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user