refactor(service): 重构服务接口和实现类结构

将服务接口从service包移动到service.imp包
修复ArticleRepository中viewCount的COALESCE处理
添加getPublishedArticles方法获取已发布文章
优化incrementViewCount方法使用仓库直接更新
修正HelpController中README_API.md路径
This commit is contained in:
qingfeng1121
2025-10-26 20:18:35 +08:00
parent 46be613f28
commit 9132feb870
15 changed files with 87 additions and 54 deletions

View File

@@ -3,7 +3,8 @@ package com.qf.myafterprojecy.controller;
import com.qf.myafterprojecy.pojo.Article;
import com.qf.myafterprojecy.pojo.ResponseMessage;
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.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
@@ -33,7 +34,14 @@ public class ArticleController {
public ResponseMessage<Article> getArticle(@PathVariable String id) {
return articleService.getArticleById(id);
}
/**
* 获取已发布的文章列表
* @return 返回包含已发布文章列表的ResponseMessage对象
*/
@GetMapping("/published")
public ResponseMessage<List<Article>> getPublishedArticles() {
return articleService.getPublishedArticles();
}
/**
* 获取所有文章列表
* @return 返回包含文章列表的ResponseMessage对象
@@ -62,16 +70,7 @@ public class ArticleController {
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获取最新文章按创建时间降序
* @param attributeId 属性ID
@@ -81,14 +80,7 @@ public class ArticleController {
public ResponseMessage<List<Article>> getLatestArticlesByAttribute(@PathVariable Integer attributeId) {
return articleService.getLatestArticlesByAttribute(attributeId);
}
/**
* 获取浏览量最高的文章列表
* @return 返回包含热门文章列表的ResponseMessage对象
*/
@GetMapping("/popular")
public ResponseMessage<List<Article>> getMostViewedArticles() {
return articleService.getMostViewedArticles();
}
/**
* 创建新文章
* 仅限AUTHOR角色用户访问

View File

@@ -3,7 +3,8 @@ package com.qf.myafterprojecy.controller;
import com.qf.myafterprojecy.pojo.Category_attribute;
import com.qf.myafterprojecy.pojo.ResponseMessage;
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.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -3,7 +3,8 @@ package com.qf.myafterprojecy.controller;
import com.qf.myafterprojecy.pojo.Category;
import com.qf.myafterprojecy.pojo.ResponseMessage;
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.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -30,14 +30,20 @@ public class HelpController {
@GetMapping
public ResponseMessage<String> getReadmeApi() {
try {
// 获取项目根目录
String rootPath = System.getProperty("user.dir");
// 构建README_API.md文件路径
File readmeFile = new File(rootPath, "README_API.md");
// 获取README_API.md文件的绝对路径
String readmePath = "e:\\MyWebProject\\MyAfterProjecy\\README_API.md";
File readmeFile = new File(readmePath);
// 检查文件是否存在
if (!readmeFile.exists() || !readmeFile.isFile()) {
// 如果不存在,尝试使用类路径资源加载
if (readmeFile.exists() && readmeFile.isFile()) {
// 读取文件内容
String markdownContent = new String(FileCopyUtils.copyToByteArray(new FileInputStream(readmeFile)), StandardCharsets.UTF_8);
// 将Markdown转换为HTML
String htmlContent = convertMarkdownToHtml(markdownContent);
return ResponseMessage.success(htmlContent, "获取API文档成功");
}
// 如果直接路径不存在,尝试从类路径加载
try {
ClassPathResource resource = new ClassPathResource("README_API.md");
String markdownContent = new String(FileCopyUtils.copyToByteArray(resource.getInputStream()), StandardCharsets.UTF_8);
@@ -45,16 +51,14 @@ public class HelpController {
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文件");
}
}
// 读取文件内容
String markdownContent = new String(FileCopyUtils.copyToByteArray(new FileInputStream(readmeFile)), StandardCharsets.UTF_8);
// 将Markdown转换为HTML
String htmlContent = convertMarkdownToHtml(markdownContent);
return ResponseMessage.success(htmlContent, "获取API文档成功");
} catch (IOException e) {
} catch (Exception e) {
// 捕获所有异常并记录详细错误信息
System.err.println("处理README_API.md时出错: " + e.getMessage());
e.printStackTrace();
return ResponseMessage.error("读取README_API.md文件失败: " + e.getMessage());
}
}

View File

@@ -3,7 +3,8 @@ package com.qf.myafterprojecy.controller;
import com.qf.myafterprojecy.pojo.Message;
import com.qf.myafterprojecy.pojo.ResponseMessage;
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.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -68,7 +68,7 @@ public interface ArticleRepository extends JpaRepository<Article, Integer> {
* @param articleid 文章的唯一标识符,通过@Param注解将方法参数与查询参数绑定
*/
@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);
/**
@@ -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")
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);
}

View File

@@ -4,7 +4,8 @@ import com.qf.myafterprojecy.pojo.Message;
import com.qf.myafterprojecy.pojo.ResponseMessage;
import com.qf.myafterprojecy.pojo.dto.MessageDto;
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.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -5,6 +5,8 @@ import com.qf.myafterprojecy.pojo.ResponseMessage;
import com.qf.myafterprojecy.pojo.dto.ArticleDto;
import com.qf.myafterprojecy.repository.ArticleRepository;
import com.qf.myafterprojecy.repository.CategoryAttributeRepository;
import com.qf.myafterprojecy.service.imp.IArticleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
@@ -46,7 +48,21 @@ public class ArticleService implements IArticleService {
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
@Transactional(readOnly = true)
public ResponseMessage<List<Article>> getArticlesByTitle(String title) {
@@ -178,10 +194,9 @@ public class ArticleService implements IArticleService {
Article article = articleRepository.findById(id)
.orElseThrow(() -> new RuntimeException("文章不存在"));
article.setViewCount(article.getViewCount() + 1);
Article updatedArticle = articleRepository.save(article);
articleRepository.incrementViewCount(id);
return ResponseMessage.success(updatedArticle);
return ResponseMessage.success(article);
} catch (Exception e) {
log.error("增加文章浏览量失败: {}", e.getMessage());
return ResponseMessage.failure("增加文章浏览量失败");

View File

@@ -4,6 +4,8 @@ import com.qf.myafterprojecy.pojo.Category_attribute;
import com.qf.myafterprojecy.pojo.ResponseMessage;
import com.qf.myafterprojecy.pojo.dto.CategoryAttributeDto;
import com.qf.myafterprojecy.repository.CategoryAttributeRepository;
import com.qf.myafterprojecy.service.imp.ICategoryAttributeService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

View File

@@ -4,6 +4,8 @@ import com.qf.myafterprojecy.pojo.Category;
import com.qf.myafterprojecy.pojo.ResponseMessage;
import com.qf.myafterprojecy.pojo.dto.CategoryDto;
import com.qf.myafterprojecy.repository.CategoryRepository;
import com.qf.myafterprojecy.service.imp.ICategoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

View File

@@ -4,6 +4,8 @@ import com.qf.myafterprojecy.pojo.Message;
import com.qf.myafterprojecy.pojo.ResponseMessage;
import com.qf.myafterprojecy.pojo.dto.MessageDto;
import com.qf.myafterprojecy.repository.MessageRepository;
import com.qf.myafterprojecy.service.imp.IMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;

View File

@@ -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.ResponseMessage;
@@ -78,4 +78,9 @@ public interface IArticleService {
* @return 返回包含更新后文章信息的ResponseMessage对象
*/
ResponseMessage<Article> incrementViewCount(Integer id);
/**
* 获取已发布的文章列表
* @return 返回包含已发布文章列表的ResponseMessage对象
*/
ResponseMessage<List<Article>> getPublishedArticles();
}

View File

@@ -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.ResponseMessage;

View File

@@ -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.ResponseMessage;

View File

@@ -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.ResponseMessage;