feat: 添加随机内容模块并优化安全配置
新增Nonsense相关实体、DTO、Repository、Service和Controller,实现随机内容的CRUD功能 优化CORS和安全配置,增加更精细的权限控制和错误处理 移除Article和Message中不必要的验证注解,调整部分API的权限要求
This commit is contained in:
@@ -20,23 +20,33 @@ public class CorsConfig {
|
||||
// 创建CORS配置对象
|
||||
CorsConfiguration config = new CorsConfiguration();
|
||||
|
||||
// 允许的来源,这里允许所有来源,实际生产环境应该限制特定域名
|
||||
// 允许的来源,使用通配符模式
|
||||
config.addAllowedOriginPattern("*");
|
||||
|
||||
// 允许携带凭证(如Cookie)
|
||||
config.setAllowCredentials(true);
|
||||
|
||||
// 允许的请求方法
|
||||
config.addAllowedMethod("*");
|
||||
// 明确列出允许的HTTP方法,比使用通配符更安全
|
||||
config.addAllowedMethod("GET");
|
||||
config.addAllowedMethod("POST");
|
||||
config.addAllowedMethod("PUT");
|
||||
config.addAllowedMethod("DELETE");
|
||||
config.addAllowedMethod("OPTIONS");
|
||||
config.addAllowedMethod("PATCH");
|
||||
|
||||
// 允许的请求头
|
||||
config.addAllowedHeader("*");
|
||||
|
||||
// 暴露的响应头,这些头信息可以被前端JavaScript访问
|
||||
config.addExposedHeader("*");
|
||||
// 明确暴露的响应头,对于JWT认证很重要
|
||||
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配置源
|
||||
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
|
||||
@@ -48,7 +48,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
if (token != null && validateToken(token)) {
|
||||
// 从token中获取用户名
|
||||
String username = jwtUtils.getUsernameFromToken(token);
|
||||
|
||||
System.out.println("username: " + username);
|
||||
// 加载用户信息
|
||||
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
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.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.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* Spring Security配置类
|
||||
@@ -53,19 +54,24 @@ public class SecurityConfig {
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
// 启用CORS支持,确保与CorsConfig中配置的过滤器配合工作
|
||||
.cors().and()
|
||||
// 禁用CSRF保护(对于API服务通常不需要)
|
||||
.csrf().disable()
|
||||
// 配置URL访问权限
|
||||
.authorizeRequests()
|
||||
// 允许公开访问的路径
|
||||
// 登录和认证相关端点应该全部公开
|
||||
.antMatchers("/api/auth/**").permitAll()
|
||||
// 公开get请求
|
||||
.antMatchers(HttpMethod.GET,"/api/auth/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET,"/api/help/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET,"/api/category-attributes/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET,"/api/markdowns/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET,"/api/articles/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET,"/api/messages/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET,"/api/categories/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET,"/api/category-attributes/**").permitAll()
|
||||
.antMatchers(HttpMethod.GET,"/api/nonsense/**").permitAll()
|
||||
// 公开post请求
|
||||
.antMatchers(HttpMethod.POST,"/api/messages/**").permitAll()
|
||||
.antMatchers(HttpMethod.POST,"/api/users/**").permitAll()
|
||||
@@ -76,7 +82,29 @@ public class SecurityConfig {
|
||||
.and()
|
||||
// 配置会话管理,使用无状态会话
|
||||
.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认证过滤器
|
||||
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
|
||||
@@ -86,10 +114,23 @@ public class SecurityConfig {
|
||||
http.addFilterBefore((request, response, chain) -> {
|
||||
// 确保响应使用UTF-8编码
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("text/html;charset=UTF-8");
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
chain.doFilter(request, response);
|
||||
}, 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();
|
||||
}
|
||||
}
|
||||
@@ -70,7 +70,6 @@ public class ArticleController {
|
||||
return articleService.getArticlesByAttribute(attributeId);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* 根据属性ID获取最新文章(按创建时间降序)
|
||||
* @param attributeId 属性ID
|
||||
@@ -88,7 +87,7 @@ public class ArticleController {
|
||||
* @return 返回包含新创建文章信息的ResponseMessage对象
|
||||
*/
|
||||
@PostMapping
|
||||
@PreAuthorize("hasRole('AUTHOR')")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseMessage<Article> createArticle(@Valid @RequestBody ArticleDto articleDto) {
|
||||
return articleService.saveArticle(articleDto);
|
||||
}
|
||||
@@ -109,7 +108,7 @@ public class ArticleController {
|
||||
* @return 返回包含更新后文章信息的ResponseMessage对象
|
||||
*/
|
||||
@PutMapping("/{id}")
|
||||
@PreAuthorize("hasRole('AUTHOR')")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseMessage<Article> updateArticle(
|
||||
@PathVariable Integer id,
|
||||
@Valid @RequestBody ArticleDto articleDto) {
|
||||
@@ -123,7 +122,7 @@ public class ArticleController {
|
||||
* @return 返回包含被删除文章信息的ResponseMessage对象
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
@PreAuthorize("hasRole('AUTHOR') or hasRole('ADMIN')")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseMessage<Article> deleteArticle(@PathVariable Integer id) {
|
||||
return articleService.deleteArticle(id);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,11 @@ public class CategoryAttributeController {
|
||||
log.info("接收根据ID获取分类属性的请求: ID={}", id);
|
||||
return categoryAttributeService.getCategoryAttributeById(id);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseMessage<List<Category_attribute>> getAttributeCount() {
|
||||
log.info("接收获取分类属性数量的请求");
|
||||
return categoryAttributeService.getAllCategoryAttributes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类ID获取属性列表
|
||||
|
||||
@@ -53,8 +53,8 @@ public class HelpController {
|
||||
// 读取文件内容
|
||||
String markdownContent = new String(FileCopyUtils.copyToByteArray(new FileInputStream(readmeFile)), StandardCharsets.UTF_8);
|
||||
// 将Markdown转换为HTML
|
||||
// String htmlContent = convertMarkdownToHtml(markdownContent);
|
||||
return ResponseMessage.success(markdownContent, "获取API文档成功");
|
||||
String htmlContent = convertMarkdownToHtml(markdownContent);
|
||||
return ResponseMessage.success(htmlContent, "获取API文档成功");
|
||||
} catch (IOException e) {
|
||||
return ResponseMessage.error("读取README_API.md文件失败: " + e.getMessage());
|
||||
}
|
||||
|
||||
@@ -108,12 +108,11 @@ public class MessageController {
|
||||
logger.info("接收删除消息的请求: {}", id);
|
||||
return messageService.deleteMessage(id);
|
||||
}
|
||||
//删除所有评论
|
||||
//删除所有评论 - 仅管理员可操作
|
||||
@DeleteMapping("/all")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
public ResponseMessage<Void> deleteAllMessages() {
|
||||
logger.info("接收删除所有消息的请求");
|
||||
return messageService.deleteAllMessages();
|
||||
}
|
||||
// 新增API端点
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@ public class Article {
|
||||
@Column(name = "title")
|
||||
private String title;
|
||||
|
||||
@NotBlank(message = "内容不能为空")
|
||||
@Column(name = "content", columnDefinition = "TEXT")
|
||||
private String content;
|
||||
|
||||
@@ -44,7 +43,6 @@ public class Article {
|
||||
private Integer status; // 0-草稿,1-已发布,2-已删除
|
||||
|
||||
@Column(name = "markdownscontent")
|
||||
@NotBlank(message = "Markdown内容不能为空")
|
||||
private String markdownscontent;
|
||||
|
||||
// Getters and Setters
|
||||
|
||||
@@ -8,7 +8,6 @@ import java.util.Date;
|
||||
public class Message {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
|
||||
@Column(name = "messageid")
|
||||
private Integer messageid;
|
||||
|
||||
@@ -21,6 +20,9 @@ public class Message {
|
||||
@Column(name = "content", columnDefinition = "text")
|
||||
private String content;
|
||||
|
||||
@Column(name = "messageimg")
|
||||
private String messageimg;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
@Column(name = "created_at")
|
||||
private Date createdAt;
|
||||
@@ -37,6 +39,7 @@ public class Message {
|
||||
@Column(name = "likes")
|
||||
private Integer likes; // 点赞数
|
||||
|
||||
|
||||
public Integer getLikes() {
|
||||
return likes;
|
||||
}
|
||||
@@ -108,4 +111,12 @@ public class Message {
|
||||
public void setArticleid(Integer articleid) {
|
||||
this.articleid = articleid;
|
||||
}
|
||||
|
||||
public String getMessageimg() {
|
||||
return messageimg;
|
||||
}
|
||||
|
||||
public void setMessageimg(String messageimg) {
|
||||
this.messageimg = messageimg;
|
||||
}
|
||||
}
|
||||
|
||||
38
src/main/java/com/qf/myafterprojecy/pojo/Nonsense.java
Normal file
38
src/main/java/com/qf/myafterprojecy/pojo/Nonsense.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,6 +20,8 @@ public class MessageDto {
|
||||
private Integer articleid;
|
||||
|
||||
private Integer likes;
|
||||
|
||||
private String messageimg;
|
||||
|
||||
public Integer getReplyid() {
|
||||
return replyid;
|
||||
@@ -92,4 +94,12 @@ public class MessageDto {
|
||||
public void setLikes(Integer likes) {
|
||||
this.likes = likes;
|
||||
}
|
||||
|
||||
public String getMessageimg() {
|
||||
return messageimg;
|
||||
}
|
||||
|
||||
public void setMessageimg(String messageimg) {
|
||||
this.messageimg = messageimg;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
List<Article> findMostViewed();
|
||||
|
||||
/**
|
||||
* 根据状态查询文章列表
|
||||
* @param status 文章状态,0-草稿,1-已发布,2-已删除
|
||||
|
||||
@@ -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> {
|
||||
}
|
||||
@@ -24,6 +24,27 @@ public class CategoryAttributeService implements ICategoryAttributeService {
|
||||
@Autowired
|
||||
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
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseMessage<Category_attribute> getCategoryAttributeById(Integer id) {
|
||||
@@ -48,6 +69,11 @@ public class CategoryAttributeService implements ICategoryAttributeService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据分类ID获取属性列表
|
||||
* @param categoryId 分类ID
|
||||
* @return 属性列表
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseMessage<List<Category_attribute>> getAttributesByCategoryId(Integer categoryId) {
|
||||
@@ -64,6 +90,11 @@ public class CategoryAttributeService implements ICategoryAttributeService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存分类属性
|
||||
* @param dto 分类属性DTO
|
||||
* @return 保存结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseMessage<Category_attribute> saveCategoryAttribute(CategoryAttributeDto dto) {
|
||||
@@ -88,6 +119,12 @@ public class CategoryAttributeService implements ICategoryAttributeService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新分类属性
|
||||
* @param id 属性ID
|
||||
* @param dto 分类属性DTO
|
||||
* @return 更新结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseMessage<Category_attribute> updateCategoryAttribute(Integer id, CategoryAttributeDto dto) {
|
||||
@@ -126,6 +163,11 @@ public class CategoryAttributeService implements ICategoryAttributeService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除分类属性
|
||||
* @param id 属性ID
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ResponseMessage<Boolean> deleteCategoryAttribute(Integer id) {
|
||||
@@ -147,7 +189,12 @@ public class CategoryAttributeService implements ICategoryAttributeService {
|
||||
return ResponseMessage.error("删除分类属性失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查分类属性是否存在
|
||||
* @param categoryId 分类ID
|
||||
* @param attributeName 属性名称
|
||||
* @return 是否存在
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public ResponseMessage<Boolean> existsByCategoryAndName(Integer categoryId, String attributeName) {
|
||||
|
||||
132
src/main/java/com/qf/myafterprojecy/service/NonsenseService.java
Normal file
132
src/main/java/com/qf/myafterprojecy/service/NonsenseService.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,11 @@ import com.qf.myafterprojecy.pojo.dto.CategoryAttributeDto;
|
||||
import java.util.List;
|
||||
|
||||
public interface ICategoryAttributeService {
|
||||
/**
|
||||
* 获取全部分类属性
|
||||
* @return 所有分类属性列表
|
||||
*/
|
||||
ResponseMessage<List<Category_attribute>> getAllCategoryAttributes();
|
||||
|
||||
/**
|
||||
* 根据ID获取分类属性
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user