testFlow/api/doc/handler.go
Wyle.Gong-巩文昕 67b0ad2723 init
2025-04-22 16:42:48 +08:00

251 lines
5.6 KiB
Go

package doc
import (
"app/cfg"
"app/models"
"app/utils"
"encoding/json"
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"
"time"
"github.com/veypi/OneBD/rest"
"gorm.io/gorm"
)
var _ = Router.Get("/:id", getHandle)
var _ = Router.Get("/:id/project", getProjectIDHandle)
var _ = Router.Get("", getHandle)
// 获取文档对应的项目ID
func getProjectIDHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
// 获取文档ID
docID, ok := x.Params.Get("id")
if !ok {
return nil, errors.New("缺少文档ID")
}
// 查询文档信息
var doc models.Doc
if err := cfg.DB().Where("id = ?", docID).First(&doc).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("文档不存在")
}
return nil, fmt.Errorf("查询文档失败: %v", err)
}
return map[string]interface{}{
"doc_id": docID,
"project_id": doc.ProjectID,
}, nil
}
// 获取文档
func getHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
id, ok := x.Params.Get("id")
// fmt.Println("getHandle", id)
if !ok {
// 获取所有文档
var docs []models.Doc
if err := cfg.DB().Find(&docs).Error; err != nil {
return nil, err
}
return docs, nil
}
// 获取特定文档
var docs []models.Doc
if err := cfg.DB().Where("project_id = ?", id).Find(&docs).Error; err != nil {
return nil, err
}
// fmt.Println("getHandle", doc)
return docs, nil
}
var _ = Router.Post("", postHandle)
// 创建文档
// 创建文档
func postHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
// 解析表单数据
if err := x.Request.ParseMultipartForm(10 << 20); err != nil { // 10 MB
return nil, fmt.Errorf("解析表单失败: %v", err)
}
// 获取项目ID
projectID := x.Request.FormValue("project_id")
if projectID == "" {
return nil, errors.New("缺少project_id参数")
}
// 获取文档名称
name := x.Request.FormValue("name")
if name == "" {
return nil, errors.New("缺少name参数")
}
// 获取文档类型
docType := x.Request.FormValue("type")
if docType == "" {
docType = "other" // 默认类型
}
// 获取文档描述
description := x.Request.FormValue("description")
// 获取上传的文件
file, header, err := x.Request.FormFile("file")
if err != nil {
return nil, fmt.Errorf("获取文件失败: %v", err)
}
defer file.Close()
// 验证文件类型
fileExt := strings.ToLower(filepath.Ext(header.Filename))
allowedTypes := map[string]bool{
".docx": true,
".txt": true,
".pdf": true,
}
if !allowedTypes[fileExt] {
return nil, fmt.Errorf("不支持的文件类型: %s", fileExt)
}
// 创建上传目录
uploadDir := filepath.Join("uploads", "docs", projectID)
if err := os.MkdirAll(uploadDir, 0755); err != nil {
return nil, fmt.Errorf("创建上传目录失败: %v", err)
}
// 生成唯一文件名
fileName := fmt.Sprintf("%d_%s", time.Now().UnixNano(), header.Filename)
filePath := filepath.Join(uploadDir, fileName)
// 保存文件
dst, err := os.Create(filePath)
if err != nil {
return nil, fmt.Errorf("创建目标文件失败: %v", err)
}
defer dst.Close()
size, err := io.Copy(dst, file)
if err != nil {
os.Remove(filePath) // 清理失败的文件
return nil, fmt.Errorf("保存文件失败: %v", err)
}
// 创建文档记录
doc := &models.Doc{
ProjectID: projectID,
Name: name,
Description: description,
FilePath: filePath,
FileType: fileExt[1:], // 移除点号
FileSize: size,
FileName: header.Filename,
AnalysisCompleted: false,
AnalysisPercent: 0,
AnalysisError: "",
Merged: false,
}
if err := cfg.DB().Create(doc).Error; err != nil {
os.Remove(filePath) // 清理文件
return nil, fmt.Errorf("创建文档记录失败: %v", err)
}
// 将文档添加到处理队列
// GetDemandProcessor().AddTask(doc, filePath)
GetAgenticDemandProcessor().AddTask(doc, filePath)
return doc, nil
}
var _ = Router.Patch("/:id", patchHandle)
// 更新文档
func patchHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
// 从URL获取ID
body, err := io.ReadAll(x.Request.Body)
if err != nil {
return nil, fmt.Errorf("读取请求体失败: %v", err)
}
id, ok := x.Params.Get("id")
if !ok {
return nil, errors.New("缺少id")
}
var updateMap map[string]interface{}
if err := json.Unmarshal(body, &updateMap); err != nil {
return nil, fmt.Errorf("解析JSON失败: %v", err)
}
// 先检查文档是否存在
var doc models.Doc
if err := cfg.DB().Where("id = ?", id).First(&doc).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("文档不存在")
}
return nil, err
}
// 删除不允许更新的字段
delete(updateMap, "id")
// 只更新提供的字段
if len(updateMap) > 0 {
if err := cfg.DB().Model(&doc).Updates(updateMap).Error; err != nil {
return nil, err
}
}
// 重新查询更新后的完整数据
if err := cfg.DB().Where("id = ?", id).First(&doc).Error; err != nil {
return nil, err
}
return doc, nil
}
var _ = Router.Delete("/:id", deleteHandle)
// 删除文档
func deleteHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
id, ok := x.Params.Get("id")
if !ok {
return nil, errors.New("缺少id")
}
var doc models.Doc
if err := cfg.DB().Where("id = ?", id).First(&doc).Error; err != nil {
return nil, err
}
// 删除文档
if err := cfg.DB().Delete(&doc).Error; err != nil {
return nil, err
}
return map[string]interface{}{
"msg": "删除成功",
}, nil
}
var _ = Router.Any("/*", anyHandle)
func anyHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
return nil, nil
}