小鹏汽车智慧材料数据库系统项目总成数据同步

1、定时任务处理

2、提供了接口

小鹏方面提供的推送的数据表结构:

这几个表总数为100多万,经过条件筛选过滤后大概2万多条数据

小鹏的人给的示例图:

界面:

SQL:

sql 复制代码
-- 查询车型
select bmm.md_material_id, bmm.material_num, bmm.material_name, bmm.material_name_en
from bm_md_material bmm
where bmm.md_material_id in
      (SELECT bpa.master_part_id
       from (SELECT bpa.master_part_id, bpa.sub_part_id FROM bm_part_assembly bpa WHERE bpa.bom_type = 'PART') a
                INNER JOIN bm_part_assembly bpa on bpa.sub_part_id = a.master_part_id AND bpa.bom_type = 'EBOM');


# 根据车型材料id(md_material_id)总成主数据
select
bpa.bm_part_assembly_id as bmPartAssemblyId,
bpa.master_part_id as master_part_id,
bpa.sub_part_id as sub_part_id,
bpa.update_date as update_date,
bpa.quantity as useNumber,
bpa.weight_tag as weight,
bpa.dev_type as developStatus,
bpa.employee_id as bomResponsibleEngineer,
bpa.suggest_sourcing as procurementType,
bpa.bom_type,
bpa.change_id,
bpae.importance_level severity,
bpae.torque as tighteningTorque,
bpae.note as connectionsCodeZhDescribe,
bpae.vehicleproject as inheritedRemodeledModels,
bmm.material_num
from bm_part_assembly bpa
    left join bm_part_assembly_ext bpae on bpae.bm_part_assembly_ext_id = bpa.part_assembly_ext_id
    inner join bm_md_material bmm on bmm.md_material_id = bpa.sub_part_id
where (bpa.bom_type = 'EBOM' or bpa.bom_type = 'PART')
         and is_latest = 1 -- 最新版本
         and active_status = 'current' -- 生效状态
         and bpa.update_date > '2024-07-01'
#          and bpa.master_part_id = '98535' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821
         and bpa.master_part_id = '23821' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821
#          and bpa.master_part_id = '98532' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821
#          and bpa.master_part_id = '193598' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821
         and bpa.master_part_id = '64332' -- 车型 md_material_id 23821, 根据 sub_part_id  4010809DF1-00-03 64332   车型的  23821   如:根据子件id:64332查询,递归去查询,直到无下级
#          and bpa.sub_part_id like '64332'
         and material_num = '4010809DF1-00-03'
;

Mapper和Mapper.xml

