|
|
|
|
@ -1,6 +1,5 @@
|
|
|
|
|
package cn.iocoder.yudao.module.mes.service.deviceledger;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.collection.CollStreamUtil;
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
|
|
|
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
|
|
|
@ -8,36 +7,33 @@ import cn.iocoder.yudao.module.common.enums.CodeTypeEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.common.enums.QrcodeBizTypeEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.common.service.qrcordrecord.QrcodeRecordService;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.autocode.util.AutoCodeUtil;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.mold.vo.MoldRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.controller.admin.product.vo.product.ErpProductRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldBrandDO;
|
|
|
|
|
import cn.iocoder.yudao.module.common.dal.dataobject.mold.MoldDO;
|
|
|
|
|
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.productdevicerel.ProductDeviceRelDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.productdevicerel.ProductDeviceRelMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceRespVO;
|
|
|
|
|
import cn.iocoder.yudao.module.iot.controller.admin.device.vo.DeviceSaveReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.iot.dal.dataobject.device.DeviceDO;
|
|
|
|
|
import cn.iocoder.yudao.module.iot.service.device.DeviceService;
|
|
|
|
|
import cn.iocoder.yudao.module.iot.service.device.TDengineService;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.devicetype.DeviceTypeDO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.organization.OrganizationDO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductUnitDO;
|
|
|
|
|
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.devicetype.DeviceTypeMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.common.dal.mysql.mold.MoldMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.dal.mysql.product.ErpProductMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.erp.service.product.ErpProductUnitService;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.controller.admin.ticketmanagement.enums.PlanTypeEnum;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.criticalcomponent.CriticalComponentDO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.dvrepair.DvRepairDO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.dvrepair.DvRepairLineDO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.ticketresults.TicketResultsDO;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.criticalcomponent.CriticalComponentMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.organization.OrganizationMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.plan.PlanMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.producereport.ProduceReportDetailMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.dvrepair.DvRepairLineMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.dvrepair.DvRepairMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.ticketresults.TicketResultsMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.mysql.workreportplan.ReportPlanSummaryMapper;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.service.organization.OrganizationService;
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
|
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
@ -48,9 +44,15 @@ import javax.annotation.Resource;
|
|
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
|
|
|
|
import java.io.UnsupportedEncodingException;
|
|
|
|
|
import java.math.BigDecimal;
|
|
|
|
|
import java.math.RoundingMode;
|
|
|
|
|
import java.time.LocalDate;
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.function.Function;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
import cn.iocoder.yudao.module.iot.dal.mysql.device.DeviceMapper;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import cn.iocoder.yudao.module.mes.controller.admin.deviceledger.vo.*;
|
|
|
|
|
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
|
|
|
|
|
@ -61,7 +63,6 @@ import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
|
|
|
|
import static cn.iocoder.yudao.module.erp.enums.ErrorCodeConstants.*;
|
|
|
|
|
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
@ -99,6 +100,27 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
|
|
|
|
|
@Resource
|
|
|
|
|
private ProductDeviceRelMapper productDeviceRelMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
@Lazy
|
|
|
|
|
private DeviceMapper deviceMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private PlanMapper planMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ProduceReportDetailMapper produceReportDetailMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ReportPlanSummaryMapper reportPlanSummaryMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
@Lazy
|
|
|
|
|
private OrganizationService organizationService;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
@Lazy
|
|
|
|
|
private OrganizationMapper organizationMapper;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private ErpProductUnitService productUnitService;
|
|
|
|
|
|
|
|
|
|
@ -114,6 +136,9 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
|
|
|
|
|
@Autowired
|
|
|
|
|
private AutoCodeUtil autoCodeUtil;
|
|
|
|
|
|
|
|
|
|
@Resource
|
|
|
|
|
private TDengineService tdengineService;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Long createDeviceLedger(DeviceLedgerSaveReqVO createReqVO) throws UnsupportedEncodingException {
|
|
|
|
|
DeviceLedgerDO deviceLedger = BeanUtils.toBean(createReqVO, DeviceLedgerDO.class);
|
|
|
|
|
@ -347,6 +372,165 @@ public class DeviceLedgerServiceImpl implements DeviceLedgerService {
|
|
|
|
|
return deviceLedgerDOPageResult;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public PageResult<DeviceCapacityReportRespVO> getDeviceCapacityReportPage(DeviceCapacityReportPageReqVO pageReqVO) {
|
|
|
|
|
DeviceLedgerPageReqVO queryReqVO = buildDeviceCapacityQuery(pageReqVO);
|
|
|
|
|
PageResult<DeviceLedgerDO> pageResult = deviceLedgerMapper.selectPage(queryReqVO);
|
|
|
|
|
List<DeviceCapacityReportRespVO> reportList = buildDeviceCapacityReportList(pageResult.getList());
|
|
|
|
|
return new PageResult<>(reportList, pageResult.getTotal());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<DeviceCapacityReportRespVO> getDeviceCapacityReportList(DeviceCapacityReportPageReqVO pageReqVO) {
|
|
|
|
|
DeviceLedgerPageReqVO queryReqVO = buildDeviceCapacityQuery(pageReqVO);
|
|
|
|
|
List<DeviceLedgerDO> list = deviceLedgerMapper.selectPage(queryReqVO).getList();
|
|
|
|
|
return buildDeviceCapacityReportList(list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private DeviceLedgerPageReqVO buildDeviceCapacityQuery(DeviceCapacityReportPageReqVO pageReqVO) {
|
|
|
|
|
DeviceLedgerPageReqVO queryReqVO = new DeviceLedgerPageReqVO();
|
|
|
|
|
queryReqVO.setPageNo(pageReqVO.getPageNo());
|
|
|
|
|
queryReqVO.setPageSize(pageReqVO.getPageSize());
|
|
|
|
|
queryReqVO.setDeviceCode(pageReqVO.getDeviceCode());
|
|
|
|
|
queryReqVO.setDeviceName(pageReqVO.getDeviceName());
|
|
|
|
|
queryReqVO.setDeviceType(pageReqVO.getDeviceType());
|
|
|
|
|
queryReqVO.setDeviceStatus(pageReqVO.getDeviceStatus() == null ? null : String.valueOf(pageReqVO.getDeviceStatus()));
|
|
|
|
|
queryReqVO.setWorkshop(pageReqVO.getWorkshop());
|
|
|
|
|
queryReqVO.setIds(pageReqVO.getIds());
|
|
|
|
|
queryReqVO.setIsScheduled(1);
|
|
|
|
|
return queryReqVO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<DeviceCapacityReportRespVO> buildDeviceCapacityReportList(List<DeviceLedgerDO> deviceList) {
|
|
|
|
|
if (CollUtil.isEmpty(deviceList)) {
|
|
|
|
|
return Collections.emptyList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Set<Long> deviceIds = deviceList.stream().map(DeviceLedgerDO::getId).filter(Objects::nonNull).collect(Collectors.toSet());
|
|
|
|
|
Set<Long> deviceTypeIds = deviceList.stream().map(DeviceLedgerDO::getDeviceType).filter(Objects::nonNull).collect(Collectors.toSet());
|
|
|
|
|
Set<Long> workshopIds = deviceList.stream()
|
|
|
|
|
.map(DeviceLedgerDO::getWorkshop)
|
|
|
|
|
.filter(StringUtils::isNotBlank)
|
|
|
|
|
.map(String::trim)
|
|
|
|
|
.filter(item -> item.matches("\\d+"))
|
|
|
|
|
.map(Long::valueOf)
|
|
|
|
|
.collect(Collectors.toSet());
|
|
|
|
|
|
|
|
|
|
Map<Long, DeviceTypeDO> deviceTypeMap = deviceTypeIds.isEmpty() ? Collections.emptyMap()
|
|
|
|
|
: deviceTypeMapper.selectBatchIds(deviceTypeIds).stream()
|
|
|
|
|
.collect(Collectors.toMap(DeviceTypeDO::getId, Function.identity(), (a, b) -> a));
|
|
|
|
|
Map<Long, OrganizationDO> organizationMap = workshopIds.isEmpty() ? Collections.emptyMap()
|
|
|
|
|
: organizationService.getMapWithDeleted(workshopIds);
|
|
|
|
|
|
|
|
|
|
List<PlanDO> planList = planMapper.selectList(new LambdaQueryWrapperX<PlanDO>()
|
|
|
|
|
.in(PlanDO::getDeviceId, deviceIds));
|
|
|
|
|
|
|
|
|
|
Map<Long, BigDecimal> reportCapacityMap = planList.stream()
|
|
|
|
|
.filter(item -> item.getDeviceId() != null)
|
|
|
|
|
.collect(Collectors.groupingBy(
|
|
|
|
|
PlanDO::getDeviceId,
|
|
|
|
|
Collectors.mapping(
|
|
|
|
|
item -> BigDecimal.valueOf(Optional.ofNullable(item.getWangongNumber()).orElse(0L)),
|
|
|
|
|
Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)
|
|
|
|
|
)
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
Map<Long, Long> machineDvMap = organizationMapper.selectList(
|
|
|
|
|
new LambdaQueryWrapper<OrganizationDO>()
|
|
|
|
|
.in(OrganizationDO::getMachineId, deviceIds)
|
|
|
|
|
.select(OrganizationDO::getMachineId, OrganizationDO::getDvId))
|
|
|
|
|
.stream()
|
|
|
|
|
.filter(item -> item.getMachineId() != null && item.getDvId() != null)
|
|
|
|
|
.collect(Collectors.toMap(
|
|
|
|
|
OrganizationDO::getMachineId,
|
|
|
|
|
OrganizationDO::getDvId,
|
|
|
|
|
(a, b) -> a
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
LocalDate endDate = LocalDate.now().minusDays(1);
|
|
|
|
|
LocalDate startDate = endDate.minusMonths(6);
|
|
|
|
|
List<LocalDate> statDays = listStatDays(startDate, endDate);
|
|
|
|
|
Map<Long, Integer> actualCapacityMap = new HashMap<>();
|
|
|
|
|
if (CollUtil.isNotEmpty(statDays)) {
|
|
|
|
|
LocalDateTime beginTime = statDays.get(0).atStartOfDay();
|
|
|
|
|
LocalDateTime endTime = statDays.get(statDays.size() - 1).plusDays(1).atStartOfDay();
|
|
|
|
|
|
|
|
|
|
Set<Long> collectDeviceIds = deviceMapper.selectList(new LambdaQueryWrapper<DeviceDO>()
|
|
|
|
|
.select(DeviceDO::getId))
|
|
|
|
|
.stream()
|
|
|
|
|
.map(DeviceDO::getId)
|
|
|
|
|
.filter(Objects::nonNull)
|
|
|
|
|
.collect(Collectors.toSet());
|
|
|
|
|
|
|
|
|
|
actualCapacityMap = queryDeviceCollectionAverageMap(collectDeviceIds, statDays, beginTime, endTime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<DeviceCapacityReportRespVO> result = new ArrayList<>();
|
|
|
|
|
for (DeviceLedgerDO device : deviceList) {
|
|
|
|
|
DeviceCapacityReportRespVO respVO = new DeviceCapacityReportRespVO();
|
|
|
|
|
respVO.setId(device.getId());
|
|
|
|
|
respVO.setDeviceCode(device.getDeviceCode());
|
|
|
|
|
respVO.setDeviceName(device.getDeviceName());
|
|
|
|
|
respVO.setDeviceStatus(device.getDeviceStatus());
|
|
|
|
|
respVO.setRatedCapacity(BigDecimal.valueOf(Optional.ofNullable(device.getRatedCapacity()).orElse(0)));
|
|
|
|
|
|
|
|
|
|
MapUtils.findAndThen(deviceTypeMap, device.getDeviceType(), item -> respVO.setTypeName(item.getName()));
|
|
|
|
|
if (StringUtils.isNotBlank(device.getWorkshop()) && device.getWorkshop().trim().matches("\\d+")) {
|
|
|
|
|
MapUtils.findAndThen(organizationMap, Long.valueOf(device.getWorkshop().trim()), item -> {
|
|
|
|
|
String workshopName = item.getName();
|
|
|
|
|
if (Boolean.TRUE.equals(item.getDeleted())) {
|
|
|
|
|
workshopName += "(已被删除)";
|
|
|
|
|
}
|
|
|
|
|
respVO.setWorkshopName(workshopName);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
respVO.setReportCapacity(reportCapacityMap.getOrDefault(device.getId(), BigDecimal.ZERO));
|
|
|
|
|
|
|
|
|
|
Long collectDeviceId = machineDvMap.get(device.getId());
|
|
|
|
|
respVO.setActualCapacity(BigDecimal.valueOf(actualCapacityMap.getOrDefault(collectDeviceId, 0)));
|
|
|
|
|
result.add(respVO);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<Long, Integer> queryDeviceCollectionAverageMap(Set<Long> deviceIds, List<LocalDate> statDays,
|
|
|
|
|
LocalDateTime beginTime, LocalDateTime endTime) {
|
|
|
|
|
Map<Long, Integer> result = new HashMap<>();
|
|
|
|
|
if (CollUtil.isEmpty(deviceIds) || CollUtil.isEmpty(statDays) || beginTime == null || endTime == null) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
Set<LocalDate> validDays = new HashSet<>(statDays);
|
|
|
|
|
Map<Long, Map<LocalDate, Double>> rawMap = tdengineService.queryDailyLatestCapacityValues(deviceIds, beginTime, endTime);
|
|
|
|
|
BigDecimal divisor = BigDecimal.valueOf(statDays.size());
|
|
|
|
|
for (Long deviceId : deviceIds) {
|
|
|
|
|
Map<LocalDate, Double> dayMap = rawMap.getOrDefault(deviceId, Collections.emptyMap());
|
|
|
|
|
BigDecimal total = BigDecimal.ZERO;
|
|
|
|
|
for (Map.Entry<LocalDate, Double> entry : dayMap.entrySet()) {
|
|
|
|
|
if (entry.getKey() == null || entry.getValue() == null || !validDays.contains(entry.getKey())) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
total = total.add(BigDecimal.valueOf(entry.getValue()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result.put(deviceId, total.divide(divisor, 0, RoundingMode.HALF_UP).intValue());
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<LocalDate> listStatDays(LocalDate startDate, LocalDate endDate) {
|
|
|
|
|
List<LocalDate> days = new ArrayList<>();
|
|
|
|
|
if (startDate == null || endDate == null || startDate.isAfter(endDate)) {
|
|
|
|
|
return days;
|
|
|
|
|
}
|
|
|
|
|
LocalDate cursor = startDate;
|
|
|
|
|
while (!cursor.isAfter(endDate)) {
|
|
|
|
|
days.add(cursor);
|
|
|
|
|
cursor = cursor.plusDays(1);
|
|
|
|
|
}
|
|
|
|
|
return days;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public List<DeviceLedgerDO> getDeviceLedgerList() {
|
|
|
|
|
return deviceLedgerMapper.selectList();
|
|
|
|
|
|