feat: Add complete user system implementation
- Create User, Role, Permission entities with their relationships - Implement service interfaces and implementations for user system - Add controllers for User, Role, Permission, UserRole, and RolePermission - Include SQL schema files for the user system - Document project structure in CLAUDE.md This adds a complete RBAC (Role-Based Access Control) system with: - User entity for managing user accounts - Role entity for defining roles - Permission entity for defining permissions - UserRole entity for user-role relationships - RolePermission entity for role-permission relationships Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
7
.claude/settings.local.json
Normal file
7
.claude/settings.local.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(git add:*)"
|
||||
]
|
||||
}
|
||||
}
|
||||
66
CLAUDE.md
Normal file
66
CLAUDE.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Build & Run Commands
|
||||
|
||||
```bash
|
||||
# Build the project
|
||||
./mvnw clean package
|
||||
|
||||
# Run the application
|
||||
./mvnw spring-boot:run
|
||||
|
||||
# Run all tests
|
||||
./mvnw test
|
||||
|
||||
# Run a single test class
|
||||
./mvnw test -Dtest=TestClassName
|
||||
|
||||
# Run a single test method
|
||||
./mvnw test -Dtest=TestClassName#methodName
|
||||
```
|
||||
|
||||
## Project Overview
|
||||
|
||||
- **Framework**: Spring Boot 3.2.3 with Java 21
|
||||
- **ORM**: MyBatis Plus 3.5.5
|
||||
- **Database**: MySQL 8.0.33
|
||||
- **Cache**: Redis (Spring Data Redis)
|
||||
- **API Docs**: Swagger UI at `/swagger-ui.html`
|
||||
- **Auth**: JWT (jjwt 0.11.5)
|
||||
|
||||
## Architecture
|
||||
|
||||
Base package: `icu.sunway.ai_spring_example`
|
||||
|
||||
This project follows a layered architecture with MyBatis Plus:
|
||||
|
||||
| Layer | Location | Pattern |
|
||||
|-------|----------|---------|
|
||||
| Controller | `Controller/{EntityName}Controller/` | One subdirectory per entity |
|
||||
| Service | `Service/` | Interface `I{Name}Service` extends `IService<Entity>` |
|
||||
| Service Impl | `Service/Implements/` | `{Name}ServiceImpl` extends `ServiceImpl<Mapper, Entity>` |
|
||||
| Mapper | `Mapper/` | `{Name}Mapper` extends `BaseMapper<Entity>` |
|
||||
| Entity | `Entity/` | Lombok + MyBatis Plus annotations |
|
||||
| Config | `Config/` | CORS, Security, Redis, OpenAPI |
|
||||
| Utils | `Utils/` | Utility classes |
|
||||
|
||||
## Key Utilities
|
||||
|
||||
- **ResponseUtils**: Standard API responses - `ResponseUtils.success(data)` / `ResponseUtils.fail(message)`
|
||||
- **PageUtils**: Pagination - `PageUtils.createPage(page, limit)` returns `Page<T>` for MyBatis Plus
|
||||
- **RedisUtils**: Redis operations (inject with `@Resource`)
|
||||
- **JsonUtils**: JSON serialization - `JsonUtils.toJson()` / `JsonUtils.toObject()`
|
||||
- **ValidationUtils**: Input validation (email, phone, URL, IP, password strength, etc.)
|
||||
|
||||
## Configuration
|
||||
|
||||
- Copy `application-example.yaml` to `application.yaml` and fill in database/Redis credentials
|
||||
- `application.yaml` is gitignored (contains sensitive data)
|
||||
- Uses dynamic multi-datasource (primary datasource named "master")
|
||||
|
||||
## Security Notes
|
||||
|
||||
- Current `SecurityConfig` is permissive (all requests allowed) - configure for production
|
||||
- Stateless session management configured for JWT authentication
|
||||
@@ -0,0 +1,73 @@
|
||||
package icu.sunway.ai_spring_example.Controller.PermissionController;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.Permission;
|
||||
import icu.sunway.ai_spring_example.Service.IPermissionService;
|
||||
import icu.sunway.ai_spring_example.Utils.ResponseUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/permission")
|
||||
public class PermissionController {
|
||||
|
||||
@Resource
|
||||
private IPermissionService permissionService;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public Object getPermissionById(@PathVariable Long id) {
|
||||
Permission permission = permissionService.getById(id);
|
||||
return ResponseUtils.success(permission);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Object getAllPermissions(
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer limit) {
|
||||
|
||||
Page<Permission> permissionPage = new Page<>(page, limit);
|
||||
Page<Permission> resultPage = permissionService.page(permissionPage);
|
||||
return ResponseUtils.success(resultPage);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Object createPermission(@RequestBody Permission permission) {
|
||||
boolean result = permissionService.save(permission);
|
||||
if (result) {
|
||||
return ResponseUtils.success(permission);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to create permission");
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public Object updatePermission(@PathVariable Long id, @RequestBody Permission permission) {
|
||||
permission.setId(id);
|
||||
boolean result = permissionService.updateById(permission);
|
||||
if (result) {
|
||||
return ResponseUtils.success(permission);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to update permission");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public Object deletePermission(@PathVariable Long id) {
|
||||
boolean result = permissionService.removeById(id);
|
||||
if (result) {
|
||||
return ResponseUtils.success("Permission deleted successfully");
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to delete permission");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/name/{name}")
|
||||
public Object getPermissionByName(@PathVariable String name) {
|
||||
QueryWrapper<Permission> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("name", name);
|
||||
Permission permission = permissionService.getOne(wrapper);
|
||||
return ResponseUtils.success(permission);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package icu.sunway.ai_spring_example.Controller.RoleController;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.Role;
|
||||
import icu.sunway.ai_spring_example.Service.IRoleService;
|
||||
import icu.sunway.ai_spring_example.Utils.ResponseUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/role")
|
||||
public class RoleController {
|
||||
|
||||
@Resource
|
||||
private IRoleService roleService;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public Object getRoleById(@PathVariable Long id) {
|
||||
Role role = roleService.getById(id);
|
||||
return ResponseUtils.success(role);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Object getAllRoles(
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer limit) {
|
||||
|
||||
Page<Role> rolePage = new Page<>(page, limit);
|
||||
Page<Role> resultPage = roleService.page(rolePage);
|
||||
return ResponseUtils.success(resultPage);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Object createRole(@RequestBody Role role) {
|
||||
boolean result = roleService.save(role);
|
||||
if (result) {
|
||||
return ResponseUtils.success(role);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to create role");
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public Object updateRole(@PathVariable Long id, @RequestBody Role role) {
|
||||
role.setId(id);
|
||||
boolean result = roleService.updateById(role);
|
||||
if (result) {
|
||||
return ResponseUtils.success(role);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to update role");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public Object deleteRole(@PathVariable Long id) {
|
||||
boolean result = roleService.removeById(id);
|
||||
if (result) {
|
||||
return ResponseUtils.success("Role deleted successfully");
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to delete role");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/name/{name}")
|
||||
public Object getRoleByName(@PathVariable String name) {
|
||||
QueryWrapper<Role> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("name", name);
|
||||
Role role = roleService.getOne(wrapper);
|
||||
return ResponseUtils.success(role);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package icu.sunway.ai_spring_example.Controller.RolePermissionController;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.RolePermission;
|
||||
import icu.sunway.ai_spring_example.Service.IRolePermissionService;
|
||||
import icu.sunway.ai_spring_example.Utils.ResponseUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/role-permission")
|
||||
public class RolePermissionController {
|
||||
|
||||
@Resource
|
||||
private IRolePermissionService rolePermissionService;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public Object getRolePermissionById(@PathVariable Long id) {
|
||||
RolePermission rolePermission = rolePermissionService.getById(id);
|
||||
return ResponseUtils.success(rolePermission);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Object getAllRolePermissions(
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer limit) {
|
||||
|
||||
Page<RolePermission> rolePermissionPage = new Page<>(page, limit);
|
||||
Page<RolePermission> resultPage = rolePermissionService.page(rolePermissionPage);
|
||||
return ResponseUtils.success(resultPage);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Object createRolePermission(@RequestBody RolePermission rolePermission) {
|
||||
boolean result = rolePermissionService.save(rolePermission);
|
||||
if (result) {
|
||||
return ResponseUtils.success(rolePermission);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to create role permission relationship");
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public Object updateRolePermission(@PathVariable Long id, @RequestBody RolePermission rolePermission) {
|
||||
rolePermission.setId(id);
|
||||
boolean result = rolePermissionService.updateById(rolePermission);
|
||||
if (result) {
|
||||
return ResponseUtils.success(rolePermission);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to update role permission relationship");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public Object deleteRolePermission(@PathVariable Long id) {
|
||||
boolean result = rolePermissionService.removeById(id);
|
||||
if (result) {
|
||||
return ResponseUtils.success("Role permission relationship deleted successfully");
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to delete role permission relationship");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/role/{roleId}")
|
||||
public Object getRolePermissionsByRoleId(@PathVariable Long roleId) {
|
||||
QueryWrapper<RolePermission> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("role_id", roleId);
|
||||
List<RolePermission> rolePermissions = rolePermissionService.list(wrapper);
|
||||
return ResponseUtils.success(rolePermissions);
|
||||
}
|
||||
|
||||
@GetMapping("/permission/{permissionId}")
|
||||
public Object getRolePermissionsByPermissionId(@PathVariable Long permissionId) {
|
||||
QueryWrapper<RolePermission> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("permission_id", permissionId);
|
||||
List<RolePermission> rolePermissions = rolePermissionService.list(wrapper);
|
||||
return ResponseUtils.success(rolePermissions);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package icu.sunway.ai_spring_example.Controller.UserController;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.User;
|
||||
import icu.sunway.ai_spring_example.Service.IUserService;
|
||||
import icu.sunway.ai_spring_example.Utils.ResponseUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user")
|
||||
public class UserController {
|
||||
|
||||
@Resource
|
||||
private IUserService userService;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public Object getUserById(@PathVariable Long id) {
|
||||
User user = userService.getById(id);
|
||||
return ResponseUtils.success(user);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Object getAllUsers(
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer limit) {
|
||||
|
||||
Page<User> userPage = new Page<>(page, limit);
|
||||
Page<User> resultPage = userService.page(userPage);
|
||||
return ResponseUtils.success(resultPage);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Object createUser(@RequestBody User user) {
|
||||
boolean result = userService.save(user);
|
||||
if (result) {
|
||||
return ResponseUtils.success(user);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to create user");
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public Object updateUser(@PathVariable Long id, @RequestBody User user) {
|
||||
user.setId(id);
|
||||
boolean result = userService.updateById(user);
|
||||
if (result) {
|
||||
return ResponseUtils.success(user);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to update user");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public Object deleteUser(@PathVariable Long id) {
|
||||
boolean result = userService.removeById(id);
|
||||
if (result) {
|
||||
return ResponseUtils.success("User deleted successfully");
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to delete user");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/username/{username}")
|
||||
public Object getUserByUsername(@PathVariable String username) {
|
||||
QueryWrapper<User> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("username", username);
|
||||
User user = userService.getOne(wrapper);
|
||||
return ResponseUtils.success(user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package icu.sunway.ai_spring_example.Controller.UserRoleController;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.UserRole;
|
||||
import icu.sunway.ai_spring_example.Service.IUserRoleService;
|
||||
import icu.sunway.ai_spring_example.Utils.ResponseUtils;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user-role")
|
||||
public class UserRoleController {
|
||||
|
||||
@Resource
|
||||
private IUserRoleService userRoleService;
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public Object getUserRoleById(@PathVariable Long id) {
|
||||
UserRole userRole = userRoleService.getById(id);
|
||||
return ResponseUtils.success(userRole);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public Object getAllUserRoles(
|
||||
@RequestParam(defaultValue = "1") Integer page,
|
||||
@RequestParam(defaultValue = "10") Integer limit) {
|
||||
|
||||
Page<UserRole> userRolePage = new Page<>(page, limit);
|
||||
Page<UserRole> resultPage = userRoleService.page(userRolePage);
|
||||
return ResponseUtils.success(resultPage);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public Object createUserRole(@RequestBody UserRole userRole) {
|
||||
boolean result = userRoleService.save(userRole);
|
||||
if (result) {
|
||||
return ResponseUtils.success(userRole);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to create user role relationship");
|
||||
}
|
||||
}
|
||||
|
||||
@PutMapping("/{id}")
|
||||
public Object updateUserRole(@PathVariable Long id, @RequestBody UserRole userRole) {
|
||||
userRole.setId(id);
|
||||
boolean result = userRoleService.updateById(userRole);
|
||||
if (result) {
|
||||
return ResponseUtils.success(userRole);
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to update user role relationship");
|
||||
}
|
||||
}
|
||||
|
||||
@DeleteMapping("/{id}")
|
||||
public Object deleteUserRole(@PathVariable Long id) {
|
||||
boolean result = userRoleService.removeById(id);
|
||||
if (result) {
|
||||
return ResponseUtils.success("User role relationship deleted successfully");
|
||||
} else {
|
||||
return ResponseUtils.fail("Failed to delete user role relationship");
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/user/{userId}")
|
||||
public Object getUserRolesByUserId(@PathVariable Long userId) {
|
||||
QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("user_id", userId);
|
||||
List<UserRole> userRoles = userRoleService.list(wrapper);
|
||||
return ResponseUtils.success(userRoles);
|
||||
}
|
||||
|
||||
@GetMapping("/role/{roleId}")
|
||||
public Object getUserRolesByRoleId(@PathVariable Long roleId) {
|
||||
QueryWrapper<UserRole> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("role_id", roleId);
|
||||
List<UserRole> userRoles = userRoleService.list(wrapper);
|
||||
return ResponseUtils.success(userRoles);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package icu.sunway.ai_spring_example.Entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("permission")
|
||||
public class Permission {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String name;
|
||||
private String code;
|
||||
private String description;
|
||||
private Long parentId;
|
||||
private Integer type; // 1: menu, 2: button, 3: api
|
||||
private String path;
|
||||
private Integer sort;
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
26
src/main/java/icu/sunway/ai_spring_example/Entity/Role.java
Normal file
26
src/main/java/icu/sunway/ai_spring_example/Entity/Role.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package icu.sunway.ai_spring_example.Entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("role")
|
||||
public class Role {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String name;
|
||||
private String code;
|
||||
private String description;
|
||||
private Integer status; // 0: disabled, 1: enabled
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package icu.sunway.ai_spring_example.Entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("role_permission")
|
||||
public class RolePermission {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Long roleId;
|
||||
private Long permissionId;
|
||||
}
|
||||
29
src/main/java/icu/sunway/ai_spring_example/Entity/User.java
Normal file
29
src/main/java/icu/sunway/ai_spring_example/Entity/User.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package icu.sunway.ai_spring_example.Entity;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("user")
|
||||
public class User {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String username;
|
||||
private String password;
|
||||
private String email;
|
||||
private String phone;
|
||||
private String avatar;
|
||||
private Integer status; // 0: disabled, 1: enabled
|
||||
private LocalDateTime createTime;
|
||||
private LocalDateTime updateTime;
|
||||
private LocalDateTime lastLoginTime;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package icu.sunway.ai_spring_example.Entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("user_role")
|
||||
public class UserRole {
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Long userId;
|
||||
private Long roleId;
|
||||
}
|
||||
276
src/main/java/icu/sunway/ai_spring_example/Entity/example.sql
Normal file
276
src/main/java/icu/sunway/ai_spring_example/Entity/example.sql
Normal file
@@ -0,0 +1,276 @@
|
||||
-- Example Data for User System
|
||||
|
||||
-- Roles
|
||||
INSERT INTO
|
||||
`role` (
|
||||
`name`,
|
||||
`code`,
|
||||
`description`,
|
||||
`status`
|
||||
)
|
||||
VALUES (
|
||||
'Super Admin',
|
||||
'SUPER_ADMIN',
|
||||
'Full system access',
|
||||
1
|
||||
),
|
||||
(
|
||||
'Admin',
|
||||
'ADMIN',
|
||||
'Administrative access',
|
||||
1
|
||||
),
|
||||
(
|
||||
'User',
|
||||
'USER',
|
||||
'Regular user access',
|
||||
1
|
||||
),
|
||||
(
|
||||
'Guest',
|
||||
'GUEST',
|
||||
'Limited guest access',
|
||||
1
|
||||
);
|
||||
|
||||
-- Permissions
|
||||
INSERT INTO
|
||||
`permission` (
|
||||
`name`,
|
||||
`code`,
|
||||
`description`,
|
||||
`parent_id`,
|
||||
`type`,
|
||||
`path`,
|
||||
`sort`
|
||||
)
|
||||
VALUES
|
||||
-- Menu permissions
|
||||
(
|
||||
'Dashboard',
|
||||
'dashboard',
|
||||
'Dashboard menu',
|
||||
0,
|
||||
1,
|
||||
'/dashboard',
|
||||
1
|
||||
),
|
||||
(
|
||||
'User Management',
|
||||
'user:manage',
|
||||
'User management menu',
|
||||
0,
|
||||
1,
|
||||
'/user',
|
||||
2
|
||||
),
|
||||
(
|
||||
'Role Management',
|
||||
'role:manage',
|
||||
'Role management menu',
|
||||
0,
|
||||
1,
|
||||
'/role',
|
||||
3
|
||||
),
|
||||
(
|
||||
'System Settings',
|
||||
'system:settings',
|
||||
'System settings menu',
|
||||
0,
|
||||
1,
|
||||
'/settings',
|
||||
4
|
||||
),
|
||||
-- User management buttons/actions
|
||||
(
|
||||
'View Users',
|
||||
'user:view',
|
||||
'View user list',
|
||||
2,
|
||||
2,
|
||||
NULL,
|
||||
1
|
||||
),
|
||||
(
|
||||
'Create User',
|
||||
'user:create',
|
||||
'Create new user',
|
||||
2,
|
||||
2,
|
||||
NULL,
|
||||
2
|
||||
),
|
||||
(
|
||||
'Edit User',
|
||||
'user:edit',
|
||||
'Edit user info',
|
||||
2,
|
||||
2,
|
||||
NULL,
|
||||
3
|
||||
),
|
||||
(
|
||||
'Delete User',
|
||||
'user:delete',
|
||||
'Delete user',
|
||||
2,
|
||||
2,
|
||||
NULL,
|
||||
4
|
||||
),
|
||||
-- Role management buttons/actions
|
||||
(
|
||||
'View Roles',
|
||||
'role:view',
|
||||
'View role list',
|
||||
3,
|
||||
2,
|
||||
NULL,
|
||||
1
|
||||
),
|
||||
(
|
||||
'Create Role',
|
||||
'role:create',
|
||||
'Create new role',
|
||||
3,
|
||||
2,
|
||||
NULL,
|
||||
2
|
||||
),
|
||||
(
|
||||
'Edit Role',
|
||||
'role:edit',
|
||||
'Edit role info',
|
||||
3,
|
||||
2,
|
||||
NULL,
|
||||
3
|
||||
),
|
||||
(
|
||||
'Delete Role',
|
||||
'role:delete',
|
||||
'Delete role',
|
||||
3,
|
||||
2,
|
||||
NULL,
|
||||
4
|
||||
),
|
||||
-- API permissions
|
||||
(
|
||||
'User API',
|
||||
'api:user',
|
||||
'User API access',
|
||||
0,
|
||||
3,
|
||||
'/api/user/**',
|
||||
1
|
||||
),
|
||||
(
|
||||
'Role API',
|
||||
'api:role',
|
||||
'Role API access',
|
||||
0,
|
||||
3,
|
||||
'/api/role/**',
|
||||
2
|
||||
);
|
||||
|
||||
-- Users (passwords are bcrypt hashed for 'password123')
|
||||
INSERT INTO
|
||||
`user` (
|
||||
`username`,
|
||||
`password`,
|
||||
`email`,
|
||||
`phone`,
|
||||
`avatar`,
|
||||
`status`
|
||||
)
|
||||
VALUES (
|
||||
'admin',
|
||||
'$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTVKIUi',
|
||||
'admin@example.com',
|
||||
'13800000001',
|
||||
NULL,
|
||||
1
|
||||
),
|
||||
(
|
||||
'john',
|
||||
'$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTVKIUi',
|
||||
'john@example.com',
|
||||
'13800000002',
|
||||
NULL,
|
||||
1
|
||||
),
|
||||
(
|
||||
'jane',
|
||||
'$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTVKIUi',
|
||||
'jane@example.com',
|
||||
'13800000003',
|
||||
NULL,
|
||||
1
|
||||
),
|
||||
(
|
||||
'guest',
|
||||
'$2a$10$N.zmdr9k7uOCQb376NoUnuTJ8iAt6Z5EHsM8lE9lBOsl7iKTVKIUi',
|
||||
'guest@example.com',
|
||||
'13800000004',
|
||||
NULL,
|
||||
1
|
||||
);
|
||||
|
||||
-- User-Role assignments
|
||||
INSERT INTO
|
||||
`user_role` (`user_id`, `role_id`)
|
||||
VALUES (1, 1), -- admin -> SUPER_ADMIN
|
||||
(2, 2), -- john -> ADMIN
|
||||
(3, 3), -- jane -> USER
|
||||
(4, 4);
|
||||
-- guest -> GUEST
|
||||
|
||||
-- Role-Permission assignments
|
||||
-- SUPER_ADMIN gets all permissions
|
||||
INSERT INTO
|
||||
`role_permission` (`role_id`, `permission_id`)
|
||||
VALUES (1, 1),
|
||||
(1, 2),
|
||||
(1, 3),
|
||||
(1, 4),
|
||||
(1, 5),
|
||||
(1, 6),
|
||||
(1, 7),
|
||||
(1, 8),
|
||||
(1, 9),
|
||||
(1, 10),
|
||||
(1, 11),
|
||||
(1, 12),
|
||||
(1, 13),
|
||||
(1, 14);
|
||||
|
||||
-- ADMIN gets user and role management
|
||||
INSERT INTO
|
||||
`role_permission` (`role_id`, `permission_id`)
|
||||
VALUES (2, 1),
|
||||
(2, 2),
|
||||
(2, 3),
|
||||
(2, 5),
|
||||
(2, 6),
|
||||
(2, 7),
|
||||
(2, 9),
|
||||
(2, 10),
|
||||
(2, 11),
|
||||
(2, 13),
|
||||
(2, 14);
|
||||
|
||||
-- USER gets dashboard and view permissions
|
||||
INSERT INTO
|
||||
`role_permission` (`role_id`, `permission_id`)
|
||||
VALUES (3, 1),
|
||||
(3, 5),
|
||||
(3, 9),
|
||||
(3, 13);
|
||||
|
||||
-- GUEST gets only dashboard
|
||||
INSERT INTO
|
||||
`role_permission` (`role_id`, `permission_id`)
|
||||
VALUES (4, 1);
|
||||
70
src/main/java/icu/sunway/ai_spring_example/Entity/main.sql
Normal file
70
src/main/java/icu/sunway/ai_spring_example/Entity/main.sql
Normal file
@@ -0,0 +1,70 @@
|
||||
-- User System Tables
|
||||
|
||||
-- User table
|
||||
CREATE TABLE `user` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`username` VARCHAR(50) NOT NULL,
|
||||
`password` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(100),
|
||||
`phone` VARCHAR(20),
|
||||
`avatar` VARCHAR(255),
|
||||
`status` INT DEFAULT 1 COMMENT '0: disabled, 1: enabled',
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`last_login_time` DATETIME,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_username` (`username`),
|
||||
UNIQUE KEY `uk_email` (`email`),
|
||||
UNIQUE KEY `uk_phone` (`phone`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Role table
|
||||
CREATE TABLE `role` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`code` VARCHAR(50) NOT NULL,
|
||||
`description` VARCHAR(255),
|
||||
`status` INT DEFAULT 1 COMMENT '0: disabled, 1: enabled',
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_code` (`code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Permission table
|
||||
CREATE TABLE `permission` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(50) NOT NULL,
|
||||
`code` VARCHAR(100) NOT NULL,
|
||||
`description` VARCHAR(255),
|
||||
`parent_id` BIGINT DEFAULT 0,
|
||||
`type` INT NOT NULL COMMENT '1: menu, 2: button, 3: api',
|
||||
`path` VARCHAR(255),
|
||||
`sort` INT DEFAULT 0,
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_code` (`code`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- User-Role junction table
|
||||
CREATE TABLE `user_role` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`user_id` BIGINT NOT NULL,
|
||||
`role_id` BIGINT NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_user_role` (`user_id`, `role_id`),
|
||||
FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`role_id`) REFERENCES `role`(`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Role-Permission junction table
|
||||
CREATE TABLE `role_permission` (
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT,
|
||||
`role_id` BIGINT NOT NULL,
|
||||
`permission_id` BIGINT NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_role_permission` (`role_id`, `permission_id`),
|
||||
FOREIGN KEY (`role_id`) REFERENCES `role`(`id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`permission_id`) REFERENCES `permission`(`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
@@ -0,0 +1,10 @@
|
||||
package icu.sunway.ai_spring_example.Mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.Permission;
|
||||
|
||||
@Mapper
|
||||
public interface PermissionMapper extends BaseMapper<Permission> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package icu.sunway.ai_spring_example.Mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.Role;
|
||||
|
||||
@Mapper
|
||||
public interface RoleMapper extends BaseMapper<Role> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package icu.sunway.ai_spring_example.Mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.RolePermission;
|
||||
|
||||
@Mapper
|
||||
public interface RolePermissionMapper extends BaseMapper<RolePermission> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package icu.sunway.ai_spring_example.Mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.User;
|
||||
|
||||
@Mapper
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package icu.sunway.ai_spring_example.Mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import icu.sunway.ai_spring_example.Entity.UserRole;
|
||||
|
||||
@Mapper
|
||||
public interface UserRoleMapper extends BaseMapper<UserRole> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package icu.sunway.ai_spring_example.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import icu.sunway.ai_spring_example.Entity.Permission;
|
||||
|
||||
public interface IPermissionService extends IService<Permission> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package icu.sunway.ai_spring_example.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import icu.sunway.ai_spring_example.Entity.RolePermission;
|
||||
|
||||
public interface IRolePermissionService extends IService<RolePermission> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package icu.sunway.ai_spring_example.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import icu.sunway.ai_spring_example.Entity.Role;
|
||||
|
||||
public interface IRoleService extends IService<Role> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package icu.sunway.ai_spring_example.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import icu.sunway.ai_spring_example.Entity.UserRole;
|
||||
|
||||
public interface IUserRoleService extends IService<UserRole> {
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package icu.sunway.ai_spring_example.Service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import icu.sunway.ai_spring_example.Entity.User;
|
||||
|
||||
public interface IUserService extends IService<User> {
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package icu.sunway.ai_spring_example.Service.Implements;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import icu.sunway.ai_spring_example.Entity.Permission;
|
||||
import icu.sunway.ai_spring_example.Mapper.PermissionMapper;
|
||||
import icu.sunway.ai_spring_example.Service.IPermissionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
|
||||
|
||||
@Resource
|
||||
private PermissionMapper permissionMapper;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package icu.sunway.ai_spring_example.Service.Implements;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import icu.sunway.ai_spring_example.Entity.RolePermission;
|
||||
import icu.sunway.ai_spring_example.Mapper.RolePermissionMapper;
|
||||
import icu.sunway.ai_spring_example.Service.IRolePermissionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermission>
|
||||
implements IRolePermissionService {
|
||||
|
||||
@Resource
|
||||
private RolePermissionMapper rolePermissionMapper;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package icu.sunway.ai_spring_example.Service.Implements;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import icu.sunway.ai_spring_example.Entity.Role;
|
||||
import icu.sunway.ai_spring_example.Mapper.RoleMapper;
|
||||
import icu.sunway.ai_spring_example.Service.IRoleService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
|
||||
|
||||
@Resource
|
||||
private RoleMapper roleMapper;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package icu.sunway.ai_spring_example.Service.Implements;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import icu.sunway.ai_spring_example.Entity.UserRole;
|
||||
import icu.sunway.ai_spring_example.Mapper.UserRoleMapper;
|
||||
import icu.sunway.ai_spring_example.Service.IUserRoleService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements IUserRoleService {
|
||||
|
||||
@Resource
|
||||
private UserRoleMapper userRoleMapper;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package icu.sunway.ai_spring_example.Service.Implements;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import icu.sunway.ai_spring_example.Entity.User;
|
||||
import icu.sunway.ai_spring_example.Mapper.UserMapper;
|
||||
import icu.sunway.ai_spring_example.Service.IUserService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
|
||||
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
}
|
||||
Reference in New Issue
Block a user