| | |
| | | import com.ard.sample.annotation.service.IAnnotationDirectoryService; |
| | | import com.ard.sample.annotation.service.IAnnotationService; |
| | | import com.ard.sample.annotation.util.JsonSerializeUtil; |
| | | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ard.sample.annotation.mapper.AnnotationDirectoryMapper; |
| | | import lombok.RequiredArgsConstructor; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | |
| | | return updateById(entity); |
| | | } |
| | | |
| | | /** |
| | | * 新增:修改目录显示状态 |
| | | */ |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) // 事务控制:目录和标注修改要么都成功,要么都回滚 |
| | | public boolean updateDirectoryVisible(String id, Boolean isTrue) { |
| | | // 1. 参数校验 |
| | | if (id == null || id.isEmpty() || isTrue == null) { |
| | | log.error("修改目录显示状态失败:参数非法,id={}, isTrue={}", id, isTrue); |
| | | return false; |
| | | } |
| | | // 2. 修改目录自身的可见状态 |
| | | AnnotationDirectoryEntity directoryEntity = new AnnotationDirectoryEntity(); |
| | | directoryEntity.setId(id); |
| | | directoryEntity.setIsTrue(isTrue); |
| | | boolean dirUpdateResult = updateById(directoryEntity); |
| | | if (!dirUpdateResult) { |
| | | log.error("修改目录{}显示状态失败", id); |
| | | return false; |
| | | } |
| | | // 3. 批量修改该目录下所有标注的可见状态(核心新增逻辑) |
| | | LambdaUpdateWrapper<AnnotationEntity> annotationUpdateWrapper = new LambdaUpdateWrapper<>(); |
| | | annotationUpdateWrapper.eq(AnnotationEntity::getDirectoryId, id) // 匹配目录ID |
| | | .set(AnnotationEntity::getIsTrue, isTrue); // 同步设置相同的可见状态 |
| | | boolean annotationUpdateResult = annotationService.update(annotationUpdateWrapper); |
| | | // 简化日志:只记录操作结果 |
| | | log.info("目录{}显示状态修改成功(状态:{}),下属标注状态同步修改结果:{}", |
| | | id, isTrue, annotationUpdateResult); |
| | | |
| | | // 4. 返回最终结果(目录修改成功且标注修改成功,或标注无数据时返回目录修改结果) |
| | | return dirUpdateResult; |
| | | } |
| | | |
| | | @Override |
| | | @Transactional(rollbackFor = Exception.class) // 事务保证级联删除 |
| | | public boolean deleteDirectory(Integer id) { |
| | | if (id == null) { |
| | | public boolean deleteDirectory(String id) { |
| | | if (id == null || id.isEmpty()) { |
| | | log.error("删除目录失败:ID为空"); |
| | | return false; |
| | | } |
| | | // ====================== 关键:不允许删除默认文件夹 ====================== |
| | | if ("default_directory_00000001".equals(id)) { |
| | | log.error("删除目录失败:默认文件夹不允许删除"); |
| | | throw new RuntimeException("默认文件夹不允许删除"); |
| | | } |
| | | // 1. 删除目录下所有标记 |
| | | annotationMapper.deleteByMap(Map.of("directory_id", id)); |
| | |
| | | return result; |
| | | } |
| | | |
| | | // /** |
| | | // * 查询全部目录(含下属标注数据) |
| | | // * 修复点:替换自定义Mapper方法为MyBatis-Plus通用查询,避免SQL映射缺失问题 |
| | | // */ |
| | | // @Override |
| | | // public List<AnnotationDirectoryDTO> listAllDirectoryWithAnnotations() { |
| | | // // 1. 查询所有目录 |
| | | // List<AnnotationDirectoryEntity> directoryEntities = lambdaQuery() |
| | | // .orderByDesc(AnnotationDirectoryEntity::getCreateTime) // 核心:目录按创建时间降序 |
| | | // .list(); |
| | | // if (directoryEntities.isEmpty()) { |
| | | // return List.of(); |
| | | // } |
| | | // |
| | | // // 2. 批量查询所有标注,按目录ID分组(减少数据库查询次数) |
| | | // List<AnnotationEntity> allAnnotations = annotationService.list(); |
| | | // Map<String, List<AnnotationEntity>> annotationMap = allAnnotations.stream() |
| | | // .collect(Collectors.groupingBy(AnnotationEntity::getDirectoryId)); |
| | | // |
| | | // // 3. 遍历目录,组装DTO(关联下属标注) |
| | | // return directoryEntities.stream().map(directoryEntity -> { |
| | | // AnnotationDirectoryDTO directoryDTO = AnnotationDirectoryDTO.builder().build(); |
| | | // BeanUtils.copyProperties(directoryEntity, directoryDTO); |
| | | // |
| | | // // 4. 获取当前目录下的标注,并按createTime降序排序 |
| | | // List<AnnotationEntity> annotationEntities = annotationMap.getOrDefault(directoryEntity.getId(), List.of()) |
| | | // .stream() |
| | | // .sorted((a1, a2) -> a2.getCreateTime().compareTo(a1.getCreateTime())) // 标注按创建时间降序 |
| | | // .collect(Collectors.toList()); |
| | | // |
| | | // // 5. 标注实体转DTO(反序列化坐标数据) |
| | | // List<AnnotationDTO> annotationDTOList = annotationEntities.stream().map(annotationEntity -> { |
| | | // AnnotationDTO annotationDTO = AnnotationDTO.builder().build(); |
| | | // BeanUtils.copyProperties(annotationEntity, annotationDTO); |
| | | // try { |
| | | // // 反序列化坐标数据 |
| | | // annotationDTO.setCoordinateInfo( |
| | | // JsonSerializeUtil.deserialize(annotationEntity.getCoordinateInfo()) |
| | | // ); |
| | | // } catch (Exception e) { |
| | | // log.error("反序列化标注坐标失败,标注ID:{}", annotationEntity.getId(), e); |
| | | // annotationDTO.setCoordinateInfo(null); |
| | | // } |
| | | // return annotationDTO; |
| | | // }).collect(Collectors.toList()); |
| | | // |
| | | // // 6. 设置目录下的标注列表 |
| | | // directoryDTO.setAnnotations(annotationDTOList); |
| | | // return directoryDTO; |
| | | // }).collect(Collectors.toList()); |
| | | // } |
| | | |
| | | /** |
| | | * 查询全部目录(含下属标注数据) |
| | | * 修复点:替换自定义Mapper方法为MyBatis-Plus通用查询,避免SQL映射缺失问题 |
| | | * 优化点: |
| | | * 1. 默认文件夹固定置顶,其余目录按createTime降序排序 |
| | | * 2. 目录下的标注按createTime降序排序 |
| | | */ |
| | | @Override |
| | | public List<AnnotationDirectoryDTO> listAllDirectoryWithAnnotations() { |
| | | // 1. 查询所有目录 |
| | | List<AnnotationDirectoryEntity> directoryEntities = list(); |
| | | if (directoryEntities.isEmpty()) { |
| | | // 1. 查询所有目录(未排序) |
| | | List<AnnotationDirectoryEntity> allDirectoryEntities = list(); |
| | | if (allDirectoryEntities.isEmpty()) { |
| | | return List.of(); |
| | | } |
| | | |
| | | // 2. 批量查询所有标注,按目录ID分组(减少数据库查询次数) |
| | | // 2. 拆分默认目录和普通目录 |
| | | String defaultDirId = "default_directory_00000001"; // 默认文件夹固定ID |
| | | AnnotationDirectoryEntity defaultDirectory = null; |
| | | List<AnnotationDirectoryEntity> normalDirectories = new ArrayList<>(); |
| | | |
| | | for (AnnotationDirectoryEntity dir : allDirectoryEntities) { |
| | | if (defaultDirId.equals(dir.getId())) { |
| | | defaultDirectory = dir; // 筛选出默认目录 |
| | | } else { |
| | | normalDirectories.add(dir); // 其余为普通目录 |
| | | } |
| | | } |
| | | |
| | | // 3. 普通目录按createTime降序排序 |
| | | List<AnnotationDirectoryEntity> sortedNormalDirectories = normalDirectories.stream() |
| | | .sorted((d1, d2) -> d2.getCreateTime().compareTo(d1.getCreateTime())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 4. 组装最终的目录列表:默认目录(如果存在) + 排序后的普通目录 |
| | | List<AnnotationDirectoryEntity> finalDirectoryEntities = new ArrayList<>(); |
| | | if (defaultDirectory != null) { |
| | | finalDirectoryEntities.add(defaultDirectory); // 默认目录置顶 |
| | | } |
| | | finalDirectoryEntities.addAll(sortedNormalDirectories); |
| | | |
| | | // 5. 批量查询所有标注,按目录ID分组(减少数据库查询次数) |
| | | List<AnnotationEntity> allAnnotations = annotationService.list(); |
| | | Map<Integer, List<AnnotationEntity>> annotationMap = allAnnotations.stream() |
| | | Map<String, List<AnnotationEntity>> annotationMap = allAnnotations.stream() |
| | | .collect(Collectors.groupingBy(AnnotationEntity::getDirectoryId)); |
| | | |
| | | // 3. 遍历目录,组装DTO(关联下属标注) |
| | | return directoryEntities.stream().map(directoryEntity -> { |
| | | // 6. 遍历组装DTO(逻辑不变,仅使用最终排序后的目录列表) |
| | | return finalDirectoryEntities.stream().map(directoryEntity -> { |
| | | AnnotationDirectoryDTO directoryDTO = AnnotationDirectoryDTO.builder().build(); |
| | | BeanUtils.copyProperties(directoryEntity, directoryDTO); |
| | | |
| | | // 4. 获取当前目录下的标注(从分组Map中获取,避免循环查库) |
| | | List<AnnotationEntity> annotationEntities = annotationMap.getOrDefault(directoryEntity.getId(), List.of()); |
| | | // 7. 目录下的标注按createTime降序排序 |
| | | List<AnnotationEntity> annotationEntities = annotationMap.getOrDefault(directoryEntity.getId(), List.of()) |
| | | .stream() |
| | | .sorted((a1, a2) -> a2.getCreateTime().compareTo(a1.getCreateTime())) |
| | | .collect(Collectors.toList()); |
| | | |
| | | // 5. 标注实体转DTO(反序列化坐标数据) |
| | | // 8. 标注实体转DTO(原有逻辑完全保留) |
| | | List<AnnotationDTO> annotationDTOList = annotationEntities.stream().map(annotationEntity -> { |
| | | AnnotationDTO annotationDTO = AnnotationDTO.builder().build(); |
| | | BeanUtils.copyProperties(annotationEntity, annotationDTO); |
| | | try { |
| | | // 反序列化坐标数据 |
| | | annotationDTO.setCoordinateInfo( |
| | | JsonSerializeUtil.deserialize(annotationEntity.getCoordinateInfo()) |
| | | ); |
| | | annotationDTO.setCoordinateInfo(JsonSerializeUtil.deserialize(annotationEntity.getCoordinateInfo())); |
| | | } catch (Exception e) { |
| | | log.error("反序列化标注坐标失败,标注ID:{}", annotationEntity.getId(), e); |
| | | annotationDTO.setCoordinateInfo(null); |
| | |
| | | return annotationDTO; |
| | | }).collect(Collectors.toList()); |
| | | |
| | | // 6. 设置目录下的标注列表 |
| | | directoryDTO.setAnnotations(annotationDTOList); |
| | | return directoryDTO; |
| | | }).collect(Collectors.toList()); |