|
@@ -1,5 +1,6 @@
|
|
package com.qmth.sop.business.service.impl;
|
|
package com.qmth.sop.business.service.impl;
|
|
|
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
@@ -7,34 +8,48 @@ import com.qmth.sop.business.bean.dto.DataPermissionDto;
|
|
import com.qmth.sop.business.bean.result.TBCrmResult;
|
|
import com.qmth.sop.business.bean.result.TBCrmResult;
|
|
import com.qmth.sop.business.bean.result.UserArchivesAllocationResult;
|
|
import com.qmth.sop.business.bean.result.UserArchivesAllocationResult;
|
|
import com.qmth.sop.business.bean.result.UserArchivesAllocationSubTotalResult;
|
|
import com.qmth.sop.business.bean.result.UserArchivesAllocationSubTotalResult;
|
|
-import com.qmth.sop.business.entity.SysUser;
|
|
|
|
-import com.qmth.sop.business.entity.TBService;
|
|
|
|
|
|
+import com.qmth.sop.business.bean.result.analyze.ServiceUnitOverview;
|
|
|
|
+import com.qmth.sop.business.entity.*;
|
|
import com.qmth.sop.business.mapper.ServiceAnalyseMapper;
|
|
import com.qmth.sop.business.mapper.ServiceAnalyseMapper;
|
|
import com.qmth.sop.business.service.*;
|
|
import com.qmth.sop.business.service.*;
|
|
import com.qmth.sop.common.contant.SystemConstant;
|
|
import com.qmth.sop.common.contant.SystemConstant;
|
|
import com.qmth.sop.common.enums.CrmStatusEnum;
|
|
import com.qmth.sop.common.enums.CrmStatusEnum;
|
|
|
|
+import com.qmth.sop.common.enums.DeviceStatusEnum;
|
|
|
|
+import com.qmth.sop.common.enums.ExceptionResultEnum;
|
|
|
|
+import com.qmth.sop.common.enums.InOutTypeEnum;
|
|
import com.qmth.sop.common.util.ServletUtil;
|
|
import com.qmth.sop.common.util.ServletUtil;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.util.CollectionUtils;
|
|
import org.springframework.util.CollectionUtils;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
|
+import java.math.RoundingMode;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Service
|
|
@Service
|
|
public class ServiceAnalyseServiceImpl extends ServiceImpl<ServiceAnalyseMapper, TBService> implements ServiceAnalyseService {
|
|
public class ServiceAnalyseServiceImpl extends ServiceImpl<ServiceAnalyseMapper, TBService> implements ServiceAnalyseService {
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
- TBSopInfoService tbSopInfoService;
|
|
|
|
|
|
+ private TBSopInfoService tbSopInfoService;
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
- TBUserArchivesSupplierService tbUserArchivesSupplierService;
|
|
|
|
|
|
+ private TBUserArchivesSupplierService tbUserArchivesSupplierService;
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
private SysUserService sysUserService;
|
|
private SysUserService sysUserService;
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
- TBUserArchivesAllocationService tbUserArchivesAllocationService;
|
|
|
|
|
|
+ private TBUserArchivesAllocationService tbUserArchivesAllocationService;
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private TBCrmService tbCrmService;
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private TBDeviceInOutService tbDeviceInOutService;
|
|
|
|
+
|
|
|
|
+ @Resource
|
|
|
|
+ private SysDeviceService sysDeviceService;
|
|
|
|
|
|
@Override
|
|
@Override
|
|
public List<TBService> list(Long startTime, Long endTime) {
|
|
public List<TBService> list(Long startTime, Long endTime) {
|
|
@@ -51,8 +66,9 @@ public class ServiceAnalyseServiceImpl extends ServiceImpl<ServiceAnalyseMapper,
|
|
* ④在服务人员总数:在执行的SOP现场服务人员数量,包括助理工程师、实施工程师、区域协调人;
|
|
* ④在服务人员总数:在执行的SOP现场服务人员数量,包括助理工程师、实施工程师、区域协调人;
|
|
* ⑤现场人员占用率:(在服务人员总数÷认证有效的在服务人员总数)×100%;
|
|
* ⑤现场人员占用率:(在服务人员总数÷认证有效的在服务人员总数)×100%;
|
|
*/
|
|
*/
|
|
|
|
+ @Deprecated
|
|
@Override
|
|
@Override
|
|
- public Map<String, Object> overview(Long serviceUnitId) {
|
|
|
|
|
|
+ public Map<String, Object> overview1(Long serviceUnitId) {
|
|
Map<String, Object> map = new HashMap<>();
|
|
Map<String, Object> map = new HashMap<>();
|
|
List<Map<String, Object>> list = this.baseMapper.projectProgress(serviceUnitId);
|
|
List<Map<String, Object>> list = this.baseMapper.projectProgress(serviceUnitId);
|
|
int finishCount = 0, size = 0;
|
|
int finishCount = 0, size = 0;
|
|
@@ -106,6 +122,111 @@ public class ServiceAnalyseServiceImpl extends ServiceImpl<ServiceAnalyseMapper,
|
|
return map;
|
|
return map;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 4.服务单元概览
|
|
|
|
+ * ①项目执行进度=服务单元下已完成的派单(研究生派单下SOP已完结;教务处派单下已有完成的SOP,无在执行的SOP。可能存在教务处多个SOP之间空窗期导致数据的误差,这个指标允许少量误差存在);
|
|
|
|
+ * ②设备出库总量:当前服务单元下已出库且尚未入库的设备总量;
|
|
|
|
+ * ③设备占用率:(设备出库总量÷正常设备总量)×100%;
|
|
|
|
+ * ④在服务人员总数:在执行的SOP现场服务人员数量,包括助理工程师、实施工程师、区域协调人;
|
|
|
|
+ * ⑤现场人员占用率:(在服务人员总数÷认证有效的在服务人员总数)×100%;
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public ServiceUnitOverview overview(Long serviceUnitId) {
|
|
|
|
+ ServiceUnitOverview result = new ServiceUnitOverview();
|
|
|
|
+ BigDecimal percent = new BigDecimal(100);
|
|
|
|
+ // -- 项目执行进度 --
|
|
|
|
+ List<TBCrm> tbCrmDatasource = tbCrmService.list(new QueryWrapper<TBCrm>().lambda()
|
|
|
|
+ .eq(TBCrm::getServiceId, serviceUnitId)
|
|
|
|
+ .eq(TBCrm::getEnable,true));
|
|
|
|
+ int crmFinishCount = (int) tbCrmDatasource.stream().filter(e -> CrmStatusEnum.FINISH.equals(e.getStatus())).count();
|
|
|
|
+ int crmTotalCount = tbCrmDatasource.size();
|
|
|
|
+ BigDecimal projectProgress = new BigDecimal(0);
|
|
|
|
+ if (crmTotalCount > 0){
|
|
|
|
+ projectProgress = new BigDecimal(crmFinishCount).divide(new BigDecimal(crmTotalCount), 2, RoundingMode.HALF_UP).multiply(percent);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // -- 设备出库总量 -- (可以知道是哪个设备没入库)
|
|
|
|
+ List<TBDeviceInOut> tbDeviceInOutDatasource = tbDeviceInOutService.list(new QueryWrapper<TBDeviceInOut>().lambda().eq(TBDeviceInOut::getServiceId, serviceUnitId));
|
|
|
|
+
|
|
|
|
+ // 设备入库map -> (设备编号,入库次数)
|
|
|
|
+ Map<String, Integer> deviceInMap = tbDeviceInOutDatasource
|
|
|
|
+ .stream()
|
|
|
|
+ .filter(e -> InOutTypeEnum.IN.equals(e.getType()))
|
|
|
|
+ .collect(Collectors.toMap(TBDeviceInOut::getDeviceNo, e -> 1, Integer::sum));
|
|
|
|
+
|
|
|
|
+ // 设备出库map -> (设备编号,出库次数)
|
|
|
|
+ int equipmentOutboundTotal = 0;
|
|
|
|
+ Map<String, Integer> deviceOutMap = tbDeviceInOutDatasource
|
|
|
|
+ .stream()
|
|
|
|
+ .filter(e -> InOutTypeEnum.OUT.equals(e.getType()))
|
|
|
|
+ .collect(Collectors.toMap(TBDeviceInOut::getDeviceNo, e -> 1, Integer::sum));
|
|
|
|
+
|
|
|
|
+ for (String deviceNo : deviceOutMap.keySet()) {
|
|
|
|
+ // 出库次数
|
|
|
|
+ Integer outCount = deviceOutMap.get(deviceNo);
|
|
|
|
+ Integer inCount = 0;
|
|
|
|
+ if (deviceInMap.containsKey(deviceNo)) {
|
|
|
|
+ inCount = deviceInMap.get(deviceNo);
|
|
|
|
+ }
|
|
|
|
+ if (inCount > outCount) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(String.format("在服务单元下,设备[%s]入库次数比出库次数多异常", deviceNo));
|
|
|
|
+ }
|
|
|
|
+ outCount = outCount - inCount;
|
|
|
|
+ if (outCount > 1) {
|
|
|
|
+ throw ExceptionResultEnum.ERROR.exception(String.format("在服务单元下,设备[%s]出库次数异常", deviceNo));
|
|
|
|
+ }
|
|
|
|
+ equipmentOutboundTotal = equipmentOutboundTotal + outCount;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // -- 设备占用率 --
|
|
|
|
+ int normalDeviceCount = sysDeviceService.count(new QueryWrapper<SysDevice>().lambda().eq(SysDevice::getStatus, DeviceStatusEnum.NORMAL));
|
|
|
|
+ BigDecimal equipmentOccupancyRate = new BigDecimal(0);
|
|
|
|
+ if (normalDeviceCount > 0){
|
|
|
|
+ equipmentOccupancyRate = new BigDecimal(equipmentOutboundTotal).divide(new BigDecimal(normalDeviceCount), 2, RoundingMode.HALF_UP).multiply(percent);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // -- 在服务人员总数 --
|
|
|
|
+ List<Map<String, Object>> sopPassageMap = tbSopInfoService.findSopPassage(serviceUnitId);
|
|
|
|
+ Integer servicePersonnelTotal = 0;
|
|
|
|
+ if (!CollectionUtils.isEmpty(sopPassageMap)) {
|
|
|
|
+ for (Map m : sopPassageMap) {
|
|
|
|
+ //需要去重
|
|
|
|
+ String regionUserStr = Objects.nonNull(m) && Objects.nonNull(m.get("regionUserIds")) ? m.get("regionUserIds").toString() : null;
|
|
|
|
+ if (Objects.nonNull(regionUserStr)) {
|
|
|
|
+ String[] strs = regionUserStr.split(",");
|
|
|
|
+ Set<String> set = new HashSet<>(Arrays.asList(strs));
|
|
|
|
+ servicePersonnelTotal = servicePersonnelTotal + set.size();
|
|
|
|
+ }
|
|
|
|
+ String engineerUserStr = Objects.nonNull(m) && Objects.nonNull(m.get("engineerUserIds")) ? m.get("engineerUserIds").toString() : null;
|
|
|
|
+ if (Objects.nonNull(engineerUserStr)) {
|
|
|
|
+ String[] strs = engineerUserStr.split(",");
|
|
|
|
+ Set<String> set = new HashSet<>(Arrays.asList(strs));
|
|
|
|
+ servicePersonnelTotal = servicePersonnelTotal + set.size();
|
|
|
|
+ }
|
|
|
|
+ String assistantEngineerUserId = Objects.nonNull(m) && Objects.nonNull(m.get("assistantEngineerUserIds")) ? m.get("assistantEngineerUserIds").toString() : null;
|
|
|
|
+ if (Objects.nonNull(assistantEngineerUserId)) {
|
|
|
|
+ String[] strs = assistantEngineerUserId.split(",");
|
|
|
|
+ Set<String> set = new HashSet<>(Arrays.asList(strs));
|
|
|
|
+ servicePersonnelTotal = servicePersonnelTotal + set.size();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //认证有效的人员总数
|
|
|
|
+ int totalUserArchives = tbUserArchivesSupplierService.countAuthentication();
|
|
|
|
+ BigDecimal sitePersonnelOccupancyRate = new BigDecimal(0);
|
|
|
|
+ if (totalUserArchives > 0) {
|
|
|
|
+ sitePersonnelOccupancyRate = new BigDecimal(servicePersonnelTotal).divide(new BigDecimal(totalUserArchives), 2, RoundingMode.HALF_UP).multiply(percent);
|
|
|
|
+ }
|
|
|
|
+ result.setProjectProgress(projectProgress);
|
|
|
|
+ result.setEquipmentOutboundTotal(equipmentOutboundTotal);
|
|
|
|
+ result.setEquipmentOccupancyRate(equipmentOccupancyRate);
|
|
|
|
+ result.setServicePersonnelTotal(servicePersonnelTotal);
|
|
|
|
+ result.setSitePersonnelOccupancyRate(sitePersonnelOccupancyRate);
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* ①当前服务单元已划分了区域协调人的项目总数、供应商分布占比;
|
|
* ①当前服务单元已划分了区域协调人的项目总数、供应商分布占比;
|
|
*/
|
|
*/
|