pom.xml
@@ -301,6 +301,12 @@ <artifactId>easyexcel</artifactId> <version>4.0.3</version> </dependency> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.3.3</version> </dependency> </dependencies> src/main/java/com/ruoyi/common/utils/MatrixToImageWriter.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,67 @@ package com.ruoyi.common.utils; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.Map; /** * é ç½®å¾ååå ¥å¨ * * @author z1292 * */ public class MatrixToImageWriter { private final int BLACK = 0xFF000000; private final int WHITE = 0xFFFFFFFF; private BufferedImage toBufferedImage(BitMatrix matrix) { int width = matrix.getWidth(); int height = matrix.getHeight(); BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); } } return image; } private void writeToFile(BitMatrix matrix, String format, File file) throws IOException { BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, file)) { throw new RuntimeException("Could not write an image of format " + format + " to " + file); } } public String code(String content, String path) { try { String codeName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yy_MM_dd&HH_mm_ss"));// äºç»´ç çå¾çå String imageType = "jpg";// å¾çç±»å MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); hints.put(EncodeHintType.MARGIN, 0); BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 400, 400, hints); File file1 = new File(path, codeName + "." + imageType); writeToFile(bitMatrix, imageType, file1); return file1.getPath(); } catch (WriterException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } throw new RuntimeException("äºç»´ç çæå¤±è´¥"); } } src/main/java/com/ruoyi/home/controller/HomeController.java
@@ -1,7 +1,5 @@ package com.ruoyi.home.controller; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.approve.pojo.ApproveProcess; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; @@ -9,9 +7,6 @@ import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.home.dto.*; import com.ruoyi.home.service.HomeService; import com.ruoyi.production.dto.ProductOrderDto; import com.ruoyi.production.dto.ProductWorkOrderDto; import com.ruoyi.production.dto.SalesLedgerWorkDto; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -59,6 +54,47 @@ return AjaxResult.success(count); } @GetMapping("/deptStaffDistribution") @ApiOperation("åé¨é¨äººååå¸") public AjaxResult deptStaffDistribution() { DeptStaffDistributionDto dto = homeService.deptStaffDistribution(); return AjaxResult.success(dto); } @GetMapping("/summaryStatistics") @ApiOperation("åå·¥-客æ·-ä¾åºåæ»æ°") public AjaxResult summaryStatistics() { HomeSummaryDto homeSummaryDto = homeService.summaryStatistics(); return AjaxResult.success(homeSummaryDto); } @GetMapping("/supplierPurchaseRanking") @ApiOperation("ä¾åºåéè´æå") public AjaxResult supplierPurchaseRanking(@RequestParam(value = "type", defaultValue = "0") Integer type) { List<SupplierPurchaseRankingDto> list = homeService.supplierPurchaseRanking(type); return AjaxResult.success(list); } @GetMapping("/customerRevenueAnalysis") @ApiOperation("客æ·è¥æ¶è´¡ç®æ°å¼åæ") public AjaxResult customerRevenueAnalysis(@RequestParam("customerId") Long customerId, @RequestParam(value = "type", defaultValue = "0") Integer type) { CustomerRevenueAnalysisDto dto = homeService.customerRevenueAnalysis(customerId, type); return AjaxResult.success(dto); } @GetMapping("/productCategoryDistribution") @ApiOperation("产å大类åå¸") public AjaxResult productCategoryDistribution() { ProductCategoryDistributionDto dto = homeService.productCategoryDistribution(); return AjaxResult.success(dto); } @GetMapping("/customerContributionRanking") @ApiOperation("客æ·éé¢è´¡ç®æå") public AjaxResult customerContributionRanking(@RequestParam(value = "type", defaultValue = "1") Integer type) { List<CustomerContributionRankingDto> list = homeService.customerContributionRanking(type); return AjaxResult.success(list); } /********************************************************è¥ééè´ç±»**************************************************/ @GetMapping("/business") src/main/java/com/ruoyi/home/dto/CustomerContributionRankingDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,21 @@ package com.ruoyi.home.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; /** * 客æ·éé¢è´¡ç®æåDTO */ @Data @ApiModel("客æ·éé¢è´¡ç®æå") public class CustomerContributionRankingDto { @ApiModelProperty("客æ·åç§°") private String customerName; @ApiModelProperty("ååæ»éé¢") private BigDecimal totalAmount; } src/main/java/com/ruoyi/home/dto/CustomerRevenueAnalysisDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,19 @@ package com.ruoyi.home.dto; import com.ruoyi.dto.MapDto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; /** * 客æ·è¥æ¶è´¡ç®æ°å¼åæDTO */ @Data @ApiModel("客æ·è¥æ¶è´¡ç®æ°å¼åæ") public class CustomerRevenueAnalysisDto { @ApiModelProperty("åææ¡ç®å表") private List<MapDto> items; } src/main/java/com/ruoyi/home/dto/DeptStaffDistributionDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,22 @@ package com.ruoyi.home.dto; import com.ruoyi.dto.MapDto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; /** * é¨é¨äººååå¸ç»è®¡DTO */ @Data @ApiModel("é¨é¨äººååå¸ç»è®¡") public class DeptStaffDistributionDto { @ApiModelProperty("é¨é¨æ»äººæ°") private Long total; @ApiModelProperty("é¨é¨åå¸å表") private List<MapDto> items; } src/main/java/com/ruoyi/home/dto/HomeSummaryDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,31 @@ package com.ruoyi.home.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * é¦é¡µæ±æ»ç»è®¡DTO */ @Data @ApiModel("é¦é¡µæ±æ»ç»è®¡") public class HomeSummaryDto { @ApiModelProperty("æ»å·¥ä½äººå") private Long totalStaff; @ApiModelProperty("æ»å·¥ä½äººå忝å¢é¿ç") private String staffGrowthRate; @ApiModelProperty("æ»å®¢æ·æ°") private Long totalCustomer; @ApiModelProperty("æ»å®¢æ·åæ¯å¢é¿ç") private String customerGrowthRate; @ApiModelProperty("æ»ä¾åºåæ°") private Long totalSupplier; @ApiModelProperty("æ»ä¾åºå忝å¢é¿ç") private String supplierGrowthRate; } src/main/java/com/ruoyi/home/dto/ProductCategoryDistributionDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,49 @@ package com.ruoyi.home.dto; import com.ruoyi.dto.MapDto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; /** * 产å大类åå¸ç»è®¡DTO */ @Data @ApiModel("产å大类åå¸ç»è®¡") public class ProductCategoryDistributionDto { @ApiModelProperty("大类åå¸å表") private List<MajorCategoryDto> items; @Data public static class MajorCategoryDto { @ApiModelProperty("大类åç§°") private String name; @ApiModelProperty("åºåæ»æ°") private String value; @ApiModelProperty("å æ¯") private String rate; @ApiModelProperty("å°ç±»åå¸è¯¦æ ") private List<MinorCategoryDto> children; } @Data public static class MinorCategoryDto { @ApiModelProperty("å°ç±»åç§°") private String name; @ApiModelProperty("åºåæ°é") private String value; @ApiModelProperty("å æ¯") private String rate; @ApiModelProperty("åå·åå¸è¯¦æ ") private List<MapDto> children; } } src/main/java/com/ruoyi/home/dto/SupplierPurchaseRankingDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,21 @@ package com.ruoyi.home.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; /** * ä¾åºåéè´æåDTO */ @Data @ApiModel("ä¾åºåéè´æå") public class SupplierPurchaseRankingDto { @ApiModelProperty("ä¾åºååç§°") private String supplierName; @ApiModelProperty("éè´æ»éé¢") private BigDecimal totalAmount; } src/main/java/com/ruoyi/home/service/HomeService.java
@@ -33,4 +33,16 @@ ProductionProgressDto productionProgress(); ProductionTurnoverDto workInProcessTurnover(); DeptStaffDistributionDto deptStaffDistribution(); HomeSummaryDto summaryStatistics(); List<SupplierPurchaseRankingDto> supplierPurchaseRanking(Integer type); CustomerRevenueAnalysisDto customerRevenueAnalysis(Long customerId, Integer type); ProductCategoryDistributionDto productCategoryDistribution(); List<CustomerContributionRankingDto> customerContributionRanking(Integer type); } src/main/java/com/ruoyi/home/service/impl/HomeServiceImpl.java
@@ -1,45 +1,40 @@ package com.ruoyi.home.service.impl; 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.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 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.basic.pojo.ProductModel; import com.ruoyi.basic.pojo.SupplierManage; import com.ruoyi.collaborativeApproval.mapper.NoticeMapper; import com.ruoyi.collaborativeApproval.pojo.Notice; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.device.mapper.DeviceMaintenanceMapper; import com.ruoyi.device.mapper.DeviceRepairMapper; import com.ruoyi.device.pojo.DeviceMaintenance; import com.ruoyi.device.pojo.DeviceRepair; import com.ruoyi.dto.MapDto; import com.ruoyi.framework.security.LoginUser; import com.ruoyi.home.dto.*; import com.ruoyi.home.service.HomeService; import com.ruoyi.lavorissue.mapper.LavorIssueMapper; import com.ruoyi.lavorissue.pojo.LaborIssue; import com.ruoyi.procurementrecord.mapper.CustomStorageMapper; import com.ruoyi.procurementrecord.mapper.ProcurementRecordMapper; import com.ruoyi.procurementrecord.mapper.ProcurementRecordOutMapper; import com.ruoyi.procurementrecord.pojo.CustomStorage; import com.ruoyi.procurementrecord.pojo.ProcurementRecordOut; 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.dto.ProductionProductMainDto; import com.ruoyi.production.mapper.ProductOrderMapper; import com.ruoyi.production.mapper.ProductProcessMapper; import com.ruoyi.production.mapper.ProductWorkOrderMapper; import com.ruoyi.production.mapper.ProductionProductMainMapper; import com.ruoyi.production.pojo.ProductOrder; import com.ruoyi.production.pojo.ProductProcess; import com.ruoyi.production.pojo.ProductWorkOrder; import com.ruoyi.project.system.domain.SysDept; import com.ruoyi.project.system.domain.SysUserDept; import com.ruoyi.project.system.mapper.SysDeptMapper; import com.ruoyi.project.system.mapper.SysUserDeptMapper; import com.ruoyi.purchase.mapper.PaymentRegistrationMapper; import com.ruoyi.purchase.mapper.PurchaseLedgerMapper; import com.ruoyi.purchase.pojo.PaymentRegistration; @@ -49,9 +44,13 @@ import com.ruoyi.sales.mapper.ReceiptPaymentMapper; import com.ruoyi.sales.mapper.SalesLedgerMapper; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.project.system.domain.SysUser; import com.ruoyi.project.system.mapper.SysUserMapper; import com.ruoyi.sales.pojo.ReceiptPayment; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.staff.mapper.StaffOnJobMapper; import com.ruoyi.staff.pojo.StaffOnJob; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -60,13 +59,11 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; /** @@ -87,13 +84,7 @@ private SalesLedgerProductMapper salesLedgerProductMapper; @Autowired private ProcurementRecordOutMapper procurementRecordOutMapper; @Autowired private ProcurementRecordMapper procurementRecordStorageMapper; @Autowired private CustomStorageMapper customStorageMapper; @Autowired private QualityInspectMapper qualityStatisticsMapper; @@ -108,9 +99,6 @@ private PaymentRegistrationMapper paymentRegistrationMapper; @Autowired private LavorIssueMapper lavorIssueMapper; @Autowired private SysDeptMapper sysDeptMapper; @Autowired @@ -118,13 +106,24 @@ @Autowired private ProductOrderMapper productOrderMapper; @Autowired private ProductProcessMapper productProcessMapper; @Autowired private ProductWorkOrderMapper productWorkOrderMapper; @Autowired private ProductModelMapper productModelMapper; @Autowired private ProductMapper productMapper; @Autowired private StockUtils stockUtils; @Autowired private StaffOnJobMapper staffOnJobMapper; @Autowired private CustomerMapper customerMapper; @Autowired private SupplierManageMapper supplierManageMapper; @Autowired private SysUserMapper sysUserMapper; @Autowired private SysUserDeptMapper sysUserDeptMapper; @Override public HomeBusinessDto business() { // æå»ºç»æ @@ -581,6 +580,398 @@ productionTurnoverDto.setProcessDetails(strings); productionTurnoverDto.setProcessQuantityDetails(processQuantityDetails); return productionTurnoverDto; } @Override public DeptStaffDistributionDto deptStaffDistribution() { DeptStaffDistributionDto dto = new DeptStaffDistributionDto(); List<MapDto> items = new ArrayList<>(); // æ¥è¯¢æææ£å¸¸ä¸æªå é¤çé¨é¨ List<SysDept> depts = sysDeptMapper.selectDeptList(new SysDept()); if (CollectionUtils.isEmpty(depts)) { dto.setItems(items); return dto; } long totalUsers = 0; List<Map<String, Object>> countsByDept = new ArrayList<>(); for (SysDept dept : depts) { if ("0".equals(dept.getStatus()) && "0".equals(dept.getDelFlag())) { Long count = sysUserDeptMapper.selectCount(new LambdaQueryWrapper<SysUserDept>() .eq(SysUserDept::getDeptId, dept.getDeptId())); if (count > 0) { Map<String, Object> map = new HashMap<>(); map.put("name", dept.getDeptName()); map.put("count", count); countsByDept.add(map); totalUsers += count; } } } if (totalUsers > 0) { BigDecimal total = BigDecimal.valueOf(totalUsers); for (Map<String, Object> map : countsByDept) { MapDto mapDto = new MapDto(); mapDto.setName((String) map.get("name")); Long count = (Long) map.get("count"); mapDto.setValue(count.toString()); mapDto.setRate(BigDecimal.valueOf(count).multiply(new BigDecimal("100")) .divide(total, 2, RoundingMode.HALF_UP).toString()); items.add(mapDto); } } dto.setTotal(totalUsers); dto.setItems(items); return dto; } @Override public HomeSummaryDto summaryStatistics() { HomeSummaryDto dto = new HomeSummaryDto(); LocalDate now = LocalDate.now(); YearMonth currentMonth = YearMonth.from(now); YearMonth prevMonth = currentMonth.minusMonths(1); LocalDateTime currentMonthEnd = currentMonth.atEndOfMonth().atTime(23, 59, 59); LocalDateTime prevMonthEnd = prevMonth.atEndOfMonth().atTime(23, 59, 59); // æ»å·¥ä½äººå Long currentStaff = countStaff(currentMonthEnd); Long prevStaff = countStaff(prevMonthEnd); dto.setTotalStaff(currentStaff); dto.setStaffGrowthRate(calculateMoM(currentStaff, prevStaff)); // æ»å®¢æ·æ° Long currentCustomers = countCustomers(currentMonthEnd); Long prevCustomers = countCustomers(prevMonthEnd); dto.setTotalCustomer(currentCustomers); dto.setCustomerGrowthRate(calculateMoM(currentCustomers, prevCustomers)); // æ»ä¾åºåæ° Long currentSuppliers = countSuppliers(currentMonthEnd); Long prevSuppliers = countSuppliers(prevMonthEnd); dto.setTotalSupplier(currentSuppliers); dto.setSupplierGrowthRate(calculateMoM(currentSuppliers, prevSuppliers)); return dto; } private Long countStaff(LocalDateTime dateTime) { Long sysUserCount = sysUserMapper.selectCount(new LambdaQueryWrapper<SysUser>() .eq(SysUser::getDelFlag, "0") .le(SysUser::getCreateTime, dateTime)); Long staffCountItem = staffOnJobMapper.selectCount(new LambdaQueryWrapper<StaffOnJob>() .le(StaffOnJob::getCreateTime, dateTime)); return sysUserCount + staffCountItem; } private Long countCustomers(LocalDateTime dateTime) { return customerMapper.selectCount(new LambdaQueryWrapper<Customer>() .le(Customer::getMaintenanceTime, dateTime.toLocalDate())); } private Long countSuppliers(LocalDateTime dateTime) { return supplierManageMapper.selectCount(new LambdaQueryWrapper<SupplierManage>() .le(SupplierManage::getCreateTime, dateTime)); } private String calculateMoM(Number current, Number prev) { BigDecimal curVal = new BigDecimal(current.toString()); BigDecimal prevVal = new BigDecimal(prev.toString()); if (prevVal.compareTo(BigDecimal.ZERO) == 0) { return curVal.compareTo(BigDecimal.ZERO) > 0 ? "100.00" : "0.00"; } return curVal.subtract(prevVal) .divide(prevVal, 4, RoundingMode.HALF_UP) .multiply(new BigDecimal("100")) .setScale(2, RoundingMode.HALF_UP) .toString(); } @Override public List<SupplierPurchaseRankingDto> supplierPurchaseRanking(Integer type) { LocalDate today = LocalDate.now(); LocalDate startDate; LocalDate endDate; switch (type) { case 0: // å¨ startDate = today.with(DayOfWeek.MONDAY); endDate = today.with(DayOfWeek.SUNDAY); break; case 1: // æ startDate = today.with(TemporalAdjusters.firstDayOfMonth()); endDate = today.with(TemporalAdjusters.lastDayOfMonth()); break; case 2: // å£åº¦ Month currentMonth = today.getMonth(); Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter(); Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2); startDate = today.withMonth(firstMonthOfQuarter.getValue()).with(TemporalAdjusters.firstDayOfMonth()); endDate = today.withMonth(lastMonthOfQuarter.getValue()).with(TemporalAdjusters.lastDayOfMonth()); break; default: return new ArrayList<>(); } QueryWrapper<PurchaseLedger> queryWrapper = new QueryWrapper<>(); queryWrapper.select("supplier_name", "SUM(contract_amount) as total_amount") .ge("entry_date", startDate) .le("entry_date", endDate) // .ne("approval_status", 3) .groupBy("supplier_name") .orderByDesc("total_amount") .last("LIMIT 5"); List<Map<String, Object>> maps = purchaseLedgerMapper.selectMaps(queryWrapper); return maps.stream().map(map -> { SupplierPurchaseRankingDto dto = new SupplierPurchaseRankingDto(); dto.setSupplierName(map.get("supplier_name") != null ? map.get("supplier_name").toString() : ""); Object amount = map.get("total_amount"); dto.setTotalAmount(amount != null ? new BigDecimal(amount.toString()) : BigDecimal.ZERO); return dto; }).collect(Collectors.toList()); } @Override public CustomerRevenueAnalysisDto customerRevenueAnalysis(Long customerId, Integer type) { CustomerRevenueAnalysisDto dto = new CustomerRevenueAnalysisDto(); List<MapDto> items = new ArrayList<>(); LocalDate today = LocalDate.now(); LocalDate start; LocalDate end; boolean groupByMonth = false; switch (type) { case 0: // å¨ start = today.with(DayOfWeek.MONDAY); end = today.with(DayOfWeek.SUNDAY); break; case 1: // æ start = today.with(TemporalAdjusters.firstDayOfMonth()); end = today.with(TemporalAdjusters.lastDayOfMonth()); break; case 2: // å£åº¦ Month firstMonthOfQuarter = today.getMonth().firstMonthOfQuarter(); start = today.withMonth(firstMonthOfQuarter.getValue()).with(TemporalAdjusters.firstDayOfMonth()); end = today.withMonth(firstMonthOfQuarter.plus(2).getValue()).with(TemporalAdjusters.lastDayOfMonth()); groupByMonth = true; break; default: dto.setItems(items); return dto; } List<SalesLedger> list = salesLedgerMapper.selectList(new LambdaQueryWrapper<SalesLedger>() .eq(SalesLedger::getCustomerId, customerId) .ge(SalesLedger::getEntryDate, start) .le(SalesLedger::getEntryDate, end)); if (groupByMonth) { for (int i = 0; i < 3; i++) { LocalDate m = start.plusMonths(i); String monthName = m.getMonthValue() + "æ"; BigDecimal sum = list.stream() .filter(l -> l.getEntryDate() != null) .filter(l -> { LocalDate ld = l.getEntryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); return ld.getMonth() == m.getMonth() && ld.getYear() == m.getYear(); }) .map(SalesLedger::getContractAmount) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add); MapDto mapDto = new MapDto(); mapDto.setName(monthName); mapDto.setValue(sum.setScale(2, RoundingMode.HALF_UP).toString()); items.add(mapDto); } } else { long days = ChronoUnit.DAYS.between(start, end) + 1; for (int i = 0; i < days; i++) { LocalDate d = start.plusDays(i); String dayName = d.getMonthValue() + "/" + d.getDayOfMonth(); BigDecimal sum = list.stream() .filter(l -> l.getEntryDate() != null) .filter(l -> l.getEntryDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate().equals(d)) .map(SalesLedger::getContractAmount) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add); MapDto mapDto = new MapDto(); mapDto.setName(dayName); mapDto.setValue(sum.setScale(2, RoundingMode.HALF_UP).toString()); items.add(mapDto); } } dto.setItems(items); return dto; } @Override public ProductCategoryDistributionDto productCategoryDistribution() { ProductCategoryDistributionDto dto = new ProductCategoryDistributionDto(); List<ProductCategoryDistributionDto.MajorCategoryDto> majorItems = new ArrayList<>(); // ææç产å大类åå°ç±» List<Product> allProducts = productMapper.selectList(new LambdaQueryWrapper<Product>()); if (CollectionUtils.isEmpty(allProducts)) { dto.setItems(majorItems); return dto; } List<Product> majorCategories = allProducts.stream().filter(p -> p.getParentId() == null).collect(Collectors.toList()); List<Product> minorCategories = allProducts.stream().filter(p -> p.getParentId() != null).collect(Collectors.toList()); // ä» sales_ledger_product æ¿å°æ¯ä¸ªäº§åçåå·åºå // éå å«è§æ ¼åå·ä»¥æ¯æä¸çº§åå¸ List<Map<String, Object>> quantityMaps = salesLedgerProductMapper.selectMaps(new QueryWrapper<SalesLedgerProduct>() .select("product_id", "specification_model", "type", "SUM(quantity) as sum_qty") .isNotNull("product_id") .groupBy("product_id", "specification_model", "type")); Map<Long, Map<String, Map<Integer, BigDecimal>>> modelStockGroups = new HashMap<>(); for (Map<String, Object> map : quantityMaps) { Long productId = Long.parseLong(map.get("product_id").toString()); String model = map.get("specification_model") != null ? map.get("specification_model").toString() : "æªç¥åå·"; Integer type = Integer.parseInt(map.get("type").toString()); BigDecimal sum = map.get("sum_qty") != null ? new BigDecimal(map.get("sum_qty").toString()) : BigDecimal.ZERO; modelStockGroups.computeIfAbsent(productId, k -> new HashMap<>()) .computeIfAbsent(model, k -> new HashMap<>()) .put(type, sum); } // åºåå¹¶æ±æ» Map<Long, List<MapDto>> productModelsMap = new HashMap<>(); Map<Long, BigDecimal> productTotalStockMap = new HashMap<>(); for (Long pid : modelStockGroups.keySet()) { Map<String, Map<Integer, BigDecimal>> models = modelStockGroups.get(pid); BigDecimal productStock = BigDecimal.ZERO; List<MapDto> modelDtos = new ArrayList<>(); for (String modelName : models.keySet()) { Map<Integer, BigDecimal> types = models.get(modelName); BigDecimal procurement = types.getOrDefault(2, BigDecimal.ZERO); BigDecimal sales = types.getOrDefault(1, BigDecimal.ZERO); BigDecimal stock = procurement.subtract(sales); if (stock.compareTo(BigDecimal.ZERO) < 0) stock = BigDecimal.ZERO; MapDto modelDto = new MapDto(); modelDto.setName(modelName); modelDto.setValue(stock.stripTrailingZeros().toPlainString()); modelDtos.add(modelDto); productStock = productStock.add(stock); } productModelsMap.put(pid, modelDtos); productTotalStockMap.put(pid, productStock); } BigDecimal totalInventory = productTotalStockMap.values().stream().reduce(BigDecimal.ZERO, BigDecimal::add); // åå·å æ¯ if (totalInventory.compareTo(BigDecimal.ZERO) > 0) { for (List<MapDto> dtos : productModelsMap.values()) { for (MapDto m : dtos) { BigDecimal val = new BigDecimal(m.getValue()); m.setRate(val.multiply(new BigDecimal("100")) .divide(totalInventory, 2, RoundingMode.HALF_UP).toString()); } } } // å屿°æ® for (Product major : majorCategories) { ProductCategoryDistributionDto.MajorCategoryDto majorDto = new ProductCategoryDistributionDto.MajorCategoryDto(); majorDto.setName(major.getProductName()); List<ProductCategoryDistributionDto.MinorCategoryDto> minorDtos = new ArrayList<>(); BigDecimal majorStock = BigDecimal.ZERO; for (Product minor : minorCategories) { if (major.getId().equals(minor.getParentId())) { BigDecimal stock = productTotalStockMap.getOrDefault(minor.getId(), BigDecimal.ZERO); ProductCategoryDistributionDto.MinorCategoryDto minorDto = new ProductCategoryDistributionDto.MinorCategoryDto(); minorDto.setName(minor.getProductName()); minorDto.setValue(stock.stripTrailingZeros().toPlainString()); if (totalInventory.compareTo(BigDecimal.ZERO) > 0) { minorDto.setRate(stock.multiply(new BigDecimal("100")) .divide(totalInventory, 2, RoundingMode.HALF_UP).toString()); } else { minorDto.setRate("0.00"); } minorDto.setChildren(productModelsMap.getOrDefault(minor.getId(), new ArrayList<>())); minorDtos.add(minorDto); majorStock = majorStock.add(stock); } } majorDto.setValue(majorStock.stripTrailingZeros().toPlainString()); if (totalInventory.compareTo(BigDecimal.ZERO) > 0) { majorDto.setRate(majorStock.multiply(new BigDecimal("100")) .divide(totalInventory, 2, RoundingMode.HALF_UP).toString()); } else { majorDto.setRate("0.00"); } majorDto.setChildren(minorDtos); majorItems.add(majorDto); } dto.setItems(majorItems); return dto; } @Override public List<CustomerContributionRankingDto> customerContributionRanking(Integer type) { LocalDate today = LocalDate.now(); LocalDate startDate = null; LocalDate endDate = null; switch (type) { case 0: startDate = today.with(DayOfWeek.MONDAY); endDate = today.with(DayOfWeek.SUNDAY); break; case 1: startDate = today.with(TemporalAdjusters.firstDayOfMonth()); endDate = today.with(TemporalAdjusters.lastDayOfMonth()); break; case 2: Month currentMonth = today.getMonth(); Month firstMonthOfQuarter = currentMonth.firstMonthOfQuarter(); Month lastMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2); startDate = today.withMonth(firstMonthOfQuarter.getValue()).with(TemporalAdjusters.firstDayOfMonth()); endDate = today.withMonth(lastMonthOfQuarter.getValue()).with(TemporalAdjusters.lastDayOfMonth()); break; } QueryWrapper<SalesLedger> queryWrapper = new QueryWrapper<>(); queryWrapper.select("customer_name", "SUM(contract_amount) as total_amount") .isNotNull("customer_name") .groupBy("customer_name") .orderByDesc("total_amount") .last("LIMIT 5"); if (startDate != null && endDate != null) { queryWrapper.between("entry_date", startDate, endDate); } List<Map<String, Object>> maps = salesLedgerMapper.selectMaps(queryWrapper); List<CustomerContributionRankingDto> result = new ArrayList<>(); for (Map<String, Object> map : maps) { CustomerContributionRankingDto rankingDto = new CustomerContributionRankingDto(); rankingDto.setCustomerName(map.get("customer_name").toString()); rankingDto.setTotalAmount(map.get("total_amount") != null ? new BigDecimal(map.get("total_amount").toString()) : BigDecimal.ZERO); result.add(rankingDto); } return result; } } src/main/java/com/ruoyi/production/controller/ProductWorkOrderController.java
@@ -3,10 +3,14 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.web.domain.R; import com.ruoyi.production.dto.ProductWorkOrderDto; import com.ruoyi.production.pojo.ProductWorkOrder; import com.ruoyi.production.service.ProductWorkOrderService; import com.ruoyi.quality.pojo.QualityInspect; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; @RestController @AllArgsConstructor @@ -43,4 +47,14 @@ return R.ok(productWorkOrderservice.getById(id)); } /** * å·¥åæµè½¬å¡ä¸è½½ * @param response * @param productWorkOrder */ @PostMapping("/down") public void down(HttpServletResponse response, @RequestBody ProductWorkOrder productWorkOrder) { productWorkOrderservice.down(response, productWorkOrder); } } src/main/java/com/ruoyi/production/controller/ProductWorkOrderFileController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,70 @@ package com.ruoyi.production.controller; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.production.pojo.ProductWorkOrderFile; import com.ruoyi.production.service.ProductWorkOrderFileService; import com.ruoyi.quality.pojo.QualityInspectFile; import com.ruoyi.quality.service.IQualityInspectFileService; import io.swagger.annotations.Api; import org.checkerframework.checker.units.qual.A; import org.springframework.util.CollectionUtils; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import java.util.List; /** * <p> * ç产工åé件表 å端æ§å¶å¨ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-01-23 03:28:32 */ @Api(tags = "ç产工åé件表") @RestController @RequestMapping("/productWorkOrderFile") public class ProductWorkOrderFileController { @Resource private ProductWorkOrderFileService productWorkOrderFileService; /** * æ°å¢ * @param productWorkOrderFile * @return */ @PostMapping("/add") public AjaxResult add(@RequestBody ProductWorkOrderFile productWorkOrderFile) { return AjaxResult.success(productWorkOrderFileService.save(productWorkOrderFile)); } /** * å é¤ * @param ids * @return */ @DeleteMapping("/del") public AjaxResult delQualityUnqualified(@RequestBody List<Integer> ids) { if(CollectionUtils.isEmpty(ids)){ return AjaxResult.error("è¯·éæ©è³å°ä¸æ¡æ°æ®"); } //å 餿£éªéä»¶ return AjaxResult.success(productWorkOrderFileService.removeBatchByIds(ids)); } /** *å页æ¥è¯¢ * @param page * @param productWorkOrderFile * @return */ @GetMapping("/listPage") public AjaxResult listPage(Page page, ProductWorkOrderFile productWorkOrderFile) { return AjaxResult.success(productWorkOrderFileService.page(page, Wrappers.<ProductWorkOrderFile>lambdaQuery().eq(ProductWorkOrderFile::getWorkOrderId,productWorkOrderFile.getWorkOrderId()))); } } src/main/java/com/ruoyi/production/dto/ProductWorkOrderDto.java
@@ -2,11 +2,13 @@ import com.ruoyi.framework.aspectj.lang.annotation.Excel; import com.ruoyi.production.pojo.ProductWorkOrder; import com.ruoyi.production.pojo.ProductWorkOrderFile; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import java.math.BigDecimal; import java.util.List; @EqualsAndHashCode(callSuper = true) @Data @@ -35,4 +37,7 @@ @ApiModelProperty(value = "宿è¿åº¦") private BigDecimal completionStatus; @ApiModelProperty(value = "æ¥åºæ°é") private BigDecimal scrapQty; } src/main/java/com/ruoyi/production/mapper/ProductWorkOrderFileMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,18 @@ package com.ruoyi.production.mapper; import com.ruoyi.production.pojo.ProductWorkOrderFile; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; /** * <p> * ç产工åé件表 Mapper æ¥å£ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-01-23 03:28:32 */ @Mapper public interface ProductWorkOrderFileMapper extends BaseMapper<ProductWorkOrderFile> { } src/main/java/com/ruoyi/production/mapper/ProductWorkOrderMapper.java
@@ -17,4 +17,5 @@ IPage<ProductWorkOrderDto> pageProductWorkOrder(Page<ProductWorkOrderDto> page, @Param("c") ProductWorkOrderDto productWorkOrder); ProductWorkOrderDto getProductWorkOrderFlowCard(@Param("id") Long id); } src/main/java/com/ruoyi/production/pojo/ProductProcessRoute.java
@@ -5,8 +5,10 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.time.LocalDateTime; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; src/main/java/com/ruoyi/production/pojo/ProductWorkOrderFile.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,65 @@ package com.ruoyi.production.pojo; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.time.LocalDateTime; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; /** * <p> * ç产工åé件表 * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-01-23 03:28:32 */ @Getter @Setter @TableName("product_work_order_file") @ApiModel(value = "ProductWorkOrderFile对象", description = "ç产工åé件表") public class ProductWorkOrderFile implements Serializable { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.AUTO) private Integer id; @ApiModelProperty("å ³èå·¥åid") private Integer workOrderId; @ApiModelProperty("æä»¶åç§°") private String name; @ApiModelProperty("æä»¶è·¯å¾") private String url; @ApiModelProperty("æä»¶å¤§å°") private Integer fileSize; @ApiModelProperty("å建æ¶é´") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; @ApiModelProperty("åå»ºç¨æ·") @TableField(fill = FieldFill.INSERT) private Long createUser; @ApiModelProperty("ä¿®æ¹æ¶é´") @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; @ApiModelProperty("ä¿®æ¹ç¨æ·") @TableField(fill = FieldFill.INSERT_UPDATE) private Long updateUser; @ApiModelProperty("ç§æ·ID") @TableField(fill = FieldFill.INSERT) private Long tenantId; } src/main/java/com/ruoyi/production/pojo/ProductionProductOutput.java
@@ -20,7 +20,6 @@ @ApiModelProperty(value = "产åid") private Long productModelId; //åæ ¼æ°é=æ¥å·¥æ°é-æ¥åºæ°é @ApiModelProperty(value = "æ¥å·¥æ°é") private BigDecimal quantity; src/main/java/com/ruoyi/production/service/ProductWorkOrderFileService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,16 @@ package com.ruoyi.production.service; import com.ruoyi.production.pojo.ProductWorkOrderFile; import com.baomidou.mybatisplus.extension.service.IService; /** * <p> * ç产工åé件表 æå¡ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-01-23 03:28:32 */ public interface ProductWorkOrderFileService extends IService<ProductWorkOrderFile> { } src/main/java/com/ruoyi/production/service/ProductWorkOrderService.java
@@ -6,10 +6,13 @@ import com.ruoyi.production.dto.ProductWorkOrderDto; import com.ruoyi.production.pojo.ProductWorkOrder; import javax.servlet.http.HttpServletResponse; public interface ProductWorkOrderService extends IService<ProductWorkOrder>{ IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder); int updateProductWorkOrder(ProductWorkOrderDto productWorkOrderDto); void down(HttpServletResponse response, ProductWorkOrder productWorkOrder); } src/main/java/com/ruoyi/production/service/impl/ProductOrderServiceImpl.java
@@ -91,7 +91,7 @@ ProductWorkOrder productWorkOrder = new ProductWorkOrder(); productWorkOrder.setProductProcessRouteItemId(productProcessRouteItem.getId()); productWorkOrder.setProductOrderId(productOrder.getId()); ProductOrder order = productOrderMapper.selectById(productOrder); ProductOrder order = productOrderMapper.selectById(productOrder.getId()); productWorkOrder.setPlanQuantity(order.getQuantity()); productWorkOrder.setWorkOrderNo(workOrderNoStr); productWorkOrder.setStatus(1); src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderFileServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,20 @@ package com.ruoyi.production.service.impl; import com.ruoyi.production.pojo.ProductWorkOrderFile; import com.ruoyi.production.mapper.ProductWorkOrderFileMapper; import com.ruoyi.production.service.ProductWorkOrderFileService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; /** * <p> * ç产工åé件表 æå¡å®ç°ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-01-23 03:28:32 */ @Service public class ProductWorkOrderFileServiceImpl extends ServiceImpl<ProductWorkOrderFileMapper, ProductWorkOrderFile> implements ProductWorkOrderFileService { } src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderServiceImpl.java
@@ -2,22 +2,49 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.PictureRenderData; import com.deepoove.poi.data.Pictures; import com.ruoyi.common.utils.HackLoopTableRenderPolicy; import com.ruoyi.common.utils.MatrixToImageWriter; import com.ruoyi.production.dto.ProductWorkOrderDto; import com.ruoyi.production.mapper.ProductWorkOrderFileMapper; import com.ruoyi.production.mapper.ProductWorkOrderMapper; import com.ruoyi.production.pojo.ProductWorkOrder; import com.ruoyi.production.pojo.ProductWorkOrderFile; import com.ruoyi.production.service.ProductWorkOrderService; import com.ruoyi.quality.pojo.QualityInspectParam; import lombok.AllArgsConstructor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Service @AllArgsConstructor @Transactional(rollbackFor = Exception.class) public class ProductWorkOrderServiceImpl extends ServiceImpl<ProductWorkOrderMapper, ProductWorkOrder> implements ProductWorkOrderService { @Autowired private ProductWorkOrderMapper productWorkOrdermapper; @Autowired private ProductWorkOrderFileMapper productWorkOrderFileMapper; @Value("${file.temp-dir}") private String tempDir; @Override public IPage<ProductWorkOrderDto> listPage(Page<ProductWorkOrderDto> page, ProductWorkOrderDto productWorkOrder) { @@ -29,4 +56,61 @@ return productWorkOrdermapper.updateById(productWorkOrderDto); } @Override public void down(HttpServletResponse response, ProductWorkOrder productWorkOrder) { ProductWorkOrderDto productWorkOrderDto = productWorkOrdermapper.getProductWorkOrderFlowCard(productWorkOrder.getId()); String codePath; try { codePath = new MatrixToImageWriter().code(productWorkOrderDto.getId().toString(), tempDir); } catch (Exception e) { throw new RuntimeException(e); } /*è·åéä»¶å¾çç±»å*/ List<Map<String, Object>> images = new ArrayList<>(); List<ProductWorkOrderFile> productWorkOrderFiles = productWorkOrderFileMapper.selectList(Wrappers.<ProductWorkOrderFile>lambdaQuery().eq(ProductWorkOrderFile::getWorkOrderId, productWorkOrder.getId())); if (CollectionUtils.isNotEmpty(productWorkOrderFiles)) { productWorkOrderFiles.forEach(productWorkOrderFile -> { Map<String, Object> image = new HashMap<>(); PictureRenderData pictureRenderData = Pictures.ofLocal( productWorkOrderFile.getUrl()).sizeInCm(17, 20).create(); image.put("url", pictureRenderData); images.add(image); }); } InputStream inputStream = this.getClass().getResourceAsStream("/static/work-order-template.docx"); XWPFTemplate template = XWPFTemplate.compile(inputStream).render( new HashMap<String, Object>() {{ put("process", productWorkOrderDto.getProcessName()); put("workOrderNo", productWorkOrderDto.getWorkOrderNo()); put("productOrderNpsNo", productWorkOrderDto.getProductOrderNpsNo()); put("productName", productWorkOrderDto.getProductName()); put("planQuantity", productWorkOrderDto.getPlanQuantity()); put("model", productWorkOrderDto.getModel()); put("completeQuantity", productWorkOrderDto.getCompleteQuantity()); put("scrapQty", productWorkOrderDto.getScrapQty()); put("planStartTime", productWorkOrderDto.getPlanStartTime()); put("planEndTime", productWorkOrderDto.getPlanEndTime()); put("actualStartTime", productWorkOrderDto.getActualStartTime()); put("actualEndTime", productWorkOrderDto.getActualEndTime()); put("twoCode", Pictures.ofLocal(codePath).create()); put("images", images.isEmpty()?null:images); }}); try { response.setContentType("application/msword"); String fileName = URLEncoder.encode( "æµè½¬å¡", "UTF-8"); response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".docx"); OutputStream os = response.getOutputStream(); template.write(os); os.flush(); os.close(); inputStream.close(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("导åºå¤±è´¥"); } } } src/main/java/com/ruoyi/production/service/impl/ProductionProductMainServiceImpl.java
@@ -187,7 +187,7 @@ qualityInspect.setModel(productModel.getModel()); qualityInspect.setUnit(productModel.getUnit()); qualityInspect.setQuantity(productQty); qualityInspect.setProcess(productProcess.getName()); qualityInspect.setProcess(process); qualityInspect.setInspectState(0); qualityInspect.setInspectType(inspectType); qualityInspect.setProductMainId(productionProductMain.getId()); @@ -209,7 +209,7 @@ } /*æ´æ°å·¥ååç产订å*/ ProductWorkOrder productWorkOrder = productWorkOrderMapper.selectById(dto.getWorkOrderId()); productWorkOrder.setCompleteQuantity(productQty.add(dto.getQuantity())); productWorkOrder.setCompleteQuantity(productWorkOrder.getCompleteQuantity().add(productQty)); if (ObjectUtils.isNull(productWorkOrder.getActualStartTime())) { productWorkOrder.setActualStartTime(LocalDate.now());//å®é å¼å§æ¶é´ } @@ -291,7 +291,7 @@ // å é¤äº§åºè®°å½ productionProductOutputMapper.delete(new LambdaQueryWrapper<ProductionProductOutput>() .eq(ProductionProductOutput::getProductMainId, productionProductMain.getId())); //å é¤å ¥åº //å é¤æå ¥è®°å½ productionProductInputMapper.delete(new LambdaQueryWrapper<ProductionProductInput>() .eq(ProductionProductInput::getProductMainId, productionProductMain.getId())); //å 餿¥åºçå ¥åºè®°å½ src/main/resources/mapper/production/ProductWorkOrderFileMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,19 @@ <?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.production.mapper.ProductWorkOrderFileMapper"> <!-- éç¨æ¥è¯¢æ å°ç»æ --> <resultMap id="BaseResultMap" type="com.ruoyi.production.pojo.ProductWorkOrderFile"> <id column="id" property="id" /> <result column="work_order_id" property="workOrderId" /> <result column="name" property="name" /> <result column="url" property="url" /> <result column="file_size" property="fileSize" /> <result column="create_time" property="createTime" /> <result column="create_user" property="createUser" /> <result column="update_time" property="updateTime" /> <result column="update_user" property="updateUser" /> <result column="tenant_id" property="tenantId" /> </resultMap> </mapper> src/main/resources/mapper/production/ProductWorkOrderMapper.xml
@@ -34,13 +34,42 @@ LEFT JOIN product_process pp ON pp.id = ppri.process_id LEFT JOIN product_model pm ON pm.id = ppri.product_model_id LEFT JOIN product p ON p.id = pm.product_id <where> where 1=1 <if test="c.workOrderNo != null and c.workOrderNo != ''"> pwo.work_order_no like concat('%',#{c.workOrderNo},'%') and pwo.work_order_no like concat('%',#{c.workOrderNo},'%') </if> <if test="c.planStartTime != null and c.planEndTime != null"> and DATE(pwo.create_time) between #{c.planStartTime} and #{c.planEndTime} </if> </where> <if test="c.productOrderId != null and c.productOrderId != ''"> and pwo.product_order_id = #{c.productOrderId} </if> </select> <select id="getProductWorkOrderFlowCard" resultType="com.ruoyi.production.dto.ProductWorkOrderDto"> SELECT pwo.*, pp.NAME as processName, pm.model, pm.unit, p.product_name AS productName, po.nps_no AS productOrderNpsNo, ROUND(pwo.complete_quantity / pwo.plan_quantity * 100, 2) AS completionStatus, sum(ppo.scrap_qty) scrapQty FROM product_work_order pwo LEFT JOIN product_process_route_item ppri ON ppri.id = pwo.product_process_route_item_id LEFT JOIN production_product_main ppm ON ppm.work_order_id = pwo.id LEFT JOIN production_product_output ppo ON ppo.product_main_id = ppm.id LEFT JOIN product_order po ON po.id = pwo.product_order_id LEFT JOIN product_process pp ON pp.id = ppri.process_id LEFT JOIN product_model pm ON pm.id = ppri.product_model_id LEFT JOIN product p ON p.id = pm.product_id WHERE pwo.id = #{id} GROUP BY pwo.id, pwo.product_process_route_item_id, pwo.create_time, pwo.update_time, pwo.work_order_no, pwo.plan_start_time, pwo.plan_end_time, pwo.actual_start_time, pwo.actual_end_time, pwo.status, pwo.tenant_id, pwo.plan_quantity, pwo.product_order_id, pwo.complete_quantity, pp.NAME , pm.model, pm.unit, p.product_name, po.nps_no </select> </mapper> src/main/resources/static/work-order-template.docxBinary files differ