feat(recycle-bin): 实现回收站功能

- 在数据库中添加逻辑删除字段和相关索引- 新增回收站相关实体类和接口
- 实现回收站列表查询、项目恢复、永久删除和清空回收站等功能
- 前端集成回收站接口,支持回收站页面操作
This commit is contained in:
ikmkj
2025-07-31 23:09:58 +08:00
parent 56633dfd3b
commit 1491cfc330
13 changed files with 254 additions and 10 deletions

View File

@@ -0,0 +1,33 @@
package com.test.bijihoudaun.service;
import com.test.bijihoudaun.entity.TrashItemVo;
import java.util.List;
public interface TrashService {
/**
* 获取回收站中的所有项目
* @return 回收站项目列表
*/
List<TrashItemVo> getTrashItems();
/**
* 恢复指定的回收站项目
* @param id 项目ID
* @param type 项目类型 ("note" 或 "group")
*/
void restoreItem(String id, String type);
/**
* 永久删除指定的回收站项目
* @param id 项目ID
* @param type 项目类型 ("note" 或 "group")
*/
void permanentlyDeleteItem(String id, String type);
/**
* 清空回收站
*/
void cleanTrash();
}

View File

@@ -0,0 +1,99 @@
package com.test.bijihoudaun.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.test.bijihoudaun.entity.Grouping;
import com.test.bijihoudaun.entity.MarkdownFile;
import com.test.bijihoudaun.entity.TrashItemVo;
import com.test.bijihoudaun.mapper.GroupingMapper;
import com.test.bijihoudaun.mapper.MarkdownFileMapper;
import com.test.bijihoudaun.service.TrashService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Service
public class TrashServiceImpl implements TrashService {
@Autowired
private MarkdownFileMapper markdownFileMapper;
@Autowired
private GroupingMapper groupingMapper;
@Override
public List<TrashItemVo> getTrashItems() {
// 查询已删除的笔记
List<TrashItemVo> deletedNotes = markdownFileMapper.selectList(new QueryWrapper<MarkdownFile>().eq("is_deleted", 1))
.stream()
.map(file -> {
TrashItemVo vo = new TrashItemVo();
vo.setId(String.valueOf(file.getId()));
vo.setName(file.getTitle());
vo.setType("note");
vo.setDeletedAt(file.getDeletedAt());
vo.setDeletedBy(String.valueOf(file.getDeletedBy()));
return vo;
})
.collect(Collectors.toList());
// 查询已删除的分组
List<TrashItemVo> deletedGroups = groupingMapper.selectList(new QueryWrapper<Grouping>().eq("is_deleted", 1))
.stream()
.map(group -> {
TrashItemVo vo = new TrashItemVo();
vo.setId(String.valueOf(group.getId()));
vo.setName(group.getGrouping());
vo.setType("group");
vo.setDeletedAt(group.getDeletedAt());
vo.setDeletedBy(String.valueOf(group.getDeletedBy()));
return vo;
})
.collect(Collectors.toList());
// 合并并返回
return Stream.concat(deletedNotes.stream(), deletedGroups.stream()).collect(Collectors.toList());
}
@Override
@Transactional
public void restoreItem(String id, String type) {
if ("note".equals(type)) {
MarkdownFile file = new MarkdownFile();
file.setId(Long.parseLong(id));
file.setIsDeleted(0);
file.setDeletedAt(null);
file.setDeletedBy(null);
markdownFileMapper.updateById(file);
} else if ("group".equals(type)) {
Grouping group = new Grouping();
group.setId(Long.parseLong(id));
group.setIsDeleted(0);
group.setDeletedAt(null);
group.setDeletedBy(null);
groupingMapper.updateById(group);
}
}
@Override
@Transactional
public void permanentlyDeleteItem(String id, String type) {
if ("note".equals(type)) {
markdownFileMapper.deleteById(Long.parseLong(id));
} else if ("group".equals(type)) {
// 删除分组时,也删除其下的所有笔记
groupingMapper.deleteById(Long.parseLong(id));
markdownFileMapper.delete(new QueryWrapper<MarkdownFile>().eq("grouping_id", id));
}
}
@Override
@Transactional
public void cleanTrash() {
markdownFileMapper.delete(new QueryWrapper<MarkdownFile>().eq("is_deleted", 1));
groupingMapper.delete(new QueryWrapper<Grouping>().eq("is_deleted", 1));
}
}