feat(question): 添加问题相关功能- 新增题单相关实体和接口
- 实现问题列表获取、问题创建、更新和删除功能 - 添加用户问题列表获取和单个问题获取功能 - 实现问题搜索功能 - 优化消息服务实现 - 重构部分现有服务的代码结构
This commit is contained in:
parent
6d8e44627f
commit
0244267ab7
@ -71,11 +71,4 @@ public class UserController {
|
|||||||
) {
|
) {
|
||||||
return userService.getUserList(userQueryParam);
|
return userService.getUserList(userQueryParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/users/resetPassword")
|
|
||||||
public ApiResponse<UserVO> updateUserPassword(
|
|
||||||
@RequestBody UserRestPasswordRequest userRestPasswordRequest
|
|
||||||
) {
|
|
||||||
return userService.updateUserPassword(userRestPasswordRequest.getOldPassword(), userRestPasswordRequest.getNewPassword());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,84 @@
|
|||||||
package com.example.copykamanotes.mapper;
|
package com.example.copykamanotes.mapper;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.model.dto.message.MessageQueryParams;
|
||||||
import com.example.copykamanotes.model.entity.Message;
|
import com.example.copykamanotes.model.entity.Message;
|
||||||
|
import com.example.copykamanotes.model.vo.message.UnreadCountByType;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息Mapper接口
|
||||||
|
*/
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface MessageMapper {
|
public interface MessageMapper {
|
||||||
|
/**
|
||||||
|
* 插入消息
|
||||||
|
*
|
||||||
|
* @param message 消息实体
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
int insert(Message message);
|
int insert(Message message);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据参数查询消息列表
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param params 查询参数
|
||||||
|
* @param offset 偏移量
|
||||||
|
* @return 消息列表
|
||||||
|
*/
|
||||||
|
List<Message> selectByParams(@Param("userId") Long userId, @Param("params") MessageQueryParams params, @Param("offset") int offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计符合条件的消息数量
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param params 查询参数
|
||||||
|
* @return 消息数量
|
||||||
|
*/
|
||||||
|
int countByParams(@Param("userId") Long userId, @Param("params") MessageQueryParams params);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记消息为已读
|
||||||
|
*
|
||||||
|
* @param messageId 消息ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int markAsRead(@Param("messageId") Integer messageId, @Param("userId") Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标记所有消息为已读
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int markAllAsRead(@Param("userId") Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除消息
|
||||||
|
*
|
||||||
|
* @param messageId 消息ID
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 影响行数
|
||||||
|
*/
|
||||||
|
int deleteMessage(@Param("messageId") Integer messageId, @Param("userId") Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计未读消息数量
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 未读消息数量
|
||||||
|
*/
|
||||||
|
int countUnread(@Param("userId") Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按类型统计未读消息数量
|
||||||
|
*
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 各类型未读消息数量
|
||||||
|
*/
|
||||||
|
List<UnreadCountByType> countUnreadByType(@Param("userId") Long userId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.example.copykamanotes.mapper;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.model.entity.QuestionList;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface QuestionListMapper {
|
||||||
|
/**
|
||||||
|
* 插入一个题单
|
||||||
|
*
|
||||||
|
* @param questionList 要插入的题单对象
|
||||||
|
* @return 插入操作影响的行数
|
||||||
|
*/
|
||||||
|
int insert(QuestionList questionList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据题单ID查找题单
|
||||||
|
*
|
||||||
|
* @param questionListId 题单的唯一标识符
|
||||||
|
* @return 返回找到的题单对象,如果没有找到则返回 null
|
||||||
|
*/
|
||||||
|
QuestionList findById(@Param("questionListId") Integer questionListId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有题单
|
||||||
|
*
|
||||||
|
* @return 返回所有题单的列表
|
||||||
|
*/
|
||||||
|
List<QuestionList> findAll();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新一个题单的信息
|
||||||
|
*
|
||||||
|
* @param questionList 要更新的题单对象,包含需要更新的字段
|
||||||
|
* @return 更新操作影响的行数
|
||||||
|
*/
|
||||||
|
int update(QuestionList questionList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据题单ID删除题单
|
||||||
|
*
|
||||||
|
* @param questionListId 题单的唯一标识符
|
||||||
|
* @return 删除操作影响的行数
|
||||||
|
*/
|
||||||
|
int deleteById(@Param("questionListId") Integer questionListId);
|
||||||
|
}
|
||||||
@ -10,27 +10,127 @@ import java.util.List;
|
|||||||
@Mapper
|
@Mapper
|
||||||
public interface UserMapper {
|
public interface UserMapper {
|
||||||
/**
|
/**
|
||||||
* 新增用户
|
* 插入新用户
|
||||||
*
|
*
|
||||||
* @param user 用户信息
|
* @param user 待插入的用户对象,包含用户的所有信息
|
||||||
*/
|
*/
|
||||||
int insert(User user);
|
int insert(User user);
|
||||||
|
|
||||||
User findByAccount(@Param("account") String account);
|
/**
|
||||||
|
* 根据ID查找用户
|
||||||
User findByEmail(@Param("email") String email);
|
*
|
||||||
|
* @param userId 用户ID,用于查询用户信息
|
||||||
int updateLastLoginAt(@Param("userId") Long userId);
|
* @return 返回用户对象,如果未找到则返回null
|
||||||
|
*/
|
||||||
User findById(@Param("userId") Long userId);
|
User findById(@Param("userId") Long userId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 ID 数组批量查找用户
|
||||||
|
*
|
||||||
|
* @param userIds 用户ID列表,用于批量查询用户信息
|
||||||
|
* @return 返回用户列表,如果未找到任何用户则返回空列表
|
||||||
|
*/
|
||||||
|
List<User> findByIdBatch(@Param("userIds") List<Long> userIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据账号查找用户
|
||||||
|
*
|
||||||
|
* @param account 用户账号,用于查询用户信息
|
||||||
|
* @return 返回用户对象,如果未找到则返回null
|
||||||
|
*/
|
||||||
|
User findByAccount(@Param("account") String account);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 OpenId 查找用户
|
||||||
|
*
|
||||||
|
* @param openId 用户的 OpenId,用于查询用户信息
|
||||||
|
* @return 返回用户对象,如果未找到则返回 null
|
||||||
|
*/
|
||||||
|
User findByOpenId(@Param("openId") String openId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据 UnionId 查找用户
|
||||||
|
*
|
||||||
|
* @param unionId 用户的 UnionId,用于查询用户信息
|
||||||
|
* @return 返回用户对象,如果未找到则返回 null
|
||||||
|
*/
|
||||||
|
User findByUnionId(@Param("unionId") String unionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据查询参数查找用户列表
|
||||||
|
*
|
||||||
|
* @param queryParams 用户查询参数对象,封装了查询用户时的各种筛选条件
|
||||||
|
* @return 符合查询条件的用户列表
|
||||||
|
*/
|
||||||
|
List<User> findByQueryParam(@Param("queryParams") UserQueryParam queryParams,
|
||||||
|
@Param("limit") Integer limit,
|
||||||
|
@Param("offset") Integer offset);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据查询参数统计用户数量
|
||||||
|
*
|
||||||
|
* @param queryParams 用户查询参数对象,封装了查询条件
|
||||||
|
* @return 满足查询条件的用户数量
|
||||||
|
*/
|
||||||
|
int countByQueryParam(@Param("queryParams") UserQueryParam queryParams);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户信息
|
||||||
|
*
|
||||||
|
* @param user 待更新的用户对象,包含用户的所有信息
|
||||||
|
*/
|
||||||
int update(User user);
|
int update(User user);
|
||||||
|
|
||||||
int updatePassword(@Param("userId") Long userId, @Param("password") String password);
|
/**
|
||||||
|
* 更新用户在线时间
|
||||||
|
*
|
||||||
|
* @param userId 用户ID,用于标识需要更新在线时间的用户
|
||||||
|
*/
|
||||||
|
int updateLastLoginAt(@Param("userId") Long userId);
|
||||||
|
|
||||||
List<User> findByIds(@Param("userIds") List<Long> userIds);
|
/**
|
||||||
|
* 绑定手机号
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param phone 手机号码
|
||||||
|
* @return 绑定结果
|
||||||
|
*/
|
||||||
|
int bindPhone(@Param("userId") Long userId, @Param("phone") String phone);
|
||||||
|
|
||||||
int countByQueryParam(@Param("queryParams") UserQueryParam userQueryParam);
|
/**
|
||||||
|
* 获取今日登录人数
|
||||||
|
* @return 今日登录人数
|
||||||
|
*/
|
||||||
|
int getTodayLoginCount();
|
||||||
|
|
||||||
List<User> findByQueryParam(@Param("queryParams") UserQueryParam userQueryParam, @Param("limit") int pageSize, @Param("offset") int offset);
|
/**
|
||||||
|
* 今日注册人数
|
||||||
|
* @return 今日注册人数
|
||||||
|
*/
|
||||||
|
int getTodayRegisterCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总注册人数
|
||||||
|
* @return 总注册人数
|
||||||
|
*/
|
||||||
|
int getTotalRegisterCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据邮箱查找用户
|
||||||
|
*
|
||||||
|
* @param email 用户邮箱,用于查询用户信息
|
||||||
|
* @return 返回用户对象,如果未找到则返回null
|
||||||
|
*/
|
||||||
|
User findByEmail(@Param("email") String email);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 搜索用户
|
||||||
|
*
|
||||||
|
* @param keyword 关键词
|
||||||
|
* @param limit 限制数量
|
||||||
|
* @param offset 偏移量
|
||||||
|
* @return 用户列表
|
||||||
|
*/
|
||||||
|
List<User> searchUsers(@Param("keyword") String keyword,
|
||||||
|
@Param("limit") int limit,
|
||||||
|
@Param("offset") int offset);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,37 @@
|
|||||||
package com.example.copykamanotes.model.entity;
|
package com.example.copykamanotes.model.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@Data
|
||||||
public class QuestionList {
|
public class QuestionList {
|
||||||
|
/*
|
||||||
|
* 题单ID(主键)
|
||||||
|
*/
|
||||||
|
private Integer questionListId;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 题单名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 题单类型
|
||||||
|
*/
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 题单描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createdAt;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private Date updatedAt;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import com.example.copykamanotes.model.base.EmptyVO;
|
|||||||
import com.example.copykamanotes.model.dto.collection.CollectionQueryParams;
|
import com.example.copykamanotes.model.dto.collection.CollectionQueryParams;
|
||||||
import com.example.copykamanotes.model.dto.collection.CreateCollectionBody;
|
import com.example.copykamanotes.model.dto.collection.CreateCollectionBody;
|
||||||
import com.example.copykamanotes.model.dto.collection.UpdateCollectionBody;
|
import com.example.copykamanotes.model.dto.collection.UpdateCollectionBody;
|
||||||
import com.example.copykamanotes.model.entity.Collection;
|
|
||||||
import com.example.copykamanotes.model.vo.collection.CollectionVO;
|
import com.example.copykamanotes.model.vo.collection.CollectionVO;
|
||||||
import com.example.copykamanotes.model.vo.collection.CreateCollectionVO;
|
import com.example.copykamanotes.model.vo.collection.CreateCollectionVO;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import com.example.copykamanotes.model.dto.questionListItem.QuestionListItemQuer
|
|||||||
import com.example.copykamanotes.model.dto.questionListItem.SortQuestionListItemBody;
|
import com.example.copykamanotes.model.dto.questionListItem.SortQuestionListItemBody;
|
||||||
import com.example.copykamanotes.model.vo.questionListItem.CreateQuestionListItemVO;
|
import com.example.copykamanotes.model.vo.questionListItem.CreateQuestionListItemVO;
|
||||||
import com.example.copykamanotes.model.vo.questionListItem.QuestionListItemUserVO;
|
import com.example.copykamanotes.model.vo.questionListItem.QuestionListItemUserVO;
|
||||||
|
import com.example.copykamanotes.model.vo.questionListItem.QuestionListItemVO;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -15,7 +16,7 @@ import java.util.List;
|
|||||||
public interface QuestionListItemService {
|
public interface QuestionListItemService {
|
||||||
ApiResponse<List<QuestionListItemUserVO>> useGetQuestionListItemUserVO(QuestionListItemQueryParams questionListItemQueryParams);
|
ApiResponse<List<QuestionListItemUserVO>> useGetQuestionListItemUserVO(QuestionListItemQueryParams questionListItemQueryParams);
|
||||||
|
|
||||||
ApiResponse<List<QuestionListItemUserVO>> getQuestionListItem(Integer questionListId);
|
ApiResponse<List<QuestionListItemVO>> getQuestionListItems(Integer questionListId);
|
||||||
|
|
||||||
ApiResponse<CreateQuestionListItemVO> createQuestionListItem(CreateQuestionListItemBody createQuestionListItemBody);
|
ApiResponse<CreateQuestionListItemVO> createQuestionListItem(CreateQuestionListItemBody createQuestionListItemBody);
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import com.example.copykamanotes.model.dto.question.UpdateQuestionBody;
|
|||||||
import com.example.copykamanotes.model.entity.Question;
|
import com.example.copykamanotes.model.entity.Question;
|
||||||
import com.example.copykamanotes.model.vo.question.CreateQuestionVO;
|
import com.example.copykamanotes.model.vo.question.CreateQuestionVO;
|
||||||
import com.example.copykamanotes.model.vo.question.QuestionNoteVO;
|
import com.example.copykamanotes.model.vo.question.QuestionNoteVO;
|
||||||
|
import com.example.copykamanotes.model.vo.question.QuestionUserVO;
|
||||||
import com.example.copykamanotes.model.vo.question.QuestionVO;
|
import com.example.copykamanotes.model.vo.question.QuestionVO;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ public interface QuestionService {
|
|||||||
|
|
||||||
ApiResponse<EmptyVO> deleteQuestion(Integer questionId);
|
ApiResponse<EmptyVO> deleteQuestion(Integer questionId);
|
||||||
|
|
||||||
ApiResponse<List<QuestionVO>> userGetQuestions(QuestionQueryParam queryParam);
|
ApiResponse<List<QuestionUserVO>> userGetQuestions(QuestionQueryParam queryParam);
|
||||||
|
|
||||||
ApiResponse<QuestionNoteVO> userGetQuestion(Integer questionId);
|
ApiResponse<QuestionNoteVO> userGetQuestion(Integer questionId);
|
||||||
|
|
||||||
|
|||||||
@ -11,5 +11,5 @@ public interface SearchService {
|
|||||||
|
|
||||||
ApiResponse<List<User>> searchUsers(String keyword, int page, int pageSize);
|
ApiResponse<List<User>> searchUsers(String keyword, int page, int pageSize);
|
||||||
|
|
||||||
ApiResponse<List<Note>> searchNotesByTag(String keyword, int page, int pageSize);
|
ApiResponse<List<Note>> searchNotesByTag(String keyword, String tag, int page, int pageSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,8 +66,6 @@ public interface UserService {
|
|||||||
*/
|
*/
|
||||||
Map<Long, User> getUserMapByIds(List<Long> authorIds);
|
Map<Long, User> getUserMapByIds(List<Long> authorIds);
|
||||||
|
|
||||||
ApiResponse<UserVO> updateUserPassword(String oldPassword, String newPassword);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取用户列表
|
* 获取用户列表
|
||||||
* @param userQueryParam 查询参数
|
* @param userQueryParam 查询参数
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import com.example.copykamanotes.model.vo.category.CategoryVO;
|
|||||||
import com.example.copykamanotes.model.vo.category.CreateCategoryVO;
|
import com.example.copykamanotes.model.vo.category.CreateCategoryVO;
|
||||||
import com.example.copykamanotes.service.CategoryService;
|
import com.example.copykamanotes.service.CategoryService;
|
||||||
import com.example.copykamanotes.utils.ApiResponseUtils;
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -21,14 +22,11 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class CategoryServiceImpl implements CategoryService {
|
public class CategoryServiceImpl implements CategoryService {
|
||||||
|
|
||||||
@Autowired
|
private final CategoryMapper categoryMapper;
|
||||||
private CategoryMapper categoryMapper;
|
private final QuestionMapper questionMapper;
|
||||||
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private QuestionMapper questionMapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<EmptyVO> updateCategory(Integer id, UpdateCategoryBody updateCategoryBody) {
|
public ApiResponse<EmptyVO> updateCategory(Integer id, UpdateCategoryBody updateCategoryBody) {
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.example.copykamanotes.service.impl;
|
|||||||
|
|
||||||
import com.example.copykamanotes.mapper.CollectionNoteMapper;
|
import com.example.copykamanotes.mapper.CollectionNoteMapper;
|
||||||
import com.example.copykamanotes.service.CollectionNoteService;
|
import com.example.copykamanotes.service.CollectionNoteService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@ -10,10 +11,10 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class CollectionNoteServiceImpl implements CollectionNoteService {
|
public class CollectionNoteServiceImpl implements CollectionNoteService {
|
||||||
|
|
||||||
@Autowired
|
private final CollectionNoteMapper collectionNoteMapper;
|
||||||
private CollectionNoteMapper collectionNoteMapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Integer> findUserCollectionNoteIds(Long userId, List<Integer> noteIds) {
|
public Set<Integer> findUserCollectionNoteIds(Long userId, List<Integer> noteIds) {
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import com.example.copykamanotes.model.vo.collection.CreateCollectionVO;
|
|||||||
import com.example.copykamanotes.scope.RequestScopeData;
|
import com.example.copykamanotes.scope.RequestScopeData;
|
||||||
import com.example.copykamanotes.service.CollectionService;
|
import com.example.copykamanotes.service.CollectionService;
|
||||||
import com.example.copykamanotes.utils.ApiResponseUtils;
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -26,19 +27,13 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class CollectionServiceImpl implements CollectionService {
|
public class CollectionServiceImpl implements CollectionService {
|
||||||
|
|
||||||
@Autowired
|
private final RequestScopeData requestScopeData;
|
||||||
private RequestScopeData requestScopeData;
|
private final CollectionMapper collectionMapper;
|
||||||
|
private final CollectionNoteMapper collectionNoteMapper;
|
||||||
@Autowired
|
private final NoteMapper noteMapper;
|
||||||
private CollectionMapper collectionMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private CollectionNoteMapper collectionNoteMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private NoteMapper noteMapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<List<CollectionVO>> getCollection(CollectionQueryParams queryParams) {
|
public ApiResponse<List<CollectionVO>> getCollection(CollectionQueryParams queryParams) {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.example.copykamanotes.service.impl;
|
|||||||
import com.example.copykamanotes.mapper.EmailVerifyCodeMapper;
|
import com.example.copykamanotes.mapper.EmailVerifyCodeMapper;
|
||||||
import com.example.copykamanotes.model.entity.EmailVerifyCode;
|
import com.example.copykamanotes.model.entity.EmailVerifyCode;
|
||||||
import com.example.copykamanotes.service.EmailService;
|
import com.example.copykamanotes.service.EmailService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -17,16 +18,12 @@ import java.util.concurrent.TimeUnit;
|
|||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class EmailServiceImpl implements EmailService {
|
public class EmailServiceImpl implements EmailService {
|
||||||
|
|
||||||
@Autowired
|
private final JavaMailSender javaMailSender;
|
||||||
private JavaMailSender javaMailSender;
|
private final EmailVerifyCodeMapper emailVerifyCodeMapper;
|
||||||
|
private final RedisTemplate<String, String> redisTemplate;
|
||||||
@Autowired
|
|
||||||
private EmailVerifyCodeMapper emailVerifyCodeMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RedisTemplate<String, String> redisTemplate;
|
|
||||||
|
|
||||||
@Value("${spring.mail.username}")
|
@Value("${spring.mail.username}")
|
||||||
private String fromEmail;
|
private String fromEmail;
|
||||||
|
|||||||
@ -1,50 +1,155 @@
|
|||||||
package com.example.copykamanotes.service.impl;
|
package com.example.copykamanotes.service.impl;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.mapper.MessageMapper;
|
||||||
|
import com.example.copykamanotes.mapper.UserMapper;
|
||||||
import com.example.copykamanotes.model.base.ApiResponse;
|
import com.example.copykamanotes.model.base.ApiResponse;
|
||||||
import com.example.copykamanotes.model.base.EmptyVO;
|
import com.example.copykamanotes.model.base.EmptyVO;
|
||||||
import com.example.copykamanotes.model.base.PageVO;
|
import com.example.copykamanotes.model.base.PageVO;
|
||||||
import com.example.copykamanotes.model.dto.message.MessageQueryParams;
|
import com.example.copykamanotes.model.dto.message.MessageQueryParams;
|
||||||
|
import com.example.copykamanotes.model.entity.Message;
|
||||||
|
import com.example.copykamanotes.model.entity.User;
|
||||||
import com.example.copykamanotes.model.vo.message.MessageVO;
|
import com.example.copykamanotes.model.vo.message.MessageVO;
|
||||||
import com.example.copykamanotes.model.vo.message.UnreadCountByType;
|
import com.example.copykamanotes.model.vo.message.UnreadCountByType;
|
||||||
import com.example.copykamanotes.service.MessageService;
|
import com.example.copykamanotes.service.MessageService;
|
||||||
|
import com.example.copykamanotes.utils.SecurityUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class MessageServiceImpl implements MessageService {
|
public class MessageServiceImpl implements MessageService {
|
||||||
|
|
||||||
|
private final MessageMapper messageMapper;
|
||||||
|
private final UserMapper userMapper;
|
||||||
|
private final RedisTemplate<String, Object> redisTemplate;
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MessageServiceImpl.class);
|
||||||
|
|
||||||
|
private static final String UNREAD_COUNT_KEY = "message:unread:count";
|
||||||
|
private static final String UNREAD_COUNT_BY_TYPE_KEY = "message:unread:type:";
|
||||||
|
private static final String MESSAGE_CACHE_KEY = "message:detail:";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<Integer> createMessage(Long receiverId, Long senderId, String type, Integer targetId, String content) {
|
public ApiResponse<Integer> createMessage(Long receiverId, Long senderId, String type, Integer targetId, String content) {
|
||||||
return null;
|
|
||||||
|
log.info("创建消息: {}", receiverId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
Message message = new Message();
|
||||||
|
message.setReceiverId(receiverId);
|
||||||
|
message.setType(type);
|
||||||
|
message.setTargetId(targetId);
|
||||||
|
message.setContent(content);
|
||||||
|
message.setCreatedAt(LocalDateTime.now());
|
||||||
|
message.setUpdatedAt(LocalDateTime.now());
|
||||||
|
|
||||||
|
int rows = messageMapper.insert(message);
|
||||||
|
log.info("创建消息成功: {}", rows);
|
||||||
|
|
||||||
|
clearMessageCache(receiverId);
|
||||||
|
|
||||||
|
return ApiResponse.success(message.getMessageId());
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponse.error(500, "创建消息失败");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<EmptyVO> markAsRead(Integer messageId) {
|
public ApiResponse<EmptyVO> markAsRead(Integer messageId) {
|
||||||
return null;
|
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
|
||||||
|
messageMapper.markAsRead(messageId, currentUserId);
|
||||||
|
clearMessageCache(currentUserId);
|
||||||
|
return ApiResponse.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<EmptyVO> markAllAsRead() {
|
public ApiResponse<EmptyVO> markAllAsRead() {
|
||||||
return null;
|
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
messageMapper.markAllAsRead(currentUserId);
|
||||||
|
|
||||||
|
clearMessageCache(currentUserId);
|
||||||
|
|
||||||
|
return ApiResponse.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<EmptyVO> deleteMessage(Integer messageId) {
|
public ApiResponse<EmptyVO> deleteMessage(Integer messageId) {
|
||||||
return null;
|
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
messageMapper.deleteMessage(messageId, currentUserId);
|
||||||
|
return ApiResponse.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<Integer> getUnreadCount() {
|
public ApiResponse<Integer> getUnreadCount() {
|
||||||
return null;
|
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
String cacheKey = UNREAD_COUNT_KEY + currentUserId;
|
||||||
|
Integer count = (Integer) redisTemplate.opsForValue().get(cacheKey);
|
||||||
|
if (count == null) {
|
||||||
|
count = messageMapper.countUnread(currentUserId);
|
||||||
|
redisTemplate.opsForValue().set(cacheKey, count, 5, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
return ApiResponse.success(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<List<UnreadCountByType>> getUnreadCountByType() {
|
public ApiResponse<List<UnreadCountByType>> getUnreadCountByType() {
|
||||||
return null;
|
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
String cacheKey = UNREAD_COUNT_BY_TYPE_KEY + currentUserId;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<UnreadCountByType> result = (List<UnreadCountByType>) redisTemplate.opsForValue().get(cacheKey);
|
||||||
|
if (result == null) {
|
||||||
|
result = messageMapper.countUnreadByType(currentUserId);
|
||||||
|
redisTemplate.opsForValue().set(cacheKey, result, 5, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.success(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<PageVO<MessageVO>> getMessages(MessageQueryParams params) {
|
public ApiResponse<PageVO<MessageVO>> getMessages(MessageQueryParams params) {
|
||||||
return null;
|
|
||||||
|
Long currentUserId = SecurityUtils.getCurrentUserId();
|
||||||
|
|
||||||
|
int total = messageMapper.countByParams(currentUserId, params);
|
||||||
|
|
||||||
|
int offset = (params.getPage() - 1) * params.getPageSize();
|
||||||
|
|
||||||
|
List<Message> messages = messageMapper.selectByParams(currentUserId, params, offset);
|
||||||
|
|
||||||
|
List<MessageVO> messageVOS = messages.stream().map(message -> {
|
||||||
|
MessageVO messageVO = new MessageVO();
|
||||||
|
messageVO.setMessageId(message.getMessageId());
|
||||||
|
messageVO.setType(message.getType());
|
||||||
|
messageVO.setTargetId(message.getTargetId());
|
||||||
|
messageVO.setContent(message.getContent());
|
||||||
|
messageVO.setIsRead(message.getIsRead());
|
||||||
|
messageVO.setCreatedAt(message.getCreatedAt());
|
||||||
|
|
||||||
|
User sender = userMapper.findById(message.getSenderId());
|
||||||
|
if (sender != null) {
|
||||||
|
MessageVO.SimpleUserVO senderVO = new MessageVO.SimpleUserVO();
|
||||||
|
senderVO.setUserId(sender.getUserId());
|
||||||
|
senderVO.setUsername(sender.getUsername());
|
||||||
|
senderVO.setAvatarUrl(sender.getAvatarUrl());
|
||||||
|
messageVO.setSender(senderVO);
|
||||||
|
}
|
||||||
|
return messageVO;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
PageVO<MessageVO> pageVO = PageVO.of(params.getPage(), params.getPageSize(), total, messageVOS);
|
||||||
|
return ApiResponse.success(pageVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearMessageCache(Long userId) {
|
||||||
|
redisTemplate.delete(UNREAD_COUNT_KEY + userId);
|
||||||
|
redisTemplate.delete(UNREAD_COUNT_BY_TYPE_KEY + userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,34 +17,24 @@ import com.example.copykamanotes.service.*;
|
|||||||
import com.example.copykamanotes.utils.ApiResponseUtils;
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
import com.example.copykamanotes.utils.MarkdownUtils;
|
import com.example.copykamanotes.utils.MarkdownUtils;
|
||||||
import com.example.copykamanotes.utils.PaginationUtils;
|
import com.example.copykamanotes.utils.PaginationUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class NoteServiceImpl implements NoteService {
|
public class NoteServiceImpl implements NoteService {
|
||||||
|
|
||||||
@Autowired
|
private final NoteMapper noteMapper;
|
||||||
private NoteMapper noteMapper;
|
private final UserService userService;
|
||||||
|
private final QuestionService questionService;
|
||||||
@Autowired
|
private final NoteLikeService noteLikeService;
|
||||||
private UserService userService;
|
private final RequestScopeData requestScopeData;
|
||||||
|
private final CategoryService categoryService;
|
||||||
@Autowired
|
private final QuestionMapper questionMapper;
|
||||||
private QuestionService questionService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private NoteLikeService noteLikeService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RequestScopeData requestScopeData;
|
|
||||||
@Autowired
|
|
||||||
private CategoryService categoryService;
|
|
||||||
@Autowired
|
|
||||||
private QuestionMapper questionMapper;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<List<NoteVO>> getNotes(NoteQueryParams noteQueryParams) {
|
public ApiResponse<List<NoteVO>> getNotes(NoteQueryParams noteQueryParams) {
|
||||||
|
|||||||
@ -0,0 +1,136 @@
|
|||||||
|
package com.example.copykamanotes.service.impl;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.mapper.NoteMapper;
|
||||||
|
import com.example.copykamanotes.mapper.QuestionListItemMapper;
|
||||||
|
import com.example.copykamanotes.mapper.QuestionListMapper;
|
||||||
|
import com.example.copykamanotes.mapper.UserMapper;
|
||||||
|
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.questionListItem.CreateQuestionListItemBody;
|
||||||
|
import com.example.copykamanotes.model.dto.questionListItem.QuestionListItemQueryParams;
|
||||||
|
import com.example.copykamanotes.model.dto.questionListItem.SortQuestionListItemBody;
|
||||||
|
import com.example.copykamanotes.model.entity.QuestionList;
|
||||||
|
import com.example.copykamanotes.model.entity.QuestionListItem;
|
||||||
|
import com.example.copykamanotes.model.vo.questionListItem.CreateQuestionListItemVO;
|
||||||
|
import com.example.copykamanotes.model.vo.questionListItem.QuestionListItemUserVO;
|
||||||
|
import com.example.copykamanotes.model.vo.questionListItem.QuestionListItemVO;
|
||||||
|
import com.example.copykamanotes.scope.RequestScopeData;
|
||||||
|
import com.example.copykamanotes.service.QuestionListItemService;
|
||||||
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class QuestionListItemServiceImpl implements QuestionListItemService {
|
||||||
|
|
||||||
|
private final QuestionListItemMapper questionListItemMapper;
|
||||||
|
private final QuestionListMapper questionListMapper;
|
||||||
|
private final RequestScopeData requestScopeData;
|
||||||
|
private final NoteMapper noteMapper;
|
||||||
|
private final UserMapper userMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<List<QuestionListItemUserVO>> useGetQuestionListItemUserVO(QuestionListItemQueryParams questionListItemQueryParams) {
|
||||||
|
|
||||||
|
int offset = questionListItemQueryParams.getPage() * questionListItemQueryParams.getPageSize();
|
||||||
|
int total = questionListItemMapper.countByQuestionListId(questionListItemQueryParams.getQuestionListId());
|
||||||
|
|
||||||
|
Pagination pagination = new Pagination(questionListItemQueryParams.getPage(), questionListItemQueryParams.getPageSize(), total);
|
||||||
|
|
||||||
|
Integer questionListId = questionListItemQueryParams.getQuestionListId();
|
||||||
|
|
||||||
|
QuestionList questionList = questionListMapper.findById(questionListId);
|
||||||
|
|
||||||
|
List<QuestionListItemVO> questionListItem = questionListItemMapper.findByQuestionListIdPage(questionListId, questionListItemQueryParams.getPageSize(), offset);
|
||||||
|
List<Integer> questionIds = questionListItem.stream().map(item -> item.getQuestion().getQuestionId()).toList();
|
||||||
|
|
||||||
|
final Set<Integer> userFinishedQuestionIds;
|
||||||
|
|
||||||
|
if (requestScopeData.isLogin()) {
|
||||||
|
userFinishedQuestionIds = noteMapper.filterFinishedQuestionIdsByUser(requestScopeData.getUserId(), questionIds);
|
||||||
|
} else {
|
||||||
|
userFinishedQuestionIds = Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<QuestionListItemUserVO> list = questionListItem.stream().map(item -> {
|
||||||
|
QuestionListItemUserVO questionListItemUserVO = new QuestionListItemUserVO();
|
||||||
|
BeanUtils.copyProperties(item, questionListItemUserVO);
|
||||||
|
|
||||||
|
QuestionListItemUserVO.UserQuestionStatus userQuestionStatus =
|
||||||
|
new QuestionListItemUserVO.UserQuestionStatus();
|
||||||
|
|
||||||
|
if (requestScopeData.isLogin()) {
|
||||||
|
userQuestionStatus.setFinished(userFinishedQuestionIds.contains(item.getQuestion().getQuestionId()));
|
||||||
|
} else {
|
||||||
|
userQuestionStatus.setFinished(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
questionListItemUserVO.setUserQuestionStatus(userQuestionStatus);
|
||||||
|
return questionListItemUserVO;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return ApiResponseUtils.success("获取问题列表成功", list, pagination);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<List<QuestionListItemVO>> getQuestionListItems(Integer questionListId) {
|
||||||
|
List<QuestionListItemVO> byQuestionListId = questionListItemMapper.findByQuestionListId(questionListId);
|
||||||
|
return ApiResponseUtils.success("获取问题列表成功", byQuestionListId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<CreateQuestionListItemVO> createQuestionListItem(CreateQuestionListItemBody createQuestionListItemBody) {
|
||||||
|
QuestionListItem questionListItem = new QuestionListItem();
|
||||||
|
BeanUtils.copyProperties(createQuestionListItemBody, questionListItem);
|
||||||
|
|
||||||
|
try {
|
||||||
|
int rank = questionListItemMapper.nextRank(createQuestionListItemBody.getQuestionListId());
|
||||||
|
questionListItem.setRank(rank);
|
||||||
|
|
||||||
|
questionListItemMapper.insert(questionListItem);
|
||||||
|
CreateQuestionListItemVO questionVO = new CreateQuestionListItemVO();
|
||||||
|
questionVO.setRank(rank);
|
||||||
|
return ApiResponseUtils.success("创建问题列表成功", questionVO);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("创建问题列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<EmptyVO> deleteQuestionListItem(Integer questionListId, Integer questionId) {
|
||||||
|
try {
|
||||||
|
questionListItemMapper.deleteByQuestionListIdAndQuestionId(questionListId, questionId);
|
||||||
|
return ApiResponseUtils.success("删除问题列表成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("删除问题列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<EmptyVO> sortQuestionListItem(SortQuestionListItemBody body) {
|
||||||
|
List<Integer> questionIds = body.getQuestionIds();
|
||||||
|
Integer questionListId = body.getQuestionListId();
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < questionIds.size(); i++) {
|
||||||
|
QuestionListItem questionListItem = new QuestionListItem();
|
||||||
|
questionListItem.setQuestionId(questionIds.get(i));
|
||||||
|
questionListItem.setQuestionListId(questionListId);
|
||||||
|
questionListItem.setRank(i + 1);
|
||||||
|
questionListItemMapper.updateQuestionRank(questionListItem);
|
||||||
|
}
|
||||||
|
return ApiResponseUtils.success("排序问题列表成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("排序问题列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,80 @@
|
|||||||
|
package com.example.copykamanotes.service.impl;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.mapper.QuestionListItemMapper;
|
||||||
|
import com.example.copykamanotes.mapper.QuestionListMapper;
|
||||||
|
import com.example.copykamanotes.model.base.ApiResponse;
|
||||||
|
import com.example.copykamanotes.model.base.EmptyVO;
|
||||||
|
import com.example.copykamanotes.model.dto.questionList.CreateQuestionListBody;
|
||||||
|
import com.example.copykamanotes.model.dto.questionList.UpdateQuestionListBody;
|
||||||
|
import com.example.copykamanotes.model.entity.QuestionList;
|
||||||
|
import com.example.copykamanotes.model.vo.questionList.CreateQuestionListVO;
|
||||||
|
import com.example.copykamanotes.service.QuestionListService;
|
||||||
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class QuestionListServiceImpl implements QuestionListService {
|
||||||
|
|
||||||
|
private final QuestionListMapper questionListMapper;
|
||||||
|
private final QuestionListItemMapper questionListItemMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<QuestionList> getQuestionList(Integer questionListId) {
|
||||||
|
return ApiResponseUtils.success("获取问题列表成功", questionListMapper.findById(questionListId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<List<QuestionList>> getQuestionLists() {
|
||||||
|
return ApiResponseUtils.success("获取问题列表成功", questionListMapper.findAll());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<CreateQuestionListVO> createQuestionList(CreateQuestionListBody body) {
|
||||||
|
QuestionList questionList = new QuestionList();
|
||||||
|
BeanUtils.copyProperties(body, questionList);
|
||||||
|
|
||||||
|
try {
|
||||||
|
questionListMapper.insert(questionList);
|
||||||
|
CreateQuestionListVO questionVO = new CreateQuestionListVO();
|
||||||
|
questionVO.setQuestionListId(questionList.getQuestionListId());
|
||||||
|
return ApiResponseUtils.success("创建问题列表成功", questionVO);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("创建问题列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<EmptyVO> deleteQuestionList(Integer questionListId) {
|
||||||
|
QuestionList questionList = questionListMapper.findById(questionListId);
|
||||||
|
|
||||||
|
if (questionList == null) {
|
||||||
|
return ApiResponseUtils.error("问题列表不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
questionListMapper.deleteById(questionListId);
|
||||||
|
questionListItemMapper.deleteByQuestionListId(questionListId);
|
||||||
|
return ApiResponseUtils.success("删除问题列表成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("删除问题列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<EmptyVO> updateQuestionList(Integer questionListId, UpdateQuestionListBody body) {
|
||||||
|
QuestionList questionList = new QuestionList();
|
||||||
|
BeanUtils.copyProperties(body, questionList);
|
||||||
|
questionList.setQuestionListId(questionListId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
questionListMapper.update(questionList);
|
||||||
|
return ApiResponseUtils.success("更新问题列表成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("更新问题列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,64 +1,198 @@
|
|||||||
package com.example.copykamanotes.service.impl;
|
package com.example.copykamanotes.service.impl;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.mapper.CategoryMapper;
|
||||||
|
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.ApiResponse;
|
||||||
import com.example.copykamanotes.model.base.EmptyVO;
|
import com.example.copykamanotes.model.base.EmptyVO;
|
||||||
|
import com.example.copykamanotes.model.base.Pagination;
|
||||||
import com.example.copykamanotes.model.dto.question.CreateQuestionBody;
|
import com.example.copykamanotes.model.dto.question.CreateQuestionBody;
|
||||||
import com.example.copykamanotes.model.dto.question.QuestionQueryParam;
|
import com.example.copykamanotes.model.dto.question.QuestionQueryParam;
|
||||||
import com.example.copykamanotes.model.dto.question.SearchQuestionBody;
|
import com.example.copykamanotes.model.dto.question.SearchQuestionBody;
|
||||||
import com.example.copykamanotes.model.dto.question.UpdateQuestionBody;
|
import com.example.copykamanotes.model.dto.question.UpdateQuestionBody;
|
||||||
|
import com.example.copykamanotes.model.entity.Category;
|
||||||
|
import com.example.copykamanotes.model.entity.Note;
|
||||||
import com.example.copykamanotes.model.entity.Question;
|
import com.example.copykamanotes.model.entity.Question;
|
||||||
import com.example.copykamanotes.model.vo.question.CreateQuestionVO;
|
import com.example.copykamanotes.model.vo.question.CreateQuestionVO;
|
||||||
import com.example.copykamanotes.model.vo.question.QuestionNoteVO;
|
import com.example.copykamanotes.model.vo.question.QuestionNoteVO;
|
||||||
|
import com.example.copykamanotes.model.vo.question.QuestionUserVO;
|
||||||
import com.example.copykamanotes.model.vo.question.QuestionVO;
|
import com.example.copykamanotes.model.vo.question.QuestionVO;
|
||||||
|
import com.example.copykamanotes.scope.RequestScopeData;
|
||||||
import com.example.copykamanotes.service.QuestionService;
|
import com.example.copykamanotes.service.QuestionService;
|
||||||
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
|
import com.example.copykamanotes.utils.PaginationUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class QuestionServiceImpl implements QuestionService {
|
public class QuestionServiceImpl implements QuestionService {
|
||||||
|
|
||||||
|
private final QuestionMapper questionMapper;
|
||||||
|
private final CategoryMapper categoryMapper;
|
||||||
|
private final RequestScopeData requestScopeData;
|
||||||
|
private final NoteMapper noteMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Question findById(Integer questionId) {
|
public Question findById(Integer questionId) {
|
||||||
return null;
|
return questionMapper.findById(questionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, Question> getQuestionMapByIds(List<Integer> questionIds) {
|
public Map<Integer, Question> getQuestionMapByIds(List<Integer> questionIds) {
|
||||||
return null;
|
if (questionIds.isEmpty())
|
||||||
|
return Collections.emptyMap();
|
||||||
|
|
||||||
|
List<Question> questions = questionMapper.findByIdBatch(questionIds);
|
||||||
|
|
||||||
|
return questions.stream().collect(Collectors.toMap(Question::getQuestionId, question -> question));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<List<QuestionVO>> getQuestions(QuestionQueryParam queryParam) {
|
public ApiResponse<List<QuestionVO>> getQuestions(QuestionQueryParam queryParam) {
|
||||||
return null;
|
int offset = PaginationUtils.calculateOffset(queryParam.getPage(), queryParam.getPageSize());
|
||||||
|
int total = questionMapper.countByQueryParam(queryParam);
|
||||||
|
|
||||||
|
Pagination pagination = new Pagination(queryParam.getPage(), queryParam.getPageSize(), total);
|
||||||
|
|
||||||
|
List<Question> questions = questionMapper.findByQueryParam(queryParam, queryParam.getPageSize(), offset);
|
||||||
|
|
||||||
|
List<QuestionVO> questionVOS = questions.stream().map(question -> {
|
||||||
|
QuestionVO questionVO = new QuestionVO();
|
||||||
|
BeanUtils.copyProperties(question, questionVO);
|
||||||
|
return questionVO;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return ApiResponseUtils.success("获取问题列表成功", questionVOS, pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<CreateQuestionVO> createQuestion(CreateQuestionBody body) {
|
public ApiResponse<CreateQuestionVO> createQuestion(CreateQuestionBody body) {
|
||||||
return null;
|
|
||||||
|
Category category = categoryMapper.findById(body.getCategoryId());
|
||||||
|
if (category == null) {
|
||||||
|
return ApiResponseUtils.error("分类 Id 不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
Question question = new Question();
|
||||||
|
BeanUtils.copyProperties(body, question);
|
||||||
|
|
||||||
|
try {
|
||||||
|
questionMapper.insert(question);
|
||||||
|
CreateQuestionVO createQuestionVO = new CreateQuestionVO();
|
||||||
|
createQuestionVO.setQuestionId(question.getQuestionId());
|
||||||
|
return ApiResponseUtils.success("创建问题成功", createQuestionVO);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("创建问题失败");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<EmptyVO> updateQuestion(Integer questionId, UpdateQuestionBody body) {
|
public ApiResponse<EmptyVO> updateQuestion(Integer questionId, UpdateQuestionBody body) {
|
||||||
return null;
|
Question question = new Question();
|
||||||
|
BeanUtils.copyProperties(body, question);
|
||||||
|
question.setQuestionId(questionId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
questionMapper.update(question);
|
||||||
|
return ApiResponseUtils.success("更新问题成功");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("更新问题失败");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<EmptyVO> deleteQuestion(Integer questionId) {
|
public ApiResponse<EmptyVO> deleteQuestion(Integer questionId) {
|
||||||
return null;
|
try {
|
||||||
|
if (questionMapper.deleteById(questionId) > 0)
|
||||||
|
return ApiResponseUtils.success("删除问题成功");
|
||||||
|
else
|
||||||
|
return ApiResponseUtils.error("删除问题失败");
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("删除问题失败");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<List<QuestionVO>> userGetQuestions(QuestionQueryParam queryParam) {
|
public ApiResponse<List<QuestionUserVO>> userGetQuestions(QuestionQueryParam queryParam) {
|
||||||
return null;
|
|
||||||
|
int offset = PaginationUtils.calculateOffset(queryParam.getPage(), queryParam.getPageSize());
|
||||||
|
int total = questionMapper.countByQueryParam(queryParam);
|
||||||
|
Pagination pagination = new Pagination(queryParam.getPage(), queryParam.getPageSize(), total);
|
||||||
|
|
||||||
|
List<Question> questions = questionMapper.findByQueryParam(queryParam, queryParam.getPageSize(), offset);
|
||||||
|
List<Integer> questionIds = questions.stream().map(Question::getQuestionId).toList();
|
||||||
|
|
||||||
|
Set<Integer> userFinishedQuestionIds;
|
||||||
|
|
||||||
|
if (requestScopeData.isLogin() && requestScopeData.getUserId() != null) {
|
||||||
|
userFinishedQuestionIds = noteMapper.filterFinishedQuestionIdsByUser(requestScopeData.getUserId(), questionIds);
|
||||||
|
} else {
|
||||||
|
userFinishedQuestionIds = Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<QuestionUserVO> questionUserVOS = questions.stream().map(question -> {
|
||||||
|
QuestionUserVO questionUserVO = new QuestionUserVO();
|
||||||
|
QuestionUserVO.UserQuestionStatus userQuestionStatus = new QuestionUserVO.UserQuestionStatus();
|
||||||
|
|
||||||
|
if (userFinishedQuestionIds.contains(question.getQuestionId())) {
|
||||||
|
userQuestionStatus.setFinished(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
BeanUtils.copyProperties(question, questionUserVO);
|
||||||
|
|
||||||
|
questionUserVO.setUserQuestionStatus(userQuestionStatus);
|
||||||
|
return questionUserVO;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return ApiResponseUtils.success("获取问题列表成功", questionUserVOS, pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<QuestionNoteVO> userGetQuestion(Integer questionId) {
|
public ApiResponse<QuestionNoteVO> userGetQuestion(Integer questionId) {
|
||||||
return null;
|
|
||||||
|
Question question = questionMapper.findById(questionId);
|
||||||
|
if (question == null) {
|
||||||
|
return ApiResponseUtils.error("问题不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
QuestionNoteVO questionNoteVO = new QuestionNoteVO();
|
||||||
|
QuestionNoteVO.UserNote userNote = new QuestionNoteVO.UserNote();
|
||||||
|
|
||||||
|
if (requestScopeData.isLogin() && requestScopeData.getUserId() != null) {
|
||||||
|
Note note = noteMapper.findByAuthorIdAndQuestionId(requestScopeData.getUserId(), questionId);
|
||||||
|
if (note != null) {
|
||||||
|
userNote.setFinished(true);
|
||||||
|
BeanUtils.copyProperties(note, userNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BeanUtils.copyProperties(question, questionNoteVO);
|
||||||
|
questionNoteVO.setUserNote(userNote);
|
||||||
|
|
||||||
|
questionMapper.incrementViewCount(questionId);
|
||||||
|
|
||||||
|
return ApiResponseUtils.success("获取问题成功", questionNoteVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<List<QuestionVO>> searchQuestion(SearchQuestionBody body) {
|
public ApiResponse<List<QuestionVO>> searchQuestion(SearchQuestionBody body) {
|
||||||
return null;
|
String keyword = body.getKeyword();
|
||||||
|
|
||||||
|
List<Question> questionList = questionMapper.findByKeyword(keyword);
|
||||||
|
|
||||||
|
List<QuestionVO> questionVOList = questionList.stream().map(question -> {
|
||||||
|
QuestionVO questionVO = new QuestionVO();
|
||||||
|
BeanUtils.copyProperties(question, questionVO);
|
||||||
|
return questionVO;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return ApiResponseUtils.success("搜索成功", questionVOList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,16 @@
|
|||||||
package com.example.copykamanotes.service.impl;
|
package com.example.copykamanotes.service.impl;
|
||||||
|
|
||||||
import com.example.copykamanotes.service.RedisService;
|
import com.example.copykamanotes.service.RedisService;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class RedisServiceImpl implements RedisService {
|
public class RedisServiceImpl implements RedisService {
|
||||||
@Autowired
|
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private final RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void set(String key, Object value) {
|
public void set(String key, Object value) {
|
||||||
|
|||||||
@ -0,0 +1,102 @@
|
|||||||
|
package com.example.copykamanotes.service.impl;
|
||||||
|
|
||||||
|
import com.example.copykamanotes.mapper.NoteMapper;
|
||||||
|
import com.example.copykamanotes.mapper.UserMapper;
|
||||||
|
import com.example.copykamanotes.model.base.ApiResponse;
|
||||||
|
import com.example.copykamanotes.model.entity.Note;
|
||||||
|
import com.example.copykamanotes.model.entity.User;
|
||||||
|
import com.example.copykamanotes.service.SearchService;
|
||||||
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
|
import com.example.copykamanotes.utils.SearchUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class SearchServiceImpl implements SearchService {
|
||||||
|
|
||||||
|
private final NoteMapper noteMapper;
|
||||||
|
private final UserMapper userMapper;
|
||||||
|
private final RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
private static final String NOTE_SEARCH_CACHE_KEY = "search:note:%s:%d:%d";
|
||||||
|
private static final String USER_SEARCH_CACHE_KEY = "search:user:%s:%d:%d";
|
||||||
|
private static final String NOTE_TAG_SEARCH_CACHE_KEY = "search:note:tag:%s:%s:%d:%d";
|
||||||
|
private static final long CACHE_EXPIRE_TIME = 30; // 分钟
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<List<Note>> searchNote(String keyword, int page, int pageSize) {
|
||||||
|
try {
|
||||||
|
String cacheKey = String.format(NOTE_SEARCH_CACHE_KEY, keyword, page, pageSize);
|
||||||
|
|
||||||
|
List<Note> cacheResult = (List<Note>) redisTemplate.opsForValue().get(cacheKey);
|
||||||
|
if (cacheResult != null) {
|
||||||
|
return ApiResponseUtils.success("搜索成功", cacheResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword = SearchUtils.preprocessKeyword(keyword);
|
||||||
|
|
||||||
|
int offset = (page - 1) * pageSize;
|
||||||
|
|
||||||
|
List<Note> notes = noteMapper.searchNotes(keyword, pageSize, offset);
|
||||||
|
|
||||||
|
redisTemplate.opsForValue().set(cacheKey, notes, CACHE_EXPIRE_TIME, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
return ApiResponseUtils.success("搜索成功", notes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("搜索失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<List<User>> searchUsers(String keyword, int page, int pageSize) {
|
||||||
|
try {
|
||||||
|
String cacheKey = String.format(NOTE_SEARCH_CACHE_KEY, keyword, page, pageSize);
|
||||||
|
|
||||||
|
List<User> cacheResult = (List<User>) redisTemplate.opsForValue().get(cacheKey);
|
||||||
|
if (cacheResult != null) {
|
||||||
|
return ApiResponseUtils.success("搜索成功", cacheResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword = SearchUtils.preprocessKeyword(keyword);
|
||||||
|
|
||||||
|
int offset = (page - 1) * pageSize;
|
||||||
|
|
||||||
|
List<User> users = userMapper.searchUsers(keyword, pageSize, offset);
|
||||||
|
|
||||||
|
redisTemplate.opsForValue().set(cacheKey, users, CACHE_EXPIRE_TIME, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
return ApiResponseUtils.success("搜索成功", users);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("搜索失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ApiResponse<List<Note>> searchNotesByTag(String keyword, String tag, int page, int pageSize) {
|
||||||
|
try {
|
||||||
|
String cacheKey = String.format(NOTE_SEARCH_CACHE_KEY, keyword, page, pageSize);
|
||||||
|
|
||||||
|
List<Note> cachedResult = (List<Note>) redisTemplate.opsForValue().get(cacheKey);
|
||||||
|
if (cachedResult != null) {
|
||||||
|
return ApiResponseUtils.success("搜索成功", cachedResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword = SearchUtils.preprocessKeyword(keyword);
|
||||||
|
|
||||||
|
int offset = (page - 1) * pageSize;
|
||||||
|
|
||||||
|
List<Note> notes = noteMapper.searchNotesByTag(keyword, tag, pageSize, offset);
|
||||||
|
|
||||||
|
redisTemplate.opsForValue().set(cacheKey, notes, CACHE_EXPIRE_TIME, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
return ApiResponseUtils.success("搜索成功", notes);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return ApiResponseUtils.error("搜索失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,15 +5,16 @@ import com.example.copykamanotes.model.vo.upload.ImageVO;
|
|||||||
import com.example.copykamanotes.service.FileService;
|
import com.example.copykamanotes.service.FileService;
|
||||||
import com.example.copykamanotes.service.UploadService;
|
import com.example.copykamanotes.service.UploadService;
|
||||||
import com.example.copykamanotes.utils.ApiResponseUtils;
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class UploadServiceImpl implements UploadService {
|
public class UploadServiceImpl implements UploadService {
|
||||||
|
|
||||||
@Autowired
|
private final FileService fileService;
|
||||||
private FileService fileService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ApiResponse<ImageVO> uploadImage(MultipartFile file) {
|
public ApiResponse<ImageVO> uploadImage(MultipartFile file) {
|
||||||
|
|||||||
@ -20,9 +20,9 @@ import com.example.copykamanotes.service.UserService;
|
|||||||
import com.example.copykamanotes.utils.ApiResponseUtils;
|
import com.example.copykamanotes.utils.ApiResponseUtils;
|
||||||
import com.example.copykamanotes.utils.JwtUtil;
|
import com.example.copykamanotes.utils.JwtUtil;
|
||||||
import com.example.copykamanotes.utils.PaginationUtils;
|
import com.example.copykamanotes.utils.PaginationUtils;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@ -31,30 +31,19 @@ import org.springframework.web.multipart.MultipartFile;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Log4j2
|
@Log4j2
|
||||||
@Service
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class UserServiceImpl implements UserService {
|
public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
@Autowired
|
private final UserMapper userMapper;
|
||||||
private UserMapper userMapper;
|
private final PasswordEncoder passwordEncoder;
|
||||||
|
private final JwtUtil jwtUtil;
|
||||||
@Autowired
|
private final RequestScopeData requestScopeData;
|
||||||
private PasswordEncoder passwordEncoder;
|
private final FileService fileService;
|
||||||
|
private final EmailService emailService;
|
||||||
@Autowired
|
|
||||||
private JwtUtil jwtUtil;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RequestScopeData requestScopeData;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private FileService fileService;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private EmailService emailService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@ -199,7 +188,7 @@ public class UserServiceImpl implements UserService {
|
|||||||
public Map<Long, User> getUserMapByIds(List<Long> authorIds) {
|
public Map<Long, User> getUserMapByIds(List<Long> authorIds) {
|
||||||
if (authorIds.isEmpty()) return Collections.emptyMap();
|
if (authorIds.isEmpty()) return Collections.emptyMap();
|
||||||
|
|
||||||
List<User> users = userMapper.findByIds(authorIds);
|
List<User> users = userMapper.findByIdBatch(authorIds);
|
||||||
|
|
||||||
return users.stream().collect(Collectors.toMap(User::getUserId, user -> user));
|
return users.stream().collect(Collectors.toMap(User::getUserId, user -> user));
|
||||||
}
|
}
|
||||||
@ -233,33 +222,4 @@ public class UserServiceImpl implements UserService {
|
|||||||
return ApiResponseUtils.error("上传失败");
|
return ApiResponseUtils.error("上传失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public ApiResponse<UserVO> updateUserPassword(String oldPassword, String newPassword) {
|
|
||||||
Long userId = requestScopeData.getUserId();
|
|
||||||
|
|
||||||
if (userId == null) {
|
|
||||||
return ApiResponseUtils.error("未登录");
|
|
||||||
}
|
|
||||||
|
|
||||||
User user = null;
|
|
||||||
user = userMapper.findById(userId);
|
|
||||||
if (user == null || !passwordEncoder.matches(oldPassword, user.getPassword())) {
|
|
||||||
return ApiResponseUtils.error("旧密码错误");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Objects.equals(oldPassword, newPassword)) {
|
|
||||||
return ApiResponseUtils.error("新密码不能与旧密码相同");
|
|
||||||
}
|
|
||||||
|
|
||||||
user.setPassword(passwordEncoder.encode(newPassword));
|
|
||||||
|
|
||||||
try {
|
|
||||||
userMapper.updatePassword(user.getUserId(), user.getPassword());
|
|
||||||
return ApiResponseUtils.success("更新密码成功");
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("更新密码失败", e);
|
|
||||||
return ApiResponseUtils.error("更新密码失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user