月报问题,发布邮件末班修改,任务切换迭代

This commit is contained in:
2025-07-09 17:32:05 +08:00
parent 19a4e73998
commit 4eb3f4662f
22 changed files with 205 additions and 113 deletions

View File

@ -1,6 +1,7 @@
package com.sa.zentao.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sa.zentao.conf.LoginRiskUser;
import com.sa.zentao.conf.RiskUserThreadLocal;
import com.sa.zentao.dao.*;
import com.sa.zentao.entity.ZtBug;

View File

@ -121,9 +121,9 @@ public class PerformanceDTO implements Serializable {
@ExcelIgnore
private BigDecimal meetScore=BigDecimal.ZERO;
//周会议
private BigDecimal meetWeek;
private BigDecimal meetWeek=BigDecimal.ZERO;
//需求会议
private BigDecimal meetStory;
private BigDecimal meetStory=BigDecimal.ZERO;
//文档质量问题个数
private BigDecimal documentQualityProblem=BigDecimal.ZERO;
//文档得分

View File

@ -32,10 +32,10 @@ public class ProjectWorkTaskDTO implements Serializable {
//已验收需求总量
@ExcelProperty(value = "需求",index =5)
private String storyName;
//验收通过率
//任务名称
@ExcelProperty(value = "任务名称",index =6)
private String taskName;
//验收不通过数量
//任务类型
@ExcelProperty(value = "任务类型",index =7)
private String typeName;
//指派人

View File

@ -52,6 +52,6 @@ public class WorkDetailsDTO implements Serializable {
private UserType userType;
@ExcelIgnore
private String account;
@ExcelIgnore
private ZtMonthScopeDTO monthScoreDto;
}

View File

@ -62,4 +62,6 @@ public class ZtKanbancolumnDTO implements Serializable {
private String cardType;
private String same;
// cellId
private Integer cellId;
}

View File

@ -0,0 +1,23 @@
package com.sa.zentao.enums;
public enum KanbanCellType {
TASK("task"),
STORY("story"),
BUG( "bug"),
;
private String value;
private KanbanCellType(String value) {
this.value = value;
}
public String getValue() {
return this.value;
}
}

View File

@ -10,7 +10,8 @@ import java.util.List;
@EqualsAndHashCode(callSuper = false)
public class StoryQo extends BaseQo {
private String orderName;
private String orderSort;
private Integer id;
private String title;

View File

@ -3,6 +3,7 @@ package com.sa.zentao.service;
import com.sa.zentao.dao.ZtKanbanlaneDTO;
import com.sa.zentao.entity.*;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sa.zentao.enums.KanbanCellType;
import com.sa.zentao.qo.KanbanQo;
import com.sa.zentao.qo.ZtProjectQo;
@ -42,4 +43,14 @@ public interface IZtKanbanlaneService extends IService<ZtKanbanlane> {
public ZtKanbancell getZtKanbanlane(String type, String status, Integer id);
//
void removeExecutionStory(Integer execution, Integer story);
/**
* 把元素从看板删除
* @param execution
* @param objectId
* @param type bug task story
*/
void removeKanbanCell(Integer execution, Integer objectId, KanbanCellType type);
void addKanbanCell(Integer execution, Integer objectId, KanbanCellType type,Object obj);
}

View File

@ -2183,12 +2183,15 @@ public class IZtCountService {
dataMap.put("Bug密度", performanceDTO.getBugScore().toString());
dataMap.put("工作量饱和度", performanceDTO.getSaturationScore().toString());
dataMap.put("代码质量", "5");
dataMap.put("工作质量", "5");
dataMap.put("文档质量", "15");
dataMap.put("工作态度和责任感", "5");
dataMap.put("创新贡献", "0");
dataMap.put("质量贡献", "0");
dataMap.put("代码质量", performanceDTO.getCodeQualityScore()==null?"0":performanceDTO.getCodeQualityScore().toString());
dataMap.put("工作态度", performanceDTO.getWorkAttitude()==null?"0":performanceDTO.getWorkAttitude().toString());
//工作态度 不规范行为
dataMap.put("文档质量", performanceDTO.getDocumentQualityScore()==null?"0":performanceDTO.getDocumentQualityScore().toString());
//创新贡献 优质分享
dataMap.put("创新贡献", performanceDTO.getExcellentShare()==null?"0":performanceDTO.getExcellentShare().toString());
//
dataMap.put("质量贡献", performanceDTO.getQuality()==null?"0":performanceDTO.getQuality().toString());
dataMap.put("totalTask", performanceDTO.getTotalTask().toString());
dataMap.put("delayTask", performanceDTO.getDelayTask().toString());
@ -2203,12 +2206,15 @@ public class IZtCountService {
dataMap.put("总分", devlopTotal(
dataMap.get("工作量饱和度"),
dataMap.get("准时率得分"),
dataMap.get("Bug密度"),
dataMap.get("代码质量"),
dataMap.get("文档质量"),
dataMap.get("工作量饱和"),
dataMap.get("工作态度和责任感")
dataMap.get("工作"),
dataMap.get("创新贡献"),
dataMap.get("质量贡献")
));
writeXlsx(name, "templates/scope/开发工程师.xlsx", name + "开发.xlsx", dataMap);
@ -2220,51 +2226,19 @@ public class IZtCountService {
dataMap.put("date", DateUtils.formatDate(d, "yyyy-MM"));
dataMap.put("总分", "100");
dataMap.put("任务总量", performanceDTO.getTotalTask().toString());
dataMap.put("超期数", performanceDTO.getDelayTask().toString());
dataMap.put("及时完成率", performanceDTO.getFinishPunctuality().toString());
dataMap.put("及时完成率得分", performanceDTO.getPunctualityScore()==null?"0":performanceDTO.getPunctualityScore().toString());
dataMap.put("设计质", performanceDTO.getDesignScore()==null?"0":performanceDTO.getDesignScore().toString());
dataMap.put("工作态度", performanceDTO.getWorkAttitude()==null?"0":performanceDTO.getWorkAttitude().toString());
dataMap.put("工作量", performanceDTO.getUiWorkScore()==null?"0":performanceDTO.getUiWorkScore().toString());
dataMap.put("创新贡献", performanceDTO.getExcellentShare()==null?"0":performanceDTO.getExcellentShare().toString());
dataMap.put("任务总量", performanceDTO.getTotalTask()==null?"0":performanceDTO.getTotalTask().toString());
dataMap.put("超期数量", performanceDTO.getDelayTask()==null?"0":performanceDTO.getDelayTask().toString());
dataMap.put("及时完成率", performanceDTO.getFinishPunctuality()==null?"0": performanceDTO.getFinishPunctuality().toString());
dataMap.put("总分", devlopTotal(dataMap.get("及时完成率得分"), dataMap.get("设计质量"), dataMap.get("工作态度"), dataMap.get("工作量"), dataMap.get("创新贡献")));
writeXlsx(name, "templates/scope/UI工程师.xlsx", name + "UI工程师.xlsx", dataMap);
InputStream templateFile = null;
// try {
// templateFile=IZtCountService.class.getClassLoader().getResourceAsStream("templates/scope/UI工程师.xlsx");
//// templateFile = IZtCountService.class.getClassLoader().getResourceAsStream("templates/scope/开发工程师.xlsx");
//
//
// //测试方案
// // 读取模板
//
// Workbook workbook = WorkbookFactory.create(templateFile);
//
// Sheet sheet = workbook.getSheetAt(0);
// workbook.setSheetName(0,name);
// // 替换占位符
// for (Row row : sheet) {
// for (Cell cell : row) {
// if (cell.getCellType() == CellType.STRING) {
// String cellValue = cell.getStringCellValue();
// for (Map.Entry<String, String> entry : dataMap.entrySet()) {
// cellValue = cellValue.replace("{" + entry.getKey() + "}", entry.getValue());
// }
// cell.setCellValue(cellValue);
// }
// }
// }
//
// // 生成新文件
// try (FileOutputStream outputStream = new FileOutputStream(name+"UI工程师.xlsx")) {
// workbook.write(outputStream);
// }
// workbook.close();
// }catch (Exception e){
// log.error("",e);
// }finally {
// try {
// templateFile.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
@ -2279,21 +2253,21 @@ public class IZtCountService {
dataMap.put("bug", bugManageScore(qo, perList, userMap));
dataMap.put("版本计划完成率", versionPlanScore(qo, perList, userMap));
dataMap.put("项目文档", "10");
dataMap.put("会议管理", performanceDTO.getMeetScore() + "");
dataMap.put("问题管理", "5");
dataMap.put("项目文档", performanceDTO.getDocumentQualityScore()==null?"0":performanceDTO.getDocumentQualityScore().toString());
dataMap.put("会议管理", performanceDTO.getMeetScore()==null?"0": performanceDTO.getMeetScore() + "");
dataMap.put("问题管理", performanceDTO.getDevelopFeedbackStory()==null?"0":performanceDTO.getDevelopFeedbackStory().toString());
dataMap.put("系统稳定性", "10");
dataMap.put("专业技能提升", "5");
dataMap.put("普通bug",performanceDTO.getSlightBug().toString());
dataMap.put("重大bug", performanceDTO.getSeriousBug().toString());
dataMap.put("线上bug率", performanceDTO.getBugDensity().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("分配工时", performanceDTO.getAllocationTime().toString());
dataMap.put("可用工时", performanceDTO.getExamineTime().toString());
dataMap.put("分配工时占比", performanceDTO.getAllocationTimeManageRate().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("召开周会数量", performanceDTO.getMeetWeek().toString());
dataMap.put("召开需求会议数量", performanceDTO.getMeetStory().toString());
dataMap.put("普通bug",performanceDTO.getSlightBug()==null?"0":performanceDTO.getSlightBug().toString());
dataMap.put("重大bug", performanceDTO.getSeriousBug()==null?"0": performanceDTO.getSeriousBug().toString());
dataMap.put("线上bug率",performanceDTO.getBugDensity()==null?"0": performanceDTO.getBugDensity().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("分配工时", performanceDTO.getAllocationTime()==null?"0": performanceDTO.getAllocationTime().toString());
dataMap.put("可用工时", performanceDTO.getExamineTime()==null?"0": performanceDTO.getExamineTime().toString());
dataMap.put("分配工时占比", performanceDTO.getAllocationTimeManageRate()==null?"0": performanceDTO.getAllocationTimeManageRate().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("召开周会数量", performanceDTO.getMeetWeek()==null?"0": performanceDTO.getMeetWeek().toString());
dataMap.put("召开需求会议数量", performanceDTO.getMeetStory()==null?"0": performanceDTO.getMeetStory().toString());
@ -2569,11 +2543,11 @@ public class IZtCountService {
dataMap.put("会议管理", performanceDTO.getMeetScore().toString());
dataMap.put("上线需求数量", performanceDTO.getReleaseCount().toString());
dataMap.put("及时验收数量", performanceDTO.getReleaseOnTimeCount().toString());
dataMap.put("及时验收率", performanceDTO.getReleaseOnTimeRate().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("召开周会数量", performanceDTO.getMeetWeek().toString());
dataMap.put("召开需求数量", performanceDTO.getMeetStory().toString());
dataMap.put("上线需求数量", performanceDTO.getReleaseCount()==null?"0": performanceDTO.getReleaseCount().toString());
dataMap.put("及时验收数量", performanceDTO.getReleaseOnTimeCount()==null?"0":performanceDTO.getReleaseOnTimeCount().toString());
dataMap.put("及时验收率", performanceDTO.getReleaseOnTimeRate()==null?"0": performanceDTO.getReleaseOnTimeRate().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("召开周会数量", performanceDTO.getMeetWeek()==null?"0":performanceDTO.getMeetWeek().toString());
dataMap.put("召开需求数量", performanceDTO.getMeetStory()==null?"0": performanceDTO.getMeetStory().toString());
@ -2600,29 +2574,32 @@ public class IZtCountService {
Map<String, String> dataMap = new HashMap<>();
dataMap.put("name", name);
dataMap.put("date", DateUtils.formatDate(d, "yyyy-MM"));
dataMap.put("准时率得分", performanceDTO.getPunctualityScore().toString());
dataMap.put("准时率得分", performanceDTO.getPunctualityScore()==null?"0": performanceDTO.getPunctualityScore().toString());
dataMap.put("缺陷检出率", performanceDTO.getBugFindScore().toString());
dataMap.put("测试文档", "20");
dataMap.put("工作态度", "5");
dataMap.put("质量贡献", "5");
dataMap.put("线上Bug", "20");
dataMap.put("测试文档", performanceDTO.getDocumentQualityScore()==null?"0":performanceDTO.getDocumentQualityScore().toString());
dataMap.put("工作态度", performanceDTO.getWorkAttitude()==null?"0":performanceDTO.getWorkAttitude().toString());
dataMap.put("质量贡献", performanceDTO.getExcellentShare()==null?"0":performanceDTO.getExcellentShare().toString());
dataMap.put("线上Bug", performanceDTO.getBugScore()==null?"0":performanceDTO.getBugScore().toString());
dataMap.put("任务总量", performanceDTO.getTotalTask().toString());
dataMap.put("延期数量", performanceDTO.getDelayTask().toString());
dataMap.put("及时完成率", performanceDTO.getFinishPunctuality().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("创新贡献", performanceDTO.getExcellentShare().toString());
dataMap.put("任务总量", performanceDTO.getTotalTask()==null?"0": performanceDTO.getTotalTask().toString());
dataMap.put("延期数量", performanceDTO.getDelayTask() ==null?"0":performanceDTO.getDelayTask().toString());
dataMap.put("及时完成率", performanceDTO.getFinishPunctuality() ==null?"0":performanceDTO.getFinishPunctuality().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("创新贡献", performanceDTO.getExcellentShare() ==null?"0":performanceDTO.getExcellentShare().toString());
dataMap.put("测试普通bug", performanceDTO.getDevSlightBug().toString());
dataMap.put("测试重大bug", performanceDTO.getDevSeriousBug().toString());
dataMap.put("缺陷检出分数", performanceDTO.getBugFindScore().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("线上普通bug", performanceDTO.getSlightBug().toString());
dataMap.put("线上重大bug", performanceDTO.getSeriousBug().toString());
dataMap.put("测试普通bug", performanceDTO.getDevSlightBug()==null?"0": performanceDTO.getDevSlightBug().toString());
dataMap.put("测试重大bug", performanceDTO.getDevSeriousBug() ==null?"0": performanceDTO.getDevSeriousBug().toString());
dataMap.put("缺陷检出分数", performanceDTO.getBugFindScore()==null?"0": performanceDTO.getBugFindScore().multiply(BigDecimal.valueOf(100)).toString());
dataMap.put("线上普通bug", performanceDTO.getSlightBug() ==null?"0": performanceDTO.getSlightBug().toString());
dataMap.put("线上重大bug", performanceDTO.getSeriousBug()==null?"0": performanceDTO.getSeriousBug().toString());
dataMap.put("总分", devlopTotal(dataMap.get("准时率得分")
, dataMap.get("缺陷检出率"), dataMap.get("测试文档"), dataMap.get("工作态度"), dataMap.get("质量贡献"), dataMap.get("线上Bug"), dataMap.get("创新贡献"))
, dataMap.get("缺陷检出率"),
dataMap.get("测试文档"), dataMap.get("工作态度"), dataMap.get("质量贡献"), dataMap.get("线上Bug"), dataMap.get("创新贡献"))
);
writeXlsx(name, "templates/scope/测试工程师.xlsx", name + "测试.xlsx", dataMap);

View File

@ -6,6 +6,7 @@ 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;
@ -17,6 +18,7 @@ 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;
@ -24,6 +26,7 @@ import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* <p>
@ -367,25 +370,33 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
}
@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> ztKanbancolumnDTOS = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId()));
List<ZtKanbancolumnDTO> kanbancolumnList = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId()));
List<ZtKanbancolumnDTO> backlog = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("wait"))
.collect(Collectors.toList());
ZtKanbancolumnDTO ztKanbancolumnDTO = backlog.get(0);
for (ZtTask ztTask:asList){
String columnStatus="";
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()),","));
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);
}
kanbancellService.updateById(kanbancell);
}
@Override
public void addBug(Integer id, List<ZtBug> asList) {
ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda()
@ -427,8 +438,24 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
if(!StringUtils.isEmpty(cell.getCards())){
String[] split = cell.getCards().split(",");
List<String> sList =new ArrayList(Arrays.asList(split));
if(sList.contains(story+"")){
sList.remove(story + "");
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);
}
@ -436,6 +463,23 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
}
}
@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());

View File

@ -872,6 +872,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
ztProjectstory.setStory(sId);
ztProjectstory.setProject(excludeId);
ztProjectstory.setType(ProjectTypeEnums.execution.getValue());
ztProjectstory.setProduct(dto.getProduct());
saveList.add(ztProjectstory);
order += 5;
}

View File

@ -459,7 +459,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
b.append("<div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\"><br></span></div>");
b.append("<table id=\"table_0\" data-editing-info=\"{&quot;topBorderColor&quot;:&quot;#ABABAB&quot;,&quot;bottomBorderColor&quot;:&quot;#ABABAB&quot;,&quot;verticalBorderColor&quot;:&quot;#ABABAB&quot;,&quot;hasHeaderRow&quot;:false,&quot;hasFirstColumn&quot;:false,&quot;hasBandedRows&quot;:false,&quot;hasBandedColumns&quot;:false,&quot;bgColorEven&quot;:null,&quot;bgColorOdd&quot;:&quot;#ABABAB20&quot;,&quot;headerRowColor&quot;:&quot;#ABABAB&quot;,&quot;tableBorderFormat&quot;:0,&quot;verticalAlign&quot;:&quot;middle&quot;}\" style=\"box-sizing: border-box; border-collapse: collapse; border-spacing: 0px;\">");
b.append("<tbody>" +
"<tr><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 67.5938px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">需求编号</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 690.922px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\">研发需求名称</div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 103.859px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">需求状态</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 121.359px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">上线时间</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 117.875px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px;\"><span style=\"line-height: 1.6;\">截止验收时间</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 105.391px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">验收人</span></div></td></tr>"
"<tr><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 67.5938px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">需求编号</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 690.922px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\">研发需求名称</div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 103.859px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">来源部门</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 121.359px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">需求状态</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 121.359px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">上线时间</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 117.875px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px;\"><span style=\"line-height: 1.6;\">截止验收时间</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 105.391px; height: 54.2766px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">验收人</span></div></td></tr>"
// "<tr><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 74.8281px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">需求编号</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 926.453px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\">研发需求名称</div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 102.672px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">需求状态</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 105.672px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">上线时间</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 108.672px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px;\"><span style=\"line-height: 1.6;\">截止验收时间</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 93.7031px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">验收人</span></div></td></tr>"
);
for (ZtStory s:ztStories) {
@ -467,11 +467,13 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
if(ztUser!=null&&!StringUtils.isEmpty(ztUser.getEmail())){
// String str= "<tr><td style=\"width: 78.25px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{id}</span></div></td><td style=\"width: 996.266px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{title}</span></div></td><td style=\"width: 108.266px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{nickName}</span></div></td>" +
// "</tr>";
String str="<tr><td style=\"width: 74.8281px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{id}</span></div></td><td style=\"width: 926.453px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{title}</span></div></td><td style=\"width: 102.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{status}</span></div></td><td style=\"width: 105.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{releaseDate}</span></div></td><td style=\"width: 108.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{endDate}</span></div></td><td style=\"width: 93.7031px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{nikename}</span></div></td></tr>";
// String str="<tr><td style=\"width: 74.8281px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{id}</span></div></td><td style=\"width: 926.453px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{title}</span></div></td><td style=\"width: 102.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{status}</span></div></td><td style=\"width: 105.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{releaseDate}</span></div></td><td style=\"width: 108.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{endDate}</span></div></td><td style=\"width: 93.7031px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{nikename}</span></div></td></tr>";
// String str="<tr><td style=\\\"width: 74.8281px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\\\"><div style=\\\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\\\"><span style=\\\"line-height: 1.6;\\\">{id}</span></div></td><td style=\\\"width: 926.453px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\\\"><div style=\\\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\\\"><span style=\\\"line-height: 1.6;\\\">{title}</span></div></td><td style=\\\"width: 102.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\\\"><div style=\\\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\\\"><span style=\\\"line-height: 1.6;\\\">{dept}</span></div></td><td style=\\\"width: 102.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\\\"><div style=\\\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\\\"><span style=\\\"line-height: 1.6;\\\">{status}</span></div></td><td style=\\\"width: 105.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\\\"><div style=\\\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\\\"><span style=\\\"line-height: 1.6;\\\">{releaseDate}</span></div></td><td style=\\\"width: 108.672px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\\\"><div style=\\\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\\\"><span style=\\\"line-height: 1.6;\\\">{endDate}</span></div></td><td style=\\\"width: 93.7031px; height: 31.8118px; border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; box-sizing: border-box;\\\"><div style=\\\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\\\"><span style=\\\"line-height: 1.6;\\\">{nikename}</span></div></td></tr>\n";
String str="<tr><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 74.8281px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{id}</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 926.453px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{title}</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 102.672px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\">{dept}</div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 102.672px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{status}</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 105.672px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{releaseDate}</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 108.672px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{endDate}</span></div></td><td style=\"border-width: 1px; border-style: solid; border-color: rgb(171, 171, 171); padding: 4px 8px; vertical-align: middle; width: 93.7031px; height: 31.8118px; box-sizing: border-box;\"><div style=\"font-family: -apple-system, system-ui; font-size: 14px; color: rgb(0, 0, 0);\"><span style=\"line-height: 1.6;\">{nikename}</span></div></td></tr>";
str=str.replace("{nikename}",ztUser.getNickname());
str=str.replace("{title}",s.getTitle());
str=str.replace("{id}",s.getId().toString());
str=str.replace("{dept}",ztUser.getDeptName());
str=str.replace("{status}","已发布");
str=str.replace("{releaseDate}",DateUtils.formatDate(release.getRealReleaseDate()==null?release.getReleaseDate():release.getRealReleaseDate(),"yyyy-MM-dd"));
str=str.replace("{endDate}",DateUtils.formatDate(DateUtils.dateAddDay(release.getRealReleaseDate()==null?release.getReleaseDate():release.getRealReleaseDate(),14)));

View File

@ -641,7 +641,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if (CollectionUtils.isEmpty(execList)) {
return;
}
//迭代关联项目
List<ZtExecutionproject> execProjectList = this.executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda()
.in(ZtExecutionproject::getExecution, execList));
@ -651,20 +651,25 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
.filter(o -> o.getExecution().intValue() == execId.intValue()).collect(Collectors.toList());
Integer project = fProjectList.get(0).getProject();
//当前迭代绑定的项目
//当前迭代绑定的项目 当前迭代的项目需求
List<ZtProjectstory> list = this.projectstoryService.list(new QueryWrapper<ZtProjectstory>().lambda()
.eq(ZtProjectstory::getProject, project)
.eq(ZtProjectstory::getStory, storyId)
);
//一个需求如果绑定多个项目 不是当前的项目
List<ZtProjectstory> bindProject = this.projectstoryService.list(new QueryWrapper<ZtProjectstory>().lambda()
.ne(ZtProjectstory::getProject, project)
.eq(ZtProjectstory::getType,"project")
.eq(ZtProjectstory::getStory, storyId)
);
if(!CollectionUtils.isEmpty(bindProject)){
Integer oldProject = bindProject.get(0).getProject();
//切换的迭代不是当前需求已经绑定的迭代
this.projectstoryService.remove(new QueryWrapper<ZtProjectstory>().lambda().eq(ZtProjectstory::getProject, oldProject).eq(ZtProjectstory::getStory, storyId));
}
/*
项目需求绑定了
Integer oldProject = bindProject.get(0).getProject();
切换的迭代不是当前需求已经绑定的迭代
this.projectstoryService.remove(new QueryWrapper<ZtProjectstory>().lambda().eq(ZtProjectstory::getProject, oldProject).eq(ZtProjectstory::getStory, storyId));
*/
if(!CollectionUtils.isEmpty(bindProject)) throw new BusinessException("需求被多个项目关联");
if (CollectionUtils.isEmpty(list)) {
ZtProjectDTO d = new ZtProjectDTO();

View File

@ -704,6 +704,9 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
String oldAssignedTo = ztTask.getAssignedTo();
Integer s1 = ztTask.getStory();
Integer s2 = dto.getStory();
//老的迭代
Integer oldExecution = ztTask.getExecution();
Integer newExecution = dto.getExecution();
//cancel取消 closed 关闭 done
@ -795,6 +798,13 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
RiskUserThreadLocal.get().getName(), dto.getRemark(), null);
}
}
if(ObjectUtils.notEqual(oldExecution,newExecution)){
//迭代切换了
this.kanbanlaneService.removeKanbanCell(oldExecution,ztTask.getId(),KanbanCellType.TASK);
//添加新的看板迭代
this.kanbanlaneService.addKanbanCell(newExecution,ztTask.getId(),KanbanCellType.TASK,ztTask);
}
taskSendZpMessage(ztTask.getId(), oldAssignedTo, ztTask.getAssignedTo());

View File

@ -39,6 +39,7 @@ public class SFunctionColums {
result.add(ZtTask::getEstStarted);
result.add(ZtTask::getRealstarted);
result.add(ZtTask::getCanceleddate);
result.add(ZtTask::getType);
result.add(ZtTask::getPri);
return result;
}

View File

@ -15,7 +15,7 @@
<result column="deleted" property="deleted" />
</resultMap>
<select id="listByLaneIds" resultType="com.sa.zentao.dao.ZtKanbancolumnDTO">
SELECT c.*,b.lane,b.kanban,b.cards, b.type cardType from zt_kanbancolumn c,zt_kanbancell b
SELECT c.*,b.lane,b.kanban,b.cards, b.type cardType ,b.id cellId from zt_kanbancolumn c,zt_kanbancell b
WHERE c.id = b.column
and b.lane in

View File

@ -220,7 +220,21 @@
</if>
order by s.id desc
<choose>
<when test="qo.orderName != '' and qo.orderName != null ">
<choose>
<when test="qo.orderSort != '' and qo.orderSort != null ">
order by s.${qo.orderName} ${qo.orderSort}
</when>
<otherwise>
order by s.id desc
</otherwise>
</choose>
</when>
<otherwise>
order by s.id desc
</otherwise>
</choose>
</select>
</mapper>