|
@@ -1,19 +1,25 @@
|
|
|
package cn.iocoder.yudao.module.pms.service.iotbom;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.lang.Snowflake;
|
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomListReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomPageReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.controller.admin.iotbom.vo.IotBomSaveReqVO;
|
|
|
import cn.iocoder.yudao.module.pms.dal.dataobject.iotbom.IotBomDO;
|
|
|
+import cn.iocoder.yudao.module.pms.dal.dataobject.iotdevicebom.IotDeviceBomDO;
|
|
|
+import cn.iocoder.yudao.module.pms.dal.mysql.IotDeviceMapper;
|
|
|
import cn.iocoder.yudao.module.pms.dal.mysql.iotbom.IotBomMapper;
|
|
|
+import cn.iocoder.yudao.module.pms.dal.mysql.iotdevicebom.IotDeviceBomMapper;
|
|
|
import cn.iocoder.yudao.module.pms.service.IotProductClassifyService;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
+import java.time.LocalDateTime;
|
|
|
import java.util.*;
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
@@ -32,6 +38,10 @@ public class IotBomServiceImpl implements IotBomService {
|
|
|
private IotBomMapper iotBomMapper;
|
|
|
@Resource
|
|
|
private IotProductClassifyService iotProductClassifyService;
|
|
|
+ @Resource
|
|
|
+ private IotDeviceBomMapper iotDeviceBomMapper;
|
|
|
+ @Resource
|
|
|
+ private IotDeviceMapper iotDeviceMapper;
|
|
|
|
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@@ -110,4 +120,92 @@ public class IotBomServiceImpl implements IotBomService {
|
|
|
return iotBomMapper.getListByDeviceCategoryIds(deviceCategoryIds);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public void copyBomByCategory(Long deviceCategoryId, Long deviceId) {
|
|
|
+ // 1. 查询源数据(按创建时间排序保证基础顺序)
|
|
|
+ List<IotBomDO> sourceBoms = iotBomMapper.selectList(new LambdaQueryWrapper<IotBomDO>()
|
|
|
+ .eq(IotBomDO::getDeviceCategoryId, deviceCategoryId)
|
|
|
+ .eq(IotBomDO::getDeleted, false)
|
|
|
+ .orderByAsc(IotBomDO::getCreateTime));
|
|
|
+ if (CollUtil.isEmpty(sourceBoms)) {
|
|
|
+ throw exception(IOT_BOM_NOT_EXISTS);
|
|
|
+ }
|
|
|
+ // 2. 构建树形结构并获取层级顺序
|
|
|
+ List<IotBomDO> orderedBoms = buildHierarchyOrder(sourceBoms);
|
|
|
+ // 3. 生成ID映射关系
|
|
|
+ Map<Long, Long> idMapping = new LinkedHashMap<>();
|
|
|
+ orderedBoms.forEach(bom -> idMapping.put(bom.getId(), IdGenerator.nextId()));
|
|
|
+ // 4. 转换目标对象
|
|
|
+ List<IotDeviceBomDO> targetBoms = convertBoms(orderedBoms, idMapping, deviceId);
|
|
|
+ // 批量插入设备BOM
|
|
|
+ iotDeviceBomMapper.insertBatch(targetBoms);
|
|
|
+ // 拷贝BOM成功后 设置设备 bom_sync_status 字段 为 1已同步
|
|
|
+ iotDeviceMapper.updateBomSyncStatus(deviceId);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 转换目标对象
|
|
|
+ * @param orderedBoms
|
|
|
+ * @param idMapping
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<IotDeviceBomDO> convertBoms(List<IotBomDO> orderedBoms, Map<Long, Long> idMapping, Long deviceId) {
|
|
|
+ List<IotDeviceBomDO> targetBoms = new ArrayList<>();
|
|
|
+ for (IotBomDO source : orderedBoms) {
|
|
|
+ IotDeviceBomDO target = new IotDeviceBomDO();
|
|
|
+
|
|
|
+ // 基础字段拷贝
|
|
|
+ BeanUtils.copyProperties(source, target);
|
|
|
+
|
|
|
+ // ID映射处理
|
|
|
+ target.setId(idMapping.get(source.getId()));
|
|
|
+ target.setParentId(idMapping.getOrDefault(source.getParentId(), 0L));
|
|
|
+
|
|
|
+ // 特殊字段处理
|
|
|
+ target.setDeviceId(deviceId);
|
|
|
+ target.setCreateTime(LocalDateTime.now());
|
|
|
+ target.setUpdateTime(LocalDateTime.now());
|
|
|
+
|
|
|
+ targetBoms.add(target);
|
|
|
+ }
|
|
|
+ return targetBoms;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 拷贝设备分类bom时构建层级结构
|
|
|
+ * @param sourceBoms
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<IotBomDO> buildHierarchyOrder(List<IotBomDO> sourceBoms) {
|
|
|
+ // 构建父子关系映射
|
|
|
+ Map<Long, List<IotBomDO>> parentChildMap = new HashMap<>();
|
|
|
+ Map<Long, IotBomDO> bomMap = new HashMap<>();
|
|
|
+ for (IotBomDO bom : sourceBoms) {
|
|
|
+ bomMap.put(bom.getId(), bom);
|
|
|
+ parentChildMap.computeIfAbsent(bom.getParentId(), k -> new ArrayList<>()).add(bom);
|
|
|
+ }
|
|
|
+ // 层级遍历排序
|
|
|
+ List<IotBomDO> orderedList = new ArrayList<>();
|
|
|
+ Queue<IotBomDO> queue = new LinkedList<>(parentChildMap.getOrDefault(0L, Collections.emptyList()));
|
|
|
+ while (!queue.isEmpty()) {
|
|
|
+ IotBomDO current = queue.poll();
|
|
|
+ orderedList.add(current);
|
|
|
+
|
|
|
+ List<IotBomDO> children = parentChildMap.get(current.getId());
|
|
|
+ if (children != null) {
|
|
|
+ queue.addAll(children);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return orderedList;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分布式ID生成器
|
|
|
+ private static class IdGenerator {
|
|
|
+ private static final Snowflake SNOWFLAKE = new Snowflake(1, 1);
|
|
|
+ public static long nextId() {
|
|
|
+ return SNOWFLAKE.nextId();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|