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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+