diff --git a/chaos_api_common/src/main/java/cn/nopj/chaos_api/common/constants/ErrorCode.java b/chaos_api_common/src/main/java/cn/nopj/chaos_api/common/constants/ErrorCode.java index 27fe0bd..3015be3 100644 --- a/chaos_api_common/src/main/java/cn/nopj/chaos_api/common/constants/ErrorCode.java +++ b/chaos_api_common/src/main/java/cn/nopj/chaos_api/common/constants/ErrorCode.java @@ -32,6 +32,8 @@ public enum ErrorCode { USER_UPDATE_USERNAME_FAILED(400,"USER-111" , "用户名更新失败"), + ROLE_ID_INVALID(400, "ROLE-100" , "角色ID无效" ), + // ================== 论坛内容相关 (200-299) ================== POST_NOT_FOUND(404, "POST-201", "帖子不存在"), POST_DELETED(410, "POST-202", "帖子已被删除"), @@ -45,7 +47,7 @@ public enum ErrorCode { CAPTCHA_ERROR(400, "SYS-301", "验证码错误"), SMS_SEND_FAILED(500, "SYS-302", "短信发送失败"), FILE_UPLOAD_FAILED(500, "SYS-303", "文件上传失败"), - RATE_LIMIT_EXCEEDED(429, "SYS-304", "操作过于频繁"); + RATE_LIMIT_EXCEEDED(429, "SYS-304", "操作过于频繁"),; private final int httpStatus; private final String code; // 业务错误码(领域-编号) diff --git a/chaos_api_common/src/main/java/cn/nopj/chaos_api/converter/UserConverter.java b/chaos_api_common/src/main/java/cn/nopj/chaos_api/converter/UserConverter.java index 99deed4..1301bac 100644 --- a/chaos_api_common/src/main/java/cn/nopj/chaos_api/converter/UserConverter.java +++ b/chaos_api_common/src/main/java/cn/nopj/chaos_api/converter/UserConverter.java @@ -15,8 +15,6 @@ public class UserConverter { user.setAccountNonExpired(true); user.setCredentialsNonExpired(true); user.setAccountNonLocked(true); - user.setCreateTime(java.time.LocalDateTime.now()); - user.setUpdateTime(java.time.LocalDateTime.now()); return user; } } diff --git a/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/RoleMapper.java b/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/RoleMapper.java index 95b8e91..6342460 100644 --- a/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/RoleMapper.java +++ b/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/RoleMapper.java @@ -3,8 +3,16 @@ package cn.nopj.chaos_api.mapper; import cn.nopj.chaos_api.domain.entity.Role; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Select; @Mapper public interface RoleMapper extends BaseMapper { + /** + * 根据角色编码查询角色信息 + * @param code 角色编码 + * @return 角色信息 + */ + @Select("SELECT * FROM t_role WHERE code = #{code}") + Role selectByCode(String code); } diff --git a/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/UserMapper.java b/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/UserMapper.java index da780ae..4f1a7d6 100644 --- a/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/UserMapper.java +++ b/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/UserMapper.java @@ -4,6 +4,7 @@ import cn.nopj.chaos_api.domain.entity.Role; import cn.nopj.chaos_api.domain.entity.User; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.*; +import org.springframework.transaction.annotation.Transactional; import java.util.List; @@ -34,6 +35,7 @@ public interface UserMapper extends BaseMapper { * @param id 用户id * @param i 角色id */ + @Select("INSERT INTO t_user_role (user_id, role_id) VALUES (#{userId}, #{roleId})") void insertUserRole(@Param("userId") Long id, @Param("roleId") Long i); @@ -54,7 +56,7 @@ public interface UserMapper extends BaseMapper { @Result(property = "roles", column = "id", many = @Many(select = "findRolesByUserId")) }) - User findUserWithRoles(Long id); + User findUserWithRolesById(Long id); /** @@ -83,4 +85,16 @@ public interface UserMapper extends BaseMapper { WHERE ur.user_id = #{userId} """) List findRolesByUserId(@Param("userId") Long userId); + + + @Select("SELECT * FROM t_user WHERE username = #{username} ") + @Results({ + @Result(id = true, property = "id", column = "id"), + @Result(property = "username", column = "username"), + @Result(property = "nickname", column = "nickname"), + @Result(property = "roles", column = "id", + + many = @Many(select = "findRolesByUserId")) + }) + User findUserWithRolesByUsername(String username); } diff --git a/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/UserRoleMapper.java b/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/UserRoleMapper.java new file mode 100644 index 0000000..a214160 --- /dev/null +++ b/chaos_api_data/src/main/java/cn/nopj/chaos_api/mapper/UserRoleMapper.java @@ -0,0 +1,7 @@ +package cn.nopj.chaos_api.mapper; + +import cn.nopj.chaos_api.domain.entity.UserRole; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface UserRoleMapper extends BaseMapper { +} diff --git a/chaos_api_domain/src/main/java/cn/nopj/chaos_api/domain/entity/User.java b/chaos_api_domain/src/main/java/cn/nopj/chaos_api/domain/entity/User.java index fe4a36a..94c81c8 100644 --- a/chaos_api_domain/src/main/java/cn/nopj/chaos_api/domain/entity/User.java +++ b/chaos_api_domain/src/main/java/cn/nopj/chaos_api/domain/entity/User.java @@ -1,57 +1,85 @@ package cn.nopj.chaos_api.domain.entity; + import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import lombok.Getter; +import lombok.Setter; -import java.io.Serializable; -import java.time.LocalDateTime; +import java.util.Date; import java.util.List; - +/** + * 系统管理-用户表 + * @TableName t_user + */ @Data -@TableName("t_user") -public class User implements Serializable { +@TableName(value ="t_user") + +public class User { /** - * 用户id + * 主键ID */ @TableId private Long id; + /** - * 用户名称 + * 用户名/登录名 */ private String username; + /** - * 密码 + * 密码(加密存储,建议BCrypt) */ private String password; + /** - * 账号是否启用 + * 用户昵称 + */ + private String nickname; + + /** + * 状态 (1:启用, 0:禁用) */ private Boolean enabled; + /** - * 账号是否未过期 + * 账号未过期 (1:是, 0:否) */ private Boolean accountNonExpired; + /** - * 密码是否未过期 + * 凭证未过期 (1:是, 0:否) */ private Boolean credentialsNonExpired; + /** - * 账号是否未锁定 + * 账号未锁定 (1:是, 0:否) */ private Boolean accountNonLocked; + + /** + * 逻辑删除 (1:已删除, 0:未删除) + */ + private Boolean deleted; + + /** + * 备注信息 + */ + private String remark; + /** * 创建时间 */ - private LocalDateTime createTime; + private Date createTime; + /** * 更新时间 */ - private LocalDateTime updateTime; + private Date updateTime; @TableField(exist = false) private List roles; -} - +} \ No newline at end of file diff --git a/chaos_api_domain/src/main/java/cn/nopj/chaos_api/domain/entity/UserRole.java b/chaos_api_domain/src/main/java/cn/nopj/chaos_api/domain/entity/UserRole.java new file mode 100644 index 0000000..aa149b5 --- /dev/null +++ b/chaos_api_domain/src/main/java/cn/nopj/chaos_api/domain/entity/UserRole.java @@ -0,0 +1,13 @@ +package cn.nopj.chaos_api.domain.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +@TableName("t_user_role") +@AllArgsConstructor +@NoArgsConstructor +public class UserRole { + private Long userId; + private Long roleId; +} diff --git a/chaos_api_domain/src/main/java/cn/nopj/chaos_api/dto/request/SetUserRoleRequest.java b/chaos_api_domain/src/main/java/cn/nopj/chaos_api/dto/request/SetUserRoleRequest.java new file mode 100644 index 0000000..383540f --- /dev/null +++ b/chaos_api_domain/src/main/java/cn/nopj/chaos_api/dto/request/SetUserRoleRequest.java @@ -0,0 +1,14 @@ +package cn.nopj.chaos_api.dto.request; + +import jakarta.validation.constraints.Pattern; +import lombok.Data; + +import java.util.List; + +@Data +public class SetUserRoleRequest { + @Pattern(regexp = "^[0-9]+$", message = "用户id格式错误") + private Long userId; + @Pattern(regexp = "^[0-9]+$", message = "角色id格式错误") + private List rolesId; +} diff --git a/chaos_api_interface/src/main/java/cn/nopj/chaos_api/service/UserInfoService.java b/chaos_api_interface/src/main/java/cn/nopj/chaos_api/service/UserInfoService.java index c4c1193..bafa368 100644 --- a/chaos_api_interface/src/main/java/cn/nopj/chaos_api/service/UserInfoService.java +++ b/chaos_api_interface/src/main/java/cn/nopj/chaos_api/service/UserInfoService.java @@ -42,4 +42,12 @@ public interface UserInfoService { * @param newUsername 新用户名 */ void updateUsername(String username, String newUsername); + + /** + * 根据用户名查询用户信息 + * + * @param username 用户名 + * @return 用户信息 + */ + UserinfoResponse findUserWithRoles(String username); } diff --git a/chaos_api_interface/src/main/java/cn/nopj/chaos_api/service/UserRoleService.java b/chaos_api_interface/src/main/java/cn/nopj/chaos_api/service/UserRoleService.java new file mode 100644 index 0000000..4bfe77b --- /dev/null +++ b/chaos_api_interface/src/main/java/cn/nopj/chaos_api/service/UserRoleService.java @@ -0,0 +1,23 @@ +package cn.nopj.chaos_api.service; + +import cn.nopj.chaos_api.dto.request.SetUserRoleRequest; + +import java.util.List; + +/** + * 用户角色服务 + */ +public interface UserRoleService { + /** + * 为用户设置角色 + * @param userId 用户id + * @param roles_id 角色id组 + */ + void setUserRole(Long userId, List roles_id); + + /** + * 为用户设置角色 + * @param request 请求参数 + */ + void setUserRole(SetUserRoleRequest request); +} diff --git a/chaos_api_service/src/main/java/cn/nopj/chaos_api/service/impl/UserInfoServiceImpl.java b/chaos_api_service/src/main/java/cn/nopj/chaos_api/service/impl/UserInfoServiceImpl.java index 772db91..ae3c70d 100644 --- a/chaos_api_service/src/main/java/cn/nopj/chaos_api/service/impl/UserInfoServiceImpl.java +++ b/chaos_api_service/src/main/java/cn/nopj/chaos_api/service/impl/UserInfoServiceImpl.java @@ -46,18 +46,7 @@ public class UserInfoServiceImpl implements UserInfoService { } return allUserWithRoles.stream().map(user -> { - UserinfoResponse userinfoResponse = new UserinfoResponse(); - userinfoResponse.setId(user.getId()); - userinfoResponse.setUsername(user.getUsername()); - userinfoResponse.setRoles( - user.getRoles().stream().map(role -> { - RoleResponse roleResponse = new RoleResponse(); - roleResponse.setId(role.getId()); - roleResponse.setName(role.getName()); - return roleResponse; - }).toList() - ); - return userinfoResponse; + return userConverterUserinfo(user); }).toList(); } @@ -89,5 +78,42 @@ public class UserInfoServiceImpl implements UserInfoService { } + @Override + public UserinfoResponse findUserWithRoles(String username) { + if (username == null || username.isEmpty()){ + throw new BizException(ErrorCode.USER_NOT_EXISTS); + } + log.info("查询用户名: {}", username); + + User user = userMapper.findUserWithRolesByUsername(username); + + log.info("查询用户名: {} 结果: {}", username, user); + if (user == null) { + throw new BizException(ErrorCode.USER_NOT_EXISTS); + } + return userConverterUserinfo(user); + } + + /** + * User 转 UserinfoResponse + * @param user + * @return + */ + private UserinfoResponse userConverterUserinfo(User user) { + UserinfoResponse userinfoResponse = new UserinfoResponse(); + userinfoResponse.setId(user.getId()); + userinfoResponse.setUsername(user.getUsername()); + userinfoResponse.setRoles( + user.getRoles().stream().map(role -> { + RoleResponse roleResponse = new RoleResponse(); + roleResponse.setId(role.getId()); + roleResponse.setName(role.getName()); + return roleResponse; + }).toList() + ); + return userinfoResponse; + } + + } diff --git a/chaos_api_service/src/main/java/cn/nopj/chaos_api/service/impl/UserRoleServiceImpl.java b/chaos_api_service/src/main/java/cn/nopj/chaos_api/service/impl/UserRoleServiceImpl.java new file mode 100644 index 0000000..886905e --- /dev/null +++ b/chaos_api_service/src/main/java/cn/nopj/chaos_api/service/impl/UserRoleServiceImpl.java @@ -0,0 +1,50 @@ +package cn.nopj.chaos_api.service.impl; + +import cn.nopj.chaos_api.common.constants.ErrorCode; +import cn.nopj.chaos_api.common.exceotion.BizException; +import cn.nopj.chaos_api.domain.entity.UserRole; +import cn.nopj.chaos_api.dto.request.SetUserRoleRequest; +import cn.nopj.chaos_api.mapper.UserRoleMapper; +import cn.nopj.chaos_api.service.UserRoleService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +@Slf4j +@Service +public class UserRoleServiceImpl implements UserRoleService { + + @Autowired + private UserRoleMapper userRoleMapper; + + @Override + + public void setUserRole(Long userId, List roles_id) { + + for (Long role_id : roles_id) { + if (role_id == null || role_id == 0L) { + throw new BizException(ErrorCode.ROLE_ID_INVALID); + }else { + userRoleMapper.insert(new UserRole(userId, role_id)); + } + } + + } + @Transactional(rollbackFor = Exception.class) + @Override + public void setUserRole(SetUserRoleRequest request) { + if (request == null || request.getUserId() == null ){ + throw new BizException(ErrorCode.USER_ID_INVALID); + } + if (request.getRolesId() == null || request.getRolesId().isEmpty()){ + throw new BizException(ErrorCode.ROLE_ID_INVALID); + } + + Long userId = request.getUserId(); + List roles_id = request.getRolesId(); + setUserRole(userId, roles_id); + } +} diff --git a/chaos_api_web/src/main/java/cn/nopj/chaos_api/config/AppConfig.java b/chaos_api_web/src/main/java/cn/nopj/chaos_api/config/AppConfig.java new file mode 100644 index 0000000..206d1a9 --- /dev/null +++ b/chaos_api_web/src/main/java/cn/nopj/chaos_api/config/AppConfig.java @@ -0,0 +1,9 @@ +package cn.nopj.chaos_api.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +@Configuration +@EnableTransactionManagement +public class AppConfig { +} diff --git a/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/RoleController.java b/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/RoleController.java index 969414b..04a8e06 100644 --- a/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/RoleController.java +++ b/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/RoleController.java @@ -1,7 +1,13 @@ package cn.nopj.chaos_api.controller; +import cn.nopj.chaos_api.dto.request.SetUserRoleRequest; +import cn.nopj.chaos_api.model.ApiResult; +import cn.nopj.chaos_api.service.UserRoleService; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -10,7 +16,21 @@ import org.springframework.web.bind.annotation.RestController; */ @Slf4j @RestController +@RequestMapping("/api/role") public class RoleController { + @Autowired + private UserRoleService userRoleService; + + /** + * 设置用户角色 + * @param request 请求参数 + * @return 处理结果 + */ + @RequestMapping("/setUserRole") + public ApiResult setUserRole(@RequestBody SetUserRoleRequest request) { + userRoleService.setUserRole(request); + return ApiResult.success("用户角色设置成功"); + } } diff --git a/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/UserController.java b/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/UserController.java index 2293fc1..46858df 100644 --- a/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/UserController.java +++ b/chaos_api_web/src/main/java/cn/nopj/chaos_api/controller/UserController.java @@ -60,4 +60,14 @@ public class UserController { userInfoService.updateUsername(username, request.getUsername()); return ApiResult.success("用户名更新成功"); } + + + /** + * 获取当前登录用户信息 + * @return 用户信息 + */ + @GetMapping("/info") + ApiResult getCurrentUserInfo(@RequestAttribute("currentUsername") String username){ + return ApiResult.success(userInfoService.findUserWithRoles(username)); + } } diff --git a/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/impl/AuthServiceImpl.java b/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/impl/AuthServiceImpl.java index cdf9298..0a075f2 100644 --- a/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/impl/AuthServiceImpl.java +++ b/chaos_api_web/src/main/java/cn/nopj/chaos_api/service/impl/AuthServiceImpl.java @@ -3,8 +3,10 @@ package cn.nopj.chaos_api.service.impl; import cn.nopj.chaos_api.common.constants.ErrorCode; import cn.nopj.chaos_api.common.exceotion.BizException; +import cn.nopj.chaos_api.domain.entity.Role; import cn.nopj.chaos_api.domain.entity.User; import cn.nopj.chaos_api.dto.response.AuthTokenResponse; +import cn.nopj.chaos_api.mapper.RoleMapper; import cn.nopj.chaos_api.mapper.UserMapper; import cn.nopj.chaos_api.service.AuthService; import cn.nopj.chaos_api.util.JwtTokenUtil; @@ -20,6 +22,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @Slf4j @@ -36,7 +39,13 @@ public class AuthServiceImpl implements AuthService { private AuthenticationManager authenticationManager; @Value("${jwt.tokenHead}") private String tokenHead; + @Value("${auth.def-role-code}") + private String defRoleCode; + @Autowired + private RoleMapper roleMapper; + @Override + @Transactional(rollbackFor = Exception.class) public User register(User user) { // 检查用户名是否已存在 @@ -48,13 +57,17 @@ public class AuthServiceImpl implements AuthService { user.setPassword(passwordEncoder.encode(user.getPassword())); userMapper.insert(user); // 你可以在这里为新用户分配默认角色 - userMapper.insertUserRole(user.getId(), 2L); + Role role = roleMapper.selectByCode(defRoleCode); + userMapper.insertUserRole(user.getId(), role.getId()); + + log.info("用户注册成功: {}", user.getUsername()); return user; } @Override public AuthTokenResponse login(String username, String password) { + log.info("用户登录: {}", username); // 尝试进行身份验证 try{ Authentication authentication = authenticationManager.authenticate( @@ -79,6 +92,7 @@ public class AuthServiceImpl implements AuthService { } catch (DisabledException e) { throw new BizException(ErrorCode.USER_NOT_ENABLED); } catch (Exception e) { + log.error("用户登录异常: {}", e.getMessage()); throw new BizException(ErrorCode.SYSTEM_ERROR); } } diff --git a/chaos_api_web/src/main/resources/application.yaml b/chaos_api_web/src/main/resources/application.yaml index afd3bbd..ffef0c4 100644 --- a/chaos_api_web/src/main/resources/application.yaml +++ b/chaos_api_web/src/main/resources/application.yaml @@ -39,4 +39,5 @@ jwt: secret: zHANgcHao@1995!20250506 expiration: 604800 - +auth: + def-role-code: user diff --git a/chaos_api_web/src/main/resources/data.sql b/chaos_api_web/src/main/resources/data.sql new file mode 100644 index 0000000..986f398 --- /dev/null +++ b/chaos_api_web/src/main/resources/data.sql @@ -0,0 +1,132 @@ + + +-- ---------------------------- +-- 1. 系统用户表 (t_user) +-- ---------------------------- +DROP TABLE IF EXISTS chaos.t_user; +CREATE TABLE chaos.t_user ( + id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键ID', + username VARCHAR(64) NOT NULL COMMENT '用户名/登录名', + password VARCHAR(255) NOT NULL COMMENT '密码(加密存储,建议BCrypt)', + nickname VARCHAR(64) DEFAULT '' COMMENT '用户昵称', + enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT '状态 (1:启用, 0:禁用)', + account_non_expired TINYINT(1) NOT NULL DEFAULT 1 COMMENT '账号未过期 (1:是, 0:否)', + credentials_non_expired TINYINT(1) NOT NULL DEFAULT 1 COMMENT '凭证未过期 (1:是, 0:否)', + account_non_locked TINYINT(1) NOT NULL DEFAULT 1 COMMENT '账号未锁定 (1:是, 0:否)', + deleted TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除 (1:已删除, 0:未删除)', + remark VARCHAR(500) DEFAULT '' COMMENT '备注信息', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (id), + UNIQUE KEY uk_username (username) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统管理-用户表'; + + +-- ---------------------------- +-- 2. 角色/用户组表 (t_role) +-- ---------------------------- +DROP TABLE IF EXISTS chaos.t_role; +CREATE TABLE chaos.t_role ( + id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键ID', + name VARCHAR(64) NOT NULL COMMENT '角色名称 (如: 管理员)', + code VARCHAR(64) NOT NULL COMMENT '角色标识 (如: admin)', + status TINYINT(1) NOT NULL DEFAULT 1 COMMENT '状态 (1:正常, 0:停用)', + remark VARCHAR(500) DEFAULT '' COMMENT '备注', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (id), + UNIQUE KEY uk_code (code) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统管理-角色表'; + + +-- ---------------------------- +-- 3. 权限表 (t_permission) +-- ---------------------------- +DROP TABLE IF EXISTS chaos.t_permission; +CREATE TABLE chaos.t_permission ( + id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键ID', + parent_id BIGINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '父权限ID (0为顶级)', + name VARCHAR(64) NOT NULL COMMENT '权限名称', + code VARCHAR(128) NOT NULL COMMENT '权限标识/资源路径', + type TINYINT(1) NOT NULL DEFAULT 1 COMMENT '类型 (1:目录, 2:菜单, 3:按钮)', + sort_order INT NOT NULL DEFAULT 0 COMMENT '排序 (数值越小越靠前)', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (id), + UNIQUE KEY uk_code (code), + INDEX idx_parent_id (parent_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统管理-权限表'; + + +-- ---------------------------- +-- 4. 用户-角色关联表 (t_user_role) +-- ---------------------------- +DROP TABLE IF EXISTS chaos.t_user_role; +CREATE TABLE chaos.t_user_role ( + user_id BIGINT UNSIGNED NOT NULL COMMENT '用户ID', + role_id BIGINT UNSIGNED NOT NULL COMMENT '角色ID', + PRIMARY KEY (user_id, role_id), + CONSTRAINT fk_ur_user_id FOREIGN KEY (user_id) REFERENCES chaos.t_user (id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT fk_ur_role_id FOREIGN KEY (role_id) REFERENCES chaos.t_role (id) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统管理-用户角色关联表'; + + +-- ---------------------------- +-- 5. 角色-权限关联表 (t_role_permission) +-- ---------------------------- +DROP TABLE IF EXISTS chaos.t_role_permission; +CREATE TABLE chaos.t_role_permission ( + role_id BIGINT UNSIGNED NOT NULL COMMENT '角色ID', + permission_id BIGINT UNSIGNED NOT NULL COMMENT '权限ID', + PRIMARY KEY (role_id, permission_id), + CONSTRAINT fk_rp_role_id FOREIGN KEY (role_id) REFERENCES chaos.t_role (id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT fk_rp_permission_id FOREIGN KEY (permission_id) REFERENCES chaos.t_permission (id) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='系统管理-角色权限关联表'; + + +-- ---------------------------- +-- 6. 基础设备表 (t_device) +-- ---------------------------- +DROP TABLE IF EXISTS chaos.t_device; +CREATE TABLE chaos.t_device ( + id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键ID', + name VARCHAR(128) NOT NULL COMMENT '设备名称', + model VARCHAR(128) DEFAULT NULL COMMENT '设备型号', + type_id BIGINT UNSIGNED DEFAULT NULL COMMENT '设备类型ID (关联类型表)', + location_id BIGINT UNSIGNED DEFAULT NULL COMMENT '位置ID (关联位置表)', + snmp_community VARCHAR(128) DEFAULT NULL COMMENT 'SNMP团体名 (加密存储建议)', + manufacturer VARCHAR(128) DEFAULT NULL COMMENT '设备制造商', + purchase_date DATE DEFAULT NULL COMMENT '采购日期', + status TINYINT DEFAULT 1 COMMENT '设备状态 (1:在线, 0:离线, 2:维护中)', + remark VARCHAR(500) DEFAULT '' COMMENT '备注', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (id), + INDEX idx_type_id (type_id), + INDEX idx_location_id (location_id) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资产管理-设备信息表'; + + +-- ---------------------------- +-- 7. 网络接口表 (t_network_interface) +-- ---------------------------- +DROP TABLE IF EXISTS chaos.t_network_interface; +CREATE TABLE chaos.t_network_interface ( + id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主键ID', + device_id BIGINT UNSIGNED NOT NULL COMMENT '设备ID', + parent_id BIGINT UNSIGNED DEFAULT NULL COMMENT '父接口ID (用于子接口/聚合口)', + name VARCHAR(64) NOT NULL COMMENT '接口名称 (如: eth0, GE0/0/1)', + mac_address VARCHAR(17) DEFAULT NULL COMMENT 'MAC地址 (格式: AA:BB:CC:DD:EE:FF)', + ip_address VARCHAR(45) DEFAULT NULL COMMENT 'IP地址 (支持IPv4/IPv6)', + subnet_mask VARCHAR(45) DEFAULT NULL COMMENT '子网掩码/前缀长度', + gateway_ip VARCHAR(45) DEFAULT NULL COMMENT '网关IP地址', + vlan_id INT DEFAULT NULL COMMENT 'VLAN ID (1-4094)', + port_speed INT DEFAULT 0 COMMENT '端口速率 (Mbps)', + status TINYINT DEFAULT 1 COMMENT '接口状态 (1:UP, 0:DOWN)', + remark VARCHAR(500) DEFAULT '' COMMENT '备注', + create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (id), + CONSTRAINT fk_ni_device_id FOREIGN KEY (device_id) REFERENCES chaos.t_device (id) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT fk_ni_parent_id FOREIGN KEY (parent_id) REFERENCES chaos.t_network_interface (id) ON DELETE SET NULL ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='资产管理-网络接口表'; \ No newline at end of file