package com.ruoyi.system.service.impl; import java.util.ArrayList; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.domain.TBatteryGroup; import com.ruoyi.system.domain.TBatteryGroupBattery; import com.ruoyi.system.domain.TBatteryGroupRelationField; import com.ruoyi.system.mapper.TBatteryGroupMapper; import com.ruoyi.system.service.ITBatteryGroupService; /** 电池组管理服务实现。 */ @Service public class TBatteryGroupServiceImpl implements ITBatteryGroupService { private static final String ENABLED = "0"; @Autowired private TBatteryGroupMapper batteryGroupMapper; /** 按查询条件返回未删除的电池组列表。 */ @Override public List selectBatteryGroupList(TBatteryGroup group) { return batteryGroupMapper.selectBatteryGroupList(group); } /** 返回已有电池组的创建人选项。 */ @Override public List> selectBatteryGroupCreatorOptions() { return batteryGroupMapper.selectBatteryGroupCreatorOptions(); } /** 返回电池组及其电池号、模板字段和值。 */ @Override public TBatteryGroup selectBatteryGroupById(Long groupId) { TBatteryGroup group = batteryGroupMapper.selectBatteryGroupById(groupId); if (group == null) { throw new ServiceException("电池组不存在"); } group.setBatteries(batteryGroupMapper.selectBatteries(groupId)); group.setTemplateFields(batteryGroupMapper.selectRelationFields(groupId)); return group; } /** 新增电池组并原子写入电池号和可选模板字段值。 */ @Override @Transactional(rollbackFor = Exception.class) public int insertBatteryGroup(TBatteryGroup group) { if (StringUtils.isEmpty(group.getStatus())) { group.setStatus(ENABLED); } validate(group, false); group.setGroupName(StringUtils.trim(group.getGroupName())); group.setCreateTime(new Date()); int rows = batteryGroupMapper.insertBatteryGroup(group); replaceRelations(group); return rows; } /** 更新电池组并原子替换电池号和可选模板字段值。 */ @Override @Transactional(rollbackFor = Exception.class) public int updateBatteryGroup(TBatteryGroup group) { if (group == null || group.getGroupId() == null) { throw new ServiceException("电池组ID不能为空"); } TBatteryGroup current = batteryGroupMapper.selectBatteryGroupById(group.getGroupId()); if (current == null) { throw new ServiceException("电池组不存在"); } if (StringUtils.isEmpty(group.getStatus())) { group.setStatus(current.getStatus()); } validateStatusChange(group, current.getStatus()); validate(group, true); group.setGroupName(StringUtils.trim(group.getGroupName())); group.setUpdateTime(new Date()); int rows = batteryGroupMapper.updateBatteryGroup(group); if (rows == 0) { throw new ServiceException("电池组不存在或已删除"); } replaceRelations(group); return rows; } /** 启用或禁用电池组,存在进行中测试时禁止禁用。 */ @Override @Transactional(rollbackFor = Exception.class) public int updateBatteryGroupStatus(TBatteryGroup group) { if (group == null || group.getGroupId() == null || StringUtils.isEmpty(group.getStatus())) { throw new ServiceException("电池组ID和目标状态不能为空"); } if (!ENABLED.equals(group.getStatus()) && !"1".equals(group.getStatus())) { throw new ServiceException("电池组状态不正确"); } if ("1".equals(group.getStatus()) && batteryGroupMapper.countTestingByGroupId(group.getGroupId()) > 0) { throw new ServiceException("检测中的电池组不能禁用"); } return batteryGroupMapper.updateBatteryGroupStatus(group); } /** 逻辑删除电池组及关系,存在进行中测试时拒绝删除。 */ @Override @Transactional(rollbackFor = Exception.class) public int deleteBatteryGroupByIds(Long[] groupIds, String updateBy) { if (groupIds == null || groupIds.length == 0) { throw new ServiceException("电池组ID不能为空"); } int rows = 0; for (Long groupId : groupIds) { if (groupId == null) { continue; } if (batteryGroupMapper.countTestingByGroupId(groupId) > 0) { throw new ServiceException("检测中的电池组不能删除"); } rows += batteryGroupMapper.deleteBatteryGroup(groupId, updateBy); batteryGroupMapper.deleteBatteries(groupId); batteryGroupMapper.deleteRelationFields(groupId); } return rows; } private void validate(TBatteryGroup group, boolean update) { if (group == null) { throw new ServiceException("电池组信息不能为空"); } if (update && group.getGroupId() == null) { throw new ServiceException("电池组ID不能为空"); } if (StringUtils.isEmpty(StringUtils.trim(group.getGroupName()))) { throw new ServiceException("电池组名称不能为空"); } if (StringUtils.isEmpty(StringUtils.trim(group.getModel()))) { throw new ServiceException("电池组型号不能为空"); } if (!ENABLED.equals(group.getStatus()) && !"1".equals(group.getStatus())) { throw new ServiceException("电池组状态不正确"); } TBatteryGroup existing = batteryGroupMapper.selectBatteryGroupByName(StringUtils.trim(group.getGroupName())); if (existing != null && (group.getGroupId() == null || !group.getGroupId().equals(existing.getGroupId()))) { throw new ServiceException("电池组名称已存在"); } if (group.getBatteryNos() == null || group.getBatteryNos().isEmpty()) { throw new ServiceException("电池号不能为空"); } Set uniqueNos = new HashSet<>(); for (String batteryNo : group.getBatteryNos()) { String normalized = StringUtils.trim(batteryNo); if (StringUtils.isEmpty(normalized) || !uniqueNos.add(normalized)) { throw new ServiceException("电池号不能重复或为空"); } TBatteryGroupBattery existingBattery = batteryGroupMapper.selectBatteryByNo(normalized, group.getGroupId()); if (existingBattery != null && (group.getGroupId() == null || !group.getGroupId().equals(existingBattery.getGroupId()))) { throw new ServiceException("电池号已被其他电池组使用"); } } if (group.getTemplateId() == null) { if (group.getTemplateFieldRelations() != null && !group.getTemplateFieldRelations().isEmpty()) { throw new ServiceException("未选择模板时不能配置模板字段"); } return; } if (batteryGroupMapper.selectTemplate(group.getTemplateId()) == null) { throw new ServiceException("模板不存在"); } List fieldIds = new ArrayList<>(); Map fieldTypes = new HashMap<>(); if (group.getTemplateFieldRelations() != null) { for (TBatteryGroupRelationField relation : group.getTemplateFieldRelations()) { if (relation == null || relation.getBatteryGroupFieldId() == null || !fieldIds.add(relation.getBatteryGroupFieldId())) { throw new ServiceException("模板字段关系不正确"); } if (relation.getFieldValue() != null && relation.getFieldValue().length() > 500) { throw new ServiceException("模板字段值长度不能超过500个字符"); } } } List templateFieldIds = batteryGroupMapper.selectTemplateFieldIds(group.getTemplateId()); if (templateFieldIds == null || templateFieldIds.isEmpty()) { throw new ServiceException("模板未配置有效字段"); } if (fieldIds.isEmpty()) { fieldIds.addAll(templateFieldIds); } if (!new HashSet<>(templateFieldIds).equals(new HashSet<>(fieldIds))) { throw new ServiceException("电池组字段必须与模板字段一致"); } List validFields = batteryGroupMapper.selectValidTemplateFields(group.getTemplateId(), fieldIds); if (validFields == null || validFields.size() != fieldIds.size()) { throw new ServiceException("电池组字段不属于指定模板"); } for (TBatteryGroupRelationField field : validFields) { fieldTypes.put(field.getBatteryGroupFieldId(), field.getFieldType()); } if (group.getTemplateFieldRelations() != null) { for (TBatteryGroupRelationField relation : group.getTemplateFieldRelations()) { relation.setFieldValue(trimToNull(relation.getFieldValue())); validateFieldValue(fieldTypes.get(relation.getBatteryGroupFieldId()), relation.getFieldValue()); } } } private void replaceRelations(TBatteryGroup group) { batteryGroupMapper.deleteBatteries(group.getGroupId()); batteryGroupMapper.deleteRelationFields(group.getGroupId()); List batteries = new ArrayList<>(); for (int i = 0; i < group.getBatteryNos().size(); i++) { TBatteryGroupBattery item = new TBatteryGroupBattery(); item.setGroupId(group.getGroupId()); item.setBatteryNo(StringUtils.trim(group.getBatteryNos().get(i))); item.setSortOrder(i); item.setDelFlag("0"); batteries.add(item); } batteryGroupMapper.batchInsertBatteries(batteries); if (group.getTemplateId() == null) { return; } List relations = group.getTemplateFieldRelations(); if (relations == null || relations.isEmpty()) { relations = new ArrayList<>(); for (Long fieldId : batteryGroupMapper.selectTemplateFieldIds(group.getTemplateId())) { TBatteryGroupRelationField relation = new TBatteryGroupRelationField(); relation.setBatteryGroupFieldId(fieldId); relations.add(relation); } } for (TBatteryGroupRelationField relation : relations) { relation.setGroupId(group.getGroupId()); relation.setTemplateId(group.getTemplateId()); relation.setDelFlag("0"); } batteryGroupMapper.batchInsertRelationFields(relations); } /** 按字段定义校验业务值,空值表示该字段暂未填写。 */ private void validateFieldValue(String fieldType, String value) { if (value == null || fieldType == null) return; try { if ("number".equals(fieldType)) { new BigDecimal(value); } else if ("time".equals(fieldType)) { try { LocalDate.parse(value); } catch (DateTimeParseException exception) { try { LocalDateTime.parse(value, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } catch (DateTimeParseException nested) { LocalDateTime.parse(value); } } } } catch (NumberFormatException | DateTimeParseException exception) { throw new ServiceException("模板字段值格式不正确"); } } private void validateStatusChange(TBatteryGroup group, String currentStatus) { if ("1".equals(group.getStatus()) && !"1".equals(currentStatus) && batteryGroupMapper.countTestingByGroupId(group.getGroupId()) > 0) { throw new ServiceException("测试中的电池组不能禁用"); } } private String trimToNull(String value) { String trimmed = StringUtils.trim(value); return StringUtils.isEmpty(trimmed) ? null : trimmed; } }