1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
package com.ard.sample.annotation.service.impl;
 
import com.ard.common.utils.bean.BeanUtils;
import com.ard.sample.annotation.mapper.AnnotationMapper;
import com.ard.sample.annotation.model.dto.AnnotationDTO;
import com.ard.sample.annotation.model.dto.AnnotationDirectoryDTO;
import com.ard.sample.annotation.model.entity.AnnotationDirectoryEntity;
import com.ard.sample.annotation.model.entity.AnnotationEntity;
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.extension.service.impl.ServiceImpl;
import com.ard.sample.annotation.mapper.AnnotationDirectoryMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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;
 
@Slf4j
@Service
@RequiredArgsConstructor
public class AnnotationDirectoryServiceImpl extends ServiceImpl<AnnotationDirectoryMapper, AnnotationDirectoryEntity>
        implements IAnnotationDirectoryService {
 
    // 注入已实现的AnnotationService(而非直接用Mapper),复用其查询逻辑
    private final IAnnotationService annotationService;
 
    private final AnnotationMapper annotationMapper;
 
    @Override
    public boolean addDirectory(AnnotationDirectoryEntity entity) {
        return save(entity);
    }
 
    @Override
    public boolean editDirectory(AnnotationDirectoryEntity entity) {
        if (entity.getId() == null) {
            log.error("修改目录失败:ID为空");
            return false;
        }
        return updateById(entity);
    }
 
    /**
     * 新增:修改目录显示状态
     */
    @Override
    public boolean updateDirectoryVisible(String id, Boolean isTrue) {
        if (id == null || id.isEmpty() || isTrue == null) {
            log.error("修改目录显示状态失败:参数非法,id={}, isTrue={}", id, isTrue);
            return false;
        }
        AnnotationDirectoryEntity entity = new AnnotationDirectoryEntity();
        entity.setId(id);
        entity.setIsTrue(isTrue);
        return updateById(entity);
    }
 
    @Override
    @Transactional(rollbackFor = Exception.class) // 事务保证级联删除
    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));
        // 2. 删除目录
        boolean result = removeById(id);
        log.info("删除目录{},结果:{}", id, result);
        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());
//    }
 
    /**
     * 查询全部目录(含下属标注数据)
     * 优化点:
     * 1. 默认文件夹固定置顶,其余目录按createTime降序排序
     * 2. 目录下的标注按createTime降序排序
     */
    @Override
    public List<AnnotationDirectoryDTO> listAllDirectoryWithAnnotations() {
        // 1. 查询所有目录(未排序)
        List<AnnotationDirectoryEntity> allDirectoryEntities = list();
        if (allDirectoryEntities.isEmpty()) {
            return List.of();
        }
 
        // 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<String, List<AnnotationEntity>> annotationMap = allAnnotations.stream()
                .collect(Collectors.groupingBy(AnnotationEntity::getDirectoryId));
 
        // 6. 遍历组装DTO(逻辑不变,仅使用最终排序后的目录列表)
        return finalDirectoryEntities.stream().map(directoryEntity -> {
            AnnotationDirectoryDTO directoryDTO = AnnotationDirectoryDTO.builder().build();
            BeanUtils.copyProperties(directoryEntity, directoryDTO);
 
            // 7. 目录下的标注按createTime降序排序
            List<AnnotationEntity> annotationEntities = annotationMap.getOrDefault(directoryEntity.getId(), List.of())
                    .stream()
                    .sorted((a1, a2) -> a2.getCreateTime().compareTo(a1.getCreateTime()))
                    .collect(Collectors.toList());
 
            // 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()));
                } catch (Exception e) {
                    log.error("反序列化标注坐标失败,标注ID:{}", annotationEntity.getId(), e);
                    annotationDTO.setCoordinateInfo(null);
                }
                return annotationDTO;
            }).collect(Collectors.toList());
 
            directoryDTO.setAnnotations(annotationDTOList);
            return directoryDTO;
        }).collect(Collectors.toList());
    }
 
//    /**
//     * 查询全部目录(含下属标注数据)
//     */
//    @Override
//    public List<AnnotationDirectoryDTO> listAllDirectoryWithAnnotations() {
//        // 1. 查询所有目录
//        List<AnnotationDirectoryEntity> directoryEntities = list();
//
//        // 2. 遍历目录,关联查询标注数据并组装DTO
//        return directoryEntities.stream().map(directoryEntity -> {
//            AnnotationDirectoryDTO directoryDTO = AnnotationDirectoryDTO.builder().build();
//            BeanUtils.copyProperties(directoryEntity, directoryDTO);
//
//            // 3. 查询当前目录下的所有标注
//            List<AnnotationEntity> annotationEntities = annotationMapper.selectByDirectoryId(directoryEntity.getId());
//
//            // 4. 标注实体转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());
//
//            // 5. 给目录DTO设置下属标注列表(需先给AnnotationDirectoryDTO新增annotations字段)
//            directoryDTO.setAnnotations(annotationDTOList);
//            return directoryDTO;
//        }).collect(Collectors.toList());
//    }
}