2026-04-21 b2bfc3c8c094d7b46f1e41fc75b26221ce945dab
feat(technology): 添加工艺路线查询功能并完善相关接口

- 在TechnologyRoutingDto中添加产品名称、规格名称和BOM编号查询字段
- 实现分页查询方法并集成产品、规格和BOM关联信息
- 添加TechnologyRoutingOperationParam的完整CRUD操作接口
- 实现工艺路线工序参数同步功能
- 更新数据库连接配置文件
- 完善异常处理和数据验证逻辑
已修改10个文件
419 ■■■■ 文件已修改
src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingDto.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/technology/bean/vo/TechnologyRoutingVo.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/technology/controller/TechnologyRoutingOperationParamController.java 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/technology/mapper/TechnologyRoutingMapper.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/technology/service/TechnologyRoutingOperationParamService.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/technology/service/impl/TechnologyRoutingOperationParamServiceImpl.java 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/technology/service/impl/TechnologyRoutingServiceImpl.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/technology/TechnologyRoutingMapper.xml 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/technology/bean/dto/TechnologyRoutingDto.java
@@ -2,14 +2,21 @@
import com.ruoyi.technology.pojo.TechnologyRouting;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "TechnologyRoutingDto对象", description = "工艺路线表")
@ApiModel(value = "TechnologyRoutingDto对象", description = "工艺路线查询参数")
public class TechnologyRoutingDto extends TechnologyRouting {
    @ApiModelProperty("产品名称")
    private String productName;
    @ApiModelProperty("规格名称")
    private String model;
    @ApiModelProperty("BOM编号")
    private String bomNo;
}
src/main/java/com/ruoyi/technology/bean/vo/TechnologyRoutingVo.java
@@ -2,11 +2,21 @@
import com.ruoyi.technology.pojo.TechnologyRouting;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
@EqualsAndHashCode(callSuper = true)
@Data
@ApiModel(value = "TechnologyRoutingVo对象", description = "工艺路线表")
@ApiModel(value = "TechnologyRoutingVo对象", description = "工艺路线返回对象")
public class TechnologyRoutingVo extends TechnologyRouting {
    @ApiModelProperty("产品名称")
    private String productName;
    @ApiModelProperty("规格名称")
    private String model;
    @ApiModelProperty("BOM编号")
    private String bomNo;
}
src/main/java/com/ruoyi/technology/controller/TechnologyRoutingOperationParamController.java
@@ -1,18 +1,68 @@
package com.ruoyi.technology.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.technology.bean.dto.TechnologyRoutingOperationParamDto;
import com.ruoyi.technology.bean.dto.TechnologyRoutingOperationParamSyncDto;
import com.ruoyi.technology.bean.vo.TechnologyRoutingOperationParamVo;
import com.ruoyi.technology.pojo.TechnologyRoutingOperationParam;
import com.ruoyi.technology.service.TechnologyRoutingOperationParamService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
/**
 * <p>
 * 生产订单工艺路线工序参数表 前端控制器
 * </p>
 *
 * @author 芯导软件(江苏)有限公司
 * @since 2026-04-20 10:22:16
 */
