11 Commits

Author SHA1 Message Date
5b8d440ff3 绩效看板等修改 2026-01-12 10:10:51 +08:00
7c379ea877 验收产品,测试人开发 2026-01-05 16:48:19 +08:00
5eb21276a9 合并代码,bug修复 2025-12-31 09:32:52 +08:00
3d815dc9e8 合并代码,bug修复 2025-12-30 17:21:21 +08:00
21f522cd1a Merge remote-tracking branch 'origin/dev-2025' into dev-2025
# Conflicts:
#	src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java
#	src/main/resources/mapper/ZtStoryMapper.xml
2025-12-30 17:17:40 +08:00
679aa5f0c1 产品角色等 2025-12-30 09:43:05 +08:00
99c17f1ef1 需求增加筛选 2025-12-30 09:38:09 +08:00
563699a527 需求增加筛选 2025-12-30 09:38:04 +08:00
0f1c7b02fe 产品角色等 2025-12-25 14:02:41 +08:00
8f0c7a020c 产品角色等 2025-12-25 13:46:26 +08:00
e948b53e89 产品角色等 2025-12-23 10:17:39 +08:00
43 changed files with 1270 additions and 281 deletions

28
pom.xml
View File

@@ -18,6 +18,17 @@
<boot.version>3.3.0</boot.version> <boot.version>3.3.0</boot.version>
</properties> </properties>
<dependencies> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.3</version>
</dependency>
<dependency> <dependency>
<groupId>com.itextpdf</groupId> <groupId>com.itextpdf</groupId>
@@ -88,13 +99,6 @@
<version>1.5.2</version> <version>1.5.2</version>
</dependency> </dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.5</version>
</dependency>
<dependency> <dependency>
<groupId>com.tencentcloudapi</groupId> <groupId>com.tencentcloudapi</groupId>
@@ -282,11 +286,11 @@
</dependency> </dependency>
<dependency> <!-- <dependency>-->
<groupId>org.apache.commons</groupId> <!-- <groupId>org.apache.commons</groupId>-->
<artifactId>commons-pool2</artifactId> <!-- <artifactId>commons-pool2</artifactId>-->
<version>2.8.1</version> <!-- <version>2.8.1</version>-->
</dependency> <!-- </dependency>-->
</dependencies> </dependencies>
<build> <build>

View File

@@ -15,26 +15,24 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice @RestControllerAdvice
public class GlobalExceptionHandler { public class GlobalExceptionHandler {
@Value("spring.application.name") @Value("${spring.application.name}")
private String application; private String application;
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public Result bizExceptionHandler(Exception e, HttpServletRequest request) { public Result bizExceptionHandler(Exception e, HttpServletRequest request) {
log.error("发生业务异常!原因: {}", e.getMessage()); log.error("系统发生异常!应用: {}, 请求路径: {}, 异常类型: {}, 异常原因: {}",
log.error(application +"发生了异常 ,异常信息 {}",e); application, request.getRequestURI(), e.getClass().getSimpleName(), e.getMessage(), e);
return Result.fail(Code.FAIL); return Result.fail(Code.FAIL);
} }
@ExceptionHandler(BusinessException.class) @ExceptionHandler(BusinessException.class)
public Result bizExceptionHandler(BusinessException e, HttpServletRequest request) { public Result bizExceptionHandler(BusinessException e, HttpServletRequest request) {
log.error("发生业务异常!原因: {}", e.getMessage()); log.error("业务异常!应用: {}, 请求路径: {}, 异常原因: {}",
log.error(application +"发生了异常 ,异常信息 {}",e); application, request.getRequestURI(), e.getMessage());
if(e.code==null){ if(e.code==null){
return Result.fail(e.value); return Result.fail(e.value);
}else{ }else{
return Result.fail(e.code); return Result.fail(e.code);
} }
} }
} }

View File

