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:
set
2026-02-05 18:52:37 +08:00
parent 98e6d6a557
commit d03897c525
29 changed files with 1094 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"Bash(git add:*)"
]
}
}

66
CLAUDE.md Normal file
View 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

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View 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("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;
}

View 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;
}

View File

@@ -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;
}

View 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;
}

View File

@@ -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;
}

View 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);

View 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;

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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> {
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}