From effcc3838d03e9e093388ea2422b30214a1fa0f1 Mon Sep 17 00:00:00 2001 From: qingfeng1121 Date: Sun, 19 Oct 2025 11:11:56 +0800 Subject: [PATCH] =?UTF-8?q?refactor(pojo):=20=E4=BF=AE=E6=AD=A3Article?= =?UTF-8?q?=E7=B1=BB=E4=B8=ADattributeid=E5=AD=97=E6=AE=B5=E7=9A=84?= =?UTF-8?q?=E5=88=97=E5=90=8D=E6=8B=BC=E5=86=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(controller): 在ArticleController中添加根据属性ID获取文章的方法 style(repository): 在CategoryRepository方法上添加空行提高可读性 chore: 移除MyAfterProjecyApplication中多余的MapperScan注解 --- README_API.md | 136 ++++++-- logs/web_project.log | 294 ++++++++++++++++++ .../MyAfterProjecyApplication.java | 1 - .../controller/ArticleController.java | 80 ++--- .../CategoryAttributeController.java | 1 + .../com/qf/myafterprojecy/pojo/Article.java | 2 +- .../myafterprojecy/pojo/dto/ArticleDto.java | 3 + .../repository/CategoryRepository.java | 1 + 8 files changed, 457 insertions(+), 61 deletions(-) diff --git a/README_API.md b/README_API.md index 0771f9d..8fa89a3 100644 --- a/README_API.md +++ b/README_API.md @@ -2,7 +2,7 @@ ## 项目概述 -MyAfterProject是一个基于Spring Boot的后端博客系统,提供文章管理、留言板等功能的API接口。本文档旨在帮助前端开发者理解和使用这些API接口。 +MyAfterProject是一个基于Spring Boot的后端博客系统,提供文章管理、留言板等功能的RESTful API接口。系统集成了Spring Security和JWT认证机制,确保API的安全性和权限控制。本文档旨在帮助前端开发者理解和使用这些API接口,包括接口规范、请求/响应格式、认证方式及最佳实践。 ## 技术栈 @@ -10,8 +10,10 @@ MyAfterProject是一个基于Spring Boot的后端博客系统,提供文章管 - **ORM框架**: Spring Data JPA - **数据库**: MySQL - **缓存**: Redis -- **认证**: Spring Security + JWT -- **API风格**: RESTful +- **认证授权**: Spring Security + JWT Token +- **API风格**: RESTful API +- **错误处理**: 全局异常处理机制 +- **权限控制**: 基于角色的访问控制(RBAC) ## 项目结构 @@ -19,29 +21,45 @@ MyAfterProject是一个基于Spring Boot的后端博客系统,提供文章管 src/main/java/com/qf/myafterprojecy/ ├── controller/ # 控制器层,处理HTTP请求 │ ├── ArticleController.java # 文章相关API -│ └── MessageController.java # 留言相关API +│ ├── MessageController.java # 留言相关API +│ └── AuthController.java # 认证相关API ├── pojo/ # 实体类和数据传输对象 -│ ├── Article.java # 文章实体 -│ ├── Message.java # 留言实体 -│ ├── ResponseMessage.java # 统一响应消息格式 -│ └── dto/ # 数据传输对象 -│ ├── ArticleDto.java # 文章DTO -│ └── MessageDto.java # 留言DTO +│ ├── Article.java # 文章实体 +│ ├── Message.java # 留言实体 +│ ├── User.java # 用户实体 +│ ├── Role.java # 角色实体 +│ ├── ResponseMessage.java # 统一响应消息格式 +│ └── dto/ # 数据传输对象 +│ ├── ArticleDto.java # 文章DTO +│ └── MessageDto.java # 留言DTO ├── repository/ # 数据访问层 -│ ├── ArticleRepository.java # 文章数据访问 -│ └── MessageRepository.java # 留言数据访问 +│ ├── ArticleRepository.java # 文章数据访问 +│ ├── MessageRepository.java # 留言数据访问 +│ ├── UserRepository.java # 用户数据访问 +│ └── RoleRepository.java # 角色数据访问 ├── service/ # 业务逻辑层 -│ ├── ArticleService.java # 文章服务实现 -│ ├── IArticleService.java # 文章服务接口 -│ ├── MessageService.java # 留言服务实现 -│ └── IMessageService.java # 留言服务接口 +│ ├── ArticleService.java # 文章服务实现 +│ ├── IArticleService.java # 文章服务接口 +│ ├── MessageService.java # 留言服务实现 +│ └── IMessageService.java # 留言服务接口 +├── config/ # 配置类 +│ ├── SecurityConfig.java # Spring Security配置 +│ └── security/ # 安全相关组件 +│ ├── JwtTokenProvider.java # JWT令牌生成器 +│ ├── JwtAuthenticationFilter.java # JWT认证过滤器 +│ └── UserDetailsServiceImpl.java # 用户认证服务 ├── GlobalExceptionHandler.java # 全局异常处理器 └── MyAfterProjecyApplication.java # 应用入口 ``` ## 配置信息 -后端服务默认运行在 `http://localhost:8080` 端口,前端项目需要将API请求指向该地址。 +- **服务地址**: `http://localhost:8080` +- **API基础路径**: `/api` +- **认证头**: `Authorization: Bearer {token}` +- **默认测试账号**: + - 作者账号: `test_author` / `password123` (拥有AUTHOR角色) + - 管理员账号: `test_admin` / `admin123` (拥有ADMIN角色) ## API接口详细说明 @@ -178,7 +196,10 @@ POST /api/articles **功能**: 创建新文章 -**权限**: 需要AUTHOR角色 +**权限**: 需要AUTHOR角色 (通过`@PreAuthorize("hasRole('AUTHOR')")`控制) + +**请求头**: +- `Authorization: Bearer {token}` (必需) **请求体**: ```json @@ -213,7 +234,10 @@ PUT /api/articles/{id} **功能**: 更新现有文章 -**权限**: 需要AUTHOR或ADMIN角色 +**权限**: 需要AUTHOR角色 (通过`@PreAuthorize("hasRole('AUTHOR')")`控制) + +**请求头**: +- `Authorization: Bearer {token}` (必需) **请求参数**: - `id`: 文章ID(路径参数) @@ -248,7 +272,10 @@ DELETE /api/articles/{id} **功能**: 删除指定文章 -**权限**: 需要AUTHOR或ADMIN角色 +**权限**: 需要AUTHOR或ADMIN角色 (通过`@PreAuthorize("hasRole('AUTHOR') or hasRole('ADMIN')")`控制) + +**请求头**: +- `Authorization: Bearer {token}` (必需) **请求参数**: - `id`: 文章ID(路径参数) @@ -362,6 +389,9 @@ DELETE /api/messages/{id} **权限**: 需要ADMIN角色 +**请求头**: +- `Authorization: Bearer {token}` (必需) + **请求参数**: - `id`: 留言ID(路径参数) @@ -411,6 +441,64 @@ DTO类用于前后端数据传输,是对实体类的简化,只包含需要 - **ArticleDto**: 包含文章的基本信息,用于创建和更新文章 - **MessageDto**: 包含留言的基本信息,用于创建和更新留言 +- **LoginRequest**: 登录请求参数 +- **SignupRequest**: 注册请求参数 +- **JwtResponse**: JWT认证响应 + +## 认证与授权 + +系统使用JWT (JSON Web Token) 进行身份认证。在访问需要授权的API接口时,前端需要在请求头中包含有效的JWT令牌。 + +### 获取JWT令牌 + +``` +POST /api/auth/signin +``` + +**功能**: 用户登录并获取JWT令牌 + +**请求体**: +```json +{ + "username": "test_author", + "password": "password123" +} +``` + +**返回数据**: +```json +{ + "code": 200, + "message": "登录成功", + "success": true, + "data": { + "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "type": "Bearer", + "id": 1, + "username": "test_author", + "email": "author@example.com", + "roles": ["ROLE_AUTHOR"] + } +} +``` + +### 用户注册 + +``` +POST /api/auth/signup +``` + +**功能**: 用户注册新账号 + +**请求体**: +```json +{ + "username": "新用户名", + "email": "user@example.com", + "password": "密码123", + "role": "author" // 可选值: user, author, admin +} +``` ## 前端调用示例 @@ -438,6 +526,14 @@ const api = axios.create({ } }); +// 认证相关API +export const authAPI = { + // 用户登录 + login: (credentials) => api.post('/auth/signin', credentials), + // 用户注册 + register: (userData) => api.post('/auth/signup', userData) +}; + // 请求拦截器 - 添加认证token api.interceptors.request.use( config => { diff --git a/logs/web_project.log b/logs/web_project.log index 31ef676..079bfb8 100644 --- a/logs/web_project.log +++ b/logs/web_project.log @@ -968,3 +968,297 @@ Caused by: org.hibernate.QueryException: could not resolve property: typeid of: at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:276) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:192) ... 91 common frames omitted +2025-10-16 16:41:18 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Starting MyAfterProjecyApplication using Java 1.8.0_461 on DESKTOP-8G5GS0I with PID 31448 (E:\MyWebProject\MyAfterProjecy\target\classes started by 30803 in E:\MyWebProject\MyAfterProjecy) +2025-10-16 16:41:18 [restartedMain] DEBUG c.q.m.MyAfterProjecyApplication - Running with Spring Boot v2.6.13, Spring v5.3.23 +2025-10-16 16:41:18 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - No active profile set, falling back to 1 default profile: "default" +2025-10-16 16:41:18 [restartedMain] INFO o.s.b.d.e.DevToolsPropertyDefaultsPostProcessor - Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable +2025-10-16 16:41:18 [restartedMain] INFO o.s.b.d.e.DevToolsPropertyDefaultsPostProcessor - For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG' +2025-10-16 16:41:18 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-10-16 16:41:18 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 48 ms. Found 4 JPA repository interfaces. +2025-10-16 16:41:19 [restartedMain] WARN o.m.s.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.qf.myafterprojecy]' package. Please check your configuration. +2025-10-16 16:41:19 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http) +2025-10-16 16:41:19 [restartedMain] INFO o.a.catalina.core.StandardService - Starting service [Tomcat] +2025-10-16 16:41:19 [restartedMain] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.68] +2025-10-16 16:41:19 [restartedMain] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext +2025-10-16 16:41:19 [restartedMain] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 1360 ms +2025-10-16 16:41:19 [restartedMain] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default] +2025-10-16 16:41:19 [restartedMain] INFO org.hibernate.Version - HHH000412: Hibernate ORM core version 5.6.12.Final +2025-10-16 16:41:20 [restartedMain] INFO o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.2.Final} +2025-10-16 16:41:20 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Starting... +2025-10-16 16:41:20 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Start completed. +2025-10-16 16:41:20 [restartedMain] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect +2025-10-16 16:41:21 [restartedMain] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] +2025-10-16 16:41:21 [restartedMain] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-10-16 16:41:22 [restartedMain] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration - + +Using generated security password: e8814a4c-8fc8-484c-9843-05e3327fe275 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-10-16 16:41:22 [restartedMain] INFO o.s.s.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@4c6343c, org.springframework.security.web.context.SecurityContextPersistenceFilter@205a03b4, org.springframework.security.web.header.HeaderWriterFilter@5d32430e, org.springframework.security.web.authentication.logout.LogoutFilter@d7acc06, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@5c4d0c68, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@5570d9fd, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@7357e1f4, org.springframework.security.web.access.ExceptionTranslationFilter@abf2f25, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@7f6072c9] +2025-10-16 16:41:22 [restartedMain] INFO o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html] +2025-10-16 16:41:23 [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729 +2025-10-16 16:41:23 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path '' +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Started MyAfterProjecyApplication in 5.335 seconds (JVM running for 6.173) +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.CategoryDataInit - ===== 分类数据初始化开始 ===== +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.CategoryDataInit - 当前数据库中分类数量: 4 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.CategoryDataInit - 数据库中已存在分类数据,无需初始化 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.CategoryDataInit - ===== 分类数据初始化结束 ===== +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.MessageDataInit - ===== 消息数据初始化开始 ===== +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.MessageDataInit - 当前数据库中消息数量: 6 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.MessageDataInit - 数据库中已存在消息数据,无需初始化 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.init.MessageDataInit - ===== 消息数据初始化结束 ===== +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 消息数据检查器开始运行 ===== +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 当前数据库中消息数量: 6 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 测试Repository查询方法 ===== +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 文章ID为1的消息数量: 0 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 根消息数量: 3 +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%张%] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [CHAR] - [\] +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 昵称包含'张'的消息数量: 1 +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 文章ID为1的评论数量: 0 +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 消息ID为1的回复数量: 1 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 测试Service层方法 ===== +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 查询所有消息 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取所有消息: 成功=true, 消息数量=6 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 根据ID查询消息: 1 +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 根据ID1获取消息: 成功=true, 昵称=张三 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 获取文章评论数量: 1 +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取文章ID为1的评论数量: 成功=true, 数量=0 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 查询所有根消息 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取根消息: 成功=true, 数量=3 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 保存消息: 测试用户 +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [这是一条测试消息] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [3] as [TIMESTAMP] - [Thu Oct 16 16:41:23 CST 2025] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - [test@example.com] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [5] as [VARCHAR] - [测试用户] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [6] as [INTEGER] - [null] +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 消息保存成功: 53 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 保存新消息: 成功=true, 消息ID=53 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 删除消息: 53 +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [53] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [53] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [53] +2025-10-16 16:41:23 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [53] +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.service.MessageService - 消息删除成功: 53 +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 删除消息ID53: 成功=true +2025-10-16 16:41:23 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 消息数据检查器运行结束 ===== +2025-10-16 16:41:30 [File Watcher] INFO o.s.b.d.a.LocalDevToolsAutoConfiguration$RestartingClassPathChangeChangedEventListener - Restarting due to 33 class path changes (0 additions, 33 deletions, 0 modifications) +2025-10-16 16:41:30 [Thread-16] INFO o.a.catalina.core.StandardService - Stopping service [Tomcat] +2025-10-16 16:41:30 [Thread-16] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default' +2025-10-16 16:41:30 [Thread-16] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown initiated... +2025-10-16 16:41:30 [Thread-16] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown completed. +2025-10-16 16:41:31 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Starting MyAfterProjecyApplication using Java 1.8.0_461 on DESKTOP-8G5GS0I with PID 31448 (E:\MyWebProject\MyAfterProjecy\target\classes started by 30803 in E:\MyWebProject\MyAfterProjecy) +2025-10-16 16:41:31 [restartedMain] DEBUG c.q.m.MyAfterProjecyApplication - Running with Spring Boot v2.6.13, Spring v5.3.23 +2025-10-16 16:41:31 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - No active profile set, falling back to 1 default profile: "default" +2025-10-16 16:41:31 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-10-16 16:41:31 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 0 ms. Found 0 JPA repository interfaces. +2025-10-16 16:41:31 [restartedMain] WARN o.m.s.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.qf.myafterprojecy]' package. Please check your configuration. +2025-10-16 16:41:31 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http) +2025-10-16 16:41:31 [restartedMain] INFO o.a.catalina.core.StandardService - Starting service [Tomcat] +2025-10-16 16:41:31 [restartedMain] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.68] +2025-10-16 16:41:31 [restartedMain] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext +2025-10-16 16:41:31 [restartedMain] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 241 ms +2025-10-16 16:41:31 [restartedMain] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default] +2025-10-16 16:41:31 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Starting... +2025-10-16 16:41:31 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Start completed. +2025-10-16 16:41:31 [restartedMain] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect +2025-10-16 16:41:31 [restartedMain] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] +2025-10-16 16:41:31 [restartedMain] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-10-16 16:41:31 [restartedMain] INFO o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html] +2025-10-16 16:41:31 [restartedMain] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration - + +Using generated security password: fb20fba2-55fa-48c2-932e-95c944238d5a + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-10-16 16:41:31 [restartedMain] INFO o.s.s.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@40f82067, org.springframework.security.web.context.SecurityContextPersistenceFilter@3ba61976, org.springframework.security.web.header.HeaderWriterFilter@b1983a, org.springframework.security.web.csrf.CsrfFilter@3f7f7a19, org.springframework.security.web.authentication.logout.LogoutFilter@2e443beb, org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter@4d7f7722, org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter@7516f6de, org.springframework.security.web.authentication.ui.DefaultLogoutPageGeneratingFilter@3877416a, org.springframework.security.web.authentication.www.BasicAuthenticationFilter@31fbbdb0, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@6e69e0ac, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@6215d513, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@393c1971, org.springframework.security.web.session.SessionManagementFilter@7f4d1b34, org.springframework.security.web.access.ExceptionTranslationFilter@1438245a, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@47b6baf7] +2025-10-16 16:41:31 [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729 +2025-10-16 16:41:31 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path '' +2025-10-16 16:41:31 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Started MyAfterProjecyApplication in 0.437 seconds (JVM running for 14.391) +2025-10-16 16:41:31 [restartedMain] INFO o.s.b.d.a.ConditionEvaluationDeltaLoggingListener - Condition evaluation delta: + + +========================== +CONDITION EVALUATION DELTA +========================== + + +Positive matches: +----------------- + + SpringBootWebSecurityConfiguration matched: + - found 'session' scope (OnWebApplicationCondition) + - AllNestedConditions 2 matched 0 did not; NestedCondition on DefaultWebSecurityCondition.Beans @ConditionalOnMissingBean (types: org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter,org.springframework.security.web.SecurityFilterChain; SearchStrategy: all) did not find any beans; NestedCondition on DefaultWebSecurityCondition.Classes @ConditionalOnClass found required classes 'org.springframework.security.web.SecurityFilterChain', 'org.springframework.security.config.annotation.web.builders.HttpSecurity' (DefaultWebSecurityCondition) + + WebSecurityEnablerConfiguration matched: + - @ConditionalOnClass found required class 'org.springframework.security.config.annotation.web.configuration.EnableWebSecurity' (OnClassCondition) + - found 'session' scope (OnWebApplicationCondition) + - @ConditionalOnMissingBean (names: springSecurityFilterChain; SearchStrategy: all) did not find any beans (OnBeanCondition) + + +Negative matches: +----------------- + + None + + +Exclusions: +----------- + + None + + +Unconditional classes: +---------------------- + + None + + + +2025-10-16 16:41:33 [File Watcher] INFO o.s.b.d.a.LocalDevToolsAutoConfiguration$RestartingClassPathChangeChangedEventListener - Restarting due to 33 class path changes (33 additions, 0 deletions, 0 modifications) +2025-10-16 16:41:33 [Thread-22] INFO o.a.catalina.core.StandardService - Stopping service [Tomcat] +2025-10-16 16:41:34 [Thread-22] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default' +2025-10-16 16:41:34 [Thread-22] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown initiated... +2025-10-16 16:41:34 [Thread-22] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown completed. +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Starting MyAfterProjecyApplication using Java 1.8.0_461 on DESKTOP-8G5GS0I with PID 31448 (E:\MyWebProject\MyAfterProjecy\target\classes started by 30803 in E:\MyWebProject\MyAfterProjecy) +2025-10-16 16:41:34 [restartedMain] DEBUG c.q.m.MyAfterProjecyApplication - Running with Spring Boot v2.6.13, Spring v5.3.23 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - No active profile set, falling back to 1 default profile: "default" +2025-10-16 16:41:34 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode. +2025-10-16 16:41:34 [restartedMain] INFO o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 15 ms. Found 4 JPA repository interfaces. +2025-10-16 16:41:34 [restartedMain] WARN o.m.s.mapper.ClassPathMapperScanner - No MyBatis mapper was found in '[com.qf.myafterprojecy]' package. Please check your configuration. +2025-10-16 16:41:34 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8080 (http) +2025-10-16 16:41:34 [restartedMain] INFO o.a.catalina.core.StandardService - Starting service [Tomcat] +2025-10-16 16:41:34 [restartedMain] INFO o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.68] +2025-10-16 16:41:34 [restartedMain] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext +2025-10-16 16:41:34 [restartedMain] INFO o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 268 ms +2025-10-16 16:41:34 [restartedMain] INFO o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default] +2025-10-16 16:41:34 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Starting... +2025-10-16 16:41:34 [restartedMain] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Start completed. +2025-10-16 16:41:34 [restartedMain] INFO org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect +2025-10-16 16:41:34 [restartedMain] INFO o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] +2025-10-16 16:41:34 [restartedMain] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default' +2025-10-16 16:41:34 [restartedMain] WARN o.s.b.a.s.s.UserDetailsServiceAutoConfiguration - + +Using generated security password: e4f76c3b-a578-4993-8c06-099ca64aac88 + +This generated password is for development use only. Your security configuration must be updated before running your application in production. + +2025-10-16 16:41:34 [restartedMain] INFO o.s.s.web.DefaultSecurityFilterChain - Will secure any request with [org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter@61e1947f, org.springframework.security.web.context.SecurityContextPersistenceFilter@43665935, org.springframework.security.web.header.HeaderWriterFilter@12df53fc, org.springframework.security.web.authentication.logout.LogoutFilter@da58f5f, org.springframework.security.web.savedrequest.RequestCacheAwareFilter@3c3161c5, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter@14532fd1, org.springframework.security.web.authentication.AnonymousAuthenticationFilter@3d9a6a52, org.springframework.security.web.access.ExceptionTranslationFilter@3c129b01, org.springframework.security.web.access.intercept.FilterSecurityInterceptor@34da3c43] +2025-10-16 16:41:34 [restartedMain] INFO o.s.b.a.w.s.WelcomePageHandlerMapping - Adding welcome page: class path resource [static/index.html] +2025-10-16 16:41:34 [restartedMain] INFO o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729 +2025-10-16 16:41:34 [restartedMain] INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8080 (http) with context path '' +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.MyAfterProjecyApplication - Started MyAfterProjecyApplication in 0.706 seconds (JVM running for 17.767) +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.CategoryDataInit - ===== 分类数据初始化开始 ===== +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.CategoryDataInit - 当前数据库中分类数量: 4 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.CategoryDataInit - 数据库中已存在分类数据,无需初始化 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.CategoryDataInit - ===== 分类数据初始化结束 ===== +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.MessageDataInit - ===== 消息数据初始化开始 ===== +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.MessageDataInit - 当前数据库中消息数量: 6 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.MessageDataInit - 数据库中已存在消息数据,无需初始化 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.init.MessageDataInit - ===== 消息数据初始化结束 ===== +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 消息数据检查器开始运行 ===== +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 当前数据库中消息数量: 6 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 测试Repository查询方法 ===== +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 文章ID为1的消息数量: 0 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 根消息数量: 3 +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%张%] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [CHAR] - [\] +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 昵称包含'张'的消息数量: 1 +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 文章ID为1的评论数量: 0 +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 消息ID为1的回复数量: 1 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 测试Service层方法 ===== +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 查询所有消息 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取所有消息: 成功=true, 消息数量=6 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 根据ID查询消息: 1 +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 根据ID1获取消息: 成功=true, 昵称=张三 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 获取文章评论数量: 1 +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取文章ID为1的评论数量: 成功=true, 数量=0 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 查询所有根消息 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 获取根消息: 成功=true, 数量=3 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 保存消息: 测试用户 +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [1] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [这是一条测试消息] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [3] as [TIMESTAMP] - [Thu Oct 16 16:41:34 CST 2025] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [4] as [VARCHAR] - [test@example.com] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [5] as [VARCHAR] - [测试用户] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [6] as [INTEGER] - [null] +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 消息保存成功: 54 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 保存新消息: 成功=true, 消息ID=54 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 删除消息: 54 +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [54] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [54] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [54] +2025-10-16 16:41:34 [restartedMain] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [INTEGER] - [54] +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.service.MessageService - 消息删除成功: 54 +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - 删除消息ID54: 成功=true +2025-10-16 16:41:34 [restartedMain] INFO c.q.m.runner.MessageDataChecker - ===== 消息数据检查器运行结束 ===== +2025-10-16 16:41:34 [restartedMain] INFO o.s.b.d.a.ConditionEvaluationDeltaLoggingListener - Condition evaluation delta: + + +========================== +CONDITION EVALUATION DELTA +========================== + + +Positive matches: +----------------- + + None + + +Negative matches: +----------------- + + SpringBootWebSecurityConfiguration: + Did not match: + - AllNestedConditions 1 matched 1 did not; NestedCondition on DefaultWebSecurityCondition.Beans @ConditionalOnMissingBean (types: org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter,org.springframework.security.web.SecurityFilterChain; SearchStrategy: all) found beans of type 'org.springframework.security.web.SecurityFilterChain' filterChain; NestedCondition on DefaultWebSecurityCondition.Classes @ConditionalOnClass found required classes 'org.springframework.security.web.SecurityFilterChain', 'org.springframework.security.config.annotation.web.builders.HttpSecurity' (DefaultWebSecurityCondition) + Matched: + - found 'session' scope (OnWebApplicationCondition) + + WebSecurityEnablerConfiguration: + Did not match: + - @ConditionalOnMissingBean (names: springSecurityFilterChain; SearchStrategy: all) found beans named springSecurityFilterChain (OnBeanCondition) + Matched: + - @ConditionalOnClass found required class 'org.springframework.security.config.annotation.web.configuration.EnableWebSecurity' (OnClassCondition) + - found 'session' scope (OnWebApplicationCondition) + + +Exclusions: +----------- + + None + + +Unconditional classes: +---------------------- + + None + + + +2025-10-16 16:41:40 [http-nio-8080-exec-2] INFO o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring DispatcherServlet 'dispatcherServlet' +2025-10-16 16:41:40 [http-nio-8080-exec-2] INFO o.s.web.servlet.DispatcherServlet - Initializing Servlet 'dispatcherServlet' +2025-10-16 16:41:40 [http-nio-8080-exec-2] INFO o.s.web.servlet.DispatcherServlet - Completed initialization in 1 ms +2025-10-16 16:43:14 [http-nio-8080-exec-8] ERROR c.q.m.service.ArticleService - 获取文章失败: For input string: "title" +2025-10-16 16:43:37 [http-nio-8080-exec-9] ERROR c.q.m.service.ArticleService - 获取文章失败: For input string: "title" +2025-10-16 16:43:46 [http-nio-8080-exec-10] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%1%] +2025-10-16 16:44:00 [http-nio-8080-exec-1] TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [%2%] +2025-10-16 16:47:16 [http-nio-8080-exec-3] INFO c.q.m.controller.MessageController - 接收获取所有消息的请求 +2025-10-16 16:47:16 [http-nio-8080-exec-3] INFO c.q.m.service.MessageService - 查询所有消息 +2025-10-16 16:47:28 [http-nio-8080-exec-4] INFO c.q.m.controller.MessageController - 接收获取所有消息的请求 +2025-10-16 16:47:28 [http-nio-8080-exec-4] INFO c.q.m.service.MessageService - 查询所有消息 +2025-10-16 17:07:29 [SpringApplicationShutdownHook] INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default' +2025-10-16 17:07:29 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown initiated... +2025-10-16 17:07:29 [SpringApplicationShutdownHook] INFO com.zaxxer.hikari.HikariDataSource - WebProjectHikariCP - Shutdown completed. diff --git a/src/main/java/com/qf/myafterprojecy/MyAfterProjecyApplication.java b/src/main/java/com/qf/myafterprojecy/MyAfterProjecyApplication.java index 33104cb..08b17ef 100644 --- a/src/main/java/com/qf/myafterprojecy/MyAfterProjecyApplication.java +++ b/src/main/java/com/qf/myafterprojecy/MyAfterProjecyApplication.java @@ -1,6 +1,5 @@ package com.qf.myafterprojecy; -import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; diff --git a/src/main/java/com/qf/myafterprojecy/controller/ArticleController.java b/src/main/java/com/qf/myafterprojecy/controller/ArticleController.java index 4317f6f..80005f1 100644 --- a/src/main/java/com/qf/myafterprojecy/controller/ArticleController.java +++ b/src/main/java/com/qf/myafterprojecy/controller/ArticleController.java @@ -52,6 +52,47 @@ public class ArticleController { return articleService.getArticlesByTitle(title); } + /** + * 根据属性ID获取该属性下的所有文章 + * @param attributeId 属性ID + * @return 返回包含文章列表的ResponseMessage对象 + */ + @GetMapping("/attribute/{attributeId}") + public ResponseMessage> getArticlesByAttribute(@PathVariable Integer attributeId) { + return articleService.getArticlesByAttribute(attributeId); + } + + + /** + * 根据分类ID获取该分类下的所有文章(兼容旧接口) + * @param categoryId 分类ID + * @return 返回包含文章列表的ResponseMessage对象 + */ + @GetMapping("/category/{categoryId}") + public ResponseMessage> getArticlesByCategory(@PathVariable Integer categoryId) { + return articleService.getArticlesByCategory(categoryId); + } + /** + * 根据属性ID获取最新文章(按创建时间降序) + * @param attributeId 属性ID + * @return 返回包含最新文章列表的ResponseMessage对象 + */ + @GetMapping("/attribute/{attributeId}/latest") + public ResponseMessage> getLatestArticlesByAttribute(@PathVariable Integer attributeId) { + return articleService.getLatestArticlesByAttribute(attributeId); + } + /** + * + * @return ar + */ + /** + * 获取浏览量最高的文章列表 + * @return 返回包含热门文章列表的ResponseMessage对象 + */ + @GetMapping("/popular") + public ResponseMessage> getMostViewedArticles() { + return articleService.getMostViewedArticles(); + } /** * 创建新文章 * 仅限AUTHOR角色用户访问 @@ -91,43 +132,4 @@ public class ArticleController { return articleService.deleteArticle(id); } - - /** - * 根据分类ID获取该分类下的所有文章(兼容旧接口) - * @param categoryId 分类ID - * @return 返回包含文章列表的ResponseMessage对象 - */ - @GetMapping("/category/{categoryId}") - public ResponseMessage> getArticlesByCategory(@PathVariable Integer categoryId) { - return articleService.getArticlesByCategory(categoryId); - } - - /** - * 根据属性ID获取该属性下的所有文章 - * @param attributeId 属性ID - * @return 返回包含文章列表的ResponseMessage对象 - */ - @GetMapping("/attribute/{attributeId}") - public ResponseMessage> getArticlesByAttribute(@PathVariable Integer attributeId) { - return articleService.getArticlesByAttribute(attributeId); - } - - /** - * 根据属性ID获取最新文章(按创建时间降序) - * @param attributeId 属性ID - * @return 返回包含最新文章列表的ResponseMessage对象 - */ - @GetMapping("/attribute/{attributeId}/latest") - public ResponseMessage> getLatestArticlesByAttribute(@PathVariable Integer attributeId) { - return articleService.getLatestArticlesByAttribute(attributeId); - } - - /** - * 获取浏览量最高的文章列表 - * @return 返回包含热门文章列表的ResponseMessage对象 - */ - @GetMapping("/popular") - public ResponseMessage> getMostViewedArticles() { - return articleService.getMostViewedArticles(); - } } diff --git a/src/main/java/com/qf/myafterprojecy/controller/CategoryAttributeController.java b/src/main/java/com/qf/myafterprojecy/controller/CategoryAttributeController.java index 4030c4f..fa52fc7 100644 --- a/src/main/java/com/qf/myafterprojecy/controller/CategoryAttributeController.java +++ b/src/main/java/com/qf/myafterprojecy/controller/CategoryAttributeController.java @@ -33,6 +33,7 @@ public class CategoryAttributeController { log.info("接收根据ID获取分类属性的请求: ID={}", id); return categoryAttributeService.getCategoryAttributeById(id); } + /** * 根据分类ID获取属性列表 diff --git a/src/main/java/com/qf/myafterprojecy/pojo/Article.java b/src/main/java/com/qf/myafterprojecy/pojo/Article.java index c0be750..f735c99 100644 --- a/src/main/java/com/qf/myafterprojecy/pojo/Article.java +++ b/src/main/java/com/qf/myafterprojecy/pojo/Article.java @@ -22,7 +22,7 @@ public class Article { private String content; @NotNull(message = "类别id不能为空") - @Column(name = "attributeid") + @Column(name = "attribute_id") private Integer attributeid; @Column(name = "img") diff --git a/src/main/java/com/qf/myafterprojecy/pojo/dto/ArticleDto.java b/src/main/java/com/qf/myafterprojecy/pojo/dto/ArticleDto.java index 085c227..2f30400 100644 --- a/src/main/java/com/qf/myafterprojecy/pojo/dto/ArticleDto.java +++ b/src/main/java/com/qf/myafterprojecy/pojo/dto/ArticleDto.java @@ -14,6 +14,9 @@ public class ArticleDto { @NotBlank(message = "内容不能为空") private String content; + + @NotNull(message = "属性ID不能为空") + private Integer attributeid; private String img; diff --git a/src/main/java/com/qf/myafterprojecy/repository/CategoryRepository.java b/src/main/java/com/qf/myafterprojecy/repository/CategoryRepository.java index ad87839..8703d69 100644 --- a/src/main/java/com/qf/myafterprojecy/repository/CategoryRepository.java +++ b/src/main/java/com/qf/myafterprojecy/repository/CategoryRepository.java @@ -14,6 +14,7 @@ public interface CategoryRepository extends JpaRepository { * @param typename 分类名称 * @return 返回符合条件的分类列表 */ + List findByTypenameContaining(String typename); /**