|
@@ -49,6 +49,7 @@ import java.text.DecimalFormat;
|
|
import java.text.ParseException;
|
|
import java.text.ParseException;
|
|
import java.text.SimpleDateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.time.*;
|
|
import java.time.*;
|
|
|
|
+import java.time.chrono.ChronoLocalDate;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.time.format.DateTimeParseException;
|
|
import java.time.format.DateTimeParseException;
|
|
import java.time.temporal.ChronoUnit;
|
|
import java.time.temporal.ChronoUnit;
|
|
@@ -58,6 +59,7 @@ import java.util.concurrent.CountDownLatch;
|
|
import java.util.concurrent.Executor;
|
|
import java.util.concurrent.Executor;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.Executors;
|
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -10222,7 +10224,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
|
|
|
|
|
|
private List<LocalDate> getDays(LocalDate start, LocalDate end) {
|
|
private List<LocalDate> getDays(LocalDate start, LocalDate end) {
|
|
List<LocalDate> result = new ArrayList();
|
|
List<LocalDate> result = new ArrayList();
|
|
- while (start.isBefore(end)) {
|
|
|
|
|
|
+ while (start!=null&&end!=null&& start.isBefore(end)) {
|
|
result.add(start);
|
|
result.add(start);
|
|
start=start.plusDays(1);
|
|
start=start.plusDays(1);
|
|
}
|
|
}
|
|
@@ -10953,6 +10955,368 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
|
|
return msg;
|
|
return msg;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ @Override
|
|
|
|
+ public HttpRespMsg getReportRateOfTask(Integer projectId, String userIds, Integer companyId, Integer type) {
|
|
|
|
+ HttpRespMsg msg = new HttpRespMsg();
|
|
|
|
+ DecimalFormat dft = new DecimalFormat("0%");
|
|
|
|
+ List<String> collect=new ArrayList<>();
|
|
|
|
+ if (userIds!=null&&!userIds.isEmpty()){
|
|
|
|
+ String[] strings = userIds.split(",");
|
|
|
|
+ collect = Arrays.stream(strings).collect(Collectors.toList());
|
|
|
|
+ }
|
|
|
|
+ List<ReportRateTaskVO> reportRateTaskVOList= reportMapper.getReportRateOfTask(projectId, collect, type,companyId);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", companyId));
|
|
|
|
+ List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
|
|
|
|
+
|
|
|
|
+ List<Integer> taskIds = reportRateTaskVOList.stream().distinct().map(r -> r.getTaskId()).collect(Collectors.toList());
|
|
|
|
+ System.out.println(taskIds.toString());
|
|
|
|
+ taskIds.add(-1);
|
|
|
|
+ List<Map<String,Object>> reportList=reportMapper.getUserReportTimelinessRateWithTask(companyId,taskIds);
|
|
|
|
+ Map<Object, List<Map<String, Object>>> listMap = reportList.stream().filter(item->!StringUtils.isEmpty(item.get("userName"))).collect(Collectors.groupingBy(rp -> rp.get("userName")));
|
|
|
|
+ //获取到公司设置的特殊节假日设置
|
|
|
|
+ List<HolidaySetting> holidaySettingList = holidaySettingService.list(new LambdaQueryWrapper<HolidaySetting>().eq(HolidaySetting::getCompanyId, companyId).isNotNull(HolidaySetting::getHolidayDate));
|
|
|
|
+ List<HolidaySetting> allUsersSetting = holidaySettingList.stream().filter(h -> h.getRangeType() == 0).collect(Collectors.toList());
|
|
|
|
+ List<HolidaySetting> targetUserOrDeptSetting = holidaySettingList.stream().filter(h -> h.getRangeType() == 1).collect(Collectors.toList());
|
|
|
|
+ TimeType timeType = timeTypeMapper.selectById(companyId);
|
|
|
|
+ Integer timeliness = timeType.getTimeliness();
|
|
|
|
+
|
|
|
|
+ for (ReportRateTaskVO rateTaskVO : reportRateTaskVOList) {
|
|
|
|
+ Optional<User> first = userList.stream().filter(u -> u.getId().equals(rateTaskVO.getUserId())).findFirst();
|
|
|
|
+ if (first.isPresent()){
|
|
|
|
+ User user = first.get();
|
|
|
|
+ rateTaskVO.setJobNumber(user.getJobNumber());
|
|
|
|
+ Optional<Department> firstDept = departmentList.stream().filter(d->d.getDepartmentId().equals(user.getDepartmentId())).findFirst();
|
|
|
|
+ if(firstDept.isPresent()){
|
|
|
|
+ Department dept= firstDept.get();
|
|
|
|
+ rateTaskVO.setDepartmentName(dept.getDepartmentName());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ List<Map<String, Object>> mapList = listMap.get(user.getName());
|
|
|
|
+ LocalDate startDate = rateTaskVO.getStartDate();
|
|
|
|
+ LocalDate endDate = rateTaskVO.getEndDate();
|
|
|
|
+ AtomicReference<List<LocalDate>> listAtomicReference = new AtomicReference<>(getDays(startDate, endDate));
|
|
|
|
+ long days = listAtomicReference.get().size();
|
|
|
|
+ for (LocalDate localDateTime : listAtomicReference.get()) {
|
|
|
|
+ if(mapList!=null){
|
|
|
|
+ //在非工作日下 填报了的情况下 及时填报了就算作及时率计算的基数
|
|
|
|
+ if(localDateTime!=null&& !WorkDayCalculateUtils.isWorkDay(localDateTime)&&!mapList.stream().anyMatch(ml->{
|
|
|
|
+ Integer taskId=ml.get("taskId")!=null?Integer.parseInt(ml.get("taskId").toString()):null;
|
|
|
|
+ if (taskId == null || !taskId.equals(rateTaskVO.getTaskId())) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ Date date = (Date) ml.get("createDate");
|
|
|
|
+ LocalDate createDate = date != null ? date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate() : null;
|
|
|
|
+ return createDate.isEqual(localDateTime);
|
|
|
|
+ })){
|
|
|
|
+ days-=1;
|
|
|
|
+ }
|
|
|
|
+ }else {
|
|
|
|
+ if(localDateTime!=null&&!WorkDayCalculateUtils.isWorkDay(localDateTime)){
|
|
|
|
+ days-=1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //获取请假数据
|
|
|
|
+ List<LeaveSheet> leaveSheetList = leaveSheetMapper.selectList(new LambdaQueryWrapper<LeaveSheet>()
|
|
|
|
+ .eq(LeaveSheet::getCompanyId, companyId).le(endDate!=null,LeaveSheet::getStartDate,endDate)
|
|
|
|
+ .ge(startDate!=null,LeaveSheet::getEndDate,startDate));
|
|
|
|
+ List<LeaveSheet> leaveSheets = leaveSheetList.stream().filter(ls -> ls.getOwnerId().equals(user.getId())
|
|
|
|
+ &&(endDate!=null &&startDate!=null)
|
|
|
|
+ &&((ls.getStartDate().isBefore(ChronoLocalDate.from(endDate))||ls.getStartDate().isEqual(ChronoLocalDate.from(endDate))))
|
|
|
|
+ &&((ls.getEndDate().isAfter(ChronoLocalDate.from(startDate))||ls.getEndDate().isEqual(ChronoLocalDate.from(startDate)))))
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+ long daysWithLeave =days;
|
|
|
|
+ if(leaveSheets.size()>0){
|
|
|
|
+ for (LeaveSheet leaveSheet : leaveSheets) {
|
|
|
|
+ AtomicReference<List<LocalDateTime>> leaveDateList = new AtomicReference<>(getDays(leaveSheet.getStartDate().atTime(LocalTime.MIN), leaveSheet.getEndDate().atTime(LocalTime.MIN)));
|
|
|
|
+ AtomicReference<List<LocalDateTime>> list = new AtomicReference<>(getDays(leaveSheet.getStartDate().atTime(LocalTime.MIN), leaveSheet.getEndDate().atTime(LocalTime.MIN)));
|
|
|
|
+ if(allUsersSetting.size()>0){
|
|
|
|
+ List<LocalDateTime> holidayDateList = allUsersSetting.stream().map(h->h.getHolidayDate().atTime(LocalTime.MIN)).collect(Collectors.toList());
|
|
|
|
+ leaveDateList.set(leaveDateList.get().stream().filter(d -> !holidayDateList.contains(d)).collect(Collectors.toList()));
|
|
|
|
+ list.set(list.get().stream().filter(d -> !holidayDateList.contains(d)).collect(Collectors.toList()));
|
|
|
|
+ }
|
|
|
|
+ if(targetUserOrDeptSetting.size()>0){
|
|
|
|
+ targetUserOrDeptSetting.forEach(t->{
|
|
|
|
+ LocalDateTime holidayDate = t.getHolidayDate().atTime(LocalTime.MIN);
|
|
|
|
+ if(!StringUtils.isEmpty(t.getTargetUsers())&&!t.getTargetUsers().equals("")){
|
|
|
|
+ String[] userSplit = t.getTargetUsers().split(",");
|
|
|
|
+ List<String> userAsList = Arrays.asList(userSplit);
|
|
|
|
+ if(userAsList.contains(user.getId())){
|
|
|
|
+ leaveDateList.set(leaveDateList.get().stream().filter(d -> !d.isEqual(holidayDate)).collect(Collectors.toList()));
|
|
|
|
+ list.set(list.get().stream().filter(d -> !d.isEqual(holidayDate)).collect(Collectors.toList()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if(!StringUtils.isEmpty(t.getTargetDepts())&&!t.getTargetDepts().equals("")){
|
|
|
|
+ String[] deptSplit = t.getTargetDepts().split(",");
|
|
|
|
+ List<String> deptAsList = Arrays.asList(deptSplit);
|
|
|
|
+ for (String deptId : deptAsList) {
|
|
|
|
+ List<Integer> subDeptIds = getBranchDepartment(Integer.valueOf(deptId), departmentList);
|
|
|
|
+ if(deptId.equals(user.getDepartmentId())||subDeptIds.contains(user.getDepartmentId())){
|
|
|
|
+ leaveDateList.set(leaveDateList.get().stream().filter(d -> !d.isEqual(holidayDate)).collect(Collectors.toList()));
|
|
|
|
+ list.set(list.get().stream().filter(d -> !d.isEqual(holidayDate)).collect(Collectors.toList()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ if(list.get().size()>1){
|
|
|
|
+ days-= list.get().size();
|
|
|
|
+ }else {
|
|
|
|
+ days-=1;
|
|
|
|
+ }
|
|
|
|
+ for (LocalDateTime localDateTime : leaveDateList.get()) {
|
|
|
|
+ //todo: 请假区间当中有非工作日在之前被当作 不需填报 所以要加上 保证基数正确
|
|
|
|
+ if(localDateTime!=null&&!WorkDayCalculateUtils.isWorkDay(localDateTime.toLocalDate())){
|
|
|
|
+ days+=1;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if((startDate!=null&&endDate!=null)&&localDateTime.isBefore(startDate.atStartOfDay())||localDateTime.isAfter(endDate.atStartOfDay().plusDays(1))){
|
|
|
|
+ days++;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if(mapList!=null&&mapList.stream().anyMatch(ml->{
|
|
|
|
+ Integer taskId=ml.get("taskId")!=null?Integer.parseInt(ml.get("taskId").toString()):null;
|
|
|
|
+ if (taskId == null || !taskId.equals(rateTaskVO.getTaskId())) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ Date date = (Date) ml.get("createDate");
|
|
|
|
+ LocalDate createDate = date != null ? date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate() : null;
|
|
|
|
+ return createDate.isEqual(localDateTime.toLocalDate());
|
|
|
|
+ })){
|
|
|
|
+ days++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int num=0;
|
|
|
|
+ if(mapList!=null){
|
|
|
|
+ for (Map<String, Object> map : mapList) {
|
|
|
|
+ if (map.get("createDate")!=null && map.get("createTime")!=null) {
|
|
|
|
+ Map<String, Object> objectMap = new HashMap<>();
|
|
|
|
+ Date date = (Date) map.get("createDate");
|
|
|
|
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
|
+ //去掉sql返回的毫秒值
|
|
|
|
+ java.sql.Date createTime = (java.sql.Date) map.get("createTime");
|
|
|
|
+ LocalDate createDate = date != null ? date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate() : null;
|
|
|
|
+ // 针对美莱德 去除2024-02-09
|
|
|
|
+ if (user.getCompanyId() == 876) {
|
|
|
|
+ if (createDate.isEqual(LocalDate.parse("2024-02-09"))) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ LocalDate createTimeDate = createTime.toLocalDate();
|
|
|
|
+ //根据设置
|
|
|
|
+ switch (timeliness) {
|
|
|
|
+ case 1:
|
|
|
|
+ createDate = createDate.plusDays(1);
|
|
|
|
+ while (createDate!=null&&!WorkDayCalculateUtils.isWorkDay(createDate)) {
|
|
|
|
+ createDate = createDate.plusDays(1);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ Integer a = 0;
|
|
|
|
+ while (a != 2) {
|
|
|
|
+ createDate = createDate.plusDays(1);
|
|
|
|
+ if (createDate!=null&&WorkDayCalculateUtils.isWorkDay(createDate)) {
|
|
|
|
+ a++;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (createTimeDate.isBefore(createDate) || createTimeDate.isEqual(createDate)) {
|
|
|
|
+ num++;
|
|
|
|
+ objectMap.put(simpleDateFormat.format(date), MessageUtils.message("entry.timely") + "/" + MessageUtils.message("entry.SubTime") + createTimeDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
|
|
|
+ } else {
|
|
|
|
+ objectMap.put(simpleDateFormat.format(date), MessageUtils.message("entry.NoTimely") + "/" + MessageUtils.message("entry.SubTime") + createTimeDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ //处理漏填的情况,漏填的也算不及时
|
|
|
|
+ boolean hasMissReport = false;
|
|
|
|
+ for (LocalDate localDateTime : listAtomicReference.get()) {
|
|
|
|
+ if(localDateTime!=null&&!WorkDayCalculateUtils.isWorkDay(localDateTime)){
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ hasMissReport = true;
|
|
|
|
+ }
|
|
|
|
+ BigDecimal bigDecimal=new BigDecimal(num);
|
|
|
|
+ BigDecimal bigDecimalWithLeave=new BigDecimal(num+(daysWithLeave-days));
|
|
|
|
+ BigDecimal divide;
|
|
|
|
+ BigDecimal divideWithLeave;
|
|
|
|
+ if(days!=0){
|
|
|
|
+ divide = bigDecimal.divide(BigDecimal.valueOf(days), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
|
+ }else if(days==0){
|
|
|
|
+ divide=new BigDecimal(1);
|
|
|
|
+ //查看当天有请假直接算100%
|
|
|
|
+ }else if (days==0&&num!=0&&leaveSheetList.size()>0){
|
|
|
|
+ divide=new BigDecimal(1);
|
|
|
|
+ }else{
|
|
|
|
+ divide=new BigDecimal(0);
|
|
|
|
+ }
|
|
|
|
+ if(divide.compareTo(new BigDecimal(1))==1){
|
|
|
|
+ divide=new BigDecimal(1);
|
|
|
|
+ log.error("填报及时率数据异常:==="+user.getName());
|
|
|
|
+ }
|
|
|
|
+ if(daysWithLeave!=0){
|
|
|
|
+ divideWithLeave = bigDecimalWithLeave.divide(BigDecimal.valueOf(daysWithLeave), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
|
+ }else if(daysWithLeave==0){
|
|
|
|
+ divideWithLeave=new BigDecimal(1);
|
|
|
|
+ //查看当天有请假直接算100%
|
|
|
|
+ }else if (daysWithLeave==0&&num!=0&&leaveSheetList.size()>0){
|
|
|
|
+ divideWithLeave=new BigDecimal(1);
|
|
|
|
+ }else{
|
|
|
|
+ divideWithLeave=new BigDecimal(0);
|
|
|
|
+ }
|
|
|
|
+ if(divideWithLeave.compareTo(new BigDecimal(1))==1){
|
|
|
|
+ divideWithLeave=new BigDecimal(1);
|
|
|
|
+ log.error("填报及时率数据异常:==="+user.getName());
|
|
|
|
+ }
|
|
|
|
+ String number = dft.format(divide);
|
|
|
|
+ String numberWithLeave = dft.format(divideWithLeave);
|
|
|
|
+ rateTaskVO.setTimelinessRate(String.valueOf(number));
|
|
|
|
+ rateTaskVO.setTimelinessRateWithLeave(String.valueOf(numberWithLeave));
|
|
|
|
+ }else {
|
|
|
|
+ BigDecimal bigDecimal=new BigDecimal(num);
|
|
|
|
+ BigDecimal bigDecimalWithLeave=new BigDecimal(num+(daysWithLeave-days));
|
|
|
|
+ BigDecimal divide;
|
|
|
|
+ BigDecimal divideWithLeave;
|
|
|
|
+ if(days!=0){
|
|
|
|
+ System.out.println("及时日=="+num+","+days);
|
|
|
|
+ divide = bigDecimal.divide(BigDecimal.valueOf(days), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
|
+ }else if(days==0){
|
|
|
|
+ divide=new BigDecimal(1);
|
|
|
|
+ //查看当天有请假直接算100%
|
|
|
|
+ }else if (days==0&&num!=0&&leaveSheetList.size()>0){
|
|
|
|
+ divide=new BigDecimal(1);
|
|
|
|
+ }else if(leaveSheets.size()>0){
|
|
|
|
+ divide=new BigDecimal(1);
|
|
|
|
+ }else{
|
|
|
|
+ divide=new BigDecimal(0);
|
|
|
|
+ }
|
|
|
|
+ if(divide.compareTo(new BigDecimal(1))==1){
|
|
|
|
+ divide=new BigDecimal(1);
|
|
|
|
+ log.error("填报及时率数据异常:==="+user.getName());
|
|
|
|
+ }
|
|
|
|
+ if(daysWithLeave!=0){
|
|
|
|
+ divideWithLeave = bigDecimalWithLeave.divide(BigDecimal.valueOf(daysWithLeave), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
|
+ }else if(daysWithLeave==0){
|
|
|
|
+ divideWithLeave=new BigDecimal(1);
|
|
|
|
+ //查看当天有请假直接算100%
|
|
|
|
+ }else if (daysWithLeave==0&&num!=0&&leaveSheetList.size()>0){
|
|
|
|
+ divideWithLeave=new BigDecimal(1);
|
|
|
|
+ }else if(leaveSheets.size()>0){
|
|
|
|
+ divideWithLeave=new BigDecimal(1);
|
|
|
|
+ }else{
|
|
|
|
+ divideWithLeave=new BigDecimal(0);
|
|
|
|
+ }
|
|
|
|
+ if(divideWithLeave.compareTo(new BigDecimal(1))==1){
|
|
|
|
+ divideWithLeave=new BigDecimal(1);
|
|
|
|
+ log.error("填报及时率数据异常:==="+user.getName());
|
|
|
|
+ }
|
|
|
|
+ String number = dft.format(divide);
|
|
|
|
+ String numberWithLeave = dft.format(divideWithLeave);
|
|
|
|
+ rateTaskVO.setTimelinessRate(String.valueOf(number));
|
|
|
|
+ rateTaskVO.setTimelinessRateWithLeave(String.valueOf(numberWithLeave));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (type==1) {
|
|
|
|
+ ArrayList<ReportRateTaskListVO> reportRateTaskListVOS = new ArrayList<>();
|
|
|
|
+ Map<String, List<ReportRateTaskVO>> groupedByTaskId = reportRateTaskVOList.stream()
|
|
|
|
+ .filter(task -> task.getUserId() != null) // 先过滤掉userId为null的记录
|
|
|
|
+ .collect(Collectors.groupingBy(ReportRateTaskVO::getUserId));
|
|
|
|
+ Set<Map.Entry<String, List<ReportRateTaskVO>>> entries = groupedByTaskId.entrySet();
|
|
|
|
+ for (Map.Entry<String, List<ReportRateTaskVO>> entry : entries) {
|
|
|
|
+ ReportRateTaskListVO taskListVO = new ReportRateTaskListVO();
|
|
|
|
+ List<ReportRateTaskVO> list = entry.getValue();
|
|
|
|
+ // 过滤并转换百分比字符串为数值
|
|
|
|
+ List<Double> rates = list.stream()
|
|
|
|
+ .filter(l -> l.getTimelinessRate() != null && !l.getTimelinessRate().isEmpty())
|
|
|
|
+ .map(l -> {
|
|
|
|
+ // 移除百分号并转换为double
|
|
|
|
+ String rateStr = l.getTimelinessRate().replace("%", "");
|
|
|
|
+ return Double.parseDouble(rateStr) / 100.0;
|
|
|
|
+ })
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+
|
|
|
|
+ // 计算平均值
|
|
|
|
+ double average = rates.isEmpty() ? 0.0 : rates.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
|
|
|
|
+
|
|
|
|
+ String averagePercentage = dft.format(average);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // 过滤并转换百分比字符串为数值
|
|
|
|
+ List<Double> ratesLeave = list.stream()
|
|
|
|
+ .filter(l -> l.getTimelinessRateWithLeave() != null && !l.getTimelinessRateWithLeave().isEmpty())
|
|
|
|
+ .map(l -> {
|
|
|
|
+ // 移除百分号并转换为double
|
|
|
|
+ String rateStr = l.getTimelinessRateWithLeave().replace("%", "");
|
|
|
|
+ return Double.parseDouble(rateStr) / 100.0;
|
|
|
|
+ })
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
+
|
|
|
|
+ // 计算平均值
|
|
|
|
+ double averageLeave = ratesLeave.isEmpty() ? 0.0 : ratesLeave.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
|
|
|
|
+ String averageLeavePercentage = dft.format(averageLeave);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ taskListVO.setList(list);
|
|
|
|
+ taskListVO.setUserName(list.get(0).getUserName());
|
|
|
|
+ taskListVO.setAveragePercentage(averagePercentage);
|
|
|
|
+ taskListVO.setAverageLeavePercentage(averageLeavePercentage);
|
|
|
|
+ reportRateTaskListVOS.add(taskListVO);
|
|
|
|
+ }
|
|
|
|
+ msg.setData(reportRateTaskListVOS);
|
|
|
|
+ }else {
|
|
|
|
+ ArrayList<ReportRateTaskListVO> reportRateTaskListVOS = new ArrayList<>();
|
|
|
|
+ Map<Integer, List<ReportRateTaskVO>> groupedByTaskId = reportRateTaskVOList.stream()
|
|
|
|
+ .filter(task -> task.getTaskId() != null) // 先过滤掉userId为null的记录
|
|
|
|
+ .collect(Collectors.groupingBy(ReportRateTaskVO::getTaskId));
|
|
|
|
+ Set<Map.Entry<Integer, List<ReportRateTaskVO>>> entries = groupedByTaskId.entrySet();
|
|
|
|
+ for (Map.Entry<Integer, List<ReportRateTaskVO>> entry : entries) {
|
|
|
|
+ ReportRateTaskListVO taskListVO = new ReportRateTaskListVO();
|
|
|
|
+ List<ReportRateTaskVO> list = entry.getValue();
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ taskListVO.setList(list);
|
|
|
|
+ taskListVO.setTaskName(list.get(0).getTaskName());
|
|
|
|
+ taskListVO.setProjectName(list.get(0).getProjectName());
|
|
|
|
+ taskListVO.setStartDate(list.get(0).getStartDate());
|
|
|
|
+ taskListVO.setEndDate(list.get(0).getEndDate());
|
|
|
|
+ reportRateTaskListVOS.add(taskListVO);
|
|
|
|
+ }
|
|
|
|
+ msg.setData(reportRateTaskListVOS);
|
|
|
|
+ }
|
|
|
|
+ return msg;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public HttpRespMsg exportReportRateOfTask(Integer projectId, String userIds, Integer companyId, Integer type) {
|
|
|
|
+ HttpRespMsg msg = new HttpRespMsg();
|
|
|
|
+ HttpRespMsg respMsg = getReportRateOfTask(projectId, userIds, companyId, type);
|
|
|
|
+ ArrayList<ReportRateTaskListVO> list = (ArrayList<ReportRateTaskListVO>) respMsg.getData();
|
|
|
|
+ String resp = ExcelUtil.exportGeneralExcelWithList(type, list, path);
|
|
|
|
+ msg.setData(resp);
|
|
|
|
+ return msg;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ private List<LocalDateTime> getDays(LocalDateTime start, LocalDateTime end) {
|
|
|
|
+ List<LocalDateTime> result = new ArrayList();
|
|
|
|
+ while (start.isBefore(end)) {
|
|
|
|
+ result.add(start);
|
|
|
|
+ start=start.plusDays(1);
|
|
|
|
+ }
|
|
|
|
+ result.add(start);
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
@Override
|
|
@Override
|
|
public List<Map<String, Object>> getReportTimeLessThanCardTimeList(LocalDate firstDay, LocalDate lastDay, Integer deptId, String userId, Integer companyId, boolean getAll) {
|
|
public List<Map<String, Object>> getReportTimeLessThanCardTimeList(LocalDate firstDay, LocalDate lastDay, Integer deptId, String userId, Integer companyId, boolean getAll) {
|
|
//获取自己的考勤未填满的记录
|
|
//获取自己的考勤未填满的记录
|