liusuyi
2026-06-11 4fafee90e483bb10e092186a9b07b8cc356dbdb2
ard-sample/src/main/java/com/ard/sample/annotation/service/impl/AnnotationDirectoryServiceImpl.java
@@ -9,6 +9,7 @@
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;
@@ -16,6 +17,7 @@
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;
@@ -45,12 +47,50 @@
        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));
@@ -60,40 +100,119 @@
        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);
@@ -101,7 +220,6 @@
                return annotationDTO;
            }).collect(Collectors.toList());
            // 6. 设置目录下的标注列表
            directoryDTO.setAnnotations(annotationDTOList);
            return directoryDTO;
        }).collect(Collectors.toList());