src/main/java/com/ruoyi/CodeGenerator.java
@@ -19,11 +19,11 @@ // æ¼ç¤ºä¾åï¼æ§è¡ main æ¹æ³æ§å¶å°è¾å ¥æ¨¡å表åå车èªå¨çæå¯¹åºé¡¹ç®ç®å½ä¸ public class CodeGenerator { public static String database_url = "jdbc:mysql://localhost:3306/product-inventory-management-new"; public static String database_url = "jdbc:mysql://localhost:3306/product-inventory-management-jtwy"; public static String database_username = "root"; public static String database_password= "123456"; public static String author = "è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸"; public static String model = "purchase"; // 模å public static String model = "sales"; // 模å public static String setParent = "com.ruoyi."+ model; // å è·¯å¾ public static String tablePrefix = ""; // è®¾ç½®è¿æ»¤è¡¨åç¼ public static void main(String[] args) { src/main/java/com/ruoyi/basic/controller/ProductController.java
@@ -3,26 +3,29 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.basic.dto.ProductDto; import com.ruoyi.basic.dto.ProductModelDto; import com.ruoyi.basic.dto.ProductTreeDto; import com.ruoyi.basic.dto.*; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.basic.service.IProductModelService; import com.ruoyi.basic.service.IProductService; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.controller.BaseController; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.production.pojo.ProductProcess; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.service.ISalesLedgerProductService; import com.ruoyi.sales.service.ISalesLedgerService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.AllArgsConstructor; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.util.List; @RestController @@ -35,6 +38,14 @@ private IProductModelService productModelService; @Autowired private ISalesLedgerProductService salesLedgerProductService; /** * å页æ¥è¯¢ */ @GetMapping("/listPage") public AjaxResult listPage(Page page, ProductAndModelDto productDto) { return productService.listPage(page, productDto); } /** * æ¥è¯¢äº§å */ @@ -74,15 +85,16 @@ */ @Log(title = "产å", businessType = BusinessType.DELETE) @DeleteMapping("/delProduct") @Transactional(rollbackFor = Exception.class) public AjaxResult remove(@RequestBody Long[] ids) { if (ids == null || ids.length == 0) { return AjaxResult.error("è¯·ä¼ å ¥è¦å é¤çID"); } // æ£æ¥æ¯å¦æéå®ååè®°å½å ³è该产å LambdaQueryWrapper<SalesLedgerProduct> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.in(SalesLedgerProduct::getProductId, ids); queryWrapper.in(SalesLedgerProduct::getProductModelId, ids); List<SalesLedgerProduct> salesLedgerProductList = salesLedgerProductService.list(queryWrapper); if (salesLedgerProductList.size() > 0) { if (CollectionUtils.isNotEmpty(salesLedgerProductList)) { return AjaxResult.error("该产ååå¨éå®/éè´è®°å½ï¼ä¸è½å é¤"); } return toAjax(productService.delProductByIds(ids)); @@ -129,4 +141,14 @@ public AjaxResult importProduct(MultipartFile file) { return AjaxResult.success(productModelService.importProduct(file)); } /** * ä¸è½½æ¨¡æ¿ */ @ApiOperation("ä¸è½½æ¨¡æ¿") @PostMapping("downloadTemplate") public void downloadTemplate(HttpServletResponse response) { ExcelUtil<ProductModelExcelCopyDto> util = new ExcelUtil<ProductModelExcelCopyDto>(ProductModelExcelCopyDto.class); util.importTemplateExcel(response, "产åå¯¼å ¥æ¨¡æ¿"); } } src/main/java/com/ruoyi/basic/dto/ProductAndModelDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,52 @@ package com.ruoyi.basic.dto; import com.baomidou.mybatisplus.annotation.TableField; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @author :yys * @date : 2026/3/16 11:47 */ @Data public class ProductAndModelDto { /** * è§æ ¼id */ private Long id; /** * 产åid */ private Long productId; /** * 产ååç§° */ private String productName; /** * è§æ ¼åå· */ private String model; /** * åä½ */ private String unit; /** * å¾çº¸ç¼å· */ private String drawingNumber; /** * 产åç±»å(1-ç©æ,2-产å) */ @ApiModelProperty(value = "1=èªå¶,2=å¤è´,3=å§å¤") private Integer productType; } src/main/java/com/ruoyi/basic/dto/ProductModelDto.java
@@ -9,4 +9,6 @@ @Data public class ProductModelDto extends ProductModel { private List<ProductStructureDto> productStructureList; private String productName; } src/main/java/com/ruoyi/basic/dto/ProductModelExcelCopyDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,37 @@ package com.ruoyi.basic.dto; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import lombok.Data; /** * @author :yys * @date : 2026/3/16 10:48 */ @Data public class ProductModelExcelCopyDto { @Excel(name = "产ååç§°") private String productName; /** * å¾çº¸ç¼å· = 产åç¼å· */ @Excel(name = "产åç¼å·") private String model; /** * åä½ */ @Excel(name = "åä½") private String unit; @Excel(name = "产å屿§",readConverterExp = "1=èªå¶,2=å¤è´,3=å§å¤",prompt = "éå¡«ï¼åªæ¯æèªå¶,å¤è´,å§å¤ï¼å¦ä¸å¡«ï¼é»è®¤èªå¶") private Integer productType; @Excel(name = "产åè§æ ¼") private String drawingNumber; @Excel(name = "å·¥èºè·¯çº¿") private String processRoute; } src/main/java/com/ruoyi/basic/dto/ProductModelExcelDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,45 @@ package com.ruoyi.basic.dto; import com.baomidou.mybatisplus.annotation.TableField; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import lombok.Data; import java.util.List; /** * @author :yys * @date : 2026/3/13 15:34 */ @Data public class ProductModelExcelDto { private String index; @Excel(name = "åºå·") private String number; @Excel(name = "产ååç§°") private String productName; /** * è§æ ¼åå· */ @Excel(name = "è§æ ¼åå·") private String model; /** * åä½ */ @Excel(name = "åä½") private String unit; @Excel(name = "产åç±»å(ç©æ,产å)",readConverterExp = "1=ç©æ,2=产å") private Integer productType; @Excel(name = "å¾çº¸ç¼å·") private String drawingNumber; private List<ProductModelExcelDto> children; private List<ProductModelExcelItemDto> items; } src/main/java/com/ruoyi/basic/dto/ProductModelExcelItemDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,31 @@ package com.ruoyi.basic.dto; import com.ruoyi.framework.aspectj.lang.annotation.Excel; import lombok.Data; /** * @author :yys * @date : 2026/3/13 16:00 */ @Data public class ProductModelExcelItemDto { /** * è§æ ¼åå· */ @Excel(name = "è§æ ¼åå·") private String model; /** * åä½ */ @Excel(name = "åä½") private String unit; @Excel(name = "产åç±»å(ç©æ,产å)",readConverterExp = "1=ç©æ,2=产å") private Integer productType; @Excel(name = "å¾çº¸ç¼å·") private String drawingNumber; } src/main/java/com/ruoyi/basic/mapper/ProductModelMapper.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.basic.dto.ProductAndModelDto; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.procurementrecord.dto.ProcurementPageDto; import org.apache.ibatis.annotations.Param; @@ -26,4 +27,6 @@ ProductModel selectLatestRecord(); List<Map<String, Object>> getProductAndModelList(); IPage<ProductAndModelDto> listPage(Page page,@Param("req") ProductAndModelDto productDto); } src/main/java/com/ruoyi/basic/pojo/ProductModel.java
@@ -33,7 +33,7 @@ /** * è§æ ¼åå· */ @Excel(name = "è§æ ¼åå·") @Excel(name = "å¾çº¸ç¼å·") private String model; /** @@ -61,10 +61,13 @@ @Excel(name = "å©ä½åºå") private BigDecimal stockQuantity; @ApiModelProperty(value = "å¾çº¸ç¼å·") @Excel(name = "å¾çº¸ç¼å·") @ApiModelProperty(value = "è§æ ¼åå·") @Excel(name = "è§æ ¼åå·") private String drawingNumber; @TableField(exist = false) private LocalDateTime createTime; @ApiModelProperty(value = "产åç±»å(1-ç©æ,2-产å)") private Integer productType; } src/main/java/com/ruoyi/basic/service/IProductService.java
@@ -3,10 +3,12 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.basic.dto.ProductAndModelDto; import com.ruoyi.basic.dto.ProductDto; import com.ruoyi.basic.dto.ProductTreeDto; import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.framework.web.domain.AjaxResult; import java.util.List; @@ -19,4 +21,6 @@ List<ProductTreeDto> selectProductList(ProductDto productDto); IPage<ProductModel> listPageProductModel(Page<ProductModel> page, ProductModel productModel); AjaxResult listPage(Page page, ProductAndModelDto productDto); } src/main/java/com/ruoyi/basic/service/impl/ProductModelServiceImpl.java
@@ -5,20 +5,23 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.dto.ProductDto; import com.ruoyi.basic.dto.ProductModelDto; import com.ruoyi.basic.dto.*; import com.ruoyi.basic.mapper.ProductMapper; import com.ruoyi.basic.mapper.ProductModelMapper; import com.ruoyi.basic.pojo.Product; import com.ruoyi.basic.pojo.ProductModel; import com.ruoyi.basic.service.IProductModelService; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.bean.BeanUtils; import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.pojo.SalesLedgerProduct; import lombok.AllArgsConstructor; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; @@ -44,12 +47,27 @@ @Override public int addOrEditProductModel(ProductModelDto productModelDto) { if(StringUtils.isEmpty(productModelDto.getProductName())){ throw new RuntimeException("产ååç§°ä¸è½ä¸ºç©º"); } Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>() .eq(Product::getProductName, productModelDto.getProductName())); if (productModelDto.getId() == null) { if(product == null){ product = new Product(); product.setProductName(productModelDto.getProductName()); productMapper.insert(product); } ProductModel productModel = new ProductModel(); BeanUtils.copyProperties(productModelDto,productModel); productModel.setProductId(product.getId()); return productModelMapper.insert(productModel); } else { if(product != null){ product.setProductName(productModelDto.getProductName()); productMapper.updateById(product); } return productModelMapper.updateById(productModelDto); } } @@ -88,24 +106,102 @@ } @Override @Transactional(rollbackFor = Exception.class) public Boolean importProduct(MultipartFile file) { try { ExcelUtil<ProductModel> productModelExcelUtil = new ExcelUtil<>(ProductModel.class); List<ProductModel> productModelList = productModelExcelUtil.importExcel(file.getInputStream()); Map<String, List<ProductModel>> collect = productModelList.stream().collect(Collectors.groupingBy(ProductModel::getProductName)); collect.forEach((k,v)->{ Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>().eq(Product::getProductName, k).last("LIMIT 1")); if (product != null) { v.forEach(productModel -> { productModel.setProductId(product.getId()); ExcelUtil<ProductModelExcelCopyDto> productModelExcelUtil = new ExcelUtil<>(ProductModelExcelCopyDto.class); List<ProductModelExcelCopyDto> productModelList = productModelExcelUtil.importExcel(file.getInputStream()); List<Product> productList = productMapper.selectList(new LambdaQueryWrapper<Product>() .isNull(Product::getParentId)); if(CollectionUtils.isEmpty(productList)) { throw new RuntimeException("è¯·å æ·»å ç¶çº§äº§å"); } if(CollectionUtils.isNotEmpty(productModelList)){ // 2. æäº§ååç§°åç» Map<String, List<ProductModelExcelCopyDto>> groupedByProductName = productModelList.stream() .collect(Collectors.groupingBy(ProductModelExcelCopyDto::getProductName)); for (Map.Entry<String, List<ProductModelExcelCopyDto>> entry : groupedByProductName.entrySet()) { // æ ¹æ®åç§°æ¥è¯¢æ¯å¦åå¨äº§å Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>() .eq(Product::getProductName, entry.getKey()) .last("limit 1")); if(product == null){ product = new Product(); product.setProductName(entry.getKey()); product.setParentId(null); // ç¶èç¹ID // 2. æå ¥å½åèç¹ï¼MyBatisä¼èªå¨åå¡«productçid屿§ productMapper.insert(product); } Product finalProduct = product; entry.getValue().forEach(productModelExcelDto -> { // æ ¹æ®å¾çº¸ç¼å·æ¥è¯¢ ProductModel productModel = productModelMapper.selectOne(new LambdaQueryWrapper<ProductModel>() .eq(ProductModel::getModel, productModelExcelDto.getModel()) .last("limit 1")); if(productModel == null){ productModel = new ProductModel(); BeanUtils.copyProperties(productModelExcelDto,productModel); if(productModelExcelDto.getProductType() == null) { productModel.setProductType(1); } productModel.setProductId(finalProduct.getId()); productModelMapper.insert(productModel); }else{ BeanUtils.copyProperties(productModelExcelDto,productModel); productModel.setProductId(finalProduct.getId()); productModelMapper.updateById(productModel); } }); this.saveOrUpdateBatch(v); } }); } // List<ProductModelExcelDto> productModelExcelDtos = OrderUtils.buildTree(productModelList); // if(CollectionUtils.isNotEmpty(productModelExcelDtos)){ // recursiveSaveProduct(productModelExcelDtos.get(0),null); // } return true; }catch (Exception e) { e.printStackTrace(); } return false; } /** * éå½å¯¼å ¥æ å½¢äº§åæ°æ® * @param excelDto Excelè§£æåçæ å½¢èç¹ * @param parentId ç¶èç¹IDï¼é¡¶çº§èç¹ä¼ null/0ï¼ */ @Transactional(rollbackFor = Exception.class) // äºå¡ä¿è¯ï¼å¤±è´¥ååæ» public void recursiveSaveProduct(ProductModelExcelDto excelDto, Long parentId) { // 1. æå»ºå½åèç¹çProductå®ä½ Product product = new Product(); product.setProductName(excelDto.getProductName()); product.setParentId(parentId); // ç¶èç¹ID // 2. æå ¥å½åèç¹ï¼MyBatisä¼èªå¨åå¡«productçid屿§ productMapper.insert(product); Long currentId = product.getId(); // è·åå½åèç¹ä¸»é® // 3. éå½å¤çåèç¹ if (excelDto.getChildren() != null && !excelDto.getChildren().isEmpty()) { for (ProductModelExcelDto childDto : excelDto.getChildren()) { recursiveSaveProduct(childDto, currentId); // ç¶ID为å½åèç¹ID } } // 4. ï¼å¯éï¼å¤çitemsæ°æ®ï¼å¦æéè¦æå ¥å°å ³èè¡¨ï¼ if (excelDto.getItems() != null && !excelDto.getItems().isEmpty()) { for (ProductModelExcelItemDto item : excelDto.getItems()) { // æå ¥itemå ³èæ°æ®ï¼å ³ècurrentId // æå»ºProductModelå®ä½ ProductModel productModel = new ProductModel(); productModel.setProductId(currentId); // å ³èå½å产åèç¹ID productModel.setModel(item.getModel()); // ä»ItemDTOè·ååå· productModel.setUnit(item.getUnit()); // ä»ItemDTOè·ååä½ productModel.setDrawingNumber(item.getDrawingNumber()); // å¾çº¸ç¼å· productModel.setProductType(item.getProductType()); // æå ¥product_model表 productModelMapper.insert(productModel); } } } } src/main/java/com/ruoyi/basic/service/impl/ProductServiceImpl.java
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.basic.dto.ProductAndModelDto; import com.ruoyi.basic.dto.ProductDto; import com.ruoyi.basic.dto.ProductTreeDto; import com.ruoyi.basic.mapper.ProductMapper; @@ -15,12 +16,14 @@ import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.web.domain.AjaxResult; import lombok.AllArgsConstructor; import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @Service @AllArgsConstructor @@ -57,6 +60,11 @@ @Override public IPage<ProductModel> listPageProductModel(Page<ProductModel> page, ProductModel productModel) { return productModelMapper.listPageProductModel(page, productModel); } @Override public AjaxResult listPage(Page page, ProductAndModelDto productDto) { return AjaxResult.success(productModelMapper.listPage(page, productDto)); } @@ -116,14 +124,24 @@ @Override public int delProductByIds(Long[] ids) { // 1. å é¤å表 product_model ä¸å ³èçæ°æ® LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.in(ProductModel::getProductId, ids); productModelMapper.delete(queryWrapper); for (Long id : ids) { LambdaQueryWrapper<ProductModel> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(ProductModel::getId, id); List<ProductModel> productModels = productModelMapper.selectList(queryWrapper); if(CollectionUtils.isNotEmpty(productModels)){ List<ProductModel> productList = productModelMapper.selectList(new LambdaQueryWrapper<ProductModel>() .eq(ProductModel::getProductId, productModels.get(0).getProductId())); if(CollectionUtils.isNotEmpty(productList) && productList.size() == 1){ // å½åªæä¸æ¡æ°æ®æ¶å é¤äº§å productMapper.deleteBatchIds(productModels.stream() .map(ProductModel::getProductId) .collect(Collectors.toList())); } return productModelMapper.deleteBatchIds(Arrays.asList(ids)); // 2. å é¤ä¸»è¡¨ product æ°æ® int deleteCount = productMapper.deleteBatchIds(Arrays.asList(ids)); return deleteCount; } } return 1; } } src/main/java/com/ruoyi/common/enums/StockInQualifiedRecordTypeEnum.java
@@ -11,7 +11,8 @@ PRODUCTION_REPORT_STOCK_IN("2", "ç产æ¥å·¥-å ¥åº"), PURCHASE_STOCK_IN("7", "éè´-å ¥åº"), QUALITYINSPECT_STOCK_IN("6", "è´¨æ£-åæ ¼å ¥åº"), DEFECTIVE_PASS("11", "ä¸åæ ¼-è®©æ¥æ¾è¡"); DEFECTIVE_PASS("11", "ä¸åæ ¼-è®©æ¥æ¾è¡"), RETURN_HE_IN("14", "éå®éè´§-åæ ¼å ¥åº"); private final String code; src/main/java/com/ruoyi/common/enums/StockInUnQualifiedRecordTypeEnum.java
@@ -10,7 +10,8 @@ DEFECTIVE_SCRAP("4", "ä¸åæ ¼å¤ç-æ¥åº"), PRODUCTION_SCRAP("5", "ç产æ¥å·¥-æ¥åº"), CUSTOMIZATION_UNSTOCK_IN("9", "ä¸åæ ¼èªå®ä¹å ¥åº"), QUALITYINSPECT_UNSTOCK_IN("12", "è´¨æ£-ä¸åæ ¼å ¥åº"); QUALITYINSPECT_UNSTOCK_IN("12", "è´¨æ£-ä¸åæ ¼å ¥åº"), RETURN_UNSTOCK_IN("15", "éå®éè´§-ä¸åæ ¼å ¥åº"); private final String code; src/main/java/com/ruoyi/common/utils/OrderUtils.java
@@ -2,6 +2,9 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.ruoyi.basic.dto.ProductModelExcelDto; import com.ruoyi.basic.dto.ProductModelExcelItemDto; import com.ruoyi.common.utils.uuid.UUID; import org.apache.poi.ss.formula.functions.T; import org.springframework.stereotype.Component; @@ -11,9 +14,8 @@ import java.time.LocalTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.*; import java.util.stream.Collectors; /** * @author :yys @@ -54,4 +56,304 @@ // æ¼æ¥è®¢åç¼å· preFix + æ¶é´ï¼yyyyMMddï¼ + è®¢åæ°é(001) return preFix + LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE).replaceAll("-", "") + String.format("%03d", (aLong + 1)) + "-" + new Date().getTime(); } /** * å°å¹³é¢å表转æ¢ä¸ºæ å½¢ç»æï¼å«è§æ ¼åå·æååè½ï¼ * @param flatList å¯¼å ¥ç平颿°æ®å表 * @return æ å½¢ç»æçæ ¹èç¹å表 */ public static List<ProductModelExcelDto> buildTree(List<ProductModelExcelDto> flatList) { // 1. åæ°æ ¡éª if (CollectionUtils.isEmpty(flatList)) { return new ArrayList<>(); } // 2. é¢å¤çï¼è¿æ»¤æ ææ°æ® + è§æ ¼åå·æå + åå§ååèç¹å表 List<ProductModelExcelDto> validList = preprocessData(flatList); if (CollectionUtils.isEmpty(validList)) { return new ArrayList<>(); } // 3. æå±çº§åç»ï¼ä¾¿äºéå±å¤ç Map<Integer, List<ProductModelExcelDto>> levelGroupMap = groupByLevel(validList); // 4. æå»ºèç¹æ å°ï¼åºå· -> èç¹ï¼ï¼æé«æ¥è¯¢æç Map<String, ProductModelExcelDto> nodeMap = buildNodeMap(validList); // 5. éå±æå»ºç¶åå ³ç³» buildParentChildRelation(levelGroupMap, nodeMap); // 6. è·åæ ¹èç¹ï¼å±çº§1ï¼å¹¶æåº List<ProductModelExcelDto> rootNodes = getRootNodes(levelGroupMap); sortTreeNodes(rootNodes); return rootNodes; } /** * æ°æ®é¢å¤çï¼ * 1. è¿æ»¤æ ææ°æ® * 2. è§æ ¼åå·æåå¹¶å¡«å å°itemséå * 3. åå§ååèç¹å表 */ private static List<ProductModelExcelDto> preprocessData(List<ProductModelExcelDto> flatList) { return flatList.stream() // è¿æ»¤æ ¸å¿åæ®µæ æçèç¹ .filter(node -> isValidNode(node)) // å¤çè§æ ¼åå·æååitemså¡«å .peek(node -> { // æåè§æ ¼åå·å¹¶å¡«å å°items splitModelAndFillItems(node); // åå§ååèç¹å表ï¼é¿å 空æéï¼ if (node.getChildren() == null) { node.setChildren(new ArrayList<>()); } }) .collect(Collectors.toList()); } /** * éªè¯èç¹æ¯å¦ææï¼æ ¸å¿åæ®µæ ¡éªï¼ */ private static boolean isValidNode(ProductModelExcelDto node) { if (node == null) { return false; } // åºå·å¿ é¡»ææï¼åºç¡æ ¡éªï¼ if (!isValidSequence(node.getNumber())) { return false; } // 产ååç§°é空ï¼ä¸å¡æ ¡éªï¼å¯æ ¹æ®å®é éæ±è°æ´ï¼ return StringUtils.isNotBlank(node.getProductName()); } /** * è§æ ¼åå·æåå¹¶å¡«å å°itemséå * @param node å¾ å¤ççèç¹ */ private static void splitModelAndFillItems(ProductModelExcelDto node) { // 1. è·ååå§è§æ ¼åå· String originalModel = node.getModel(); List<ProductModelExcelItemDto> items = new ArrayList<>(); if (StringUtils.isNotBlank(originalModel)) { // 2. æ"+"æåè§æ ¼åå·ï¼å¦ææå¤ä¸ªï¼ï¼å¤çæ¯ä¸ªç段 List<String> splitModels = Arrays.stream(originalModel.split("\\+")) .map(String::trim) .filter(StringUtils::isNotBlank) .distinct() .collect(Collectors.toList()); // 3. 为æ¯ä¸ªè§æ ¼å建Itemï¼å³ä½¿åªæä¸ä¸ªï¼ä¹çæä¸ä¸ªItemï¼ items = splitModels.stream() .map(model -> createExcelItem(node, model)) .collect(Collectors.toList()); } // 4. å¡«å å°èç¹çitemséåï¼è¦çåææ°æ®ï¼ node.setItems(items); } /** * å建ProductModelExcelItemDto对象ï¼ç»§æ¿åèç¹çå ¬å ±å±æ§ï¼ * @param node åèç¹ * @param model æååçè§æ ¼åå· * @return æå»ºå¥½çItem对象 */ private static ProductModelExcelItemDto createExcelItem(ProductModelExcelDto node, String model) { ProductModelExcelItemDto item = new ProductModelExcelItemDto(); // 1. æååçè§æ ¼åå· item.setModel(model); // 2. ç»§æ¿åèç¹çåä½ï¼ç©ºå¼å¤çï¼ item.setUnit(StringUtils.defaultIfBlank(node.getUnit(), "")); // 3. ç»§æ¿åèç¹ç产åç±»åï¼ç©ºå¼å¤çï¼é»è®¤0表示æªç¥ï¼ item.setProductType(Optional.ofNullable(node.getProductType()).orElse(0)); // 4. ç»§æ¿åèç¹çå¾çº¸ç¼å·ï¼ç©ºå¼å¤çï¼ item.setDrawingNumber(StringUtils.defaultIfBlank(node.getDrawingNumber(), "")); return item; } /** * éªè¯åºå·æ ¼å¼æ¯å¦ææï¼æ¯æ1ã1.1ã1.1.1çæ ¼å¼ï¼ */ private static boolean isValidSequence(String sequence) { if (StringUtils.isBlank(sequence)) { return false; } // æ£å表达å¼ï¼å¹é æ°åå¼å¤´ï¼åç»å¯è·.åæ°å return sequence.trim().matches("^\\d+(\\.\\d+)*$"); } /** * æèç¹å±çº§åç» */ private static Map<Integer, List<ProductModelExcelDto>> groupByLevel(List<ProductModelExcelDto> validList) { return validList.stream() .collect(Collectors.groupingBy( node -> getNodeLevel(node.getNumber()), // 计ç®å±çº§ TreeMap::new, // æå±çº§ååºæåº Collectors.toList() )); } /** * 计ç®èç¹å±çº§ï¼åºå·ä¸.çæ°é + 1ï¼ * ä¾ï¼1 -> 1级ï¼1.1 -> 2级ï¼1.1.1 -> 3级 */ private static int getNodeLevel(String sequence) { if (StringUtils.isBlank(sequence)) { return 0; } String trimmedSeq = sequence.trim(); return trimmedSeq.split("\\.").length; } /** * æå»ºèç¹æ å°è¡¨ï¼åºå· -> èç¹ï¼ */ private static Map<String, ProductModelExcelDto> buildNodeMap(List<ProductModelExcelDto> validList) { return validList.stream() .collect(Collectors.toMap( node -> node.getNumber().trim(), // é®ï¼åºå·ï¼å»ç©ºæ ¼ï¼ node -> node, // å¼ï¼èç¹å¯¹è±¡ (oldVal, newVal) -> oldVal // å¤çéå¤åºå·ï¼ä¿ç第ä¸ä¸ª )); } /** * æå»ºç¶åèç¹å ³ç³» */ private static void buildParentChildRelation(Map<Integer, List<ProductModelExcelDto>> levelGroupMap, Map<String, ProductModelExcelDto> nodeMap) { // ä»å±çº§2å¼å§å¤çï¼å±çº§1æ¯æ ¹èç¹ï¼æ ç¶èç¹ï¼ for (Map.Entry<Integer, List<ProductModelExcelDto>> entry : levelGroupMap.entrySet()) { int currentLevel = entry.getKey(); if (currentLevel <= 1) { continue; // è·³è¿æ ¹èç¹å±çº§ } List<ProductModelExcelDto> currentLevelNodes = entry.getValue(); for (ProductModelExcelDto currentNode : currentLevelNodes) { // 计ç®ç¶èç¹åºå· String parentSequence = getParentSequence(currentNode.getNumber()); if (StringUtils.isBlank(parentSequence)) { continue; } // æ¥æ¾ç¶èç¹ ProductModelExcelDto parentNode = nodeMap.get(parentSequence); if (parentNode != null && parentNode.getChildren() != null) { // æ·»å å°ç¶èç¹çåèç¹å表 parentNode.getChildren().add(currentNode); } } } } /** * æ ¹æ®å½åèç¹åºå·è·åç¶èç¹åºå· * ä¾ï¼1.1.2 -> 1.1ï¼1.2 -> 1ï¼1 -> null */ private static String getParentSequence(String currentSequence) { if (StringUtils.isBlank(currentSequence)) { return null; } String trimmedSeq = currentSequence.trim(); String[] seqParts = trimmedSeq.split("\\."); if (seqParts.length <= 1) { return null; // æ ¹èç¹æ ç¶èç¹ } // 廿æåä¸é¨åï¼æ¼æ¥ç¶èç¹åºå· String[] parentParts = Arrays.copyOfRange(seqParts, 0, seqParts.length - 1); return String.join(".", parentParts); } /** * è·åæ ¹èç¹å表ï¼å±çº§1çèç¹ï¼ */ private static List<ProductModelExcelDto> getRootNodes(Map<Integer, List<ProductModelExcelDto>> levelGroupMap) { return levelGroupMap.getOrDefault(1, new ArrayList<>()); } /** * éå½æåºææèç¹ï¼æåºå·æ°å顺åºï¼ */ private static void sortTreeNodes(List<ProductModelExcelDto> nodeList) { if (CollectionUtils.isEmpty(nodeList)) { return; } // æåºå½åå±çº§èç¹ nodeList.sort(Comparator.comparing( ProductModelExcelDto::getNumber, new SequenceComparator() // èªå®ä¹åºå·æ¯è¾å¨ )); // é彿åºåèç¹ for (ProductModelExcelDto node : nodeList) { sortTreeNodes(node.getChildren()); } } /** * åºå·æ¯è¾å¨ï¼ææ°åé¡ºåºæåºï¼æ¯æ1.10å¨1.2ä¹åï¼ */ private static class SequenceComparator implements Comparator<String> { @Override public int compare(String seq1, String seq2) { if (StringUtils.isBlank(seq1) && StringUtils.isBlank(seq2)) { return 0; } if (StringUtils.isBlank(seq1)) { return -1; } if (StringUtils.isBlank(seq2)) { return 1; } // åå²åºå·ä¸ºæ°åæ°ç» String[] parts1 = seq1.trim().split("\\."); String[] parts2 = seq2.trim().split("\\."); // éæ®µæ¯è¾æ°å int minLength = Math.min(parts1.length, parts2.length); for (int i = 0; i < minLength; i++) { int num1 = parseSequencePart(parts1[i]); int num2 = parseSequencePart(parts2[i]); if (num1 != num2) { return num1 - num2; } } // é¿åº¦ä¸åæ¶ï¼ççå¨åï¼å¦1.1å¨1.1.1ä¹åï¼ return parts1.length - parts2.length; } /** * è§£æåºå·ç段为æ°åï¼å¤çå¼å¸¸æ åµï¼ */ private int parseSequencePart(String part) { try { return Integer.parseInt(part.trim()); } catch (NumberFormatException e) { return 0; // å¼å¸¸æ 嵿0å¤ç } } } /** * 产åç±»åæ å°ï¼1=ç©æï¼2=产åï¼0=æªç¥ï¼ */ private static String mapProductType(Integer productType) { return Optional.ofNullable(productType) .map(type -> type == 1 ? "ç©æ" : (type == 2 ? "产å" : "æªç¥")) .orElse("æªç¥"); } } src/main/java/com/ruoyi/procurementrecord/controller/ReturnManagementController.java
@@ -1,14 +1,16 @@ package com.ruoyi.procurementrecord.controller; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.framework.web.controller.BaseController; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper; import com.ruoyi.procurementrecord.pojo.ReturnManagement; import com.ruoyi.procurementrecord.dto.ReturnManagementDto; import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct; import com.ruoyi.procurementrecord.service.ReturnManagementService; import com.ruoyi.procurementrecord.service.ReturnSaleProductService; import com.ruoyi.sales.dto.SalesLedgerDto; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -22,48 +24,69 @@ * @date : 2025/9/17 10:34 */ @RestController @Api(tags = "å°è´§ç®¡ç") @Api(tags = "éå®éè´§") @RequestMapping("/returnManagement") public class ReturnManagementController extends BaseController { @Autowired private ReturnManagementService returnManagementService; @Autowired private ReturnManagementMapper returnManagementMapper; private ReturnSaleProductService returnSaleProductService; @GetMapping("/listPage") @ApiOperation("å°è´§ç®¡ç-æ¥è¯¢") public AjaxResult listPage(Page page, ReturnManagement returnManagement) { IPage<ReturnManagement> result = returnManagementService.listPage(page, returnManagement); @ApiOperation("éå®éè´§-æ¥è¯¢") public AjaxResult listPage(Page page, ReturnManagementDto returnManagement) { IPage<ReturnManagementDto> result = returnManagementService.listPage(page, returnManagement); return AjaxResult.success(result); } @PostMapping("/add") @ApiOperation("å°è´§ç®¡ç-æ·»å ") @ApiOperation("éå®éè´§-æ·»å ") @Transactional(rollbackFor = Exception.class) public AjaxResult add(@RequestBody ReturnManagement returnManagement) { String rt = OrderUtils.countTodayByCreateTime(returnManagementMapper, "RT"); returnManagement.setReturnNo(rt); boolean result = returnManagementService.save(returnManagement); return result ? success() : error(); public AjaxResult add(@RequestBody ReturnManagementDto returnManagementDto) { return returnManagementService.addReturnManagementDto(returnManagementDto) ? success() : error(); } @PostMapping("/update") @ApiOperation("å°è´§ç®¡ç-ä¿®æ¹") @ApiOperation("éå®éè´§-ä¿®æ¹") @Transactional(rollbackFor = Exception.class) public AjaxResult update(@RequestBody ReturnManagement returnManagement) { boolean result = returnManagementService.updateById(returnManagement); return result ? success() : error(); public AjaxResult update(@RequestBody ReturnManagementDto returnManagementDto) { return returnManagementService.updateReturnManagementDto(returnManagementDto) ? success() : error(); } @ApiOperation("éå®éè´§-å¤çéè´§å") @GetMapping("/handle") @Transactional(rollbackFor = Exception.class) public AjaxResult handle(Long returnManagementId) { return returnManagementService.handle(returnManagementId) ? success() : error(); } @DeleteMapping("/del") @ApiOperation("å°è´§ç®¡ç-å é¤") @ApiOperation("éå®éè´§-å é¤") @Transactional(rollbackFor = Exception.class) public AjaxResult del(@RequestBody List<Long> ids) { if (CollectionUtils.isEmpty(ids)) return error("è¯·éæ©è³å°ä¸æ¡æ°æ®"); returnSaleProductService.remove(new QueryWrapper<ReturnSaleProduct>() .lambda() .in(ReturnSaleProduct::getReturnManagementId, ids)); boolean result = returnManagementService.removeByIds(ids); return result ? success() : error(); } @GetMapping("/getById") @ApiOperation("éå®éè´§-æ ¹æ®idæ¥è¯¢") public AjaxResult getById(Long returnManagementId) { ReturnManagementDto returnManagementDto = returnManagementService.getReturnManagementDtoById(returnManagementId); return success(returnManagementDto); } @GetMapping("/getByShippingId") @ApiOperation("éå®éè´§-æ ¹æ®åºåºåæ¥è¯¢éå®è®¢å以å产åä¿¡æ¯") public AjaxResult getByShippingId(Long shippingId) { SalesLedgerDto salesLedgerDto = returnManagementService.getReturnManagementDtoByShippingIdId(shippingId); return success(salesLedgerDto); } } src/main/java/com/ruoyi/procurementrecord/dto/ReturnManagementDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,39 @@ package com.ruoyi.procurementrecord.dto; import com.ruoyi.procurementrecord.pojo.ReturnManagement; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.util.List; /** * @author :yys * @date : 2025/9/17 10:28 */ @Data public class ReturnManagementDto extends ReturnManagement { @ApiModelProperty(value = "客æ·åç§°") private String customerName; @ApiModelProperty(value = "éå®åå·") private String salesContractNo; @ApiModelProperty(value = "ä¸å¡å") private String salesman; @ApiModelProperty("å ³èåºåºåå·") private String shippingNo; @ApiModelProperty(value = "项ç®åç§°") private String projectName; @ApiModelProperty(value = "éå®å°è´¦id") private Long salesLedgerId; @ApiModelProperty(value = "éå®äº§å对象æ°ç»") private List<ReturnSaleProductDto> returnSaleProducts; } src/main/java/com/ruoyi/procurementrecord/dto/ReturnSaleProductDto.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,27 @@ package com.ruoyi.procurementrecord.dto; import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct; import lombok.Data; import java.math.BigDecimal; @Data public class ReturnSaleProductDto extends ReturnSaleProduct { private String productName; private String model; private String unit; //æªéè´§æ°é private BigDecimal unQuantity; private BigDecimal totalReturnNum; // éè´§æ»ä»· private BigDecimal price; // éè´§æ»ä»· private BigDecimal taxInclusiveUnitPrice; } src/main/java/com/ruoyi/procurementrecord/mapper/ReturnManagementMapper.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.procurementrecord.dto.ReturnManagementDto; import com.ruoyi.procurementrecord.pojo.ReturnManagement; import org.apache.ibatis.annotations.Param; @@ -18,5 +19,7 @@ * @param page * @return */ IPage<ReturnManagement> listPage(Page page,@Param("req") ReturnManagement returnManagement); IPage<ReturnManagementDto> listPage(Page page, @Param("req") ReturnManagementDto returnManagement); ReturnManagementDto getReturnManagementDtoById(Long id); } src/main/java/com/ruoyi/procurementrecord/mapper/ReturnSaleProductMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,25 @@ package com.ruoyi.procurementrecord.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.procurementrecord.dto.ReturnSaleProductDto; import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; /** * <p> * é货产å表 Mapper æ¥å£ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-05 03:57:42 */ @Mapper public interface ReturnSaleProductMapper extends BaseMapper<ReturnSaleProduct> { List<ReturnSaleProductDto> listReturnSaleProductDto(@Param("returnManagementId") Long returnManagementId); List<ReturnSaleProductDto> listReturnSaleProduct(@Param("returnManagementId") Long returnManagementId); } src/main/java/com/ruoyi/procurementrecord/pojo/ReturnManagement.java
@@ -1,14 +1,16 @@ package com.ruoyi.procurementrecord.pojo; import com.baomidou.mybatisplus.annotation.*; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Date; /** * @author :yys @@ -29,44 +31,45 @@ @ApiModelProperty(value = "éè´§åå·") private String returnNo; @ApiModelProperty(value = "å ³èåå·") private String relatedNo; @ApiModelProperty("客æ·id") private Long customerId; @ApiModelProperty(value = "éè´§ç±»å") private String returnType; @ApiModelProperty("å ³èåºåºåå·Id") private Long shippingId; @ApiModelProperty(value = "ä¾åºååç§°") private String supplierName; @ApiModelProperty("项ç®id") private Long projectId; @ApiModelProperty(value = "éè´§åå ") @ApiModelProperty("项ç®é¶æ®µ") private String projectStage; @ApiModelProperty("å¶å人") private String maker; @ApiModelProperty("éè´§åå ") private String returnReason; @ApiModelProperty(value = "éè´§ç¶æ") private String status; @ApiModelProperty("鿬¾æ»é¢") private BigDecimal refundAmount; @ApiModelProperty(value = "夿³¨") private String remark; @ApiModelProperty(value = "å建æ¶é´") @TableField(fill = FieldFill.INSERT) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @ApiModelProperty("å¶åæ¶é´") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime makeTime; @ApiModelProperty("ç»ç®äºº") private String settler; @ApiModelProperty("ç¶æ") private Integer status; @ApiModelProperty("å建æ¶é´") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime createTime; @ApiModelProperty(value = "åå»ºç¨æ·") @TableField(fill = FieldFill.INSERT) private Integer createUser; @ApiModelProperty(value = "ä¿®æ¹æ¶é´") @TableField(fill = FieldFill.INSERT_UPDATE) @ApiModelProperty("æ´æ°æ¶é´") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime updateTime; @ApiModelProperty(value = "ä¿®æ¹ç¨æ·") @TableField(fill = FieldFill.INSERT_UPDATE) private Integer updateUser; @ApiModelProperty(value = "ç§æ·ID") @TableField(fill = FieldFill.INSERT) private Long tenantId; } src/main/java/com/ruoyi/procurementrecord/pojo/ReturnSaleProduct.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,60 @@ package com.ruoyi.procurementrecord.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; import java.io.Serializable; import java.math.BigDecimal; /** * <p> * é货产å表 * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-05 03:57:42 */ @Getter @Setter @TableName("return_sale_product") @ApiModel(value = "ReturnSaleProduct对象", description = "é货产å表") public class ReturnSaleProduct implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("产åè§æ ¼id") private Long productModelId; @ApiModelProperty("主é®id") @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty("éè´§åid") private Long returnManagementId; @ApiModelProperty("é货产åid") private Long returnSaleLedgerProductId; @ApiModelProperty("éè´§äº§åæ°é") private BigDecimal num; @ApiModelProperty("é货产ååä»·") private BigDecimal price; @ApiModelProperty("é货产åéé¢") private BigDecimal amount; @ApiModelProperty("éè´§ç¶æ 0 æªéå 1å·²éè´§") private Integer status; @ApiModelProperty("夿³¨") private String remark; @ApiModelProperty("æ¯å¦æè´¨éé®é¢(1-æ¯ 2-å¦)") private Integer isQuality; } src/main/java/com/ruoyi/procurementrecord/service/ReturnManagementService.java
@@ -3,7 +3,9 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.procurementrecord.dto.ReturnManagementDto; import com.ruoyi.procurementrecord.pojo.ReturnManagement; import com.ruoyi.sales.dto.SalesLedgerDto; /** * @author :yys @@ -18,5 +20,15 @@ * @param returnManagement * @return */ IPage<ReturnManagement> listPage(Page page, ReturnManagement returnManagement); IPage<ReturnManagementDto> listPage(Page page, ReturnManagementDto returnManagement); boolean addReturnManagementDto(ReturnManagementDto returnManagementDto); boolean updateReturnManagementDto(ReturnManagementDto returnManagementDto); SalesLedgerDto getReturnManagementDtoByShippingIdId(Long shippingId); boolean handle(Long returnManagementId); ReturnManagementDto getReturnManagementDtoById(Long returnManagementId); } src/main/java/com/ruoyi/procurementrecord/service/ReturnSaleProductService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,22 @@ package com.ruoyi.procurementrecord.service; import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.procurementrecord.dto.ReturnSaleProductDto; import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct; import java.util.List; /** * <p> * é货产å表 æå¡ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-05 03:57:42 */ public interface ReturnSaleProductService extends IService<ReturnSaleProduct> { List<ReturnSaleProductDto> listReturnSaleProductDto(Long returnManagementId); List<ReturnSaleProductDto> listReturnSaleProduct(Long returnManagementId); } src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnManagementServiceImpl.java
@@ -3,12 +3,35 @@ import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.account.mapper.AccountExpenseMapper; import com.ruoyi.account.pojo.AccountExpense; import com.ruoyi.common.enums.StockInQualifiedRecordTypeEnum; import com.ruoyi.common.enums.StockInUnQualifiedRecordTypeEnum; import com.ruoyi.common.utils.OrderUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.procurementrecord.dto.ReturnManagementDto; import com.ruoyi.procurementrecord.dto.ReturnSaleProductDto; import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper; import com.ruoyi.procurementrecord.pojo.ReturnManagement; import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct; import com.ruoyi.procurementrecord.service.ReturnManagementService; import com.ruoyi.procurementrecord.service.ReturnSaleProductService; import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.sales.dto.SalesLedgerDto; import com.ruoyi.sales.mapper.SalesLedgerMapper; import com.ruoyi.sales.pojo.SalesLedger; import com.ruoyi.sales.pojo.ShippingInfo; import com.ruoyi.sales.service.ShippingInfoService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; /** * @author :yys @@ -21,9 +44,115 @@ @Autowired private ReturnManagementMapper returnManagementMapper; @Autowired private ReturnSaleProductService returnSaleProductService; @Autowired private ShippingInfoService shippingInfoService; @Autowired private SalesLedgerMapper salesLedgerMapper; // @Autowired // private SalesRefundAmountOrderService salesRefundAmountOrderService; @Autowired private StockUtils stockUtils; @Autowired private AccountExpenseMapper accountExpenseMapper; @Override public IPage<ReturnManagement> listPage(Page page, ReturnManagement returnManagement) { IPage<ReturnManagement> returnManagementIPage = returnManagementMapper.listPage(page, returnManagement); public IPage<ReturnManagementDto> listPage(Page page, ReturnManagementDto returnManagement) { IPage<ReturnManagementDto> returnManagementIPage = returnManagementMapper.listPage(page, returnManagement); return returnManagementIPage; } @Override public boolean addReturnManagementDto(ReturnManagementDto returnManagementDto) { String rt = OrderUtils.countTodayByCreateTime(returnManagementMapper, "RT"); returnManagementDto.setReturnNo(rt); save(returnManagementDto); for (ReturnSaleProduct returnSaleProduct : returnManagementDto.getReturnSaleProducts()) { returnSaleProduct.setReturnManagementId(returnManagementDto.getId()); returnSaleProduct.setStatus(0); returnSaleProductService.save(returnSaleProduct); } return true; } @Override public boolean updateReturnManagementDto(ReturnManagementDto returnManagementDto) { List<ReturnSaleProduct> returnSaleProducts = new ArrayList<>(); if (!CollectionUtils.isEmpty(returnManagementDto.getReturnSaleProducts())) { returnManagementDto.getReturnSaleProducts().stream().forEach(returnSaleProductDto -> { ReturnSaleProduct returnSaleProduct = new ReturnSaleProduct(); BeanUtils.copyProperties(returnSaleProductDto, returnSaleProduct); returnSaleProducts.add(returnSaleProduct); }); } returnSaleProductService.updateBatchById(returnSaleProducts); return updateById(returnManagementDto); } @Override public SalesLedgerDto getReturnManagementDtoByShippingIdId(Long shippingId) { ShippingInfo byId = shippingInfoService.getById(shippingId); SalesLedger salesLedger = salesLedgerMapper.selectById(byId.getSalesLedgerId()); SalesLedgerDto salesLedgerDto = new SalesLedgerDto(); BeanUtils.copyProperties(salesLedger, salesLedgerDto); // List<SalesLedgerProductDto> salesLedgerProductDtos = shippingInfoService.getReturnManagementDtoById(byId.getId()); // salesLedgerDto.setProductDtoData(salesLedgerProductDtos); return salesLedgerDto; } @Override public boolean handle(Long returnManagementId) { ReturnManagement byId = this.getById(returnManagementId); List<ReturnSaleProductDto> list = returnSaleProductService.listReturnSaleProduct(returnManagementId); byId.setStatus(1); updateById(byId); // SalesRefundAmountOrderDto salesRefundAmountOrder = new SalesRefundAmountOrderDto(); // salesRefundAmountOrder.setReturnManagementId(returnManagementId); // salesRefundAmountOrder.setStatus(0); // salesRefundAmountOrder.setCreateTime(byId.getCreateTime()); // salesRefundAmountOrder.setCreateUserId(SecurityUtils.getUserId()); BigDecimal bigDecimal = new BigDecimal(0); for (ReturnSaleProductDto returnSaleProduct : list) { bigDecimal = bigDecimal.add(returnSaleProduct.getPrice()); // salesRefundAmountOrder.setRefundedAmount(new BigDecimal(0)); // æ¯å¦æè´¨éé®é¢ if (returnSaleProduct.getIsQuality() == 1) { // æè´¨éé®é¢ï¼å ¥ä¸åæ ¼åº stockUtils.addUnStock(returnSaleProduct.getProductModelId(),returnSaleProduct.getNum(), StockInUnQualifiedRecordTypeEnum.RETURN_UNSTOCK_IN.getCode(),returnSaleProduct.getId()); }else{ // æ è´¨éé®é¢ï¼å ¥åæ ¼åº stockUtils.addStock(returnSaleProduct.getProductModelId(),returnSaleProduct.getNum(), StockInQualifiedRecordTypeEnum.RETURN_HE_IN.getCode(),returnSaleProduct.getId()); } } // salesRefundAmountOrder.setRefundAmount(bigDecimal); // salesRefundAmountOrder.setNotRefundedAmount(salesRefundAmountOrder.getRefundedAmount()); // 忹鿬¾ // salesRefundAmountOrderService.addSalesRefundAmountOrderDto(salesRefundAmountOrder); // åè´¢å¡èå¨ï¼æ°å¢æ¯åº AccountExpense accountExpense = new AccountExpense(); accountExpense.setBusinessType(3); accountExpense.setExpenseMoney(byId.getRefundAmount()); accountExpense.setBusinessId(byId.getId()); accountExpense.setExpenseDate(new Date()); accountExpense.setExpenseMethod("3"); accountExpense.setExpenseType("5"); accountExpense.setExpenseDescribed("éå®éè´§éæ¬¾"); accountExpense.setNote(byId.getReturnReason()); accountExpense.setInputUser(SecurityUtils.getLoginUser().getNickName()); accountExpense.setInputTime(new Date()); accountExpenseMapper.insert(accountExpense); return true; } @Override public ReturnManagementDto getReturnManagementDtoById(Long returnManagementId) { ReturnManagementDto returnManagementDtoById = returnManagementMapper.getReturnManagementDtoById(returnManagementId); returnManagementDtoById.setReturnSaleProducts(returnSaleProductService.listReturnSaleProductDto(returnManagementId)); return returnManagementDtoById; } } src/main/java/com/ruoyi/procurementrecord/service/impl/ReturnSaleProductServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,36 @@ package com.ruoyi.procurementrecord.service.impl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.procurementrecord.dto.ReturnSaleProductDto; import com.ruoyi.procurementrecord.mapper.ReturnSaleProductMapper; import com.ruoyi.procurementrecord.pojo.ReturnSaleProduct; import com.ruoyi.procurementrecord.service.ReturnSaleProductService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * <p> * é货产å表 æå¡å®ç°ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-05 03:57:42 */ @Service public class ReturnSaleProductServiceImpl extends ServiceImpl<ReturnSaleProductMapper, ReturnSaleProduct> implements ReturnSaleProductService { @Autowired private ReturnSaleProductMapper returnSaleProductMapper; @Override public List<ReturnSaleProductDto> listReturnSaleProductDto(Long returnManagementId) { return returnSaleProductMapper.listReturnSaleProductDto(returnManagementId); } @Override public List<ReturnSaleProductDto> listReturnSaleProduct(Long returnManagementId) { return returnSaleProductMapper.listReturnSaleProduct(returnManagementId); } } src/main/java/com/ruoyi/sales/controller/ShippingInfoDetailController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,65 @@ package com.ruoyi.sales.controller; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.aspectj.lang.annotation.Log; import com.ruoyi.framework.aspectj.lang.enums.BusinessType; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.sales.pojo.ShippingInfoDetail; import com.ruoyi.sales.service.ShippingInfoDetailService; import com.ruoyi.sales.service.ShippingInfoService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; import java.util.List; /** * <p> * åè´§æç»è¡¨ å端æ§å¶å¨ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-16 01:27:40 */ @Api(tags = "åè´§æç»è¡¨") @RestController @RequestMapping("/shippingInfoDetail") public class ShippingInfoDetailController { @Autowired private ShippingInfoDetailService shippingInfoDetailService; @ApiOperation("å页æ¥è¯¢") @GetMapping("/listPage") public AjaxResult listPage(Page page, ShippingInfoDetail shippingInfoDetail){ return AjaxResult.success(shippingInfoDetailService.listPage(page, shippingInfoDetail)); } @ApiOperation("æ°å¢") @PostMapping("/add") @Transactional(rollbackFor = Exception.class) @Log(title = "åè´§æç»è¡¨", businessType = BusinessType.INSERT) public AjaxResult add(@RequestBody ShippingInfoDetail shippingInfoDetail) throws Exception{ return shippingInfoDetailService.add(shippingInfoDetail); } @ApiOperation("ä¿®æ¹") @PostMapping("/update") @Transactional(rollbackFor = Exception.class) @Log(title = "åè´§æç»è¡¨", businessType = BusinessType.UPDATE) public AjaxResult update(@RequestBody ShippingInfoDetail shippingInfoDetail){ return shippingInfoDetailService.updateShippingInfoDetail(shippingInfoDetail); } @ApiOperation("å é¤") @DeleteMapping("/delete") @Transactional(rollbackFor = Exception.class) @Log(title = "åè´§æç»è¡¨", businessType = BusinessType.DELETE) public AjaxResult delete(@RequestBody List<Long> ids){ return shippingInfoDetailService.delete(ids); } } src/main/java/com/ruoyi/sales/dto/ShippingInfoDto.java
@@ -7,6 +7,7 @@ import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; import java.util.List; /** @@ -29,4 +30,14 @@ @TableField(exist = false) private List<CommonFile> commonFileList; /** * å·²åè´§æ°é */ private BigDecimal shippingSuccessTotal = BigDecimal.ZERO; /** * å¾ åè´§æ°é */ private BigDecimal waitShippingTotal = BigDecimal.ZERO; } src/main/java/com/ruoyi/sales/mapper/ShippingInfoDetailMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,22 @@ package com.ruoyi.sales.mapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.sales.pojo.ShippingInfoDetail; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; /** * <p> * åè´§æç»è¡¨ Mapper æ¥å£ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-16 01:27:40 */ @Mapper public interface ShippingInfoDetailMapper extends BaseMapper<ShippingInfoDetail> { IPage<ShippingInfoDetail> listPage(Page page,@Param("req") ShippingInfoDetail shippingInfoDetail); } src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
@@ -7,6 +7,7 @@ import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.Date; @@ -67,6 +68,9 @@ @Excel(name = "å货车çå·") private String shippingCarNumber; @ApiModelProperty(value = "åè´§æ»æ°é") private BigDecimal shippingTotal; @ApiModelProperty(value = "å建æ¶é´") @TableField(fill = FieldFill.INSERT) private LocalDateTime createTime; src/main/java/com/ruoyi/sales/pojo/ShippingInfoDetail.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,98 @@ package com.ruoyi.sales.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.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import com.fasterxml.jackson.annotation.JsonFormat; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Getter; import lombok.Setter; /** * <p> * åè´§æç»è¡¨ * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-16 01:27:40 */ @Getter @Setter @TableName("shipping_info_detail") @ApiModel(value = "ShippingInfoDetail对象", description = "åè´§æç»è¡¨") public class ShippingInfoDetail implements Serializable { private static final long serialVersionUID = 1L; @TableField(exist = false) private List<String> tempFileIds; @TableField(exist = false) private List<CommonFile> commonFileList; @ApiModelProperty("åè´§æ»é") @TableField(exist = false) private BigDecimal shippingTotal; @ApiModelProperty("id") @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty("éå®å°è´¦id") private Long salesLedgerId; @ApiModelProperty("åè´§ä¿¡æ¯id") private Long shippingInfoId; @ApiModelProperty("åè´§æ¥æ") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",shape = JsonFormat.Shape.STRING) private LocalDateTime shippingDate; @ApiModelProperty("å货车çå·") private String shippingCarNumber; @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") private Integer salesLedgerProductId; @ApiModelProperty("åè´§ç¼å·") private String shippingNo; @ApiModelProperty("å¿«éåå·") private String expressNumber; @ApiModelProperty("å¿«éå ¬å¸") private String expressCompany; @ApiModelProperty("åè´§ç±»å") private String type; @ApiModelProperty("ç¶æ") private String status; @ApiModelProperty("åè´§æ°é") private BigDecimal shippingNum; } src/main/java/com/ruoyi/sales/service/ShippingInfoDetailService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,29 @@ package com.ruoyi.sales.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.sales.pojo.ShippingInfoDetail; import com.baomidou.mybatisplus.extension.service.IService; import java.io.IOException; import java.util.List; /** * <p> * åè´§æç»è¡¨ æå¡ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-16 01:27:40 */ public interface ShippingInfoDetailService extends IService<ShippingInfoDetail> { IPage<ShippingInfoDetail> listPage(Page page, ShippingInfoDetail shippingInfoDetail); AjaxResult updateShippingInfoDetail(ShippingInfoDetail shippingInfoDetail); AjaxResult add(ShippingInfoDetail shippingInfoDetail) throws IOException; AjaxResult delete(List<Long> ids); } src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -592,9 +592,12 @@ // 3. æ°å¢ææ´æ°ä¸»è¡¨ if (salesLedger.getId() == null) { String contractNo = generateSalesContractNo(); salesLedger.setSalesContractNo(contractNo); salesLedger.setSalesContractNo(salesLedgerDto.getSalesContractNo() == null ? contractNo : salesLedgerDto.getSalesContractNo()); salesLedgerMapper.insert(salesLedger); } else { if(StringUtils.isNotEmpty(salesLedgerDto.getSalesContractNo())){ salesLedger.setSalesContractNo(salesLedgerDto.getSalesContractNo()); } salesLedgerMapper.updateById(salesLedger); } src/main/java/com/ruoyi/sales/service/impl/ShippingInfoDetailServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,108 @@ package com.ruoyi.sales.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.common.enums.FileNameType; import com.ruoyi.framework.web.domain.AjaxResult; import com.ruoyi.other.service.impl.TempFileServiceImpl; import com.ruoyi.sales.dto.ShippingInfoDto; import com.ruoyi.sales.pojo.ShippingInfo; import com.ruoyi.sales.pojo.ShippingInfoDetail; import com.ruoyi.sales.mapper.ShippingInfoDetailMapper; import com.ruoyi.sales.service.ShippingInfoDetailService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.sales.service.ShippingInfoService; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.IOException; import java.math.BigDecimal; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; /** * <p> * åè´§æç»è¡¨ æå¡å®ç°ç±» * </p> * * @author è¯å¯¼è½¯ä»¶ï¼æ±èï¼æéå ¬å¸ * @since 2026-03-16 01:27:40 */ @Service public class ShippingInfoDetailServiceImpl extends ServiceImpl<ShippingInfoDetailMapper, ShippingInfoDetail> implements ShippingInfoDetailService { @Autowired private ShippingInfoDetailMapper shippingInfoDetailMapper; @Autowired private ShippingInfoService shippingInfoService; @Autowired private TempFileServiceImpl tempFileService; @Autowired private CommonFileServiceImpl commonFileService; @Override public IPage<ShippingInfoDetail> listPage(Page page, ShippingInfoDetail shippingInfoDetail) { IPage<ShippingInfoDetail> shippingInfoDetailIPage = shippingInfoDetailMapper.listPage(page, shippingInfoDetail); shippingInfoDetailIPage.getRecords().forEach(item ->{ item.setCommonFileList(commonFileService.getFileListByBusinessId(item.getId(), FileNameType.SHIP.getValue())); }); return shippingInfoDetailIPage; } @Override public AjaxResult updateShippingInfoDetail(ShippingInfoDetail shippingInfoDetail) { return AjaxResult.success(shippingInfoDetailMapper.updateById(shippingInfoDetail)); } @Override public AjaxResult add(ShippingInfoDetail shippingInfoDetail) throws IOException { BigDecimal shippingSuccessTotal = getShippingSuccessTotal(shippingInfoDetail.getShippingInfoId()); BigDecimal add = shippingSuccessTotal.add(shippingInfoDetail.getShippingNum()); shippingInfoDetailMapper.insert(shippingInfoDetail); ShippingInfoDto shippingInfo = new ShippingInfoDto(); BeanUtils.copyProperties(shippingInfoDetail, shippingInfo); shippingInfo.setId(shippingInfoDetail.getShippingInfoId()); // 夿æ¯ä¸æ¯æå䏿¹è´§ if (add.compareTo(shippingInfoDetail.getShippingTotal()) == 0) { shippingInfo.setStatus("å·²åè´§"); }else{ shippingInfo.setStatus("åè´§ä¸"); } shippingInfoService.deductStock(shippingInfo); // è¿ç§»æä»¶ if(CollectionUtils.isNotEmpty(shippingInfoDetail.getTempFileIds())){ tempFileService.migrateTempFilesToFormal(shippingInfoDetail.getId(), shippingInfoDetail.getTempFileIds(), FileNameType.SHIP.getValue()); } return AjaxResult.success("åè´§æå"); } @Override public AjaxResult delete(List<Long> ids) { boolean b = this.removeByIds(ids); // å é¤éä»¶ commonFileService.deleteByBusinessIds(ids, FileNameType.SHIP.getValue()); return b ? AjaxResult.success("å 餿å") : AjaxResult.error("å é¤å¤±è´¥"); } /** * éè¿åè´§ä¿¡æ¯idè·åå·²åè´§æ°é */ public BigDecimal getShippingSuccessTotal(Long shippingInfoId) { List<ShippingInfoDetail> shippingInfoDetails = shippingInfoDetailMapper.selectList(new LambdaQueryWrapper<ShippingInfoDetail>() .eq(ShippingInfoDetail::getShippingInfoId, shippingInfoId)); return Optional.ofNullable(shippingInfoDetails) .orElse(Collections.emptyList()) .stream() .filter(Objects::nonNull) .map(ShippingInfoDetail::getShippingNum) .reduce(BigDecimal.ZERO, BigDecimal::add); } } src/main/java/com/ruoyi/sales/service/impl/ShippingInfoServiceImpl.java
@@ -12,9 +12,12 @@ import com.ruoyi.procurementrecord.utils.StockUtils; import com.ruoyi.sales.dto.ShippingInfoDto; import com.ruoyi.sales.mapper.SalesLedgerProductMapper; import com.ruoyi.sales.mapper.ShippingInfoDetailMapper; import com.ruoyi.sales.mapper.ShippingInfoMapper; import com.ruoyi.sales.pojo.SalesLedgerProduct; import com.ruoyi.sales.pojo.ShippingInfo; import com.ruoyi.sales.pojo.ShippingInfoDetail; import com.ruoyi.sales.service.ShippingInfoDetailService; import com.ruoyi.sales.service.ShippingInfoService; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; @@ -22,8 +25,12 @@ import org.springframework.stereotype.Service; import java.io.IOException; import java.math.BigDecimal; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; /** * @author :yys @@ -37,8 +44,6 @@ private ShippingInfoMapper shippingInfoMapper; @Autowired private TempFileServiceImpl tempFileService; @Autowired private SalesLedgerProductMapper salesLedgerProductMapper; @Autowired private StockUtils stockUtils; @@ -48,11 +53,29 @@ @Autowired private ApproveProcessServiceImpl approveProcessService; @Autowired private ShippingInfoDetailMapper shippingInfoDetailMapper; @Autowired private ShippingInfoDetailService shippingInfoDetailService; @Override public IPage<ShippingInfoDto> listPage(Page page, ShippingInfo req) { IPage<ShippingInfoDto> listPage = shippingInfoMapper.listPage(page, req); listPage.getRecords().forEach(item ->{ item.setCommonFileList(commonFileService.getFileListByBusinessId(item.getId(), FileNameType.SHIP.getValue())); List<ShippingInfoDetail> shippingInfoDetails = shippingInfoDetailMapper.selectList(new LambdaQueryWrapper<ShippingInfoDetail>() .eq(ShippingInfoDetail::getShippingInfoId, item.getId())); // æ ¸å¿ä¼åï¼å±å±é²æ¤ç©ºæé + å¤ç空éååºæ¯ item.setShippingSuccessTotal(Optional.ofNullable(shippingInfoDetails) .orElse(Collections.emptyList()) .stream() .filter(Objects::nonNull) .map(ShippingInfoDetail::getShippingNum) .filter(Objects::nonNull) .reduce(BigDecimal.ZERO, BigDecimal::add)); // ç¨Lambdaæ¿ä»£æ¹æ³å¼ç¨ item.setWaitShippingTotal(item.getShippingTotal().subtract(item.getShippingSuccessTotal())); }); return listPage; } @@ -64,20 +87,13 @@ throw new RuntimeException("åè´§ä¿¡æ¯ä¸åå¨"); } //æ£ååºå if(!"å·²åè´§".equals(byId.getStatus())){ SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(byId.getSalesLedgerProductId()); stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId()); } SalesLedgerProduct salesLedgerProduct = salesLedgerProductMapper.selectById(byId.getSalesLedgerProductId()); stockUtils.substractStock(salesLedgerProduct.getProductModelId(), salesLedgerProduct.getQuantity(), StockOutQualifiedRecordTypeEnum.SALE_SHIP_STOCK_OUT.getCode(), req.getId()); byId.setExpressNumber(req.getExpressNumber()); byId.setExpressCompany(req.getExpressCompany()); byId.setStatus("å·²åè´§"); byId.setStatus(req.getStatus()); byId.setShippingCarNumber(req.getShippingCarNumber()); boolean update = this.updateById(byId); // è¿ç§»æä»¶ if(CollectionUtils.isNotEmpty(req.getTempFileIds())){ tempFileService.migrateTempFilesToFormal(req.getId(), req.getTempFileIds(), FileNameType.SHIP.getValue()); } return update ; return this.updateById(byId); } @Override @@ -85,8 +101,12 @@ List<ShippingInfo> shippingInfos = shippingInfoMapper.selectList(new LambdaQueryWrapper<ShippingInfo>() .in(ShippingInfo::getId, ids)); if(CollectionUtils.isEmpty(shippingInfos)) return false; // å é¤éä»¶ commonFileService.deleteByBusinessIds(ids, FileNameType.SHIP.getValue()); // å é¤å表 List<ShippingInfoDetail> shippingInfoDetails = shippingInfoDetailMapper.selectList(new LambdaQueryWrapper<ShippingInfoDetail>() .in(ShippingInfoDetail::getShippingInfoId, ids)); if(CollectionUtils.isNotEmpty(shippingInfoDetails)){ shippingInfoDetailService.delete(shippingInfoDetails.stream().map(ShippingInfoDetail::getId).collect(Collectors.toList())); } // æ£å·²åè´§åºå for (ShippingInfo shippingInfo : shippingInfos) { if("å·²åè´§".equals(shippingInfo.getStatus())) { src/main/resources/mapper/basic/ProductModelMapper.xml
@@ -106,5 +106,34 @@ left join product p on p.id = pm.product_id order by p.id,pm.id desc </select> <select id="listPage" resultType="com.ruoyi.basic.dto.ProductAndModelDto"> select pm.id as id, p.id as productId, p.product_name as productName , pm.model as model, pm.unit as unit, pm.drawing_number as drawingNumber, pm.product_type as productType from product_model pm left join product p on p.id = pm.product_id <where> <if test="req.productName != null and req.productName != ''"> and p.product_name like concat('%',#{req.productName},'%') </if> <if test="req.model != null and req.model != ''"> and pm.model like concat('%',#{req.model},'%') </if> <if test="req.unit != null and req.unit != ''"> and pm.unit like concat('%',#{req.unit},'%') </if> <if test="req.drawingNumber != null and req.drawingNumber != ''"> and pm.drawing_number like concat('%',#{req.drawingNumber},'%') </if> <if test="req.productType != null and req.productType != ''"> and pm.product_type = #{req.productType} </if> </where> order by pm.id desc </select> </mapper> src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml
@@ -2,15 +2,55 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ruoyi.procurementrecord.mapper.ReturnManagementMapper"> <select id="listPage" resultType="com.ruoyi.procurementrecord.pojo.ReturnManagement"> select * from return_management <select id="listPage" resultType="com.ruoyi.procurementrecord.dto.ReturnManagementDto"> select rm.*, c.customer_name, si.shipping_no, sl.project_name, sl.sales_contract_no, sl.salesman from return_management rm left join shipping_info si on rm.shipping_id = si.id left join customer c on rm.customer_id = c.id left join sales_ledger sl on si.sales_ledger_id = sl.id <where> <if test="req.returnNo != null and req.returnNo != ''"> and return_no like concat('%',#{req.returnNo},'%') and rm.return_no like concat('%',#{req.returnNo},'%') </if> <if test="req.returnType != null and req.returnType != ''"> and return_type = #{req.returnType} <if test="req.customerName != null and req.customerName != ''"> and c.customer_name like concat('%',#{req.customerName},'%') </if> <if test="req.projectName != null and req.projectName != ''"> and sl.project_name like concat('%',#{req.projectName},'%') </if> <if test="req.salesman != null and req.salesman != ''"> and sl.salesman like concat('%',#{req.salesman},'%') </if> <if test="req.shippingNo != null and req.shippingNo != ''"> and si.shipping_no like concat('%',#{req.shippingNo},'%') </if> <if test="req.projectStage != null and req.projectStage != ''"> and rm.project_stage like concat('%',#{req.projectStage},'%') </if> <if test="req.maker != null and req.maker != ''"> and rm.maker like concat('%',#{req.maker},'%') </if> <if test="req.salesContractNo != null and req.salesContractNo != ''"> and sl.sales_contract_no like concat('%',#{req.salesContractNo},'%') </if> </where> </select> <select id="getReturnManagementDtoById" resultType="com.ruoyi.procurementrecord.dto.ReturnManagementDto"> select rm.*, c.customer_name, si.shipping_no, sl.project_name, sl.sales_contract_no, sl.salesman from return_management rm left join shipping_info si on rm.shipping_id = si.id left join customer c on rm.customer_id = c.id left join sales_ledger sl on si.sales_ledger_id = sl.id where rm.id = #{id} </select> </mapper> src/main/resources/mapper/procurementrecord/ReturnSaleProductMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,39 @@ <?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.procurementrecord.mapper.ReturnSaleProductMapper"> <!-- éç¨æ¥è¯¢æ å°ç»æ --> <resultMap id="BaseResultMap" type="com.ruoyi.procurementrecord.pojo.ReturnSaleProduct"> <id column="id" property="id" /> <result column="return_management_id" property="returnManagementId" /> <result column="return_sale_ledger_product_id" property="returnSaleLedgerProductId" /> <result column="num" property="num" /> <result column="status" property="status" /> </resultMap> <select id="listReturnSaleProductDto" resultType="com.ruoyi.procurementrecord.dto.ReturnSaleProductDto"> SELECT slp.product_category as product_name, slp.specification_model as model, slp.unit as unit, rsp.*, GREATEST(slp.quantity - COALESCE(rs.total_return_num, 0), 0) AS un_quantity, COALESCE(rs.total_return_num, 0) AS total_return_num FROM return_sale_product rsp LEFT JOIN return_management rm ON rm.id = rsp.return_management_id LEFT JOIN shipping_info si ON si.id = rm.shipping_id LEFT JOIN sales_ledger_product slp ON si.sales_ledger_product_id = slp.id and slp.type = 1 LEFT JOIN (SELECT return_sale_ledger_product_id, SUM(num) AS total_return_num FROM return_sale_product WHERE 1 = 1 and return_management_id != #{returnManagementId} GROUP BY return_sale_ledger_product_id) rs ON rs.return_sale_ledger_product_id = slp.id where rm.id =#{returnManagementId} </select> <select id="listReturnSaleProduct" resultType="com.ruoyi.procurementrecord.dto.ReturnSaleProductDto"> select rsp.*,slp.tax_inclusive_unit_price ,slp.tax_inclusive_total_price*rsp.num as price from return_sale_product rsp left join sales_ledger_product slp on slp.id = rsp.return_sale_ledger_product_id where rsp.return_management_id = #{returnManagementId} </select> </mapper> src/main/resources/mapper/sales/ShippingInfoDetailMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,35 @@ <?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.sales.mapper.ShippingInfoDetailMapper"> <!-- éç¨æ¥è¯¢æ å°ç»æ --> <resultMap id="BaseResultMap" type="com.ruoyi.sales.pojo.ShippingInfoDetail"> <id column="id" property="id" /> <result column="sales_ledger_id" property="salesLedgerId" /> <result column="shipping_info_id" property="shippingInfoId" /> <result column="shipping_date" property="shippingDate" /> <result column="shipping_car_number" property="shippingCarNumber" /> <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="sales_ledger_product_id" property="salesLedgerProductId" /> <result column="shipping_no" property="shippingNo" /> <result column="express_number" property="expressNumber" /> <result column="express_company" property="expressCompany" /> <result column="type" property="type" /> <result column="status" property="status" /> <result column="shipping_num" property="shippingNum" /> </resultMap> <select id="listPage" resultType="com.ruoyi.sales.pojo.ShippingInfoDetail"> SELECT * FROM shipping_info_detail <where> <if test="req.shippingInfoId != null"> AND shipping_info_id = #{req.shippingInfoId} </if> </where> </select> </mapper> src/main/resources/mapper/sales/ShippingInfoMapper.xml
@@ -19,7 +19,8 @@ s.update_user, s.tenant_id, sl.sales_contract_no, sl.customer_name sl.customer_name, s.shipping_total AS shipping_total FROM shipping_info s LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id WHERE 1=1