|
@@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.pms.controller.admin.depttype.vo.IotDeptTypePageR
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.failure.vo.IotFailureReportPageReqVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.failure.vo.IotFailureReportPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.inspect.order.vo.IotInspectOrderPageReqVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.inspect.order.vo.IotInspectOrderPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.inspect.plan.vo.IotInspectPlanPageReqVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.inspect.plan.vo.IotInspectPlanPageReqVO;
|
|
|
|
|
+import cn.iocoder.yudao.module.pms.controller.admin.iotdeviceassociate.vo.IotDeviceAssociatePageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogPageReqVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotdevicerunlog.vo.IotDeviceRunLogRespVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorder.vo.IotMainWorkOrderPageReqVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotmainworkorder.vo.IotMainWorkOrderPageReqVO;
|
|
@@ -28,6 +29,7 @@ import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDai
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotrhdailyreport.vo.IotRhDailyReportPageReqVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotrhdailyreport.vo.IotRhDailyReportPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportPageReqVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportTaskCountVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotrydailyreport.vo.IotRyDailyReportTaskCountVO;
|
|
|
|
|
+import cn.iocoder.yudao.module.pms.controller.admin.iotryhidailyreport.vo.IotRyHiDailyReportPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.stat.vo.*;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.stat.vo.*;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.vo.DeviceVO;
|
|
import cn.iocoder.yudao.module.pms.controller.admin.vo.DeviceVO;
|
|
@@ -41,11 +43,14 @@ import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectOrderDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectOrderDetailDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectOrderDetailDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectPlanDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.inspect.IotInspectPlanDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotcountdata.IotCountDataDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotcountdata.IotCountDataDO;
|
|
|
|
|
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdeviceassociate.IotDeviceAssociateDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorder.IotMainWorkOrderDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotmainworkorder.IotMainWorkOrderDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotoutbound.IotOutboundDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotoutbound.IotOutboundDO;
|
|
|
|
|
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttaskattrs.IotTaskAttrModelProperty;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrddailyreport.IotRdDailyReportDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrddailyreport.IotRdDailyReportDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrhdailyreport.IotRhDailyReportDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrhdailyreport.IotRhDailyReportDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrydailyreport.IotRyDailyReportDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrydailyreport.IotRyDailyReportDO;
|
|
|
|
|
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotryhidailyreport.IotRyHiDailyReportDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotsapstock.IotSapStockDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotsapstock.IotSapStockDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.IotMaintainDO;
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.maintain.IotMaintainDO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
|
|
@@ -56,6 +61,7 @@ import cn.iocoder.yudao.module.pms.dal.mysql.failure.IotFailureReportMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderDetailMapper;
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderDetailMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderMapper;
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectOrderMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectPlanMapper;
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.inspect.IotInspectPlanMapper;
|
|
|
|
|
+import cn.iocoder.yudao.module.pms.dal.mysql.iotdeviceassociate.IotDeviceAssociateMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicerunlog.IotDeviceRunLogMapper;
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicerunlog.IotDeviceRunLogMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotmainworkorder.IotMainWorkOrderMapper;
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotmainworkorder.IotMainWorkOrderMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillMapper;
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotopeationfill.IotOpeationFillMapper;
|
|
@@ -70,6 +76,7 @@ import cn.iocoder.yudao.module.pms.service.DeviceServiceImpl;
|
|
|
import cn.iocoder.yudao.module.pms.service.inspect.IotInspectOrderService;
|
|
import cn.iocoder.yudao.module.pms.service.inspect.IotInspectOrderService;
|
|
|
import cn.iocoder.yudao.module.pms.service.iotmainworkorder.IotMainWorkOrderService;
|
|
import cn.iocoder.yudao.module.pms.service.iotmainworkorder.IotMainWorkOrderService;
|
|
|
import cn.iocoder.yudao.module.pms.service.iotrydailyreport.IotRyDailyReportService;
|
|
import cn.iocoder.yudao.module.pms.service.iotrydailyreport.IotRyDailyReportService;
|
|
|
|
|
+import cn.iocoder.yudao.module.pms.service.iotryhidailyreport.IotRyHiDailyReportService;
|
|
|
import cn.iocoder.yudao.module.pms.service.maintain.IotMaintainService;
|
|
import cn.iocoder.yudao.module.pms.service.maintain.IotMaintainService;
|
|
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
|
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
|
@@ -177,6 +184,11 @@ public class IotStaticController {
|
|
|
private DeptUtil deptUtil;
|
|
private DeptUtil deptUtil;
|
|
|
@Autowired
|
|
@Autowired
|
|
|
private IotMainWorkOrderService iotMainWorkOrderService;
|
|
private IotMainWorkOrderService iotMainWorkOrderService;
|
|
|
|
|
+ @Autowired
|
|
|
|
|
+ private IotRyHiDailyReportService iotRyHiDailyReportService;
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private IotDeviceAssociateMapper iotDeviceAssociateMapper;
|
|
|
|
|
+
|
|
|
|
|
|
|
|
@GetMapping("/main/day")
|
|
@GetMapping("/main/day")
|
|
|
public CommonResult<Map<String, Object>> getMaintainDay() {
|
|
public CommonResult<Map<String, Object>> getMaintainDay() {
|
|
@@ -1450,6 +1462,120 @@ public class IotStaticController {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ @Operation(summary = "瑞都 近1周的设备利用率")
|
|
|
|
|
+ @GetMapping("/rd/device/sevenDayUtilization")
|
|
|
|
|
+ @PermitAll
|
|
|
|
|
+ public CommonResult<Map<String, Object>> rdSevenDayUtilization() {
|
|
|
|
|
+
|
|
|
|
|
+ List<String> lastSevenDays = getLastSevenDays();
|
|
|
|
|
+ String first = lastSevenDays.get(0);
|
|
|
|
|
+ String last = lastSevenDays.get(lastSevenDays.size() - 1);
|
|
|
|
|
+ LocalDateTime startOfDay = getStartOfDay(last);
|
|
|
|
|
+ LocalDateTime endOfDay = getEndOfDay(first);
|
|
|
|
|
+ LocalDateTime[] createTime = new LocalDateTime[]{startOfDay, endOfDay};
|
|
|
|
|
+
|
|
|
|
|
+ IotRdDailyReportPageReqVO iotRdDailyReportPageReqVO = new IotRdDailyReportPageReqVO();
|
|
|
|
|
+ iotRdDailyReportPageReqVO.setCreateTime(createTime);
|
|
|
|
|
+ iotRdDailyReportPageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
|
|
|
|
+ PageResult<IotRdDailyReportDO> pageReports = iotRdDailyReportMapper.selectPage(iotRdDailyReportPageReqVO);
|
|
|
|
|
+ if (ObjUtil.isEmpty(pageReports)) {
|
|
|
|
|
+ return buildEmptyResult(lastSevenDays);
|
|
|
|
|
+ }
|
|
|
|
|
+ List<IotRdDailyReportDO> reports = pageReports.getList();
|
|
|
|
|
+ if (CollUtil.isEmpty(reports)) {
|
|
|
|
|
+ return buildEmptyResult(lastSevenDays);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 计算最近7天公司整体的设备利用率
|
|
|
|
|
+ Set<Long> allRhChildDeptIds = deptService.getChildDeptIdListFromCache(163l);
|
|
|
|
|
+
|
|
|
|
|
+ // 设备利用率逻辑调整 只筛选 压裂 连油 主设备 rq_iot_device_associate
|
|
|
|
|
+ // 队伍日报中关联的主设备数量 /(队伍下所有主设备数量-封存设备数量)
|
|
|
|
|
+ Set<Long> mainDeviceIds = new HashSet<>();
|
|
|
|
|
+ Set<Long> fcMainDeviceIds = new HashSet<>();
|
|
|
|
|
+ // key设备id value设备所属部门id
|
|
|
|
|
+ Map<Long, Long> mainDeviceIdPair = new HashMap<>();
|
|
|
|
|
+ IotDeviceAssociatePageReqVO deviceAssocReqVO = new IotDeviceAssociatePageReqVO();
|
|
|
|
|
+ deviceAssocReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
|
|
|
|
+ deviceAssocReqVO.setDeptIds(allRhChildDeptIds);
|
|
|
|
|
+ PageResult<IotDeviceAssociateDO> pageResult = iotDeviceAssociateMapper.selectPage(deviceAssocReqVO);
|
|
|
|
|
+ if (ObjUtil.isNotEmpty(pageResult)) {
|
|
|
|
|
+ List<IotDeviceAssociateDO> deviceAssociates = pageResult.getList();
|
|
|
|
|
+ // 查询出所有瑞都压裂 连油主设备
|
|
|
|
|
+ deviceAssociates.forEach(assoc -> {
|
|
|
|
|
+ mainDeviceIds.add(assoc.getDeviceId());
|
|
|
|
|
+ mainDeviceIdPair.put(assoc.getDeviceId(), assoc.getDeptId());
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // 所有压裂连油主设备
|
|
|
|
|
+ Set<Long> abDeviceIds = new HashSet<>();
|
|
|
|
|
+ // 查询瑞都 压裂 连油 主设备详情信息
|
|
|
|
|
+ IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
|
|
|
|
|
+ deviceReqVO.setDeviceIds(new ArrayList<>(mainDeviceIds));
|
|
|
|
|
+ List<IotDeviceDO> mainDevices = iotDeviceMapper.selectListAlone(deviceReqVO);
|
|
|
|
|
+ // 筛选出 封存 的主设备
|
|
|
|
|
+ if (CollUtil.isNotEmpty(mainDevices)) {
|
|
|
|
|
+ mainDevices.forEach(device -> {
|
|
|
|
|
+ if ("fc".equals(device.getDeviceStatus())) {
|
|
|
|
|
+ fcMainDeviceIds.add(device.getId());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ abDeviceIds.add(device.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // key日期2026-06-08 value日期对应的日报数量
|
|
|
|
|
+ Map<String, Set<Long>> dateReportDeviceIdPair = new HashMap<>();
|
|
|
|
|
+ reports.forEach(report -> {
|
|
|
|
|
+ // 按照日期维度统计各 工作量数据 累计用电量 累计油耗 累计注气量 累计注水量
|
|
|
|
|
+ LocalDateTime reportLocalDate = report.getCreateTime();
|
|
|
|
|
+ // 将日期格式转换成 字符串
|
|
|
|
|
+ String reportDateStr = LocalDateTimeUtil.format(reportLocalDate, DatePattern.NORM_DATE_PATTERN);
|
|
|
|
|
+ // 统计日报关联施工AB类设备的利用率
|
|
|
|
|
+ Set<Long> reportDeviceIds = report.getDeviceIds();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(reportDeviceIds)) {
|
|
|
|
|
+ if (dateReportDeviceIdPair.containsKey(reportDateStr)) {
|
|
|
|
|
+ Set<Long> tempDeviceIds = dateReportDeviceIdPair.get(reportDateStr);
|
|
|
|
|
+ tempDeviceIds.addAll(reportDeviceIds);
|
|
|
|
|
+ dateReportDeviceIdPair.put(reportDateStr, tempDeviceIds);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ dateReportDeviceIdPair.put(reportDateStr, reportDeviceIds);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ // 计算每天的设备利用率
|
|
|
|
|
+ Map<String, BigDecimal> dateReportUtilizationPair = new HashMap<>();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(dateReportDeviceIdPair)) {
|
|
|
|
|
+ dateReportDeviceIdPair.forEach((reportDateStr, deviceIds) -> {
|
|
|
|
|
+ // 计算每天的所有日报涉及到的压裂连油主设备
|
|
|
|
|
+ // 1. 求交集:实际使用的A B类设备
|
|
|
|
|
+ Set<Long> utilizedDeviceIds = deviceIds.stream()
|
|
|
|
|
+ .filter(abDeviceIds::contains)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ if (CollUtil.isNotEmpty(abDeviceIds)) {
|
|
|
|
|
+ BigDecimal deviceUtilization = new BigDecimal((double) utilizedDeviceIds.size() / abDeviceIds.size())
|
|
|
|
|
+ .setScale(4, RoundingMode.HALF_UP);
|
|
|
|
|
+ dateReportUtilizationPair.put(reportDateStr, deviceUtilization);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // 5. 按日期升序补全最近7天,缺失填0
|
|
|
|
|
+ List<String> sortedDays = lastSevenDays.stream()
|
|
|
|
|
+ .sorted() // yyyy-MM-dd 字符串自然升序
|
|
|
|
|
+ .collect(Collectors.toList());
|
|
|
|
|
+ LinkedHashMap<String, BigDecimal> fillMap = new LinkedHashMap<>();
|
|
|
|
|
+ sortedDays.forEach(day ->
|
|
|
|
|
+ fillMap.put(day, dateReportUtilizationPair.getOrDefault(day, BigDecimal.ZERO))
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ LinkedList<Object> xAxis = new LinkedList<>(fillMap.keySet());
|
|
|
|
|
+ LinkedList<Object> fillData = new LinkedList<>(fillMap.values());
|
|
|
|
|
+
|
|
|
|
|
+ ImmutableMap<String, Serializable> fillResult = ImmutableMap.of("name", "设备利用率~~en**device utilization", "data", fillData);
|
|
|
|
|
+ return success(ImmutableMap.of("xAxis", xAxis, "series", ImmutableList.of(fillResult)));
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 无日报时直接返回全0序列
|
|
* 无日报时直接返回全0序列
|
|
|
*/
|
|
*/
|
|
@@ -1964,6 +2090,135 @@ public class IotStaticController {
|
|
|
return success(ImmutableMap.of("xAxis", xAxis, "series", ImmutableList.of(monthResult, yearResult)));
|
|
return success(ImmutableMap.of("xAxis", xAxis, "series", ImmutableList.of(monthResult, yearResult)));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询瑞鹰历史日报数据
|
|
|
|
|
+ * 钻井:进尺 完井数
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @GetMapping("/ry/hiZjDailyReports")
|
|
|
|
|
+ @PermitAll
|
|
|
|
|
+ public CommonResult<Map<String, Object>> hiZjDailyReports() {
|
|
|
|
|
+ // 查询历史数据
|
|
|
|
|
+ IotRyHiDailyReportPageReqVO pageReqVO = new IotRyHiDailyReportPageReqVO();
|
|
|
|
|
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
|
|
|
|
+ PageResult<IotRyHiDailyReportDO> pageReports = iotRyHiDailyReportService.getIotRyHiDailyReportPage(pageReqVO);
|
|
|
|
|
+ if (ObjUtil.isEmpty(pageReports)) {
|
|
|
|
|
+ return success(emptyResult());
|
|
|
|
|
+ }
|
|
|
|
|
+ List<IotRyHiDailyReportDO> reports = pageReports.getList();
|
|
|
|
|
+ if (CollUtil.isEmpty(reports)) {
|
|
|
|
|
+ return success(emptyResult());
|
|
|
|
|
+ }
|
|
|
|
|
+ // 将历史日报数据按照年份 为维度 统计 进尺、完井数
|
|
|
|
|
+ // key年份 value 钻井累计进尺m
|
|
|
|
|
+ Map<Integer, BigDecimal> footagePair = new HashMap<>();
|
|
|
|
|
+ // key年份 value 钻井累计完井数
|
|
|
|
|
+ Map<Integer, BigDecimal> zjWellsPair = new HashMap<>();
|
|
|
|
|
+ // key年份 value 修井累计完井数
|
|
|
|
|
+ Map<Integer, BigDecimal> xjWellsPair = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ reports.forEach(report -> {
|
|
|
|
|
+ LocalDateTime reportDate = report.getCreateTime();
|
|
|
|
|
+ Integer year = reportDate.getYear();
|
|
|
|
|
+ String classification = report.getProjectClassification();
|
|
|
|
|
+ BigDecimal footage = report.getAnnualFootage();
|
|
|
|
|
+ BigDecimal completedWells = report.getTotalCompletedWells();
|
|
|
|
|
+ if ("1".equals(classification)) {
|
|
|
|
|
+ // 钻井
|
|
|
|
|
+ if (footagePair.containsKey(year)) {
|
|
|
|
|
+ BigDecimal existFootage = footagePair.get(year);
|
|
|
|
|
+ BigDecimal tempFootage = existFootage.add(footage);
|
|
|
|
|
+ footagePair.put(year, tempFootage);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ footagePair.put(year, footage);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (zjWellsPair.containsKey(year)) {
|
|
|
|
|
+ BigDecimal existWells = zjWellsPair.get(year);
|
|
|
|
|
+ BigDecimal tempWells = existWells.add(completedWells);
|
|
|
|
|
+ zjWellsPair.put(year, tempWells);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ zjWellsPair.put(year, completedWells);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ LinkedList<Object> xAxis = new LinkedList<>();
|
|
|
|
|
+ LinkedList<Object> footageData = new LinkedList<>();
|
|
|
|
|
+ LinkedList<Object> wellsData = new LinkedList<>();
|
|
|
|
|
+
|
|
|
|
|
+ footagePair.forEach((k,v)->{
|
|
|
|
|
+ xAxis.add(k);
|
|
|
|
|
+ footageData.add(v);
|
|
|
|
|
+ if (zjWellsPair.containsKey(k)) {
|
|
|
|
|
+ BigDecimal wells = zjWellsPair.get(k);
|
|
|
|
|
+ wellsData.add(wells);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ ImmutableMap<String, Serializable> footageResult = ImmutableMap.of("name", "累计进尺~~en**footage", "data", footageData);
|
|
|
|
|
+ ImmutableMap<String, Serializable> wellsResult = ImmutableMap.of("name", "累计完井数~~en**finishedWells", "data", wellsData);
|
|
|
|
|
+ return success(ImmutableMap.of("xAxis", xAxis, "series", ImmutableList.of(footageResult, wellsResult)));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 查询瑞鹰历史日报数据
|
|
|
|
|
+ * 修井:完井数
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @GetMapping("/ry/hiXjDailyReports")
|
|
|
|
|
+ @PermitAll
|
|
|
|
|
+ public CommonResult<Map<String, Object>> hiXjDailyReports() {
|
|
|
|
|
+ // 查询历史数据
|
|
|
|
|
+ IotRyHiDailyReportPageReqVO pageReqVO = new IotRyHiDailyReportPageReqVO();
|
|
|
|
|
+ pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
|
|
|
|
+ PageResult<IotRyHiDailyReportDO> pageReports = iotRyHiDailyReportService.getIotRyHiDailyReportPage(pageReqVO);
|
|
|
|
|
+ if (ObjUtil.isEmpty(pageReports)) {
|
|
|
|
|
+ return success(emptyResult());
|
|
|
|
|
+ }
|
|
|
|
|
+ List<IotRyHiDailyReportDO> reports = pageReports.getList();
|
|
|
|
|
+ if (CollUtil.isEmpty(reports)) {
|
|
|
|
|
+ return success(emptyResult());
|
|
|
|
|
+ }
|
|
|
|
|
+ // 将历史日报数据按照年份 为维度 统计 进尺、完井数
|
|
|
|
|
+ // key年份 value 修井累计完井数
|
|
|
|
|
+ Map<Integer, BigDecimal> xjWellsPair = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ reports.forEach(report -> {
|
|
|
|
|
+ LocalDateTime reportDate = report.getCreateTime();
|
|
|
|
|
+ Integer year = reportDate.getYear();
|
|
|
|
|
+ String classification = report.getProjectClassification();
|
|
|
|
|
+ BigDecimal footage = report.getAnnualFootage();
|
|
|
|
|
+ BigDecimal completedWells = report.getTotalCompletedWells();
|
|
|
|
|
+ if ("2".equals(classification)) {
|
|
|
|
|
+ // 修井
|
|
|
|
|
+ if (xjWellsPair.containsKey(year)) {
|
|
|
|
|
+ BigDecimal existWells = xjWellsPair.get(year);
|
|
|
|
|
+ BigDecimal tempWells = existWells.add(completedWells);
|
|
|
|
|
+ xjWellsPair.put(year, tempWells);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ xjWellsPair.put(year, completedWells);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ LinkedList<Object> xAxis = new LinkedList<>();
|
|
|
|
|
+ LinkedList<Object> wellsData = new LinkedList<>();
|
|
|
|
|
+ xjWellsPair.forEach((k,v)->{
|
|
|
|
|
+ xAxis.add(k);
|
|
|
|
|
+ wellsData.add(v);
|
|
|
|
|
+ });
|
|
|
|
|
+ ImmutableMap<String, Serializable> wellsResult = ImmutableMap.of("name", "累计完井数~~en**finishedWells", "data", wellsData);
|
|
|
|
|
+ return success(ImmutableMap.of("xAxis", xAxis, "series", ImmutableList.of(wellsResult)));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 空数据返回结构
|
|
|
|
|
+ */
|
|
|
|
|
+ private Map<String, Object> emptyResult() {
|
|
|
|
|
+ return ImmutableMap.of(
|
|
|
|
|
+ "xAxis", Collections.emptyList(),
|
|
|
|
|
+ "series", Collections.emptyList()
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 瑞恒 设备利用率 按项目部统计
|
|
* 瑞恒 设备利用率 按项目部统计
|
|
|
* @return
|
|
* @return
|
|
@@ -3014,6 +3269,158 @@ public class IotStaticController {
|
|
|
return success(resultNptCounts);
|
|
return success(resultNptCounts);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 瑞都 生产异常 数量
|
|
|
|
|
+ * 无工作量 井场待命 维修设备 物资影响 异常/复杂
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @GetMapping("/rd/device/productionAbnormality")
|
|
|
|
|
+ @PermitAll
|
|
|
|
|
+ public CommonResult<List<NptCountVo>> productionAbnormality(IotRdDailyReportPageReqVO reqVO) {
|
|
|
|
|
+ if (ObjUtil.isEmpty(reqVO.getCreateTime())) {
|
|
|
|
|
+ throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (reqVO.getCreateTime().length < 2) {
|
|
|
|
|
+ throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 查询瑞鹰 158l 所有项目部
|
|
|
|
|
+ Set<Long> childDeptIds = deptService.getChildDeptIdListFromCache(158l);
|
|
|
|
|
+ Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(childDeptIds);
|
|
|
|
|
+ Set<String> projectDeptNames = new HashSet<>();
|
|
|
|
|
+ Set<Long> projectDeptIds = new HashSet<>();
|
|
|
|
|
+ // key项目部id value项目部名称
|
|
|
|
|
+ Map<Long, String> projectPair = new HashMap<>();
|
|
|
|
|
+ // 队伍id 集合
|
|
|
|
|
+ Set<Long> crewIds = new HashSet<>();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(allDeptPair)) {
|
|
|
|
|
+ allDeptPair.forEach((deptId, dept) -> {
|
|
|
|
|
+ if ("2".equals(dept.getType())) {
|
|
|
|
|
+ projectDeptIds.add(deptId);
|
|
|
|
|
+ projectDeptNames.add(dept.getName());
|
|
|
|
|
+ projectPair.put(deptId, dept.getName());
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("3".equals(dept.getType())) {
|
|
|
|
|
+ // 队伍
|
|
|
|
|
+ crewIds.add(dept.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // 查询出指定时间区间内 已经填写的日报数量
|
|
|
|
|
+ List<IotRdDailyReportDO> dailyReports = iotRdDailyReportMapper.dailyReports(reqVO);
|
|
|
|
|
+
|
|
|
|
|
+ List<NptCountVo> resultNptCounts = new ArrayList<>();
|
|
|
|
|
+ // no 无工作量
|
|
|
|
|
+ Map<String, Integer> noStatusPair = new HashMap<>();
|
|
|
|
|
+ // xcdm 井场待命
|
|
|
|
|
+ Map<String, Integer> dmStatusPair = new HashMap<>();
|
|
|
|
|
+ // wxz 维修设备
|
|
|
|
|
+ Map<String, Integer> wxStatusPair = new HashMap<>();
|
|
|
|
|
+ // wz 物资影响
|
|
|
|
|
+ Map<String, Integer> wzStatusPair = new HashMap<>();
|
|
|
|
|
+ // yc 异常/复杂
|
|
|
|
|
+ Map<String, Integer> ycStatusPair = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ if (CollUtil.isNotEmpty(dailyReports)) {
|
|
|
|
|
+ // 整理出每个项目部下的队伍填报的日报数量
|
|
|
|
|
+ dailyReports.forEach(report -> {
|
|
|
|
|
+ String rdStatus = report.getRdStatus();
|
|
|
|
|
+ if ("no".equals(rdStatus)) {
|
|
|
|
|
+ if (noStatusPair.containsKey("no")) {
|
|
|
|
|
+ Integer tempNum = noStatusPair.get("no");
|
|
|
|
|
+ noStatusPair.put("no", ++tempNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ noStatusPair.put("no", 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("xcdm".equals(rdStatus)) {
|
|
|
|
|
+ if (dmStatusPair.containsKey("xcdm")) {
|
|
|
|
|
+ Integer tempNum = dmStatusPair.get("xcdm");
|
|
|
|
|
+ dmStatusPair.put("xcdm", ++tempNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ dmStatusPair.put("xcdm", 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("wxz".equals(rdStatus)) {
|
|
|
|
|
+ if (wxStatusPair.containsKey("wxz")) {
|
|
|
|
|
+ Integer tempNum = wxStatusPair.get("wxz");
|
|
|
|
|
+ wxStatusPair.put("wxz", ++tempNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ wxStatusPair.put("wxz", 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("wz".equals(rdStatus)) {
|
|
|
|
|
+ if (wzStatusPair.containsKey("wz")) {
|
|
|
|
|
+ Integer tempNum = wzStatusPair.get("wz");
|
|
|
|
|
+ wzStatusPair.put("wz", ++tempNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ wzStatusPair.put("wz", 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("yc".equals(rdStatus)) {
|
|
|
|
|
+ if (ycStatusPair.containsKey("yc")) {
|
|
|
|
|
+ Integer tempNum = ycStatusPair.get("yc");
|
|
|
|
|
+ ycStatusPair.put("yc", ++tempNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ycStatusPair.put("yc", 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // 无工作量
|
|
|
|
|
+ NptCountVo noVo = new NptCountVo();
|
|
|
|
|
+ noVo.setNptName("no");
|
|
|
|
|
+ if (CollUtil.isNotEmpty(noStatusPair)) {
|
|
|
|
|
+ Integer noStatusNum = noStatusPair.get("no");
|
|
|
|
|
+ noVo.setTeamCount(noStatusNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ noVo.setTeamCount(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ resultNptCounts.add(noVo);
|
|
|
|
|
+ // 井场待命
|
|
|
|
|
+ NptCountVo dmVo = new NptCountVo();
|
|
|
|
|
+ dmVo.setNptName("xcdm");
|
|
|
|
|
+ if (CollUtil.isNotEmpty(dmStatusPair)) {
|
|
|
|
|
+ Integer dmStatusNum = dmStatusPair.get("xcdm");
|
|
|
|
|
+ dmVo.setTeamCount(dmStatusNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ dmVo.setTeamCount(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ resultNptCounts.add(dmVo);
|
|
|
|
|
+ // 维修设备
|
|
|
|
|
+ NptCountVo wxVo = new NptCountVo();
|
|
|
|
|
+ wxVo.setNptName("wxz");
|
|
|
|
|
+ if (CollUtil.isNotEmpty(wxStatusPair)) {
|
|
|
|
|
+ Integer wxStatusNum = wxStatusPair.get("wxz");
|
|
|
|
|
+ wxVo.setTeamCount(wxStatusNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ wxVo.setTeamCount(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ resultNptCounts.add(wxVo);
|
|
|
|
|
+ // 物资影响
|
|
|
|
|
+ NptCountVo wzVo = new NptCountVo();
|
|
|
|
|
+ wzVo.setNptName("wz");
|
|
|
|
|
+ if (CollUtil.isNotEmpty(wzStatusPair)) {
|
|
|
|
|
+ Integer wzStatusNum = wzStatusPair.get("wz");
|
|
|
|
|
+ wzVo.setTeamCount(wzStatusNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ wzVo.setTeamCount(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ resultNptCounts.add(wzVo);
|
|
|
|
|
+ // 异常/复杂
|
|
|
|
|
+ NptCountVo ycVo = new NptCountVo();
|
|
|
|
|
+ ycVo.setNptName("yc");
|
|
|
|
|
+ if (CollUtil.isNotEmpty(ycStatusPair)) {
|
|
|
|
|
+ Integer ycStatusNum = ycStatusPair.get("yc");
|
|
|
|
|
+ ycVo.setTeamCount(ycStatusNum);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ycVo.setTeamCount(0);
|
|
|
|
|
+ }
|
|
|
|
|
+ resultNptCounts.add(ycVo);
|
|
|
|
|
+ // 按照每种非生产时间队伍数量 降序排列
|
|
|
|
|
+ resultNptCounts.sort(Comparator.comparingInt(NptCountVo::getTeamCount).reversed());
|
|
|
|
|
+ return success(resultNptCounts);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 瑞鹰 设备利用率 按 队伍 统计
|
|
* 瑞鹰 设备利用率 按 队伍 统计
|
|
|
* @return
|
|
* @return
|
|
@@ -3191,9 +3598,29 @@ public class IotStaticController {
|
|
|
Map<Long, Long> deviceIdToDeptIdMap = new HashMap<>();
|
|
Map<Long, Long> deviceIdToDeptIdMap = new HashMap<>();
|
|
|
// key项目部id value项目部下包含的队伍的 压裂 连油 设备数量
|
|
// key项目部id value项目部下包含的队伍的 压裂 连油 设备数量
|
|
|
Map<Long, Integer> projectDevicePair = new HashMap<>();
|
|
Map<Long, Integer> projectDevicePair = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 设备利用率逻辑调整 只筛选 压裂 连油 主设备 rq_iot_device_associate
|
|
|
|
|
+ // 队伍日报中关联的主设备数量 /(队伍下所有主设备数量-封存设备数量)
|
|
|
|
|
+ Set<Long> mainDeviceIds = new HashSet<>();
|
|
|
|
|
+ Set<Long> fcMainDeviceIds = new HashSet<>();
|
|
|
|
|
+ // key设备id value设备所属部门id
|
|
|
|
|
+ Map<Long, Long> mainDeviceIdPair = new HashMap<>();
|
|
|
|
|
+ IotDeviceAssociatePageReqVO deviceAssocReqVO = new IotDeviceAssociatePageReqVO();
|
|
|
|
|
+ deviceAssocReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
|
|
|
|
+ deviceAssocReqVO.setDeptIds(childDeptIds);
|
|
|
|
|
+ PageResult<IotDeviceAssociateDO> pageResult = iotDeviceAssociateMapper.selectPage(deviceAssocReqVO);
|
|
|
|
|
+ if (ObjUtil.isNotEmpty(pageResult)) {
|
|
|
|
|
+ List<IotDeviceAssociateDO> deviceAssociates = pageResult.getList();
|
|
|
|
|
+ // 查询出所有瑞都压裂 连油主设备
|
|
|
|
|
+ deviceAssociates.forEach(assoc -> {
|
|
|
|
|
+ mainDeviceIds.add(assoc.getDeviceId());
|
|
|
|
|
+ mainDeviceIdPair.put(assoc.getDeviceId(), assoc.getDeptId());
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (CollUtil.isNotEmpty(allDeptPair)) {
|
|
if (CollUtil.isNotEmpty(allDeptPair)) {
|
|
|
allDeptPair.forEach((deptId, dept) -> {
|
|
allDeptPair.forEach((deptId, dept) -> {
|
|
|
- if (dept.getName().contains("项目部") ) {
|
|
|
|
|
|
|
+ if ("2".equals(dept.getType())) {
|
|
|
projectDeptIds.add(deptId);
|
|
projectDeptIds.add(deptId);
|
|
|
projectDeptNames.add(dept.getName());
|
|
projectDeptNames.add(dept.getName());
|
|
|
projectPair.put(deptId, dept.getName());
|
|
projectPair.put(deptId, dept.getName());
|
|
@@ -3351,67 +3778,242 @@ public class IotStaticController {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
// 日报应用前先模拟数据
|
|
// 日报应用前先模拟数据
|
|
|
- rates.clear();
|
|
|
|
|
- ProjectUtilizationRateVo ylk = new ProjectUtilizationRateVo();
|
|
|
|
|
- ylk.setProjectDeptId(331l);
|
|
|
|
|
- ylk.setProjectDeptName("伊拉克项目部");
|
|
|
|
|
- ylk.setTeamCount(4);
|
|
|
|
|
- ylk.setCumulativeDays(1216l);
|
|
|
|
|
- ylk.setConstructionDays(646);
|
|
|
|
|
- ylk.setUtilizationRate(0.5313);
|
|
|
|
|
- ProjectUtilizationRateVo xj = new ProjectUtilizationRateVo();
|
|
|
|
|
- xj.setProjectDeptId(329l);
|
|
|
|
|
- xj.setProjectDeptName("新疆项目部");
|
|
|
|
|
- xj.setTeamCount(2);
|
|
|
|
|
- xj.setCumulativeDays(852l);
|
|
|
|
|
- xj.setConstructionDays(387);
|
|
|
|
|
- xj.setUtilizationRate(0.4542);
|
|
|
|
|
- ProjectUtilizationRateVo db = new ProjectUtilizationRateVo();
|
|
|
|
|
- db.setProjectDeptId(326l);
|
|
|
|
|
- db.setProjectDeptName("东部项目部");
|
|
|
|
|
- db.setTeamCount(3);
|
|
|
|
|
- db.setCumulativeDays(912l);
|
|
|
|
|
- db.setConstructionDays(261);
|
|
|
|
|
- db.setUtilizationRate(0.2862);
|
|
|
|
|
- ProjectUtilizationRateVo qh = new ProjectUtilizationRateVo();
|
|
|
|
|
- qh.setProjectDeptId(327l);
|
|
|
|
|
- qh.setProjectDeptName("青海项目部");
|
|
|
|
|
- qh.setTeamCount(1);
|
|
|
|
|
- qh.setCumulativeDays(304l);
|
|
|
|
|
- qh.setConstructionDays(179);
|
|
|
|
|
- qh.setUtilizationRate(0.5888);
|
|
|
|
|
- ProjectUtilizationRateVo xnyl = new ProjectUtilizationRateVo();
|
|
|
|
|
- xnyl.setProjectDeptId(325l);
|
|
|
|
|
- xnyl.setProjectDeptName("西南压裂项目部");
|
|
|
|
|
- xnyl.setTeamCount(1);
|
|
|
|
|
- xnyl.setCumulativeDays(304l);
|
|
|
|
|
- xnyl.setConstructionDays(252);
|
|
|
|
|
- xnyl.setUtilizationRate(0.8289);
|
|
|
|
|
- ProjectUtilizationRateVo xnly = new ProjectUtilizationRateVo();
|
|
|
|
|
- xnly.setProjectDeptId(330l);
|
|
|
|
|
- xnly.setProjectDeptName("西南连续油管项目部");
|
|
|
|
|
- xnly.setTeamCount(3);
|
|
|
|
|
- xnly.setCumulativeDays(912l);
|
|
|
|
|
- xnly.setConstructionDays(443);
|
|
|
|
|
- xnly.setUtilizationRate(0.4857);
|
|
|
|
|
- ProjectUtilizationRateVo lby = new ProjectUtilizationRateVo();
|
|
|
|
|
- lby.setProjectDeptId(349l);
|
|
|
|
|
- lby.setProjectDeptName("利比亚项目部");
|
|
|
|
|
- lby.setTeamCount(1);
|
|
|
|
|
- lby.setCumulativeDays(304l);
|
|
|
|
|
- lby.setConstructionDays(21);
|
|
|
|
|
- lby.setUtilizationRate(0.0691);
|
|
|
|
|
- rates.add(ylk);
|
|
|
|
|
- rates.add(xj);
|
|
|
|
|
- rates.add(db);
|
|
|
|
|
- rates.add(qh);
|
|
|
|
|
- rates.add(xnyl);
|
|
|
|
|
- rates.add(xnly);
|
|
|
|
|
- rates.add(lby);
|
|
|
|
|
rates.sort(Comparator.comparingDouble(ProjectUtilizationRateVo::getUtilizationRate).reversed());
|
|
rates.sort(Comparator.comparingDouble(ProjectUtilizationRateVo::getUtilizationRate).reversed());
|
|
|
return success(rates);
|
|
return success(rates);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 瑞都 时间区间内整体的 设备利用率
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @GetMapping("/rd/device/totalUtilizationRate")
|
|
|
|
|
+ @PermitAll
|
|
|
|
|
+ public CommonResult<BigDecimal> rdTotalUtilizationRate(IotRdDailyReportPageReqVO reqVO) {
|
|
|
|
|
+ if (ObjUtil.isEmpty(reqVO.getCreateTime())) {
|
|
|
|
|
+ throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (reqVO.getCreateTime().length < 2) {
|
|
|
|
|
+ throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 计算公司整体的设备利用率
|
|
|
|
|
+ BigDecimal totalDeviceUtilization = BigDecimal.ZERO;
|
|
|
|
|
+
|
|
|
|
|
+ // 查询瑞都 163l 所有项目部
|
|
|
|
|
+ Set<Long> childDeptIds = deptService.getChildDeptIdListFromCache(163l);
|
|
|
|
|
+ Map<Long, DeptDO> allDeptPair = deptService.getDeptMap(childDeptIds);
|
|
|
|
|
+ Set<String> projectDeptNames = new HashSet<>();
|
|
|
|
|
+ Set<Long> projectDeptIds = new HashSet<>();
|
|
|
|
|
+ // key项目部id value项目部名称
|
|
|
|
|
+ Map<Long, String> projectPair = new HashMap<>();
|
|
|
|
|
+ // key项目部id value项目部包含的队伍id集合
|
|
|
|
|
+ Map<Long, Set<Long>> projectTeamPair = new HashMap<>();
|
|
|
|
|
+ // 设备ID到其所属部门ID的映射
|
|
|
|
|
+ Map<Long, Long> deviceIdToDeptIdMap = new HashMap<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 20260611 设备利用率逻辑调整 只筛选 压裂 连油 主设备 rq_iot_device_associate
|
|
|
|
|
+ // 队伍日报中关联的主设备数量 /(队伍下所有主设备数量-封存设备数量)
|
|
|
|
|
+ Set<Long> mainDeviceIds = new HashSet<>();
|
|
|
|
|
+ Set<Long> fcMainDeviceIds = new HashSet<>();
|
|
|
|
|
+ // key设备id value设备所属部门id
|
|
|
|
|
+ Map<Long, Long> mainDeviceIdPair = new HashMap<>();
|
|
|
|
|
+ IotDeviceAssociatePageReqVO deviceAssocReqVO = new IotDeviceAssociatePageReqVO();
|
|
|
|
|
+ deviceAssocReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
|
|
|
|
+ deviceAssocReqVO.setDeptIds(childDeptIds);
|
|
|
|
|
+ PageResult<IotDeviceAssociateDO> pageResult = iotDeviceAssociateMapper.selectPage(deviceAssocReqVO);
|
|
|
|
|
+ if (ObjUtil.isNotEmpty(pageResult)) {
|
|
|
|
|
+ List<IotDeviceAssociateDO> deviceAssociates = pageResult.getList();
|
|
|
|
|
+ // 查询出所有瑞都压裂 连油主设备
|
|
|
|
|
+ deviceAssociates.forEach(assoc -> {
|
|
|
|
|
+ mainDeviceIds.add(assoc.getDeviceId());
|
|
|
|
|
+ mainDeviceIdPair.put(assoc.getDeviceId(), assoc.getDeptId());
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // 过滤掉 封存 的 压裂 连油 主设备id集合
|
|
|
|
|
+ Set<Long> abDeviceIds = new HashSet<>();
|
|
|
|
|
+
|
|
|
|
|
+ if (CollUtil.isNotEmpty(allDeptPair)) {
|
|
|
|
|
+ allDeptPair.forEach((deptId, dept) -> {
|
|
|
|
|
+ if ("2".equals(dept.getType())) {
|
|
|
|
|
+ projectDeptIds.add(deptId);
|
|
|
|
|
+ projectDeptNames.add(dept.getName());
|
|
|
|
|
+ projectPair.put(deptId, dept.getName());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ // 遍历所有部门
|
|
|
|
|
+ allDeptPair.forEach((deptId, dept) -> {
|
|
|
|
|
+ // 找出每个项目部下的队伍
|
|
|
|
|
+ if (projectPair.containsKey(dept.getParentId())) {
|
|
|
|
|
+ // 获得当前部门的上级项目部
|
|
|
|
|
+ projectPair.forEach((projectDeptId, projectDept) -> {
|
|
|
|
|
+ if (projectDeptId.equals(dept.getParentId())) {
|
|
|
|
|
+ if (projectTeamPair.containsKey(projectDeptId)) {
|
|
|
|
|
+ Set<Long> teamIds = projectTeamPair.get(projectDeptId);
|
|
|
|
|
+ teamIds.add(deptId);
|
|
|
|
|
+ projectTeamPair.put(projectDeptId, teamIds);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Set<Long> teamIds = new HashSet<>();
|
|
|
|
|
+ teamIds.add(deptId);
|
|
|
|
|
+ projectTeamPair.put(projectDeptId, teamIds);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ IotDevicePageReqVO deviceReqVO = new IotDevicePageReqVO();
|
|
|
|
|
+ deviceReqVO.setDeviceIds(new ArrayList<>(mainDeviceIds));
|
|
|
|
|
+ List<IotDeviceDO> utilizeDevices = iotDeviceMapper.selectListAlone(deviceReqVO);
|
|
|
|
|
+ // 筛选出项目部下包含的队伍的设备数量
|
|
|
|
|
+ // 过滤掉 封存 的 压裂 连油 主设备
|
|
|
|
|
+ if (CollUtil.isNotEmpty(utilizeDevices)) {
|
|
|
|
|
+ utilizeDevices.forEach(device -> {
|
|
|
|
|
+ if ("fc".equals(device.getDeviceStatus())) {
|
|
|
|
|
+ fcMainDeviceIds.add(device.getId());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ abDeviceIds.add(device.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 查询出指定时间区间内 已经填写的日报 再根据设备id 进行筛选 通过设备id 建立项目部 与 日报数量之间的关联
|
|
|
|
|
+ // 判断日报中 device_ids 字段中每个设备 是否属于需要统计的 压裂 连油 设备
|
|
|
|
|
+ List<IotRdDailyReportDO> dailyReports = iotRdDailyReportMapper.dailyReports(reqVO);
|
|
|
|
|
+ // key项目部id value项目部包含的队伍指定时间区域内日报数量
|
|
|
|
|
+ Map<Long, Integer> projectReportPair = new HashMap<>();
|
|
|
|
|
+ // 日报涉及到的施工设备id集合
|
|
|
|
|
+ Set<Long> reportDeviceIds = new HashSet<>();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(dailyReports)) {
|
|
|
|
|
+ // 整理出每个项目部下的队伍填报的日报数量
|
|
|
|
|
+ dailyReports.forEach(report -> {
|
|
|
|
|
+ // 筛选出日报中施工的 设备id集合
|
|
|
|
|
+ if (CollUtil.isNotEmpty(report.getDeviceIds())) {
|
|
|
|
|
+ reportDeviceIds.addAll(report.getDeviceIds());
|
|
|
|
|
+ }
|
|
|
|
|
+ if (CollUtil.isNotEmpty(projectTeamPair)) {
|
|
|
|
|
+ projectTeamPair.forEach((projectDeptId, teamDeptIds) -> {
|
|
|
|
|
+ Set<Long> tempDeviceIds = report.getDeviceIds();
|
|
|
|
|
+ // 判断 集合 tempDeviceIds 中的任意的 ‘设备id’ 是否包含在 集合 teamDeptIds 中
|
|
|
|
|
+ // 判断tempDeviceIds中的任意设备所属部门是否在当前项目部的队伍部门中
|
|
|
|
|
+ boolean hasMatchingDevice = CollUtil.isNotEmpty(tempDeviceIds) && tempDeviceIds.stream()
|
|
|
|
|
+ .map(deviceIdToDeptIdMap::get) // 通过映射表获取设备所属部门ID
|
|
|
|
|
+ .filter(Objects::nonNull) // 过滤掉非统计范围内的设备(避免空指针)
|
|
|
|
|
+ .anyMatch(teamDeptIds::contains); // 任意设备所属部门在队伍部门中则匹配
|
|
|
|
|
+ if (hasMatchingDevice) {
|
|
|
|
|
+ if (projectReportPair.containsKey(projectDeptId)) {
|
|
|
|
|
+ Integer tempCount = projectReportPair.get(projectDeptId);
|
|
|
|
|
+ projectReportPair.put(projectDeptId, ++tempCount);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ projectReportPair.put(projectDeptId, 1);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ // 计算公司整体的设备利用率
|
|
|
|
|
+ // 指定时间范围内 日报中所有施工的设备数量/总设备数量 (A B类)
|
|
|
|
|
+ // abDeviceIds所有AB类设备 reportDeviceIds日报中用到的所有设备 交集求出日报中使用到的AB类设备
|
|
|
|
|
+ if (CollUtil.isNotEmpty(abDeviceIds) && CollUtil.isNotEmpty(reportDeviceIds)) {
|
|
|
|
|
+ // 1. 求交集:实际使用的A B类设备
|
|
|
|
|
+ Set<Long> utilizedDeviceIds = reportDeviceIds.stream()
|
|
|
|
|
+ .filter(abDeviceIds::contains)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ // 2. 计算设备利用率(实际使用设备数 / 总设备数)
|
|
|
|
|
+ // 转换为BigDecimal进行计算,保留4位小数
|
|
|
|
|
+ totalDeviceUtilization = BigDecimal.valueOf(utilizedDeviceIds.size())
|
|
|
|
|
+ .divide(BigDecimal.valueOf(abDeviceIds.size()), 4, RoundingMode.HALF_UP);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return success(totalDeviceUtilization);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 瑞都 时间区间内整体的 工作量统计
|
|
|
|
|
+ * 压裂层数 连油井数
|
|
|
|
|
+ * @return
|
|
|
|
|
+ */
|
|
|
|
|
+ @GetMapping("/rd/device/workloadStatistics")
|
|
|
|
|
+ @PermitAll
|
|
|
|
|
+ public CommonResult<Map<String, Object>> rdWorkloadStatistics(IotRdDailyReportPageReqVO reqVO) {
|
|
|
|
|
+ if (ObjUtil.isEmpty(reqVO.getCreateTime())) {
|
|
|
|
|
+ throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (reqVO.getCreateTime().length < 2) {
|
|
|
|
|
+ throw exception(IOT_DAILY_REPORT_TIME_NOT_EXISTS);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Map<String, Object> result = new HashMap<>();
|
|
|
|
|
+ result.put("layers", 0.0);
|
|
|
|
|
+ result.put("wells", 0.0);
|
|
|
|
|
+
|
|
|
|
|
+ // 查询出指定时间区间内 已经填写的日报 再根据设备id 进行筛选 通过设备id 建立项目部 与 日报数量之间的关联
|
|
|
|
|
+ // 判断日报中 device_ids 字段中每个设备 是否属于需要统计的 压裂 连油 设备
|
|
|
|
|
+ List<IotRdDailyReportDO> dailyReports = iotRdDailyReportMapper.dailyReports(reqVO);
|
|
|
|
|
+ // 日报涉及到的施工设备id集合
|
|
|
|
|
+ Set<Long> reportDeviceIds = new HashSet<>();
|
|
|
|
|
+ // key工作量标识 value累计 段数 累计施工-层
|
|
|
|
|
+ Map<String, BigDecimal> cumulativeWorkingLayersPair = new HashMap<>();
|
|
|
|
|
+ // 连油井数
|
|
|
|
|
+ Set<Long> cumulativeWells = new HashSet<>();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(dailyReports)) {
|
|
|
|
|
+ // 整理出每个项目部下的队伍填报的日报数量
|
|
|
|
|
+ dailyReports.forEach(report -> {
|
|
|
|
|
+ // 筛选出日报中施工的 设备id集合
|
|
|
|
|
+ if (CollUtil.isNotEmpty(report.getDeviceIds())) {
|
|
|
|
|
+ reportDeviceIds.addAll(report.getDeviceIds());
|
|
|
|
|
+ }
|
|
|
|
|
+ // 设置每个任务的工作量数据 单位相同的工作量值作合并处理
|
|
|
|
|
+ List<IotTaskAttrModelProperty> taskAttrs = report.getExtProperty();
|
|
|
|
|
+ // 段数 累计施工-层
|
|
|
|
|
+ BigDecimal tempTotalCumulativeWorkingLayers = BigDecimal.ZERO;
|
|
|
|
|
+ if (CollUtil.isNotEmpty(taskAttrs)) {
|
|
|
|
|
+ for (IotTaskAttrModelProperty attr : taskAttrs) {
|
|
|
|
|
+ // 工作量单位
|
|
|
|
|
+ String unit = attr.getUnit();
|
|
|
|
|
+ // 工作量属性的实际值
|
|
|
|
|
+ String actualValueStr = attr.getActualValue();
|
|
|
|
|
+ // 处理实际值:避免null或非数字字符串导致的异常
|
|
|
|
|
+ BigDecimal actualValue = BigDecimal.ZERO;
|
|
|
|
|
+ if (StrUtil.isNotBlank(actualValueStr)) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ actualValue = new BigDecimal(actualValueStr);
|
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
|
+ // 若字符串格式错误,默认按0处理(可根据业务调整)
|
|
|
|
|
+ actualValue = BigDecimal.ZERO;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if ("段数".equals(unit)) {
|
|
|
|
|
+ // 累计施工层
|
|
|
|
|
+ tempTotalCumulativeWorkingLayers = tempTotalCumulativeWorkingLayers.add(actualValue);
|
|
|
|
|
+ if (cumulativeWorkingLayersPair.containsKey("cumulativeWorkingLayers")) {
|
|
|
|
|
+ BigDecimal tempWorkingLayer = cumulativeWorkingLayersPair.get("cumulativeWorkingLayers");
|
|
|
|
|
+ cumulativeWorkingLayersPair.put("cumulativeWorkingLayers", tempTotalCumulativeWorkingLayers.add(tempWorkingLayer));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ cumulativeWorkingLayersPair.put("cumulativeWorkingLayers", tempTotalCumulativeWorkingLayers);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (ObjUtil.isNotEmpty(report.getTaskId()) && "wg".equals(report.getRdStatus())) {
|
|
|
|
|
+ cumulativeWells.add(report.getTaskId());
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ // 压裂层数
|
|
|
|
|
+ if (CollUtil.isNotEmpty(cumulativeWorkingLayersPair)) {
|
|
|
|
|
+ cumulativeWorkingLayersPair.forEach((key, layers) -> {
|
|
|
|
|
+ result.put("layers", layers);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ // 连油井数 完工 的任务井
|
|
|
|
|
+ if (CollUtil.isNotEmpty(cumulativeWells)) {
|
|
|
|
|
+ result.put("wells", cumulativeWells.size());
|
|
|
|
|
+ }
|
|
|
|
|
+ return success(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 瑞都 设备利用率 按 项目部 统计
|
|
* 瑞都 设备利用率 按 项目部 统计
|
|
|
* @return
|
|
* @return
|