feat(model): 添加多个视图对象和 Redis 配置

- 新增 CategoryVO、CollectionVO、CommentVO 等多个视图对象
- 添加 RedisConfig 配置类
- 更新 RedisServiceImpl,移除不必要的 Qualifier 注解
- 修改 NoteMapper.xml,更新命名空间和结果映射
This commit is contained in:
LingandRX 2025-03-31 22:02:17 +08:00 committed by LingandRX
parent a550815308
commit 341aadfe5a
38 changed files with 1069 additions and 31 deletions

8
gradlew vendored
View File

@ -15,8 +15,6 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# #
# SPDX-License-Identifier: Apache-2.0
#
############################################################################## ##############################################################################
# #
@ -57,7 +55,7 @@
# Darwin, MinGW, and NonStop. # Darwin, MinGW, and NonStop.
# #
# (3) This script is generated from the Groovy template # (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project. # within the Gradle project.
# #
# You can find Gradle at https://github.com/gradle/gradle/. # You can find Gradle at https://github.com/gradle/gradle/.
@ -86,7 +84,7 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum
@ -205,7 +203,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command: # Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped. # and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line. # treated as '${Hostname}' itself on the command line.

22
gradlew.bat vendored
View File

@ -13,8 +13,6 @@
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@rem SPDX-License-Identifier: Apache-2.0
@rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%"=="" @echo off
@rem ########################################################################## @rem ##########################################################################
@ -45,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2 echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo. 1>&2 echo.
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. 1>&2 echo location of your Java installation.
goto fail goto fail
@ -59,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. 1>&2 echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. 1>&2 echo.
echo Please set the JAVA_HOME variable in your environment to match the 1>&2 echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. 1>&2 echo location of your Java installation.
goto fail goto fail

View File

@ -0,0 +1,32 @@
package com.example.copykamanotes.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 使用 String 序列化键key
template.setKeySerializer(new StringRedisSerializer());
// 使用 JSON 序列化值value
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// 使用 String 序列化哈希键hash key和值hash value
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
@Bean
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
}

View File

@ -0,0 +1,28 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.Category;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface CategoryMapper {
int insert(Category category);
int insertBatch(@Param("entities") List<Category> entities);
List<Category> categoryList(@Param("entities") List<Category> entities);
Category findById(@Param("id") Integer id);
Category findByIdBatch(@Param("ids") List<Integer> ids);
Category findByIdOrParentId(@Param("id") Integer id, @Param("parentId") Integer parentId);
int deleteById(@Param("id") Integer id);
int deleteByIdBatch(@Param("ids") List<Integer> ids);
int update(@Param("entities") Category category);
}

View File

@ -0,0 +1,71 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.Collection;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface CollectionMapper {
/**
* 根据ID查询收藏夹
*
* @param collectionId 收藏夹的ID
* @return 返回查询到的收藏夹对象
*/
Collection findById(@Param("collectionId") Integer collectionId);
/**
* 根据创建者 ID 查询收藏夹
*
* @param creatorId 创建者 ID
* @return 返回查询到的收藏夹列表
*/
List<Collection> findByCreatorId(@Param("creatorId") Long creatorId);
/**
* 根据收藏夹 ID 和创建者 ID 查询收藏夹
*
* @param collectionId 收藏夹 ID
* @param creatorId 创建者 ID
* @return 返回查询到的收藏夹对象
*/
Collection findByIdAndCreatorId(@Param("collectionId") Integer collectionId, @Param("creatorId") Long creatorId);
/**
* 根据收藏夹 ID创建者 ID 和笔记 ID 查询收藏夹
*
* @param collectionId 收藏夹 ID
* @param creatorId 创建者 ID
* @param noteId 笔记 ID
* @return 返回查询到的收藏夹对象
*/
int countByCreatorIdAndNoteId(
@Param("creatorId") Long creatorId,
@Param("noteId") Integer noteId);
/**
* 创建收藏夹
*
* @param collection 要创建的收藏夹对象
* @return 返回插入操作的影响行数
*/
int insert(Collection collection);
/**
* 更新收藏夹
*
* @param collection 要更新的收藏夹对象
* @return 返回更新操作的影响行数
*/
int update(Collection collection);
/**
* 删除收藏夹
*
* @param collectionId 要删除的收藏夹的ID
* @return 返回删除操作的影响行数
*/
int deleteById(@Param("collectionId") Integer collectionId);
}

