完成部分帖子相关功能,同时完善了一些用户功能

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,