完成部分帖子相关功能,同时完善了一些用户功能
Change-Id: Ie9d22bcceec197930d48f578d8b9a749ce7a3382
diff --git a/src/main/java/com/pt/constant/Constants.java b/src/main/java/com/pt/constant/Constants.java
index 5cf22a0..d277ea2 100644
--- a/src/main/java/com/pt/constant/Constants.java
+++ b/src/main/java/com/pt/constant/Constants.java
@@ -4,12 +4,18 @@
public static final int DEFAULT_EXPIRE_TIME = 600000;
- public static enum UserRole {
- ADMIN(0),
- USER(1);
+ /*
+ * 用户角色
+ * 0: 普通用户
+ * 1: 管理员
+ * value既用来区分角色,也表示权限大小,value越大权限越大。
+ */
+ public enum UserRole {
+ ADMIN(1),
+ USER(0);
private final int value;
- private UserRole(int value) {
+ UserRole(int value) {
this.value = value;
}
diff --git a/src/main/java/com/pt/controller/AdminController.java b/src/main/java/com/pt/controller/AdminController.java
new file mode 100644
index 0000000..1ddfc92
--- /dev/null
+++ b/src/main/java/com/pt/controller/AdminController.java
@@ -0,0 +1,41 @@
+package com.pt.controller;
+
+import com.pt.constant.Constants;
+import com.pt.entity.Admin;
+import com.pt.repository.AdminRepository;
+import com.pt.service.AdminService;
+import com.pt.utils.JWTUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.http.ResponseEntity;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/admin")
+@CrossOrigin(origins = "*")
+public class AdminController {
+
+ @Autowired
+ private AdminService adminService;
+
+ @PostMapping("/login")
+ public ResponseEntity<?> loginAdmin(@RequestParam("username") String username,
+ @RequestParam("password") String password) {
+ Map<String, Object> ans = new HashMap<>();
+ Admin admin = adminService.findByUsernameAndPassword(username, password);
+ if (admin != null) {
+ ans.put("result", "Login successful");
+ ans.put("token", JWTUtils.generateToken(username, Constants.UserRole.ADMIN, (int)1.2e8));
+ return ResponseEntity.ok().body(ans);
+ } else {
+ ans.put("result", "Invalid username or password");
+ return ResponseEntity.badRequest().body(ans);
+ }
+ }
+}
diff --git a/src/main/java/com/pt/controller/PostController.java b/src/main/java/com/pt/controller/PostController.java
new file mode 100644
index 0000000..844dc65
--- /dev/null
+++ b/src/main/java/com/pt/controller/PostController.java
@@ -0,0 +1,131 @@
+package com.pt.controller;
+
+import com.pt.constant.Constants;
+import com.pt.entity.Post;
+import com.pt.service.PostService;
+import com.pt.utils.JWTUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/api/posts")
+@CrossOrigin(origins = "*")
+public class PostController {
+
+ @Autowired
+ private PostService postService;
+
+ /*
+ * 创建一个新帖子
+ * @param token 用户的JWT令牌
+ * @param title 帖子标题
+ * @param content 帖子内容
+ * @param author 帖子作者(用户名)
+ * @return 创建成功的响应
+ */
+ @PostMapping("/create")
+ public ResponseEntity<?> createPost(
+ @RequestHeader("token") String token,
+ @RequestParam("title") String title,
+ @RequestParam("content") String content,
+ @RequestParam("author") String author
+ ) {
+
+ Map<String, Object> ans = new HashMap<>();
+
+ if(!JWTUtils.checkToken(token, author, Constants.UserRole.USER)){
+ ans.put("result", "Invalid token");
+ return ResponseEntity.badRequest().body(ans);
+ }
+
+ Post existingPost = postService.findPostByTitle(title);
+ if (existingPost != null) {
+ ans.put("result", "Post with this title already exists");
+ return ResponseEntity.badRequest().body(ans);
+ }
+
+ postService.createPost(title, content, author);
+ ans.put("result", "Post created successfully");
+ return ResponseEntity.ok(ans);
+ }
+
+ /*
+ * 获取帖子列表
+ * @param token 用户的JWT令牌
+ * @param username 用户名
+ * @param title 帖子标题(可选)
+ * @param author 帖子作者(可选)
+ * @param date 帖子发布日期(可选)
+ * @return 帖子列表的响应
+ */
+ @GetMapping("/list")
+ public ResponseEntity<?> getPost(
+ @RequestHeader("token") String token,
+ @RequestParam("username") String username,
+ @RequestParam(value = "title", required = false) String title,
+ @RequestParam(value = "author", required = false) String author,
+ @RequestParam(value = "date", required = false) String date
+ ) {
+
+ Map<String, Object> ans = new HashMap<>();
+
+ if(!JWTUtils.checkToken(token, username, Constants.UserRole.USER)){
+ ans.put("result", "Invalid token");
+ return ResponseEntity.badRequest().body(ans);
+ }
+
+ List<Post> posts = postService.listAll();
+
+ if(title != null){
+ posts.removeIf(post -> !post.getTitle().startsWith(title));
+ }
+
+ if(author != null){
+ posts.removeIf(post -> !post.getAuthor().startsWith(author));
+ }
+
+ if(date != null){
+ posts.removeIf(post -> !post.getPublishDate().toString().equals(date));
+ }
+ ans.put("result", "Post retrieved successfully");
+ ans.put("post", posts);
+ return ResponseEntity.ok(ans);
+ }
+
+ /*
+ * 删除帖子
+ * @param token 用户的JWT令牌
+ * @param username 用户名
+ * @param pid 帖子ID
+ * @return 删除成功的响应
+ */
+ @DeleteMapping("/delete")
+ public ResponseEntity<?> deletePost(
+ @RequestHeader("token") String token,
+ @RequestParam("username") String username,
+ @RequestParam("pid") int pid
+ ) {
+
+ Map<String, Object> ans = new HashMap<>();
+
+ if(!JWTUtils.checkToken(token, username, Constants.UserRole.ADMIN)){
+ ans.put("result", "Invalid token");
+ return ResponseEntity.badRequest().body(ans);
+ }
+
+ Post post = postService.findPostById(pid);
+ if (post == null) {
+ ans.put("result", "Post not found");
+ return ResponseEntity.badRequest().body(ans);
+ }
+
+ postService.deletePost(post);
+ ans.put("result", "Post deleted successfully");
+ return ResponseEntity.ok(ans);
+ }
+}
diff --git a/src/main/java/com/pt/controller/UserController.java b/src/main/java/com/pt/controller/UserController.java
index ea4dcab..f72e7db 100644
--- a/src/main/java/com/pt/controller/UserController.java
+++ b/src/main/java/com/pt/controller/UserController.java
@@ -112,4 +112,54 @@
return ResponseEntity.badRequest().body("User not found");
}
}
+
+ @DeleteMapping("/delete")
+ public ResponseEntity<?> deleteUser(@RequestHeader("token") String token,
+ @RequestParam("username") String username,
+ @RequestParam("targetUsername") String targetUsername
+ ) {
+ if(!JWTUtils.checkToken(token, username, Constants.UserRole.ADMIN)) {
+ return ResponseEntity.badRequest().body("Invalid token");
+ }
+
+ User user = userService.findByUsername(targetUsername);
+ if (user != null) {
+ userService.deleteById(user.getUid());
+ return ResponseEntity.ok("User deleted successfully");
+ } else {
+ return ResponseEntity.badRequest().body("User not found");
+ }
+ }
+
+ @GetMapping("/list")
+ public ResponseEntity<?> listUsers(@RequestHeader("token") String token,
+ @RequestParam("username") String username) {
+ if(!JWTUtils.checkToken(token, username, Constants.UserRole.ADMIN)) {
+ return ResponseEntity.badRequest().body("Invalid token");
+ }
+
+ Map<String, Object> ans = new HashMap<>();
+ ans.put("result", "User list retrieved successfully");
+ ans.put("amount", userService.listAll().size());
+ ans.put("users", userService.listAll());
+ return ResponseEntity.ok(ans);
+ }
+
+ @GetMapping("/get/info")
+ public ResponseEntity<?> getUserInfo(@RequestHeader("token") String token,
+ @RequestParam("username") String username) {
+ if(!JWTUtils.checkToken(token, username, Constants.UserRole.USER)) {
+ return ResponseEntity.badRequest().body("Invalid token");
+ }
+
+ User user = userService.findByUsername(username);
+ if (user != null) {
+ Map<String, Object> ans = new HashMap<>();
+ ans.put("result", "User info retrieved successfully");
+ ans.put("user", user);
+ return ResponseEntity.ok(ans);
+ } else {
+ return ResponseEntity.badRequest().body("User not found");
+ }
+ }
}
diff --git a/src/main/java/com/pt/entity/Admin.java b/src/main/java/com/pt/entity/Admin.java
new file mode 100644
index 0000000..856924d
--- /dev/null
+++ b/src/main/java/com/pt/entity/Admin.java
@@ -0,0 +1,46 @@
+package com.pt.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.Id;
+
+@Entity
+public class Admin {
+
+ @Id
+ private String id;
+
+ private String username;
+ private String password;
+
+ public Admin() {
+ }
+ public Admin(String id, String username, String password) {
+ this.id = id;
+ this.username = username;
+ this.password = password;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String adminId) {
+ this.id = adminId;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+}
diff --git a/src/main/java/com/pt/entity/Post.java b/src/main/java/com/pt/entity/Post.java
new file mode 100644
index 0000000..ef36c5c
--- /dev/null
+++ b/src/main/java/com/pt/entity/Post.java
@@ -0,0 +1,71 @@
+package com.pt.entity;
+
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+
+import java.time.LocalDate;
+
+@Entity
+public class Post {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private int pid;
+
+ private String title;
+ private String content;
+ private String author;
+ private LocalDate publishDate;
+
+ public Post() {
+ }
+
+ public Post(String title, String content, String author) {
+ this.title = title;
+ this.content = content;
+ this.author = author;
+ this.publishDate = LocalDate.now();
+ }
+
+ public int getPid() {
+ return pid;
+ }
+
+ public void setPid(int pid) {
+ this.pid = pid;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ public LocalDate getPublishDate() {
+ return publishDate;
+ }
+
+ public void setPublishDate(LocalDate publishDate) {
+ this.publishDate = publishDate;
+ }
+}
diff --git a/src/main/java/com/pt/entity/User.java b/src/main/java/com/pt/entity/User.java
index a2f462d..9caab3e 100644
--- a/src/main/java/com/pt/entity/User.java
+++ b/src/main/java/com/pt/entity/User.java
@@ -60,4 +60,16 @@
public void setPoints(int points) {
this.points = points;
}
+
+ @Override
+ public String toString() {
+ return "{" +
+ "uid:'" + uid + '\'' +
+ ",\nusername:'" + username + '\'' +
+ ",\npassword:'" + password + '\'' +
+ ",\nemail:'" + email + '\'' +
+ ",\nlevel:" + level +
+ ",\npoints:" + points +
+ '}';
+ }
}
diff --git a/src/main/java/com/pt/repository/AdminRepository.java b/src/main/java/com/pt/repository/AdminRepository.java
new file mode 100644
index 0000000..11d2c71
--- /dev/null
+++ b/src/main/java/com/pt/repository/AdminRepository.java
@@ -0,0 +1,8 @@
+package com.pt.repository;
+
+import com.pt.entity.Admin;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AdminRepository extends JpaRepository<Admin, String> {
+ Admin findByUsernameAndPassword(String username, String password);
+}
diff --git a/src/main/java/com/pt/repository/PostRepository.java b/src/main/java/com/pt/repository/PostRepository.java
new file mode 100644
index 0000000..74e53dc
--- /dev/null
+++ b/src/main/java/com/pt/repository/PostRepository.java
@@ -0,0 +1,25 @@
+package com.pt.repository;
+
+import com.pt.entity.Post;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.data.repository.query.Param;
+
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+
+public interface PostRepository extends JpaRepository<Post, Integer> {
+ Post findByTitle(String title);
+
+ Post findByAuthor(String author);
+
+ @Query(value = "SELECT p FROM Post p WHERE p.author = :author")
+ List<Post> listByAuthor(String author);
+
+ @Query(value = "SELECT p FROM Post p WHERE p.title LIKE :title%")
+ List<Post> listByTitle(@Param("title") String title);
+
+ @Query(value = "SELECT p FROM Post p WHERE p.publishDate = :date")
+ List<Post> listByDate(@Param("date") LocalDate date);
+}
diff --git a/src/main/java/com/pt/service/AdminService.java b/src/main/java/com/pt/service/AdminService.java
new file mode 100644
index 0000000..a4ce98a
--- /dev/null
+++ b/src/main/java/com/pt/service/AdminService.java
@@ -0,0 +1,23 @@
+package com.pt.service;
+
+import com.pt.entity.Admin;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import com.pt.repository.AdminRepository;
+
+@Service
+public class AdminService {
+
+ @Autowired
+ private AdminRepository adminRepository;
+
+ public AdminService(AdminRepository adminRepository) {
+ this.adminRepository = adminRepository;
+ }
+
+ public Admin findByUsernameAndPassword(String username, String password) {
+ return adminRepository.findByUsernameAndPassword(username, password);
+ }
+
+}
diff --git a/src/main/java/com/pt/service/PostService.java b/src/main/java/com/pt/service/PostService.java
new file mode 100644
index 0000000..f1ab50e
--- /dev/null
+++ b/src/main/java/com/pt/service/PostService.java
@@ -0,0 +1,50 @@
+package com.pt.service;
+
+import com.pt.entity.Post;
+import com.pt.repository.PostRepository;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Service
+public class PostService {
+
+ @Autowired
+ private PostRepository postRepository;
+
+ public void createPost(String title, String content, String author) {
+ System.out.println("Post created with title: " + title);
+ postRepository.save(new Post(title, content, author));
+ }
+
+ public Post findPostByTitle(String title) {
+ return postRepository.findByTitle(title);
+ }
+
+ public List<Post> listByAuthor(String author) {
+ return postRepository.listByAuthor(author);
+ }
+
+ public List<Post> listByTitle(String title) {
+ return postRepository.listByTitle(title);
+ }
+
+ public List<Post> listByDate(String date) {
+ LocalDate nDate = LocalDate.parse(date);
+ return postRepository.listByDate(nDate);
+ }
+
+ public List<Post> listAll() {
+ return postRepository.findAll();
+ }
+
+ public void deletePost(Post p) {
+ postRepository.delete(p);
+ }
+
+ public Post findPostById(int id) {
+ return postRepository.findById(id).orElse(null);
+ }
+}
diff --git a/src/main/java/com/pt/service/UserService.java b/src/main/java/com/pt/service/UserService.java
index 7025e5a..bdffeea 100644
--- a/src/main/java/com/pt/service/UserService.java
+++ b/src/main/java/com/pt/service/UserService.java
@@ -5,6 +5,8 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.util.List;
+
@Service
public class UserService {
@@ -42,4 +44,8 @@
public void deleteById(String uid) {
userRepository.deleteById(uid);
}
+
+ public List<User> listAll() {
+ return userRepository.findAll();
+ }
}
diff --git a/src/main/java/com/pt/utils/JWTUtils.java b/src/main/java/com/pt/utils/JWTUtils.java
index c47bc5f..70a1221 100644
--- a/src/main/java/com/pt/utils/JWTUtils.java
+++ b/src/main/java/com/pt/utils/JWTUtils.java
@@ -51,7 +51,7 @@
System.out.printf("Token username: %s, Token userType: %d, Provided username: %s, Provided userType: %d%n",
tokenUsername, tokenUserType, username, userType.getValue());
- return tokenUsername.equals(username) && tokenUserType == userType.getValue();
+ return tokenUsername.equals(username) && tokenUserType >= userType.getValue();
}
public static String generateToken(String username,