Quellcode durchsuchen

feat: 讨论区+模糊搜索知识点

chenjiawei09 vor 3 Jahren
Ursprung
Commit
e2d040785c

+ 20 - 0
pom.xml

@@ -39,6 +39,26 @@
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+
+        <dependency>
+            <groupId>org.mybatis</groupId>
+            <artifactId>mybatis</artifactId>
+            <version>3.5.6</version>
+        </dependency>
+
+        <!-- MyBatis Starter -->
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.2.0</version>
+        </dependency>
+
+        <!-- ********************** Mysql JDBC驱动 ********************** -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.28</version>
+        </dependency>
     </dependencies>
     <dependencyManagement>
         <dependencies>

+ 2 - 0
src/main/java/com/seeckg/knowledgegraph_backend/KnowledgeGraphBackendApplication.java

@@ -1,9 +1,11 @@
 package com.seeckg.knowledgegraph_backend;
 
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 @SpringBootApplication
+@MapperScan("com.seeckg.knowledgegraph_backend.dao")
 public class KnowledgeGraphBackendApplication {
 
     public static void main(String[] args) {

+ 23 - 0
src/main/java/com/seeckg/knowledgegraph_backend/convert/KnowledgeForumConvert.java

@@ -0,0 +1,23 @@
+package com.seeckg.knowledgegraph_backend.convert;
+
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum;
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForumVO;
+
+/**
+ * @author chenjiawei09 <chenjiawei09@kuaishou.com>
+ * Created on 2023-05-22
+ */
+public class KnowledgeForumConvert {
+    public static KnowledgeForum convert(KnowledgeForumVO knowledgeForumVO) {
+
+        return KnowledgeForum.builder()
+                .id(knowledgeForumVO.getId())
+                .type(knowledgeForumVO.getType())
+                .preForumId(knowledgeForumVO.getPreForumId())
+                .context(knowledgeForumVO.getContext())
+                .createTime(knowledgeForumVO.getCreateTime())
+                .updateTime(knowledgeForumVO.getUpdateTime())
+                .knowledgeId(knowledgeForumVO.getKnowledgeId())
+                .creatorId(knowledgeForumVO.getCreatorId()).build();
+    }
+}

+ 6 - 0
src/main/java/com/seeckg/knowledgegraph_backend/dao/KnowledgeDao.java

@@ -1,9 +1,15 @@
 package com.seeckg.knowledgegraph_backend.dao;
 
+import java.util.List;
+
 import com.seeckg.knowledgegraph_backend.pojo.Knowledge;
 import org.springframework.data.neo4j.repository.Neo4jRepository;
+import org.springframework.data.neo4j.repository.query.Query;
 
 public interface KnowledgeDao extends Neo4jRepository<Knowledge,Long> {
     Knowledge findByName(String name);
 
+    @Query("MATCH (k:Knowledge) WHERE k.name CONTAINS $name AND (k.bindClassId = 0 OR k.bindClassId IN $courseIds) RETURN k")
+    List<Knowledge> findByNameAndBindClassId(String name, List<Long> courseIds);
+
 }

+ 35 - 0
src/main/java/com/seeckg/knowledgegraph_backend/dao/KnowledgeForumDao.java

@@ -0,0 +1,35 @@
+package com.seeckg.knowledgegraph_backend.dao;
+
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum;
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForumExample;
+import java.util.List;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+@Mapper
+@Repository
+public interface KnowledgeForumDao {
+    long countByExample(KnowledgeForumExample example);
+
+    int deleteByExample(KnowledgeForumExample example);
+
+    int deleteByPrimaryKey(Long id);
+
+    int insert(KnowledgeForum record);
+
+    int insertSelective(KnowledgeForum record);
+
+    List<KnowledgeForum> selectByExample(KnowledgeForumExample example);
+
+    KnowledgeForum selectByPrimaryKey(Long id);
+
+    int updateByExampleSelective(@Param("record") KnowledgeForum record, @Param("example") KnowledgeForumExample example);
+
+    int updateByExample(@Param("record") KnowledgeForum record, @Param("example") KnowledgeForumExample example);
+
+    int updateByPrimaryKeySelective(KnowledgeForum record);
+
+    int updateByPrimaryKey(KnowledgeForum record);
+}

+ 27 - 0
src/main/java/com/seeckg/knowledgegraph_backend/enums/KnowledgeForumType.java

@@ -0,0 +1,27 @@
+package com.seeckg.knowledgegraph_backend.enums;
+
+/**
+ * @author chenjiawei09 <chenjiawei09@kuaishou.com>
+ * Created on 2023-05-22
+ */
+public enum KnowledgeForumType {
+    QUESTION(1, "提问"),
+    ANSWER(2, "回答");
+
+    private int code;
+
+    private String desc;
+
+    KnowledgeForumType(int code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public int getCode() {
+        return this.code;
+    }
+
+    public String getDesc() {
+        return this.desc;
+    }
+}

+ 3 - 3
src/main/java/com/seeckg/knowledgegraph_backend/enums/ReturnCode.java

@@ -5,9 +5,9 @@ package com.seeckg.knowledgegraph_backend.enums;
  * Created on 2023-05-19
  */
 public enum ReturnCode {
-    PARAM_ERROR(1, "参数错误"),
-    SERVER_ERROR(2, "系统错误"),
-    INVALID_USER(3, "用户无权限");
+    PARAM_ERROR(1001, "参数错误"),
+    SERVER_ERROR(1002, "系统错误"),
+    INVALID_USER(1003, "用户无权限");
 
     private int code;
 

+ 0 - 1
src/main/java/com/seeckg/knowledgegraph_backend/pojo/Knowledge.java

@@ -18,7 +18,6 @@ public class Knowledge {
     @Id
     @GeneratedValue
     private Long id;
-
     /**
      * 绑定的课程id,0代表全局知识点
      */

+ 56 - 0
src/main/java/com/seeckg/knowledgegraph_backend/pojo/KnowledgeForum.java

@@ -0,0 +1,56 @@
+package com.seeckg.knowledgegraph_backend.pojo;
+
+import java.io.Serializable;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * knowledge_forum
+ * @author 
+ */
+@Data
+@Builder
+public class KnowledgeForum implements Serializable {
+    /**
+     * 主键id
+     */
+    private Long id;
+
+    /**
+     * 内容
+     */
+    private String context;
+
+    /**
+     * 创建用户id
+     */
+    private Long creatorId;
+
+    /**
+     * 类别
+     */
+    private Integer type;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+
+    /**
+     * 关联的知识点id
+     */
+    private Long knowledgeId;
+
+    /**
+     * 上级讨论id
+     */
+    private Long preForumId;
+
+    private static final long serialVersionUID = 1L;
+}

+ 721 - 0
src/main/java/com/seeckg/knowledgegraph_backend/pojo/KnowledgeForumExample.java

@@ -0,0 +1,721 @@
+package com.seeckg.knowledgegraph_backend.pojo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class KnowledgeForumExample {
+    protected String orderByClause;
+
+    protected boolean distinct;
+
+    protected List<Criteria> oredCriteria;
+
+    private Integer limit;
+
+    private Long offset;
+
+    private Boolean forUpdate;
+
+    public KnowledgeForumExample() {
+        oredCriteria = new ArrayList<>();
+    }
+
+    public void setOrderByClause(String orderByClause) {
+        this.orderByClause = orderByClause;
+    }
+
+    public String getOrderByClause() {
+        return orderByClause;
+    }
+
+    public void setDistinct(boolean distinct) {
+        this.distinct = distinct;
+    }
+
+    public boolean isDistinct() {
+        return distinct;
+    }
+
+    public List<Criteria> getOredCriteria() {
+        return oredCriteria;
+    }
+
+    public void or(Criteria criteria) {
+        oredCriteria.add(criteria);
+    }
+
+    public Criteria or() {
+        Criteria criteria = createCriteriaInternal();
+        oredCriteria.add(criteria);
+        return criteria;
+    }
+
+    public Criteria createCriteria() {
+        Criteria criteria = createCriteriaInternal();
+        if (oredCriteria.size() == 0) {
+            oredCriteria.add(criteria);
+        }
+        return criteria;
+    }
+
+    protected Criteria createCriteriaInternal() {
+        Criteria criteria = new Criteria();
+        return criteria;
+    }
+
+    public void clear() {
+        oredCriteria.clear();
+        orderByClause = null;
+        distinct = false;
+    }
+
+    public void setLimit(Integer limit) {
+        this.limit = limit;
+    }
+
+    public Integer getLimit() {
+        return limit;
+    }
+
+    public void setOffset(Long offset) {
+        this.offset = offset;
+    }
+
+    public Long getOffset() {
+        return offset;
+    }
+
+    public void setForUpdate(Boolean forUpdate) {
+        this.forUpdate = forUpdate;
+    }
+
+    public Boolean getForUpdate() {
+        return forUpdate;
+    }
+
+    protected abstract static class GeneratedCriteria {
+        protected List<Criterion> criteria;
+
+        protected GeneratedCriteria() {
+            super();
+            criteria = new ArrayList<>();
+        }
+
+        public boolean isValid() {
+            return criteria.size() > 0;
+        }
+
+        public List<Criterion> getAllCriteria() {
+            return criteria;
+        }
+
+        public List<Criterion> getCriteria() {
+            return criteria;
+        }
+
+        protected void addCriterion(String condition) {
+            if (condition == null) {
+                throw new RuntimeException("Value for condition cannot be null");
+            }
+            criteria.add(new Criterion(condition));
+        }
+
+        protected void addCriterion(String condition, Object value, String property) {
+            if (value == null) {
+                throw new RuntimeException("Value for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value));
+        }
+
+        protected void addCriterion(String condition, Object value1, Object value2, String property) {
+            if (value1 == null || value2 == null) {
+                throw new RuntimeException("Between values for " + property + " cannot be null");
+            }
+            criteria.add(new Criterion(condition, value1, value2));
+        }
+
+        public Criteria andIdIsNull() {
+            addCriterion("id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIsNotNull() {
+            addCriterion("id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdEqualTo(Long value) {
+            addCriterion("id =", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotEqualTo(Long value) {
+            addCriterion("id <>", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThan(Long value) {
+            addCriterion("id >", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("id >=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThan(Long value) {
+            addCriterion("id <", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdLessThanOrEqualTo(Long value) {
+            addCriterion("id <=", value, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdIn(List<Long> values) {
+            addCriterion("id in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotIn(List<Long> values) {
+            addCriterion("id not in", values, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdBetween(Long value1, Long value2) {
+            addCriterion("id between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andIdNotBetween(Long value1, Long value2) {
+            addCriterion("id not between", value1, value2, "id");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextIsNull() {
+            addCriterion("context is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextIsNotNull() {
+            addCriterion("context is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextEqualTo(String value) {
+            addCriterion("context =", value, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextNotEqualTo(String value) {
+            addCriterion("context <>", value, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextGreaterThan(String value) {
+            addCriterion("context >", value, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextGreaterThanOrEqualTo(String value) {
+            addCriterion("context >=", value, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextLessThan(String value) {
+            addCriterion("context <", value, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextLessThanOrEqualTo(String value) {
+            addCriterion("context <=", value, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextLike(String value) {
+            addCriterion("context like", value, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextNotLike(String value) {
+            addCriterion("context not like", value, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextIn(List<String> values) {
+            addCriterion("context in", values, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextNotIn(List<String> values) {
+            addCriterion("context not in", values, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextBetween(String value1, String value2) {
+            addCriterion("context between", value1, value2, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andContextNotBetween(String value1, String value2) {
+            addCriterion("context not between", value1, value2, "context");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdIsNull() {
+            addCriterion("creator_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdIsNotNull() {
+            addCriterion("creator_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdEqualTo(Long value) {
+            addCriterion("creator_id =", value, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdNotEqualTo(Long value) {
+            addCriterion("creator_id <>", value, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdGreaterThan(Long value) {
+            addCriterion("creator_id >", value, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("creator_id >=", value, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdLessThan(Long value) {
+            addCriterion("creator_id <", value, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdLessThanOrEqualTo(Long value) {
+            addCriterion("creator_id <=", value, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdIn(List<Long> values) {
+            addCriterion("creator_id in", values, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdNotIn(List<Long> values) {
+            addCriterion("creator_id not in", values, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdBetween(Long value1, Long value2) {
+            addCriterion("creator_id between", value1, value2, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreatorIdNotBetween(Long value1, Long value2) {
+            addCriterion("creator_id not between", value1, value2, "creatorId");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeIsNull() {
+            addCriterion("`type` is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeIsNotNull() {
+            addCriterion("`type` is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeEqualTo(Byte value) {
+            addCriterion("`type` =", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeNotEqualTo(Byte value) {
+            addCriterion("`type` <>", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeGreaterThan(Byte value) {
+            addCriterion("`type` >", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeGreaterThanOrEqualTo(Byte value) {
+            addCriterion("`type` >=", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeLessThan(Byte value) {
+            addCriterion("`type` <", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeLessThanOrEqualTo(Byte value) {
+            addCriterion("`type` <=", value, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeIn(List<Byte> values) {
+            addCriterion("`type` in", values, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeNotIn(List<Byte> values) {
+            addCriterion("`type` not in", values, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeBetween(Byte value1, Byte value2) {
+            addCriterion("`type` between", value1, value2, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andTypeNotBetween(Byte value1, Byte value2) {
+            addCriterion("`type` not between", value1, value2, "type");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIsNull() {
+            addCriterion("create_time is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIsNotNull() {
+            addCriterion("create_time is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeEqualTo(Long value) {
+            addCriterion("create_time =", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotEqualTo(Long value) {
+            addCriterion("create_time <>", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeGreaterThan(Long value) {
+            addCriterion("create_time >", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeGreaterThanOrEqualTo(Long value) {
+            addCriterion("create_time >=", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeLessThan(Long value) {
+            addCriterion("create_time <", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeLessThanOrEqualTo(Long value) {
+            addCriterion("create_time <=", value, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeIn(List<Long> values) {
+            addCriterion("create_time in", values, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotIn(List<Long> values) {
+            addCriterion("create_time not in", values, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeBetween(Long value1, Long value2) {
+            addCriterion("create_time between", value1, value2, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andCreateTimeNotBetween(Long value1, Long value2) {
+            addCriterion("create_time not between", value1, value2, "createTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIsNull() {
+            addCriterion("update_time is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIsNotNull() {
+            addCriterion("update_time is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeEqualTo(Long value) {
+            addCriterion("update_time =", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotEqualTo(Long value) {
+            addCriterion("update_time <>", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeGreaterThan(Long value) {
+            addCriterion("update_time >", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeGreaterThanOrEqualTo(Long value) {
+            addCriterion("update_time >=", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeLessThan(Long value) {
+            addCriterion("update_time <", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeLessThanOrEqualTo(Long value) {
+            addCriterion("update_time <=", value, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeIn(List<Long> values) {
+            addCriterion("update_time in", values, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotIn(List<Long> values) {
+            addCriterion("update_time not in", values, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeBetween(Long value1, Long value2) {
+            addCriterion("update_time between", value1, value2, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andUpdateTimeNotBetween(Long value1, Long value2) {
+            addCriterion("update_time not between", value1, value2, "updateTime");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdIsNull() {
+            addCriterion("knowledge_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdIsNotNull() {
+            addCriterion("knowledge_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdEqualTo(Long value) {
+            addCriterion("knowledge_id =", value, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdNotEqualTo(Long value) {
+            addCriterion("knowledge_id <>", value, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdGreaterThan(Long value) {
+            addCriterion("knowledge_id >", value, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("knowledge_id >=", value, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdLessThan(Long value) {
+            addCriterion("knowledge_id <", value, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdLessThanOrEqualTo(Long value) {
+            addCriterion("knowledge_id <=", value, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdIn(List<Long> values) {
+            addCriterion("knowledge_id in", values, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdNotIn(List<Long> values) {
+            addCriterion("knowledge_id not in", values, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdBetween(Long value1, Long value2) {
+            addCriterion("knowledge_id between", value1, value2, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andKnowledgeIdNotBetween(Long value1, Long value2) {
+            addCriterion("knowledge_id not between", value1, value2, "knowledgeId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdIsNull() {
+            addCriterion("pre_forum_id is null");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdIsNotNull() {
+            addCriterion("pre_forum_id is not null");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdEqualTo(Long value) {
+            addCriterion("pre_forum_id =", value, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdNotEqualTo(Long value) {
+            addCriterion("pre_forum_id <>", value, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdGreaterThan(Long value) {
+            addCriterion("pre_forum_id >", value, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdGreaterThanOrEqualTo(Long value) {
+            addCriterion("pre_forum_id >=", value, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdLessThan(Long value) {
+            addCriterion("pre_forum_id <", value, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdLessThanOrEqualTo(Long value) {
+            addCriterion("pre_forum_id <=", value, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdIn(List<Long> values) {
+            addCriterion("pre_forum_id in", values, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdNotIn(List<Long> values) {
+            addCriterion("pre_forum_id not in", values, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdBetween(Long value1, Long value2) {
+            addCriterion("pre_forum_id between", value1, value2, "preForumId");
+            return (Criteria) this;
+        }
+
+        public Criteria andPreForumIdNotBetween(Long value1, Long value2) {
+            addCriterion("pre_forum_id not between", value1, value2, "preForumId");
+            return (Criteria) this;
+        }
+    }
+
+    /**
+     */
+    public static class Criteria extends GeneratedCriteria {
+        protected Criteria() {
+            super();
+        }
+    }
+
+    public static class Criterion {
+        private String condition;
+
+        private Object value;
+
+        private Object secondValue;
+
+        private boolean noValue;
+
+        private boolean singleValue;
+
+        private boolean betweenValue;
+
+        private boolean listValue;
+
+        private String typeHandler;
+
+        public String getCondition() {
+            return condition;
+        }
+
+        public Object getValue() {
+            return value;
+        }
+
+        public Object getSecondValue() {
+            return secondValue;
+        }
+
+        public boolean isNoValue() {
+            return noValue;
+        }
+
+        public boolean isSingleValue() {
+            return singleValue;
+        }
+
+        public boolean isBetweenValue() {
+            return betweenValue;
+        }
+
+        public boolean isListValue() {
+            return listValue;
+        }
+
+        public String getTypeHandler() {
+            return typeHandler;
+        }
+
+        protected Criterion(String condition) {
+            super();
+            this.condition = condition;
+            this.typeHandler = null;
+            this.noValue = true;
+        }
+
+        protected Criterion(String condition, Object value, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.typeHandler = typeHandler;
+            if (value instanceof List<?>) {
+                this.listValue = true;
+            } else {
+                this.singleValue = true;
+            }
+        }
+
+        protected Criterion(String condition, Object value) {
+            this(condition, value, null);
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
+            super();
+            this.condition = condition;
+            this.value = value;
+            this.secondValue = secondValue;
+            this.typeHandler = typeHandler;
+            this.betweenValue = true;
+        }
+
+        protected Criterion(String condition, Object value, Object secondValue) {
+            this(condition, value, secondValue, null);
+        }
+    }
+}

+ 53 - 0
src/main/java/com/seeckg/knowledgegraph_backend/pojo/KnowledgeForumVO.java

@@ -0,0 +1,53 @@
+package com.seeckg.knowledgegraph_backend.pojo;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * @author chenjiawei09 <chenjiawei09@kuaishou.com>
+ * Created on 2023-05-22
+ */
+@Data
+@Builder
+public class KnowledgeForumVO {
+    /**
+     * 主键id
+     */
+    private Long id;
+
+    /**
+     * 内容
+     */
+    private String context;
+
+    /**
+     * 创建用户id
+     */
+    private Long creatorId;
+
+    /**
+     * 类别
+     */
+    private Integer type;
+
+    /**
+     * 创建时间
+     */
+    private Long createTime;
+
+    /**
+     * 更新时间
+     */
+    private Long updateTime;
+
+    /**
+     * 关联的知识点id
+     */
+    private Long knowledgeId;
+
+    /**
+     * 上级讨论id
+     */
+    private Long preForumId;
+
+}

+ 9 - 1
src/main/java/com/seeckg/knowledgegraph_backend/remote/SeeCoderRemoteService.java

@@ -23,7 +23,15 @@ public class SeeCoderRemoteService {
         return new CourseVO();
     }
 
-    public List<CourseVO> getCourseByUserId(long userId){
+    public List<CourseVO> getCourseByUserId(long userId) {
+        return new ArrayList<>();
+    }
+
+    public boolean checkCourseSelection(long userId, long courseId) {
+        return true;
+    }
+
+    public List<CourseVO> getCourses(long userId) {
         return new ArrayList<>();
     }
 }

+ 195 - 0
src/main/java/com/seeckg/knowledgegraph_backend/service/FormService.java

@@ -0,0 +1,195 @@
+package com.seeckg.knowledgegraph_backend.service;
+
+import java.util.List;
+import java.util.Objects;
+
+import javax.annotation.Resource;
+
+import org.springframework.stereotype.Service;
+
+import com.seeckg.knowledgegraph_backend.convert.KnowledgeConvert;
+import com.seeckg.knowledgegraph_backend.convert.KnowledgeForumConvert;
+import com.seeckg.knowledgegraph_backend.dao.KnowledgeDao;
+import com.seeckg.knowledgegraph_backend.dao.KnowledgeForumDao;
+import com.seeckg.knowledgegraph_backend.enums.KnowledgeForumType;
+import com.seeckg.knowledgegraph_backend.enums.ReturnCode;
+import com.seeckg.knowledgegraph_backend.enums.UserRole;
+import com.seeckg.knowledgegraph_backend.pojo.CourseVO;
+import com.seeckg.knowledgegraph_backend.pojo.Knowledge;
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum;
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForumExample;
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForumExample.Criteria;
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForumVO;
+import com.seeckg.knowledgegraph_backend.pojo.Response;
+import com.seeckg.knowledgegraph_backend.pojo.UserVO;
+import com.seeckg.knowledgegraph_backend.remote.SeeCoderRemoteService;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @author chenjiawei09 <chenjiawei09@kuaishou.com>
+ * Created on 2023-05-22
+ */
+@Service
+@Slf4j
+public class FormService {
+    @Resource
+    KnowledgeForumDao knowledgeForumDao;
+    @Resource
+    KnowledgeDao knowledgeDao;
+    @Resource
+    SeeCoderRemoteService seeCoderRemoteService;
+
+    public Response addKnowledgeForum(KnowledgeForumVO knowledgeForumVO) {
+        UserVO userVO = seeCoderRemoteService.getUserById(knowledgeForumVO.getCreatorId());
+
+        Knowledge knowledge = knowledgeDao.findById(knowledgeForumVO.getKnowledgeId()).orElse(null);
+        if (Objects.isNull(knowledge)) {
+            log.error("[FormService.addKnowledgeForum] 知识点信息错误,查无该知识点 knowledgeForumVO = {}",
+                    knowledgeForumVO);
+            return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
+        }
+
+        if (knowledge.getBindClassId() != 0L) {
+            // 水平权限校验
+            CourseVO courseVO = seeCoderRemoteService.getCourseById(knowledge.getBindClassId());
+            if (Objects.isNull(courseVO)) {
+                log.error("[FormService.addKnowledgeForum] 课程信息错误,查无该课程 knowledge = {}", knowledge);
+                return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "课程信息错误,查无该课程");
+            }
+            if (userVO.getRole().equals(UserRole.STUDENT) && !seeCoderRemoteService.checkCourseSelection(
+                    knowledgeForumVO.getCreatorId(), courseVO.getId())) {
+                log.error("[FormService.addKnowledgeForum] 课程信息错误,用户无权限 knowledgeVO = {}", knowledge);
+                return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
+            } else if (userVO.getRole().equals(UserRole.TEACHER) && (
+                    !Objects.equals(courseVO.getTeacherId(), knowledgeForumVO.getCreatorId())
+                            || knowledgeForumVO.getType()
+                            .equals(KnowledgeForumType.QUESTION.getCode()))) {
+                log.error("[FormService.addKnowledgeForum] 用户无权限 knowledgeVO = {}", knowledge);
+                return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
+            }
+        }
+
+        // 上级讨论校验
+        if (knowledgeForumVO.getType().equals(KnowledgeForumType.ANSWER.getCode())) {
+            if (knowledgeForumVO.getPreForumId().equals(0L) || Objects.isNull(knowledgeForumDao.selectByPrimaryKey(
+                    knowledgeForumVO.getPreForumId()))) {
+                log.error("[FormService.addKnowledgeForum] 提问不存在 knowledgeForumVO = {}", knowledgeForumVO);
+                return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "提问不存在");
+            }
+        }
+
+        knowledgeForumVO.setCreateTime(System.currentTimeMillis());
+        knowledgeForumVO.setUpdateTime(System.currentTimeMillis());
+        KnowledgeForum knowledgeForum = KnowledgeForumConvert.convert(knowledgeForumVO);
+        int res = knowledgeForumDao.insertSelective(knowledgeForum);
+        if (res < 0) {
+            log.error("[FormService.addKnowledgeForum] 插入失败 knowledgeForum = {}", knowledgeForum);
+            return Response.buildFailed(ReturnCode.SERVER_ERROR.getCode(), ReturnCode.SERVER_ERROR.getDesc());
+        }
+        return Response.buildSuccess();
+    }
+
+    public Response deleteKnowledgeForum(long knowledgeForumId, long userId) {
+
+        KnowledgeForum knowledgeForum = knowledgeForumDao.selectByPrimaryKey(knowledgeForumId);
+        UserVO userVO = seeCoderRemoteService.getUserById(userId);
+        // 水平权限校验
+        if (userId != knowledgeForum.getCreatorId()) {
+            log.error("[FormService.deleteKnowledgeForum] 用户无权限 knowledgeForum = {},userVO = {}",
+                    knowledgeForum, userVO);
+            return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
+        }
+        Knowledge knowledge = knowledgeDao.findById(knowledgeForum.getKnowledgeId()).orElse(null);
+        if (Objects.isNull(knowledge)) {
+            log.error("[FormService.deleteKnowledgeForum] 知识点信息错误,查无该知识点 knowledgeForum = {}",
+                    knowledgeForum);
+            return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
+        }
+
+        if (knowledge.getBindClassId() != 0L) {
+            // 垂直权限校验
+            CourseVO courseVO = seeCoderRemoteService.getCourseById(knowledge.getBindClassId());
+            if (Objects.isNull(courseVO)) {
+                log.error("[FormService.deleteKnowledgeForum] 课程信息错误,查无该课程 knowledge = {}", knowledge);
+                return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "课程信息错误,查无该课程");
+            }
+            if (userVO.getRole().equals(UserRole.STUDENT) && !seeCoderRemoteService.checkCourseSelection(
+                    knowledgeForum.getCreatorId(), courseVO.getId())) {
+                log.error("[FormService.deleteKnowledgeForum] 课程信息错误,用户无权限 knowledgeVO = {}", knowledge);
+                return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
+            } else if (userVO.getRole().equals(UserRole.TEACHER) && (
+                    !Objects.equals(courseVO.getTeacherId(), knowledgeForum.getCreatorId())
+                            || knowledgeForum.getType()
+                            .equals(KnowledgeForumType.QUESTION.getCode()))) {
+                log.error("[FormService.deleteKnowledgeForum] 用户无权限 knowledgeVO = {}", knowledge);
+                return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
+            }
+        }
+
+        // 上级讨论校验
+        if (knowledgeForum.getType().equals(KnowledgeForumType.ANSWER.getCode())) {
+            if (knowledgeForum.getPreForumId().equals(0L) || Objects.isNull(knowledgeForumDao.selectByPrimaryKey(
+                    knowledgeForum.getPreForumId()))) {
+                log.error("[FormService.deleteKnowledgeForum] 提问不存在 knowledgeForumVO = {}", knowledgeForum);
+                return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "提问不存在");
+            }
+        }
+
+        deleteForum(knowledgeForumId);
+        return Response.buildSuccess();
+    }
+
+    private void deleteForum(long knowledgeForumId) {
+        if (Objects.isNull(knowledgeForumDao.selectByPrimaryKey(knowledgeForumId))) {
+            return;
+        }
+        knowledgeForumDao.deleteByPrimaryKey(knowledgeForumId);
+        KnowledgeForumExample example = new KnowledgeForumExample();
+        Criteria criteria = example.createCriteria();
+        criteria.andPreForumIdEqualTo(knowledgeForumId);
+        List<KnowledgeForum> childKnowledgeForum = knowledgeForumDao.selectByExample(example);
+        for (KnowledgeForum forum : childKnowledgeForum) {
+            knowledgeForumDao.deleteByPrimaryKey(forum.getId());
+            deleteForum(forum.getId());
+        }
+    }
+
+    public Response getKnowledgeForum(long knowledgeForumId, long userId) {
+
+        KnowledgeForum knowledgeForum = knowledgeForumDao.selectByPrimaryKey(knowledgeForumId);
+        if (Objects.isNull(knowledgeForum)) {
+            log.error("[FormService.getKnowledgeForum] 查无讨论 knowledgeForum = {}",
+                    knowledgeForum);
+            return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "查无讨论");
+        }
+        UserVO userVO = seeCoderRemoteService.getUserById(userId);
+        Knowledge knowledge = knowledgeDao.findById(knowledgeForum.getKnowledgeId()).orElse(null);
+        if (Objects.isNull(knowledge)) {
+            log.error("[FormService.getKnowledgeForum] 知识点信息错误,查无该知识点 knowledgeForum = {}",
+                    knowledgeForum);
+            return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
+        }
+
+        if (knowledge.getBindClassId() != 0L) {
+            // 垂直权限校验
+            CourseVO courseVO = seeCoderRemoteService.getCourseById(knowledge.getBindClassId());
+            if (Objects.isNull(courseVO)) {
+                log.error("[FormService.getKnowledgeForum] 课程信息错误,查无该课程 knowledge = {}", knowledge);
+                return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "课程信息错误,查无该课程");
+            }
+            if (userVO.getRole().equals(UserRole.STUDENT) && !seeCoderRemoteService.checkCourseSelection(
+                    knowledgeForum.getCreatorId(), courseVO.getId())) {
+                log.error("[FormService.getKnowledgeForum] 课程信息错误,用户无权限 knowledgeVO = {}", knowledge);
+                return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
+            } else if (userVO.getRole().equals(UserRole.TEACHER) && (
+                    !Objects.equals(courseVO.getTeacherId(), knowledgeForum.getCreatorId()))) {
+                log.error("[FormService.getKnowledgeForum] 用户无权限 knowledgeVO = {}", knowledge);
+                return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
+            }
+        }
+        
+        return Response.buildSuccess(knowledgeForum);
+    }
+
+}

+ 65 - 54
src/main/java/com/seeckg/knowledgegraph_backend/service/KnowledgeService.java

@@ -1,6 +1,7 @@
 package com.seeckg.knowledgegraph_backend.service;
 
 import java.util.*;
+import java.util.stream.Collectors;
 
 import javax.annotation.Resource;
 
@@ -13,6 +14,7 @@ import com.seeckg.knowledgegraph_backend.pojo.*;
 import com.seeckg.knowledgegraph_backend.remote.SeeCoderRemoteService;
 
 import com.seeckg.knowledgegraph_backend.util.GetKGReturnFormat;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
@@ -69,15 +71,16 @@ public class KnowledgeService {
                 log.error("[KnowledgeService.addKnowledge] 课程信息错误,用户无权限 knowledgeVO = {}", knowledgeVO);
                 return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
             }
-        }  else {
+        } else {
             if (knowledgeVO.getCreatorId() != userId) {
-                log.error("[KnowledgeService.addKnowledge] 用户无权限 knowledgeVO = {},userVO = {}", knowledgeVO, userVO);
+                log.error("[KnowledgeService.addKnowledge] 用户无权限 knowledgeVO = {},userVO = {}", knowledgeVO,
+                        userVO);
                 return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
             }
         }
 
         Knowledge knowledgeOld = knowledgeDao.findById(knowledgeVO.getId()).orElse(null);
-        if (Objects.isNull(knowledgeOld)){
+        if (Objects.isNull(knowledgeOld)) {
             log.error("[KnowledgeService.addKnowledge] 查无该知识点 knowledgeVO = {}", knowledgeVO);
             return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
         }
@@ -87,7 +90,7 @@ public class KnowledgeService {
         return Response.buildSuccess();
     }
 
-    public Response deleteKnowledge(long knowledgeId , long userId) {
+    public Response deleteKnowledge(long knowledgeId, long userId) {
         UserVO userVO = seeCoderRemoteService.getUserById(userId);
         // 垂直权限校验
         if (!userVO.getRole().equals(UserRole.TEACHER)) {
@@ -96,8 +99,8 @@ public class KnowledgeService {
         }
 
         Knowledge knowledgeOld = knowledgeDao.findById(knowledgeId).orElse(null);
-        if (Objects.isNull(knowledgeOld)){
-            log.error("[KnowledgeService.addKnowledge] 查无该知识点 knowledgeId  = {}", knowledgeId );
+        if (Objects.isNull(knowledgeOld)) {
+            log.error("[KnowledgeService.addKnowledge] 查无该知识点 knowledgeId  = {}", knowledgeId);
             return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
         }
 
@@ -114,7 +117,8 @@ public class KnowledgeService {
             }
         } else {
             if (knowledgeOld.getCreatorId() != userId) {
-                log.error("[KnowledgeService.addKnowledge] 用户无权限 knowledgeId = {},userVO = {}", knowledgeId, userVO);
+                log.error("[KnowledgeService.addKnowledge] 用户无权限 knowledgeId = {},userVO = {}", knowledgeId,
+                        userVO);
                 return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
             }
         }
@@ -123,6 +127,11 @@ public class KnowledgeService {
         return Response.buildSuccess();
     }
 
+    public List<Knowledge> searchKnowledge(String keyword, long userId) {
+        List<CourseVO> courseVOS = seeCoderRemoteService.getCourses(userId);
+        return knowledgeDao.findByNameAndBindClassId(keyword,
+                courseVOS.stream().map(CourseVO::getId).collect(Collectors.toList()));
+    }
 
     public Knowledge findByName(String name) {
         return knowledgeDao.findByName(name);
@@ -133,37 +142,37 @@ public class KnowledgeService {
     }
 
     /**
-     *
      * 添加关系
      */
-    public Response addRelationship(long startKnowledgeId, long endKnowledgeId, knowledgeType type ,long userId) {
+    public Response addRelationship(long startKnowledgeId, long endKnowledgeId, knowledgeType type, long userId) {
         UserVO userVO = seeCoderRemoteService.getUserById(userId);
         // 垂直权限校验
         if (!userVO.getRole().equals(UserRole.TEACHER)) {
-            log.error("[KnowledgeService.addRelationship] 用户无权限 knowledgeId = {} and {} ,userVO = {}", startKnowledgeId, endKnowledgeId,userVO);
+            log.error("[KnowledgeService.addRelationship] 用户无权限 knowledgeId = {} and {} ,userVO = {}",
+                    startKnowledgeId, endKnowledgeId, userVO);
             return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
         }
 
         Knowledge knowledgeStart = knowledgeDao.findById(startKnowledgeId).orElse(null);
-        if (Objects.isNull(knowledgeStart)){
-            log.error("[KnowledgeService.addRelationship] 查无该知识点 knowledgeId  = {}", startKnowledgeId );
+        if (Objects.isNull(knowledgeStart)) {
+            log.error("[KnowledgeService.addRelationship] 查无该知识点 knowledgeId  = {}", startKnowledgeId);
             return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
         }
         Knowledge knowledgeEnd = knowledgeDao.findById(endKnowledgeId).orElse(null);
-        if (Objects.isNull(knowledgeEnd)){
-            log.error("[KnowledgeService.addRelationship] 查无该知识点 knowledgeId  = {}", endKnowledgeId );
+        if (Objects.isNull(knowledgeEnd)) {
+            log.error("[KnowledgeService.addRelationship] 查无该知识点 knowledgeId  = {}", endKnowledgeId);
             return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
         }
 
         try {
-            if(type==knowledgeType.DEFINE){
+            if (type == knowledgeType.DEFINE) {
                 knowledgeStart.defineRelationship(knowledgeEnd);
-            }else if (type==knowledgeType.SIMILAR){
+            } else if (type == knowledgeType.SIMILAR) {
                 knowledgeStart.similarRelationship(knowledgeEnd);
-            }else {
+            } else {
                 knowledgeStart.subRelationship(knowledgeEnd);
             }
-        }catch (Exception e){
+        } catch (Exception e) {
             return Response.buildFailed(ReturnCode.SERVER_ERROR.getCode(), e.getMessage());
         }
 
@@ -171,52 +180,53 @@ public class KnowledgeService {
     }
 
 
-    public Response deleteRelationship(long startKnowledgeId, long endKnowledgeId, knowledgeType type ,long userId){
+    public Response deleteRelationship(long startKnowledgeId, long endKnowledgeId, knowledgeType type, long userId) {
         UserVO userVO = seeCoderRemoteService.getUserById(userId);
         if (!userVO.getRole().equals(UserRole.TEACHER)) {
-            log.error("[KnowledgeService.deleteRelationship] 用户无权限 knowledgeId = {} and {} ,userVO = {}", startKnowledgeId, endKnowledgeId,userVO);
+            log.error("[KnowledgeService.deleteRelationship] 用户无权限 knowledgeId = {} and {} ,userVO = {}",
+                    startKnowledgeId, endKnowledgeId, userVO);
             return Response.buildFailed(ReturnCode.INVALID_USER.getCode(), ReturnCode.INVALID_USER.getDesc());
         }
 
 
         Knowledge knowledgeStart = knowledgeDao.findById(startKnowledgeId).orElse(null);
-        if (Objects.isNull(knowledgeStart)){
-            log.error("[KnowledgeService.deleteRelationship] 查无该知识点 knowledgeId  = {}", startKnowledgeId );
+        if (Objects.isNull(knowledgeStart)) {
+            log.error("[KnowledgeService.deleteRelationship] 查无该知识点 knowledgeId  = {}", startKnowledgeId);
             return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
         }
 
         Knowledge knowledgeEnd = knowledgeDao.findById(endKnowledgeId).orElse(null);
-        if (Objects.isNull(knowledgeEnd)){
-            log.error("[KnowledgeService.deleteRelationship] 查无该知识点 knowledgeId  = {}", endKnowledgeId );
+        if (Objects.isNull(knowledgeEnd)) {
+            log.error("[KnowledgeService.deleteRelationship] 查无该知识点 knowledgeId  = {}", endKnowledgeId);
             return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "知识点信息错误,查无该知识点");
         }
 
-        try{
-            if(type==knowledgeType.SIMILAR){
-                Set<Knowledge> similar=knowledgeStart.getSimilar();
-                if(similar.contains(knowledgeEnd)){
+        try {
+            if (type == knowledgeType.SIMILAR) {
+                Set<Knowledge> similar = knowledgeStart.getSimilar();
+                if (similar.contains(knowledgeEnd)) {
                     //正常运行
                     similar.remove(knowledgeEnd);
-                }else{
+                } else {
                     return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "关系不存在!");
                 }
-            }else  if(type==knowledgeType.DEFINE){
-                Set<Knowledge> define=knowledgeStart.getDefine();
-                if(define.contains(knowledgeEnd)){
+            } else if (type == knowledgeType.DEFINE) {
+                Set<Knowledge> define = knowledgeStart.getDefine();
+                if (define.contains(knowledgeEnd)) {
                     define.remove(knowledgeEnd);
-                }else {
-                    return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(),"关系不存在!" );
+                } else {
+                    return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "关系不存在!");
                 }
-            }else {
-                Set<Knowledge> sub=knowledgeStart.getSub();
-                if(sub.contains(knowledgeEnd)){
+            } else {
+                Set<Knowledge> sub = knowledgeStart.getSub();
+                if (sub.contains(knowledgeEnd)) {
                     sub.remove(knowledgeEnd);
-                }else {
+                } else {
                     return Response.buildFailed(ReturnCode.PARAM_ERROR.getCode(), "关系不存在!");
                 }
             }
-        }catch (Exception e){
-            return  Response.buildFailed(ReturnCode.SERVER_ERROR.getCode(), e.getMessage());
+        } catch (Exception e) {
+            return Response.buildFailed(ReturnCode.SERVER_ERROR.getCode(), e.getMessage());
         }
         return Response.buildSuccess();
     }
@@ -224,27 +234,28 @@ public class KnowledgeService {
     /**
      * 获取图谱所有节点和边
      * 返回的数据格式是{list:nodes,list:edges}
+     *
      * @return 包含上述数据的Response
      */
-    public Response getAllNodesAndEdges(){
-        List<Knowledge> allNodes=knowledgeDao.findAll();
-        List<Relationship> relationList=new ArrayList<>();
-        for(int i=0;i<allNodes.size();i++){
-            Set<Knowledge> define=allNodes.get(i).getDefine();
-            for(Knowledge knowledge:define){
-                relationList.add(new Relationship(i,allNodes.indexOf(knowledge),"define"));
+    public Response getAllNodesAndEdges() {
+        List<Knowledge> allNodes = knowledgeDao.findAll();
+        List<Relationship> relationList = new ArrayList<>();
+        for (int i = 0; i < allNodes.size(); i++) {
+            Set<Knowledge> define = allNodes.get(i).getDefine();
+            for (Knowledge knowledge : define) {
+                relationList.add(new Relationship(i, allNodes.indexOf(knowledge), "define"));
             }
-            Set<Knowledge> similar=allNodes.get(i).getSimilar();
-            for(Knowledge knowledge:similar){
-                relationList.add(new Relationship(i,allNodes.indexOf(knowledge),"similar"));
+            Set<Knowledge> similar = allNodes.get(i).getSimilar();
+            for (Knowledge knowledge : similar) {
+                relationList.add(new Relationship(i, allNodes.indexOf(knowledge), "similar"));
             }
 
-            Set<Knowledge> sub=allNodes.get(i).getSub();
-            for (Knowledge knowledge:sub){
-                relationList.add(new Relationship(i,allNodes.indexOf(knowledge),"sub"));
+            Set<Knowledge> sub = allNodes.get(i).getSub();
+            for (Knowledge knowledge : sub) {
+                relationList.add(new Relationship(i, allNodes.indexOf(knowledge), "sub"));
             }
         }
-        GetKGReturnFormat getKGReturnFormat=new GetKGReturnFormat(allNodes,relationList);
+        GetKGReturnFormat getKGReturnFormat = new GetKGReturnFormat(allNodes, relationList);
         return Response.buildSuccess(getKGReturnFormat);
     }
 

+ 7 - 0
src/main/resources/application.properties

@@ -3,3 +3,10 @@ server.port=8080
 spring.neo4j.uri=bolt://124.221.29.13/:7687
 spring.neo4j.authentication.username=neo4j
 spring.neo4j.authentication.password=seecoder
+# \u6570\u636E\u5E93\u8FDE\u63A5\u914D\u7F6E
+spring.datasource.url=jdbc:mysql://@knowlege-db.seec.seecoder.cn:3306/knowledge
+spring.datasource.username=root
+spring.datasource.password=NJU67mysql
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+mybatis.mapper-locations=classpath:mapper/*.xml
+

+ 263 - 0
src/main/resources/mapper/KnowledgeForumDao.xml

@@ -0,0 +1,263 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.seeckg.knowledgegraph_backend.dao.KnowledgeForumDao">
+  <resultMap id="BaseResultMap" type="com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum">
+    <id column="id" jdbcType="BIGINT" property="id" />
+    <result column="context" jdbcType="VARCHAR" property="context" />
+    <result column="creator_id" jdbcType="BIGINT" property="creatorId" />
+    <result column="type" jdbcType="TINYINT" property="type" />
+    <result column="create_time" jdbcType="BIGINT" property="createTime" />
+    <result column="update_time" jdbcType="BIGINT" property="updateTime" />
+    <result column="knowledge_id" jdbcType="BIGINT" property="knowledgeId" />
+    <result column="pre_forum_id" jdbcType="BIGINT" property="preForumId" />
+  </resultMap>
+  <sql id="Example_Where_Clause">
+    <where>
+      <foreach collection="oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Update_By_Example_Where_Clause">
+    <where>
+      <foreach collection="example.oredCriteria" item="criteria" separator="or">
+        <if test="criteria.valid">
+          <trim prefix="(" prefixOverrides="and" suffix=")">
+            <foreach collection="criteria.criteria" item="criterion">
+              <choose>
+                <when test="criterion.noValue">
+                  and ${criterion.condition}
+                </when>
+                <when test="criterion.singleValue">
+                  and ${criterion.condition} #{criterion.value}
+                </when>
+                <when test="criterion.betweenValue">
+                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
+                </when>
+                <when test="criterion.listValue">
+                  and ${criterion.condition}
+                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
+                    #{listItem}
+                  </foreach>
+                </when>
+              </choose>
+            </foreach>
+          </trim>
+        </if>
+      </foreach>
+    </where>
+  </sql>
+  <sql id="Base_Column_List">
+    id, context, creator_id, `type`, create_time, update_time, knowledge_id, pre_forum_id
+  </sql>
+  <select id="selectByExample" parameterType="com.seeckg.knowledgegraph_backend.pojo.KnowledgeForumExample" resultMap="BaseResultMap">
+    select
+    <if test="distinct">
+      distinct
+    </if>
+    <include refid="Base_Column_List" />
+    from knowledge_forum
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+    <if test="orderByClause != null">
+      order by ${orderByClause}
+    </if>
+    <if test="limit != null">
+      <if test="offset != null">
+        limit ${offset}, ${limit}
+      </if>
+      <if test="offset == null">
+        limit ${limit}
+      </if>
+    </if>
+    <if test="forUpdate != null and forUpdate == true">
+      for update
+    </if>
+  </select>
+  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
+    select 
+    <include refid="Base_Column_List" />
+    from knowledge_forum
+    where id = #{id,jdbcType=BIGINT}
+  </select>
+  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
+    delete from knowledge_forum
+    where id = #{id,jdbcType=BIGINT}
+  </delete>
+  <delete id="deleteByExample" parameterType="com.seeckg.knowledgegraph_backend.pojo.KnowledgeForumExample">
+    delete from knowledge_forum
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </delete>
+  <insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum" useGeneratedKeys="true">
+    insert into knowledge_forum (context, creator_id, `type`, 
+      create_time, update_time, knowledge_id, 
+      pre_forum_id)
+    values (#{context,jdbcType=VARCHAR}, #{creatorId,jdbcType=BIGINT}, #{type,jdbcType=TINYINT}, 
+      #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{knowledgeId,jdbcType=BIGINT}, 
+      #{preForumId,jdbcType=BIGINT})
+  </insert>
+  <insert id="insertSelective" keyColumn="id" keyProperty="id" parameterType="com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum" useGeneratedKeys="true">
+    insert into knowledge_forum
+    <trim prefix="(" suffix=")" suffixOverrides=",">
+      <if test="context != null">
+        context,
+      </if>
+      <if test="creatorId != null">
+        creator_id,
+      </if>
+      <if test="type != null">
+        `type`,
+      </if>
+      <if test="createTime != null">
+        create_time,
+      </if>
+      <if test="updateTime != null">
+        update_time,
+      </if>
+      <if test="knowledgeId != null">
+        knowledge_id,
+      </if>
+      <if test="preForumId != null">
+        pre_forum_id,
+      </if>
+    </trim>
+    <trim prefix="values (" suffix=")" suffixOverrides=",">
+      <if test="context != null">
+        #{context,jdbcType=VARCHAR},
+      </if>
+      <if test="creatorId != null">
+        #{creatorId,jdbcType=BIGINT},
+      </if>
+      <if test="type != null">
+        #{type,jdbcType=TINYINT},
+      </if>
+      <if test="createTime != null">
+        #{createTime,jdbcType=BIGINT},
+      </if>
+      <if test="updateTime != null">
+        #{updateTime,jdbcType=BIGINT},
+      </if>
+      <if test="knowledgeId != null">
+        #{knowledgeId,jdbcType=BIGINT},
+      </if>
+      <if test="preForumId != null">
+        #{preForumId,jdbcType=BIGINT},
+      </if>
+    </trim>
+  </insert>
+  <select id="countByExample" parameterType="com.seeckg.knowledgegraph_backend.pojo.KnowledgeForumExample" resultType="java.lang.Long">
+    select count(*) from knowledge_forum
+    <if test="_parameter != null">
+      <include refid="Example_Where_Clause" />
+    </if>
+  </select>
+  <update id="updateByExampleSelective" parameterType="map">
+    update knowledge_forum
+    <set>
+      <if test="record.id != null">
+        id = #{record.id,jdbcType=BIGINT},
+      </if>
+      <if test="record.context != null">
+        context = #{record.context,jdbcType=VARCHAR},
+      </if>
+      <if test="record.creatorId != null">
+        creator_id = #{record.creatorId,jdbcType=BIGINT},
+      </if>
+      <if test="record.type != null">
+        `type` = #{record.type,jdbcType=TINYINT},
+      </if>
+      <if test="record.createTime != null">
+        create_time = #{record.createTime,jdbcType=BIGINT},
+      </if>
+      <if test="record.updateTime != null">
+        update_time = #{record.updateTime,jdbcType=BIGINT},
+      </if>
+      <if test="record.knowledgeId != null">
+        knowledge_id = #{record.knowledgeId,jdbcType=BIGINT},
+      </if>
+      <if test="record.preForumId != null">
+        pre_forum_id = #{record.preForumId,jdbcType=BIGINT},
+      </if>
+    </set>
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByExample" parameterType="map">
+    update knowledge_forum
+    set id = #{record.id,jdbcType=BIGINT},
+      context = #{record.context,jdbcType=VARCHAR},
+      creator_id = #{record.creatorId,jdbcType=BIGINT},
+      `type` = #{record.type,jdbcType=TINYINT},
+      create_time = #{record.createTime,jdbcType=BIGINT},
+      update_time = #{record.updateTime,jdbcType=BIGINT},
+      knowledge_id = #{record.knowledgeId,jdbcType=BIGINT},
+      pre_forum_id = #{record.preForumId,jdbcType=BIGINT}
+    <if test="_parameter != null">
+      <include refid="Update_By_Example_Where_Clause" />
+    </if>
+  </update>
+  <update id="updateByPrimaryKeySelective" parameterType="com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum">
+    update knowledge_forum
+    <set>
+      <if test="context != null">
+        context = #{context,jdbcType=VARCHAR},
+      </if>
+      <if test="creatorId != null">
+        creator_id = #{creatorId,jdbcType=BIGINT},
+      </if>
+      <if test="type != null">
+        `type` = #{type,jdbcType=TINYINT},
+      </if>
+      <if test="createTime != null">
+        create_time = #{createTime,jdbcType=BIGINT},
+      </if>
+      <if test="updateTime != null">
+        update_time = #{updateTime,jdbcType=BIGINT},
+      </if>
+      <if test="knowledgeId != null">
+        knowledge_id = #{knowledgeId,jdbcType=BIGINT},
+      </if>
+      <if test="preForumId != null">
+        pre_forum_id = #{preForumId,jdbcType=BIGINT},
+      </if>
+    </set>
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+  <update id="updateByPrimaryKey" parameterType="com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum">
+    update knowledge_forum
+    set context = #{context,jdbcType=VARCHAR},
+      creator_id = #{creatorId,jdbcType=BIGINT},
+      `type` = #{type,jdbcType=TINYINT},
+      create_time = #{createTime,jdbcType=BIGINT},
+      update_time = #{updateTime,jdbcType=BIGINT},
+      knowledge_id = #{knowledgeId,jdbcType=BIGINT},
+      pre_forum_id = #{preForumId,jdbcType=BIGINT}
+    where id = #{id,jdbcType=BIGINT}
+  </update>
+</mapper>

+ 34 - 0
src/test/java/com/seeckg/knowledgegraph_backend/KnowledgeForumTest.java

@@ -0,0 +1,34 @@
+package com.seeckg.knowledgegraph_backend;
+
+import javax.annotation.Resource;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import com.seeckg.knowledgegraph_backend.dao.KnowledgeForumDao;
+import com.seeckg.knowledgegraph_backend.enums.KnowledgeForumType;
+import com.seeckg.knowledgegraph_backend.pojo.KnowledgeForum;
+
+/**
+ * @author chenjiawei09 <chenjiawei09@kuaishou.com>
+ * Created on 2023-05-22
+ */
+@SpringBootTest
+public class KnowledgeForumTest {
+    @Resource
+    KnowledgeForumDao knowledgeForumDao;
+
+    @Test
+    void testInsert() {
+        KnowledgeForum knowledgeForum = KnowledgeForum.builder()
+                .knowledgeId(111L)
+                .creatorId(1L)
+                .createTime(System.currentTimeMillis())
+                .updateTime(System.currentTimeMillis())
+                .type(KnowledgeForumType.QUESTION.getCode())
+                .preForumId(0L)
+                .context("con")
+                .build();
+        knowledgeForumDao.insertSelective(knowledgeForum);
+    }
+}