@@ -17,9 +17,6 @@ public class WebMvcConfig implements WebMvcConfigurer {
@Override @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) { public void addResourceHandlers(ResourceHandlerRegistry registry) {
for (int i =0;i<200;i++){
log.info("win");
}
String os = System.getProperty("os.name"); String os = System.getProperty("os.name");
if (os.toLowerCase().startsWith("win")) { //如果是Windows系统 if (os.toLowerCase().startsWith("win")) { //如果是Windows系统
log.info("win"); log.info("win");

View File

@@ -0,0 +1,37 @@
package com.sa.zentao.constants;
/**
* 导出相关常量
*/
public class ExportConstants {
/**
* 导出最大记录数
*/
public static final int MAX_EXPORT_SIZE = 1000000;
/**
* Excel sheet 名称
*/
public static final String SHEET_NAME = "sheet1";
/**
* URL 编码空格
*/
public static final String URL_SPACE_ENCODE = "%20";
/**
* 字符串分隔符
*/
public static final String STRING_SEPARATOR = ":";
/**
* ID 分隔符
*/
public static final String ID_SEPARATOR = ",";
/**
* 逗号替换为空字符串
*/
public static final String COMMA_REPLACE = "";
}

View File

@@ -160,4 +160,9 @@ public class ZtProductController {
public Result projectTeamById(@RequestBody ZtProjectQo qo){ public Result projectTeamById(@RequestBody ZtProjectQo qo){
return Result.success(this.ztProductService.productTeamByPid(qo)); return Result.success(this.ztProductService.productTeamByPid(qo));
} }
@RequestMapping(value = "/getExecutionByProductId", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result getExecutionByProductId(@RequestBody ZtProjectQo qo){
return Result.success(ztProductService.getExecutionByProductId(qo));
}
} }

View File

@@ -8,11 +8,14 @@ import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.sa.zentao.constants.ExportConstants;
import com.sa.zentao.dao.*; import com.sa.zentao.dao.*;
import com.sa.zentao.entity.ZtProject; import com.sa.zentao.entity.ZtProject;
import com.sa.zentao.entity.ZtProjectproduct; import com.sa.zentao.entity.ZtProjectproduct;
import com.sa.zentao.entity.ZtStoryFeedback; import com.sa.zentao.entity.ZtStoryFeedback;
import com.sa.zentao.entity.ZtStoryUser;
import com.sa.zentao.enums.StoryStageEnums; import com.sa.zentao.enums.StoryStageEnums;
import com.sa.zentao.enums.StoryStatusEnums; import com.sa.zentao.enums.StoryStatusEnums;
import com.sa.zentao.enums.UserStoryEnums; import com.sa.zentao.enums.UserStoryEnums;
@@ -26,6 +29,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@@ -68,7 +72,7 @@ public class ZtStoryController {
@RequestMapping(value = "/storyExport", method = RequestMethod.POST) @RequestMapping(value = "/storyExport", method = RequestMethod.POST)
public void storyExport(@RequestBody ZtProjectQo qo, jakarta.servlet.ServletResponse response){ public void storyExport(@RequestBody ZtProjectQo qo, jakarta.servlet.ServletResponse response){
qo.setPageSize(1000000); qo.setPageSize(ExportConstants.MAX_EXPORT_SIZE);
PageInfo<ZtStoryDTO> p = ztStoryService.pageList(qo); PageInfo<ZtStoryDTO> p = ztStoryService.pageList(qo);
List<ZtStoryDTO> list = p.getList(); List<ZtStoryDTO> list = p.getList();
List<Integer> feedbackIds = list.stream().filter(o -> o.getFeedback() != null && o.getFeedback() != 0).map(o -> o.getFeedback()).collect(Collectors.toList()); List<Integer> feedbackIds = list.stream().filter(o -> o.getFeedback() != null && o.getFeedback() != 0).map(o -> o.getFeedback()).collect(Collectors.toList());
@@ -79,12 +83,12 @@ public class ZtStoryController {
ZtStoryFeedback ztStoryFeedback = feedbackMap.get(ztStoryUserDTO.getFeedback()); ZtStoryFeedback ztStoryFeedback = feedbackMap.get(ztStoryUserDTO.getFeedback());
if (ztStoryFeedback != null) { if (ztStoryFeedback != null) {
String reName=ztStoryFeedback.getId()+":"+ztStoryFeedback.getSpec(); String reName=ztStoryFeedback.getId()+ExportConstants.STRING_SEPARATOR+ztStoryFeedback.getSpec();
String reUrl = url+"/#/product-feedback-info/"+ztStoryFeedback.getId(); String reUrl = url+"/#/product-feedback-info/"+ztStoryFeedback.getId();
WriteCellData<String> hyperlink = new WriteCellData<>(reName); WriteCellData<String> hyperlink = new WriteCellData<>(reName);
HyperlinkData hyperlinkData = new HyperlinkData(); HyperlinkData hyperlinkData = new HyperlinkData();
try { try {
hyperlinkData.setAddress(reUrl.replace(" ", "%20")); hyperlinkData.setAddress(reUrl.replace(" ", ExportConstants.URL_SPACE_ENCODE));
hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL); hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);
hyperlink.setHyperlinkData(hyperlinkData); hyperlink.setHyperlinkData(hyperlinkData);
ztStoryUserDTO.setFeedbackSpecUrl(hyperlink ); ztStoryUserDTO.setFeedbackSpecUrl(hyperlink );
@@ -93,12 +97,12 @@ public class ZtStoryController {
} }
} }
if(ztStoryUserDTO.getParent()!=null&&ztStoryUserDTO.getParent()!=0){ if(ztStoryUserDTO.getParent()!=null&&ztStoryUserDTO.getParent()!=0){
String reName = ztStoryUserDTO.getParent()+":"+ztStoryUserDTO.getParentName(); String reName = ztStoryUserDTO.getParent()+ExportConstants.STRING_SEPARATOR+ztStoryUserDTO.getParentName();
String reUrl = url+"/#/product-story-info/"+ztStoryUserDTO.getParent(); String reUrl = url+"/#/product-story-info/"+ztStoryUserDTO.getParent();
WriteCellData<String> hyperlink = new WriteCellData<>(reName); WriteCellData<String> hyperlink = new WriteCellData<>(reName);
HyperlinkData hyperlinkData = new HyperlinkData(); HyperlinkData hyperlinkData = new HyperlinkData();
try { try {
hyperlinkData.setAddress(reUrl.replace(" ", "%20")); hyperlinkData.setAddress(reUrl.replace(" ", ExportConstants.URL_SPACE_ENCODE));
hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL); hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);
hyperlink.setHyperlinkData(hyperlinkData); hyperlink.setHyperlinkData(hyperlinkData);
ztStoryUserDTO.setParentNameUrl(hyperlink); ztStoryUserDTO.setParentNameUrl(hyperlink);
@@ -107,12 +111,12 @@ public class ZtStoryController {
} }
} }
if(ztStoryUserDTO.getUserStory()!=null&&ztStoryUserDTO.getUserStory()!=0){ if(ztStoryUserDTO.getUserStory()!=null&&ztStoryUserDTO.getUserStory()!=0){
String reName=ztStoryUserDTO.getUserStory()+":"+ztStoryUserDTO.getUserStoryName(); String reName=ztStoryUserDTO.getUserStory()+ExportConstants.STRING_SEPARATOR+ztStoryUserDTO.getUserStoryName();
String reUrl = url+"/#/product-user-story-info/"+ztStoryUserDTO.getUserStory(); String reUrl = url+"/#/product-user-story-info/"+ztStoryUserDTO.getUserStory();
WriteCellData<String> hyperlink = new WriteCellData<>(reName); WriteCellData<String> hyperlink = new WriteCellData<>(reName);
HyperlinkData hyperlinkData = new HyperlinkData(); HyperlinkData hyperlinkData = new HyperlinkData();
try { try {
hyperlinkData.setAddress(reUrl.replace(" ", "%20")); hyperlinkData.setAddress(reUrl.replace(" ", ExportConstants.URL_SPACE_ENCODE));
hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL); hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);
hyperlink.setHyperlinkData(hyperlinkData); hyperlink.setHyperlinkData(hyperlinkData);
ztStoryUserDTO.setUserStoryNameUrl(hyperlink); ztStoryUserDTO.setUserStoryNameUrl(hyperlink);
@@ -120,12 +124,12 @@ public class ZtStoryController {
ztStoryUserDTO.setUserStoryNameUrl(null); ztStoryUserDTO.setUserStoryNameUrl(null);
} }
} }
String reName=ztStoryUserDTO.getId()+":"+ztStoryUserDTO.getTitle(); String reName=ztStoryUserDTO.getId()+ExportConstants.STRING_SEPARATOR+ztStoryUserDTO.getTitle();
String reUrl = url+"/#/product-story-info/"+ztStoryUserDTO.getId(); String reUrl = url+"/#/product-story-info/"+ztStoryUserDTO.getId();
WriteCellData<String> hyperlink = new WriteCellData<>(reName); WriteCellData<String> hyperlink = new WriteCellData<>(reName);
HyperlinkData hyperlinkData = new HyperlinkData(); HyperlinkData hyperlinkData = new HyperlinkData();
try { try {
hyperlinkData.setAddress(reUrl.replace(" ", "%20")); hyperlinkData.setAddress(reUrl.replace(" ", ExportConstants.URL_SPACE_ENCODE));
hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL); hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);
hyperlink.setHyperlinkData(hyperlinkData); hyperlink.setHyperlinkData(hyperlinkData);
ztStoryUserDTO.setStoryUrl(hyperlink); ztStoryUserDTO.setStoryUrl(hyperlink);
@@ -134,7 +138,7 @@ public class ZtStoryController {
} }
if(!StringUtils.isEmpty(ztStoryUserDTO.getReviewedbyName())){ if(!StringUtils.isEmpty(ztStoryUserDTO.getReviewedbyName())){
ztStoryUserDTO.setReviewedbyName(ztStoryUserDTO.getReviewedbyName().replaceAll(",","")); ztStoryUserDTO.setReviewedbyName(ztStoryUserDTO.getReviewedbyName().replaceAll(ExportConstants.ID_SEPARATOR, ExportConstants.COMMA_REPLACE));
} }
ztStoryUserDTO.setStatus(StoryStatusEnums.transfer(ztStoryUserDTO.getStatus())==null?null:StoryStatusEnums.transfer(ztStoryUserDTO.getStatus()).getDesc()); ztStoryUserDTO.setStatus(StoryStatusEnums.transfer(ztStoryUserDTO.getStatus())==null?null:StoryStatusEnums.transfer(ztStoryUserDTO.getStatus()).getDesc());
ztStoryUserDTO.setStage(StoryStageEnums.transfer(ztStoryUserDTO.getStage())==null?null:StoryStageEnums.transfer(ztStoryUserDTO.getStage()).getDesc()); ztStoryUserDTO.setStage(StoryStageEnums.transfer(ztStoryUserDTO.getStage())==null?null:StoryStageEnums.transfer(ztStoryUserDTO.getStage()).getDesc());
@@ -142,10 +146,10 @@ public class ZtStoryController {
ztStoryUserDTO.setYsFlagName(ztStoryUserDTO.getYsFlag()==1?"通过":"不通过"); ztStoryUserDTO.setYsFlagName(ztStoryUserDTO.getYsFlag()==1?"通过":"不通过");
} }
if(!StringUtils.isEmpty(ztStoryUserDTO.getUserStoryName())){ if(!StringUtils.isEmpty(ztStoryUserDTO.getUserStoryName())){
ztStoryUserDTO.setUserStoryName(ztStoryUserDTO.getUserStoryId()+":"+ztStoryUserDTO.getUserStoryName()); ztStoryUserDTO.setUserStoryName(ztStoryUserDTO.getUserStoryId()+ExportConstants.STRING_SEPARATOR+ztStoryUserDTO.getUserStoryName());
} }
if(ztStoryUserDTO.getParent()!=null&&ztStoryUserDTO.getParent()!=0){ if(ztStoryUserDTO.getParent()!=null&&ztStoryUserDTO.getParent()!=0){
ztStoryUserDTO.setParentName(ztStoryUserDTO.getParent()+":"+ztStoryUserDTO.getParentName()); ztStoryUserDTO.setParentName(ztStoryUserDTO.getParent()+ExportConstants.STRING_SEPARATOR+ztStoryUserDTO.getParentName());
} }
} }
@@ -156,7 +160,7 @@ public class ZtStoryController {
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.needHead(Boolean.TRUE).build(); .needHead(Boolean.TRUE).build();
WriteSheet writeSheet = EasyExcel.writerSheet(0, "sheet1") WriteSheet writeSheet = EasyExcel.writerSheet(0, ExportConstants.SHEET_NAME)
.head(ZtStoryDTO.class) .head(ZtStoryDTO.class)
.needHead(Boolean.TRUE).build(); .needHead(Boolean.TRUE).build();
@@ -182,6 +186,27 @@ public class ZtStoryController {
} }
/**
* 测试提交验收
* @param qo
* @return
*/
@RequestMapping(value = "/testSubmitVerified", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result<ZtStoryDTO> testSubmitVerified(@RequestBody ZtStoryDTO qo){
ztStoryService.testSubmitVerified(qo);
return Result.success();
}
/**
* 产品验收通过
* @param qo
* @return
*/
@RequestMapping(value = "/storyProductUserYs", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result<ZtStoryDTO> storyProductUserYs(@RequestBody ZtStoryDTO qo){
ztStoryService.storyProductUserYs(qo);
return Result.success();
}
@RequestMapping(value = "/storyListByProject", method = RequestMethod.POST, produces = "application/json; charset=UTF-8") @RequestMapping(value = "/storyListByProject", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result<ZtStoryDTO> storyListByProject(@RequestBody ZtProjectQo qo){ public Result<ZtStoryDTO> storyListByProject(@RequestBody ZtProjectQo qo){
@@ -336,6 +361,26 @@ public class ZtStoryController {
List<ZtProject> list = ztStoryService.execListByProject(dto); List<ZtProject> list = ztStoryService.execListByProject(dto);
return Result.success(list); return Result.success(list);
} }
/**
* 指派产品人
* @param dto
* @return
*/
@RequestMapping(value = "/assignedToProductUser", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result assignedToProductUser(@RequestBody @Validated ZtStoryDTO dto){
this.ztStoryService.assignedToProductUser(dto);
return Result.success();
}
/**
* 指派测试人
* @param dto
* @return
*/
@RequestMapping(value = "/assignedToTestUser", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result assignedToTestUser(@RequestBody @Validated ZtStoryDTO dto){
this.ztStoryService.assignedToTestUser(dto);
return Result.success();
}

View File

@@ -7,10 +7,14 @@ import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.sa.zentao.conf.RiskUserThreadLocal;
import com.sa.zentao.dao.*; import com.sa.zentao.dao.*;
import com.sa.zentao.entity.ZtStory; import com.sa.zentao.entity.ZtStory;
import com.sa.zentao.entity.ZtStoryUser; import com.sa.zentao.entity.ZtStoryUser;
import com.sa.zentao.enums.ActionStatus;
import com.sa.zentao.enums.ActionType;
import com.sa.zentao.enums.UserStoryEnums; import com.sa.zentao.enums.UserStoryEnums;
import com.sa.zentao.qo.StoryQo; import com.sa.zentao.qo.StoryQo;
import com.sa.zentao.qo.ZtProjectQo; import com.sa.zentao.qo.ZtProjectQo;
@@ -19,6 +23,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.io.IOException; import java.io.IOException;
@@ -56,6 +61,17 @@ public class ZtStoryUserController {
return Result.success(); return Result.success();
} }
/**
* 指派产品人
* @param dto
* @return
*/
@RequestMapping(value = "/assignedToProductUser", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result assignedToProductUser(@RequestBody @Validated ZtStoryUserDTO dto){
this.storyUserService.assignedToProductUser(dto);
return Result.success();
}
@RequestMapping(value = "/addStory", method = RequestMethod.POST, produces = "application/json; charset=UTF-8") @RequestMapping(value = "/addStory", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result addStory(@RequestBody ZtStoryUserDTO dto){ public Result addStory(@RequestBody ZtStoryUserDTO dto){
@@ -124,7 +140,7 @@ public class ZtStoryUserController {
eq.in(ZtStoryUser::getStatus, UserStoryEnums.JH.getCode(),UserStoryEnums.CFM.getCode(),UserStoryEnums.KFZ.getCode()); eq.in(ZtStoryUser::getStatus, UserStoryEnums.JH.getCode(),UserStoryEnums.CFM.getCode(),UserStoryEnums.KFZ.getCode());
} }
eq.select(ZtStoryUser::getId,ZtStoryUser::getTitle,ZtStoryUser::getProduct, eq.select(ZtStoryUser::getId,ZtStoryUser::getTitle,ZtStoryUser::getProduct,
ZtStoryUser::getOpenedby,ZtStoryUser::getAssignedto,ZtStoryUser::getYsUser ZtStoryUser::getOpenedby,ZtStoryUser::getAssignedto,ZtStoryUser::getYsUser,ZtStoryUser::getProductUser
); );
List<ZtStoryUser> list = storyUserService.list(eq List<ZtStoryUser> list = storyUserService.list(eq
); );

View File

@@ -135,11 +135,11 @@ public class ZtUserController {
} }
eq.in(ZtUser::getAccount,execution.stream().map(o->o.getAccount()).collect(Collectors.toList())); eq.in(ZtUser::getAccount,execution.stream().map(o->o.getAccount()).collect(Collectors.toList()));
}else{ }else{
this.userMapper.selectOne(new QueryWrapper<ZtUser>().lambda().eq(ZtUser::getAccount,RiskUserThreadLocal.get().getName())); this.userMapper.selectOne(new QueryWrapper<ZtUser>().lambda()
.eq(ZtUser::getAccount,RiskUserThreadLocal.get().getName()));
} }
eq.eq(dto.getUserType()!=null,ZtUser::getUserType,dto.getUserType());
return Result.success(userService.list(eq return Result.success(userService.list(eq));
));
} }
@RequestMapping(value = "/storyReviewList", method = RequestMethod.POST, produces = "application/json; charset=UTF-8") @RequestMapping(value = "/storyReviewList", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")

View File

@@ -3,15 +3,33 @@ package com.sa.zentao.dao;
public class BusinessException extends RuntimeException { public class BusinessException extends RuntimeException {
public BusinessException(Code code){ public BusinessException(Code code){
super(code.getValue()); super(code.getValue());
this.code=code; this.code=code;
} }
public BusinessException(String value){ public BusinessException(String value){
super(value); super(value);
this.value=value; this.value=value;
} }
public BusinessException(Code code, String message){
super(message);
this.code=code;
this.value=message;
}
public BusinessException(String value, Throwable cause){
super(value, cause);
this.value=value;
}
public BusinessException(Code code, String message, Throwable cause){
super(message, cause);
this.code=code;
this.value=message;
}
public String value; public String value;
public Code code; public Code code;
} }

View File

@@ -4,7 +4,11 @@ public enum Code {
SUCCESS(0, "成功"), SUCCESS(0, "成功"),
FAIL(-1, "失败"), FAIL(-1, "失败"),
CFTJ(-2, "重复添加"), CFTJ(-2, "重复添加"),
PLEASELOGIN(401, "请登录"); PLEASELOGIN(401, "请登录"),
PARAM_ERROR(400, "参数错误"),
NOT_FOUND(404, "资源不存在"),
FORBIDDEN(403, "无权限访问"),
INTERNAL_ERROR(500, "系统内部错误");
private Integer code; private Integer code;
private String value; private String value;

View File

@@ -160,4 +160,26 @@ public class PerformanceDTO implements Serializable {
private BigDecimal professionalSkillEnhancementScore=BigDecimal.ZERO; private BigDecimal professionalSkillEnhancementScore=BigDecimal.ZERO;
//问题管理得分 //问题管理得分
private BigDecimal developFeedbackStory=BigDecimal.valueOf(10); private BigDecimal developFeedbackStory=BigDecimal.valueOf(10);
/**
* 产品经理
*/
// 产品缺陷率
private BigDecimal productBugRate=BigDecimal.ZERO;
//项目准时率 需求发布准时率 研发需求/用户需求
private BigDecimal productProjectOnTimeRateScore=BigDecimal.ZERO;
//主动性责任感
private BigDecimal productResponsibilityScore=BigDecimal.valueOf(5);
//需求会议
private BigDecimal productMeetScore=BigDecimal.valueOf(10);
//问题响应
private BigDecimal productProblemResponse=BigDecimal.valueOf(15);
//需求准确性
private BigDecimal accurateDemand=BigDecimal.valueOf(20);;
//产品规划
private BigDecimal productPlanning=BigDecimal.valueOf(10);;
//本阶段计划发布数量
private BigDecimal productPlanStoryNum;
//本阶段准时发布研发数量
private BigDecimal productPlanStoryOnTimeNum;
} }

View File

@@ -3,6 +3,7 @@ package com.sa.zentao.dao;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.sa.zentao.enums.UserType;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -205,6 +206,8 @@ public class ZtProjectDTO<T> implements Serializable {
private String deleted; private String deleted;
private UserType userType;
private List<T> children; private List<T> children;
private List<Integer> storyIds; private List<Integer> storyIds;

View File

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.sa.zentao.entity.ZtStoryCase; import com.sa.zentao.entity.ZtStoryCase;
import com.sa.zentao.entity.ZtStoryreview; import com.sa.zentao.entity.ZtStoryreview;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@@ -31,6 +32,7 @@ public class ZtStoryDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@NotNull(message = "请录入ID")
@ExcelProperty(value = "ID",index =0) @ExcelProperty(value = "ID",index =0)
private Integer id; private Integer id;
@ExcelProperty(value = "研发需求名称",index =1) @ExcelProperty(value = "研发需求名称",index =1)
@@ -48,6 +50,8 @@ public class ZtStoryDTO implements Serializable {
private Date planEndDate; private Date planEndDate;
@ExcelProperty(value = "阶段",index =6) @ExcelProperty(value = "阶段",index =6)
private String stage; private String stage;
@ExcelIgnore
private String stageName;
@ExcelProperty(value = "指派给",index =7) @ExcelProperty(value = "指派给",index =7)
private String assignedToName; private String assignedToName;
@@ -152,8 +156,36 @@ public class ZtStoryDTO implements Serializable {
private Integer frombug; private Integer frombug;
@ExcelIgnore @ExcelIgnore
private Integer feedback; private Integer feedback;
/**
* 产品人
*/
@ExcelIgnore
private String productUser;
/**
* 产品人
*/
@ExcelIgnore
private String productUserName;
@ExcelIgnore
private String productUserColor;
/**
* 产品人
*/
@ExcelIgnore
private String testUser;
@ExcelIgnore
private String testUserColor;
/**
* 产品人
*/
@ExcelIgnore
private String testUserName;
/**
* 1是否内部验收 0不需要
*/
@ExcelIgnore
private Integer innerYsFlag;
@ExcelIgnore @ExcelIgnore
private String keywords; private String keywords;
@@ -217,7 +249,6 @@ public class ZtStoryDTO implements Serializable {
private Date planYsDate; private Date planYsDate;
@ExcelIgnore @ExcelIgnore
private Date activateddate; private Date activateddate;
@ExcelIgnore @ExcelIgnore

View File

@@ -2,18 +2,25 @@ package com.sa.zentao.dao;
import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.metadata.data.HyperlinkData;
import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.metadata.data.WriteCellData;
import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.sa.zentao.entity.ZtProject;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable; import java.io.Serializable;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set;
/** /**
* <p> * <p>
@@ -25,12 +32,14 @@ import java.util.List;
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@Slf4j
public class ZtStoryUserDTO implements Serializable { public class ZtStoryUserDTO implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// @TableId(value = "id", type = IdType.AUTO) // @TableId(value = "id", type = IdType.AUTO)
// @ExcelProperty // @ExcelProperty
@NotNull(message = "ID不能为空")
@ExcelProperty(value = "ID",index =0) @ExcelProperty(value = "ID",index =0)
private Integer id; private Integer id;
@@ -46,6 +55,8 @@ public class ZtStoryUserDTO implements Serializable {
*/ */
@ExcelProperty(value = "关联研发需求",index =4) @ExcelProperty(value = "关联研发需求",index =4)
private String storyList; private String storyList;
@ExcelIgnore
private Set<ZtProject> execList;
@ExcelProperty(value = "状态",index =5) @ExcelProperty(value = "状态",index =5)
private String status; private String status;
@@ -130,6 +141,10 @@ public class ZtStoryUserDTO implements Serializable {
@ExcelIgnore @ExcelIgnore
private String color; private String color;
@ExcelIgnore @ExcelIgnore
private String productUserName;
@ExcelIgnore
private String productUserColor;
@ExcelIgnore
private String stage; private String stage;
@ExcelIgnore @ExcelIgnore
@@ -147,7 +162,7 @@ public class ZtStoryUserDTO implements Serializable {
private String openedby; private String openedby;
@NotBlank(message = "指派??")
@ExcelIgnore @ExcelIgnore
private String assignedto; private String assignedto;
@ExcelIgnore @ExcelIgnore
@@ -273,4 +288,30 @@ public class ZtStoryUserDTO implements Serializable {
//1.需要 2.不需要 //1.需要 2.不需要
@ExcelIgnore @ExcelIgnore
private Integer needImprove; private Integer needImprove;
/**
* 需求背景
*/
@ExcelIgnore
private String storyBackground;
/**
* 产品用户
*/
@ExcelIgnore
private String productUser;
public void setLinkUrl(String baseUrl) {
String reName = this.getTitle();
String reUrl = baseUrl + "/#/product-user-story-info/" + this.getId();
WriteCellData<String> hyperlink = new WriteCellData<>(reName);
HyperlinkData hyperlinkData = new HyperlinkData();
try {
hyperlinkData.setAddress(reUrl.replace(" ", "%20"));
hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);
hyperlink.setHyperlinkData(hyperlinkData);
this.setUrl(hyperlink);
} catch (Exception e) {
log.error(e.getMessage(), e);
this.setUrl(null);
}
}
} }

View File

@@ -212,4 +212,8 @@ public class ZtTaskDTO implements Serializable {
* 交付物 * 交付物
*/ */
private String deliverContent; private String deliverContent;
/**
* 1提交 0不提交
*/
private Integer innerYsFlag;
} }

View File

@@ -190,7 +190,12 @@ public class ZtStory implements Serializable {
private Date developedDate; private Date developedDate;
//结束日期 测试结束 //结束日期 测试结束
private Date endDate; private Date endDate;
//内部验收时间
@TableField(exist = false)
private Date innerYsTime;
//测试提交验收时间
@TableField(exist = false)
private Date testSubmitYsTime;
private Integer project; private Integer project;
//1通过 2不通过 //1通过 2不通过
private Integer ysFlag; private Integer ysFlag;
@@ -223,5 +228,16 @@ public class ZtStory implements Serializable {
// private Date develDate; // private Date develDate;
// //测试完成时间 // //测试完成时间
// private Date testedDate; // private Date testedDate;
/**
* 内部验收标识 1需要内部验收 0不需要
*/
private Integer innerYsFlag;
/**
* 产品人员
*/
private String productUser;
/**
* 测试人员
*/
private String testUser;
} }

View File

@@ -225,4 +225,9 @@ public class ZtStoryUser implements Serializable {
private String deliverRemark; private String deliverRemark;
private String oldStatus; private String oldStatus;
/**
* 产品用户
*/
private String productUser;
} }

View File

@@ -31,5 +31,6 @@ public class ZtStoryUserspec implements Serializable {
private String files; private String files;
private String storyBackground;
} }

View File

@@ -62,6 +62,12 @@ public enum ActionStatus {
XGMM(101, "xgmm","修改密码"), XGMM(101, "xgmm","修改密码"),
CZMM(102, "czmm","重置密码"), CZMM(102, "czmm","重置密码"),
CZINFO(103, "czmm","重置"), CZINFO(103, "czmm","重置"),
//测试提交验收
TESTSUBMITYS(200, "testSubmitYs","测试提交验收"),
PRODUCTYS(201, "productYs","产品验收"),
ASSIGNTOPRODUCTUSER(202, "assignProductUser","指派产品人"),
ASSIGNTOTESTUSER(203, "assignTestUser","指派测试人"),
; ;
@EnumValue @EnumValue

View File

@@ -0,0 +1,49 @@
package com.sa.zentao.enums;
public enum KanbanColumnType {
// 需求看板列类型
STORY_BACKLOG("backlog", "待办"),
STORY_DEVELOPING("developing", "研发中"),
STORY_DEVELOPED("developed", "研发完毕"),
STORY_TESTING("testing", "测试中"),
STORY_TESTED("tested", "测试完毕"),
STORY_RELEASED("released", "已发布"),
STORY_VERIFIED("verified", "已验收"),
STORY_CLOSED("closed", "已关闭"),
// Bug看板列类型
BUG_UNCONFIRMED("unconfirmed", "未确认"),
BUG_CONFIRMED("confirmed", "已确认"),
BUG_RESOLVED("resolved", "已解决"),
BUG_CLOSED("closed", "已关闭"),
// 任务看板列类型
TASK_WAIT("wait", "等待"),
TASK_DEVELOPING("developing", "进行中"),
TASK_DEVELOPED("developed", "已完成"),
TASK_CANCEL("cancel", "已取消"),
TASK_CLOSED("closed", "已关闭"),
// 通用列类型
WAIT("wait", "等待"),
DOING("doing", "进行中"),
DONE("done", "已完成"),
CLOSED("closed", "已关闭");
private String value;
private String desc;
private KanbanColumnType(String value, String desc) {
this.value = value;
this.desc = desc;
}
public String getValue() {
return this.value;
}
public String getDesc() {
return this.desc;
}
}

View File

@@ -16,6 +16,8 @@ public enum StoryStageEnums {
developed(10, "developed","研发完毕"), developed(10, "developed","研发完毕"),
testing(5, "testing","测试中"), testing(5, "testing","测试中"),
tested(6, "tested","测试完毕"), tested(6, "tested","测试完毕"),
productWaitVerified(9, "productWaitVerified","产品验收中"),
productVerified(10, "productVerified","产品已验收"),
released(7, "released","已发布"), released(7, "released","已发布"),
verified(8, "verified","已验收"), verified(8, "verified","已验收"),
; ;

View File

@@ -13,6 +13,7 @@ public enum UserType {
UI(7, "UI工程师"), UI(7, "UI工程师"),
XMJL(8, "项目经理"), XMJL(8, "项目经理"),
XMZL(9, "项目助理"), XMZL(9, "项目助理"),
CPJL(10, "产品经理"),
; ;
@EnumValue @EnumValue

View File

@@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Param;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* <p> * <p>
@@ -59,4 +60,7 @@ public interface ZtStoryMapper extends BaseMapper<ZtStory> {
* @return * @return
*/ */
List<SearchDTO> searchAll(@Param("keyword") String keyword,@Param("pIds")List<Integer> pIds); List<SearchDTO> searchAll(@Param("keyword") String keyword,@Param("pIds")List<Integer> pIds);
Map<String, Object> storyReleaseOnTimeByProducts(@Param("pIds") List<Integer> pids,
@Param("startTime") Date firstDayOfMonth,@Param("endTime") Date lastDayOfMonth);
} }

View File

@@ -22,6 +22,10 @@ public class StoryQo extends BaseQo {
private Integer productId; private Integer productId;
private String openedby; private String openedby;
private String status; private String status;
/**
* 用户产品
*/
private String productUser;
private List<Integer> productIds; private List<Integer> productIds;
private List<String> statusList; private List<String> statusList;

View File

@@ -37,7 +37,6 @@ public class ZtProjectQo extends BaseQo {
private String severity; private String severity;
private String productName; private String productName;
private Integer productId; private Integer productId;
private List<Integer> productIds; private List<Integer> productIds;
@@ -64,6 +63,8 @@ public class ZtProjectQo extends BaseQo {
private String status; private String status;
private List<String> statusList;
private List<String> stageList; private List<String> stageList;
private String title; private String title;
@@ -107,6 +108,14 @@ public class ZtProjectQo extends BaseQo {
private String spec; private String spec;
private String bugType; private String bugType;
/**
* 测试人员
*/
private String testUser;
/**
* 产品人员
*/
private String productUser;
private String account; private String account;
//1 延期 2不延期 //1 延期 2不延期

View File

@@ -57,4 +57,6 @@ public interface IZtProductService extends IService<ZtProduct> {
List<ZtProduct> productListByProgramName(String programName); List<ZtProduct> productListByProgramName(String programName);
PageInfo<ZtProjectDTO> getExecutionByProductId(ZtProjectQo qo);
} }

View File

@@ -57,7 +57,7 @@ public interface IZtStoryService extends IService<ZtStory> {
void waitStory(Integer story); void waitStory(Integer story);
void startStory(Integer story); void startStory(Integer story);
//开发完成 //开发完成
void finishStory(Integer story,String finishBy); void develFinishStory(Integer story,String finishBy);
//测试完毕 //测试完毕
void testedStory(Integer story,String finishBy); void testedStory(Integer story,String finishBy);
//测试中 //测试中
@@ -105,4 +105,15 @@ public interface IZtStoryService extends IService<ZtStory> {
List<ZtStory> getStoryListByDatePidsProject(List<Integer> pids, Integer id, Date firstDayOfMonth, Date lastDayOfMonth); List<ZtStory> getStoryListByDatePidsProject(List<Integer> pids, Integer id, Date firstDayOfMonth, Date lastDayOfMonth);
PageInfo<SearchDTO> searchByName(SearchQo qo); PageInfo<SearchDTO> searchByName(SearchQo qo);
void testSubmitVerified(ZtStoryDTO qo);
void storyProductUserYs(ZtStoryDTO qo);
Map<String, Object> storyReleaseOnTimeByProducts(@Param("pids") List<Integer> pids, @Param("startTime")Date firstDayOfMonth,
@Param("endTime")Date lastDayOfMonth);
void assignedToProductUser(ZtStoryDTO dto);
void assignedToTestUser(ZtStoryDTO dto);
} }

View File

@@ -54,4 +54,7 @@ public interface IZtStoryUserService extends IService<ZtStoryUser> {
void confirmStory(ZtStoryUserDTO dto); void confirmStory(ZtStoryUserDTO dto);
void needMeetOrDesign(ZtStoryUserDTO dto); void needMeetOrDesign(ZtStoryUserDTO dto);
void assignedToProductUser(ZtStoryUserDTO dto);
} }

View File

@@ -46,7 +46,9 @@ public class FestivalConfigServiceImpl extends ServiceImpl<FestivalConfigMapper,
List<FestivalConfig> festivalConfigs = this.baseMapper.selectList(new QueryWrapper<FestivalConfig>().lambda().eq(FestivalConfig::getName, qo.getName()). List<FestivalConfig> festivalConfigs = this.baseMapper.selectList(new QueryWrapper<FestivalConfig>().lambda()
.eq(FestivalConfig::getYear,qo.getYear())
.eq(FestivalConfig::getName, qo.getName()).
eq(FestivalConfig::getDeleteFlag, DeleteFlagEnum.USED)); eq(FestivalConfig::getDeleteFlag, DeleteFlagEnum.USED));
if(!CollectionUtils.isEmpty(festivalConfigs)){ if(!CollectionUtils.isEmpty(festivalConfigs)){
throw new BusinessException("已存在"); throw new BusinessException("已存在");

View File

@@ -1,5 +1,6 @@
package com.sa.zentao.service.impl; package com.sa.zentao.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnore;
@@ -242,7 +243,10 @@ public class IZtCountService {
.map(o -> o.getId() + "").collect(Collectors.joining(","))); .map(o -> o.getId() + "").collect(Collectors.joining(",")));
result.setTestingCount(ztStory.stream().filter(o -> "active".equals(o.getStatus())) result.setTestingCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
.filter(o -> Arrays.asList("testing", "tested").contains(o.getStage())).map(o -> o.getId() + "").collect(Collectors.joining(","))); .filter(o -> Arrays.asList("testing", "tested"
,StoryStageEnums.productWaitVerified.getValue()
,StoryStageEnums.productVerified.getValue()
).contains(o.getStage())).map(o -> o.getId() + "").collect(Collectors.joining(",")));
// developing 研发中 developed 研发完毕 testing 测试中 tested测试完毕 // developing 研发中 developed 研发完毕 testing 测试中 tested测试完毕
result.setJxzCount(ztStory.stream().filter(o -> "active".equals(o.getStatus())) result.setJxzCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
@@ -350,7 +354,10 @@ public class IZtCountService {
//0825 计划中和研发中合并 //0825 计划中和研发中合并
result.setJxzCount(ztStory.stream().filter(o -> "active".equals(o.getStatus())) result.setJxzCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
.filter(o -> Arrays.asList("wait","tested", "testing", "developed", "developing").contains(o.getStage()) .filter(o -> Arrays.asList("wait","tested", "testing", "developed", "developing"
,StoryStageEnums.productWaitVerified.getValue()
,StoryStageEnums.productVerified.getValue()).contains(o.getStage()
)
).map(o -> o.getId() + "").collect(Collectors.joining(","))); ).map(o -> o.getId() + "").collect(Collectors.joining(",")));
result.setCswbCount(ztStory.stream().filter(o -> "active".equals(o.getStatus())) result.setCswbCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
@@ -380,7 +387,7 @@ public class IZtCountService {
result = setFeedback(result, feedbacks); result = setFeedback(result, feedbacks);
} else if (userType == UserType.XMGLY || userType == UserType.XMZL) { } else if (userType == UserType.XMGLY || userType == UserType.XMZL||userType == UserType.CPJL) {
List<ZtProduct> pList = this.productService.listByIds(pIds); List<ZtProduct> pList = this.productService.listByIds(pIds);
@@ -412,7 +419,9 @@ public class IZtCountService {
.map(o -> o.getId() + "").collect(Collectors.joining(","))); .map(o -> o.getId() + "").collect(Collectors.joining(",")));
result.setTestingCount(ztStory.stream().filter(o -> "active".equals(o.getStatus())) result.setTestingCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
.filter(o -> Arrays.asList("testing", "tested").contains(o.getStage())).map(o -> o.getId() + "").collect(Collectors.joining(","))); .filter(o -> Arrays.asList("testing", "tested",StoryStageEnums.productVerified.getValue()
,StoryStageEnums.productWaitVerified.getValue()
).contains(o.getStage())).map(o -> o.getId() + "").collect(Collectors.joining(",")));
result.setJxzCount(ztStory.stream().filter(o -> "active".equals(o.getStatus())) result.setJxzCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
.filter(o -> Arrays.asList("developing", "developed").contains(o.getStage())).map(o -> o.getId() + "").collect(Collectors.joining(","))); .filter(o -> Arrays.asList("developing", "developed").contains(o.getStage())).map(o -> o.getId() + "").collect(Collectors.joining(",")));
@@ -543,6 +552,10 @@ public class IZtCountService {
continue; continue;
} }
performanceDTO=JSON.parseObject(ztMonthScore.getScopeJson(),PerformanceDTO.class); performanceDTO=JSON.parseObject(ztMonthScore.getScopeJson(),PerformanceDTO.class);
if (ztUser.getAccount().equals("weidongxia")) {
generatorCPJLExcel(qo, performanceDTO.getUserName(), performanceDTO, qo.getDate(), perList);
list.add(performanceDTO.getUserName() + "产品经理考核.xlsx");
} else
if (ztUser.getAccount().equals("liyuyan")) { if (ztUser.getAccount().equals("liyuyan")) {
generatorXMZLExcel(performanceDTO.getUserName(), performanceDTO, qo.getDate()); generatorXMZLExcel(performanceDTO.getUserName(), performanceDTO, qo.getDate());
list.add(performanceDTO.getUserName() + "项目助理考核.xlsx"); list.add(performanceDTO.getUserName() + "项目助理考核.xlsx");
@@ -564,6 +577,9 @@ public class IZtCountService {
} else if (ztUser.getUserType() == UserType.XMJL || ztUser.getUserType() == UserType.XMGLY || ztUser.getUserType() == UserType.GSGC) { } else if (ztUser.getUserType() == UserType.XMJL || ztUser.getUserType() == UserType.XMGLY || ztUser.getUserType() == UserType.GSGC) {
generatorXMJLExcel(qo, performanceDTO.getUserName(), performanceDTO, qo.getDate(), perList); generatorXMJLExcel(qo, performanceDTO.getUserName(), performanceDTO, qo.getDate(), perList);
list.add(performanceDTO.getUserName() + "项目经理考核.xlsx"); list.add(performanceDTO.getUserName() + "项目经理考核.xlsx");
}else if (ztUser.getUserType() == UserType.CPJL ) {
generatorCPJLExcel(qo, performanceDTO.getUserName(), performanceDTO, qo.getDate(), perList);
list.add(performanceDTO.getUserName() + "产品经理考核.xlsx");
} }
} }
String dir = System.getProperty("user.dir") + "/"; String dir = System.getProperty("user.dir") + "/";
@@ -725,7 +741,11 @@ public class IZtCountService {
for (ZtUser u : ztUsers) { for (ZtUser u : ztUsers) {
List<ItApproval> approvalList = this.taskService.itApprovalByUserName(u.getNickname(), firstDayOfMonth, lastDayOfMonth); List<ItApproval> approvalList = this.taskService.itApprovalByUserName(u.getNickname(), firstDayOfMonth, lastDayOfMonth);
if (u.getAccount().equals("liyuyan")) { if (u.getAccount().equals("weidongxia")||u.getUserType() == UserType.CPJL) {
ZtProjectQo ztProjectQo =new ZtProjectQo();
ztProjectQo.setDate(qo.getDate());
result.add(buildCPJLScore(u, userMap , ztProjectQo,approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d,pids));
}else if (u.getAccount().equals("liyuyan")) {
result.add(buildXMZLScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d)); result.add(buildXMZLScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d));
} else if ("liushengqing".equals(u.getAccount())) { } else if ("liushengqing".equals(u.getAccount())) {
result.add(buildUiScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d)); result.add(buildUiScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d));
@@ -1167,6 +1187,69 @@ public class IZtCountService {
return dto; return dto;
} }
PerformanceDTO buildCPJLScore(ZtUser u,Map<String, ZtUser> userMap,ZtProjectQo qo, List<ItApproval> approvalList, Date firstDayOfMonth, Date lastDayOfMonth, List<ZtTask> taskList, Date d,List<Integer> pids) {
/**
* 产品经理
*/
PerformanceDTO dto = new PerformanceDTO();
dto.setUserName(u.getNickname());
dto.setAccount(u.getAccount());
//项目准时率 Σ (当月上线准时上线的需求量) / Σ (当月规划上线的需求总量) * 100≥95%
// dto.setProjectOnTimeRate();
//产品缺陷率
// dto.setProductBugRate();
Map<String,Object> map=this.storyService.storyReleaseOnTimeByProducts(pids,firstDayOfMonth,lastDayOfMonth);
Integer planReleaseStoryNum = Integer.valueOf(map.getOrDefault("planReleaseStoryNum", 0).toString());
Integer storyOnTimeNum = Integer.valueOf(map.getOrDefault("onTimeNum", 0).toString());
dto.setProductPlanStoryNum(BigDecimal.valueOf(planReleaseStoryNum));
dto.setProductPlanStoryOnTimeNum(BigDecimal.valueOf(storyOnTimeNum));
int storyOnTimeRate = ObjectUtil.equal(planReleaseStoryNum, 0) ? 0 :
(BigDecimal.valueOf(storyOnTimeNum*100).divide(BigDecimal.valueOf(planReleaseStoryNum), 0, BigDecimal.ROUND_UP)).intValue();
int productProjectOnTimeRateScore=storyOnTimeRate==0?0: (storyOnTimeRate>=95)? 20:
(storyOnTimeRate>=90&&storyOnTimeRate<95)?(20-(95-storyOnTimeRate)):
((90-storyOnTimeRate)*2+5>20)? 0:(20-((90-storyOnTimeRate)*2+5));
dto.setProductProjectOnTimeRateScore(BigDecimal.valueOf(productProjectOnTimeRateScore));
List<ZtBug> allBugList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().select(SFunctionColums.bugColumes())
.eq(ZtBug::getOpenedby, u.getAccount())
.in(ZtBug::getBugType,"releaseBug","prod")
.ge(ZtBug::getOpeneddate,firstDayOfMonth)
.le(ZtBug::getOpeneddate,lastDayOfMonth)
.in(ZtBug::getProduct,pids));
allBugList = this.bugService.getNormalBugList(allBugList);
//开发分配工时
ZtCountQo ztCountQo = new ZtCountQo();
BeanUtils.copyProperties(qo, ztCountQo);
List<ZtProduct> ztProducts = this.productService.listByIds(pids);
List<PerformanceDTO> perList = this.programCount(ztCountQo,ztProducts.stream().map(o->o.getProgram()).collect(Collectors.toList()));
dto = buildTaskManage(dto, perList, userMap,firstDayOfMonth,lastDayOfMonth,pids);
//开发任务分配工时
BigDecimal allocationTime = dto.getAllocationTime();
double bugRate=(allocationTime.doubleValue()==0||allBugList.size()==0)?0:BigDecimal.valueOf(allBugList.size()*1000).divide(allocationTime,2,BigDecimal.ROUND_HALF_UP).doubleValue();
dto.setBugDensity(BigDecimal.valueOf(bugRate));
if(bugRate<=5){
dto.setBugScore(BigDecimal.valueOf(20));
}else{
// long deductBugScore = Math.min(seriousBug * 10L + slightBug * 3L, 20L);
// dto.setBugScore(BigDecimal.valueOf(20L-deductBugScore));
//严重10 分 轻微3分一个
int bugScore = 0;
for (ZtBug b : allBugList) {
bugScore += b.getSeverity() != 1 ? 3 : 10;
}
dto.setBugScore(bugScore>20?BigDecimal.ZERO:BigDecimal.valueOf((20 - bugScore)));
}
dto.setProductBugRate(dto.getBugScore());
//线上重大
dto.setSeriousBug(BigDecimal.valueOf(allBugList.stream().filter(o -> Arrays.asList(1).contains(o.getSeverity())).count()));
//线上轻微
dto.setSlightBug( BigDecimal.valueOf(allBugList.stream().filter(o -> Arrays.asList(4, 2, 3).contains(o.getSeverity())).count()));
return dto;
}
//满分30 //满分30
private PerformanceDTO getMeetScore(ZtUser u, Date start, Date end, PerformanceDTO dto) { private PerformanceDTO getMeetScore(ZtUser u, Date start, Date end, PerformanceDTO dto) {
List<Integer> pIds = this.projectService.authProductList(); List<Integer> pIds = this.projectService.authProductList();
@@ -1425,6 +1508,7 @@ public class IZtCountService {
Date thisDay = new Date(); Date thisDay = new Date();
thisDay.setMonth(date.getMonth()); thisDay.setMonth(date.getMonth());
thisDay.setDate(date.getDate()); thisDay.setDate(date.getDate());
thisDay.setYear(date.getYear());
thisDay.setHours(17); thisDay.setHours(17);
thisDay.setMinutes(30); thisDay.setMinutes(30);
thisDay.setSeconds(0); thisDay.setSeconds(0);
@@ -2197,7 +2281,52 @@ public class IZtCountService {
writeXlsx(name, "templates/scope/项目经理考核.xlsx", name + "项目经理考核.xlsx", dataMap); writeXlsx(name, "templates/scope/项目经理考核.xlsx", name + "项目经理考核.xlsx", dataMap);
} }
void generatorCPJLExcel(ZtCountQo qo, String name, PerformanceDTO performanceDTO, Date d, List<PerformanceDTO> perList) {
Map<String, ZtUser> userMap = userService.userMapByIds(null);
Map<String, String> dataMap = new HashMap<>();
dataMap.put("name", name);
dataMap.put("date", DateUtils.formatDate(d, "yyyy-MM"));
//产品规划
dataMap.put("productPlanning",performanceDTO.getProductPlanning()==null?"0":performanceDTO.getProductPlanning().toString());
//需求准确性
dataMap.put("accurateDemand", performanceDTO.getAccurateDemand()==null?"0": performanceDTO.getAccurateDemand().toString());
//项目准时率
dataMap.put("productProjectOnTimeRateScore",performanceDTO.getProductProjectOnTimeRateScore()==null?"0": performanceDTO.getProductProjectOnTimeRateScore().toString());
//线上Bug得分 缺陷
dataMap.put("bugScope", performanceDTO.getBugScore()==null?"0": performanceDTO.getBugScore().toString());
//开发分配工时
dataMap.put("allocationTime", performanceDTO.getBugScore()==null?"0": performanceDTO.getAllocationTime().toString());
//轻微
dataMap.put("slightBug", performanceDTO.getSlightBug()==null?"0": performanceDTO.getSlightBug().toString());
dataMap.put("seriousBug", performanceDTO.getSeriousBug()==null?"0": performanceDTO.getSeriousBug().toString());
//问题响应
dataMap.put("productProblemResponse", performanceDTO.getProductProblemResponse()==null?"0": performanceDTO.getProductProblemResponse().toString());
//会议管理
dataMap.put("productMeetScore", performanceDTO.getProductMeetScore()==null?"0": performanceDTO.getProductMeetScore().toString());
//主动性责任感
dataMap.put("productResponsibilityScore", performanceDTO.getProductResponsibilityScore()==null?"0": performanceDTO.getProductResponsibilityScore().toString());
dataMap.put("productPlanStoryNum", performanceDTO.getProductPlanStoryNum()==null?"0": performanceDTO.getProductPlanStoryNum().toString());
dataMap.put("productPlanStoryOnTimeNum", performanceDTO.getProductPlanStoryOnTimeNum()==null?"0": performanceDTO.getProductPlanStoryOnTimeNum().toString());
dataMap.put("allocationTime", performanceDTO.getAllocationTime()==null?"0": performanceDTO.getAllocationTime().toString());
dataMap.put("slightBug", performanceDTO.getSlightBug()==null?"0": performanceDTO.getSlightBug().toString());
dataMap.put("seriousBug", performanceDTO.getSeriousBug()==null?"0": performanceDTO.getSeriousBug().toString());
dataMap.put("bugDensity", performanceDTO.getBugDensity()==null?"0": performanceDTO.getBugDensity().toString());
dataMap.put("总分", devlopTotal(
dataMap.get("productPlanning"),
dataMap.get("accurateDemand"),
dataMap.get("productProjectOnTimeRateScore"),
dataMap.get("bugScope"),
dataMap.get("productProblemResponse"),
dataMap.get("productMeetScore"),
dataMap.get("productResponsibilityScore")
));
writeXlsx(name, "templates/scope/产品经理考核.xlsx", name + "产品经理考核.xlsx", dataMap);
}
private String versionPlanScore(ZtCountQo qo, List<PerformanceDTO> perList, Map<String, ZtUser> userMap) { private String versionPlanScore(ZtCountQo qo, List<PerformanceDTO> perList, Map<String, ZtUser> userMap) {
return "20"; return "20";
// BigDecimal allocationTime =BigDecimal.ZERO; // BigDecimal allocationTime =BigDecimal.ZERO;
@@ -2280,7 +2409,7 @@ public class IZtCountService {
//线上bug //线上bug
List<ZtBug> bList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().in(ZtBug::getProject, projectIds) List<ZtBug> bList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().in(ZtBug::getProject, projectIds)
.ge(ZtBug::getOpeneddate, firstDayOfMonth).le(ZtBug::getOpeneddate, lastDayOfMonth) .ge(ZtBug::getOpeneddate, firstDayOfMonth).le(ZtBug::getOpeneddate, lastDayOfMonth)
.eq(ZtBug::getBugType, "prod") .in(ZtBug::getBugType, "prod","releaseBug")
); );
if (CollectionUtils.isEmpty(bList)) { if (CollectionUtils.isEmpty(bList)) {
result.setBugScore(BigDecimal.valueOf(20)); result.setBugScore(BigDecimal.valueOf(20));
@@ -2303,9 +2432,9 @@ public class IZtCountService {
List<ZtBug> slightBugList = bList.stream().filter(o -> slights.contains(o.getSeverity())).collect(Collectors.toList()); List<ZtBug> slightBugList = bList.stream().filter(o -> slights.contains(o.getSeverity())).collect(Collectors.toList());
result.setSlightBug(BigDecimal.valueOf(slightBugList.size())); result.setSlightBug(BigDecimal.valueOf(slightBugList.size()));
BigDecimal bugRate = BigDecimal.valueOf(bList.size()).divide(BigDecimalUtils.isZero(allocationTime) ? BigDecimal.valueOf(1) : allocationTime, 2, BigDecimal.ROUND_HALF_UP); BigDecimal bugRate = BigDecimal.valueOf(bList.size()).divide(BigDecimalUtils.isZero(allocationTime) ? BigDecimal.valueOf(1) : allocationTime, 3, BigDecimal.ROUND_HALF_UP);
result.setBugDensity(bugRate); result.setBugDensity(bugRate);
int i = bugRate.multiply(BigDecimal.valueOf(100)).intValue(); int i = bugRate.multiply(BigDecimal.valueOf(1000)).intValue();
if (i <= 5) { if (i <= 5) {
result.setBugScore(BigDecimal.valueOf(20)); result.setBugScore(BigDecimal.valueOf(20));
return result; return result;
@@ -2367,10 +2496,6 @@ public class IZtCountService {
} }
private PerformanceDTO buildTaskManage(PerformanceDTO result, List<PerformanceDTO> perList, Map<String, ZtUser> userMap,Date startDate,Date endDate,List<Integer> pids) { private PerformanceDTO buildTaskManage(PerformanceDTO result, List<PerformanceDTO> perList, Map<String, ZtUser> userMap,Date startDate,Date endDate,List<Integer> pids) {
//多个项目组人员 //多个项目组人员
List multipUser = this.getmultipleDepartProjectTeam(startDate, endDate); List multipUser = this.getmultipleDepartProjectTeam(startDate, endDate);
//分配总工时 //分配总工时
@@ -2588,7 +2713,9 @@ public class IZtCountService {
//获取测试需求 //获取测试需求
List<ZtStory> cswcStoryList = this.storyService.list(new QueryWrapper<ZtStory>().lambda().in(ZtStory::getProduct, pids) List<ZtStory> cswcStoryList = this.storyService.list(new QueryWrapper<ZtStory>().lambda().in(ZtStory::getProduct, pids)
.in(ZtStory::getAssignedTo, Arrays.asList(u.getAccount())).ge(ZtStory::getReleaseddate, firstDayOfMonth).le(ZtStory::getReleaseddate, lastDayOfMonth)); .in(ZtStory::getAssignedTo, Arrays.asList(u.getAccount())).ge(ZtStory::getReleaseddate, firstDayOfMonth).le(ZtStory::getReleaseddate, lastDayOfMonth));
if (name.equals("weidongxia")) {
result = buildCPJLScore(u, userMap , qo,approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d,pids);
} else
if (name.equals("liyuyan")) { if (name.equals("liyuyan")) {
result = buildXMZLScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d); result = buildXMZLScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d);
} else if ("liushengqing".equals(name)) { } else if ("liushengqing".equals(name)) {
@@ -2616,6 +2743,9 @@ public class IZtCountService {
result.setProfessionalSkillEnhancementScore(BigDecimal.valueOf(0)); result.setProfessionalSkillEnhancementScore(BigDecimal.valueOf(0));
} else if (u.getUserType() == UserType.XMZL) { } else if (u.getUserType() == UserType.XMZL) {
result = buildXMZLScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d); result = buildXMZLScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d);
} else if (u.getUserType() == UserType.CPJL) {
//产品经理
result = buildCPJLScore(u, userMap , qo,approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d,pids);
} }
return result; return result;

View File

@@ -7,7 +7,9 @@ import com.sa.zentao.entity.*;
import com.sa.zentao.enums.ActionStatus; import com.sa.zentao.enums.ActionStatus;
import com.sa.zentao.enums.ActionType; import com.sa.zentao.enums.ActionType;
import com.sa.zentao.enums.KanbanCellType; import com.sa.zentao.enums.KanbanCellType;
import com.sa.zentao.enums.KanbanColumnType;
import com.sa.zentao.enums.ProjectTypeEnums; import com.sa.zentao.enums.ProjectTypeEnums;
import com.sa.zentao.utils.KanbanStageMapping;
import com.sa.zentao.mapper.ZtKanbancolumnMapper; import com.sa.zentao.mapper.ZtKanbancolumnMapper;
import com.sa.zentao.mapper.ZtKanbanlaneMapper; import com.sa.zentao.mapper.ZtKanbanlaneMapper;
import com.sa.zentao.qo.KanbanQo; import com.sa.zentao.qo.KanbanQo;
@@ -17,6 +19,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sa.zentao.utils.BeanCopyUtil; import com.sa.zentao.utils.BeanCopyUtil;
import com.sa.zentao.utils.DateUtils; import com.sa.zentao.utils.DateUtils;
import com.sa.zentao.utils.KanBanConstant; import com.sa.zentao.utils.KanBanConstant;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -37,6 +40,7 @@ import java.util.stream.Stream;
* @since 2024-07-09 * @since 2024-07-09
*/ */
@Service @Service
@Slf4j
public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtKanbanlane> implements IZtKanbanlaneService { public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtKanbanlane> implements IZtKanbanlaneService {
@Autowired @Autowired
@@ -116,6 +120,16 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
st.setAssignedToName(ztUser.getNickname()); st.setAssignedToName(ztUser.getNickname());
st.setColor(ztUser.getColor()); st.setColor(ztUser.getColor());
} }
ztUser = userMap.get(st.getProductUser());
if(ztUser!=null){
st.setProductUserName(ztUser.getNickname());
st.setProductUserColor(ztUser.getColor());
}
ztUser = userMap.get(st.getTestUser());
if(ztUser!=null){
st.setTestUserName(ztUser.getNickname());
st.setTestUserColor(ztUser.getColor());
}
if(product!=null){ if(product!=null){
st.setProductName(product.getName()); st.setProductName(product.getName());
} }
@@ -243,14 +257,14 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
this.kanbancellService.updateById(tokanbancell); this.kanbancellService.updateById(tokanbancell);
ActionType type= null; ActionType type= null;
if("story".equalsIgnoreCase(tabType)){ if(KanbanCellType.STORY.getValue().equalsIgnoreCase(tabType)){
type=ActionType.XQ; type=ActionType.XQ;
//需求 //需求
// storyChange(qo); // storyChange(qo);
//testing 测试中 //testing 测试中
} }
if("bug".equalsIgnoreCase(tabType)){ if(KanbanCellType.BUG.getValue().equalsIgnoreCase(tabType)){
type=ActionType.BUG; type=ActionType.BUG;
//bug //bug
// bugChange(qo); // bugChange(qo);
@@ -261,7 +275,7 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
//closed 关闭 //closed 关闭
} }
if("task".equalsIgnoreCase(tabType)){ if(KanbanCellType.TASK.getValue().equalsIgnoreCase(tabType)){
type=ActionType.RW; type=ActionType.RW;
//task //task
// taskChange(qo); // taskChange(qo);
@@ -273,7 +287,7 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
//完成有新任务回退到进行中 //完成有新任务回退到进行中
// //
// if("canceled".equalsIgnoreCase(statusType)){ // if(KanbanColumnType.TASK_CANCEL.getValue().equalsIgnoreCase(statusType)){
// //取消 // //取消
// } // }
@@ -303,12 +317,15 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
List<String> carIds = new ArrayList<>(Arrays.asList(cell.getCards().split(","))); List<String> carIds = new ArrayList<>(Arrays.asList(cell.getCards().split(",")));
if(carIds.contains(bussId.toString())){ if(carIds.contains(bussId.toString())){
thisZtKanbancell=cell; thisZtKanbancell=cell;
continue; break;
} }
} }
List<String> carIds = new ArrayList<>(Arrays.asList(thisZtKanbancell.getCards().split(","))); List<String> carIds = new ArrayList<>(Arrays.asList(thisZtKanbancell.getCards().split(",")));
while (carIds.contains(bussId.toString())) {
carIds.remove(bussId.toString()); carIds.remove(bussId.toString());
}
if(CollectionUtils.isEmpty(carIds)){ if(CollectionUtils.isEmpty(carIds)){
thisZtKanbancell.setCards(""); thisZtKanbancell.setCards("");
@@ -317,8 +334,13 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
thisZtKanbancell.setCards(StringUtils.join(carIds,",")); thisZtKanbancell.setCards(StringUtils.join(carIds,","));
} }
this.kanbancellService.updateById(thisZtKanbancell);
ZtKanbancell ztKanbanlane = this.baseMapper.getZtKanbanlane(type, toStatus, execId); ZtKanbancell ztKanbanlane = this.baseMapper.getZtKanbanlane(type, toStatus, execId);
if(ztKanbanlane==null){
log.info("看板未获取到execId={} bussId={} type={} toStatus={}", execId, bussId, type, toStatus);
return;
}
this.kanbancellService.updateById(thisZtKanbancell);
String cards = ztKanbanlane.getCards(); String cards = ztKanbanlane.getCards();
List l=StringUtils.isEmpty(cards)?new ArrayList<>():new ArrayList<>(Arrays.asList(cards.split(","))); List l=StringUtils.isEmpty(cards)?new ArrayList<>():new ArrayList<>(Arrays.asList(cards.split(",")));
l.add(bussId.toString()); l.add(bussId.toString());
@@ -329,7 +351,7 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
@Override @Override
public void addStory(Integer id, List<ZtStory> ztStories) { public void addStory(Integer id, List<ZtStory> ztStories) {
ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda() ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda()
.eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, "story")); .eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, KanbanCellType.STORY.getValue()));
List<ZtKanbancolumnDTO> ztKanbancolumnDTOS = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId())); List<ZtKanbancolumnDTO> ztKanbancolumnDTOS = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId()));
@@ -382,7 +404,7 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
public void addTask(Integer id, List<ZtTask> asList) { public void addTask(Integer id, List<ZtTask> asList) {
ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda() ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda()
.eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, "task")); .eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, KanbanCellType.TASK.getValue()));
List<ZtKanbancolumnDTO> kanbancolumnList = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId())); List<ZtKanbancolumnDTO> kanbancolumnList = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId()));
@@ -408,11 +430,13 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
@Override @Override
public void addBug(Integer id, List<ZtBug> asList) { public void addBug(Integer id, List<ZtBug> asList) {
ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda() ZtKanbanlane lane = this.baseMapper.selectOne(new QueryWrapper<ZtKanbanlane>().lambda()
.eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, "bug")); .eq(ZtKanbanlane::getExecution, id).eq(ZtKanbanlane::getType, KanbanCellType.BUG.getValue()));
List<ZtKanbancolumnDTO> ztKanbancolumnDTOS = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId())); List<ZtKanbancolumnDTO> ztKanbancolumnDTOS = this.kanbancolumnMapper.listByLaneIds(Arrays.asList(lane.getId()));
List<ZtKanbancolumnDTO> backlog = ztKanbancolumnDTOS.stream().filter(o -> o.getType().equals("unconfirmed")).collect(Collectors.toList()); List<ZtKanbancolumnDTO> backlog = ztKanbancolumnDTOS.stream()
.filter(o -> o.getType().equals(KanbanColumnType.BUG_UNCONFIRMED.getValue()))
.collect(Collectors.toList());
ZtKanbancolumnDTO ztKanbancolumnDTO = backlog.get(0); ZtKanbancolumnDTO ztKanbancolumnDTO = backlog.get(0);
ZtKanbancell kanbancell = this.kanbancellService.getOne(new QueryWrapper<ZtKanbancell>().lambda() ZtKanbancell kanbancell = this.kanbancellService.getOne(new QueryWrapper<ZtKanbancell>().lambda()

View File

@@ -88,17 +88,17 @@ public class ZtMeetingServiceImpl extends ServiceImpl<ZtMeetingMapper, ZtMeeting
Map<Integer,ZtStoryUser> sMap=getUserStoryMap(list); Map<Integer,ZtStoryUser> sMap=getUserStoryMap(list);
for (ZtMeetingDTO d:list) { for (ZtMeetingDTO d:list) {
StringBuilder b=new StringBuilder(); // StringBuilder b=new StringBuilder();
if(!StringUtils.isEmpty(d.getUsers())){ // if(!StringUtils.isEmpty(d.getUsers())){
String[] split = d.getUsers().split(","); // String[] split = d.getUsers().split(",");
for (String s:split) { // for (String s:split) {
ZtUser ztUser = userMap.get(s); // ZtUser ztUser = userMap.get(s);
if(ztUser!=null){ // if(ztUser!=null){
b.append(ztUser.getNickname()).append(","); // b.append(ztUser.getNickname()).append(",");
} // }
} // }
d.setUsersName(b.toString()); // d.setUsersName(b.toString());
} // }
StringBuilder storyStr=new StringBuilder(); StringBuilder storyStr=new StringBuilder();
if(!StringUtils.isEmpty( d.getStoryIds())){ if(!StringUtils.isEmpty( d.getStoryIds())){
String[] split = d.getStoryIds().split(","); String[] split = d.getStoryIds().split(",");

View File

@@ -1,6 +1,7 @@
package com.sa.zentao.service.impl; package com.sa.zentao.service.impl;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page; import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
@@ -687,4 +688,63 @@ public class ZtProductServiceImpl extends ServiceImpl<ZtProductMapper, ZtProduct
return ztProjectDTOS.stream().collect(Collectors.groupingBy(ZtProductDTO::getProgram)); return ztProjectDTOS.stream().collect(Collectors.groupingBy(ZtProductDTO::getProgram));
} }
@Override
public PageInfo<ZtProjectDTO> getExecutionByProductId(ZtProjectQo qo) {
Integer productId = qo.getProductId();
if (productId == null || productId == 0) {
throw new BusinessException("产品ID不能为空");
}
// 查询产品关联的项目
List<ZtProjectproduct> projectproductlist = this.projectproductService.list(
new QueryWrapper<ZtProjectproduct>().lambda()
.eq(ZtProjectproduct::getProduct, productId)
);
if (CollectionUtils.isEmpty(projectproductlist)) {
return new PageInfo<>();
}
// 获取项目ID列表
List<Integer> projectIds = projectproductlist.stream()
.map(ZtProjectproduct::getProject)
.collect(Collectors.toList());
// 查询项目关联的迭代
List<ZtExecutionproject> executionprojectList = this.executionprojectService.list(
new QueryWrapper<ZtExecutionproject>().lambda()
.in(ZtExecutionproject::getProject, projectIds)
);
if (CollectionUtils.isEmpty(executionprojectList)) {
return new PageInfo<>();
}
// 获取迭代ID列表
List<Integer> executionIds = executionprojectList.stream()
.map(ZtExecutionproject::getExecution)
.collect(Collectors.toList());
// 分页查询迭代按ID倒序排列
com.github.pagehelper.Page<ZtProjectDTO> page = PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
LambdaQueryWrapper<ZtProject> queryWrapper = new QueryWrapper<ZtProject>().lambda()
.in(ZtProject::getId, executionIds);
// 添加名称搜索
if (!StringUtils.isEmpty(qo.getName())) {
queryWrapper.like(ZtProject::getName, qo.getName());
}
queryWrapper.orderByDesc(ZtProject::getId);
List<ZtProject> executionList = this.projectService.list(queryWrapper);
// 转换为DTO
List<ZtProjectDTO> dtoList = BeanCopyUtil.copyListProperties(executionList, ZtProjectDTO::new);
PageInfo<ZtProjectDTO> ztProjectDTOPageInfo = new PageInfo<>(dtoList);
ztProjectDTOPageInfo.setTotal(page.getTotal());
return ztProjectDTOPageInfo;
}
} }

View File

@@ -260,7 +260,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
cell.setColumn(ztKanbancolumn.getId()); cell.setColumn(ztKanbancolumn.getId());
cell.setType(ztKanbanlane.getType()); cell.setType(ztKanbanlane.getType());
kanbancellService.save(cell); kanbancellService.save(cell);
} }
} }
} }
@@ -314,8 +313,11 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
public void projectClose(ZtProjectDTO dto) { public void projectClose(ZtProjectDTO dto) {
ZtProject ztProject = this.baseMapper.selectById(dto.getId()); ZtProject ztProject = this.baseMapper.selectById(dto.getId());
if (ztProject == null || "closed".equalsIgnoreCase(ztProject.getStatus())) { if (ztProject == null) {
throw new BusinessException("未查询到"); throw new BusinessException("未查询到项目项目ID: " + dto.getId());
}
if ("closed".equalsIgnoreCase(ztProject.getStatus())) {
throw new BusinessException("项目已关闭无法重复关闭项目ID: " + dto.getId());
} }
ztProject.setRealEnd(dto.getClosedDate()); ztProject.setRealEnd(dto.getClosedDate());
ztProject.setLastEditedDate(new Date()); ztProject.setLastEditedDate(new Date());
@@ -351,6 +353,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
@Override @Override
@Transactional
public void projectStart(ZtProjectDTO dto) { public void projectStart(ZtProjectDTO dto) {
ZtProject ztProject = this.baseMapper.selectById(dto.getId()); ZtProject ztProject = this.baseMapper.selectById(dto.getId());
if (ztProject == null || !"wait".equalsIgnoreCase(ztProject.getStatus())) { if (ztProject == null || !"wait".equalsIgnoreCase(ztProject.getStatus())) {
@@ -386,8 +389,11 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
@Override @Override
public void projectDeleted(ZtProjectDTO dto) { public void projectDeleted(ZtProjectDTO dto) {
ZtProject ztProject = this.baseMapper.selectById(dto.getId()); ZtProject ztProject = this.baseMapper.selectById(dto.getId());
if (ztProject == null || "1".equalsIgnoreCase(ztProject.getDeleted())) { if (ztProject == null) {
throw new BusinessException("未查询到"); throw new BusinessException("未查询到项目项目ID: " + dto.getId());
}
if ("1".equalsIgnoreCase(ztProject.getDeleted())) {
throw new BusinessException("项目已删除无法重复删除项目ID: " + dto.getId());
} }
ztProject.setDeleted("1"); ztProject.setDeleted("1");
ztProject.setCanceledBy(RiskUserThreadLocal.get().getName()); ztProject.setCanceledBy(RiskUserThreadLocal.get().getName());
@@ -422,8 +428,11 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
@Override @Override
public void projectActivated(ZtProjectDTO dto) { public void projectActivated(ZtProjectDTO dto) {
ZtProject ztProject = this.baseMapper.selectById(dto.getId()); ZtProject ztProject = this.baseMapper.selectById(dto.getId());
if (ztProject == null || !"closed".equalsIgnoreCase(ztProject.getStatus())) { if (ztProject == null) {
throw new BusinessException("未查询到"); throw new BusinessException("未查询到项目项目ID: " + dto.getId());
}
if (!"closed".equalsIgnoreCase(ztProject.getStatus())) {
throw new BusinessException("项目未关闭,无法激活,当前状态: " + ztProject.getStatus() + "项目ID: " + dto.getId());
} }
LambdaUpdateWrapper<ZtProject> updateWrapper = new UpdateWrapper<ZtProject>().lambda().set(ZtProject::getStatus, "doing") LambdaUpdateWrapper<ZtProject> updateWrapper = new UpdateWrapper<ZtProject>().lambda().set(ZtProject::getStatus, "doing")
.set(ZtProject::getRealEnd,null) .set(ZtProject::getRealEnd,null)
@@ -458,8 +467,11 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
@Override @Override
public void projectSuspended(ZtProjectDTO dto) { public void projectSuspended(ZtProjectDTO dto) {
ZtProject ztProject = this.baseMapper.selectById(dto.getId()); ZtProject ztProject = this.baseMapper.selectById(dto.getId());
if (ztProject == null || !"wait".equalsIgnoreCase(ztProject.getStatus())) { if (ztProject == null) {
throw new BusinessException("未查询到"); throw new BusinessException("未查询到项目项目ID: " + dto.getId());
}
if (!"wait".equalsIgnoreCase(ztProject.getStatus())) {
throw new BusinessException("项目状态不是等待状态,无法挂起,当前状态: " + ztProject.getStatus() + "项目ID: " + dto.getId());
} }
ztProject.setStatus("suspended"); ztProject.setStatus("suspended");
ztProject.setLastEditedBy(RiskUserThreadLocal.get().getName()); ztProject.setLastEditedBy(RiskUserThreadLocal.get().getName());
@@ -1941,9 +1953,9 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
List<ZtTask> allTaskList =this.taskService.taskListByEIdsAndDate(firstDayOfMonth,lastDayOfMonth,products.stream().map(o->o.getId()).collect(Collectors.toList())); List<ZtTask> allTaskList =this.taskService.taskListByEIdsAndDate(firstDayOfMonth,lastDayOfMonth,products.stream().map(o->o.getId()).collect(Collectors.toList()));
if (CollectionUtils.isEmpty(allTaskList)) { // if (CollectionUtils.isEmpty(allTaskList)) {
return new PageInfo<>(); // return new PageInfo<>();
} // }
List<ZtTeam> teams = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getType, "execution") List<ZtTeam> teams = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getType, "execution")

View File

@@ -112,7 +112,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
List<ZtStory> sList = this.storyService.list(new QueryWrapper<ZtStory>() List<ZtStory> sList = this.storyService.list(new QueryWrapper<ZtStory>()
.lambda().eq(ZtStory::getStatus, "active") .lambda().eq(ZtStory::getStatus, "active")
.in(ZtStory::getId, list.stream().map(o -> o.getStory()).distinct().collect(Collectors.toList())) .in(ZtStory::getId, list.stream().map(o -> o.getStory()).distinct().collect(Collectors.toList()))
.eq(ZtStory::getStage, StoryStageEnums.tested.getValue())); .eq(ZtStory::getStage, StoryStageEnums.productVerified.getValue()));
if (!CollectionUtils.isEmpty(sList)) { if (!CollectionUtils.isEmpty(sList)) {
//没有被关联的需求 测试完成的 //没有被关联的需求 测试完成的
List<ZtReleaseDetails> releaseStoryList = this.releaseDetailsService.list(new QueryWrapper<ZtReleaseDetails>().lambda() List<ZtReleaseDetails> releaseStoryList = this.releaseDetailsService.list(new QueryWrapper<ZtReleaseDetails>().lambda()
@@ -368,9 +368,9 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
List<ZtStory> ztStories = CollectionUtils.isEmpty(storyList)?new ArrayList<>():storyService.listByIds(storyList); List<ZtStory> ztStories = CollectionUtils.isEmpty(storyList)?new ArrayList<>():storyService.listByIds(storyList);
List<ZtBug> bugs =CollectionUtils.isEmpty(bugList)?new ArrayList<>(): bugService.listByIds(bugList); List<ZtBug> bugs =CollectionUtils.isEmpty(bugList)?new ArrayList<>(): bugService.listByIds(bugList);
long notTested = ztStories.stream().filter(o -> !o.getStage().equals("tested")).count(); List<ZtStory> notProductYsList = ztStories.stream().filter(o -> !o.getStage().equals(StoryStageEnums.productVerified.getValue())).toList();
if(notTested>0){ if(!CollectionUtils.isEmpty(notProductYsList)){
throw new BusinessException("当前需求存在未测试完成的请检查"); throw new BusinessException("当前需求存在未产品验收的需求请检查 id="+notProductYsList.get(0).getId()+" name="+notProductYsList.get(0).getTitle());
} }
//'active','resolved','closed'? //'active','resolved','closed'?
long count = bugs.stream().filter(o -> !Arrays.asList("resolved","closed").contains(o.getStatus())).count(); long count = bugs.stream().filter(o -> !Arrays.asList("resolved","closed").contains(o.getStatus())).count();
@@ -378,7 +378,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
throw new BusinessException("当前bug存在未完成请检查"); throw new BusinessException("当前bug存在未完成请检查");
} }
for (ZtStory st : ztStories) { for (ZtStory st : ztStories) {
if (!"tested".equals(st.getStage())) { if (! StoryStageEnums.productVerified.getValue().equals(st.getStage())) {
throw new BusinessException(st.getTitle() + " 当前需求无法发布,请检查"); throw new BusinessException(st.getTitle() + " 当前需求无法发布,请检查");
} }
this.storyService.releaseStory(st.getId()); this.storyService.releaseStory(st.getId());
@@ -391,8 +391,6 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
} }
if(!CollectionUtils.isEmpty(ztStories)){ if(!CollectionUtils.isEmpty(ztStories)){
sendReleaseMail(ztStories); sendReleaseMail(ztStories);
} }
} else { } else {
actionService.addAction(ActionType.FB, ActionStatus.FBSB, ztRelease.getId(), ztRelease.getProduct() + "", ztRelease.getProject(), null, actionService.addAction(ActionType.FB, ActionStatus.FBSB, ztRelease.getId(), ztRelease.getProduct() + "", ztRelease.getProject(), null,

View File

@@ -1,5 +1,6 @@
package com.sa.zentao.service.impl; package com.sa.zentao.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -156,6 +157,14 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if (ztUser != null) { if (ztUser != null) {
d.setUserStoryCreateUser(ztUser.getNickname()); d.setUserStoryCreateUser(ztUser.getNickname());
} }
ztUser = userMap.get(d.getProductUser());
if (ztUser != null) {
d.setProductUserName(ztUser.getNickname());
}
ztUser = userMap.get(d.getTestUser());
if (ztUser != null) {
d.setTestUserName(ztUser.getNickname());
}
List<ZtProject> ztProjectList = executionMapByStory.get(d.getId()); List<ZtProject> ztProjectList = executionMapByStory.get(d.getId());
if (!CollectionUtils.isEmpty(ztProjectList)) { if (!CollectionUtils.isEmpty(ztProjectList)) {
// d.setExecution(ztProject.getId()); // d.setExecution(ztProject.getId());
@@ -808,6 +817,8 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
for (ZtStoryDTO d : list) { for (ZtStoryDTO d : list) {
d.setRevieweUser(d.getReviewedby().replaceAll(",", "")); d.setRevieweUser(d.getReviewedby().replaceAll(",", ""));
d.setViews(rMap.get(d.getId())); d.setViews(rMap.get(d.getId()));
StoryStageEnums stageEnums = StoryStageEnums.transfer(d.getStage());
d.setStageName(stageEnums==null?null:stageEnums.getDesc());
List<ZtTask> ztTasks = taskCountMap.get(d.getId()); List<ZtTask> ztTasks = taskCountMap.get(d.getId());
ZtStoryCaseDTO ztStoryCaseDTO = caseMap.get(d.getId()); ZtStoryCaseDTO ztStoryCaseDTO = caseMap.get(d.getId());
if (ztStoryCaseDTO != null) { if (ztStoryCaseDTO != null) {
@@ -849,6 +860,14 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if (ztUser != null) { if (ztUser != null) {
d.setYsUserName(ztUser.getNickname()); d.setYsUserName(ztUser.getNickname());
} }
ztUser = userMap.get(d.getProductUser());
if (ztUser != null) {
d.setProductUserName(ztUser.getNickname());
}
ztUser = userMap.get(d.getTestUser());
if (ztUser != null) {
d.setTestUserName(ztUser.getNickname());
}
} }
} }
@@ -956,6 +975,105 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
return searchDTOPageInfo; return searchDTOPageInfo;
} }
@Override
@Transactional
public void testSubmitVerified(ZtStoryDTO qo) {
ZtStory ztStory = this.baseMapper.selectById(qo.getId());
if(ztStory==null){
throw new BusinessException("未查询到需求需求ID: " + qo.getId());
}
if(!StoryStatusEnums.active.getValue().equals(ztStory.getStatus())){
throw new BusinessException("需求状态不是激活状态,无法提交验收,当前状态: " + ztStory.getStatus() + "需求ID: " + qo.getId());
}
if(!StoryStageEnums.tested.getValue().equals(ztStory.getStage())){
throw new BusinessException("需求阶段不是测试完毕,无法提交验收,当前阶段: " + ztStory.getStage() + "需求ID: " + qo.getId());
}
if(!ObjectUtil.equal(ztStory.getInnerYsFlag(),1)){
throw new BusinessException("无需内部验收不需要提交需求ID: " + qo.getId());
}
//产品验收中
ztStory.setStage(StoryStageEnums.productWaitVerified.getValue());
ztStory.setTestSubmitYsTime(new Date());
ztStory.setLasteditedby(RiskUserThreadLocal.get().getName());
ztStory.setLastediteddate(new Date());
this.baseMapper.updateById(ztStory);
List<ZtProjectstory> ztProjectstories = this.projectstoryService.projectListByStory(Arrays.asList(ztStory.getId()), ProjectTypeEnums.execution);
//更改看板
if(!CollectionUtils.isEmpty(ztProjectstories)){
for(ZtProjectstory ztProjectstory:ztProjectstories){
kanbanlaneService.changeStatus(ztProjectstory.getProject(),ztStory.getId(),"story",StoryStageEnums.productWaitVerified.getValue());
}
}
actionService.addAction(ActionType.XQ, ActionStatus.TESTSUBMITYS, ztStory.getId(), ztStory.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), "", "");
}
@Override
public void storyProductUserYs(ZtStoryDTO qo) {
ZtStory ztStory = this.baseMapper.selectById(qo.getId());
if(ztStory==null){
throw new BusinessException("未查询到需求需求ID: " + qo.getId());
}
if(!StoryStatusEnums.active.getValue().equals(ztStory.getStatus())){
throw new BusinessException("需求状态不是激活状态,无法验收,当前状态: " + ztStory.getStatus() + "需求ID: " + qo.getId());
}
if(!StoryStageEnums.productWaitVerified.getValue().equals(ztStory.getStage())){
throw new BusinessException("需求阶段不是待验收状态,无法验收,当前阶段: " + ztStory.getStage() + "需求ID: " + qo.getId());
}
//产品验收中
ztStory.setStage(StoryStageEnums.productVerified.getValue());
ztStory.setLasteditedby(RiskUserThreadLocal.get().getName());
ztStory.setLastediteddate(new Date());
ztStory.setInnerYsTime(new Date());
this.baseMapper.updateById(ztStory);
List<ZtProjectstory> ztProjectstories = this.projectstoryService.projectListByStory(Arrays.asList(ztStory.getId()), ProjectTypeEnums.execution);
//更改看板
if(!CollectionUtils.isEmpty(ztProjectstories)){
for(ZtProjectstory ztProjectstory:ztProjectstories){
kanbanlaneService.changeStatus(ztProjectstory.getProject(),ztStory.getId(),"story",StoryStageEnums.productVerified.getValue());
}
}
actionService.addAction(ActionType.XQ, ActionStatus.PRODUCTYS, ztStory.getId(), ztStory.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), "", "");
}
@Override
public Map<String, Object> storyReleaseOnTimeByProducts(List<Integer> pids, Date firstDayOfMonth, Date lastDayOfMonth) {
return this.baseMapper.storyReleaseOnTimeByProducts(pids,firstDayOfMonth,lastDayOfMonth);
}
@Override
public void assignedToProductUser(ZtStoryDTO dto) {
ZtStory ztStory = this.baseMapper.selectById(dto.getId());
if(ztStory==null){
throw new BusinessException("未查询到数据");
}
ztStory.setProductUser(dto.getAssignedTo());
ztStory.setLastediteddate(new Date());
ztStory.setLasteditedby(RiskUserThreadLocal.get().getName());
this.baseMapper.updateById(ztStory);
actionService.addAction(ActionType.XQ, ActionStatus.ASSIGNTOPRODUCTUSER, ztStory.getId(), ztStory.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), "", dto.getAssignedTo());
}
@Override
public void assignedToTestUser(ZtStoryDTO dto) {
ZtStory ztStory = this.baseMapper.selectById(dto.getId());
if(ztStory==null){
throw new BusinessException("未查询到数据");
}
ztStory.setTestUser(dto.getAssignedTo());
ztStory.setLastediteddate(new Date());
ztStory.setLasteditedby(RiskUserThreadLocal.get().getName());
this.baseMapper.updateById(ztStory);
actionService.addAction(ActionType.XQ, ActionStatus.ASSIGNTOTESTUSER, ztStory.getId(), ztStory.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), "", dto.getAssignedTo());
}
private List<SearchDTO> searchBug(SearchQo qo) { private List<SearchDTO> searchBug(SearchQo qo) {
return this.baseMapper.searchBug(qo.getKeyword()); return this.baseMapper.searchBug(qo.getKeyword());
} }
@@ -1153,9 +1271,14 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
} }
} }
/**
* 开发完成
* @param id
* @param finishBy
*/
@Override @Override
@Transactional @Transactional
public void finishStory(Integer id, String finishBy) { public void develFinishStory(Integer id, String finishBy) {
if (id == null || id == 0) { if (id == null || id == 0) {
return; return;
@@ -1207,7 +1330,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
throw new BusinessException("未查询到数据-需求"); throw new BusinessException("未查询到数据-需求");
} }
if (!Arrays.asList("wait", "projected", "developing", "developed", "testing").contains(ztStory.getStage())) { if (!Arrays.asList("wait", "projected", "developing", "developed", "testing",StoryStageEnums.productWaitVerified.getValue(),StoryStageEnums.productVerified.getValue()).contains(ztStory.getStage())) {
return; return;
} }
@@ -1242,6 +1365,13 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
actionService.addAction(ActionType.XQ, ActionStatus.CSWC, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null, actionService.addAction(ActionType.XQ, ActionStatus.CSWC, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null,
RiskUserThreadLocal.get().getName(), null, ""); RiskUserThreadLocal.get().getName(), null, "");
} }
//不需要内部验收 产品已验收
if(!ObjectUtil.equal(ztStory.getInnerYsFlag(),1)){
newStatus = StoryStageEnums.productVerified.getValue();
ztStory.setStage(newStatus);
ztStory.setInnerYsTime(new Date());
}
if (ztStory.getStartDate() == null) { if (ztStory.getStartDate() == null) {
ztStory.setStartDate(new Date()); ztStory.setStartDate(new Date());
} }
@@ -1253,7 +1383,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
for (Integer execId : execIds) { for (Integer execId : execIds) {
if (execId != null) { if (execId != null) {
this.kanbanlaneService.changeStatus(execId, ztStory.getId(), "story", "tested"); this.kanbanlaneService.changeStatus(execId, ztStory.getId(), "story", newStatus);
if (!oldStatus.equalsIgnoreCase(newStatus) && ztStory.getProduct() != 0) { if (!oldStatus.equalsIgnoreCase(newStatus) && ztStory.getProduct() != 0) {
ProductStoryStatus oldPStatus = null; ProductStoryStatus oldPStatus = null;
@@ -1270,7 +1400,6 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
} }
//发布 //发布
@Override @Override
@Transactional @Transactional
@@ -1280,22 +1409,25 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
} }
ZtStory ztStory = this.baseMapper.selectById(story); ZtStory ztStory = this.baseMapper.selectById(story);
if (ztStory == null) {
throw new BusinessException("未查询到数据-需求");
}
if (ztStory.getFeedback() != null && ztStory.getFeedback() != 0) { if (ztStory.getFeedback() != null && ztStory.getFeedback() != 0) {
this.storyFeedbackService.feedbackFinished(ztStory.getFeedback(), null); this.storyFeedbackService.feedbackFinished(ztStory.getFeedback(), null);
} }
if (ztStory == null) {
throw new BusinessException("未查询到数据-需求");
}
if (!Arrays.asList("wait", "projected", "developing", "developed", "testing", "tested").contains(ztStory.getStage())) {
if (!Arrays.asList("wait", "projected", "developing", "developed", "testing", "tested",
StoryStageEnums.productWaitVerified.getValue()
,StoryStageEnums.productVerified.getValue()).contains(ztStory.getStage())) {
return; return;
} }
if ("closed".equals(ztStory.getStatus())) { if ("closed".equals(ztStory.getStatus())) {
throw new BusinessException("当前已关闭"); throw new BusinessException("当前已关闭");
} }
if (!"tested".equals(ztStory.getStage())) { if (!StoryStageEnums.productVerified.getValue().equals(ztStory.getStage())) {
throw new BusinessException("当前无法更改发布状态"); throw new BusinessException("当前无法更改发布状态");
} }
//这个需求被多少执行关联 //这个需求被多少执行关联
@@ -1358,16 +1490,10 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
@Override @Override
public void taskFinishChangeStatus(Integer story, String finishBy, TaskType type, Boolean cancelFlag) { public void taskFinishChangeStatus(Integer story, String finishBy, TaskType type, Boolean cancelFlag) {
ZtStory ztStory = this.getById(story); ZtStory ztStory = this.getById(story);
if(ztStory == null) { if(ztStory == null|| story == 0) {
return; return;
} }
if (ztStory != null && ztStory.getStatus().equals("closed")) { if (ztStory.getStatus().equals("closed")) {
return;
}
if (type != TaskType.test && type != TaskType.devel) {
// return;
}
if (story == null || story == 0) {
return; return;
} }
if (cancelFlag && type == TaskType.devel) { if (cancelFlag && type == TaskType.devel) {
@@ -1397,7 +1523,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if (!CollectionUtils.isEmpty(testedList)) { if (!CollectionUtils.isEmpty(testedList)) {
testedStory(story, finishBy); testedStory(story, finishBy);
} else { } else {
this.finishStory(story, finishBy); this.develFinishStory(story, finishBy);
} }
} }
@@ -1438,7 +1564,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
.eq(ZtTask::getType, TaskType.devel.getCode()) .eq(ZtTask::getType, TaskType.devel.getCode())
.in(ZtTask::getStatus, Arrays.asList("done"))); .in(ZtTask::getStatus, Arrays.asList("done")));
if (!CollectionUtils.isEmpty(develedList)) { if (!CollectionUtils.isEmpty(develedList)) {
this.finishStory(story, finishBy); this.develFinishStory(story, finishBy);
return; return;
} }
return; return;
@@ -1486,7 +1612,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if (done < 1) { if (done < 1) {
} else { } else {
this.finishStory(story, finishBy); this.develFinishStory(story, finishBy);
} }
} }
} else { } else {
@@ -2150,6 +2276,14 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if (ztUser != null) { if (ztUser != null) {
d.setYsUserName(ztUser.getNickname()); d.setYsUserName(ztUser.getNickname());
} }
ztUser = userMap.get(d.getProductUser());
if (ztUser != null) {
d.setProductUserName(ztUser.getNickname());
}
ztUser = userMap.get(d.getTestUser());
if (ztUser != null) {
d.setTestUserName(ztUser.getNickname());
}
ZtStoryspec storyspec = this.storyspecService.getOne(new QueryWrapper<ZtStoryspec>().lambda().eq(ZtStoryspec::getStory, d.getId())); ZtStoryspec storyspec = this.storyspecService.getOne(new QueryWrapper<ZtStoryspec>().lambda().eq(ZtStoryspec::getStory, d.getId()));
if (storyspec != null) { if (storyspec != null) {
@@ -2449,6 +2583,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
ProductStoryStatus oldPStatus = null; ProductStoryStatus oldPStatus = null;
if (status.equalsIgnoreCase("developing") || status.equalsIgnoreCase("testing") if (status.equalsIgnoreCase("developing") || status.equalsIgnoreCase("testing")
|| status.equalsIgnoreCase("tested") || status.equalsIgnoreCase("developed") || status.equalsIgnoreCase("tested") || status.equalsIgnoreCase("developed")
|| status.equalsIgnoreCase(StoryStageEnums.productWaitVerified.getValue())|| status.equalsIgnoreCase(StoryStageEnums.productVerified.getValue())
) { ) {
oldPStatus = ProductStoryStatus.JH; oldPStatus = ProductStoryStatus.JH;

View File

@@ -19,10 +19,7 @@ import com.sa.zentao.qo.StoryQo;
import com.sa.zentao.qo.ZtProjectQo; import com.sa.zentao.qo.ZtProjectQo;
import com.sa.zentao.service.*; import com.sa.zentao.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sa.zentao.utils.BeanCopyUtil; import com.sa.zentao.utils.*;
import com.sa.zentao.utils.BeanCopyUtilCallBack;
import com.sa.zentao.utils.SendEmail;
import com.sa.zentao.utils.VxMessageUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
@@ -81,6 +78,9 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
@Autowired @Autowired
private VxService vxService; private VxService vxService;
@Autowired
private IZtProjectstoryService projectstoryService;
@Value("${file.backUrl}") @Value("${file.backUrl}")
private String url; private String url;
@@ -125,6 +125,7 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
spec.setSpec(dto.getSpec()); spec.setSpec(dto.getSpec());
spec.setVerify(dto.getVerify()); spec.setVerify(dto.getVerify());
spec.setFiles(dto.getFileUrl()); spec.setFiles(dto.getFileUrl());
spec.setStoryBackground(dto.getStoryBackground());
return spec; return spec;
} }
@@ -220,7 +221,7 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
ztStory.setVerify(null); ztStory.setVerify(null);
this.baseMapper.updateById(ztStory); this.baseMapper.updateById(ztStory);
ZtStoryUserspec spec = this.storyUserspecService.getOne(new QueryWrapper<ZtStoryUserspec>().lambda().eq(ZtStoryUserspec::getStory, id)); ZtStoryUserspec spec = this.storyUserspecService.getOne(new QueryWrapper<ZtStoryUserspec>().lambda().eq(ZtStoryUserspec::getStory, id).last(" limit 1"));
if (spec == null) { if (spec == null) {
spec = new ZtStoryUserspec(); spec = new ZtStoryUserspec();
spec.setStory(id); spec.setStory(id);
@@ -229,6 +230,7 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
spec.setSpec(dto.getSpec()); spec.setSpec(dto.getSpec());
spec.setVerify(dto.getVerify()); spec.setVerify(dto.getVerify());
spec.setFiles(dto.getFileUrl()); spec.setFiles(dto.getFileUrl());
spec.setStoryBackground(dto.getStoryBackground());
storyUserspecService.save(spec); storyUserspecService.save(spec);
} else { } else {
spec.setVersion(1); spec.setVersion(1);
@@ -236,9 +238,11 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
spec.setSpec(dto.getSpec()); spec.setSpec(dto.getSpec());
spec.setVerify(dto.getVerify()); spec.setVerify(dto.getVerify());
spec.setFiles(dto.getFileUrl()); spec.setFiles(dto.getFileUrl());
spec.setStoryBackground(dto.getStoryBackground());
storyUserspecService.update(new UpdateWrapper<ZtStoryUserspec>().lambda().eq(ZtStoryUserspec::getStory, id) storyUserspecService.update(new UpdateWrapper<ZtStoryUserspec>().lambda().eq(ZtStoryUserspec::getStory, id)
.set(ZtStoryUserspec::getSpec, dto.getSpec()) .set(ZtStoryUserspec::getSpec, dto.getSpec())
.set(ZtStoryUserspec::getVerify, dto.getVerify()) .set(ZtStoryUserspec::getVerify, dto.getVerify())
.set(ZtStoryUserspec::getStoryBackground, dto.getStoryBackground())
.set(ZtStoryUserspec::getFiles, dto.getFileUrl()) .set(ZtStoryUserspec::getFiles, dto.getFileUrl())
); );
} }
@@ -246,16 +250,15 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
fileService.updateFile(dto.getFiles(), ztStory.getId(), FileTypes.userStory); fileService.updateFile(dto.getFiles(), ztStory.getId(), FileTypes.userStory);
} }
@Override @Override
public Map<String, List<ZtStoryUserDTO>> getKanban(Integer productId) { public Map<String, List<ZtStoryUserDTO>> getKanban(Integer productId) {
List<ZtStoryUser> ztStoryUsers = this.baseMapper.selectList(new QueryWrapper<ZtStoryUser>() List<ZtStoryUser> ztStoryUsers = this.baseMapper.selectList(new QueryWrapper<ZtStoryUser>()
.lambda().select(ZtStoryUser::getId,ZtStoryUser::getPri,ZtStoryUser::getTitle,ZtStoryUser::getStage,ZtStoryUser::getStatus,ZtStoryUser::getOpenedby,ZtStoryUser::getOpeneddate,ZtStoryUser::getLastediteddate) .lambda().select(ZtStoryUser::getId, ZtStoryUser::getPri, ZtStoryUser::getTitle, ZtStoryUser::getStage, ZtStoryUser::getStatus, ZtStoryUser::getOpenedby, ZtStoryUser::getOpeneddate, ZtStoryUser::getLastediteddate, ZtStoryUser::getProductUser)
.eq(ZtStoryUser::getProduct, productId).orderByDesc(ZtStoryUser::getId)); .eq(ZtStoryUser::getProduct, productId).orderByDesc(ZtStoryUser::getId));
Map<String, List<ZtStoryUserDTO>> map = new HashMap<>(); Map<String, List<ZtStoryUserDTO>> map = new HashMap<>();
Map<String, ZtUser> stringZtUserMap = this.userService.userMapByIds(ztStoryUsers.stream().map(o -> o.getOpenedby()).collect(Collectors.toList())); Map<String, ZtUser> stringZtUserMap = this.userService.userMapByIds(null);
List<ZtStoryUserDTO> ztStoryUserDTOS = BeanCopyUtil.copyListProperties(ztStoryUsers, ZtStoryUserDTO::new, new BeanCopyUtilCallBack<ZtStoryUser, ZtStoryUserDTO>() { List<ZtStoryUserDTO> ztStoryUserDTOS = BeanCopyUtil.copyListProperties(ztStoryUsers, ZtStoryUserDTO::new, new BeanCopyUtilCallBack<ZtStoryUser, ZtStoryUserDTO>() {
@Override @Override
@@ -265,6 +268,11 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
s.setOpenedbyName(ztUser.getNickname()); s.setOpenedbyName(ztUser.getNickname());
s.setColor(ztUser.getColor()); s.setColor(ztUser.getColor());
} }
ztUser = stringZtUserMap.get(t.getProductUser());
if (ztUser != null) {
s.setProductUserName(ztUser.getNickname());
s.setProductUserColor(ztUser.getColor());
}
} }
}); });
@@ -315,7 +323,9 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
Map<String, ZtUser> userMap = this.userService.userMapByIds(null); Map<String, ZtUser> userMap = this.userService.userMapByIds(null);
Map<Integer, List<ZtStory>> storyUserMap = getStoryUserMap(list); Map<Integer, List<ZtStory>> storyMap = getStoryMap(list);
//story - exec
Map<Integer,List<ZtProject>> execMap= getExecMap(storyMap);
Map<Integer, List<ZtStoryreviewDTO>> rMap = getReviewMap(list); Map<Integer, List<ZtStoryreviewDTO>> rMap = getReviewMap(list);
for (ZtStoryUserDTO d : list) { for (ZtStoryUserDTO d : list) {
@@ -359,32 +369,82 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
if (ztUser != null) { if (ztUser != null) {
d.setYsUserName(ztUser.getNickname()); d.setYsUserName(ztUser.getNickname());
} }
List<ZtStory> ztStories = storyUserMap.get(d.getId()); ztUser = userMap.get(d.getProductUser());
if (ztUser != null) {
d.setProductUserName(ztUser.getNickname());
}
List<ZtStory> ztStories = storyMap.get(d.getId());
if (!CollectionUtils.isEmpty(ztStories)) { if (!CollectionUtils.isEmpty(ztStories)) {
for (ZtStory story:ztStories){
List<ZtProject> execList = execMap.get(story.getId());
if(!CollectionUtils.isEmpty(execList)){
if(CollectionUtils.isEmpty(d.getExecList())){
d.setExecList(new HashSet<>());
}
d.getExecList().addAll(execList);
}
}
d.setStoryList(ztStories.stream().map(o -> o.getId() + ":" + o.getTitle()).collect(Collectors.joining(","))); d.setStoryList(ztStories.stream().map(o -> o.getId() + ":" + o.getTitle()).collect(Collectors.joining(",")));
d.setSList(CollectionUtils.isEmpty(ztStories) ? null : BeanCopyUtil.copyListProperties(ztStories, ZtStoryDTO::new)); d.setSList(CollectionUtils.isEmpty(ztStories) ? null : BeanCopyUtil.copyListProperties(ztStories, ZtStoryDTO::new));
} }
d.setLinkUrl(url);
String reName = d.getTitle();
String reUrl = url+"/#/product-user-story-info/"+d.getId();
WriteCellData<String> hyperlink = new WriteCellData<>(reName);
HyperlinkData hyperlinkData = new HyperlinkData();
try {
hyperlinkData.setAddress(reUrl.replace(" ", "%20"));
hyperlinkData.setHyperlinkType(HyperlinkData.HyperlinkType.URL);
hyperlink.setHyperlinkData(hyperlinkData);
d.setUrl(hyperlink );
} catch (Exception e) {
log.error(e.getMessage(), e);
d.setUrl(null );
}
} }
} }
return new PageInfo<ZtStoryUserDTO>(list); return new PageInfo<ZtStoryUserDTO>(list);
} }
private Map<Integer, List<ZtProject>> getExecMap(Map<Integer, List<ZtStory>> storyMap) {
if(storyMap==null||storyMap.isEmpty()){
return new HashMap<>();
}
// 收集到指定类型的列表比如ArrayList还可扩展去重、排序等
List<ZtStory> storyList = storyMap.values()
.stream()
.filter(list -> list != null)
.flatMap(List::stream)
// 自定义收集器指定ArrayList还可加.distinct()去重
.collect(Collectors.toCollection(ArrayList::new));
if(CollectionUtils.isEmpty(storyList)){
return new HashMap<>();
}
List<ZtProjectstory> list = this.projectstoryService.list(new QueryWrapper<ZtProjectstory>().lambda()
.eq(ZtProjectstory::getType,ProjectTypeEnums.execution.getValue())
.in(ZtProjectstory::getStory, storyList.stream().map(o -> o.getId()).collect(Collectors.toUnmodifiableList())));
if(CollectionUtils.isEmpty(list)){
return new HashMap<>();
}
List<ZtProject> ztExecList = this.projectService.listByIds(list.stream().map(o -> o.getProject()).collect(Collectors.toUnmodifiableList()));
if(CollectionUtils.isEmpty(list)){
return new HashMap<>();
}
// 第一步:先构建 projectId -> ZtProject 的映射(方便快速查找)
Map<Integer, ZtProject> projectIdToProjectMap = ztExecList.stream()
.collect(Collectors.toMap(
ZtProject::getId, // key项目ID
project -> project, // value项目对象
(existing, replacement) -> existing // 处理重复projectId的情况保留原有值
));
// 第二步按story分组收集对应的ZtProject列表
Map<Integer, List<ZtProject>> storyToProjectsMap = list.stream()
.collect(Collectors.groupingBy(
ZtProjectstory::getStory, // 分组keystory字段
// 分组value将每个ZtProjectstory对应的project转换成ZtProject并收集为列表
Collectors.mapping(
projectStory -> projectIdToProjectMap.get(projectStory.getProject()),
// 过滤掉null防止projectId不存在的情况并收集为List
Collectors.filtering(
project -> project != null,
Collectors.toList()
)
)
));
// 最终返回这个Map你可以根据需要调整返回逻辑
return storyToProjectsMap;
}
@Override @Override
@Transactional @Transactional
public void changeStatus(ZtStoryUserDTO dto) { public void changeStatus(ZtStoryUserDTO dto) {
@@ -477,7 +537,6 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
} }
lambda.set(ZtStoryreview::getReviewdate, new Date()); lambda.set(ZtStoryreview::getReviewdate, new Date());
lambda.eq(ZtStoryreview::getStory, ztStory.getId()); lambda.eq(ZtStoryreview::getStory, ztStory.getId());
lambda.eq(ZtStoryreview::getReviewer, RiskUserThreadLocal.get().getName()); lambda.eq(ZtStoryreview::getReviewer, RiskUserThreadLocal.get().getName());
@@ -518,10 +577,6 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
//添加action //添加action
actionService.addAction(ActionType.USERXQ, actionStatus, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null, actionService.addAction(ActionType.USERXQ, actionStatus, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null,
RiskUserThreadLocal.get().getName(), dto.getDesc(), ztStory.getAssignedto()); RiskUserThreadLocal.get().getName(), dto.getDesc(), ztStory.getAssignedto());
return null; return null;
} }
@@ -549,7 +604,11 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
if (ztUser != null) { if (ztUser != null) {
dto.setYsUserName(ztUser.getNickname()); dto.setYsUserName(ztUser.getNickname());
} }
Map<Integer, List<ZtStory>> storyUserMap = getStoryUserMap(Arrays.asList(dto)); ztUser = userMap.get(dto.getProductUser());
if (ztUser != null) {
dto.setProductUserName(ztUser.getNickname());
}
Map<Integer, List<ZtStory>> storyUserMap = getStoryMap(Arrays.asList(dto));
List<ZtStory> ztStories = storyUserMap.get(d.getId()); List<ZtStory> ztStories = storyUserMap.get(d.getId());
if (!CollectionUtils.isEmpty(ztStories)) { if (!CollectionUtils.isEmpty(ztStories)) {
dto.setStoryList(ztStories.stream().map(o -> o.getTitle()).collect(Collectors.joining(","))); dto.setStoryList(ztStories.stream().map(o -> o.getTitle()).collect(Collectors.joining(",")));
@@ -602,8 +661,9 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
List<ZtStory> list = this.storyService.list(new QueryWrapper<ZtStory>().lambda().eq(ZtStory::getUserStory, dto.getId())); List<ZtStory> list = this.storyService.list(new QueryWrapper<ZtStory>().lambda().eq(ZtStory::getUserStory, dto.getId()));
if (!CollectionUtils.isEmpty(list)) { if (!CollectionUtils.isEmpty(list)) {
List<ZtStoryDTO> storyDTOList = BeanCopyUtil.copyListProperties(list, ZtStoryDTO::new); List<ZtStoryDTO> storyDTOList = BeanCopyUtil.copyListProperties(list, ZtStoryDTO::new);
if (!CollectionUtils.isEmpty(storyDTOList)) { Map<Integer,List<ZtProject>> execMap= getExecMap(list.stream().collect(Collectors.groupingBy(ZtStory::getId)));
if (!CollectionUtils.isEmpty(storyDTOList)) {
for (ZtStoryDTO storyDTO : storyDTOList) { for (ZtStoryDTO storyDTO : storyDTOList) {
ztUser = userMap.get(storyDTO.getAssignedTo()); ztUser = userMap.get(storyDTO.getAssignedTo());
if (ztUser != null) { if (ztUser != null) {
@@ -613,10 +673,19 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
if (ztUser != null) { if (ztUser != null) {
storyDTO.setOpenedbyName(ztUser.getNickname()); storyDTO.setOpenedbyName(ztUser.getNickname());
} }
List<ZtProject> execList = execMap.get(storyDTO.getId());
if(!CollectionUtils.isEmpty(execList)){
if(CollectionUtils.isEmpty(dto.getExecList())){
dto.setExecList(new HashSet<>());
}
dto.getExecList().addAll(execList);
}
} }
dto.setSList(storyDTOList); dto.setSList(storyDTOList);
} }
//story - exec
} }
List<ZtStoryUserTask> tasks = this.storyUserTaskService.list(new QueryWrapper<ZtStoryUserTask>().lambda().eq(ZtStoryUserTask::getUserStoryId, dto.getId())); List<ZtStoryUserTask> tasks = this.storyUserTaskService.list(new QueryWrapper<ZtStoryUserTask>().lambda().eq(ZtStoryUserTask::getUserStoryId, dto.getId()));
if (!CollectionUtils.isEmpty(tasks)) { if (!CollectionUtils.isEmpty(tasks)) {
@@ -642,6 +711,7 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
ZtStoryUserspec ztStoryUserspec = specList.get(0); ZtStoryUserspec ztStoryUserspec = specList.get(0);
dto.setSpec(ztStoryUserspec.getSpec()); dto.setSpec(ztStoryUserspec.getSpec());
dto.setVerify(ztStoryUserspec.getVerify()); dto.setVerify(ztStoryUserspec.getVerify());
dto.setStoryBackground(ztStoryUserspec.getStoryBackground());
} }
return dto; return dto;
@@ -694,7 +764,6 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
} }
@Override @Override
public void changeStatus(Integer id, UserStoryEnums status) { public void changeStatus(Integer id, UserStoryEnums status) {
ZtStoryUser storyUser = this.baseMapper.selectById(id); ZtStoryUser storyUser = this.baseMapper.selectById(id);
@@ -867,7 +936,19 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
} }
} }
private Map<Integer, List<ZtStory>> getStoryUserMap(List<ZtStoryUserDTO> list) { @Override
public void assignedToProductUser(ZtStoryUserDTO dto) {
ZtStoryUser ztStoryUser = this.baseMapper.selectById(dto.getId());
if (ztStoryUser == null) {
throw new BusinessException("未查询到数据");
}
ztStoryUser.setProductUser(dto.getAssignedto());
this.baseMapper.updateById(ztStoryUser);
actionService.addAction(ActionType.USERXQ, ActionStatus.ASSIGNTOPRODUCTUSER, ztStoryUser.getId(), ztStoryUser.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), "", "");
}
private Map<Integer, List<ZtStory>> getStoryMap(List<ZtStoryUserDTO> list) {
List<Integer> ids = list.stream().map(o -> o.getId()).collect(Collectors.toList()); List<Integer> ids = list.stream().map(o -> o.getId()).collect(Collectors.toList());
List<ZtStory> list1 = storyService.list(new QueryWrapper<ZtStory>().lambda().in(ZtStory::getUserStory, ids)); List<ZtStory> list1 = storyService.list(new QueryWrapper<ZtStory>().lambda().in(ZtStory::getUserStory, ids));
@@ -905,14 +986,17 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
} }
} }
//发送消息给微信 产品已经设计 //发送消息给微信 产品已经设计
private void sendDesigndoneMessage(Integer id, String account) { private void sendDesigndoneMessage(Integer id, String account) {
this.vxService.sendMessageToVx(account, VxMessageUtils.storyUserMessage.designdoneMessage(id), new Date()); this.vxService.sendMessageToVx(account, VxMessageUtils.storyUserMessage.designdoneMessage(id), new Date());
} }
//发送消息给微信 提交交付物 //发送消息给微信 提交交付物
private void sendSubmitMessage(Integer id, String account) { private void sendSubmitMessage(Integer id, String account) {
this.vxService.sendMessageToVx(account, VxMessageUtils.storyUserMessage.submitMessage(id), new Date()); this.vxService.sendMessageToVx(account, VxMessageUtils.storyUserMessage.submitMessage(id), new Date());
} }
//确认交付物 //确认交付物
private void sendConfirmMessage(Integer id, String account) { private void sendConfirmMessage(Integer id, String account) {
this.vxService.sendMessageToVx(account, VxMessageUtils.storyUserMessage.sendConfirmMessage(id), new Date()); this.vxService.sendMessageToVx(account, VxMessageUtils.storyUserMessage.sendConfirmMessage(id), new Date());

View File

@@ -1,5 +1,6 @@
package com.sa.zentao.service.impl; package com.sa.zentao.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -231,6 +232,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
ZtStory ztStory = this.storyService.getById(story); ZtStory ztStory = this.storyService.getById(story);
if (ztStory != null) { if (ztStory != null) {
dto.setStoryName(ztStory.getTitle()); dto.setStoryName(ztStory.getTitle());
dto.setInnerYsFlag(ztStory.getInnerYsFlag());
} }
} }
@@ -577,7 +579,8 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
if (story != null && story != 0) { if (story != null && story != 0) {
ZtStory ztStory = this.storyService.getById(story); ZtStory ztStory = this.storyService.getById(story);
// wait 初始化 projected 已立项 developing 研发中 developed 研发完毕 testing 测试中 tested // wait 初始化 projected 已立项 developing 研发中 developed 研发完毕 testing 测试中 tested
if (!Arrays.asList("wait", "projected", "developing", "developed", "testing", "tested").contains(ztStory.getStage())) { if (!Arrays.asList("wait", "projected", "developing", "developed", "testing", "tested", StoryStageEnums.productWaitVerified.getValue()
, StoryStageEnums.productVerified.getValue()).contains(ztStory.getStage())) {
throw new BusinessException("当前状态无法添加任务"); throw new BusinessException("当前状态无法添加任务");
} }
if (ztStory.getStatus().equals("closed")) { if (ztStory.getStatus().equals("closed")) {
@@ -1034,6 +1037,13 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
actionService.addAction(ActionType.RW, ActionStatus.TJJFW, dto.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), ztTask.getExecution(), actionService.addAction(ActionType.RW, ActionStatus.TJJFW, dto.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), ztTask.getExecution(),
StringUtils.isEmpty(finishBy) ? RiskUserThreadLocal.get().getName() : finishBy, dto.getDeliverContent(), null); StringUtils.isEmpty(finishBy) ? RiskUserThreadLocal.get().getName() : finishBy, dto.getDeliverContent(), null);
if (ztTask.getStory() != null && ztTask.getStory() != 0) { if (ztTask.getStory() != null && ztTask.getStory() != 0) {
ZtStory ztStory = this.storyService.getById(ztTask.getStory());
if (ztStory != null) {
ztStory.setDeliverContent(dto.getDeliverContent());
ztStory.setLasteditedby(RiskUserThreadLocal.get().getName());
ztStory.setLastediteddate(new Date());
this.storyService.updateById(ztStory);
}
actionService.addAction(ActionType.XQ, ActionStatus.TJJFW, ztTask.getStory(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), ztTask.getExecution(), actionService.addAction(ActionType.XQ, ActionStatus.TJJFW, ztTask.getStory(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), ztTask.getExecution(),
StringUtils.isEmpty(finishBy) ? RiskUserThreadLocal.get().getName() : finishBy, dto.getDeliverContent(), null); StringUtils.isEmpty(finishBy) ? RiskUserThreadLocal.get().getName() : finishBy, dto.getDeliverContent(), null);
} }
@@ -1073,7 +1083,11 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
if (ztTask.getFeedback() != null && ztTask.getFeedback() != 0) { if (ztTask.getFeedback() != null && ztTask.getFeedback() != 0) {
this.storyFeedbackService.feedbackFinished(ztTask.getFeedback(), ztTask.getFeedbackRemark()); this.storyFeedbackService.feedbackFinished(ztTask.getFeedback(), ztTask.getFeedbackRemark());
} }
// if (ztTask.getStory() != null && ztTask.getStory() != 0 && ObjectUtil.equal(dto.getInnerYsFlag(), 1)) {
// ZtStoryDTO qo = new ZtStoryDTO();
// qo.setId(ztTask.getStory());
// this.storyService.testSubmitVerified(qo);
// }
} }
@Override @Override

