已添加6个文件
已修改5个文件
435 ■■■■■ 文件已修改
src/main/java/com/ruoyi/production/controller/ProductBomController.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductWorkOrderFileController.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/dto/ProductStructureDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/mapper/ProductWorkOrderFileMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductStructure.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/pojo/ProductWorkOrderFile.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/ProductWorkOrderFileService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductBomServiceImpl.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java 148 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/service/impl/ProductWorkOrderFileServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductWorkOrderFileMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/controller/ProductBomController.java
@@ -8,14 +8,8 @@
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.production.dto.ProductBomDto;
import com.ruoyi.production.dto.ProductProcessDto;
import com.ruoyi.production.pojo.ProcessRoute;
import com.ruoyi.production.pojo.ProductBom;
import com.ruoyi.production.pojo.ProductProcess;
import com.ruoyi.production.pojo.ProductProcessRoute;
import com.ruoyi.production.service.ProcessRouteService;
import com.ruoyi.production.service.ProductBomService;
import com.ruoyi.production.service.ProductProcessRouteService;
import com.ruoyi.production.service.ProductProcessService;
import com.ruoyi.production.pojo.*;
import com.ruoyi.production.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
@@ -46,6 +40,9 @@
    @Autowired
    private ProductProcessRouteService productProcessRouteService;
    @Autowired
    private ProductStructureService productStructureService;
    @GetMapping("/listPage")
    @Log(title = "BOM-分页查询", businessType = BusinessType.OTHER)