import java.util.List;
@RestController
@RequestMapping("/technologyRoutingOperationParam")
@Api(tags = "生产订单工艺路线工序参数")
@RequiredArgsConstructor
public class TechnologyRoutingOperationParamController {
    private final TechnologyRoutingOperationParamService technologyRoutingOperationParamService;
    @GetMapping("/page")
    @ApiOperation("生产订单工艺路线工序参数分页查询")
    public R<IPage<TechnologyRoutingOperationParamVo>> page(Page<TechnologyRoutingOperationParamDto> page,
                                                            TechnologyRoutingOperationParamDto dto) {
        return R.ok(technologyRoutingOperationParamService.pageTechnologyRoutingOperationParam(page, dto));
    }
    @GetMapping("/list")
    @ApiOperation("生产订单工艺路线工序参数列表")
    public R<List<TechnologyRoutingOperationParamVo>> list(TechnologyRoutingOperationParamDto dto) {
        return R.ok(technologyRoutingOperationParamService.listTechnologyRoutingOperationParam(dto));
    }
    @GetMapping("/{id}")
    @ApiOperation("生产订单工艺路线工序参数详情")
    public R<TechnologyRoutingOperationParamVo> getInfo(@PathVariable("id") Long id) {
        return R.ok(technologyRoutingOperationParamService.getTechnologyRoutingOperationParamInfo(id));
    }
    @PostMapping
    @ApiOperation("新增生产订单工艺路线工序参数")
    public R<Boolean> add(@RequestBody TechnologyRoutingOperationParam technologyRoutingOperationParam) {
        return R.ok(technologyRoutingOperationParamService.saveTechnologyRoutingOperationParam(technologyRoutingOperationParam));
    }
    @PutMapping
    @ApiOperation("修改生产订单工艺路线工序参数")
    public R<Boolean> edit(@RequestBody TechnologyRoutingOperationParam technologyRoutingOperationParam) {
        return R.ok(technologyRoutingOperationParamService.saveTechnologyRoutingOperationParam(technologyRoutingOperationParam));
    }
    @DeleteMapping("/{id}")
    @ApiOperation("删除生产订单工艺路线工序参数")
    public R<Boolean> remove(@PathVariable("id") Long id) {
        return R.ok(technologyRoutingOperationParamService.removeTechnologyRoutingOperationParam(id));
    }
    @PostMapping("/sync")
    @ApiOperation("按工艺路线工序同步工序参数")
    public R<Integer> sync(@RequestBody TechnologyRoutingOperationParamSyncDto syncDto) {
        return R.ok(technologyRoutingOperationParamService.syncTechnologyRoutingOperationParam(syncDto));
    }
}
src/main/java/com/ruoyi/technology/mapper/TechnologyRoutingMapper.java
@@ -1,20 +1,18 @@
package com.ruoyi.technology.mapper;
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.technology.bean.dto.TechnologyRoutingDto;
import com.ruoyi.technology.bean.vo.TechnologyRoutingVo;
import com.ruoyi.technology.pojo.TechnologyRouting;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
 * 工艺路线表 Mapper 接口
 * </p>
 *
 * @author 芯导软件(江苏)有限公司
 * @since 2026-04-20 10:06:33
 */
@Mapper
public interface TechnologyRoutingMapper extends BaseMapper<TechnologyRouting> {
    IPage<TechnologyRoutingVo> pageTechnologyRouting(Page<TechnologyRoutingDto> page, @Param("c") TechnologyRoutingDto technologyRoutingDto);
    int updateProductModelByBomId(@Param("productModelId") Long productModelId, @Param("bomId") Long bomId);
}
src/main/java/com/ruoyi/technology/service/TechnologyRoutingOperationParamService.java
@@ -1,16 +1,27 @@
package com.ruoyi.technology.service;
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.technology.bean.dto.TechnologyRoutingOperationParamDto;
import com.ruoyi.technology.bean.dto.TechnologyRoutingOperationParamSyncDto;
import com.ruoyi.technology.bean.vo.TechnologyRoutingOperationParamVo;
import com.ruoyi.technology.pojo.TechnologyRoutingOperationParam;
/**
 * <p>
 * 生产订单工艺路线工序参数表 服务类
 * </p>
 *
 * @author 芯导软件(江苏)有限公司
 * @since 2026-04-20 10:22:16
 */
