package service import ( "fmt" "dd_fiber_api/internal/question" "dd_fiber_api/internal/question/dao" ) // KnowledgeTreeService 知识树服务 type KnowledgeTreeService struct { knowledgeTreeDAO dao.KnowledgeTreeDAOInterface } // NewKnowledgeTreeService 创建知识树服务 func NewKnowledgeTreeService(knowledgeTreeDAO dao.KnowledgeTreeDAOInterface) *KnowledgeTreeService { return &KnowledgeTreeService{ knowledgeTreeDAO: knowledgeTreeDAO, } } // CreateKnowledgeTreeNode 创建知识树节点 func (s *KnowledgeTreeService) CreateKnowledgeTreeNode(req *CreateKnowledgeTreeNodeRequest) (*question.KnowledgeTree, error) { nodeID := question.GenerateID() now := question.GetCurrentTimestamp() node := &question.KnowledgeTree{ ID: nodeID, Type: req.Type, Title: req.Title, ParentID: req.ParentID, CreatedAt: now, UpdatedAt: now, } if err := s.knowledgeTreeDAO.Create(node); err != nil { return nil, fmt.Errorf("创建知识树节点失败: %v", err) } return node, nil } // GetKnowledgeTreeNode 获取知识树节点 func (s *KnowledgeTreeService) GetKnowledgeTreeNode(id string) (*question.KnowledgeTree, error) { return s.knowledgeTreeDAO.GetByID(id) } // GetKnowledgeTreeNames 获取知识树名称,返回 id -> 标题 的映射;不存在的节点跳过,不报错 func (s *KnowledgeTreeService) GetKnowledgeTreeNames(ids []string) (map[string]string, error) { idToName := make(map[string]string, len(ids)) for _, id := range ids { if id == "" { continue } tree, err := s.knowledgeTreeDAO.GetByID(id) if err != nil { // 知识树节点不存在或已删除时跳过,不影响整体结果 continue } idToName[id] = tree.Title } return idToName, nil } // GetAllKnowledgeTreeNodes 获取所有知识树节点(扁平列表) func (s *KnowledgeTreeService) GetAllKnowledgeTreeNodes(treeType question.KnowledgeTreeType) ([]*question.KnowledgeTree, error) { return s.knowledgeTreeDAO.GetAll(treeType) } // GetKnowledgeTreeByParentID 根据父节点ID获取子节点列表 func (s *KnowledgeTreeService) GetKnowledgeTreeByParentID(parentID string, treeType question.KnowledgeTreeType) ([]*question.KnowledgeTree, error) { return s.knowledgeTreeDAO.GetByParentID(parentID, treeType) } // GetKnowledgeTree 获取完整树形结构 func (s *KnowledgeTreeService) GetKnowledgeTree(treeType question.KnowledgeTreeType) ([]*question.KnowledgeTree, error) { return s.knowledgeTreeDAO.GetTree(treeType) } // UpdateKnowledgeTreeNode 更新知识树节点 func (s *KnowledgeTreeService) UpdateKnowledgeTreeNode(req *UpdateKnowledgeTreeNodeRequest) error { // 先获取现有节点 existingNode, err := s.knowledgeTreeDAO.GetByID(req.ID) if err != nil { return fmt.Errorf("知识树节点不存在: %v", err) } // 更新字段 existingNode.Title = req.Title existingNode.ParentID = req.ParentID existingNode.UpdatedAt = question.GetCurrentTimestamp() if err := s.knowledgeTreeDAO.Update(existingNode); err != nil { return fmt.Errorf("更新知识树节点失败: %v", err) } return nil } // DeleteKnowledgeTreeNode 删除知识树节点 func (s *KnowledgeTreeService) DeleteKnowledgeTreeNode(id string) error { // 先获取节点,获取类型 existingNode, err := s.knowledgeTreeDAO.GetByID(id) if err != nil { return fmt.Errorf("知识树节点不存在: %v", err) } // 检查是否有子节点 children, err := s.knowledgeTreeDAO.GetByParentID(id, existingNode.Type) if err != nil { return fmt.Errorf("查询子节点失败: %v", err) } if len(children) > 0 { return fmt.Errorf("该节点存在子节点,无法删除") } if err := s.knowledgeTreeDAO.Delete(id); err != nil { return fmt.Errorf("删除知识树节点失败: %v", err) } return nil } // CreateKnowledgeTreeNodeRequest 创建知识树节点请求 type CreateKnowledgeTreeNodeRequest struct { Type question.KnowledgeTreeType `json:"type" binding:"required"` // 知识树类型:objective(客观题)或 subjective(主观题) Title string `json:"title" binding:"required"` // 节点标题 ParentID string `json:"parent_id"` // 父节点ID,根节点为空字符串 } // UpdateKnowledgeTreeNodeRequest 更新知识树节点请求 type UpdateKnowledgeTreeNodeRequest struct { ID string `json:"id" binding:"required"` // 节点ID Title string `json:"title" binding:"required"` // 节点标题 ParentID string `json:"parent_id"` // 父节点ID }