package controllers import ( "encoding/json" "fmt" "io" "strconv" "strings" "time" "server/models" "server/pkg/jwtutil" beego "github.com/beego/beego/v2/server/web" ) // BackendAiChatPresetController AI聊天角色预设控制器 type BackendAiChatPresetController struct { beego.Controller } func (c *BackendAiChatPresetController) presetClaims() (*jwtutil.Claims, error) { auth := c.Ctx.Request.Header.Get("Authorization") if auth == "" { return nil, fmt.Errorf("未登录") } parts := strings.SplitN(auth, " ", 2) if len(parts) != 2 || parts[0] != "Bearer" { return nil, fmt.Errorf("认证信息格式错误") } claims, err := jwtutil.ParseToken(parts[1]) if err != nil { return nil, fmt.Errorf("无效的token") } if claims.UserType != "backend" { return nil, fmt.Errorf("无权访问") } return claims, nil } func (c *BackendAiChatPresetController) presetJsonErr(httpStatus, bizCode int, msg string) { c.Ctx.Output.SetStatus(httpStatus) c.Data["json"] = map[string]interface{}{"code": bizCode, "msg": msg} _ = c.ServeJSON() } func (c *BackendAiChatPresetController) presetOk(data interface{}) { c.Data["json"] = map[string]interface{}{"code": 200, "msg": "success", "data": data} _ = c.ServeJSON() } type aiPresetPayload struct { Name string `json:"name"` Content string `json:"content"` IsDefault int8 `json:"is_default"` } // List GET /backend/ai/preset/list func (c *BackendAiChatPresetController) List() { claims, err := c.presetClaims() if err != nil { c.presetJsonErr(401, 401, err.Error()) return } var list []models.BackendAiChatPreset _, err = models.Orm.QueryTable(new(models.BackendAiChatPreset)). Filter("tenant_id", fmt.Sprintf("%d", claims.TenantId)). Filter("user_id", uint64(claims.UserID)). Filter("delete_time__isnull", true). OrderBy("-is_default", "-id"). All(&list) if err != nil { c.presetJsonErr(500, 500, "查询失败: "+err.Error()) return } c.presetOk(map[string]interface{}{"list": list}) } // Create POST /backend/ai/preset func (c *BackendAiChatPresetController) Create() { claims, err := c.presetClaims() if err != nil { c.presetJsonErr(401, 401, err.Error()) return } body, err := io.ReadAll(c.Ctx.Request.Body) if err != nil { c.presetJsonErr(400, 400, "读取请求体失败") return } var p aiPresetPayload if err := json.Unmarshal(body, &p); err != nil { c.presetJsonErr(400, 400, "参数格式错误") return } if strings.TrimSpace(p.Name) == "" { c.presetJsonErr(400, 400, "预设名称不能为空") return } if strings.TrimSpace(p.Content) == "" { c.presetJsonErr(400, 400, "预设内容不能为空") return } // 如果设为默认,先取消其他默认 if p.IsDefault == 1 { var defaults []models.BackendAiChatPreset _, _ = models.Orm.QueryTable(new(models.BackendAiChatPreset)). Filter("tenant_id", fmt.Sprintf("%d", claims.TenantId)). Filter("user_id", uint64(claims.UserID)). Filter("is_default", 1). All(&defaults) for _, d := range defaults { d.IsDefault = 0 d.UpdateTime = time.Now() _, _ = models.Orm.Update(&d, "is_default", "update_time") } } preset := models.BackendAiChatPreset{ TenantID: fmt.Sprintf("%d", claims.TenantId), UserID: uint64(claims.UserID), Name: strings.TrimSpace(p.Name), Content: strings.TrimSpace(p.Content), IsDefault: p.IsDefault, CreateTime: time.Now(), UpdateTime: time.Now(), } id, err := models.Orm.Insert(&preset) if err != nil { c.presetJsonErr(500, 500, "创建失败: "+err.Error()) return } c.presetOk(map[string]interface{}{"id": id}) } // Update PUT /backend/ai/preset/:id func (c *BackendAiChatPresetController) Update() { claims, err := c.presetClaims() if err != nil { c.presetJsonErr(401, 401, err.Error()) return } idStr := c.Ctx.Input.Param(":id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.presetJsonErr(400, 400, "ID格式错误") return } preset := models.BackendAiChatPreset{ID: id} if err := models.Orm.Read(&preset); err != nil { c.presetJsonErr(404, 404, "预设不存在") return } if preset.TenantID != fmt.Sprintf("%d", claims.TenantId) || preset.UserID != uint64(claims.UserID) { c.presetJsonErr(403, 403, "无权操作") return } body, err := io.ReadAll(c.Ctx.Request.Body) if err != nil { c.presetJsonErr(400, 400, "读取请求体失败") return } var p aiPresetPayload if err := json.Unmarshal(body, &p); err != nil { c.presetJsonErr(400, 400, "参数格式错误") return } // 如果设为默认,先取消其他默认 if p.IsDefault == 1 && preset.IsDefault != 1 { var defaults []models.BackendAiChatPreset _, _ = models.Orm.QueryTable(new(models.BackendAiChatPreset)). Filter("tenant_id", fmt.Sprintf("%d", claims.TenantId)). Filter("user_id", uint64(claims.UserID)). Filter("is_default", 1). All(&defaults) for _, d := range defaults { d.IsDefault = 0 d.UpdateTime = time.Now() _, _ = models.Orm.Update(&d, "is_default", "update_time") } } preset.Name = strings.TrimSpace(p.Name) preset.Content = strings.TrimSpace(p.Content) preset.IsDefault = p.IsDefault preset.UpdateTime = time.Now() _, err = models.Orm.Update(&preset) if err != nil { c.presetJsonErr(500, 500, "更新失败: "+err.Error()) return } c.presetOk(nil) } // SetDefault PUT /backend/ai/preset/:id/default func (c *BackendAiChatPresetController) SetDefault() { claims, err := c.presetClaims() if err != nil { c.presetJsonErr(401, 401, err.Error()) return } idStr := c.Ctx.Input.Param(":id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.presetJsonErr(400, 400, "ID格式错误") return } preset := models.BackendAiChatPreset{ID: id} if err := models.Orm.Read(&preset); err != nil { c.presetJsonErr(404, 404, "预设不存在") return } if preset.TenantID != fmt.Sprintf("%d", claims.TenantId) || preset.UserID != uint64(claims.UserID) { c.presetJsonErr(403, 403, "无权操作") return } // 取消其他默认 var defaults []models.BackendAiChatPreset _, _ = models.Orm.QueryTable(new(models.BackendAiChatPreset)). Filter("tenant_id", fmt.Sprintf("%d", claims.TenantId)). Filter("user_id", uint64(claims.UserID)). Filter("is_default", 1). All(&defaults) for _, d := range defaults { d.IsDefault = 0 d.UpdateTime = time.Now() _, _ = models.Orm.Update(&d, "is_default", "update_time") } // 设为默认 preset.IsDefault = 1 preset.UpdateTime = time.Now() _, _ = models.Orm.Update(&preset, "is_default", "update_time") c.presetOk(nil) } // Delete DELETE /backend/ai/preset/:id func (c *BackendAiChatPresetController) Delete() { claims, err := c.presetClaims() if err != nil { c.presetJsonErr(401, 401, err.Error()) return } idStr := c.Ctx.Input.Param(":id") id, err := strconv.ParseUint(idStr, 10, 64) if err != nil { c.presetJsonErr(400, 400, "ID格式错误") return } preset := models.BackendAiChatPreset{ID: id} if err := models.Orm.Read(&preset); err != nil { c.presetJsonErr(404, 404, "预设不存在") return } if preset.TenantID != fmt.Sprintf("%d", claims.TenantId) || preset.UserID != uint64(claims.UserID) { c.presetJsonErr(403, 403, "无权操作") return } now := time.Now() preset.DeleteTime = &now _, err = models.Orm.Update(&preset, "delete_time") if err != nil { c.presetJsonErr(500, 500, "删除失败: "+err.Error()) return } c.presetOk(nil) }