diff --git a/pom.xml b/pom.xml index 83b13af..a2e48c1 100644 --- a/pom.xml +++ b/pom.xml @@ -25,7 +25,11 @@ 1.5.2 - + + com.alibaba + easyexcel + 3.0.5 + @@ -102,10 +106,22 @@ 3.5.5 + + + + + + + + + + + + com.baomidou - mybatis-plus-spring-boot3-starter - 3.5.5 + dynamic-datasource-spring-boot3-starter + 4.2.0 diff --git a/src/main/java/com/sa/zentao/dao/ZtStoryDTO.java b/src/main/java/com/sa/zentao/dao/ZtStoryDTO.java index c580507..903495b 100644 --- a/src/main/java/com/sa/zentao/dao/ZtStoryDTO.java +++ b/src/main/java/com/sa/zentao/dao/ZtStoryDTO.java @@ -233,6 +233,8 @@ public class ZtStoryDTO implements Serializable { private Integer execution; + private List executions; + private Boolean psFlag; private String executionName; diff --git a/src/main/java/com/sa/zentao/entity/ZtProjectstory.java b/src/main/java/com/sa/zentao/entity/ZtProjectstory.java index e6e495d..9f955d8 100644 --- a/src/main/java/com/sa/zentao/entity/ZtProjectstory.java +++ b/src/main/java/com/sa/zentao/entity/ZtProjectstory.java @@ -24,7 +24,6 @@ public class ZtProjectstory implements Serializable { private Integer product; - private Integer execution; private Integer branch; @@ -34,6 +33,9 @@ public class ZtProjectstory implements Serializable { @TableField("`order`") private Integer order; - + //execution + @TableField("`type`") + private String type; +// private Integer execution; } diff --git a/src/main/java/com/sa/zentao/enums/ProjectTypeEnums.java b/src/main/java/com/sa/zentao/enums/ProjectTypeEnums.java new file mode 100644 index 0000000..c2e0bd2 --- /dev/null +++ b/src/main/java/com/sa/zentao/enums/ProjectTypeEnums.java @@ -0,0 +1,41 @@ +package com.sa.zentao.enums; + +import com.baomidou.mybatisplus.annotation.EnumValue; + +public enum ProjectTypeEnums { + + //产品集 + program(1,"program"), + //项目 + project(2, "project"), + //执行 + execution(3, "execution"), + ; + + @EnumValue + private int code; + private String value; + + private ProjectTypeEnums(int code, String value) { + this.code = code; + this.value = value; + } + + public int getCode() { + return this.code; + } + + public String getValue() { + return this.value; + } + + public static ProjectTypeEnums transferType(Integer code){ + ProjectTypeEnums[] values = values(); + for (ProjectTypeEnums v:values ) { + if(v.code==code){ + return v; + } + } + return null; + } +} diff --git a/src/main/java/com/sa/zentao/service/IZtProjectService.java b/src/main/java/com/sa/zentao/service/IZtProjectService.java index 2b9abc8..339dc9d 100644 --- a/src/main/java/com/sa/zentao/service/IZtProjectService.java +++ b/src/main/java/com/sa/zentao/service/IZtProjectService.java @@ -101,5 +101,5 @@ public interface IZtProjectService extends IService { List execListByProject(Integer project); - void removeExecutionStory(Integer id); + void removeExecutionStory(Integer id,Integer execution); } diff --git a/src/main/java/com/sa/zentao/service/IZtProjectstoryService.java b/src/main/java/com/sa/zentao/service/IZtProjectstoryService.java index 3cf1f3b..6e37b36 100644 --- a/src/main/java/com/sa/zentao/service/IZtProjectstoryService.java +++ b/src/main/java/com/sa/zentao/service/IZtProjectstoryService.java @@ -2,6 +2,7 @@ package com.sa.zentao.service; import com.sa.zentao.entity.ZtProjectstory; import com.baomidou.mybatisplus.extension.service.IService; +import com.sa.zentao.enums.ProjectTypeEnums; import java.util.List; @@ -16,4 +17,10 @@ import java.util.List; public interface IZtProjectstoryService extends IService { List storyListPrd(Integer id); + //根据 项目 迭代 查找需求 + List projectStoryList(List projectIds, ProjectTypeEnums type); + //根据需求查找项目 或者迭代 + List projectListByStory(List storyIds, ProjectTypeEnums type); + + } diff --git a/src/main/java/com/sa/zentao/service/impl/ZtProjectServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtProjectServiceImpl.java index b1ac88a..c1d4785 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtProjectServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtProjectServiceImpl.java @@ -12,6 +12,7 @@ import com.sa.zentao.dao.ZtStoryDTO; import com.sa.zentao.entity.*; import com.sa.zentao.enums.ActionStatus; import com.sa.zentao.enums.ActionType; +import com.sa.zentao.enums.ProjectTypeEnums; import com.sa.zentao.enums.UserType; import com.sa.zentao.mapper.ZtProjectMapper; import com.sa.zentao.qo.ZtProjectQo; @@ -795,13 +796,12 @@ public class ZtProjectServiceImpl extends ServiceImpl syncStoryList = this.projectstoryService.list(new QueryWrapper() - .lambda().ne(ZtProjectstory::getExecution, 0) + .lambda().ne(ZtProjectstory::getProject, excludeId) .in(ZtProjectstory::getStory, storyIds) ); + if(!CollectionUtils.isEmpty(syncStoryList)){ throw new BusinessException("当前已关联请刷新"); } @@ -810,7 +810,8 @@ public class ZtProjectServiceImpl extends ServiceImpl list = this.projectstoryService.list(new QueryWrapper().lambda() - .eq(ZtProjectstory::getStory, id).ne(ZtProjectstory::getExecution, 0)); + .eq(ZtProjectstory::getStory, id).eq(ZtProjectstory::getProject, execution)); if(!CollectionUtils.isEmpty(list)){ //删除迭代 this.projectstoryService.remove(new QueryWrapper().lambda() - .eq(ZtProjectstory::getStory,id).ne(ZtProjectstory::getExecution,0)); + .eq(ZtProjectstory::getStory,id).eq(ZtProjectstory::getProject,execution)); //删除看板 - this.kanbanlaneService.removeExecutionStory(list.get(0).getExecution(),id); + this.kanbanlaneService.removeExecutionStory(execution,id); } } diff --git a/src/main/java/com/sa/zentao/service/impl/ZtProjectstoryServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtProjectstoryServiceImpl.java index 1c44dba..15367f6 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtProjectstoryServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtProjectstoryServiceImpl.java @@ -1,11 +1,15 @@ package com.sa.zentao.service.impl; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.sa.zentao.entity.ZtProjectstory; +import com.sa.zentao.enums.ProjectTypeEnums; import com.sa.zentao.mapper.ZtProjectstoryMapper; import com.sa.zentao.service.IZtProjectstoryService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import java.util.ArrayList; import java.util.List; /** @@ -23,4 +27,28 @@ public class ZtProjectstoryServiceImpl extends ServiceImpl storyListPrd(Integer id) { return this.baseMapper.storyListPrd(id); } + + @Override + public List projectStoryList(List projectIds, ProjectTypeEnums type) { + if(CollectionUtils.isEmpty(projectIds)){ + return new ArrayList<>(); + } + List ztProjectstories = this.baseMapper.selectList(new QueryWrapper().lambda().in(ZtProjectstory::getProject, projectIds) + .eq(ZtProjectstory::getType, type.getValue()) + ); + + return ztProjectstories; + } + + @Override + public List projectListByStory(List storyIds, ProjectTypeEnums type) { + if(CollectionUtils.isEmpty(storyIds)){ + return new ArrayList<>(); + } + List ztProjectstories = this.baseMapper.selectList(new QueryWrapper().lambda().in(ZtProjectstory::getStory, storyIds) + .eq(ZtProjectstory::getType, type.getValue()) + ); + + return ztProjectstories; + } } diff --git a/src/main/java/com/sa/zentao/service/impl/ZtReleaseServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtReleaseServiceImpl.java index d7b21c1..57140d4 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtReleaseServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtReleaseServiceImpl.java @@ -8,6 +8,7 @@ import com.github.pagehelper.PageInfo; import com.sa.zentao.conf.RiskUserThreadLocal; import com.sa.zentao.dao.*; import com.sa.zentao.entity.*; +import com.sa.zentao.enums.ProjectTypeEnums; import com.sa.zentao.enums.StoryStageEnums; import com.sa.zentao.mapper.ZtReleaseMapper; import com.sa.zentao.qo.ZtReleaseQo; @@ -64,7 +65,9 @@ public class ZtReleaseServiceImpl extends ServiceImpl execIds = new ArrayList(Arrays.asList(execStr.split(","))); List list = this.projectstoryService.list(new QueryWrapper().lambda() - .in(ZtProjectstory::getExecution, execIds)); + .in(ZtProjectstory::getProject, execIds) + .eq(ZtProjectstory::getType, ProjectTypeEnums.execution.getValue()) + ); if(!CollectionUtils.isEmpty(list)){ List sList = this.storyService.list(new QueryWrapper() .lambda().eq(ZtStory::getStatus, "active") @@ -326,13 +329,13 @@ public class ZtReleaseServiceImpl extends ServiceImpl(); } //迭代查找所有需求 - List pStorys = this.projectstoryService.list(new QueryWrapper().lambda().in(ZtProjectstory::getExecution, - execList.stream().map(o -> o.getExecution()).collect(Collectors.toList()))); - if(CollectionUtils.isEmpty(pStorys)){ + List execStorys = projectstoryService.projectStoryList(execList.stream().map(o -> o.getExecution()).collect(Collectors.toList()),ProjectTypeEnums.execution); + + if(CollectionUtils.isEmpty(execStorys)){ return new PageInfo(); } //过滤掉已关联的迭代需求 - List storyIdList = pStorys.stream().map(o -> o.getStory()).collect(Collectors.toList()); + List storyIdList = execStorys.stream().map(o -> o.getStory()).collect(Collectors.toList()); List ztReleases = this.baseMapper.selectList(new QueryWrapper().lambda().eq(ZtRelease::getProject, project)); @@ -343,7 +346,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl fIds = list.stream().map(o -> o.getObjectId()).collect(Collectors.toList()); - Iterator iterator = pStorys.iterator(); + Iterator iterator = execStorys.iterator(); while (iterator.hasNext()){ ZtProjectstory next = iterator.next(); if(fIds.contains(next.getStory())){ @@ -351,7 +354,7 @@ public class ZtReleaseServiceImpl extends ServiceImplo.getStory()).collect(Collectors.toList())); + qo.setStoryList(execStorys.stream().map(o->o.getStory()).collect(Collectors.toList())); Page page = PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize()); List storyList = this.releaseDetailsService.storyPageList(qo); diff --git a/src/main/java/com/sa/zentao/service/impl/ZtStoryServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtStoryServiceImpl.java index 777cfd1..c85a868 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtStoryServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtStoryServiceImpl.java @@ -321,18 +321,33 @@ public class ZtStoryServiceImpl extends ServiceImpl impl } //老的迭代 List pList = projectstoryService.list(new QueryWrapper().lambda().eq(ZtProjectstory::getStory, ztStory.getId()) - .ne(ZtProjectstory::getExecution, 0) + .eq(ZtProjectstory::getType, ProjectTypeEnums.execution.getValue()) ); - Integer execution = dto.getExecution(); - if(execution!=null&&execution!=0){ - if(!CollectionUtils.isEmpty(pList)&&pList.get(0).getExecution().intValue()!=execution.intValue()){ - List list = this.taskService.list(new QueryWrapper().lambda().eq(ZtTask::getStory, ztStory.getId())); - if(!CollectionUtils.isEmpty(list)){ - throw new BusinessException("当前任务已开始无法更换迭代"); + //如果关联了迭代 执行 + List executions = dto.getExecutions(); + if(!CollectionUtils.isEmpty(executions)){ + List oldExecIds = pList.stream().map(o -> o.getProject()).collect(Collectors.toList()); + //查找需求管理的项目 需求只会被项目关联一次 + List projectList = this.projectstoryService.projectListByStory(Arrays.asList(id), ProjectTypeEnums.project); + + List execList=new ArrayList(); + for (Integer exec:executions) { + if(!oldExecIds.contains(exec)){ + //新增迭代关联 + execList.add(exec); + } } - + executionBindStory(ztStory.getId(),projectList.get(0).getProject(),execList); + execList.clear(); + for (Integer oldExec:oldExecIds) { + if(!executions.contains(oldExec)){ + //删除迭代关联 + execList.add(oldExec); + } + } + executionUnBindStory(ztStory.getId(),projectList.get(0).getProject(),execList); } @@ -346,7 +361,6 @@ public class ZtStoryServiceImpl extends ServiceImpl impl this.productService.updateById(product); } } - if(!StringUtils.isEmpty(dto.getFileUrl())){ ZtStoryspec spec = this.storyspecService.getOne(new QueryWrapper().lambda().eq(ZtStoryspec::getStory, id)); if(spec==null){ spec = new ZtStoryspec(); @@ -358,11 +372,14 @@ public class ZtStoryServiceImpl extends ServiceImpl impl spec.setFiles(dto.getFileUrl()); storyspecService.save(spec); }else{ + spec.setVersion(1); + spec.setTitle(ztStory.getTitle()); + spec.setSpec(dto.getSpec()); + spec.setVerify(dto.getVerify()); spec.setFiles(dto.getFileUrl()); storyspecService.update(new UpdateWrapper().lambda().eq(ZtStoryspec::getStory,id).set(ZtStoryspec::getFiles,dto.getFileUrl()) ); } - } @@ -406,60 +423,60 @@ public class ZtStoryServiceImpl extends ServiceImpl impl - if(dto.getExecution()!=null&&dto.getExecution()!=0){ - //1.没有绑定 解绑 - ZtProjectstory execStory = this.projectstoryService.getOne(new QueryWrapper().lambda().eq(ZtProjectstory::getStory, ztStory.getId()) - .ne(ZtProjectstory::getExecution, 0)); - //如果没有关联过迭代 去关联 第一次 - if(execStory==null){ - //如果是产品型需求 加项目 加迭代 如果是项目型产品 加迭代 - - if (ztStory.getProduct() != null&&ztStory.getProduct()!=0) { - List execlist = this.executionprojectService.list(new QueryWrapper().lambda() - .eq(ZtExecutionproject::getExecution, dto.getExecution())); - if(CollectionUtils.isEmpty(execlist)){ - List list = this.projectproductService.list(new QueryWrapper() - .lambda().eq(ZtProjectproduct::getProduct, ztStory.getProduct())); - ZtProjectproduct ztProjectproduct = list.get(0); - - - ZtProjectstory ztProjectstory = new ZtProjectstory(); - ztProjectstory.setOrder(1); - ztProjectstory.setStory(ztStory.getId()); - ztProjectstory.setProject(ztProjectproduct.getProject()); - this.projectstoryService.save(ztProjectstory); - //添加执行 - }else{ - - ZtProjectstory ztProjectstory = new ZtProjectstory(); - ztProjectstory.setOrder(1); - ztProjectstory.setStory(ztStory.getId()); - ztProjectstory.setProject(execlist.get(0).getProject()); - this.projectstoryService.save(ztProjectstory); - } - } - ZtProjectDTO d=new ZtProjectDTO(); - d.setExcludeId(dto.getExecution()); - d.setStoryIds(new ArrayList<>(){{add(ztStory.getId());}}); - projectService.executionSyncStory(d); - } - else if(dto.getExecution().intValue()==pList.get(0).getExecution().intValue()){ - //编辑没动 不用管 - }else{ - - - - //2.绑定了 切换 - //1. 删除projectStory 迭代的 删除看板 - projectService.removeExecutionStory(ztStory.getId()); - //2. 新增 - ZtProjectDTO d=new ZtProjectDTO(); - d.setExcludeId(dto.getExecution()); - d.setStoryIds(new ArrayList<>(){{add(ztStory.getId());}}); - projectService.executionSyncStory(d); - } - - } +// if(dto.getExecution()!=null&&dto.getExecution()!=0){ +// //1.没有绑定 解绑 +// ZtProjectstory execStory = this.projectstoryService.getOne(new QueryWrapper().lambda().eq(ZtProjectstory::getStory, ztStory.getId()) +// .ne(ZtProjectstory::getExecution, 0)); +// //如果没有关联过迭代 去关联 第一次 +// if(execStory==null){ +// //如果是产品型需求 加项目 加迭代 如果是项目型产品 加迭代 +// +// if (ztStory.getProduct() != null&&ztStory.getProduct()!=0) { +// List execlist = this.executionprojectService.list(new QueryWrapper().lambda() +// .eq(ZtExecutionproject::getExecution, dto.getExecution())); +// if(CollectionUtils.isEmpty(execlist)){ +// List list = this.projectproductService.list(new QueryWrapper() +// .lambda().eq(ZtProjectproduct::getProduct, ztStory.getProduct())); +// ZtProjectproduct ztProjectproduct = list.get(0); +// +// +// ZtProjectstory ztProjectstory = new ZtProjectstory(); +// ztProjectstory.setOrder(1); +// ztProjectstory.setStory(ztStory.getId()); +// ztProjectstory.setProject(ztProjectproduct.getProject()); +// this.projectstoryService.save(ztProjectstory); +// //添加执行 +// }else{ +// +// ZtProjectstory ztProjectstory = new ZtProjectstory(); +// ztProjectstory.setOrder(1); +// ztProjectstory.setStory(ztStory.getId()); +// ztProjectstory.setProject(execlist.get(0).getProject()); +// this.projectstoryService.save(ztProjectstory); +// } +// } +// ZtProjectDTO d=new ZtProjectDTO(); +// d.setExcludeId(dto.getExecution()); +// d.setStoryIds(new ArrayList<>(){{add(ztStory.getId());}}); +// projectService.executionSyncStory(d); +// } +// else if(dto.getExecution().intValue()==pList.get(0).getExecution().intValue()){ +// //编辑没动 不用管 +// }else{ +// +// +// +// //2.绑定了 切换 +// //1. 删除projectStory 迭代的 删除看板 +// projectService.removeExecutionStory(ztStory.getId(),dto.getExecution()); +// //2. 新增 +// ZtProjectDTO d=new ZtProjectDTO(); +// d.setExcludeId(dto.getExecution()); +// d.setStoryIds(new ArrayList<>(){{add(ztStory.getId());}}); +// projectService.executionSyncStory(d); +// } +// +// } // else{ // List list = this.taskService.list(new QueryWrapper().lambda().eq(ZtTask::getStory, ztStory.getId())); // if(!CollectionUtils.isEmpty(list)){ @@ -471,6 +488,52 @@ public class ZtStoryServiceImpl extends ServiceImpl impl } + private void executionBindStory(Integer storyId,Integer project,List execList){ + if(CollectionUtils.isEmpty(execList)){ + return; + } + + List list = this.projectstoryService.list(new QueryWrapper().lambda() + .eq(ZtProjectstory::getProject, project) + .eq(ZtProjectstory::getStory, storyId) + ); + if(CollectionUtils.isEmpty(list)){ + ZtProjectDTO d=new ZtProjectDTO(); + d.setStoryIds(new ArrayList<>(Arrays.asList(storyId))); + d.setProject(project); + this.projectService.projectSyncStory(d); + } + for (Integer execId:execList) { + ZtProjectDTO d=new ZtProjectDTO(); + d.setStoryIds(new ArrayList<>(Arrays.asList(storyId))); + d.setExcludeId(execId); + this.projectService.executionSyncStory(d); + } + } + + private void executionUnBindStory(Integer storyId,Integer project,List execList){ + if(CollectionUtils.isEmpty(execList)){ + return; + } + + List list = this.projectstoryService.list(new QueryWrapper().lambda() + .eq(ZtProjectstory::getProject, project) + .eq(ZtProjectstory::getStory, storyId) + ); + if(CollectionUtils.isEmpty(list)){ + ZtProjectDTO d=new ZtProjectDTO(); + d.setStoryIds(new ArrayList<>(Arrays.asList(storyId))); + d.setProject(project); + this.projectService.projectSyncStory(d); + } + for (Integer execId:execList) { + ZtProjectDTO d=new ZtProjectDTO(); + d.setStoryIds(new ArrayList<>(Arrays.asList(storyId))); + d.setExcludeId(execId); + this.projectService.executionSyncStory(d); + } + } + @Override public void addRemark(ZtStoryDTO dto) { ZtStory ztStory = this.baseMapper.selectById(dto.getId()); diff --git a/src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java index 7d3d796..67317be 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java @@ -196,7 +196,8 @@ public class ZtTaskServiceImpl extends ServiceImpl impleme if(!CollectionUtils.isEmpty(projectList)){ projectId=projectList.get(0).getProject(); } - List executionList = list.stream().filter(o -> o.getProject() != null && o.getProject() != 0).collect(Collectors.toList()); + List executionList = list.stream().filter(o -> o.getProject() != null && o.getProject() != 0) + .collect(Collectors.toList()); if(!CollectionUtils.isEmpty(executionList)){ execution=executionList.get(0).getExecution(); }