refactor(service): 重构服务接口和实现类结构
将服务接口从service包移动到service.imp包 修复ArticleRepository中viewCount的COALESCE处理 添加getPublishedArticles方法获取已发布文章 优化incrementViewCount方法使用仓库直接更新 修正HelpController中README_API.md路径
This commit is contained in:
@@ -3,7 +3,8 @@ package com.qf.myafterprojecy.controller;
|
|||||||
import com.qf.myafterprojecy.pojo.Article;
|
import com.qf.myafterprojecy.pojo.Article;
|
||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
import com.qf.myafterprojecy.pojo.dto.ArticleDto;
|
import com.qf.myafterprojecy.pojo.dto.ArticleDto;
|
||||||
import com.qf.myafterprojecy.service.IArticleService;
|
import com.qf.myafterprojecy.service.imp.IArticleService;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -33,7 +34,14 @@ public class ArticleController {
|
|||||||
public ResponseMessage<Article> getArticle(@PathVariable String id) {
|
public ResponseMessage<Article> getArticle(@PathVariable String id) {
|
||||||
return articleService.getArticleById(id);
|
return articleService.getArticleById(id);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取已发布的文章列表
|
||||||
|
* @return 返回包含已发布文章列表的ResponseMessage对象
|
||||||
|
*/
|
||||||
|
@GetMapping("/published")
|
||||||
|
public ResponseMessage<List<Article>> getPublishedArticles() {
|
||||||
|
return articleService.getPublishedArticles();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 获取所有文章列表
|
* 获取所有文章列表
|
||||||
* @return 返回包含文章列表的ResponseMessage对象
|
* @return 返回包含文章列表的ResponseMessage对象
|
||||||
@@ -62,16 +70,7 @@ public class ArticleController {
|
|||||||
return articleService.getArticlesByAttribute(attributeId);
|
return articleService.getArticlesByAttribute(attributeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据分类ID获取该分类下的所有文章(兼容旧接口)
|
|
||||||
* @param categoryId 分类ID
|
|
||||||
* @return 返回包含文章列表的ResponseMessage对象
|
|
||||||
*/
|
|
||||||
@GetMapping("/category/{categoryId}")
|
|
||||||
public ResponseMessage<List<Article>> getArticlesByCategory(@PathVariable Integer categoryId) {
|
|
||||||
return articleService.getArticlesByCategory(categoryId);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 根据属性ID获取最新文章(按创建时间降序)
|
* 根据属性ID获取最新文章(按创建时间降序)
|
||||||
* @param attributeId 属性ID
|
* @param attributeId 属性ID
|
||||||
@@ -81,14 +80,7 @@ public class ArticleController {
|
|||||||
public ResponseMessage<List<Article>> getLatestArticlesByAttribute(@PathVariable Integer attributeId) {
|
public ResponseMessage<List<Article>> getLatestArticlesByAttribute(@PathVariable Integer attributeId) {
|
||||||
return articleService.getLatestArticlesByAttribute(attributeId);
|
return articleService.getLatestArticlesByAttribute(attributeId);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* 获取浏览量最高的文章列表
|
|
||||||
* @return 返回包含热门文章列表的ResponseMessage对象
|
|
||||||
*/
|
|
||||||
@GetMapping("/popular")
|
|
||||||
public ResponseMessage<List<Article>> getMostViewedArticles() {
|
|
||||||
return articleService.getMostViewedArticles();
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 创建新文章
|
* 创建新文章
|
||||||
* 仅限AUTHOR角色用户访问
|
* 仅限AUTHOR角色用户访问
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ package com.qf.myafterprojecy.controller;
|
|||||||
import com.qf.myafterprojecy.pojo.Category_attribute;
|
import com.qf.myafterprojecy.pojo.Category_attribute;
|
||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
import com.qf.myafterprojecy.pojo.dto.CategoryAttributeDto;
|
import com.qf.myafterprojecy.pojo.dto.CategoryAttributeDto;
|
||||||
import com.qf.myafterprojecy.service.ICategoryAttributeService;
|
import com.qf.myafterprojecy.service.imp.ICategoryAttributeService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ package com.qf.myafterprojecy.controller;
|
|||||||
import com.qf.myafterprojecy.pojo.Category;
|
import com.qf.myafterprojecy.pojo.Category;
|
||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
import com.qf.myafterprojecy.pojo.dto.CategoryDto;
|
import com.qf.myafterprojecy.pojo.dto.CategoryDto;
|
||||||
import com.qf.myafterprojecy.service.ICategoryService;
|
import com.qf.myafterprojecy.service.imp.ICategoryService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|||||||
@@ -30,31 +30,35 @@ public class HelpController {
|
|||||||
@GetMapping
|
@GetMapping
|
||||||
public ResponseMessage<String> getReadmeApi() {
|
public ResponseMessage<String> getReadmeApi() {
|
||||||
try {
|
try {
|
||||||
// 获取项目根目录
|
// 获取README_API.md文件的绝对路径
|
||||||
String rootPath = System.getProperty("user.dir");
|
String readmePath = "e:\\MyWebProject\\MyAfterProjecy\\README_API.md";
|
||||||
// 构建README_API.md文件路径
|
File readmeFile = new File(readmePath);
|
||||||
File readmeFile = new File(rootPath, "README_API.md");
|
|
||||||
|
|
||||||
// 检查文件是否存在
|
// 检查文件是否存在
|
||||||
if (!readmeFile.exists() || !readmeFile.isFile()) {
|
if (readmeFile.exists() && readmeFile.isFile()) {
|
||||||
// 如果不存在,尝试使用类路径资源加载
|
// 读取文件内容
|
||||||
try {
|
String markdownContent = new String(FileCopyUtils.copyToByteArray(new FileInputStream(readmeFile)), StandardCharsets.UTF_8);
|
||||||
ClassPathResource resource = new ClassPathResource("README_API.md");
|
// 将Markdown转换为HTML
|
||||||
String markdownContent = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()), StandardCharsets.UTF_8);
|
String htmlContent = convertMarkdownToHtml(markdownContent);
|
||||||
// 将Markdown转换为HTML
|
return ResponseMessage.success(htmlContent, "获取API文档成功");
|
||||||
String htmlContent = convertMarkdownToHtml(markdownContent);
|
|
||||||
return ResponseMessage.success(htmlContent, "获取API文档成功");
|
|
||||||
} catch (IOException e) {
|
|
||||||
return ResponseMessage.error("未找到README_API.md文件");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 读取文件内容
|
// 如果直接路径不存在,尝试从类路径加载
|
||||||
String markdownContent = new String(FileCopyUtils.copyToByteArray(new FileInputStream(readmeFile)), StandardCharsets.UTF_8);
|
try {
|
||||||
// 将Markdown转换为HTML
|
ClassPathResource resource = new ClassPathResource("README_API.md");
|
||||||
String htmlContent = convertMarkdownToHtml(markdownContent);
|
String markdownContent = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()), StandardCharsets.UTF_8);
|
||||||
return ResponseMessage.success(htmlContent, "获取API文档成功");
|
// 将Markdown转换为HTML
|
||||||
} catch (IOException e) {
|
String htmlContent = convertMarkdownToHtml(markdownContent);
|
||||||
|
return ResponseMessage.success(htmlContent, "获取API文档成功");
|
||||||
|
} catch (IOException e) {
|
||||||
|
// 记录详细错误信息以便调试
|
||||||
|
System.err.println("无法从类路径加载README_API.md: " + e.getMessage());
|
||||||
|
return ResponseMessage.error("未找到README_API.md文件");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// 捕获所有异常并记录详细错误信息
|
||||||
|
System.err.println("处理README_API.md时出错: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
return ResponseMessage.error("读取README_API.md文件失败: " + e.getMessage());
|
return ResponseMessage.error("读取README_API.md文件失败: " + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ package com.qf.myafterprojecy.controller;
|
|||||||
import com.qf.myafterprojecy.pojo.Message;
|
import com.qf.myafterprojecy.pojo.Message;
|
||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
import com.qf.myafterprojecy.pojo.dto.MessageDto;
|
import com.qf.myafterprojecy.pojo.dto.MessageDto;
|
||||||
import com.qf.myafterprojecy.service.IMessageService;
|
import com.qf.myafterprojecy.service.imp.IMessageService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public interface ArticleRepository extends JpaRepository<Article, Integer> {
|
|||||||
* @param articleid 文章的唯一标识符,通过@Param注解将方法参数与查询参数绑定
|
* @param articleid 文章的唯一标识符,通过@Param注解将方法参数与查询参数绑定
|
||||||
*/
|
*/
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("UPDATE Article a SET a.viewCount = a.viewCount + 1 WHERE a.articleid = :articleid")
|
@Query("UPDATE Article a SET a.viewCount = COALESCE(a.viewCount, 0) + 1 WHERE a.articleid = :articleid")
|
||||||
void incrementViewCount(@Param("articleid") Integer articleid);
|
void incrementViewCount(@Param("articleid") Integer articleid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -79,4 +79,11 @@ public interface ArticleRepository extends JpaRepository<Article, Integer> {
|
|||||||
*/
|
*/
|
||||||
@Query("SELECT a FROM Article a WHERE a.status = 1 ORDER BY a.viewCount DESC")
|
@Query("SELECT a FROM Article a WHERE a.status = 1 ORDER BY a.viewCount DESC")
|
||||||
List<Article> findMostViewed();
|
List<Article> findMostViewed();
|
||||||
|
/**
|
||||||
|
* 根据状态查询文章列表
|
||||||
|
* @param status 文章状态,0-草稿,1-已发布,2-已删除
|
||||||
|
* @return 返回符合状态条件的文章列表
|
||||||
|
*/
|
||||||
|
@Query("SELECT a FROM Article a WHERE a.status = :status")
|
||||||
|
List<Article> findByStatus(@Param("status") Integer status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import com.qf.myafterprojecy.pojo.Message;
|
|||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
import com.qf.myafterprojecy.pojo.dto.MessageDto;
|
import com.qf.myafterprojecy.pojo.dto.MessageDto;
|
||||||
import com.qf.myafterprojecy.repository.MessageRepository;
|
import com.qf.myafterprojecy.repository.MessageRepository;
|
||||||
import com.qf.myafterprojecy.service.IMessageService;
|
import com.qf.myafterprojecy.service.imp.IMessageService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import com.qf.myafterprojecy.pojo.ResponseMessage;
|
|||||||
import com.qf.myafterprojecy.pojo.dto.ArticleDto;
|
import com.qf.myafterprojecy.pojo.dto.ArticleDto;
|
||||||
import com.qf.myafterprojecy.repository.ArticleRepository;
|
import com.qf.myafterprojecy.repository.ArticleRepository;
|
||||||
import com.qf.myafterprojecy.repository.CategoryAttributeRepository;
|
import com.qf.myafterprojecy.repository.CategoryAttributeRepository;
|
||||||
|
import com.qf.myafterprojecy.service.imp.IArticleService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
@@ -46,7 +48,21 @@ public class ArticleService implements IArticleService {
|
|||||||
return ResponseMessage.failure("获取文章失败");
|
return ResponseMessage.failure("获取文章失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 获取已发布的文章列表
|
||||||
|
* @return 返回包含已发布文章列表的ResponseMessage对象
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public ResponseMessage<List<Article>> getPublishedArticles() {
|
||||||
|
try {
|
||||||
|
List<Article> articles = articleRepository.findByStatus(1);
|
||||||
|
return ResponseMessage.success(articles);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取已发布文章列表失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("获取已发布文章列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseMessage<List<Article>> getArticlesByTitle(String title) {
|
public ResponseMessage<List<Article>> getArticlesByTitle(String title) {
|
||||||
@@ -178,10 +194,9 @@ public class ArticleService implements IArticleService {
|
|||||||
Article article = articleRepository.findById(id)
|
Article article = articleRepository.findById(id)
|
||||||
.orElseThrow(() -> new RuntimeException("文章不存在"));
|
.orElseThrow(() -> new RuntimeException("文章不存在"));
|
||||||
|
|
||||||
article.setViewCount(article.getViewCount() + 1);
|
articleRepository.incrementViewCount(id);
|
||||||
Article updatedArticle = articleRepository.save(article);
|
|
||||||
|
|
||||||
return ResponseMessage.success(updatedArticle);
|
return ResponseMessage.success(article);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("增加文章浏览量失败: {}", e.getMessage());
|
log.error("增加文章浏览量失败: {}", e.getMessage());
|
||||||
return ResponseMessage.failure("增加文章浏览量失败");
|
return ResponseMessage.failure("增加文章浏览量失败");
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import com.qf.myafterprojecy.pojo.Category_attribute;
|
|||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
import com.qf.myafterprojecy.pojo.dto.CategoryAttributeDto;
|
import com.qf.myafterprojecy.pojo.dto.CategoryAttributeDto;
|
||||||
import com.qf.myafterprojecy.repository.CategoryAttributeRepository;
|
import com.qf.myafterprojecy.repository.CategoryAttributeRepository;
|
||||||
|
import com.qf.myafterprojecy.service.imp.ICategoryAttributeService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import com.qf.myafterprojecy.pojo.Category;
|
|||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
import com.qf.myafterprojecy.pojo.dto.CategoryDto;
|
import com.qf.myafterprojecy.pojo.dto.CategoryDto;
|
||||||
import com.qf.myafterprojecy.repository.CategoryRepository;
|
import com.qf.myafterprojecy.repository.CategoryRepository;
|
||||||
|
import com.qf.myafterprojecy.service.imp.ICategoryService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import com.qf.myafterprojecy.pojo.Message;
|
|||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
import com.qf.myafterprojecy.pojo.dto.MessageDto;
|
import com.qf.myafterprojecy.pojo.dto.MessageDto;
|
||||||
import com.qf.myafterprojecy.repository.MessageRepository;
|
import com.qf.myafterprojecy.repository.MessageRepository;
|
||||||
|
import com.qf.myafterprojecy.service.imp.IMessageService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.qf.myafterprojecy.service;
|
package com.qf.myafterprojecy.service.imp;
|
||||||
|
|
||||||
import com.qf.myafterprojecy.pojo.Article;
|
import com.qf.myafterprojecy.pojo.Article;
|
||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
@@ -78,4 +78,9 @@ public interface IArticleService {
|
|||||||
* @return 返回包含更新后文章信息的ResponseMessage对象
|
* @return 返回包含更新后文章信息的ResponseMessage对象
|
||||||
*/
|
*/
|
||||||
ResponseMessage<Article> incrementViewCount(Integer id);
|
ResponseMessage<Article> incrementViewCount(Integer id);
|
||||||
|
/**
|
||||||
|
* 获取已发布的文章列表
|
||||||
|
* @return 返回包含已发布文章列表的ResponseMessage对象
|
||||||
|
*/
|
||||||
|
ResponseMessage<List<Article>> getPublishedArticles();
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.qf.myafterprojecy.service;
|
package com.qf.myafterprojecy.service.imp;
|
||||||
|
|
||||||
import com.qf.myafterprojecy.pojo.Category_attribute;
|
import com.qf.myafterprojecy.pojo.Category_attribute;
|
||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.qf.myafterprojecy.service;
|
package com.qf.myafterprojecy.service.imp;
|
||||||
|
|
||||||
import com.qf.myafterprojecy.pojo.Category;
|
import com.qf.myafterprojecy.pojo.Category;
|
||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.qf.myafterprojecy.service;
|
package com.qf.myafterprojecy.service.imp;
|
||||||
|
|
||||||
import com.qf.myafterprojecy.pojo.Message;
|
import com.qf.myafterprojecy.pojo.Message;
|
||||||
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
Reference in New Issue
Block a user