View File

@ -0,0 +1,61 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.CollectionNote;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Set;
@Mapper
public interface CollectionNoteMapper {
/**
* 查询用户收藏的笔记 ID 列表
*
* @param userId 用户 ID
* @param noteIds 笔记 ID 列表
* @return 用户收藏的笔记 ID 列表
*/
List<Integer> findUserCollectedNoteIds(
@Param("userId") Long userId,
@Param("noteIds") List<Integer> noteIds
);
/**
* 筛选出所给的收藏夹 ID 列表中收藏了 noteId 对应的 note 的记录
*
* @param noteId 笔记 ID
* @param collectionIds 收藏夹 ID 列表
* @return 筛选结果
*/
Set<Integer> filterCollectionIdsByNoteId(
@Param("noteId") Integer noteId,
@Param("collectionIds") List<Integer> collectionIds);
/**
* 插入记录
*
* @param collectionNote 收藏笔记记录
* @return 插入记录数
*/
int insert(CollectionNote collectionNote);
/**
* 根据 collectionId 删除记录
*
* @param collectionId 收藏夹 ID
* @return 删除记录数
*/
int deleteByCollectionId(@Param("collectionId") Integer collectionId);
/**
* 根据 collectionId noteId 删除记录
*
* @param collectionId 收藏夹 ID
* @param noteId 笔记 ID
* @return 删除记录数
*/
int deleteByCollectionIdAndNoteId(
@Param("collectionId") Integer collectionId,
@Param("noteId") Integer noteId);
}

View File

@ -0,0 +1,44 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.CommentLike;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Set;
/**
* 评论点赞Mapper接口
*/
@Mapper
public interface CommentLikeMapper {
/**
* 插入评论点赞
*
* @param commentLike 评论点赞实体
*/
void insert(CommentLike commentLike);
/**
* 删除评论点赞
*
* @param commentId 评论ID
* @param userId 用户ID
*/
void delete(@Param("commentId") Integer commentId, @Param("userId") Long userId);
/**
* 查询用户点赞的评论ID列表
*
* @param userId 用户ID
* @param commentIds 评论ID列表
* @return 用户点赞的评论ID集合
*/
Set<Integer> findUserLikedCommentIds(@Param("userId") Long userId,
@Param("commentIds") List<Integer> commentIds);
@Select("SELECT COUNT(*) > 0 FROM comment_like " +
"WHERE user_id = #{userId} AND comment_id = #{commentId}")
Boolean checkIsLiked(@Param("userId") Long userId, @Param("commentId") Integer commentId);
}

View File

@ -0,0 +1,91 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.dto.comment.CommentQueryParams;
import com.example.copykamanotes.model.entity.Comment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 评论Mapper接口
*/
@Mapper
public interface CommentMapper {
/**
* 插入评论
*
* @param comment 评论实体
*/
void insert(Comment comment);
/**
* 更新评论
*
* @param comment 评论实体
*/
void update(Comment comment);
/**
* 删除评论
*
* @param commentId 评论ID
*/
void deleteById(Integer commentId);
/**
* 根据ID查询评论
*
* @param commentId 评论ID
* @return 评论实体
*/
Comment findById(Integer commentId);
/**
* 查询评论列表
*
* @param params 查询参数
* @param pageSize 每页大小
* @param offset 偏移量
* @return 评论列表
*/
List<Comment> findByQueryParam(@Param("params") CommentQueryParams params,
@Param("pageSize") Integer pageSize,
@Param("offset") Integer offset);
/**
* 统计评论数量
*
* @param params 查询参数
* @return 评论数量
*/
int countByQueryParam(@Param("params") CommentQueryParams params);
/**
* 增加评论点赞数
*
* @param commentId 评论ID
*/
void incrementLikeCount(Integer commentId);
/**
* 减少评论点赞数
*
* @param commentId 评论ID
*/
void decrementLikeCount(Integer commentId);
/**
* 增加评论回复数
*
* @param commentId 评论ID
*/
void incrementReplyCount(Integer commentId);
/**
* 减少评论回复数
*
* @param commentId 评论ID
*/
void decrementReplyCount(Integer commentId);
}