java 复制代码
<!-- 总成主数据 -->
    <select id="syncDataByPage" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">
        select
        bpa.bm_part_assembly_id as syncPartAssemblyId,
        bpa.master_part_id as masterPartId, -- 父件id(父物料id)
        bpa.sub_part_id as subPartId, -- 子件id(子物料id)
        bpa.update_date as lastSyncUpdateDate,  -- 同步版本号
        bpa.quantity as useNumber, -- 用量
        bpa.weight_tag as weight, -- 重量
        bpa.dev_type as developStatus, -- 开发状态
        bpa.employee_id as employeeId, -- 员工id 根据这个员工id去员工表查询 责任工程师
        bpa.suggest_sourcing as procurementType, -- 采购类型
        bpa.bom_type as bomType,
        bpa.change_id as changeId,
        bpae.importance_level as severity, -- 重要度
        bpae.torque as tighteningTorque, -- 紧固力矩
        bpae.note as connectionsCodeZhDescribe, -- 连接点代码中文描述
        bpae.vehicleproject as inheritedRemodeledModels
        from bm_part_assembly bpa
            left join bm_part_assembly_ext bpae on bpae.bm_part_assembly_ext_id = bpa.part_assembly_ext_id
            inner join bm_md_material bmm on bmm.md_material_id = bpa.sub_part_id
        where (bpa.bom_type = 'EBOM' or bpa.bom_type = 'PART')
        and is_latest = 1 -- 最新版本
        and active_status = 'current'
        <if test="lastSyncUpdateDate!='' and lastSyncUpdateDate!=null">
            and bpa.update_date &gt; #{lastSyncUpdateDate}
        </if>
        <if test="masterPartId!='' and masterPartId!=null">
            and bpa.master_part_id = #{masterPartId}
        </if>
        ORDER BY bpa.update_date DESC
        LIMIT #{start}, #{pageSize}
    </select>

    <!-- 车型数据 -->
    <select id="selectCarData" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">
        select bmm.md_material_id as materielId,
               bmm.material_num as materielCode,
               bmm.material_name as materielCnName,
               bmm.material_name_en as materielEnName
        from bm_md_material bmm
        where bmm.md_material_id in (SELECT bpa.master_part_id from
            (SELECT  bpa.master_part_id, bpa.sub_part_id FROM bm_part_assembly bpa
                                                         WHERE bpa.bom_type  = 'PART') a
                INNER JOIN bm_part_assembly bpa on bpa.sub_part_id  = a.master_part_id AND bpa.bom_type  = 'EBOM')
    </select>

    <!-- BOM责任工程师 -->
    <select id="bomResponsibleEngineer" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">
        select bau.user_id userId,
               bau.user_name userName,
               bau.organization_id organizationId
        from bm_acct_user bau where user_id = #{employeeId};
    </select>

    <!-- 责任部门 -->
    <select id="bomResponsibleDepartment" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">
        select
            bao.id as orgId, bao.org_name as bomResponsibleDepartment, bao.org_name_en as orgNameEn
        from bm_acct_organization bao
        where id = #{organizationId}
    </select>

    <!--生效ECN编号-->
    <select id="selectEcnNumberEffect" resultType="string">
        select bmc.change_code AS ecnNumberEffect
        from bm_md_change bmc where md_change_id = #{changeId}
    </select>

    <!-- 查询已同步的最新的一条版本号 -->
    <select id="selectLastSyncUpdateDate" resultType="java.time.LocalDateTime">
        select DATE_FORMAT(last_sync_update_time, '%Y-%m-%d') as last_sync_update_time from bom_assembly_material_parts order by last_sync_update_time desc limit 1;
    </select>

    <!-- 根据物料id查询总成下级 -->
    <select id="selectByMaterialId" resultType="com.ruiyada.whole.domain.vo.BomAssemblyVo">
        select bmm.md_material_id as materielId,
               bmm.material_name as materielCnName,
               bmm.material_name_en as materielEnName,
               bmm.material_num as materielCode
        from  bm_md_material bmm
        where md_material_id in
        <foreach item="item" index="index" collection="materialIds" open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>

    <!-- 统计车型下的总成总数 -->
    <select id="assentlyCount" resultType="java.lang.Integer">
        select
            count(1)
        from bm_part_assembly bpa
                 left join bm_part_assembly_ext bpae on bpae.bm_part_assembly_ext_id = bpa.part_assembly_ext_id
                 inner join bm_md_material bmm on bmm.md_material_id = bpa.sub_part_id
        where (bpa.bom_type = 'EBOM' or bpa.bom_type = 'PART')
          and is_latest = 1 -- 最新版本
          and active_status = 'current' -- 生效状态
          and bpa.master_part_id = #{masterPartId}
    </select>
java 复制代码
@Mapper
public interface BomAssemblyMaterialPartsMapper extends BaseMapper<BomAssemblyMaterialParts> {


    List<BomAssembyMaterialPartsVO> ListById(@Param("bom_id") String bomId);

    /**
     * 查询已同步的最新的一条版本号
     */
    LocalDateTime selectLastSyncUpdateDate();

    /**
     * 分页查询总成主数据
     * @param start
     * @param pageSize
     * @param lastSyncUpdateDate
     * @return
     */
    List<BomAssemblyVo> syncDataByPage(@Param("start") int start, @Param("pageSize") int pageSize,
                                       @Param("lastSyncUpdateDate") String lastSyncUpdateDate,
                                       @Param("masterPartId") String masterPartId);

    /**
     * 车型数据
     * @return
     */
    List<BomAssemblyVo>  selectCarData();

    /**
     * BOM责任工程师
     * @return
     */
    BomAssemblyVo  bomResponsibleEngineer(@Param("employeeId") String employeeId);

    /**
     * 责任部门
     * @return
     */
    BomAssemblyVo  bomResponsibleDepartment(@Param("organizationId") String organizationId);

    /**
     * 生效ECN编号
     * @return
     */
    String  selectEcnNumberEffect(@Param("changeId") String changeId);

