refactor: 将 evaluation 重构成 appraise

11111
winter 1 year ago
parent 5e06e8ed1e
commit 610c6d4e81

@ -7,4 +7,14 @@
- Azure OIDC(SSO) 迁移
- id-token(jwt) 验证迁移 (出现语言框架之间的签名算法规范问题,解决见: [输出复盘](https://juejin.cn/post/7300036605099163702))
- 钉钉告警: 异常通知
- 异常文件记录
- 异常文件记录
## 数据表规则:
### 教育评价树
分区键: `Appraise` , 表内 `schoolId` 区分学校, `periodId` 区分学区
### 教育评价项
> 学生每学期所有的评价项都在一个项中,按学校进行分区
分区键: `AppraiseItem-{学校id}`

@ -8,6 +8,9 @@ import com.azure.cosmos.models.PartitionKey;
* @create 2023-11-22 15:31
*/
public interface PK {
PartitionKey PK_EVALUATION = new PartitionKey("Evaluation");
/**
*
*/
PartitionKey PK_EVALUATION = new PartitionKey("Appraise");
}

@ -5,7 +5,7 @@ import cn.teammodel.model.dto.DeleteNodeDto;
import cn.teammodel.model.dto.GetEvaluateTreeDto;
import cn.teammodel.model.dto.InsertNodeDto;
import cn.teammodel.model.dto.UpdateNodeDto;
import cn.teammodel.model.entity.Evaluation;
import cn.teammodel.model.entity.Appraise;
import cn.teammodel.service.EvaluationService;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
@ -27,28 +27,28 @@ public class EvaluationController {
@PostMapping("getTrees")
@ApiOperation(value = "获取评价树", notes = "获取评价树")
public R<Evaluation> getEvaluateTree(@RequestBody GetEvaluateTreeDto getEvaluateTreeDto) {
Evaluation evaluation = evaluationService.getTree(getEvaluateTreeDto);
return R.success(evaluation);
public R<Appraise> getEvaluateTree(@RequestBody GetEvaluateTreeDto getEvaluateTreeDto) {
Appraise appraise = evaluationService.getTree(getEvaluateTreeDto);
return R.success(appraise);
}
@PostMapping("insertNode")
@ApiOperation(value = "新增评价树的节点")
public R<Evaluation> insertNode(@RequestBody InsertNodeDto insertNodeDto) {
Evaluation evaluation = evaluationService.insertNode(insertNodeDto);
return R.success(evaluation);
public R<Appraise> insertNode(@RequestBody InsertNodeDto insertNodeDto) {
Appraise appraise = evaluationService.insertNode(insertNodeDto);
return R.success(appraise);
}
@PostMapping("updateNode")
@ApiOperation(value = "更新评价树的节点", notes = "传递更新后的节点,而不是局部更新的值")
public R<Evaluation> updateTree(@RequestBody UpdateNodeDto updateNodeDto) {
Evaluation evaluation = evaluationService.updateNode(updateNodeDto);
return R.success(evaluation);
public R<Appraise> updateTree(@RequestBody UpdateNodeDto updateNodeDto) {
Appraise appraise = evaluationService.updateNode(updateNodeDto);
return R.success(appraise);
}
@PostMapping("deleteNode")
@ApiOperation(value = "删除评价树的节点")
public R<Evaluation> deleteNode(@RequestBody DeleteNodeDto deleteNodeDto) {
public R<Appraise> deleteNode(@RequestBody DeleteNodeDto deleteNodeDto) {
// todo: 注意删除子节点
Evaluation evaluation = evaluationService.deleteNode(deleteNodeDto);
return R.success(evaluation);
Appraise appraise = evaluationService.deleteNode(deleteNodeDto);
return R.success(appraise);
}
}

@ -1,6 +1,6 @@
package cn.teammodel.dao;
import cn.teammodel.model.entity.Evaluation;
import cn.teammodel.model.entity.Appraise;
import com.azure.cosmos.models.PartitionKey;
import com.azure.spring.data.cosmos.repository.CosmosRepository;
import org.springframework.stereotype.Repository;
@ -16,9 +16,9 @@ import org.springframework.stereotype.Repository;
* List<User> findByLastname(String lastname, Pageable pageable);<br/>
*/
@Repository
public interface EvaluationRepository extends CosmosRepository<Evaluation, String> {
Evaluation findBySchoolId(String schoolId, PartitionKey partitionKey);
Evaluation findBySchoolIdAndPeriodId(String schoolId,String periodId, PartitionKey partitionKey);
public interface EvaluationRepository extends CosmosRepository<Appraise, String> {
Appraise findBySchoolId(String schoolId, PartitionKey partitionKey);
Appraise findBySchoolIdAndPeriodId(String schoolId, String periodId, PartitionKey partitionKey);
}

@ -17,7 +17,7 @@ import java.util.List;
@Container(containerName = "School")
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Evaluation {
public class Appraise {
@Id
@GeneratedValue
private String id;
@ -35,6 +35,6 @@ public class Evaluation {
*/
private String periodId;
private List<EvaluationTreeNode> nodes;
private List<AppraiseTreeNode> nodes;
}

@ -10,7 +10,7 @@ import java.util.List;
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class EvaluationTreeNode {
public class AppraiseTreeNode {
String id;
String pid;
String name;
@ -33,5 +33,5 @@ public class EvaluationTreeNode {
@JsonProperty("isPraise")
boolean isPraise;
List<EvaluationTreeNode> children;
List<AppraiseTreeNode> children;
}

@ -4,8 +4,8 @@ import cn.teammodel.model.dto.DeleteNodeDto;
import cn.teammodel.model.dto.GetEvaluateTreeDto;
import cn.teammodel.model.dto.InsertNodeDto;
import cn.teammodel.model.dto.UpdateNodeDto;
import cn.teammodel.model.entity.Evaluation;
import cn.teammodel.model.entity.EvaluationTreeNode;
import cn.teammodel.model.entity.Appraise;
import cn.teammodel.model.entity.AppraiseTreeNode;
import java.util.List;
@ -14,12 +14,12 @@ import java.util.List;
* @create 2023-11-20 17:46
*/
public interface EvaluationService {
Evaluation getTree(GetEvaluateTreeDto getEvaluateTreeDto);
Appraise getTree(GetEvaluateTreeDto getEvaluateTreeDto);
/**
*
*/
Evaluation buildTree(Evaluation evaluation);
Appraise buildTree(Appraise appraise);
/**
*
@ -30,20 +30,20 @@ public interface EvaluationService {
* @date: 2023/11/21 16:40
* @description:
*/
void flattenTree(List<EvaluationTreeNode> trees, List<EvaluationTreeNode> nodes);
void flattenTree(List<AppraiseTreeNode> trees, List<AppraiseTreeNode> nodes);
/**
*
*/
Evaluation insertNode(InsertNodeDto insertNodeDto);
Appraise insertNode(InsertNodeDto insertNodeDto);
/**
*
*/
Evaluation updateNode(UpdateNodeDto updateNodeDto);
Appraise updateNode(UpdateNodeDto updateNodeDto);
/**
* ,
*/
Evaluation deleteNode(DeleteNodeDto deleteNodeDto);
Appraise deleteNode(DeleteNodeDto deleteNodeDto);
}

@ -9,8 +9,8 @@ import cn.teammodel.model.dto.DeleteNodeDto;
import cn.teammodel.model.dto.GetEvaluateTreeDto;
import cn.teammodel.model.dto.InsertNodeDto;
import cn.teammodel.model.dto.UpdateNodeDto;
import cn.teammodel.model.entity.Evaluation;
import cn.teammodel.model.entity.EvaluationTreeNode;
import cn.teammodel.model.entity.Appraise;
import cn.teammodel.model.entity.AppraiseTreeNode;
import cn.teammodel.model.entity.User;
import cn.teammodel.security.utils.SecurityUtils;
import cn.teammodel.service.EvaluationService;
@ -40,56 +40,56 @@ public class EvaluationServiceImpl implements EvaluationService {
* evaluation : , <br/>
* token schoolId
*/
private Evaluation findEvaluation(String periodId) {
private Appraise findEvaluation(String periodId) {
periodId = StringUtils.isEmpty(periodId) ? "default" : periodId;
User loginUser = SecurityUtils.getLoginUser();
String schoolId = loginUser.getSchoolId();
// 拿到要新增节点的原始数据
Evaluation evaluation = evaluationRepository.findBySchoolIdAndPeriodId(schoolId, periodId, PK.PK_EVALUATION);
if (evaluation == null) {
Appraise appraise = evaluationRepository.findBySchoolIdAndPeriodId(schoolId, periodId, PK.PK_EVALUATION);
if (appraise == null) {
throw new ServiceException(ErrorCode.PARAMS_ERROR.getCode(), "学校评价数据不存在");
}
return evaluation;
return appraise;
}
@Override
public Evaluation getTree(GetEvaluateTreeDto getEvaluateTreeDto) {
Evaluation evaluation = findEvaluation(getEvaluateTreeDto.getPeriodId());
public Appraise getTree(GetEvaluateTreeDto getEvaluateTreeDto) {
Appraise appraise = findEvaluation(getEvaluateTreeDto.getPeriodId());
return this.buildTree(evaluation);
return this.buildTree(appraise);
}
@Override
public Evaluation buildTree(Evaluation evaluation) {
if (evaluation == null) {
public Appraise buildTree(Appraise appraise) {
if (appraise == null) {
return null;
}
List<EvaluationTreeNode> nodes = evaluation.getNodes();
List<EvaluationTreeNode> parents = new ArrayList<>();
List<AppraiseTreeNode> nodes = appraise.getNodes();
List<AppraiseTreeNode> parents = new ArrayList<>();
// pid 为 null 或者 "" 则为 parents
for (EvaluationTreeNode node : nodes) {
for (AppraiseTreeNode node : nodes) {
if (StringUtils.isBlank(node.getPid())) {
parents.add(node);
}
}
// 迭代构建孩子节点
for (EvaluationTreeNode parent : parents) {
for (AppraiseTreeNode parent : parents) {
buildChildren(parent, nodes);
}
evaluation.setNodes(parents);
return evaluation;
appraise.setNodes(parents);
return appraise;
}
@Override
public void flattenTree(List<EvaluationTreeNode> trees, List<EvaluationTreeNode> nodes) {
public void flattenTree(List<AppraiseTreeNode> trees, List<AppraiseTreeNode> nodes) {
// 递归结束条件
if (ObjectUtils.isEmpty(trees)) return;
// 这里的每个 tree 都是组装好的树,区别于单个节点
for (EvaluationTreeNode tree : trees) {
for (AppraiseTreeNode tree : trees) {
// 递归
flattenTree(tree.getChildren(), nodes);
// 回溯时删除 children,添加进列表
@ -99,13 +99,13 @@ public class EvaluationServiceImpl implements EvaluationService {
}
@Override
public Evaluation insertNode(InsertNodeDto insertNodeDto) {
Evaluation evaluation = findEvaluation(insertNodeDto.getPeriodId());
public Appraise insertNode(InsertNodeDto insertNodeDto) {
Appraise appraise = findEvaluation(insertNodeDto.getPeriodId());
User loginUser = SecurityUtils.getLoginUser();
List<EvaluationTreeNode> originNodes = evaluation.getNodes();
List<AppraiseTreeNode> originNodes = appraise.getNodes();
// 拷贝数据到新节点
EvaluationTreeNode newNode = new EvaluationTreeNode();
AppraiseTreeNode newNode = new AppraiseTreeNode();
BeanUtils.copyProperties(insertNodeDto, newNode);
String newNodePid = newNode.getPid();
@ -123,17 +123,17 @@ public class EvaluationServiceImpl implements EvaluationService {
newNode.setCreateTime(LocalDateTime.now());
originNodes.add(newNode);
return buildTree(evaluationRepository.save(evaluation));
return buildTree(evaluationRepository.save(appraise));
}
@Override
public Evaluation updateNode(UpdateNodeDto updateNodeDto) {
public Appraise updateNode(UpdateNodeDto updateNodeDto) {
String updateNodeId = updateNodeDto.getId();
Evaluation evaluation = findEvaluation(updateNodeDto.getPeriodId());
List<EvaluationTreeNode> originNodes = evaluation.getNodes();
Appraise appraise = findEvaluation(updateNodeDto.getPeriodId());
List<AppraiseTreeNode> originNodes = appraise.getNodes();
// 每个节点都有 id, 直接校验是否合法
EvaluationTreeNode updateNode = originNodes.stream()
AppraiseTreeNode updateNode = originNodes.stream()
.filter(item -> updateNodeId.equals(item.getId()))
.findFirst()
.orElseThrow(() -> new ServiceException(ErrorCode.PARAMS_ERROR.getCode(), "更新节点不存在"));
@ -144,18 +144,18 @@ public class EvaluationServiceImpl implements EvaluationService {
updateNode.setPraise(updateNodeDto.isPraise());
// todo: 为新节点赋值必须参数 (id, creator), 可不可以添加默认值 order ?
return buildTree(evaluationRepository.save(evaluation));
return buildTree(evaluationRepository.save(appraise));
}
@Override
public Evaluation deleteNode(DeleteNodeDto deleteNodeDto) {
public Appraise deleteNode(DeleteNodeDto deleteNodeDto) {
// 删除指定节点,可能是(一级,二级,三级),设计一个通用的
Evaluation evaluation = findEvaluation(deleteNodeDto.getPeriodId());
List<EvaluationTreeNode> nodes = evaluation.getNodes();
List<EvaluationTreeNode> nodesToDelete = new ArrayList<>();
Appraise appraise = findEvaluation(deleteNodeDto.getPeriodId());
List<AppraiseTreeNode> nodes = appraise.getNodes();
List<AppraiseTreeNode> nodesToDelete = new ArrayList<>();
// 迭代器安全删除
for (EvaluationTreeNode node : nodes) {
for (AppraiseTreeNode node : nodes) {
if (node.getId().equals(deleteNodeDto.getId())) {
// 删除当前节点
nodesToDelete.add(node);
@ -165,14 +165,14 @@ public class EvaluationServiceImpl implements EvaluationService {
}
nodes.removeAll(nodesToDelete);
return buildTree(evaluationRepository.save(evaluation));
return buildTree(evaluationRepository.save(appraise));
}
/**
* id id ()
*/
private void collectNodesToDelete(String id, List<EvaluationTreeNode> nodes, List<EvaluationTreeNode> nodesToDelete) {
for (EvaluationTreeNode node : nodes) {
private void collectNodesToDelete(String id, List<AppraiseTreeNode> nodes, List<AppraiseTreeNode> nodesToDelete) {
for (AppraiseTreeNode node : nodes) {
if (id.equals(node.getPid())) {
// 收集
nodesToDelete.add(node);
@ -186,12 +186,12 @@ public class EvaluationServiceImpl implements EvaluationService {
/**
* , (,)
*/
private void buildChildren(EvaluationTreeNode parent, List<EvaluationTreeNode> nodes) {
List<EvaluationTreeNode> children = getChildren(parent, nodes);
private void buildChildren(AppraiseTreeNode parent, List<AppraiseTreeNode> nodes) {
List<AppraiseTreeNode> children = getChildren(parent, nodes);
if (children.size() == 0) return;
parent.setChildren(children);
for (EvaluationTreeNode child : children) {
for (AppraiseTreeNode child : children) {
// 如果子节点还有孩子的话,就继续递归构建
if (getChildren(child, nodes).size() > 0) {
buildChildren(child, nodes);
@ -204,9 +204,9 @@ public class EvaluationServiceImpl implements EvaluationService {
/**
*
*/
private List<EvaluationTreeNode> getChildren(EvaluationTreeNode parent, List<EvaluationTreeNode> nodes) {
List<EvaluationTreeNode> children = new ArrayList<>();
for (EvaluationTreeNode node : nodes) {
private List<AppraiseTreeNode> getChildren(AppraiseTreeNode parent, List<AppraiseTreeNode> nodes) {
List<AppraiseTreeNode> children = new ArrayList<>();
for (AppraiseTreeNode node : nodes) {
if (StringUtils.isNotBlank(node.getPid()) && node.getPid().equals(parent.getId())) {
children.add(node);
}

@ -3,8 +3,8 @@ package cn.teammodel;
import cn.teammodel.dao.EvaluationRepository;
import cn.teammodel.dao.StudentRepository;
import cn.teammodel.manager.DingAlertNotifier;
import cn.teammodel.model.entity.Evaluation;
import cn.teammodel.model.entity.EvaluationTreeNode;
import cn.teammodel.model.entity.Appraise;
import cn.teammodel.model.entity.AppraiseTreeNode;
import cn.teammodel.service.EvaluationService;
import cn.teammodel.service.impl.EvaluationServiceImpl;
import com.azure.cosmos.models.PartitionKey;
@ -38,27 +38,27 @@ class TeamModelExtensionApplicationTests {
@Test
public void testCrud() {
Evaluation evaluation = new Evaluation();
evaluation.setCode("evaluation");
evaluation.setPeriodId("default");
List<EvaluationTreeNode> nodes = new ArrayList<>();
Appraise appraise = new Appraise();
appraise.setCode("evaluation");
appraise.setPeriodId("default");
List<AppraiseTreeNode> nodes = new ArrayList<>();
// 1
String rootId = UUID.randomUUID().toString();
EvaluationTreeNode node = new EvaluationTreeNode();
AppraiseTreeNode node = new AppraiseTreeNode();
node.setId(rootId);
node.setPid(null);
node.setName("root");
node.setScore(0);
// 2
EvaluationTreeNode node1 = new EvaluationTreeNode();
AppraiseTreeNode node1 = new AppraiseTreeNode();
String subId = UUID.randomUUID().toString();
node1.setId(subId);
node1.setPid(rootId);
node1.setName("child-1");
node1.setScore(0);
// 3
EvaluationTreeNode node2 = new EvaluationTreeNode();
AppraiseTreeNode node2 = new AppraiseTreeNode();
node2.setId(UUID.randomUUID().toString());
node2.setPid(subId);
node2.setName("child-2");
@ -66,22 +66,22 @@ class TeamModelExtensionApplicationTests {
nodes.add(node);
nodes.add(node1);
nodes.add(node2);
evaluation.setNodes(nodes);
appraise.setNodes(nodes);
Evaluation saved = cosmosTemplate.insert(evaluation, null);
Appraise saved = cosmosTemplate.insert(appraise, null);
System.out.println(saved);
}
@Test
public void testSelect() {
Evaluation saved = evaluationRepository.findBySchoolId("hbcn", new PartitionKey("evaluation"));
Appraise 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"));
Appraise saved = evaluationRepository.findBySchoolId("hbcn", new PartitionKey("evaluation"));
EvaluationService service = new EvaluationServiceImpl();
//System.out.println(JSONUtil.parse(service.buildTree(saved.getNodes())).toStringPretty());
evaluationRepository.save(saved);

@ -1,7 +1,7 @@
package cn.teammodel;
import cn.teammodel.model.entity.Evaluation;
import cn.teammodel.model.entity.EvaluationTreeNode;
import cn.teammodel.model.entity.Appraise;
import cn.teammodel.model.entity.AppraiseTreeNode;
import cn.teammodel.service.impl.EvaluationServiceImpl;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
@ -88,20 +88,20 @@ public class TestWithoutSpring {
@Test
public void testResult() {
EvaluationServiceImpl service = new EvaluationServiceImpl();
Evaluation evaluation = new Evaluation();
evaluation.setCode("evaluation");
evaluation.setPeriodId("default");
List<EvaluationTreeNode> nodes = new ArrayList<>();
Appraise appraise = new Appraise();
appraise.setCode("evaluation");
appraise.setPeriodId("default");
List<AppraiseTreeNode> nodes = new ArrayList<>();
String root2Id = UUID.randomUUID().toString();
EvaluationTreeNode root1 = new EvaluationTreeNode();
AppraiseTreeNode root1 = new AppraiseTreeNode();
root1.setId(root2Id);
root1.setPid(null);
root1.setName("root1");
root1.setScore(0);
// 1
String rootId = UUID.randomUUID().toString();
EvaluationTreeNode node = new EvaluationTreeNode();
AppraiseTreeNode node = new AppraiseTreeNode();
node.setId(rootId);
node.setPid(null);
node.setName("root");
@ -109,14 +109,14 @@ public class TestWithoutSpring {
// 2
EvaluationTreeNode node1 = new EvaluationTreeNode();
AppraiseTreeNode node1 = new AppraiseTreeNode();
String subId = UUID.randomUUID().toString();
node1.setId(subId);
node1.setPid(rootId);
node1.setName("child-1");
node1.setScore(0);
// 3
EvaluationTreeNode node2 = new EvaluationTreeNode();
AppraiseTreeNode node2 = new AppraiseTreeNode();
node2.setId(UUID.randomUUID().toString());
node2.setPid(subId);
node2.setName("child-2");
@ -125,7 +125,7 @@ public class TestWithoutSpring {
nodes.add(root1);
nodes.add(node1);
nodes.add(node2);
evaluation.setNodes(nodes);
appraise.setNodes(nodes);
//List<EvaluationTreeNode> tree = service.buildTree(nodes);
//System.out.println(JSONUtil.parse(service.buildTree(tree)).toStringPretty());

Loading…
Cancel
Save