|
@@ -0,0 +1,214 @@
|
|
|
+package com.qmth.sop.business.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.qmth.sop.business.entity.TBService;
|
|
|
+import com.qmth.sop.business.entity.TBSopInfo;
|
|
|
+import com.qmth.sop.business.mapper.SopAnalyseMapper;
|
|
|
+import com.qmth.sop.business.service.SopAnalyseService;
|
|
|
+import com.qmth.sop.common.enums.SopAnalyseGroupEnum;
|
|
|
+import com.qmth.sop.common.enums.SopAnalyseSortEnum;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class SopAnalyseServiceImpl extends ServiceImpl<SopAnalyseMapper, TBSopInfo> implements SopAnalyseService {
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<TBService> list(String year) {
|
|
|
+ return this.baseMapper.list(year);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * * ①可按照大区/人力供应商进行切换如图;
|
|
|
+ * * ②按照派单数TOP3的大区、人力供应商显示;
|
|
|
+ * * ③完成进度:该大区/供应商派单的完成进度,按照派单已有完成SOP,且没有在执行的SOP认为是已完成的派单;
|
|
|
+ * * ④平均处理时限:该大区/供应商预警处理的平均时限。按照预警产生到关闭的时长的均值,≥1小时,按小时显示;<小时,按分钟显示;
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<Map<String, Object>> overview(Long serviceId, SopAnalyseGroupEnum group) {
|
|
|
+ List<Map<String, Object>> list = this.baseMapper.overview(serviceId);
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ if (group.equals(SopAnalyseGroupEnum.REGION)) {
|
|
|
+ list.stream().collect(Collectors.groupingBy(map -> map.get("province"))).forEach((k, v) -> {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("province", k);
|
|
|
+ processOverviewData(v, map);
|
|
|
+ result.add(map);
|
|
|
+ });
|
|
|
+ } else if (group.equals(SopAnalyseGroupEnum.SUPPLIER)) {
|
|
|
+ list.stream().collect(Collectors.groupingBy(map -> map.get("supplier"))).forEach((k, v) -> {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("supplier", k);
|
|
|
+ processOverviewData(v, map);
|
|
|
+ result.add(map);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return result.stream().sorted(Comparator.comparingInt(o -> Integer.parseInt(o.get("crmNum").toString()))).limit(3).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void processOverviewData(List<Map<String, Object>> v, Map<String, Object> map) {
|
|
|
+ //派单数
|
|
|
+ map.put("crmNum", v.stream().collect(Collectors.groupingBy(map1 -> map1.get("crm_no"))).size());
|
|
|
+ //已完成派单数
|
|
|
+ map.put("finishCrmNum", v.stream().collect(Collectors.groupingBy(map1 -> map1.get("crm_no"))).values().stream().filter(list1 -> list1.stream().allMatch(map1 -> "FINISH".equals(map1.get("sopStatus"))) || list1.stream().allMatch(map1 -> "FINISH".equals(map1.get("status")))).count());
|
|
|
+ //违规数
|
|
|
+ map.put("violationNum", v.stream().filter(map1 -> map1.get("did") != null).collect(Collectors.groupingBy(map1 -> map1.get("did"))).size());
|
|
|
+ //已关闭违规数
|
|
|
+ map.put("finishViolationNum", v.stream().filter(map1 -> map1.get("did") != null && "CLOSE".equals(map1.get("dstatus"))).count());
|
|
|
+ //延期数
|
|
|
+ map.put("delayNum", v.stream().filter(map1 -> map1.get("vid") != null).collect(Collectors.groupingBy(map1 -> map1.get("vid"))).size());
|
|
|
+ //已关闭延期数
|
|
|
+ map.put("finishDelayNum", v.stream().filter(map1 -> map1.get("vid") != null && "CLOSE".equals(map1.get("vstatus"))).count());
|
|
|
+ Double processViolationTime = v.stream().filter(map1 -> map1.get("ddiff") != null).mapToDouble(map1 -> Double.parseDouble(map1.get("ddiff").toString())).sum();
|
|
|
+ Double processDelayTime = v.stream().filter(map1 -> map1.get("vdiff") != null).mapToDouble(map1 -> Double.parseDouble(map1.get("vdiff").toString())).sum();
|
|
|
+ //平均处理时限分钟
|
|
|
+ int total = (Integer.parseInt(map.get("finishViolationNum").toString()) + Integer.parseInt(map.get("finishDelayNum").toString()));
|
|
|
+ map.put("avgMinutes", total == 0 ? 0 : (processViolationTime + processDelayTime) / total);
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 4.项目/供应商/大区预警待处理TOP10:
|
|
|
+ * ①待处理(待处理预警):按派单统计待处理的预警数(违规+延期);
|
|
|
+ * ②处理最慢(已处理完毕的预警):
|
|
|
+ * A.平均时限:按照预警产生到关闭的时长的均值,≥1小时,按小时显示;<小时,按分钟显示;
|
|
|
+ * 若预警为关闭后重启,则需要重新从预警产生到最后一次关闭的时长进行计算;
|
|
|
+ * B.排序:按平均时限的倒序排列;
|
|
|
+ * ③处理最快(已处理完毕的预警):
|
|
|
+ * A.平均时限:同上;
|
|
|
+ * B.排序:按平均时限的顺序排列。
|
|
|
+ * ④(预警数)均值:由于供应商分配的项目数量不同,所以单从总数无法判定供应商对预警处理的力度。均值=预警总数/派单数;
|
|
|
+ * ⑤【数据下钻】不提供。
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<Map<String, Object>> processing(Long serviceId, SopAnalyseGroupEnum group, SopAnalyseSortEnum sort) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ List<Map<String, Object>> list = this.baseMapper.overview(serviceId);
|
|
|
+ if (group.equals(SopAnalyseGroupEnum.CRM)) {
|
|
|
+ list.stream().collect(Collectors.groupingBy(map -> map.get("name"))).forEach((k, v) -> {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("crmName", k);
|
|
|
+ //大区
|
|
|
+ map.put("province", v.get(0).get("province"));
|
|
|
+ processing(v, map);
|
|
|
+ result.add(map);
|
|
|
+ });
|
|
|
+ } else if (group.equals(SopAnalyseGroupEnum.REGION)) {
|
|
|
+ list.stream().collect(Collectors.groupingBy(map -> map.get("province"))).forEach((k, v) -> {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("province", k);
|
|
|
+ processing(v, map);
|
|
|
+ result.add(map);
|
|
|
+ });
|
|
|
+ } else if (group.equals(SopAnalyseGroupEnum.SUPPLIER)) {
|
|
|
+ list.stream().collect(Collectors.groupingBy(map -> map.get("supplier"))).forEach((k, v) -> {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("supplier", k);
|
|
|
+ //大区
|
|
|
+ map.put("province", v.get(0).get("province"));
|
|
|
+ processing(v, map);
|
|
|
+ result.add(map);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sort.equals(SopAnalyseSortEnum.PENDING)) {
|
|
|
+ return result.stream().sorted(Comparator.comparingInt(o -> -Integer.parseInt(o.get("pendingProcessing").toString()))).limit(10).collect(Collectors.toList());
|
|
|
+ } else if (sort.equals(SopAnalyseSortEnum.SLOWEST)) {
|
|
|
+ return result.stream().sorted(Comparator.comparingDouble(o -> -Double.parseDouble(o.get("avgMinutes").toString()))).limit(10).collect(Collectors.toList());
|
|
|
+ } else if (sort.equals(SopAnalyseSortEnum.FASTEST)) {
|
|
|
+ return result.stream().sorted(Comparator.comparingDouble(o -> Double.parseDouble(o.get("avgMinutes").toString()))).limit(10).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void processing(List<Map<String, Object>> v, Map<String, Object> map) {
|
|
|
+ //区域协调人
|
|
|
+ map.put("real_name", v.get(0).get("real_name"));
|
|
|
+ //违规数
|
|
|
+ Integer violationNum = v.stream().filter(map1 -> map1.get("did") != null).collect(Collectors.groupingBy(map1 -> map1.get("did"))).size();
|
|
|
+ //已关闭违规数
|
|
|
+ Long finishViolationNum = v.stream().filter(map1 -> map1.get("did") != null && "CLOSE".equals(map1.get("dstatus"))).count();
|
|
|
+ //延期数
|
|
|
+ Integer delayNum = v.stream().filter(map1 -> map1.get("vid") != null).collect(Collectors.groupingBy(map1 -> map1.get("vid"))).size();
|
|
|
+ //已关闭延期数
|
|
|
+ Long finishDelayNum = v.stream().filter(map1 -> map1.get("vid") != null && "CLOSE".equals(map1.get("vstatus"))).count();
|
|
|
+ Double processViolationTime = v.stream().filter(map1 -> map1.get("ddiff") != null).mapToDouble(map1 -> Double.parseDouble(map1.get("ddiff").toString())).sum();
|
|
|
+ Double processDelayTime = v.stream().filter(map1 -> map1.get("vdiff") != null).mapToDouble(map1 -> Double.parseDouble(map1.get("vdiff").toString())).sum();
|
|
|
+ //平均处理时限分钟
|
|
|
+ long total = finishViolationNum + finishDelayNum;
|
|
|
+ map.put("avgMinutes", total == 0 ? 0 : (processViolationTime + processDelayTime) / total);
|
|
|
+ //待处理总数数
|
|
|
+ map.put("pendingProcessing", violationNum + delayNum - total);
|
|
|
+ //预警均值
|
|
|
+ map.put("avgWarn", (violationNum + delayNum) / v.stream().collect(Collectors.groupingBy(map1 -> map1.get("crm_no"))).size());
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * 5.供应商预警均值走势:
|
|
|
+ * 供应商近一周预警数的均值走势。
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Map<Object, Map<Object, List<Map<String, Object>>>> trend(Long serviceId) {
|
|
|
+ List<Map<String, Object>> list = this.baseMapper.trend(serviceId);
|
|
|
+ Map<Object, List<Map<String, Object>>> collect1 = list.stream().collect(Collectors.groupingBy(map -> map.get("click_date")));
|
|
|
+ Map<Object, Map<Object, List<Map<String, Object>>>> collect = new HashMap<>();
|
|
|
+ collect1.forEach((k, v) -> collect.put(k,v.stream().filter(map -> map.get("supplier") != null).collect(Collectors.groupingBy(map1 -> map1.get("supplier")))));
|
|
|
+ return collect;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ 6.项目/大区/供应商考勤异常TOP:
|
|
|
+ ①(异常)均值=异常总数/派单数;
|
|
|
+ ②【数据下钻】不提供;
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<Map<String, Object>> attendance(Long serviceId, SopAnalyseGroupEnum group) {
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
+ List<Map<String, Object>> attendance = this.baseMapper.attendance(serviceId);
|
|
|
+ if (group.equals(SopAnalyseGroupEnum.CRM)) {
|
|
|
+ attendance.stream().collect(Collectors.groupingBy(map -> map.get("name"))).forEach((k, v) -> {
|
|
|
+
|
|
|
+ v.stream().filter(map -> map.get("dname")!=null).collect(Collectors.groupingBy(map -> map.get("dname"))).forEach((x,y)->{
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("crmName", k);
|
|
|
+ map.put("dname", x);
|
|
|
+ map.put("real_name", v.get(0).get("real_name"));
|
|
|
+ map.put("total", y.stream().filter(map1 -> map1.get("id") != null).count());
|
|
|
+ result.add(map);
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ } else if (group.equals(SopAnalyseGroupEnum.REGION)) {
|
|
|
+ attendance.stream().collect(Collectors.groupingBy(map -> map.get("province"))).forEach((k, v) -> {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("supplier", k);
|
|
|
+ map.put("real_name", v.get(0).get("real_name"));
|
|
|
+ long total = v.stream().filter(map1 -> map1.get("id") != null).count();
|
|
|
+ map.put("total", total);
|
|
|
+ map.put("avg", Double.parseDouble(total+"")/v.stream().collect(Collectors.groupingBy(map1 -> map1.get("crm_no"))).size());
|
|
|
+ result.add(map);
|
|
|
+ });
|
|
|
+
|
|
|
+ } else if (group.equals(SopAnalyseGroupEnum.SUPPLIER)) {
|
|
|
+ attendance.stream().collect(Collectors.groupingBy(map -> map.get("supplier"))).forEach((k, v) -> {
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("supplier", k);
|
|
|
+ long total = v.stream().filter(map1 -> map1.get("id") != null).count();
|
|
|
+ map.put("total",total);
|
|
|
+ map.put("avg", Double.parseDouble(total+"")/v.stream().collect(Collectors.groupingBy(map1 -> map1.get("crm_no"))).size());
|
|
|
+ result.add(map);
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ return result.stream().sorted(Comparator.comparingInt(o -> -Integer.parseInt(o.get("total").toString()))).limit(10).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+}
|