|
|
@@ -0,0 +1,126 @@
|
|
|
+package com.zksy.WaterSupply.importing;
|
|
|
+
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.bean.copier.CopyOptions;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.zksy.base.domain.EquipmentBase;
|
|
|
+import com.zksy.base.domain.EquipmentType;
|
|
|
+import com.zksy.base.mapper.EquipmentTypeMapper;
|
|
|
+import com.zksy.base.service.EquipmentBaseService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.HashSet;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Objects;
|
|
|
+import java.util.Set;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/** 供水设备台账 Excel 导入服务;设备类型必须归属供水顶级类型。 */
|
|
|
+@Service
|
|
|
+@Transactional(rollbackFor = Exception.class)
|
|
|
+public class WaterDeviceLedgerImportService {
|
|
|
+ private static final String WATER_TOP_TYPE_NAME = "供水";
|
|
|
+
|
|
|
+ private final EquipmentBaseService equipmentBaseService;
|
|
|
+ private final EquipmentTypeMapper equipmentTypeMapper;
|
|
|
+
|
|
|
+ public WaterDeviceLedgerImportService(EquipmentBaseService equipmentBaseService,
|
|
|
+ EquipmentTypeMapper equipmentTypeMapper) {
|
|
|
+ this.equipmentBaseService = equipmentBaseService;
|
|
|
+ this.equipmentTypeMapper = equipmentTypeMapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String importDevices(List<WaterDeviceLedgerImportDTO> rows, boolean updateSupport) {
|
|
|
+ if (rows == null || rows.isEmpty()) {
|
|
|
+ throw new IllegalArgumentException("导入文件不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ Set<String> seenCodes = new HashSet<>();
|
|
|
+ int count = 0;
|
|
|
+ for (int index = 0; index < rows.size(); index++) {
|
|
|
+ WaterDeviceLedgerImportDTO row = rows.get(index);
|
|
|
+ String code = StrUtil.trimToNull(row.getEquipmentCode());
|
|
|
+ if (code == null) {
|
|
|
+ throw new IllegalArgumentException("导入失败:第 " + (index + 1) + " 行设备编码不能为空");
|
|
|
+ }
|
|
|
+ if (!seenCodes.add(code)) {
|
|
|
+ throw new IllegalArgumentException("导入失败:设备编码重复:" + code);
|
|
|
+ }
|
|
|
+
|
|
|
+ String typeName = StrUtil.trimToNull(row.getEquipmentTypeName());
|
|
|
+ if (typeName == null) {
|
|
|
+ throw new IllegalArgumentException("导入失败:设备编码 " + code + " 的设备类型不能为空");
|
|
|
+ }
|
|
|
+ String waterTypeId = resolveWaterTypeId(typeName);
|
|
|
+
|
|
|
+ EquipmentBase existing = equipmentBaseService.getOne(
|
|
|
+ Wrappers.<EquipmentBase>lambdaQuery().eq(EquipmentBase::getEquipmentCode, code), false);
|
|
|
+ boolean update = existing != null;
|
|
|
+ if (update && !updateSupport) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ EquipmentBase device = update ? existing : new EquipmentBase();
|
|
|
+ BeanUtil.copyProperties(row, device, CopyOptions.create().setIgnoreNullValue(true));
|
|
|
+ device.setEquipmentCode(code);
|
|
|
+ device.setEquipmentTypeId(waterTypeId);
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
+ if (update) {
|
|
|
+ device.setUpdateTime(now);
|
|
|
+ if (!equipmentBaseService.updateById(device)) {
|
|
|
+ throw new IllegalStateException("供水设备数据更新失败:" + code);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ device.setCreateTime(now);
|
|
|
+ device.setUpdateTime(now);
|
|
|
+ if (!equipmentBaseService.save(device)) {
|
|
|
+ throw new IllegalStateException("供水设备数据保存失败:" + code);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ return "成功导入 " + count + " 台供水设备";
|
|
|
+ }
|
|
|
+
|
|
|
+ private String resolveWaterTypeId(String typeName) {
|
|
|
+ List<EquipmentType> allTypes = equipmentTypeMapper.selectList(Wrappers.emptyWrapper());
|
|
|
+ Map<String, EquipmentType> typesById = allTypes.stream()
|
|
|
+ .collect(Collectors.toMap(EquipmentType::getId, Function.identity(), (left, right) -> left));
|
|
|
+ List<EquipmentType> matches = allTypes.stream()
|
|
|
+ .filter(type -> typeName.equals(type.getTypeName()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (matches.isEmpty()) {
|
|
|
+ throw new IllegalArgumentException("导入失败:设备类型不存在:" + typeName);
|
|
|
+ }
|
|
|
+
|
|
|
+ Set<String> waterTypeIds = matches.stream()
|
|
|
+ .filter(type -> isWaterType(type, typesById))
|
|
|
+ .map(EquipmentType::getId)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+ if (waterTypeIds.isEmpty()) {
|
|
|
+ throw new IllegalArgumentException("导入失败:设备类型不属于供水:" + typeName);
|
|
|
+ }
|
|
|
+ if (waterTypeIds.size() > 1) {
|
|
|
+ throw new IllegalArgumentException("导入失败:存在多个同名供水设备类型:" + typeName);
|
|
|
+ }
|
|
|
+ return waterTypeIds.iterator().next();
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean isWaterType(EquipmentType type, Map<String, EquipmentType> typesById) {
|
|
|
+ EquipmentType cursor = type;
|
|
|
+ int guard = 0;
|
|
|
+ while (cursor != null && guard++ <= typesById.size()) {
|
|
|
+ if (WATER_TOP_TYPE_NAME.equals(cursor.getTypeName())
|
|
|
+ && "0".equals(cursor.getParentTypeId())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ cursor = typesById.get(cursor.getParentTypeId());
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|