feat: 添加随机内容模块并优化安全配置

新增Nonsense相关实体、DTO、Repository、Service和Controller,实现随机内容的CRUD功能
优化CORS和安全配置,增加更精细的权限控制和错误处理
移除Article和Message中不必要的验证注解,调整部分API的权限要求
This commit is contained in:
qingfeng1121
2025-11-05 16:11:38 +08:00
parent 25eeab4940
commit 5136a3a78b
24 changed files with 9960 additions and 17168 deletions

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -20,23 +20,33 @@ public class CorsConfig {
// 创建CORS配置对象 // 创建CORS配置对象
CorsConfiguration config = new CorsConfiguration(); CorsConfiguration config = new CorsConfiguration();
// 允许的来源,这里允许所有来源,实际生产环境应该限制特定域名 // 允许的来源,使用通配符模式
config.addAllowedOriginPattern("*"); config.addAllowedOriginPattern("*");
// 允许携带凭证如Cookie // 允许携带凭证如Cookie
config.setAllowCredentials(true); config.setAllowCredentials(true);
// 允许的请求方法 // 明确列出允许的HTTP方法比使用通配符更安全
config.addAllowedMethod("*"); config.addAllowedMethod("GET");
config.addAllowedMethod("POST");
config.addAllowedMethod("PUT");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("PATCH");
// 允许的请求头 // 允许的请求头
config.addAllowedHeader("*"); config.addAllowedHeader("*");
// 暴露的响应头,这些头信息可以被前端JavaScript访问 // 明确暴露的响应头,对于JWT认证很重要
config.addExposedHeader("*"); config.addExposedHeader("Authorization");
config.addExposedHeader("Content-Type");
config.addExposedHeader("X-Requested-With");
config.addExposedHeader("Accept");
config.addExposedHeader("Access-Control-Allow-Origin");
config.addExposedHeader("Access-Control-Allow-Credentials");
// 设置预检请求的有效期(秒) // 设置预检请求的有效期(秒)
config.setMaxAge(3600L); config.setMaxAge(86400L); // 增加到24小时减少预检请求次数
// 创建基于URL的CORS配置源 // 创建基于URL的CORS配置源
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

View File

@@ -48,7 +48,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
if (token != null && validateToken(token)) { if (token != null && validateToken(token)) {
// 从token中获取用户名 // 从token中获取用户名
String username = jwtUtils.getUsernameFromToken(token); String username = jwtUtils.getUsernameFromToken(token);
System.out.println("username: " + username);
// 加载用户信息 // 加载用户信息
UserDetails userDetails = userDetailsService.loadUserByUsername(username); UserDetails userDetails = userDetailsService.loadUserByUsername(username);

View File

@@ -1,6 +1,6 @@
package com.qf.myafterprojecy.config; package com.qf.myafterprojecy.config;
import javax.ws.rs.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@@ -15,6 +15,7 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import javax.servlet.http.HttpServletResponse;
/** /**
* Spring Security配置类 * Spring Security配置类
@@ -53,19 +54,24 @@ public class SecurityConfig {
@Bean @Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http http
// 启用CORS支持确保与CorsConfig中配置的过滤器配合工作
.cors().and()
// 禁用CSRF保护对于API服务通常不需要 // 禁用CSRF保护对于API服务通常不需要
.csrf().disable() .csrf().disable()
// 配置URL访问权限 // 配置URL访问权限
.authorizeRequests() .authorizeRequests()
// 允许公开访问的路径 // 允许公开访问的路径
// 登录和认证相关端点应该全部公开
.antMatchers("/api/auth/**").permitAll()
// 公开get请求 // 公开get请求
.antMatchers(HttpMethod.GET,"/api/auth/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/help/**").permitAll() .antMatchers(HttpMethod.GET,"/api/help/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/category-attributes/**").permitAll() .antMatchers(HttpMethod.GET,"/api/category-attributes/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/markdowns/**").permitAll() .antMatchers(HttpMethod.GET,"/api/markdowns/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/articles/**").permitAll() .antMatchers(HttpMethod.GET,"/api/articles/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/messages/**").permitAll() .antMatchers(HttpMethod.GET,"/api/messages/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/categories/**").permitAll() .antMatchers(HttpMethod.GET,"/api/categories/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/category-attributes/**").permitAll()
.antMatchers(HttpMethod.GET,"/api/nonsense/**").permitAll()
// 公开post请求 // 公开post请求
.antMatchers(HttpMethod.POST,"/api/messages/**").permitAll() .antMatchers(HttpMethod.POST,"/api/messages/**").permitAll()
.antMatchers(HttpMethod.POST,"/api/users/**").permitAll() .antMatchers(HttpMethod.POST,"/api/users/**").permitAll()
@@ -76,7 +82,29 @@ public class SecurityConfig {
.and() .and()
// 配置会话管理,使用无状态会话 // 配置会话管理,使用无状态会话
.sessionManagement() .sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS); .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
// 确保OPTIONS请求能够通过处理预检请求
.exceptionHandling()
.authenticationEntryPoint((request, response, authException) -> {
// 设置CORS头信息
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Max-Age", "86400");
// 如果是预检请求直接返回200
if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
// 未认证处理
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("{\"message\": \"未授权访问,请先登录\"}");
});
// 添加JWT认证过滤器 // 添加JWT认证过滤器
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
@@ -86,10 +114,23 @@ public class SecurityConfig {
http.addFilterBefore((request, response, chain) -> { http.addFilterBefore((request, response, chain) -> {
// 确保响应使用UTF-8编码 // 确保响应使用UTF-8编码
response.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8"); response.setContentType("application/json;charset=UTF-8");
chain.doFilter(request, response); chain.doFilter(request, response);
}, JwtAuthenticationFilter.class); }, JwtAuthenticationFilter.class);
// 配置访问拒绝处理器
http.exceptionHandling()
.accessDeniedHandler((request, response, accessDeniedException) -> {
// 设置CORS头信息
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
// 无权限处理
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("{\"message\": \"权限不足,无法访问\"}");
});
return http.build(); return http.build();
} }
} }

View File

@@ -70,7 +70,6 @@ public class ArticleController {
return articleService.getArticlesByAttribute(attributeId); return articleService.getArticlesByAttribute(attributeId);
} }
/**
/** /**
* 根据属性ID获取最新文章按创建时间降序 * 根据属性ID获取最新文章按创建时间降序
* @param attributeId 属性ID * @param attributeId 属性ID
@@ -88,7 +87,7 @@ public class ArticleController {
* @return 返回包含新创建文章信息的ResponseMessage对象 * @return 返回包含新创建文章信息的ResponseMessage对象
*/ */
@PostMapping @PostMapping
@PreAuthorize("hasRole('AUTHOR')") @PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Article> createArticle(@Valid @RequestBody ArticleDto articleDto) { public ResponseMessage<Article> createArticle(@Valid @RequestBody ArticleDto articleDto) {
return articleService.saveArticle(articleDto); return articleService.saveArticle(articleDto);
} }
@@ -109,7 +108,7 @@ public class ArticleController {
* @return 返回包含更新后文章信息的ResponseMessage对象 * @return 返回包含更新后文章信息的ResponseMessage对象
*/ */
@PutMapping("/{id}") @PutMapping("/{id}")
@PreAuthorize("hasRole('AUTHOR')") @PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Article> updateArticle( public ResponseMessage<Article> updateArticle(
@PathVariable Integer id, @PathVariable Integer id,
@Valid @RequestBody ArticleDto articleDto) { @Valid @RequestBody ArticleDto articleDto) {
@@ -123,7 +122,7 @@ public class ArticleController {
* @return 返回包含被删除文章信息的ResponseMessage对象 * @return 返回包含被删除文章信息的ResponseMessage对象
*/ */
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
@PreAuthorize("hasRole('AUTHOR') or hasRole('ADMIN')") @PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Article> deleteArticle(@PathVariable Integer id) { public ResponseMessage<Article> deleteArticle(@PathVariable Integer id) {
return articleService.deleteArticle(id); return articleService.deleteArticle(id);
} }

View File

@@ -35,7 +35,11 @@ public class CategoryAttributeController {
log.info("接收根据ID获取分类属性的请求: ID={}", id); log.info("接收根据ID获取分类属性的请求: ID={}", id);
return categoryAttributeService.getCategoryAttributeById(id); return categoryAttributeService.getCategoryAttributeById(id);
} }
@GetMapping
public ResponseMessage<List<Category_attribute>> getAttributeCount() {
log.info("接收获取分类属性数量的请求");
return categoryAttributeService.getAllCategoryAttributes();
}
/** /**
* 根据分类ID获取属性列表 * 根据分类ID获取属性列表

View File

@@ -53,8 +53,8 @@ public class HelpController {
// 读取文件内容 // 读取文件内容
String markdownContent = new String(FileCopyUtils.copyToByteArray(new FileInputStream(readmeFile)), StandardCharsets.UTF_8); String markdownContent = new String(FileCopyUtils.copyToByteArray(new FileInputStream(readmeFile)), StandardCharsets.UTF_8);
// 将Markdown转换为HTML // 将Markdown转换为HTML
// String htmlContent = convertMarkdownToHtml(markdownContent); String htmlContent = convertMarkdownToHtml(markdownContent);
return ResponseMessage.success(markdownContent, "获取API文档成功"); return ResponseMessage.success(htmlContent, "获取API文档成功");
} catch (IOException e) { } catch (IOException e) {
return ResponseMessage.error("读取README_API.md文件失败: " + e.getMessage()); return ResponseMessage.error("读取README_API.md文件失败: " + e.getMessage());
} }

View File

@@ -108,12 +108,11 @@ public class MessageController {
logger.info("接收删除消息的请求: {}", id); logger.info("接收删除消息的请求: {}", id);
return messageService.deleteMessage(id); return messageService.deleteMessage(id);
} }
//删除所有评论 //删除所有评论 - 仅管理员可操作
@DeleteMapping("/all") @DeleteMapping("/all")
@PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Void> deleteAllMessages() { public ResponseMessage<Void> deleteAllMessages() {
logger.info("接收删除所有消息的请求"); logger.info("接收删除所有消息的请求");
return messageService.deleteAllMessages(); return messageService.deleteAllMessages();
} }
// 新增API端点
} }

View File

@@ -0,0 +1,87 @@
package com.qf.myafterprojecy.controller;
import com.qf.myafterprojecy.config.ResponseMessage;
import com.qf.myafterprojecy.pojo.Nonsense;
import com.qf.myafterprojecy.pojo.dto.NonsenseDto;
import com.qf.myafterprojecy.service.imp.INonsenseService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.List;
@RestController
@RequestMapping("/api/nonsense")
@Validated
public class NonsenseController {
private static final Logger logger = LoggerFactory.getLogger(NonsenseController.class);
@Autowired
private INonsenseService nonsenseService;
/**
* 获取所有随机内容
* @return 随机内容列表
*/
@GetMapping("")
public ResponseMessage<List<Nonsense>> getAllNonsense() {
logger.info("请求获取所有随机内容");
return nonsenseService.getAllNonsense();
}
/**
* 根据ID获取随机内容
* @param id 随机内容ID
* @return 随机内容
*/
@GetMapping("/{id}")
public ResponseMessage<Nonsense> getNonsenseById(@PathVariable("id") Integer id) {
logger.info("请求获取ID为{}的随机内容", id);
return nonsenseService.getNonsenseById(id);
}
/**
* 创建随机内容
* 需要管理员权限
* @param nonsenseDto 随机内容数据
* @return 创建结果
*/
@PostMapping("")
@PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Nonsense> saveNonsense(@Valid @RequestBody NonsenseDto nonsenseDto) {
logger.info("请求保存随机内容");
return nonsenseService.saveNonsense(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);
return nonsenseService.updateNonsense(id, nonsenseDto);
}
/**
* 删除随机内容
* 需要管理员权限
* @param id 随机内容ID
* @return 删除结果
*/
@DeleteMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseMessage<Boolean> deleteNonsense(@PathVariable("id") Integer id) {
logger.info("请求删除ID为{}的随机内容", id);
return nonsenseService.deleteNonsense(id);
}
}

View File

@@ -17,7 +17,6 @@ public class Article {
@Column(name = "title") @Column(name = "title")
private String title; private String title;
@NotBlank(message = "内容不能为空")
@Column(name = "content", columnDefinition = "TEXT") @Column(name = "content", columnDefinition = "TEXT")
private String content; private String content;
@@ -44,7 +43,6 @@ public class Article {
private Integer status; // 0-草稿1-已发布2-已删除 private Integer status; // 0-草稿1-已发布2-已删除
@Column(name = "markdownscontent") @Column(name = "markdownscontent")
@NotBlank(message = "Markdown内容不能为空")
private String markdownscontent; private String markdownscontent;
// Getters and Setters // Getters and Setters

View File

@@ -8,7 +8,6 @@ import java.util.Date;
public class Message { public class Message {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "messageid") @Column(name = "messageid")
private Integer messageid; private Integer messageid;
@@ -21,6 +20,9 @@ public class Message {
@Column(name = "content", columnDefinition = "text") @Column(name = "content", columnDefinition = "text")
private String content; private String content;
@Column(name = "messageimg")
private String messageimg;
@Temporal(TemporalType.TIMESTAMP) @Temporal(TemporalType.TIMESTAMP)
@Column(name = "created_at") @Column(name = "created_at")
private Date createdAt; private Date createdAt;
@@ -37,6 +39,7 @@ public class Message {
@Column(name = "likes") @Column(name = "likes")
private Integer likes; // 点赞数 private Integer likes; // 点赞数
public Integer getLikes() { public Integer getLikes() {
return likes; return likes;
} }
@@ -108,4 +111,12 @@ public class Message {
public void setArticleid(Integer articleid) { public void setArticleid(Integer articleid) {
this.articleid = articleid; this.articleid = articleid;
} }
public String getMessageimg() {
return messageimg;
}
public void setMessageimg(String messageimg) {
this.messageimg = messageimg;
}
} }

View File

@@ -0,0 +1,38 @@
package com.qf.myafterprojecy.pojo;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "nonsense")
public class Nonsense {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false, unique = true)
private Integer id;
@Column(name = "content",nullable = false)
private String content;
@Column(name = "time")
private Date time;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}

View File

@@ -20,6 +20,8 @@ public class MessageDto {
private Integer articleid; private Integer articleid;
private Integer likes; private Integer likes;
private String messageimg;
public Integer getReplyid() { public Integer getReplyid() {
return replyid; return replyid;
@@ -92,4 +94,12 @@ public class MessageDto {
public void setLikes(Integer likes) { public void setLikes(Integer likes) {
this.likes = likes; this.likes = likes;
} }
public String getMessageimg() {
return messageimg;
}
public void setMessageimg(String messageimg) {
this.messageimg = messageimg;
}
} }

View File

@@ -0,0 +1,36 @@
package com.qf.myafterprojecy.pojo.dto;
import java.util.Date;
public class NonsenseDto {
private Integer id;
private String content;
private Date time;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}

View File

@@ -79,6 +79,7 @@ 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-已删除 * @param status 文章状态0-草稿1-已发布2-已删除

View File

@@ -0,0 +1,9 @@
package com.qf.myafterprojecy.repository;
import com.qf.myafterprojecy.pojo.Nonsense;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface NonsenseRepository extends JpaRepository<Nonsense, Integer> {
}

View File

@@ -24,6 +24,27 @@ public class CategoryAttributeService implements ICategoryAttributeService {
@Autowired @Autowired
private CategoryAttributeRepository categoryAttributeRepository; private CategoryAttributeRepository categoryAttributeRepository;
/**
* 获取全部分类属性
* @return 所有分类属性列表
*/
@Override
@Transactional(readOnly = true)
public ResponseMessage<List<Category_attribute>> getAllCategoryAttributes() {
try {
List<Category_attribute> attributes = categoryAttributeRepository.findAll();
return ResponseMessage.success(attributes, "获取所有分类属性成功");
} catch (DataAccessException e) {
log.error("获取所有分类属性失败: {}", e.getMessage());
return ResponseMessage.error("获取所有分类属性失败");
}
}
/**
* 根据ID获取分类属性
* @param id 属性ID
* @return 分类属性信息
*/
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseMessage<Category_attribute> getCategoryAttributeById(Integer id) { public ResponseMessage<Category_attribute> getCategoryAttributeById(Integer id) {
@@ -48,6 +69,11 @@ public class CategoryAttributeService implements ICategoryAttributeService {
} }
} }
/**
* 根据分类ID获取属性列表
* @param categoryId 分类ID
* @return 属性列表
*/
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseMessage<List<Category_attribute>> getAttributesByCategoryId(Integer categoryId) { public ResponseMessage<List<Category_attribute>> getAttributesByCategoryId(Integer categoryId) {
@@ -64,6 +90,11 @@ public class CategoryAttributeService implements ICategoryAttributeService {
} }
} }
/**
* 保存分类属性
* @param dto 分类属性DTO
* @return 保存结果
*/
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseMessage<Category_attribute> saveCategoryAttribute(CategoryAttributeDto dto) { public ResponseMessage<Category_attribute> saveCategoryAttribute(CategoryAttributeDto dto) {
@@ -88,6 +119,12 @@ public class CategoryAttributeService implements ICategoryAttributeService {
} }
} }
/**
* 更新分类属性
* @param id 属性ID
* @param dto 分类属性DTO
* @return 更新结果
*/
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseMessage<Category_attribute> updateCategoryAttribute(Integer id, CategoryAttributeDto dto) { public ResponseMessage<Category_attribute> updateCategoryAttribute(Integer id, CategoryAttributeDto dto) {
@@ -126,6 +163,11 @@ public class CategoryAttributeService implements ICategoryAttributeService {
} }
} }
/**
* 删除分类属性
* @param id 属性ID
* @return 删除结果
*/
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ResponseMessage<Boolean> deleteCategoryAttribute(Integer id) { public ResponseMessage<Boolean> deleteCategoryAttribute(Integer id) {
@@ -147,7 +189,12 @@ public class CategoryAttributeService implements ICategoryAttributeService {
return ResponseMessage.error("删除分类属性失败"); return ResponseMessage.error("删除分类属性失败");
} }
} }
/**
* 检查分类属性是否存在
* @param categoryId 分类ID
* @param attributeName 属性名称
* @return 是否存在
*/
@Override @Override
@Transactional(readOnly = true) @Transactional(readOnly = true)
public ResponseMessage<Boolean> existsByCategoryAndName(Integer categoryId, String attributeName) { public ResponseMessage<Boolean> existsByCategoryAndName(Integer categoryId, String attributeName) {

View File

@@ -0,0 +1,132 @@
package com.qf.myafterprojecy.service;
import com.qf.myafterprojecy.config.ResponseMessage;
import com.qf.myafterprojecy.pojo.Nonsense;
import com.qf.myafterprojecy.pojo.dto.NonsenseDto;
import com.qf.myafterprojecy.repository.NonsenseRepository;
import com.qf.myafterprojecy.service.imp.INonsenseService;
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.Date;
import java.util.List;
import java.util.Optional;
@Service
public class NonsenseService implements INonsenseService {
private static final Logger logger = LoggerFactory.getLogger(NonsenseService.class);
@Autowired
private NonsenseRepository nonsenseRepository;
@Override
public ResponseMessage<List<Nonsense>> getAllNonsense() {
try {
List<Nonsense> nonsenseList = nonsenseRepository.findAll();
logger.info("获取所有随机内容成功,共{}条数据", nonsenseList.size());
return new ResponseMessage<>(200, "获取成功", nonsenseList, true);
} catch (DataAccessException e) {
logger.error("获取所有随机内容失败", e);
return new ResponseMessage<>(500, "数据库查询异常", null, false);
} catch (Exception e) {
logger.error("获取所有随机内容失败", e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@Override
public ResponseMessage<Nonsense> getNonsenseById(Integer id) {
try {
Optional<Nonsense> nonsenseOptional = nonsenseRepository.findById(id);
if (nonsenseOptional.isPresent()) {
logger.info("获取ID为{}的随机内容成功", id);
return new ResponseMessage<>(200, "获取成功", nonsenseOptional.get(), true);
} else {
logger.warn("未找到ID为{}的随机内容", id);
return new ResponseMessage<>(404, "未找到指定随机内容", null, false);
}
} catch (DataAccessException e) {
logger.error("根据ID查询随机内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "数据库查询异常", null, false);
} catch (Exception e) {
logger.error("根据ID查询随机内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@Override
@Transactional
public ResponseMessage<Nonsense> saveNonsense(NonsenseDto nonsenseDto) {
try {
Nonsense nonsense = new Nonsense();
BeanUtils.copyProperties(nonsenseDto, nonsense);
// 设置创建时间
if (nonsense.getTime() == null) {
nonsense.setTime(new Date());
}
Nonsense savedNonsense = nonsenseRepository.save(nonsense);
logger.info("保存随机内容成功ID: {}", savedNonsense.getId());
return new ResponseMessage<>(200, "保存成功", savedNonsense, true);
} catch (DataAccessException e) {
logger.error("保存随机内容失败", e);
return new ResponseMessage<>(500, "数据库操作异常", null, false);
} catch (Exception e) {
logger.error("保存随机内容失败", e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@Override
@Transactional
public ResponseMessage<Nonsense> updateNonsense(Integer id, NonsenseDto nonsenseDto) {
try {
Optional<Nonsense> nonsenseOptional = nonsenseRepository.findById(id);
if (nonsenseOptional.isPresent()) {
Nonsense nonsense = nonsenseOptional.get();
BeanUtils.copyProperties(nonsenseDto, nonsense, "id");
Nonsense updatedNonsense = nonsenseRepository.save(nonsense);
logger.info("更新随机内容成功ID: {}", id);
return new ResponseMessage<>(200, "更新成功", updatedNonsense, true);
} else {
logger.warn("更新失败未找到ID为{}的随机内容", id);
return new ResponseMessage<>(404, "未找到指定随机内容", null, false);
}
} catch (DataAccessException e) {
logger.error("更新随机内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "数据库操作异常", null, false);
} catch (Exception e) {
logger.error("更新随机内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "服务器内部错误", null, false);
}
}
@Override
@Transactional
public ResponseMessage<Boolean> deleteNonsense(Integer id) {
try {
if (nonsenseRepository.existsById(id)) {
nonsenseRepository.deleteById(id);
logger.info("删除随机内容成功ID: {}", id);
return new ResponseMessage<>(200, "删除成功", true, true);
} else {
logger.warn("删除失败未找到ID为{}的随机内容", id);
return new ResponseMessage<>(404, "未找到指定随机内容", false, false);
}
} catch (DataAccessException e) {
logger.error("删除随机内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "数据库操作异常", false, false);
} catch (Exception e) {
logger.error("删除随机内容失败ID: {}", id, e);
return new ResponseMessage<>(500, "服务器内部错误", false, false);
}
}
}

View File

@@ -7,6 +7,11 @@ import com.qf.myafterprojecy.pojo.dto.CategoryAttributeDto;
import java.util.List; import java.util.List;
public interface ICategoryAttributeService { public interface ICategoryAttributeService {
/**
* 获取全部分类属性
* @return 所有分类属性列表
*/
ResponseMessage<List<Category_attribute>> getAllCategoryAttributes();
/** /**
* 根据ID获取分类属性 * 根据ID获取分类属性

View File

@@ -0,0 +1,44 @@
package com.qf.myafterprojecy.service.imp;
import com.qf.myafterprojecy.config.ResponseMessage;
import com.qf.myafterprojecy.pojo.Nonsense;
import com.qf.myafterprojecy.pojo.dto.NonsenseDto;
import java.util.List;
public interface INonsenseService {
/**
* 获取所有随机内容
* @return 随机内容列表
*/
ResponseMessage<List<Nonsense>> getAllNonsense();
/**
* 根据ID获取随机内容
* @param id 随机内容ID
* @return 随机内容
*/
ResponseMessage<Nonsense> getNonsenseById(Integer id);
/**
* 保存随机内容
* @param nonsenseDto 随机内容数据传输对象
* @return 保存结果
*/
ResponseMessage<Nonsense> saveNonsense(NonsenseDto nonsenseDto);
/**
* 更新随机内容
* @param id 随机内容ID
* @param nonsenseDto 随机内容数据传输对象
* @return 更新结果
*/
ResponseMessage<Nonsense> updateNonsense(Integer id, NonsenseDto nonsenseDto);
/**
* 删除随机内容
* @param id 随机内容ID
* @return 删除结果
*/
ResponseMessage<Boolean> deleteNonsense(Integer id);
}