266 lines
6.1 KiB
Go
266 lines
6.1 KiB
Go
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
|
||
}
|