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

266 lines
6.1 KiB
Go
Raw Permalink 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 demand
import (
"app/cfg"
"app/models"
"app/utils"
"encoding/json"
"errors"
"fmt"
"io"
"github.com/veypi/OneBD/rest"
"gorm.io/gorm"
)
var _ = Router.Get("/:id/descendants", getDescendantsHandle)
var _ = Router.Get("/:id/:min_level/", getHandle)
var _ = Router.Get("/:id/", getHandle)
var _ = Router.Get("", getHandle)
// 获取需求
func getHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
id, ok := x.Params.Get("id")
minLevel, hasMinLevel := x.Params.Get("min_level")
doc_id := id
fmt.Println(doc_id)
// 获取所有根节点需求
var demands []models.Demand
query := cfg.DB()
// 如果指定了最小级别,添加筛选条件
if hasMinLevel {
minLevelInt := 0
fmt.Sscanf(minLevel, "%d", &minLevelInt)
query = query.Where("level >= ?", minLevelInt)
}
if !ok || id == "-1" {
if err := query.Find(&demands).Error; err != nil {
return nil, err
}
return demands, nil
}
if err := query.Where("doc_id = ?", doc_id).Find(&demands).Error; err != nil {
return nil, err
}
return demands, nil
// }
// 获取特定节点及其子节点
// var demand models.Demand
// if err := cfg.DB().Where("id = ?", id).First(&demand).Error; err != nil {
// return nil, err
// }
// children, _ := demand.Children(cfg.DB())
// var res = map[string]interface{}{
// "node": demand,
// "children": children,
// }
// return res, nil
}
// 获取所有后代节点
func getDescendantsHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
id, ok := x.Params.Get("id")
if !ok {
return nil, errors.New("缺少id")
}
// 获取特定节点
var demand models.Demand
if err := cfg.DB().Where("id = ?", id).First(&demand).Error; err != nil {
return nil, err
}
// 获取所有子孙节点
descendants, err := demand.Descendants(cfg.DB())
if err != nil {
return nil, err
}
return map[string]interface{}{
"node": demand,
"descendants": descendants,
}, nil
}
// 创建需求
var _ = Router.Post("/:id/", postHandle)
func postHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
docID, hasDocID := x.Params.Get("id")
if !hasDocID {
return nil, errors.New("缺少doc_id")
}
demand := &models.Demand{}
if err := json.NewDecoder(x.Request.Body).Decode(&demand); err != nil {
return nil, err
}
fmt.Printf("demand: %v\n", demand)
fmt.Printf("demand.parentid: %v\n", demand.ParentID)
// 设置文档ID和UUID
demand.DocID = docID
// demand.ID = uuid.New().String()[0:32]
// 设置级别
if demand.ParentID == "-1" || demand.ParentID == "" {
demand.Level = 0
} else {
var parent models.Demand
if err := cfg.DB().Where("id = ? AND doc_id = ?", demand.ParentID, docID).First(&parent).Error; err != nil {
return nil, fmt.Errorf("父节点不存在或不属于当前文档: %v", err)
}
demand.Level = parent.Level + 1
}
if err := cfg.DB().Create(&demand).Error; err != nil {
return nil, err
}
return demand, nil
}
var _ = Router.Patch("/:id/", patchHandle)
// 更新需求
func patchHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
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 demand models.Demand
if err := cfg.DB().Where("id = ?", id).First(&demand).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("需求不存在")
}
return nil, err
}
// 如果更新包含parent_id需要特殊处理层级
if parentID, ok := updateMap["parent_id"]; ok {
newParentID, ok := parentID.(string)
if !ok {
return nil, errors.New("parent_id 必须是字符串类型")
}
// 检查是否形成循环引用
if newParentID == demand.ID {
return nil, errors.New("不能将节点的父节点设置为自身")
}
if newParentID != demand.ParentID {
var newLevel int
// 检查新的父节点是否存在(除非是设置为根节点)
if newParentID != "-1" && newParentID != "" {
var parent models.Demand
if err := cfg.DB().Where("id = ?", newParentID).First(&parent).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("父节点不存在")
}
return nil, err
}
// 检查新父节点是否是当前节点的子节点
children, err := demand.Children(cfg.DB())
if err != nil {
return nil, err
}
for _, child := range children {
if child.ID == newParentID {
return nil, errors.New("不能将子节点设置为父节点")
}
}
newLevel = parent.Level + 1
} else {
newLevel = 0
}
updateMap["level"] = newLevel
}
}
// 删除不允许更新的字段
delete(updateMap, "id")
delete(updateMap, "doc_id")
// 只更新提供的字段
if len(updateMap) > 0 {
if err := cfg.DB().Model(&demand).Updates(updateMap).Error; err != nil {
return nil, err
}
}
// 重新查询更新后的完整数据
if err := cfg.DB().Where("id = ?", id).First(&demand).Error; err != nil {
return nil, err
}
return demand, 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 demand models.Demand
if err := cfg.DB().Where("id = ?", id).First(&demand).Error; err != nil {
return nil, err
}
// 删除需求及其所有子需求
descendants, err := demand.Descendants(cfg.DB())
if err != nil {
return nil, err
}
tx := cfg.DB().Begin()
// 删除所有子需求
for _, desc := range descendants {
if err := tx.Delete(&desc).Error; err != nil {
tx.Rollback()
return nil, err
}
}
// 删除当前需求
if err := tx.Delete(&demand).Error; err != nil {
tx.Rollback()
return nil, err
}
tx.Commit()
return map[string]interface{}{
"msg": "删除成功",
}, nil
}
var _ = Router.Any("/*", anyHandle)
func anyHandle(x *rest.X) (any, error) {
utils.SetCORSHeaders(x)
return nil, nil
}