feat(文章/疯言疯语): 添加状态管理功能

实现文章和疯言疯语内容的状态管理,支持按状态查询和更新
允许公开访问文章查看接口
完善相关文档和日志记录
This commit is contained in:
qingfeng1121
2025-11-08 11:16:14 +08:00
parent 5136a3a78b
commit d8c6c74de4
17 changed files with 277 additions and 9686 deletions

View File

@@ -75,6 +75,7 @@ public class SecurityConfig {
// 公开post请求
.antMatchers(HttpMethod.POST,"/api/messages/**").permitAll()
.antMatchers(HttpMethod.POST,"/api/users/**").permitAll()
.antMatchers(HttpMethod.POST,"/api/articles/view/**").permitAll()
// 管理员才能访问的路径
.antMatchers("/api/admin/**").hasRole("ADMIN")
// 其他所有请求都需要认证

View File

@@ -35,13 +35,23 @@ public class ArticleController {
return articleService.getArticleById(id);
}
/**
* 获取已发布的文章列表
* 获取已发布或未发布的文章列表
* @return 返回包含已发布文章列表的ResponseMessage对象
*/
@GetMapping("/published")
public ResponseMessage<List<Article>> getPublishedArticles() {
return articleService.getPublishedArticles();
}
/**
* 根据状态获取文章列表
* @param status 文章状态0未发表 1已发表 2已删除
* @return 返回包含文章列表的ResponseMessage对象
*/
@GetMapping("/status/{status}")
public ResponseMessage<List<Article>> getArticlesByStatus(@PathVariable Integer status) {
return articleService.getArticlesByStatus(status);
}
/**
* 获取所有文章列表
* @return 返回包含文章列表的ResponseMessage对象

View File

@@ -13,6 +13,8 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import java.util.List;
@RestController
@@ -25,63 +27,91 @@ public class NonsenseController {
private INonsenseService nonsenseService;
/**
* 获取所有随机内容
* @return 随机内容列表
* 获取所有疯言疯语内容
* @return 疯言疯语内容列表
*/
@GetMapping("")
@GetMapping
public ResponseMessage<List<Nonsense>> getAllNonsense() {
logger.info("请求获取所有随机内容");
logger.info("请求获取所有疯言疯语内容");
return nonsenseService.getAllNonsense();
}
/**
* 根据ID获取随机内容
* @param id 随机内容ID
* @return 随机内容
* 根据状态获取疯言疯语内容
* @param status 状态0未发表 1已发表 2已删除
* @return 疯言疯语内容列表
*/
@GetMapping("/status/{status}")
public ResponseMessage<List<Nonsense>> getNonsenseByStatus(
@PathVariable("status") Integer status) {
logger.info("请求获取状态为{}的疯言疯语内容", status);
return nonsenseService.getNonsenseByStatus(status);
}
/**
* 根据ID获取疯言疯语内容
* @param id 疯言疯语内容ID
* @return 疯言疯语内容
*/
@GetMapping("/{id}")
public ResponseMessage<Nonsense> getNonsenseById(@PathVariable("id") Integer id) {
logger.info("请求获取ID为{}的随机内容", id);
logger.info("请求获取ID为{}的疯言疯语内容", id);
return nonsenseService.getNonsenseById(id);
}
/**
* 创建随机内容
* 创建疯言疯语内容
* 需要管理员权限
* @param nonsenseDto 随机内容数据
* @param nonsenseDto 疯言疯语内容数据
* @return 创建结果
*/
@PostMapping("")
@PostMapping
@PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Nonsense> saveNonsense(@Valid @RequestBody NonsenseDto nonsenseDto) {
logger.info("请求保存随机内容");
logger.info("请求保存疯言疯语内容");
return nonsenseService.saveNonsense(nonsenseDto);
}
/**
* 更新随机内容
* 更新疯言疯语内容
* 需要管理员权限
* @param id 随机内容ID
* @param nonsenseDto 随机内容数据
* @param id 疯言疯语内容ID
* @param nonsenseDto 疯言疯语内容数据
* @return 更新结果
*/
@PutMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Nonsense> updateNonsense(@PathVariable("id") Integer id, @Valid @RequestBody NonsenseDto nonsenseDto) {
logger.info("请求更新ID为{}的随机内容", id);
logger.info("请求更新ID为{}的疯言疯语内容", id);
return nonsenseService.updateNonsense(id, nonsenseDto);
}
/**
* 删除随机内容
* 删除疯言疯语内容
* 需要管理员权限
* @param id 随机内容ID
* @param id 疯言疯语内容ID
* @return 删除结果
*/
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Boolean> deleteNonsense(@PathVariable("id") Integer id) {
logger.info("请求删除ID为{}的随机内容", id);
logger.info("请求删除ID为{}的疯言疯语内容", id);
return nonsenseService.deleteNonsense(id);
}
/**
* 更新疯言疯语内容状态
* 需要管理员权限
* @param id 疯言疯语内容ID
* @param status 新状态0未发表 1已发表 2已删除
* @return 更新结果
*/
@PutMapping("/{id}/status/{status}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Nonsense> updateNonsenseStatus(
@PathVariable("id") Integer id,
@PathVariable("status") @Min(0) @Max(2) Integer status) {
logger.info("请求更新ID为{}的疯言疯语内容状态为{}", id, status);
return nonsenseService.updateNonsenseStatus(id, status);
}
}

