Files
ai-code-review/handlers/config.go
2025-02-19 08:46:26 +08:00

161 lines
4.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 handlers
import (
"net/http"
"code-review/config"
"code-review/utils"
"log"
"strings"
"github.com/gin-gonic/gin"
)
type ConfigHandler struct {
cfg *config.Config
}
func NewConfigHandler(cfg *config.Config) *ConfigHandler {
return &ConfigHandler{
cfg: cfg,
}
}
// GetConfig 获取当前配置
func (h *ConfigHandler) GetConfig(c *gin.Context) {
// 使用 ToMap 方法转换配置
configMap := h.cfg.ToMapHtml()
c.JSON(http.StatusOK, configMap)
}
// UpdateConfig 更新配置
func (h *ConfigHandler) UpdateConfig(c *gin.Context) {
// 首先解析为 map
var configMap map[string]interface{}
if err := c.ShouldBindJSON(&configMap); err != nil {
log.Printf("解析配置 JSON 失败: %v", err)
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
log.Printf("开始更新配置")
// 使用当前配置作为基础
newConfig := *h.cfg
// 处理自动禁用配置
if autoDisable, ok := configMap["auto_disable"].(map[string]interface{}); ok {
log.Printf("更新自动禁用配置")
if enabled, exists := autoDisable["enabled"].(bool); exists {
newConfig.AutoDisableConfig.Enabled = enabled
log.Printf("自动禁用功能状态设置为: %v", enabled)
}
if maxFailures, ok := autoDisable["max_failures"].(float64); ok {
newConfig.AutoDisableConfig.MaxFailures = int(maxFailures)
}
if resetAfter, ok := autoDisable["reset_after"].(float64); ok {
newConfig.AutoDisableConfig.ResetAfter = int(resetAfter)
}
}
// 处理 AI 配置
newConfig.AIs = make([]config.AIConfig, 0)
for key, value := range configMap {
if strings.HasPrefix(key, "ais[") {
if aiMap, ok := value.(map[string]interface{}); ok {
aiConfig := config.AIConfig{
Name: utils.GetString(aiMap, "name"),
Type: utils.GetString(aiMap, "type"),
APIKey: utils.GetString(aiMap, "api_key"),
APIBase: utils.GetString(aiMap, "url"),
Model: utils.GetString(aiMap, "model"),
SystemMsg: utils.GetString(aiMap, "system_msg"),
Temperature: utils.GetFloat64(aiMap, "temperature"),
Stream: utils.GetBool(aiMap, "stream"),
Weight: utils.GetInt(aiMap, "weight"),
Priority: utils.GetInt(aiMap, "priority"),
Enabled: utils.GetBool(aiMap, "enabled"),
AutoDisable: utils.GetBool(aiMap, "auto_disable"),
MaxFailures: utils.GetIntPtr(aiMap, "max_failures"),
ResetAfter: utils.GetIntPtr(aiMap, "reset_after"),
}
log.Printf("添加 AI 配置: %s, 类型: %s", aiConfig.Name, aiConfig.Type)
newConfig.AIs = append(newConfig.AIs, aiConfig)
}
}
}
// 处理 Git 平台配置
newConfig.Git = make([]config.GitConfig, 0)
for key, value := range configMap {
if strings.HasPrefix(key, "git[") {
if p, ok := value.(map[string]interface{}); ok {
platformType := utils.GetString(p, "type")
platformConfig := config.GitConfig{
Name: utils.GetString(p, "name"),
Type: platformType,
Token: utils.GetString(p, "token"),
Secret: utils.GetString(p, "webhook_secret"),
APIBase: utils.GetString(p, "api_base"),
}
// 根据平台类型设置对应的 header
switch platformType {
case "gitlab":
platformConfig.SignatureHeader = "X-Gitlab-Token"
platformConfig.EventHeader = "X-Gitlab-Event"
case "gogs":
platformConfig.SignatureHeader = "X-Gogs-Signature"
platformConfig.EventHeader = "X-Gogs-Event"
case "github":
platformConfig.SignatureHeader = "X-Hub-Signature"
platformConfig.EventHeader = "X-GitHub-Event"
case "gitee":
platformConfig.SignatureHeader = "X-Gitee-Token"
platformConfig.EventHeader = "X-Gitee-Event"
default:
// 如果前端传入了自定义的 header则使用前端传入的值
platformConfig.SignatureHeader = utils.GetString(p, "signature_header")
platformConfig.EventHeader = utils.GetString(p, "event_header")
}
log.Printf("添加 Git 平台配置: %s, 类型: %s, SignatureHeader: %s, EventHeader: %s",
platformConfig.Name, platformConfig.Type,
platformConfig.SignatureHeader, platformConfig.EventHeader)
newConfig.Git = append(newConfig.Git, platformConfig)
}
}
}
if err := config.Save(&newConfig); err != nil {
log.Printf("保存配置失败: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 更新运行时配置
h.cfg = &newConfig
// 重新初始化 AI 负载均衡器
config.ResetAIBalancer(newConfig.AIs)
log.Printf("配置更新成功")
c.JSON(http.StatusOK, gin.H{"message": "配置更新成功"})
}
func AuthRequired() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("X-Admin-Token")
cfg := config.GetConfig()
if token == "" || token != cfg.AdminToken {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "未授权访问"})
return
}
c.Next()
}
}