فهرست منبع

fix:服务单元概况

caozixuan 1 سال پیش
والد
کامیت
083e7db7cd

+ 1 - 2
sop-api/src/main/java/com/qmth/sop/server/api/ServiceAnalyseController.java

@@ -70,8 +70,7 @@ public class ServiceAnalyseController {
     @RequestMapping(value = "/overview", method = RequestMethod.POST)
     @ApiResponses({@ApiResponse(code = 200, message = "服务单元概览", response = Map.class)})
     public Result overview(@ApiParam(value = "服务单元", required = true) @RequestParam Long serviceUnitId) {
-        Map<String, Object> map = serviceAnalyseService.overview(serviceUnitId);
-        return ResultUtil.ok(map);
+        return ResultUtil.ok(serviceAnalyseService.overview(serviceUnitId));
     }
 
     /**

+ 67 - 0
sop-business/src/main/java/com/qmth/sop/business/bean/result/analyze/ServiceUnitOverview.java

@@ -0,0 +1,67 @@
+package com.qmth.sop.business.bean.result.analyze;
+
+import io.swagger.annotations.ApiModelProperty;
+
+import java.math.BigDecimal;
+
+/**
+ * @Description: 服务单元概况
+ * @Author: CaoZixuan
+ * @Date: 2023-11-18
+ */
+public class ServiceUnitOverview {
+    @ApiModelProperty("项目执行进度")
+    private BigDecimal projectProgress;
+
+    @ApiModelProperty("设备出库总量")
+    private Integer equipmentOutboundTotal;
+
+    @ApiModelProperty("设备占用率")
+    private BigDecimal equipmentOccupancyRate;
+
+    @ApiModelProperty("在服务人员总数")
+    private Integer servicePersonnelTotal;
+
+    @ApiModelProperty("现场人员占用率")
+    private BigDecimal sitePersonnelOccupancyRate;
+
+    public BigDecimal getProjectProgress() {
+        return projectProgress;
+    }
+
+    public void setProjectProgress(BigDecimal projectProgress) {
+        this.projectProgress = projectProgress;
+    }
+
+    public Integer getEquipmentOutboundTotal() {
+        return equipmentOutboundTotal;
+    }
+
+    public void setEquipmentOutboundTotal(Integer equipmentOutboundTotal) {
+        this.equipmentOutboundTotal = equipmentOutboundTotal;
+    }
+
+    public BigDecimal getEquipmentOccupancyRate() {
+        return equipmentOccupancyRate;
+    }
+
+    public void setEquipmentOccupancyRate(BigDecimal equipmentOccupancyRate) {
+        this.equipmentOccupancyRate = equipmentOccupancyRate;
+    }
+
+    public Integer getServicePersonnelTotal() {
+        return servicePersonnelTotal;
+    }
+
+    public void setServicePersonnelTotal(Integer servicePersonnelTotal) {
+        this.servicePersonnelTotal = servicePersonnelTotal;
+    }
+
+    public BigDecimal getSitePersonnelOccupancyRate() {
+        return sitePersonnelOccupancyRate;
+    }
+
+    public void setSitePersonnelOccupancyRate(BigDecimal sitePersonnelOccupancyRate) {
+        this.sitePersonnelOccupancyRate = sitePersonnelOccupancyRate;
+    }
+}

+ 5 - 1
sop-business/src/main/java/com/qmth/sop/business/service/ServiceAnalyseService.java

@@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.sop.business.bean.result.TBCrmResult;
 import com.qmth.sop.business.bean.result.UserArchivesAllocationResult;
 import com.qmth.sop.business.bean.result.UserArchivesAllocationSubTotalResult;
+import com.qmth.sop.business.bean.result.analyze.ServiceUnitOverview;
 import com.qmth.sop.business.entity.TBService;
 
 import java.util.List;
@@ -14,7 +15,10 @@ import java.util.Map;
 public interface ServiceAnalyseService extends IService<TBService> {
     List<TBService> list(Long startTime, Long endTime);
 
-    Map<String, Object> overview(Long serviceUnitId);
+    @Deprecated
+    Map<String, Object> overview1(Long serviceUnitId);
+
+    ServiceUnitOverview overview(Long serviceUnitId);
 
     Map<String, Object> supplier(Long serviceUnitId);
 

+ 127 - 6
sop-business/src/main/java/com/qmth/sop/business/service/impl/ServiceAnalyseServiceImpl.java

@@ -1,5 +1,6 @@
 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.extension.plugins.pagination.Page;
 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.UserArchivesAllocationResult;
 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.service.*;
 import com.qmth.sop.common.contant.SystemConstant;
 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 org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.*;
+import java.util.stream.Collectors;
 
 @Service
 public class ServiceAnalyseServiceImpl extends ServiceImpl<ServiceAnalyseMapper, TBService> implements ServiceAnalyseService {
 
     @Resource
-    TBSopInfoService tbSopInfoService;
+    private TBSopInfoService tbSopInfoService;
 
     @Resource
-    TBUserArchivesSupplierService tbUserArchivesSupplierService;
+    private TBUserArchivesSupplierService tbUserArchivesSupplierService;
 
     @Resource
     private SysUserService sysUserService;
 
     @Resource
-    TBUserArchivesAllocationService tbUserArchivesAllocationService;
+    private TBUserArchivesAllocationService tbUserArchivesAllocationService;
+
+    @Resource
+    private TBCrmService tbCrmService;
+
+    @Resource
+    private TBDeviceInOutService tbDeviceInOutService;
+
+    @Resource
+    private SysDeviceService sysDeviceService;
 
     @Override
     public List<TBService> list(Long startTime, Long endTime) {
@@ -51,8 +66,9 @@ public class ServiceAnalyseServiceImpl extends ServiceImpl<ServiceAnalyseMapper,
      * ④在服务人员总数:在执行的SOP现场服务人员数量,包括助理工程师、实施工程师、区域协调人;
      * ⑤现场人员占用率:(在服务人员总数÷认证有效的在服务人员总数)×100%;
      */
+    @Deprecated
     @Override
-    public Map<String, Object> overview(Long serviceUnitId) {
+    public Map<String, Object> overview1(Long serviceUnitId) {
         Map<String, Object> map = new HashMap<>();
         List<Map<String, Object>> list = this.baseMapper.projectProgress(serviceUnitId);
         int finishCount = 0, size = 0;
@@ -106,6 +122,111 @@ public class ServiceAnalyseServiceImpl extends ServiceImpl<ServiceAnalyseMapper,
         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;
+    }
+
     /**
      * ①当前服务单元已划分了区域协调人的项目总数、供应商分布占比;
      */