| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.ruoyi.home.mapper.HomeMapper; |
| | | import com.ruoyi.approve.mapper.ApproveProcessMapper; |
| | | import com.ruoyi.approve.pojo.ApproveProcess; |
| | | import com.ruoyi.basic.mapper.CustomerMapper; |
| | |
| | | import com.ruoyi.basic.mapper.SupplierManageMapper; |
| | | import com.ruoyi.basic.pojo.Customer; |
| | | import com.ruoyi.basic.pojo.Product; |
| | | import com.ruoyi.basic.pojo.ProductModel; |
| | | import com.ruoyi.basic.pojo.SupplierManage; |
| | | import com.ruoyi.collaborativeApproval.mapper.NoticeMapper; |
| | | import com.ruoyi.collaborativeApproval.pojo.Notice; |
| | |
| | | private SalesLedgerProductMapper salesLedgerProductMapper; |
| | | |
| | | @Autowired |
| | | private StockInventoryMapper stockInventoryMapper; |
| | | |
| | | @Autowired |
| | | private ProcurementRecordMapper procurementRecordStorageMapper; |
| | | |
| | | @Autowired |
| | |
| | | private SysUserMapper sysUserMapper; |
| | | @Autowired |
| | | private SysUserDeptMapper sysUserDeptMapper; |
| | | |
| | | @Autowired |
| | | private StockInventoryMapper stockInventoryMapper; |
| | | private HomeMapper homeMapper; |
| | | |
| | | @Override |
| | | public HomeBusinessDto business() { |
| | |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public List<MapDto> productSalesAnalysis() { |
| | | // 获取所有产品大类的销售额 |
| | | List<Map<String, Object>> analysisResults = salesLedgerProductMapper.selectProductSalesAnalysis(); |
| | | if (CollectionUtils.isEmpty(analysisResults)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // 计算总销售额 |
| | | BigDecimal totalSalesAmount = analysisResults.stream() |
| | | .map(r -> (BigDecimal) r.get("value")) |
| | | .filter(Objects::nonNull) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | | return analysisResults.stream() |
| | | .map(result -> { |
| | | MapDto mapDto = new MapDto(); |
| | | String name = (String) result.get("name"); |
| | | BigDecimal value = (BigDecimal) result.get("value"); |
| | | |
| | | mapDto.setName(name); |
| | | mapDto.setValue(value != null ? value.setScale(2, RoundingMode.HALF_UP).toString() : "0.00"); |
| | | |
| | | if (totalSalesAmount.compareTo(BigDecimal.ZERO) == 0 || value == null) { |
| | | mapDto.setRate("0.00"); |
| | | } else { |
| | | String rate = value.divide(totalSalesAmount, 4, RoundingMode.HALF_UP) |
| | | .multiply(new BigDecimal("100")) |
| | | .setScale(2, RoundingMode.HALF_UP) |
| | | .toString(); |
| | | mapDto.setRate(rate); |
| | | } |
| | | return mapDto; |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | public List<MapDto> rawMaterialPurchaseAmountRatio() { |
| | | // 获取所有原材料的采购额 |
| | | List<Map<String, Object>> analysisResults = salesLedgerProductMapper.selectRawMaterialPurchaseAnalysis(); |
| | | if (CollectionUtils.isEmpty(analysisResults)) { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | // 计算总采购额 |
| | | BigDecimal totalPurchaseAmount = analysisResults.stream() |
| | | .map(r -> (BigDecimal) r.get("value")) |
| | | .filter(Objects::nonNull) |
| | | .reduce(BigDecimal.ZERO, BigDecimal::add); |
| | | |
| | | return analysisResults.stream() |
| | | .map(result -> { |
| | | MapDto mapDto = new MapDto(); |
| | | String name = (String) result.get("name"); |
| | | BigDecimal value = (BigDecimal) result.get("value"); |
| | | |
| | | mapDto.setName(name); |
| | | mapDto.setValue(value != null ? value.setScale(2, RoundingMode.HALF_UP).toString() : "0.00"); |
| | | |
| | | if (totalPurchaseAmount.compareTo(BigDecimal.ZERO) == 0 || value == null) { |
| | | mapDto.setRate("0.00"); |
| | | } else { |
| | | String rate = value.divide(totalPurchaseAmount, 4, RoundingMode.HALF_UP) |
| | | .multiply(new BigDecimal("100")) |
| | | .setScale(2, RoundingMode.HALF_UP) |
| | | .toString(); |
| | | mapDto.setRate(rate); |
| | | } |
| | | return mapDto; |
| | | }) |
| | | .collect(Collectors.toList()); |
| | | } |
| | | |
| | | @Override |
| | | public List<MapDto> salesPurchaseStorageProductCount() { |
| | | LocalDate now = LocalDate.now(); |
| | | DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd"); |
| | | |
| | | 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 lastSales = salesLedgerProductMapper.selectProductCountByTypeAndDate(1, lastMonthStart, lastMonthEnd); |
| | | |
| | | // 采购 |
| | | int currentPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, currentMonthStart, currentMonthNow); |
| | | int lastPurchase = salesLedgerProductMapper.selectProductCountByTypeAndDate(2, lastMonthStart, lastMonthEnd); |
| | | |
| | | // 储存 |
| | | int currentStorage = stockInventoryMapper.selectStorageProductCountByDate(currentMonthStart, currentMonthNow); |
| | | int lastStorage = stockInventoryMapper.selectStorageProductCountByDate(lastMonthStart, lastMonthEnd); |
| | | |
| | | List<MapDto> list = new ArrayList<>(); |
| | | list.add(createMapDto("销售产品数", currentSales, lastSales)); |
| | | list.add(createMapDto("采购产品数", currentPurchase, lastPurchase)); |
| | | list.add(createMapDto("储存产品数", currentStorage, lastStorage)); |
| | | |
| | | return list; |
| | | } |
| | | |
| | | private MapDto createMapDto(String name, int current, int last) { |
| | | MapDto dto = new MapDto(); |
| | | dto.setName(name); |
| | | dto.setValue(String.valueOf(current)); |
| | | |
| | | if (last == 0) { |
| | | dto.setRate(current > 0 ? "100.00" : "0.00"); |
| | | } else { |
| | | BigDecimal curDec = new BigDecimal(current); |
| | | BigDecimal lastDec = new BigDecimal(last); |
| | | // 增长率 |
| | | String rate = curDec.subtract(lastDec) |
| | | .divide(lastDec, 4, RoundingMode.HALF_UP) |
| | | .multiply(new BigDecimal("100")) |
| | | .setScale(2, RoundingMode.HALF_UP) |
| | | .toString(); |
| | | dto.setRate(rate); |
| | | } |
| | | return dto; |
| | | } |
| | | |
| | | @Override |
| | | public List<Map<String, Object>> productInOutAnalysis(Integer type) { |
| | | String targetName; |
| | | if (type == 1) { |
| | | targetName = "原材料"; |
| | | } else if (type == 2) { |
| | | targetName = "成品"; |
| | | } else if (type == 3) { |
| | | targetName = "半成品"; |
| | | } else { |
| | | return new ArrayList<>(); |
| | | } |
| | | |
| | | LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>(); |
| | | queryWrapper.eq(Product::getProductName, targetName).isNull(Product::getParentId); |
| | | Product rootCategory = productMapper.selectOne(queryWrapper); |
| | | |
| | | if (rootCategory == null) { |
| | | log.warn("未找到名称为 {} 的顶级产品分类", targetName); |
| | | return new ArrayList<>(); |
| | | } |
| | | Long rootCategoryId = rootCategory.getId(); |
| | | |
| | | LocalDate now = LocalDate.now(); |
| | | DateTimeFormatter displayDtf = DateTimeFormatter.ofPattern("M/d"); |
| | | |
| | | String startDate = now.minusDays(6).toString(); |
| | | String endDate = now.toString(); |
| | | |
| | | List<Map<String, Object>> inCounts = stockInventoryMapper.selectDailyStockInCounts(rootCategoryId, startDate, endDate + " 23:59:59"); |
| | | |
| | | List<Map<String, Object>> outCounts = stockInventoryMapper.selectDailyStockOutCounts(rootCategoryId, startDate, endDate + " 23:59:59"); |
| | | |
| | | Map<LocalDate, BigDecimal> inMap = inCounts.stream() |
| | | .collect(Collectors.toMap( |
| | | m -> ((java.sql.Date) m.get("date")).toLocalDate(), |
| | | m -> (BigDecimal) m.get("count"), |
| | | BigDecimal::add |
| | | )); |
| | | |
| | | Map<LocalDate, BigDecimal> outMap = outCounts.stream() |
| | | .collect(Collectors.toMap( |
| | | m -> ((java.sql.Date) m.get("date")).toLocalDate(), |
| | | m -> (BigDecimal) m.get("count"), |
| | | BigDecimal::add |
| | | )); |
| | | |
| | | List<Map<String, Object>> result = new ArrayList<>(); |
| | | |
| | | for (int i = 6; i >= 0; i--) { |
| | | LocalDate date = now.minusDays(i); |
| | | |
| | | Map<String, Object> dataPoint = new LinkedHashMap<>(); |
| | | dataPoint.put("date", date.format(displayDtf)); // 1/23 |
| | | dataPoint.put("inCount", inMap.getOrDefault(date, BigDecimal.ZERO)); |
| | | dataPoint.put("outCount", outMap.getOrDefault(date, BigDecimal.ZERO)); |
| | | |
| | | result.add(dataPoint); |
| | | } |
| | | |
| | | return result; |
| | | } |
| | | |
| | | @Override |
| | | public List<MapDto> productTurnoverDays() { |
| | | return homeMapper.productTurnoverDays(); |
| | | } |
| | | } |