| src/main/java/com/ruoyi/home/controller/HomeController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/home/mapper/HomeMapper.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/home/service/HomeService.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/mapper/home/HomeMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/mapper/sales/SalesLedgerProductMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
| src/main/resources/mapper/stock/StockInventoryMapper.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -7,6 +7,7 @@ import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.home.dto.*; import com.ruoyi.home.service.HomeService; import com.ruoyi.dto.MapDto; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -96,6 +97,41 @@ return AjaxResult.success(list); } @GetMapping("/productSalesAnalysis") @ApiOperation("å产åéå®éé¢åæ") public AjaxResult productSalesAnalysis() { List<MapDto> list = homeService.productSalesAnalysis(); return AjaxResult.success(list); } @GetMapping("/rawMaterialPurchaseAmountRatio") @ApiOperation("åææéè´éé¢å æ¯") public AjaxResult rawMaterialPurchaseAmountRatio(){ List<MapDto> list = homeService.rawMaterialPurchaseAmountRatio(); return AjaxResult.success(list); } @GetMapping("/salesPurchaseStorageProductCount") @ApiOperation("éå®-éè´-å¨åäº§åæ°") public AjaxResult salesPurchaseStorageProductCount(){ List<MapDto> list = homeService.salesPurchaseStorageProductCount(); return AjaxResult.success(list); } @GetMapping("/productInOutAnalysis") @ApiOperation("产ååºå ¥åºåæ") public AjaxResult productInOutAnalysis(@RequestParam(value = "type", defaultValue = "1") Integer type){ List<Map<String, Object>> result = homeService.productInOutAnalysis(type); return AjaxResult.success(result); } @GetMapping("/productTurnoverDays") @ApiOperation("产åå¨è½¬å¤©æ°") public AjaxResult productTurnoverDays(){ List<MapDto> list = homeService.productTurnoverDays(); return AjaxResult.success(list); } /********************************************************è¥ééè´ç±»**************************************************/ @GetMapping("/business") @Log(title = "éå®-éè´-åºåæ°æ®", businessType = BusinessType.OTHER) @@ -130,6 +166,7 @@ } /********************************************************è´¨éç±»*****************************************************/ @GetMapping("/qualityStatistics") @Log(title = "è´¨éåæ", businessType = BusinessType.OTHER) src/main/java/com/ruoyi/home/mapper/HomeMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ package com.ruoyi.home.mapper; import com.ruoyi.dto.MapDto; import org.apache.ibatis.annotations.Mapper; import java.util.List; /** * é¦é¡µç»è®¡ Mapper * * @author antigravity */ @Mapper public interface HomeMapper { /** * æ¥è¯¢äº§åå¨è½¬å¤©æ° * * @return 产åå¨è½¬å¤©æ°å表 */ List<MapDto> productTurnoverDays(); } src/main/java/com/ruoyi/home/service/HomeService.java
@@ -1,9 +1,8 @@ package com.ruoyi.home.service; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.dto.MapDto; import com.ruoyi.home.dto.*; import com.ruoyi.production.dto.ProductOrderDto; import com.ruoyi.production.dto.ProductWorkOrderDto; import java.text.ParseException; import java.util.List; @@ -45,4 +44,14 @@ ProductCategoryDistributionDto productCategoryDistribution(); List<CustomerContributionRankingDto> customerContributionRanking(Integer type); List<MapDto> productSalesAnalysis(); List<MapDto> rawMaterialPurchaseAmountRatio(); List<MapDto> salesPurchaseStorageProductCount(); List<Map<String, Object>> productInOutAnalysis(Integer type); List<MapDto> productTurnoverDays(); } src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -2,8 +2,8 @@ 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; @@ -12,7 +12,6 @@ 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; @@ -86,6 +85,9 @@ private SalesLedgerProductMapper salesLedgerProductMapper; @Autowired private StockInventoryMapper stockInventoryMapper; @Autowired private ProcurementRecordMapper procurementRecordStorageMapper; @Autowired @@ -125,8 +127,9 @@ private SysUserMapper sysUserMapper; @Autowired private SysUserDeptMapper sysUserDeptMapper; @Autowired private StockInventoryMapper stockInventoryMapper; private HomeMapper homeMapper; @Override public HomeBusinessDto business() { @@ -900,4 +903,199 @@ } 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(); } } src/main/java/com/ruoyi/sales/mapper/SalesLedgerProductMapper.java
@@ -12,6 +12,7 @@ import java.math.BigDecimal; import java.util.List; import java.util.Map; /** * 产åä¿¡æ¯Mapperæ¥å£ @@ -33,4 +34,10 @@ IPage<ProcurementBusinessSummaryDto> procurementBusinessSummaryListPage(Page page,@Param("req") ProcurementBusinessSummaryDto procurementBusinessSummaryDto); List<LossProductModelDto> selectProductBomStructure(@Param("salesLedegerId") Long salesLedegerId); List<Map<String, Object>> selectProductSalesAnalysis(); List<Map<String, Object>> selectRawMaterialPurchaseAnalysis(); int selectProductCountByTypeAndDate(@Param("type") Integer type, @Param("startDate") String startDate, @Param("endDate") String endDate); } src/main/java/com/ruoyi/stock/mapper/StockInventoryMapper.java
@@ -13,6 +13,7 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.util.List; import java.util.Map; /** * <p> @@ -40,5 +41,11 @@ BigDecimal selectTotal(); int selectStorageProductCountByDate(@Param("startDate") String startDate, @Param("endDate") String endDate); List<Map<String, Object>> selectDailyStockInCounts(@Param("rootCategoryId") Long rootCategoryId, @Param("startDate") String startDate, @Param("endDate") String endDate); List<Map<String, Object>> selectDailyStockOutCounts(@Param("rootCategoryId") Long rootCategoryId, @Param("startDate") String startDate, @Param("endDate") String endDate); BigDecimal selectTotalByDate( @Param("now") LocalDate now); } src/main/resources/mapper/home/HomeMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,16 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.home.mapper.HomeMapper"> <select id="productTurnoverDays" resultType="com.ruoyi.dto.MapDto"> SELECT p.product_name AS name, DATEDIFF(IFNULL(MAX(sor.create_time), NOW()), MAX(sir.create_time)) AS value FROM product p JOIN product_model pm ON p.id = pm.product_id JOIN stock_in_record sir ON pm.id = sir.product_model_id LEFT JOIN stock_out_record sor ON pm.id = sor.product_model_id GROUP BY p.id, p.product_name </select> </mapper> src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -147,7 +147,7 @@ LEFT JOIN product_structure ps ON pb.id = ps.bom_id LEFT JOIN product_model pm1 ON pm1.id = ps.product_model_id LEFT JOIN product p ON p.id = pm1.product_id WHERE sl.id = #{salesLedegerId}) A WHERE sl.id = #{salesLedegerId}) A group by a.model, a.product_name, a.unit </select> <select id="selectProduct" resultType="com.ruoyi.sales.pojo.SalesLedgerProduct"> @@ -158,4 +158,46 @@ from product_model pm left join product p on pm.product_id = p.id </select> </mapper> <select id="selectProductSalesAnalysis" resultType="java.util.LinkedHashMap"> SELECT product_category as name, SUM( tax_inclusive_total_price ) AS value FROM sales_ledger_product WHERE type = 1 GROUP BY product_category ORDER BY value DESC LIMIT 5 </select> <select id="selectRawMaterialPurchaseAnalysis" resultType="java.util.LinkedHashMap"> SELECT pr.product_name AS name, SUM( slp.tax_inclusive_total_price ) AS value FROM sales_ledger_product slp JOIN product pr ON slp.product_id = pr.id WHERE slp.type = 2 AND pr.parent_id = ( SELECT id FROM product WHERE product_name = 'åææ' ) GROUP BY pr.id, pr.product_name ORDER BY value DESC LIMIT 5 </select> <select id="selectProductCountByTypeAndDate" resultType="int"> SELECT COUNT(*) FROM sales_ledger_product WHERE type = #{type} AND register_date >= #{startDate} AND register_date <= #{endDate} </select> </mapper> src/main/resources/mapper/stock/StockInventoryMapper.xml
@@ -185,7 +185,7 @@ p.product_name </select> <select id="selectTotal" resultType="java.math.BigDecimal"> select ifnull(sum(qualitity),0) select ifnull(sum(qualitity), 0) from stock_inventory </select> <select id="selectTotalByDate" resultType="java.math.BigDecimal"> @@ -195,4 +195,41 @@ create_time >= #{now} and create_time < DATE_ADD(#{now}, INTERVAL 1 DAY) </select> <select id="selectStorageProductCountByDate" resultType="int"> SELECT COUNT(*) FROM (SELECT create_time FROM stock_inventory UNION ALL SELECT create_time FROM stock_uninventory) combined WHERE create_time >= #{startDate} AND create_time <= #{endDate} </select> <select id="selectDailyStockInCounts" resultType="java.util.Map"> SELECT DATE(sir.create_time) AS date, SUM(sir.stock_in_num) AS count FROM stock_in_record sir JOIN product_model pm ON sir.product_model_id = pm.id JOIN product p ON pm.product_id = p.id WHERE (p.parent_id = #{rootCategoryId} OR p.id = #{rootCategoryId}) AND sir.create_time >= #{startDate} AND sir.create_time <= #{endDate} GROUP BY DATE(sir.create_time) ORDER BY DATE(sir.create_time) ASC </select> <select id="selectDailyStockOutCounts" resultType="java.util.Map"> SELECT DATE(sor.create_time) AS date, SUM(sor.stock_out_num) AS count FROM stock_out_record sor JOIN product_model pm ON sor.product_model_id = pm.id JOIN product p ON pm.product_id = p.id WHERE (p.parent_id = #{rootCategoryId} OR p.id = #{rootCategoryId}) AND sor.create_time >= #{startDate} AND sor.create_time <= #{endDate} GROUP BY DATE(sor.create_time) ORDER BY DATE(sor.create_time) ASC </select> </mapper>