View File

@ -0,0 +1,47 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.NoteCollect;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 笔记收藏Mapper接口
*/
@Mapper
public interface NoteCollectMapper {
/**
* 插入收藏记录
*
* @param noteCollect 收藏记录
* @return 影响的行数
*/
int insert(NoteCollect noteCollect);
/**
* 删除收藏记录
*
* @param noteId 笔记ID
* @param userId 用户ID
* @return 影响的行数
*/
int delete(@Param("noteId") Integer noteId, @Param("userId") Long userId);
/**
* 查找收藏记录
*
* @param noteId 笔记ID
* @param userId 用户ID
* @return 收藏记录
*/
NoteCollect findByNoteIdAndUserId(@Param("noteId") Integer noteId, @Param("userId") Long userId);
/**
* 获取用户收藏的笔记ID列表
*
* @param userId 用户ID
* @return 笔记ID列表
*/
List<Integer> findNoteIdsByUserId(@Param("userId") Long userId);
}

View File

@ -0,0 +1,31 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.NoteComment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface NoteCommentMapper {
/**
* 插入评论
*/
void insert(NoteComment comment);
/**
* 更新评论
*/
void update(NoteComment comment);
/**
* 根据ID查询评论
*/
NoteComment findById(@Param("id") Integer id);
/**
* 查询笔记的评论列表
*/
List<NoteComment> findByNoteId(@Param("noteId") Integer noteId);
}

View File

@ -0,0 +1,79 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.QuestionListItem;
import com.example.copykamanotes.model.vo.questionListItem.QuestionListItemVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface QuestionListItemMapper {
/**
* 插入一个题单项
*
* @param questionListItem 题单项对象包含需要插入的题单项的信息
* @return 影响的行数表示插入操作是否成功
*/
int insert(QuestionListItem questionListItem);
/**
* 根据题单ID查找题单项
*
* @param questionListId 题单的唯一标识符
* @return 返回一个包含题单项的列表如果找不到对应的项则返回空列表
*/
List<QuestionListItemVO> findByQuestionListId(@Param("questionListId") Integer questionListId);
/**
* 根据题单ID查找题单项的数量
*
* @param questionListId 题单的ID用于标识要查找的题单项数量
* @return 返回题单项的数量
*/
int countByQuestionListId(@Param("questionListId") Integer questionListId);
/**
* 根据题单ID查找题单项分页
*
* @param questionListId 题单的ID用于标识要查找的题单项
* @param limit 每页显示的记录数
* @param offset 从第几条记录开始查询
*/
List<QuestionListItemVO> findByQuestionListIdPage(@Param("questionListId") Integer questionListId,
@Param("limit") Integer limit,
@Param("offset") Integer offset);
/**
* 根据题单ID删除题单项
*
* @param questionListId 题单的ID用于标识要删除的题单项
* @return 影响的行数表示删除操作是否成功
*/
int deleteByQuestionListId(Integer questionListId);
/**
* 根据题单ID和题目ID删除题单项
*
* @param questionListId 题单的ID用于标识要删除的题单项
* @param questionId 题目的ID用于标识要删除的题单项
* @return 影响的行数表示删除操作是否成功
*/
int deleteByQuestionListIdAndQuestionId(@Param("questionListId") Integer questionListId, @Param("questionId") Integer questionId);
/**
* 根据题单ID获取下一个序号
*
* @param questionListId 题单的ID
* @return 返回下一个序号
*/
int nextRank(Integer questionListId);
/**
* 更新题单项的序号
*
* @param questionListItem 新顺序的题单项
* @return 影响的行数表示更新操作是否成功
*/
int updateQuestionRank(QuestionListItem questionListItem);
}