import java.util.List;
public interface TechnologyRoutingOperationParamService extends IService<TechnologyRoutingOperationParam> {
    IPage<TechnologyRoutingOperationParamVo> pageTechnologyRoutingOperationParam(Page<TechnologyRoutingOperationParamDto> page,
                                                                                 TechnologyRoutingOperationParamDto technologyRoutingOperationParamDto);
    List<TechnologyRoutingOperationParamVo> listTechnologyRoutingOperationParam(TechnologyRoutingOperationParamDto technologyRoutingOperationParamDto);
    TechnologyRoutingOperationParamVo getTechnologyRoutingOperationParamInfo(Long id);
    boolean saveTechnologyRoutingOperationParam(TechnologyRoutingOperationParam technologyRoutingOperationParam);
    boolean removeTechnologyRoutingOperationParam(Long id);
    int syncTechnologyRoutingOperationParam(TechnologyRoutingOperationParamSyncDto syncDto);
}
src/main/java/com/ruoyi/technology/service/impl/TechnologyRoutingOperationParamServiceImpl.java
@@ -1,20 +1,204 @@
package com.ruoyi.technology.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
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.ruoyi.common.exception.ServiceException;
import com.ruoyi.technology.bean.dto.TechnologyRoutingOperationParamDto;
import com.ruoyi.technology.bean.dto.TechnologyRoutingOperationParamSyncDto;
import com.ruoyi.technology.bean.vo.TechnologyRoutingOperationParamVo;
import com.ruoyi.technology.mapper.TechnologyOperationParamMapper;
import com.ruoyi.technology.mapper.TechnologyParamMapper;
import com.ruoyi.technology.mapper.TechnologyRoutingOperationMapper;
import com.ruoyi.technology.mapper.TechnologyRoutingOperationParamMapper;
import com.ruoyi.technology.pojo.TechnologyOperationParam;
import com.ruoyi.technology.pojo.TechnologyParam;
import com.ruoyi.technology.pojo.TechnologyRoutingOperation;
import com.ruoyi.technology.pojo.TechnologyRoutingOperationParam;
import com.ruoyi.technology.service.TechnologyRoutingOperationParamService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
 * <p>
 * 生产订单工艺路线工序参数表 服务实现类
 * </p>
 *
 * @author 芯导软件(江苏)有限公司
 * @since 2026-04-20 10:22:16
 */
