| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.toolkit.ObjectUtils; |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.account.mapper.AccountExpenseMapper; |
| | | import com.ruoyi.account.mapper.AccountIncomeMapper; |
| | | import com.ruoyi.account.pojo.AccountExpense; |
| | | import com.ruoyi.home.mapper.HomeMapper; |
| | | import com.ruoyi.account.mapper.AccountExpenseMapper; |
| | | import com.ruoyi.approve.mapper.ApproveProcessMapper; |
| | | import com.ruoyi.approve.pojo.ApproveProcess; |
| | | import com.ruoyi.basic.mapper.CustomerMapper; |
| | | import com.ruoyi.basic.mapper.ProductMapper; |
| | | import com.ruoyi.basic.mapper.ProductModelMapper; |
| | | import com.ruoyi.basic.mapper.SupplierManageMapper; |
| | | import com.ruoyi.basic.pojo.Customer; |
| | | import com.ruoyi.basic.pojo.Product; |
| | |
| | | import com.ruoyi.dto.MapDto; |
| | | import com.ruoyi.framework.security.LoginUser; |
| | | import com.ruoyi.home.dto.*; |
| | | import com.ruoyi.home.mapper.HomeMapper; |
| | | import com.ruoyi.home.service.HomeService; |
| | | import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper; |
| | | import com.ruoyi.procurementrecord.pojo.ProcurementRecordStorage; |
| | | import com.ruoyi.procurementrecord.utils.StockUtils; |
| | | import com.ruoyi.production.dto.ProductOrderDto; |
| | | import com.ruoyi.production.dto.ProductWorkOrderDto; |
| | | import com.ruoyi.production.mapper.ProductOrderMapper; |
| | | import com.ruoyi.production.mapper.ProductProcessMapper; |
| | | 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.ProductProcess; |
| | | import com.ruoyi.production.pojo.ProductWorkOrder; |
| | | import com.ruoyi.production.mapper.*; |
| | | import com.ruoyi.production.pojo.*; |
| | | import com.ruoyi.production.service.*; |
| | | import com.ruoyi.productionPlan.enums.AddressRegionEnum; |
| | | import com.ruoyi.productionPlan.mapper.SalesDeliveryMapper; |
| | | import com.ruoyi.productionPlan.pojo.SalesDelivery; |
| | | import com.ruoyi.productionPlan.pojo.ProductionPlan; |
| | | import com.ruoyi.productionPlan.service.ProductionPlanService; |
| | | import com.ruoyi.project.system.domain.SysDept; |
| | | import com.ruoyi.project.system.domain.SysDictData; |
| | | import com.ruoyi.project.system.mapper.SysDeptMapper; |
| | | import com.ruoyi.project.system.mapper.SysDictDataMapper; |
| | | import com.ruoyi.purchase.mapper.PaymentRegistrationMapper; |
| | | import com.ruoyi.purchase.mapper.PurchaseLedgerMapper; |
| | | import com.ruoyi.purchase.pojo.PaymentRegistration; |
| | |
| | | import com.ruoyi.sales.pojo.ReceiptPayment; |
| | | import com.ruoyi.sales.pojo.SalesLedger; |
| | | import com.ruoyi.sales.pojo.SalesLedgerProduct; |
| | | import com.ruoyi.production.utils.UnitUtils; |
| | | import com.ruoyi.staff.mapper.StaffOnJobMapper; |
| | | import com.ruoyi.staff.pojo.StaffOnJob; |
| | | import com.ruoyi.stock.mapper.StockInventoryMapper; |
| | | import com.ruoyi.energy.mapper.EnergyMapper; |
| | | import com.ruoyi.energy.pojo.Energy; |
| | | import com.ruoyi.energy.dto.EnergyCostDto; |
| | | import com.ruoyi.energy.mapper.EnergyConsumptionDetailMapper; |
| | | import com.ruoyi.energy.vo.EnergyStatisticsVo; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | |
| | | private QualityInspectMapper qualityInspectMapper; |
| | | |
| | | @Autowired |
| | | private EnergyConsumptionDetailMapper energyConsumptionDetailMapper; |
| | | |
| | | @Autowired |
| | | private QualityUnqualifiedMapper qualityUnqualifiedMapper; |
| | | |
| | | @Autowired |
| | | private ProductProcessMapper productProcessMapper; |
| | | |
| | | @Autowired |
| | | private AccountExpenseMapper accountExpenseMapper; |
| | | |
| | | @Autowired |
| | | private AccountIncomeMapper accountIncomeMapper; |
| | | |
| | | @Autowired |
| | | private SalesDeliveryMapper salesDeliveryMapper; |
| | | |
| | | @Autowired |
| | | private EnergyMapper energyMapper; |
| | | |
| | | |
| | | @Override |
| | | public HomeBusinessDto business() { |
| | |
| | | LambdaQueryWrapper<PurchaseLedger> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.ge(PurchaseLedger::getEntryDate, currentMonth.atDay(1).atStartOfDay()) // 大于等于本月第一天 |
| | | .lt(PurchaseLedger::getEntryDate, currentMonth.plusMonths(1).atDay(1).atStartOfDay()); // 小于下月第一天 |
| | | // 执行查询并计算总和 |
| | | |
| | | List<PurchaseLedger> purchaseLedgers = purchaseLedgerMapper.selectList(queryWrapper); |
| | | if (!CollectionUtils.isEmpty(purchaseLedgers)) { |
| | | LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductMapperLambdaQueryWrapperCopy = new LambdaQueryWrapper<SalesLedgerProduct>(); |
| | | salesLedgerProductMapperLambdaQueryWrapperCopy.eq(SalesLedgerProduct::getType, 2) |
| | | LambdaQueryWrapper<SalesLedgerProduct> salesLedgerProductMapperLambdaQueryWrapperCopy = new LambdaQueryWrapper<>(); |
| | | salesLedgerProductMapperLambdaQueryWrapperCopy.eq(SalesLedgerProduct::getType, 2) // 采购类型 |
| | | .in(SalesLedgerProduct::getSalesLedgerId, |
| | | purchaseLedgers.stream().map(PurchaseLedger::getId).collect(Collectors.toList())); |
| | | |
| | | List<SalesLedgerProduct> salesLedgerProductsCopy = salesLedgerProductMapper |
| | | .selectList(salesLedgerProductMapperLambdaQueryWrapperCopy); |
| | | // 合计合同金额 |
| | | |
| | | // 合计合同总金额 |
| | | BigDecimal receiveAmount = purchaseLedgers.stream() |
| | | .map(PurchaseLedger::getContractAmount) |
| | | .filter(Objects::nonNull) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | // 未开票金额 |
| | | |
| | | // 待付款总金额 |
| | | BigDecimal unReceiptPaymentAmount = salesLedgerProductsCopy.stream() |
| | | .map(SalesLedgerProduct::getNoInvoiceAmount) |
| | | .map(SalesLedgerProduct::getPendingTicketsTotal) |
| | | .filter(Objects::nonNull) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | | homeBusinessDto.setMonthPurchaseMoney(receiveAmount.setScale(2, RoundingMode.HALF_UP).toString()); |
| | | homeBusinessDto |
| | | .setMonthPurchaseHaveMoney(unReceiptPaymentAmount.setScale(2, RoundingMode.HALF_UP).toString()); |
| | | homeBusinessDto.setMonthPurchaseHaveMoney(unReceiptPaymentAmount.setScale(2, RoundingMode.HALF_UP).toString()); |
| | | } |
| | | // 统计库存 |
| | | BigDecimal stockQuantityTotal = stockInventoryMapper.selectTotal(); |
| | |
| | | // 当月的结束日期(每月最后一天) |
| | | LocalDate monthEnd = currentMonth.withDayOfMonth(currentMonth.lengthOfMonth()); |
| | | |
| | | // 构建当月的查询条件(如果想一次性查全4个月数据再内存筛选,可优化为先查全再循环筛选) |
| | | // 构建当月的查询条件 |
| | | LambdaQueryWrapper<QualityInspect> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.ge(QualityInspect::getCheckTime, monthStart) |
| | | .le(QualityInspect::getCheckTime, monthEnd); // 筛选当月数据 |
| | | queryWrapper.ge(QualityInspect::getCheckTime, monthStart.toString()) |
| | | .le(QualityInspect::getCheckTime, monthEnd.toString()); |
| | | List<QualityInspect> monthInspects = qualityStatisticsMapper.selectList(queryWrapper); |
| | | BigDecimal reduce = monthInspects.stream() |
| | | .filter(inspect -> inspect.getInspectType().equals(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) |
| | |
| | | |
| | | @Override |
| | | public List<MapDto> salesPurchaseStorageProductCount() { |
| | | LocalDate now = LocalDate.now(); |
| | | DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | LocalDateTime now = LocalDateTime.now(); |
| | | LocalDateTime currentMonthStart = now.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN); |
| | | LocalDateTime lastMonth = now.minusMonths(1); |
| | | LocalDateTime lastMonthStart = lastMonth.with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN); |
| | | LocalDateTime lastMonthEnd = lastMonth.with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX); |
| | | |
| | | String currentMonthStart = now.with(TemporalAdjusters.firstDayOfMonth()).format(dtf); |
| | | String currentMonthNow = now.format(dtf); |
| | | |
| | | LocalDate lastMonth = now.minusMonths(1); |
| | | String lastMonthStart = lastMonth.with(TemporalAdjusters.firstDayOfMonth()).format(dtf); |
| | | String lastMonthEnd = lastMonth.with(TemporalAdjusters.lastDayOfMonth()).format(dtf); |
| | | |
| | | // 销售 |
| | | int currentSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, currentMonthStart, |
| | | currentMonthNow); |
| | | // 销售 |
| | | int currentSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, currentMonthStart, now); |
| | | int lastSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, lastMonthStart, lastMonthEnd); |
| | | |
| | | // 采购 |
| | | int currentPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, currentMonthStart, |
| | | currentMonthNow); |
| | | // 采购 |
| | | int currentPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, currentMonthStart, now); |
| | | int lastPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, lastMonthStart, lastMonthEnd); |
| | | |
| | | // 储存 |
| | | int currentStorage = stockInventoryMapper.selectStorageProductCountByDate(currentMonthStart, currentMonthNow); |
| | | // 储存 |
| | | int currentStorage = stockInventoryMapper.selectStorageProductCountByDate(currentMonthStart, now); |
| | | int lastStorage = stockInventoryMapper.selectStorageProductCountByDate(lastMonthStart, lastMonthEnd); |
| | | |
| | | List<MapDto> list = new ArrayList<>(); |
| | |
| | | public List<MapDto> productTurnoverDays() { |
| | | return homeMapper.productTurnoverDays(); |
| | | } |
| | | |
| | | @Autowired |
| | | private AccountExpenseMapper accountExpenseMapper; |
| | | |
| | | @Autowired |
| | | private AccountIncomeMapper accountIncomeMapper; |
| | | |
| | | public List<Map<String, Object>> incomeExpenseAnalysis(Integer type) { |
| | | |
| | |
| | | String startStr = startDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); |
| | | String endStr = endDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); |
| | | |
| | | // List<IncomeExpenseAnalysisDto> incomeList = |
| | | // salesLedgerMapper.selectIncomeStats(startStr, endStr, dateFormat); |
| | | List<IncomeExpenseAnalysisDto> incomeList = new ArrayList<>(); |
| | | List<IncomeExpenseAnalysisDto> purchaseList = purchaseLedgerMapper.selectPurchaseStats(startStr, endStr, |
| | | dateFormat); |
| | | List<IncomeExpenseAnalysisDto> expenseList = accountExpenseMapper.selectAccountExpenseStats(startStr, endStr, |
| | | dateFormat); |
| | | List<IncomeExpenseAnalysisDto> incomeList = accountIncomeMapper.selectIncomeStats(startStr, endStr, dateFormat); |
| | | List<IncomeExpenseAnalysisDto> expenseList = accountExpenseMapper.selectAccountExpenseStats(startStr, endStr, dateFormat); |
| | | |
| | | Map<String, BigDecimal> incomeMap = incomeList.stream().collect(Collectors |
| | | .toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add)); |
| | | Map<String, BigDecimal> purchaseMap = purchaseList.stream().collect(Collectors |
| | | .toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add)); |
| | | Map<String, BigDecimal> expenseMap = expenseList.stream().collect(Collectors |
| | | .toMap(IncomeExpenseAnalysisDto::getDateStr, IncomeExpenseAnalysisDto::getAmount, BigDecimal::add)); |
| | | |
| | | List<MapDto> result = new ArrayList<>(); |
| | | |
| | | for (String month : months) { |
| | | MapDto dto = new MapDto(); |
| | | dto.setName(month); |
| | | |
| | | BigDecimal income = incomeMap.getOrDefault(month, BigDecimal.ZERO); |
| | | |
| | | BigDecimal purchase = purchaseMap.getOrDefault(month, BigDecimal.ZERO); |
| | | income = BigDecimal.ZERO; |
| | | BigDecimal expense = expenseMap.getOrDefault(month, BigDecimal.ZERO); |
| | | BigDecimal totalExpense = purchase.add(expense); |
| | | |
| | | BigDecimal profit = income.subtract(totalExpense); |
| | | |
| | | BigDecimal profit = income.subtract(expense); |
| | | dto.setValue(profit.setScale(2, RoundingMode.HALF_UP).toString()); |
| | | result.add(dto); |
| | | } |
| | |
| | | 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")); |
| | | String startStr = startDate.toString(); |
| | | String endStr = endDate.toString(); |
| | | |
| | | List<QualityInspect> list = qualityInspectMapper.selectList( |
| | | new LambdaQueryWrapper<QualityInspect>() |
| | |
| | | endDate = today.with(DayOfWeek.SUNDAY); |
| | | } |
| | | |
| | | return new LocalDate[] { startDate, endDate }; |
| | | return new LocalDate[]{startDate, endDate}; |
| | | } |
| | | |
| | | private QualityQualifiedAnalysisDto buildQualifiedAnalysis(List<QualityInspect> list) { |
| | |
| | | |
| | | @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); |
| | | String todayStr = LocalDate.now().toString(); |
| | | String prevDayStr = LocalDate.now().minusDays(1).toString(); |
| | | // 查询出截止今日的总检验数 |
| | | List<QualityInspect> todayList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | // .eq(QualityInspect::getInspectState, 1) |
| | | .le(QualityInspect::getCheckTime, todayEnd)); |
| | | .le(QualityInspect::getCheckTime, todayStr)); |
| | | // 查询出截止前一天的总检验数 |
| | | List<QualityInspect> prevList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | // .eq(QualityInspect::getInspectState, 1) |
| | | .le(QualityInspect::getCheckTime, prevEnd)); |
| | | .le(QualityInspect::getCheckTime, prevDayStr)); |
| | | // 计算今日的总检验数 |
| | | BigDecimal todayCount = todayList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | |
| | | // 计算今天的待完成数量 |
| | | List<QualityInspect> todayPendingList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 0) |
| | | .ge(QualityInspect::getCheckTime, todayStart) |
| | | .le(QualityInspect::getCheckTime, todayEnd)); |
| | | .eq(QualityInspect::getCheckTime, todayStr)); |
| | | |
| | | // 计算前一天的待完成数量 |
| | | List<QualityInspect> prevPendingList = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 0) |
| | | .ge(QualityInspect::getCheckTime, prevStart) |
| | | .le(QualityInspect::getCheckTime, prevEnd)); |
| | | .eq(QualityInspect::getCheckTime, prevDayStr)); |
| | | // 计算今天的待完成数量 |
| | | BigDecimal todayPendingCount = todayPendingList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | |
| | | List<QualityInspect> todayCompletedList = qualityInspectMapper |
| | | .selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 1) |
| | | .ge(QualityInspect::getCheckTime, todayStart) |
| | | .le(QualityInspect::getCheckTime, todayEnd)); |
| | | .eq(QualityInspect::getCheckTime, todayStr)); |
| | | // 计算前一天的已完成数量 |
| | | List<QualityInspect> prevCompletedList = qualityInspectMapper |
| | | .selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 1) |
| | | .ge(QualityInspect::getCheckTime, prevStart) |
| | | .le(QualityInspect::getCheckTime, prevEnd)); |
| | | .eq(QualityInspect::getCheckTime, prevDayStr)); |
| | | // 计算今天的已完成数量 |
| | | BigDecimal todayCompletedCount = todayCompletedList.stream() |
| | | .map(QualityInspect::getQuantity) |
| | |
| | | |
| | | @Override |
| | | public NonComplianceWarningDto nonComplianceWarning() { |
| | | |
| | | // 近七天时间区间 |
| | | LocalDateTime[] range = lastSevenDaysRange(); |
| | | LocalDateTime startTime = range[0]; |
| | | LocalDateTime endTime = range[1]; |
| | | String[] range = lastSevenDaysDateRange(); |
| | | String startStr = range[0]; |
| | | String endStr = range[1]; |
| | | |
| | | // 查询近七天已处理不合格数据 |
| | | List<QualityUnqualified> list = qualityUnqualifiedMapper.selectList( |
| | | new LambdaQueryWrapper<QualityUnqualified>() |
| | | .eq(QualityUnqualified::getInspectState, 1) |
| | | .ge(QualityUnqualified::getCheckTime, startTime) |
| | | .le(QualityUnqualified::getCheckTime, endTime)); |
| | | .ge(QualityUnqualified::getCheckTime, startStr) |
| | | .le(QualityUnqualified::getCheckTime, endStr)); |
| | | |
| | | NonComplianceWarningDto dto = new NonComplianceWarningDto(); |
| | | |
| | |
| | | } |
| | | |
| | | /** |
| | | * 获取近七天的时间区间(包含今天) |
| | | * 获取近七天的日期区间(仅含年月日) |
| | | */ |
| | | public static LocalDateTime[] lastSevenDaysRange() { |
| | | public static String[] lastSevenDaysDateRange() { |
| | | LocalDate today = LocalDate.now(); |
| | | |
| | | LocalDateTime startTime = today.minusDays(6).atStartOfDay(); |
| | | LocalDateTime endTime = today.atTime(23, 59, 59); |
| | | |
| | | return new LocalDateTime[] { startTime, endTime }; |
| | | return new String[]{today.minusDays(6).toString(), today.toString()}; |
| | | } |
| | | |
| | | @Override |
| | | public List<CompletedInspectionCountDto> completedInspectionCount() { |
| | | // 近七天时间区间 |
| | | LocalDateTime[] range = lastSevenDaysRange(); |
| | | LocalDateTime startTime = range[0]; |
| | | LocalDateTime endTime = range[1]; |
| | | String[] range = lastSevenDaysDateRange(); |
| | | String startStr = range[0]; |
| | | String endStr = range[1]; |
| | | |
| | | // 查询近七天已完成的检验数据 |
| | | List<QualityInspect> list = qualityInspectMapper.selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .eq(QualityInspect::getInspectState, 1) |
| | | .ge(QualityInspect::getCheckTime, startTime) |
| | | .le(QualityInspect::getCheckTime, endTime)); |
| | | .ge(QualityInspect::getCheckTime, startStr) |
| | | .le(QualityInspect::getCheckTime, endStr)); |
| | | |
| | | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd"); |
| | | |
| | |
| | | |
| | | List<QualityInspect> qualityInspectList = qualityInspectMapper |
| | | .selectList(new LambdaQueryWrapper<QualityInspect>() |
| | | .ge(QualityInspect::getCheckTime, startDate) |
| | | .le(QualityInspect::getCheckTime, endDate) |
| | | .ge(QualityInspect::getCheckTime, startDate.toString()) |
| | | .le(QualityInspect::getCheckTime, endDate.toString()) |
| | | .eq(QualityInspect::getInspectState, 1)); |
| | | |
| | | QualityStatisticsDto dto = new QualityStatisticsDto(); |
| | |
| | | Map<String, List<QualityInspect>> groupedByCheckResult = qualityInspectList.stream() |
| | | .collect(Collectors.groupingBy(QualityInspect::getCheckResult)); |
| | | List<QualityInspect> qualityInspects = groupedByCheckResult.get("不合格"); |
| | | if (ObjectUtils.isNull(qualityInspects) || qualityInspects.size() == 0) { |
| | | return null; |
| | | } |
| | | // 4. 处理图表项 (Item) |
| | | List<QualityStatisticsItem> itemList = new ArrayList<>(); |
| | | |
| | |
| | | |
| | | @Override |
| | | public List<processDataProductionStatisticsDto> processDataProductionStatistics(Integer type, |
| | | List<Long> processIds) { |
| | | List<Long> processIds) { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Long userId = SecurityUtils.isAdmin(loginUser.getUserId()) ? null : loginUser.getUserId(); |
| | | |
| | |
| | | |
| | | return productProcessMapper.calculateProductionStatistics(startDateTime, endDateTime, userId, processIds); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Long> total() { |
| | | Map<String, Long> map = new HashMap<>(); |
| | | List<SalesDelivery> salesDeliveries = salesDeliveryMapper.selectList(null); |
| | | //总销售金额 |
| | | BigDecimal sum = salesDeliveries.stream() |
| | | .map(item -> item.getPrice() != null ? new BigDecimal(item.getPrice().toString()) : BigDecimal.ZERO) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | long finalPrice = sum.divide(new BigDecimal("10000"), 0, RoundingMode.HALF_UP).longValue(); |
| | | map.put("price", finalPrice);//单位w |
| | | //总发货单 |
| | | map.put("delivery", (long) salesDeliveries.size()); |
| | | //总销售方数 |
| | | BigDecimal volume = salesDeliveries.stream() |
| | | .map(item -> item.getVolume() != null ? new BigDecimal(item.getVolume().toString()) : BigDecimal.ZERO) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | long finalVolume = volume.divide(new BigDecimal("1000"), 0, RoundingMode.HALF_UP).longValue(); |
| | | map.put("volume", finalVolume); |
| | | //累计客户 |
| | | Long count = customerMapper.selectCount(null); |
| | | map.put("customer", count); |
| | | return map; |
| | | } |
| | | |
| | | @Override |
| | | public SalesTotalDto salesAnalysis(SalesDeliveryDto salesDeliveryDto) { |
| | | SalesTotalDto salesTotalDto = new SalesTotalDto(); |
| | | List<LocalDate> dates = convertDateList(salesDeliveryDto.getDays()); |
| | | List<Map<String, Long>> maps = new ArrayList<>(); |
| | | List<SalesDelivery> salesDeliveries = salesDeliveryMapper.selectList(Wrappers.<SalesDelivery>lambdaQuery() |
| | | .eq(SalesDelivery::getProductName, salesDeliveryDto.getType())); |
| | | for (LocalDate date : dates) { |
| | | LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth()); |
| | | LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth()); |
| | | if (salesDeliveryDto.getDays().equals("年")) { |
| | | lastDay = date.with(TemporalAdjusters.lastDayOfYear()); |
| | | } |
| | | LocalDate finalLastDay = lastDay; |
| | | salesDeliveries = salesDeliveries |
| | | .stream() |
| | | .filter(delivery -> { |
| | | LocalDate deliveryDate = delivery.getDeliveryDate(); |
| | | return !deliveryDate.isBefore(firstDay) && !deliveryDate.isAfter(finalLastDay); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | Map<String, Long> regionCountMap = Arrays.stream(AddressRegionEnum.values()) |
| | | .collect(Collectors.toMap( |
| | | AddressRegionEnum::getRegionName, // 区域名作为key |
| | | enumItem -> 0L // 初始值全部为0 |
| | | )); |
| | | if (!CollectionUtils.isEmpty(salesDeliveries)) { |
| | | // 按区域分组,统计每个区域的销量总和 |
| | | regionCountMap = salesDeliveries.stream() |
| | | .filter(delivery -> delivery.getDeliveryPlace() != null) |
| | | .collect(Collectors.groupingBy( |
| | | delivery -> { |
| | | AddressRegionEnum regionEnum = AddressRegionEnum.matchRegion(delivery.getDeliveryPlace()); |
| | | return regionEnum != null ? regionEnum.getRegionName() : null; |
| | | }, |
| | | Collectors.summingLong(delivery -> delivery.getVolume() != null ? delivery.getVolume().longValue() : 0L) |
| | | )); |
| | | } |
| | | regionCountMap.put("全部", salesDeliveries.stream() |
| | | .mapToLong(item -> item.getVolume() != null ? item.getVolume().longValue() : 0L) |
| | | .sum()); |
| | | maps.add(regionCountMap); |
| | | } |
| | | salesTotalDto.setDates(dates); |
| | | salesTotalDto.setCustomerTrends(maps); |
| | | return salesTotalDto; |
| | | } |
| | | |
| | | @Override |
| | | public List<SalesTotalDetailDto> salesRanking(SalesDeliveryDto salesDeliveryDto) { |
| | | List<SalesTotalDetailDto> salesTotalDetailDtos = new ArrayList<>(); |
| | | List<LocalDate> dates = convertDateList(salesDeliveryDto.getDays()); |
| | | List<SalesDelivery> salesDeliveries = salesDeliveryMapper.selectList(Wrappers.<SalesDelivery>lambdaQuery() |
| | | .eq(SalesDelivery::getProductName, salesDeliveryDto.getType())); |
| | | for (LocalDate date : dates) { |
| | | LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth()); |
| | | LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth()); |
| | | if (salesDeliveryDto.getDays().equals("年")) { |
| | | lastDay = date.with(TemporalAdjusters.lastDayOfYear()); |
| | | } |
| | | LocalDate finalLastDay = lastDay; |
| | | salesDeliveries = salesDeliveries |
| | | .stream() |
| | | .filter(delivery -> { |
| | | LocalDate deliveryDate = delivery.getDeliveryDate(); |
| | | return !deliveryDate.isBefore(firstDay) && !deliveryDate.isAfter(finalLastDay); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | Map<String, Long> regionCountMap = Arrays.stream(AddressRegionEnum.values()) |
| | | .collect(Collectors.toMap( |
| | | AddressRegionEnum::getRegionName, // 区域名作为key |
| | | enumItem -> 0L // 初始值全部为0 |
| | | )); |
| | | if (!CollectionUtils.isEmpty(salesDeliveries)) { |
| | | // 按区域分组,统计每个区域的销量总和 |
| | | regionCountMap = salesDeliveries.stream() |
| | | .filter(delivery -> delivery.getDeliveryPlace() != null) |
| | | .collect(Collectors.groupingBy( |
| | | delivery -> { |
| | | AddressRegionEnum regionEnum = AddressRegionEnum.matchRegion(delivery.getDeliveryPlace()); |
| | | return regionEnum != null ? regionEnum.getRegionName() : null; |
| | | }, |
| | | Collectors.summingLong(delivery -> delivery.getVolume() != null ? delivery.getVolume().longValue() : 0L) |
| | | )); |
| | | } |
| | | regionCountMap.put("全部", salesDeliveries.stream() |
| | | .mapToLong(item -> item.getVolume() != null ? item.getVolume().longValue() : 0L) |
| | | .sum()); |
| | | SalesTotalDetailDto salesTotalDetailDto = new SalesTotalDetailDto(); |
| | | salesTotalDetailDto.setDate(date); |
| | | salesTotalDetailDto.setType(salesDeliveryDto.getType()); |
| | | salesTotalDetailDtos.add(salesTotalDetailDto); |
| | | } |
| | | return salesTotalDetailDtos; |
| | | } |
| | | |
| | | @Override |
| | | public SalesTotalDto salesAmount(SalesDeliveryDto salesDeliveryDto) { |
| | | SalesTotalDto salesTotalDto = new SalesTotalDto(); |
| | | List<LocalDate> dates = convertDateList(salesDeliveryDto.getDays()); |
| | | List<Map<String, Long>> maps = new ArrayList<>(); |
| | | List<SalesDelivery> salesDeliveries = salesDeliveryMapper.selectList(Wrappers.<SalesDelivery>lambdaQuery() |
| | | .eq(SalesDelivery::getProductName, salesDeliveryDto.getType())); |
| | | for (LocalDate date : dates) { |
| | | LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth()); |
| | | LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth()); |
| | | if (salesDeliveryDto.getDays().equals("年")) { |
| | | lastDay = date.with(TemporalAdjusters.lastDayOfYear()); |
| | | } |
| | | LocalDate finalLastDay = lastDay; |
| | | salesDeliveries = salesDeliveries |
| | | .stream() |
| | | .filter(delivery -> { |
| | | LocalDate deliveryDate = delivery.getDeliveryDate(); |
| | | return !deliveryDate.isBefore(firstDay) && !deliveryDate.isAfter(finalLastDay); |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | Map<String, Long> regionCountMap = Arrays.stream(AddressRegionEnum.values()) |
| | | .collect(Collectors.toMap( |
| | | AddressRegionEnum::getRegionName, // 区域名作为key |
| | | enumItem -> 0L // 初始值全部为0 |
| | | )); |
| | | if (!CollectionUtils.isEmpty(salesDeliveries)) { |
| | | // 按区域分组,统计每个区域的销量总和 |
| | | regionCountMap = salesDeliveries.stream() |
| | | .filter(delivery -> delivery.getDeliveryPlace() != null) |
| | | .collect(Collectors.groupingBy( |
| | | delivery -> { |
| | | AddressRegionEnum regionEnum = AddressRegionEnum.matchRegion(delivery.getDeliveryPlace()); |
| | | return regionEnum != null ? regionEnum.getRegionName() : null; |
| | | }, |
| | | Collectors.summingLong(delivery -> delivery.getPrice() != null ? delivery.getPrice().longValue() : 0L) |
| | | )); |
| | | } |
| | | regionCountMap.put("全部", salesDeliveries.stream() |
| | | .mapToLong(item -> item.getPrice() != null ? item.getPrice().longValue() : 0L) |
| | | .sum()); |
| | | maps.add(regionCountMap); |
| | | } |
| | | salesTotalDto.setDates(dates); |
| | | salesTotalDto.setCustomerTrends(maps); |
| | | return salesTotalDto; |
| | | } |
| | | |
| | | @Override |
| | | public List<SalesTotalDetailDto> salesDataRanking(SalesDeliveryDto salesDeliveryDto) { |
| | | List<SalesTotalDetailDto> salesTotalDetailDtos = new ArrayList<>(); |
| | | List<LocalDate> dates = convertDateList(salesDeliveryDto.getDays()); |
| | | |
| | | return salesTotalDetailDtos; |
| | | } |
| | | |
| | | @Override |
| | | public SalesTotalDto customerTrends(SalesDeliveryDto salesDeliveryDto) { |
| | | SalesTotalDto salesTotalDto = new SalesTotalDto(); |
| | | List<LocalDate> dates = convertDateList(salesDeliveryDto.getDays()); |
| | | List<Map<String, Long>> maps = new ArrayList<>(); |
| | | for (LocalDate date : dates) { |
| | | LocalDate firstDay = date.with(TemporalAdjusters.firstDayOfMonth()); |
| | | LocalDate lastDay = date.with(TemporalAdjusters.lastDayOfMonth()); |
| | | if (salesDeliveryDto.getDays().equals("年")) { |
| | | lastDay = date.with(TemporalAdjusters.lastDayOfYear()); |
| | | } |
| | | Date startDate = Date.from(firstDay.atStartOfDay(ZoneId.systemDefault()).toInstant()); |
| | | Date endDate = Date.from(lastDay.atTime(23, 59, 59).atZone(ZoneId.systemDefault()).toInstant()); |
| | | List<Customer> customers = customerMapper.selectList(Wrappers.<Customer>lambdaQuery() |
| | | .between(Customer::getMaintenanceTime, startDate, endDate)); |
| | | Map<String, Long> regionCountMap = Arrays.stream(AddressRegionEnum.values()) |
| | | .collect(Collectors.toMap( |
| | | AddressRegionEnum::getRegionName, // 区域名作为key |
| | | enumItem -> 0L // 初始值全部为0 |
| | | )); |
| | | if (!CollectionUtils.isEmpty(customers)) { |
| | | regionCountMap = customers.stream() |
| | | // 调用方法将原始地址转换为目标区域 |
| | | .map(customer -> AddressRegionEnum.matchRegion(customer.getCompanyAddress()).getRegionName()) |
| | | // 过滤掉转换失败/空的区域(可选,根据业务需求) |
| | | .filter(region -> region != null && !region.isEmpty()) |
| | | // 按区域分组,统计每个区域的数量 |
| | | .collect(Collectors.groupingBy( |
| | | region -> region, // 分组依据:转换后的区域 |
| | | Collectors.counting() // 计数 |
| | | )); |
| | | } |
| | | regionCountMap.put("全部", customers.stream().count()); |
| | | maps.add(regionCountMap); |
| | | } |
| | | salesTotalDto.setDates(dates); |
| | | salesTotalDto.setCustomerTrends(maps); |
| | | return salesTotalDto; |
| | | } |
| | | |
| | | /** |
| | | * 根据前端传参 年/月 转换为对应LocalDate列表 |
| | | * |
| | | * @param days 前端参数:"年" / "月" |
| | | * @return List<LocalDate> |
| | | */ |
| | | public static List<LocalDate> convertDateList(String days) { |
| | | List<LocalDate> resultList = new ArrayList<>(); |
| | | LocalDate now = LocalDate.now(); |
| | | int currentYear = now.getYear(); |
| | | |
| | | if ("年".equals(days)) { |
| | | // 需求:近5年 → 每年的 1月1日 |
| | | for (int i = 0; i < 5; i++) { |
| | | resultList.add(LocalDate.of(currentYear - i, 1, 1)); |
| | | } |
| | | } else if ("月".equals(days)) { |
| | | // 需求:当年12个月 → 每月1日 |
| | | for (int month = 1; month <= 12; month++) { |
| | | resultList.add(LocalDate.of(currentYear, month, 1)); |
| | | } |
| | | } |
| | | return resultList; |
| | | } |
| | | |
| | | @Autowired |
| | | private ProductionProductMainService productionProductMainService; |
| | | |
| | | @Autowired |
| | | private ProductOrderService productOrderService; |
| | | |
| | | @Autowired |
| | | private ProductionProductInputService productionProductInputService; |
| | | |
| | | @Autowired |
| | | private ProductionProductOutputService productionProductOutputService; |
| | | |
| | | @Autowired |
| | | private IProductionOrderRouteService productionOrderRouteService; |
| | | |
| | | @Autowired |
| | | private SysDictDataMapper sysDictDataMapper; |
| | | |
| | | @Override |
| | | public Map<String, List<MaterialProductionAnalysisDto>> materialProductionAnalysis(productionStatisticsDto dto) { |
| | | if (dto == null) { |
| | | dto = new productionStatisticsDto(); |
| | | dto.setMaterialName("全部"); |
| | | dto.setDateType(1); |
| | | } |
| | | |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDate startDate = null; |
| | | |
| | | if (dto.getDateType() == 1) { // 本月至今 |
| | | startDate = now.withDayOfMonth(1); |
| | | } else { // 本年至今 |
| | | startDate = now.withDayOfYear(1); |
| | | } |
| | | |
| | | List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("product_type"); |
| | | Set<Long> blockDictCodes = sysDictDataList.stream() |
| | | .filter(d -> d.getDictLabel() != null && d.getDictLabel().contains("砌块")) |
| | | .map(SysDictData::getDictCode) |
| | | .collect(Collectors.toSet()); |
| | | Set<Long> plateDictCodes = sysDictDataList.stream() |
| | | .filter(d -> d.getDictLabel() != null && d.getDictLabel().contains("板材")) |
| | | .map(SysDictData::getDictCode) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | // 查询报工主表数据 |
| | | List<ProductionProductMain> productionProductMainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .between(ProductionProductMain::getReportingTime, |
| | | startDate.atStartOfDay(), |
| | | now.atTime(LocalTime.MAX))); |
| | | |
| | | if (CollectionUtils.isEmpty(productionProductMainList)) { |
| | | return Collections.emptyMap(); |
| | | } |
| | | |
| | | List<Long> productionMainIds = productionProductMainList.stream() |
| | | .map(ProductionProductMain::getId) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 获取产出明细 |
| | | List<ProductionProductOutput> productionProductOutputs = productionProductOutputService.list(new LambdaQueryWrapper<ProductionProductOutput>() |
| | | .in(ProductionProductOutput::getProductMainId, productionMainIds)); |
| | | |
| | | Map<Long, ProductionProductMain> mainMap = productionProductMainList.stream() |
| | | .collect(Collectors.toMap(ProductionProductMain::getId, m -> m)); |
| | | |
| | | // 获取订单工艺 |
| | | List<Long> productionOrderIds = productionProductMainList.stream() |
| | | .map(ProductionProductMain::getProductOrderId) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | |
| | | Map<Long, Long> orderRouteMap = new HashMap<>(); |
| | | if (!CollectionUtils.isEmpty(productionOrderIds)) { |
| | | List<ProductionOrderRoute> routes = productionOrderRouteService.list(Wrappers.<ProductionOrderRoute>lambdaQuery() |
| | | .in(ProductionOrderRoute::getOrderId, productionOrderIds)); |
| | | orderRouteMap = routes.stream() |
| | | .filter(r -> r.getOrderId() != null && r.getDictCode() != null) |
| | | .collect(Collectors.toMap(ProductionOrderRoute::getOrderId, ProductionOrderRoute::getDictCode, (v1, v2) -> v1)); |
| | | } |
| | | |
| | | List<String> dateLabels = new ArrayList<>(); |
| | | DateTimeFormatter formatter; |
| | | if (dto.getDateType() == 1) { // 本月按天 |
| | | formatter = DateTimeFormatter.ofPattern("MM-dd"); |
| | | long days = ChronoUnit.DAYS.between(startDate, now) + 1; |
| | | for (int i = 0; i < days; i++) { |
| | | dateLabels.add(startDate.plusDays(i).format(formatter)); |
| | | } |
| | | } else { // 本年按月 |
| | | formatter = DateTimeFormatter.ofPattern("yy-M"); |
| | | int currentMonth = now.getMonthValue(); |
| | | for (int i = 1; i <= currentMonth; i++) { |
| | | dateLabels.add(startDate.withMonth(i).format(formatter)); |
| | | } |
| | | } |
| | | |
| | | Map<String, Map<String, BigDecimal>> aggregateData = new HashMap<>(); |
| | | String[] categories = {"全部", "砌块", "板材"}; |
| | | for (String cat : categories) { |
| | | Map<String, BigDecimal> dayMap = new LinkedHashMap<>(); |
| | | for (String label : dateLabels) { |
| | | dayMap.put(label, BigDecimal.ZERO); |
| | | } |
| | | aggregateData.put(cat, dayMap); |
| | | } |
| | | |
| | | // 累加数据 |
| | | for (ProductionProductOutput output : productionProductOutputs) { |
| | | ProductionProductMain main = mainMap.get(output.getProductMainId()); |
| | | if (main == null || main.getReportingTime() == null) continue; |
| | | String label = main.getReportingTime().format(formatter); |
| | | if (!aggregateData.get("全部").containsKey(label)) continue; |
| | | BigDecimal qty = output.getQuantity() != null ? output.getQuantity() : BigDecimal.ZERO; |
| | | // 累加总产出 |
| | | aggregateData.get("全部").merge(label, qty, BigDecimal::add); |
| | | // 分类累加 |
| | | Long dictCode = orderRouteMap.get(main.getProductOrderId()); |
| | | if (dictCode != null) { |
| | | if (blockDictCodes.contains(dictCode)) { |
| | | aggregateData.get("砌块").merge(label, qty, BigDecimal::add); |
| | | } else if (plateDictCodes.contains(dictCode)) { |
| | | aggregateData.get("板材").merge(label, qty, BigDecimal::add); |
| | | } |
| | | } |
| | | } |
| | | |
| | | Map<String, List<MaterialProductionAnalysisDto>> result = new LinkedHashMap<>(); |
| | | for (String category : categories) { |
| | | List<MaterialProductionAnalysisDto> dtoList = new ArrayList<>(); |
| | | for (String label : dateLabels) { |
| | | MaterialProductionAnalysisDto item = new MaterialProductionAnalysisDto(); |
| | | item.setDateStr(label); |
| | | item.setTotalOutput(BigDecimal.ZERO); |
| | | item.setBlockOutput(BigDecimal.ZERO); |
| | | item.setPlateOutput(BigDecimal.ZERO); |
| | | BigDecimal val = aggregateData.get(category).get(label); |
| | | switch (category) { |
| | | case "全部": |
| | | item.setTotalOutput(val); |
| | | break; |
| | | case "砌块": |
| | | item.setBlockOutput(val); |
| | | break; |
| | | case "板材": |
| | | item.setPlateOutput(val); |
| | | break; |
| | | } |
| | | dtoList.add(item); |
| | | } |
| | | result.put(category, dtoList); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | @Autowired |
| | | private IProductionOrderStructureService productionOrderStructureService; |
| | | |
| | | @Autowired |
| | | private ProductMaterialService productMaterialService; |
| | | |
| | | @Autowired |
| | | private ProductMaterialSkuService productMaterialSkuService; |
| | | |
| | | @Override |
| | | public List<String> getMaterials(Integer materialType) { |
| | | // 获取产品类型字典 |
| | | List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("product_type"); |
| | | Set<Long> targetDictCodes; |
| | | if (materialType != null && materialType == 1) { // 砌块 |
| | | targetDictCodes = sysDictDataList.stream() |
| | | .filter(d -> d.getDictLabel() != null && d.getDictLabel().contains("砌块")) |
| | | .map(SysDictData::getDictCode) |
| | | .collect(Collectors.toSet()); |
| | | } else if (materialType != null && materialType == 2) { // 板材 |
| | | targetDictCodes = sysDictDataList.stream() |
| | | .filter(d -> d.getDictLabel() != null && d.getDictLabel().contains("板材")) |
| | | .map(SysDictData::getDictCode) |
| | | .collect(Collectors.toSet()); |
| | | } else { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | if (CollectionUtils.isEmpty(targetDictCodes)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 根据产品类型字典编码找到对应的生产订单ID |
| | | List<ProductionOrderRoute> routes = productionOrderRouteService.list(Wrappers.<ProductionOrderRoute>lambdaQuery() |
| | | .in(ProductionOrderRoute::getDictCode, targetDictCodes)); |
| | | List<Long> orderIds = routes.stream().map(ProductionOrderRoute::getOrderId).distinct().collect(Collectors.toList()); |
| | | |
| | | if (CollectionUtils.isEmpty(orderIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 根据生产订单ID查询BOM结构中的物料SKU ID |
| | | List<ProductionOrderStructure> structures = productionOrderStructureService.list(Wrappers.<ProductionOrderStructure>lambdaQuery() |
| | | .in(ProductionOrderStructure::getOrderId, orderIds)); |
| | | List<Long> skuIds = structures.stream() |
| | | .map(ProductionOrderStructure::getProductModelId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | |
| | | if (CollectionUtils.isEmpty(skuIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 根据SKU ID获取物料表ID |
| | | List<ProductMaterialSku> skus = productMaterialSkuService.list(Wrappers.<ProductMaterialSku>lambdaQuery() |
| | | .in(ProductMaterialSku::getId, skuIds)); |
| | | List<Long> productIds = skus.stream() |
| | | .map(ProductMaterialSku::getProductId) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | |
| | | if (CollectionUtils.isEmpty(productIds)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | // 根据物料主表ID获取物料名称 |
| | | List<ProductMaterial> materials = productMaterialService.list(Wrappers.<ProductMaterial>lambdaQuery() |
| | | .in(ProductMaterial::getId, productIds)); |
| | | |
| | | return materials.stream() |
| | | .map(ProductMaterial::getProductName) |
| | | .filter(Objects::nonNull) |
| | | .distinct() |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | public List<ProductionCostAnalysisDto> productionCostAnalysis(productionStatisticsDto dto, Integer materialType) { |
| | | // 获取动态字典ID |
| | | List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("product_type"); |
| | | Set<Long> targetDictCodes = sysDictDataList.stream() |
| | | .filter(d -> d.getDictLabel() != null && d.getDictLabel().contains(materialType == 1 ? "砌块" : "板材")) |
| | | .map(SysDictData::getDictCode) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | if (CollectionUtils.isEmpty(targetDictCodes)) return Collections.emptyList(); |
| | | |
| | | // 获取该类型的订单 |
| | | List<ProductionOrderRoute> routes = productionOrderRouteService.list(Wrappers.<ProductionOrderRoute>lambdaQuery() |
| | | .in(ProductionOrderRoute::getDictCode, targetDictCodes)); |
| | | List<Long> orderIds = routes.stream().map(ProductionOrderRoute::getOrderId).distinct().collect(Collectors.toList()); |
| | | if (CollectionUtils.isEmpty(orderIds)) return Collections.emptyList(); |
| | | |
| | | // 时间范围处理 |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDateTime yearStart = now.withDayOfYear(1).atStartOfDay(); |
| | | LocalDateTime monthStart = now.withDayOfMonth(1).atStartOfDay(); |
| | | |
| | | LocalDateTime trendStart; |
| | | DateTimeFormatter trendFormatter; |
| | | int points; |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { |
| | | trendStart = monthStart; |
| | | trendFormatter = DateTimeFormatter.ofPattern("MM-dd"); |
| | | points = now.getDayOfMonth(); |
| | | } else { |
| | | trendStart = yearStart; |
| | | trendFormatter = DateTimeFormatter.ofPattern("yy-MM"); |
| | | points = now.getMonthValue(); |
| | | } |
| | | |
| | | // 查询报工数据 |
| | | List<ProductionProductMain> mainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .in(ProductionProductMain::getProductOrderId, orderIds) |
| | | .ge(ProductionProductMain::getReportingTime, yearStart)); |
| | | if (CollectionUtils.isEmpty(mainList)) return Collections.emptyList(); |
| | | |
| | | List<Long> mainIds = mainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList()); |
| | | Map<Long, ProductionProductMain> mainMap = mainList.stream().collect(Collectors.toMap(ProductionProductMain::getId, m -> m)); |
| | | |
| | | // 查询投入和产出 |
| | | List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery() |
| | | .in(ProductionProductInput::getProductMainId, mainIds)); |
| | | List<ProductionProductOutput> allOutputs = productionProductOutputService.list(Wrappers.<ProductionProductOutput>lambdaQuery() |
| | | .in(ProductionProductOutput::getProductMainId, mainIds)); |
| | | |
| | | // 获取投入物料的基础信息 |
| | | Set<Long> inputSkuIds = allInputs.stream().map(ProductionProductInput::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Set<Long> outputSkuIds = allOutputs.stream().map(ProductionProductOutput::getProductModelId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | |
| | | Map<Long, ProductMaterial> inputSkuToMatMap = new HashMap<>(); |
| | | if (!inputSkuIds.isEmpty()) { |
| | | List<ProductMaterialSku> inputSkus = productMaterialSkuService.listByIds(inputSkuIds); |
| | | Set<Long> inputActualProdIds = inputSkus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, ProductMaterial> materialMap = productMaterialService.listByIds(inputActualProdIds).stream() |
| | | .collect(Collectors.toMap(ProductMaterial::getId, m -> m)); |
| | | inputSkuToMatMap = inputSkus.stream().collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialMap.get(s.getProductId()))); |
| | | } |
| | | |
| | | Map<Long, String> outputSkuToUnitMap = new HashMap<>(); |
| | | if (!outputSkuIds.isEmpty()) { |
| | | List<ProductMaterialSku> outSkus = productMaterialSkuService.listByIds(outputSkuIds); |
| | | Set<Long> outProdIds = outSkus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> matUnitMap = productMaterialService.listByIds(outProdIds).stream().collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getUnit)); |
| | | outputSkuToUnitMap = outSkus.stream().collect(Collectors.toMap(ProductMaterialSku::getId, s -> matUnitMap.getOrDefault(s.getProductId(), "吨"))); |
| | | } |
| | | |
| | | // 按物料分组聚合 |
| | | Map<Long, ProductMaterial> finalSkuToMatMap = inputSkuToMatMap; |
| | | Map<String, List<ProductionProductInput>> inputByMaterial = allInputs.stream() |
| | | .filter(i -> finalSkuToMatMap.containsKey(i.getProductId()) && finalSkuToMatMap.get(i.getProductId()) != null) |
| | | .collect(Collectors.groupingBy(i -> finalSkuToMatMap.get(i.getProductId()).getProductName())); |
| | | |
| | | if (dto.getMaterialName() != null && !"全部".equals(dto.getMaterialName())) { |
| | | String target = dto.getMaterialName(); |
| | | inputByMaterial = inputByMaterial.entrySet().stream() |
| | | .filter(e -> e.getKey().equals(target)) |
| | | .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); |
| | | } |
| | | |
| | | List<ProductionCostAnalysisDto> resultList = new ArrayList<>(); |
| | | |
| | | for (Map.Entry<String, List<ProductionProductInput>> entry : inputByMaterial.entrySet()) { |
| | | String materialName = entry.getKey(); |
| | | List<ProductionProductInput> materialInputs = entry.getValue(); |
| | | |
| | | ProductionCostAnalysisDto analysisDto = new ProductionCostAnalysisDto(); |
| | | analysisDto.setMaterialName(materialName); |
| | | |
| | | Set<Long> relatedMainIds = materialInputs.stream().map(ProductionProductInput::getProductMainId).collect(Collectors.toSet()); |
| | | List<ProductionProductOutput> relatedOutputs = allOutputs.stream() |
| | | .filter(o -> relatedMainIds.contains(o.getProductMainId())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | BigDecimal monthInputSum = BigDecimal.ZERO; |
| | | BigDecimal monthOutputSum = BigDecimal.ZERO; |
| | | BigDecimal yearInputSum = BigDecimal.ZERO; |
| | | BigDecimal yearOutputSum = BigDecimal.ZERO; |
| | | |
| | | Map<String, InputOutputAnalysisDto> trendMap = new LinkedHashMap<>(); |
| | | for (int i = 0; i < points; i++) { |
| | | String label; |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { |
| | | label = now.withDayOfMonth(i + 1).format(trendFormatter); |
| | | } else { |
| | | label = now.withMonth(i + 1).format(trendFormatter); |
| | | } |
| | | InputOutputAnalysisDto trendDto = new InputOutputAnalysisDto(); |
| | | trendDto.setDate(label); |
| | | trendDto.setInputSum(BigDecimal.ZERO); |
| | | trendDto.setOutputSum(BigDecimal.ZERO); |
| | | trendMap.put(label, trendDto); |
| | | } |
| | | |
| | | for (ProductionProductInput input : materialInputs) { |
| | | BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit()); |
| | | yearInputSum = yearInputSum.add(qty); |
| | | LocalDateTime repTime = mainMap.get(input.getProductMainId()).getReportingTime(); |
| | | if (repTime != null && (repTime.isAfter(monthStart) || repTime.isEqual(monthStart))) { |
| | | monthInputSum = monthInputSum.add(qty); |
| | | } |
| | | if (repTime != null && (repTime.isAfter(trendStart) || repTime.isEqual(trendStart))) { |
| | | String label = repTime.format(trendFormatter); |
| | | if (trendMap.containsKey(label)) { |
| | | trendMap.get(label).setInputSum(trendMap.get(label).getInputSum().add(qty)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | for (ProductionProductOutput output : relatedOutputs) { |
| | | String unit = outputSkuToUnitMap.getOrDefault(output.getProductModelId(), "吨"); |
| | | BigDecimal qty = UnitUtils.convertValueToTon(output.getQuantity(), unit); |
| | | yearOutputSum = yearOutputSum.add(qty); |
| | | LocalDateTime repTime = mainMap.get(output.getProductMainId()).getReportingTime(); |
| | | if (repTime != null && (repTime.isAfter(monthStart) || repTime.isEqual(monthStart))) { |
| | | monthOutputSum = monthOutputSum.add(qty); |
| | | } |
| | | if (repTime != null && (repTime.isAfter(trendStart) || repTime.isEqual(trendStart))) { |
| | | String label = repTime.format(trendFormatter); |
| | | if (trendMap.containsKey(label)) { |
| | | trendMap.get(label).setOutputSum(trendMap.get(label).getOutputSum().add(qty)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | analysisDto.setMonthlyConsumption(formatRatio(monthInputSum, monthOutputSum)); |
| | | analysisDto.setYearlyConsumption(formatRatio(yearInputSum, yearOutputSum)); |
| | | analysisDto.setChartData(new ArrayList<>(trendMap.values())); |
| | | resultList.add(analysisDto); |
| | | } |
| | | |
| | | return resultList; |
| | | } |
| | | |
| | | private String formatRatio(BigDecimal input, BigDecimal output) { |
| | | String inputStr = input.setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString(); |
| | | String outputStr = output.setScale(2, RoundingMode.HALF_UP).stripTrailingZeros().toPlainString(); |
| | | return inputStr + "/" + outputStr; |
| | | } |
| | | |
| | | @Override |
| | | public ProductionStatisticsMiddleDto middle() { |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDate monthStart = now.withDayOfMonth(1); |
| | | LocalDate yearStart = now.withDayOfYear(1); |
| | | |
| | | // 获取产品类型字典 |
| | | List<SysDictData> sysDictDataList = sysDictDataMapper.selectDictDataByType("product_type"); |
| | | Set<Long> blockDictCodes = sysDictDataList.stream() |
| | | .filter(d -> d.getDictLabel() != null && d.getDictLabel().contains("砌块")) |
| | | .map(SysDictData::getDictCode) |
| | | .collect(Collectors.toSet()); |
| | | Set<Long> plateDictCodes = sysDictDataList.stream() |
| | | .filter(d -> d.getDictLabel() != null && d.getDictLabel().contains("板材")) |
| | | .map(SysDictData::getDictCode) |
| | | .collect(Collectors.toSet()); |
| | | |
| | | // 查询本年报工主表 |
| | | List<ProductionProductMain> yearMainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .ge(ProductionProductMain::getReportingTime, yearStart.atStartOfDay())); |
| | | if (CollectionUtils.isEmpty(yearMainList)) return new ProductionStatisticsMiddleDto(); |
| | | |
| | | List<Long> mainIds = yearMainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList()); |
| | | Map<Long, ProductionProductMain> mainMap = yearMainList.stream().collect(Collectors.toMap(ProductionProductMain::getId, m -> m)); |
| | | |
| | | // 获取订单信息 |
| | | List<Long> orderIds = yearMainList.stream().map(ProductionProductMain::getProductOrderId).distinct().collect(Collectors.toList()); |
| | | Map<Long, Long> orderRouteMap = new HashMap<>(); |
| | | if (!CollectionUtils.isEmpty(orderIds)) { |
| | | List<ProductionOrderRoute> routes = productionOrderRouteService.list(Wrappers.<ProductionOrderRoute>lambdaQuery() |
| | | .in(ProductionOrderRoute::getOrderId, orderIds)); |
| | | orderRouteMap = routes.stream() |
| | | .filter(r -> r.getOrderId() != null && r.getDictCode() != null) |
| | | .collect(Collectors.toMap(ProductionOrderRoute::getOrderId, ProductionOrderRoute::getDictCode, (v1, v2) -> v1)); |
| | | } |
| | | |
| | | // 获取产出明细(用于砌块、板材产量) |
| | | List<ProductionProductOutput> allOutputs = productionProductOutputService.list(Wrappers.<ProductionProductOutput>lambdaQuery() |
| | | .in(ProductionProductOutput::getProductMainId, mainIds)); |
| | | |
| | | // 获取投入明细(用于粉煤灰、石膏处理量) |
| | | List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery() |
| | | .in(ProductionProductInput::getProductMainId, mainIds)); |
| | | |
| | | // 统一处理规格/物料名称映射 |
| | | Set<Long> allSkuIds = new HashSet<>(); |
| | | allOutputs.forEach(o -> allSkuIds.add(o.getProductModelId())); |
| | | allInputs.forEach(i -> allSkuIds.add(i.getProductId())); |
| | | allSkuIds.remove(null); |
| | | |
| | | Map<Long, String> skuToMaterialNameMap = new HashMap<>(); |
| | | if (!allSkuIds.isEmpty()) { |
| | | List<ProductMaterialSku> skus = productMaterialSkuService.listByIds(allSkuIds); |
| | | Set<Long> productIds = skus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> materialNameMap = productMaterialService.listByIds(productIds).stream() |
| | | .collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getProductName)); |
| | | skuToMaterialNameMap = skus.stream() |
| | | .filter(s -> s.getProductId() != null && materialNameMap.containsKey(s.getProductId())) |
| | | .collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialNameMap.get(s.getProductId()))); |
| | | } |
| | | |
| | | ProductionStatisticsMiddleDto result = new ProductionStatisticsMiddleDto(); |
| | | LocalDateTime monthStartDt = monthStart.atStartOfDay(); |
| | | |
| | | // 统计固废处理量,从投入获取数据 |
| | | for (ProductionProductInput input : allInputs) { |
| | | ProductionProductMain main = mainMap.get(input.getProductMainId()); |
| | | if (main == null || main.getReportingTime() == null) continue; |
| | | |
| | | BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit()); |
| | | boolean isCurrentMonth = !main.getReportingTime().isBefore(monthStartDt); |
| | | String materialName = skuToMaterialNameMap.get(input.getProductId()); |
| | | |
| | | if ("粉煤灰".equals(materialName)) { |
| | | result.setFlyAshYear(result.getFlyAshYear().add(qty)); |
| | | if (isCurrentMonth) result.setFlyAshMonth(result.getFlyAshMonth().add(qty)); |
| | | } else if ("石膏".equals(materialName)) { |
| | | result.setGypsumYear(result.getGypsumYear().add(qty)); |
| | | if (isCurrentMonth) result.setGypsumMonth(result.getGypsumMonth().add(qty)); |
| | | } |
| | | } |
| | | |
| | | // 统计项目产量,从产出获取数据 |
| | | for (ProductionProductOutput output : allOutputs) { |
| | | ProductionProductMain main = mainMap.get(output.getProductMainId()); |
| | | if (main == null || main.getReportingTime() == null) continue; |
| | | |
| | | BigDecimal qty = UnitUtils.convertValueToTon(output.getQuantity(), "吨"); // 产出方量通常为吨 |
| | | boolean isCurrentMonth = !main.getReportingTime().isBefore(monthStartDt); |
| | | |
| | | Long dictCode = orderRouteMap.get(main.getProductOrderId()); |
| | | if (dictCode != null) { |
| | | if (blockDictCodes.contains(dictCode)) { |
| | | result.setBlockYear(result.getBlockYear().add(qty)); |
| | | if (isCurrentMonth) result.setBlockMonth(result.getBlockMonth().add(qty)); |
| | | } else if (plateDictCodes.contains(dictCode)) { |
| | | result.setPlateYear(result.getPlateYear().add(qty)); |
| | | if (isCurrentMonth) result.setPlateMonth(result.getPlateMonth().add(qty)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public List<SolidWasteStatisticsDto> solidWaste(productionStatisticsDto dto) { |
| | | if (dto == null) { |
| | | dto = new productionStatisticsDto(); |
| | | dto.setDateType(1); |
| | | } |
| | | |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDate startDate = null; |
| | | |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { // 本月至今 |
| | | startDate = now.withDayOfMonth(1); |
| | | } else { // 本年至今 |
| | | startDate = now.withDayOfYear(1); |
| | | } |
| | | |
| | | List<String> dateLabels = new ArrayList<>(); |
| | | DateTimeFormatter formatter; |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { // 本月按天 |
| | | formatter = DateTimeFormatter.ofPattern("MM-dd"); |
| | | long days = ChronoUnit.DAYS.between(startDate, now) + 1; |
| | | for (int i = 0; i < days; i++) { |
| | | dateLabels.add(startDate.plusDays(i).format(formatter)); |
| | | } |
| | | } else { // 本年按月 |
| | | formatter = DateTimeFormatter.ofPattern("yy-MM"); |
| | | int currentMonth = now.getMonthValue(); |
| | | for (int i = 1; i <= currentMonth; i++) { |
| | | dateLabels.add(startDate.withMonth(i).format(formatter)); |
| | | } |
| | | } |
| | | |
| | | // 查询时间范围内的报工数据 |
| | | List<ProductionProductMain> mainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .ge(ProductionProductMain::getReportingTime, startDate.atStartOfDay())); |
| | | if (CollectionUtils.isEmpty(mainList)) return new ArrayList<>(); |
| | | |
| | | List<Long> mainIds = mainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList()); |
| | | Map<Long, ProductionProductMain> mainMap = mainList.stream().collect(Collectors.toMap(ProductionProductMain::getId, m -> m)); |
| | | |
| | | // 获取投入明细 |
| | | List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery() |
| | | .in(ProductionProductInput::getProductMainId, mainIds)); |
| | | if (CollectionUtils.isEmpty(allInputs)) return new ArrayList<>(); |
| | | |
| | | // 获取规格和物料名称 |
| | | Set<Long> skuIds = allInputs.stream().map(ProductionProductInput::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> skuToMaterialNameMap = new HashMap<>(); |
| | | if (!skuIds.isEmpty()) { |
| | | List<ProductMaterialSku> skus = productMaterialSkuService.listByIds(skuIds); |
| | | Set<Long> productIds = skus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> materialNameMap = productMaterialService.listByIds(productIds).stream() |
| | | .collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getProductName)); |
| | | skuToMaterialNameMap = skus.stream() |
| | | .filter(s -> s.getProductId() != null && materialNameMap.containsKey(s.getProductId())) |
| | | .collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialNameMap.get(s.getProductId()))); |
| | | } |
| | | |
| | | Map<String, SolidWasteStatisticsDto> resultData = new LinkedHashMap<>(); |
| | | for (String label : dateLabels) { |
| | | SolidWasteStatisticsDto item = new SolidWasteStatisticsDto(); |
| | | item.setDateStr(label); |
| | | resultData.put(label, item); |
| | | } |
| | | |
| | | // 按日期和物料 |
| | | for (ProductionProductInput input : allInputs) { |
| | | ProductionProductMain main = mainMap.get(input.getProductMainId()); |
| | | if (main == null || main.getReportingTime() == null) continue; |
| | | String label = main.getReportingTime().format(formatter); |
| | | if (!resultData.containsKey(label)) continue; |
| | | |
| | | BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit()); |
| | | String materialName = skuToMaterialNameMap.get(input.getProductId()); |
| | | |
| | | SolidWasteStatisticsDto dayDto = resultData.get(label); |
| | | if ("粉煤灰".equals(materialName)) { |
| | | dayDto.setFlyAsh(dayDto.getFlyAsh().add(qty)); |
| | | } else if ("石膏".equals(materialName)) { |
| | | dayDto.setGypsum(dayDto.getGypsum().add(qty)); |
| | | } else if ("石灰".equals(materialName)) { |
| | | dayDto.setLime(dayDto.getLime().add(qty)); |
| | | } |
| | | dayDto.setTotal(dayDto.getTotal().add(qty)); |
| | | } |
| | | |
| | | return new ArrayList<>(resultData.values()); |
| | | } |
| | | |
| | | @Override |
| | | public List<HomeEnergyStatisticsDto> energy(productionStatisticsDto dto) { |
| | | if (dto == null) { |
| | | dto = new productionStatisticsDto(); |
| | | dto.setDateType(1); |
| | | } |
| | | |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDate startDate = null; |
| | | |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { // 本月至今 |
| | | startDate = now.withDayOfMonth(1); |
| | | } else { // 本年至今 |
| | | startDate = now.withDayOfYear(1); |
| | | } |
| | | |
| | | EnergyStatisticsVo vo = new EnergyStatisticsVo(); |
| | | vo.setStartDate(startDate); |
| | | vo.setEndDate(now); |
| | | |
| | | List<EnergyCostDto> costDtos; |
| | | String labelPattern; |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { // 本月按天 |
| | | costDtos = energyConsumptionDetailMapper.energyCostDtos1(vo); |
| | | labelPattern = "MM-dd"; |
| | | } else { // 本年按月 |
| | | costDtos = energyConsumptionDetailMapper.energyCostDtos2(vo); |
| | | labelPattern = "yy-MM"; |
| | | } |
| | | |
| | | List<String> dateLabels = new ArrayList<>(); |
| | | DateTimeFormatter labelFormatter = DateTimeFormatter.ofPattern(labelPattern); |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { |
| | | long days = ChronoUnit.DAYS.between(startDate, now) + 1; |
| | | for (int i = 0; i < days; i++) { |
| | | dateLabels.add(startDate.plusDays(i).format(labelFormatter)); |
| | | } |
| | | } else { |
| | | int currentMonth = now.getMonthValue(); |
| | | for (int i = 1; i <= currentMonth; i++) { |
| | | dateLabels.add(startDate.withMonth(i).format(labelFormatter)); |
| | | } |
| | | } |
| | | |
| | | Map<String, HomeEnergyStatisticsDto> resultData = new LinkedHashMap<>(); |
| | | for (String label : dateLabels) { |
| | | HomeEnergyStatisticsDto item = new HomeEnergyStatisticsDto(); |
| | | item.setDateStr(label); |
| | | resultData.put(label, item); |
| | | } |
| | | |
| | | if (!CollectionUtils.isEmpty(costDtos)) { |
| | | // 获取单位 |
| | | List<Energy> energies = energyMapper.selectList(Wrappers.<Energy>lambdaQuery() |
| | | .in(Energy::getEnergyTyep, Arrays.asList("水", "电", "气"))); |
| | | String waterUnit = energies.stream().filter(e -> "水".equals(e.getEnergyTyep())).map(Energy::getUnit).findFirst().orElse(""); |
| | | String electricityUnit = energies.stream().filter(e -> "电".equals(e.getEnergyTyep())).map(Energy::getUnit).findFirst().orElse(""); |
| | | String steamUnit = energies.stream().filter(e -> "气".equals(e.getEnergyTyep())).map(Energy::getUnit).findFirst().orElse(""); |
| | | |
| | | for (EnergyCostDto costDto : costDtos) { |
| | | String dateStr = costDto.getMeterReadingDate(); |
| | | String label = ""; |
| | | try { |
| | | if (dto.getDateType() == 1) { |
| | | label = LocalDate.parse(dateStr).format(labelFormatter); |
| | | } else { |
| | | // yyyy-MM 转化为 yy-MM |
| | | label = YearMonth.parse(dateStr).format(labelFormatter); |
| | | } |
| | | } catch (Exception e) { |
| | | label = dateStr; |
| | | } |
| | | |
| | | if (resultData.containsKey(label)) { |
| | | HomeEnergyStatisticsDto dayDto = resultData.get(label); |
| | | BigDecimal water = costDto.getWaterConsumption() != null ? costDto.getWaterConsumption() : BigDecimal.ZERO; |
| | | BigDecimal electricity = costDto.getElectricityConsumption() != null ? costDto.getElectricityConsumption() : BigDecimal.ZERO; |
| | | BigDecimal steam = costDto.getGasConsumption() != null ? costDto.getGasConsumption() : BigDecimal.ZERO; |
| | | dayDto.setWater(water); |
| | | dayDto.setElectricity(electricity); |
| | | dayDto.setSteam(steam); |
| | | dayDto.setWaterUnit(waterUnit); |
| | | dayDto.setElectricityUnit(electricityUnit); |
| | | dayDto.setSteamUnit(steamUnit); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return new ArrayList<>(resultData.values()); |
| | | } |
| | | |
| | | @Override |
| | | public SolidWasteCoreIndicatorsDto coreIndicators(productionStatisticsDto dto) { |
| | | if (dto == null) { |
| | | dto = new productionStatisticsDto(); |
| | | dto.setDateType(1); |
| | | } |
| | | |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDate startDate = null; |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { // 本月至今 |
| | | startDate = now.withDayOfMonth(1); |
| | | } else { // 本年至今 |
| | | startDate = now.withDayOfYear(1); |
| | | } |
| | | |
| | | // 累计消纳量从2022-01-01开始 |
| | | LocalDate cumulativeStartDate = LocalDate.of(2022, 1, 1); |
| | | // 查询从2022-01-01至今的所有报工数据 |
| | | List<ProductionProductMain> mainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .ge(ProductionProductMain::getReportingTime, cumulativeStartDate.atStartOfDay())); |
| | | if (CollectionUtils.isEmpty(mainList)) return new SolidWasteCoreIndicatorsDto(); |
| | | |
| | | List<Long> mainIds = mainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList()); |
| | | Map<Long, ProductionProductMain> mainMap = mainList.stream().collect(Collectors.toMap(ProductionProductMain::getId, m -> m)); |
| | | |
| | | // 获取投入明细 |
| | | List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery() |
| | | .in(ProductionProductInput::getProductMainId, mainIds)); |
| | | if (CollectionUtils.isEmpty(allInputs)) return new SolidWasteCoreIndicatorsDto(); |
| | | |
| | | // 获取规格和物料名称 |
| | | Set<Long> skuIds = allInputs.stream().map(ProductionProductInput::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> skuToMaterialNameMap = new HashMap<>(); |
| | | if (!skuIds.isEmpty()) { |
| | | List<ProductMaterialSku> skus = productMaterialSkuService.listByIds(skuIds); |
| | | Set<Long> productIds = skus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> materialNameMap = productMaterialService.listByIds(productIds).stream() |
| | | .collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getProductName)); |
| | | skuToMaterialNameMap = skus.stream() |
| | | .filter(s -> s.getProductId() != null && materialNameMap.containsKey(s.getProductId())) |
| | | .collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialNameMap.get(s.getProductId()))); |
| | | } |
| | | |
| | | BigDecimal totalAmount = BigDecimal.ZERO; |
| | | BigDecimal cumulativeAmount = BigDecimal.ZERO; |
| | | |
| | | Set<String> targetMaterials = new HashSet<>(Arrays.asList("粉煤灰", "石膏", "石灰")); |
| | | |
| | | for (ProductionProductInput input : allInputs) { |
| | | String materialName = skuToMaterialNameMap.get(input.getProductId()); |
| | | if (materialName == null || !targetMaterials.contains(materialName)) continue; |
| | | |
| | | ProductionProductMain main = mainMap.get(input.getProductMainId()); |
| | | if (main == null || main.getReportingTime() == null) continue; |
| | | |
| | | BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit()); |
| | | // 累加累计消纳量 |
| | | cumulativeAmount = cumulativeAmount.add(qty); |
| | | |
| | | if (!main.getReportingTime().toLocalDate().isBefore(startDate)) { |
| | | totalAmount = totalAmount.add(qty); |
| | | } |
| | | } |
| | | |
| | | SolidWasteCoreIndicatorsDto result = new SolidWasteCoreIndicatorsDto(); |
| | | result.setTotalAmount(totalAmount.setScale(2, RoundingMode.HALF_UP)); |
| | | result.setCumulativeAmount(cumulativeAmount.setScale(2, RoundingMode.HALF_UP)); |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public List<SolidWasteStatisticsDto> trends(productionStatisticsDto dto) { |
| | | return solidWaste(dto); |
| | | } |
| | | |
| | | @Override |
| | | public List<MapDto> typeDistribution(productionStatisticsDto dto) { |
| | | if (dto == null) { |
| | | dto = new productionStatisticsDto(); |
| | | dto.setDateType(1); |
| | | } |
| | | |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDate startDate = null; |
| | | if (dto.getDateType() != null && dto.getDateType() == 1) { // 本月至今 |
| | | startDate = now.withDayOfMonth(1); |
| | | } else { // 本年至今 |
| | | startDate = now.withDayOfYear(1); |
| | | } |
| | | |
| | | // 查询报工主表 |
| | | List<ProductionProductMain> mainList = productionProductMainService.list(Wrappers.<ProductionProductMain>lambdaQuery() |
| | | .ge(ProductionProductMain::getReportingTime, startDate.atStartOfDay())); |
| | | if (CollectionUtils.isEmpty(mainList)) return new ArrayList<>(); |
| | | |
| | | List<Long> mainIds = mainList.stream().map(ProductionProductMain::getId).collect(Collectors.toList()); |
| | | |
| | | // 获取投入明细 |
| | | List<ProductionProductInput> allInputs = productionProductInputService.list(Wrappers.<ProductionProductInput>lambdaQuery() |
| | | .in(ProductionProductInput::getProductMainId, mainIds)); |
| | | if (CollectionUtils.isEmpty(allInputs)) return new ArrayList<>(); |
| | | |
| | | // 获取规格和物料名称 |
| | | Set<Long> skuIds = allInputs.stream().map(ProductionProductInput::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> skuToMaterialNameMap = new HashMap<>(); |
| | | if (!skuIds.isEmpty()) { |
| | | List<ProductMaterialSku> skus = productMaterialSkuService.listByIds(skuIds); |
| | | Set<Long> productIds = skus.stream().map(ProductMaterialSku::getProductId).filter(Objects::nonNull).collect(Collectors.toSet()); |
| | | Map<Long, String> materialNameMap = productMaterialService.listByIds(productIds).stream() |
| | | .collect(Collectors.toMap(ProductMaterial::getId, ProductMaterial::getProductName)); |
| | | skuToMaterialNameMap = skus.stream() |
| | | .filter(s -> s.getProductId() != null && materialNameMap.containsKey(s.getProductId())) |
| | | .collect(Collectors.toMap(ProductMaterialSku::getId, s -> materialNameMap.get(s.getProductId()))); |
| | | } |
| | | |
| | | Map<String, BigDecimal> countMap = new HashMap<>(); |
| | | countMap.put("粉煤灰", BigDecimal.ZERO); |
| | | countMap.put("石膏", BigDecimal.ZERO); |
| | | countMap.put("石灰", BigDecimal.ZERO); |
| | | |
| | | BigDecimal total = BigDecimal.ZERO; |
| | | |
| | | for (ProductionProductInput input : allInputs) { |
| | | String materialName = skuToMaterialNameMap.get(input.getProductId()); |
| | | if (materialName == null || !countMap.containsKey(materialName)) continue; |
| | | |
| | | BigDecimal qty = UnitUtils.convertValueToTon(input.getQuantity(), input.getUnit()); |
| | | countMap.put(materialName, countMap.get(materialName).add(qty)); |
| | | total = total.add(qty); |
| | | } |
| | | |
| | | List<MapDto> result = new ArrayList<>(); |
| | | for (Map.Entry<String, BigDecimal> entry : countMap.entrySet()) { |
| | | MapDto mapDto = new MapDto(); |
| | | mapDto.setName(entry.getKey()); |
| | | BigDecimal value = entry.getValue().setScale(2, RoundingMode.HALF_UP); |
| | | mapDto.setValue(value.toString()); |
| | | |
| | | if (total.compareTo(BigDecimal.ZERO) > 0) { |
| | | BigDecimal rate = entry.getValue().divide(total, 4, RoundingMode.HALF_UP) |
| | | .multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP); |
| | | mapDto.setRate(rate.toString()); |
| | | } else { |
| | | mapDto.setRate("0.00"); |
| | | } |
| | | result.add(mapDto); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public Map<String, Long> manage() { |
| | | Map<String, Long> map = new HashMap<>(); |
| | | //生产订单总数 |
| | | Long total = productOrderMapper.selectCount(new QueryWrapper<ProductOrder>().ne("status", 4)); |
| | | map.put("total", total); |
| | | //已完成订单数 |
| | | Long completed = productOrderMapper.selectCount(new QueryWrapper<ProductOrder>().eq("status", 3)); |
| | | map.put("completed", completed); |
| | | //未完成订单数 |
| | | Long uncompleted = productOrderMapper.selectCount(new QueryWrapper<ProductOrder>().eq("status", 1)); |
| | | map.put("uncompleted", uncompleted); |
| | | //部分完成订单数 |
| | | Long partialCompleted = productOrderMapper.selectCount(new QueryWrapper<ProductOrder>().eq("status", 2)); |
| | | map.put("partialCompleted", partialCompleted); |
| | | //来料检总数 |
| | | Long materialInspection = qualityInspectMapper.selectCount(new QueryWrapper<QualityInspect>().eq("inspect_type", 0)); |
| | | map.put("materialInspection", materialInspection); |
| | | return map; |
| | | } |
| | | |
| | | @Autowired |
| | | private ProductionPlanService productionPlanService; |
| | | |
| | | @Override |
| | | public List<PlanTrendsDto> planTrends(Integer type) { |
| | | LocalDate now = LocalDate.now(); |
| | | LocalDate startDate; |
| | | DateTimeFormatter formatter; |
| | | int points; |
| | | |
| | | if (type == null) type = 1; |
| | | if (type == 1) { // 日 |
| | | points = 1; |
| | | startDate = now; |
| | | formatter = DateTimeFormatter.ofPattern("MM-dd"); |
| | | } else if (type == 2) { // 周 |
| | | startDate = now.with(DayOfWeek.MONDAY); |
| | | points = (int) ChronoUnit.DAYS.between(startDate, now) + 1; |
| | | formatter = DateTimeFormatter.ofPattern("MM-dd"); |
| | | } else { // 月 |
| | | startDate = now.with(TemporalAdjusters.firstDayOfMonth()); |
| | | points = now.getDayOfMonth(); |
| | | formatter = DateTimeFormatter.ofPattern("MM-dd"); |
| | | } |
| | | |
| | | Map<String, PlanTrendsDto> resultMap = new LinkedHashMap<>(); |
| | | for (int i = 0; i < points; i++) { |
| | | String label = startDate.plusDays(i).format(formatter); |
| | | PlanTrendsDto dto = new PlanTrendsDto(); |
| | | dto.setDateStr(label); |
| | | dto.setPlannedVolume(BigDecimal.ZERO); |
| | | dto.setLowerVolume(BigDecimal.ZERO); |
| | | dto.setCompletionVolume(BigDecimal.ZERO); |
| | | resultMap.put(label, dto); |
| | | } |
| | | // 统计计划量 |
| | | List<ProductionPlan> plans = productionPlanService.list(Wrappers.<ProductionPlan>lambdaQuery() |
| | | .ge(ProductionPlan::getStartDate, Date.from(startDate.atStartOfDay(ZoneId.systemDefault()).toInstant()))); |
| | | for (ProductionPlan plan : plans) { |
| | | if (plan.getStartDate() == null || plan.getVolume() == null) continue; |
| | | LocalDate d = plan.getStartDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); |
| | | String label = d.format(formatter); |
| | | if (resultMap.containsKey(label)) { |
| | | PlanTrendsDto dto = resultMap.get(label); |
| | | dto.setPlannedVolume(dto.getPlannedVolume().add(plan.getVolume())); |
| | | } |
| | | } |
| | | // 统计下发量 |
| | | List<ProductOrder> orders = productOrderMapper.selectList(Wrappers.<ProductOrder>lambdaQuery() |
| | | .ge(ProductOrder::getStartTime, startDate.atStartOfDay())); |
| | | for (ProductOrder order : orders) { |
| | | if (order.getStartTime() == null || order.getQuantity() == null) continue; |
| | | LocalDate d = order.getStartTime().toLocalDate(); |
| | | String label = d.format(formatter); |
| | | if (resultMap.containsKey(label)) { |
| | | PlanTrendsDto dto = resultMap.get(label); |
| | | dto.setLowerVolume(dto.getLowerVolume().add(order.getQuantity())); |
| | | } |
| | | } |
| | | // 统计完成量 |
| | | List<ProductionProductOutput> outputs = productionProductOutputMapper.selectList(Wrappers.<ProductionProductOutput>lambdaQuery() |
| | | .ge(ProductionProductOutput::getCreateTime, startDate.atStartOfDay())); |
| | | for (ProductionProductOutput output : outputs) { |
| | | if (output.getCreateTime() == null || output.getQuantity() == null) continue; |
| | | LocalDate d = output.getCreateTime().toLocalDate(); |
| | | String label = d.format(formatter); |
| | | if (resultMap.containsKey(label)) { |
| | | PlanTrendsDto dto = resultMap.get(label); |
| | | dto.setCompletionVolume(dto.getCompletionVolume().add(output.getQuantity())); |
| | | } |
| | | } |
| | | |
| | | return new ArrayList<>(resultMap.values()); |
| | | } |
| | | |
| | | } |