- 新增 CategoryController、CollectionController、CommentController 等多个控制器类 - 实现了分类、收藏、评论、消息等功能的接口 - 优化了部分方法名称,提高了代码可读性
276 lines
10 KiB
Java
276 lines
10 KiB
Java
package com.example.copykamanotes.service.impl;
|
|
|
|
import com.example.copykamanotes.annotation.NeedLogin;
|
|
import com.example.copykamanotes.mapper.NoteMapper;
|
|
import com.example.copykamanotes.mapper.QuestionMapper;
|
|
import com.example.copykamanotes.model.base.ApiResponse;
|
|
import com.example.copykamanotes.model.base.EmptyVO;
|
|
import com.example.copykamanotes.model.base.Pagination;
|
|
import com.example.copykamanotes.model.dto.note.*;
|
|
import com.example.copykamanotes.model.entity.Note;
|
|
import com.example.copykamanotes.model.entity.Question;
|
|
import com.example.copykamanotes.model.entity.User;
|
|
import com.example.copykamanotes.model.vo.category.CategoryVO;
|
|
import com.example.copykamanotes.model.vo.note.*;
|
|
import com.example.copykamanotes.scope.RequestScopeData;
|
|
import com.example.copykamanotes.service.*;
|
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
|
import com.example.copykamanotes.utils.MarkdownUtils;
|
|
import com.example.copykamanotes.utils.PaginationUtils;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.beans.BeanUtils;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.util.*;
|
|
import java.util.stream.Collectors;
|
|
|
|
@Service
|
|
@RequiredArgsConstructor
|
|
public class NoteServiceImpl implements NoteService {
|
|
|
|
private final NoteMapper noteMapper;
|
|
private final UserService userService;
|
|
private final QuestionService questionService;
|
|
private final NoteLikeService noteLikeService;
|
|
private final RequestScopeData requestScopeData;
|
|
private final CategoryService categoryService;
|
|
private final QuestionMapper questionMapper;
|
|
|
|
@Override
|
|
public ApiResponse<List<NoteVO>> getNotes(NoteQueryParams noteQueryParams) {
|
|
int offset = PaginationUtils.calculateOffset(noteQueryParams.getPage(), noteQueryParams.getPageSize());
|
|
|
|
int total = noteMapper.countNotes(noteQueryParams);
|
|
|
|
Pagination pagination = new Pagination(noteQueryParams.getPage(), noteQueryParams.getPageSize(), total);
|
|
|
|
List<Note> notes = noteMapper.findByQueryParams(noteQueryParams, noteQueryParams.getPageSize(), offset);
|
|
|
|
List<Integer> questionIds = notes.stream().map(Note::getQuestionId).distinct().toList();
|
|
List<Long> authorIds = notes.stream().map(Note::getAuthorId).distinct().toList();
|
|
List<Integer> noteIds = notes.stream().map(Note::getNoteId).toList();
|
|
|
|
Map<Long, User> userMapByIds = userService.getUserMapByIds(authorIds);
|
|
|
|
Map<Integer, Question> questionMapByIds = questionService.getQuestionMapByIds(questionIds);
|
|
|
|
Set<Integer> userLikedNoteIds;
|
|
Set<Integer> userCollectedNoteIds;
|
|
|
|
if (requestScopeData.isLogin() && requestScopeData.getUserId() != null) {
|
|
Long currentUserId = requestScopeData.getUserId();
|
|
userLikedNoteIds = noteLikeService.findUserLikedNoteIds(currentUserId, noteIds);
|
|
userCollectedNoteIds = noteLikeService.findUserLikedNoteIds(currentUserId, noteIds);
|
|
} else {
|
|
userLikedNoteIds = Collections.emptySet();
|
|
userCollectedNoteIds = Collections.emptySet();
|
|
}
|
|
|
|
try {
|
|
List<NoteVO> noteVOs = notes.stream().map(note -> {
|
|
NoteVO noteVO = new NoteVO();
|
|
BeanUtils.copyProperties(note, noteVO);
|
|
|
|
User author = userMapByIds.get(note.getAuthorId());
|
|
|
|
if (author != null) {
|
|
NoteVO.SimpleAuthorVO authorVO = new NoteVO.SimpleAuthorVO();
|
|
BeanUtils.copyProperties(author, authorVO);
|
|
noteVO.setAuthor(authorVO);
|
|
}
|
|
|
|
Question question = questionMapByIds.get(note.getQuestionId());
|
|
if (question != null) {
|
|
NoteVO.SimpleQuestionVO questionVO = new NoteVO.SimpleQuestionVO();
|
|
BeanUtils.copyProperties(question, questionVO);
|
|
noteVO.setQuestion(questionVO);
|
|
}
|
|
|
|
NoteVO.UserActionsVO userActionsVO = new NoteVO.UserActionsVO();
|
|
if (userLikedNoteIds != null && userLikedNoteIds.contains(note.getNoteId())) {
|
|
userActionsVO.setIsLiked(true);
|
|
}
|
|
if (userCollectedNoteIds != null && userCollectedNoteIds.contains(note.getNoteId())) {
|
|
userActionsVO.setIsCollected(true);
|
|
}
|
|
|
|
if (MarkdownUtils.needCollapsed(note.getContent())) {
|
|
noteVO.setNeedCollapsed(true);
|
|
noteVO.setDisplayContent(MarkdownUtils.extractIntroduction(note.getContent()));
|
|
} else {
|
|
noteVO.setNeedCollapsed(false);
|
|
}
|
|
|
|
noteVO.setUserActions(userActionsVO);
|
|
return noteVO;
|
|
}).toList();
|
|
|
|
return ApiResponseUtils.success("获取笔记列表成功", noteVOs, pagination);
|
|
} catch (Exception e) {
|
|
return ApiResponseUtils.error("获取笔记列表失败");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@NeedLogin
|
|
public ApiResponse<CreateNoteVO> createNote(CreateNoteRequest createNoteRequest) {
|
|
Long userId = requestScopeData.getUserId();
|
|
Integer questionId = createNoteRequest.getQuestionId();
|
|
|
|
Question question = questionService.findById(questionId);
|
|
|
|
if (question == null) {
|
|
return ApiResponseUtils.error("问题不存在");
|
|
}
|
|
|
|
Note note = new Note();
|
|
BeanUtils.copyProperties(createNoteRequest, note);
|
|
note.setAuthorId(userId);
|
|
|
|
try {
|
|
noteMapper.insert(note);
|
|
CreateNoteVO createNoteVO = new CreateNoteVO();
|
|
createNoteVO.setNoteId(note.getNoteId());
|
|
return ApiResponseUtils.success("创建笔记成功", createNoteVO);
|
|
} catch (Exception e) {
|
|
return ApiResponseUtils.error("创建笔记失败");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@NeedLogin
|
|
public ApiResponse<EmptyVO> updateNote(Integer noteId, UpdateNoteRequest updateNoteRequest) {
|
|
Long userId = requestScopeData.getUserId();
|
|
|
|
Note note = noteMapper.findById(noteId);
|
|
|
|
if (note == null) {
|
|
return ApiResponseUtils.error("笔记不存在");
|
|
}
|
|
|
|
if (!Objects.equals(userId, note.getAuthorId())) {
|
|
return ApiResponseUtils.error("无权限");
|
|
}
|
|
|
|
try {
|
|
note.setContent(updateNoteRequest.getContent());
|
|
noteMapper.update(note);
|
|
return ApiResponseUtils.success("更新笔记成功");
|
|
} catch (Exception e) {
|
|
return ApiResponseUtils.error("更新笔记失败");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
@NeedLogin
|
|
public ApiResponse<EmptyVO> deleteNote(Integer noteId) {
|
|
Long userId = requestScopeData.getUserId();
|
|
|
|
Note note = noteMapper.findById(noteId);
|
|
|
|
if (note == null) {
|
|
return ApiResponseUtils.error("笔记不存在");
|
|
}
|
|
|
|
if (!Objects.equals(userId, note.getAuthorId())) {
|
|
return ApiResponseUtils.error("无权限");
|
|
}
|
|
|
|
try {
|
|
noteMapper.deleteById(noteId);
|
|
return ApiResponseUtils.success("删除笔记成功");
|
|
} catch (Exception e) {
|
|
return ApiResponseUtils.error("删除笔记失败");
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public ApiResponse<DownloadNoteVO> downloadNote() {
|
|
Long userId = requestScopeData.getUserId();
|
|
|
|
List<Note> userNotes = noteMapper.findByAuthorId(userId);
|
|
|
|
Map<Integer, Note> questionNoteMap = userNotes.stream()
|
|
.collect(Collectors.toMap(Note::getNoteId, note -> note));
|
|
|
|
if (userNotes.isEmpty()) {
|
|
return ApiResponseUtils.error("无笔记");
|
|
}
|
|
|
|
List<CategoryVO> categoryTree = categoryService.buildCategoryTree();
|
|
|
|
StringBuilder markdownContent = new StringBuilder();
|
|
|
|
List<Integer> questionIds = userNotes.stream()
|
|
.map(Note::getQuestionId)
|
|
.toList();
|
|
|
|
List<Question> questions = questionMapper.findByIdBatch(questionIds);
|
|
|
|
for (CategoryVO categoryVO : categoryTree) {
|
|
boolean hasTopLevelToc = false;
|
|
|
|
if (categoryVO.getChildren().isEmpty()) {
|
|
continue;
|
|
}
|
|
|
|
for (CategoryVO.ChildrenCategoryVO childrenCategoryVO : categoryVO.getChildren()) {
|
|
boolean hasSubLevelToc = false;
|
|
Integer categoryId = childrenCategoryVO.getCategoryId();
|
|
|
|
List<Question> categoryQuestionsList = questions.stream()
|
|
.filter(question -> Objects.equals(question.getCategoryId(), categoryId))
|
|
.toList();
|
|
|
|
if (categoryQuestionsList.isEmpty()) {
|
|
continue;
|
|
}
|
|
|
|
for (Question question : categoryQuestionsList) {
|
|
if (!hasTopLevelToc) {
|
|
markdownContent.append("# ").append(categoryVO.getName()).append("\n\n");
|
|
hasTopLevelToc = true;
|
|
}
|
|
|
|
if (!hasSubLevelToc) {
|
|
markdownContent.append("## ").append(childrenCategoryVO.getName()).append("\n\n");
|
|
hasSubLevelToc = true;
|
|
}
|
|
|
|
markdownContent.append("### [")
|
|
.append(question.getTitle())
|
|
.append("](")
|
|
.append(question.getQuestionId())
|
|
.append(")\n\n");
|
|
|
|
Note note = questionNoteMap.get(question.getQuestionId());
|
|
|
|
markdownContent.append(note.getContent()).append("\n\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
DownloadNoteVO downloadNoteVO = new DownloadNoteVO();
|
|
downloadNoteVO.setMarkdown(markdownContent.toString());
|
|
return ApiResponseUtils.success("生产笔记成功", downloadNoteVO);
|
|
}
|
|
|
|
@Override
|
|
public ApiResponse<List<NoteRankListItem>> submitNoteRank() {
|
|
return ApiResponseUtils.success("获取笔记排行榜成功", noteMapper.submitNoteRank());
|
|
}
|
|
|
|
@Override
|
|
public ApiResponse<List<NoteHeatMapItem>> submitNoteHeatMap() {
|
|
Long userId = requestScopeData.getUserId();
|
|
return ApiResponseUtils.success("获取笔记热力图成功", noteMapper.submitNoteHeatMap(userId));
|
|
}
|
|
|
|
@Override
|
|
public ApiResponse<Top3Count> submitNoteTop3Count() {
|
|
Long userId = requestScopeData.getUserId();
|
|
Top3Count top3Count = noteMapper.submitNoteTop3Count(userId);
|
|
return ApiResponseUtils.success("获取笔记top3成功", top3Count);
|
|
}
|
|
}
|