diff --git a/pom.xml b/pom.xml index f997e28..647e22c 100644 --- a/pom.xml +++ b/pom.xml @@ -18,6 +18,17 @@ 3.3.0 + + org.springframework.boot + spring-boot-starter-validation + + + + + cn.hutool + hutool-all + 4.6.3 + com.itextpdf diff --git a/src/main/java/com/sa/zentao/controller/ZtStoryController.java b/src/main/java/com/sa/zentao/controller/ZtStoryController.java index b5b24b3..3d7588d 100644 --- a/src/main/java/com/sa/zentao/controller/ZtStoryController.java +++ b/src/main/java/com/sa/zentao/controller/ZtStoryController.java @@ -8,11 +8,13 @@ import com.alibaba.excel.metadata.data.WriteCellData; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.github.pagehelper.PageInfo; import com.sa.zentao.dao.*; import com.sa.zentao.entity.ZtProject; import com.sa.zentao.entity.ZtProjectproduct; import com.sa.zentao.entity.ZtStoryFeedback; +import com.sa.zentao.entity.ZtStoryUser; import com.sa.zentao.enums.StoryStageEnums; import com.sa.zentao.enums.StoryStatusEnums; import com.sa.zentao.enums.UserStoryEnums; @@ -26,6 +28,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.CollectionUtils; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -182,6 +185,27 @@ public class ZtStoryController { } + /** + * 测试提交验收 + * @param qo + * @return + */ + @RequestMapping(value = "/testSubmitVerified", method = RequestMethod.POST, produces = "application/json; charset=UTF-8") + public Result 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 storyProductUserYs(@RequestBody ZtStoryDTO qo){ + ztStoryService.storyProductUserYs(qo); + return Result.success(); + } + @RequestMapping(value = "/storyListByProject", method = RequestMethod.POST, produces = "application/json; charset=UTF-8") public Result storyListByProject(@RequestBody ZtProjectQo qo){ @@ -336,6 +360,26 @@ public class ZtStoryController { List list = ztStoryService.execListByProject(dto); 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(); + } diff --git a/src/main/java/com/sa/zentao/controller/ZtStoryUserController.java b/src/main/java/com/sa/zentao/controller/ZtStoryUserController.java index 3b798b9..686b97a 100644 --- a/src/main/java/com/sa/zentao/controller/ZtStoryUserController.java +++ b/src/main/java/com/sa/zentao/controller/ZtStoryUserController.java @@ -7,10 +7,14 @@ import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.github.pagehelper.PageInfo; +import com.sa.zentao.conf.RiskUserThreadLocal; import com.sa.zentao.dao.*; import com.sa.zentao.entity.ZtStory; 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.qo.StoryQo; import com.sa.zentao.qo.ZtProjectQo; @@ -19,6 +23,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import java.io.IOException; @@ -56,6 +61,17 @@ public class ZtStoryUserController { 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") public Result addStory(@RequestBody ZtStoryUserDTO dto){ diff --git a/src/main/java/com/sa/zentao/controller/ZtUserController.java b/src/main/java/com/sa/zentao/controller/ZtUserController.java index bdeaf2c..dfcc160 100644 --- a/src/main/java/com/sa/zentao/controller/ZtUserController.java +++ b/src/main/java/com/sa/zentao/controller/ZtUserController.java @@ -135,11 +135,11 @@ public class ZtUserController { } eq.in(ZtUser::getAccount,execution.stream().map(o->o.getAccount()).collect(Collectors.toList())); }else{ - this.userMapper.selectOne(new QueryWrapper().lambda().eq(ZtUser::getAccount,RiskUserThreadLocal.get().getName())); + this.userMapper.selectOne(new QueryWrapper().lambda() + .eq(ZtUser::getAccount,RiskUserThreadLocal.get().getName())); } - - return Result.success(userService.list(eq - )); + eq.eq(dto.getUserType()!=null,ZtUser::getUserType,dto.getUserType()); + return Result.success(userService.list(eq)); } @RequestMapping(value = "/storyReviewList", method = RequestMethod.POST, produces = "application/json; charset=UTF-8") diff --git a/src/main/java/com/sa/zentao/dao/PerformanceDTO.java b/src/main/java/com/sa/zentao/dao/PerformanceDTO.java index 55434c6..13411e5 100644 --- a/src/main/java/com/sa/zentao/dao/PerformanceDTO.java +++ b/src/main/java/com/sa/zentao/dao/PerformanceDTO.java @@ -160,4 +160,26 @@ public class PerformanceDTO implements Serializable { private BigDecimal professionalSkillEnhancementScore=BigDecimal.ZERO; //问题管理得分 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; } diff --git a/src/main/java/com/sa/zentao/dao/ZtProjectDTO.java b/src/main/java/com/sa/zentao/dao/ZtProjectDTO.java index 0dc7b63..9b165a0 100644 --- a/src/main/java/com/sa/zentao/dao/ZtProjectDTO.java +++ b/src/main/java/com/sa/zentao/dao/ZtProjectDTO.java @@ -3,6 +3,7 @@ package com.sa.zentao.dao; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; +import com.sa.zentao.enums.UserType; import lombok.Data; import lombok.EqualsAndHashCode; @@ -205,6 +206,8 @@ public class ZtProjectDTO implements Serializable { private String deleted; + private UserType userType; + private List children; private List storyIds; diff --git a/src/main/java/com/sa/zentao/dao/ZtStoryDTO.java b/src/main/java/com/sa/zentao/dao/ZtStoryDTO.java index 1c7f84d..973ad71 100644 --- a/src/main/java/com/sa/zentao/dao/ZtStoryDTO.java +++ b/src/main/java/com/sa/zentao/dao/ZtStoryDTO.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.sa.zentao.entity.ZtStoryCase; import com.sa.zentao.entity.ZtStoryreview; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; @@ -31,6 +32,7 @@ public class ZtStoryDTO implements Serializable { private static final long serialVersionUID = 1L; + @NotNull(message = "请录入ID") @ExcelProperty(value = "ID",index =0) private Integer id; @ExcelProperty(value = "研发需求名称",index =1) @@ -48,6 +50,8 @@ public class ZtStoryDTO implements Serializable { private Date planEndDate; @ExcelProperty(value = "阶段",index =6) private String stage; + @ExcelIgnore + private String stageName; @ExcelProperty(value = "指派给",index =7) private String assignedToName; @@ -152,8 +156,32 @@ public class ZtStoryDTO implements Serializable { private Integer frombug; @ExcelIgnore private Integer feedback; + /** + * 产品人 + */ + @ExcelIgnore + private String productUser; + /** + * 产品人 + */ + @ExcelIgnore + private String productUserName; + /** + * 产品人 + */ + @ExcelIgnore + private String testUser; + /** + * 产品人 + */ + @ExcelIgnore + private String testUserName; - + /** + * 1是否内部验收 0不需要 + */ + @ExcelIgnore + private Integer innerYsFlag; @ExcelIgnore private String keywords; @@ -217,7 +245,6 @@ public class ZtStoryDTO implements Serializable { private Date planYsDate; - @ExcelIgnore private Date activateddate; @ExcelIgnore diff --git a/src/main/java/com/sa/zentao/dao/ZtStoryUserDTO.java b/src/main/java/com/sa/zentao/dao/ZtStoryUserDTO.java index 2f0b99b..0ce81ab 100644 --- a/src/main/java/com/sa/zentao/dao/ZtStoryUserDTO.java +++ b/src/main/java/com/sa/zentao/dao/ZtStoryUserDTO.java @@ -6,8 +6,11 @@ import com.alibaba.excel.metadata.data.WriteCellData; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.NonNull; import java.io.Serializable; import java.time.LocalDate; @@ -31,6 +34,7 @@ public class ZtStoryUserDTO implements Serializable { // @TableId(value = "id", type = IdType.AUTO) // @ExcelProperty + @NotNull(message = "ID不能为空") @ExcelProperty(value = "ID",index =0) private Integer id; @@ -130,6 +134,10 @@ public class ZtStoryUserDTO implements Serializable { @ExcelIgnore private String color; @ExcelIgnore + private String productUserName; + @ExcelIgnore + private String productUserColor; + @ExcelIgnore private String stage; @ExcelIgnore @@ -147,7 +155,7 @@ public class ZtStoryUserDTO implements Serializable { private String openedby; - + @NotBlank(message = "指派??") @ExcelIgnore private String assignedto; @ExcelIgnore @@ -273,4 +281,10 @@ public class ZtStoryUserDTO implements Serializable { //1.需要 2.不需要 @ExcelIgnore private Integer needImprove; + + /** + * 产品用户 + */ + @ExcelIgnore + private String productUser; } diff --git a/src/main/java/com/sa/zentao/dao/ZtTaskDTO.java b/src/main/java/com/sa/zentao/dao/ZtTaskDTO.java index e2cb23d..8a29081 100644 --- a/src/main/java/com/sa/zentao/dao/ZtTaskDTO.java +++ b/src/main/java/com/sa/zentao/dao/ZtTaskDTO.java @@ -212,4 +212,8 @@ public class ZtTaskDTO implements Serializable { * 交付物 */ private String deliverContent; + /** + * 1提交 0不提交 + */ + private Integer innerYsFlag; } diff --git a/src/main/java/com/sa/zentao/entity/ZtStory.java b/src/main/java/com/sa/zentao/entity/ZtStory.java index 0455a44..effffcf 100644 --- a/src/main/java/com/sa/zentao/entity/ZtStory.java +++ b/src/main/java/com/sa/zentao/entity/ZtStory.java @@ -190,7 +190,12 @@ public class ZtStory implements Serializable { private Date developedDate; //结束日期 测试结束 private Date endDate; - + //内部验收时间 + @TableField(exist = false) + private Date innerYsTime; + //测试提交验收时间 + @TableField(exist = false) + private Date testSubmitYsTime; private Integer project; //1通过 2不通过 private Integer ysFlag; @@ -223,5 +228,16 @@ public class ZtStory implements Serializable { // private Date develDate; // //测试完成时间 // private Date testedDate; - + /** + * 内部验收标识 1需要内部验收 0不需要 + */ + private Integer innerYsFlag; + /** + * 产品人员 + */ + private String productUser; + /** + * 测试人员 + */ + private String testUser; } diff --git a/src/main/java/com/sa/zentao/entity/ZtStoryUser.java b/src/main/java/com/sa/zentao/entity/ZtStoryUser.java index e746de6..a5c83bf 100644 --- a/src/main/java/com/sa/zentao/entity/ZtStoryUser.java +++ b/src/main/java/com/sa/zentao/entity/ZtStoryUser.java @@ -225,4 +225,8 @@ public class ZtStoryUser implements Serializable { private String deliverRemark; private String oldStatus; + /** + * 产品用户 + */ + private String productUser; } diff --git a/src/main/java/com/sa/zentao/enums/ActionStatus.java b/src/main/java/com/sa/zentao/enums/ActionStatus.java index 701aa8a..c285fe9 100644 --- a/src/main/java/com/sa/zentao/enums/ActionStatus.java +++ b/src/main/java/com/sa/zentao/enums/ActionStatus.java @@ -62,6 +62,12 @@ public enum ActionStatus { XGMM(101, "xgmm","修改密码"), CZMM(102, "czmm","重置密码"), CZINFO(103, "czmm","重置"), + + //测试提交验收 + TESTSUBMITYS(200, "testSubmitYs","测试提交验收"), + PRODUCTYS(201, "productYs","产品验收"), + ASSIGNTOPRODUCTUSER(202, "assignProductUser","指派产品人"), + ASSIGNTOTESTUSER(203, "assignTestUser","指派测试人"), ; @EnumValue diff --git a/src/main/java/com/sa/zentao/enums/StoryStageEnums.java b/src/main/java/com/sa/zentao/enums/StoryStageEnums.java index 5268e39..b3b7a38 100644 --- a/src/main/java/com/sa/zentao/enums/StoryStageEnums.java +++ b/src/main/java/com/sa/zentao/enums/StoryStageEnums.java @@ -16,6 +16,8 @@ public enum StoryStageEnums { developed(10, "developed","研发完毕"), testing(5, "testing","测试中"), tested(6, "tested","测试完毕"), + productWaitVerified(9, "productWaitVerified","产品验收中"), + productVerified(10, "productVerified","产品已验收"), released(7, "released","已发布"), verified(8, "verified","已验收"), ; diff --git a/src/main/java/com/sa/zentao/enums/UserType.java b/src/main/java/com/sa/zentao/enums/UserType.java index b6ea646..f0defeb 100644 --- a/src/main/java/com/sa/zentao/enums/UserType.java +++ b/src/main/java/com/sa/zentao/enums/UserType.java @@ -13,6 +13,7 @@ public enum UserType { UI(7, "UI工程师"), XMJL(8, "项目经理"), XMZL(9, "项目助理"), + CPJL(10, "产品经理"), ; @EnumValue diff --git a/src/main/java/com/sa/zentao/mapper/ZtStoryMapper.java b/src/main/java/com/sa/zentao/mapper/ZtStoryMapper.java index 8b0ab39..347c065 100644 --- a/src/main/java/com/sa/zentao/mapper/ZtStoryMapper.java +++ b/src/main/java/com/sa/zentao/mapper/ZtStoryMapper.java @@ -10,6 +10,7 @@ import org.apache.ibatis.annotations.Param; import java.util.Date; import java.util.List; +import java.util.Map; /** *

@@ -59,4 +60,7 @@ public interface ZtStoryMapper extends BaseMapper { * @return */ List searchAll(@Param("keyword") String keyword,@Param("pIds")List pIds); + + Map storyReleaseOnTimeByProducts(@Param("pIds") List pids, + @Param("startTime") Date firstDayOfMonth,@Param("endTime") Date lastDayOfMonth); } diff --git a/src/main/java/com/sa/zentao/qo/StoryQo.java b/src/main/java/com/sa/zentao/qo/StoryQo.java index 497ddeb..22300c6 100644 --- a/src/main/java/com/sa/zentao/qo/StoryQo.java +++ b/src/main/java/com/sa/zentao/qo/StoryQo.java @@ -22,6 +22,10 @@ public class StoryQo extends BaseQo { private Integer productId; private String openedby; private String status; + /** + * 用户产品 + */ + private String productUser; private List productIds; private List statusList; diff --git a/src/main/java/com/sa/zentao/qo/ZtProjectQo.java b/src/main/java/com/sa/zentao/qo/ZtProjectQo.java index daa873f..b616861 100644 --- a/src/main/java/com/sa/zentao/qo/ZtProjectQo.java +++ b/src/main/java/com/sa/zentao/qo/ZtProjectQo.java @@ -37,7 +37,11 @@ public class ZtProjectQo extends BaseQo { private String severity; private String productName; - + /** + * 产品人 + */ + private String productUser; + private String testUser; private Integer productId; private List productIds; diff --git a/src/main/java/com/sa/zentao/service/IZtStoryService.java b/src/main/java/com/sa/zentao/service/IZtStoryService.java index 010a171..ec9b0c9 100644 --- a/src/main/java/com/sa/zentao/service/IZtStoryService.java +++ b/src/main/java/com/sa/zentao/service/IZtStoryService.java @@ -57,7 +57,7 @@ public interface IZtStoryService extends IService { void waitStory(Integer story); void startStory(Integer story); //开发完成 - void finishStory(Integer story,String finishBy); + void develFinishStory(Integer story,String finishBy); //测试完毕 void testedStory(Integer story,String finishBy); //测试中 @@ -105,4 +105,15 @@ public interface IZtStoryService extends IService { List getStoryListByDatePidsProject(List pids, Integer id, Date firstDayOfMonth, Date lastDayOfMonth); PageInfo searchByName(SearchQo qo); + + void testSubmitVerified(ZtStoryDTO qo); + + void storyProductUserYs(ZtStoryDTO qo); + + Map storyReleaseOnTimeByProducts(@Param("pids") List pids, @Param("startTime")Date firstDayOfMonth, + @Param("endTime")Date lastDayOfMonth); + + void assignedToProductUser(ZtStoryDTO dto); + + void assignedToTestUser(ZtStoryDTO dto); } diff --git a/src/main/java/com/sa/zentao/service/IZtStoryUserService.java b/src/main/java/com/sa/zentao/service/IZtStoryUserService.java index 8974572..2c7a6e3 100644 --- a/src/main/java/com/sa/zentao/service/IZtStoryUserService.java +++ b/src/main/java/com/sa/zentao/service/IZtStoryUserService.java @@ -54,4 +54,7 @@ public interface IZtStoryUserService extends IService { void confirmStory(ZtStoryUserDTO dto); void needMeetOrDesign(ZtStoryUserDTO dto); + + void assignedToProductUser(ZtStoryUserDTO dto); + } diff --git a/src/main/java/com/sa/zentao/service/impl/IZtCountService.java b/src/main/java/com/sa/zentao/service/impl/IZtCountService.java index 0609081..b1dad68 100644 --- a/src/main/java/com/sa/zentao/service/impl/IZtCountService.java +++ b/src/main/java/com/sa/zentao/service/impl/IZtCountService.java @@ -1,5 +1,6 @@ package com.sa.zentao.service.impl; +import cn.hutool.core.util.ObjectUtil; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.annotation.ExcelIgnore; @@ -242,7 +243,10 @@ public class IZtCountService { .map(o -> o.getId() + "").collect(Collectors.joining(","))); 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测试完毕 result.setJxzCount(ztStory.stream().filter(o -> "active".equals(o.getStatus())) @@ -350,7 +354,10 @@ public class IZtCountService { //0825 计划中和研发中合并 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(","))); result.setCswbCount(ztStory.stream().filter(o -> "active".equals(o.getStatus())) @@ -380,7 +387,7 @@ public class IZtCountService { result = setFeedback(result, feedbacks); - } else if (userType == UserType.XMGLY || userType == UserType.XMZL) { + } else if (userType == UserType.XMGLY || userType == UserType.XMZL||userType == UserType.CPJL) { List pList = this.productService.listByIds(pIds); @@ -412,7 +419,9 @@ public class IZtCountService { .map(o -> o.getId() + "").collect(Collectors.joining(","))); 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())) .filter(o -> Arrays.asList("developing", "developed").contains(o.getStage())).map(o -> o.getId() + "").collect(Collectors.joining(","))); @@ -543,6 +552,10 @@ public class IZtCountService { continue; } 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")) { generatorXMZLExcel(performanceDTO.getUserName(), performanceDTO, qo.getDate()); 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) { generatorXMJLExcel(qo, performanceDTO.getUserName(), performanceDTO, qo.getDate(), perList); 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") + "/"; @@ -1167,6 +1183,69 @@ public class IZtCountService { return dto; } + PerformanceDTO buildCPJLScore(ZtUser u,Map userMap,ZtProjectQo qo, List approvalList, Date firstDayOfMonth, Date lastDayOfMonth, List taskList, Date d,List pids) { + + /** + * 产品经理 + */ + PerformanceDTO dto = new PerformanceDTO(); + dto.setUserName(u.getNickname()); + dto.setAccount(u.getAccount()); + //项目准时率 Σ (当月上线准时上线的需求量) / Σ (当月规划上线的需求总量) * 100≥95% + +// dto.setProjectOnTimeRate(); + //产品缺陷率 +// dto.setProductBugRate(); + Map 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 allBugList = this.bugService.list(new QueryWrapper().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 ztProducts = this.productService.listByIds(pids); + List 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.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 private PerformanceDTO getMeetScore(ZtUser u, Date start, Date end, PerformanceDTO dto) { List pIds = this.projectService.authProductList(); @@ -2197,7 +2276,52 @@ public class IZtCountService { writeXlsx(name, "templates/scope/项目经理考核.xlsx", name + "项目经理考核.xlsx", dataMap); } + void generatorCPJLExcel(ZtCountQo qo, String name, PerformanceDTO performanceDTO, Date d, List perList) { + Map userMap = userService.userMapByIds(null); + Map 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().multiply(BigDecimal.valueOf(100)).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 perList, Map userMap) { return "20"; // BigDecimal allocationTime =BigDecimal.ZERO; @@ -2280,7 +2404,7 @@ public class IZtCountService { //线上bug List bList = this.bugService.list(new QueryWrapper().lambda().in(ZtBug::getProject, projectIds) .ge(ZtBug::getOpeneddate, firstDayOfMonth).le(ZtBug::getOpeneddate, lastDayOfMonth) - .eq(ZtBug::getBugType, "prod") + .in(ZtBug::getBugType, "prod","releaseBug") ); if (CollectionUtils.isEmpty(bList)) { result.setBugScore(BigDecimal.valueOf(20)); @@ -2303,9 +2427,9 @@ public class IZtCountService { List slightBugList = bList.stream().filter(o -> slights.contains(o.getSeverity())).collect(Collectors.toList()); 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); - int i = bugRate.multiply(BigDecimal.valueOf(100)).intValue(); + int i = bugRate.multiply(BigDecimal.valueOf(1000)).intValue(); if (i <= 5) { result.setBugScore(BigDecimal.valueOf(20)); return result; @@ -2367,10 +2491,6 @@ public class IZtCountService { } private PerformanceDTO buildTaskManage(PerformanceDTO result, List perList, Map userMap,Date startDate,Date endDate,List pids) { - - - - //多个项目组人员 List multipUser = this.getmultipleDepartProjectTeam(startDate, endDate); //分配总工时 @@ -2588,7 +2708,9 @@ public class IZtCountService { //获取测试需求 List cswcStoryList = this.storyService.list(new QueryWrapper().lambda().in(ZtStory::getProduct, pids) .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")) { result = buildXMZLScore(u, approvalList, firstDayOfMonth, lastDayOfMonth, taskList, d); } else if ("liushengqing".equals(name)) { @@ -2616,6 +2738,9 @@ public class IZtCountService { result.setProfessionalSkillEnhancementScore(BigDecimal.valueOf(0)); } else if (u.getUserType() == UserType.XMZL) { 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; diff --git a/src/main/java/com/sa/zentao/service/impl/ZtProjectServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtProjectServiceImpl.java index 2267ddc..aa4d873 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtProjectServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtProjectServiceImpl.java @@ -260,7 +260,6 @@ public class ZtProjectServiceImpl extends ServiceImpl allTaskList =this.taskService.taskListByEIdsAndDate(firstDayOfMonth,lastDayOfMonth,products.stream().map(o->o.getId()).collect(Collectors.toList())); - if (CollectionUtils.isEmpty(allTaskList)) { - return new PageInfo<>(); - } +// if (CollectionUtils.isEmpty(allTaskList)) { +// return new PageInfo<>(); +// } List teams = this.teamService.list(new QueryWrapper().lambda().eq(ZtTeam::getType, "execution") diff --git a/src/main/java/com/sa/zentao/service/impl/ZtReleaseServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtReleaseServiceImpl.java index 1cfd7c7..d071a2d 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtReleaseServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtReleaseServiceImpl.java @@ -112,7 +112,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl sList = this.storyService.list(new QueryWrapper() .lambda().eq(ZtStory::getStatus, "active") .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)) { //没有被关联的需求 测试完成的 List releaseStoryList = this.releaseDetailsService.list(new QueryWrapper().lambda() @@ -368,7 +368,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl ztStories = CollectionUtils.isEmpty(storyList)?new ArrayList<>():storyService.listByIds(storyList); List bugs =CollectionUtils.isEmpty(bugList)?new ArrayList<>(): bugService.listByIds(bugList); - long notTested = ztStories.stream().filter(o -> !o.getStage().equals("tested")).count(); + long notTested = ztStories.stream().filter(o -> !o.getStage().equals(StoryStageEnums.productVerified.getValue())).count(); if(notTested>0){ throw new BusinessException("当前需求存在未测试完成的请检查"); } @@ -378,7 +378,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl impl if (ztUser != null) { d.setUserStoryCreateUser(ztUser.getNickname()); } + ztUser = userMap.get(d.getProductUser()); + if (ztUser != null) { + d.setProductUserName(ztUser.getNickname()); + } List ztProjectList = executionMapByStory.get(d.getId()); if (!CollectionUtils.isEmpty(ztProjectList)) { // d.setExecution(ztProject.getId()); @@ -808,6 +813,8 @@ public class ZtStoryServiceImpl extends ServiceImpl impl for (ZtStoryDTO d : list) { d.setRevieweUser(d.getReviewedby().replaceAll(",", "")); d.setViews(rMap.get(d.getId())); + StoryStageEnums stageEnums = StoryStageEnums.transfer(d.getStage()); + d.setStageName(stageEnums==null?null:stageEnums.getDesc()); List ztTasks = taskCountMap.get(d.getId()); ZtStoryCaseDTO ztStoryCaseDTO = caseMap.get(d.getId()); if (ztStoryCaseDTO != null) { @@ -849,6 +856,14 @@ public class ZtStoryServiceImpl extends ServiceImpl impl if (ztUser != null) { 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 +971,105 @@ public class ZtStoryServiceImpl extends ServiceImpl impl return searchDTOPageInfo; } + @Override + @Transactional + public void testSubmitVerified(ZtStoryDTO qo) { + ZtStory ztStory = this.baseMapper.selectById(qo.getId()); + if(ztStory==null){ + throw new BusinessException("未查询到需求"); + } + if(!StoryStatusEnums.active.getValue().equals(ztStory.getStatus())){ + throw new BusinessException("需求状态不对"); + } + if(!StoryStageEnums.tested.getValue().equals(ztStory.getStage())){ + throw new BusinessException("需求状态不对"); + } + if(ObjectUtil.equal(ztStory.getInnerYsFlag(),1)){ + throw new BusinessException("无需内部验收,不需要提交"); + } + //产品验收中 + ztStory.setStage(StoryStageEnums.productWaitVerified.getValue()); + ztStory.setTestSubmitYsTime(new Date()); + ztStory.setLasteditedby(RiskUserThreadLocal.get().getName()); + ztStory.setLastediteddate(new Date()); + this.baseMapper.updateById(ztStory); + + List 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("未查询到需求"); + } + if(!StoryStatusEnums.active.getValue().equals(ztStory.getStatus())){ + throw new BusinessException("需求状态不对"); + } + if(!StoryStageEnums.productWaitVerified.getValue().equals(ztStory.getStage())){ + throw new BusinessException("需求状态不对"); + } + //产品验收中 + ztStory.setStage(StoryStageEnums.productWaitVerified.getValue()); + ztStory.setLasteditedby(RiskUserThreadLocal.get().getName()); + ztStory.setLastediteddate(new Date()); + ztStory.setInnerYsTime(new Date()); + this.baseMapper.updateById(ztStory); + + List 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 storyReleaseOnTimeByProducts(List 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(), "", ""); + } + + @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(), "", ""); + } + private List searchBug(SearchQo qo) { return this.baseMapper.searchBug(qo.getKeyword()); } @@ -1153,9 +1267,14 @@ public class ZtStoryServiceImpl extends ServiceImpl impl } } + /** + * 开发完成 + * @param id + * @param finishBy + */ @Override @Transactional - public void finishStory(Integer id, String finishBy) { + public void develFinishStory(Integer id, String finishBy) { if (id == null || id == 0) { return; @@ -1207,7 +1326,7 @@ public class ZtStoryServiceImpl extends ServiceImpl impl 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; } @@ -1242,6 +1361,13 @@ public class ZtStoryServiceImpl extends ServiceImpl impl actionService.addAction(ActionType.XQ, ActionStatus.CSWC, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), 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) { ztStory.setStartDate(new Date()); } @@ -1253,7 +1379,7 @@ public class ZtStoryServiceImpl extends ServiceImpl impl for (Integer execId : execIds) { 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) { ProductStoryStatus oldPStatus = null; @@ -1270,7 +1396,6 @@ public class ZtStoryServiceImpl extends ServiceImpl impl } - //发布 @Override @Transactional @@ -1280,22 +1405,25 @@ public class ZtStoryServiceImpl extends ServiceImpl impl } ZtStory ztStory = this.baseMapper.selectById(story); + if (ztStory == null) { + throw new BusinessException("未查询到数据-需求"); + } if (ztStory.getFeedback() != null && ztStory.getFeedback() != 0) { 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; } if ("closed".equals(ztStory.getStatus())) { throw new BusinessException("当前已关闭"); } - if (!"tested".equals(ztStory.getStage())) { + if (!StoryStageEnums.productVerified.getValue().equals(ztStory.getStage())) { throw new BusinessException("当前无法更改发布状态"); } //这个需求被多少执行关联 @@ -1397,7 +1525,7 @@ public class ZtStoryServiceImpl extends ServiceImpl impl if (!CollectionUtils.isEmpty(testedList)) { testedStory(story, finishBy); } else { - this.finishStory(story, finishBy); + this.develFinishStory(story, finishBy); } } @@ -1438,7 +1566,7 @@ public class ZtStoryServiceImpl extends ServiceImpl impl .eq(ZtTask::getType, TaskType.devel.getCode()) .in(ZtTask::getStatus, Arrays.asList("done"))); if (!CollectionUtils.isEmpty(develedList)) { - this.finishStory(story, finishBy); + this.develFinishStory(story, finishBy); return; } return; @@ -1486,7 +1614,7 @@ public class ZtStoryServiceImpl extends ServiceImpl impl if (done < 1) { } else { - this.finishStory(story, finishBy); + this.develFinishStory(story, finishBy); } } } else { @@ -2150,6 +2278,14 @@ public class ZtStoryServiceImpl extends ServiceImpl impl if (ztUser != null) { 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().lambda().eq(ZtStoryspec::getStory, d.getId())); if (storyspec != null) { @@ -2449,6 +2585,7 @@ public class ZtStoryServiceImpl extends ServiceImpl impl ProductStoryStatus oldPStatus = null; if (status.equalsIgnoreCase("developing") || status.equalsIgnoreCase("testing") || status.equalsIgnoreCase("tested") || status.equalsIgnoreCase("developed") + || status.equalsIgnoreCase(StoryStageEnums.productWaitVerified.getValue())|| status.equalsIgnoreCase(StoryStageEnums.productVerified.getValue()) ) { oldPStatus = ProductStoryStatus.JH; diff --git a/src/main/java/com/sa/zentao/service/impl/ZtStoryUserServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtStoryUserServiceImpl.java index 9530596..f91bf89 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtStoryUserServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtStoryUserServiceImpl.java @@ -252,10 +252,10 @@ public class ZtStoryUserServiceImpl extends ServiceImpl> getKanban(Integer productId) { List ztStoryUsers = this.baseMapper.selectList(new QueryWrapper() - .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)); Map> map = new HashMap<>(); - Map stringZtUserMap = this.userService.userMapByIds(ztStoryUsers.stream().map(o -> o.getOpenedby()).collect(Collectors.toList())); + Map stringZtUserMap = this.userService.userMapByIds(null); List ztStoryUserDTOS = BeanCopyUtil.copyListProperties(ztStoryUsers, ZtStoryUserDTO::new, new BeanCopyUtilCallBack() { @Override @@ -265,6 +265,11 @@ public class ZtStoryUserServiceImpl extends ServiceImpl ztStories = storyUserMap.get(d.getId()); if (!CollectionUtils.isEmpty(ztStories)) { d.setStoryList(ztStories.stream().map(o ->o.getId()+":"+o.getTitle()).collect(Collectors.joining(","))); @@ -377,7 +387,6 @@ public class ZtStoryUserServiceImpl extends ServiceImpl> storyUserMap = getStoryUserMap(Arrays.asList(dto)); List ztStories = storyUserMap.get(d.getId()); if (!CollectionUtils.isEmpty(ztStories)) { @@ -867,6 +880,18 @@ public class ZtStoryUserServiceImpl extends ServiceImpl> getStoryUserMap(List list) { List ids = list.stream().map(o -> o.getId()).collect(Collectors.toList()); diff --git a/src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java b/src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java index a722d3c..8e77e89 100644 --- a/src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java +++ b/src/main/java/com/sa/zentao/service/impl/ZtTaskServiceImpl.java @@ -1,5 +1,6 @@ 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.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; @@ -577,7 +578,8 @@ public class ZtTaskServiceImpl extends ServiceImpl impleme if (story != null && story != 0) { ZtStory ztStory = this.storyService.getById(story); // 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("当前状态无法添加任务"); } if (ztStory.getStatus().equals("closed")) { @@ -1034,6 +1036,13 @@ public class ZtTaskServiceImpl extends ServiceImpl impleme 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); 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(), StringUtils.isEmpty(finishBy) ? RiskUserThreadLocal.get().getName() : finishBy, dto.getDeliverContent(), null); } @@ -1073,7 +1082,11 @@ public class ZtTaskServiceImpl extends ServiceImpl impleme if (ztTask.getFeedback() != null && ztTask.getFeedback() != 0) { 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 diff --git a/src/main/java/com/sa/zentao/utils/KanBanConstant.java b/src/main/java/com/sa/zentao/utils/KanBanConstant.java index 21af141..d6b14fc 100644 --- a/src/main/java/com/sa/zentao/utils/KanBanConstant.java +++ b/src/main/java/com/sa/zentao/utils/KanBanConstant.java @@ -22,6 +22,8 @@ public class KanBanConstant { put("test","测试"); put("testing","进行中"); put("tested","完成"); + put("productWaitVerified","产品验收中"); + put("productVerified","产品已验收"); put("released","已发布"); put("verified","已验收"); put("closed","已关闭"); @@ -70,6 +72,8 @@ public class KanBanConstant { put("story-test","test"); put("story-testing","test"); put("story-tested","test"); + put("story-productWaitVerified","productWaitVerified"); + put("story-productVerified","productVerified"); put("story-verified","verified"); put("story-released","released"); put("story-closed","closed"); diff --git a/src/main/resources/mapper/ZtStoryMapper.xml b/src/main/resources/mapper/ZtStoryMapper.xml index 75480d1..2adafaa 100644 --- a/src/main/resources/mapper/ZtStoryMapper.xml +++ b/src/main/resources/mapper/ZtStoryMapper.xml @@ -136,6 +136,8 @@ s.ys_user, s.task_count, s.ys_date, + s.inner_ys_flag, + s.product_user, su.title userStoryName, su.id userStoryId, ps.title parentName, @@ -160,6 +162,10 @@ and s.assignedTo= #{qo.userName} + + and s.product_user= #{qo.userName} + + and s.openedBy= #{qo.userName} @@ -219,6 +225,9 @@ and s.title like concat('%', #{qo.title}, '%') + + and s.product_user like concat('%', #{qo.productUser}, '%') + and s.module = #{qo.module} @@ -357,6 +366,9 @@ s.ys_date, s.devel_plan_end_time, s.test_plan_end_time, + s.inner_ys_flag, + s.product_user, + s.test_user, pt.name productName from zt_story s @@ -410,7 +422,12 @@ and s.title like concat('%', #{qo.name}, '%') - + + and s.product_user like concat('%', #{qo.productUser}, '%') + + + and s.assignedTo like concat('%', #{qo.testUser}, '%') + and pt.name like concat('%', #{qo.productName}, '%') @@ -455,7 +472,12 @@ and s.status ='reviewing' and v.result = '' - + + and s.product_user = #{qo.userName} + + + and s.assignedTo = #{qo.userName} + and s.status = 'active' @@ -1292,4 +1314,25 @@ and (spc.spec like concat('%', #{keyword}, '%') or spc.verify like concat('%', #{keyword}, '%') or st.title like concat('%', #{keyword}, '%') ) order by id desc ) + + + diff --git a/src/main/resources/mapper/ZtStoryUserMapper.xml b/src/main/resources/mapper/ZtStoryUserMapper.xml index de8f051..4e0e5b4 100644 --- a/src/main/resources/mapper/ZtStoryUserMapper.xml +++ b/src/main/resources/mapper/ZtStoryUserMapper.xml @@ -140,7 +140,7 @@ s.deliver_remark, s.old_status, 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 @@ -188,9 +188,9 @@ and pt.name like concat('%', #{qo.productName}, '%') - - - + + and s.product_user like concat('%', #{qo.productUser}, '%') + @@ -199,10 +199,12 @@ and s.status != 'closed' + + and s.product_user = #{qo.userName} + and s.openedby= #{qo.userName} - and s.id = #{qo.id} diff --git a/src/main/resources/templates/scope/产品经理考核.xlsx b/src/main/resources/templates/scope/产品经理考核.xlsx new file mode 100644 index 0000000..815aeb4 Binary files /dev/null and b/src/main/resources/templates/scope/产品经理考核.xlsx differ