日报月报
This commit is contained in:
@ -1,17 +1,49 @@
|
||||
package com.sa.zentao;
|
||||
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import com.tencentcloudapi.ses.v20201002.models.EmailSender;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.poi.ss.usermodel.DateUtil;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCell;
|
||||
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRow;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
//,exclude = DataSourceAutoConfiguration.class
|
||||
@SpringBootApplication(scanBasePackages = {"com.sa.zentao"})
|
||||
@MapperScan({"com.sa.zentao.mapper","com.sa.**.mapper"})
|
||||
@EnableScheduling
|
||||
public class ZentaoApplication {
|
||||
|
||||
//
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
@ -19,4 +51,39 @@ public class ZentaoApplication {
|
||||
}
|
||||
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// // 定义数据
|
||||
// Map<String, String> dataMap = new HashMap<>();
|
||||
// dataMap.put("name", "张三");
|
||||
// dataMap.put("age", "28");
|
||||
//
|
||||
// // 读取模板
|
||||
// try (FileInputStream templateFile =(FileInputStream)ZentaoApplication.class.getClassLoader().getResourceAsStream("templates/scope测试.xlsx")) {
|
||||
// Workbook workbook = WorkbookFactory.create(templateFile);
|
||||
// Sheet sheet = workbook.getSheetAt(0);
|
||||
//
|
||||
// // 替换占位符
|
||||
// for (Row row : sheet) {
|
||||
// for (Cell cell : row) {
|
||||
// if (cell.getCellType() == CellType.STRING) {
|
||||
// String cellValue = cell.getStringCellValue();
|
||||
// for (Map.Entry<String, String> entry : dataMap.entrySet()) {
|
||||
// cellValue = cellValue.replace("${" + entry.getKey() + "}", entry.getValue());
|
||||
// }
|
||||
// cell.setCellValue(cellValue);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 生成新文件
|
||||
// try (FileOutputStream outputStream = new FileOutputStream("output.xlsx")) {
|
||||
// workbook.write(outputStream);
|
||||
// }
|
||||
// workbook.close();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -29,9 +29,6 @@ import java.util.Objects;
|
||||
public class JwtAuthenticationFilter implements jakarta.servlet.Filter {
|
||||
|
||||
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void doFilter(jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse servletResponse
|
||||
@ -69,6 +66,8 @@ public class JwtAuthenticationFilter implements jakarta.servlet.Filter {
|
||||
RiskUserThreadLocal.set(u);
|
||||
RiskUserThreadLocal.risk.set(u);
|
||||
}
|
||||
}else{
|
||||
RiskUserThreadLocal.risk.set(null);
|
||||
}
|
||||
filterChain.doFilter(request,servletResponse);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.sa.zentao.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.sa.zentao.ZentaoApplication;
|
||||
import com.sa.zentao.conf.RiskUserThreadLocal;
|
||||
import com.sa.zentao.dao.BusinessException;
|
||||
import com.sa.zentao.dao.Code;
|
||||
@ -14,6 +15,7 @@ import com.sa.zentao.utils.UploadUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@ -134,9 +136,14 @@ public class CommonsController {
|
||||
|
||||
@GetMapping("/test")
|
||||
public Result<String> upload(){
|
||||
downLoad("http://192.168.1.161:8088/file-download-1.html");
|
||||
// downLoad("http://192.168.1.161:8088/file-download-1.html");
|
||||
|
||||
// vxxervice.sendMessageToVx("GuoQiBing","测试消息",new Date());
|
||||
// 定义数据
|
||||
|
||||
// 定义数据
|
||||
|
||||
|
||||
vxxervice.sendMessageToVx("GuoQiBing","测试消息",new Date());
|
||||
|
||||
return Result.success();
|
||||
|
||||
|
@ -55,6 +55,7 @@ public class ZtBugController {
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
//批量新增bug
|
||||
@RequestMapping(value = "/batchAddBug", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result batchAddBug(@RequestBody ZtBugDTO dto){
|
||||
bugService.batchAddBug(dto);
|
||||
|
@ -15,6 +15,7 @@ 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.http.HttpServletResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@ -22,8 +23,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@ -98,7 +97,14 @@ public class ZtCountController {
|
||||
public void exportProjectCount(@RequestBody ZtCountQo qo, jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse response){
|
||||
countService.exportProjectCount(qo,request,response) ;
|
||||
}
|
||||
//
|
||||
|
||||
//导出员工绩效
|
||||
@RequestMapping(value = "/exportScope", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public void exportScope(@RequestBody ZtCountQo qo, jakarta.servlet.ServletRequest request, HttpServletResponse response){
|
||||
countService.exportScope(qo,request,response) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@RequestMapping(value = "/projectList", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result projectList(@RequestBody ZtCaseDTO dto){
|
||||
@ -112,7 +118,10 @@ public class ZtCountController {
|
||||
@RequestMapping(value = "/projectListAsc", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result projectListAsc(@RequestBody ZtCaseDTO dto){
|
||||
|
||||
List<Integer> authList = this.projectService.authList();
|
||||
|
||||
List<ZtProject> project = projectService.list(new QueryWrapper<ZtProject>().lambda().eq(ZtProject::getType, "program")
|
||||
.in(ZtProject::getId,authList)
|
||||
.eq(ZtProject::getStatus,"doing")
|
||||
.eq(ZtProject::getDeleted,"0")
|
||||
.orderByAsc(ZtProject::getId)
|
||||
|
@ -227,9 +227,14 @@ public class ZtProjectController {
|
||||
//执行列表
|
||||
@RequestMapping(value = "/implementPageList", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result<PageInfo<ZtProjectDTO>> implementPageList(@RequestBody ZtProjectQo qo){
|
||||
|
||||
return Result.success(ztProjectService.implementPageList(qo));
|
||||
}
|
||||
//执行下拉列表 包含本人且 未完成的迭代
|
||||
@RequestMapping(value = "/myProgressImplementPageList", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result<PageInfo<ZtProjectDTO>> myProgressImplementPageList(@RequestBody ZtProjectQo qo){
|
||||
return Result.success(ztProjectService.myProgressImplementPageList(qo));
|
||||
}
|
||||
|
||||
//执行下拉
|
||||
@RequestMapping(value = "/implementList", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result<List<ZtProjectDTO>> implementList(@RequestBody ZtProjectQo qo){
|
||||
@ -314,6 +319,25 @@ public class ZtProjectController {
|
||||
return Result.success(this.ztProjectService.projectTeamTimeWork(qo));
|
||||
}
|
||||
|
||||
//产品集工时项目工时 每个人 按月份 工时统计 日报
|
||||
@RequestMapping(value = "/pageDaysTimeWorkCount", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result pageDaysTimeWorkCount(@RequestBody ZtProjectQo qo){
|
||||
return Result.success(this.ztProjectService.pageDaysTimeWorkCount(qo));
|
||||
}
|
||||
|
||||
//迭代工时 每个人
|
||||
@RequestMapping(value = "/execWorkCount", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result execWorkCount(@RequestBody ZtProjectQo qo){
|
||||
return Result.success(this.ztProjectService.execWorkCount(qo));
|
||||
}
|
||||
|
||||
//项目统计 每个人 按月份 工时统计 月报
|
||||
@RequestMapping(value = "/pageMonthReport", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result pageMonthReport(@RequestBody ZtProjectQo qo){
|
||||
return Result.success(this.ztProjectService.pageMonthReport(qo));
|
||||
}
|
||||
|
||||
|
||||
//迭代列表根据项目
|
||||
@RequestMapping(value = "/executionByProject", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result executionByProject(@RequestBody ZtProjectQo qo){
|
||||
|
@ -11,6 +11,7 @@ import com.sa.zentao.qo.StoryQo;
|
||||
import com.sa.zentao.qo.ZtProjectQo;
|
||||
import com.sa.zentao.service.IZtStoryUserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
@ -104,4 +105,12 @@ public class ZtStoryUserController {
|
||||
storyUserService.addRemark(dto);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/myWaitYsStory", method = RequestMethod.POST, produces = "application/json; charset=UTF-8")
|
||||
public Result myWaitYsStory(@RequestBody ZtStoryDTO dto){
|
||||
List list = storyUserService.myWaitYsStory(dto);
|
||||
return Result.success(CollectionUtils.isEmpty(list)?list:list.get(0));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import com.sa.zentao.service.IZtActionService;
|
||||
import com.sa.zentao.service.IZtTeamService;
|
||||
import com.sa.zentao.service.IZtUserService;
|
||||
import com.sa.zentao.utils.ChineseUtil;
|
||||
import com.sa.zentao.utils.CryptoUtils;
|
||||
import com.sa.zentao.utils.JwtUtil;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
@ -149,6 +150,9 @@ public class ZtUserController {
|
||||
}
|
||||
|
||||
ztUser.setPinyin(ChineseUtil.getFirst(ztUser.getNickname()));
|
||||
if(!StringUtils.isEmpty(ztUser.getVx())){
|
||||
ztUser.setVx(CryptoUtils.aesEncryptForFront(ztUser.getVx(), CryptoUtils.KEY_DES));
|
||||
}
|
||||
|
||||
this.userService.save(ztUser);
|
||||
this.actionService.addAction(ActionType.USER, ActionStatus.XJ,ztUser.getId(),null,null,null, RiskUserThreadLocal.get().getName(),null,ztUser.getAccount());
|
||||
@ -194,6 +198,11 @@ public class ZtUserController {
|
||||
if(!ztUser.getNickname().equals(user.getNickname())){
|
||||
ztUser.setPinyin(ChineseUtil.getFirst(ztUser.getNickname()));
|
||||
}
|
||||
|
||||
if(!StringUtils.isEmpty(user.getVx())){
|
||||
ztUser.setVx(CryptoUtils.aesEncryptForFront(user.getVx(), CryptoUtils.KEY_DES));
|
||||
}
|
||||
|
||||
ztUser.setAccount(user.getAccount());
|
||||
|
||||
ztUser.setPassword(user.getPassword());
|
||||
|
22
src/main/java/com/sa/zentao/dao/DkInfo.java
Normal file
22
src/main/java/com/sa/zentao/dao/DkInfo.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.sa.zentao.dao;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class DkInfo implements Serializable {
|
||||
|
||||
private String account;
|
||||
|
||||
private String name;
|
||||
|
||||
private String dateStr;
|
||||
|
||||
private Date startDate;
|
||||
|
||||
private Date endDate;
|
||||
}
|
22
src/main/java/com/sa/zentao/dao/ItApproval.java
Normal file
22
src/main/java/com/sa/zentao/dao/ItApproval.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.sa.zentao.dao;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ItApproval implements Serializable {
|
||||
|
||||
private String name;
|
||||
|
||||
private Integer applyDays;
|
||||
|
||||
private Date applyTimeStart;
|
||||
|
||||
private Date applyTimeEnd;
|
||||
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.sa.zentao.dao;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnore;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -19,6 +20,9 @@ public class PerformanceDTO implements Serializable {
|
||||
//需求总工时
|
||||
@ExcelProperty(value = "天数",index =2)
|
||||
private BigDecimal days;
|
||||
// 小时
|
||||
@ExcelIgnore
|
||||
private BigDecimal approvalDays;
|
||||
//实际产出工时
|
||||
@ExcelProperty(value = "可用工时",index =3)
|
||||
private BigDecimal totalTime;
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.sa.zentao.dao;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelIgnore;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@ -16,6 +17,12 @@ public class WorkDetailsDTO implements Serializable {
|
||||
//任务总量
|
||||
@ExcelProperty(value = "任务总量",index =1)
|
||||
private BigDecimal taskCount;
|
||||
//任务延期
|
||||
@ExcelIgnore
|
||||
private BigDecimal taskDelayCount;
|
||||
//任务准时完成率
|
||||
@ExcelIgnore
|
||||
private BigDecimal taskFinishOnTimeRate;
|
||||
//需求总工时
|
||||
@ExcelProperty(value = "需求总工时",index =2)
|
||||
private BigDecimal storyTotalTime;
|
||||
|
@ -7,6 +7,7 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Date;
|
||||
@ -187,8 +188,15 @@ public class ZtTaskDTO implements Serializable {
|
||||
|
||||
//0 否 1 是
|
||||
private Integer finishedFlag=0;
|
||||
//0 否 1 是
|
||||
private Integer draftFlag;
|
||||
|
||||
private String implementName;
|
||||
private Integer implementId;
|
||||
private Integer product;
|
||||
private String productName;
|
||||
|
||||
private Date applyDate;
|
||||
|
||||
private BigDecimal useTime;
|
||||
}
|
||||
|
@ -136,4 +136,9 @@ public class ZtUserDTO implements Serializable {
|
||||
|
||||
private String color;
|
||||
|
||||
private String vx;
|
||||
|
||||
private Date startDate;
|
||||
|
||||
private Date endDate;
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.sa.zentao.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import java.time.LocalDateTime;
|
||||
@ -75,7 +77,7 @@ public class ZtTask implements Serializable {
|
||||
//deadline 预计完成 estStarted预计开始
|
||||
private Date deadline;
|
||||
|
||||
//pause 暂停 cancel取消 closed 关闭 done 完成 wait reviewing待评审 doing
|
||||
//pause 暂停 cancel取消 closed 关闭 done 完成 wait reviewing待评审 doing 草稿 draft
|
||||
@TableField("`status`")
|
||||
private String status;
|
||||
|
||||
@ -93,13 +95,19 @@ public class ZtTask implements Serializable {
|
||||
|
||||
@TableField("openedBy")
|
||||
private String openedby;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String openedbyAccount;
|
||||
@TableField(exist = false)
|
||||
private String openedbyName;
|
||||
@TableField("openedDate")
|
||||
private Date openeddate;
|
||||
|
||||
@TableField("assignedTo")
|
||||
private String assignedTo;
|
||||
|
||||
@TableField(exist = false)
|
||||
private String assignedToAccount;
|
||||
@TableField(exist = false)
|
||||
private String assignedToName;
|
||||
@TableField("assignedDate")
|
||||
private Date assignedDate;
|
||||
//预计开始
|
||||
@ -111,7 +119,7 @@ public class ZtTask implements Serializable {
|
||||
|
||||
@TableField("finishedBy")
|
||||
private String finishedby;
|
||||
//完成日期
|
||||
//真实完成日期
|
||||
@TableField("finishedDate")
|
||||
private Date finishedDate;
|
||||
|
||||
@ -175,4 +183,11 @@ public class ZtTask implements Serializable {
|
||||
private Long deadlineTime;
|
||||
|
||||
private Integer product;
|
||||
// 0否 1.是
|
||||
// @TableField(exist = false)
|
||||
private Integer finishedFlag;
|
||||
// @TableField(exist = false)
|
||||
private Date applyDate;
|
||||
// @TableField(exist = false)
|
||||
private BigDecimal useTime;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ public interface ZtProjectMapper extends BaseMapper<ZtProject> {
|
||||
|
||||
List<ZtProjectDTO> implementPageList(@Param("qo")ZtProjectQo qo);
|
||||
|
||||
|
||||
List<ZtProject> getProjectByProduct(@Param("qo") ZtProjectQo qo);
|
||||
|
||||
List<ZtProject> executionListByProduct(@Param("qo")ZtProjectQo qo);
|
||||
|
@ -1,12 +1,14 @@
|
||||
package com.sa.zentao.mapper;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.sa.zentao.dao.ItApproval;
|
||||
import com.sa.zentao.dao.ZtTaskDTO;
|
||||
import com.sa.zentao.entity.ZtTask;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sa.zentao.qo.ZtProjectQo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -23,4 +25,6 @@ public interface ZtTaskMapper extends BaseMapper<ZtTask> {
|
||||
|
||||
@DS("slave")
|
||||
List<ZtTaskDTO> taskListPrd(@Param("id") Integer id);
|
||||
|
||||
List<ItApproval> itApprovalByUserName(@Param("name") String name,@Param("startDate") Date firstDayOfMonth, @Param("endDate") Date lastDayOfMonth);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.sa.zentao.mapper;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.sa.zentao.dao.DkInfo;
|
||||
import com.sa.zentao.dao.ZtUserDTO;
|
||||
import com.sa.zentao.entity.ZtUser;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
@ -8,6 +9,7 @@ import com.sa.zentao.qo.ZtUserQo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -22,6 +24,7 @@ public interface ZtUserMapper extends BaseMapper<ZtUser> {
|
||||
|
||||
List<ZtUser> pageList(@Param("qo") ZtUserQo qo);
|
||||
|
||||
List<DkInfo> dkList(@Param("ids") List<String> account, @Param("startDate") Date startDate, @Param("endDate")Date endDate);
|
||||
|
||||
@DS("slave")
|
||||
@Select("select * from zt_user")
|
||||
@ -30,4 +33,6 @@ public interface ZtUserMapper extends BaseMapper<ZtUser> {
|
||||
@DS("slave")
|
||||
ZtUser selectPrdByName(@Param("name")String userName);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ public interface IZtProjectService extends IService<ZtProject> {
|
||||
void executionSyncStory(ZtProjectDTO dto);
|
||||
|
||||
|
||||
//产品集权限
|
||||
//产品权限
|
||||
List<Integer> authProductList();
|
||||
//产品集权限
|
||||
List<Integer> authList();
|
||||
@ -113,4 +113,13 @@ public interface IZtProjectService extends IService<ZtProject> {
|
||||
List<PerformanceDTO> performanceCount(Date startDate, Date endDate);
|
||||
|
||||
ZtProjectDTO projectProductByExecution(String execution);
|
||||
|
||||
PageInfo< Map<String, Object>> pageDaysTimeWorkCount(ZtProjectQo qo);
|
||||
|
||||
|
||||
PageInfo pageMonthReport(ZtProjectQo qo);
|
||||
|
||||
List<Map<String, Object>> execWorkCount(ZtProjectQo qo);
|
||||
|
||||
PageInfo<ZtProjectDTO> myProgressImplementPageList(ZtProjectQo qo);
|
||||
}
|
||||
|
@ -38,4 +38,7 @@ public interface IZtStoryUserService extends IService<ZtStoryUser> {
|
||||
void addRemark(ZtStoryDTO dto);
|
||||
|
||||
void closedStory(ZtStoryUserDTO dto);
|
||||
|
||||
List myWaitYsStory(ZtStoryDTO dto);
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.sa.zentao.service;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.sa.zentao.dao.ItApproval;
|
||||
import com.sa.zentao.dao.ZtProjectDTO;
|
||||
import com.sa.zentao.dao.ZtTaskDTO;
|
||||
import com.sa.zentao.dao.ZtYwTaskDTO;
|
||||
@ -8,6 +9,7 @@ import com.sa.zentao.entity.ZtTask;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sa.zentao.qo.ZtProjectQo;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -53,4 +55,7 @@ public interface IZtTaskService extends IService<ZtTask> {
|
||||
ZtTaskDTO getTaskById(Integer id);
|
||||
|
||||
List<ZtTaskDTO> taskListPrd(Integer id);
|
||||
|
||||
List<ItApproval> itApprovalByUserName(String s, Date firstDayOfMonth, Date lastDayOfMonth);
|
||||
|
||||
}
|
||||
|
@ -1,12 +1,15 @@
|
||||
package com.sa.zentao.service;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.sa.zentao.dao.DkInfo;
|
||||
import com.sa.zentao.dao.ZtProjectDTO;
|
||||
import com.sa.zentao.dao.ZtUserDTO;
|
||||
import com.sa.zentao.entity.ZtUser;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sa.zentao.qo.ZtUserQo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -29,6 +32,8 @@ public interface IZtUserService extends IService<ZtUser> {
|
||||
|
||||
Map<String, ZtUser> userMapByIds(List<String> accounts);
|
||||
|
||||
Map<String, ZtUser> userMapByIdsOrderByType(List<String> accounts);
|
||||
|
||||
void sendCode(ZtUser user);
|
||||
|
||||
ZtUser login(ZtUser user);
|
||||
@ -36,4 +41,6 @@ public interface IZtUserService extends IService<ZtUser> {
|
||||
ZtUser selectPrdByName(String userName);
|
||||
|
||||
ZtUser getbyVxId(String vx);
|
||||
|
||||
List<DkInfo> dkList(@Param("ids") List<String> account, @Param("startDate") Date startDate, @Param("endDate")Date endDate);
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.sa.zentao.service.impl;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.ExcelWriter;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.read.listener.PageReadListener;
|
||||
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
|
||||
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||
import com.alibaba.excel.write.metadata.WriteTable;
|
||||
@ -11,6 +12,7 @@ import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.mysql.cj.x.protobuf.MysqlxCrud;
|
||||
import com.sa.zentao.conf.LoginRiskUser;
|
||||
import com.sa.zentao.conf.RiskUserThreadLocal;
|
||||
import com.sa.zentao.dao.*;
|
||||
@ -24,16 +26,19 @@ import com.sa.zentao.qo.ZtProjectQo;
|
||||
import com.sa.zentao.qo.ZtUserQo;
|
||||
import com.sa.zentao.service.*;
|
||||
import com.sa.zentao.utils.DateUtils;
|
||||
import com.sa.zentao.utils.ExcelUtil;
|
||||
import jakarta.servlet.ServletOutputStream;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.*;
|
||||
@ -355,13 +360,15 @@ public class IZtCountService {
|
||||
.filter(o -> o.getStage().equals("wait")) .map(o->o.getId()+"").collect(Collectors.joining(",")));
|
||||
|
||||
result.setJxzCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
|
||||
.filter(o -> o.getStage().equals("developing")) .map(o->o.getId()+"").collect(Collectors.joining(",")));
|
||||
.filter(o -> Arrays.asList("tested","testing","developed","developing").contains(o.getStage())
|
||||
) .map(o->o.getId()+"").collect(Collectors.joining(",")));
|
||||
|
||||
result.setCswbCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
|
||||
.filter(o -> o.getStage().equals("tested"))
|
||||
.map(o->o.getId()+"").collect(Collectors.joining(",")));
|
||||
result.setDysCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
|
||||
.filter(o -> o.getStage().equals("released"))
|
||||
.filter(o->o.getYsUser().equals(RiskUserThreadLocal.get().getName()))
|
||||
.map(o->o.getId()+"").collect(Collectors.joining(",")));
|
||||
result.setYsNoCount(ztStory.stream().filter(o -> "active".equals(o.getStatus()))
|
||||
.filter(o -> o.getStage().equals("verified"))
|
||||
@ -520,24 +527,97 @@ public class IZtCountService {
|
||||
// @Autowired
|
||||
// private IZtBugService bugService;
|
||||
|
||||
public void exportScope(ZtCountQo qo, ServletRequest request, HttpServletResponse response) {
|
||||
|
||||
try {
|
||||
|
||||
|
||||
|
||||
List<PerformanceDTO> perList =performanceCount(qo);
|
||||
if(CollectionUtils.isEmpty(perList)){
|
||||
throw new BusinessException("未查询到数据");
|
||||
}
|
||||
|
||||
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||
|
||||
|
||||
Map<String, ZtUser> userMap = userService.userMapByIds(null);
|
||||
|
||||
|
||||
//生成模板
|
||||
for (int i = 0; i < perList.size(); i++) {
|
||||
PerformanceDTO performanceDTO = perList.get(i);
|
||||
ZtUser ztUser = userMap.get(performanceDTO.getAccount());
|
||||
|
||||
if(ztUser.getUserType()==UserType.CS){
|
||||
generatorTestExcel(performanceDTO.getUserName(),performanceDTO,qo.getDate());
|
||||
}else if(ztUser.getUserType()==UserType.KFZ){
|
||||
generatorDevlopExcel(performanceDTO.getUserName(),performanceDTO,qo.getDate());
|
||||
}else if(ztUser.getUserType()==UserType.XMGLY){
|
||||
}else{
|
||||
}
|
||||
}
|
||||
//生成多sheetexcel
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
for (int i = 0; i < perList.size(); i++) {
|
||||
PerformanceDTO performanceDTO = perList.get(i);
|
||||
ZtUser ztUser = userMap.get(performanceDTO.getAccount());
|
||||
|
||||
|
||||
if(ztUser.getUserType()==UserType.CS){
|
||||
list.add(performanceDTO.getUserName()+"测试.xlsx");
|
||||
|
||||
generatorTestExcel(performanceDTO.getUserName(),performanceDTO,qo.getDate());
|
||||
}else if(ztUser.getUserType()==UserType.KFZ){
|
||||
list.add(performanceDTO.getUserName()+"开发.xlsx");
|
||||
generatorDevlopExcel(performanceDTO.getUserName(),performanceDTO,qo.getDate());
|
||||
}
|
||||
}
|
||||
String excelName=DateUtils.formatDate(qo.getDate(),"yyyy-MM-dd")+"绩效"+".xlsx";
|
||||
String dir=System.getProperty("user.dir")+"/";
|
||||
ExcelUtil.mergexcel(list,excelName, dir);
|
||||
|
||||
|
||||
|
||||
File f = new File(dir+excelName);
|
||||
InputStream fis = new BufferedInputStream(new FileInputStream(f));
|
||||
// InputStream fis = new BufferedInputStream(new FileInputStream("D:\\1.bmp"));
|
||||
byte[] buffer = new byte[fis.available()];
|
||||
|
||||
fis.read(buffer);
|
||||
fis.close();
|
||||
// 清空response
|
||||
response.reset();
|
||||
// 设置response的Header
|
||||
response.addHeader("Content-Disposition", "attachment;filename=" + new String("1.xlsx"));
|
||||
response.addHeader("Content-Length", "" + f.length());
|
||||
|
||||
|
||||
OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
|
||||
response.setContentType("application/octet-stream");
|
||||
toClient.write(buffer);
|
||||
toClient.flush();
|
||||
toClient.close();
|
||||
// ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
|
||||
// . registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
// .needHead(Boolean.TRUE).build();
|
||||
// excelWriter.finish();
|
||||
response.getOutputStream().close();
|
||||
response.flushBuffer();
|
||||
|
||||
}catch (Exception e){
|
||||
log.error("",e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void exportProjectCount(ZtCountQo qo,jakarta.servlet.ServletRequest request, jakarta.servlet.ServletResponse response) {
|
||||
|
||||
|
||||
|
||||
try {
|
||||
List<ProjectWorkDetailsDTO> workDetailsDTOS = projectWorkCount(qo,request,response);
|
||||
|
||||
ByteArrayOutputStream os = new ByteArrayOutputStream();
|
||||
// ExcelWriter excelWriter = EasyExcel.write(os).build();
|
||||
|
||||
// WriteSheet 统计 = EasyExcel.writerSheet("统计").
|
||||
// registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
// .needHead(Boolean.TRUE)
|
||||
// .build();
|
||||
|
||||
|
||||
|
||||
List<WorkDetailsDTO> workDetailsDTOS1 = workDetailsCount(qo);
|
||||
|
||||
@ -545,17 +625,9 @@ public class IZtCountService {
|
||||
|
||||
|
||||
List<PerformanceDTO> perList =performanceCount(qo);
|
||||
// excelWriter.write(workDetailsDTOS, 统计, accountInfo);
|
||||
// excelWriter.write(workDetailsDTOS1, 统计, tweetInfo);
|
||||
|
||||
// EasyExcel.write(os, ProjectWorkDetailsDTO.class)
|
||||
// .sheet("统计").doWrite(workDetailsDTOS);
|
||||
|
||||
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
|
||||
// response.("Access-Control-Expose-Headers","Content-Disposition");//不设置该参数前端(vue)接收不到文件名
|
||||
// response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
|
||||
|
||||
ServletOutputStream outputStream = response.getOutputStream();
|
||||
|
||||
|
||||
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
|
||||
@ -594,10 +666,6 @@ public class IZtCountService {
|
||||
excelWriter.finish();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
response.getOutputStream().close();
|
||||
response.flushBuffer();
|
||||
|
||||
@ -630,15 +698,237 @@ public class IZtCountService {
|
||||
if (CollectionUtils.isEmpty(projectproducts)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<ZtExecutionproject> list = executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda()
|
||||
List<ZtExecutionproject> execList = executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda()
|
||||
.in(ZtExecutionproject::getProject, projectproducts.stream().map(o->o.getProject()).collect(Collectors.toList())));
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
if (CollectionUtils.isEmpty(execList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<ZtTask> taskList = this.taskService.list(new QueryWrapper<ZtTask>().lambda()
|
||||
.and(o->o.between(ZtTask::getDeadline, firstDayOfMonth,lastDayOfMonth)
|
||||
.or()
|
||||
.between(ZtTask::getFinishedDate, firstDayOfMonth,lastDayOfMonth)
|
||||
)
|
||||
.in(ZtTask::getExecution, execList.stream().map(o -> o.getExecution())
|
||||
.collect(Collectors.toList())));
|
||||
if (CollectionUtils.isEmpty(taskList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<ZtProject> ztProjects = this.projectService.listByIds(execList.stream().map(o -> o.getExecution()).collect(Collectors.toList()));
|
||||
|
||||
// this.teamService.list(new QueryWrapper<>().lambda().eq());
|
||||
List<ZtTeam> teams = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getType, "execution")
|
||||
.in(ZtTeam::getRoot, ztProjects.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
|
||||
return this.projectService.performanceCount(firstDayOfMonth,lastDayOfMonth);
|
||||
List<String> accountIds = teams.stream().map(o -> o.getAccount()).distinct().collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(accountIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
//accountIds 成员
|
||||
|
||||
List<ZtUser> ztUsers = this.userService.list(new QueryWrapper<ZtUser>().lambda().in(ZtUser::getAccount,accountIds));
|
||||
|
||||
|
||||
List<PerformanceDTO> result =new ArrayList<>();
|
||||
|
||||
for (ZtUser u:ztUsers) {
|
||||
|
||||
List<ItApproval> approvalList = this.taskService.itApprovalByUserName(u.getNickname(),firstDayOfMonth, lastDayOfMonth);
|
||||
|
||||
if(u.getUserType()==UserType.CS){
|
||||
|
||||
}else if(u.getUserType()==UserType.KFZ){
|
||||
|
||||
}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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return result;
|
||||
// return this.projectService.performanceCount(firstDayOfMonth,lastDayOfMonth);
|
||||
}
|
||||
|
||||
//分钟 请假
|
||||
private Integer getApprovalTime(List<ItApproval> approvalList,Date d) {
|
||||
String dFormat = DateUtils.formatDate(d, "yyyyMM");
|
||||
Integer value=0;
|
||||
for (ItApproval approval:approvalList) {
|
||||
|
||||
Date applyTimeEnd = approval.getApplyTimeEnd();
|
||||
Date applyTimeStart = approval.getApplyTimeStart();
|
||||
String startStr = DateUtils.formatDate(applyTimeEnd, "yyyyMM");
|
||||
String endStr = DateUtils.formatDate(applyTimeStart, "yyyyMM");
|
||||
|
||||
int intStart = Integer.valueOf(DateUtils.formatDate(applyTimeEnd, "yyyyMMdd"));
|
||||
int intEnd = Integer.valueOf(DateUtils.formatDate(applyTimeStart, "yyyyMMdd"));
|
||||
if((intEnd-intStart)==0){
|
||||
value+=approval.getApplyDays();
|
||||
}else{
|
||||
// 情况 1 1月27 -2 2
|
||||
//情况2 2.月28 -3.1
|
||||
int days = DateUtils.daysBetween(applyTimeStart, applyTimeEnd)+1;
|
||||
for (int i =0;i<days ;i++) {
|
||||
Date date = DateUtils.dateAddDay(applyTimeStart, i);
|
||||
if(date.getMonth()!=d.getMonth()){
|
||||
continue;
|
||||
}
|
||||
if(DateUtils.isWork(date)){
|
||||
continue;
|
||||
}
|
||||
|
||||
if(i!=0){
|
||||
date.setHours(9);
|
||||
date.setSeconds(0);
|
||||
date.setMinutes(0);
|
||||
}
|
||||
if(dFormat.equals(DateUtils.formatDate(date,"yyyyMM"))){
|
||||
//请假在范围
|
||||
Integer mStart = Integer.valueOf(DateUtils.formatDate(date, "HHmm"));
|
||||
// 8个半小时
|
||||
Date thisDay = new Date();
|
||||
thisDay.setDate(date.getDate());
|
||||
thisDay.setHours(17);
|
||||
thisDay.setMinutes(30);
|
||||
thisDay.setSeconds(0);
|
||||
if(mStart<=1300){
|
||||
//早上请假
|
||||
if(thisDay.getTime()<applyTimeEnd.getTime()){
|
||||
value+=(int)((thisDay.getTime()-date.getTime())/1000-(30*60));
|
||||
}else{
|
||||
value+=(int)((applyTimeEnd.getTime()-date.getTime())/1000-(30*60));
|
||||
}
|
||||
|
||||
}else
|
||||
{
|
||||
if(thisDay.getTime()<applyTimeEnd.getTime()){
|
||||
value+= (int)(thisDay.getTime()-date.getTime())/1000;
|
||||
}else{
|
||||
value+= (int)(applyTimeEnd.getTime()-date.getTime())/1000;
|
||||
}
|
||||
|
||||
//下午请假
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return value/60;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Date thisDay = new Date();
|
||||
thisDay.setHours(17);
|
||||
thisDay.setMinutes(30);
|
||||
thisDay.setSeconds(0);
|
||||
System.out.print(thisDay);
|
||||
}
|
||||
|
||||
private List<ProjectWorkTaskDTO> workTaskCounts(ZtCountQo qo) {
|
||||
@ -871,12 +1161,12 @@ public class IZtCountService {
|
||||
if(size==0){
|
||||
dto.setYsYesRate(BigDecimal.ZERO);
|
||||
}else{
|
||||
dto.setYsYesRate(BigDecimal.valueOf(size).divide(BigDecimal.valueOf(ysVerified.size()),2,BigDecimal.ROUND_HALF_UP));
|
||||
dto.setYsYesRate(BigDecimal.valueOf(size).divide(BigDecimal.valueOf(ysVerified.size()),2,BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(100)));
|
||||
}
|
||||
if(CollectionUtils.isEmpty(ysVerified)){
|
||||
dto.setYsNoRate(BigDecimal.ZERO);
|
||||
}else{
|
||||
dto.setYsNoRate(BigDecimal.valueOf(1).subtract(dto.getYsYesRate()));
|
||||
dto.setYsNoRate(BigDecimal.valueOf(ysVerified.stream().filter(o -> o.getStage().equals("verified")&&o.getYsFlag()==2).collect(Collectors.toList()).size()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1018,10 +1308,16 @@ public class IZtCountService {
|
||||
// return zeroMap(map,objMap);
|
||||
// }
|
||||
|
||||
List<ZtRelease> releases = this.releaseService.list(new QueryWrapper<ZtRelease>().lambda()
|
||||
List<ZtRelease> releases =null;
|
||||
if(CollectionUtils.isEmpty(projectList)){
|
||||
releases=new ArrayList<>();
|
||||
}else{
|
||||
releases=this.releaseService.list(new QueryWrapper<ZtRelease>().lambda()
|
||||
.eq(ZtRelease::getStatus,"released")
|
||||
.in(ZtRelease::getProject, projectList.stream().map(o -> o.getProject()).collect(Collectors.toList())));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<ZtStory> ztStories = this.storyService.list(new QueryWrapper<ZtStory>().lambda().in(ZtStory::getProduct,
|
||||
@ -1090,6 +1386,7 @@ public class IZtCountService {
|
||||
if(!CollectionUtils.isEmpty(releases)){
|
||||
long relaese= this.releaseDetailsService.count(new QueryWrapper<ZtReleaseDetails>().lambda()
|
||||
.in(ZtReleaseDetails::getReleaseId, releases.stream().map(o -> o.getId()).collect(Collectors.toList()))
|
||||
.ne(ZtReleaseDetails::getStatus,"closed")
|
||||
.eq(ZtReleaseDetails::getObjectType, "story"));
|
||||
objMap.put("online",relaese);
|
||||
}else{
|
||||
@ -1234,5 +1531,118 @@ public class IZtCountService {
|
||||
return cronDevopsService.pageList(dto).getList();
|
||||
}
|
||||
|
||||
void generatorDevlopExcel(String name,PerformanceDTO performanceDTO,Date d){
|
||||
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("准时率得分", performanceDTO.getPunctualityScore().toString());
|
||||
dataMap.put("代码质量", "10");
|
||||
dataMap.put("文档质量", "10");
|
||||
dataMap.put("饱和度得分", performanceDTO.getSaturationScore().toString());
|
||||
dataMap.put("线上bug得分", performanceDTO.getBugScore().toString());
|
||||
dataMap.put("工作态度", "5");
|
||||
dataMap.put("创新贡献", "0");
|
||||
dataMap.put("总分", devlopTotal(
|
||||
dataMap.get("准时率得分"),
|
||||
dataMap.get("线上bug得分"),
|
||||
dataMap.get("代码质量"),
|
||||
dataMap.get("文档质量"),
|
||||
dataMap.get("饱和度得分"),
|
||||
dataMap.get("工作态度")
|
||||
));
|
||||
//测试方案
|
||||
// 读取模板
|
||||
|
||||
Workbook workbook = WorkbookFactory.create(templateFile);
|
||||
workbook.setSheetName(0,name);
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
|
||||
// 替换占位符
|
||||
for (Row row : sheet) {
|
||||
for (Cell cell : row) {
|
||||
if (cell.getCellType() == CellType.STRING) {
|
||||
String cellValue = cell.getStringCellValue();
|
||||
for (Map.Entry<String, String> entry : dataMap.entrySet()) {
|
||||
cellValue = cellValue.replace("${" + entry.getKey() + "}", entry.getValue());
|
||||
}
|
||||
cell.setCellValue(cellValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成新文件
|
||||
try (FileOutputStream outputStream = new FileOutputStream(name+"开发.xlsx")) {
|
||||
workbook.write(outputStream);
|
||||
}
|
||||
workbook.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
String devlopTotal(String ...args){
|
||||
int i =0;
|
||||
for (String s:args) {
|
||||
try {
|
||||
i+=new BigDecimal(s).intValue();
|
||||
}catch (Exception e){
|
||||
log.error("",e);
|
||||
}
|
||||
|
||||
}
|
||||
return i+"";
|
||||
}
|
||||
void generatorTestExcel(String name,PerformanceDTO performanceDTO,Date d){
|
||||
try (FileInputStream templateFile =new FileInputStream("scope测试.xlsx")) {
|
||||
Map<String, String> dataMap = new HashMap<>();
|
||||
dataMap.put("name", name);
|
||||
dataMap.put("date", DateUtils.formatDate(d,"yyyy-MM"));
|
||||
dataMap.put("准时率得分",performanceDTO.getPunctualityScore().toString());
|
||||
dataMap.put("测试方案", "20");
|
||||
dataMap.put("缺陷管理", "10");
|
||||
|
||||
dataMap.put("线上bug得分", performanceDTO.getBugScore().toString());
|
||||
dataMap.put("测试报告编写", "10");
|
||||
dataMap.put("测试技能", "5");
|
||||
dataMap.put("态度", "5");
|
||||
dataMap.put("创新贡献", "0");
|
||||
dataMap.put("总分", devlopTotal(dataMap.get("准时率得分")
|
||||
,dataMap.get("缺陷管理")
|
||||
,dataMap.get("线上bug得分")
|
||||
,dataMap.get("线上bug得分")
|
||||
,dataMap.get("测试技能")
|
||||
,dataMap.get("态度")
|
||||
,dataMap.get("创新贡献") ));
|
||||
//测试方案
|
||||
// 读取模板
|
||||
|
||||
Workbook workbook = WorkbookFactory.create(templateFile);
|
||||
Sheet sheet = workbook.getSheetAt(0);
|
||||
workbook.setSheetName(0,name);
|
||||
// 替换占位符
|
||||
for (Row row : sheet) {
|
||||
for (Cell cell : row) {
|
||||
if (cell.getCellType() == CellType.STRING) {
|
||||
String cellValue = cell.getStringCellValue();
|
||||
for (Map.Entry<String, String> entry : dataMap.entrySet()) {
|
||||
cellValue = cellValue.replace("${" + entry.getKey() + "}", entry.getValue());
|
||||
}
|
||||
cell.setCellValue(cellValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成新文件
|
||||
try (FileOutputStream outputStream = new FileOutputStream(name+"测试.xlsx")) {
|
||||
workbook.write(outputStream);
|
||||
}
|
||||
workbook.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -224,10 +224,28 @@ public class ZtBugServiceImpl extends ServiceImpl<ZtBugMapper, ZtBug> implements
|
||||
@Override
|
||||
@Transactional
|
||||
public void assignedTo(ZtBugQo qo) {
|
||||
|
||||
LoginRiskUser loginRiskUser = RiskUserThreadLocal.get();
|
||||
if(loginRiskUser==null){
|
||||
throw new BusinessException("未查询到数据");
|
||||
}
|
||||
ZtBug ztBug = this.baseMapper.selectById(qo.getId());
|
||||
|
||||
if(!ztBug.getOpenedby().equals(loginRiskUser.getName())){
|
||||
if(!ztBug.getAssignedTo().equals(loginRiskUser.getName())){
|
||||
if(loginRiskUser.getUserType()!=UserType.XMGLY||loginRiskUser.getUserType()!=UserType.GSGC){
|
||||
throw new BusinessException("当前无法指派请联系管理员");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(ztBug==null){
|
||||
throw new BusinessException("未查询到");
|
||||
}
|
||||
|
||||
|
||||
ztBug.setAssignedTo(qo.getAssignedTo());
|
||||
ztBug.setLasteditedby(RiskUserThreadLocal.get().getName());
|
||||
ztBug.setLastediteddate(new Date());
|
||||
|
@ -205,6 +205,7 @@ public class ZtMeetingServiceImpl extends ServiceImpl<ZtMeetingMapper, ZtMeeting
|
||||
|
||||
String pfdStr="<h1 style=\"line-height: 70px;font-size: 41px\">{meetType}记录 {titleDate} </h1>\n" +
|
||||
"\n" +
|
||||
"<div style=\"line-height: 50px;font-family: 宋体;\">会议名称: {name} </div>\n" +
|
||||
"<div style=\"line-height: 50px;font-family: 宋体;\">会议时间: {meetingDate} </div>\n" +
|
||||
"<div style=\"line-height: 50px;font-family: 宋体\">会议地点: {address} </div>\n" +
|
||||
"<div style=\"line-height: 50px;font-family: 宋体\">参会人员: {usersName} </div>\n" +
|
||||
@ -214,14 +215,14 @@ public class ZtMeetingServiceImpl extends ServiceImpl<ZtMeetingMapper, ZtMeeting
|
||||
|
||||
// 替换内容集合
|
||||
Map<String, String> textMap = new LinkedHashMap<>();
|
||||
textMap.put("titleDate", DateUtils.formatDate(ztMeeting.getMeetingDate(),"YYYY-MM-DD"));
|
||||
|
||||
textMap.put("titleDate", DateUtils.formatDate(ztMeeting.getMeetingDate(),"yyyy-MM-dd"));
|
||||
textMap.put("name", ztMeeting.getName());
|
||||
|
||||
pfdStr=pfdStr.replace("{meetType}",ztMeeting.getType().getValue());
|
||||
pfdStr=pfdStr.replace("{titleDate}",DateUtils.formatDate(ztMeeting.getMeetingDate(),"YYYY-MM-DD "));
|
||||
pfdStr=pfdStr.replace("{titleDate}",DateUtils.formatDate(ztMeeting.getMeetingDate(),"yyyy-MM-dd "));
|
||||
|
||||
textMap.put("meetingDate", DateUtils.formatDate(ztMeeting.getMeetingDate(),"YYYY/MM/DD"));
|
||||
pfdStr= pfdStr.replace("{meetingDate}",DateUtils.formatDate(ztMeeting.getMeetingDate(),"YYYY/MM/DD HH:mm"));
|
||||
textMap.put("meetingDate", DateUtils.formatDate(ztMeeting.getMeetingDate(),"yyyy/MM/dd"));
|
||||
pfdStr= pfdStr.replace("{meetingDate}",DateUtils.formatDate(ztMeeting.getMeetingDate(),"yyyy/MM/dd HH:mm"));
|
||||
textMap.put("address",ztMeeting.getAddress());
|
||||
pfdStr= pfdStr.replace("{address}",ztMeeting.getAddress());
|
||||
StringBuilder b=new StringBuilder();
|
||||
@ -252,6 +253,7 @@ public class ZtMeetingServiceImpl extends ServiceImpl<ZtMeetingMapper, ZtMeeting
|
||||
// textMap.put("remark", ztMeeting.getRemark());
|
||||
}
|
||||
pfdStr= pfdStr.replace("{remark}",ztMeeting.getRemark());
|
||||
pfdStr= pfdStr.replace("{name}",ztMeeting.getName());
|
||||
// 调用工具类,registerTemplatePath 模板路径,textMap 文字内容
|
||||
// 调用工具类,registerTemplatePath 模板路径,textMap 文字内容
|
||||
try {
|
||||
|
@ -210,9 +210,14 @@ public class ZtProductServiceImpl extends ServiceImpl<ZtProductMapper, ZtProduct
|
||||
|
||||
@Override
|
||||
public List<ZtProductDTO> productList(ZtProjectQo qo) {
|
||||
List<Integer> pIds = this.ztProjectService.authProductList();
|
||||
if(CollectionUtils.isEmpty(pIds)){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<ZtProduct> ztProducts = this.baseMapper.selectList(new QueryWrapper<ZtProduct>()
|
||||
.lambda().eq(ZtProduct::getDeleted,"0")
|
||||
.notIn(ZtProduct::getStatus, Arrays.asList("closed"))
|
||||
.notIn(ZtProduct::getStatus, Arrays.asList("closed")).in(ZtProduct::getId,pIds)
|
||||
);
|
||||
if(CollectionUtils.isEmpty(ztProducts)){
|
||||
return new ArrayList<>();
|
||||
|
@ -1,15 +1,13 @@
|
||||
package com.sa.zentao.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.github.pagehelper.Page;
|
||||
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.PerformanceDTO;
|
||||
import com.sa.zentao.dao.ZtProjectDTO;
|
||||
import com.sa.zentao.dao.ZtStoryDTO;
|
||||
import com.sa.zentao.dao.*;
|
||||
import com.sa.zentao.entity.*;
|
||||
import com.sa.zentao.enums.ActionStatus;
|
||||
import com.sa.zentao.enums.ActionType;
|
||||
@ -20,6 +18,7 @@ import com.sa.zentao.qo.ZtProjectQo;
|
||||
import com.sa.zentao.service.*;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sa.zentao.utils.BeanCopyUtil;
|
||||
import com.sa.zentao.utils.Constant;
|
||||
import com.sa.zentao.utils.DateUtils;
|
||||
import com.sa.zentao.utils.KanBanConstant;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@ -94,7 +93,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
}};
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void addProject(ZtProjectDTO dto) {
|
||||
@ -121,7 +119,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
ztProject.setPm(dto.getPm());
|
||||
|
||||
|
||||
|
||||
Integer exection = null;
|
||||
ActionType type = null;
|
||||
|
||||
@ -461,14 +458,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
public List<ZtStoryDTO> getStoryByImplementId(ZtProjectDTO dto) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Integer id = dto.getId();
|
||||
|
||||
LambdaQueryWrapper<ZtProjectproduct> eq1 = new QueryWrapper<ZtProjectproduct>().lambda()
|
||||
@ -511,8 +500,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
if (CollectionUtils.isEmpty(active)) {
|
||||
return new ArrayList<>();
|
||||
} else {
|
||||
@ -590,6 +577,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//搜索项目根据产品
|
||||
@Override
|
||||
public List<ZtProject> getProjectByProduct(ZtProjectQo qo) {
|
||||
@ -687,7 +675,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
Map<Integer, List<ZtTask>> taskMap = execTaskMap(result);
|
||||
|
||||
|
||||
|
||||
for (ZtProjectDTO d : result) {
|
||||
List<ZtProject> ztProjects = projectMap.get(d.getId());
|
||||
if (!CollectionUtils.isEmpty(ztProjects)) {
|
||||
@ -719,14 +706,11 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Map<String, Integer>> countProject(ZtProjectQo qo) {
|
||||
Integer id = qo.getId();
|
||||
|
||||
|
||||
|
||||
Map<String, Map<String, Integer>> result = new HashMap<String, Map<String, Integer>>();
|
||||
|
||||
Map<String, Integer> story = new HashMap<>();
|
||||
@ -1030,7 +1014,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
public Map<String, List<Map<String, Object>>> projectTeamTimeWork(ZtProjectQo qo) {
|
||||
Map<String, List<Map<String, Object>>> map = new HashMap<>();
|
||||
|
||||
Date date = qo.getDate();
|
||||
Date date = qo.getDate()==null?new Date():qo.getDate();
|
||||
|
||||
Date firstDayOfMonth = DateUtils.getFirstDayOfMonth(date);
|
||||
Date lastDayOfMonth = new Date(DateUtils.getLastDayOfMonth(date).getTime() + 1000 * 2);
|
||||
@ -1068,7 +1052,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
);
|
||||
|
||||
|
||||
|
||||
if (CollectionUtils.isEmpty(execList)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
@ -1130,13 +1113,12 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
.collect(Collectors.toList());
|
||||
|
||||
|
||||
|
||||
Map<String, Object> m = new HashMap<>();
|
||||
if (!CollectionUtils.isEmpty(taskList)) {
|
||||
m.put("name", ztUser.getNickname());
|
||||
|
||||
//分配
|
||||
m.put("allocation",taskList.stream().map(o->o.getEstimate()).mapToDouble(e -> Double.valueOf(e)).sum()+"");
|
||||
m.put("allocation", BigDecimal.valueOf(taskList.stream().map(o -> o.getEstimate()).mapToDouble(e -> Double.valueOf(e)).sum()).setScale(2, BigDecimal.ROUND_HALF_UP));
|
||||
|
||||
m.put("task", taskList);
|
||||
} else {
|
||||
@ -1159,38 +1141,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
map.put(DateUtils.formatDate(d, "dd"), l);
|
||||
}
|
||||
return map;
|
||||
|
||||
// //项目id
|
||||
// Integer project = qo.getProject();
|
||||
// Date date = qo.getDate();
|
||||
//
|
||||
// Date sDate = DateUtils.getMonthStartDate(date);
|
||||
// Date startDate=new Date(sDate.getTime()-1000*60);
|
||||
// Date endDate = DateUtils.getMonthEndDate(date);
|
||||
//
|
||||
//
|
||||
//
|
||||
// //执行下的所有任务
|
||||
// List<ZtEffort> effortList = this.effortService
|
||||
// .list(new QueryWrapper<ZtEffort>().lambda().in(ZtEffort::getExecution, execList.stream().map(o -> o.getExecution()).collect(Collectors.toList()))
|
||||
// .gt(ZtEffort::getDate, startDate).lt(ZtEffort::getDate, endDate));
|
||||
// if(CollectionUtils.isEmpty(effortList)){
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
// List<Map<String, String>> result=new ArrayList<>();
|
||||
//
|
||||
// for (String account:accountIds){
|
||||
// Map<String, String> m=new HashMap<>();
|
||||
// List<ZtEffort> fList = effortList.stream().filter(o -> o.getAccount().equals(account)).collect(Collectors.toList());
|
||||
// if(CollectionUtils.isEmpty(fList)){
|
||||
// m.put(account,0+"");
|
||||
// }else{
|
||||
// double sum = fList.stream().mapToDouble(o -> o.getConsumed()).sum();
|
||||
// m.put(account,sum+"");
|
||||
// }
|
||||
// result.add(m);
|
||||
// }
|
||||
// return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1358,6 +1308,437 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Map<String, Object>> execWorkCount(ZtProjectQo qo) {
|
||||
// Map<String, List<Map<String, Object>>> map = new HashMap<>();
|
||||
|
||||
Date date = qo.getDate()==null?new Date():qo.getDate();
|
||||
|
||||
Date firstDayOfMonth = DateUtils.getDayStartDate(qo.getStartDate()==null?DateUtils.getMonthStartDate(date):qo.getStartDate());
|
||||
Date lastDayOfMonth = new Date(DateUtils.getDayEndDate(qo.getEndDate()==null?DateUtils.getMonthEndDate(date):qo.getEndDate()).getTime() + 1000 * 2);
|
||||
//产品集
|
||||
String execution = qo.getExecution();
|
||||
|
||||
|
||||
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda()
|
||||
.gt(ZtTask::getOpeneddate, firstDayOfMonth)
|
||||
.lt(ZtTask::getOpeneddate, lastDayOfMonth)
|
||||
.eq(ZtTask::getExecution, execution));
|
||||
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<ZtEffort> effList = this.effortService.list(new QueryWrapper<ZtEffort>().lambda()
|
||||
.in(ZtEffort::getObjectid, list.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
|
||||
List<ZtTeam> teams = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getType, "execution")
|
||||
.eq(ZtTeam::getRoot, execution));
|
||||
|
||||
List<String> accountIds = teams.stream().map(o -> o.getAccount()).distinct().collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(accountIds)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
List<ZtUser> uList = this.userService.list(new QueryWrapper<ZtUser>().lambda().in(ZtUser::getAccount, accountIds).orderByDesc(ZtUser::getUserType));
|
||||
|
||||
|
||||
Map<String, ZtUser> uMap = this.userService.userMapByIdsOrderByType(null);
|
||||
if (CollectionUtils.isEmpty(uMap.values())) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
return workBuildResult(firstDayOfMonth,lastDayOfMonth, uList,list,effList,uMap);
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<Map<String, Object>> workBuildResult(Date firstDayOfMonth,Date lastDayOfMonth,List<ZtUser> uList,List<ZtTask> list,List<ZtEffort> effList,Map<String, ZtUser> uMap){
|
||||
for (ZtTask t : list) {
|
||||
if (t.getDeadline() != null) {
|
||||
t.setDeadline(DateUtils.getDayLast(t.getDeadline()));
|
||||
}
|
||||
ZtUser ztUser = uMap.get(t.getAssignedTo());
|
||||
if(ztUser!=null){
|
||||
t.setAssignedToAccount(t.getAssignedTo());
|
||||
t.setAssignedToName(ztUser.getNickname());
|
||||
// t.setAssignedTo(ztUser.getNickname());
|
||||
}
|
||||
ztUser = uMap.get(t.getOpenedby());
|
||||
if (ztUser != null) {
|
||||
t.setOpenedbyAccount(t.getOpenedby());
|
||||
t.setOpenedby(ztUser.getNickname());
|
||||
t.setOpenedbyName(ztUser.getNickname());
|
||||
}
|
||||
ztUser = uMap.get(t.getFinishedby());
|
||||
if (ztUser != null) {
|
||||
t.setFinishedby(ztUser.getNickname());
|
||||
}
|
||||
ztUser = uMap.get(t.getCanceledby());
|
||||
if (ztUser != null) {
|
||||
t.setCanceledby(ztUser.getNickname());
|
||||
}
|
||||
ztUser = uMap.get(t.getClosedby());
|
||||
if (ztUser != null) {
|
||||
t.setClosedby(ztUser.getNickname());
|
||||
}
|
||||
}
|
||||
|
||||
List<Map<String, Object>> result = new ArrayList<>();
|
||||
|
||||
|
||||
List<ZtUser> userList =orderByUserype(uList);
|
||||
|
||||
|
||||
//打卡数据
|
||||
Map<String,List<DkInfo>> dkMap= getDkMap(uList,firstDayOfMonth,lastDayOfMonth);
|
||||
|
||||
|
||||
|
||||
for (ZtUser ztUser : userList) {
|
||||
List<ItApproval> itApprovals = this.taskService.itApprovalByUserName(ztUser.getNickname(), DateUtils.getDayStartDate(firstDayOfMonth), DateUtils.getDayEndDate(lastDayOfMonth));
|
||||
|
||||
Map<String, Object> m = new HashMap<>();
|
||||
m.put("name", ztUser.getNickname());
|
||||
List<DkInfo> dkInfos = dkMap.get(ztUser.getAccount());
|
||||
for (int i = 0; i < DateUtils.daysBetween(firstDayOfMonth,lastDayOfMonth); i++) {
|
||||
Date d = DateUtils.dateAddDay(firstDayOfMonth, i);
|
||||
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());
|
||||
|
||||
// //假期
|
||||
// String s = Constant.vacationDateMap.get(DateUtils.formatDate(d, "yyyy-MM-dd"));
|
||||
// //补班
|
||||
// s = Constant.vacationDateMap.get(DateUtils.formatDate(d, "yyyy-MM-dd"));
|
||||
// //假期
|
||||
// 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{
|
||||
List<DkInfo> dayDkList = dkInfos.stream().filter(o -> DateUtils.formatDate(d).equals(o.getDateStr())).collect(Collectors.toList());
|
||||
if(CollectionUtils.isEmpty(dayDkList)){
|
||||
obj.put("workCount","0");
|
||||
}else{
|
||||
DkInfo dkInfo = dayDkList.get(0);
|
||||
Date endDate = dkInfo.getEndDate();
|
||||
Date startDate = dkInfo.getStartDate();
|
||||
BigDecimal workcount = (endDate.getTime() - startDate.getTime()) < 1000?BigDecimal.ZERO:BigDecimal.valueOf((endDate.getTime() - startDate.getTime()) / 1000).divide(BigDecimal.valueOf(60),2,BigDecimal.ROUND_HALF_UP).divide(BigDecimal.valueOf(60), 2, BigDecimal.ROUND_HALF_UP);
|
||||
Integer fTime = Integer.valueOf(DateUtils.formatDate(startDate, "HHmmss"));
|
||||
if(workcount.floatValue()>0){
|
||||
if(fTime>130000){
|
||||
//大于下午一点点
|
||||
}else{
|
||||
workcount=workcount.subtract(BigDecimal.valueOf(1));
|
||||
}
|
||||
}
|
||||
obj.put("workCount",workcount.floatValue());
|
||||
}
|
||||
}
|
||||
if(work){
|
||||
obj.put("work","班");
|
||||
}else{
|
||||
obj.put("work","假");
|
||||
}
|
||||
//如果请假
|
||||
List<ItApproval> fitApprovals=itApprovals.stream().filter(o->o.getName().equals(ztUser.getNickname())).filter(o->(
|
||||
o.getApplyTimeStart().getTime() >=DateUtils.getDayStartDate(d).getTime() && o.getApplyTimeStart().getTime() <=DateUtils.getDayEndDate(d).getTime() )
|
||||
||
|
||||
(o.getApplyTimeEnd().getTime() >=DateUtils.getDayStartDate(d).getTime() && o.getApplyTimeEnd().getTime() <=DateUtils.getDayEndDate(d).getTime() )
|
||||
).collect(Collectors.toList());
|
||||
if(!CollectionUtils.isEmpty(fitApprovals)){
|
||||
obj.put("leave","1");
|
||||
}else{
|
||||
obj.put("leave","0");
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(taskList)) {
|
||||
//分配
|
||||
obj.put("allocation",BigDecimal.valueOf(taskList.stream()
|
||||
.map(o -> o.getEstimate()).mapToDouble(e -> Double.valueOf(e))
|
||||
.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())
|
||||
.sum()).setScale(2, BigDecimal.ROUND_HALF_UP));
|
||||
obj.put("task",taskList);
|
||||
if(CollectionUtils.isEmpty(taskList)){
|
||||
obj.put("consume",0);
|
||||
}else{
|
||||
List<ZtEffort> efforts = effList.stream().filter(o->DateUtils.formatDate(o.getDate()).equals(DateUtils.formatDate(d))).filter(o -> "task".equals(o.getObjecttype())).filter(o -> taskList.stream().map(x -> x.getId()).collect(Collectors.toList()).contains(o.getObjectid())).collect(Collectors.toList());
|
||||
if(!CollectionUtils.isEmpty(efforts)){
|
||||
obj.put("consume",floatBatchAdd(efforts.stream().map(o->o.getConsumed()).collect(Collectors.toList())) );
|
||||
}else {
|
||||
obj.put("consume",0);
|
||||
}
|
||||
}
|
||||
m.put(DateUtils.formatDate(d,"dd").toString(),obj);
|
||||
} else {
|
||||
//分配
|
||||
obj.put("consume","");
|
||||
obj.put("allocation","");
|
||||
obj.put("task",new ArrayList<>());
|
||||
m.put(DateUtils.formatDate(d,"dd").toString(),obj);
|
||||
}
|
||||
}
|
||||
|
||||
result.add(m);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<ZtUser> orderByUserype(List<ZtUser> uList) {
|
||||
List<ZtUser> userList =new ArrayList<>();
|
||||
userList.addAll(uList.stream().filter(o->o.getUserType()==UserType.KFZ).collect(Collectors.toList()));
|
||||
userList.addAll(uList.stream().filter(o->o.getUserType()==UserType.CS).collect(Collectors.toList()));
|
||||
userList.addAll(uList.stream().filter(o->o.getUserType()==UserType.XMGLY).collect(Collectors.toList()));
|
||||
userList.addAll(uList.stream().filter(o->o.getUserType()==UserType.GSGC).collect(Collectors.toList()));
|
||||
return userList;
|
||||
}
|
||||
|
||||
private Map<String, List<DkInfo>> getDkMap(List<ZtUser> uList, Date firstDayOfMonth, Date lastDayOfMonth) {
|
||||
List<DkInfo> dkInfos = this.userService.dkList(uList.stream().map(o -> o.getAccount()).collect(Collectors.toList()), firstDayOfMonth, lastDayOfMonth);
|
||||
Map<String,List<DkInfo>> dkMap=new HashMap<>();
|
||||
if(!CollectionUtils.isEmpty(dkInfos)){
|
||||
dkMap=dkInfos.stream().collect(Collectors.groupingBy(DkInfo::getAccount));
|
||||
}
|
||||
return dkMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo< Map<String, Object>> pageDaysTimeWorkCount(ZtProjectQo qo) {
|
||||
qo.setPageSize(1000);
|
||||
Map<String, List<Map<String, Object>>> map = new HashMap<>();
|
||||
|
||||
Date date = qo.getDate()==null?new Date():qo.getDate();
|
||||
|
||||
Date firstDayOfMonth = DateUtils.getDayStartDate(qo.getStartDate()==null?DateUtils.getMonthStartDate(date):qo.getStartDate());
|
||||
Date lastDayOfMonth = new Date(DateUtils.getDayEndDate(qo.getEndDate()==null?DateUtils.getMonthEndDate(date):qo.getEndDate()).getTime() + 1000 * 2);
|
||||
//产品集
|
||||
Integer project = qo.getProject();
|
||||
|
||||
//产品
|
||||
List<ZtProduct> products = this.productService.list(new QueryWrapper<ZtProduct>().lambda().eq(ZtProduct::getProgram, project));
|
||||
if (CollectionUtils.isEmpty(products)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
//项目列表
|
||||
List<ZtProjectproduct> projectList = this.projectproductService.list(new QueryWrapper<ZtProjectproduct>().lambda()
|
||||
.in(ZtProjectproduct::getProduct, products.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
if (CollectionUtils.isEmpty(projectList)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
List<ZtExecutionproject> execList = this.executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda()
|
||||
.in(ZtExecutionproject::getProject, projectList.stream().map(o -> o.getProject()).collect(Collectors.toList())));
|
||||
if (CollectionUtils.isEmpty(execList)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
|
||||
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda()
|
||||
.gt(ZtTask::getOpeneddate, firstDayOfMonth)
|
||||
.lt(ZtTask::getOpeneddate, lastDayOfMonth)
|
||||
.in(ZtTask::getExecution, execList.stream().map(o -> o.getExecution())
|
||||
.collect(Collectors.toList())));
|
||||
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
List<ZtEffort> effList = this.effortService.list(new QueryWrapper<ZtEffort>().lambda()
|
||||
.in(ZtEffort::getObjectid, list.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
// 时间 T1 T2
|
||||
// 任务 T3 T4
|
||||
List<ZtProject> ztProjects = this.listByIds(execList.stream().map(o -> o.getExecution()).collect(Collectors.toList()));
|
||||
// ztProjects=ztProjects.stream().filter(o->
|
||||
// ( firstDayOfMonth .getTime()>=o.getBegin().getTime() &&lastDayOfMonth.getTime()>o.getEnd().getTime())||
|
||||
// ( firstDayOfMonth .getTime()<=o.getBegin().getTime() &&lastDayOfMonth.getTime()>=o.getEnd().getTime())||
|
||||
// ( firstDayOfMonth .getTime()<=o.getBegin().getTime() &&lastDayOfMonth.getTime()<=o.getEnd().getTime())
|
||||
// ).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(ztProjects)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
List<ZtTeam> teams = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getType, "execution")
|
||||
.in(ZtTeam::getRoot, ztProjects.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
|
||||
List<String> accountIds = teams.stream().map(o -> o.getAccount()).distinct().collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(accountIds)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
Page<Map> page = PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
|
||||
|
||||
|
||||
List<ZtUser> uList = this.userService.list(new QueryWrapper<ZtUser>().lambda().in(ZtUser::getAccount, accountIds).orderByDesc(ZtUser::getUserType));
|
||||
|
||||
|
||||
Map<String, ZtUser> uMap = this.userService.userMapByIdsOrderByType(null);
|
||||
if (CollectionUtils.isEmpty(uMap.values())) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
return new PageInfo< Map<String, Object>>(workBuildResult(firstDayOfMonth,lastDayOfMonth, uList,list,effList,uMap));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo pageMonthReport(ZtProjectQo qo) {
|
||||
qo.setPageSize(10000);
|
||||
Map<String, List<Map<String, Object>>> map = new HashMap<>();
|
||||
|
||||
Date date = qo.getDate()==null?new Date():qo.getDate();
|
||||
|
||||
Date firstDayOfMonth = DateUtils.getFirstDayOfMonth(date);
|
||||
Date lastDayOfMonth = new Date(DateUtils.getLastDayOfMonth(date).getTime() + 1000 * 2);
|
||||
//产品集
|
||||
Integer project = qo.getProject();
|
||||
List<ZtProduct> products =null;
|
||||
if(project==null||project==0){
|
||||
List<Integer> productIds = authProductList();
|
||||
products=this.productService.listByIds(productIds);
|
||||
}else{
|
||||
//产品
|
||||
products = this.productService.list(new QueryWrapper<ZtProduct>().lambda().eq(ZtProduct::getProgram, project));
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(products)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
//项目列表
|
||||
List<ZtProjectproduct> projectList = this.projectproductService.list(new QueryWrapper<ZtProjectproduct>().lambda()
|
||||
.in(ZtProjectproduct::getProduct, products.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
if (CollectionUtils.isEmpty(projectList)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
List<ZtExecutionproject> execList = this.executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda()
|
||||
.in(ZtExecutionproject::getProject, projectList.stream().map(o -> o.getProject()).collect(Collectors.toList())));
|
||||
if (CollectionUtils.isEmpty(execList)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
|
||||
List<ZtTask> list = this.taskService.list(new QueryWrapper<ZtTask>().lambda()
|
||||
.between(ZtTask::getEstStarted, firstDayOfMonth, lastDayOfMonth)
|
||||
.in(ZtTask::getExecution, execList.stream().map(o -> o.getExecution())
|
||||
.collect(Collectors.toList())));
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
//工时
|
||||
List<ZtEffort> efforts = this.effortService.list(new QueryWrapper<ZtEffort>().lambda()
|
||||
.eq(ZtEffort::getObjecttype, "task")
|
||||
.in(ZtEffort::getObjectid, list.stream().map(o -> o.getId()).collect(Collectors.toList()))
|
||||
.gt(ZtEffort::getDate, new Date(firstDayOfMonth.getTime() - 2000)).lt(ZtEffort::getDate, lastDayOfMonth)
|
||||
);
|
||||
|
||||
|
||||
if (CollectionUtils.isEmpty(execList)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
// 时间 T1 T2
|
||||
// 任务 T3 T4
|
||||
List<ZtProject> ztProjects = this.listByIds(execList.stream().map(o -> o.getExecution()).collect(Collectors.toList()));
|
||||
if (CollectionUtils.isEmpty(ztProjects)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
List<ZtTeam> teams = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getType, "execution")
|
||||
.in(ZtTeam::getRoot, ztProjects.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
|
||||
List<String> accountIds = teams.stream().map(o -> o.getAccount()).distinct().collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(accountIds)) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
Page<Map> page = PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
|
||||
|
||||
Map<String, ZtUser> uMap = this.userService.userMapByIds(null);
|
||||
if (CollectionUtils.isEmpty(uMap.values())) {
|
||||
return new PageInfo<>();
|
||||
}
|
||||
|
||||
List result =new ArrayList();
|
||||
|
||||
|
||||
for (String account :accountIds) {
|
||||
|
||||
List<ZtTask> taskList = list.stream().filter(o->account.equals(o.getAssignedTo()))
|
||||
.filter(o ->
|
||||
(
|
||||
o.getFinishedDate()!=null
|
||||
&& (o.getFinishedDate().getTime() >= firstDayOfMonth.getTime()
|
||||
&& o.getFinishedDate().getTime() <= lastDayOfMonth.getTime()))
|
||||
||
|
||||
(o.getEstStarted()!=null&&o.getDeadline()!=null)&&
|
||||
(( o.getDeadline().getTime()<=lastDayOfMonth.getTime()&& o.getDeadline().getTime()>=firstDayOfMonth.getTime())
|
||||
||
|
||||
( o.getEstStarted().getTime()<=lastDayOfMonth.getTime()&& o.getEstStarted().getTime()>=firstDayOfMonth.getTime()))
|
||||
).filter(o->o.getStatus().equals("done"))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
var d=new WorkDetailsDTO();
|
||||
ZtUser ztUser = uMap.get(account);
|
||||
d.setUserName(ztUser.getNickname());
|
||||
//需求总工时
|
||||
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()))));
|
||||
//可用工时
|
||||
d.setHaveTime(BigDecimal.valueOf(DateUtils.getWorkDaysInCurrentMonth(date) * 6));
|
||||
//工作饱和度
|
||||
d.setSaturation(d.getWorkTime().compareTo(BigDecimal.ZERO)==0?BigDecimal.ZERO:d.getWorkTime().divide(d.getHaveTime(),2,BigDecimal.ROUND_HALF_UP));
|
||||
// 任务总量
|
||||
List<ZtTask> taskCountList = list.stream().filter(o->account.equals(o.getAssignedTo()))
|
||||
.filter(o ->
|
||||
( o.getFinishedDate()!=null&& (o.getFinishedDate().getTime() >= firstDayOfMonth.getTime()
|
||||
&& o.getFinishedDate().getTime() <= lastDayOfMonth.getTime()))
|
||||
||
|
||||
(o.getEstStarted()!=null&&o.getDeadline()!=null)&&
|
||||
(( DateUtils.getDayLast(o.getDeadline()).getTime()<=lastDayOfMonth.getTime()&& DateUtils.getDayLast(o.getDeadline()).getTime()>=firstDayOfMonth.getTime())
|
||||
||
|
||||
( o.getEstStarted().getTime()<=lastDayOfMonth.getTime()&& o.getEstStarted().getTime()>=firstDayOfMonth.getTime()))
|
||||
).filter(o->!o.getStatus().equals("closed"))
|
||||
.collect(Collectors.toList());
|
||||
d.setTaskCount(BigDecimal.valueOf(taskCountList.size()));
|
||||
|
||||
List<ZtTask> delayList = list.stream().filter(o->account.equals(o.getAssignedTo()))
|
||||
.filter(o ->
|
||||
( o.getFinishedDate()!=null&& (o.getFinishedDate().getTime() >= firstDayOfMonth.getTime()
|
||||
&& o.getFinishedDate().getTime() <= lastDayOfMonth.getTime()))
|
||||
||
|
||||
(o.getEstStarted()!=null&&o.getDeadline()!=null)&&
|
||||
(( o.getDeadline().getTime()<=lastDayOfMonth.getTime()&& o.getDeadline().getTime()>=firstDayOfMonth.getTime())
|
||||
||
|
||||
( o.getEstStarted().getTime()<=lastDayOfMonth.getTime()&& o.getEstStarted().getTime()>=firstDayOfMonth.getTime()))
|
||||
)
|
||||
.filter(o->
|
||||
((o.getFinishedDate()!=null &&DateUtils.getDayLast(o.getFinishedDate()).getTime()>DateUtils.getDayLast(o.getDeadline()).getTime()) ) //实际完成大于预计完成 延期
|
||||
||o.getFinishedDate()==null &&lastDayOfMonth.getTime()>DateUtils.getDayLast(o.getDeadline()).getTime()
|
||||
)
|
||||
.filter(o->!o.getStatus().equals("closed"))
|
||||
.collect(Collectors.toList());
|
||||
//任务延期量
|
||||
d.setTaskDelayCount(BigDecimal.valueOf(delayList.size()));
|
||||
//任务及时完成率
|
||||
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));
|
||||
|
||||
d.setBugCount(BigDecimal.valueOf(bugList.size()));
|
||||
result.add(d);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return new PageInfo(result);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//修改项目集
|
||||
@Override
|
||||
@ -1433,7 +1814,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<ZtProjectDTO> parentList(ZtProjectDTO dto) {
|
||||
List<Integer> pIds = authList();
|
||||
@ -1475,7 +1855,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
Map<Integer, List<ZtProjectDTO>> m = getChildrenMap(result, qo);
|
||||
|
||||
|
||||
|
||||
for (ZtProjectDTO d : result) {
|
||||
if (!StringUtils.isEmpty(d.getPm())) {
|
||||
ZtUser ztUser = userMap.get(d.getPm());
|
||||
@ -1492,6 +1871,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
|
||||
return new PageInfo<ZtProjectDTO>(result);
|
||||
}
|
||||
|
||||
List getChild(Integer id, Map<Integer, List<ZtProjectDTO>> m) {
|
||||
List<ZtProjectDTO> ztProjectDTOS = m.get(id);
|
||||
if (CollectionUtils.isEmpty(ztProjectDTOS)) {
|
||||
@ -1546,6 +1926,86 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
Map<Integer, List<ZtTask>> taskMap = execTaskMap(result);
|
||||
|
||||
|
||||
for (ZtProjectDTO d : result) {
|
||||
List<ZtProject> ztProjects = projectMap.get(d.getId());
|
||||
if (!CollectionUtils.isEmpty(ztProjects)) {
|
||||
d.setProjectName(StringUtils.join(ztProjects.stream().map(o -> o.getName()).collect(Collectors.toList()), ","));
|
||||
}
|
||||
|
||||
List<ZtProjectproduct> ztProjectproducts = ztProjectproductMap.get(d.getId());
|
||||
if (!CollectionUtils.isEmpty(ztProjectproducts)) {
|
||||
d.setProductIds(ztProjectproducts.stream().map(o -> o.getProject()).collect(Collectors.toList()));
|
||||
}
|
||||
List<ZtTask> tasks = taskMap.get(d.getId());
|
||||
if (!CollectionUtils.isEmpty(tasks)) {
|
||||
List<Float> leftList = tasks.stream().map(o -> o.getLeft()).collect(Collectors.toList());
|
||||
List<Float> consumedList = tasks.stream().map(o -> o.getConsumed()).collect(Collectors.toList());
|
||||
List<Float> planList = tasks.stream().map(o -> o.getEstimate()).collect(Collectors.toList());
|
||||
|
||||
|
||||
d.setLeft(floatBatchAdd(leftList));
|
||||
d.setPlan(floatBatchAdd(planList));
|
||||
d.setConsumed(floatBatchAdd(consumedList));
|
||||
}
|
||||
ZtUser ztUser = userMap.get(d.getPm());
|
||||
if (ztUser != null) {
|
||||
d.setPoValue(ztUser.getNickname());
|
||||
}
|
||||
}
|
||||
}
|
||||
return new PageInfo<ZtProjectDTO>(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageInfo<ZtProjectDTO> myProgressImplementPageList(ZtProjectQo qo) {
|
||||
List<Integer> pIds = execAuthList();
|
||||
if (CollectionUtils.isEmpty(pIds)) {
|
||||
return new PageInfo<ZtProjectDTO>();
|
||||
}
|
||||
|
||||
List<ZtProject> doingImplements = this.baseMapper.selectList(new QueryWrapper<ZtProject>().lambda().eq(ZtProject::getStatus, "doing").in(ZtProject::getId, pIds));
|
||||
if(CollectionUtils.isEmpty(doingImplements)){
|
||||
return new PageInfo<ZtProjectDTO>();
|
||||
}
|
||||
|
||||
List<ZtTeam> teamImplements = this.teamService.list(new QueryWrapper<ZtTeam>().lambda().eq(ZtTeam::getAccount, RiskUserThreadLocal.get().getName())
|
||||
.in(ZtTeam::getRoot,doingImplements.stream().map(o->o.getId()).collect(Collectors.toList()))
|
||||
.eq(ZtTeam::getType, "execution").groupBy(ZtTeam::getRoot));
|
||||
if(CollectionUtils.isEmpty(teamImplements)){
|
||||
return new PageInfo<ZtProjectDTO>();
|
||||
}
|
||||
|
||||
|
||||
qo.setProjectIds(teamImplements.stream().map(o->o.getRoot()).collect(Collectors.toList()));
|
||||
Page<ZtProjectDTO> page = PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
|
||||
if (!"admin".equals(RiskUserThreadLocal.get().getName())) {
|
||||
qo.setUserName(RiskUserThreadLocal.get().getName());
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<ZtProjectDTO> result = this.baseMapper.implementPageList(qo);
|
||||
if (!CollectionUtils.isEmpty(result)) {
|
||||
|
||||
Map<String, ZtUser> userMap = this.userService.userMapByIds(null);
|
||||
|
||||
List<ZtExecutionproject> list = executionprojectService.list(new QueryWrapper<ZtExecutionproject>().lambda()
|
||||
.in(ZtExecutionproject::
|
||||
getExecution, result.stream().map(o -> o.getId()).collect(Collectors.toList())
|
||||
));
|
||||
Map<Integer, List<ZtProject>> projectMap = null;
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
projectMap = new HashMap<>();
|
||||
} else {
|
||||
projectMap = getProjectMapByExec(list, this.baseMapper
|
||||
.selectBatchIds(list.stream().map(o -> o.getProject()).collect(Collectors.toList())));
|
||||
}
|
||||
|
||||
Map<Integer, List<ZtProjectproduct>> ztProjectproductMap = getZtProjectproductMap(result);
|
||||
|
||||
|
||||
Map<Integer, List<ZtTask>> taskMap = execTaskMap(result);
|
||||
|
||||
|
||||
for (ZtProjectDTO d : result) {
|
||||
List<ZtProject> ztProjects = projectMap.get(d.getId());
|
||||
@ -1655,7 +2115,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
LambdaQueryWrapper<ZtProject> lambda = new QueryWrapper<ZtProject>().lambda();
|
||||
|
||||
|
||||
|
||||
lambda.eq(ZtProject::getType, "program");
|
||||
lambda.eq(ZtProject::getDeleted, "0");
|
||||
|
||||
@ -1702,6 +2161,7 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ZtProjectDTO> authTreeParentList(ZtProjectDTO dto) {
|
||||
LambdaQueryWrapper<ZtProject> lambda = new QueryWrapper<ZtProject>().lambda();
|
||||
@ -1760,29 +2220,37 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
@Override
|
||||
public List<ZtProjectDTO> typeProductList(ZtProjectQo qo) {
|
||||
|
||||
LambdaQueryWrapper<ZtProject> eq = new QueryWrapper<ZtProject>().lambda()
|
||||
.eq(ZtProject::getType, "project")
|
||||
.eq(ZtProject::getDeleted, "0");
|
||||
// LambdaQueryWrapper<ZtProject> eq = new QueryWrapper<ZtProject>().lambda()
|
||||
// .eq(ZtProject::getType, "project")
|
||||
// .eq(ZtProject::getDeleted, "0");
|
||||
//
|
||||
// if (qo.getStatus() != null) {
|
||||
// eq.eq(ZtProject::getStatus, qo.getStatus());
|
||||
// }
|
||||
//
|
||||
// List<ZtProject> project = this.baseMapper.selectList(
|
||||
// eq
|
||||
// );
|
||||
//
|
||||
//
|
||||
//
|
||||
// if (CollectionUtils.isEmpty(project)) {
|
||||
// return new ArrayList<>();
|
||||
// }
|
||||
//
|
||||
// List<String> listAuth = project.stream().map(o -> o.getPath()).collect(Collectors.toList());
|
||||
// List<Integer> ids = new ArrayList<>();
|
||||
// for (String str : listAuth) {
|
||||
// ids.add(Integer.valueOf(Arrays.asList(str.split(",")).stream().filter(o -> !StringUtils.isEmpty(o)).collect(Collectors.toList()).get(0)));
|
||||
// }
|
||||
|
||||
if(qo.getStatus()!=null){
|
||||
eq.eq(ZtProject::getStatus,qo.getStatus());
|
||||
}
|
||||
List<Integer> authList = projectAuthList();
|
||||
List<ZtProject> pList = this.baseMapper.selectList(
|
||||
new QueryWrapper<ZtProject>().lambda().in(ZtProject::getId, authList).eq(ZtProject::getDeleted,"0").ne(ZtProject::getStatus, "closed"));
|
||||
|
||||
List<ZtProject> project = this.baseMapper.selectList(
|
||||
eq
|
||||
);
|
||||
if(CollectionUtils.isEmpty(project)){
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<String> listAuth = project.stream().map(o -> o.getPath()).collect(Collectors.toList());
|
||||
List<Integer> ids =new ArrayList<>();
|
||||
for (String str:listAuth) {
|
||||
ids.add(Integer.valueOf(Arrays.asList(str.split(",")).stream().filter(o->!StringUtils.isEmpty(o)).collect(Collectors.toList()).get(0)));
|
||||
}
|
||||
Map<Integer, ZtProject> projectMap = getProjectMap(this.baseMapper.selectList(
|
||||
new QueryWrapper<ZtProject>().lambda().in(ZtProject::getId,ids).ne(ZtProject::getStatus,"closed")));
|
||||
List<ZtProjectDTO> ztProjectDTOS = BeanCopyUtil.copyListProperties(project, ZtProjectDTO::new);
|
||||
Map<Integer, ZtProject> projectMap = getProjectMap(pList);
|
||||
List<ZtProjectDTO> ztProjectDTOS = BeanCopyUtil.copyListProperties(pList, ZtProjectDTO::new);
|
||||
for (ZtProjectDTO p : ztProjectDTOS) {
|
||||
ZtProject ztProject = projectMap.get(Integer.valueOf(Arrays.asList(p.getPath().split(",")).stream().filter(o -> !StringUtils.isEmpty(o)).collect(Collectors.toList()).get(0)));
|
||||
if (ztProject.getId().intValue() != p.getId().intValue()) {
|
||||
@ -1795,7 +2263,6 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
}
|
||||
|
||||
|
||||
|
||||
private Map<Integer, ZtProject> getProjectMap(List<ZtProject> ztProjects) {
|
||||
if (CollectionUtils.isEmpty(ztProjects)) {
|
||||
return new HashMap<>();
|
||||
@ -1833,11 +2300,20 @@ public class ZtProjectServiceImpl extends ServiceImpl<ZtProjectMapper, ZtProject
|
||||
return ztProjectDTOS.stream().collect(Collectors.groupingBy(ZtProjectDTO::getParent));
|
||||
}
|
||||
|
||||
BigDecimal floatToBigDecimal(Float f){
|
||||
if(f==null){
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
BigDecimal decimal = BigDecimal.valueOf(f);
|
||||
return decimal.setScale(2,BigDecimal.ROUND_HALF_UP);
|
||||
}
|
||||
|
||||
private Float floatBatchAdd(List<Float> list) {
|
||||
BigDecimal f = BigDecimal.ZERO;
|
||||
for (Float i : list) {
|
||||
f = f.add(BigDecimal.valueOf(i));
|
||||
}
|
||||
f = f.setScale(1, BigDecimal.ROUND_HALF_UP);
|
||||
return f.floatValue();
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
|
||||
private IZtStoryService storyService;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void addRelease(ZtReleaseDTO dto) {
|
||||
Integer project = dto.getProject();
|
||||
|
||||
@ -101,6 +102,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
|
||||
.eq(ZtStory::getStage, StoryStageEnums.tested.getValue()));
|
||||
if(!CollectionUtils.isEmpty(sList)){
|
||||
List<ZtReleaseDetails> releaseStoryList = this.releaseDetailsService.list(new QueryWrapper<ZtReleaseDetails>().lambda()
|
||||
.ne(ZtReleaseDetails::getStatus,"closed")
|
||||
.in(ZtReleaseDetails::getObjectId, sList.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
List<Integer> sIds = releaseStoryList.stream().map(o -> o.getObjectId().intValue()).collect(Collectors.toList());
|
||||
|
||||
@ -116,7 +118,12 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
|
||||
saveBatch.add(e);
|
||||
}
|
||||
}
|
||||
if(CollectionUtils.isEmpty(saveBatch)){
|
||||
throw new BusinessException("当前没有符合发布的需求,请检查");
|
||||
}
|
||||
releaseDetailsService.saveBatch(saveBatch);
|
||||
}else{
|
||||
throw new BusinessException("当前没有符合发布的需求,请检查");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -309,7 +316,7 @@ public class ZtReleaseServiceImpl extends ServiceImpl<ZtReleaseMapper, ZtRelease
|
||||
notice.setFlag(0);
|
||||
noticeService.save(notice);
|
||||
}
|
||||
List<ZtReleaseDetails> details = this.releaseDetailsService.list(new QueryWrapper<ZtReleaseDetails>().lambda().eq(ZtReleaseDetails::getReleaseId, ztRelease.getId()).eq(ZtReleaseDetails::getObjectType, "story"));
|
||||
List<ZtReleaseDetails> details = this.releaseDetailsService.list(new QueryWrapper<ZtReleaseDetails>().lambda().eq(ZtReleaseDetails::getReleaseId, ztRelease.getId()).ne(ZtReleaseDetails::getStatus,"closed").eq(ZtReleaseDetails::getObjectType, "story"));
|
||||
|
||||
List<Integer> storyList=new ArrayList<Integer>();
|
||||
for (ZtReleaseDetails d:details ) {
|
||||
|
@ -112,7 +112,8 @@ public class ZtStoryFeedbackServiceImpl extends ServiceImpl<ZtStoryFeedbackMappe
|
||||
if(loginRiskUser!=null){
|
||||
name=loginRiskUser.getName();
|
||||
}
|
||||
ZtUser user= this.userService.getbyVxId(dto.getVx());
|
||||
ZtUser user= this.userService.getbyVxId(org.apache.commons.lang3.StringUtils.isEmpty(dto.getVx())?
|
||||
dto.getWeixin():dto.getVx());
|
||||
if(user!=null){
|
||||
name=user.getAccount();
|
||||
}
|
||||
|
@ -399,11 +399,11 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
|
||||
|
||||
BeanUtils.copyProperties(dto, ztStory,"stage");
|
||||
if("draft".equalsIgnoreCase(ztStory.getStatus())){
|
||||
ztStory.setStatus("reviewing");
|
||||
ztStory.setStatus("active");
|
||||
if (ztStory.getProduct() != null&&ztStory.getProduct()!=0) {
|
||||
ZtProduct product = productService.getById(ztStory.getProduct());
|
||||
product.setDraftStories(product.getDraftStories() - 1);
|
||||
product.setReviewingStories(product.getReviewingStories() + 1);
|
||||
product.setActiveStories(product.getReviewingStories() + 1);
|
||||
this.productService.updateById(product);
|
||||
}
|
||||
}
|
||||
@ -423,7 +423,10 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
|
||||
spec.setSpec(dto.getSpec());
|
||||
spec.setVerify(dto.getVerify());
|
||||
spec.setFiles(dto.getFileUrl());
|
||||
storyspecService.update(new UpdateWrapper<ZtStoryspec>().lambda().eq(ZtStoryspec::getStory,id).set(ZtStoryspec::getFiles,dto.getFileUrl())
|
||||
storyspecService.update(new UpdateWrapper<ZtStoryspec>().lambda().eq(ZtStoryspec::getStory,id)
|
||||
.set(ZtStoryspec::getSpec,dto.getSpec())
|
||||
.set(ZtStoryspec::getVerify,dto.getVerify())
|
||||
.set(ZtStoryspec::getFiles,dto.getFileUrl())
|
||||
);
|
||||
}
|
||||
|
||||
@ -779,6 +782,7 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
|
||||
}
|
||||
LambdaQueryWrapper<ZtStory> lambda = new QueryWrapper<ZtStory>().lambda();
|
||||
lambda.eq(ZtStory::getStatus, "active");
|
||||
lambda.notIn(ZtStory::getStage,"released","verified");
|
||||
lambda.in(ZtStory::getId,resultIds);
|
||||
List<ZtStory> ztStories = this.baseMapper.selectList(lambda);
|
||||
if (CollectionUtils.isEmpty(ztStories)) {
|
||||
@ -917,6 +921,9 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
|
||||
}
|
||||
|
||||
ztStory.setStage("developed");
|
||||
if(ztStory.getStartDate()==null){
|
||||
ztStory.setStartDate(new Date());
|
||||
}
|
||||
this.baseMapper.updateById(ztStory);
|
||||
List<Integer> executionId = this.getExecutionId(ztStory);
|
||||
for (Integer execution:executionId ) {
|
||||
@ -974,6 +981,10 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
|
||||
actionService.addAction(ActionType.XQ, ActionStatus.CSWC, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null,
|
||||
RiskUserThreadLocal.get().getName(), null, "");
|
||||
}
|
||||
if(ztStory.getStartDate()==null){
|
||||
ztStory.setStartDate(new Date());
|
||||
}
|
||||
ztStory.setEndDate(new Date());
|
||||
this.baseMapper.updateById(ztStory);
|
||||
|
||||
for (Integer execId : execIds) {
|
||||
@ -1037,6 +1048,9 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
|
||||
String newStatus ="released";
|
||||
|
||||
ztStory.setStage(newStatus);
|
||||
if(ztStory.getEndDate()==null){
|
||||
ztStory.setEndDate(new Date());
|
||||
}
|
||||
this.baseMapper.updateById(ztStory);
|
||||
|
||||
for (Integer execId : execIds) {
|
||||
@ -1095,6 +1109,9 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
|
||||
actionService.addAction(ActionType.XQ, ActionStatus.KSCE, ztStory.getId(), ztStory.getProduct() + "", ztStory.getProject(), null,
|
||||
RiskUserThreadLocal.get().getName(), null, "");
|
||||
}
|
||||
if(ztStory.getStartDate()==null){
|
||||
ztStory.setStartDate(new Date());
|
||||
}
|
||||
this.baseMapper.updateById(ztStory);
|
||||
|
||||
for (Integer execId : execIds) {
|
||||
@ -1604,9 +1621,6 @@ public class ZtStoryServiceImpl extends ServiceImpl<ZtStoryMapper, ZtStory> impl
|
||||
}
|
||||
|
||||
|
||||
List<String> userIds = new ArrayList<>();
|
||||
userIds.add(ztStory.getAssignedTo());
|
||||
userIds.add(ztStory.getOpenedby());
|
||||
|
||||
Map<String, ZtUser> userMap = this.userService.userMapByIds(null);
|
||||
|
||||
|
@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.sa.zentao.conf.LoginRiskUser;
|
||||
import com.sa.zentao.conf.RiskUserThreadLocal;
|
||||
import com.sa.zentao.dao.*;
|
||||
import com.sa.zentao.entity.*;
|
||||
@ -427,6 +428,24 @@ public class ZtStoryUserServiceImpl extends ServiceImpl<ZtStoryUserMapper, ZtSto
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List myWaitYsStory(ZtStoryDTO dto) {
|
||||
LoginRiskUser loginRiskUser = RiskUserThreadLocal.get();
|
||||
if(loginRiskUser==null||dto.getProductId()==null){
|
||||
throw new BusinessException("请检查");
|
||||
}
|
||||
|
||||
List<ZtStory> released = this.storyService.list(new QueryWrapper<ZtStory>().lambda()
|
||||
.eq(ZtStory::getProduct, dto.getProductId())
|
||||
.eq(ZtStory::getYsUser, loginRiskUser.getName())
|
||||
.eq(ZtStory::getStage, "released")
|
||||
);
|
||||
|
||||
|
||||
|
||||
return released;
|
||||
}
|
||||
|
||||
private Map<Integer, List<ZtStory>> getStoryUserMap(List<ZtStoryUserDTO> list) {
|
||||
List<Integer> ids = list.stream().map(o -> o.getId()).collect(Collectors.toList());
|
||||
|
||||
|
@ -179,7 +179,6 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void addRemark(ZtTaskDTO dto) {
|
||||
ZtTask task = this.baseMapper.selectById(dto.getId());
|
||||
@ -234,6 +233,11 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
return this.baseMapper.taskListPrd(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItApproval> itApprovalByUserName(String s, Date firstDayOfMonth, Date lastDayOfMonth) {
|
||||
return this.baseMapper.itApprovalByUserName(s, firstDayOfMonth, lastDayOfMonth);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public PageInfo<ZtTaskDTO> myTaskPageList(ZtProjectQo qo) {
|
||||
@ -242,14 +246,13 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
LoginRiskUser loginRiskUser = RiskUserThreadLocal.get();
|
||||
//执行ids
|
||||
List<Integer> projectAuthList = new ArrayList<>();
|
||||
if(UserType.GSGC!=loginRiskUser.getUserType()){
|
||||
|
||||
|
||||
//自己有权限的 产品集
|
||||
List<Integer> integers = this.ztProjectService.authList();
|
||||
List<Integer> authList = this.ztProjectService.authList();
|
||||
|
||||
if(!CollectionUtils.isEmpty(integers)){
|
||||
List<ZtProduct> pList = this.productService.list(new QueryWrapper<ZtProduct>().lambda().in(ZtProduct::getProgram, integers));
|
||||
if (!CollectionUtils.isEmpty(authList)) {
|
||||
List<ZtProduct> pList = this.productService.list(new QueryWrapper<ZtProduct>().lambda().in(ZtProduct::getProgram, authList));
|
||||
//所有的产品
|
||||
if (!CollectionUtils.isEmpty(pList)) {
|
||||
List<ZtProjectproduct> list = this.projectproductService.list(new QueryWrapper<ZtProjectproduct>().lambda().in(ZtProjectproduct::getProduct, pList.stream().map(o -> o.getId()).collect(Collectors.toList())));
|
||||
@ -261,8 +264,8 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(UserType.GSGC!=loginRiskUser.getUserType()&&CollectionUtils.isEmpty(projectAuthList)){
|
||||
|
||||
if (CollectionUtils.isEmpty(projectAuthList)) {
|
||||
return new PageInfo<ZtTaskDTO>();
|
||||
}
|
||||
Page<ZtTaskDTO> page = PageHelper.startPage(qo.getCurrentPage(), qo.getPageSize());
|
||||
@ -312,7 +315,6 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Autowired
|
||||
private IZtProjectstoryService projectstoryService;
|
||||
|
||||
@ -329,9 +331,6 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
ztTask.setEstimate(dto.getLeft());
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//getExecution()执行
|
||||
//项目
|
||||
Integer story = ztTask.getStory();
|
||||
@ -362,6 +361,10 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
}
|
||||
//如果是开发人员 需要评审
|
||||
UserType userType = RiskUserThreadLocal.get().getUserType();
|
||||
|
||||
if (dto.getDraftFlag() != null && dto.getDraftFlag() == 1) {
|
||||
ztTask.setStatus("draft");
|
||||
} else {
|
||||
if (userType == UserType.KFZ) {
|
||||
ZtProject ztProject = this.ztProjectService.getById(ztTask.getExecution());
|
||||
ztTask.setStatus("reviewing");
|
||||
@ -370,7 +373,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
ztTask.setStatus("wait");
|
||||
ztTask.setReviewingUser(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (ztTask.getDeadline() != null) {
|
||||
ztTask.setDeadlineTime(ztTask.getDeadline().getTime() / 1000);
|
||||
@ -381,6 +384,18 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
if (ztProjectproduct != null) {
|
||||
ztTask.setProduct(ztProjectproduct.getProduct());
|
||||
}
|
||||
if(dto.getFinishedFlag()==null||dto.getFinishedFlag()==0){
|
||||
//不完成任务
|
||||
}else{
|
||||
//完成修补数据
|
||||
ztTask.setRealstarted(new Date(ztTask.getApplyDate().getTime()-ztTask.getUseTime()
|
||||
.multiply(BigDecimal.valueOf(60*60*1000)).longValue()));
|
||||
ztTask.setEstStarted(ztTask.getRealstarted());
|
||||
ztTask.setDeadline(new Date(DateUtils.getDayEndDate(ztTask.getApplyDate()).getTime()-1000*60*5));
|
||||
ztTask.setEstimate(ztTask.getUseTime().floatValue());
|
||||
ztTask.setLeft(ztTask.getUseTime().floatValue());
|
||||
}
|
||||
|
||||
this.baseMapper.insert(ztTask);
|
||||
|
||||
fileService.updateFile(dto.getFiles(), ztTask.getId(), FileTypes.task);
|
||||
@ -391,10 +406,21 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
ZtProjectproduct projectproduct = projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, ztTask.getProject()));
|
||||
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
if(dto.getFinishedFlag()!=null&&dto.getFinishedFlag()==1){
|
||||
//如果选了完成并且不需要审核那么直接完成
|
||||
if((userType==UserType.XMGLY||userType==UserType.GSGC)&&!ztTask.getStatus().equals("draft")){
|
||||
dto.setId(ztTask.getId());
|
||||
dto.setConsumed(ztTask.getUseTime().floatValue());
|
||||
dto.setLeft(ztTask.getUseTime().floatValue());
|
||||
this.startTask(dto);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -405,16 +431,49 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
throw new BusinessException("未查询到数据");
|
||||
}
|
||||
String desc = ztTask.getDesc();
|
||||
|
||||
String status = ztTask.getStatus();
|
||||
BeanUtils.copyProperties(dto, ztTask, "left", "consumed");
|
||||
ztTask.setEstimate(dto.getLeft());
|
||||
ztTask.setEstimate(dto.getEstimate());
|
||||
//剩余
|
||||
ztTask.setLeft(BigDecimal.valueOf(dto.getLeft()).subtract(BigDecimal.valueOf(ztTask.getConsumed())).setScale(2,BigDecimal.ROUND_HALF_UP).floatValue());
|
||||
ztTask.setLeft(BigDecimal.valueOf(dto.getEstimate()).subtract(BigDecimal.valueOf(ztTask.getConsumed())).setScale(2, BigDecimal.ROUND_HALF_UP).floatValue());
|
||||
ztTask.setLastediteddate(new Date());
|
||||
ztTask.setLasteditedby(RiskUserThreadLocal.get().getName());
|
||||
if (ztTask.getDeadline() != null) {
|
||||
ztTask.setDeadlineTime(ztTask.getDeadline().getTime() / 1000);
|
||||
}
|
||||
|
||||
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");
|
||||
ztTask.setReviewingUser(ztProject.getPm());
|
||||
} else {
|
||||
ztTask.setStatus("wait");
|
||||
ztTask.setReviewingUser(null);
|
||||
}
|
||||
}else{
|
||||
ztTask.setStatus("reviewing");
|
||||
ZtProject ztProject = this.ztProjectService.getById(ztTask.getExecution());
|
||||
ztTask.setReviewingUser(ztProject.getPm());
|
||||
}
|
||||
}
|
||||
if(dto.getFinishedFlag()==null||dto.getFinishedFlag()==0){
|
||||
//不完成任务
|
||||
}else{
|
||||
//完成修补数据
|
||||
ztTask.setRealstarted(new Date(ztTask.getApplyDate().getTime()-ztTask.getUseTime()
|
||||
.multiply(BigDecimal.valueOf(60*60*1000)).longValue()));
|
||||
ztTask.setEstStarted(ztTask.getRealstarted());
|
||||
ztTask.setDeadline(new Date(DateUtils.getDayEndDate(ztTask.getApplyDate()).getTime()-1000*60*5));
|
||||
ztTask.setEstimate(ztTask.getUseTime().floatValue());
|
||||
ztTask.setLeft(ztTask.getUseTime().floatValue());
|
||||
}
|
||||
|
||||
this.baseMapper.updateById(ztTask);
|
||||
|
||||
fileService.updateFile(dto.getFiles(), ztTask.getId(), FileTypes.task);
|
||||
@ -438,14 +497,12 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void startTask(ZtTaskDTO dto) {
|
||||
|
||||
if (dto.getLeft() < dto.getConsumed()) {
|
||||
throw new BusinessException("工时填写错误");
|
||||
}
|
||||
@ -455,7 +512,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
throw new BusinessException("未查询到数据");
|
||||
}
|
||||
ztTask.setAssignedTo(dto.getAssignedTo());
|
||||
ztTask.setRealstarted(dto.getEstStarted());
|
||||
ztTask.setRealstarted(new Date());
|
||||
if (dto.getFinishedFlag() == 0) {
|
||||
ztTask.setStatus("doing");
|
||||
} else {
|
||||
@ -545,8 +602,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
if (ztTask.getStory() != null && ztTask.getStory() != 0) {
|
||||
if ("test".equals(type)) {
|
||||
this.storyService.testedStory(ztTask.getStory());
|
||||
}else
|
||||
if("devel".equals(type)){
|
||||
} else if ("devel".equals(type)) {
|
||||
//开发
|
||||
this.storyService.finishStory(ztTask.getStory());
|
||||
}
|
||||
@ -566,9 +622,13 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
ztTask.setConsumed(dto.getConsumed() + ztTask.getConsumed());
|
||||
ztTask.setLeft(ztTask.getEstimate() - ztTask.getConsumed());
|
||||
ztTask.setStatus("done");
|
||||
ztTask.setRealstarted(dto.getRealstarted());
|
||||
if(ztTask.getFinishedFlag()!=null&&ztTask.getFinishedFlag()==1){
|
||||
ztTask.setFinishedby(ztTask.getAssignedTo());
|
||||
}else{
|
||||
ztTask.setFinishedby(RiskUserThreadLocal.get().getName());
|
||||
ztTask.setFinishedDate(dto.getFinishedDate());
|
||||
}
|
||||
|
||||
ztTask.setFinishedDate(new Date());
|
||||
ztTask.setLasteditedby(RiskUserThreadLocal.get().getName());
|
||||
ztTask.setLastediteddate(new Date());
|
||||
this.baseMapper.updateById(ztTask);
|
||||
@ -586,18 +646,18 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
RiskUserThreadLocal.get().getName(), dto.getRemark(), null);
|
||||
if (ztTask.getExecution() != null && ztTask.getExecution() != 0) {
|
||||
if (StringUtils.isEmpty(dto.getTabType())) {
|
||||
KanbanQo qo =new KanbanQo();
|
||||
qo.setStatusType("developed");
|
||||
qo.setTabType("task");
|
||||
qo.setId(dto.getId());
|
||||
//查
|
||||
ZtKanbancell ztKanbanlane = this.kanbanlaneService.getZtKanbanlane("task", "developing", ztTask.getExecution());
|
||||
|
||||
qo.setFromId(ztKanbanlane.getColumn());
|
||||
//查
|
||||
ztKanbanlane = this.kanbanlaneService.getZtKanbanlane("task", "developed", ztTask.getExecution());
|
||||
qo.setToId(ztKanbanlane.getColumn());
|
||||
kanbanlaneService.changeStatus(qo);
|
||||
// KanbanQo qo = new KanbanQo();
|
||||
// qo.setStatusType("developed");
|
||||
// qo.setTabType("task");
|
||||
// qo.setId(dto.getId());
|
||||
// //查
|
||||
// ZtKanbancell ztKanbanlane = this.kanbanlaneService.getZtKanbanlane("task", "developing", ztTask.getExecution());
|
||||
//
|
||||
// qo.setFromId(ztKanbanlane.getColumn());
|
||||
// //查
|
||||
// ztKanbanlane = this.kanbanlaneService.getZtKanbanlane("task", "developed", ztTask.getExecution());
|
||||
// qo.setToId(ztKanbanlane.getColumn());
|
||||
kanbanlaneService.changeStatus(ztTask.getExecution(),ztTask.getId(),"task","developed");
|
||||
} else {
|
||||
KanbanQo qo = new KanbanQo();
|
||||
qo.setStatusType(dto.getStatusType());
|
||||
@ -608,8 +668,6 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
kanbanlaneService.changeStatus(qo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// devel 开发 request 需求 test
|
||||
//如果有一个开发任务进行中,并且所有的测试任务还没有开始,需求的研发阶段为“研发中”
|
||||
//如果所有的开发任务已经完成,并且所有的测试任务还没有开始,则为“研发完毕"
|
||||
@ -622,20 +680,11 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
if (ztTask.getStory() != null && ztTask.getStory() != 0) {
|
||||
if ("test".equals(type)) {
|
||||
this.storyService.testedStory(ztTask.getStory());
|
||||
}else
|
||||
if("devel".equals(type)){
|
||||
} else if ("devel".equals(type)) {
|
||||
//开发
|
||||
this.storyService.finishStory(ztTask.getStory());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// if(ztTask.getStory()!=null&&ztTask.getStory()!=0){
|
||||
// this.storyService.finishStory(ztTask.getStory(),ztTask.getExecution());
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -658,18 +707,6 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
RiskUserThreadLocal.get().getName(), dto.getDesc(), null);
|
||||
if (ztTask.getExecution() != null && ztTask.getExecution() != 0) {
|
||||
if (StringUtils.isEmpty(dto.getTabType())) {
|
||||
// KanbanQo qo =new KanbanQo();
|
||||
// qo.setStatusType("developed");
|
||||
// qo.setTabType("task");
|
||||
// qo.setId(dto.getId());
|
||||
// // 完成才能取消
|
||||
// String cellStatus="developed";
|
||||
// ZtKanbancell ztKanbanlane = this.kanbanlaneService.getZtKanbanlane("task", cellStatus, ztTask.getExecution());
|
||||
//
|
||||
// qo.setFromId(ztKanbanlane.getColumn());
|
||||
// //查
|
||||
// ztKanbanlane = this.kanbanlaneService.getZtKanbanlane("task", "closed", ztTask.getExecution());
|
||||
// qo.setToId(ztKanbanlane.getColumn());
|
||||
kanbanlaneService.changeStatus(ztTask.getExecution(), ztTask.getId(), "task", "closed");
|
||||
} else {
|
||||
KanbanQo qo = new KanbanQo();
|
||||
@ -693,6 +730,9 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
if ("cancel".equalsIgnoreCase(ztTask.getStatus())) {
|
||||
throw new BusinessException("未查询到数据");
|
||||
}
|
||||
if("done".equals(status)||"closed".equals(status)){
|
||||
throw new BusinessException("当前状态无法取消");
|
||||
}
|
||||
ztTask.setLeft(0f);
|
||||
ztTask.setStatus("cancel");
|
||||
ztTask.setLasteditedby(RiskUserThreadLocal.get().getName());
|
||||
@ -707,20 +747,7 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
if (ztTask.getExecution() != null && ztTask.getExecution() != 0) {
|
||||
if (StringUtils.isEmpty(dto.getTabType())) {
|
||||
|
||||
String cellStatus = KanBanConstant.TaskMap.get(status);
|
||||
|
||||
|
||||
KanbanQo qo =new KanbanQo();
|
||||
qo.setStatusType("canceled");
|
||||
qo.setTabType("task");
|
||||
qo.setId(dto.getId());
|
||||
ZtKanbancell ztKanbanlane = this.kanbanlaneService.getZtKanbanlane("task", cellStatus, ztTask.getExecution());
|
||||
|
||||
qo.setFromId(ztKanbanlane.getColumn());
|
||||
//查
|
||||
ztKanbanlane = this.kanbanlaneService.getZtKanbanlane("task", "canceled", ztTask.getExecution());
|
||||
qo.setToId(ztKanbanlane.getColumn());
|
||||
kanbanlaneService.changeStatus(qo);
|
||||
kanbanlaneService.changeStatus(ztTask.getExecution(),ztTask.getId(),"task","canceled");
|
||||
} else {
|
||||
KanbanQo qo = new KanbanQo();
|
||||
qo.setStatusType(dto.getStatusType());
|
||||
@ -790,7 +817,6 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.saveBatch(saveList);
|
||||
|
||||
kanbanlaneService.addTask(list.get(0).getExecution(), saveList);
|
||||
@ -810,21 +836,52 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
@Override
|
||||
@Transactional
|
||||
public void approval(ZtTaskDTO dto) {
|
||||
|
||||
|
||||
LoginRiskUser loginRiskUser = RiskUserThreadLocal.get();
|
||||
if(loginRiskUser==null){
|
||||
throw new BusinessException("请登录");
|
||||
}
|
||||
String account = loginRiskUser.getName();
|
||||
|
||||
|
||||
|
||||
|
||||
ZtTask t = this.baseMapper.selectById(dto.getId());
|
||||
|
||||
if (!t.getStatus().equals("reviewing")) {
|
||||
throw new BusinessException("未查询到数据");
|
||||
}
|
||||
if(!account.equals(t.getReviewingUser())){
|
||||
throw new BusinessException("当前无法评审");
|
||||
}
|
||||
if (dto.getApprovalStatus() == 1) {
|
||||
t.setStatus("wait");
|
||||
//完成任务
|
||||
|
||||
|
||||
} else {
|
||||
t.setStatus("closed");
|
||||
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());
|
||||
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);
|
||||
}
|
||||
}
|
||||
this.baseMapper.updateById(t);
|
||||
|
||||
ZtProjectproduct projectproduct = projectproductService.getOne(new QueryWrapper<ZtProjectproduct>().lambda().eq(ZtProjectproduct::getProject, t.getProject()));
|
||||
|
||||
@ -840,7 +897,6 @@ public class ZtTaskServiceImpl extends ServiceImpl<ZtTaskMapper, ZtTask> impleme
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public List<ZtTaskDTO> taskListByExecution(ZtTaskDTO dto) {
|
||||
LambdaQueryWrapper<ZtTask> eq = new QueryWrapper<ZtTask>().lambda();
|
||||
|
@ -5,10 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.sa.zentao.dao.BusinessException;
|
||||
import com.sa.zentao.dao.ZtProjectDTO;
|
||||
import com.sa.zentao.dao.ZtStoryDTO;
|
||||
import com.sa.zentao.dao.ZtUserDTO;
|
||||
import com.sa.zentao.dao.*;
|
||||
import com.sa.zentao.entity.VerificationCode;
|
||||
import com.sa.zentao.entity.ZtProduct;
|
||||
import com.sa.zentao.entity.ZtProject;
|
||||
@ -18,6 +15,7 @@ import com.sa.zentao.qo.ZtUserQo;
|
||||
import com.sa.zentao.service.*;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sa.zentao.utils.BeanCopyUtil;
|
||||
import com.sa.zentao.utils.CryptoUtils;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.sms.v20190711.SmsClient;
|
||||
@ -74,6 +72,10 @@ public class ZtUserServiceImpl extends ServiceImpl<ZtUserMapper, ZtUser> impleme
|
||||
PageInfo<ZtUserDTO> ztUserDTOPageInfo = new PageInfo<>(ztUserDTOS);
|
||||
ztUserDTOPageInfo.setTotal(page.getTotal());
|
||||
for (ZtUserDTO dto:ztUserDTOS) {
|
||||
if(!StringUtils.isEmpty(dto.getVx())){
|
||||
dto.setVx(CryptoUtils.aesDecryptForFront(dto.getVx(), CryptoUtils.KEY_DES));
|
||||
}
|
||||
|
||||
if(dto.getUserType()!=null){
|
||||
dto.setUserTypeValue(dto.getUserType().getValue());
|
||||
}
|
||||
@ -133,6 +135,20 @@ public class ZtUserServiceImpl extends ServiceImpl<ZtUserMapper, ZtUser> impleme
|
||||
return ztUsers.stream().collect(Collectors.toMap(ZtUser::getAccount,o->o));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Map<String, ZtUser> userMapByIdsOrderByType(List<String> accounts) {
|
||||
List<ZtUser> ztUsers =null;
|
||||
if(CollectionUtils.isEmpty(accounts)){
|
||||
ztUsers = this.baseMapper.selectList(new QueryWrapper<ZtUser>().lambda().orderByDesc(ZtUser::getUserType));
|
||||
}else{
|
||||
ztUsers = this.baseMapper.selectList(new QueryWrapper<ZtUser>().lambda().in(ZtUser::getAccount, accounts).orderByDesc(ZtUser::getUserType));
|
||||
}
|
||||
if(CollectionUtils.isEmpty(ztUsers)){
|
||||
return new HashMap<>();
|
||||
}else{
|
||||
return ztUsers.stream().collect(Collectors.toMap(ZtUser::getAccount,o->o));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@ -210,13 +226,19 @@ public class ZtUserServiceImpl extends ServiceImpl<ZtUserMapper, ZtUser> impleme
|
||||
if(StringUtils.isEmpty(vx)){
|
||||
return null;
|
||||
}
|
||||
List<ZtUser> ztUsers = this.baseMapper.selectList(new QueryWrapper<ZtUser>().lambda().eq(ZtUser::getVx, vx));
|
||||
List<ZtUser> ztUsers = this.baseMapper.selectList(new QueryWrapper<ZtUser>().lambda().eq(ZtUser::getVx, CryptoUtils.aesEncryptForFront(vx,CryptoUtils.KEY_DES)));
|
||||
if(CollectionUtils.isEmpty(ztUsers)){
|
||||
return null;
|
||||
}
|
||||
return ztUsers.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DkInfo> dkList(List<String> account, Date startDate, Date endDate) {
|
||||
|
||||
return this.baseMapper.dkList(account,startDate,endDate);
|
||||
}
|
||||
|
||||
public boolean sendSms(String phoneNumber, String verificationCode) {
|
||||
try {
|
||||
// 初始化腾讯云短信服务客户端
|
||||
|
130
src/main/java/com/sa/zentao/utils/CryptoUtils.java
Normal file
130
src/main/java/com/sa/zentao/utils/CryptoUtils.java
Normal file
@ -0,0 +1,130 @@
|
||||
package com.sa.zentao.utils;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Base64;
|
||||
|
||||
public class CryptoUtils {
|
||||
|
||||
//这个密钥需要是16位
|
||||
public static final String KEY_DES = "aaaaaaaabbbbbbbb";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String old = "12345678";
|
||||
String target ="hy+A8P/oEYPdOpwfRVpgwg=="; // 加密后的字符串
|
||||
|
||||
//解密
|
||||
System.out.println(CryptoUtils.aesDecryptForFront(target, CryptoUtils.KEY_DES));
|
||||
|
||||
//加密
|
||||
System.out.println(CryptoUtils.aesEncryptForFront(old, CryptoUtils.KEY_DES));
|
||||
|
||||
File file = new File("C:\\111.txt");
|
||||
// 以 byte 的形式读取,不改变文件数据的编码格式
|
||||
byte[] bytes = Files.readAllBytes(file.toPath());
|
||||
|
||||
byte[] outFile = CryptoUtils.aesEncryptForFront(bytes, CryptoUtils.KEY_DES);
|
||||
OutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\model1.zm"));
|
||||
out.write(outFile);
|
||||
|
||||
// // 这里生成加密后的文件后缀可以自定义
|
||||
// File file = new File("C:\\\\model.zm");
|
||||
// // 以 byte 的形式读取,不改变文件数据的编码格式
|
||||
// byte[] bytes = Files.readAllBytes(file.toPath());
|
||||
// byte[] outFile = CryptoUtils.aesDecryptForFront(bytes, CryptoUtils.KEY_DES);
|
||||
// OutputStream out = new BufferedOutputStream(new FileOutputStream("C:\\model2.glb"));
|
||||
// out.write(outFile);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* AES解密
|
||||
* @param encryptStr 密文
|
||||
* @param decryptKey 秘钥,必须为16个字符组成
|
||||
* @return 明文
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesDecryptForFront(String encryptStr, String decryptKey) {
|
||||
if (StringUtils.isEmpty(encryptStr) || StringUtils.isEmpty(decryptKey)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
byte[] encryptByte = Base64.getDecoder().decode(encryptStr);
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
|
||||
byte[] decryptBytes = cipher.doFinal(encryptByte);
|
||||
return new String(decryptBytes);
|
||||
|
||||
} catch (Exception var3) {
|
||||
var3.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// AES解密文件
|
||||
public static byte[] aesDecryptForFront(byte[] bytes, String decryptKey) {
|
||||
if (StringUtils.isEmpty(bytes) || StringUtils.isEmpty(decryptKey)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
|
||||
return cipher.doFinal(bytes);
|
||||
|
||||
} catch (Exception var3) {
|
||||
var3.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* AES加密文本
|
||||
* @param content 明文
|
||||
* @param encryptKey 秘钥,必须为16个字符组成
|
||||
* @return 密文
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String aesEncryptForFront(String content, String encryptKey) {
|
||||
if (StringUtils.isEmpty(content) || StringUtils.isEmpty(encryptKey)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
|
||||
|
||||
byte[] encryptStr = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
|
||||
return Base64.getEncoder().encodeToString(encryptStr);
|
||||
|
||||
} catch (Exception var3) {
|
||||
var3.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
// AES加密文件
|
||||
public static byte[] aesEncryptForFront(byte[] bytes, String encryptKey) {
|
||||
if (StringUtils.isEmpty(bytes) || StringUtils.isEmpty(encryptKey)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
|
||||
|
||||
byte[] encryptStr = cipher.doFinal(bytes);
|
||||
return encryptStr;
|
||||
|
||||
} catch (Exception var3) {
|
||||
var3.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -114,7 +114,8 @@ public class DateUtils {
|
||||
}
|
||||
|
||||
public static String formatDate(Date smdate) {
|
||||
return smdate == null ? null : sdf.format(smdate);
|
||||
//todo s Index 14 out of bounds for length 13
|
||||
return smdate == null ? "" : sdf.format(smdate);
|
||||
}
|
||||
public static Date parseDate(String smdate, String f) {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(f);
|
||||
|
182
src/main/java/com/sa/zentao/utils/ExcelUtil.java
Normal file
182
src/main/java/com/sa/zentao/utils/ExcelUtil.java
Normal file
@ -0,0 +1,182 @@
|
||||
package com.sa.zentao.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.ss.usermodel.DateUtil;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xssf.usermodel.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @description: 多个Excel合并Sheet
|
||||
* @author: wyj
|
||||
* @time: 2020/9/18 15:28
|
||||
*/
|
||||
@Slf4j
|
||||
public class ExcelUtil {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String currentDir = System.getProperty("user.dir");
|
||||
System.out.println("Current Directory: " + currentDir);
|
||||
List<String> list = Arrays.asList(
|
||||
new File("scope测试.xlsx").toString(),
|
||||
new File("scope开发.xlsx").toString()
|
||||
);
|
||||
|
||||
mergexcel(list,"杨洪-家庭贷-20190908(报告).xlsx", System.getProperty("user.dir")+"\\");
|
||||
System.out.println("OJBK");
|
||||
}
|
||||
|
||||
/**
|
||||
* * 合并多个ExcelSheet
|
||||
*
|
||||
* @param files 文件字符串(file.toString)集合,按顺序进行合并,合并的Excel中Sheet名称不可重复
|
||||
* @param excelName 合并后Excel名称(包含后缀.xslx)
|
||||
* @param dirPath 存储目录
|
||||
* @return
|
||||
* @Date: 2020/9/18 15:31
|
||||
*/
|
||||
public static void mergexcel(List<String> files, String excelName, String dirPath) {
|
||||
XSSFWorkbook newExcelCreat = new XSSFWorkbook();
|
||||
// 遍历每个源excel文件,TmpList为源文件的名称集合
|
||||
for (String fromExcelName : files) {
|
||||
try (InputStream in = new FileInputStream(fromExcelName)) {
|
||||
XSSFWorkbook fromExcel = new XSSFWorkbook(in);
|
||||
int length = fromExcel.getNumberOfSheets();
|
||||
if (length <= 1) { //长度为1时
|
||||
XSSFSheet oldSheet = fromExcel.getSheetAt(0);
|
||||
// XSSFSheet newSheet = newExcelCreat.createSheet(oldSheet.getSheetName());
|
||||
XSSFSheet newSheet = newExcelCreat.createSheet(oldSheet.getSheetName());
|
||||
copySheet(newExcelCreat, oldSheet, newSheet);
|
||||
} else {
|
||||
for (int i = 0; i < length; i++) {// 遍历每个sheet
|
||||
XSSFSheet oldSheet = fromExcel.getSheetAt(i);
|
||||
XSSFSheet newSheet = newExcelCreat.createSheet(oldSheet.getSheetName());
|
||||
copySheet(newExcelCreat, oldSheet, newSheet);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// 定义新生成的xlxs表格文件
|
||||
String allFileName = dirPath + File.separator + excelName;
|
||||
try (FileOutputStream fileOut = new FileOutputStream(allFileName)) {
|
||||
newExcelCreat.write(fileOut);
|
||||
fileOut.flush();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
newExcelCreat.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并单元格
|
||||
*
|
||||
* @param fromSheet
|
||||
* @param toSheet
|
||||
*/
|
||||
private static void mergeSheetAllRegion(XSSFSheet fromSheet, XSSFSheet toSheet) {
|
||||
int num = fromSheet.getNumMergedRegions();
|
||||
CellRangeAddress cellR = null;
|
||||
for (int i = 0; i < num; i++) {
|
||||
cellR = fromSheet.getMergedRegion(i);
|
||||
toSheet.addMergedRegion(cellR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制单元格
|
||||
*
|
||||
* @param wb
|
||||
* @param fromCell
|
||||
* @param toCell
|
||||
*/
|
||||
private static void copyCell(XSSFWorkbook wb, XSSFCell fromCell, XSSFCell toCell) {
|
||||
XSSFCellStyle newstyle = wb.createCellStyle();
|
||||
// 复制单元格样式
|
||||
try {
|
||||
newstyle.cloneStyleFrom(fromCell.getCellStyle());
|
||||
}catch (Exception e){
|
||||
System.out.print(""+e);
|
||||
}
|
||||
|
||||
// 样式
|
||||
toCell.setCellStyle(newstyle);
|
||||
if (fromCell.getCellComment() != null) {
|
||||
toCell.setCellComment(fromCell.getCellComment());
|
||||
}
|
||||
// 不同数据类型处理
|
||||
CellType fromCellType = fromCell.getCellType();
|
||||
toCell.setCellType(fromCellType);
|
||||
if (fromCellType == CellType.NUMERIC) {
|
||||
if (DateUtil.isCellDateFormatted(fromCell)) {
|
||||
toCell.setCellValue(fromCell.getDateCellValue());
|
||||
} else {
|
||||
toCell.setCellValue(fromCell.getNumericCellValue());
|
||||
}
|
||||
} else if (fromCellType == CellType.STRING) {
|
||||
toCell.setCellValue(fromCell.getRichStringCellValue());
|
||||
} else if (fromCellType == CellType.BLANK) {
|
||||
// nothing21
|
||||
} else if (fromCellType == CellType.BOOLEAN) {
|
||||
toCell.setCellValue(fromCell.getBooleanCellValue());
|
||||
} else if (fromCellType == CellType.ERROR) {
|
||||
toCell.setCellErrorValue(fromCell.getErrorCellValue());
|
||||
} else if (fromCellType == CellType.FORMULA) {
|
||||
toCell.setCellFormula(fromCell.getCellFormula());
|
||||
} else {
|
||||
// nothing29
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 行复制功能
|
||||
*
|
||||
* @param wb
|
||||
* @param oldRow
|
||||
* @param toRow
|
||||
*/
|
||||
private static void copyRow(XSSFWorkbook wb, XSSFRow oldRow, XSSFRow toRow) {
|
||||
toRow.setHeight(oldRow.getHeight());
|
||||
for (Iterator cellIt = oldRow.cellIterator(); cellIt.hasNext(); ) {
|
||||
XSSFCell tmpCell = (XSSFCell) cellIt.next();
|
||||
XSSFCell newCell = toRow.createCell(tmpCell.getColumnIndex());
|
||||
copyCell(wb, tmpCell, newCell);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sheet复制
|
||||
*
|
||||
* @param wb
|
||||
* @param fromSheet
|
||||
* @param toSheet
|
||||
*/
|
||||
private static void copySheet(XSSFWorkbook wb, XSSFSheet fromSheet, XSSFSheet toSheet) {
|
||||
mergeSheetAllRegion(fromSheet, toSheet);
|
||||
// 设置列宽
|
||||
int length =0;
|
||||
try {
|
||||
length = fromSheet.getRow(fromSheet.getFirstRowNum()).getLastCellNum();
|
||||
}catch (Exception e){
|
||||
length=10;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= length; i++) {
|
||||
toSheet.setColumnWidth(i, fromSheet.getColumnWidth(i));
|
||||
}
|
||||
for (Iterator rowIt = fromSheet.rowIterator(); rowIt.hasNext(); ) {
|
||||
XSSFRow oldRow = (XSSFRow) rowIt.next();
|
||||
XSSFRow newRow = toSheet.createRow(oldRow.getRowNum());
|
||||
copyRow(wb, oldRow, newRow);
|
||||
}
|
||||
}
|
||||
}
|
@ -17,6 +17,12 @@
|
||||
SELECT * from zt_story_feedback s WHERE 1 = 1
|
||||
|
||||
|
||||
|
||||
|
||||
<if test="qo.productId != null and qo.productId != ''">
|
||||
and s.product = #{qo.productId}
|
||||
</if>
|
||||
|
||||
<if test="qo.searchVal == 'ALL' ">
|
||||
|
||||
</if>
|
||||
|
@ -70,6 +70,7 @@
|
||||
where 1=1
|
||||
and product = #{qo.productId}
|
||||
|
||||
|
||||
<if test="qo.searchVal == 'ALL' ">
|
||||
|
||||
</if>
|
||||
|
@ -80,7 +80,6 @@
|
||||
</if>
|
||||
|
||||
|
||||
|
||||
<if test="qo.objIds != null and qo.objIds.size() > 0">
|
||||
and s.id in
|
||||
<foreach collection="qo.objIds" item="id" index="index"
|
||||
@ -222,14 +221,24 @@
|
||||
</choose>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</select>
|
||||
<select id="taskListPrd" resultType="com.sa.zentao.dao.ZtTaskDTO">
|
||||
|
||||
select * from zt_task where execution = #{id}
|
||||
|
||||
</select>
|
||||
<select id="itApprovalByUserName" resultType="com.sa.zentao.dao.ItApproval">
|
||||
SELECT * from os_system.it_approval a WHERE 1=1
|
||||
and a.name = #{name}
|
||||
and
|
||||
(
|
||||
(date(apply_time_start) BETWEEN date( #{startDate}) and date(#{endDate}))
|
||||
or(
|
||||
date(apply_time_end) BETWEEN date(#{startDate}) and date(#{endDate}))
|
||||
)
|
||||
|
||||
|
||||
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
@ -65,5 +65,22 @@
|
||||
<select id="selectPrdByName" resultType="com.sa.zentao.entity.ZtUser">
|
||||
SELECT * from zt_user WHERE 1=1 and account=#{name}
|
||||
</select>
|
||||
<select id="dkList" resultType="com.sa.zentao.dao.DkInfo">
|
||||
SELECT u.account,dk.date_str,staff.`name` ,min(dk_time) startDate,max(dk_time) endDate from os_system.new_dk_data dk LEFT JOIN os_system.base_staff staff on dk.staff_id = staff.id
|
||||
LEFT JOIN zentao_dev.zt_user u on staff.vx_id = u.vx
|
||||
WHERE 1=1 and dk.dk_time <![CDATA[>=]]> #{startDate} and dk.dk_time <![CDATA[<=]]> #{endDate}
|
||||
|
||||
|
||||
<if test="ids != null and ids.size() > 0">
|
||||
and u.account in
|
||||
<foreach collection="ids" item="id" index="index"
|
||||
open="(" close=")" separator=",">
|
||||
#{id}
|
||||
</foreach>
|
||||
|
||||
</if>
|
||||
GROUP BY date_str,u.account
|
||||
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
Reference in New Issue
Block a user