diff --git a/pom.xml b/pom.xml index 3e6d540..5755458 100644 --- a/pom.xml +++ b/pom.xml @@ -49,6 +49,11 @@ spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-aop + + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/com/xuxd/kafka/console/KafkaConsoleUiApplication.java b/src/main/java/com/xuxd/kafka/console/KafkaConsoleUiApplication.java index aa36b29..73d9a44 100644 --- a/src/main/java/com/xuxd/kafka/console/KafkaConsoleUiApplication.java +++ b/src/main/java/com/xuxd/kafka/console/KafkaConsoleUiApplication.java @@ -6,6 +6,9 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.scheduling.annotation.EnableScheduling; +/** + * @author 晓东哥哥 + */ @MapperScan("com.xuxd.kafka.console.dao") @SpringBootApplication @EnableScheduling diff --git a/src/main/java/com/xuxd/kafka/console/aspect/ControllerLogAspect.java b/src/main/java/com/xuxd/kafka/console/aspect/ControllerLogAspect.java new file mode 100644 index 0000000..139fbf8 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/aspect/ControllerLogAspect.java @@ -0,0 +1,117 @@ +package com.xuxd.kafka.console.aspect; + +import com.xuxd.kafka.console.aspect.annotation.ControllerLog; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + +/** + * @author 晓东哥哥 + */ +@Slf4j +@Order(-1) +@Aspect +@Component +public class ControllerLogAspect { + + private Map descMap = new HashMap<>(); + + private ReentrantLock lock = new ReentrantLock(); + + @Pointcut("@annotation(com.xuxd.kafka.console.aspect.annotation.ControllerLog)") + private void pointcut() { + + } + + @Around("pointcut()") + public Object around(ProceedingJoinPoint joinPoint) throws Throwable { + StringBuilder params = new StringBuilder("["); + try { + String methodName = getMethodFullName(joinPoint.getTarget().getClass().getName(), joinPoint.getSignature().getName()); + + if (!descMap.containsKey(methodName)) { + cacheDescInfo(joinPoint); + } + + Object[] args = joinPoint.getArgs(); + long startTime = System.currentTimeMillis(); + Object res = joinPoint.proceed(); + long endTime = System.currentTimeMillis(); + + for (int i = 0; i < args.length; i++) { + params.append(args[i]); + } + params.append("]"); + + String resStr = "[" + (res != null ? res.toString() : "") + "]"; + + StringBuilder sb = new StringBuilder(); + String shortMethodName = descMap.getOrDefault(methodName, ".-"); + shortMethodName = shortMethodName.substring(shortMethodName.lastIndexOf(".") + 1); + sb.append("[").append(shortMethodName) + .append("调用完成: ") + .append("请求参数=").append(params).append(", ") + .append("响应值=").append(resStr).append(", ") + .append("耗时=").append(endTime - startTime) + .append(" ms"); + log.info(sb.toString()); + return res; + } catch (Throwable e) { + log.error("调用方法异常, 请求参数:" + params, e); + throw e; + } + } + + private void cacheDescInfo(ProceedingJoinPoint joinPoint) { + lock.lock(); + try { + String methodName = joinPoint.getSignature().getName(); + Class aClass = joinPoint.getTarget().getClass(); + + Method method = null; + try { + Object[] args = joinPoint.getArgs(); + + Class[] clzArr = new Class[args.length]; + for (int i = 0; i < args.length; i++) { + clzArr[i] = args[i].getClass(); + } + method = aClass.getDeclaredMethod(methodName, clzArr); + + } catch (Exception e) { + log.warn("cacheDescInfo error: {}", e.getMessage()); + } + + String fullMethodName = getMethodFullName(aClass.getName(), methodName); + String desc = "[" + fullMethodName + "]"; + if (method == null) { + descMap.put(fullMethodName, desc); + return; + } + + ControllerLog controllerLog = method.getAnnotation(ControllerLog.class); + String value = controllerLog.value(); + if (StringUtils.isBlank(value)) { + descMap.put(fullMethodName, desc); + } else { + descMap.put(fullMethodName, value); + } + } finally { + lock.unlock(); + } + } + + private String getMethodFullName(String className, String methodName) { + return className + "#" + methodName; + } +} diff --git a/src/main/java/com/xuxd/kafka/console/aspect/annotation/ControllerLog.java b/src/main/java/com/xuxd/kafka/console/aspect/annotation/ControllerLog.java new file mode 100644 index 0000000..b74a2bb --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/aspect/annotation/ControllerLog.java @@ -0,0 +1,15 @@ +package com.xuxd.kafka.console.aspect.annotation; + +import java.lang.annotation.*; + +/** + * 该注解用到controller层的方法上 + * @author 晓东哥哥 + */ +@Inherited +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface ControllerLog { + + String value() default ""; +} diff --git a/src/main/java/com/xuxd/kafka/console/beans/dos/SysPermissionDO.java b/src/main/java/com/xuxd/kafka/console/beans/dos/SysPermissionDO.java new file mode 100644 index 0000000..2548878 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/beans/dos/SysPermissionDO.java @@ -0,0 +1,29 @@ +package com.xuxd.kafka.console.beans.dos; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @author: xuxd + * @date: 2023/4/11 21:17 + **/ +@Data +@TableName("t_sys_permission") +public class SysPermissionDO { + + @TableId(type = IdType.AUTO) + private Long id; + + private String name; + + /** + * 权限类型: 0:菜单,1:按钮 + */ + private Integer type; + + private Long parentId; + + private String permission; +} diff --git a/src/main/java/com/xuxd/kafka/console/beans/dos/SysRoleDO.java b/src/main/java/com/xuxd/kafka/console/beans/dos/SysRoleDO.java new file mode 100644 index 0000000..fc6f65a --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/beans/dos/SysRoleDO.java @@ -0,0 +1,24 @@ +package com.xuxd.kafka.console.beans.dos; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @author: xuxd + * @date: 2023/4/11 21:17 + **/ +@Data +@TableName("t_sys_role") +public class SysRoleDO { + + @TableId(type = IdType.AUTO) + private Long id; + + private String roleName; + + private String description; + + private String permissionIds; +} diff --git a/src/main/java/com/xuxd/kafka/console/beans/dos/SysUserDO.java b/src/main/java/com/xuxd/kafka/console/beans/dos/SysUserDO.java new file mode 100644 index 0000000..df70186 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/beans/dos/SysUserDO.java @@ -0,0 +1,26 @@ +package com.xuxd.kafka.console.beans.dos; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +/** + * @author: xuxd + * @date: 2023/4/11 21:17 + **/ +@Data +@TableName("t_sys_user") +public class SysUserDO { + + @TableId(type = IdType.AUTO) + private Long id; + + private String username; + + private String password; + + private String salt; + + private String roleIds; +} diff --git a/src/main/java/com/xuxd/kafka/console/beans/dto/SysPermissionDTO.java b/src/main/java/com/xuxd/kafka/console/beans/dto/SysPermissionDTO.java new file mode 100644 index 0000000..5f34954 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/beans/dto/SysPermissionDTO.java @@ -0,0 +1,32 @@ +package com.xuxd.kafka.console.beans.dto; + +import com.xuxd.kafka.console.beans.dos.SysPermissionDO; +import lombok.Data; + +/** + * @author: xuxd + * @date: 2023/4/11 21:17 + **/ +@Data +public class SysPermissionDTO { + + private String name; + + /** + * 权限类型: 0:菜单,1:按钮 + */ + private Integer type; + + private Long parentId; + + private String permission; + + public SysPermissionDO toSysPermissionDO() { + SysPermissionDO permissionDO = new SysPermissionDO(); + permissionDO.setName(this.name); + permissionDO.setType(this.type); + permissionDO.setParentId(this.parentId); + permissionDO.setPermission(this.permission); + return permissionDO; + } +} diff --git a/src/main/java/com/xuxd/kafka/console/beans/dto/SysRoleDTO.java b/src/main/java/com/xuxd/kafka/console/beans/dto/SysRoleDTO.java new file mode 100644 index 0000000..9ee1fc6 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/beans/dto/SysRoleDTO.java @@ -0,0 +1,26 @@ +package com.xuxd.kafka.console.beans.dto; + +import com.xuxd.kafka.console.beans.dos.SysRoleDO; +import lombok.Data; + +/** + * @author: xuxd + * @date: 2023/4/11 21:17 + **/ +@Data +public class SysRoleDTO { + + private String roleName; + + private String description; + + private String permissionIds; + + public SysRoleDO toDO() { + SysRoleDO roleDO = new SysRoleDO(); + roleDO.setRoleName(this.roleName); + roleDO.setDescription(this.description); + roleDO.setPermissionIds(this.permissionIds); + return roleDO; + } +} diff --git a/src/main/java/com/xuxd/kafka/console/beans/dto/SysUserDTO.java b/src/main/java/com/xuxd/kafka/console/beans/dto/SysUserDTO.java new file mode 100644 index 0000000..2c8be8e --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/beans/dto/SysUserDTO.java @@ -0,0 +1,29 @@ +package com.xuxd.kafka.console.beans.dto; + +import com.xuxd.kafka.console.beans.dos.SysUserDO; +import lombok.Data; + +/** + * @author: xuxd + * @date: 2023/4/11 21:17 + **/ +@Data +public class SysUserDTO { + + private String username; + + private String password; + + private String salt; + + private String roleIds; + + public SysUserDO toDO() { + SysUserDO userDO = new SysUserDO(); + userDO.setUsername(this.username); + userDO.setPassword(this.password); + userDO.setSalt(this.salt); + userDO.setRoleIds(this.roleIds); + return userDO; + } +} diff --git a/src/main/java/com/xuxd/kafka/console/controller/UserManageController.java b/src/main/java/com/xuxd/kafka/console/controller/UserManageController.java new file mode 100644 index 0000000..f10074d --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/controller/UserManageController.java @@ -0,0 +1,44 @@ +package com.xuxd.kafka.console.controller; + +import com.xuxd.kafka.console.aspect.annotation.ControllerLog; +import com.xuxd.kafka.console.beans.dto.SysPermissionDTO; +import com.xuxd.kafka.console.beans.dto.SysRoleDTO; +import com.xuxd.kafka.console.beans.dto.SysUserDTO; +import com.xuxd.kafka.console.service.UserManageService; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author: xuxd + * @date: 2023/4/11 21:34 + **/ +@RestController +@RequestMapping("/sys/user/manage") +public class UserManageController { + + private final UserManageService userManageService; + + public UserManageController(UserManageService userManageService) { + this.userManageService = userManageService; + } + + @ControllerLog("新增用户") + @PostMapping("/user") + public Object addUser(@RequestBody SysUserDTO userDTO) { + return userManageService.addUser(userDTO); + } + + @ControllerLog("新增角色") + @PostMapping("/role") + public Object addRole(@RequestBody SysRoleDTO roleDTO) { + return userManageService.addRole(roleDTO); + } + + @ControllerLog("新增权限") + @PostMapping("/permission") + public Object addPermission(@RequestBody SysPermissionDTO permissionDTO) { + return userManageService.addPermission(permissionDTO); + } +} diff --git a/src/main/java/com/xuxd/kafka/console/dao/SysPermissionMapper.java b/src/main/java/com/xuxd/kafka/console/dao/SysPermissionMapper.java new file mode 100644 index 0000000..f88ff78 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/dao/SysPermissionMapper.java @@ -0,0 +1,13 @@ +package com.xuxd.kafka.console.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.xuxd.kafka.console.beans.dos.SysPermissionDO; + +/** + * 系统权限 . + * + * @author: xuxd + * @date: 2023/4/11 21:21 + **/ +public interface SysPermissionMapper extends BaseMapper { +} diff --git a/src/main/java/com/xuxd/kafka/console/dao/SysRoleMapper.java b/src/main/java/com/xuxd/kafka/console/dao/SysRoleMapper.java new file mode 100644 index 0000000..d70ad4b --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/dao/SysRoleMapper.java @@ -0,0 +1,11 @@ +package com.xuxd.kafka.console.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.xuxd.kafka.console.beans.dos.SysRoleDO; + +/** + * @author: xuxd + * @date: 2023/4/11 21:22 + **/ +public interface SysRoleMapper extends BaseMapper { +} diff --git a/src/main/java/com/xuxd/kafka/console/dao/SysUserMapper.java b/src/main/java/com/xuxd/kafka/console/dao/SysUserMapper.java new file mode 100644 index 0000000..7a3af87 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/dao/SysUserMapper.java @@ -0,0 +1,11 @@ +package com.xuxd.kafka.console.dao; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.xuxd.kafka.console.beans.dos.SysUserDO; + +/** + * @author: xuxd + * @date: 2023/4/11 21:22 + **/ +public interface SysUserMapper extends BaseMapper { +} diff --git a/src/main/java/com/xuxd/kafka/console/service/UserManageService.java b/src/main/java/com/xuxd/kafka/console/service/UserManageService.java new file mode 100644 index 0000000..a6677e5 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/service/UserManageService.java @@ -0,0 +1,24 @@ +package com.xuxd.kafka.console.service; + +import com.xuxd.kafka.console.beans.ResponseData; +import com.xuxd.kafka.console.beans.dto.SysPermissionDTO; +import com.xuxd.kafka.console.beans.dto.SysRoleDTO; +import com.xuxd.kafka.console.beans.dto.SysUserDTO; + +/** + * 登录用户权限管理. + * + * @author: xuxd + * @date: 2023/4/11 21:24 + **/ +public interface UserManageService { + + /** + * 增加权限 + */ + ResponseData addPermission(SysPermissionDTO permissionDTO); + + ResponseData addRole(SysRoleDTO roleDTO); + + ResponseData addUser(SysUserDTO userDTO); +} diff --git a/src/main/java/com/xuxd/kafka/console/service/impl/UserManageServiceImpl.java b/src/main/java/com/xuxd/kafka/console/service/impl/UserManageServiceImpl.java new file mode 100644 index 0000000..dc85b96 --- /dev/null +++ b/src/main/java/com/xuxd/kafka/console/service/impl/UserManageServiceImpl.java @@ -0,0 +1,54 @@ +package com.xuxd.kafka.console.service.impl; + +import com.xuxd.kafka.console.beans.ResponseData; +import com.xuxd.kafka.console.beans.dto.SysPermissionDTO; +import com.xuxd.kafka.console.beans.dto.SysRoleDTO; +import com.xuxd.kafka.console.beans.dto.SysUserDTO; +import com.xuxd.kafka.console.dao.SysPermissionMapper; +import com.xuxd.kafka.console.dao.SysRoleMapper; +import com.xuxd.kafka.console.dao.SysUserMapper; +import com.xuxd.kafka.console.service.UserManageService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.stereotype.Service; + +/** + * @author: xuxd + * @date: 2023/4/11 21:24 + **/ +@Slf4j +@Service +public class UserManageServiceImpl implements UserManageService { + + private final SysUserMapper userMapper; + + private final SysRoleMapper roleMapper; + + private final SysPermissionMapper permissionMapper; + + public UserManageServiceImpl(ObjectProvider userMapper, + ObjectProvider roleMapper, + ObjectProvider permissionMapper) { + this.userMapper = userMapper.getIfAvailable(); + this.roleMapper = roleMapper.getIfAvailable(); + this.permissionMapper = permissionMapper.getIfAvailable(); + } + + @Override + public ResponseData addPermission(SysPermissionDTO permissionDTO) { + permissionMapper.insert(permissionDTO.toSysPermissionDO()); + return ResponseData.create().success(); + } + + @Override + public ResponseData addRole(SysRoleDTO roleDTO) { + roleMapper.insert(roleDTO.toDO()); + return ResponseData.create().success(); + } + + @Override + public ResponseData addUser(SysUserDTO userDTO) { + userMapper.insert(userDTO.toDO()); + return ResponseData.create().success(); + } +} diff --git a/src/main/resources/db/schema-h2.sql b/src/main/resources/db/schema-h2.sql index 355ffc1..305ec7d 100644 --- a/src/main/resources/db/schema-h2.sql +++ b/src/main/resources/db/schema-h2.sql @@ -34,4 +34,35 @@ CREATE TABLE IF NOT EXISTS T_CLUSTER_INFO UPDATE_TIME TIMESTAMP NOT NULL DEFAULT NOW() COMMENT '更新时间', PRIMARY KEY (ID), UNIQUE (CLUSTER_NAME) +); + +-- 登录用户的角色权限配置 +CREATE TABLE IF NOT EXISTS t_sys_permission +( + ID IDENTITY NOT NULL COMMENT '主键ID', + name varchar(100) DEFAULT NULL COMMENT '权限名称', + type tinyint(1) NOT NULL DEFAULT 0 COMMENT '权限类型: 0:菜单,1:按钮', + parent_id bigint(20) DEFAULT NULL COMMENT '所属父权限ID', + permission varchar(100) DEFAULT NULL COMMENT '权限字符串', + PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS t_sys_role +( + ID IDENTITY NOT NULL COMMENT '主键ID', + role_name varchar(100) NOT NULL COMMENT '角色名称', + description varchar(100) DEFAULT NULL COMMENT '角色描述', + permission_ids varchar(500) DEFAULT NULL COMMENT '分配的权限ID', + PRIMARY KEY (id) +); + +CREATE TABLE IF NOT EXISTS t_sys_user +( + ID IDENTITY NOT NULL COMMENT '主键ID', + username varchar(100) DEFAULT NULL COMMENT '用户名', + password varchar(100) DEFAULT NULL COMMENT '用户密码', + salt varchar(100) DEFAULT NULL COMMENT '加密的盐值', + role_ids varchar(100) DEFAULT NULL COMMENT '分配角色的ID', + PRIMARY KEY (id), + UNIQUE (username) ); \ No newline at end of file diff --git a/ui/src/App.vue b/ui/src/App.vue index db6fde5..a07c4a0 100644 --- a/ui/src/App.vue +++ b/ui/src/App.vue @@ -16,6 +16,8 @@ |Acl |用户 + |运维 集群:{{ clusterName }} diff --git a/ui/src/router/index.js b/ui/src/router/index.js index d14b862..d69f292 100644 --- a/ui/src/router/index.js +++ b/ui/src/router/index.js @@ -55,6 +55,12 @@ const routes = [ component: () => import(/* webpackChunkName: "cluster" */ "../views/quota/ClientQuota.vue"), }, + { + path: "/user-page", + name: "UserManage", + component: () => + import(/* webpackChunkName: "cluster" */ "../views/user/UserManage.vue"), + }, ]; const router = new VueRouter({ diff --git a/ui/src/views/user/UserManage.vue b/ui/src/views/user/UserManage.vue new file mode 100644 index 0000000..3cd1f78 --- /dev/null +++ b/ui/src/views/user/UserManage.vue @@ -0,0 +1,35 @@ + + + + +