    /**
     * 根据物料id查询总成下级数据
     * @param materialIds
     * @return
     */
    List<BomAssemblyVo>  selectByMaterialId(@Param("materialIds") List<String> materialIds);

    /**
     * 统计车型下的总成总数
     * @param masterPartId
     * @return
     */
    Integer assentlyCount(@Param("masterPartId") String masterPartId);

}
java 复制代码
/**
 * <p>
 * BOM总成材料零件表 服务实现类
 * </p>
 *
 * @author 袁腾飞
 * @since 2024-10-14
 */
@Slf4j
@Service
public class BomAssemblyMaterialPartsServiceImpl extends ServiceImpl<BomAssemblyMaterialPartsMapper, BomAssemblyMaterialParts> implements BomAssemblyMaterialPartsService {

    @Autowired
    private BomAssemblyMaterialPartsMapper bomAssemblyMaterialPartsMapper;

    @Autowired
    private BomCategoryService bomCategoryService;
@Override
    public List<BomAssemblyMaterialParts> syncDataByPage(int pageSize) {
        // 获取上一次同步数据的更新时间
        LocalDateTime lastSyncUpdateDate = selectLastSyncUpdateDate();
        String formatLastSyncUpdateDate = lastSyncUpdateDate==null ? "" : lastSyncUpdateDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        // 组装数据
        List<BomAssemblyDto> bomAssemblyDtos = assemblingData(pageSize, formatLastSyncUpdateDate);
        // 把组装后的数据转换为BomAssemblyMaterialParts对象
        // bomAssemblyDtos在里面取出每个字段
        // bomAssemblyDtos的父级,给BomAssemblyMaterialParts对象父级设置parentId为0,id自动生成;里层的children的parentId为外层的id
        // 父级的parentId设为0
        List<BomAssemblyMaterialParts> partsList = convertToBomAssemblyMaterialParts(bomAssemblyDtos, "0");
        // partsList里面的children取出与父节点一起保存
        if (!partsList.isEmpty()) {
            bomAssemblyMaterialPartSaveBatch(partsList);
        }
        return partsList;
    }