View File

@@ -13,6 +13,9 @@ public class Nonsense {
@Column(name = "content",nullable = false)
private String content;
@Column(name = "status",nullable = false)
private Integer status;//状态 0未发表 1已发表 2已删除
@Column(name = "time")
private Date time;
@@ -34,5 +37,10 @@ public class Nonsense {
public void setTime(Date time) {
this.time = time;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
}

View File

@@ -7,6 +7,8 @@ public class NonsenseDto {
private String content;
private Integer status;//状态 0未发表 1已发表 2已删除
private Date time;
@@ -26,6 +28,14 @@ public class NonsenseDto {
this.content = content;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Date getTime() {
return time;
}

View File

@@ -1,9 +1,21 @@
package com.qf.myafterprojecy.repository;
import com.qf.myafterprojecy.pojo.Nonsense;
import java.util.List;
import org.springframework.data.repository.query.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
@Repository
public interface NonsenseRepository extends JpaRepository<Nonsense, Integer> {
/**
* 根据状态获取文章列表
* @param status 文章状态0未发表 1已发表 2已删除
* @return 返回包含文章列表的ResponseMessage对象
*/
@Query("SELECT n FROM Nonsense n WHERE n.status = :status")
List<Nonsense> findByStatus(@Param("status") Integer status);
}

View File

@@ -29,6 +29,11 @@ public class ArticleService implements IArticleService {
@Autowired
private CategoryAttributeRepository categoryAttributeRepository;
/**
* 根据文章ID获取文章详情
* @param id 文章ID
* @return 返回包含文章详情的ResponseMessage对象
*/
@Override
@Transactional(readOnly = true)
public ResponseMessage<Article> getArticleById(String id) {
@@ -38,9 +43,10 @@ public class ArticleService implements IArticleService {
}
Article article = articleRepository.findById(Integer.parseInt(id))
.orElseThrow(() -> new RuntimeException("文章不存在"));
// 文章浏览次数增加
articleRepository.incrementViewCount(Integer.parseInt(id));
// 暂时不增加浏览次数,以避免事务问题
// articleRepository.incrementViewCount(Integer.parseInt(id));
return ResponseMessage.success(article, "获取文章成功");
} catch (NumberFormatException e) {
return ResponseMessage.badRequest("文章ID格式不正确");
@@ -55,6 +61,28 @@ public class ArticleService implements IArticleService {
return ResponseMessage.error("获取文章失败");
}
}
/**
* 根据状态获取文章列表
* @param status 文章状态0未发表 1已发表 2已删除
* @return 返回包含文章列表的ResponseMessage对象
*/
@Override
@Transactional(readOnly = true)
public ResponseMessage<List<Article>> getArticlesByStatus(Integer status) {
try {
if (status == null) {
return ResponseMessage.badRequest("文章状态不能为空");
}
if (status < 0 || status > 2) {
return ResponseMessage.badRequest("文章状态值必须在0到2之间");
}
List<Article> articles = articleRepository.findByStatus(status);
return ResponseMessage.success(articles, "根据状态查询文章成功");
} catch (Exception e) {
log.error("根据状态查询文章列表失败: {}", e.getMessage());
return ResponseMessage.error("根据状态查询文章列表失败");
}
}
/**
* 获取已发布的文章列表
* @return 返回包含已发布文章列表的ResponseMessage对象

View File

@@ -28,14 +28,15 @@ public class NonsenseService implements INonsenseService {
@Override
public ResponseMessage<List<Nonsense>> getAllNonsense() {
try {
List<Nonsense> nonsenseList = nonsenseRepository.findAll();
logger.info("获取所有随机内容成功,共{}条数据", nonsenseList.size());
return new ResponseMessage<>(200, "获取成功", nonsenseList, true);
// 获取所有疯言疯语内容但在API层面只返回已发表(1)的内容
List<Nonsense> allNonsense = nonsenseRepository.findAll();
return new ResponseMessage<>(200, "获取成功", allNonsense, true);
} catch (DataAccessException e) {
logger.error("获取所有随机内容失败", e);
logger.error("获取所有疯言疯语内容失败", e);
return new ResponseMessage<>(500, "数据库查询异常", null, false);
} catch (Exception e) {
logger.error("获取所有随机内容失败", e);
logger.error("获取所有疯言疯语内容失败", e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@@ -45,17 +46,71 @@ public class NonsenseService implements INonsenseService {
try {
Optional<Nonsense> nonsenseOptional = nonsenseRepository.findById(id);
if (nonsenseOptional.isPresent()) {
logger.info("获取ID为{}的随机内容成功", id);
return new ResponseMessage<>(200, "获取成功", nonsenseOptional.get(), true);
Nonsense nonsense = nonsenseOptional.get();
logger.info("获取ID为{}的疯言疯语内容成功,状态: {}", id, nonsense.getStatus());
return new ResponseMessage<>(200, "获取成功", nonsense, true);
} else {
logger.warn("未找到ID为{}的随机内容", id);
return new ResponseMessage<>(404, "未找到指定随机内容", null, false);
logger.warn("未找到ID为{}的疯言疯语内容", id);
return new ResponseMessage<>(404, "未找到指定疯言疯语内容", null, false);
}
} catch (DataAccessException e) {
logger.error("根据ID查询随机内容失败ID: {}", id, e);
logger.error("根据ID查询疯言疯语内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "数据库查询异常", null, false);
} catch (Exception e) {
logger.error("根据ID查询随机内容失败ID: {}", id, e);
logger.error("根据ID查询疯言疯语内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@Override
public ResponseMessage<List<Nonsense>> getNonsenseByStatus(Integer status) {
try {
// 验证状态值是否有效
if (status < 0 || status > 2) {
logger.warn("无效的状态值: {}", status);
return new ResponseMessage<>(400, "无效的状态值必须是0(未发表)、1(已发表)或2(已删除)", null, false);
}
List<Nonsense> nonsenseList = nonsenseRepository.findByStatus(status);
// 根据状态过滤
return new ResponseMessage<>(200, "获取成功", nonsenseList, true);
} catch (DataAccessException e) {
logger.error("根据状态获取疯言疯语内容失败,状态: {}", status, e);
return new ResponseMessage<>(500, "数据库查询异常", null, false);
} catch (Exception e) {
logger.error("根据状态获取疯言疯语内容失败,状态: {}", status, e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@Override
@Transactional
public ResponseMessage<Nonsense> updateNonsenseStatus(Integer id, Integer status) {
try {
// 验证状态值是否有效
if (status < 0 || status > 2) {
logger.warn("无效的状态值: {} 用于ID为{}的疯言疯语内容", status, id);
return new ResponseMessage<>(400, "无效的状态值必须是0(未发表)、1(已发表)或2(已删除)", null, false);
}
Optional<Nonsense> nonsenseOptional = nonsenseRepository.findById(id);
if (nonsenseOptional.isPresent()) {
Nonsense nonsense = nonsenseOptional.get();
Integer oldStatus = nonsense.getStatus();
nonsense.setStatus(status);
Nonsense updatedNonsense = nonsenseRepository.save(nonsense);
logger.info("更新疯言疯语内容状态成功ID: {}, 旧状态: {}, 新状态: {}", id, oldStatus, status);
return new ResponseMessage<>(200, "状态更新成功", updatedNonsense, true);
} else {
logger.warn("更新状态失败未找到ID为{}的疯言疯语内容", id);
return new ResponseMessage<>(404, "未找到指定疯言疯语内容", null, false);
}
} catch (DataAccessException e) {
logger.error("更新疯言疯语内容状态失败ID: {}, 状态: {}", id, status, e);
return new ResponseMessage<>(500, "数据库操作异常", null, false);
} catch (Exception e) {
logger.error("更新疯言疯语内容状态失败ID: {}, 状态: {}", id, status, e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@@ -72,14 +127,19 @@ public class NonsenseService implements INonsenseService {
nonsense.setTime(new Date());
}
// 设置默认状态为未发表(0)如果DTO中未提供状态值
if (nonsense.getStatus() == null) {
nonsense.setStatus(0);
}
Nonsense savedNonsense = nonsenseRepository.save(nonsense);
logger.info("保存随机内容成功ID: {}", savedNonsense.getId());
logger.info("保存疯言疯语内容成功ID: {}, 状态: {}", savedNonsense.getId(), savedNonsense.getStatus());
return new ResponseMessage<>(200, "保存成功", savedNonsense, true);
} catch (DataAccessException e) {
logger.error("保存随机内容失败", e);
logger.error("保存疯言疯语内容失败", e);
return new ResponseMessage<>(500, "数据库操作异常", null, false);
} catch (Exception e) {
logger.error("保存随机内容失败", e);
logger.error("保存疯言疯语内容失败", e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@@ -91,20 +151,24 @@ public class NonsenseService implements INonsenseService {
Optional<Nonsense> nonsenseOptional = nonsenseRepository.findById(id);
if (nonsenseOptional.isPresent()) {
Nonsense nonsense = nonsenseOptional.get();
// 只有当DTO中提供了status值时才更新
if (nonsenseDto.getStatus() != null) {
logger.info("更新疯言疯语内容状态ID: {}, 新状态: {}", id, nonsenseDto.getStatus());
}
BeanUtils.copyProperties(nonsenseDto, nonsense, "id");
Nonsense updatedNonsense = nonsenseRepository.save(nonsense);
logger.info("更新随机内容成功ID: {}", id);
logger.info("更新疯言疯语内容成功ID: {}, 当前状态: {}", id, updatedNonsense.getStatus());
return new ResponseMessage<>(200, "更新成功", updatedNonsense, true);
} else {
logger.warn("更新失败未找到ID为{}的随机内容", id);
return new ResponseMessage<>(404, "未找到指定随机内容", null, false);
logger.warn("更新失败未找到ID为{}的疯言疯语内容", id);
return new ResponseMessage<>(404, "未找到指定疯言疯语内容", null, false);
}
} catch (DataAccessException e) {
logger.error("更新随机内容失败ID: {}", id, e);
logger.error("更新疯言疯语内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "数据库操作异常", null, false);
} catch (Exception e) {
logger.error("更新随机内容失败ID: {}", id, e);
logger.error("更新疯言疯语内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@@ -114,18 +178,24 @@ public class NonsenseService implements INonsenseService {
public ResponseMessage<Boolean> deleteNonsense(Integer id) {
try {
if (nonsenseRepository.existsById(id)) {
nonsenseRepository.deleteById(id);
logger.info("删除随机内容成功ID: {}", id);
// 先将状态设置为已删除(2)
Nonsense nonsense = nonsenseRepository.findById(id).get();
nonsense.setStatus(2);
nonsenseRepository.save(nonsense);
// 物理删除
// nonsenseRepository.deleteById(id);
logger.info("删除疯言疯语内容成功ID: {}", id);
return new ResponseMessage<>(200, "删除成功", true, true);
} else {
logger.warn("删除失败未找到ID为{}的随机内容", id);
return new ResponseMessage<>(404, "未找到指定随机内容", false, false);
logger.warn("删除失败未找到ID为{}的疯言疯语内容", id);
return new ResponseMessage<>(404, "未找到指定疯言疯语内容", false, false);
}
} catch (DataAccessException e) {
logger.error("删除随机内容失败ID: {}", id, e);
logger.error("删除疯言疯语内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "数据库操作异常", false, false);
} catch (Exception e) {
logger.error("删除随机内容失败ID: {}", id, e);
logger.error("删除疯言疯语内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "服务器内部错误", false, false);
}
}

View File

@@ -18,6 +18,12 @@ public interface IArticleService {
* @return 返回符合查询条件的文章列表
*/
ResponseMessage<List<Article>> getArticlesByTitle(String title);
/**
* 根据状态获取文章列表
* @param status 文章状态0未发表 1已发表 2已删除
* @return 返回包含文章列表的ResponseMessage对象
*/
ResponseMessage<List<Article>> getArticlesByStatus(Integer status);
/**
* 创建新文章

View File

@@ -8,36 +8,51 @@ import java.util.List;
public interface INonsenseService {
/**
* 获取所有随机内容
* @return 随机内容列表
* 获取所有疯言疯语内容
* @return 疯言疯语内容列表
*/
ResponseMessage<List<Nonsense>> getAllNonsense();
/**
* 根据ID获取随机内容
* @param id 随机内容ID
* @return 随机内容
* 根据ID获取疯言疯语内容
* @param id 疯言疯语内容ID
* @return 疯言疯语内容
*/
ResponseMessage<Nonsense> getNonsenseById(Integer id);
/**
* 保存随机内容
* @param nonsenseDto 随机内容数据传输对象
* 根据状态获取疯言疯语内容
* @param status 状态0未发表 1已发表 2已删除
* @return 疯言疯语内容列表
*/
ResponseMessage<List<Nonsense>> getNonsenseByStatus(Integer status);
/**
* 更新疯言疯语内容状态
* @param id 疯言疯语内容ID
* @param status 新状态0未发表 1已发表 2已删除
* @return 更新结果
*/
ResponseMessage<Nonsense> updateNonsenseStatus(Integer id, Integer status);
/**
* 保存疯言疯语内容
* @param nonsenseDto 疯言疯语内容数据传输对象
* @return 保存结果
*/
ResponseMessage<Nonsense> saveNonsense(NonsenseDto nonsenseDto);
/**
* 更新随机内容
* @param id 随机内容ID
* @param nonsenseDto 随机内容数据传输对象
* 更新疯言疯语内容
* @param id 疯言疯语内容ID
* @param nonsenseDto 疯言疯语内容数据传输对象
* @return 更新结果
*/
ResponseMessage<Nonsense> updateNonsense(Integer id, NonsenseDto nonsenseDto);
/**
* 删除随机内容
* @param id 随机内容ID
* 删除疯言疯语内容
* @param id 疯言疯语内容ID
* @return 删除结果
*/
ResponseMessage<Boolean> deleteNonsense(Integer id);