feat(分类属性): 实现分类属性管理功能
新增分类属性相关实体、DTO、仓库、服务及控制器 扩展文章服务以支持按属性查询文章 重构文章实体将typeid改为attributeid 添加按标题查询文章功能
This commit is contained in:
2951
logs/web_project.log
2951
logs/web_project.log
File diff suppressed because it is too large
Load Diff
BIN
logs/web_project.log.2025-10-12.0.gz
Normal file
BIN
logs/web_project.log.2025-10-12.0.gz
Normal file
Binary file not shown.
@@ -42,6 +42,15 @@ public class ArticleController {
|
|||||||
public ResponseMessage<List<Article>> getAllArticles() {
|
public ResponseMessage<List<Article>> getAllArticles() {
|
||||||
return articleService.getAllArticles();
|
return articleService.getAllArticles();
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 根据标题查询文章列表
|
||||||
|
* @param title 文章标题
|
||||||
|
* @return 返回包含文章列表的ResponseMessage对象
|
||||||
|
*/
|
||||||
|
@GetMapping("/title/{title}")
|
||||||
|
public ResponseMessage<List<Article>> getArticlesByTitle(@PathVariable String title) {
|
||||||
|
return articleService.getArticlesByTitle(title);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建新文章
|
* 创建新文章
|
||||||
@@ -84,13 +93,33 @@ public class ArticleController {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据分类ID获取该分类下的所有文章
|
* 根据分类ID获取该分类下的所有文章(兼容旧接口)
|
||||||
* @param typeid 分类ID
|
* @param categoryId 分类ID
|
||||||
* @return 返回包含文章列表的ResponseMessage对象
|
* @return 返回包含文章列表的ResponseMessage对象
|
||||||
*/
|
*/
|
||||||
@GetMapping("/category/{categoryId}")
|
@GetMapping("/category/{categoryId}")
|
||||||
public ResponseMessage<List<Article>> getArticlesByCategory(@PathVariable Integer typeid) {
|
public ResponseMessage<List<Article>> getArticlesByCategory(@PathVariable Integer categoryId) {
|
||||||
return articleService.getArticlesByCategory(typeid);
|
return articleService.getArticlesByCategory(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据属性ID获取该属性下的所有文章
|
||||||
|
* @param attributeId 属性ID
|
||||||
|
* @return 返回包含文章列表的ResponseMessage对象
|
||||||
|
*/
|
||||||
|
@GetMapping("/attribute/{attributeId}")
|
||||||
|
public ResponseMessage<List<Article>> getArticlesByAttribute(@PathVariable Integer attributeId) {
|
||||||
|
return articleService.getArticlesByAttribute(attributeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据属性ID获取最新文章(按创建时间降序)
|
||||||
|
* @param attributeId 属性ID
|
||||||
|
* @return 返回包含最新文章列表的ResponseMessage对象
|
||||||
|
*/
|
||||||
|
@GetMapping("/attribute/{attributeId}/latest")
|
||||||
|
public ResponseMessage<List<Article>> getLatestArticlesByAttribute(@PathVariable Integer attributeId) {
|
||||||
|
return articleService.getLatestArticlesByAttribute(attributeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
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 org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/category-attributes")
|
||||||
|
@Validated
|
||||||
|
public class CategoryAttributeController {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CategoryAttributeController.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ICategoryAttributeService categoryAttributeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取分类属性
|
||||||
|
* @param id 属性ID
|
||||||
|
* @return 属性信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
public ResponseMessage<Category_attribute> getAttributeById(@PathVariable Integer id) {
|
||||||
|
log.info("接收根据ID获取分类属性的请求: ID={}", id);
|
||||||
|
return categoryAttributeService.getCategoryAttributeById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分类ID获取属性列表
|
||||||
|
* @param categoryId 分类ID
|
||||||
|
* @return 属性列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/category/{categoryId}")
|
||||||
|
public ResponseMessage<List<Category_attribute>> getAttributesByCategory(@PathVariable Integer categoryId) {
|
||||||
|
log.info("接收根据分类ID获取属性列表的请求: 分类ID={}", categoryId);
|
||||||
|
return categoryAttributeService.getAttributesByCategoryId(categoryId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新的分类属性
|
||||||
|
* @param dto 分类属性数据
|
||||||
|
* @return 创建结果
|
||||||
|
*/
|
||||||
|
@PostMapping
|
||||||
|
public ResponseMessage<Category_attribute> createAttribute(@Valid @RequestBody CategoryAttributeDto dto) {
|
||||||
|
log.info("接收创建分类属性的请求: 分类ID={}, 属性名称={}",
|
||||||
|
dto.getCategoryid(), dto.getAttributename());
|
||||||
|
return categoryAttributeService.saveCategoryAttribute(dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新分类属性
|
||||||
|
* @param id 属性ID
|
||||||
|
* @param dto 分类属性数据
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public ResponseMessage<Category_attribute> updateAttribute(
|
||||||
|
@PathVariable Integer id,
|
||||||
|
@Valid @RequestBody CategoryAttributeDto dto) {
|
||||||
|
log.info("接收更新分类属性的请求: ID={}, 分类ID={}, 属性名称={}",
|
||||||
|
id, dto.getCategoryid(), dto.getAttributename());
|
||||||
|
return categoryAttributeService.updateCategoryAttribute(id, dto);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除分类属性
|
||||||
|
* @param id 属性ID
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
public ResponseMessage<Boolean> deleteAttribute(@PathVariable Integer id) {
|
||||||
|
log.info("接收删除分类属性的请求: ID={}", id);
|
||||||
|
return categoryAttributeService.deleteCategoryAttribute(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查分类下是否存在指定名称的属性
|
||||||
|
* @param categoryId 分类ID
|
||||||
|
* @param attributeName 属性名称
|
||||||
|
* @return 是否存在
|
||||||
|
*/
|
||||||
|
@GetMapping("/check-exists")
|
||||||
|
public ResponseMessage<Boolean> checkAttributeExists(
|
||||||
|
@RequestParam Integer categoryId,
|
||||||
|
@RequestParam String attributeName) {
|
||||||
|
log.info("接收检查分类属性是否存在的请求: 分类ID={}, 属性名称={}", categoryId, attributeName);
|
||||||
|
return categoryAttributeService.existsByCategoryAndName(categoryId, attributeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,8 +22,8 @@ public class Article {
|
|||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
@NotNull(message = "类别id不能为空")
|
@NotNull(message = "类别id不能为空")
|
||||||
@Column(name = "typeid")
|
@Column(name = "attributeid")
|
||||||
private Integer typeid;
|
private Integer attributeid;
|
||||||
|
|
||||||
@Column(name = "img")
|
@Column(name = "img")
|
||||||
private String img;
|
private String img;
|
||||||
@@ -42,6 +42,14 @@ public class Article {
|
|||||||
// Getters and Setters
|
// Getters and Setters
|
||||||
|
|
||||||
|
|
||||||
|
public Integer getAttributeid() {
|
||||||
|
return attributeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttributeid(Integer attributeid) {
|
||||||
|
this.attributeid = attributeid;
|
||||||
|
}
|
||||||
|
|
||||||
public Integer getArticleid() {
|
public Integer getArticleid() {
|
||||||
return articleid;
|
return articleid;
|
||||||
}
|
}
|
||||||
@@ -66,14 +74,6 @@ public class Article {
|
|||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getTypeid() {
|
|
||||||
return typeid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTypeid(Integer typeid) {
|
|
||||||
this.typeid = typeid;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getCreatedAt() {
|
public LocalDateTime getCreatedAt() {
|
||||||
return createdAt;
|
return createdAt;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,42 @@
|
|||||||
package com.qf.myafterprojecy.pojo;
|
package com.qf.myafterprojecy.pojo;
|
||||||
|
|
||||||
public class category_attribute {
|
import javax.persistence.*;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "category_attribute")
|
||||||
|
public class Category_attribute {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Column(name = "attributeid")
|
||||||
|
private Integer attributeid;
|
||||||
|
|
||||||
|
@Column(name = "categoryid")
|
||||||
|
private Integer categoryid;
|
||||||
|
|
||||||
|
@Column(name = "attributename")
|
||||||
|
private String attributename;
|
||||||
|
|
||||||
|
public Integer getAttributeid() {
|
||||||
|
return attributeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttributeid(Integer attributeid) {
|
||||||
|
this.attributeid = attributeid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getCategoryid() {
|
||||||
|
return categoryid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategoryid(Integer categoryid) {
|
||||||
|
this.categoryid = categoryid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAttributename() {
|
||||||
|
return attributename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttributename(String attributename) {
|
||||||
|
this.attributename = attributename;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package com.qf.myafterprojecy.pojo.dto;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
public class CategoryAttributeDto {
|
||||||
|
|
||||||
|
@NotNull(message = "分类ID不能为空")
|
||||||
|
private Integer categoryid;
|
||||||
|
|
||||||
|
@NotBlank(message = "属性名称不能为空")
|
||||||
|
private String attributename;
|
||||||
|
|
||||||
|
// Getters and Setters
|
||||||
|
public Integer getCategoryid() {
|
||||||
|
return categoryid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCategoryid(Integer categoryid) {
|
||||||
|
this.categoryid = categoryid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAttributename() {
|
||||||
|
return attributename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttributename(String attributename) {
|
||||||
|
this.attributename = attributename;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -21,6 +21,13 @@ public interface ArticleRepository extends JpaRepository<Article, Integer> {
|
|||||||
*/
|
*/
|
||||||
@Query("SELECT a FROM Article a WHERE a.articleid = :id")
|
@Query("SELECT a FROM Article a WHERE a.articleid = :id")
|
||||||
Optional<Article> findById(@Param("id") Integer id);
|
Optional<Article> findById(@Param("id") Integer id);
|
||||||
|
/**
|
||||||
|
* 根据标题查询文章列表
|
||||||
|
* @param title 文章标题的一部分,用于模糊查询
|
||||||
|
* @return 返回符合查询条件的文章列表
|
||||||
|
*/
|
||||||
|
@Query("SELECT a FROM Article a WHERE a.title LIKE %:title%")
|
||||||
|
List<Article> findByTitle(@Param("title") String title);
|
||||||
/**
|
/**
|
||||||
* 根据文章ID查询已发布的文章
|
* 根据文章ID查询已发布的文章
|
||||||
* 使用JPQL查询语句,只查询状态为1(已发布)且指定ID的文章
|
* 使用JPQL查询语句,只查询状态为1(已发布)且指定ID的文章
|
||||||
@@ -34,11 +41,20 @@ public interface ArticleRepository extends JpaRepository<Article, Integer> {
|
|||||||
* 根据分类ID查询已发布的文章列表
|
* 根据分类ID查询已发布的文章列表
|
||||||
* 使用JPQL查询语句,筛选状态为已发布(status=1)且指定分类(typeid)的文章
|
* 使用JPQL查询语句,筛选状态为已发布(status=1)且指定分类(typeid)的文章
|
||||||
*
|
*
|
||||||
* @param typeid 分类ID,通过@Param注解映射到查询语句中的:typeid参数
|
* @param attributeid 分类ID,通过@Param注解映射到查询语句中的:attributeid参数
|
||||||
* @return 返回符合条件Article对象的列表
|
* @return 返回符合条件Article对象的列表
|
||||||
*/
|
*/
|
||||||
@Query("SELECT a FROM Article a WHERE a.status = 1 AND a.typeid = :typeid")
|
@Query("SELECT a FROM Article a WHERE a.status = 1 AND a.attributeid = :attributeid")
|
||||||
List<Article> findPublishedByCategory(@Param("typeid") Integer typeid);
|
List<Article> findPublishedByAttribute(@Param("attributeid") Integer attributeid);
|
||||||
|
/**
|
||||||
|
* 根据属性ID查询最新的文章列表
|
||||||
|
* 使用JPQL查询语句,筛选状态为已发布(status=1)且指定属性(attributeid)的文章,按创建时间降序排序
|
||||||
|
*
|
||||||
|
* @param attributeid 属性ID,通过@Param注解映射到查询语句中的:attributeid参数
|
||||||
|
* @return 返回符合条件Article对象的列表,按创建时间降序排列
|
||||||
|
*/
|
||||||
|
@Query("SELECT a FROM Article a WHERE a.status = 1 AND a.attributeid = :attributeid ORDER BY a.createdAt DESC")
|
||||||
|
List<Article> findLatestByAttribute(@Param("attributeid") Integer attributeid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用@Modifying注解标记这是一个修改操作,通常用于UPDATE或DELETE语句
|
* 使用@Modifying注解标记这是一个修改操作,通常用于UPDATE或DELETE语句
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.qf.myafterprojecy.repository;
|
||||||
|
|
||||||
|
import com.qf.myafterprojecy.pojo.Category_attribute;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface CategoryAttributeRepository extends JpaRepository<Category_attribute, Integer> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分类ID查询分类属性列表
|
||||||
|
* @param categoryid 分类ID
|
||||||
|
* @return 返回该分类下的所有属性列表
|
||||||
|
*/
|
||||||
|
@Query("SELECT ca FROM Category_attribute ca WHERE ca.categoryid = :categoryid")
|
||||||
|
List<Category_attribute> findByCategoryId(@Param("categoryid") Integer categoryid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据属性ID查询属性信息
|
||||||
|
* @param attributeid 属性ID
|
||||||
|
* @return 返回属性对象
|
||||||
|
*/
|
||||||
|
@Query("SELECT ca FROM Category_attribute ca WHERE ca.attributeid = :attributeid")
|
||||||
|
Optional<Category_attribute> findByAttributeId(@Param("attributeid") Integer attributeid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查分类下是否存在指定名称的属性
|
||||||
|
* @param categoryid 分类ID
|
||||||
|
* @param attributename 属性名称
|
||||||
|
* @return 是否存在
|
||||||
|
*/
|
||||||
|
boolean existsByCategoryidAndAttributename(Integer categoryid, String attributename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分类ID和属性名称查询属性
|
||||||
|
* @param categoryid 分类ID
|
||||||
|
* @param attributename 属性名称
|
||||||
|
* @return 属性对象
|
||||||
|
*/
|
||||||
|
Optional<Category_attribute> findByCategoryidAndAttributename(Integer categoryid, String attributename);
|
||||||
|
}
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
package com.qf.myafterprojecy.repository;
|
package com.qf.myafterprojecy.repository;
|
||||||
|
|
||||||
public interface Category_attribute {
|
import org.hibernate.metamodel.model.convert.spi.JpaAttributeConverter;
|
||||||
|
|
||||||
|
public interface Category_attribute extends JpaAttributeConverter<Category_attribute, Integer> {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ 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.repository.ArticleRepository;
|
import com.qf.myafterprojecy.repository.ArticleRepository;
|
||||||
|
import com.qf.myafterprojecy.repository.CategoryAttributeRepository;
|
||||||
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;
|
||||||
@@ -22,6 +23,9 @@ public class ArticleService implements IArticleService {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ArticleRepository articleRepository;
|
private ArticleRepository articleRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CategoryAttributeRepository categoryAttributeRepository;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
@@ -42,7 +46,21 @@ public class ArticleService implements IArticleService {
|
|||||||
return ResponseMessage.failure("获取文章失败");
|
return ResponseMessage.failure("获取文章失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public ResponseMessage<List<Article>> getArticlesByTitle(String title) {
|
||||||
|
try {
|
||||||
|
if (title == null || title.isEmpty()) {
|
||||||
|
return ResponseMessage.failure("文章标题不能为空");
|
||||||
|
}
|
||||||
|
List<Article> articles = articleRepository.findByTitle(title);
|
||||||
|
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>> getAllArticles() {
|
public ResponseMessage<List<Article>> getAllArticles() {
|
||||||
@@ -114,13 +132,58 @@ public class ArticleService implements IArticleService {
|
|||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public ResponseMessage<List<Article>> getArticlesByCategory(Integer categoryId) {
|
public ResponseMessage<List<Article>> getArticlesByCategory(Integer categoryId) {
|
||||||
try {
|
try {
|
||||||
List<Article> articles = articleRepository.findPublishedByCategory(categoryId);
|
// 为了兼容旧接口,这里需要调整逻辑
|
||||||
return ResponseMessage.success(articles);
|
// 旧接口使用typeid,但我们现在用attributeid
|
||||||
|
// 可以考虑查询该分类下的所有属性,然后获取相关文章
|
||||||
|
log.warn("使用了旧接口getArticlesByCategory,请考虑迁移到getArticlesByAttribute");
|
||||||
|
return ResponseMessage.success(articleRepository.findPublishedByAttribute(categoryId));
|
||||||
} catch (DataAccessException e) {
|
} catch (DataAccessException e) {
|
||||||
log.error("获取分类文章失败: {}", e.getMessage());
|
log.error("获取分类文章失败: {}", e.getMessage());
|
||||||
return ResponseMessage.failure("获取分类文章失败");
|
return ResponseMessage.failure("获取分类文章失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public ResponseMessage<List<Article>> getArticlesByAttribute(Integer attributeid) {
|
||||||
|
try {
|
||||||
|
if (attributeid == null || attributeid <= 0) {
|
||||||
|
return ResponseMessage.failure("属性ID无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证属性是否存在
|
||||||
|
if (!categoryAttributeRepository.existsById(attributeid)) {
|
||||||
|
return ResponseMessage.failure("属性不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Article> articles = articleRepository.findPublishedByAttribute(attributeid);
|
||||||
|
return ResponseMessage.success(articles);
|
||||||
|
} catch (DataAccessException e) {
|
||||||
|
log.error("获取属性文章失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("获取属性文章失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public ResponseMessage<List<Article>> getLatestArticlesByAttribute(Integer attributeid) {
|
||||||
|
try {
|
||||||
|
if (attributeid == null || attributeid <= 0) {
|
||||||
|
return ResponseMessage.failure("属性ID无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证属性是否存在
|
||||||
|
if (!categoryAttributeRepository.existsById(attributeid)) {
|
||||||
|
return ResponseMessage.failure("属性不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Article> articles = articleRepository.findLatestByAttribute(attributeid);
|
||||||
|
return ResponseMessage.success(articles);
|
||||||
|
} catch (DataAccessException e) {
|
||||||
|
log.error("获取最新属性文章失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("获取最新属性文章失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
|
|||||||
@@ -0,0 +1,154 @@
|
|||||||
|
package com.qf.myafterprojecy.service;
|
||||||
|
|
||||||
|
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 org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.dao.DataAccessException;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CategoryAttributeService implements ICategoryAttributeService {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CategoryAttributeService.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CategoryAttributeRepository categoryAttributeRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public ResponseMessage<Category_attribute> getCategoryAttributeById(Integer id) {
|
||||||
|
try {
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
return ResponseMessage.failure("属性ID无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
Category_attribute attribute = categoryAttributeRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new RuntimeException("分类属性不存在"));
|
||||||
|
|
||||||
|
return ResponseMessage.success(attribute);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取分类属性失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("获取分类属性失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public ResponseMessage<List<Category_attribute>> getAttributesByCategoryId(Integer categoryId) {
|
||||||
|
try {
|
||||||
|
if (categoryId == null || categoryId <= 0) {
|
||||||
|
return ResponseMessage.failure("分类ID无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Category_attribute> attributes = categoryAttributeRepository.findByCategoryId(categoryId);
|
||||||
|
return ResponseMessage.success(attributes);
|
||||||
|
} catch (DataAccessException e) {
|
||||||
|
log.error("获取分类属性列表失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("获取分类属性列表失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ResponseMessage<Category_attribute> saveCategoryAttribute(CategoryAttributeDto dto) {
|
||||||
|
try {
|
||||||
|
// 检查属性名称是否已存在于该分类下
|
||||||
|
if (categoryAttributeRepository.existsByCategoryidAndAttributename(
|
||||||
|
dto.getCategoryid(), dto.getAttributename())) {
|
||||||
|
return ResponseMessage.failure("该分类下已存在同名属性");
|
||||||
|
}
|
||||||
|
|
||||||
|
Category_attribute attribute = new Category_attribute();
|
||||||
|
BeanUtils.copyProperties(dto, attribute);
|
||||||
|
|
||||||
|
Category_attribute savedAttribute = categoryAttributeRepository.save(attribute);
|
||||||
|
log.info("成功创建分类属性: {}, 分类ID: {}",
|
||||||
|
savedAttribute.getAttributename(), savedAttribute.getCategoryid());
|
||||||
|
|
||||||
|
return ResponseMessage.success(savedAttribute);
|
||||||
|
} catch (DataAccessException e) {
|
||||||
|
log.error("保存分类属性失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("保存分类属性失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ResponseMessage<Category_attribute> updateCategoryAttribute(Integer id, CategoryAttributeDto dto) {
|
||||||
|
try {
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
return ResponseMessage.failure("属性ID无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
Category_attribute attribute = categoryAttributeRepository.findById(id)
|
||||||
|
.orElseThrow(() -> new RuntimeException("分类属性不存在"));
|
||||||
|
|
||||||
|
// 如果修改了属性名称,检查新名称是否已存在
|
||||||
|
if (!attribute.getAttributename().equals(dto.getAttributename()) &&
|
||||||
|
categoryAttributeRepository.existsByCategoryidAndAttributename(
|
||||||
|
dto.getCategoryid(), dto.getAttributename())) {
|
||||||
|
return ResponseMessage.failure("该分类下已存在同名属性");
|
||||||
|
}
|
||||||
|
|
||||||
|
BeanUtils.copyProperties(dto, attribute);
|
||||||
|
attribute.setAttributeid(id); // 确保ID不变
|
||||||
|
|
||||||
|
Category_attribute updatedAttribute = categoryAttributeRepository.save(attribute);
|
||||||
|
log.info("成功更新分类属性: ID={}, 名称={}",
|
||||||
|
updatedAttribute.getAttributeid(), updatedAttribute.getAttributename());
|
||||||
|
|
||||||
|
return ResponseMessage.success(updatedAttribute);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新分类属性失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("更新分类属性失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public ResponseMessage<Boolean> deleteCategoryAttribute(Integer id) {
|
||||||
|
try {
|
||||||
|
if (id == null || id <= 0) {
|
||||||
|
return ResponseMessage.failure("属性ID无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!categoryAttributeRepository.existsById(id)) {
|
||||||
|
return ResponseMessage.failure("分类属性不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
categoryAttributeRepository.deleteById(id);
|
||||||
|
log.info("成功删除分类属性: ID={}", id);
|
||||||
|
|
||||||
|
return ResponseMessage.success(true);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("删除分类属性失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("删除分类属性失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public ResponseMessage<Boolean> existsByCategoryAndName(Integer categoryId, String attributeName) {
|
||||||
|
try {
|
||||||
|
if (categoryId == null || categoryId <= 0 || attributeName == null || attributeName.isEmpty()) {
|
||||||
|
return ResponseMessage.failure("参数无效");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean exists = categoryAttributeRepository.existsByCategoryidAndAttributename(
|
||||||
|
categoryId, attributeName);
|
||||||
|
|
||||||
|
return ResponseMessage.success(exists);
|
||||||
|
} catch (DataAccessException e) {
|
||||||
|
log.error("检查分类属性是否存在失败: {}", e.getMessage());
|
||||||
|
return ResponseMessage.failure("检查分类属性是否存在失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,9 +9,34 @@ import java.util.List;
|
|||||||
public interface IArticleService {
|
public interface IArticleService {
|
||||||
ResponseMessage<Article> getArticleById(String id);
|
ResponseMessage<Article> getArticleById(String id);
|
||||||
ResponseMessage<List<Article>> getAllArticles();
|
ResponseMessage<List<Article>> getAllArticles();
|
||||||
|
/**
|
||||||
|
* 根据标题查询文章列表
|
||||||
|
* @param title 文章标题的一部分,用于模糊查询
|
||||||
|
* @return 返回符合查询条件的文章列表
|
||||||
|
*/
|
||||||
|
ResponseMessage<List<Article>> getArticlesByTitle(String title);
|
||||||
ResponseMessage<Article> saveArticle(ArticleDto articleDto);
|
ResponseMessage<Article> saveArticle(ArticleDto articleDto);
|
||||||
ResponseMessage<Article> updateArticle(Integer id, ArticleDto articleDto);
|
ResponseMessage<Article> updateArticle(Integer id, ArticleDto articleDto);
|
||||||
ResponseMessage<Article> deleteArticle(Integer id);
|
ResponseMessage<Article> deleteArticle(Integer id);
|
||||||
|
/**
|
||||||
|
* 根据分类ID查询文章列表(兼容旧接口)
|
||||||
|
* @param typeid 分类ID
|
||||||
|
* @return 返回符合查询条件的文章列表
|
||||||
|
*/
|
||||||
ResponseMessage<List<Article>> getArticlesByCategory(Integer typeid);
|
ResponseMessage<List<Article>> getArticlesByCategory(Integer typeid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据属性ID查询文章列表
|
||||||
|
* @param attributeid 属性ID
|
||||||
|
* @return 返回符合查询条件的文章列表
|
||||||
|
*/
|
||||||
|
ResponseMessage<List<Article>> getArticlesByAttribute(Integer attributeid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据属性ID查询最新文章列表
|
||||||
|
* @param attributeid 属性ID
|
||||||
|
* @return 返回符合查询条件的最新文章列表
|
||||||
|
*/
|
||||||
|
ResponseMessage<List<Article>> getLatestArticlesByAttribute(Integer attributeid);
|
||||||
ResponseMessage<List<Article>> getMostViewedArticles();
|
ResponseMessage<List<Article>> getMostViewedArticles();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.qf.myafterprojecy.service;
|
||||||
|
|
||||||
|
import com.qf.myafterprojecy.pojo.Category_attribute;
|
||||||
|
import com.qf.myafterprojecy.pojo.ResponseMessage;
|
||||||
|
import com.qf.myafterprojecy.pojo.dto.CategoryAttributeDto;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface ICategoryAttributeService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取分类属性
|
||||||
|
* @param id 属性ID
|
||||||
|
* @return 分类属性信息
|
||||||
|
*/
|
||||||
|
ResponseMessage<Category_attribute> getCategoryAttributeById(Integer id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据分类ID获取属性列表
|
||||||
|
* @param categoryId 分类ID
|
||||||
|
* @return 属性列表
|
||||||
|
*/
|
||||||
|
ResponseMessage<List<Category_attribute>> getAttributesByCategoryId(Integer categoryId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新的分类属性
|
||||||
|
* @param dto 分类属性数据
|
||||||
|
* @return 创建结果
|
||||||
|
*/
|
||||||
|
ResponseMessage<Category_attribute> saveCategoryAttribute(CategoryAttributeDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新分类属性
|
||||||
|
* @param id 属性ID
|
||||||
|
* @param dto 分类属性数据
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
ResponseMessage<Category_attribute> updateCategoryAttribute(Integer id, CategoryAttributeDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除分类属性
|
||||||
|
* @param id 属性ID
|
||||||
|
* @return 删除结果
|
||||||
|
*/
|
||||||
|
ResponseMessage<Boolean> deleteCategoryAttribute(Integer id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查分类下是否存在指定名称的属性
|
||||||
|
* @param categoryId 分类ID
|
||||||
|
* @param attributeName 属性名称
|
||||||
|
* @return 是否存在
|
||||||
|
*/
|
||||||
|
ResponseMessage<Boolean> existsByCategoryAndName(Integer categoryId, String attributeName);
|
||||||
|
}
|
||||||
@@ -165,7 +165,6 @@ public class MessageService implements IMessageService {
|
|||||||
logger.warn("根据父消息ID查询回复时ID无效: {}", parentId);
|
logger.warn("根据父消息ID查询回复时ID无效: {}", parentId);
|
||||||
return ResponseMessage.failure("父消息ID无效");
|
return ResponseMessage.failure("父消息ID无效");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
logger.info("根据父消息ID查询回复: {}", parentId);
|
logger.info("根据父消息ID查询回复: {}", parentId);
|
||||||
List<Message> replies = messageRepository.findByParentid(parentId);
|
List<Message> replies = messageRepository.findByParentid(parentId);
|
||||||
|
|||||||
Reference in New Issue
Block a user