View File

@ -0,0 +1,31 @@
package com.example.copykamanotes.mapper;
import com.example.copykamanotes.model.entity.Statistic;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface StatisticMapper {
/**
* 添加统计数据
* @param statistic 统计数据
* @return 添加的记录数
*/
int insert(Statistic statistic);
/**
* 获取统计数据的 total
* @return total
*/
int countStatistic();
/**
* 查询统计数据
* @param limit 限制
* @param offset 偏移
* @return 统计数据
*/
List<Statistic> findByPage(@Param("limit") Integer limit, @Param("offset") Integer offset);
}

View File

@ -0,0 +1,42 @@
package com.example.copykamanotes.model.dto.comment;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
/**
* 评论查询参数
*/
@Data
public class CommentQueryParams {
/**
* 笔记ID
*/
@NotNull(message = "笔记ID不能为空")
private Integer noteId;
/**
* 父评论ID
*/
private Integer parentId;
/**
* 作者ID
*/
private Long authorId;
/**
* 页码
*/
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码必须大于0")
private Integer page;
/**
* 每页大小
*/
@NotNull(message = "每页大小不能为空")
@Min(value = 1, message = "每页大小必须大于0")
private Integer pageSize;
}

View File

@ -0,0 +1,19 @@
package com.example.copykamanotes.model.vo.category;
import lombok.Data;
import java.util.List;
@Data
public class CategoryVO {
private Integer categoryId;
private String name;
private Integer parentCategoryId;
private List<ChildrenCategoryVO> children;
@Data
public static class ChildrenCategoryVO {
private Integer categoryId;
private String name;
private Integer parentCategoryId;
}
}

View File

@ -0,0 +1,8 @@
package com.example.copykamanotes.model.vo.category;
import lombok.Data;
@Data
public class CreateCategoryVO {
private Integer categoryId;
}

View File

@ -0,0 +1,21 @@
package com.example.copykamanotes.model.vo.collection;
import lombok.Data;
@Data
public class CollectionVO {
private Integer collectionId;
private String name;
private String description;
/**
* 查询收藏夹时可能会携带的 noteId 参数这个 noteStatus 可以用来判断该 note 是否被收藏
*/
private NoteStatus noteStatus;
@Data
public static class NoteStatus {
private Integer noteId;
private Boolean isCollected;
}
}

View File

@ -0,0 +1,8 @@
package com.example.copykamanotes.model.vo.collection;
import lombok.Data;
@Data
public class CreateCollectionVO {
private Integer collectionId;
}

View File

@ -0,0 +1,73 @@
package com.example.copykamanotes.model.vo.comment;
import com.example.copykamanotes.model.vo.user.UserActionVO;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* 评论视图对象
*/
@Data
public class CommentVO {
/**
* 评论ID
*/
private Integer commentId;
/**
* 笔记ID
*/
private Integer noteId;
/**
* 评论内容
*/
private String content;
/**
* 点赞数
*/
private Integer likeCount;
/**
* 回复数
*/
private Integer replyCount;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 更新时间
*/
private LocalDateTime updatedAt;
/**
* 作者信息
*/
private SimpleAuthorVO author;
/**
* 用户操作信息
*/
private UserActionVO userActions;
/**
* 回复列表
*/
private List<CommentVO> replies;
/**
* 简单作者信息
*/
@Data
public static class SimpleAuthorVO {
private Long userId;
private String username;
private String avatarUrl;
}
}

View File

