package com.yuanchu.mom.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yuanchu.mom.common.GetLook; import com.yuanchu.mom.dto.CostStatisticsDto; import com.yuanchu.mom.dto.InsOrderUserDto; import com.yuanchu.mom.mapper.*; import com.yuanchu.mom.pojo.*; import com.yuanchu.mom.service.ReportService; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; @Service @AllArgsConstructor public class ReportServiceImpl implements ReportService { private InsOrderMapper insOrderMapper; private InsSampleMapper insSampleMapper; private InsProductUserMapper insProductUserMapper; private InsProductMapper insProductMapper; private GetLook getLook; private ScheduleMapper scheduleMapper; private UserMapper userMapper; private RoleMapper roleMapper; private InsSampleUserMapper insSampleUserMapper; private AuxiliaryOutputWorkingHoursMapper auxiliaryOutputWorkingHoursMapper; private InsOrderStateMapper insOrderStateMapper; private InsOrderUserMapper insOrderUserMapper; //每日业务统计 @Override public Map businessStatisticsByDay(String startTime, String endTime, String type) { DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime start = LocalDate.parse(startTime, format).atStartOfDay(); LocalDateTime end = LocalDate.parse(endTime, format).atTime(23, 59, 59); LocalDateTime oldStart = start; LocalDateTime oldEnd = end; switch (type) { case "周": oldStart = start.minusDays(7); oldEnd = end.minusDays(7); break; case "月": oldStart = start.minusMonths(1); oldEnd = end.minusMonths(1); break; case "年": oldStart = start.minusYears(1); oldEnd = end.minusYears(1); break; } Map map = new HashMap<>(); /*任务接收*/ //今日任务接收 Long receive = insOrderMapper.selectCount(Wrappers.lambdaQuery() .eq(InsOrder::getState, 1) .between(InsOrder::getCreateTime, start, end)); map.put("RECEIVE", receive); //昨日任务接收 Long received = insOrderMapper.selectCount(Wrappers.lambdaQuery() .eq(InsOrder::getState, 1) .between(InsOrder::getCreateTime, oldStart, oldEnd)); //比例=(今天-昨天)/昨天 BigDecimal ratio = new BigDecimal(receive - received).divide(new BigDecimal(received == 0 ? 1 : received), 2, BigDecimal.ROUND_HALF_UP); map.put("RECEIVE_RATIO", ratio); /*任务已完成*/ //今日任务完成 Long finishe = insOrderMapper.selectCount(Wrappers.lambdaQuery() .eq(InsOrder::getState, 4) .between(InsOrder::getCreateTime, start, end)); map.put("FINISHE", finishe); //昨日任务完成 Long finished = insOrderMapper.selectCount(Wrappers.lambdaQuery() .eq(InsOrder::getState, 4) .between(InsOrder::getCreateTime, oldStart, oldEnd)); //任务完成比例=(今天-昨天)/昨天 BigDecimal finishedRatio = new BigDecimal(finishe - finished).divide(new BigDecimal(finished == 0 ? 1 : finished), 2, BigDecimal.ROUND_HALF_UP); map.put("FINISHE_RATIO", finishedRatio); /*任务剩余*/ //今日任务剩余 long surplus = receive - finishe; map.put("SURPLUS", surplus); //昨日任务剩余 long surplused = received - finished; //剩余比例=(今天-昨天)/昨天 BigDecimal surplusRatio = new BigDecimal(surplus - surplused).divide(new BigDecimal(surplused == 0 ? 1 : surplused), 2, BigDecimal.ROUND_HALF_UP); map.put("SURPLUS_RATIO", surplusRatio); /*检测费用*/ //今日检测费用 QueryWrapper costStatisticsDtoQueryWrappers = new QueryWrapper<>(); costStatisticsDtoQueryWrappers.between("create_time", start, end); IPage page = new Page<>(); page.setSize(-1); page.setCurrent(-1); IPage iPage = insOrderMapper.selectCostStatistics(page, costStatisticsDtoQueryWrappers); BigDecimal price = BigDecimal.ZERO; for (CostStatisticsDto record : iPage.getRecords()) { price = price.add(ObjectUtils.isNotEmpty(record.getPrice()) ? record.getPrice() : BigDecimal.ZERO); } map.put("PRICE", price); //昨日检测费用 QueryWrapper costWrappers = new QueryWrapper<>(); costWrappers.between("create_time", oldStart, oldEnd); IPage dtoIPage = insOrderMapper.selectCostStatistics(page, costWrappers); BigDecimal priced = BigDecimal.ZERO; for (CostStatisticsDto record : dtoIPage.getRecords()) { priced = priced.add(ObjectUtils.isNotEmpty(record.getPrice()) ? record.getPrice() : BigDecimal.ZERO); } //比例=(今日-昨日)/昨日 BigDecimal priceRatio = (price.subtract(priced)).divide(priced.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ONE : priced, 2, BigDecimal.ROUND_HALF_UP); map.put("PRICE_RATIO", priceRatio); /*检测工时*/ //今日检测工时 Double cost = 0.0; for (CostStatisticsDto record : iPage.getRecords()) { cost += ObjectUtils.isNotEmpty(record.getCost()) ? record.getCost() : 0.0; } map.put("COST", cost); //昨日检测工时 Double costed = 0.0; for (CostStatisticsDto record : dtoIPage.getRecords()) { costed += ObjectUtils.isNotEmpty(record.getCost()) ? record.getCost() : 0.0; } //比例=(今日-昨日)/昨日 BigDecimal costRatio = new BigDecimal(cost - costed).divide(new BigDecimal(costed == 0 ? 1 : costed), 2, BigDecimal.ROUND_HALF_UP); map.put("COST_RATIO", costRatio); /*检测人员*/ //今日检测人员 List insProductUsers = insProductUserMapper.selectList(Wrappers.lambdaQuery() .between(InsProductUser::getCreateTime, start, end)); long person = insProductUsers.stream().map(InsProductUser::getCreateUser).distinct().count(); map.put("PERSON", person); //昨日检测人员 List insProductUserss = insProductUserMapper.selectList(Wrappers.lambdaQuery() .between(InsProductUser::getCreateTime, oldStart, oldEnd)); long persons = insProductUserss.stream().map(InsProductUser::getCreateUser).distinct().count(); //比例=(今天-昨天)/昨天 BigDecimal personRatio = new BigDecimal(person - persons).divide(new BigDecimal(persons == 0 ? 1 : persons), 2, BigDecimal.ROUND_HALF_UP); map.put("PERSON_RATIO", personRatio); /*近十日任务接收量与完成量*/ //获取近十日的横坐标 LocalDate startDate = LocalDate.parse(startTime, format); LocalDate endDate = LocalDate.parse(endTime, format); List lastTenDays = new ArrayList<>(); List receTenDays = new ArrayList<>(); List finTenDays = new ArrayList<>(); while (!startDate.isAfter(endDate)) { if (type.equals("年")) { lastTenDays.add(startDate.format(format).substring(0, 7)); } else { lastTenDays.add(startDate.format(format)); } receTenDays.add(insOrderMapper.selectCount(Wrappers.lambdaQuery() .eq(InsOrder::getState, 1) .between(InsOrder::getCreateTime, startDate.atStartOfDay(), startDate.plusMonths(1).minusDays(1).atTime(23, 59, 59)))); finTenDays.add(insOrderMapper.selectCount(Wrappers.lambdaQuery() .eq(InsOrder::getState, 4) .between(InsOrder::getCreateTime, startDate.atStartOfDay(), startDate.plusMonths(1).minusDays(1).atTime(23, 59, 59)))); if (type.equals("年")) { startDate = startDate.plusMonths(1); } else { startDate = startDate.plusDays(1); } } map.put("DAYS", lastTenDays); map.put("RECETENDAYS", receTenDays); map.put("FINISHTENDAYS", finTenDays); return map; } //检测项目统计 @Override public Map testProductByDay(String startTime, String endTime, String type) { DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime start = LocalDate.parse(startTime, format).atStartOfDay(); LocalDateTime end = LocalDate.parse(endTime, format).atTime(23, 59, 59); LocalDateTime oldStart = start; LocalDateTime oldEnd = end; Map map = new HashMap<>(); switch (type) { case "周": oldStart = start.minusDays(7); oldEnd = end.minusDays(7); break; case "月": oldStart = start.minusMonths(1); oldEnd = end.minusMonths(1); break; case "年": oldStart = start.minusYears(1); oldEnd = end.minusYears(1); break; } /*项目接收*/ //今日项目接收量 Long receive = insProductMapper.selectCount(Wrappers.lambdaQuery() .eq(InsProduct::getState, 1) .between(InsProduct::getCreateTime, start, end)); map.put("RECEVICE", receive); //昨日项目接收量 Long received = insProductMapper.selectCount(Wrappers.lambdaQuery() .eq(InsProduct::getState, 1) .between(InsProduct::getCreateTime, oldStart, oldEnd)); //比例=(今天-昨天)/昨天 BigDecimal ratio = new BigDecimal(receive - received).divide(new BigDecimal(received == 0 ? 1 : received), 2, BigDecimal.ROUND_HALF_UP); map.put("RECEIVE_RATIO", ratio); /*项目完成*/ //今日项目完成量 Long finishe = insProductMapper.selectCount(Wrappers.lambdaQuery() .eq(InsProduct::getState, 1) .isNotNull(InsProduct::getInsResult) .between(InsProduct::getCreateTime, start, end)); map.put("FINISHE", finishe); //昨日项目完成量 Long finished = insProductMapper.selectCount(Wrappers.lambdaQuery() .eq(InsProduct::getState, 1) .isNotNull(InsProduct::getInsResult) .between(InsProduct::getCreateTime, oldStart, oldEnd)); //任务完成比例=(今天-昨天)/昨天 BigDecimal finishedRatio = new BigDecimal(finishe - finished).divide(new BigDecimal(finished == 0 ? 1 : finished), 2, BigDecimal.ROUND_HALF_UP); map.put("FINISHE_RATIO", finishedRatio); /*项目剩余*/ //今日项目剩余量 long surplus = receive - finishe; map.put("SURPLUS", surplus); //昨日项目剩余 long surplused = received - finished; //剩余比例=(今天-昨天)/昨天 BigDecimal surplusRatio = new BigDecimal(surplus - surplused).divide(new BigDecimal(surplused == 0 ? 1 : surplused), 2, BigDecimal.ROUND_HALF_UP); map.put("SURPLUS_RATIO", surplusRatio); /*今日项目合格率*/ //今日完成量中的合格量/今日完成量 Long accept = insProductMapper.selectCount(Wrappers.lambdaQuery() .eq(InsProduct::getState, 1) .isNotNull(InsProduct::getInsResult) .ne(InsProduct::getInsResult, 0) .between(InsProduct::getCreateTime, start, end)); map.put("ACCEPT", accept); BigDecimal acceptRate = new BigDecimal(accept).divide(new BigDecimal(finishe == 0 ? 1 : finishe), 2, BigDecimal.ROUND_HALF_UP); map.put("ACCEPT_RATE_TODAY", acceptRate); /*今日项目完成率*/ //今日完成量/今日接收量 BigDecimal finishRate = new BigDecimal(finishe).divide(new BigDecimal(receive == 0 ? 1 : receive), 2, BigDecimal.ROUND_HALF_UP); map.put("FINISH_RATE_TODAY", finishRate); /*今日项目延期率*/ //今日项目剩余/今日项目接收量 BigDecimal delayRate = new BigDecimal(surplus).divide(new BigDecimal(received == 0 ? 1 : received), 2, BigDecimal.ROUND_HALF_UP); map.put("DELAY_RATE_TODAY", delayRate); /*近十日的项目接收量与完成量*/ //获取近十日的横坐标 LocalDate startDate = LocalDate.parse(startTime, format); LocalDate endDate = LocalDate.parse(endTime, format); List lastTenDays = new ArrayList<>(); List receTenDays = new ArrayList<>(); List finTenDays = new ArrayList<>(); while (!startDate.isAfter(endDate)) { if (type.equals("年")) { lastTenDays.add(startDate.format(format).substring(0, 7)); } else { lastTenDays.add(startDate.format(format)); } receTenDays.add(insProductMapper.selectCount(Wrappers.lambdaQuery() .eq(InsProduct::getState, 1) .between(InsProduct::getCreateTime, startDate.atStartOfDay(), startDate.plusMonths(1).minusDays(1).atTime(23, 59, 59)))); finTenDays.add(insProductMapper.selectCount(Wrappers.lambdaQuery() .eq(InsProduct::getState, 1) .isNotNull(InsProduct::getInsResult) .between(InsProduct::getCreateTime, startDate.atStartOfDay(), startDate.plusMonths(1).minusDays(1).atTime(23, 59, 59)))); if (type.equals("年")) { startDate = startDate.plusMonths(1); } else { startDate = startDate.plusDays(1); } } map.put("DAYS", lastTenDays); map.put("RECETENDAYS", receTenDays); map.put("FINISHTENDAYS", finTenDays); return map; } //首页-->日历任务图 @Override public Map calendarWorkByWeek() { Integer userId = getLook.selectPowerByMethodAndUserId(null).get("userId"); String name = roleMapper.selectById(userMapper.selectById(userId).getRoleId()).getName(); Map map = new HashMap<>(); List insState = new ArrayList<>(); insState.add(0); insState.add(1); /*获取后一周日期*/ LocalDate currentDate = LocalDate.now(); List weekDays = new ArrayList<>(); for (int i = 6, j = 0; i >= 0; i--, j++) { weekDays.add(currentDate.minusDays(i)); //查询当天需要检测的委托订单 List insOrders = insOrderMapper.selectList(Wrappers.lambdaQuery() .eq(InsOrder::getState, 1) .in(InsOrder::getInsState, insState) .apply("DATE(create_time) = CURDATE() - INTERVAL " + j + " DAY")); //如果当前登录人是测试工程师或者是检测组长,需要过滤出检验人是他们的订单或者是还没检验的订单 if (name.equals("测试工程师") || name.equals("检测组长")) { insOrders = insOrders.stream().filter(insOrder -> { List insSamples = insSampleMapper.selectList(Wrappers.lambdaQuery().eq(InsSample::getInsOrderId, insOrder.getId())); List sampleId = insSamples.stream().map(InsSample::getId).collect(Collectors.toList()); List insSampleUsers = insSampleUserMapper.selectList(Wrappers.lambdaQuery() .in(InsSampleUser::getInsSampleId, sampleId) .eq(InsSampleUser::getState, 0) //检验人 ); return insSampleUsers.size() == 0 || insSampleUsers.stream().map(InsSampleUser::getUserId).collect(Collectors.toList()).contains(userId); }).collect(Collectors.toList()); } //如果当前登录人是送样员,需过滤出单子的送样员是当前人的订单 else if (name.equals("送样员")) { insOrders = insOrders.stream().filter(insOrder -> ObjectUtils.isNotEmpty(insOrder.getIssueUser()) && insOrder.getIssueUser().equals(userId) ).collect(Collectors.toList()); } List> works = insOrders.stream().map(insOrder -> { List insSamples = insSampleMapper.selectList(Wrappers.lambdaQuery().eq(InsSample::getInsOrderId, insOrder.getId())); HashMap hashMap = new HashMap<>(); hashMap.put("text", insOrder.getEntrustCode()); hashMap.put("sample", insSamples.stream().map(InsSample::getSample).collect(Collectors.joining(","))); hashMap.put("type", insOrder.getType()); hashMap.put("state", insOrder.getState()); User user = userMapper.selectById(insOrder.getCreateUser()); hashMap.put("name", user.getName()); return hashMap; }).collect(Collectors.toList()); map.put("work" + i, works); } map.put("weekDays", weekDays); return map; } //首页-->添加日程 @Override public int addSchedule(String time, String text) { //获取当前用户id Integer userId = getLook.selectPowerByMethodAndUserId(null).get("userId"); Schedule schedule = new Schedule(); schedule.setUserId(userId); schedule.setScheduleTime(LocalDateTime.parse(time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); schedule.setText(text); return scheduleMapper.insert(schedule); } //首页-->我的日程 @Override public List ScheduleByMe(String date) { //获取当前用户id Integer userId = getLook.selectPowerByMethodAndUserId(null).get("userId"); LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd")); LocalDateTime startTime = localDate.atStartOfDay(); LocalDateTime endTime = localDate.plusDays(1).atStartOfDay().minusSeconds(1); return scheduleMapper.selectList(Wrappers.lambdaQuery().eq(Schedule::getUserId, userId).between(Schedule::getScheduleTime, startTime, endTime)); } //首页-->各站点的工时 @Override public String manHourByStation(String startTime, String endTime, String sonLaboratory) { DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime start = LocalDate.parse(startTime, format).atStartOfDay(); LocalDateTime end = LocalDate.parse(endTime, format).atTime(23, 59, 59); //查询这个时间内所有的工时 List auxiliaryOutputWorkingHours = auxiliaryOutputWorkingHoursMapper.selectList(Wrappers.lambdaQuery() .between(AuxiliaryOutputWorkingHours::getCreateTime, start, end)); double sum = auxiliaryOutputWorkingHours.stream() .filter(auxiliaryOutputWorkingHours1 -> insProductMapper.selectById(auxiliaryOutputWorkingHours1.getInsProductId()).getSonLaboratory().equals(sonLaboratory) ).mapToDouble(AuxiliaryOutputWorkingHours::getOutputWorkTime).sum(); String num = String.format("%.2f", sum); return num; } //首页-->各站点工时每个人所占百分比 @Override public Map manHourByPerson(String startTime, String endTime, String sonLaboratory) { DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime start = LocalDate.parse(startTime, format).atStartOfDay(); LocalDateTime end = LocalDate.parse(endTime, format).atTime(23, 59, 59); //查询这个时间内所有的工时 List auxiliaryOutputWorkingHours = auxiliaryOutputWorkingHoursMapper.selectList(Wrappers.lambdaQuery() .between(AuxiliaryOutputWorkingHours::getCreateTime, start, end)); //根据检验项查出来的站点进行分类 List outputWorkingHours = auxiliaryOutputWorkingHours.stream() .filter(auxiliaryOutputWorkingHours1 -> insProductMapper.selectById(auxiliaryOutputWorkingHours1.getInsProductId()).getSonLaboratory().equals(sonLaboratory) ).collect(Collectors.toList()); Map mapMap = outputWorkingHours.stream() .collect(Collectors.groupingBy( t -> userMapper.selectById(t.getCheck()).getName(), Collectors.summingDouble(AuxiliaryOutputWorkingHours::getOutputWorkTime))); return mapMap; } @Override public Map> timeByStation(String startTime, String endTime, Page page, String sonLaboratory) { DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDateTime start = LocalDate.parse(startTime, format).atStartOfDay(); LocalDateTime end = LocalDate.parse(endTime, format).atTime(23, 59, 59); Map> map = new HashMap<>(); //查询这个时间内所有检验任务 if (ObjectUtils.isNotEmpty(sonLaboratory)) { IPage insOrderUserDtoIPage = insOrderUserMapper.selectInsOrderUserDto(start, end, sonLaboratory, page); map.put(sonLaboratory, insOrderUserDtoIPage); }else { List insOrderStates = insOrderStateMapper.selectList(Wrappers.lambdaQuery() .between(InsOrderState::getCreateTime, start, end)); Map> listMap = insOrderStates.stream().collect(Collectors.groupingBy(InsOrderState::getLaboratory)); for (Map.Entry> entry : listMap.entrySet()) { List ids = entry.getValue().stream().map(InsOrderState::getId).collect(Collectors.toList()); IPage insOrderUserDtoIPage = insOrderUserMapper.selectInsOrderUserDto2(ids, new Page(1,9)); map.put(entry.getKey(), insOrderUserDtoIPage); } } return map; } }