AI 生成的一个基于springboot后端权限框架

  金牌会员 | 2024-12-16 03:07:51 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 989|帖子 989|积分 2967

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
构建一个完整的基于Spring Boot的权限管理系统是一个巨大的任务,涉及多个模块和复杂的业务逻辑。由于代码量较大,我将提供一个简化版本的框架结构,并详细解释每个部分的关键实现。你可以根据需要进一步扩展和完善这个系统。
项目结构

  1. src
  2. ├── main
  3. │   ├── java
  4. │   │   └── com
  5. │   │       └── example
  6. │   │           └── demo
  7. │   │               ├── controller
  8. │   │               │   ├── UserController.java
  9. │   │               │   ├── RoleController.java
  10. │   │               │   ├── OrganizationController.java
  11. │   │               │   ├── MenuController.java
  12. │   │               │   ├── AuthController.java
  13. │   │               │   └── PermissionController.java
  14. │   │               ├── service
  15. │   │               │   ├── UserService.java
  16. │   │               │   ├── RoleService.java
  17. │   │               │   ├── OrganizationService.java
  18. │   │               │   ├── MenuService.java
  19. │   │               │   ├── PermissionService.java
  20. │   │               │   ├── AuthService.java
  21. │   │               │   └── impl
  22. │   │               │       ├── UserServiceImpl.java
  23. │   │               │       ├── RoleServiceImpl.java
  24. │   │               │       ├── OrganizationServiceImpl.java
  25. │   │               │       ├── MenuServiceImpl.java
  26. │   │               │       ├── PermissionServiceImpl.java
  27. │   │               │       └── AuthServiceImpl.java
  28. │   │               ├── mapper
  29. │   │               │   ├── UserMapper.java
  30. │   │               │   ├── RoleMapper.java
  31. │   │               │   ├── OrganizationMapper.java
  32. │   │               │   ├── MenuMapper.java
  33. │   │               │   ├── PermissionMapper.java
  34. │   │               │   └── AuthMapper.java
  35. │   │               ├── config
  36. │   │               │   ├── JwtConfig.java
  37. │   │               │   └── SecurityConfig.java
  38. │   │               └── DemoApplication.java
  39. │   └── resources
  40. │       ├── application.properties
  41. │       ├── mapper
  42. │       │   ├── UserMapper.xml
  43. │       │   ├── RoleMapper.xml
  44. │       │   ├── OrganizationMapper.xml
  45. │       │   ├── MenuMapper.xml
  46. │       │   ├── PermissionMapper.xml
  47. │       │   └── AuthMapper.xml
  48. │       └── static
  49. └── test
  50.     └── java
  51.         └── com
  52.             └── example
  53.                 └── demo
  54.                     └── DemoApplicationTests.java
复制代码
核心依靠 (pom.xml)

确保你的pom.xml文件中包含以下核心依靠:
  1. <dependencies>
  2.     <!-- Spring Boot Starter Web -->
  3.     <dependency>
  4.         <groupId>org.springframework.boot</groupId>
  5.         <artifactId>spring-boot-starter-web</artifactId>
  6.     </dependency>
  7.     <!-- MyBatis -->
  8.     <dependency>
  9.         <groupId>org.mybatis.spring.boot</groupId>
  10.         <artifactId>mybatis-spring-boot-starter</artifactId>
  11.         <version>2.2.0</version>
  12.     </dependency>
  13.     <!-- MySQL Connector -->
  14.     <dependency>
  15.         <groupId>mysql</groupId>
  16.         <artifactId>mysql-connector-java</artifactId>
  17.         <scope>runtime</scope>
  18.     </dependency>
  19.     <!-- JWT -->
  20.     <dependency>
  21.         <groupId>io.jsonwebtoken</groupId>
  22.         <artifactId>jjwt-api</artifactId>
  23.         <version>0.11.2</version>
  24.     </dependency>
  25.     <dependency>
  26.         <groupId>io.jsonwebtoken</groupId>
  27.         <artifactId>jjwt-impl</artifactId>
  28.         <version>0.11.2</version>
  29.         <scope>runtime</scope>
  30.     </dependency>
  31.     <dependency>
  32.         <groupId>io.jsonwebtoken</groupId>
  33.         <artifactId>jjwt-jackson</artifactId>
  34.         <version>0.11.2</version>
  35.         <scope>runtime</scope>
  36.     </dependency>
  37.     <!-- Spring Security -->
  38.     <dependency>
  39.         <groupId>org.springframework.boot</groupId>
  40.         <artifactId>spring-boot-starter-security</artifactId>
  41.     </dependency>
  42.     <!-- Lombok for less boilerplate code -->
  43.     <dependency>
  44.         <groupId>org.projectlombok</groupId>
  45.         <artifactId>lombok</artifactId>
  46.         <optional>true</optional>
  47.     </dependency>
  48. </dependencies>
