|
@@ -0,0 +1,322 @@
|
|
|
+package com.qmth.sop.business.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.excel.EasyExcel;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.qmth.sop.business.bean.dto.UserArchivesAllocationDto;
|
|
|
+import com.qmth.sop.business.bean.result.*;
|
|
|
+import com.qmth.sop.business.entity.TBCrm;
|
|
|
+import com.qmth.sop.business.entity.TBService;
|
|
|
+import com.qmth.sop.business.entity.TBSopInfo;
|
|
|
+import com.qmth.sop.business.mapper.ServiceUnitAnalyseMapper;
|
|
|
+import com.qmth.sop.business.service.ServiceUnitAnalyseService;
|
|
|
+import com.qmth.sop.business.service.TBCrmService;
|
|
|
+import com.qmth.sop.business.service.TBSopInfoService;
|
|
|
+import com.qmth.sop.business.service.TBUserArchivesAllocationService;
|
|
|
+import com.qmth.sop.common.contant.SystemConstant;
|
|
|
+import com.qmth.sop.common.enums.*;
|
|
|
+import com.qmth.sop.common.util.FileUtil;
|
|
|
+import com.qmth.sop.common.util.ServletUtil;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.math.BigDecimal;
|
|
|
+import java.math.RoundingMode;
|
|
|
+import java.text.NumberFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class ServiceUnitAnalyseServiceImpl extends ServiceImpl<ServiceUnitAnalyseMapper, TBService> implements ServiceUnitAnalyseService {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TBCrmService tbCrmService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TBSopInfoService tbSopInfoService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private TBUserArchivesAllocationService tbUserArchivesAllocationService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ServiceUnitOverviewResult overview(Long serviceUnitId) {
|
|
|
+ ServiceUnitOverviewResult result = new ServiceUnitOverviewResult();
|
|
|
+ //派单数量
|
|
|
+ LambdaQueryWrapper<TBCrm> crmWrapper = new LambdaQueryWrapper<>();
|
|
|
+ crmWrapper.eq(TBCrm::getServiceId, serviceUnitId);
|
|
|
+ int crmNum = tbCrmService.count(crmWrapper);
|
|
|
+ result.setCrmNum(crmNum);
|
|
|
+
|
|
|
+ //sop数量
|
|
|
+ LambdaQueryWrapper<TBSopInfo> sopWrapper = new LambdaQueryWrapper<>();
|
|
|
+ sopWrapper.eq(TBSopInfo::getServiceId, serviceUnitId);
|
|
|
+ int sopNum = tbSopInfoService.count(sopWrapper);
|
|
|
+ result.setSopNum(sopNum);
|
|
|
+
|
|
|
+ //大区经理人数
|
|
|
+ int leadNum = baseMapper.countLead(serviceUnitId);
|
|
|
+ result.setLeadNum(leadNum);
|
|
|
+
|
|
|
+ //总投入人数
|
|
|
+ int totalPerson = baseMapper.countTotalPerson(serviceUnitId);
|
|
|
+ result.setTotalPerson(totalPerson);
|
|
|
+
|
|
|
+ //扫描仪数量
|
|
|
+ List<DeviceDeliveryStatusEnum> deliveryStatusList = Arrays.asList(DeviceDeliveryStatusEnum.USING, DeviceDeliveryStatusEnum.IN, DeviceDeliveryStatusEnum.TRANSFER,
|
|
|
+ DeviceDeliveryStatusEnum.TRANSFER_SIGN);
|
|
|
+ int scannerNum = baseMapper.countScanner(serviceUnitId, deliveryStatusList, InOutTypeEnum.OUT);
|
|
|
+ result.setScannerNum(scannerNum);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ServiceUnitProgressResult> progress(Long serviceUnitId) {
|
|
|
+ List<ServiceUnitProgressResult> progressResultList = new ArrayList<>();
|
|
|
+ List<ServiceUnitProgressResult> sopList = baseMapper.listSopProgress(serviceUnitId);
|
|
|
+ if (sopList != null && !sopList.isEmpty()) {
|
|
|
+ //系统中任务状态汇总,并根据业务状态计算数量
|
|
|
+ Map<String, List<ServiceUnitProgressResult>> map = sopList.stream().collect(Collectors.groupingBy(ServiceUnitProgressResult::getTaskName));
|
|
|
+ Map<CrmProcessEnum, Integer> summaryMap = getCrmProcessNum(map);
|
|
|
+
|
|
|
+ //sop的总量
|
|
|
+ int total = summaryMap.values().stream().mapToInt(Integer::intValue).sum();
|
|
|
+ BigDecimal totalNum = BigDecimal.valueOf(total);
|
|
|
+ NumberFormat formatter = NumberFormat.getPercentInstance();
|
|
|
+ formatter.setMinimumFractionDigits(2);
|
|
|
+
|
|
|
+ //界面定义的阶段组装
|
|
|
+ ServiceUnitProgressResult progressResult;
|
|
|
+ CrmProcessEnum[] processValues = CrmProcessEnum.values();
|
|
|
+ for (CrmProcessEnum process : processValues) {
|
|
|
+ progressResult = new ServiceUnitProgressResult();
|
|
|
+ //补充sop数量为0的阶段
|
|
|
+ if (!summaryMap.containsKey(process)) {
|
|
|
+ progressResult.setProcess(process);
|
|
|
+ progressResult.setSopNum(0);
|
|
|
+ progressResultList.add(progressResult);
|
|
|
+ } else {
|
|
|
+ Integer sopNum = summaryMap.get(process);
|
|
|
+ progressResult.setProcess(process);
|
|
|
+ progressResult.setSopNum(sopNum);
|
|
|
+ //计算占比
|
|
|
+ BigDecimal processNum = BigDecimal.valueOf(sopNum);
|
|
|
+ processNum = processNum.divide(totalNum, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
|
|
|
+ progressResult.setRatio(formatter.format(processNum.doubleValue() / 100));
|
|
|
+ progressResultList.add(progressResult);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return progressResultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ServiceUnitProvinceResult> province(Long serviceUnitId) {
|
|
|
+ List<ServiceUnitProvinceResult> provinceResultList = new ArrayList<>();
|
|
|
+ List<ServiceUnitProgressResult> sopList = baseMapper.listSopProgress(serviceUnitId);
|
|
|
+ List<ServiceUnitProvinceResult> provinceCrmNumList = baseMapper.listProvinceCrmNum(serviceUnitId);
|
|
|
+
|
|
|
+ // 各省份的派单数量
|
|
|
+ provinceCrmNumList.forEach(province -> {
|
|
|
+ ServiceUnitProvinceResult result = new ServiceUnitProvinceResult();
|
|
|
+ result.setProvince(province.getProvince());
|
|
|
+ result.setCrmNum(province.getProvinceCrmNum());
|
|
|
+
|
|
|
+ //某个省份下所有sop数量,并按照所处阶段分组
|
|
|
+ Map<String, List<ServiceUnitProgressResult>> processMap = sopList.stream()
|
|
|
+ .filter(item -> StringUtils.isNotEmpty(item.getProvinceName()) && item.getProvinceName().equals(province.getProvince()))
|
|
|
+ .collect(Collectors.groupingBy(ServiceUnitProgressResult::getTaskName));
|
|
|
+ //统计界面定义的阶段,sop的数量
|
|
|
+ Map<CrmProcessEnum, Integer> summaryMap = getCrmProcessNum(processMap);
|
|
|
+
|
|
|
+ Integer prepareSopNum = summaryMap.get(CrmProcessEnum.PREPARE);
|
|
|
+ Integer scanSopNum = summaryMap.get(CrmProcessEnum.SCAN);
|
|
|
+ Integer markSopNum = summaryMap.get(CrmProcessEnum.MARK);
|
|
|
+ Integer finalSopNum = summaryMap.get(CrmProcessEnum.FINAL);
|
|
|
+ Integer finishSopNum = summaryMap.get(CrmProcessEnum.FINISH);
|
|
|
+
|
|
|
+ result.setPrepareSopNum(prepareSopNum == null ? 0 : prepareSopNum);
|
|
|
+ result.setScanSopNum(scanSopNum == null ? 0 : scanSopNum);
|
|
|
+ result.setMarkSopNum(markSopNum == null ? 0 : markSopNum);
|
|
|
+ result.setFinalSopNum(finalSopNum == null ? 0 : finalSopNum);
|
|
|
+ result.setFinishSopNum(finishSopNum == null ? 0 : finishSopNum);
|
|
|
+ Integer sopNum = result.getPrepareSopNum() + result.getScanSopNum() + result.getMarkSopNum() + result.getFinalSopNum() + result.getFinishSopNum();
|
|
|
+ result.setSopNum(sopNum);
|
|
|
+ Integer sopSum = result.getScanSopNum() + result.getMarkSopNum() + result.getFinalSopNum() + result.getFinishSopNum();
|
|
|
+ result.setSopSum(sopSum);
|
|
|
+
|
|
|
+ provinceResultList.add(result);
|
|
|
+ });
|
|
|
+
|
|
|
+ return provinceResultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<ProjectMonitorResult> pageSop(Page<ProjectMonitorResult> page, Long serviceUnitId, Long crmUserId, String customName, CrmProcessEnum process,
|
|
|
+ Long leadId, String province, Long supplierId, Long coordinatorId) {
|
|
|
+ List<String> processList = new ArrayList<>();
|
|
|
+ if (process != null) {
|
|
|
+ processList = getProcessList(process);
|
|
|
+ }
|
|
|
+ SopRoleTypeEnum roleType = null;
|
|
|
+ if (supplierId != null) {
|
|
|
+ roleType = SopRoleTypeEnum.PROJECT_MANAGER;
|
|
|
+ }
|
|
|
+ if (coordinatorId != null) {
|
|
|
+ roleType = SopRoleTypeEnum.REGION_COORDINATOR;
|
|
|
+ }
|
|
|
+
|
|
|
+ IPage<ProjectMonitorResult> pageSop;
|
|
|
+ // 人力供应商、区域协调人
|
|
|
+ if (supplierId == null && coordinatorId == null) {
|
|
|
+ pageSop = baseMapper.pageSop(new Page<>(page.getCurrent(), page.getSize()), serviceUnitId, crmUserId,
|
|
|
+ customName, process, leadId, province, processList);
|
|
|
+ } else { // 其他
|
|
|
+ pageSop = baseMapper.pageSopByUserAllocation(new Page<>(page.getCurrent(), page.getSize()), serviceUnitId, crmUserId,
|
|
|
+ customName, process, leadId, province, processList, supplierId, coordinatorId, roleType);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ProjectMonitorResult> monitorResultList = pageSop.getRecords();
|
|
|
+ for (ProjectMonitorResult monitorResult : monitorResultList) {
|
|
|
+ monitorResult.setProcess(CrmProcessEnum.findCrmProcessByDesc(monitorResult.getTaskName()));
|
|
|
+ //设置区域协调人、大区经理、工程师
|
|
|
+ List<UserArchivesAllocationDto> allocationDtoList = tbUserArchivesAllocationService.listUserArchivesAllocation(
|
|
|
+ monitorResult.getCrmDetailId());
|
|
|
+ List<ProjectMonitorUserResult> coordinatorList = filterUserArchivesAllocation(allocationDtoList, SopRoleTypeEnum.REGION_COORDINATOR);
|
|
|
+ monitorResult.setRegionCoordinator(!coordinatorList.isEmpty() ? coordinatorList.get(0) : null);
|
|
|
+ List<ProjectMonitorUserResult> managerList = filterUserArchivesAllocation(allocationDtoList, SopRoleTypeEnum.PROJECT_MANAGER);
|
|
|
+ monitorResult.setProjectManager(!managerList.isEmpty() ? managerList.get(0) : null);
|
|
|
+ monitorResult.setEngineerList(filterUserArchivesAllocation(allocationDtoList, SopRoleTypeEnum.ENGINEER));
|
|
|
+ }
|
|
|
+ return pageSop;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void export(Long serviceUnitId, Long crmUserId, String customName, CrmProcessEnum process, Long leadId, String province, Long supplierId, Long coordinatorId) {
|
|
|
+ List<String> processList = new ArrayList<>();
|
|
|
+ if (process != null) {
|
|
|
+ processList = getProcessList(process);
|
|
|
+ }
|
|
|
+ SopRoleTypeEnum roleType = null;
|
|
|
+ if (supplierId != null) {
|
|
|
+ roleType = SopRoleTypeEnum.PROJECT_MANAGER;
|
|
|
+ }
|
|
|
+ if (coordinatorId != null) {
|
|
|
+ roleType = SopRoleTypeEnum.REGION_COORDINATOR;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<ProjectMonitorResult> resultList;
|
|
|
+ // 人力供应商、区域协调人
|
|
|
+ if (supplierId == null && coordinatorId == null) {
|
|
|
+ resultList = baseMapper.listSop(serviceUnitId, crmUserId, customName, process, leadId, province, processList);
|
|
|
+ } else {
|
|
|
+ resultList = baseMapper.listSopByUserAllocation(serviceUnitId, crmUserId, customName, process, leadId, province, processList, supplierId,
|
|
|
+ coordinatorId, roleType);
|
|
|
+ }
|
|
|
+
|
|
|
+ //封装导出结果
|
|
|
+ List<SopInfoExportResult> exportResultList = new ArrayList<>();
|
|
|
+ for(ProjectMonitorResult result : resultList) {
|
|
|
+ result.setProcess(CrmProcessEnum.findCrmProcessByDesc(result.getTaskName()));
|
|
|
+ SopInfoExportResult exportResult = getSopInfoExportResult(result);
|
|
|
+ exportResultList.add(exportResult);
|
|
|
+ }
|
|
|
+
|
|
|
+ File fileTemp = null;
|
|
|
+ try {
|
|
|
+ fileTemp = SystemConstant.getFileTempVar(SystemConstant.XLSX_PREFIX);
|
|
|
+ EasyExcel.write(fileTemp, SopInfoExportResult.class).sheet("sop信息").doWrite(exportResultList);
|
|
|
+ HttpServletResponse response = ServletUtil.getResponse();
|
|
|
+ FileUtil.outputFile(response, fileTemp, "sop信息.xlsx");
|
|
|
+ } catch (IOException e) {
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(e.getMessage());
|
|
|
+ } finally {
|
|
|
+ if (Objects.nonNull(fileTemp)) {
|
|
|
+ fileTemp.delete();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private SopInfoExportResult getSopInfoExportResult(ProjectMonitorResult result) {
|
|
|
+ SopInfoExportResult exportResult = new SopInfoExportResult();
|
|
|
+ exportResult.setCustomName(result.getCustomName());
|
|
|
+ exportResult.setCrmName(result.getCrmName());
|
|
|
+ exportResult.setCourseName(result.getCourseName());
|
|
|
+ exportResult.setProcess(result.getProcess().getTitle());
|
|
|
+ exportResult.setLeadName(result.getLeadName()+"-"+ result.getLeadMobile());
|
|
|
+ List<UserArchivesAllocationDto> allocationDtoList = tbUserArchivesAllocationService.listUserArchivesAllocation(result.getCrmDetailId());
|
|
|
+ //设置区域协调人
|
|
|
+ List<ProjectMonitorUserResult> coordinatorList = filterUserArchivesAllocation(allocationDtoList, SopRoleTypeEnum.REGION_COORDINATOR);
|
|
|
+ ProjectMonitorUserResult coordinator;
|
|
|
+ if(!coordinatorList.isEmpty()) {
|
|
|
+ coordinator = coordinatorList.get(0);
|
|
|
+ exportResult.setRegionCoordinator(String.join("-", coordinator.getSupplierName(), coordinator.getUserName(), coordinator.getMobileNumber()));
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置项目经理
|
|
|
+ List<ProjectMonitorUserResult> managerList = filterUserArchivesAllocation(allocationDtoList, SopRoleTypeEnum.PROJECT_MANAGER);
|
|
|
+ if(!managerList.isEmpty()) {
|
|
|
+ ProjectMonitorUserResult projectManager = managerList.get(0);
|
|
|
+ exportResult.setProjectManager(String.join("-", projectManager.getSupplierName(), projectManager.getUserName(), projectManager.getMobileNumber()));
|
|
|
+ }
|
|
|
+
|
|
|
+ //设置工程师
|
|
|
+ List<ProjectMonitorUserResult> engineerList = filterUserArchivesAllocation(allocationDtoList, SopRoleTypeEnum.ENGINEER);
|
|
|
+ if(!engineerList.isEmpty()) {
|
|
|
+ int index = 0;
|
|
|
+ StringBuilder engineer = new StringBuilder();
|
|
|
+ for(ProjectMonitorUserResult engineerUser : engineerList) {
|
|
|
+ engineer.append(String.join("-", engineerUser.getSupplierName(), engineerUser.getUserName(), engineerUser.getMobileNumber()));
|
|
|
+ if(index < engineerList.size() - 1) {
|
|
|
+ engineer.append(",");
|
|
|
+ }
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+ exportResult.setEngineer(engineer.toString());
|
|
|
+ }
|
|
|
+ return exportResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<ProjectMonitorUserResult> filterUserArchivesAllocation(List<UserArchivesAllocationDto> allocationDtoList, SopRoleTypeEnum roleType) {
|
|
|
+ List<ProjectMonitorUserResult> monitorResultList = new ArrayList<>();
|
|
|
+ List<UserArchivesAllocationDto> filterUserList = allocationDtoList.stream().filter(user -> user.getSopRoleType().equals(roleType)).collect(
|
|
|
+ Collectors.toList());
|
|
|
+ for (UserArchivesAllocationDto dto : filterUserList) {
|
|
|
+ ProjectMonitorUserResult userResult = new ProjectMonitorUserResult();
|
|
|
+ BeanUtils.copyProperties(dto, userResult);
|
|
|
+ monitorResultList.add(userResult);
|
|
|
+ }
|
|
|
+ return monitorResultList;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<String> getProcessList(CrmProcessEnum process) {
|
|
|
+ List<String> processList = new ArrayList<>();
|
|
|
+ if (process == CrmProcessEnum.FINISH) {
|
|
|
+ return processList;
|
|
|
+ }
|
|
|
+ String[] descArr = process.getDesc().split(",");
|
|
|
+ return Arrays.asList(descArr);
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<CrmProcessEnum, Integer> getCrmProcessNum(Map<String, List<ServiceUnitProgressResult>> processMap) {
|
|
|
+ Map<CrmProcessEnum, Integer> summaryMap = new HashMap<>();
|
|
|
+ processMap.forEach((k, v) -> {
|
|
|
+ CrmProcessEnum crmProcess = CrmProcessEnum.findCrmProcessByDesc(k);
|
|
|
+ if (crmProcess == null)
|
|
|
+ return;
|
|
|
+ if (!summaryMap.containsKey(crmProcess)) {
|
|
|
+ summaryMap.put(crmProcess, v.size());
|
|
|
+ } else {
|
|
|
+ summaryMap.put(crmProcess, summaryMap.get(crmProcess) + v.size());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return summaryMap;
|
|
|
+ }
|
|
|
+}
|