@ -0,0 +1,55 @@
package com.example.copykamanotes.model.vo.message;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 消息视图对象
*/
@Data
public class MessageVO {
/**
* 消息ID
*/
private Integer messageId;
/**
* 发送者信息
*/
private SimpleUserVO sender;
/**
* 消息类型
*/
private String type;
/**
* 目标ID
*/
private Integer targetId;
/**
* 消息内容
*/
private String content;
/**
* 是否已读
*/
private Boolean isRead;
/**
* 创建时间
*/
private LocalDateTime createdAt;
/**
* 简单用户信息
*/
@Data
public static class SimpleUserVO {
private Long userId;
private String username;
private String avatarUrl;
}
}

View File

@ -0,0 +1,16 @@
package com.example.copykamanotes.model.vo.message;
import lombok.Data;
@Data
public class UnreadCountByType {
/**
* 消息类型
*/
private String type;
/**
* 未读数量
*/
private Integer count;
}

View File

@ -0,0 +1,12 @@
package com.example.copykamanotes.model.vo.note;
import lombok.Data;
import java.time.LocalDate;
@Data
public class NoteHeatMapItem {
private LocalDate date;
private Integer count;
private Integer rank;
}

View File

@ -0,0 +1,12 @@
package com.example.copykamanotes.model.vo.note;
import lombok.Data;
@Data
public class NoteRankListItem {
private Long userId;
private String username;
private String avatarUrl;
private Integer noteCount;
private Integer rank;
}

View File

@ -0,0 +1,9 @@
package com.example.copykamanotes.model.vo.note;
import lombok.Data;
@Data
public class Top3Count {
private Integer lastMonthTop3Count;
private Integer thisMonthTop3Count;
}

View File

@ -0,0 +1,8 @@
package com.example.copykamanotes.model.vo.notification;
import lombok.Data;
@Data
public class NotificationVO {
private String content;
}

View File

@ -0,0 +1,38 @@
package com.example.copykamanotes.model.vo.question;
import lombok.Data;
@Data
public class BaseQuestionVO {
/*
* 问题ID主键
*/
private Integer questionId;
/*
* 问题所属分类ID
*/
private Integer categoryId;
/*
* 问题标题
*/
private String title;
/*
* 问题难度
* 1=简单2=中等3=困难
*/
private Integer difficulty;
/*
* 题目考点
*/
private String examPoint;
/*
* 浏览量
*/
private Integer viewCount;
}

View File

@ -0,0 +1,8 @@
package com.example.copykamanotes.model.vo.question;
import lombok.Data;
@Data
public class CreateQuestionVO {
private Integer questionId;
}

View File

@ -0,0 +1,53 @@
package com.example.copykamanotes.model.vo.question;
import lombok.Data;
@Data
public class QuestionNoteVO {
/*
* 问题ID主键
*/
private Integer questionId;
/*
* 问题标题
*/
private String title;
/*
* 问题难度
* 1=简单2=中等3=困难
*/
private Integer difficulty;
/*
* 题目考点
*/
private String examPoint;
/*
* 浏览量
*/
private Integer viewCount;
/**
* 关于这道题用户的详细信息
*/
private UserNote userNote;
@Data
public static class UserNote {
/*
* 是否完成
*/
private boolean finished = false;
/**
* noteId
*/
private Integer noteId;
/**
* 笔记内容
*/
private String content;
}
}

View File

@ -0,0 +1,43 @@
package com.example.copykamanotes.model.vo.question;
import lombok.Data;
// 用于普通用户查询携带个人信息的问题 VO
@Data
public class QuestionUserVO {
/*
* 问题ID主键
*/
private Integer questionId;
/*
* 问题标题
*/
private String title;
/*
* 问题难度
* 1=简单2=中等3=困难
*/
private Integer difficulty;
/*
* 题目考点
*/
private String examPoint;
/*
* 浏览量
*/
private Integer viewCount;
/**
* 用户问题状态
*/
private UserQuestionStatus userQuestionStatus;
@Data
public static class UserQuestionStatus {
private boolean finished = false; // 用户是否完成过这道题
}
}

View File

