Files
zentao/src/main/java/com/sa/zentao/service/impl/ZtKanbanlaneServiceImpl.java
2025-08-25 15:02:17 +08:00

546 lines
24 KiB
Java

package com.sa.zentao.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sa.zentao.conf.RiskUserThreadLocal;
import com.sa.zentao.dao.*;
import com.sa.zentao.entity.*;
import com.sa.zentao.enums.ActionStatus;
import com.sa.zentao.enums.ActionType;
import com.sa.zentao.enums.KanbanCellType;
import com.sa.zentao.enums.ProjectTypeEnums;
import com.sa.zentao.mapper.ZtKanbancolumnMapper;
import com.sa.zentao.mapper.ZtKanbanlaneMapper;
import com.sa.zentao.qo.KanbanQo;
import com.sa.zentao.qo.ZtProjectQo;
import com.sa.zentao.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sa.zentao.utils.BeanCopyUtil;
import com.sa.zentao.utils.DateUtils;
import com.sa.zentao.utils.KanBanConstant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* <p>
* 服务实现类
* </p>
*
* @author gqb
* @since 2024-07-09
*/
@Service
public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtKanbanlane> implements IZtKanbanlaneService {
@Autowired
private IZtKanbancolumnService kanbancolumnService;
@Autowired
private IZtKanbancellService kanbancellService;
@Autowired
private IZtStoryService storyService;
@Autowired
private IZtStoryspecService storyspecService;
@Autowired
private IZtTaskService taskService;
@Autowired
private IZtBugService bugService;
@Autowired
private ZtKanbancolumnMapper kanbancolumnMapper;
@Autowired
private IZtActionService actionService;
@Autowired
private IZtUserService userService;
@Autowired
private IZtProductService productService;
@Override
public List<ZtKanbanlaneDTO> lookInfoByExec(ZtProjectQo qo) {
List<ZtKanbanlane> list = list(new QueryWrapper<ZtKanbanlane>()
.lambda().eq(ZtKanbanlane::getExecution, qo.getId()));
if(CollectionUtils.isEmpty(list)){
return new ArrayList<>();
}
List<ZtKanbanlaneDTO> ztKanbanlanes = BeanCopyUtil.copyListProperties(list, ZtKanbanlaneDTO::new);
Map<String, ZtUser> userMap = this.userService.userMapByIds(null);
List<ZtKanbancolumnDTO> listColumn =kanbancolumnService.listByLaneIds(ztKanbanlanes.stream().map(o->o.getId()).collect(Collectors.toList()));
for (ZtKanbanlaneDTO dto:ztKanbanlanes) {
List<ZtKanbancolumnDTO> collect = listColumn.stream().filter(o -> o.getLane().intValue() == dto.getId().intValue()).collect(Collectors.toList());
for (ZtKanbancolumnDTO d:collect) {
String s = KanBanConstant.columnTypeMap.get(dto.getType() + "-" + d.getType());
d.setSame(s);
String cards = d.getCards();
if(!StringUtils.isEmpty(cards)){
List<String> ids = (List<String>)CollectionUtils.arrayToList(cards.split(",")).stream().filter(o -> !StringUtils.isEmpty(String.valueOf(o))).collect(Collectors.toList());
if("story".equalsIgnoreCase(d.getCardType())){
Map<Integer, List<ZtProject>> executionMapByStory=null;
if(CollectionUtils.isEmpty(ids)){
executionMapByStory=new HashMap<>();
}else{
executionMapByStory = getExecutionMapByStory(ids.stream().map(o->Integer.valueOf(o)).collect(Collectors.toList()));
}
List<ZtStory> ztStories = this.storyService.listByIds(ids);
List<ZtStoryDTO> ztStoryDTOS = BeanCopyUtil.copyListProperties(ztStories, ZtStoryDTO::new);
if(!CollectionUtils.isEmpty(ztStories)){
ZtProduct product = this.productService.getById(ztStoryDTOS.get(0).getProduct());
Map<Integer, ZtStoryCaseDTO> caseMap = this.storyService.getStoryCaseMap(ztStoryDTOS);
for (ZtStoryDTO st:ztStoryDTOS) {
ZtUser ztUser = userMap.get(st.getAssignedTo());
List<ZtProject> ztProjects = executionMapByStory.get(st.getId());
if(!CollectionUtils.isEmpty(ztProjects)){
st.setExecutionName(ztProjects.stream().map(o->o.getName()).collect(Collectors.joining(",")));
st.setExecutions(ztProjects.stream().map(o->o.getId()).collect(Collectors.toList()));
}
if(ztUser!=null){
st.setAssignedToName(ztUser.getNickname());
st.setColor(ztUser.getColor());
}
if(product!=null){
st.setProductName(product.getName());
}
ZtStoryCaseDTO ztStoryCaseDTO = caseMap.get(st.getId());
if(ztStoryCaseDTO!=null){
ztUser = userMap.get(ztStoryCaseDTO.getOpenedUser());
if(ztUser!=null){
ztStoryCaseDTO.setOpenedUserName(ztUser.getNickname());
}
ztUser = userMap.get(ztStoryCaseDTO.getUpdateUser());
if(ztUser!=null){
ztStoryCaseDTO.setUpdateUserName(ztUser.getNickname());
}
ztUser = userMap.get(ztStoryCaseDTO.getPsUser());
if(ztUser!=null){
ztStoryCaseDTO.setPsUserName(ztUser.getNickname());
}
st.setCaseInfo(ztStoryCaseDTO);
}
}
}
//排序
ztStoryDTOS.sort(Comparator.comparing(ZtStoryDTO::getPlanEndDate, Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(ZtStoryDTO::getPri, Comparator.nullsLast(Comparator.naturalOrder())).thenComparing(ZtStoryDTO::getId));
d.setList(ztStoryDTOS);
}else if("bug".equalsIgnoreCase(d.getCardType())){
List<ZtBug> ztBugs = bugService.bugListByIds(ids);
List<ZtBugDTO> ztBugDTOS =new ArrayList<>();
if(!CollectionUtils.isEmpty(ztBugs)){
ztBugDTOS=BeanCopyUtil.copyListProperties(ztBugs, ZtBugDTO::new);
for (ZtBugDTO st:ztBugDTOS) {
ZtUser ztUser = userMap.get(st.getAssignedTo());
if(ztUser!=null){
st.setColor(ztUser.getColor());
st.setAssignedToName(ztUser.getNickname());
}
}
}
ztBugDTOS.sort(Comparator.comparing(ZtBugDTO::getDeadline, Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(ZtBugDTO::getPri, Comparator.nullsLast(Comparator.naturalOrder())).thenComparing(ZtBugDTO::getId));
d.setList(ztBugDTOS);
}else if("task".equalsIgnoreCase(d.getCardType())){
List<ZtTask> ztTasks = taskService.taskListByIds(ids);
List<ZtTaskDTO> ztTaskDTOS =new ArrayList<>();
if(!CollectionUtils.isEmpty(ztTasks)){
ztTaskDTOS=BeanCopyUtil.copyListProperties(ztTasks,ZtTaskDTO::new);
for (ZtTaskDTO st:ztTaskDTOS) {
ZtUser ztUser = userMap.get(st.getAssignedTo());
if(ztUser!=null){
st.setColor(ztUser.getColor());
st.setAssignedToName(ztUser.getNickname());
}
if(st.getDeadline()!=null){
st.setDeadline(DateUtils.getDayLast(st.getDeadline()));
}
ztUser = userMap.get(st.getOpenedby());
if(ztUser!=null){
st.setOpenedbyName(ztUser.getNickname());
}
ztUser = userMap.get(st.getFinishedby());
if(ztUser!=null){
st.setFinishedbyName(ztUser.getNickname());
}
ztUser = userMap.get(st.getCanceledby());
if(ztUser!=null){
st.setCanceledbyName(ztUser.getNickname());
}
ztUser = userMap.get(st.getClosedby());
if(ztUser!=null){
st.setClosedbyName(ztUser.getNickname());
}
}
}
ztTaskDTOS.sort(Comparator.comparing(ZtTaskDTO::getDeadline, Comparator.nullsLast(Comparator.naturalOrder()))
.thenComparing(ZtTaskDTO::getPri, Comparator.nullsLast(Comparator.naturalOrder())).thenComparing(ZtTaskDTO::getId));
d.setList(ztTaskDTOS);
}
}
}
dto.setList(collect);
}
return ztKanbanlanes;
}
@Override
public void changeStatus(KanbanQo qo) {
Integer id = qo.getId();
String tabType = qo.getTabType();
String statusType = qo.getStatusType();
Integer fromId = qo.getFromId();
ZtKanbancell fromkanbancell = this.kanbancellService.getOne(new QueryWrapper<ZtKanbancell>().lambda()
.eq(ZtKanbancell::getColumn, fromId));
List<String> carIds = new ArrayList<>(Arrays.asList(fromkanbancell.getCards().split(",")));
carIds.remove(qo.getId().toString());
fromkanbancell.setCards(StringUtils.join(carIds,","));
this.kanbancellService.updateById(fromkanbancell);
Integer toId = qo.getToId();
ZtKanbancell tokanbancell = this.kanbancellService.getOne(new QueryWrapper<ZtKanbancell>().lambda()
.eq(ZtKanbancell::getColumn, toId));
if(StringUtils.isEmpty(tokanbancell.getCards())){
tokanbancell.setCards(qo.getId().toString());
}else{
carIds = new ArrayList<>(Arrays.asList(tokanbancell.getCards().split(",")));
carIds.add(qo.getId().toString());
tokanbancell.setCards(StringUtils.join(carIds,","));
}
this.kanbancellService.updateById(tokanbancell);
ActionType type= null;
if("story".equalsIgnoreCase(tabType)){
type=ActionType.XQ;
//需求
// storyChange(qo);
//testing 测试中
}
if("bug".equalsIgnoreCase(tabType)){
type=ActionType.BUG;
//bug
// bugChange(qo);
//active 已确认 confirmetd =1
//resolved 完成
//closed 关闭
}
if("task".equalsIgnoreCase(tabType)){
type=ActionType.RW;
//task
// taskChange(qo);
// 任务开始 story developing task doing
//任务完成 story developed task done
//任务回退 story developing task doing
//完成有新任务回退到进行中
//
// if("canceled".equalsIgnoreCase(statusType)){
// //取消
// }
}
// ActionStatus status=null;
//
//
// this.actionService.addAction(type,status,
// qo.getId(),null,null,null,
// RiskUserThreadLocal.get().getName(),qo.get
// );
}
@Override
public void changeStatus(Integer execId, Integer bussId, String type, String toStatus) {
//执行id bussId :业务id type story bug task toStatus:toStatus
List<ZtKanbancell> ztKanbanlaneList = this.baseMapper.getZtKanbanlaneList(type,execId.toString());
ZtKanbancell thisZtKanbancell=null;
for (ZtKanbancell cell:ztKanbanlaneList) {
if(StringUtils.isEmpty(cell.getCards())){
continue;
}
List<String> carIds = new ArrayList<>(Arrays.asList(cell.getCards().split(",")));
if(carIds.contains(bussId.toString())){
thisZtKanbancell=cell;
continue;
}
}
List<String> carIds = new ArrayList<>(Arrays.asList(thisZtKanbancell.getCards().split(",")));
carIds.remove(bussId.toString());
if(CollectionUtils.isEmpty(carIds)){
thisZtKanbancell.setCards("");
}else{
thisZtKanbancell.setCards(StringUtils.join(carIds,","));
}
this.kanbancellService.updateById(thisZtKanbancell);
ZtKanbancell ztKanbanlane = this.baseMapper.getZtKanbanlane(type, toStatus, execId);
String cards = ztKanbanlane.getCards();
List l=StringUtils.isEmpty(cards)?new ArrayList<>():new ArrayList<>(Arrays.asList(cards.split(",")));
l.add(bussId.toString());
ztKanbanlane.setCards(StringUtils.join(l,","));
this.kanbancellService.updateById(ztKanbanlane);
}
@Override
public void addStory(Integer id, List<ZtStory> ztStories) {
ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda()
.eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, "story"));
List<ZtKanbancolumnDTO> ztKanbancolumnDTOS = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId()));
for (ZtStory st:ztStories ) {
ZtKanbancolumnDTO ztKanbancolumnDTO =null;
if("closed".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("closed")).collect(Collectors.toList()).get(0);
}else if ("wait".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("backlog")).collect(Collectors.toList()).get(0);
}else if ("projected".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("backlog")).collect(Collectors.toList()).get(0);
}else if ("developing".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("developing")).collect(Collectors.toList()).get(0);
}else if ("developed".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("developed")).collect(Collectors.toList()).get(0);
}else if ("testing".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("testing")).collect(Collectors.toList()).get(0);
}else if ("tested".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("tested")).collect(Collectors.toList()).get(0);
}else if ("released".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("released")).collect(Collectors.toList()).get(0);
}else if ("verified".equals(st.getStage())){
ztKanbancolumnDTO = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("verified")).collect(Collectors.toList()).get(0);
}
ZtKanbancell kanbancell = this.kanbancellService.getOne(new QueryWrapper<ZtKanbancell>().lambda()
.eq(ZtKanbancell::getKanban, id).eq(ZtKanbancell::getColumn, ztKanbancolumnDTO.getId()));
if(StringUtils.isEmpty(kanbancell.getCards())){
kanbancell.setCards(StringUtils.join(ztStories.stream().map(o->o.getId()).collect(Collectors.toList()),","));
}else{
kanbancell.setCards(kanbancell.getCards()+","+StringUtils.join(ztStories.stream().map(o->o.getId()).collect(Collectors.toList()),","));
}
kanbancellService.updateById(kanbancell);
}
}
@Override
@Transactional
public void addTask(Integer id, List<ZtTask> asList) {
ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda()
.eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, "task"));
List<ZtKanbancolumnDTO> kanbancolumnList = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId()));
for (ZtTask ztTask:asList){
String columnStatus="";
if(ztTask.getStatus().equals("wait")||ztTask.getStatus().equals("reviewing")||ztTask.getStatus().equals("draft")){
columnStatus="wait";
}else if(ztTask.getStatus().equals("doing")){
columnStatus="developing";
}else{
columnStatus="developed";
}
String finalColumnStatus = columnStatus;
ZtKanbancolumnDTO column = kanbancolumnList.stream().filter(o -> o.getCardType().equals("task")).filter(o->o.getType().equals(finalColumnStatus)).findFirst().orElseThrow(()->new BusinessException("看板不存在"));
ZtKanbancell kanbancell = this.kanbancellService.getById(column.getCellId());
List<String> cards = StringUtils.isEmpty(kanbancell.getCards()) ? Arrays.asList(ztTask.getId().toString()) : new ArrayList<>(Arrays.asList(kanbancell.getCards().split(","))){{add(ztTask.getId().toString());}};
kanbancell.setCards(cards.stream().collect(Collectors.joining(",")));
this.kanbancellService.updateById(kanbancell);
}
}
@Override
public void addBug(Integer id, List<ZtBug> asList) {
ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda()
.eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, "bug"));
List<ZtKanbancolumnDTO> ztKanbancolumnDTOS = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId()));
List<ZtKanbancolumnDTO> backlog = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("unconfirmed")).collect(Collectors.toList());
ZtKanbancolumnDTO ztKanbancolumnDTO = backlog.get(0);
ZtKanbancell kanbancell = this.kanbancellService.getOne(new QueryWrapper<ZtKanbancell>().lambda()
.eq(ZtKanbancell::getKanban, id).eq(ZtKanbancell::getColumn, ztKanbancolumnDTO.getId()));
if(StringUtils.isEmpty(kanbancell.getCards())){
kanbancell.setCards(StringUtils.join(asList.stream().map(o->o.getId()).collect(Collectors.toList()),","));
}else{
kanbancell.setCards(kanbancell.getCards()+","+StringUtils.join(asList.stream().map(o->o.getId()).collect(Collectors.toList()),","));
}
kanbancellService.updateById(kanbancell);
}
/**
*
* @param type bug task story
* @param status
* @param id
* @return
*/
@Override
public ZtKanbancell getZtKanbanlane(String type, String status, Integer id) {
return this.baseMapper.getZtKanbanlane(type,status,id);
}
@Override
@Transactional
public void removeExecutionStory(Integer execution, Integer story) {
List<ZtKanbancell> list = this.kanbancellService.list(new QueryWrapper<ZtKanbancell>().lambda().eq(ZtKanbancell::getKanban, execution));
for (ZtKanbancell cell:list) {
if(!StringUtils.isEmpty(cell.getCards())){
String[] split = cell.getCards().split(",");
List<String> sList =new ArrayList(Arrays.asList(split));
while (sList.contains(story.toString())){
sList.remove(story.toString());
}
cell.setCards(sList.stream().collect(Collectors.joining(",")));
this.kanbancellService.updateById(cell);
}
}
}
@Override
public void removeKanbanCell(Integer execution, Integer objectId, KanbanCellType type) {
List<ZtKanbancell> list = this.kanbancellService.list(new QueryWrapper<ZtKanbancell>().lambda().eq(ZtKanbancell::getType,type.getValue()).eq(ZtKanbancell::getKanban, execution));
for (ZtKanbancell cell:list) {
if(!StringUtils.isEmpty(cell.getCards())){
String[] split = cell.getCards().split(",");
List<String> sList =new ArrayList(Arrays.asList(split));
if(sList.contains(objectId.toString())){
sList.remove(objectId.toString());
cell.setCards(sList.stream().collect(Collectors.joining(",")));
this.kanbancellService.updateById(cell);
}
}
}
}
@Override
public void addKanbanCell(Integer execution, Integer objectId, KanbanCellType type, Object obj) {
//看板
List<ZtKanbancell> list = this.kanbancellService.list(new QueryWrapper<ZtKanbancell>().lambda().eq(ZtKanbancell::getType,type.getValue()).eq(ZtKanbancell::getKanban, execution));
if(type==KanbanCellType.TASK){
ZtKanbancell ztKanbancell = list.get(0);
ZtTask task=(ZtTask)obj;
addTask(execution,Arrays.asList(task));
}else if(type==KanbanCellType.STORY){
ZtKanbancell ztKanbancell = list.get(0);
ZtStory story=(ZtStory)obj;
addStory(execution,Arrays.asList(story));
}else if(type==KanbanCellType.BUG){
//TODO待处理
}
}
private void taskChange(KanbanQo qo) {
ZtTask ztTask = this.taskService.getById(qo.getId());
ztTask.setStatus(qo.getStatusType());
this.taskService.updateById(ztTask);
}
private void bugChange(KanbanQo qo) {
}
private void storyChange(KanbanQo qo) {
}
@Autowired
private IZtProjectService projectService;
@Autowired
private IZtProjectstoryService projectstoryService;
//需求id 执行
public Map<Integer,List<ZtProject>> getExecutionMapByStory(List<Integer> list) {
List<ZtProjectstory> pStoryList = projectstoryService.list(new QueryWrapper<ZtProjectstory>().lambda().eq(ZtProjectstory::getType, ProjectTypeEnums.execution.getValue())
.in(ZtProjectstory::getStory, list)
);
if(CollectionUtils.isEmpty(pStoryList)){
return new HashMap<>();
}
List<Integer> execIds = pStoryList.stream().map(o -> o.getProject()).collect(Collectors.toList());
List<ZtProject> ztProjects = this.projectService.listByIds(execIds);
Map<Integer,List<ZtProject>> result =new HashMap<>();
for (ZtProjectstory st:pStoryList) {
Integer execution = st.getProject();
List<ZtProject> fExecution = ztProjects.stream().filter(o -> o.getId().intValue() == execution.intValue()).collect(Collectors.toList());
ZtProject ztProject = fExecution.get(0);
List<ZtProject> mpList = result.get(st.getStory());
if(CollectionUtils.isEmpty(mpList)){
List<ZtProject> mList=new ArrayList<>();
mList.add(ztProject);
result.put(st.getStory(),mList);
}else{
mpList.add(ztProject);
}
}
return result;
}
}