feat: 新增语音转文字(ASR)功能
- 后端:新增 /api/audio/transcribe 接口,调用 Ollama whisper 进行语音识别 - 前端:新增 AudioTranscribePage.vue 页面,支持 MP3/WAV/M4A/OGG/FLAC 等格式 - 注册路由、工具卡片、智能助手欢迎语更新 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"eai_agentplatform/backend/internal/middleware"
|
||||
"eai_agentplatform/backend/internal/model"
|
||||
"eai_agentplatform/backend/internal/store"
|
||||
"eai_agentplatform/backend/internal/web"
|
||||
)
|
||||
|
||||
var validNoteItemTypes = map[string]bool{"company": true, "product": true, "course": true}
|
||||
|
||||
// ListNotes GET /api/notes?item_type=&item_id= —— 我的学习笔记
|
||||
func ListNotes(c *gin.Context) {
|
||||
u := middleware.CurrentUser(c)
|
||||
if u == nil {
|
||||
web.Fail(c, web.NewAuthError("未登录"))
|
||||
return
|
||||
}
|
||||
q := store.DB.Where("user_id = ?", u.ID)
|
||||
if t := c.Query("item_type"); t != "" {
|
||||
q = q.Where("item_type = ?", t)
|
||||
}
|
||||
if s := c.Query("item_id"); s != "" {
|
||||
if n, err := strconv.ParseUint(s, 10, 64); err == nil {
|
||||
q = q.Where("item_id = ?", n)
|
||||
}
|
||||
}
|
||||
var items []model.StudyNote
|
||||
if err := q.Order("updated_at DESC").Find(&items).Error; err != nil {
|
||||
web.Fail(c, web.NewBadRequest("查询笔记失败"))
|
||||
return
|
||||
}
|
||||
web.OK(c, items)
|
||||
}
|
||||
|
||||
// CreateNote POST /api/notes —— 新增学习笔记
|
||||
func CreateNote(c *gin.Context) {
|
||||
u := middleware.CurrentUser(c)
|
||||
if u == nil {
|
||||
web.Fail(c, web.NewAuthError("未登录"))
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
ItemType string `json:"item_type"`
|
||||
ItemID uint `json:"item_id"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
web.Fail(c, web.NewBadRequest("请求参数错误"))
|
||||
return
|
||||
}
|
||||
if !validNoteItemTypes[req.ItemType] {
|
||||
web.Fail(c, web.NewBadRequest("item_type 必须为 company/product/course"))
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(req.Content) == "" {
|
||||
web.Fail(c, web.NewBadRequest("笔记内容不能为空"))
|
||||
return
|
||||
}
|
||||
n := model.StudyNote{UserID: u.ID, ItemType: req.ItemType, ItemID: req.ItemID, Content: strings.TrimSpace(req.Content)}
|
||||
if err := store.DB.Create(&n).Error; err != nil {
|
||||
web.Fail(c, web.NewBadRequest("保存笔记失败"))
|
||||
return
|
||||
}
|
||||
web.OK(c, n)
|
||||
}
|
||||
|
||||
// UpdateNote PUT /api/notes/{id} —— 编辑学习笔记
|
||||
func UpdateNote(c *gin.Context) {
|
||||
u := middleware.CurrentUser(c)
|
||||
if u == nil {
|
||||
web.Fail(c, web.NewAuthError("未登录"))
|
||||
return
|
||||
}
|
||||
id, ok := parseID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var n model.StudyNote
|
||||
if err := store.DB.First(&n, id).Error; err != nil {
|
||||
web.Fail(c, web.NewNotFoundError("笔记不存在"))
|
||||
return
|
||||
}
|
||||
if n.UserID != u.ID {
|
||||
web.Fail(c, web.NewForbiddenError("无权操作他人笔记"))
|
||||
return
|
||||
}
|
||||
var req struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
web.Fail(c, web.NewBadRequest("请求参数错误"))
|
||||
return
|
||||
}
|
||||
if strings.TrimSpace(req.Content) == "" {
|
||||
web.Fail(c, web.NewBadRequest("笔记内容不能为空"))
|
||||
return
|
||||
}
|
||||
n.Content = strings.TrimSpace(req.Content)
|
||||
if err := store.DB.Save(&n).Error; err != nil {
|
||||
web.Fail(c, web.NewBadRequest("更新笔记失败"))
|
||||
return
|
||||
}
|
||||
web.OK(c, n)
|
||||
}
|
||||
|
||||
// DeleteNote DELETE /api/notes/{id} —— 删除学习笔记
|
||||
func DeleteNote(c *gin.Context) {
|
||||
u := middleware.CurrentUser(c)
|
||||
if u == nil {
|
||||
web.Fail(c, web.NewAuthError("未登录"))
|
||||
return
|
||||
}
|
||||
id, ok := parseID(c, "id")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
var n model.StudyNote
|
||||
if err := store.DB.First(&n, id).Error; err != nil {
|
||||
web.Fail(c, web.NewNotFoundError("笔记不存在"))
|
||||
return
|
||||
}
|
||||
if n.UserID != u.ID {
|
||||
web.Fail(c, web.NewForbiddenError("无权操作他人笔记"))
|
||||
return
|
||||
}
|
||||
if err := store.DB.Delete(&n).Error; err != nil {
|
||||
web.Fail(c, web.NewBadRequest("删除笔记失败"))
|
||||
return
|
||||
}
|
||||
web.OK(c, gin.H{"id": id})
|
||||
}
|
||||
Reference in New Issue
Block a user