复制代码
设置文件 (application.properties)

  1. # MySQL Configuration
  2. spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC
  3. spring.datasource.username=root
  4. spring.datasource.password=password
  5. spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  6. # MyBatis Configuration
  7. mybatis.mapper-locations=classpath:mapper/*.xml
  8. # JWT Configuration
  9. jwt.secret=yourSecretKey
  10. jwt.expiration=86400 # seconds
复制代码
JWT设置 (JwtConfig.java)

  1. package com.example.demo.config;
  2. import io.jsonwebtoken.Claims;
  3. import io.jsonwebtoken.Jwts;
  4. import io.jsonwebtoken.SignatureAlgorithm;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.stereotype.Component;
  7. import java.util.Date;
  8. @Component
  9. public class JwtConfig {
  10.     @Value("${jwt.secret}")
  11.     private String secret;
  12.     @Value("${jwt.expiration}")
  13.     private long expiration;
  14.     public String generateToken(String username) {
  15.         return Jwts.builder()
  16.                    .setSubject(username)
  17.                    .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
  18.                    .signWith(SignatureAlgorithm.HS512, secret)
  19.                    .compact();
  20.     }
  21.     public Claims getClaimsFromToken(String token) {
  22.         return Jwts.parser()
  23.                   .setSigningKey(secret)
  24.                   .parseClaimsJws(token)
  25.                   .getBody();
  26.     }
  27. }
复制代码
安全设置 (SecurityConfig.java)

  1. package com.example.demo.config;
  2. import com.example.demo.service.impl.AuthServiceImpl;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import org.springframework.security.authentication.AuthenticationManager;
  7. import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
  8. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  9. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  10. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  11. import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
  12. import org.springframework.security.crypto.password.PasswordEncoder;
  13. @Configuration
  14. @EnableWebSecurity
  15. public class SecurityConfig extends WebSecurityConfigurerAdapter {
  16.     @Autowired
  17.     private AuthServiceImpl authService;
  18.     @Bean
  19.     public PasswordEncoder passwordEncoder() {
  20.         return new BCryptPasswordEncoder();
  21.     }
  22.     @Override
  23.     protected void configure(AuthenticationManagerBuilder auth) throws Exception {
  24.         auth.userDetailsService(authService).passwordEncoder(passwordEncoder());
  25.     }
  26.     @Override
  27.     protected void configure(HttpSecurity http) throws Exception {
  28.         http.csrf().disable()
  29.             .authorizeRequests()
  30.             .antMatchers("/api/auth/**").permitAll()
  31.             .anyRequest().authenticated()
  32.             .and()
  33.             .addFilter(new JwtAuthenticationFilter(authenticationManager()))
  34.             .addFilter(new JwtAuthorizationFilter(authenticationManager()));
  35.     }
  36.     @Override
  37.     @Bean
  38.     public AuthenticationManager authenticationManagerBean() throws Exception {
  39.         return super.authenticationManagerBean();
  40.     }
  41. }
复制代码
实体类

用户实体 (User.java)

  1. package com.example.demo.model;
  2. import lombok.Data;
  3. @Data
  4. public class User {
  5.     private Long id;
  6.     private String username;
  7.     private String password;
  8.     private String email;
  9.     private Long roleId;
  10. }
复制代码
脚色实体 (Role.java)

  1. package com.example.demo.model;
  2. import lombok.Data;
  3. @Data
  4. public class Role {
  5.     private Long id;
  6.     private String name;
  7.     private String description;
  8. }
复制代码
组织机构实体 (Organization.java)

  1. package com.example.demo.model;
  2. import lombok.Data;
  3. @Data
  4. public class Organization {
  5.     private Long id;
  6.     private String name;
  7.     private String description;
  8. }
复制代码
菜单实体 (Menu.java)

  1. package com.example.demo.model;
  2. import lombok.Data;
  3. @Data
  4. public class Menu {
  5.     private Long id;
  6.     private String name;
  7.     private String url;
  8.     private Long parentId;
  9. }
复制代码
权限实体 (Permission.java)

  1. package com.example.demo.model;
  2. import lombok.Data;
  3. @Data
  4. public class Permission {
  5.     private Long id;
  6.     private String name;
  7.     private String code;
  8. }
复制代码
Mapper接口及XML设置

为每个实体创建对应的Mapper接口和XML设置文件(如UserMapper.java、UserMapper.xml等),并定义相应的CRUD方法。
示例:UserMapper.java 和 UserMapper.xml

  1. package com.example.demo.mapper;
  2. import com.example.demo.model.User;
  3. import org.apache.ibatis.annotations.*;
  4. @Mapper
  5. public interface UserMapper {
  6.     @Select("SELECT * FROM users WHERE id = #{id}")
  7.     User selectById(Long id);
  8.     // ... other CRUD methods
  9. }
复制代码
  1. <!-- src/main/resources/mapper/UserMapper.xml -->
  2. <?xml version="1.0" encoding="UTF-8" ?>
  3. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.example.demo.mapper.UserMapper">
  5.     <!-- Additional SQL mappings can be added here if needed -->
  6. </mapper>
复制代码
Service接口及实现

为每个实体创建服务接口和服务实现类(如UserService.java、UserServiceImpl.java等),并实现业务逻辑。
示例:UserServiceImpl.java

  1. package com.example.demo.service.impl;
  2. import com.example.demo.mapper.UserMapper;
  3. import com.example.demo.model.User;
  4. import com.example.demo.service.UserService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. import java.util.List;
  8. @Service
  9. public class UserServiceImpl implements UserService {
  10.     @Autowired
  11.     private UserMapper userMapper;
  12.     @Override
  13.     public User getUserById(Long id) {
  14.         return userMapper.selectById(id);
  15.     }
  16.     // ... other service methods
  17. }
复制代码
控制器 (Controllers)

为每个功能模块创建控制器,处理HTTP请求,并调用对应的服务层方法。
示例:UserController.java

  1. package com.example.demo.controller;
  2. import com.example.demo.model.User;
  3. import com.example.demo.service.UserService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.*;
  6. import java.util.List;
  7. @RestController
  8. @RequestMapping("/api/users")
  9. public class UserController {
  10.     @Autowired
  11.     private UserService userService;
  12.     @GetMapping("/{id}")
  13.     public User getUser(@PathVariable Long id) {
  14.         return userService.getUserById(id);
  15.     }
  16.     @GetMapping
  17.     public List<User> getAllUsers() {
  18.         return userService.getAllUsers();
  19.     }
  20.     @PostMapping
  21.     public User createUser(@RequestBody User user) {
  22.         return userService.createUser(user);
  23.     }
  24.     @PutMapping("/{id}")
  25.     public User updateUser(@PathVariable Long id, @RequestBody User user) {
  26.         user.setId(id);
  27.         return userService.updateUser(user);
  28.     }
  29.     @DeleteMapping("/{id}")
  30.     public void deleteUser(@PathVariable Long id) {
  31.         userService.deleteUser(id);
  32.     }
  33. }
复制代码
为了实现权限管理功能,我们将创建PermissionController.java、PermissionService.java、PermissionServiceImpl.java和PermissionMapper.java。这些组件将负责处理权限的创建、读取、更新和删除(CRUD)操纵。
PermissionController.java

这个控制器将处理与权限相关的HTTP请求。它将调用服务层的方法来实行详细的操纵。
  1. package com.example.demo.controller;
  2. import com.example.demo.model.Permission;
  3. import com.example.demo.service.PermissionService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.*;
  6. import java.util.List;
  7. @RestController
  8. @RequestMapping("/api/permissions")
  9. public class PermissionController {
  10.     @Autowired
  11.     private PermissionService permissionService;
  12.     @GetMapping
  13.     public List<Permission> getAllPermissions() {
  14.         return permissionService.getAllPermissions();
  15.     }
  16.     @GetMapping("/{id}")
  17.     public Permission getPermissionById(@PathVariable Long id) {
  18.         return permissionService.getPermissionById(id);
  19.     }
  20.     @PostMapping
  21.     public Permission createPermission(@RequestBody Permission permission) {
  22.         return permissionService.createPermission(permission);
  23.     }
  24.     @PutMapping("/{id}")
  25.     public Permission updatePermission(@PathVariable Long id, @RequestBody Permission permissionDetails) {
  26.         return permissionService.updatePermission(id, permissionDetails);
  27.     }
  28.     @DeleteMapping("/{id}")
  29.     public void deletePermission(@PathVariable Long id) {
  30.         permissionService.deletePermission(id);
  31.     }
  32. }
复制代码
PermissionService.java

服务接口定义了权限管理所需的全部业务逻辑方法。
  1. package com.example.demo.service;
  2. import com.example.demo.model.Permission;
  3. import java.util.List;
  4. public interface PermissionService {
  5.     List<Permission> getAllPermissions();
  6.     Permission getPermissionById(Long id);
  7.     Permission createPermission(Permission permission);
  8.     Permission updatePermission(Long id, Permission permission);
  9.     void deletePermission(Long id);
  10. }
复制代码
PermissionServiceImpl.java

这是服务接口的详细实现类,包含了权限管理的实际业务逻辑。
  1. package com.example.demo.service.impl;
  2. import com.example.demo.mapper.PermissionMapper;
  3. import com.example.demo.model.Permission;
  4. import com.example.demo.service.PermissionService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Service;
  7. import java.util.List;
  8. @Service
  9. public class PermissionServiceImpl implements PermissionService {
  10.     @Autowired
  11.     private PermissionMapper permissionMapper;
  12.     @Override
  13.     public List<Permission> getAllPermissions() {
  14.         return permissionMapper.selectAllPermissions();
  15.     }
  16.     @Override
  17.     public Permission getPermissionById(Long id) {
  18.         return permissionMapper.selectPermissionById(id);
  19.     }
  20.     @Override
  21.     public Permission createPermission(Permission permission) {
  22.         permissionMapper.insertPermission(permission);
  23.         return permission;
  24.     }
  25.     @Override
  26.     public Permission updatePermission(Long id, Permission permissionDetails) {
  27.         Permission updatedPermission = permissionMapper.selectPermissionById(id);
  28.         if (updatedPermission != null) {
  29.             // 更新权限信息
  30.             updatedPermission.setName(permissionDetails.getName());
  31.             updatedPermission.setCode(permissionDetails.getCode());
  32.             permissionMapper.updatePermission(updatedPermission);
  33.         }
  34.         return updatedPermission;
  35.     }
  36.     @Override
  37.     public void deletePermission(Long id) {
  38.         permissionMapper.deletePermissionById(id);
  39.     }
  40. }
复制代码
PermissionMapper.java

MyBatis Mapper接口用于定义对数据库中权限表的操纵。请留意,你还需要为这个接口编写对应的XML映射文件(PermissionMapper.xml),以提供详细的SQL语句。
  1. package com.example.demo.mapper;
  2. import com.example.demo.model.Permission;
  3. import org.apache.ibatis.annotations.*;
  4. import java.util.List;
  5. @Mapper
  6. public interface PermissionMapper {
  7.     @Select("SELECT * FROM permissions")
  8.     List<Permission> selectAllPermissions();
  9.     @Select("SELECT * FROM permissions WHERE id = #{id}")
  10.     Permission selectPermissionById(Long id);
  11.     @Insert("INSERT INTO permissions(name, code) VALUES(#{name}, #{code})")
  12.     @Options(useGeneratedKeys = true, keyProperty = "id")
  13.     void insertPermission(Permission permission);
  14.     @Update("UPDATE permissions SET name=#{name}, code=#{code} WHERE id=#{id}")
  15.     void updatePermission(Permission permission);
  16.     @Delete("DELETE FROM permissions WHERE id=#{id}")
  17.     void deletePermissionById(Long id);
  18. }
复制代码
PermissionMapper.xml

在src/main/resources/mapper/PermissionMapper.xml中添加以下内容:
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.example.demo.mapper.PermissionMapper">
  4.     <!-- You can define additional SQL mappings here if needed -->
  5. </mapper>
复制代码
  1. ### 数据库表结构
  2. 你需要在MySQL数据库中创建多个表来存储用户、角色、组织机构、菜单和权限的信息。以下是简化版的SQL语句:
  3. ```sql
  4. CREATE TABLE users (
  5.     id BIGINT AUTO_INCREMENT PRIMARY KEY,
  6.     username VARCHAR(255) NOT NULL UNIQUE,
  7.     password VARCHAR(255) NOT NULL,
  8.     email VARCHAR(255),
  9.     role_id BIGINT
  10. );
  11. CREATE TABLE roles (
  12.     id BIGINT AUTO_INCREMENT PRIMARY KEY,
  13.     name VARCHAR(255) NOT NULL,
  14.     description TEXT
  15. );
  16. CREATE TABLE organizations (
  17.     id BIGINT AUTO_INCREMENT PRIMARY KEY,
  18.     name VARCHAR(255) NOT NULL,
  19.     description TEXT
  20. );
  21. CREATE TABLE menus (
  22.     id BIGINT AUTO_INCREMENT PRIMARY KEY,
  23.     name VARCHAR(255) NOT NULL,
  24.     url VARCHAR(255),
  25.     parent_id BIGINT
  26. );
  27. CREATE TABLE permissions (
  28.     id BIGINT AUTO_INCREMENT PRIMARY KEY,
  29.     name VARCHAR(255) NOT NULL,
  30.     code VARCHAR(255)
  31. );
  32. -- 创建关联表
  33. CREATE TABLE user_roles (
  34.     user_id BIGINT,
  35.     role_id BIGINT,
  36.     FOREIGN KEY (user_id) REFERENCES users(id),
  37.     FOREIGN KEY (role_id) REFERENCES roles(id)
  38. );
  39. CREATE TABLE role_permissions (
  40.     role_id BIGINT,
  41.     permission_id BIGINT,
  42.     FOREIGN KEY (role_id) REFERENCES roles(id),
  43.     FOREIGN KEY (permission_id) REFERENCES permissions(id)
  44. );
复制代码
启动类 (DemoApplication.java)

  1. package com.example.demo;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class DemoApplication {
  6.     public static void main(String[] args) {
  7.         SpringApplication.run(DemoApplication.class, args);
  8.     }
  9. }
复制代码
Token认证过滤器

JwtAuthenticationFilter.java 和 JwtAuthorizationFilter.java

  1. package com.example.demo.config;
  2. import io.jsonwebtoken.Claims;
  3. import io.jsonwebtoken.ExpiredJwtException;
  4. import io.jsonwebtoken.MalformedJwtException;
  5. import io.jsonwebtoken.UnsupportedJwtException;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
  8. import org.springframework.security.core.context.SecurityContextHolder;
  9. import org.springframework.security.core.userdetails.UserDetails;
  10. import org.springframework.security.core.userdetails.UserDetailsService;
  11. import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
  12. import org.springframework.web.filter.OncePerRequestFilter;
  13. import javax.servlet.FilterChain;
  14. import javax.servlet.ServletException;
  15. import javax.servlet.http.HttpServletRequest;
  16. import javax.servlet.http.HttpServletResponse;
  17. import java.io.IOException;
  18. public class JwtAuthenticationFilter extends OncePerRequestFilter {
  19.     @Autowired
  20.     private JwtConfig jwtConfig;
  21.     @Autowired
  22.     private UserDetailsService userDetailsService;
  23.     @Override
  24.     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
  25.             throws ServletException, IOException {
  26.         try {
  27.             String token = parseJwt(request);
  28.             if (token != null && jwtConfig.getClaimsFromToken(token) != null) {
  29.                 Claims claims = jwtConfig.getClaimsFromToken(token);
  30.                 String username = claims.getSubject();
  31.                 UserDetails userDetails = userDetailsService.loadUserByUsername(username);
  32.                 UsernamePasswordAuthenticationToken authentication =
  33.                         new UsernamePasswordAuthenticationToken(
  34.                                 userDetails, null, userDetails.getAuthorities());
  35.                 authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
  36.                 SecurityContextHolder.getContext().setAuthentication(authentication);
  37.             }
  38.         } catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException e) {
  39.             logger.error("Invalid JWT token: {}", e.getMessage());
  40.             response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid JWT token");
  41.             return;
  42.         }
  43.         chain.doFilter(request, response);
  44.     }
  45.     private String parseJwt(HttpServletRequest request) {
  46.         String headerAuth = request.getHeader("Authorization");
  47.         if (headerAuth != null && headerAuth.startsWith("Bearer ")) {
  48.             return headerAuth.substring(7);
  49.         }
  50.         return null;
  51.     }
  52. }
  53. // JwtAuthorizationFilter would extend OncePerRequestFilter and handle authorization logic.
复制代码
总结

以上代码片断展示了怎样构建一个基于Spring Boot的权限管理系统,包括用户管理、脚色管理、组织机构管理、菜单管理和权限管理等功能。通过这些组件,你可以实现对用户的注册、登录、信息修改以及权限分配等操纵。别的,系统还支持通过JWT举行Token认证,确保了安全性。
请留意,这只是一个基础框架,实际应用中大概还需要添加更多的特性,如输入验证、非常处理、日记记载等。同时,考虑到系统的复杂性,建议徐徐开发各个模块,并举行充分的测试以保证系统的稳定性和可靠性。如果你有更详细的需求或想要进一步细化某些部分,请告诉我!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表