import java.util.List;
@Service
public class TechnologyRoutingOperationParamServiceImpl extends ServiceImpl<TechnologyRoutingOperationParamMapper, TechnologyRoutingOperationParam> implements TechnologyRoutingOperationParamService {
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class TechnologyRoutingOperationParamServiceImpl extends ServiceImpl<TechnologyRoutingOperationParamMapper, TechnologyRoutingOperationParam>
        implements TechnologyRoutingOperationParamService {
    private final TechnologyRoutingOperationParamMapper technologyRoutingOperationParamMapper;
    private final TechnologyRoutingOperationMapper technologyRoutingOperationMapper;
    private final TechnologyOperationParamMapper technologyOperationParamMapper;
    private final TechnologyParamMapper technologyParamMapper;
    @Override
    public IPage<TechnologyRoutingOperationParamVo> pageTechnologyRoutingOperationParam(Page<TechnologyRoutingOperationParamDto> page,
                                                                                        TechnologyRoutingOperationParamDto dto) {
        Page<TechnologyRoutingOperationParam> entityPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        return this.page(entityPage, buildQueryWrapper(dto))
                .convert(item -> BeanUtil.copyProperties(item, TechnologyRoutingOperationParamVo.class));
    }
    @Override
    public List<TechnologyRoutingOperationParamVo> listTechnologyRoutingOperationParam(TechnologyRoutingOperationParamDto dto) {
        return BeanUtil.copyToList(this.list(buildQueryWrapper(dto)), TechnologyRoutingOperationParamVo.class);
    }
    @Override
    public TechnologyRoutingOperationParamVo getTechnologyRoutingOperationParamInfo(Long id) {
        TechnologyRoutingOperationParam item = this.getById(id);
        if (item == null) {
            return null;
        }
        return BeanUtil.copyProperties(item, TechnologyRoutingOperationParamVo.class);
    }
    @Override
    public boolean saveTechnologyRoutingOperationParam(TechnologyRoutingOperationParam item) {
        TechnologyRoutingOperation routingOperation = getRoutingOperation(item.getTechnologyRoutingOperationId());
        fillFromOperationParam(item, routingOperation);
        validateManualFields(item);
        checkDuplicate(item);
        return this.saveOrUpdate(item);
    }
    @Override
    public boolean removeTechnologyRoutingOperationParam(Long id) {
        return this.removeById(id);
    }
    @Override
    public int syncTechnologyRoutingOperationParam(TechnologyRoutingOperationParamSyncDto syncDto) {
        if (syncDto == null || syncDto.getTechnologyRoutingOperationId() == null) {
            throw new ServiceException("technologyRoutingOperationId is required");
        }
        TechnologyRoutingOperation routingOperation = getRoutingOperation(syncDto.getTechnologyRoutingOperationId());
        List<TechnologyOperationParam> operationParamList = technologyOperationParamMapper.selectList(
                Wrappers.<TechnologyOperationParam>lambdaQuery()
                        .eq(TechnologyOperationParam::getTechnologyOperationId, routingOperation.getTechnologyOperationId())
                        .orderByAsc(TechnologyOperationParam::getId)
        );
        boolean replaceExisting = syncDto.getReplaceExisting() == null || syncDto.getReplaceExisting();
        if (replaceExisting) {
            technologyRoutingOperationParamMapper.delete(
                    Wrappers.<TechnologyRoutingOperationParam>lambdaQuery()
                            .eq(TechnologyRoutingOperationParam::getTechnologyRoutingOperationId, routingOperation.getId())
            );
        }
        int successCount = 0;
        for (TechnologyOperationParam operationParam : operationParamList) {
            boolean exists = technologyRoutingOperationParamMapper.selectCount(
                    Wrappers.<TechnologyRoutingOperationParam>lambdaQuery()
                            .eq(TechnologyRoutingOperationParam::getTechnologyRoutingOperationId, routingOperation.getId())
                            .eq(TechnologyRoutingOperationParam::getTechnologyOperationParamId, operationParam.getId())
            ) > 0;
            if (!replaceExisting && exists) {
                continue;
            }
            TechnologyRoutingOperationParam snapshot = new TechnologyRoutingOperationParam();
            snapshot.setTechnologyRoutingOperationId(routingOperation.getId());
            snapshot.setTechnologyOperationParamId(operationParam.getId());
            snapshot.setTechnologyOperationId(operationParam.getTechnologyOperationId());
            snapshot.setStandardValue(operationParam.getStandardValue());
            fillFromOperationParam(snapshot, routingOperation);
            technologyRoutingOperationParamMapper.insert(snapshot);
            successCount++;
        }
        return successCount;
    }
    private LambdaQueryWrapper<TechnologyRoutingOperationParam> buildQueryWrapper(TechnologyRoutingOperationParamDto dto) {
        TechnologyRoutingOperationParam query = dto == null ? new TechnologyRoutingOperationParam() : dto;
        return Wrappers.<TechnologyRoutingOperationParam>lambdaQuery()
                .eq(query.getId() != null, TechnologyRoutingOperationParam::getId, query.getId())
                .eq(query.getTechnologyRoutingOperationId() != null,
                        TechnologyRoutingOperationParam::getTechnologyRoutingOperationId, query.getTechnologyRoutingOperationId())
                .eq(query.getTechnologyOperationId() != null,
                        TechnologyRoutingOperationParam::getTechnologyOperationId, query.getTechnologyOperationId())
                .eq(query.getTechnologyOperationParamId() != null,
                        TechnologyRoutingOperationParam::getTechnologyOperationParamId, query.getTechnologyOperationParamId())
                .eq(query.getParamId() != null, TechnologyRoutingOperationParam::getParamId, query.getParamId())
                .eq(query.getParamType() != null, TechnologyRoutingOperationParam::getParamType, query.getParamType())
                .like(query.getParamCode() != null && !query.getParamCode().isEmpty(),
                        TechnologyRoutingOperationParam::getParamCode, query.getParamCode())
                .like(query.getParamName() != null && !query.getParamName().isEmpty(),
                        TechnologyRoutingOperationParam::getParamName, query.getParamName())
                .orderByAsc(TechnologyRoutingOperationParam::getTechnologyRoutingOperationId)
                .orderByAsc(TechnologyRoutingOperationParam::getId);
    }
    private TechnologyRoutingOperation getRoutingOperation(Long technologyRoutingOperationId) {
        if (technologyRoutingOperationId == null) {
            throw new ServiceException("technologyRoutingOperationId is required");
        }
        TechnologyRoutingOperation routingOperation = technologyRoutingOperationMapper.selectById(technologyRoutingOperationId);
        if (routingOperation == null) {
            throw new ServiceException("Technology routing operation not found");
        }
        return routingOperation;
    }
    private void fillFromOperationParam(TechnologyRoutingOperationParam item, TechnologyRoutingOperation routingOperation) {
        if (item.getTechnologyOperationId() == null) {
            item.setTechnologyOperationId(routingOperation.getTechnologyOperationId());
        } else if (!item.getTechnologyOperationId().equals(routingOperation.getTechnologyOperationId())) {
            throw new ServiceException("technologyOperationId does not match routing operation");
        }
        if (item.getTechnologyOperationParamId() == null) {
            return;
        }
        TechnologyOperationParam operationParam = technologyOperationParamMapper.selectById(item.getTechnologyOperationParamId());
        if (operationParam == null) {
            throw new ServiceException("Technology operation param not found");
        }
        if (!routingOperation.getTechnologyOperationId().equals(operationParam.getTechnologyOperationId())) {
            throw new ServiceException("Operation param does not belong to routing operation");
        }
        TechnologyParam technologyParam = technologyParamMapper.selectById(operationParam.getTechnologyParamId());
        if (technologyParam == null) {
            throw new ServiceException("Technology param not found");
        }
        item.setParamId(technologyParam.getId());
        item.setParamCode(technologyParam.getParamCode());
        item.setParamName(technologyParam.getParamName());
        item.setParamType(technologyParam.getParamType());
        item.setParamFormat(technologyParam.getParamFormat());
        item.setUnit(technologyParam.getUnit());
        item.setIsRequired(technologyParam.getIsRequired());
        if (item.getRemark() == null || item.getRemark().trim().isEmpty()) {
            item.setRemark(technologyParam.getRemark());
        }
        if (item.getStandardValue() == null) {
            item.setStandardValue(operationParam.getStandardValue());
        }
    }
    private void validateManualFields(TechnologyRoutingOperationParam item) {
        if (item.getParamCode() == null || item.getParamCode().trim().isEmpty()) {
            throw new ServiceException("paramCode is required");
        }
        if (item.getParamName() == null || item.getParamName().trim().isEmpty()) {
            throw new ServiceException("paramName is required");
        }
    }
    private void checkDuplicate(TechnologyRoutingOperationParam item) {
        boolean duplicate = technologyRoutingOperationParamMapper.selectCount(
                Wrappers.<TechnologyRoutingOperationParam>lambdaQuery()
                        .eq(TechnologyRoutingOperationParam::getTechnologyRoutingOperationId, item.getTechnologyRoutingOperationId())
                        .eq(item.getTechnologyOperationParamId() != null,
                                TechnologyRoutingOperationParam::getTechnologyOperationParamId, item.getTechnologyOperationParamId())
                        .eq(item.getTechnologyOperationParamId() == null && item.getParamCode() != null,
                                TechnologyRoutingOperationParam::getParamCode, item.getParamCode())
                        .ne(item.getId() != null, TechnologyRoutingOperationParam::getId, item.getId())
        ) > 0;
        if (duplicate) {
            throw new ServiceException("Duplicate routing operation param");
        }
    }
}
src/main/java/com/ruoyi/technology/service/impl/TechnologyRoutingServiceImpl.java
@@ -6,6 +6,7 @@
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.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.OrderUtils;
import com.ruoyi.technology.bean.dto.TechnologyRoutingDto;
import com.ruoyi.technology.bean.vo.TechnologyRoutingVo;
@@ -43,15 +44,7 @@
    @Override
    public IPage<TechnologyRoutingVo> pageTechnologyRouting(Page<TechnologyRoutingDto> page, TechnologyRoutingDto technologyRoutingDto) {
        LambdaQueryWrapper<TechnologyRouting> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(technologyRoutingDto.getId() != null, TechnologyRouting::getId, technologyRoutingDto.getId())
                .eq(technologyRoutingDto.getProductModelId() != null, TechnologyRouting::getProductModelId, technologyRoutingDto.getProductModelId())
                .eq(technologyRoutingDto.getBomId() != null, TechnologyRouting::getBomId, technologyRoutingDto.getBomId())
                .like(isNotBlank(technologyRoutingDto.getProcessRouteCode()), TechnologyRouting::getProcessRouteCode, technologyRoutingDto.getProcessRouteCode())
                .like(isNotBlank(technologyRoutingDto.getDescription()), TechnologyRouting::getDescription, technologyRoutingDto.getDescription())
                .orderByDesc(TechnologyRouting::getId);
        Page<TechnologyRouting> entityPage = new Page<>(page.getCurrent(), page.getSize(), page.getTotal());
        return this.page(entityPage, queryWrapper).convert(item -> BeanUtil.copyProperties(item, TechnologyRoutingVo.class));
        return technologyRoutingMapper.pageTechnologyRouting(page, technologyRoutingDto);
    }
    @Override
@@ -67,6 +60,7 @@
    public Long saveTechnologyRouting(TechnologyRouting technologyRouting) {
        String code = OrderUtils.countTodayByCreateTime(technologyRoutingMapper, "GYLX", "process_route_code");
        technologyRouting.setProcessRouteCode(code);
        technologyRoutingMapper.insert(technologyRouting);
        // 带入bom产品结构
        syncRoutingOperationsByBom(technologyRouting);
        return technologyRouting.getId();
@@ -111,7 +105,7 @@
                        .orderByAsc(TechnologyBomStructure::getId)
        );
        if (bomStructures.isEmpty()) {
            return;
            throw new ServiceException("bom产品结构为空!");
        }
        // 同一个 BOM 中可能重复引用相同工序,这里按首次出现顺序去重。
src/main/resources/application-dev.yml
@@ -74,7 +74,7 @@
    druid:
      # 主库数据源
      master:
        url: jdbc:mysql://localhost:3306/product-inventory-management-new?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        url: jdbc:mysql://localhost:3306/product-inventory-management-new-pro?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456
      # 从库数据源
src/main/resources/application.yml
@@ -1,4 +1,4 @@
# Spring配置
spring:
  profiles:
    active: dev-pro
    active: dev
src/main/resources/mapper/technology/TechnologyRoutingMapper.xml
@@ -2,19 +2,66 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.technology.mapper.TechnologyRoutingMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.ruoyi.technology.pojo.TechnologyRouting">
        <id column="id" property="id" />
        <result column="product_model_id" property="productModelId" />
        <result column="description" property="description" />
        <result column="create_time" property="createTime" />
        <result column="update_time" property="updateTime" />
        <result column="process_route_code" property="processRouteCode" />
        <result column="bom_id" property="bomId" />
        <result column="create_user" property="createUser" />
        <result column="dept_id" property="deptId" />
        <id column="id" property="id"/>
        <result column="product_model_id" property="productModelId"/>
        <result column="description" property="description"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
        <result column="process_route_code" property="processRouteCode"/>
        <result column="bom_id" property="bomId"/>
        <result column="create_user" property="createUser"/>
        <result column="dept_id" property="deptId"/>
    </resultMap>
    <select id="pageTechnologyRouting" resultType="com.ruoyi.technology.bean.vo.TechnologyRoutingVo">
        select tr.id,
               tr.product_model_id as productModelId,
               tr.description,
               tr.create_time as createTime,
               tr.update_time as updateTime,
               tr.process_route_code as processRouteCode,
               tr.bom_id as bomId,
               tr.create_user as createUser,
               tr.dept_id as deptId,
               p.product_name as productName,
               pm.model,
               tb.bom_no as bomNo
        from technology_routing tr
        left join product_model pm on tr.product_model_id = pm.id
        left join product p on pm.product_id = p.id
        left join technology_bom tb on tr.bom_id = tb.id
        <where>
            <if test="c != null">
                <if test="c.id != null">
                    and tr.id = #{c.id}
                </if>
                <if test="c.productModelId != null">
                    and tr.product_model_id = #{c.productModelId}
                </if>
                <if test="c.bomId != null">
                    and tr.bom_id = #{c.bomId}
                </if>
                <if test="c.processRouteCode != null and c.processRouteCode != ''">
                    and tr.process_route_code like concat('%', #{c.processRouteCode}, '%')
                </if>
                <if test="c.description != null and c.description != ''">
                    and tr.description like concat('%', #{c.description}, '%')
                </if>
                <if test="c.model != null and c.model != ''">
                    and pm.model like concat('%', #{c.model}, '%')
                </if>
                <if test="c.productName != null and c.productName != ''">
                    and p.product_name like concat('%', #{c.productName}, '%')
                </if>
                <if test="c.bomNo != null and c.bomNo != ''">
                    and tb.bom_no like concat('%', #{c.bomNo}, '%')
                </if>
            </if>
        </where>
        order by tr.id desc
    </select>
    <update id="updateProductModelByBomId">
        update technology_routing
        set product_model_id = #{productModelId}