修改bug

This commit is contained in:
2025-03-12 15:39:32 +08:00
parent ff8faf7606
commit 016458af4b
40 changed files with 1590 additions and 482 deletions

View File

@ -2,10 +2,7 @@ package com.sa.zentao.controller;
import com.github.pagehelper.PageInfo;
import com.sa.zentao.dao.BusinessException;
import com.sa.zentao.dao.Result;
import com.sa.zentao.dao.ZtBugDTO;
import com.sa.zentao.dao.ZtCaseDTO;
import com.sa.zentao.dao.*;
import com.sa.zentao.entity.ZtBug;
import com.sa.zentao.qo.ZtBugQo;
import com.sa.zentao.qo.ZtProjectQo;
@ -55,6 +52,13 @@ public class ZtBugController {
return Result.success();
}
@RequestMapping(value = "/taskStoryAddBug", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result taskStoryAddBug(@RequestBody ZtBugDTO dto){
bugService.taskStoryAddBug(dto);
return Result.success();
}
//批量新增bug
@RequestMapping(value = "/batchAddBug", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result batchAddBug(@RequestBody ZtBugDTO dto){
@ -107,5 +111,18 @@ public class ZtBugController {
return Result.success();
}
//验收
@RequestMapping(value = "/bugYs", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result bugYs(@RequestBody ZtBugDTO dto){
bugService.bugYs(dto);
return Result.success();
}
@RequestMapping(value = "/bugListByTaskStory", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result bugListByTaskStory(@RequestBody ZtBugDTO dto){
return Result.success(bugService.bugListByTaskStory(dto));
}
}

View File

@ -15,7 +15,9 @@ import com.sa.zentao.service.IZtStoryService;
import com.sa.zentao.service.IZtTaskService;
import com.sa.zentao.service.impl.IZtCountService;
import com.sa.zentao.utils.DateUtils;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
@ -93,9 +95,21 @@ public class ZtCountController {
//导出项目统计
//work总量 月
@SneakyThrows
@RequestMapping(value = "/exportProjectCount", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public void exportProjectCount(@RequestBody ZtCountQo qo, jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse response){
countService.exportProjectCount(qo,request,response) ;
ServletOutputStream outputStream = response.getOutputStream();
try {
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
countService.exportProjectCount(qo,request,outputStream) ;
}catch (Exception e){
response.setContentType("application/json;charset=UTF-8");
throw new BusinessException("导出失败");
}finally {
outputStream.close();
response.flushBuffer();
}
}
//导出员工绩效

View File

@ -3,10 +3,7 @@ package com.sa.zentao.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageInfo;
import com.sa.zentao.dao.BusinessException;
import com.sa.zentao.dao.Result;
import com.sa.zentao.dao.ZtProductDTO;
import com.sa.zentao.dao.ZtProjectDTO;
import com.sa.zentao.dao.*;
import com.sa.zentao.entity.ZtExecutionproject;
import com.sa.zentao.entity.ZtProduct;
import com.sa.zentao.entity.ZtProjectproduct;
@ -140,4 +137,10 @@ public class ZtProductController {
}
@RequestMapping(value = "/getAllBusinessSelect", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result getAllBusinessSelect(@RequestBody ZtAllBusinessDTO dto){
return Result.success(ztProductService.getAllBusinessSelect(dto));
}
}

View File

@ -291,6 +291,7 @@ public class ZtProjectController {
}
//countProject
@RequestMapping(value = "/countProject", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result countProject(@RequestBody ZtProjectQo qo){
@ -302,6 +303,17 @@ public class ZtProjectController {
public Result execTeamById(@RequestBody ZtProjectQo qo){
return Result.success(this.ztProjectService.execTeamById(qo));
}
//查询team根据项目id
@RequestMapping(value = "/projectTeamById", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result projectTeamById(@RequestBody ZtProjectQo qo){
return Result.success(this.ztProjectService.projectTeamById(qo));
}
@RequestMapping(value = "/projectTeamUpdate", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result projectTeamUpdate(@RequestBody ZtProjectQo qo){
this.ztProjectService.projectTeamUpdate(qo);
return Result.success();
}
@RequestMapping(value = "/execTeamUpdate", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result execTeamUpdate(@RequestBody ZtProjectQo qo){
this.ztProjectService.execTeamUpdate(qo);
@ -325,6 +337,11 @@ public class ZtProjectController {
return Result.success(this.ztProjectService.pageDaysTimeWorkCount(qo));
}
@RequestMapping(value = "/getWorkInfoByDate", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result getWorkInfoByDate(@RequestBody ZtProjectQo qo){
return Result.success(this.ztProjectService.getWorkInfoByDate(qo));
}
//迭代工时 每个人
@RequestMapping(value = "/execWorkCount", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result execWorkCount(@RequestBody ZtProjectQo qo){
@ -347,7 +364,6 @@ public class ZtProjectController {
}
//迭代列表根据项目
@RequestMapping(value = "/projectProductByExecution", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result projectProductByExecution(@RequestBody ZtProjectQo qo){
@ -357,6 +373,13 @@ public class ZtProjectController {
}
@RequestMapping(value = "/executionBatchRemoveStory", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result executionBatchRemoveStory(@RequestBody ZtProjectQo qo){
this.ztProjectService.executionBatchRemoveStory(qo.getExecution(),qo.getStoryIds());
return Result.success();
}
}

View File

@ -38,6 +38,10 @@ public class ZtStoryController {
@Autowired
private IZtStoryService ztStoryService;
@Autowired
private IZtProjectproductService projectproductService;
@RequestMapping(value = "/pageList", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result<ZtStoryDTO> storyPageList(@RequestBody ZtProjectQo qo){
@ -177,8 +181,6 @@ public class ZtStoryController {
return Result.success();
}
@Autowired
private IZtProjectproductService projectproductService;
//迭代列表根据项目id
@RequestMapping(value = "/execListByProject", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")

View File

@ -38,6 +38,11 @@ public class ZtStoryFeedbackController {
return Result.success(storyFeedbackService.pageList(qo));
}
@RequestMapping(value = "/getFeedbackById", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result<ZtStoryFeedbackDTO> getFeedbackById(@RequestBody ZtProjectQo qo){
return Result.success(storyFeedbackService.getFeedbackById(qo));
}
@RequestMapping(value = "/addFeedback", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result addStory(@RequestBody ZtStoryFeedbackDTO dto){
storyFeedbackService.addFeedback(dto);
@ -63,6 +68,13 @@ public class ZtStoryFeedbackController {
storyFeedbackService.changeStatus(dto);
return Result.success();
}
@RequestMapping(value = "/dontHand", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result dontHand(@RequestBody ZtStoryFeedbackDTO dto){
storyFeedbackService.dontHand(dto);
return Result.success();
}
@RequestMapping(value = "/closedStory", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result closedStory(@RequestBody ZtStoryFeedbackDTO dto){
storyFeedbackService.closedFeedback(dto);
@ -91,4 +103,24 @@ public class ZtStoryFeedbackController {
return Result.success();
}
//提交验收
@RequestMapping(value = "/submitVerified", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result submitVerified(@RequestBody ZtStoryDTO dto){
storyFeedbackService.submitVerified(dto);
return Result.success();
}
//提交验收
@RequestMapping(value = "/storyYs", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result storyYs(@RequestBody ZtStoryDTO dto){
storyFeedbackService.storyYs(dto);
return Result.success();
}
//添加备注
@RequestMapping(value = "/addRemark", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result addRemark(@RequestBody ZtStoryDTO dto){
storyFeedbackService.addRemark(dto);
return Result.success();
}
}

View File

@ -55,8 +55,6 @@ public class ZtTaskController {
@Autowired
private IZtKanbanlaneService kanbanlaneService;
@Autowired
private com.sa.zentao.service.IZtStoryService IZtStoryService;
@Autowired
@ -127,7 +125,7 @@ public class ZtTaskController {
//结束任务
@RequestMapping(value = "/finishTask", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
public Result finishTask(@RequestBody ZtTaskDTO dto){
ztTaskService.finishTask(dto);
ztTaskService.finishTask(dto,null);
return Result.success();
}

View File

@ -95,6 +95,14 @@ public class ZtUserController {
return Result.success(new ArrayList<>());
}
eq.in(ZtUser::getAccount,execution.stream().map(o->o.getAccount()).collect(Collectors.toList()));
}else if("project".equals(dto.getType())){
//迭代id
Integer id = dto.getId();
List<ZtTeam> execution = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getRoot, id).eq(ZtTeam::getType, "project"));
if(CollectionUtils.isEmpty(execution)){
return Result.success(new ArrayList<>());
}
eq.in(ZtUser::getAccount,execution.stream().map(o->o.getAccount()).collect(Collectors.toList()));
}
return Result.success(userService.list(eq

View File

@ -60,7 +60,12 @@ public class ProjectWorkTaskDTO implements Serializable {
@ExcelProperty(value = "任务结束时间",index =14)
private String endDate;
@ExcelProperty(value = "持续日期",index =15)
@ExcelProperty(value = "分配结束时间",index =15)
private String planEndDate;
@ExcelProperty(value = "持续日期",index =16)
private Integer keepTime;
@ExcelProperty(value = "是否延期",index =17)
private String delayRemark;
}

View File

@ -32,6 +32,8 @@ public class WorkDetailsDTO implements Serializable {
//可用工时 6*工作天数
@ExcelProperty(value = "可用工时 ",index =4)
private BigDecimal haveTime;
@ExcelIgnore
private BigDecimal qjTime;
//工作饱和度
@ExcelProperty(value = "工作饱和度 ",index =5)
private BigDecimal saturation;

View File

@ -0,0 +1,32 @@
package com.sa.zentao.dao;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
@Data
@EqualsAndHashCode(callSuper = false)
public class ZtAllBusinessDTO implements Serializable {
private Integer productId;
private Integer projectId;
private Integer feedbackId;
private Integer executionId;
private Integer storyId;
private Integer taskId;
private String storyName;
private String taskName;
private Integer bugId;
}

View File

@ -125,6 +125,8 @@ public class ZtBugDTO implements Serializable {
@TableField("resolvedBy")
private String resolvedby;
private String resolvedbyName;
private String resolution;
@TableField("resolvedBuild")
@ -197,4 +199,14 @@ public class ZtBugDTO implements Serializable {
private String files;
private List<ZtBugDTO> list;
private String bugType;
private String ysUser;
private String ysUserName;
private String ysFlag;
private String ysRemark;
private Integer reviewerResult;
private String desc;
}

View File

@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
/**
* <p>
@ -100,5 +101,19 @@ public class ZtStoryFeedbackDTO implements Serializable {
private String approvalRemark;
private String weixin;
//无需处理
private String dontHandSelect;
//无需处理
private String dontHandRemark;
private List<ZtTaskDTO> taskList;
private List<ZtBugDTO> bugList;
private List<ZtStoryDTO> storyList;
//1通过 2不通过
private Integer ysFlag;
}

View File

@ -199,4 +199,6 @@ public class ZtTaskDTO implements Serializable {
private Date applyDate;
private BigDecimal useTime;
}

View File

@ -86,7 +86,7 @@ public class ZtBug implements Serializable {
// tested
// closed
// ZtBug 已完成
//1.active 2.confire=1 3.解决进行中 不变 4 resolved 完成 5.测试中不变 6.测试完毕不变
//1.active 2.confire=1 3.解决进行中 不变 4 resolved 完成 5.测试中不变 6.测试完毕不变 verified验收
// 'active','resolved','closed'?
// active 激活
@TableField("`status`")
@ -193,4 +193,12 @@ public class ZtBug implements Serializable {
private String fileUrl;
private String bugType;
private String ysUser;
//1 通过 2不通过
private Integer ysFlag;
private String ysRemark;
}

View File

@ -3,9 +3,13 @@ package com.sa.zentao.entity;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.sa.zentao.dao.ZtBugDTO;
import com.sa.zentao.dao.ZtStoryDTO;
import com.sa.zentao.dao.ZtTaskDTO;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -64,8 +68,8 @@ public class ZtStoryFeedback implements Serializable {
private String assignedTo;
private String spec;
// wait doing finished closed reviewing
// wait doing finished submitVerified 提交验收 closed reviewing verified 验收 dontHand 无需处理
private String status;
@ -97,4 +101,11 @@ public class ZtStoryFeedback implements Serializable {
private String businessId;
private String weixin;
//1通过 2不通过
private Integer ysFlag;
private String dontHandSelect;
private String dontHandRemark;
}

View File

@ -30,8 +30,7 @@ public class ZtTask implements Serializable {
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
//审核拒绝原因
private String approvalRemark;
private Integer project;
@ -44,6 +43,8 @@ public class ZtTask implements Serializable {
private Integer design;
private Integer story;
//问题反馈id
private Integer feedback;
@TableField("storyVersion")
private Integer storyversion;
@ -54,8 +55,6 @@ public class ZtTask implements Serializable {
@TableField("fromBug")
private Integer frombug;
private Integer feedback;
@TableField("fromIssue")
private Integer fromissue;
@TableField("`name`")
@ -190,4 +189,10 @@ public class ZtTask implements Serializable {
private Date applyDate;
// @TableField(exist = false)
private BigDecimal useTime;
// 0 默认 1审核不通过
private Integer approvalResult;
private String approvalRemark;
}

View File

@ -30,7 +30,7 @@ public class ZtTeam implements Serializable {
private Integer id;
private Integer root;
//execution project
private String type;
private String account;

View File

@ -26,10 +26,13 @@ public enum ActionStatus {
FBCG(18, "fb","发布通过"),
FBSB(30, "fb","发布不通过"),
QR(19, "qr","确认"),
KSCE(21, "tested","开始测试"),
KSCE(21, "testing","开始测试"),
CSWC(20, "tested","测试完成"),
KFWC(41, "developed","开发完成"),
TJYS(51, "verified","提交验收"),
LOGIN(100, "login","登录"),
XGMM(101, "xgmm","修改密码"),
;

View File

@ -81,4 +81,8 @@ public class ZtProjectQo extends BaseQo {
private List<String> objIds;
private List<Integer> projectList;
private List<Integer> storyIds;
private Boolean needWeek=false;
}

View File

@ -7,6 +7,8 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.sa.zentao.qo.ZtBugQo;
import com.sa.zentao.qo.ZtProjectQo;
import java.util.List;
/**
* <p>
* 服务类
@ -37,4 +39,9 @@ public interface IZtBugService extends IService<ZtBug> {
void batchAddBug(ZtBugDTO dto);
void bugYs(ZtBugDTO dto);
void taskStoryAddBug(ZtBugDTO dto);
List<ZtBugDTO> bugListByTaskStory(ZtBugDTO dto);
}

View File

@ -1,6 +1,7 @@
package com.sa.zentao.service;
import com.github.pagehelper.PageInfo;
import com.sa.zentao.dao.ZtAllBusinessDTO;
import com.sa.zentao.dao.ZtProductDTO;
import com.sa.zentao.dao.ZtProjectDTO;
import com.sa.zentao.entity.ZtProduct;
@ -45,4 +46,7 @@ public interface IZtProductService extends IService<ZtProduct> {
List<ZtProductDTO> myProductList(ZtProjectQo qo);
Map<String,Object> getAllBusinessSelect(ZtAllBusinessDTO dto);
}

View File

@ -122,4 +122,15 @@ public interface IZtProjectService extends IService<ZtProject> {
List<Map<String, Object>> execWorkCount(ZtProjectQo qo);
PageInfo<ZtProjectDTO> myProgressImplementPageList(ZtProjectQo qo);
ZtProject projectByImplement(ZtProjectQo qo);
Map<String,Boolean> getWorkInfoByDate(ZtProjectQo qo);
void executionBatchRemoveStory(String execution, List<Integer> storyIds);
void projectTeamUpdate(ZtProjectQo qo);
List<String> projectTeamById(ZtProjectQo qo);
}

View File

@ -38,5 +38,22 @@ public interface IZtStoryFeedbackService extends IService<ZtStoryFeedback> {
void closedFeedback(ZtStoryFeedbackDTO dto);
void approval(ZtStoryFeedbackDTO dto);
// task story bug
void split(String type,Integer businessId);
void feedbackStart(Integer feedbackId);
void feedbackFinished(Integer feedbackId);
void submitVerified(ZtStoryDTO dto);
void ysFeedback(Integer feedbackId);
void storyYs(ZtStoryDTO dto);
void dontHand(ZtStoryFeedbackDTO dto);
ZtStoryFeedbackDTO getFeedbackById(ZtProjectQo qo);
void addRemark(ZtStoryDTO dto);
}

View File

@ -47,10 +47,10 @@ public interface IZtStoryService extends IService<ZtStory> {
List<ZtStoryDTO> storyNoSyncProject(ZtProjectQo qo);
void startStory(Integer story);
void finishStory(Integer story);
//开发完成
void finishStory(Integer story,String finishBy);
//测试完毕
void testedStory(Integer story);
void testedStory(Integer story,String finishBy);
//测试中
void testingStory(Integer story);
//发布

View File

@ -30,7 +30,7 @@ public interface IZtTaskService extends IService<ZtTask> {
void startTask(ZtTaskDTO dto);
void finishTask(ZtTaskDTO dto);
void finishTask(ZtTaskDTO dto,String account);
List<ZtTaskDTO> taskListByExecution(ZtTaskDTO dto);

View File

@ -538,7 +538,7 @@ public class IZtCountService {
throw new BusinessException("未查询到数据");
}
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
Map<String, ZtUser> userMap = userService.userMapByIds(null);
@ -557,9 +557,21 @@ public class IZtCountService {
}else{
}
}
String dir=System.getProperty("user.dir")+"/";
//生成多sheetexcel
String fileName=dir+DateUtils.formatDate(new Date(),"yyyyMMddHHmmss")+".xlsx";
FileOutputStream stream = new FileOutputStream(fileName);
try {
exportProjectCount(qo,request,stream);
}catch (Exception e){
throw new BusinessException("导出失败");
}finally {
stream.close();
}
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
List<String> list = new ArrayList<>();
list.add(fileName);
for (int i = 0; i < perList.size(); i++) {
PerformanceDTO performanceDTO = perList.get(i);
ZtUser ztUser = userMap.get(performanceDTO.getAccount());
@ -575,7 +587,7 @@ public class IZtCountService {
}
}
String excelName=DateUtils.formatDate(qo.getDate(),"yyyy-MM-dd")+"绩效"+".xlsx";
String dir=System.getProperty("user.dir")+"/";
ExcelUtil.mergexcel(list,excelName, dir);
@ -612,12 +624,12 @@ public class IZtCountService {
}
public void exportProjectCount(ZtCountQo qo,jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse response) {
public void exportProjectCount(ZtCountQo qo,jakarta.servlet.ServletRequest request,OutputStream outputStream) {
try {
List<ProjectWorkDetailsDTO> workDetailsDTOS = projectWorkCount(qo,request,response);
List<ProjectWorkDetailsDTO> workDetailsDTOS = projectWorkCount(qo,request);
ByteArrayOutputStream os = new ByteArrayOutputStream();
// ByteArrayOutputStream os = new ByteArrayOutputStream();
List<WorkDetailsDTO> workDetailsDTOS1 = workDetailsCount(qo);
@ -626,11 +638,11 @@ public class IZtCountService {
List<PerformanceDTO> perList =performanceCount(qo);
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
ExcelWriter excelWriter = EasyExcel.write(outputStream)
. registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.needHead(Boolean.TRUE).build();
for (int i = 0; i < 4; i++) {
@ -665,12 +677,6 @@ public class IZtCountService {
}
excelWriter.finish();
response.getOutputStream().close();
response.flushBuffer();
}catch (Exception e){
log.error("",e);
}
@ -732,131 +738,134 @@ public class IZtCountService {
for (ZtUser u:ztUsers) {
List<ItApproval> approvalList = this.taskService.itApprovalByUserName(u.getNickname(),firstDayOfMonth, lastDayOfMonth);
result.add(buildCsScore(u,approvalList,firstDayOfMonth,lastDayOfMonth,taskList,d));
}
return result;
}
PerformanceDTO buildCsScore(ZtUser u ,List<ItApproval> approvalList,Date firstDayOfMonth,Date lastDayOfMonth,List<ZtTask> taskList,Date d ){
if(u.getUserType()==UserType.CS){
if(u.getUserType()==UserType.CS){
}else if(u.getUserType()==UserType.KFZ){
}else if(u.getUserType()==UserType.KFZ){
}else if(u.getUserType()==UserType.XMGLY){
}else if(u.getUserType()==UserType.XMGLY){
}
PerformanceDTO dto=new PerformanceDTO();
dto.setUserName(u.getNickname());
dto.setAccount(u.getAccount());
//本月天数
int workDaysInCurrentMonth = DateUtils.getWorkDaysInCurrentMonth(d);
//获取本月请假
Integer applyTime=0;
if(!CollectionUtils.isEmpty(approvalList)){
for (ItApproval a:approvalList) {
//分钟
applyTime=getApprovalTime(approvalList,firstDayOfMonth);;
}
}
//本月天数
dto.setDays(BigDecimal.valueOf(workDaysInCurrentMonth));
//本月天数 请假天数
dto.setApprovalDays(applyTime<1?BigDecimal.ZERO:BigDecimal.valueOf(applyTime).divide(BigDecimal.valueOf(60),2,BigDecimal.ROUND_HALF_UP));
//可用工时 6小时算
dto.setTotalTime(
dto.getApprovalDays().intValue()==0?dto.getDays().multiply(BigDecimal.valueOf(8)).setScale(2,BigDecimal.ROUND_HALF_UP)
:dto.getDays().multiply(BigDecimal.valueOf(8)).subtract(dto.getApprovalDays()).setScale(2,BigDecimal.ROUND_HALF_UP));
//达标工时
dto.setExamineTime(dto.getTotalTime().multiply(BigDecimal.valueOf(0.75)));
//产出工时 算task
List<Float> taskTimeList = taskList.stream().filter(o->o.getFinishedDate()!=null&&
o.getFinishedDate().getTime()<=lastDayOfMonth.getTime() &&firstDayOfMonth.getTime()<=o.getFinishedDate().getTime()
).map(o -> o.getConsumed()).collect(Collectors.toList());
//分配总工时
taskTimeList = taskList.stream().filter(o->u.getAccount().equals(o.getAssignedTo())).map(o -> o.getEstimate()).collect(Collectors.toList());
dto.setAllocationTime(floatBatchAdd(taskTimeList));
dto.setWorkTime(floatBatchAdd(taskList.stream().filter(o->u.getAccount().equals(o.getAssignedTo())).map(o -> o.getConsumed()).collect(Collectors.toList())));
//工作饱和度
dto.setSaturation(dto.getTotalTime().floatValue()==0?BigDecimal.ZERO:dto.getAllocationTime().divide(dto.getExamineTime(),2,BigDecimal.ROUND_HALF_UP));
float saturation = dto.getSaturation().floatValue();
//完成准时率 TODO 延期 / 总完成
List<ZtTask> delayTaskList = taskList.stream().filter(o->u.getAccount().equals(o.getAssignedTo())).filter(o -> o.getFinishedDate() != null
&& DateUtils.getDayLast(o.getFinishedDate()).getTime() > DateUtils.getDayLast(o.getDeadline()).getTime()).collect(Collectors.toList());
dto.setFinishTask(BigDecimal.valueOf(taskTimeList.size()));
dto.setDelayTask(BigDecimal.valueOf(delayTaskList.size()));
//准时完成率
dto.setFinishPunctuality(taskTimeList.size()==0?BigDecimal.valueOf(0):
CollectionUtils.isEmpty(delayTaskList)?BigDecimal.valueOf(1):
BigDecimal.valueOf(1).subtract(BigDecimal.valueOf(delayTaskList.size())
.divide(BigDecimal.valueOf(taskTimeList.size()),2,BigDecimal.ROUND_HALF_UP)));
//工作饱和度
if(saturation<0.7){
// = 0
dto.setSaturationScore(BigDecimal.ZERO);
}else{
if(saturation<0.9){
dto.setSaturationScore(BigDecimal.valueOf(40 - ( 0.9 - saturation ) * 100 * 1).setScale(2,BigDecimal.ROUND_HALF_UP));
}else{
dto.setSaturationScore(BigDecimal.valueOf(40));
}
}
BigDecimal finishPunctuality = dto.getFinishPunctuality();
// 准时率得分 ( `完成准时率` < 1 , 25 - (1 - `完成准时率`) * 100 * 1, 25 )) `准时率得分`,
if(finishPunctuality.floatValue()<1){
//TODO 完成准时率 0.8
if(finishPunctuality.floatValue()<0.8){
dto.setPunctualityScore(BigDecimal.ZERO);
}else{
dto.setPunctualityScore(BigDecimal.valueOf(25 - (1 - finishPunctuality.floatValue()) * 100 * 1).setScale(2,BigDecimal.ROUND_HALF_UP));
}
}else{
//饱和率得分
dto.setPunctualityScore(BigDecimal.valueOf(25));
}
List<ZtBug> bugList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().between(ZtBug::getOpeneddate, firstDayOfMonth, lastDayOfMonth)
.in(ZtBug::getSeverity, 1, 2).eq(ZtBug::getResolvedby,u.getAccount()));
if(CollectionUtils.isEmpty(bugList)){
dto.setSeriousBug(BigDecimal.ZERO);
dto.setSlightBug(BigDecimal.ZERO);
dto.setBugScore(BigDecimal.valueOf(10));
}else{
Long seriousBug = bugList.stream().filter(o -> o.getSeverity() == 1).count();
dto.setSeriousBug(BigDecimal.valueOf(seriousBug));
Long slightBug = bugList.stream().filter(o -> o.getSeverity() == 1).count();
dto.setSlightBug(BigDecimal.valueOf(slightBug));
//测试 if(`线上严重bug` = 0 AND `线上普通bug` = 0, 20, 20 - `线上严重bug` * 20 - `线上普通bug` * 5 )
if(u.getUserType()==UserType.CS){
dto.setBugScore(
(seriousBug==0l&&slightBug==0l)?BigDecimal.valueOf(20):BigDecimal.valueOf(20).subtract(BigDecimal.valueOf(seriousBug).multiply(BigDecimal.valueOf(20).subtract(BigDecimal.valueOf(slightBug).multiply(BigDecimal.valueOf(5)))))
);
}else{
dto.setBugScore((seriousBug==0l&&slightBug==0l)?BigDecimal.valueOf(10):BigDecimal.valueOf(10).subtract(BigDecimal.valueOf(seriousBug).multiply(BigDecimal.valueOf(10).subtract(BigDecimal.valueOf(slightBug).multiply(BigDecimal.valueOf(3))))));
}
//其余 if(`线上严重bug` = 0 AND `线上普通bug` = 0, 10, 10 - `线上严重bug` * 10 - `线上普通bug` * 3 )
}
if(u.getUserType()==UserType.CS){
//算绩效 `线上bug得分` + `准时率得分` + 50,
dto.setScore(dto.getBugScore() .add(dto.getPunctualityScore()).add(BigDecimal.valueOf(50)) );
}else{
//`饱和率得分`+ `线上bug得分` + `准时率得分` + 25
dto.setScore(dto.getSaturationScore() .add(dto.getBugScore()).add(dto.getPunctualityScore()).add(BigDecimal.valueOf(25)));
}
result.add(dto);
}
PerformanceDTO dto=new PerformanceDTO();
dto.setUserName(u.getNickname());
dto.setAccount(u.getAccount());
//本月天数
int workDaysInCurrentMonth = DateUtils.getWorkDaysInCurrentMonth(d);
//获取本月请假
Integer applyTime=0;
if(!CollectionUtils.isEmpty(approvalList)){
applyTime=getApprovalTime(approvalList,firstDayOfMonth);;
}
//本月天数
dto.setDays(BigDecimal.valueOf(workDaysInCurrentMonth));
//本月天数 请假天数
dto.setApprovalDays(applyTime<1?BigDecimal.ZERO:BigDecimal.valueOf(applyTime).divide(BigDecimal.valueOf(60),2,BigDecimal.ROUND_HALF_UP));
//可用工时 6小时算
dto.setTotalTime(
dto.getApprovalDays().intValue()==0?dto.getDays().multiply(BigDecimal.valueOf(8)).setScale(2,BigDecimal.ROUND_HALF_UP)
:dto.getDays().multiply(BigDecimal.valueOf(8)).subtract(dto.getApprovalDays()).setScale(2,BigDecimal.ROUND_HALF_UP));
//达标工时
dto.setExamineTime(dto.getTotalTime().multiply(BigDecimal.valueOf(0.75)));
//产出工时 算task
List<ZtTask> taskTimeList = taskList.stream()
.filter(o->o.getFinishedDate()!=null&&
o.getFinishedDate().getTime()<=lastDayOfMonth.getTime() &&firstDayOfMonth.getTime()<=o.getFinishedDate().getTime()
).collect(Collectors.toList());
//分配总工时
taskTimeList = taskList.stream().filter(o->u.getAccount().equals(o.getAssignedTo())).collect(Collectors.toList());
dto.setAllocationTime(floatBatchAdd(taskTimeList.stream().map(o->o.getEstimate()).collect(Collectors.toList())));
dto.setWorkTime(floatBatchAdd(taskList.stream().filter(o->u.getAccount().equals(o.getAssignedTo())).map(o -> o.getConsumed()).collect(Collectors.toList())));
//工作饱和度
dto.setSaturation(dto.getTotalTime().floatValue()==0?BigDecimal.ZERO:dto.getAllocationTime().divide(dto.getExamineTime(),2,BigDecimal.ROUND_HALF_UP));
float saturation = dto.getSaturation().floatValue();
//完成准时率 TODO 延期 / 总完成
List<ZtTask> delayTaskList = taskList.stream().filter(o->u.getAccount().equals(o.getAssignedTo())).filter(o -> o.getFinishedDate() != null
&& o.getFinishedDate().getTime() > DateUtils.getDayLast(o.getDeadline()).getTime()).collect(Collectors.toList());
dto.setFinishTask(BigDecimal.valueOf(taskTimeList.stream().filter(o->o.getFinishedDate()!=null).map(o->o.getEstimate()).collect(Collectors.toList()).size()));
dto.setDelayTask(BigDecimal.valueOf(delayTaskList.size()));
//准时完成率
dto.setFinishPunctuality(taskTimeList.size()==0?BigDecimal.valueOf(0):
CollectionUtils.isEmpty(delayTaskList)?BigDecimal.valueOf(1):
BigDecimal.valueOf(1).subtract(BigDecimal.valueOf(delayTaskList.size())
.divide(dto.getFinishTask(),2,BigDecimal.ROUND_HALF_UP)));
//工作饱和度
if(saturation<0.7){
// = 0
dto.setSaturationScore(BigDecimal.ZERO);
}else{
if(saturation<0.9){
dto.setSaturationScore(BigDecimal.valueOf(40 - ( 0.9 - saturation ) * 100 * 1).setScale(2,BigDecimal.ROUND_HALF_UP));
}else{
dto.setSaturationScore(BigDecimal.valueOf(40));
}
}
BigDecimal finishPunctuality = dto.getFinishPunctuality();
// 准时率得分 ( `完成准时率` < 1 , 25 - (1 - `完成准时率`) * 100 * 1, 25 )) `准时率得分`,
if(finishPunctuality.floatValue()<1){
//TODO 完成准时率 0.8
if(finishPunctuality.floatValue()<0.8){
dto.setPunctualityScore(BigDecimal.ZERO);
}else{
dto.setPunctualityScore(BigDecimal.valueOf(25 - (1 - finishPunctuality.floatValue()) * 100 * 1).setScale(2,BigDecimal.ROUND_HALF_UP));
}
}else{
//饱和率得分
dto.setPunctualityScore(BigDecimal.valueOf(25));
}
// if(CollectionUtils.isEmpty(taskTimeList)){
// bugList=new ArrayList<>();
// }else{
// bugList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().between(ZtBug::getOpeneddate, firstDayOfMonth, lastDayOfMonth)
// .in(ZtBug::getSeverity, 1, 2).eq(ZtBug::getResolvedby,u.getAccount()));
// }
List<ZtBug> bugList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().between(ZtBug::getOpeneddate, firstDayOfMonth, lastDayOfMonth)
.in(ZtBug::getSeverity, 1, 2).eq(ZtBug::getResolvedby,u.getAccount()));
// if(!CollectionUtils.isEmpty(fTask)){
// count = bugService.count(new QueryWrapper<ZtBug>().lambda().in(ZtBug::getTotask, fTask.stream().map(o -> o.getId()).collect(Collectors.toList())));
// }
if(CollectionUtils.isEmpty(bugList)){
dto.setSeriousBug(BigDecimal.ZERO);
dto.setSlightBug(BigDecimal.ZERO);
dto.setBugScore(BigDecimal.valueOf(10));
}else{
Long seriousBug = bugList.stream().filter(o -> o.getSeverity() == 1).count();
dto.setSeriousBug(BigDecimal.valueOf(seriousBug));
Long slightBug = bugList.stream().filter(o -> o.getSeverity() == 1).count();
dto.setSlightBug(BigDecimal.valueOf(slightBug));
return result;
// return this.projectService.performanceCount(firstDayOfMonth,lastDayOfMonth);
//测试 if(`线上严重bug` = 0 AND `线上普通bug` = 0, 20, 20 - `线上严重bug` * 20 - `线上普通bug` * 5 )
if(u.getUserType()==UserType.CS){
dto.setBugScore(
(seriousBug==0l&&slightBug==0l)?BigDecimal.valueOf(20):BigDecimal.valueOf(20).subtract(BigDecimal.valueOf(seriousBug).multiply(BigDecimal.valueOf(20).subtract(BigDecimal.valueOf(slightBug).multiply(BigDecimal.valueOf(5)))))
);
}else{
dto.setBugScore((seriousBug==0l&&slightBug==0l)?BigDecimal.valueOf(10):BigDecimal.valueOf(10).subtract(BigDecimal.valueOf(seriousBug).multiply(BigDecimal.valueOf(10).subtract(BigDecimal.valueOf(slightBug).multiply(BigDecimal.valueOf(3))))));
}
//其余 if(`线上严重bug` = 0 AND `线上普通bug` = 0, 10, 10 - `线上严重bug` * 10 - `线上普通bug` * 3 )
}
if(u.getUserType()==UserType.CS){
//算绩效 `线上bug得分` + `准时率得分` + 50,
dto.setScore(dto.getBugScore() .add(dto.getPunctualityScore()).add(BigDecimal.valueOf(50)) );
}else{
//`饱和率得分`+ `线上bug得分` + `准时率得分` + 25
dto.setScore(dto.getSaturationScore() .add(dto.getBugScore()).add(dto.getPunctualityScore()).add(BigDecimal.valueOf(25)));
}
return dto;
}
//分钟 请假
private Integer getApprovalTime(List<ItApproval> approvalList,Date d) {
//分钟 请假 d 月份
public Integer getApprovalTime(List<ItApproval> approvalList,Date d) {
String dFormat = DateUtils.formatDate(d, "yyyyMM");
Integer value=0;
for (ItApproval approval:approvalList) {
@ -879,7 +888,7 @@ public class IZtCountService {
if(date.getMonth()!=d.getMonth()){
continue;
}
if(DateUtils.isWork(date)){
if(!DateUtils.isWork(date)){
continue;
}
@ -893,6 +902,7 @@ public class IZtCountService {
Integer mStart = Integer.valueOf(DateUtils.formatDate(date, "HHmm"));
// 8个半小时
Date thisDay = new Date();
thisDay.setMonth(date.getMonth());
thisDay.setDate(date.getDate());
thisDay.setHours(17);
thisDay.setMinutes(30);
@ -900,17 +910,17 @@ public class IZtCountService {
if(mStart<=1300){
//早上请假
if(thisDay.getTime()<applyTimeEnd.getTime()){
value+=(int)((thisDay.getTime()-date.getTime())/1000-(30*60));
value+=(int)((thisDay.getTime()-date.getTime())/1000-(30*60))/60;
}else{
value+=(int)((applyTimeEnd.getTime()-date.getTime())/1000-(30*60));
value+=(int)((applyTimeEnd.getTime()-date.getTime())/1000-(30*60))/60;
}
}else
{
if(thisDay.getTime()<applyTimeEnd.getTime()){
value+= (int)(thisDay.getTime()-date.getTime())/1000;
value+= (int)(thisDay.getTime()-date.getTime())/1000/60;
}else{
value+= (int)(applyTimeEnd.getTime()-date.getTime())/1000;
value+= (int)(applyTimeEnd.getTime()-date.getTime())/1000/60;
}
//下午请假
@ -1024,8 +1034,9 @@ public class IZtCountService {
dto.setStartDate(DateUtils.formatDate(t.getRealstarted()));
dto.setEndDate(DateUtils.formatDate(t.getFinishedDate()));
dto.setPlanEndDate(DateUtils.formatDate(t.getDeadline()));
dto.setKeepTime(t.getFinishedDate()==null?(DateUtils.daysBetween(t.getRealstarted(),t.getFinishedDate())):(DateUtils.daysBetween(t.getEstStarted(),t.getDeadline())));
dto.setDelayRemark(((t.getFinishedDate()==null?new Date():t.getFinishedDate()).getTime()>DateUtils.getDayLast(t.getDeadline()).getTime())?"":"");
result.add(dto);
}
return result;
@ -1063,7 +1074,7 @@ public class IZtCountService {
return list1.stream().map(o->o.getStory()).collect(Collectors.toList());
}
public List<ProjectWorkDetailsDTO> projectWorkCount(ZtCountQo qo,jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse response){
public List<ProjectWorkDetailsDTO> projectWorkCount(ZtCountQo qo,jakarta.servlet.ServletRequest request){
Date d = qo.getDate();
Date firstDayOfMonth = DateUtils.getFirstDayOfMonth(d);
Date lastDayOfMonth = DateUtils.getLastDayOfMonth(d);
@ -1189,6 +1200,8 @@ public class IZtCountService {
Date d = qo.getDate();
int time = DateUtils.getWorkDaysInCurrentMonth(d) * 6;
if(d==null){
@ -1268,6 +1281,13 @@ public class IZtCountService {
//项目
//迭代
for (ZtUser u : userList) {
List<ItApproval> approvalList = this.taskService.itApprovalByUserName(u.getNickname(),firstDayOfMonth, lastDayOfMonth);
Integer approvalTime =0;
if(!CollectionUtils.isEmpty(approvalList)){
approvalTime = this.getApprovalTime(approvalList, firstDayOfMonth);
}
List<ZtTask> fTask = taskList.stream().filter(o -> o.getAssignedTo().equals(u.getAccount())).collect(Collectors.toList());
@ -1279,11 +1299,13 @@ public class IZtCountService {
//
dto.setWorkTime(floatBatchAdd(fTask.stream().map(o -> o.getConsumed()).collect(Collectors.toList())));
// 6*实际工作天数
dto.setHaveTime(BigDecimal.valueOf(time));
dto.setHaveTime(BigDecimal.valueOf(time-approvalTime));
dto.setSaturation(dto.getWorkTime().compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:dto.getWorkTime().divide(dto.getHaveTime(),2,BigDecimal.ROUND_HALF_UP));
long count =0;
if(!CollectionUtils.isEmpty(fTask)){
count = bugService.count(new QueryWrapper<ZtBug>().lambda().in(ZtBug::getTotask, fTask.stream().map(o -> o.getId()).collect(Collectors.toList())));
count = this.bugService.count(new QueryWrapper<ZtBug>().lambda().between(ZtBug::getOpeneddate, firstDayOfMonth, lastDayOfMonth)
.in(ZtBug::getSeverity, 1, 2).eq(ZtBug::getResolvedby,u.getAccount()));
// count = bugService.count(new QueryWrapper<ZtBug>().lambda().in(ZtBug::getTotask, fTask.stream().map(o -> o.getId()).collect(Collectors.toList())));
}
dto.setBugCount(BigDecimal.valueOf(count));
result.add(dto);
@ -1535,7 +1557,7 @@ public class IZtCountService {
try (FileInputStream templateFile =new FileInputStream("scope开发.xlsx")) {
Map<String, String> dataMap = new HashMap<>();
dataMap.put("name", name);
dataMap.put("date", DateUtils.formatDate(new Date(),"yyyy-MM"));
dataMap.put("date", DateUtils.formatDate(d,"yyyy-MM"));
dataMap.put("准时率得分", performanceDTO.getPunctualityScore().toString());
dataMap.put("代码质量", "10");
dataMap.put("文档质量", "10");

View File

@ -21,6 +21,7 @@ import com.sa.zentao.qo.ZtBugQo;
import com.sa.zentao.qo.ZtProjectQo;
import com.sa.zentao.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sa.zentao.utils.BeanCopyUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -46,6 +47,9 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
@Autowired
private IZtKanbanlaneService kanbanlaneService;
@Autowired
private IZtExecutionprojectService executionprojectService;
@Autowired
private IZtActionService actionService;
@ -75,6 +79,10 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
@Autowired
private IZtTaskService taskService;
@Autowired
private IZtStoryFeedbackService storyFeedbackService;
@Override
public PageInfo<ZtBugDTO> bugPageList(ZtProjectQo qo) {
@ -84,7 +92,7 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
if(!CollectionUtils.isEmpty(result)){
List<String> fIds = result.stream().map(o -> o.getOpenedby()).collect(Collectors.toList());
fIds.addAll(result.stream().map(o->o.getAssignedTo()).collect(Collectors.toList()));
Map<String, ZtUser> userMap = userService.userMapByIds(fIds);
Map<String, ZtUser> userMap = userService.userMapByIds(null);
for (ZtBugDTO bug:result ) {
@ -97,7 +105,11 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
if(ztUser!=null){
bug.setAssignedToName(ztUser.getNickname());
}
ztUser = userMap.get(bug.getYsUser());
if(ztUser!=null){
bug.setYsUserName(ztUser.getNickname());
}
}
}
return new PageInfo<ZtBugDTO>(result);
@ -158,9 +170,7 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
List<ZtBugDTO> result = this.baseMapper.myBugPageList(qo);
if(!CollectionUtils.isEmpty(result)){
List<String> fIds = result.stream().map(o -> o.getOpenedby()).collect(Collectors.toList());
fIds.addAll(result.stream().map(o->o.getAssignedTo()).collect(Collectors.toList()));
Map<String, ZtUser> userMap = userService.userMapByIds(fIds);
Map<String, ZtUser> userMap = userService.userMapByIds(null);
for (ZtBugDTO bug:result ) {
@ -173,6 +183,11 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
if(ztUser!=null){
bug.setAssignedToName(ztUser.getNickname());
}
ztUser = userMap.get(bug.getYsUser());
if(ztUser!=null){
bug.setYsUserName(ztUser.getNickname());
}
}
}
@ -216,8 +231,15 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
if(ztUser!=null){
d.setAssignedToName(ztUser.getNickname());
}
ztUser = userMap.get(d.getOpenedby());
if(ztUser!=null){
d.setOpenedbyName(ztUser.getNickname());
}
ztUser = userMap.get(d.getYsUser());
if(ztUser!=null){
d.setYsUserName(ztUser.getNickname());
}
return d;
}
@ -257,24 +279,68 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
@Override
public void batchAddBug(ZtBugDTO dto) {
LoginRiskUser loginRiskUser = RiskUserThreadLocal.get();
if(loginRiskUser==null){
throw new BusinessException("请检查");
}
List<ZtBugDTO> list = dto.getList();
if(CollectionUtils.isEmpty(list)){
throw new BusinessException("请检查数据");
}
List<ZtBug> saveBatch=new ArrayList();
for (ZtBugDTO d:list) {
ZtBug b=new ZtBug();
BeanUtils.copyProperties(d,b);
b.setOpeneddate(new Date());
b.setOpenedby(RiskUserThreadLocal.get().getName());
b.setStatus("active");
saveBatch.add(b);
}
this.saveBatch(saveBatch);
if(dto.getExecution()!=null&&dto.getExecution()!=0){
kanbanlaneService.addBug(dto.getExecution(), saveBatch);
if(dto.getProject()!=null&&dto.getProject()!=0){
ZtProjectproduct projectproduct = this.projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, dto.getProject()));
Integer product = projectproduct.getProduct();
//项目bug
for (ZtBugDTO d:list) {
ZtBug b=new ZtBug();
BeanUtils.copyProperties(d,b);
b.setProduct(product);
b.setStory(d.getStory());
b.setTask(d.getTask());
b.setProject(dto.getProject());
b.setOpeneddate(new Date());
b.setOpenedby(loginRiskUser.getName());
b.setStatus("active");
saveBatch.add(b);
}
this.saveBatch(saveBatch);
Map<Integer, List<ZtBug>> eMap = saveBatch.stream().filter(o->o.getExecution()!=null&&o.getExecution()!=0).collect(Collectors.groupingBy(ZtBug::getExecution));
for (Integer e:eMap.keySet()) {
kanbanlaneService.addBug(e, eMap.get(e));
}
}
Integer execution = dto.getExecution();
if(execution!=null&&execution!=0){
ZtExecutionproject executionproject = this.executionprojectService.getOne(new QueryWrapper<ZtExecutionproject>().lambda().eq(ZtExecutionproject::getExecution, execution));
ZtProjectproduct projectproduct = this.projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, executionproject.getProject()));
Integer product = projectproduct.getProduct();
//项目bug
for (ZtBugDTO d:list) {
ZtBug b=new ZtBug();
BeanUtils.copyProperties(d,b);
b.setExecution(execution);
b.setProduct(product);
b.setStory(d.getStory());
b.setTask(d.getTask());
b.setProject(executionproject.getProject());
b.setOpeneddate(new Date());
b.setOpenedby(loginRiskUser.getName());
b.setStatus("active");
saveBatch.add(b);
}
this.saveBatch(saveBatch);
Map<Integer, List<ZtBug>> eMap = saveBatch.stream().collect(Collectors.groupingBy(ZtBug::getExecution));
kanbanlaneService.addBug(execution, saveBatch);
}
for (ZtBug ztBug:saveBatch) {
@ -284,6 +350,100 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
}
}
@Override
public void bugYs(ZtBugDTO dto) {
ZtBug bug = this.baseMapper.selectById(dto.getId());
if("closed".equals(bug.getStatus())){
throw new BusinessException("当前已关闭");
}
String resolved = bug.getStatus();
Integer revieweResult = dto.getReviewerResult();
ActionStatus status;
bug.setStatus("verified");
if(revieweResult==1){
status=ActionStatus.YSTG;
bug.setYsFlag(1);
}else{
status=ActionStatus.YSBTG;
bug.setYsFlag(2);
}
bug.setLasteditedby(RiskUserThreadLocal.get().getName());
bug.setLastediteddate(new Date());
bug.setYsRemark(dto.getDesc());
this.baseMapper.updateById(bug);
if(revieweResult==1&&bug.getFeedback()!=null&&bug.getFeedback()!=0){
}
//添加action
actionService.addAction(ActionType.BUG, status, bug.getId(), bug.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getDesc(), null);
}
@Override
public void taskStoryAddBug(ZtBugDTO dto) {
Integer task = dto.getTask();
Integer story = dto.getStory();
ZtBugDTO addBug=new ZtBugDTO();
BeanUtils.copyProperties(dto,addBug);
if(task!=null&&task!=0){
//任务bug
ZtTask ztTask = this.taskService.getById(task);
addBug.setStory(ztTask.getStory());
addBug.setExecution(ztTask.getExecution());
addBug.setProject(ztTask.getProject());
addBug.setProduct(ztTask.getProduct());
}else if(story!=null&&story!=0){
}
this.addBug(addBug);
}
@Override
public List<ZtBugDTO> bugListByTaskStory(ZtBugDTO dto) {
Integer task = dto.getTotask();
Integer story = dto.getTostory();
List<ZtBug> ztBugs = null;
if(task!=null&&task!=0){
ztBugs = this.baseMapper.selectList(new QueryWrapper<ZtBug>().lambda().eq(ZtBug::getTask, task));
}
if(story!=null&&story!=0){
ztBugs = this.baseMapper.selectList(new QueryWrapper<ZtBug>().lambda().eq(ZtBug::getStory, story));
}
List<ZtBugDTO> ztBugDTOS =new ArrayList<>();
if(!CollectionUtils.isEmpty(ztBugs)){
ztBugDTOS= BeanCopyUtil.copyListProperties(ztBugs, ZtBugDTO::new);
Map<String, ZtUser> userMap = this.userService.userMapByIds(null);
this.productService.getMap(new QueryWrapper<ZtProduct>());
for (ZtBugDTO bug:ztBugDTOS) {
ZtUser ztUser = userMap.get(bug.getOpenedby());
if(ztUser!=null){
bug.setOpenedbyName(ztUser.getNickname());
}
ztUser = userMap.get(bug.getAssignedTo());
if(ztUser!=null){
bug.setAssignedToName(ztUser.getNickname());
}
ztUser = userMap.get(bug.getYsUser());
if(ztUser!=null){
bug.setYsUserName(ztUser.getNickname());
}
}
}
return ztBugDTOS;
}
@Override
@Transactional
@ -321,7 +481,7 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
this.actionService.addAction(ActionType.BUG, ActionStatus.XJ,ztBug.getId(),ztBug.getProject()+"",ztBug.getProject(),ztBug.getExecution()
,RiskUserThreadLocal.get().getName(),ztBug.getSteps(),""
,RiskUserThreadLocal.get().getName(),"",""
);
}
@ -421,8 +581,10 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
if(ztBug.getExecution()!=null&&ztBug.getExecution()!=0) {
kanbanlaneService.changeStatus(ztBug.getExecution(), ztBug.getId(), "bug", "fixed");
}
if(ztBug.getFeedback()!=null&&ztBug.getFeedback()!=0){
this.storyFeedbackService.feedbackStart(ztBug.getFeedback());
this.storyFeedbackService.feedbackFinished(ztBug.getFeedback());
}
this.actionService.addAction(ActionType.BUG, ActionStatus.WC,ztBug.getId(),ztBug.getProject()+"",ztBug.getProject(),ztBug.getExecution()

View File

@ -9,6 +9,7 @@ import com.sa.zentao.dao.ZtStoryDTO;
import com.sa.zentao.entity.*;
import com.sa.zentao.enums.ActionStatus;
import com.sa.zentao.enums.ActionType;
import com.sa.zentao.enums.ProjectTypeEnums;
import com.sa.zentao.mapper.ZtKanbancolumnMapper;
import com.sa.zentao.mapper.ZtKanbanlaneMapper;
import com.sa.zentao.qo.KanbanQo;
@ -24,10 +25,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;
/**
@ -81,6 +79,7 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
Map<String, ZtUser> userMap = this.userService.userMapByIds(null);
List<ZtKanbancolumnDTO> listColumn =kanbancolumnService.listByLaneIds(ztKanbanlanes.stream().map(o->o.getId()).collect(Collectors.toList()));
for (ZtKanbanlaneDTO dto:ztKanbanlanes) {
List<ZtKanbancolumnDTO> collect = listColumn.stream().filter(o -> o.getLane().intValue() == dto.getId().intValue()).collect(Collectors.toList());
for (ZtKanbancolumnDTO d:collect) {
@ -90,6 +89,16 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
if(!StringUtils.isEmpty(cards)){
List<String> ids = (List<String>)CollectionUtils.arrayToList(cards.split(",")).stream().filter(o -> !StringUtils.isEmpty(String.valueOf(o))).collect(Collectors.toList());
if("story".equalsIgnoreCase(d.getCardType())){
Map<Integer, List<ZtProject>> executionMapByStory=null;
if(CollectionUtils.isEmpty(ids)){
executionMapByStory=new HashMap<>();
}else{
executionMapByStory = getExecutionMapByStory(ids.stream().map(o->Integer.valueOf(o)).collect(Collectors.toList()));
}
List<ZtStory> ztStories = this.storyService.listByIds(ids);
List<ZtStoryDTO> ztStoryDTOS = BeanCopyUtil.copyListProperties(ztStories, ZtStoryDTO::new);
List<ZtStoryspec> storySpecList = storyspecService.list(new QueryWrapper<ZtStoryspec>().lambda().in(ZtStoryspec::getStory, ids));
@ -98,6 +107,11 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
for (ZtStoryDTO st:ztStoryDTOS) {
ZtUser ztUser = userMap.get(st.getAssignedTo());
List<ZtProject> ztProjects = executionMapByStory.get(st.getId());
if(!CollectionUtils.isEmpty(ztProjects)){
st.setExecutionName(ztProjects.stream().map(o->o.getName()).collect(Collectors.joining(",")));
st.setExecutions(ztProjects.stream().map(o->o.getId()).collect(Collectors.toList()));
}
if(ztUser!=null){
st.setAssignedTo(ztUser.getNickname());
st.setColor(ztUser.getColor());
@ -395,5 +409,45 @@ public class ZtKanbanlaneServiceImpl extends ServiceImpl<ZtKanbanlaneMapper, ZtK
}
@Autowired
private IZtProjectService projectService;
@Autowired
private IZtProjectstoryService projectstoryService;
//需求id 执行
public Map<Integer,List<ZtProject>> getExecutionMapByStory(List<Integer> list) {
List<ZtProjectstory> pStoryList = projectstoryService.list(new QueryWrapper<ZtProjectstory>().lambda().eq(ZtProjectstory::getType, ProjectTypeEnums.execution.getValue())
.in(ZtProjectstory::getStory, list)
);
if(CollectionUtils.isEmpty(pStoryList)){
return new HashMap<>();
}
List<Integer> execIds = pStoryList.stream().map(o -> o.getProject()).collect(Collectors.toList());
List<ZtProject> ztProjects = this.projectService.listByIds(execIds);
Map<Integer,List<ZtProject>> result =new HashMap<>();
for (ZtProjectstory st:pStoryList) {
Integer execution = st.getProject();
List<ZtProject> fExecution = ztProjects.stream().filter(o -> o.getId().intValue() == execution.intValue()).collect(Collectors.toList());
ZtProject ztProject = fExecution.get(0);
List<ZtProject> mpList = result.get(st.getStory());
if(CollectionUtils.isEmpty(mpList)){
List<ZtProject> mList=new ArrayList<>();
mList.add(ztProject);
result.put(st.getStory(),mList);
}else{
mpList.add(ztProject);
}
}
return result;
}
}

View File

@ -129,7 +129,7 @@ public class ZtMeetingServiceImpl extends ServiceImpl<ZtMeetingMapper, ZtMeeting
//添加action
actionService.addAction(ActionType.MEET, ActionStatus.XJ, ztMeeting.getId(), ztMeeting.getProductId() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getRemark(), null);
RiskUserThreadLocal.get().getName(),"", null);
}

View File

@ -6,6 +6,7 @@ import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sa.zentao.conf.RiskUserThreadLocal;
import com.sa.zentao.dao.BusinessException;
import com.sa.zentao.dao.ZtAllBusinessDTO;
import com.sa.zentao.dao.ZtProductDTO;
import com.sa.zentao.dao.ZtProjectDTO;
import com.sa.zentao.entity.*;
@ -105,7 +106,7 @@ public class ZtProductServiceImpl extends ServiceImpl<ZtProductMapper, ZtProduct
ztProduct.setWhitelist(","+StringUtils.join(dto.getAuthList(),","));
}
this.baseMapper.insert(ztProduct);
actionService.addAction(ActionType.CP, ActionStatus.XJ,ztProduct.getId(),ztProduct.getId()+"",null,null,RiskUserThreadLocal.get().getName(),dto.getDesc(),null);
actionService.addAction(ActionType.CP, ActionStatus.XJ,ztProduct.getId(),ztProduct.getId()+"",null,null,RiskUserThreadLocal.get().getName(),"",null);
}
@ -395,6 +396,151 @@ public class ZtProductServiceImpl extends ServiceImpl<ZtProductMapper, ZtProduct
return ztProductDTOS;
}
}
@Autowired
private IZtProjectService projectService;
@Autowired
private IZtProjectproductService projectproductService;
@Autowired
private IZtExecutionprojectService executionprojectService;
@Autowired
private IZtStoryFeedbackService storyFeedbackService;
@Autowired
private IZtTaskService taskService;
@Override
public Map<String, Object> getAllBusinessSelect(ZtAllBusinessDTO dto) {
Map<String,Object> result=new HashMap<>();
Integer productId = dto.getProductId();
if(productId!=null&&productId!=0){
ZtProduct product = this.baseMapper.selectById(productId);
result.put("product",Arrays.asList(product));
List<ZtProjectproduct> projectproductlist = this.projectproductService.list(new QueryWrapper<ZtProjectproduct>().lambda()
.eq(ZtProjectproduct::getProduct, productId));
if(!CollectionUtils.isEmpty(projectproductlist)){
List<ZtProject> ztProjects = this.projectService.listByIds(projectproductlist.stream().map(o -> o.getProject()).collect(Collectors.toList()));
result.put("project",Arrays.asList(ztProjects));
List<ZtExecutionproject> list = this.executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda().in(ZtExecutionproject::getProject, ztProjects.stream().map(o -> o.getId()).collect(Collectors.toList())));
List<ZtProject> execList = this.projectService.listByIds(list.stream().map(o -> o.getExecution()).collect(Collectors.toList()));
result.put("execution",Arrays.asList(ztProjects));
}else{
result.put("project",Arrays.asList());
result.put("execution",Arrays.asList());
}
}
Integer projectId = dto.getProjectId();
if(projectId!=null&&projectId!=0){
ZtProject ztProject = this.projectService.getById(projectId);
result.put("project",Arrays.asList(ztProject));
ZtProjectproduct projectproduct = this.projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, projectId));
ZtProduct product = this.baseMapper.selectById(projectproduct.getProduct());
result.put("product",Arrays.asList(product));
List<ZtExecutionproject> list = this.executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda().in(ZtExecutionproject::getProject,
Arrays.asList(projectId)));
if(!CollectionUtils.isEmpty(list)){
List<ZtProject> execList = this.projectService.listByIds(list.stream().map(o -> o.getExecution()).collect(Collectors.toList()));
result.put("execution",execList);
}else{
result.put("execution",Arrays.asList());
}
}
Integer feedbackId = dto.getFeedbackId();
if(feedbackId!=null&&feedbackId!=0){
ZtStoryFeedback storyFeedback = storyFeedbackService.getById(feedbackId);
result.put("feedback",Arrays.asList(storyFeedback));
Integer pId = storyFeedback.getProduct();
ZtProduct product = this.baseMapper.selectById(pId);
result.put("product",Arrays.asList(product));
List<ZtProjectproduct> projectproductlist = this.projectproductService.list(new QueryWrapper<ZtProjectproduct>().lambda()
.eq(ZtProjectproduct::getProduct, pId));
if(!CollectionUtils.isEmpty(projectproductlist)){
List<ZtProject> ztProjects = this.projectService.listByIds(projectproductlist.stream().map(o -> o.getProject()).collect(Collectors.toList()));
result.put("project",Arrays.asList(ztProjects));
List<ZtExecutionproject> list = this.executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda().in(ZtExecutionproject::getProject, ztProjects.stream().map(o -> o.getId()).collect(Collectors.toList())));
List<ZtProject> execList = this.projectService.listByIds(list.stream().map(o -> o.getExecution()).collect(Collectors.toList()));
result.put("execution",Arrays.asList(ztProjects));
}else{
result.put("project",Arrays.asList());
result.put("execution",Arrays.asList());
}
}
Integer executionId = dto.getExecutionId();
if(executionId!=null&&executionId!=0){
ZtProject ztProject = this.projectService.getById(executionId);
result.put("execution",Arrays.asList(ztProject));
List<ZtExecutionproject> list = this.executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda().in(ZtExecutionproject::getExecution,
Arrays.asList(executionId)));
List<ZtProject> pList = this.projectService.listByIds(list.stream().map(o -> o.getProject()).collect(Collectors.toList()));
result.put("project",pList);
if(!CollectionUtils.isEmpty(pList)){
List<ZtProjectproduct> productList = this.projectproductService.list(new QueryWrapper<ZtProjectproduct>().lambda().in(ZtProjectproduct::getProject, pList.stream().map(o -> o.getProject()).collect(Collectors.toList())));
List<ZtProduct> products = this.baseMapper.selectList(new QueryWrapper<ZtProduct>().lambda().in(ZtProduct::getId, productList.stream().map(o -> o.getProduct()).collect(Collectors.toList())));
result.put("product",products);
}
}
Integer taskId = dto.getTaskId();
if(taskId!=null){
ZtTask task = this.taskService.getById(taskId);
result.put("task",task);
Integer execution = task.getExecution();
Integer product = task.getProduct();
Integer project = task.getProject();
Integer feedback = task.getFeedback();
result.put("product",(product==null||product==0)?Arrays.asList():Arrays.asList(this.getById(product)));
result.put("project",(project==null||project==0)?Arrays.asList():Arrays.asList(this.projectService.getById(project)));
result.put("execution",(execution==null||execution==0)?Arrays.asList():Arrays.asList(this.projectService.getById(execution)));
result.put("feedback",(feedback==null||feedback==0)?Arrays.asList():Arrays.asList(this.storyFeedbackService.getById(feedback)));
}else{
result.put("task",null);
}
Integer storyId = dto.getStoryId();
if(storyId!=null){
ZtStory ztStory = this.storyService.getById(storyId);
result.put("story",ztStory);
ZtProduct product = this.baseMapper.selectById(ztStory.getProduct());
result.put("product",Arrays.asList(product));
List<ZtProjectproduct> projectproductlist = this.projectproductService.list(new QueryWrapper<ZtProjectproduct>().lambda()
.eq(ZtProjectproduct::getProduct, product.getId()));
if(!CollectionUtils.isEmpty(projectproductlist)){
List<ZtProject> ztProjects = this.projectService.listByIds(projectproductlist.stream().map(o -> o.getProject()).collect(Collectors.toList()));
result.put("project",Arrays.asList(ztProjects));
List<ZtExecutionproject> list = this.executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda().in(ZtExecutionproject::getProject, ztProjects.stream().map(o -> o.getId()).collect(Collectors.toList())));
List<ZtProject> execList = this.projectService.listByIds(list.stream().map(o -> o.getExecution()).collect(Collectors.toList()));
result.put("execution",Arrays.asList(ztProjects));
}
}else{
result.put("story",null);
}
Integer bugId = dto.getBugId();
return result;
}
private Map<Integer, List<ZtProductDTO>> getChildrenMap(List<ZtProjectDTO> result) {

View File

@ -161,6 +161,8 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
}
String product = null;
Integer project = null;
if ("project".equalsIgnoreCase(ztProject.getType()) || "sprint".equalsIgnoreCase(ztProject.getType())) {
if (!CollectionUtils.isEmpty(dto.getProductIds())) {
List<Integer> productIds = dto.getProductIds();
@ -178,69 +180,8 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
//执行 要加看板
if ("sprint".equalsIgnoreCase(ztProject.getType())) {
//执行手动加 关联产品
List<Integer> projectList = new ArrayList<>(Arrays.asList(dto.getProject()));
List<ZtExecutionproject> saveList = new ArrayList();
for (Integer pId : projectList) {
ZtExecutionproject p = new ZtExecutionproject();
p.setExecution(ztProject.getId());
p.setProject(pId);
saveList.add(p);
}
this.executionprojectService.saveBatch(saveList);
addKanban(dto, ztProject);
int index = 5;
for (int i = 0; i < 3; i++) {
List<String> list = KanBanConstant.LANEMAP.get(i);
ZtKanbanlane ztKanbanlane = new ZtKanbanlane();
ztKanbanlane.setExecution(ztProject.getId());
ztKanbanlane.setType(list.get(0));
ztKanbanlane.setName(list.get(1));
ztKanbanlane.setOrder(index);
kanbanlaneService.save(ztKanbanlane);
index += 5;
Map<String, String> cMap = KanBanConstant.columnMap.get(i);
int pIndex = 0;
int pId = 0;
for (Map.Entry<String, String> e : cMap.entrySet()) {
String key = e.getKey();
String value = e.getValue();
if (pLis.contains(key)) {
ZtKanbancolumn ztKanbancolumn = new ZtKanbancolumn();
ztKanbancolumn.setParent(-1);
ztKanbancolumn.setType(key);
ztKanbancolumn.setName(value);
kanbancolumnService.save(ztKanbancolumn);
pIndex = 2;
pId = ztKanbancolumn.getId();
} else {
ZtKanbancolumn ztKanbancolumn = new ZtKanbancolumn();
ztKanbancolumn.setParent(pId);
ztKanbancolumn.setType(key);
ztKanbancolumn.setName(value);
kanbancolumnService.save(ztKanbancolumn);
if (pIndex != 0) {
pIndex = pIndex - 1;
if (pIndex == 0) {
pId = 0;
}
}
ZtKanbancell cell = new ZtKanbancell();
cell.setKanban(ztProject.getId());
cell.setLane(ztKanbanlane.getId());
cell.setColumn(ztKanbancolumn.getId());
cell.setType(ztKanbanlane.getType());
kanbancellService.save(cell);
}
}
}
}
}
addTeam(dto, ztProject);
@ -250,19 +191,95 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
actionService.addAction(type, ActionStatus.XJ, ztProject.getId(), product, project, exection, RiskUserThreadLocal.get().getName(), null, null);
}
private void addKanban(ZtProjectDTO dto,ZtProject ztProject) {
//执行手动加 关联产品
List<Integer> projectList = new ArrayList<>(Arrays.asList(dto.getProject()));
List<ZtExecutionproject> saveList = new ArrayList();
for (Integer pId : projectList) {
ZtExecutionproject p = new ZtExecutionproject();
p.setExecution(ztProject.getId());
p.setProject(pId);
saveList.add(p);
}
this.executionprojectService.saveBatch(saveList);
int index = 5;
for (int i = 0; i < 3; i++) {
List<String> list = KanBanConstant.LANEMAP.get(i);
ZtKanbanlane ztKanbanlane = new ZtKanbanlane();
ztKanbanlane.setExecution(ztProject.getId());
ztKanbanlane.setType(list.get(0));
ztKanbanlane.setName(list.get(1));
ztKanbanlane.setOrder(index);
kanbanlaneService.save(ztKanbanlane);
index += 5;
Map<String, String> cMap = KanBanConstant.columnMap.get(i);
int pIndex = 0;
int pId = 0;
for (Map.Entry<String, String> e : cMap.entrySet()) {
String key = e.getKey();
String value = e.getValue();
if (pLis.contains(key)) {
ZtKanbancolumn ztKanbancolumn = new ZtKanbancolumn();
ztKanbancolumn.setParent(-1);
ztKanbancolumn.setType(key);
ztKanbancolumn.setName(value);
kanbancolumnService.save(ztKanbancolumn);
pIndex = 2;
pId = ztKanbancolumn.getId();
} else {
ZtKanbancolumn ztKanbancolumn = new ZtKanbancolumn();
ztKanbancolumn.setParent(pId);
ztKanbancolumn.setType(key);
ztKanbancolumn.setName(value);
kanbancolumnService.save(ztKanbancolumn);
if (pIndex != 0) {
pIndex = pIndex - 1;
if (pIndex == 0) {
pId = 0;
}
}
ZtKanbancell cell = new ZtKanbancell();
cell.setKanban(ztProject.getId());
cell.setLane(ztKanbanlane.getId());
cell.setColumn(ztKanbancolumn.getId());
cell.setType(ztKanbanlane.getType());
kanbancellService.save(cell);
}
}
}
}
private void addTeam(ZtProjectDTO dto, ZtProject ztProject) {
if ("project".equalsIgnoreCase(dto.getType())) {
if (StringUtils.isEmpty(dto.getPm())) {
if (CollectionUtils.isEmpty(dto.getTeamList())) {
return;
}
ZtTeam ztTeam = new ZtTeam();
ztTeam.setRoot(ztProject.getId());
ztTeam.setAccount(ztProject.getPm());
ztTeam.setLimited("no");
ztTeam.setJoin(new Date());
ztTeam.setDays(ztProject.getDays());
ztTeam.setType("project");
this.teamService.save(ztTeam);
// ZtTeam ztTeam = new ZtTeam();
// ztTeam.setRoot(ztProject.getId());
// ztTeam.setAccount(ztProject.getPm());
// ztTeam.setLimited("no");
// ztTeam.setJoin(new Date());
// ztTeam.setDays(ztProject.getDays());
// ztTeam.setType("project");
// this.teamService.save(ztTeam);
for (String user : (List<String>) dto.getTeamList()) {
ZtTeam ztTeam = new ZtTeam();
ztTeam.setRoot(ztProject.getId());
ztTeam.setAccount(user);
ztTeam.setLimited("no");
ztTeam.setJoin(new Date());
ztTeam.setDays(ztProject.getDays());
ztTeam.setType("execution");
this.teamService.save(ztTeam);
}
}
if ("sprint".equalsIgnoreCase(dto.getType())) {
if (CollectionUtils.isEmpty(dto.getTeamList())) {
@ -952,6 +969,55 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
return execution.stream().map(o -> o.getAccount()).collect(Collectors.toList());
}
@Override
public List<String> projectTeamById(ZtProjectQo qo) {
List<ZtTeam> execution = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getType, "project")
.eq(ZtTeam::getRoot, qo.getId()));
if (CollectionUtils.isEmpty(execution)) {
return new ArrayList<>();
}
return execution.stream().map(o -> o.getAccount()).collect(Collectors.toList());
}
@Override
public void projectTeamUpdate(ZtProjectQo qo) {
List<String> teamList = qo.getTeamList();
if (CollectionUtils.isEmpty(teamList)) {
throw new BusinessException("请选择");
}
List saveList = new ArrayList();
List<ZtTeam> oldTeam = this.teamService.list(new QueryWrapper<ZtTeam>()
.lambda().eq(ZtTeam::getRoot, qo.getId())
.eq(ZtTeam::getType, "project"));
for (ZtTeam t : oldTeam) {
if (!teamList.contains(t.getAccount())) {
this.teamService.removeById(t.getId());
}
}
for (String s : teamList) {
List<ZtTeam> execution = this.teamService.list(new QueryWrapper<ZtTeam>()
.lambda().eq(ZtTeam::getAccount, s).eq(ZtTeam::getRoot, qo.getId())
.eq(ZtTeam::getType, "project"));
if (CollectionUtils.isEmpty(execution)) {
ZtTeam t = new ZtTeam();
t.setType("project");
t.setAccount(s);
t.setRoot(qo.getId());
t.setJoin(new Date());
saveList.add(t);
}
}
if (!CollectionUtils.isEmpty(saveList)) {
this.teamService.saveBatch(saveList);
}
}
@Override
@Transactional
public void execTeamUpdate(ZtProjectQo qo) {
@ -1039,8 +1105,9 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
return new HashMap<>();
}
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda().in(ZtTask::getExecution, execList.stream().map(o -> o.getExecution()).collect(Collectors.toList())));
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda()
.notIn(ZtTask::getStatus,"cancel","closed","reviewing","draft")
.in(ZtTask::getExecution, execList.stream().map(o -> o.getExecution()).collect(Collectors.toList())));
if (CollectionUtils.isEmpty(list)) {
return new HashMap<>();
}
@ -1112,7 +1179,9 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
.filter(o -> o.getAssignedTo().equals(ztUser.getAccount()))
.collect(Collectors.toList());
for (ZtTask t:taskList ) {
t.setAssignedToName(ztUser.getNickname());
}
Map<String, Object> m = new HashMap<>();
if (!CollectionUtils.isEmpty(taskList)) {
m.put("name", ztUser.getNickname());
@ -1319,8 +1388,8 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
//产品集
String execution = qo.getExecution();
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda()
.notIn(ZtTask::getStatus,"cancel","closed","reviewing" ,"draft")
.gt(ZtTask::getOpeneddate, firstDayOfMonth)
.lt(ZtTask::getOpeneddate, lastDayOfMonth)
.eq(ZtTask::getExecution, execution));
@ -1339,8 +1408,14 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
return new ArrayList<>();
}
List<ZtUser> accountList = this.userService.list(new QueryWrapper<ZtUser>().lambda().in(ZtUser::getAccount, accountIds)
.in(ZtUser::getUserType, UserType.KFZ, UserType.CS));
if (CollectionUtils.isEmpty(accountList)) {
return new ArrayList<>();
}
List<ZtUser> uList = this.userService.list(new QueryWrapper<ZtUser>().lambda().in(ZtUser::getAccount, accountIds).orderByDesc(ZtUser::getUserType));
List<ZtUser> uList = this.userService.list(new QueryWrapper<ZtUser>().lambda().in(ZtUser::getAccount, accountList.stream().map(o->o.getAccount()).collect(Collectors.toList())).orderByDesc(ZtUser::getUserType));
Map<String, ZtUser> uMap = this.userService.userMapByIdsOrderByType(null);
@ -1349,12 +1424,12 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
}
return workBuildResult(firstDayOfMonth,lastDayOfMonth, uList,list,effList,uMap);
return workBuildResult(firstDayOfMonth,lastDayOfMonth, uList,list,effList,uMap,qo.getNeedWeek());
}
List<Map<String, Object>> workBuildResult(Date firstDayOfMonth,Date lastDayOfMonth,List<ZtUser> uList,List<ZtTask> list,List<ZtEffort> effList,Map<String, ZtUser> uMap){
List<Map<String, Object>> workBuildResult(Date firstDayOfMonth,Date lastDayOfMonth,List<ZtUser> uList,List<ZtTask> list,List<ZtEffort> effList,Map<String, ZtUser> uMap,boolean needWeek){
for (ZtTask t : list) {
if (t.getDeadline() != null) {
t.setDeadline(DateUtils.getDayLast(t.getDeadline()));
@ -1401,9 +1476,18 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
Map<String, Object> m = new HashMap<>();
m.put("name", ztUser.getNickname());
m.put("account", ztUser.getAccount());
List<DkInfo> dkInfos = dkMap.get(ztUser.getAccount());
for (int i = 0; i < DateUtils.daysBetween(firstDayOfMonth,lastDayOfMonth); i++) {
Date d = DateUtils.dateAddDay(firstDayOfMonth, i);
boolean work = DateUtils.isWork(d);
if(needWeek){
if(!work){
continue;
}
}
List<ZtTask> taskList = list.stream().filter(o -> o.getEstStarted() != null && DateUtils.formatDate(o.getEstStarted()).equals(DateUtils.formatDate(d)))
.filter(o -> o.getAssignedTo().equals(ztUser.getAccount()))
.collect(Collectors.toList());
@ -1415,7 +1499,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
// //假期
// s = Constant.legalRepairDateMap.get(DateUtils.formatDate(d, "yyyy-MM-dd"));
JSONObject obj=new JSONObject();
boolean work = DateUtils.isWork(d);
if(CollectionUtils.isEmpty(dkInfos)){
obj.put("workCount","0");
}else{
@ -1461,7 +1545,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
.sum()).setScale(2, BigDecimal.ROUND_HALF_UP));
obj.put("selfAllocation",BigDecimal.valueOf(taskList.stream()
.filter(o->o.getOpenedbyAccount().equals(o.getAssignedToAccount()))
.map(o -> o.getUseTime()).mapToDouble(e -> e==null?0:e.floatValue())
.map(o -> o.getEstimate()).mapToDouble(e -> e==null?0:e.floatValue())
.sum()).setScale(2, BigDecimal.ROUND_HALF_UP));
obj.put("task",taskList);
if(CollectionUtils.isEmpty(taskList)){
@ -1539,6 +1623,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda()
.notIn(ZtTask::getStatus,"cancel","closed","reviewing" ,"draft")
.gt(ZtTask::getOpeneddate, firstDayOfMonth)
.lt(ZtTask::getOpeneddate, lastDayOfMonth)
.in(ZtTask::getExecution, execList.stream().map(o -> o.getExecution())
@ -1581,8 +1666,10 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
return new PageInfo< Map<String, Object>>(workBuildResult(firstDayOfMonth,lastDayOfMonth, uList,list,effList,uMap));
return new PageInfo< Map<String, Object>>(workBuildResult(firstDayOfMonth,lastDayOfMonth, uList,list,effList,uMap,qo.getNeedWeek()));
}
@Autowired
private IZtCountService countService;
@Override
public PageInfo pageMonthReport(ZtProjectQo qo) {
@ -1686,8 +1773,14 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
d.setStoryTotalTime(floatToBigDecimal(floatBatchAdd(taskList.stream().map(o -> o.getEstimate()).collect(Collectors.toList()))));
//实际产出工时
d.setWorkTime(floatToBigDecimal(floatBatchAdd(taskList.stream().map(o -> o.getConsumed()).collect(Collectors.toList()))));
List<ItApproval> approvalList = this.taskService.itApprovalByUserName(ztUser.getNickname(),firstDayOfMonth, lastDayOfMonth);
Integer applyTime=0;
if(!CollectionUtils.isEmpty(approvalList)){
applyTime=countService.getApprovalTime(approvalList,firstDayOfMonth);;
}
d.setQjTime(BigDecimal.valueOf(applyTime));
//可用工时
d.setHaveTime(BigDecimal.valueOf(DateUtils.getWorkDaysInCurrentMonth(date) * 6));
d.setHaveTime(BigDecimal.valueOf(DateUtils.getWorkDaysInCurrentMonth(date) * 6).subtract(applyTime<1?BigDecimal.ZERO:d.getQjTime()));
//工作饱和度
d.setSaturation(d.getWorkTime().compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:d.getWorkTime().divide(d.getHaveTime(),2,BigDecimal.ROUND_HALF_UP));
// 任务总量
@ -1726,7 +1819,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
d.setTaskFinishOnTimeRate(delayList.size()==0?BigDecimal.valueOf(100):BigDecimal.valueOf(100).subtract(BigDecimal.valueOf(delayList.size()).divide(d.getTaskCount(),2,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100))));
List<ZtBug> bugList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().in(ZtBug::getProduct, products.stream().map(o -> o.getId()).collect(Collectors.toList()))
.between(ZtBug::getOpenedby, firstDayOfMonth, lastDayOfMonth).eq(ZtBug::getResolvedby, account));
.between(ZtBug::getOpeneddate, firstDayOfMonth, lastDayOfMonth).eq(ZtBug::getResolvedby, account));
d.setBugCount(BigDecimal.valueOf(bugList.size()));
result.add(d);
@ -2037,6 +2130,60 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
return new PageInfo<ZtProjectDTO>(result);
}
@Override
public ZtProject projectByImplement(ZtProjectQo qo) {
String execution = qo.getExecution();
if(StringUtils.isEmpty(execution)){
throw new BusinessException("未查询到数据");
}
ZtExecutionproject execProject = this.executionprojectService.getOne(new QueryWrapper<ZtExecutionproject>().lambda().eq(ZtExecutionproject::getExecution, execution));
ZtProject project = this.baseMapper.selectById(execProject.getProject());
return project;
}
@Override
public Map<String, Boolean> getWorkInfoByDate(ZtProjectQo qo) {
Date startDate = qo.getStartDate();
Date endDate = qo.getEndDate();
Map<String,Boolean> map=new HashMap<>();
for (int i =0;i<DateUtils.daysBetween(startDate,endDate)+1;i++) {
Date date = DateUtils.dateAddDay(startDate, i);
if(DateUtils.isWork(date)){
map.put(DateUtils.formatDate(date,"yyyy-MM-dd"),true);
}else{
map.put(DateUtils.formatDate(date,"yyyy-MM-dd"),false);
}
}
return map;
}
@Override
@Transactional
public void executionBatchRemoveStory(String execution, List<Integer> storyIds) {
if(StringUtils.isEmpty(execution)||"0".equals(execution)||CollectionUtils.isEmpty(storyIds)){
throw new BusinessException("请检查参数");
}
List<ZtStory> storyList = this.storyService.listByIds(storyIds);
if(CollectionUtils.isEmpty(storyList)){
throw new BusinessException("未查询到数据");
}
for (ZtStory story:storyList) {
if(Arrays.asList("closed","released","tested","verified").contains(story.getStage())){
throw new BusinessException("当前需求无法更换迭代,请检查需求状态");
}
}
for (Integer storyId:storyIds ) {
this.removeExecutionStory(storyId,Arrays.asList(Integer.valueOf(execution)));
}
}
private Map<Integer, List<ZtTask>> execTaskMap(List<ZtProjectDTO> result) {
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda().in(ZtTask::getExecution, result.stream().map(o -> o.getId()).collect(Collectors.toList())));

View File

@ -129,7 +129,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
}
actionService.addAction(ActionType.FB, ActionStatus.XJ, ztRelease.getId(), ztRelease.getProduct() + "", ztRelease.getProject(), null,
RiskUserThreadLocal.get().getName(), dto.getDanger(), "");
RiskUserThreadLocal.get().getName(), "", "");
}
@Override

View File

@ -10,9 +10,7 @@ import com.github.pagehelper.PageInfo;
import com.sa.zentao.conf.LoginRiskUser;
import com.sa.zentao.conf.RiskUserThreadLocal;
import com.sa.zentao.controller.CommonsController;
import com.sa.zentao.dao.BusinessException;
import com.sa.zentao.dao.ZtStoryDTO;
import com.sa.zentao.dao.ZtStoryFeedbackDTO;
import com.sa.zentao.dao.*;
import com.sa.zentao.entity.*;
import com.sa.zentao.enums.ActionStatus;
import com.sa.zentao.enums.ActionType;
@ -35,7 +33,7 @@ import java.util.stream.Collectors;
/**
* <p>
* 服务实现类
* 服务实现类
* </p>
*
* @author gqb
@ -50,6 +48,12 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
@Autowired
private IZtStoryService storyService;
@Autowired
private IZtBugService bugService;
@Autowired
private IZtTaskService taskService;
@Autowired
private IZtActionService actionService;
@ -64,23 +68,23 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
List<ZtStoryFeedbackDTO> list = this.baseMapper.pageList(qo);
Map<String, ZtUser> userMap = userService.userMapByIds(null);
if(!CollectionUtils.isEmpty(list)){
Map<Integer, ZtStory> sMap =getStoryMap(list);
if (!CollectionUtils.isEmpty(list)) {
Map<Integer, ZtStory> sMap = getStoryMap(list);
for (ZtStoryFeedbackDTO dto:list) {
for (ZtStoryFeedbackDTO dto : list) {
ZtStory ztStory = sMap.get(dto.getStoryId());
if(ztStory!=null){
if (ztStory != null) {
dto.setStoryName(ztStory.getTitle());
}
ZtUser ztUser = userMap.get(dto.getOpenedBy());
if(ztUser!=null){
if (ztUser != null) {
dto.setOpenedByName(ztUser.getNickname());
}
ztUser = userMap.get(dto.getAssignedTo());
if(ztUser!=null){
if (ztUser != null) {
dto.setAssignedToName(ztUser.getNickname());
}
}
@ -93,12 +97,12 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
private Map<Integer, ZtStory> getStoryMap(List<ZtStoryFeedbackDTO> list) {
List<Integer> collect = list.stream().filter(o -> o.getStoryId() != null).map(o -> o.getStoryId()).collect(Collectors.toList());
if(CollectionUtils.isEmpty(collect)){
if (CollectionUtils.isEmpty(collect)) {
return new HashMap<>();
}
List<ZtStory> ztStories = this.storyService.listByIds(collect);
return ztStories.stream().collect(Collectors.toMap(ZtStory::getId,o->o));
return ztStories.stream().collect(Collectors.toMap(ZtStory::getId, o -> o));
}
@Autowired
@ -108,63 +112,63 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
@Transactional
public void addFeedback(ZtStoryFeedbackDTO dto) {
LoginRiskUser loginRiskUser = RiskUserThreadLocal.get();
String name=null;
if(loginRiskUser!=null){
name=loginRiskUser.getName();
String name = null;
if (loginRiskUser != null) {
name = loginRiskUser.getName();
}
ZtUser user= this.userService.getbyVxId(org.apache.commons.lang3.StringUtils.isEmpty(dto.getVx())?
dto.getWeixin():dto.getVx());
if(user!=null){
name=user.getAccount();
ZtUser user = this.userService.getbyVxId(org.apache.commons.lang3.StringUtils.isEmpty(dto.getVx()) ?
dto.getWeixin() : dto.getVx());
if (user != null) {
name = user.getAccount();
}
ZtStoryFeedback ztStoryFeedback = new ZtStoryFeedback();
BeanUtils.copyProperties(dto,ztStoryFeedback);
BeanUtils.copyProperties(dto, ztStoryFeedback);
ztStoryFeedback.setOpenedBy(name);
ztStoryFeedback.setOpenedDate(new Date());
ztStoryFeedback.setUpdateDate(new Date());
ztStoryFeedback.setUpdateUser(name);
if(ztStoryFeedback.getProduct()==null){
if (ztStoryFeedback.getProduct() == null) {
ztStoryFeedback.setProduct(145);
}
if(!org.apache.commons.lang3.StringUtils.isEmpty(ztStoryFeedback.getOpenSource())&&"weixin".equals(ztStoryFeedback.getOpenSource())){
if (!org.apache.commons.lang3.StringUtils.isEmpty(ztStoryFeedback.getOpenSource()) && "weixin".equals(ztStoryFeedback.getOpenSource())) {
ztStoryFeedback.setOpenSource("weixin");
ztStoryFeedback.setStatus("reviewing");
}else{
} else {
ztStoryFeedback.setStatus("wait");
}
ztStoryFeedback.setFileUrl(dto.getUrls());
this.baseMapper.insert(ztStoryFeedback);
if(!org.apache.commons.lang3.StringUtils.isEmpty(dto.getUrls())){
JSONArray array = JSONArray.parseArray(dto.getUrls());
if(array.size()>0){
List<String> list=new ArrayList<>();
for (int i =0;i<array.size();i++){
String o = array.getString(0);
ZtFile ztFile = commonsController.downLoad(o);
list.add(ztFile.getId().toString());
}
if (!org.apache.commons.lang3.StringUtils.isEmpty(dto.getUrls())) {
JSONArray array = JSONArray.parseArray(dto.getUrls());
if (array.size() > 0) {
List<String> list = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
String o = array.getString(0);
ZtFile ztFile = commonsController.downLoad(o);
list.add(ztFile.getId().toString());
}
fileService.updateFile(list.stream().collect(Collectors.joining(",")), ztStoryFeedback.getId(), FileTypes.feedbackStory);
}
}
fileService.updateFile(list.stream().collect(Collectors.joining(",")), ztStoryFeedback.getId(), FileTypes.feedbackStory);
}
}
actionService.addAction(ActionType.WTFK, ActionStatus.XJ, dto.getId(), dto.getProduct()+"", null, null,
RiskUserThreadLocal.get()==null?"admin":RiskUserThreadLocal.get().getName(), dto.getSpec(), "");
actionService.addAction(ActionType.WTFK, ActionStatus.XJ, dto.getId(), dto.getProduct() + "", null, null,
RiskUserThreadLocal.get() == null ? "admin" : RiskUserThreadLocal.get().getName(), "", "");
}
@Override
public void editFeedback(ZtStoryFeedbackDTO dto) {
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(dto.getId());
BeanUtils.copyProperties(dto,ztStoryFeedback);
BeanUtils.copyProperties(dto, ztStoryFeedback);
ztStoryFeedback.setUpdateUser(RiskUserThreadLocal.get().getName());
ztStoryFeedback.setUpdateDate(new Date());
this.baseMapper.updateById(ztStoryFeedback);
fileService.updateFile(dto.getFiles(),ztStoryFeedback.getId(), FileTypes.feedbackStory);
fileService.updateFile(dto.getFiles(), ztStoryFeedback.getId(), FileTypes.feedbackStory);
actionService.addAction(ActionType.WTFK, ActionStatus.BJ, dto.getId(), dto.getProduct()+"", null, null,
actionService.addAction(ActionType.WTFK, ActionStatus.BJ, dto.getId(), dto.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), null, "");
}
@ -174,32 +178,32 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
@Override
public void changeStatus(ZtStoryFeedbackDTO dto) {
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(dto.getId());
if(ztStoryFeedback.getStatus().equals("finished")|| ztStoryFeedback.getStatus().equals("closed")){
if (ztStoryFeedback.getStatus().equals("finished") || ztStoryFeedback.getStatus().equals("closed")) {
throw new BusinessException("无法更改");
}
ztStoryFeedback.setStatus(dto.getStatus());
ztStoryFeedback.setCloseRemark(dto.getCloseRemark());
if("finished".equals(dto.getStatus())){
if ("finished".equals(dto.getStatus())) {
ztStoryFeedback.setFinishDate(new Date());
}else{
} else {
ztStoryFeedback.setCloseDate(new Date());
}
if(!org.apache.commons.lang3.StringUtils.isEmpty(ztStoryFeedback.getOpenSource())&&ztStoryFeedback.getOpenSource().equals("weixin")){
StringBuilder b=new StringBuilder();
if (!org.apache.commons.lang3.StringUtils.isEmpty(ztStoryFeedback.getOpenSource()) && ztStoryFeedback.getOpenSource().equals("weixin")) {
StringBuilder b = new StringBuilder();
b.append(ztStoryFeedback.getName()).append(" 的问题");
if("finished".equals(dto.getStatus())){
if ("finished".equals(dto.getStatus())) {
//完成
b.append("已解决");
}else{
} else {
//关闭
b.append("已关闭");
}
vxService.sendMessageToVx(ztStoryFeedback.getWeixin(),b.toString(),new Date());
vxService.sendMessageToVx(ztStoryFeedback.getWeixin(), b.toString(), new Date());
}
this.baseMapper.updateById(ztStoryFeedback);
if(!StringUtils.isEmpty(dto.getCloseRemark())){
actionService.addAction(ActionType.WTFK, ActionStatus.BJ, dto.getId(), dto.getProduct()+"", null, null,
if (!StringUtils.isEmpty(dto.getCloseRemark())) {
actionService.addAction(ActionType.WTFK, ActionStatus.BJ, dto.getId(), dto.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getCloseRemark(), "");
}
}
@ -211,7 +215,7 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
if (ztStory == null) {
throw new BusinessException("未查询到");
}
if("closed".equals(ztStory.getStatus())){
if ("closed".equals(ztStory.getStatus())) {
throw new BusinessException("当前已关闭");
}
ztStory.setAssignedTo(org.apache.commons.lang3.StringUtils.isEmpty(dto.getAssignedTo()) ? "" : dto.getAssignedTo());
@ -227,7 +231,7 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
@Override
public void startHand(ZtStoryDTO dto) {
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(dto.getId());
if(ztStoryFeedback==null){
if (ztStoryFeedback == null) {
throw new BusinessException("未查询到");
}
ztStoryFeedback.setStatus("doing");
@ -238,8 +242,9 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
actionService.addAction(ActionType.WTFK, ActionStatus.KS, ztStoryFeedback.getId(), ztStoryFeedback.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getDesc(), ztStoryFeedback.getAssignedTo());
}
@Autowired
private IZtProjectService projectService;
private IZtProjectService projectService;
@Autowired
private IZtProductService productService;
@ -247,63 +252,62 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
public List<ZtStoryFeedbackDTO> ztStoryFeedbackDTO(ZtProjectQo qo) {
List<Integer> authList = this.projectService.authList();
if(CollectionUtils.isEmpty(authList)){
if (CollectionUtils.isEmpty(authList)) {
return new ArrayList<>();
}
List<ZtProduct> list = productService.list(new QueryWrapper<ZtProduct>().lambda().in(ZtProduct::getProgram, authList));
if(CollectionUtils.isEmpty(list)){
if (CollectionUtils.isEmpty(list)) {
return new ArrayList<>();
}
LambdaQueryWrapper<ZtStoryFeedback> query = new QueryWrapper<ZtStoryFeedback>().lambda()
.eq(ZtStoryFeedback::getAssignedTo, RiskUserThreadLocal.get().getName())
.or().eq(ZtStoryFeedback::getOpenedBy, RiskUserThreadLocal.get().getName());
if(!org.apache.commons.lang3.StringUtils.isEmpty(qo.getSearchValue())){
if("ALL".equals(qo.getSearchValue())){
query.eq(ZtStoryFeedback::getAssignedTo,RiskUserThreadLocal.get().getName());
if (!org.apache.commons.lang3.StringUtils.isEmpty(qo.getSearchValue())) {
if ("ALL".equals(qo.getSearchValue())) {
query.eq(ZtStoryFeedback::getAssignedTo, RiskUserThreadLocal.get().getName());
}
if("ZGW".equals(qo.getSearchValue())){
query.eq(ZtStoryFeedback::getAssignedTo,RiskUserThreadLocal.get().getName());
if ("ZGW".equals(qo.getSearchValue())) {
query.eq(ZtStoryFeedback::getAssignedTo, RiskUserThreadLocal.get().getName());
}
if("WCJ".equals(qo.getSearchValue())){
query.eq(ZtStoryFeedback::getOpenedBy,RiskUserThreadLocal.get().getName());
if ("WCJ".equals(qo.getSearchValue())) {
query.eq(ZtStoryFeedback::getOpenedBy, RiskUserThreadLocal.get().getName());
}
if("YJJ".equals(qo.getSearchValue())){
query.eq(ZtStoryFeedback::getStatus,"finished");
if ("YJJ".equals(qo.getSearchValue())) {
query.eq(ZtStoryFeedback::getStatus, "finished");
}
if("YGB".equals(qo.getSearchValue())){
if ("YGB".equals(qo.getSearchValue())) {
query.eq(ZtStoryFeedback::getStatus, "closed");
}
}else{
} else {
query.ne(ZtStoryFeedback::getStatus, "closed");
}
if(UserType.GSGC==RiskUserThreadLocal.get().getUserType()||"admin".equals(RiskUserThreadLocal.get().getName())){
if (UserType.GSGC == RiskUserThreadLocal.get().getUserType() || "admin".equals(RiskUserThreadLocal.get().getName())) {
}else {
} else {
query.in(ZtStoryFeedback::getProduct, list.stream().map(o -> o.getId()).collect(Collectors.toList()));
}
query.orderByDesc(ZtStoryFeedback::getId);
List<ZtStoryFeedback> closed = this.baseMapper.selectList(
query
);
if(CollectionUtils.isEmpty(closed)){
if (CollectionUtils.isEmpty(closed)) {
return new ArrayList<>();
}
return BeanCopyUtil.copyListProperties(closed,ZtStoryFeedbackDTO::new);
return BeanCopyUtil.copyListProperties(closed, ZtStoryFeedbackDTO::new);
}
@Override
public PageInfo<ZtStoryFeedbackDTO> myFeedbackPageList(ZtProjectQo qo) {
List<Integer> authList = this.projectService.authList();
if(CollectionUtils.isEmpty(authList)){
if (CollectionUtils.isEmpty(authList)) {
return new PageInfo<ZtStoryFeedbackDTO>();
}
List<ZtProduct> list = productService.list(new QueryWrapper<ZtProduct>().lambda().in(ZtProduct::getProgram, authList));
if(CollectionUtils.isEmpty(list)){
if (CollectionUtils.isEmpty(list)) {
return new PageInfo<ZtStoryFeedbackDTO>();
}
@ -315,76 +319,75 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
// .or()
// .eq(ZtStoryFeedback::getOpenedBy, RiskUserThreadLocal.get().getName()) ;}) ;
if(!org.apache.commons.lang3.StringUtils.isEmpty(qo.getSearchVal())){
if("ALL".equals(qo.getSearchVal())){
if (!org.apache.commons.lang3.StringUtils.isEmpty(qo.getSearchVal())) {
if ("ALL".equals(qo.getSearchVal())) {
}
if("ZGW".equals(qo.getSearchVal())){
query.eq(ZtStoryFeedback::getAssignedTo,RiskUserThreadLocal.get().getName());
if ("ZGW".equals(qo.getSearchVal())) {
query.eq(ZtStoryFeedback::getAssignedTo, RiskUserThreadLocal.get().getName());
}
if("WCJ".equals(qo.getSearchVal())){
query.eq(ZtStoryFeedback::getOpenedBy,RiskUserThreadLocal.get().getName());
if ("WCJ".equals(qo.getSearchVal())) {
query.eq(ZtStoryFeedback::getOpenedBy, RiskUserThreadLocal.get().getName());
}
if("YJJ".equals(qo.getSearchVal())){
query.eq(ZtStoryFeedback::getStatus,"finished");
if ("YJJ".equals(qo.getSearchVal())) {
query.eq(ZtStoryFeedback::getStatus, "finished");
}
if("YGB".equals(qo.getSearchVal())){
if ("YGB".equals(qo.getSearchVal())) {
query.eq(ZtStoryFeedback::getStatus, "closed");
}
if("WGB".equals(qo.getSearchVal())){
if ("WGB".equals(qo.getSearchVal())) {
query.ne(ZtStoryFeedback::getStatus, "closed");
}
}else{
} else {
query.ne(ZtStoryFeedback::getStatus, "closed");
}
// UserType.GSGC==RiskUserThreadLocal.get().getUserType()||
if("admin".equals(RiskUserThreadLocal.get().getName())){
if ("admin".equals(RiskUserThreadLocal.get().getName())) {
}else {
} else {
query.in(ZtStoryFeedback::getProduct, list.stream().map(o -> o.getId()).collect(Collectors.toList()));
}
if(!org.apache.commons.lang3.StringUtils.isEmpty(qo.getIds())){
if (!org.apache.commons.lang3.StringUtils.isEmpty(qo.getIds())) {
String[] split = qo.getIds().split(",");
query.in(ZtStoryFeedback::getId, new ArrayList<>(Arrays.asList(split)));
}
List<ZtProduct> products = this.productService.selectProductByName(qo.getProductName());
if(!CollectionUtils.isEmpty(products)){
query.in(ZtStoryFeedback::getProduct,products.stream().map(o->o.getId()).collect(Collectors.toList()));
if (!CollectionUtils.isEmpty(products)) {
query.in(ZtStoryFeedback::getProduct, products.stream().map(o -> o.getId()).collect(Collectors.toList()));
}
if(qo.getStartDate()!=null){
query.gt(ZtStoryFeedback::getOpenedDate,qo.getStartDate());
if (qo.getStartDate() != null) {
query.gt(ZtStoryFeedback::getOpenedDate, qo.getStartDate());
}
if(qo.getEndDate()!=null){
query.lt(ZtStoryFeedback::getOpenedDate,qo.getEndDate());
if (qo.getEndDate() != null) {
query.lt(ZtStoryFeedback::getOpenedDate, qo.getEndDate());
}
query.orderByDesc(ZtStoryFeedback::getId);
List<ZtStoryFeedback> listFeedback= this.baseMapper.selectList(
List<ZtStoryFeedback> listFeedback = this.baseMapper.selectList(
query
);
List<ZtStoryFeedbackDTO> ztStoryFeedbackDTOS = BeanCopyUtil.copyListProperties(listFeedback, ZtStoryFeedbackDTO::new);
if(!CollectionUtils.isEmpty(ztStoryFeedbackDTOS)){
if (!CollectionUtils.isEmpty(ztStoryFeedbackDTOS)) {
Map<String, ZtUser> userMap = this.userService.userMapByIds(null);
Map<Integer,ZtProduct> pMap=this.productService.selectMapProduct();
for (ZtStoryFeedbackDTO f:ztStoryFeedbackDTOS ) {
Map<Integer, ZtProduct> pMap = this.productService.selectMapProduct();
for (ZtStoryFeedbackDTO f : ztStoryFeedbackDTOS) {
ZtProduct ztProduct = pMap.get(f.getProduct());
if(ztProduct!=null){
if (ztProduct != null) {
f.setProductName(ztProduct.getName());
}
ZtUser ztUser = userMap.get(f.getOpenedBy());
if(ztUser!=null){
if (ztUser != null) {
f.setOpenedByName(ztUser.getNickname());
}
ztUser = userMap.get(f.getAssignedTo());
if(ztUser!=null){
if (ztUser != null) {
f.setAssignedToName(ztUser.getNickname());
}
@ -414,17 +417,286 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectOne(new QueryWrapper<ZtStoryFeedback>().lambda()
.eq(ZtStoryFeedback::getBusinessId,dto.getBusinessId()));
if(ztStoryFeedback!=null){
if(approval==1){
.eq(ZtStoryFeedback::getBusinessId, dto.getBusinessId()));
if (ztStoryFeedback != null) {
if (approval == 1) {
ztStoryFeedback.setStatus("wait");
}else{
} else {
ztStoryFeedback.setStatus("closed");
ztStoryFeedback.setApprovalRemark(dto.getApprovalRemark());
}
this.baseMapper.updateById(ztStoryFeedback);
}
//添加action
actionService.addAction(ActionType.WTFK, approval==1?ActionStatus.YSTG:ActionStatus.YSBTG, ztStoryFeedback.getId(), ztStoryFeedback.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getApprovalRemark(), null);
}
// task story bug
@Override
public void split(String type, Integer businessId) {
// if(Str){
//
// }
}
@Override
public void feedbackStart(Integer feedbackId) {
if (feedbackId == null || feedbackId == 0) {
throw new BusinessException("请检查问题反馈id");
}
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(feedbackId);
if (ztStoryFeedback == null) {
throw new BusinessException("未查询到问题反馈");
}
String status = ztStoryFeedback.getStatus();
if ("wait".equals(status)) {
ztStoryFeedback.setStatus("doing");
this.baseMapper.updateById(ztStoryFeedback);
}
}
@Override
public void feedbackFinished(Integer feedbackId) {
if (feedbackId == null || feedbackId == 0) {
throw new BusinessException("请检查问题反馈id");
}
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(feedbackId);
if (ztStoryFeedback == null) {
throw new BusinessException("未查询到问题反馈");
}
List<ZtStory> list = this.storyService.list(new QueryWrapper<ZtStory>().lambda().eq(ZtStory::getFeedback, feedbackId));
if(!CollectionUtils.isEmpty(list)){
for (ZtStory story :list) {
if(Arrays.asList("wait","projected","developing","developed","testing","tested").contains(story.getStage())){
return;
}
}
}
List<ZtBug> bugList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().eq(ZtBug::getFeedback, feedbackId));
if(!CollectionUtils.isEmpty(bugList)){
for (ZtBug b :bugList) {
if(Arrays.asList("wait","active").contains(b.getStatus())){
return;
}
}
}
List<ZtTask> feedbackList = this.taskService.list(new QueryWrapper<ZtTask>().lambda().eq(ZtTask::getFeedback, feedbackId));
if(!CollectionUtils.isEmpty(feedbackList)){
for (ZtTask t :feedbackList) {
if(Arrays.asList("pause","wait","reviewing","doing","draft").contains(t.getStatus())){
return;
}
}
}
ztStoryFeedback.setStatus("finished");
this.baseMapper.updateById(ztStoryFeedback);
}
@Override
public void submitVerified(ZtStoryDTO dto) {
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(dto.getId());
if(ztStoryFeedback==null){
throw new BusinessException("未查询到数据");
}
if(!ztStoryFeedback.getStatus().equals("finished")){
throw new BusinessException("当前状态无法提交");
}
ztStoryFeedback.setStatus("submitVerified");
this.baseMapper.updateById(ztStoryFeedback);
actionService.addAction(ActionType.WTFK, ActionStatus.TJYS, ztStoryFeedback.getId(), ztStoryFeedback.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getDesc(), ztStoryFeedback.getAssignedTo());
}
@Override
public void ysFeedback(Integer feedbackId) {
if (feedbackId == null || feedbackId == 0) {
throw new BusinessException("请检查问题反馈id");
}
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(feedbackId);
if (ztStoryFeedback == null) {
throw new BusinessException("未查询到问题反馈");
}
if (!Arrays.asList("finished","submitVerified").contains(ztStoryFeedback.getStatus())) {
return;
}
List<ZtStory> list = this.storyService.list(new QueryWrapper<ZtStory>().lambda().eq(ZtStory::getFeedback, feedbackId));
if(!CollectionUtils.isEmpty(list)){
for (ZtStory story :list) {
if(Arrays.asList("wait","projected","developing","developed","testing","tested","released").contains(story.getStage())){
return;
}
}
}
List<ZtBug> bugList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().eq(ZtBug::getFeedback, feedbackId));
if(!CollectionUtils.isEmpty(bugList)){
for (ZtBug b :bugList) {
if(Arrays.asList("wait","active").contains(b.getStatus())){
return;
}
}
}
List<ZtTask> feedbackList = this.taskService.list(new QueryWrapper<ZtTask>().lambda().eq(ZtTask::getFeedback, feedbackId));
if(!CollectionUtils.isEmpty(feedbackList)){
for (ZtTask t :feedbackList) {
if(Arrays.asList("pause","wait","reviewing","doing","draft").contains(t.getStatus())){
return;
}
}
}
ztStoryFeedback.setStatus("verified");
this.baseMapper.updateById(ztStoryFeedback);
}
@Override
@Transactional
public void storyYs(ZtStoryDTO dto) {
ZtStoryFeedback ztStory = this.baseMapper.selectById(dto.getId());
if("closed".equals(ztStory.getStatus())){
throw new BusinessException("当前已关闭");
}
if(!RiskUserThreadLocal.get().getName().equals(ztStory.getOpenedBy())){
throw new BusinessException("无验收权限");
}
String status = ztStory.getStatus();
if(!"submitVerified".equals(status)){
throw new BusinessException("当前无法验收");
}
Integer revieweResult = dto.getRevieweResult();
if(revieweResult==1){
ztStory.setStatus("verified");
ztStory.setYsFlag(1);
}else{
ztStory.setStatus("wait");
ztStory.setYsFlag(2);
}
this.baseMapper.updateById(ztStory);
//添加action
actionService.addAction(ActionType.WTFK, revieweResult==1?ActionStatus.YSTG:ActionStatus.YSBTG, ztStory.getId(), ztStory.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getDesc(), null);
}
@Override
@Transactional
public void dontHand(ZtStoryFeedbackDTO dto) {
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(dto.getId());
if(!ztStoryFeedback.getStatus().equals("wait")){
throw new BusinessException("当前状态无法处理");
}
ztStoryFeedback.setStatus("finished");
ztStoryFeedback.setDontHandRemark(dto.getDontHandRemark());
ztStoryFeedback.setDontHandSelect(dto.getDontHandSelect());
ztStoryFeedback.setUpdateDate(new Date());
ztStoryFeedback.setUpdateUser(RiskUserThreadLocal.get().getName());
this.baseMapper.updateById(ztStoryFeedback);
}
@Override
public ZtStoryFeedbackDTO getFeedbackById(ZtProjectQo qo) {
ZtStoryFeedback ztStoryFeedback = this.baseMapper.selectById(qo.getId());
ZtStoryFeedbackDTO d=new ZtStoryFeedbackDTO();
BeanUtils.copyProperties(ztStoryFeedback,d);
Map<String, ZtUser> userMap = this.userService.userMapByIds(null);
ZtUser ztUser = userMap.get(d.getAssignedTo());
if(ztUser!=null){
d.setAssignedToName(ztUser.getNickname());
}
ztUser = userMap.get(d.getOpenedBy());
if(ztUser!=null){
d.setOpenedByName(ztUser.getNickname());
}
ZtProduct product = this.productService.getById(ztStoryFeedback.getProduct());
d.setProductName(product.getName());
List<ZtTask> taskList = this.taskService.list(new QueryWrapper<ZtTask>().lambda().eq(ZtTask::getFeedback, ztStoryFeedback.getId()));
if(!CollectionUtils.isEmpty(taskList)){
List<ZtTaskDTO> tList = BeanCopyUtil.copyListProperties(taskList, ZtTaskDTO::new);
for (ZtTaskDTO t:tList) {
ztUser = userMap.get(t.getFinishedby());
if (ztUser != null) {
t.setFinishedbyName(ztUser.getNickname());
}
ztUser = userMap.get(t.getAssignedTo());
if (ztUser != null) {
t.setAssignedToName(ztUser.getNickname());
}
}
d.setTaskList(tList);
}
List<ZtBug> bugList = this.bugService.list(new QueryWrapper<ZtBug>().lambda().eq(ZtBug::getFeedback, ztStoryFeedback.getId()));
if(!CollectionUtils.isEmpty(bugList)){
List<ZtBugDTO> ztBugDTOS = BeanCopyUtil.copyListProperties(bugList, ZtBugDTO::new);
for (ZtBugDTO dto:ztBugDTOS) {
ztUser = userMap.get(dto.getOpenedby());
if(ztUser!=null){
dto.setOpenedbyName(ztUser.getNickname());
}
ztUser = userMap.get(dto.getAssignedTo());
if(ztUser!=null){
dto.setAssignedToName(ztUser.getNickname());
}
ztUser = userMap.get(dto.getYsUser());
if(ztUser!=null){
dto.setYsUserName(ztUser.getNickname());
}
ztUser = userMap.get(dto.getResolvedby());
if(ztUser!=null){
dto.setResolvedbyName(ztUser.getNickname());
}
}
d.setBugList(ztBugDTOS);
}
List<ZtStory> storyList = this.storyService.list(new QueryWrapper<ZtStory>().lambda().eq(ZtStory::getFeedback, ztStoryFeedback.getId()));
if(!CollectionUtils.isEmpty(storyList)){
List<ZtStoryDTO> storyDTOList = BeanCopyUtil.copyListProperties(storyList, ZtStoryDTO::new);
for (ZtStoryDTO dto:storyDTOList ) {
ztUser = userMap.get(d.getAssignedTo());
if(ztUser!=null){
d.setAssignedToName(ztUser.getNickname());
}
ztUser = userMap.get(dto.getOpenedby());
if(ztUser!=null){
dto.setOpenedbyName(ztUser.getNickname());
}
ztUser = userMap.get(dto.getYsUser());
if(ztUser!=null){
dto.setYsUserName(ztUser.getNickname());
}
}
d.setStoryList(storyDTOList);
}
return d;
}
@Override
public void addRemark(ZtStoryDTO dto) {
ZtStoryFeedback ztStory = this.baseMapper.selectById(dto.getId());
actionService.addAction(ActionType.WTFK, ActionStatus.TJBZ, dto.getId(), ztStory.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getRemark(), "");
}
}

View File

@ -199,11 +199,11 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if(!storyFeedback.getStatus().equals("wait")){
throw new BusinessException("问题反馈已被处理");
}
storyFeedback.setStatus("doing");
storyFeedback.setStoryId(s.getId());
storyFeedback.setUpdateDate(new Date());
storyFeedback.setUpdateUser(RiskUserThreadLocal.get().getName());
this.storyFeedbackService.updateById(storyFeedback);
// storyFeedback.setStatus("doing");
// storyFeedback.setStoryId(s.getId());
// storyFeedback.setUpdateDate(new Date());
// storyFeedback.setUpdateUser(RiskUserThreadLocal.get().getName());
// this.storyFeedbackService.updateById(storyFeedback);
}
if(dto.getUserStory()!=null&&dto.getUserStory()!=0){
ZtStoryUser storyUser = storyUserService.getById(dto.getUserStory());
@ -218,7 +218,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
actionService.addAction(ActionType.XQ, ActionStatus.XJ, s.getId(), "", dto.getProduct(), null,
RiskUserThreadLocal.get().getName(), dto.getClosedreason(), "");
RiskUserThreadLocal.get().getName(), "", "");
if (!CollectionUtils.isEmpty(dto.getUserViewId())) {
for (String str : dto.getUserViewId()) {
@ -254,7 +254,6 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
private ZtStoryspec buildSpec(ZtStoryDTO dto, ZtStory s) {
@ -284,7 +283,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
}
s.setFeedback(dto.getFeedbackId());
s.setStage("wait");
return s;
}
@ -319,7 +318,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
actionService.addAction(ActionType.XQ, ActionStatus.XJ, s.getId(), "", dto.getProduct(), null,
RiskUserThreadLocal.get().getName(), dto.getClosedreason(), "");
RiskUserThreadLocal.get().getName(), "", "");
if (!CollectionUtils.isEmpty(dto.getUserViewId())) {
for (String str : dto.getUserViewId()) {
@ -384,7 +383,10 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
}
//迭代关联
executionBindStory(ztStory,execList);
if(!CollectionUtils.isEmpty(execList)){
executionBindStory(ztStory,execList);
}
execList.clear();
for (Integer oldExec:oldExecIds) {
if(!executions.contains(oldExec)){
@ -393,7 +395,21 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
}
//取消关联
// executionUnBindStory(ztStory.getId(),execList);
if(!CollectionUtils.isEmpty(execList)){
executionUnBindStory(ztStory.getId(),execList);
}
}else{
if(Arrays.asList("closed","released","tested","verified").contains(ztStory.getStage())){
throw new BusinessException("当前需求无法更换迭代,请检查需求状态");
}
Integer storyId = ztStory.getId();
List<ZtProjectstory> execList = this.projectstoryService.list(new QueryWrapper<ZtProjectstory>().lambda().eq(ZtProjectstory::getStory, storyId)
.eq(ZtProjectstory::getType, "execution")
);
if(!CollectionUtils.isEmpty(execList)){
executionUnBindStory(storyId,execList.stream().map(o->o.getProject()).collect(Collectors.toList()));
}
}
@ -433,7 +449,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
String stage = ztStory.getStage();
if(!StringUtils.isEmpty(stage)&&!stage.equals(dto.getStage())){
if(!StringUtils.isEmpty(stage)&&!StringUtils.isEmpty(dto.getStage())&&!stage.equals(dto.getStage())){
ZtStoryDTO s =new ZtStoryDTO();
s.setIdList(Arrays.asList(ztStory.getId()));
s.setStage(dto.getStage());
@ -512,17 +528,17 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
private void executionUnBindStory(Integer storyId,List<Integer> execList){
if(CollectionUtils.isEmpty(execList)){
return;
}else{
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda().eq(ZtTask::getStory, storyId)
.in(ZtTask::getExecution, execList)
);
if(!CollectionUtils.isEmpty(list)){
throw new BusinessException("当前迭代已开始任务,无法取消关联 迭代Id:"+list.get(0).getId());
}
}
// if(CollectionUtils.isEmpty(execList)){
// return;
// }else{
// List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda().eq(ZtTask::getStory, storyId)
// .in(ZtTask::getExecution, execList)
// );
//
// if(!CollectionUtils.isEmpty(list)){
// throw new BusinessException("当前迭代已开始任务,无法取消关联 迭代Id:"+list.get(0).getId());
// }
// }
projectService.removeExecutionStory(storyId,execList);
@ -682,6 +698,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if(!CollectionUtils.isEmpty(ztProjectList)){
d.setPlan(ztProjectList.stream().map(o->o.getName()).collect(Collectors.joining(",")));
d.setExecutions(ztProjectList.stream().map(o->o.getId()).collect(Collectors.toList()));
}
ZtUser ztUser = userMap.get(d.getAssignedTo());
@ -845,23 +862,11 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
for (Integer execution:executionId) {
kanbanlaneService.changeStatus(execution,id,"story","developing");
}
// if(execution!=null&&execution!=0){
// //查 ready
// //backlog
// ZtKanbancell backlog = this.kanbanlaneService.getZtKanbanlane("story", "backlog", execution);
// ZtKanbancell ready = this.kanbanlaneService.getZtKanbanlane("story", "ready", execution);
// ZtKanbancell toCell = this.kanbanlaneService.getZtKanbanlane("story", "developing", execution);
// Integer fromId = backlog.getCards().contains(id.toString()) ? backlog.getColumn() : ready.getColumn();
//
//
// KanbanQo qo = new KanbanQo();
// qo.setStatusType("developing");
// qo.setTabType("story");
// qo.setId(ztStory.getId());
// qo.setFromId(fromId);
// qo.setToId(toCell.getColumn());
// kanbanlaneService.changeStatus(qo);
// }
if(ztStory.getFeedback()!=null&&ztStory.getFeedback()!=0){
this.storyFeedbackService.feedbackStart(ztStory.getFeedback());
}
actionService.addAction(ActionType.XQ, ActionStatus.KS, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null,
RiskUserThreadLocal.get().getName(), null, "");
@ -869,25 +874,31 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
@Override
@Transactional
public void finishStory(Integer id) {
public void finishStory(Integer id,String finishBy) {
if(id==null||id==0){
return;
}
ZtStory ztStory = this.baseMapper.selectById(id);
if(ztStory.getFeedback()!=null&&ztStory.getFeedback()!=0){
this.storyFeedbackService.feedbackStart(ztStory.getFeedback());
}
if(ztStory==null){
throw new BusinessException("未查询到需求");
}
List<ZtTask> taskList = taskService.list(new QueryWrapper<ZtTask>().lambda().eq(ZtTask::getStory, id)
.in(ZtTask::getStatus, Arrays.asList("wait", "doing", "pause"))
.in(ZtTask::getStatus, Arrays.asList("reviewing","wait", "doing", "pause"))
.eq(ZtTask::getType,"devel")
);
//任务没有做完
//任务没有做完 如果任务还没开始
if(!CollectionUtils.isEmpty(taskList)){
if(Arrays.asList("wait","projected").contains(ztStory.getStage())){
this.startStory(id);
}
return;
}
//developed 研发完毕 testing 测试中 tested测试完毕 released已发布 verified已验收 closed
@ -930,18 +941,22 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
kanbanlaneService.changeStatus(execution,id,"story","developed");
}
actionService.addAction(ActionType.XQ, ActionStatus.WC, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null,
RiskUserThreadLocal.get().getName(), null, "");
actionService.addAction(ActionType.XQ, ActionStatus.KFWC, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null,
StringUtils.isEmpty(finishBy)?RiskUserThreadLocal.get().getName():finishBy, null, "");
}
@Override
public void testedStory(Integer story) {
public void testedStory(Integer story,String finishBy) {
if(story==null||story==0){
return;
}
ZtStory ztStory = this.baseMapper.selectById(story);
if(ztStory.getFeedback()!=null&&ztStory.getFeedback()!=0){
this.storyFeedbackService.feedbackStart(ztStory.getFeedback());
}
if(ztStory==null){
throw new BusinessException("未查询到数据-需求");
}
@ -1016,6 +1031,10 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
ZtStory ztStory = this.baseMapper.selectById(story);
if(ztStory.getFeedback()!=null&&ztStory.getFeedback()!=0){
this.storyFeedbackService.feedbackFinished(ztStory.getFeedback());
}
if(ztStory==null){
throw new BusinessException("未查询到数据-需求");
}
@ -1070,6 +1089,12 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
}
}
if(ztStory.getFeedback()!=null&&ztStory.getFeedback()!=0){
this.storyFeedbackService.feedbackFinished(ztStory.getFeedback());
}
actionService.addAction(ActionType.XQ, ActionStatus.FBCG, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), execIds.get(0),
RiskUserThreadLocal.get().getName(), null, "");
}
@ -1085,6 +1110,9 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
if(ztStory==null){
throw new BusinessException("未查询到数据-需求");
}
if(ztStory.getFeedback()!=null&&ztStory.getFeedback()!=0){
this.storyFeedbackService.feedbackStart(ztStory.getFeedback());
}
if(!Arrays.asList("wait","projected","developing","developed").contains(ztStory.getStage())){
return;
}
@ -1583,6 +1611,11 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
status=ActionStatus.YSBTG;
}
this.baseMapper.updateById(ztStory);
if(revieweResult==1&&ztStory.getFeedback()!=null&&ztStory.getFeedback()!=0){
this.storyFeedbackService.ysFeedback(ztStory.getFeedback());
}
//添加action
actionService.addAction(ActionType.XQ, status, ztStory.getId(), ztStory.getProduct() + "", null, null,
RiskUserThreadLocal.get().getName(), dto.getDesc(), ztStory.getAssignedTo());

View File

@ -83,7 +83,7 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
fileService.updateFile(dto.getFiles(),s.getId(), FileTypes.userStory);
actionService.addAction(ActionType.USERXQ, ActionStatus.XJ, s.getId(), dto.getProduct()+"", null, null,
RiskUserThreadLocal.get().getName(), dto.getClosedreason(), "");
RiskUserThreadLocal.get().getName(), "", "");
if (!CollectionUtils.isEmpty(dto.getUserViewId())) {
for (String str : dto.getUserViewId()) {
@ -94,7 +94,7 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
v.setType("userStory");
this.storyreviewService.save(v);
actionService.addAction(ActionType.USERXQ, ActionStatus.PS, s.getId(), s.getProduct() + "", s.getProject(), null,
RiskUserThreadLocal.get().getName(), dto.getClosedreason(), str);
RiskUserThreadLocal.get().getName(),"", str);
}
}

View File

@ -57,6 +57,9 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
@Autowired
private IZtStoryService storyService;
@Autowired
private IZtStoryFeedbackService storyFeedbackService;
@Autowired
private IZtUserService userService;
@ -138,28 +141,34 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
throw new BusinessException(tList.get(0).getName() + "当前评审人错误");
}
for (ZtTask t : ztTasks) {
if (dto.getApprovalStatus() == 1) {
t.setStatus("wait");
} else {
t.setStatus("closed");
}
t.setApprovalRemark(dto.getApprovalRemark());
t.setLastediteddate(new Date());
t.setLasteditedby(RiskUserThreadLocal.get().getName());
this.baseMapper.updateById(t);
ZtProjectproduct projectproduct = projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, t.getProject()));
if (dto.getApprovalStatus() == 1) {
actionService.addAction(ActionType.RW, ActionStatus.PSTG, t.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), t.getExecution(),
RiskUserThreadLocal.get().getName(), dto.getApprovalRemark(), null);
} else if (dto.getApprovalStatus() == 2) {
actionService.addAction(ActionType.RW, ActionStatus.PSBTG, t.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), t.getExecution(),
RiskUserThreadLocal.get().getName(), dto.getApprovalRemark(), null);
}
ZtTaskDTO ztTaskDTO = new ZtTaskDTO();
ztTaskDTO.setApprovalStatus(dto.getApprovalStatus());
ztTaskDTO.setApprovalRemark(dto.getApprovalRemark());
BeanUtils.copyProperties(t,ztTaskDTO);
this.approval(ztTaskDTO);
//
// if (dto.getApprovalStatus() == 1) {
// t.setStatus("wait");
// } else {
// t.setStatus("closed");
// }
//
// t.setApprovalRemark(dto.getApprovalRemark());
// t.setLastediteddate(new Date());
// t.setLasteditedby(RiskUserThreadLocal.get().getName());
// this.baseMapper.updateById(t);
//
//
// ZtProjectproduct projectproduct = projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, t.getProject()));
//
//
// if (dto.getApprovalStatus() == 1) {
// actionService.addAction(ActionType.RW, ActionStatus.PSTG, t.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), t.getExecution(),
// RiskUserThreadLocal.get().getName(), dto.getApprovalRemark(), null);
// } else if (dto.getApprovalStatus() == 2) {
// actionService.addAction(ActionType.RW, ActionStatus.PSBTG, t.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), t.getExecution(),
// RiskUserThreadLocal.get().getName(), dto.getApprovalRemark(), null);
// }
}
}
@ -408,7 +417,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
actionService.addAction(ActionType.RW, ActionStatus.XJ, ztTask.getId()
, projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), ztTask.getExecution(),
RiskUserThreadLocal.get().getName(), dto.getDesc(), null);
RiskUserThreadLocal.get().getName(),"", null);
if(dto.getFinishedFlag()!=null&&dto.getFinishedFlag()==1){
@ -430,6 +439,9 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
if (ztTask == null) {
throw new BusinessException("未查询到数据");
}
// if(!Arrays.asList("draft","reviewing").contains(ztTask.getStatus())){
// throw new BusinessException("当前无法编辑");
// }
String desc = ztTask.getDesc();
String status = ztTask.getStatus();
BeanUtils.copyProperties(dto, ztTask, "left", "consumed");
@ -441,13 +453,13 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
if (ztTask.getDeadline() != null) {
ztTask.setDeadlineTime(ztTask.getDeadline().getTime() / 1000);
}
UserType userType = RiskUserThreadLocal.get().getUserType();
if (dto.getDraftFlag() != null && dto.getDraftFlag() == 1) {
ztTask.setStatus("draft");
}else{
if(status.equals("draft")){
//如果是开发人员 需要评审
UserType userType = RiskUserThreadLocal.get().getUserType();
if (userType == UserType.KFZ) {
ZtProject ztProject = this.ztProjectService.getById(ztTask.getExecution());
ztTask.setStatus("reviewing");
@ -456,11 +468,15 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
ztTask.setStatus("wait");
ztTask.setReviewingUser(null);
}
}else if ((userType==UserType.XMGLY||userType==UserType.GSGC) &&status.equals("wait")){
ztTask.setStatus("wait");
}else{
ztTask.setStatus("reviewing");
ZtProject ztProject = this.ztProjectService.getById(ztTask.getExecution());
ztTask.setReviewingUser(ztProject.getPm());
ztTask.setApprovalResult(0);
}
}
if(dto.getFinishedFlag()==null||dto.getFinishedFlag()==0){
//不完成任务
@ -526,6 +542,14 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
ztTask.setConsumed(dto.getConsumed());
ztTask.setLeft(dto.getLeft() - dto.getConsumed());
this.baseMapper.updateById(ztTask);
if(ztTask.getFeedback()!=null&&ztTask.getFeedback()!=0){
if("doing".equals(ztTask.getStatus())){
this.storyFeedbackService.feedbackStart(ztTask.getFeedback());
}else{
this.storyFeedbackService.feedbackFinished(ztTask.getFeedback());
}
}
if (dto.getConsumed() > 0) {
ZtEffortDTO e = new ZtEffortDTO();
BeanUtils.copyProperties(ztTask, e);
@ -575,7 +599,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
//处理需求
if ("done".equals(ztTask.getStatus())) {
this.storyService.finishStory(ztTask.getStory());
this.storyService.finishStory(ztTask.getStory(),null);
} else if ("doing".equals(ztTask.getStatus())) {
this.storyService.startStory(ztTask.getStory());
}
@ -583,7 +607,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
if ("test".equals(ztTask.getType())) {
//处理需求
if ("done".equals(ztTask.getStatus())) {
this.storyService.testedStory(ztTask.getStory());
this.storyService.testedStory(ztTask.getStory(),null);
} else if ("doing".equals(ztTask.getStatus())) {
this.storyService.testingStory(ztTask.getStory());
}
@ -601,20 +625,21 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
String type = ztTask.getType();
if (ztTask.getStory() != null && ztTask.getStory() != 0) {
if ("test".equals(type)) {
this.storyService.testedStory(ztTask.getStory());
this.storyService.testedStory(ztTask.getStory(),null);
} else if ("devel".equals(type)) {
//开发
this.storyService.finishStory(ztTask.getStory());
this.storyService.finishStory(ztTask.getStory(),null);
}
}
}
}
@Override
@Transactional
public void finishTask(ZtTaskDTO dto) {
public void finishTask(ZtTaskDTO dto,String finishBy) {
ZtTask ztTask = this.baseMapper.selectById(dto.getId());
if ("done".equalsIgnoreCase(ztTask.getStatus())) {
throw new BusinessException("未查询到数据");
@ -638,12 +663,13 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
e.setObjectid(ztTask.getId());
e.setLeft(0F);
e.setConsumed(dto.getConsumed());
e.setAccount(StringUtils.isEmpty(finishBy)?RiskUserThreadLocal.get().getName():finishBy);
this.effortService.add(e);
//添加action
ZtProjectproduct projectproduct = projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, ztTask.getProject()));
actionService.addAction(ActionType.RW, ActionStatus.WC, dto.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), ztTask.getExecution(),
RiskUserThreadLocal.get().getName(), dto.getRemark(), null);
StringUtils.isEmpty(finishBy)?RiskUserThreadLocal.get().getName():finishBy, dto.getRemark(), null);
if (ztTask.getExecution() != null && ztTask.getExecution() != 0) {
if (StringUtils.isEmpty(dto.getTabType())) {
// KanbanQo qo = new KanbanQo();
@ -679,12 +705,16 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
String type = ztTask.getType();
if (ztTask.getStory() != null && ztTask.getStory() != 0) {
if ("test".equals(type)) {
this.storyService.testedStory(ztTask.getStory());
this.storyService.testedStory(ztTask.getStory(),finishBy);
} else if ("devel".equals(type)) {
//开发
this.storyService.finishStory(ztTask.getStory());
this.storyService.finishStory(ztTask.getStory(),finishBy);
}
}
if(ztTask.getFeedback()!=null&&ztTask.getFeedback()!=0){
this.storyFeedbackService.feedbackFinished(ztTask.getFeedback());
}
}
@Override
@ -828,7 +858,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
ZtProjectproduct projectproduct = projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, projectStory.getProject()));
actionService.addAction(ActionType.RW, ActionStatus.XJ, t.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), t.getExecution(),
RiskUserThreadLocal.get().getName(), dto.getDesc(), null);
RiskUserThreadLocal.get().getName(), "", null);
}
}
@ -861,31 +891,16 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
} else {
t.setApprovalResult(1);
t.setStatus("draft");
// if(t.getFinishedFlag()!=null&&t.getFinishedFlag()==1){
// t.setStatus("draft");
// }else{
// t.setStatus("closed");
// }
}
t.setApprovalRemark(dto.getApprovalRemark());
t.setLastediteddate(new Date());
t.setLasteditedby(RiskUserThreadLocal.get().getName());
if (dto.getApprovalStatus() == 1) {
if(t.getFinishedFlag()!=null&&t.getFinishedFlag()==1){
dto.setConsumed(t.getEstimate());
dto.setRealstarted(t.getRealstarted());
dto.setFinishedDate(t.getFinishedDate());
this.finishTask(dto);
}
}
this.baseMapper.updateById(t);
ZtProjectproduct projectproduct = projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, t.getProject()));
if (dto.getApprovalStatus() == 1) {
actionService.addAction(ActionType.RW, ActionStatus.PSTG, t.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), t.getExecution(),
RiskUserThreadLocal.get().getName(), dto.getApprovalRemark(), null);
@ -893,6 +908,19 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
actionService.addAction(ActionType.RW, ActionStatus.PSBTG, t.getId(), projectproduct == null ? null : projectproduct.getProduct().toString(), projectproduct == null ? null : projectproduct.getProject(), t.getExecution(),
RiskUserThreadLocal.get().getName(), dto.getApprovalRemark(), null);
}
this.baseMapper.updateById(t);
if (dto.getApprovalStatus() == 1) {
if(t.getFinishedFlag()!=null&&t.getFinishedFlag()==1){
dto.setConsumed(t.getEstimate());
dto.setRealstarted(t.getRealstarted());
dto.setFinishedDate(t.getFinishedDate());
this.finishTask(dto,t.getAssignedTo());
}
}
}

View File

@ -70,7 +70,14 @@
SELECT * from zt_bug
WHERE 1=1
and project =#{qo.project}
<if test="qo.project != null and qo.project != 0">
and project =#{qo.project}
</if>
<if test="qo.execution != null and qo.execution != '' ">
and execution =#{qo.execution}
</if>
<if test="qo.searchVal == 'ALL' ">
</if>

View File

@ -209,6 +209,8 @@
WHERE pj.id = pd.project
and pj.type = 'project'
and pd.product = #{qo.productId}
and pj.deleted='0'
and pj.status not in('closed')
</select>
<select id="executionListByProduct" resultType="com.sa.zentao.entity.ZtProject">
SELECT * from zt_project pj,zt_projectproduct pd

Binary file not shown.