477 lines
14 KiB
Go
477 lines
14 KiB
Go
package app
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"git.echol.cn/loser/st/server/global"
|
|
"git.echol.cn/loser/st/server/middleware"
|
|
"git.echol.cn/loser/st/server/model/app/request"
|
|
"git.echol.cn/loser/st/server/model/common/response"
|
|
"github.com/gin-gonic/gin"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
type ProviderApi struct{}
|
|
|
|
// ==================== 提供商接口 ====================
|
|
|
|
// CreateProvider 创建AI提供商
|
|
// @Tags AI配置
|
|
// @Summary 创建AI提供商
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body request.CreateProviderRequest true "提供商信息"
|
|
// @Success 200 {object} response.Response{data=appResponse.ProviderResponse} "创建成功"
|
|
// @Router /app/provider [post]
|
|
func (pa *ProviderApi) CreateProvider(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
var req request.CreateProviderRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
provider, err := providerService.CreateProvider(req, userID)
|
|
if err != nil {
|
|
global.GVA_LOG.Error("创建AI提供商失败", zap.Error(err))
|
|
response.FailWithMessage("创建失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(provider, c)
|
|
}
|
|
|
|
// GetProviderList 获取AI提供商列表
|
|
// @Tags AI配置
|
|
// @Summary 获取AI提供商列表
|
|
// @Security ApiKeyAuth
|
|
// @Produce application/json
|
|
// @Param page query int true "页码"
|
|
// @Param pageSize query int true "每页数量"
|
|
// @Param keyword query string false "搜索关键词"
|
|
// @Success 200 {object} response.Response{data=appResponse.ProviderListResponse} "获取成功"
|
|
// @Router /app/provider/list [get]
|
|
func (pa *ProviderApi) GetProviderList(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
var req request.ProviderListRequest
|
|
if err := c.ShouldBindQuery(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
// 默认分页
|
|
if req.Page == 0 {
|
|
req.Page = 1
|
|
}
|
|
if req.PageSize == 0 {
|
|
req.PageSize = 20
|
|
}
|
|
|
|
list, err := providerService.GetProviderList(req, userID)
|
|
if err != nil {
|
|
global.GVA_LOG.Error("获取AI提供商列表失败", zap.Error(err))
|
|
response.FailWithMessage("获取失败", c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(list, c)
|
|
}
|
|
|
|
// GetProviderDetail 获取AI提供商详情
|
|
// @Tags AI配置
|
|
// @Summary 获取AI提供商详情
|
|
// @Security ApiKeyAuth
|
|
// @Produce application/json
|
|
// @Param id path uint true "提供商ID"
|
|
// @Success 200 {object} response.Response{data=appResponse.ProviderResponse} "获取成功"
|
|
// @Router /app/provider/:id [get]
|
|
func (pa *ProviderApi) GetProviderDetail(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
response.FailWithMessage("无效的ID", c)
|
|
return
|
|
}
|
|
|
|
provider, err := providerService.GetProviderDetail(uint(id), userID)
|
|
if err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(provider, c)
|
|
}
|
|
|
|
// UpdateProvider 更新AI提供商
|
|
// @Tags AI配置
|
|
// @Summary 更新AI提供商
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body request.UpdateProviderRequest true "更新信息"
|
|
// @Success 200 {object} response.Response{data=appResponse.ProviderResponse} "更新成功"
|
|
// @Router /app/provider [put]
|
|
func (pa *ProviderApi) UpdateProvider(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
var req request.UpdateProviderRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
provider, err := providerService.UpdateProvider(req, userID)
|
|
if err != nil {
|
|
global.GVA_LOG.Error("更新AI提供商失败", zap.Error(err))
|
|
response.FailWithMessage("更新失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(provider, c)
|
|
}
|
|
|
|
// DeleteProvider 删除AI提供商
|
|
// @Tags AI配置
|
|
// @Summary 删除AI提供商
|
|
// @Security ApiKeyAuth
|
|
// @Produce application/json
|
|
// @Param id path uint true "提供商ID"
|
|
// @Success 200 {object} response.Response{msg=string} "删除成功"
|
|
// @Router /app/provider/:id [delete]
|
|
func (pa *ProviderApi) DeleteProvider(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
response.FailWithMessage("无效的ID", c)
|
|
return
|
|
}
|
|
|
|
if err := providerService.DeleteProvider(uint(id), userID); err != nil {
|
|
global.GVA_LOG.Error("删除AI提供商失败", zap.Error(err))
|
|
response.FailWithMessage("删除失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithMessage("删除成功", c)
|
|
}
|
|
|
|
// SetDefaultProvider 设置默认提供商
|
|
// @Tags AI配置
|
|
// @Summary 设置默认AI提供商
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body request.SetDefaultProviderRequest true "提供商ID"
|
|
// @Success 200 {object} response.Response{msg=string} "设置成功"
|
|
// @Router /app/provider/setDefault [post]
|
|
func (pa *ProviderApi) SetDefaultProvider(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
var req request.SetDefaultProviderRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
if err := providerService.SetDefaultProvider(req.ProviderID, userID); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithMessage("设置成功", c)
|
|
}
|
|
|
|
// TestProvider 测试提供商连通性(不需要先保存)
|
|
// @Tags AI配置
|
|
// @Summary 测试AI提供商连通性
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body request.TestProviderRequest true "测试参数"
|
|
// @Success 200 {object} response.Response{data=appResponse.TestProviderResponse} "测试结果"
|
|
// @Router /app/provider/test [post]
|
|
func (pa *ProviderApi) TestProvider(c *gin.Context) {
|
|
var req request.TestProviderRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
result, err := providerService.TestProvider(req)
|
|
if err != nil {
|
|
response.FailWithMessage("测试失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(result, c)
|
|
}
|
|
|
|
// TestExistingProvider 测试已保存的提供商连通性
|
|
// @Tags AI配置
|
|
// @Summary 测试已保存的提供商连通性
|
|
// @Security ApiKeyAuth
|
|
// @Produce application/json
|
|
// @Param id path uint true "提供商ID"
|
|
// @Success 200 {object} response.Response{data=appResponse.TestProviderResponse} "测试结果"
|
|
// @Router /app/provider/test/:id [get]
|
|
func (pa *ProviderApi) TestExistingProvider(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
response.FailWithMessage("无效的ID", c)
|
|
return
|
|
}
|
|
|
|
result, err := providerService.TestExistingProvider(uint(id), userID)
|
|
if err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(result, c)
|
|
}
|
|
|
|
// ==================== 模型接口 ====================
|
|
|
|
// AddModel 为提供商添加模型
|
|
// @Tags AI配置
|
|
// @Summary 添加AI模型
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body request.CreateModelRequest true "模型信息"
|
|
// @Success 200 {object} response.Response{data=appResponse.ModelResponse} "创建成功"
|
|
// @Router /app/provider/model [post]
|
|
func (pa *ProviderApi) AddModel(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
var req request.CreateModelRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
model, err := providerService.AddModel(req, userID)
|
|
if err != nil {
|
|
global.GVA_LOG.Error("添加模型失败", zap.Error(err))
|
|
response.FailWithMessage("添加失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(model, c)
|
|
}
|
|
|
|
// UpdateModel 更新模型
|
|
// @Tags AI配置
|
|
// @Summary 更新AI模型
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body request.UpdateModelRequest true "更新信息"
|
|
// @Success 200 {object} response.Response{data=appResponse.ModelResponse} "更新成功"
|
|
// @Router /app/provider/model [put]
|
|
func (pa *ProviderApi) UpdateModel(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
var req request.UpdateModelRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
model, err := providerService.UpdateModel(req, userID)
|
|
if err != nil {
|
|
global.GVA_LOG.Error("更新模型失败", zap.Error(err))
|
|
response.FailWithMessage("更新失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(model, c)
|
|
}
|
|
|
|
// DeleteModel 删除模型
|
|
// @Tags AI配置
|
|
// @Summary 删除AI模型
|
|
// @Security ApiKeyAuth
|
|
// @Produce application/json
|
|
// @Param id path uint true "模型ID"
|
|
// @Success 200 {object} response.Response{msg=string} "删除成功"
|
|
// @Router /app/provider/model/:id [delete]
|
|
func (pa *ProviderApi) DeleteModel(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
response.FailWithMessage("无效的ID", c)
|
|
return
|
|
}
|
|
|
|
if err := providerService.DeleteModel(uint(id), userID); err != nil {
|
|
global.GVA_LOG.Error("删除模型失败", zap.Error(err))
|
|
response.FailWithMessage("删除失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithMessage("删除成功", c)
|
|
}
|
|
|
|
// ==================== 远程模型获取 ====================
|
|
|
|
// FetchRemoteModels 获取远程可用模型列表(不需要先保存)
|
|
// @Tags AI配置
|
|
// @Summary 从远程获取可用模型列表
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body request.FetchRemoteModelsRequest true "提供商配置"
|
|
// @Success 200 {object} response.Response{data=appResponse.FetchRemoteModelsResponse} "获取结果"
|
|
// @Router /app/provider/fetchModels [post]
|
|
func (pa *ProviderApi) FetchRemoteModels(c *gin.Context) {
|
|
var req request.FetchRemoteModelsRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
result, err := providerService.FetchRemoteModels(req)
|
|
if err != nil {
|
|
response.FailWithMessage("获取失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(result, c)
|
|
}
|
|
|
|
// FetchRemoteModelsExisting 获取已保存提供商的远程模型列表
|
|
// @Tags AI配置
|
|
// @Summary 获取已保存提供商的远程可用模型
|
|
// @Security ApiKeyAuth
|
|
// @Produce application/json
|
|
// @Param id path uint true "提供商ID"
|
|
// @Success 200 {object} response.Response{data=appResponse.FetchRemoteModelsResponse} "获取结果"
|
|
// @Router /app/provider/fetchModels/:id [get]
|
|
func (pa *ProviderApi) FetchRemoteModelsExisting(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
response.FailWithMessage("无效的ID", c)
|
|
return
|
|
}
|
|
|
|
result, err := providerService.FetchRemoteModelsExisting(uint(id), userID)
|
|
if err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(result, c)
|
|
}
|
|
|
|
// ==================== 测试消息 ====================
|
|
|
|
// SendTestMessage 发送测试消息(不需要先保存)
|
|
// @Tags AI配置
|
|
// @Summary 发送测试消息验证AI接口
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param data body request.SendTestMessageRequest true "测试参数"
|
|
// @Success 200 {object} response.Response{data=appResponse.SendTestMessageResponse} "测试结果"
|
|
// @Router /app/provider/testMessage [post]
|
|
func (pa *ProviderApi) SendTestMessage(c *gin.Context) {
|
|
var req request.SendTestMessageRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
result, err := providerService.SendTestMessage(req)
|
|
if err != nil {
|
|
response.FailWithMessage("测试失败: "+err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(result, c)
|
|
}
|
|
|
|
// SendTestMessageExisting 使用已保存的提供商发送测试消息
|
|
// @Tags AI配置
|
|
// @Summary 使用已保存的提供商发送测试消息
|
|
// @Security ApiKeyAuth
|
|
// @accept application/json
|
|
// @Produce application/json
|
|
// @Param id path uint true "提供商ID"
|
|
// @Param data body object{modelName=string,message=string} true "测试参数"
|
|
// @Success 200 {object} response.Response{data=appResponse.SendTestMessageResponse} "测试结果"
|
|
// @Router /app/provider/testMessage/:id [post]
|
|
func (pa *ProviderApi) SendTestMessageExisting(c *gin.Context) {
|
|
userID := middleware.GetAppUserID(c)
|
|
|
|
idStr := c.Param("id")
|
|
id, err := strconv.ParseUint(idStr, 10, 32)
|
|
if err != nil {
|
|
response.FailWithMessage("无效的ID", c)
|
|
return
|
|
}
|
|
|
|
var body struct {
|
|
ModelName string `json:"modelName" binding:"required"`
|
|
Message string `json:"message"`
|
|
}
|
|
if err := c.ShouldBindJSON(&body); err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
result, err := providerService.SendTestMessageExisting(uint(id), userID, body.ModelName, body.Message)
|
|
if err != nil {
|
|
response.FailWithMessage(err.Error(), c)
|
|
return
|
|
}
|
|
|
|
response.OkWithData(result, c)
|
|
}
|
|
|
|
// ==================== 辅助接口 ====================
|
|
|
|
// GetProviderTypes 获取支持的提供商类型列表
|
|
// @Tags AI配置
|
|
// @Summary 获取支持的AI提供商类型
|
|
// @Produce application/json
|
|
// @Success 200 {object} response.Response{data=[]appResponse.ProviderTypeOption} "获取成功"
|
|
// @Router /app/provider/types [get]
|
|
func (pa *ProviderApi) GetProviderTypes(c *gin.Context) {
|
|
types := providerService.GetProviderTypes()
|
|
response.OkWithData(types, c)
|
|
}
|
|
|
|
// GetPresetModels 获取预设模型列表
|
|
// @Tags AI配置
|
|
// @Summary 获取指定提供商类型的预设模型
|
|
// @Produce application/json
|
|
// @Param type query string true "提供商类型(openai/claude/gemini/custom)"
|
|
// @Success 200 {object} response.Response{data=[]appResponse.PresetModelOption} "获取成功"
|
|
// @Router /app/provider/presetModels [get]
|
|
func (pa *ProviderApi) GetPresetModels(c *gin.Context) {
|
|
providerType := c.Query("type")
|
|
if providerType == "" {
|
|
response.FailWithMessage("请指定提供商类型", c)
|
|
return
|
|
}
|
|
|
|
models := providerService.GetPresetModels(providerType)
|
|
response.OkWithData(models, c)
|
|
}
|