@ -0,0 +1,18 @@
package com.example.copykamanotes.model.vo.question;
import lombok.Data;
import java.time.LocalDateTime;
// 用于管理员批量查询题目
@Data
public class QuestionVO {
private Integer questionId;
private Integer categoryId;
private String title;
private Integer difficulty;
private String examPoint;
private Integer viewCount;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}

View File

@ -0,0 +1,9 @@
package com.example.copykamanotes.model.vo.question;
import lombok.Data;
@Data
public class SimpleQuestionVO {
private Integer questionId;
private String title;
}

View File

@ -0,0 +1,8 @@
package com.example.copykamanotes.model.vo.questionList;
import lombok.Data;
@Data
public class CreateQuestionListVO {
private Integer questionListId;
}

View File

@ -0,0 +1,5 @@
package com.example.copykamanotes.model.vo.questionList;
public class QuestionListVO {
}

View File

@ -0,0 +1,8 @@
package com.example.copykamanotes.model.vo.questionListItem;
import lombok.Data;
@Data
public class CreateQuestionListItemVO {
private Integer rank;
}

View File

@ -0,0 +1,32 @@
package com.example.copykamanotes.model.vo.questionListItem;
import com.example.copykamanotes.model.vo.question.BaseQuestionVO;
import lombok.Data;
@Data
public class QuestionListItemUserVO {
/**
* 题单ID联合主键
*/
private Integer questionListId;
/**
* 题目ID联合主键
*/
private BaseQuestionVO question;
/**
* 用户是否完成了这道题
*/
private UserQuestionStatus userQuestionStatus;
/*
* 题单内题目的顺序从1开始
*/
private Integer rank;
@Data
public static class UserQuestionStatus {
private boolean finished;
}
}

View File

@ -0,0 +1,23 @@
package com.example.copykamanotes.model.vo.questionListItem;
import com.example.copykamanotes.model.vo.question.BaseQuestionVO;
import lombok.Data;
@Data
public class QuestionListItemVO {
/*
* 题单ID联合主键
*/
private Integer questionListId;
/*
* 题目ID联合主键
*/
private BaseQuestionVO question;
/*
* 题单内题目的顺序从1开始
*/
private Integer rank;
}

View File

