diff --git a/pom.xml b/pom.xml
index 75fc48a..5bd160e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,23 @@
mybatis-spring-boot-starter
2.2.2
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+
+ org.springframework.security
+ spring-security-config
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-aop
+
org.springframework.boot
spring-boot-devtools
diff --git a/src/main/java/com/qf/myafterprojecy/controller/ArticleController.java b/src/main/java/com/qf/myafterprojecy/controller/ArticleController.java
index e913b7d..6ec9b50 100644
--- a/src/main/java/com/qf/myafterprojecy/controller/ArticleController.java
+++ b/src/main/java/com/qf/myafterprojecy/controller/ArticleController.java
@@ -5,37 +5,63 @@ import com.qf.myafterprojecy.pojo.ResponseMessage;
import com.qf.myafterprojecy.pojo.dto.ArticleDto;
import com.qf.myafterprojecy.service.IArticleService;
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("/article")
+@RequestMapping("/api/articles")
+@Validated
public class ArticleController {
- /**
- *
- */
@Autowired
- IArticleService ArticleService;
+ private IArticleService articleService;
+
+ @GetMapping("/{id}")
+ public ResponseMessage getArticle(@PathVariable Integer id) {
+ return articleService.getArticleById(id);
+ }
@GetMapping
- public ResponseMessage> getArticleAllByID(@Validated @RequestBody ArticleDto articleDto){
- return ArticleService.getArticleAllByID(articleDto);
+ public ResponseMessage> getAllArticles() {
+ return articleService.getAllArticles();
}
-
- @PutMapping
- public ResponseMessage UpdateArticle(@RequestBody ArticleDto articleDto){
- return ArticleService.SaveArticle(articleDto);
- };
@PostMapping
- public ResponseMessage AddArticle(@RequestBody ArticleDto articleDto){
- return ArticleService.SaveArticle(articleDto);
+ @PreAuthorize("hasRole('AUTHOR')")
+ public ResponseMessage createArticle(@Valid @RequestBody ArticleDto articleDto) {
+ return articleService.saveArticle(articleDto);
}
- @DeleteMapping
- public ResponseMessage DeleteArticle(@RequestBody ArticleDto articleDto){
- return ArticleService.deleteArticle(articleDto.getArticleid());
+ @PutMapping("/{id}")
+ @PreAuthorize("hasRole('AUTHOR') or hasRole('ADMIN')")
+ public ResponseMessage updateArticle(
+ @PathVariable Integer id,
+ @Valid @RequestBody ArticleDto articleDto) {
+ return articleService.updateArticle(id, articleDto);
}
+ @DeleteMapping("/{id}")
+ @PreAuthorize("hasRole('AUTHOR') or hasRole('ADMIN')")
+ public ResponseMessage deleteArticle(@PathVariable Integer id) {
+ return articleService.deleteArticle(id);
+ }
+
+ @GetMapping("/author/{authorId}")
+ public ResponseMessage> getArticlesByAuthor(@PathVariable Integer authorId) {
+ return articleService.getArticlesByAuthor(authorId);
+ }
+
+ @GetMapping("/category/{categoryId}")
+ public ResponseMessage> getArticlesByCategory(@PathVariable Integer categoryId) {
+ return articleService.getArticlesByCategory(categoryId);
+ }
+
+ @GetMapping("/popular")
+ public ResponseMessage> getMostViewedArticles() {
+ return articleService.getMostViewedArticles();
+ }
}
diff --git a/src/main/java/com/qf/myafterprojecy/controller/MessageController.java b/src/main/java/com/qf/myafterprojecy/controller/MessageController.java
new file mode 100644
index 0000000..11ae3be
--- /dev/null
+++ b/src/main/java/com/qf/myafterprojecy/controller/MessageController.java
@@ -0,0 +1,35 @@
+package com.qf.myafterprojecy.controller;
+
+import com.qf.myafterprojecy.pojo.Message;
+import com.qf.myafterprojecy.pojo.ResponseMessage;
+import com.qf.myafterprojecy.pojo.dto.MessageDto;
+import com.qf.myafterprojecy.service.IMessageService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/api/messages")
+public class MessageController {
+ @Autowired
+ private IMessageService messageService;
+
+ @GetMapping
+ public ResponseMessage> getAllMessages() {
+ return messageService.getAllMessages();
+ }
+
+ @GetMapping("/{id}")
+ public ResponseMessage getMessage(@PathVariable Integer id) {
+ return messageService.getMessageById(id);
+ }
+
+ @PostMapping
+ public ResponseMessage createMessage(@RequestBody MessageDto message) {
+ return messageService.saveMessage(message);
+ }
+
+ @DeleteMapping("/{id}")
+ public ResponseMessage deleteMessage(@PathVariable Integer id) {
+ return messageService.deleteMessage(id);
+ }
+}
diff --git a/src/main/java/com/qf/myafterprojecy/pojo/Article.java b/src/main/java/com/qf/myafterprojecy/pojo/Article.java
index 07fa9e2..4edc98d 100644
--- a/src/main/java/com/qf/myafterprojecy/pojo/Article.java
+++ b/src/main/java/com/qf/myafterprojecy/pojo/Article.java
@@ -1,8 +1,9 @@
package com.qf.myafterprojecy.pojo;
-import lombok.Data;
-
import javax.persistence.*;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
@Entity
@Table(name = "article")
@@ -11,18 +12,35 @@ public class Article {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "articleid")
private Integer articleid;
+
+ @NotBlank(message = "标题不能为空")
@Column(name = "title")
private String title;
- @Column(name = "content")
+
+ @NotBlank(message = "内容不能为空")
+ @Column(name = "content", columnDefinition = "TEXT")
private String content;
+
+ @NotNull(message = "类别id不能为空")
+ @Column(name = "typeid")
+ private Integer typeid;
+
@Column(name = "img")
private String img;
- @Column(name = "typeid")
- private int typeid;
- @Column(name = "published_at")
- private String publisher_at;
+
@Column(name = "created_at")
- private String created_at;
+ private LocalDateTime createdAt;
+
+ @Column(name = "updated_at")
+ private LocalDateTime updatedAt;
+ @Column(name = "view_count")
+ private Integer viewCount;
+
+ @Column(name = "status")
+ private Integer status; // 0-草稿,1-已发布,2-已删除
+
+ // Getters and Setters
+
public Integer getArticleid() {
return articleid;
@@ -48,6 +66,38 @@ public class Article {
this.content = content;
}
+ public Integer getTypeid() {
+ return typeid;
+ }
+
+ public void setTypeid(Integer typeid) {
+ this.typeid = typeid;
+ }
+
+ public LocalDateTime getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(LocalDateTime createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public LocalDateTime getUpdatedAt() {
+ return updatedAt;
+ }
+
+ public void setUpdatedAt(LocalDateTime updatedAt) {
+ this.updatedAt = updatedAt;
+ }
+
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
public String getImg() {
return img;
}
@@ -56,40 +106,11 @@ public class Article {
this.img = img;
}
- public int getTypeid() {
- return typeid;
+ public Integer getViewCount() {
+ return viewCount;
}
- public void setTypeid(int typeid) {
- this.typeid = typeid;
- }
-
- public String getPublisher_at() {
- return publisher_at;
- }
-
- public void setPublisher_at(String publisher_at) {
- this.publisher_at = publisher_at;
- }
-
- public String getCreated_at() {
- return created_at;
- }
-
- public void setCreated_at(String created_at) {
- this.created_at = created_at;
- }
-
- @Override
- public String toString() {
- return "Article{" +
- "articleid=" + articleid +
- ", title='" + title + '\'' +
- ", content='" + content + '\'' +
- ", img='" + img + '\'' +
- ", typeid=" + typeid +
- ", publisher_at='" + publisher_at + '\'' +
- ", created_at='" + created_at + '\'' +
- '}';
+ public void setViewCount(Integer viewCount) {
+ this.viewCount = viewCount;
}
}
diff --git a/src/main/java/com/qf/myafterprojecy/pojo/Message.java b/src/main/java/com/qf/myafterprojecy/pojo/Message.java
new file mode 100644
index 0000000..f4d5b8a
--- /dev/null
+++ b/src/main/java/com/qf/myafterprojecy/pojo/Message.java
@@ -0,0 +1,83 @@
+package com.qf.myafterprojecy.pojo;
+
+import javax.persistence.*;
+import java.util.Date;
+
+@Entity
+@Table(name = "message")
+public class Message {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer messageid;
+
+ private String nickname;
+
+ private String email;
+
+ @Column(columnDefinition = "text")
+ private String content;
+
+ @Temporal(TemporalType.TIMESTAMP)
+ private Date createdAt;
+
+ private Integer parentid;
+
+ private Integer articleid;
+
+
+ public Integer getMessageid() {
+ return messageid;
+ }
+
+ public void setMessageid(Integer messageid) {
+ this.messageid = messageid;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public Date getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Integer getParentid() {
+ return parentid;
+ }
+
+ public void setParentid(Integer parentid) {
+ this.parentid = parentid;
+ }
+
+ public Integer getArticleid() {
+ return articleid;
+ }
+
+ public void setArticleid(Integer articleid) {
+ this.articleid = articleid;
+ }
+}
diff --git a/src/main/java/com/qf/myafterprojecy/pojo/ResponseMessage.java b/src/main/java/com/qf/myafterprojecy/pojo/ResponseMessage.java
index bc45cc3..6657f3d 100644
--- a/src/main/java/com/qf/myafterprojecy/pojo/ResponseMessage.java
+++ b/src/main/java/com/qf/myafterprojecy/pojo/ResponseMessage.java
@@ -2,10 +2,11 @@ package com.qf.myafterprojecy.pojo;
import lombok.Data;
import org.springframework.http.HttpStatus;
-
+@Data
public class ResponseMessage {
private Integer code;
private String message;
+ private boolean success;
private T data;
public ResponseMessage(Integer code, String message, T data) {
this.code = code;
@@ -13,6 +14,14 @@ public class ResponseMessage {
this.data = data;
}
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public void setSuccess(boolean success) {
+ this.success = success;
+ }
+
public Integer getCode() {
return code;
}
@@ -36,18 +45,54 @@ public class ResponseMessage {
public void setData(T data) {
this.data = data;
}
+ public ResponseMessage(Integer code, String message, T data, boolean success) {
+ this.code = code;
+ this.message = message;
+ this.data = data;
+ this.success = success;
+ }
// 接口请求成功
+ public static ResponseMessage success(T data ,String message ,boolean success) {
+ return new ResponseMessage(HttpStatus.OK.value(), message, data ,success);
+ }
+
+ /**
+ * 创建一个表示操作失败的响应消息
+ * @param message 失败原因的描述信息
+ * @return 返回一个包含错误状态码和错误信息的ResponseMessage对象
+ */
+ public static ResponseMessage failure(String message) {
+ return new ResponseMessage<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), message, null, false);
+ }
+
+
public static ResponseMessage success(T data) {
- return new ResponseMessage(HttpStatus.OK.value(), "success", data);
+ return new ResponseMessage<>(HttpStatus.OK.value(), "操作成功", data, true);
}
- public static ResponseMessage Delete(Boolean delete) {
- return new ResponseMessage(HttpStatus.OK.value(), "delete", delete);
+ public static ResponseMessage success(T data, String message) {
+ return new ResponseMessage<>(HttpStatus.OK.value(), message, data, true);
}
- public static ResponseMessage Save(Boolean save) {
- return new ResponseMessage(HttpStatus.OK.value(), "save", save);
+ public static ResponseMessage error(String message) {
+ return new ResponseMessage<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), message, null, false);
+ }
+
+ public static ResponseMessage error(Integer code, String message) {
+ return new ResponseMessage<>(code, message, null, false);
+ }
+
+ public static ResponseMessage Save(boolean success) {
+ return success ?
+ new ResponseMessage<>(HttpStatus.OK.value(), "保存成功", null, true) :
+ new ResponseMessage<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "保存失败", null, false);
+ }
+
+ public static ResponseMessage Delete(boolean success) {
+ return success ?
+ new ResponseMessage<>(HttpStatus.OK.value(), "删除成功", null, true) :
+ new ResponseMessage<>(HttpStatus.INTERNAL_SERVER_ERROR.value(), "删除失败", null, false);
}
}
diff --git a/src/main/java/com/qf/myafterprojecy/pojo/dto/ArticleDto.java b/src/main/java/com/qf/myafterprojecy/pojo/dto/ArticleDto.java
index dbcd37b..085c227 100644
--- a/src/main/java/com/qf/myafterprojecy/pojo/dto/ArticleDto.java
+++ b/src/main/java/com/qf/myafterprojecy/pojo/dto/ArticleDto.java
@@ -1,21 +1,32 @@
package com.qf.myafterprojecy.pojo.dto;
+import lombok.Getter;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+@Getter
public class ArticleDto {
- private Integer articleid;
- private String title;
- private String content;
- private String img;
- private Integer typeid;
- private String publisher_at;
- private String created_at;
+ private Integer id;
- public Integer getArticleid() {
- return articleid;
+ @NotBlank(message = "标题不能为空")
+ private String title;
+
+ @NotBlank(message = "内容不能为空")
+ private String content;
+
+ private String img;
+
+ private Integer status;
+
+ // Getters and Setters
+
+ public Integer getId() {
+ return id;
}
- public void setArticleid(Integer articleid) {
- this.articleid = articleid;
+ public void setId(Integer id) {
+ this.id = id;
}
public String getTitle() {
@@ -34,6 +45,14 @@ public class ArticleDto {
this.content = content;
}
+ public Integer getStatus() {
+ return status;
+ }
+
+ public void setStatus(Integer status) {
+ this.status = status;
+ }
+
public String getImg() {
return img;
}
@@ -41,41 +60,4 @@ public class ArticleDto {
public void setImg(String img) {
this.img = img;
}
-
- public Integer getTypeid() {
- return typeid;
- }
-
- public void setTypeid(Integer typeid) {
- this.typeid = typeid;
- }
-
- public String getPublisher_at() {
- return publisher_at;
- }
-
- public void setPublisher_at(String publisher_at) {
- this.publisher_at = publisher_at;
- }
-
- public String getCreated_at() {
- return created_at;
- }
-
- public void setCreated_at(String created_at) {
- this.created_at = created_at;
- }
-
- @Override
- public String toString() {
- return "ArticleDto{" +
- "articleid=" + articleid +
- ", title='" + title + '\'' +
- ", content='" + content + '\'' +
- ", img='" + img + '\'' +
- ", typeid=" + typeid +
- ", publisher_at='" + publisher_at + '\'' +
- ", created_at='" + created_at + '\'' +
- '}';
- }
}
diff --git a/src/main/java/com/qf/myafterprojecy/pojo/dto/MessageDto.java b/src/main/java/com/qf/myafterprojecy/pojo/dto/MessageDto.java
new file mode 100644
index 0000000..d19dade
--- /dev/null
+++ b/src/main/java/com/qf/myafterprojecy/pojo/dto/MessageDto.java
@@ -0,0 +1,77 @@
+package com.qf.myafterprojecy.pojo.dto;
+
+import javax.persistence.*;
+import java.util.Date;
+
+public class MessageDto {
+ private Integer messageid;
+
+ private String nickname;
+
+ private String email;
+
+ private String content;
+
+ private Date createdAt;
+
+ private Integer parentid;
+
+ private Integer articleid;
+
+
+ public Integer getMessageid() {
+ return messageid;
+ }
+
+ public void setMessageid(Integer messageid) {
+ this.messageid = messageid;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public Date getCreatedAt() {
+ return createdAt;
+ }
+
+ public void setCreatedAt(Date createdAt) {
+ this.createdAt = createdAt;
+ }
+
+ public Integer getParentid() {
+ return parentid;
+ }
+
+ public void setParentid(Integer parentid) {
+ this.parentid = parentid;
+ }
+
+ public Integer getArticleid() {
+ return articleid;
+ }
+
+ public void setArticleid(Integer articleid) {
+ this.articleid = articleid;
+ }
+}
diff --git a/src/main/java/com/qf/myafterprojecy/repository/ArticleRepository.java b/src/main/java/com/qf/myafterprojecy/repository/ArticleRepository.java
index 6f03b76..ff33fbe 100644
--- a/src/main/java/com/qf/myafterprojecy/repository/ArticleRepository.java
+++ b/src/main/java/com/qf/myafterprojecy/repository/ArticleRepository.java
@@ -1,9 +1,30 @@
package com.qf.myafterprojecy.repository;
import com.qf.myafterprojecy.pojo.Article;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Modifying;
+import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
+import java.util.List;
+
@Repository
-public interface ArticleRepository extends CrudRepository {
+//public interface ArticleRepository extends CrudRepository {
+//}
+public interface ArticleRepository extends JpaRepository {
+
+ @Query("SELECT a FROM Article a WHERE a.status = 1 AND a.articleid = :articleid")
+ List findPublishedByAuthor(@Param("authorId") Integer authorId);
+
+ @Query("SELECT a FROM Article a WHERE a.status = 1 AND a.typeid = :typeid")
+ List findPublishedByCategory(@Param("categoryId") Integer categoryId);
+
+ @Modifying
+ @Query("UPDATE Article a SET a.viewCount = a.viewCount + 1 WHERE a.id = :id")
+ void incrementViewCount(@Param("id") Integer id);
+
+ @Query("SELECT a FROM Article a WHERE a.status = 1 ORDER BY a.viewCount DESC")
+ List findMostViewed();
}
diff --git a/src/main/java/com/qf/myafterprojecy/repository/MessageRepository.java b/src/main/java/com/qf/myafterprojecy/repository/MessageRepository.java
new file mode 100644
index 0000000..cb6817c
--- /dev/null
+++ b/src/main/java/com/qf/myafterprojecy/repository/MessageRepository.java
@@ -0,0 +1,8 @@
+package com.qf.myafterprojecy.repository;
+
+import com.qf.myafterprojecy.pojo.Message;
+import org.springframework.data.repository.CrudRepository;
+
+public interface MessageRepository extends CrudRepository {
+ // 可根据需要添加自定义查询方法
+}
diff --git a/src/main/java/com/qf/myafterprojecy/service/ArticleService.java b/src/main/java/com/qf/myafterprojecy/service/ArticleService.java
index cbcd2c3..53cc562 100644
--- a/src/main/java/com/qf/myafterprojecy/service/ArticleService.java
+++ b/src/main/java/com/qf/myafterprojecy/service/ArticleService.java
@@ -4,39 +4,140 @@ import com.qf.myafterprojecy.pojo.Article;
import com.qf.myafterprojecy.pojo.ResponseMessage;
import com.qf.myafterprojecy.pojo.dto.ArticleDto;
import com.qf.myafterprojecy.repository.ArticleRepository;
+import lombok.extern.slf4j.Slf4j;
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.Collections;
+import java.time.LocalDateTime;
+import java.util.List;
+@Slf4j
@Service
-public class ArticleService implements IArticleService{
+public class ArticleService implements IArticleService {
+
@Autowired
- ArticleRepository articleRepository;
+ private ArticleRepository articleRepository;
@Override
- public ResponseMessage> getArticleAllByID(ArticleDto articleDto){
- Iterable Articles = null;
- if (articleDto.getArticleid()!=null && articleDto.getArticleid()!=0){
+ @Transactional(readOnly = true)
+ public ResponseMessage getArticleById(Integer id) {
+ try {
+ Article article = articleRepository.findById(id)
+ .orElseThrow(() -> new RuntimeException("文章不存在"));
- Articles = Collections.singleton(articleRepository.findById(articleDto.getArticleid()).orElseThrow(()-> new RuntimeException("没有该文章")));
- }else {
- Articles = articleRepository.findAll();
+ // 增加浏览次数
+ articleRepository.incrementViewCount(id);
+
+ return ResponseMessage.success(article);
+ } catch (Exception e) {
+ log.error("获取文章失败: {}", e.getMessage());
+ return ResponseMessage.failure("获取文章失败");
}
- return ResponseMessage.success(Articles) ;
}
@Override
- public ResponseMessage SaveArticle(ArticleDto article) {
- Article articlenew = new Article();
- BeanUtils.copyProperties(article,articlenew);
- return ResponseMessage.Save(articleRepository.save(articlenew)!= null);
+ @Transactional(readOnly = true)
+ public ResponseMessage> getAllArticles() {
+ try {
+ List articles = articleRepository.findAll();
+ return ResponseMessage.success(articles);
+ } catch (DataAccessException e) {
+ log.error("获取文章列表失败: {}", e.getMessage());
+ return ResponseMessage.failure("获取文章列表失败");
+ }
}
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public ResponseMessage saveArticle(ArticleDto articleDto) {
+ try {
+ Article article = new Article();
+ BeanUtils.copyProperties(articleDto, article);
+ article.setCreatedAt(LocalDateTime.now());
+ article.setUpdatedAt(LocalDateTime.now());
+ article.setImg(articleDto.getImg() != null ? articleDto.getImg() : "");
+ article.setStatus(articleDto.getStatus() != null ? articleDto.getStatus() : 0);
+
+ Article savedArticle = articleRepository.save(article);
+ return ResponseMessage.success(savedArticle);
+ } catch (DataAccessException e) {
+ log.error("保存文章失败: {}", e.getMessage());
+ return ResponseMessage.failure("保存文章失败");
+ }
+ }
@Override
- public ResponseMessage deleteArticle(Integer articleid) {
- return ResponseMessage.Delete(articleRepository.existsById(articleid)) ;
+ @Transactional(rollbackFor = Exception.class)
+ public ResponseMessage updateArticle(Integer id, ArticleDto articleDto) {
+ try {
+ Article article = articleRepository.findById(id)
+ .orElseThrow(() -> new RuntimeException("文章不存在"));
+
+ BeanUtils.copyProperties(articleDto, article);
+ article.setUpdatedAt(LocalDateTime.now());
+
+ Article updatedArticle = articleRepository.save(article);
+ return ResponseMessage.success(updatedArticle);
+ } catch (Exception e) {
+ log.error("更新文章失败: {}", e.getMessage());
+ return ResponseMessage.failure("更新文章失败");
+ }
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public ResponseMessage deleteArticle(Integer id) {
+ try {
+ Article article = articleRepository.findById(id)
+ .orElseThrow(() -> new RuntimeException("文章不存在"));
+
+ article.setStatus(2); // 标记为已删除
+ article.setUpdatedAt(LocalDateTime.now());
+ articleRepository.save(article);
+
+ return ResponseMessage.success(null);
+ } catch (Exception e) {
+ log.error("删除文章失败: {}", e.getMessage());
+ return ResponseMessage.failure("删除文章失败");
+ }
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public ResponseMessage> getArticlesByAuthor(Integer authorId) {
+ try {
+ List articles = articleRepository.findPublishedByAuthor(authorId);
+ return ResponseMessage.success(articles);
+ } catch (DataAccessException e) {
+ log.error("获取作者文章失败: {}", e.getMessage());
+ return ResponseMessage.failure("获取作者文章失败");
+ }
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public ResponseMessage> getArticlesByCategory(Integer categoryId) {
+ try {
+ List articles = articleRepository.findPublishedByCategory(categoryId);
+ return ResponseMessage.success(articles);
+ } catch (DataAccessException e) {
+ log.error("获取分类文章失败: {}", e.getMessage());
+ return ResponseMessage.failure("获取分类文章失败");
+ }
+ }
+
+ @Override
+ @Transactional(readOnly = true)
+ public ResponseMessage> getMostViewedArticles() {
+ try {
+ List articles = articleRepository.findMostViewed();
+ return ResponseMessage.success(articles);
+ } catch (DataAccessException e) {
+ log.error("获取热门文章失败: {}", e.getMessage());
+ return ResponseMessage.failure("获取热门文章失败");
+ }
}
}
diff --git a/src/main/java/com/qf/myafterprojecy/service/IArticleService.java b/src/main/java/com/qf/myafterprojecy/service/IArticleService.java
index b0a7da4..7b74b97 100644
--- a/src/main/java/com/qf/myafterprojecy/service/IArticleService.java
+++ b/src/main/java/com/qf/myafterprojecy/service/IArticleService.java
@@ -4,30 +4,15 @@ import com.qf.myafterprojecy.pojo.Article;
import com.qf.myafterprojecy.pojo.ResponseMessage;
import com.qf.myafterprojecy.pojo.dto.ArticleDto;
+import java.util.List;
+
public interface IArticleService {
-
- /**
- * 根据id查询 如果id为空查询所有
- *
- * @param articleDto
- * @return ResponseMessage
- */
- ResponseMessage> getArticleAllByID(ArticleDto articleDto);
-
-
- /**
- * 新增(id=0)
- * 修改 (id=修改数据的id)
- * @param article
- * @return ResponseMessage
- */
- ResponseMessage SaveArticle(ArticleDto article);
-
- /**
- * 删除
- * @param articleid
- * @return ResponseMessage
- */
- ResponseMessage deleteArticle(Integer articleid);
-
+ ResponseMessage getArticleById(Integer id);
+ ResponseMessage> getAllArticles();
+ ResponseMessage saveArticle(ArticleDto articleDto);
+ ResponseMessage updateArticle(Integer id, ArticleDto articleDto);
+ ResponseMessage deleteArticle(Integer id);
+ ResponseMessage> getArticlesByAuthor(Integer authorId);
+ ResponseMessage> getArticlesByCategory(Integer categoryId);
+ ResponseMessage> getMostViewedArticles();
}
diff --git a/src/main/java/com/qf/myafterprojecy/service/IMessageService.java b/src/main/java/com/qf/myafterprojecy/service/IMessageService.java
new file mode 100644
index 0000000..da9b4fe
--- /dev/null
+++ b/src/main/java/com/qf/myafterprojecy/service/IMessageService.java
@@ -0,0 +1,32 @@
+package com.qf.myafterprojecy.service;
+
+import com.qf.myafterprojecy.pojo.Message;
+import com.qf.myafterprojecy.pojo.ResponseMessage;
+import com.qf.myafterprojecy.pojo.dto.MessageDto;
+
+public interface IMessageService {
+/**
+ * 获取所有消息的方法
+ * @return 返回一个ResponseMessage对象,其中包含一个可迭代的Message集合
+ * ResponseMessage是响应消息的包装类,Iterable表示可迭代的消息集合
+ */
+ ResponseMessage> getAllMessages();
+/**
+ * 根据消息ID获取消息的方法
+ * @param id 消息的唯一标识符
+ * @return ResponseMessage 包含消息的响应对象,其中Message为消息的具体内容
+ */
+ ResponseMessage getMessageById(Integer id);
+/**
+ * 保存消息的方法
+ * @param message 消息数据传输对象,包含需要保存的消息信息
+ * @return ResponseMessage 返回一个响应消息对象,包含操作结果和保存后的消息信息
+ */
+ ResponseMessage saveMessage(MessageDto message);
+/**
+ * 根据消息ID删除消息的方法
+ * @param id 要删除的消息ID
+ * @return ResponseMessage 包含操作结果的响应消息,其中泛型Message表示被删除的消息内容
+ */
+ ResponseMessage deleteMessage(Integer id);
+}
diff --git a/src/main/java/com/qf/myafterprojecy/service/MessageService.java b/src/main/java/com/qf/myafterprojecy/service/MessageService.java
new file mode 100644
index 0000000..1267f06
--- /dev/null
+++ b/src/main/java/com/qf/myafterprojecy/service/MessageService.java
@@ -0,0 +1,60 @@
+package com.qf.myafterprojecy.service;
+
+import com.qf.myafterprojecy.pojo.Message;
+import com.qf.myafterprojecy.pojo.ResponseMessage;
+import com.qf.myafterprojecy.pojo.dto.MessageDto;
+import com.qf.myafterprojecy.repository.MessageRepository;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.dao.DataAccessException;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import static jdk.nashorn.internal.runtime.regexp.joni.Config.log;
+
+@Service
+public class MessageService implements IMessageService {
+ @Autowired
+ private MessageRepository messageRepository;
+
+ @Override
+ public ResponseMessage> getAllMessages() {
+ return ResponseMessage.success(messageRepository.findAll(), "查询成功", true);
+ }
+
+ @Override
+ public ResponseMessage getMessageById(Integer id) {
+ return ResponseMessage.success(messageRepository.findById(id).orElse(null), "查询成功", true);
+ }
+
+ @Override
+ public ResponseMessage saveMessage(MessageDto messageDto) {
+ // 参数校验
+ if (messageDto == null) {
+ throw new IllegalArgumentException("MessageDto cannot be null");
+ }
+ // 业务逻辑校验
+ if (StringUtils.isEmpty(messageDto.getContent())) {
+ throw new IllegalArgumentException("Message content cannot be empty");
+ }
+ // 调用Repository保存数据
+ try {
+ Message message = new Message();
+ BeanUtils.copyProperties(messageDto,message);
+ Message savedMessage = messageRepository.save(message);
+ return ResponseMessage.success(savedMessage, "保存成功", true);
+ } catch (DataAccessException e) {
+ return ResponseMessage.failure("Failed to save message");
+ }
+ }
+
+ @Override
+ public ResponseMessage deleteMessage(Integer id) {
+ if (messageRepository.existsById(id)) {
+ messageRepository.deleteById(id);
+ return ResponseMessage.success(null, "删除成功", true);
+ } else {
+ return ResponseMessage.failure("Message not found");
+ }
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 43f261a..05a7dce 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -6,10 +6,56 @@ spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
-spring.jpa.show-sql=true
-spring.jpa.properties.hibernate.format_sql=true
#下面这些内容是为了让MyBatis映射
#指定Mybatis的Mapper文件
mybatis.mapper-locations=classpath:mappers/*xml
#指定Mybatis的实体目录
mybatis.type-aliases-package=com.qf.myafterprojecy.mybatis.entity
+# 数据库连接池配置
+spring.datasource.hikari.maximum-pool-size=10
+spring.datasource.hikari.minimum-idle=5
+spring.datasource.hikari.idle-timeout=300000
+spring.datasource.hikari.connection-timeout=20000
+spring.datasource.hikari.max-lifetime=1200000
+# JPA配置
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.format_sql=true
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
+spring.jpa.open-in-view=false
+# 缓存配置
+spring.cache.type=redis
+spring.cache.redis.time-to-live=1800000
+spring.cache.redis.key-prefix=CACHE_
+spring.cache.redis.use-key-prefix=true
+spring.cache.redis.cache-null-values=false
+# Redis配置
+spring.redis.host=localhost
+spring.redis.port=6379
+spring.redis.password=
+spring.redis.database=0
+spring.redis.timeout=10000ms
+spring.redis.lettuce.pool.max-active=8
+spring.redis.lettuce.pool.max-wait=-1ms
+spring.redis.lettuce.pool.max-idle=8
+spring.redis.lettuce.pool.min-idle=0
+# 日志配置
+logging.level.root=INFO
+logging.level.com.qf.myafterprojecy=DEBUG
+logging.file.name=logs/web_project.log
+logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
+logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
+# Actuator配置
+management.endpoints.web.exposure.include=*
+management.endpoint.health.show-details=always
+management.metrics.export.prometheus.enabled=true
+# 安全配置
+# JWT配置
+jwt.secret=mySecretKey
+jwt.expiration=86400000
+
+# CORS配置
+cors.allowed-origins=http://localhost:3000
+cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS
+cors.allowed-headers=*
+cors.allow-credentials=true