🎨 优化扩展模块,完成ai接入和对话功能
This commit is contained in:
@@ -3,7 +3,10 @@ package app
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
|
||||
"git.echol.cn/loser/st/server/global"
|
||||
@@ -563,3 +566,72 @@ func (a *ExtensionApi) InstallExtensionFromGit(c *gin.Context) {
|
||||
|
||||
sysResponse.OkWithData(response.ToExtensionResponse(extension), c)
|
||||
}
|
||||
|
||||
// ProxyExtensionAsset 获取扩展资源文件(从本地文件系统读取)
|
||||
// @Summary 获取扩展资源文件
|
||||
// @Description 从本地存储读取扩展的 JS/CSS 等资源文件(与原版 SillyTavern 一致,扩展文件存储在本地)
|
||||
// @Tags 扩展管理
|
||||
// @Produce octet-stream
|
||||
// @Param id path int true "扩展ID"
|
||||
// @Param path path string true "资源文件路径"
|
||||
// @Success 200 {file} binary
|
||||
// @Router /app/extension/:id/asset/*path [get]
|
||||
func (a *ExtensionApi) ProxyExtensionAsset(c *gin.Context) {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.ParseUint(idStr, 10, 32)
|
||||
if err != nil {
|
||||
sysResponse.FailWithMessage("无效的扩展ID", c)
|
||||
return
|
||||
}
|
||||
extensionID := uint(id)
|
||||
|
||||
// 获取资源路径(去掉前导 /)
|
||||
assetPath := c.Param("path")
|
||||
if len(assetPath) > 0 && assetPath[0] == '/' {
|
||||
assetPath = assetPath[1:]
|
||||
}
|
||||
if assetPath == "" {
|
||||
sysResponse.FailWithMessage("资源路径不能为空", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 通过扩展 ID 查库获取信息(公开路由,不做 userID 过滤)
|
||||
extInfo, err := extensionService.GetExtensionByID(extensionID)
|
||||
if err != nil {
|
||||
sysResponse.FailWithMessage("扩展不存在", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 从本地文件系统读取资源
|
||||
localPath, err := extensionService.GetExtensionAssetLocalPath(extInfo.Name, assetPath)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("获取扩展资源失败",
|
||||
zap.Error(err),
|
||||
zap.String("name", extInfo.Name),
|
||||
zap.String("asset", assetPath))
|
||||
sysResponse.FailWithMessage("资源不存在: "+err.Error(), c)
|
||||
return
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
data, err := os.ReadFile(localPath)
|
||||
if err != nil {
|
||||
global.GVA_LOG.Error("读取扩展资源文件失败", zap.Error(err), zap.String("path", localPath))
|
||||
sysResponse.FailWithMessage("资源读取失败", c)
|
||||
return
|
||||
}
|
||||
|
||||
// 根据文件扩展名设置正确的 Content-Type
|
||||
fileExt := filepath.Ext(assetPath)
|
||||
contentType := mime.TypeByExtension(fileExt)
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
|
||||
// 设置缓存和 CORS 头
|
||||
c.Header("Content-Type", contentType)
|
||||
c.Header("Cache-Control", "public, max-age=3600")
|
||||
c.Header("Access-Control-Allow-Origin", "*")
|
||||
|
||||
c.Data(http.StatusOK, contentType, data)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user