@ -2,7 +2,6 @@ package com.example.copykamanotes.service.impl;
import com.example.copykamanotes.service.RedisService; import com.example.copykamanotes.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@ -7,8 +7,8 @@ spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
server.port= 19090 server.port= 19090
# Redis?? # Redis
spring.data.redis.host=127.0.0.1 spring.data.redis.host=localhost
spring.data.redis.port=6379 spring.data.redis.port=6379
spring.data.redis.database=0 spring.data.redis.database=0
spring.data.redis.timeout=3000 spring.data.redis.timeout=3000

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kama.notes.mapper.NoteMapper"> <mapper namespace="com.example.copykamanotes.mapper.NoteMapper">
<sql id="whereClause"> <sql id="whereClause">
<where> <where>
@ -24,7 +24,7 @@
<include refid="whereClause"/> <include refid="whereClause"/>
</select> </select>
<select id="findByQueryParams" resultType="com.kama.notes.model.entity.Note"> <select id="findByQueryParams" resultType="com.example.copykamanotes.model.entity.Note">
SELECT * FROM note SELECT * FROM note
<include refid="whereClause"/> <include refid="whereClause"/>
<choose> <choose>
@ -58,14 +58,14 @@
</if> </if>
</select> </select>
<select id="findByAuthorIdAndQuestionId" resultType="com.kama.notes.model.entity.Note"> <select id="findByAuthorIdAndQuestionId" resultType="com.example.copykamanotes.model.entity.Note">
SELECT * SELECT *
FROM note FROM note
WHERE question_id = #{questionId} WHERE question_id = #{questionId}
AND author_id = #{authorId} AND author_id = #{authorId}
</select> </select>
<select id="findByAuthorId" resultType="com.kama.notes.model.entity.Note"> <select id="findByAuthorId" resultType="com.example.copykamanotes.model.entity.Note">
SELECT * SELECT *
FROM note FROM note
WHERE author_id = #{authorId} WHERE author_id = #{authorId}
@ -76,7 +76,7 @@
VALUES (#{questionId}, #{authorId}, #{content}) VALUES (#{questionId}, #{authorId}, #{content})
</insert> </insert>
<resultMap id="BaseResultMap" type="com.kama.notes.model.entity.Note"> <resultMap id="BaseResultMap" type="com.example.copykamanotes.model.entity.Note">
<id column="note_id" property="noteId"/> <id column="note_id" property="noteId"/>
<result column="author_id" property="authorId"/> <result column="author_id" property="authorId"/>
<result column="question_id" property="questionId"/> <result column="question_id" property="questionId"/>
@ -128,13 +128,13 @@
WHERE note_id = #{noteId} WHERE note_id = #{noteId}
</delete> </delete>
<select id="findCollections" resultType="com.kama.notes.model.entity.Collection"> <select id="findCollections" resultType="com.example.copykamanotes.model.entity.Collection">
SELECT * SELECT *
FROM collection FROM collection
WHERE collection_id = #{collectionId} WHERE collection_id = #{collectionId}
</select> </select>
<resultMap id="NoteRankListItemMap" type="com.kama.notes.model.vo.note.NoteRankListItem"> <resultMap id="NoteRankListItemMap" type="com.example.copykamanotes.model.vo.note.NoteRankListItem">
<result property="userId" column="author_id"/> <result property="userId" column="author_id"/>
<result property="username" column="username"/> <result property="username" column="username"/>
<result property="avatarUrl" column="avatar_url"/> <result property="avatarUrl" column="avatar_url"/>
@ -155,7 +155,7 @@
ORDER BY author_notes_count DESC LIMIT 10 ORDER BY author_notes_count DESC LIMIT 10
</select> </select>
<resultMap id="submitNoteHeatMapMap" type="com.kama.notes.model.vo.note.NoteHeatMapItem"> <resultMap id="submitNoteHeatMapMap" type="com.example.copykamanotes.model.vo.note.NoteHeatMapItem">
<result property="count" column="note_count"/> <result property="count" column="note_count"/>
<result property="date" column="note_date"/> <result property="date" column="note_date"/>
<result property="rank" column="note_rank"/> <result property="rank" column="note_rank"/>
@ -185,7 +185,7 @@
WHERE author_id = #{authorId}; WHERE author_id = #{authorId};
</select> </select>
<resultMap id="submitNoteTop3CountMap" type="com.kama.notes.model.vo.note.Top3Count"> <resultMap id="submitNoteTop3CountMap" type="com.example.copykamanotes.model.vo.note.Top3Count">
<result property="thisMonthTop3Count" column="this_month_top_3"/> <result property="thisMonthTop3Count" column="this_month_top_3"/>
<result property="lastMonthTop3Count" column="last_month_top_3"/> <result property="lastMonthTop3Count" column="last_month_top_3"/>
</resultMap> </resultMap>
@ -268,7 +268,7 @@
</update> </update>
<!-- 搜索笔记 --> <!-- 搜索笔记 -->
<select id="searchNotes" resultType="com.kama.notes.model.entity.Note"> <select id="searchNotes" resultType="com.example.copykamanotes.model.entity.Note">
SELECT SELECT
n.*, n.*,
MATCH(n.search_vector) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) as relevance MATCH(n.search_vector) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) as relevance
@ -279,7 +279,7 @@
</select> </select>
<!-- 根据标签搜索笔记 --> <!-- 根据标签搜索笔记 -->
<select id="searchNotesByTag" resultType="com.kama.notes.model.entity.Note"> <select id="searchNotesByTag" resultType="com.example.copykamanotes.model.entity.Note">
SELECT DISTINCT SELECT DISTINCT
n.*, n.*,
MATCH(n.search_vector) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) as relevance MATCH(n.search_vector) AGAINST(#{keyword} IN NATURAL LANGUAGE MODE) as relevance