    private void bomAssemblyMaterialPartSaveBatch(List<BomAssemblyMaterialParts> partsList) {
        // 收集所有需要保存的节点
        List<BomAssemblyMaterialParts> allNodes = collectAllNodes(partsList);
        // 批量插入所有节点

        // 判断allNodes里面的syncPartAssemblyId是否在数据库中存在,如果不存在,则插入,如果存在,则更新
        // List<String> list = allNodes.stream().map(BomAssemblyMaterialParts::getSyncPartAssemblyId).collect(Collectors.toList());
        allNodes.stream().map(item -> item).forEach(item -> {
            // 判断item是否在数据库中存在
            LambdaQueryWrapper<BomAssemblyMaterialParts> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BomAssemblyMaterialParts::getSyncPartAssemblyId, item.getSyncPartAssemblyId());
            BomAssemblyMaterialParts bomAssemblyMaterialParts = bomAssemblyMaterialPartsMapper.selectOne(queryWrapper);
            if (bomAssemblyMaterialParts == null) {
                // 不存在,则插入
                bomAssemblyMaterialPartsMapper.insert(item);
            } else {
                // 存在,则更新
                bomAssemblyMaterialPartsMapper.update(item, queryWrapper);
            }
        });
        // bomAssemblyMaterialPartsMapper.insertOrUpdate(allNodes);
    }

    private List<BomAssemblyMaterialParts> collectAllNodes(List<BomAssemblyMaterialParts> nodes) {
        List<BomAssemblyMaterialParts> allNodes = new ArrayList<>();
        for (BomAssemblyMaterialParts node : nodes) {
            allNodes.add(node);
            if (node.getChildren() != null && !node.getChildren().isEmpty()) {
                allNodes.addAll(collectAllNodes(node.getChildren()));
            }
        }
        return allNodes;
    }

    private List<BomAssemblyDto> convertToBomAssemblyDtos(List<BomAssemblyVo> bomAssemblyVos, String ecnNumberEffect) {
        if (bomAssemblyVos == null || bomAssemblyVos.isEmpty()) {
            return Collections.emptyList();
        }
        return bomAssemblyVos.stream()
                .map(vo -> {
                    BomAssemblyDto dto = new BomAssemblyDto();
                    BeanUtils.copyProperties(vo, dto);
                    dto.setChildren(convertToBomAssemblyDtos(vo.getChildren(), ecnNumberEffect));
                    return dto;
                })
                .collect(Collectors.toList());
    }

    private List<BomAssemblyMaterialParts> convertToBomAssemblyMaterialParts(List<BomAssemblyDto> dtos, String parentId) {
        List<BomAssemblyMaterialParts> collect = dtos.stream().map(dto -> {
            String id = "";

            // 判断item是否在数据库中存在
            LambdaQueryWrapper<BomAssemblyMaterialParts> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(BomAssemblyMaterialParts::getSyncPartAssemblyId, dto.getSyncPartAssemblyId());
            BomAssemblyMaterialParts bomAssemblyMaterialParts = bomAssemblyMaterialPartsMapper.selectOne(queryWrapper);
            if (bomAssemblyMaterialParts == null) {
                // 不存在,则就生成id
                id = IdUtil.simpleUUID();
            } else {
                // 存在,id 和 parentId 保持不变
                id = bomAssemblyMaterialParts.getId();
            }
            BomAssemblyMaterialParts parts = new BomAssemblyMaterialParts();
            String bomCategoryId = dto.getBomCategoryId();
            BeanUtils.copyProperties(dto, parts);
            parts.setId(id);
            parts.setParentId(parentId);
            parts.setBomId(bomCategoryId);
            List<BomAssemblyDto> children = dto.getChildren();
            if (!children.isEmpty()) {
                List<BomAssemblyMaterialParts> partsList = convertToBomAssemblyMaterialParts(dto.getChildren(), parts.getId());
                // 这里的partList里面的数据bomId没有给赋值,需要给bomId赋值:bomCategoryId
                // parts.setBomId(bomCategoryId);
                partsList.forEach(part -> part.setBomId(bomCategoryId));
                parts.setChildren(partsList);
            }
            parts.setLastSyncUpdateTime(dto.getLastSyncUpdateDate());
            parts.setCreateTime(LocalDateTime.now());
            parts.setUpdateTime(LocalDateTime.now());
            return parts;
        }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 组装数据
     *
     * @param pageSize          每页大小
     * @param lastSyncVersionNo 上一次同步的版本号
     * @return
     */
    private List<BomAssemblyDto> assemblingData(int pageSize, String lastSyncVersionNo) {
        // 先查询车型
        List<BomAssemblyVo> selectedCarData = selectCarData();
        // todo 暂时过滤一下数据,只查询一个车型
        // List<BomAssemblyVo> collect = selectedCarData.stream().filter(bomAssemblyVo -> bomAssemblyVo.getMaterielId().equals("23821")).collect(Collectors.toList());
        // 构建 md_material_id 到 BomAssemblyVo 的映射
        Map<String, BomAssemblyVo> carDataMap = selectedCarData.stream().collect(Collectors.toMap(BomAssemblyVo::getMaterielId, vo -> vo));
        // Map<String, BomAssemblyVo> carDataMap = collect.stream().collect(Collectors.toMap(BomAssemblyVo::getMaterielId, vo -> vo));
        /*
            步骤:
            1、先是查询出基础总成数据
            2、先查询车型,拿到车型的md_material_id
            3、根据拿到每个车型的md_material_id 查询 bm_part_assembly表的master_part_id,就得到了得到sub_part_id
            4、得到sub_part_id 查询bm_md_material表,得到了下级总成,循环类推,递归
            5、查询的下级放在BomAssemblyVo里面的children集合里面
            6、拼装数据,把查询生效ECN编号、
            数据量很大,100多万数据
            能不能用stream流、递归、树形结构
            select bmm.md_material_id as materialId, bmm.material_name materielName, bmm.material_num from  bm_md_material bmm
            where md_material_id in #{materialId}
         */

        List<BomAssemblyDto> result = new ArrayList<>();
        // 用carDataMap key查询数据
        carDataMap.forEach((masterPartId, value) -> {
            // 获取总数
            Integer totalCount = assentlyCount(masterPartId);
            double totalPage = Math.ceil((double) totalCount / pageSize);

            // 分页处理
            for (int currentPage = 0; currentPage < totalPage; currentPage++) {
                int offset = currentPage * pageSize;
                // 根据查询的车型的id的这个key查询获取sub_part_id,在这里bomAssemblyVos获取sub_part_id值,获得sub_part_id值后再次用bomAssemblyMaterialPartsMapper.syncDataByPage查询,把查询到的sub_part_id值传入到key的位置,直到查询不到数据
                // 第一次查询的是父节点,递归出来的后面的查询是子节点放在children里面
                List<BomAssemblyVo> bomAssemblyVos = bomAssemblyMaterialPartsMapper.syncDataByPage(offset, pageSize, lastSyncVersionNo, masterPartId);
                // todo 临时测试用
                // List<BomAssemblyVo> bomAssemblyVos = bomAssemblyVoList.stream().filter(bomAssemblyVo -> bomAssemblyVo.getSubPartId().equals("64332")).collect(Collectors.toList());
                // List<BomAssemblyVo> bomAssemblyVos = bomAssemblyVoList.stream().filter(bomAssemblyVo -> bomAssemblyVo.getSubPartId().equals("98535")).collect(Collectors.toList());
                // List<BomAssemblyVo> bomAssemblyVos = bomAssemblyVoList.stream().filter(bomAssemblyVo -> bomAssemblyVo.getSubPartId().equals("64332")).collect(Collectors.toList());

                // BOM分类车型数据
                LambdaQueryWrapper<BomCategory> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(BomCategory::getIsCar, 1);
                List<BomCategory> bomCategories = bomCategoryService.list(queryWrapper);
                // 车型名称
                String carType = value.getMaterielCnName();
                // 在这里获取所有的分类名称(categoryName)和id,如果categoryName与carType比较,
                // 如果匹配上就把bomCategories的id给BomAssemblyVo对象的bomCategoryId并保存数据,否则就不保存数据
                // 查找匹配的车型分类
                Optional<BomCategory> categoryOptional = bomCategories.stream()
                        .filter(cat -> cat.getCategoryName().equals(carType))
                        .findFirst();

                if (categoryOptional.isPresent()) {
                    String categoryId = categoryOptional.get().getId();
                    // 设置categoryId到每个BomAssemblyVo对象
                    setCategoryIdRecursively(bomAssemblyVos, categoryId);
                } else {
                    // 如果没有匹配的分类,则跳过这些数据
                    return;
                }

                // 补充 materialName 和 materialNum 对于父节点
                Set<String> parentIds = bomAssemblyVos.stream()
                        .map(BomAssemblyVo::getSubPartId)
                        .filter(Objects::nonNull)
                        .collect(Collectors.toSet());

                if (!parentIds.isEmpty()) {
                    List<BomAssemblyVo> parentDetails = selectByMaterialIds(new ArrayList<>(parentIds));
                    Map<String, BomAssemblyVo> parentDetailMap = parentDetails.stream()
                            .collect(Collectors.toMap(BomAssemblyVo::getMaterielId, vo -> vo));

                    for (BomAssemblyVo assembly : bomAssemblyVos) {
                        BomAssemblyVo detail = parentDetailMap.get(assembly.getSubPartId());
                        if (detail != null) {
                            assembly.setMaterielCnName(detail.getMaterielCnName());
                            assembly.setMaterielEnName(detail.getMaterielEnName());
                            assembly.setMaterielCode(detail.getMaterielCode());
                            assembly.setPartCode(detail.getPartCode());
                            assembly.setCarType(detail.getCarType());
                            assembly.setEcnNumberEffect(detail.getEcnNumberEffect());
                            assembly.setPartNumber(detail.getPartNumber());
                            assembly.setBomType(detail.getBomType());
                        }
                    }
                }

                // 再组装数据
                for (BomAssemblyVo assembly : bomAssemblyVos) {
                    buildTree(assembly, offset, pageSize, lastSyncVersionNo);
                    String changeId = assembly.getChangeId();
                    String changeCode = selectEcnNumberEffect(changeId);

                    String employeeId = assembly.getEmployeeId();

                    String userName = "";
                    String organizationId = "";
                    if (StringUtils.isNotBlank(employeeId)) {
                        // BOM责任工程师
                        BomAssemblyVo bomAssemblyVo = bomResponsibleEngineer(employeeId);
                        if (bomAssemblyVo != null) {
                            userName = bomAssemblyVo.getUserName();
                            organizationId = bomAssemblyVo.getOrganizationId();
                        }
                    }

                    String bomResponsibleDepartment = "";
                    if (StringUtils.isNotBlank(organizationId)) {
                        // BOM责任部门
                        BomAssemblyVo assemblyVo = bomResponsibleDepartment(organizationId);
                        if (assemblyVo != null) {
                            bomResponsibleDepartment = assemblyVo.getBomResponsibleDepartment();
                        }
                    }

                    assembly.setUserName(userName);
                    assembly.setBomResponsibleDepartment(bomResponsibleDepartment);

                    BomAssemblyDto bomAssemblyDto = new BomAssemblyDto();
                    BeanUtils.copyProperties(assembly, bomAssemblyDto);
                    bomAssemblyDto.setChildren(convertToBomAssemblyDtos(assembly.getChildren(), changeCode));
                    result.add(bomAssemblyDto);
                }
            }
        });

        log.info("result:::::::::" + result);
        // 拼装数据,包括生效ECN编号等信息
        // convertToBomAssemblyMaterialParts(result);
        return result;
    }

    private void setCategoryIdRecursively(List<BomAssemblyVo> bomAssemblyVos, String categoryId) {
        for (BomAssemblyVo assembly : bomAssemblyVos) {
            assembly.setBomCategoryId(categoryId);
            if (assembly.getChildren() != null && !assembly.getChildren().isEmpty()) {
                setCategoryIdRecursively(assembly.getChildren(), categoryId);
            }
        }
    }

    private void buildTree(BomAssemblyVo parent, int pageNo, int pageSize, String lastSyncVersionNo) {
        if (parent == null || parent.getSubPartId() == null) {
            return;
        }

        List<BomAssemblyVo> children = bomAssemblyMaterialPartsMapper.syncDataByPage(pageNo, pageSize, lastSyncVersionNo, parent.getSubPartId());

        // 补充 materialName 和 materialNum
        Set<String> subPartIds = children.stream()
                .map(BomAssemblyVo::getSubPartId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        if (!subPartIds.isEmpty()) {
            List<BomAssemblyVo> materialDetails = selectByMaterialIds(new ArrayList<>(subPartIds));
            Map<String, BomAssemblyVo> materialDetailMap = materialDetails.stream()
                    .collect(Collectors.toMap(BomAssemblyVo::getMaterielId, vo -> vo));

            for (BomAssemblyVo child : children) {
                BomAssemblyVo detail = materialDetailMap.get(child.getSubPartId());
                if (detail != null) {
                    child.setMaterielCnName(detail.getMaterielCnName());
                    child.setMaterielEnName(detail.getMaterielEnName());
                    child.setMaterielCode(detail.getMaterielCode());
                    child.setPartCode(detail.getPartCode());
                    child.setCarType(detail.getCarType());
                    child.setEcnNumberEffect(detail.getEcnNumberEffect());
                    child.setPartNumber(detail.getPartNumber());
                    child.setBomType(detail.getBomType());
                }
            }
        }

        parent.setChildren(children);
        for (BomAssemblyVo child : children) {
            buildTree(child, pageNo, pageSize, lastSyncVersionNo);
        }
    }

    /**
     * 查询车型
     *
     * @return
     */
    private List<BomAssemblyVo> selectCarData() {
        List<BomAssemblyVo> list = bomAssemblyMaterialPartsMapper.selectCarData();
        return list;
    }

    /**
     * 查询生效ECN编号
     *
     * @return
     */
    private String selectEcnNumberEffect(String changeId) {
        return bomAssemblyMaterialPartsMapper.selectEcnNumberEffect(changeId);
    }

    /**
     * 根据物料id查询总成下级数据
     *
     * @param materialIds
     * @return
     */
    private List<BomAssemblyVo> selectByMaterialIds(List<String> materialIds) {
        /*
            这个sql是这样的:select bmm.md_material_id as materialId, bmm.material_name materielName, bmm.material_num from  bm_md_material bmm
            where md_material_id in #{materialIds}
         */
        if (materialIds == null || materialIds.isEmpty()) {
            return Collections.emptyList();
        }
        return bomAssemblyMaterialPartsMapper.selectByMaterialId(materialIds);
    }

    /**
     * BOM责任工程师
     *
     * @return
     */
    private BomAssemblyVo bomResponsibleEngineer(String employeeId) {
        return bomAssemblyMaterialPartsMapper.bomResponsibleEngineer(employeeId);
    }

    /**
     * BOM责任部门
     *
     * @param organizationId
     * @return
     */
    private BomAssemblyVo bomResponsibleDepartment(String organizationId) {
        return bomAssemblyMaterialPartsMapper.bomResponsibleDepartment(organizationId);
    }

    /**
     * 同步版本号
     *
     * @return
     */
    private LocalDateTime selectLastSyncUpdateDate() {
        LocalDateTime lastSyncUpdateDate = bomAssemblyMaterialPartsMapper.selectLastSyncUpdateDate();
        log.info("最新版本号:{}", lastSyncUpdateDate);
        return lastSyncUpdateDate;
    }

    @Override
    public Integer assentlyCount(String masterPartId) {
        Integer assentlyCount = bomAssemblyMaterialPartsMapper.assentlyCount(masterPartId);
        return assentlyCount == null ? 0 : assentlyCount;
    }

}
java 复制代码
/**
 * <p>
 * BOM总成材料零件表 服务类
 * </p>
 *
 * @author 袁腾飞
 * @since 2024-10-14
 */
public interface BomAssemblyMaterialPartsService extends IService<BomAssemblyMaterialParts> {

    IPage<BomAssemblyMaterialParts> pageListCondition(PagingQuery pagingQuery, BomAssemblyQuery queryParam);

    List<BomAssembyMaterialPartsVO> ListById(String bomId);

    List<BomAssemblyMaterialParts> listCondition(PagingQuery pagingQuery, BomAssemblyQuery queryParam);

    List<BomAssemblyMaterialParts> syncDataByPage(int pageSize);

    Integer assentlyCount(String masterPartId);
}

定时任务层

java 复制代码
/**
 * 同步总成数据
 */
@Slf4j
@Lazy(value = false)
@Component
// @PropertySource(value = "classpath:jobTask.properties",encoding = "UTF-8")
public class SyncWholeData {

    @Autowired
    private BomAssemblyMaterialPartsService bomAssemblyMaterialPartsService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Value("${pageSize}")
    private Integer pageSize;

    /**
     * 同步总成数据
     */
    @Transactional(rollbackFor = Exception.class)
    @Async
    @Scheduled(cron = "${inactiveaccountCron}")
    public void syncWhole1() {
        String lockKey = "lock:sync:whole:";
        boolean isLocked = tryLock(lockKey);
        try {
            if (isLocked) {
                // 成功获取锁,执行同步逻辑
                bomAssemblyMaterialPartsService.syncDataByPage(pageSize);
            }
        } finally {
            unlock(lockKey);
        }
    }

    /**
     * 尝试获取锁
     *
     * @param key
     * @return
     */
    private boolean tryLock(String key) {
        // setIfAbsent 如果存在
        Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent(key, "1", 2, TimeUnit.HOURS);
        return BooleanUtil.isTrue(flag);
    }

    /**
     * 释放锁
     *
     * @param key
     */
    private void unlock(String key) {
        stringRedisTemplate.delete(key);
    }

}
相关推荐
亚远景aspice2 小时前
ISO 21434标准:汽车网络安全管理的利与弊
网络·web安全·汽车
龙智DevSecOps解决方案2 小时前
汽车软件开发中的ASPICE合规挑战与Jama Connect解决方案
汽车·需求管理·jamaconnect·汽车aspice·汽车软件开发
国际展会招商12 小时前
2025杭州国际智能网联新能源汽车展览会
汽车
虹科Pico汽车示波器12 小时前
汽车免拆诊断案例 | 2012款路虎揽胜运动版柴油车加速无力
汽车·虹科pico汽车示波器·汽修·发动机故障·路虎揽胜·汽车失火·喷油器
哔哥哔特商务网1 天前
一文探究48V新型电气架构下的汽车连接器
架构·汽车
电子科技圈1 天前
IAR与鸿轩科技共同推进汽车未来
科技·嵌入式硬件·mcu·汽车
思尔芯S2C2 天前
面向未来的智能视觉参考设计与汽车架构,思尔芯提供基于Arm技术的创新方案
arm开发·架构·汽车·iot·fpga原型验证·prototyping·智慧视觉
IT生活课堂2 天前
Android智能座舱,视频播放场景,通过多指滑屏退回桌面,闪屏问题的另一种解法
android·智能手机·汽车
EasyCVR2 天前
ISUP协议视频平台EasyCVR私有化视频平台新能源汽车充电停车管理方案的创新与实践
大数据·网络·汽车·音视频·h.265·h.264