| | |
| | | import com.ruoyi.collaborativeApproval.pojo.Notice; |
| | | import com.ruoyi.common.enums.ApproveTypeEnum; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.device.mapper.DeviceRepairMapper; |
| | | import com.ruoyi.device.pojo.DeviceRepair; |
| | | import com.ruoyi.dto.MapDto; |
| | |
| | | import com.ruoyi.production.mapper.ProductWorkOrderMapper; |
| | | import com.ruoyi.production.mapper.ProductionProductInputMapper; |
| | | import com.ruoyi.production.mapper.ProductionProductOutputMapper; |
| | | import com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper; |
| | | import com.ruoyi.production.pojo.ProductWorkOrder; |
| | | import com.ruoyi.project.system.domain.SysDept; |
| | | import com.ruoyi.project.system.domain.SysUser; |
| | |
| | | import com.ruoyi.purchase.pojo.PaymentRegistration; |
| | | import com.ruoyi.purchase.pojo.PurchaseLedger; |
| | | import com.ruoyi.quality.mapper.QualityInspectMapper; |
| | | import com.ruoyi.quality.mapper.QualityUnqualifiedMapper; |
| | | import com.ruoyi.quality.pojo.QualityInspect; |
| | | import com.ruoyi.quality.pojo.QualityUnqualified; |
| | | import com.ruoyi.sales.mapper.ReceiptPaymentMapper; |
| | | import com.ruoyi.sales.mapper.SalesLedgerMapper; |
| | | import com.ruoyi.sales.mapper.SalesLedgerProductMapper; |
| | |
| | | private StockInventoryMapper stockInventoryMapper; |
| | | |
| | | @Autowired |
| | | private ProcurementRecordMapper procurementRecordStorageMapper; |
| | | |
| | | @Autowired |
| | | private QualityInspectMapper qualityStatisticsMapper; |
| | | |
| | | @Autowired |
| | |
| | | |
| | | @Autowired |
| | | private NoticeMapper noticeMapper; |
| | | |
| | | @Autowired |
| | | private ProductOrderMapper productOrderMapper; |
| | | |
| | | @Autowired |
| | | private ProductWorkOrderMapper productWorkOrderMapper; |
| | | @Autowired |
| | | private ProductModelMapper productModelMapper; |
| | | |
| | | @Autowired |
| | | private ProductMapper productMapper; |
| | | @Autowired |
| | | private StockUtils stockUtils; |
| | | |
| | | @Autowired |
| | | private StaffOnJobMapper staffOnJobMapper; |
| | | |
| | | @Autowired |
| | | private CustomerMapper customerMapper; |
| | | |
| | | @Autowired |
| | | private SupplierManageMapper supplierManageMapper; |
| | | @Autowired |
| | | private SysUserMapper sysUserMapper; |
| | | @Autowired |
| | | private SysUserDeptMapper sysUserDeptMapper; |
| | | |
| | | @Autowired |
| | | private HomeMapper homeMapper; |
| | | |
| | | @Autowired |
| | | private ProductionProductOutputMapper productionProductOutputMapper; |
| | | |
| | | @Autowired |
| | | private QualityInspectMapper qualityInspectMapper; |
| | | |
| | | @Autowired |
| | | private QualityUnqualifiedMapper qualityUnqualifiedMapper; |
| | | |
| | | @Override |
| | | public HomeBusinessDto business() { |
| | |
| | | .filter(Objects::nonNull) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | BigDecimal subtract1 = todayContractAmount.subtract(lastYearYesterdayContractAmount); // 修改:使用 |
| | | // todayContractAmount 而不是 |
| | | // yesterdayContractAmount |
| | | // todayContractAmount 而不是 |
| | | // yesterdayContractAmount |
| | | // 日环比 |
| | | String chain = ""; |
| | | if (subtract1.compareTo(BigDecimal.ZERO) == 0 |
| | |
| | | } |
| | | // 应收 |
| | | List<SalesLedger> salesLedgers = salesLedgerMapper.selectList(new LambdaQueryWrapper<SalesLedger>() |
| | | // .ge(SalesLedger::getEntryDate, startDate) |
| | | // .lt(SalesLedger::getEntryDate, endDate) |
| | | // .ge(SalesLedger::getEntryDate, startDate) |
| | | // .lt(SalesLedger::getEntryDate, endDate) |
| | | ); |
| | | // BigDecimal receivableMoney = |
| | | // salesLedgers.stream().map(SalesLedger::getContractAmount).reduce(BigDecimal.ZERO, |
| | |
| | | // 应付 |
| | | List<PurchaseLedger> procurementRecords = purchaseLedgerMapper |
| | | .selectList(new LambdaQueryWrapper<PurchaseLedger>() |
| | | // .ge(PurchaseLedger::getEntryDate, startDate) |
| | | // .lt(PurchaseLedger::getEntryDate, endDate) |
| | | // .ge(PurchaseLedger::getEntryDate, startDate) |
| | | // .lt(PurchaseLedger::getEntryDate, endDate) |
| | | ); |
| | | // BigDecimal payableMoney = |
| | | // procurementRecords.stream().map(PurchaseLedger::getContractAmount).reduce(BigDecimal.ZERO, |
| | |
| | | BigDecimal payableMoney = sumAmount(procurementRecords, PurchaseLedger::getContractAmount); |
| | | // 预收 |
| | | List<ReceiptPayment> receiptPayments = receiptPaymentMapper.selectList(new LambdaQueryWrapper<ReceiptPayment>() |
| | | // .ge(ReceiptPayment::getReceiptPaymentDate, startDate) |
| | | // .lt(ReceiptPayment::getReceiptPaymentDate, endDate) |
| | | // .ge(ReceiptPayment::getReceiptPaymentDate, startDate) |
| | | // .lt(ReceiptPayment::getReceiptPaymentDate, endDate) |
| | | ); |
| | | // BigDecimal advanceMoney = |
| | | // receiptPayments.stream().map(ReceiptPayment::getReceiptPaymentAmount).reduce(BigDecimal.ZERO, |
| | |
| | | // 预付 |
| | | List<PaymentRegistration> paymentRegistrations = paymentRegistrationMapper |
| | | .selectList(new LambdaQueryWrapper<PaymentRegistration>() |
| | | // .ge(PaymentRegistration::getPaymentDate, startDate) |
| | | // .lt(PaymentRegistration::getPaymentDate, endDate) |
| | | // .ge(PaymentRegistration::getPaymentDate, startDate) |
| | | // .lt(PaymentRegistration::getPaymentDate, endDate) |
| | | ); |
| | | // BigDecimal prepayMoney = |
| | | // paymentRegistrations.stream().map(PaymentRegistration::getCurrentPaymentAmount).reduce(BigDecimal.ZERO, |
| | |
| | | productionProgressDto.setCompletedOrderDetails(productOrderDtos); |
| | | long totalCount = productOrderDtos.size(); |
| | | long count = productOrderDtos.stream().filter( |
| | | productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(productOrderDto.getQuantity()) >= 0) |
| | | productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(productOrderDto.getQuantity()) >= 0) |
| | | .count(); |
| | | long count2 = productOrderDtos.stream() |
| | | .filter(productOrderDto -> productOrderDto.getCompleteQuantity().compareTo(BigDecimal.ZERO) == 0) |
| | |
| | | } |
| | | |
| | | @Autowired |
| | | private com.ruoyi.production.mapper.SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper; |
| | | private SalesLedgerProductionAccountingMapper salesLedgerProductionAccountingMapper; |
| | | |
| | | @Override |
| | | public List<MapDto> productionAccountingAnalysis(Integer type) { |
| | | public List<ProductionAccountingDto> productionAccountingAnalysis(Integer type) { |
| | | LocalDate today = LocalDate.now(); |
| | | LocalDate startDate; |
| | | LocalDate endDate = today; |
| | |
| | | break; |
| | | } |
| | | |
| | | String startStr = startDate.atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); |
| | | String endStr = endDate.atTime(LocalTime.MAX).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); |
| | | String startStr = startDate.atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); |
| | | |
| | | String endStr = endDate.plusDays(1).atStartOfDay().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); |
| | | |
| | | List<Map<String, Object>> wagesList = salesLedgerProductionAccountingMapper.selectDailyWagesStats(startStr, |
| | | endStr); |
| | |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | List<MapDto> result = new ArrayList<>(); |
| | | List<ProductionAccountingDto> result = new ArrayList<>(); |
| | | for (Map<String, Object> map : wagesList) { |
| | | MapDto dto = new MapDto(); |
| | | dto.setName((String) map.get("date")); |
| | | BigDecimal wages = (BigDecimal) map.get("wages"); |
| | | dto.setValue(wages != null ? wages.toString() : "0"); |
| | | ProductionAccountingDto dto = new ProductionAccountingDto(); |
| | | dto.setDateStr(map.get("dateStr").toString()); |
| | | dto.setNumberOfCompleted(((BigDecimal) map.get("numberOfCompleted")).intValue()); |
| | | dto.setAmount(map.get("amount") != null ? (BigDecimal) map.get("amount") : BigDecimal.ZERO); |
| | | dto.setPassRate(map.get("passRate") != null ? (BigDecimal) map.get("passRate") : BigDecimal.ZERO); |
| | | result.add(dto); |
| | | } |
| | | |
| | | result.sort(Comparator.comparing(MapDto::getName)); |
| | | result.sort(Comparator.comparing(ProductionAccountingDto::getDateStr)); |
| | | |
| | | return result; |
| | | } |
| | |
| | | return dto; |
| | | } |
| | | |
| | | } |
| | | |
| | | @Override |
| | | public List<QualityQualifiedAnalysisDto> rawMaterialDetection(Integer type) { |
| | | return commonDetection(type, 0); |
| | | } |
| | | |
| | | @Override |
| | | public List<QualityQualifiedAnalysisDto> processDetection(Integer type) { |
| | | return commonDetection(type, 1); |
| | | } |
| | | |
| | | @Override |
| | | public List<QualityQualifiedAnalysisDto> factoryDetection(Integer type) { |
| | | return commonDetection(type, 2); |
| | | } |
| | | |
| | | private List<QualityQualifiedAnalysisDto> commonDetection(Integer type, Integer inspectType) { |
| | | |
| | | LocalDate[] range = calcDateRange(type); |
| | | LocalDate startDate = range[0]; |
| | | LocalDate endDate = range[1]; |
| | | |
| | | String startStr = startDate.atStartOfDay() |
| | | .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); |
| | | String endStr = endDate.atTime(LocalTime.MAX) |
| | | .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); |
| | | |
| | | List<QualityInspect> list = qualityInspectMapper.selectList( |
| | | new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectType, inspectType) |
| | | .eq(QualityInspect::getInspectState, 1) |
| | | .ge(QualityInspect::getCheckTime, startStr) |
| | | .le(QualityInspect::getCheckTime, endStr)); |
| | | |
| | | return buildQualifiedAnalysis(list); |
| | | } |
| | | |
| | | private LocalDate[] calcDateRange(Integer type) { |
| | | LocalDate today = LocalDate.now(); |
| | | LocalDate startDate; |
| | | LocalDate endDate; |
| | | |
| | | switch (type) { |
| | | case 1: // 周 |
| | | startDate = today.with(DayOfWeek.MONDAY); |
| | | endDate = today.with(DayOfWeek.SUNDAY); |
| | | break; |
| | | case 2: // 月 |
| | | startDate = today.with(TemporalAdjusters.firstDayOfMonth()); |
| | | endDate = today.with(TemporalAdjusters.lastDayOfMonth()); |
| | | break; |
| | | case 3: // 季度 |
| | | int currentMonth = today.getMonthValue(); |
| | | int startMonth = ((currentMonth - 1) / 3) * 3 + 1; |
| | | startDate = LocalDate.of(today.getYear(), startMonth, 1); |
| | | endDate = LocalDate.of(today.getYear(), startMonth + 2, 1) |
| | | .with(TemporalAdjusters.lastDayOfMonth()); |
| | | break; |
| | | default: |
| | | startDate = today.with(DayOfWeek.MONDAY); |
| | | endDate = today.with(DayOfWeek.SUNDAY); |
| | | } |
| | | |
| | | return new LocalDate[]{startDate, endDate}; |
| | | } |
| | | |
| | | private List<QualityQualifiedAnalysisDto> buildQualifiedAnalysis(List<QualityInspect> list) { |
| | | List<QualityQualifiedAnalysisDto> result = new ArrayList<>(); |
| | | QualityQualifiedAnalysisDto dto = new QualityQualifiedAnalysisDto(); |
| | | |
| | | if (CollectionUtils.isEmpty(list)) { |
| | | dto.setQualifiedCount(0); |
| | | dto.setUnqualifiedCount(0); |
| | | dto.setQualifiedRate(BigDecimal.ZERO.setScale(2)); |
| | | dto.setUnqualifiedRate(BigDecimal.ZERO.setScale(2)); |
| | | result.add(dto); |
| | | return result; |
| | | } |
| | | |
| | | BigDecimal qualifiedCount = BigDecimal.ZERO; |
| | | BigDecimal unqualifiedCount = BigDecimal.ZERO; |
| | | |
| | | for (QualityInspect item : list) { |
| | | if ("合格".equals(item.getCheckResult())) { |
| | | qualifiedCount = qualifiedCount.add(item.getQuantity()); |
| | | } else { |
| | | unqualifiedCount = unqualifiedCount.add(item.getQuantity()); |
| | | } |
| | | } |
| | | |
| | | BigDecimal totalCount = qualifiedCount.add(unqualifiedCount); |
| | | |
| | | dto.setQualifiedCount(qualifiedCount.intValue()); |
| | | dto.setUnqualifiedCount(unqualifiedCount.intValue()); |
| | | |
| | | if (totalCount.compareTo(BigDecimal.ZERO) == 0) { |
| | | dto.setQualifiedRate(BigDecimal.ZERO.setScale(2)); |
| | | dto.setUnqualifiedRate(BigDecimal.ZERO.setScale(2)); |
| | | result.add(dto); |
| | | return result; |
| | | } |
| | | |
| | | BigDecimal hundred = BigDecimal.valueOf(100); |
| | | |
| | | dto.setQualifiedRate(qualifiedCount.divide(totalCount, 4, RoundingMode.HALF_UP) |
| | | .multiply(hundred) |
| | | .setScale(2, RoundingMode.HALF_UP)); |
| | | |
| | | dto.setUnqualifiedRate(unqualifiedCount.divide(totalCount, 4, RoundingMode.HALF_UP) |
| | | .multiply(hundred) |
| | | .setScale(2, RoundingMode.HALF_UP)); |
| | | |
| | | result.add(dto); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public QualityInspectionCountDto qualityInspectionCount() { |
| | | // 获取今天的开始和结束日期,包含时分秒 |
| | | LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0); |
| | | LocalDateTime todayEnd = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(0); |
| | | // 获取前一天的开始和结束日期,包含时分秒 |
| | | LocalDateTime prevStart = todayStart.minusDays(1); |
| | | LocalDateTime prevEnd = todayEnd.minusDays(1); |
| | | // 查询出截止今日的总检验数 |
| | | List<QualityInspect> todayList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | // .eq(QualityInspect::getInspectState, 1) |
| | | .le(QualityInspect::getCheckTime, todayEnd)); |
| | | // 查询出截止前一天的总检验数 |
| | | List<QualityInspect> prevList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | // .eq(QualityInspect::getInspectState, 1) |
| | | .le(QualityInspect::getCheckTime, prevEnd)); |
| | | // 计算今日的总检验数 |
| | | BigDecimal todayCount = todayList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | // 计算前一天的总检验数 |
| | | BigDecimal prevCount = prevList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | | // 计算今日相对昨天的一个总比增长 |
| | | BigDecimal growthRate = calcGrowthRate(todayCount, prevCount); |
| | | |
| | | // 计算今天的待完成数量 |
| | | List<QualityInspect> todayPendingList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 0) |
| | | .ge(QualityInspect::getCheckTime, todayStart) |
| | | .le(QualityInspect::getCheckTime, todayEnd)); |
| | | |
| | | // 计算前一天的待完成数量 |
| | | List<QualityInspect> prevPendingList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 0) |
| | | .ge(QualityInspect::getCheckTime, prevStart) |
| | | .le(QualityInspect::getCheckTime, prevEnd)); |
| | | // 计算今天的待完成数量 |
| | | BigDecimal todayPendingCount = todayPendingList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | | // 计算前一天的待完成数量 |
| | | BigDecimal prevPendingCount = prevPendingList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | // 计算今天的待完成数量相对昨天的一个同比增长 |
| | | BigDecimal todayPendingCountGrowthRate = calcGrowthRate(todayPendingCount, prevPendingCount); |
| | | // 计算今天的已完成数量 |
| | | List<QualityInspect> todayCompletedList = qualityInspectMapper |
| | | .selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 1) |
| | | .ge(QualityInspect::getCheckTime, todayStart) |
| | | .le(QualityInspect::getCheckTime, todayEnd)); |
| | | // 计算前一天的已完成数量 |
| | | List<QualityInspect> prevCompletedList = qualityInspectMapper |
| | | .selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 1) |
| | | .ge(QualityInspect::getCheckTime, prevStart) |
| | | .le(QualityInspect::getCheckTime, prevEnd)); |
| | | // 计算今天的已完成数量 |
| | | BigDecimal todayCompletedCount = todayCompletedList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | // 计算前一天的已完成数量 |
| | | BigDecimal prevCompletedCount = prevCompletedList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | // 计算今天的已完成数量相对昨天的一个同比增长 |
| | | BigDecimal todayCompletedCountGrowthRate = calcGrowthRate(todayCompletedCount, prevCompletedCount); |
| | | QualityInspectionCountDto dto = new QualityInspectionCountDto(); |
| | | dto.setTotalCount(todayCount); |
| | | dto.setTotalCountGrowthRate(growthRate); |
| | | dto.setTodayPendingCount(todayPendingCount); |
| | | dto.setTodayPendingCountGrowthRate(todayPendingCountGrowthRate); |
| | | dto.setTodayCompletedCount(todayCompletedCount); |
| | | dto.setTodayCompletedCountGrowthRate(todayCompletedCountGrowthRate); |
| | | return dto; |
| | | } |
| | | |
| | | private BigDecimal calcGrowthRate(BigDecimal today, BigDecimal prev) { |
| | | if (prev == null || prev.compareTo(BigDecimal.ZERO) == 0) { |
| | | return BigDecimal.ZERO.setScale(2); |
| | | } |
| | | return today.subtract(prev) |
| | | .divide(prev, 4, RoundingMode.HALF_UP) |
| | | .multiply(BigDecimal.valueOf(100)) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | @Override |
| | | public NonComplianceWarningDto nonComplianceWarning() { |
| | | |
| | | // 近七天时间区间 |
| | | LocalDateTime[] range = lastSevenDaysRange(); |
| | | LocalDateTime startTime = range[0]; |
| | | LocalDateTime endTime = range[1]; |
| | | |
| | | // 查询近七天已处理不合格数据 |
| | | List<QualityUnqualified> list = qualityUnqualifiedMapper.selectList( |
| | | new LambdaQueryWrapper<QualityUnqualified>() |
| | | .eq(QualityUnqualified::getInspectState, 1) |
| | | .ge(QualityUnqualified::getCheckTime, startTime) |
| | | .le(QualityUnqualified::getCheckTime, endTime)); |
| | | |
| | | NonComplianceWarningDto dto = new NonComplianceWarningDto(); |
| | | |
| | | if (CollectionUtils.isEmpty(list)) { |
| | | dto.setRawMaterialRatio(BigDecimal.ZERO); |
| | | dto.setSemiFinishedProductRatio(BigDecimal.ZERO); |
| | | dto.setFinishedProductRatio(BigDecimal.ZERO); |
| | | dto.setChildren(new ArrayList<>()); |
| | | return dto; |
| | | } |
| | | |
| | | // 查询所有产品 |
| | | List<Product> products = productMapper.selectList(null); |
| | | |
| | | Map<Long, Product> productMap = products.stream() |
| | | .collect(Collectors.toMap(Product::getId, p -> p)); |
| | | |
| | | BigDecimal rawMaterialCount = BigDecimal.ZERO; |
| | | BigDecimal semiFinishedCount = BigDecimal.ZERO; |
| | | BigDecimal finishedCount = BigDecimal.ZERO; |
| | | |
| | | List<NonComplianceWarningDto.Item> children = new ArrayList<>(); |
| | | |
| | | for (QualityUnqualified item : list) { |
| | | |
| | | BigDecimal quantity = item.getQuantity(); |
| | | Long productId = item.getProductId(); |
| | | |
| | | Product product = productMap.get(productId); |
| | | if (product == null) { |
| | | continue; |
| | | } |
| | | |
| | | // 找到产品大类 |
| | | Product parent = product.getParentId() == null |
| | | ? product |
| | | : productMap.get(product.getParentId()); |
| | | |
| | | if (parent == null) { |
| | | continue; |
| | | } |
| | | |
| | | switch (parent.getProductName()) { |
| | | case "原材料": |
| | | rawMaterialCount = rawMaterialCount.add(quantity); |
| | | break; |
| | | case "半成品": |
| | | semiFinishedCount = semiFinishedCount.add(quantity); |
| | | break; |
| | | case "成品": |
| | | finishedCount = finishedCount.add(quantity); |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | // 组装明细 |
| | | NonComplianceWarningDto.Item child = new NonComplianceWarningDto.Item(); |
| | | // child.setProductTitle(item.getProductName()); |
| | | child.setProductTitle(parent.getProductName()); |
| | | child.setDescription(item.getDefectivePhenomena()); |
| | | child.setDate(formatDate(item.getCheckTime())); |
| | | children.add(child); |
| | | } |
| | | |
| | | BigDecimal total = rawMaterialCount |
| | | .add(semiFinishedCount) |
| | | .add(finishedCount); |
| | | |
| | | dto.setRawMaterialRatio(calcRate(rawMaterialCount, total)); |
| | | dto.setSemiFinishedProductRatio(calcRate(semiFinishedCount, total)); |
| | | dto.setFinishedProductRatio(calcRate(finishedCount, total)); |
| | | dto.setChildren(children); |
| | | |
| | | return dto; |
| | | } |
| | | |
| | | private BigDecimal calcRate(BigDecimal part, BigDecimal total) { |
| | | if (total == null || total.compareTo(BigDecimal.ZERO) == 0) { |
| | | return BigDecimal.ZERO.setScale(2); |
| | | } |
| | | return part.divide(total, 4, RoundingMode.HALF_UP) |
| | | .multiply(BigDecimal.valueOf(100)) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | } |
| | | |
| | | public static String formatDate(Date date) { |
| | | if (date == null) { |
| | | return null; |
| | | } |
| | | return date.toInstant() |
| | | .atZone(ZoneId.systemDefault()) |
| | | .toLocalDate() |
| | | .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); |
| | | } |
| | | |
| | | /** |
| | | * 获取近七天的时间区间(包含今天) |
| | | */ |
| | | public static LocalDateTime[] lastSevenDaysRange() { |
| | | LocalDate today = LocalDate.now(); |
| | | |
| | | LocalDateTime startTime = today.minusDays(6).atStartOfDay(); |
| | | LocalDateTime endTime = today.atTime(23, 59, 59); |
| | | |
| | | return new LocalDateTime[]{startTime, endTime}; |
| | | } |
| | | |
| | | @Override |
| | | public List<CompletedInspectionCountDto> completedInspectionCount() { |
| | | // 近七天时间区间 |
| | | LocalDateTime[] range = lastSevenDaysRange(); |
| | | LocalDateTime startTime = range[0]; |
| | | LocalDateTime endTime = range[1]; |
| | | |
| | | // 查询近七天已完成的检验数据 |
| | | List<QualityInspect> list = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 1) |
| | | .ge(QualityInspect::getCheckTime, startTime) |
| | | .le(QualityInspect::getCheckTime, endTime)); |
| | | |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd"); |
| | | |
| | | Map<String, CompletedInspectionCountDto> resultMap = new LinkedHashMap<>(); |
| | | |
| | | for (int i = 6; i >= 0; i--) { |
| | | LocalDate date = LocalDate.now().minusDays(i); |
| | | String dateStr = date.format(formatter); |
| | | |
| | | CompletedInspectionCountDto dto = new CompletedInspectionCountDto(); |
| | | dto.setDateStr(dateStr); |
| | | dto.setQualifiedCount(BigDecimal.ZERO); |
| | | dto.setUnqualifiedCount(BigDecimal.ZERO); |
| | | dto.setPassRate(BigDecimal.ZERO); |
| | | |
| | | resultMap.put(dateStr, dto); |
| | | } |
| | | |
| | | // 累加合格 / 不合格数量 |
| | | for (QualityInspect item : list) { |
| | | |
| | | String dateStr = item.getCheckTime() |
| | | .toInstant() |
| | | .atZone(ZoneId.systemDefault()) |
| | | .toLocalDate() |
| | | .format(formatter); |
| | | |
| | | CompletedInspectionCountDto dto = resultMap.get(dateStr); |
| | | if (dto == null) { |
| | | continue; |
| | | } |
| | | |
| | | BigDecimal quantity = item.getQuantity(); |
| | | |
| | | if ("合格".equals(item.getCheckResult())) { |
| | | dto.setQualifiedCount(dto.getQualifiedCount().add(quantity)); |
| | | } else { |
| | | dto.setUnqualifiedCount(dto.getUnqualifiedCount().add(quantity)); |
| | | } |
| | | } |
| | | |
| | | // 计算合格率 |
| | | for (CompletedInspectionCountDto dto : resultMap.values()) { |
| | | BigDecimal total = dto.getQualifiedCount().add(dto.getUnqualifiedCount()); |
| | | dto.setPassRate(calcRate(dto.getQualifiedCount(), total)); |
| | | } |
| | | |
| | | return new ArrayList<>(resultMap.values()); |
| | | } |
| | | |
| | | @Override |
| | | public List<UnqualifiedProductRankDto> unqualifiedProductRanking() { |
| | | |
| | | List<QualityInspect> list = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 1)); |
| | | |
| | | if (CollectionUtils.isEmpty(list)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | Map<Long, String> productNameMap = productMapper.selectList(null) |
| | | .stream() |
| | | .collect(Collectors.toMap(Product::getId, Product::getProductName)); |
| | | |
| | | Map<Long, List<QualityInspect>> groupMap = list.stream() |
| | | .collect(Collectors.groupingBy(QualityInspect::getProductId)); |
| | | |
| | | List<UnqualifiedProductRankDto> resultList = new ArrayList<>(); |
| | | |
| | | for (Map.Entry<Long, List<QualityInspect>> entry : groupMap.entrySet()) { |
| | | |
| | | Long productId = entry.getKey(); |
| | | List<QualityInspect> items = entry.getValue(); |
| | | |
| | | BigDecimal totalCount = BigDecimal.ZERO; |
| | | BigDecimal qualifiedCount = BigDecimal.ZERO; |
| | | BigDecimal unqualifiedCount = BigDecimal.ZERO; |
| | | |
| | | for (QualityInspect item : items) { |
| | | BigDecimal qty = item.getQuantity(); |
| | | totalCount = totalCount.add(qty); |
| | | |
| | | if ("合格".equals(item.getCheckResult())) { |
| | | qualifiedCount = qualifiedCount.add(qty); |
| | | } else { |
| | | unqualifiedCount = unqualifiedCount.add(qty); |
| | | } |
| | | } |
| | | |
| | | if (totalCount.compareTo(BigDecimal.ZERO) == 0) { |
| | | continue; |
| | | } |
| | | |
| | | BigDecimal passRate = qualifiedCount |
| | | .divide(totalCount, 4, RoundingMode.HALF_UP) |
| | | .multiply(new BigDecimal("100")) |
| | | .setScale(2, RoundingMode.HALF_UP); |
| | | |
| | | UnqualifiedProductRankDto dto = new UnqualifiedProductRankDto(); |
| | | dto.setProductName(productNameMap.get(productId)); |
| | | dto.setTotalCount(totalCount); |
| | | dto.setCompletedCount(qualifiedCount); |
| | | dto.setPassRate(passRate); |
| | | |
| | | resultList.add(dto); |
| | | } |
| | | |
| | | resultList.sort(Comparator.comparing(UnqualifiedProductRankDto::getPassRate)); |
| | | |
| | | return resultList.stream().limit(5).collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | public List<MapDto> unqualifiedProductProcessingAnalysis() { |
| | | |
| | | List<QualityUnqualified> list = qualityUnqualifiedMapper.selectList(null); |
| | | if (CollectionUtils.isEmpty(list)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // 统计每种处理结果的数量 |
| | | Map<String, BigDecimal> countMap = new HashMap<>(); |
| | | for (QualityUnqualified item : list) { |
| | | if (StringUtils.isEmpty(item.getDealResult()) || item.getQuantity() == null) { |
| | | continue; |
| | | } |
| | | countMap.merge(item.getDealResult(), item.getQuantity(), BigDecimal::add); |
| | | } |
| | | |
| | | if (countMap.isEmpty()) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // 计算总数 |
| | | BigDecimal totalCount = countMap.values() |
| | | .stream() |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | | if (totalCount.compareTo(BigDecimal.ZERO) == 0) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // 按数量倒序排序 |
| | | List<Map.Entry<String, BigDecimal>> sortedList = countMap.entrySet() |
| | | .stream() |
| | | .sorted((a, b) -> b.getValue().compareTo(a.getValue())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | List<MapDto> result = new ArrayList<>(); |
| | | |
| | | int limit = Math.min(3, sortedList.size()); |
| | | BigDecimal otherCount = BigDecimal.ZERO; |
| | | |
| | | for (int i = 0; i < sortedList.size(); i++) { |
| | | Map.Entry<String, BigDecimal> entry = sortedList.get(i); |
| | | |
| | | if (i < limit) { |
| | | MapDto dto = new MapDto(); |
| | | dto.setName(entry.getKey()); |
| | | dto.setValue(entry.getValue().setScale(2, RoundingMode.HALF_UP).toPlainString()); |
| | | dto.setRate(calcRate(entry.getValue(), totalCount).toString()); |
| | | result.add(dto); |
| | | } else { |
| | | otherCount = otherCount.add(entry.getValue()); |
| | | } |
| | | } |
| | | |
| | | if (otherCount.compareTo(BigDecimal.ZERO) > 0) { |
| | | MapDto otherDto = new MapDto(); |
| | | otherDto.setName("其他"); |
| | | otherDto.setValue(otherCount.setScale(2, RoundingMode.HALF_UP).toPlainString()); |
| | | otherDto.setRate(calcRate(otherCount, totalCount).toString()); |
| | | result.add(otherDto); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | } |