下面提到的CheckList大致是这样一个对象,如下图。有点像是组织架构,或者是有父子关系的树形结构。
/**
* 递归:根据父节点id获取该父节点下所有的CheckList,不包括该节点
*/
public List<CheckList> getChildByParentId(String parentId, List<CheckList> res, List<CheckList> allCheckList) {
List<CheckList> checkLists = allCheckList.stream().filter(checkList -> parentId.equals(checkList.getParentId())).collect(Collectors.toList());
if (isEmpty(checkLists)) {
return res;
}
for (CheckList checkList : checkLists) {
res.add(checkList);
allCheckList.remove(checkList);
getChildByParentId(checkList.getId(), res, allCheckList);
}
return res;
}
/**
* 递归:根据子节点的parentId获取该子节点上的所有父节点,包括该节点
*/
public List<CheckList> getParentByChildId(String childId, List<CheckList> res){
CheckList checkList = checkListCacheService.getByCheckListId(childId);
if(checkList.getParentId() == null){
res.add(checkList);
return res;
}
res.add(checkList);
return getParentByChildId(checkList.getParentId(), res);
}
下面这个方法的大致需求是:根据传入参数tasks复制一份任务(具体要复制哪些字段看业务),任务id要生成新的id,最后返回新旧任务id映射的Map。因为在调用该方法的地方有判断tasks是否为null,所以这里就不在进行判断了,即tasks一定有值。
/**
* 递归:复制任务
*/
private Map<String, String> createTasks(String creator, List<TaskProtocol.Query.Output> tasks, Map<String, String> res) {
TaskProtocol.Query.Output output = tasks.get(0);
List<TaskProtocol.Query.Output> outputs = tasks.stream() // 获取以该任务为父亲的所有子任务
.filter(o -> output.getId().equals(o.getParentTaskId()))
.collect(Collectors.toList());
Task task = copy(output, Task.class)
.set_id(UuidGenerator.generate())
.setTeamId(creator)
.setProjectId(null)
.setCreator(output.getCreator().getStaffId())
.setCreatorName(output.getCreator().getName())
.setMilestoneId(null) // 不能影响里程碑的计算
.setCheckLists(null)
.setForceCommit(false);
taskDAO.insertOne(task);
tasks.remove(output); // 已经生成任务的移除
res.put(output.getId(), task.get_id()); // 保存旧的任务Id 与 新的任务Id 映射
if (isNotEmpty(outputs)) { // 修改子任务的ParentTaskId为父任务的新id
for (TaskProtocol.Query.Output output1 : outputs) {
output1.setParentTaskId(task.get_id());
}
}
if (tasks.size() == 0) {
return res;
} else {
return createTasks(creator, tasks, res);
}
}