@@ -81,6 +78,8 @@
        if(CollectionUtils.isEmpty(ids)){
            return AjaxResult.error("请选择至少一条数据");
        }
        //删除bom子表
        productStructureService.remove(Wrappers.<ProductStructure>lambdaQuery().in(ProductStructure::getBomId,ids));
        return AjaxResult.success(productBomService.removeBatchByIds(ids));
    }
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/ProductStructureDto.java
@@ -1,22 +1,34 @@
package com.ruoyi.production.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.ruoyi.production.pojo.ProductStructure;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
public class ProductStructureDto extends ProductStructure {
    @ApiModelProperty(value = "工艺名称")
    private String processName;
    @ApiModelProperty(value = "产品名称")
    private String productName;
    @ApiModelProperty(value = "产品id")
    private Long productId;
    private String model;
    private List<ProductStructure> productStructureList;
    @TableField(exist = false)
    private String tempId;
    @TableField(exist = false)
    private String parentTempId;
    @TableField(exist = false)
    private List<ProductStructureDto> children;
}
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/pojo/ProductStructure.java
@@ -52,5 +52,10 @@
     */
    private Long bomId;
    /**
     * çˆ¶èŠ‚ç‚¹ID
     */
    private Long parentId;
}
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/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/impl/ProductBomServiceImpl.java
@@ -1,19 +1,23 @@
package com.ruoyi.production.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.pojo.ProductModel;
import com.ruoyi.basic.service.IProductModelService;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.production.dto.ProductBomDto;
import com.ruoyi.production.dto.ProductProcessDto;
import com.ruoyi.production.pojo.ProductBom;
import com.ruoyi.production.mapper.ProductBomMapper;
import com.ruoyi.production.pojo.ProductProcess;
import com.ruoyi.production.mapper.ProductStructureMapper;
import com.ruoyi.production.pojo.ProductBom;
import com.ruoyi.production.pojo.ProductStructure;
import com.ruoyi.production.service.ProductBomService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
/**
 * <p>
@@ -29,12 +33,19 @@
    @Autowired
    private ProductBomMapper productBomMapper;
    @Autowired
    private IProductModelService productModelService;
    @Autowired
    private ProductStructureMapper productStructureMapper;
    @Override
    public IPage<ProductBomDto> listPage(Page page, ProductBomDto productBomDto) {
        return productBomMapper.listPage(page,productBomDto);
        return productBomMapper.listPage(page, productBomDto);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult add(ProductBom productBom) {
        boolean save = productBomMapper.insert(productBom) > 0;
        if (save) {
@@ -42,6 +53,26 @@
            String no = "BM." + String.format("%05d", productBom.getId());
            productBom.setBomNo(no);
            productBomMapper.updateById(productBom);
            //  æŸ¥è¯¢å‡ºäº§å“æ¨¡åž‹ä¿¡æ¯
            if (productBom.getProductModelId() == null) {
                throw new ServiceException("请选择产品模型");
            }
            ProductModel productModel = productModelService.getById(productBom.getProductModelId());
            if (productModel == null) {
                throw new ServiceException("选择的产品模型不存在");
            }
            //  æ·»åŠ åˆå§‹çš„äº§å“ç»“æž„
            ProductStructure productStructure = new ProductStructure();
            productStructure.setProductModelId(productBom.getProductModelId());
            productStructure.setUnit(productModel.getUnit());
            productStructure.setUnitQuantity(BigDecimal.valueOf(1));
            productStructure.setBomId(Long.valueOf(productBom.getId()));
            productStructureMapper.insert(productStructure);
            return AjaxResult.success();
        }
        return AjaxResult.error();
src/main/java/com/ruoyi/production/service/impl/ProductStructureServiceImpl.java
@@ -1,16 +1,8 @@
package com.ruoyi.production.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.basic.dto.ProductModelDto;
import com.ruoyi.basic.dto.ProductTreeDto;
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.production.dto.ProductStructureDto;
import com.ruoyi.production.mapper.ProductBomMapper;
import com.ruoyi.production.mapper.ProductStructureMapper;
import com.ruoyi.production.pojo.ProductStructure;
import com.ruoyi.production.service.ProductStructureService;
@@ -19,9 +11,10 @@
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@@ -29,23 +22,138 @@
public class ProductStructureServiceImpl extends ServiceImpl<ProductStructureMapper, ProductStructure> implements ProductStructureService {
    @Autowired
    private  ProductStructureMapper productStructureMapper;
    private ProductStructureMapper productStructureMapper;
    @Override
    public Boolean addProductStructureDto(ProductStructureDto productStructureDto) {
        this.remove(new QueryWrapper<ProductStructure>().lambda().eq(ProductStructure::getBomId, productStructureDto.getBomId()));
        productStructureDto.getProductStructureList().forEach(productStructure -> {
            productStructure.setBomId(productStructureDto.getBomId());
        });
        return this.saveBatch(productStructureDto.getProductStructureList());
    @Transactional
    public Boolean addProductStructureDto(ProductStructureDto dto) {
        Long bomId = dto.getBomId();
        //  å°†æ ‘扁平化
        List<ProductStructureDto> flatDtoList = new ArrayList<>();
        flattenTree(dto.getChildren(), flatDtoList);
        //  æŸ¥è¯¢æ•°æ®åº“中已有的 BOM æ•°æ®
        List<ProductStructure> dbList = this.list(new LambdaQueryWrapper<ProductStructure>().eq(ProductStructure::getBomId, bomId));
        //  æŸ¥æ‰¾å·²å­˜åœ¨çš„节点 - ID
        Set<Long> frontendIds = flatDtoList.stream()
                .map(ProductStructureDto::getId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
        //  éœ€è¦åˆ é™¤çš„节点 - ID
        Set<Long> deleteIds = dbList.stream()
                .map(ProductStructure::getId)
                .filter(id -> !frontendIds.contains(id))
                .collect(Collectors.toSet());
        if (!deleteIds.isEmpty()) {
            this.removeByIds(deleteIds);
        }
        //  æ–°å¢ž / æ›´æ–°
        List<ProductStructure> insertList = new ArrayList<>();
        List<ProductStructure> updateList = new ArrayList<>();
        // ç”¨äºŽå›žå†™ parentId
        Map<String, ProductStructure> tempEntityMap = new HashMap<>();
        for (ProductStructureDto psDto : flatDtoList) {
            ProductStructure entity = new ProductStructure();
            BeanUtils.copyProperties(psDto, entity);
            entity.setBomId(bomId);
            if (psDto.getId() == null) {
                // æ–°å¢ž
                entity.setId(null);
                entity.setParentId(null);
                insertList.add(entity);
                tempEntityMap.put(psDto.getTempId(), entity);
            } else {
                // æ›´æ–°
                updateList.add(entity);
            }
        }
        //  æ’入新节点
        if (!insertList.isEmpty()) {
            this.saveBatch(insertList);
        }
        //  å›žå†™æ–°å¢žèŠ‚ç‚¹ parentId
        List<ProductStructure> parentFixList = new ArrayList<>();
        //  çœŸå®žçš„父节点 ID
        Long realParentId;
        for (ProductStructureDto psDto : flatDtoList) {
            if (psDto.getId() == null && psDto.getParentTempId() != null) {
                ProductStructure child = tempEntityMap.get(psDto.getTempId());
                if (tempEntityMap.containsKey(psDto.getParentTempId())) {
                    // çˆ¶èŠ‚ç‚¹æ˜¯æ–°èŠ‚ç‚¹
                    realParentId = tempEntityMap.get(psDto.getParentTempId()).getId();
                } else {
                    // çˆ¶èŠ‚ç‚¹æ˜¯è€èŠ‚ç‚¹
                    realParentId = Long.valueOf(psDto.getParentTempId());
                }
                child.setParentId(realParentId);
                parentFixList.add(child);
            }
        }
        if (!parentFixList.isEmpty()) {
            this.updateBatchById(parentFixList);
        }
        if (!updateList.isEmpty()) {
            this.updateBatchById(updateList);
        }
        return true;
    }
    /**
     * å°†å‰ç«¯ä¼ å…¥çš„æ ‘进行扁平化
     *
     * @param source æ•°æ®æ ‘
     * @param result æ‰å¹³åŒ–数据
     */
    private void flattenTree(List<ProductStructureDto> source, List<ProductStructureDto> result) {
        if (source == null) {
            return;
        }
        for (ProductStructureDto node : source) {
            result.add(node);
            flattenTree(node.getChildren(), result);
        }
    }
    @Override
    public List<ProductStructureDto> listBybomId(Long bomId) {
        List<ProductStructureDto> tree = productStructureMapper.listBybomId(bomId);
        return tree;
        List<ProductStructureDto> list = productStructureMapper.listBybomId(bomId);
        Map<Long, ProductStructureDto> map = new HashMap<>();
        for (ProductStructureDto node : list) {
            node.setChildren(new ArrayList<>());
            map.put(node.getId(), node);
        }
        List<ProductStructureDto> tree = new ArrayList<>();
        for (ProductStructureDto node : list) {
            Long parentId = node.getParentId();
            if (parentId == null || parentId == 0) {
                tree.add(node);
            } else {
                ProductStructureDto parent = map.get(parentId);
                if (parent != null) {
                    parent.getChildren().add(node);
                }
            }
        }
        return tree;
    }
}
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/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>