View File

@@ -22,6 +22,8 @@ public class KanBanConstant {
put("test","测试"); put("test","测试");
put("testing","进行中"); put("testing","进行中");
put("tested","完成"); put("tested","完成");
put("productWaitVerified","产品验收中");
put("productVerified","产品已验收");
put("released","已发布"); put("released","已发布");
put("verified","已验收"); put("verified","已验收");
put("closed","已关闭"); put("closed","已关闭");
@@ -70,6 +72,8 @@ public class KanBanConstant {
put("story-test","test"); put("story-test","test");
put("story-testing","test"); put("story-testing","test");
put("story-tested","test"); put("story-tested","test");
put("story-productWaitVerified","productWaitVerified");
put("story-productVerified","productVerified");
put("story-verified","verified"); put("story-verified","verified");
put("story-released","released"); put("story-released","released");
put("story-closed","closed"); put("story-closed","closed");

View File

@@ -0,0 +1,87 @@
package com.sa.zentao.utils;
import com.sa.zentao.enums.KanbanColumnType;
import java.util.HashMap;
import java.util.Map;
/**
* 看板阶段映射工具类
* 用于将业务阶段映射到看板列类型
*/
public class KanbanStageMapping {
/**
* 需求阶段到看板列的映射
*/
private static final Map<String, KanbanColumnType> STORY_STAGE_MAP = new HashMap<>();
/**
* 任务状态到看板列的映射
*/
private static final Map<String, KanbanColumnType> TASK_STATUS_MAP = new HashMap<>();
static {
// 初始化需求阶段映射
STORY_STAGE_MAP.put("closed", KanbanColumnType.STORY_CLOSED);
STORY_STAGE_MAP.put("wait", KanbanColumnType.STORY_BACKLOG);
STORY_STAGE_MAP.put("projected", KanbanColumnType.STORY_BACKLOG);
STORY_STAGE_MAP.put("developing", KanbanColumnType.STORY_DEVELOPING);
STORY_STAGE_MAP.put("developed", KanbanColumnType.STORY_DEVELOPED);
STORY_STAGE_MAP.put("testing", KanbanColumnType.STORY_TESTING);
STORY_STAGE_MAP.put("tested", KanbanColumnType.STORY_TESTED);
STORY_STAGE_MAP.put("released", KanbanColumnType.STORY_RELEASED);
STORY_STAGE_MAP.put("verified", KanbanColumnType.STORY_VERIFIED);
// 初始化任务状态映射
TASK_STATUS_MAP.put("wait", KanbanColumnType.TASK_WAIT);
TASK_STATUS_MAP.put("reviewing", KanbanColumnType.TASK_WAIT);
TASK_STATUS_MAP.put("draft", KanbanColumnType.TASK_WAIT);
TASK_STATUS_MAP.put("doing", KanbanColumnType.TASK_DEVELOPING);
TASK_STATUS_MAP.put("done", KanbanColumnType.TASK_DEVELOPED);
TASK_STATUS_MAP.put("cancel", KanbanColumnType.TASK_CANCEL);
TASK_STATUS_MAP.put("closed", KanbanColumnType.TASK_CLOSED);
}
/**
* 根据需求阶段获取看板列类型
*
* @param stage 需求阶段
* @return 看板列类型
*/
public static KanbanColumnType getStoryColumnByStage(String stage) {
return STORY_STAGE_MAP.getOrDefault(stage, KanbanColumnType.STORY_BACKLOG);
}
/**
* 根据任务状态获取看板列类型
*
* @param status 任务状态
* @return 看板列类型
*/
public static KanbanColumnType getTaskColumnByStatus(String status) {
return TASK_STATUS_MAP.getOrDefault(status, KanbanColumnType.TASK_WAIT);
}
/**
* 获取需求阶段对应的看板列值
*
* @param stage 需求阶段
* @return 看板列值
*/
public static String getStoryColumnValue(String stage) {
KanbanColumnType columnType = getStoryColumnByStage(stage);
return columnType.getValue();
}
/**
* 获取任务状态对应的看板列值
*
* @param status 任务状态
* @return 看板列值
*/
public static String getTaskColumnValue(String status) {
KanbanColumnType columnType = getTaskColumnByStatus(status);
return columnType.getValue();
}
}

View File

@@ -136,30 +136,51 @@
s.ys_user, s.ys_user,
s.task_count, s.task_count,
s.ys_date, s.ys_date,
s.inner_ys_flag,
su.title userStoryName, su.title userStoryName,
su.id userStoryId, su.id userStoryId,
ps.title parentName, ps.title parentName,
su.openedDate userStoryCreateTime, su.openedDate userStoryCreateTime,
su.openedBy userStoryCreateUser, su.openedBy userStoryCreateUser,
s.devel_plan_end_time, s.devel_plan_end_time,
s.test_plan_end_time s.test_plan_end_time,
s.test_user,
s.product_user
from zt_story s from zt_story s
left join zt_story_user su on s.user_story = su.id left join zt_story_user su on s.user_story = su.id
left join zt_storyreview v on s.id = v.story and s.version = v.version left join zt_storyreview v on s.id = v.story and s.version = v.version
left join zt_story ps on s.parent = ps.id left join zt_story ps on s.parent = ps.id
<if test="qo.execution != null and qo.execution != '' ">
left join zt_projectstory pstory on s.id = pstory.story and pstory.type = 'execution'
</if>
where 1=1 where 1=1
and s.product = #{qo.productId} and s.product = #{qo.productId}
<if test="qo.execution != null and qo.execution != '' ">
and pstory.project = #{qo.execution }
</if>
<if test="qo.searchVal == 'ALL' "> <if test="qo.searchVal == 'ALL' ">
</if> </if>
<if test="qo.searchVal == 'WGB' "> <if test="qo.searchVal == 'WGB' ">
and s.status != 'closed' and s.status != 'closed'
</if>
<if test="qo.searchVal != null and qo.searchVal == 'WDCP' ">
and s.product_user = #{qo.userName}
</if>
<if test="qo.searchVal != null and qo.searchVal == 'WCS' ">
and s.test_user = #{qo.userName}
</if> </if>
<if test="qo.searchVal != null and qo.searchVal == 'ZGW' "> <if test="qo.searchVal != null and qo.searchVal == 'ZGW' ">
and s.assignedTo= #{qo.userName} and s.assignedTo= #{qo.userName}
</if> </if>
<if test="qo.searchVal != null and qo.searchVal == 'WDCP' ">
and s.product_user= #{qo.userName}
</if>
<if test="qo.searchVal != null and qo.searchVal == 'WCJ' "> <if test="qo.searchVal != null and qo.searchVal == 'WCJ' ">
and s.openedBy= #{qo.userName} and s.openedBy= #{qo.userName}
</if> </if>
@@ -213,12 +234,22 @@
and s.title like concat('%', #{qo.title}, '%') and s.title like concat('%', #{qo.title}, '%')
</if> </if>
<if test="qo.testUser != null and qo.testUser != '' ">
and s.test_user like concat('%', #{qo.testUser}, '%')
</if>
<if test="qo.productUser != null and qo.productUser != '' ">
and s.product_user like concat('%', #{qo.productUser}, '%')
</if>
<if test="qo.id != null "> <if test="qo.id != null ">
and s.id = #{qo.id} and s.id = #{qo.id}
</if> </if>
<if test="qo.title != null and qo.title != '' "> <if test="qo.title != null and qo.title != '' ">
and s.title like concat('%', #{qo.title}, '%') and s.title like concat('%', #{qo.title}, '%')
</if> </if>
<if test="qo.productUser != null and qo.productUser != '' ">
and s.product_user like concat('%', #{qo.productUser}, '%')
</if>
<if test="qo.module != null and qo.module != '' "> <if test="qo.module != null and qo.module != '' ">
and s.module = #{qo.module} and s.module = #{qo.module}
</if> </if>
@@ -240,6 +271,7 @@
and s.openedBy = #{qo.openedby} and s.openedBy = #{qo.openedby}
</if> </if>
<if test="qo.startDate !=null"> <if test="qo.startDate !=null">
and s.openedDate <![CDATA[>=]]> #{qo.startDate} and s.openedDate <![CDATA[>=]]> #{qo.startDate}
</if> </if>
@@ -263,10 +295,17 @@
open="(" close=")" separator=","> open="(" close=")" separator=",">
#{id} #{id}
</foreach> </foreach>
</if> </if>
<if test="qo.statusList != null and qo.statusList.size() > 0">
and s.status in
<foreach collection="qo.statusList" item="id" index="index"
open="(" close=")" separator=",">
#{id}
</foreach>
</if>
group by s.id group by s.id
<choose> <choose>
<when test="qo.orderName != '' and qo.orderName != null "> <when test="qo.orderName != '' and qo.orderName != null ">
<choose> <choose>
@@ -357,6 +396,9 @@
s.ys_date, s.ys_date,
s.devel_plan_end_time, s.devel_plan_end_time,
s.test_plan_end_time, s.test_plan_end_time,
s.inner_ys_flag,
s.product_user,
s.test_user,
pt.name productName pt.name productName
from zt_story s from zt_story s
@@ -366,14 +408,6 @@
left join zt_product pt on s.product = pt.id left join zt_product pt on s.product = pt.id
left join zt_projectstory ps on s.id = ps.story left join zt_projectstory ps on s.id = ps.story
WHERE 1=1 WHERE 1=1
<!-- <if test="qo.startDate !=null">-->
<!-- and s.openedDate <![CDATA[>=]]> #{qo.startDate}-->
<!-- </if>-->
<!-- <if test="qo.endDate !=null">-->
<!-- and s.openedDate <![CDATA[<=]]> #{qo.endDate}-->
<!-- </if>-->
<if test="qo.pri != null and qo.pri != '' "> <if test="qo.pri != null and qo.pri != '' ">
and s.pri = #{qo.pri} and s.pri = #{qo.pri}
</if> </if>
@@ -411,6 +445,12 @@
and s.title like concat('%', #{qo.name}, '%') and s.title like concat('%', #{qo.name}, '%')
</if> </if>
<if test="qo.testUser != null and qo.testUser != '' ">
and s.test_user like concat('%', #{qo.testUser}, '%')
</if>
<if test="qo.productUser != null and qo.productUser != '' ">
and s.product_user like concat('%', #{qo.productUser}, '%')
</if>
<if test="qo.productName != null and qo.productName != '' "> <if test="qo.productName != null and qo.productName != '' ">
and pt.name like concat('%', #{qo.productName}, '%') and pt.name like concat('%', #{qo.productName}, '%')
</if> </if>
@@ -455,7 +495,15 @@
and s.status ='reviewing' and s.status ='reviewing'
and v.result = '' and v.result = ''
</if> </if>
<if test="qo.searchVal != null and qo.searchVal == 'WDCP' ">
and s.product_user = #{qo.userName}
</if>
<if test="qo.searchVal != null and qo.searchVal == 'WCS' ">
and s.test_user = #{qo.userName}
</if>
<if test="qo.searchVal != null and qo.searchVal == 'WCC' ">
and s.assignedTo = #{qo.userName}
</if>
<if test="qo.searchVal == 'JH' "> <if test="qo.searchVal == 'JH' ">
and s.status = 'active' and s.status = 'active'
@@ -483,7 +531,9 @@
<if test="qo.searchVal == 'PSZ' "> <if test="qo.searchVal == 'PSZ' ">
and s.status = 'reviewing' and s.status = 'reviewing'
</if> </if>
<if test="qo.searchVal == 'WYS' ">
and s.ys_user = #{qo.userName}
</if>
<if test="qo.searchVal == 'DYS' "> <if test="qo.searchVal == 'DYS' ">
and ( s.stage = 'released' and ( s.stage = 'released'
@@ -563,8 +613,15 @@
open="(" close=")" separator=","> open="(" close=")" separator=",">
#{id} #{id}
</foreach> </foreach>
</if> </if>
<if test="qo.statusList != null and qo.statusList.size() > 0">
and s.status in
<foreach collection="qo.statusList" item="id" index="index"
open="(" close=")" separator=",">
#{id}
</foreach>
</if>
group by s.id group by s.id
@@ -592,7 +649,6 @@
</select> </select>
<select id="allStoryPageList" resultType="com.sa.zentao.dao.ZtStoryDTO"> <select id="allStoryPageList" resultType="com.sa.zentao.dao.ZtStoryDTO">
select s.id, select s.id,
s.vision, s.vision,
s.parent, s.parent,
@@ -879,7 +935,12 @@
WHERE 1=1 WHERE 1=1
<if test="qo.testUser != null and qo.testUser != '' ">
and s.test_user like concat('%', #{qo.testUser}, '%')
</if>
<if test="qo.productUser != null and qo.productUser != '' ">
and s.product_user like concat('%', #{qo.productUser}, '%')
</if>
<if test="qo.pri != null and qo.pri != '' "> <if test="qo.pri != null and qo.pri != '' ">
and s.pri = #{qo.pri} and s.pri = #{qo.pri}
@@ -952,8 +1013,15 @@
</if> </if>
<if test="qo.searchVal != null and qo.searchVal == 'WGB' "> <if test="qo.searchVal != null and qo.searchVal == 'WGB' ">
and s.status !='closed' and s.status !='closed'
</if> </if>
<if test="qo.searchVal != null and qo.searchVal == 'WDCP' ">
and s.product_user = #{qo.userName}
</if>
<if test="qo.searchVal != null and qo.searchVal == 'WCS' ">
and s.test_user = #{qo.userName}
</if>
<if test="qo.searchVal != null and qo.searchVal == 'ZGW' "> <if test="qo.searchVal != null and qo.searchVal == 'ZGW' ">
and s.assignedTo = #{qo.userName} and s.assignedTo = #{qo.userName}
</if> </if>
@@ -1034,8 +1102,15 @@
open="(" close=")" separator=","> open="(" close=")" separator=",">
#{id} #{id}
</foreach> </foreach>
</if> </if>
<if test="qo.statusList != null and qo.statusList.size() > 0">
and s.status in
<foreach collection="qo.statusList" item="id" index="index"
open="(" close=")" separator=",">
#{id}
</foreach>
</if>
group by s.id group by s.id
<choose> <choose>
@@ -1292,4 +1367,28 @@
and (spc.spec like concat('%', #{keyword}, '%') or spc.verify like concat('%', #{keyword}, '%') or st.title like concat('%', #{keyword}, '%') ) order by id desc ) and (spc.spec like concat('%', #{keyword}, '%') or spc.verify like concat('%', #{keyword}, '%') or st.title like concat('%', #{keyword}, '%') ) order by id desc )
</select> </select>
<select id="storyReleaseOnTimeByProducts" resultType="java.util.Map">
select (SELECT count(1) waitRelease from zt_story
WHERE plan_end_date >=#{startTime} and plan_end_date &lt;= #{endTime}
and status not in ('closed')
AND product in
<foreach collection="pIds" item="id" index="index"
open="(" close=")" separator=",">
#{id}
</foreach>) planReleaseStoryNum,
(SELECT count(1) waitRelease from zt_story
WHERE plan_end_date >=#{startTime} and plan_end_date &lt;=#{endTime} and releasedDate >=#{startTime}
and releasedDate &lt;=#{endTime}
and status not in ('closed')
AND product in
<foreach collection="pIds" item="id" index="index"
open="(" close=")" separator=",">
#{id}
</foreach>
) onTimeNum
from dual;
</select>
</mapper> </mapper>

View File

@@ -140,7 +140,7 @@
s.deliver_remark, s.deliver_remark,
s.old_status, s.old_status,
s.ys_user, s.ys_user,
s.product_user,
pt.name productName from zt_story_user s LEFT JOIN zt_product pt on s.product = pt.id WHERE 1=1 pt.name productName from zt_story_user s LEFT JOIN zt_product pt on s.product = pt.id WHERE 1=1
<if test="qo.productIds != null and qo.productIds.size() > 0"> <if test="qo.productIds != null and qo.productIds.size() > 0">
@@ -188,9 +188,9 @@
<if test="qo.productName != null and qo.productName != '' "> <if test="qo.productName != null and qo.productName != '' ">
and pt.name like concat('%', #{qo.productName}, '%') and pt.name like concat('%', #{qo.productName}, '%')
</if> </if>
<if test="qo.productUser != null and qo.productUser != '' ">
and s.product_user like concat('%', #{qo.productUser}, '%')
</if>
<if test="qo.searchVal == 'ALL' "> <if test="qo.searchVal == 'ALL' ">
@@ -199,10 +199,12 @@
and s.status != 'closed' and s.status != 'closed'
</if> </if>
<if test="qo.searchVal == 'WDCP' ">
and s.product_user = #{qo.userName}
</if>
<if test="qo.searchVal == 'WCJ' "> <if test="qo.searchVal == 'WCJ' ">
and s.openedby= #{qo.userName} and s.openedby= #{qo.userName}
</if> </if>
<if test="qo.id != null "> <if test="qo.id != null ">
and s.id = #{qo.id} and s.id = #{qo.id}
</if> </if>