diff --git a/pom.xml b/pom.xml index 03aec4c..3952c49 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,12 @@ spring-cloud-azure-starter-data-cosmos + + cn.hutool + hutool-all + 5.8.16 + + org.projectlombok lombok diff --git a/src/main/java/cn/teammodel/common/PK.java b/src/main/java/cn/teammodel/common/PK.java new file mode 100644 index 0000000..b269ee8 --- /dev/null +++ b/src/main/java/cn/teammodel/common/PK.java @@ -0,0 +1,13 @@ +package cn.teammodel.common; + +import com.azure.cosmos.models.PartitionKey; + +/** + * 分区键常量 + * @author winter + * @create 2023-11-22 15:31 + */ +public interface PK { + PartitionKey PK_SCHOOL = new PartitionKey("School"); + +} diff --git a/src/main/java/cn/teammodel/controller/EvaluationController.java b/src/main/java/cn/teammodel/controller/EvaluationController.java new file mode 100644 index 0000000..af5a405 --- /dev/null +++ b/src/main/java/cn/teammodel/controller/EvaluationController.java @@ -0,0 +1,30 @@ +package cn.teammodel.controller; + +import cn.teammodel.common.R; +import cn.teammodel.model.dto.GetEvaluateTreeDto; +import cn.teammodel.model.entity.EvaluationTreeNode; +import cn.teammodel.service.EvaluationService; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @author winter + * @create 2023-11-22 15:10 + */ +@RestController +@RequestMapping("/public/evaluate") +public class EvaluationController { + @Resource + private EvaluationService evaluationService; + + @PostMapping("getTrees") + public R> getEvaluateTree(@RequestBody GetEvaluateTreeDto getEvaluateTreeDto) { + List tree = evaluationService.getTree(getEvaluateTreeDto); + return R.success(tree); + } +} diff --git a/src/main/java/cn/teammodel/controller/HelloController.java b/src/main/java/cn/teammodel/controller/HelloController.java index e0cac8a..3e901f1 100644 --- a/src/main/java/cn/teammodel/controller/HelloController.java +++ b/src/main/java/cn/teammodel/controller/HelloController.java @@ -1,7 +1,7 @@ package cn.teammodel.controller; import cn.teammodel.common.R; -import cn.teammodel.dao.EvaluationTreeRepository; +import cn.teammodel.dao.EvaluationRepository; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; @@ -15,7 +15,7 @@ import javax.annotation.Resource; public class HelloController { @Resource - private EvaluationTreeRepository evaluationTreeRepository; + private EvaluationRepository evaluationRepository; @GetMapping("hello") @PreAuthorize("@ss.hasRole('admin')") diff --git a/src/main/java/cn/teammodel/dao/EvaluationTreeRepository.java b/src/main/java/cn/teammodel/dao/EvaluationRepository.java similarity index 65% rename from src/main/java/cn/teammodel/dao/EvaluationTreeRepository.java rename to src/main/java/cn/teammodel/dao/EvaluationRepository.java index 3a96a5d..fd50dfe 100644 --- a/src/main/java/cn/teammodel/dao/EvaluationTreeRepository.java +++ b/src/main/java/cn/teammodel/dao/EvaluationRepository.java @@ -1,9 +1,8 @@ package cn.teammodel.dao; -import cn.teammodel.model.entity.EvaluationTree; +import cn.teammodel.model.entity.Evaluation; +import com.azure.cosmos.models.PartitionKey; import com.azure.spring.data.cosmos.repository.CosmosRepository; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; /** @@ -17,6 +16,9 @@ import org.springframework.stereotype.Repository; * List findByLastname(String lastname, Pageable pageable);
*/ @Repository -public interface EvaluationTreeRepository extends CosmosRepository { - Page findById(String lastname, Pageable pageable); +public interface EvaluationRepository extends CosmosRepository { + Evaluation findBySchoolId(String schoolId, PartitionKey partitionKey); + Evaluation findBySchoolIdAndPeriodId(String schoolId,String periodId, PartitionKey partitionKey); + + } diff --git a/src/main/java/cn/teammodel/model/dto/GetEvaluateTreeDto.java b/src/main/java/cn/teammodel/model/dto/GetEvaluateTreeDto.java new file mode 100644 index 0000000..133e6dc --- /dev/null +++ b/src/main/java/cn/teammodel/model/dto/GetEvaluateTreeDto.java @@ -0,0 +1,14 @@ +package cn.teammodel.model.dto; + +import lombok.Data; + +/** + * @author winter + * @create 2023-11-22 15:21 + */ +@Data +public class GetEvaluateTreeDto { + // todo: 校验非空 + String schoolId; + String periodId; +} diff --git a/src/main/java/cn/teammodel/model/entity/EvaluationTree.java b/src/main/java/cn/teammodel/model/entity/Evaluation.java similarity index 73% rename from src/main/java/cn/teammodel/model/entity/EvaluationTree.java rename to src/main/java/cn/teammodel/model/entity/Evaluation.java index bd196e7..1547dd1 100644 --- a/src/main/java/cn/teammodel/model/entity/EvaluationTree.java +++ b/src/main/java/cn/teammodel/model/entity/Evaluation.java @@ -17,20 +17,24 @@ import java.util.List; @Container(containerName = "School") @Data @ToString -public class EvaluationTree { +public class Evaluation { @Id @GeneratedValue - String id; + private String id; /** * 分区键: evaluation */ @PartitionKey - String code; + private String code; + /** + * 学校 Id + */ + private String schoolId; /** * 学段 id */ - String campusId; + private String periodId; - List nodes; + private List nodes; } diff --git a/src/main/java/cn/teammodel/model/entity/EvaluationTreeNode.java b/src/main/java/cn/teammodel/model/entity/EvaluationTreeNode.java index 94e5e75..7539d96 100644 --- a/src/main/java/cn/teammodel/model/entity/EvaluationTreeNode.java +++ b/src/main/java/cn/teammodel/model/entity/EvaluationTreeNode.java @@ -1,7 +1,7 @@ package cn.teammodel.model.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; -import org.springframework.data.annotation.Transient; import java.util.List; @@ -10,7 +10,20 @@ public class EvaluationTreeNode { String id; String pid; String name; + String logo; + String creator; + /** + * 排序 + */ + String order; + /** + * 分值 + */ Integer score; - @Transient + /** + * 是否表扬? 默认 true + */ + boolean isPraise = true; + @JsonIgnore List children; } diff --git a/src/main/java/cn/teammodel/service/EvaluationService.java b/src/main/java/cn/teammodel/service/EvaluationService.java new file mode 100644 index 0000000..8769380 --- /dev/null +++ b/src/main/java/cn/teammodel/service/EvaluationService.java @@ -0,0 +1,30 @@ +package cn.teammodel.service; + +import cn.teammodel.model.dto.GetEvaluateTreeDto; +import cn.teammodel.model.entity.EvaluationTreeNode; + +import java.util.List; + +/** + * @author winter + * @create 2023-11-20 17:46 + */ +public interface EvaluationService { + List getTree(GetEvaluateTreeDto getEvaluateTreeDto); + + /** + * 递归构建树 + */ + List buildTree(List nodes); + + /** + * 递归扁平化树 + * @param trees: 树的列表 + * @param nodes: 扁平化后的节点列表 + * @return: void + * @author: winter + * @date: 2023/11/21 16:40 + * @description: + */ + void flattenTree(List trees, List nodes); +} diff --git a/src/main/java/cn/teammodel/service/EvaluationTreeService.java b/src/main/java/cn/teammodel/service/EvaluationTreeService.java deleted file mode 100644 index 8caf3bd..0000000 --- a/src/main/java/cn/teammodel/service/EvaluationTreeService.java +++ /dev/null @@ -1,13 +0,0 @@ -package cn.teammodel.service; - -import cn.teammodel.model.entity.EvaluationTreeNode; - -import java.util.List; - -/** - * @author winter - * @create 2023-11-20 17:46 - */ -public interface EvaluationTreeService { - List buildTree(List nodes); -} diff --git a/src/main/java/cn/teammodel/service/impl/EvaluationTreeServiceImpl.java b/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java similarity index 53% rename from src/main/java/cn/teammodel/service/impl/EvaluationTreeServiceImpl.java rename to src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java index 0da4f17..2f96eca 100644 --- a/src/main/java/cn/teammodel/service/impl/EvaluationTreeServiceImpl.java +++ b/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java @@ -1,9 +1,16 @@ package cn.teammodel.service.impl; +import cn.teammodel.common.PK; +import cn.teammodel.dao.EvaluationRepository; +import cn.teammodel.model.dto.GetEvaluateTreeDto; +import cn.teammodel.model.entity.Evaluation; import cn.teammodel.model.entity.EvaluationTreeNode; -import cn.teammodel.service.EvaluationTreeService; +import cn.teammodel.service.EvaluationService; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import javax.annotation.Resource; import java.util.ArrayList; import java.util.List; @@ -11,7 +18,23 @@ import java.util.List; * @author winter * @create 2023-11-20 17:47 */ -public class EvaluationTreeServiceImpl implements EvaluationTreeService { +@Service +public class EvaluationServiceImpl implements EvaluationService { + @Resource + private EvaluationRepository evaluationRepository; + + @Override + public List getTree(GetEvaluateTreeDto getEvaluateTreeDto) { + String schoolId = getEvaluateTreeDto.getSchoolId(); + String periodId = getEvaluateTreeDto.getPeriodId(); + periodId = StringUtils.isEmpty(periodId) ? "default" : periodId; + + Evaluation evaluation = evaluationRepository.findBySchoolIdAndPeriodId(schoolId, periodId, PK.PK_SCHOOL); + List nodes = evaluation.getNodes(); + List trees = this.buildTree(nodes); + evaluation.setNodes(trees); + return trees; + } @Override public List buildTree(List nodes) { @@ -22,7 +45,6 @@ public class EvaluationTreeServiceImpl implements EvaluationTreeService { parents.add(node); } } - // 迭代构建孩子节点 for (EvaluationTreeNode parent : parents) { buildChildren(parent, nodes); @@ -30,6 +52,21 @@ public class EvaluationTreeServiceImpl implements EvaluationTreeService { return parents; } + @Override + public void flattenTree(List trees, List nodes) { + // 递归结束条件 + if (ObjectUtils.isEmpty(trees)) return; + + // 这里的每个 tree 都是组装好的树,区别于单个节点 + for (EvaluationTreeNode tree : trees) { + // 递归 + flattenTree(tree.getChildren(), nodes); + // 回溯时删除 children,添加进列表 + tree.setChildren(null); + nodes.add(tree); + } + } + /** * 递归的构建父亲节点的孩子,以及孩子的孩子 (理论支持无极树,但应该考虑是否增加递归深度) */ diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ec779ad..968fddf 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,7 +4,7 @@ spring: cosmos: endpoint: https://cdhabookdep-free.documents.azure.cn:443 database: TEAMModelOS - key: v07dMthUjNk8AbwI8698AXHPbXBaaADgtgdYf4sFGXohei6aD2doq6XV45sLMGpDtDDpENAnlGkEUBu9RaAhpg== + key: JTUVk92Gjsx17L0xqxn0X4wX2thDPMKiw4daeTyV1HzPb6JmBeHdtFY1MF1jdctW1ofgzqkDMFOtcqS46by31A== security: oauth2: diff --git a/src/test/java/cn/teammodel/TeamModelExtensionApplicationTests.java b/src/test/java/cn/teammodel/TeamModelExtensionApplicationTests.java index 5d58733..e0aa427 100644 --- a/src/test/java/cn/teammodel/TeamModelExtensionApplicationTests.java +++ b/src/test/java/cn/teammodel/TeamModelExtensionApplicationTests.java @@ -1,11 +1,13 @@ package cn.teammodel; -import cn.teammodel.dao.EvaluationTreeRepository; +import cn.hutool.json.JSONUtil; +import cn.teammodel.dao.EvaluationRepository; import cn.teammodel.dao.StudentRepository; import cn.teammodel.manager.DingAlertNotifier; -import cn.teammodel.model.entity.EvaluationTree; +import cn.teammodel.model.entity.Evaluation; import cn.teammodel.model.entity.EvaluationTreeNode; -import cn.teammodel.model.entity.Student; +import cn.teammodel.service.EvaluationService; +import cn.teammodel.service.impl.EvaluationServiceImpl; import com.azure.cosmos.models.PartitionKey; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -13,7 +15,6 @@ import org.springframework.boot.test.context.SpringBootTest; import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.UUID; @SpringBootTest @@ -25,7 +26,7 @@ class TeamModelExtensionApplicationTests { @Autowired StudentRepository studentRepository; @Autowired - private EvaluationTreeRepository evaluationTreeRepository; + private EvaluationRepository evaluationRepository; @Test void contextLoads() { @@ -34,9 +35,9 @@ class TeamModelExtensionApplicationTests { @Test public void testCrud() { - EvaluationTree evaluationTree = new EvaluationTree(); - evaluationTree.setCode("evaluation"); - evaluationTree.setCampusId("default"); + Evaluation evaluation = new Evaluation(); + evaluation.setCode("evaluation"); + evaluation.setPeriodId("default"); List nodes = new ArrayList<>(); // 1 @@ -62,16 +63,25 @@ class TeamModelExtensionApplicationTests { nodes.add(node); nodes.add(node1); nodes.add(node2); - evaluationTree.setNodes(nodes); + evaluation.setNodes(nodes); - EvaluationTree saved = evaluationTreeRepository.save(evaluationTree); + Evaluation saved = evaluationRepository.save(evaluation); System.out.println(saved); } @Test public void testSelect() { - Optional s = studentRepository.findById("24913", new PartitionKey("Base-hbcn")); - System.out.println(s.orElse(null)); + Evaluation saved = evaluationRepository.findBySchoolId("hbcn", new PartitionKey("evaluation")); + EvaluationService service = new EvaluationServiceImpl(); + System.out.println(JSONUtil.parse(service.buildTree(saved.getNodes())).toStringPretty()); + } + @Test + public void testUpdate() { + //EvaluationTree saved = evaluationTreeRepository.findBySchoolId("hbcn", new PartitionKey("evaluation")); + Evaluation saved = evaluationRepository.findBySchoolId("hbcn", new PartitionKey("evaluation")); + EvaluationService service = new EvaluationServiceImpl(); + System.out.println(JSONUtil.parse(service.buildTree(saved.getNodes())).toStringPretty()); + evaluationRepository.save(saved); } } diff --git a/src/test/java/cn/teammodel/TestWithoutSpring.java b/src/test/java/cn/teammodel/TestWithoutSpring.java index bfb67f3..3546d66 100644 --- a/src/test/java/cn/teammodel/TestWithoutSpring.java +++ b/src/test/java/cn/teammodel/TestWithoutSpring.java @@ -1,10 +1,9 @@ package cn.teammodel; -import cn.teammodel.common.R; -import cn.teammodel.model.entity.EvaluationTree; +import cn.hutool.json.JSONUtil; +import cn.teammodel.model.entity.Evaluation; import cn.teammodel.model.entity.EvaluationTreeNode; -import cn.teammodel.model.entity.User; -import cn.teammodel.service.impl.EvaluationTreeServiceImpl; +import cn.teammodel.service.impl.EvaluationServiceImpl; import com.dingtalk.api.DefaultDingTalkClient; import com.dingtalk.api.DingTalkClient; import com.dingtalk.api.request.OapiRobotSendRequest; @@ -88,12 +87,18 @@ public class TestWithoutSpring { } @Test public void testResult() { - EvaluationTreeServiceImpl service = new EvaluationTreeServiceImpl(); - EvaluationTree evaluationTree = new EvaluationTree(); - evaluationTree.setCode("evaluation"); - evaluationTree.setCampusId("default"); + EvaluationServiceImpl service = new EvaluationServiceImpl(); + Evaluation evaluation = new Evaluation(); + evaluation.setCode("evaluation"); + evaluation.setPeriodId("default"); List nodes = new ArrayList<>(); + String root2Id = UUID.randomUUID().toString(); + EvaluationTreeNode root1 = new EvaluationTreeNode(); + root1.setId(root2Id); + root1.setPid(null); + root1.setName("root1"); + root1.setScore(0); // 1 String rootId = UUID.randomUUID().toString(); EvaluationTreeNode node = new EvaluationTreeNode(); @@ -101,6 +106,8 @@ public class TestWithoutSpring { node.setPid(null); node.setName("root"); node.setScore(0); + + // 2 EvaluationTreeNode node1 = new EvaluationTreeNode(); String subId = UUID.randomUUID().toString(); @@ -115,11 +122,16 @@ public class TestWithoutSpring { node2.setName("child-2"); node2.setScore(0); nodes.add(node); + nodes.add(root1); nodes.add(node1); nodes.add(node2); - evaluationTree.setNodes(nodes); + evaluation.setNodes(nodes); List tree = service.buildTree(nodes); - System.out.println(tree); + System.out.println(JSONUtil.parse(service.buildTree(tree)).toStringPretty()); + + List nodeList = new ArrayList<>(); + service.flattenTree(tree, nodeList); + System.out.println(JSONUtil.parse(nodeList).toStringPretty()); } }