diff --git a/kernel-d-log/log-spring-boot-starter/pom.xml b/kernel-d-log/log-spring-boot-starter/pom.xml
index b003f1af3..878ffb0aa 100644
--- a/kernel-d-log/log-spring-boot-starter/pom.xml
+++ b/kernel-d-log/log-spring-boot-starter/pom.xml
@@ -43,6 +43,13 @@
7.0.2
+
+
+ cn.stylefeng.roses
+ log-business-login-log
+ 7.0.2
+
+
diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/constants/SystemConstants.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/constants/SystemConstants.java
index 3bfe951f2..00650fc24 100644
--- a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/constants/SystemConstants.java
+++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/constants/SystemConstants.java
@@ -48,4 +48,14 @@ public interface SystemConstants {
*/
Long USER_CACHE_TIMEOUT_SECONDS = 3600L;
+ /**
+ * 超级管理员的角色编码
+ */
+ String SUPER_ADMIN_ROLE_CODE = "superAdmin";
+
+ /**
+ * 初始化超级管理员的监听器顺序
+ */
+ Integer SUPER_ADMIN_INIT_LISTENER_SORT = 400;
+
}
diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/LoginDetailsResponse.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/LoginDetailsResponse.java
new file mode 100644
index 000000000..37477b408
--- /dev/null
+++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/LoginDetailsResponse.java
@@ -0,0 +1,52 @@
+package cn.stylefeng.roses.kernel.system.api.pojo.login;
+
+import cn.stylefeng.roses.kernel.system.api.pojo.login.details.SimpleAuthDetail;
+import cn.stylefeng.roses.kernel.system.api.pojo.login.details.SimpleUserDetail;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * 登陆信息详情相应结果
+ *
+ * @author majianguo
+ * @date 2021/1/7 11:59
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class LoginDetailsResponse {
+
+ /**
+ * 登录人的token
+ */
+ private String token;
+
+ /**
+ * 到期时间
+ */
+ private Long expireAt;
+
+ /**
+ * 用户基本信息
+ */
+ private SimpleUserDetail user;
+
+ /**
+ * 权限信息
+ */
+ private List permissions;
+
+ /**
+ * 角色信息
+ */
+ private List roles;
+
+ /**
+ * 登录人的ws-url
+ */
+ private String wsUrl;
+
+}
diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/details/SimpleAuthDetail.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/details/SimpleAuthDetail.java
new file mode 100644
index 000000000..cfb28225b
--- /dev/null
+++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/details/SimpleAuthDetail.java
@@ -0,0 +1,26 @@
+package cn.stylefeng.roses.kernel.system.api.pojo.login.details;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 相关权限的数据,用在登录接口的返回详情
+ *
+ * @author fengshuonan
+ * @date 2021/1/7 17:06
+ */
+@Data
+public class SimpleAuthDetail {
+
+ /**
+ * 角色的编码
+ */
+ private String id;
+
+ /**
+ * 具体的按钮
+ */
+ private List operation;
+
+}
diff --git a/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/details/SimpleUserDetail.java b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/details/SimpleUserDetail.java
new file mode 100644
index 000000000..2990a92d7
--- /dev/null
+++ b/kernel-s-system/system-api/src/main/java/cn/stylefeng/roses/kernel/system/api/pojo/login/details/SimpleUserDetail.java
@@ -0,0 +1,39 @@
+package cn.stylefeng.roses.kernel.system.api.pojo.login.details;
+
+import lombok.Data;
+
+/**
+ * 用于登录返回详情
+ *
+ * @author fengshuonan
+ * @date 2021/1/7 17:06
+ */
+@Data
+public class SimpleUserDetail {
+
+ /**
+ * 用户id
+ */
+ private Long userId;
+
+ /**
+ * 姓名
+ */
+ private String name;
+
+ /**
+ * 头像
+ */
+ private String avatar;
+
+ /**
+ * 地址
+ */
+ private String address;
+
+ /**
+ * 职位
+ */
+ private String position;
+
+}
diff --git a/kernel-s-system/system-business-user/src/main/java/cn/stylefeng/roses/kernel/system/modular/user/controller/LoginController.java b/kernel-s-system/system-business-user/src/main/java/cn/stylefeng/roses/kernel/system/modular/user/controller/LoginController.java
new file mode 100644
index 000000000..d2436421e
--- /dev/null
+++ b/kernel-s-system/system-business-user/src/main/java/cn/stylefeng/roses/kernel/system/modular/user/controller/LoginController.java
@@ -0,0 +1,85 @@
+package cn.stylefeng.roses.kernel.system.modular.user.controller;
+
+import cn.stylefeng.roses.kernel.auth.api.AuthServiceApi;
+import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
+import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginRequest;
+import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginResponse;
+import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
+import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
+import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
+import cn.stylefeng.roses.kernel.scanner.api.annotation.ApiResource;
+import cn.stylefeng.roses.kernel.scanner.api.annotation.GetResource;
+import cn.stylefeng.roses.kernel.scanner.api.annotation.PostResource;
+import cn.stylefeng.roses.kernel.system.api.pojo.login.LoginDetailsResponse;
+import cn.stylefeng.roses.kernel.system.modular.user.factory.LoginResponseFactory;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * 登录登出控制器
+ *
+ * @author fengshuonan
+ * @date 2021/3/17 17:23
+ */
+@RestController
+@Slf4j
+@ApiResource(name = "登陆登出管理")
+public class LoginController {
+
+ @Resource
+ private AuthServiceApi authServiceApi;
+
+ /**
+ * 用户登陆
+ *
+ * @author fengshuonan
+ * @date 2021/3/17 17:23
+ */
+ @PostResource(name = "登陆", path = "/login", requiredLogin = false, requiredPermission = false)
+ public ResponseData doAuth(@RequestBody @Validated LoginRequest loginRequest) {
+ LoginResponse loginResponse = authServiceApi.login(loginRequest);
+ return new SuccessResponseData(loginResponse.getToken());
+ }
+
+ /**
+ * 用户登出
+ *
+ * @author fengshuonan
+ * @date 2021/3/17 17:24
+ */
+ @GetResource(name = "登出", path = "/logout", requiredPermission = false)
+ public ResponseData logoutPage() {
+ authServiceApi.logout();
+ return new SuccessResponseData();
+ }
+
+ /**
+ * 用户登陆并返回详情
+ *
+ * @author fengshuonan
+ * @date 2021/3/17 17:24
+ */
+ @PostResource(name = "用户登陆并返回详情", path = "/loginWithDetail", requiredLogin = false, requiredPermission = false)
+ public ResponseData loginWithDetail(@RequestBody @Validated LoginRequest loginRequest) {
+ LoginResponse loginResponse = authServiceApi.login(loginRequest);
+ LoginDetailsResponse loginDetail = LoginResponseFactory.createLoginDetail(loginResponse);
+ return new SuccessResponseData(loginDetail);
+ }
+
+ /**
+ * 获取当前用户的用户信息
+ *
+ * @author fengshuonan
+ * @date 2021/3/17 17:37
+ */
+ @GetResource(name = "获取当前用户的用户信息", path = "/getCurrentLoginUserInfo", requiredPermission = false)
+ public ResponseData getCurrentLoginUserInfo() {
+ LoginUser loginUser = LoginContext.me().getLoginUser();
+ return new SuccessResponseData(loginUser);
+ }
+
+}
diff --git a/kernel-s-system/system-business-user/src/main/java/cn/stylefeng/roses/kernel/system/modular/user/factory/LoginResponseFactory.java b/kernel-s-system/system-business-user/src/main/java/cn/stylefeng/roses/kernel/system/modular/user/factory/LoginResponseFactory.java
new file mode 100644
index 000000000..42b82ee8b
--- /dev/null
+++ b/kernel-s-system/system-business-user/src/main/java/cn/stylefeng/roses/kernel/system/modular/user/factory/LoginResponseFactory.java
@@ -0,0 +1,81 @@
+package cn.stylefeng.roses.kernel.system.modular.user.factory;
+
+import cn.hutool.extra.spring.SpringUtil;
+import cn.stylefeng.roses.kernel.auth.api.pojo.auth.LoginResponse;
+import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
+import cn.stylefeng.roses.kernel.auth.api.pojo.login.basic.SimpleRoleInfo;
+import cn.stylefeng.roses.kernel.auth.api.pojo.login.basic.SimpleUserInfo;
+import cn.stylefeng.roses.kernel.system.api.pojo.login.LoginDetailsResponse;
+import cn.stylefeng.roses.kernel.system.api.pojo.login.details.SimpleAuthDetail;
+import cn.stylefeng.roses.kernel.system.api.pojo.login.details.SimpleUserDetail;
+import cn.stylefeng.roses.kernel.system.modular.user.service.SysUserService;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 登录返回结果组装
+ *
+ * @author fengshuonan
+ * @date 2021/1/7 17:11
+ */
+public class LoginResponseFactory {
+
+ /**
+ * 用于登录接口的返回值创建
+ *
+ * @author fengshuonan
+ * @date 2021/1/7 17:12
+ */
+ public static LoginDetailsResponse createLoginDetail(LoginResponse loginResponse) {
+
+ SysUserService sysUserService = SpringUtil.getBean(SysUserService.class);
+
+ LoginDetailsResponse loginDetailsResponse = new LoginDetailsResponse();
+
+ // 获取用户详细信息
+ LoginUser loginUser = loginResponse.getLoginUser();
+ SimpleUserInfo simpleUserInfo = loginUser.getSimpleUserInfo();
+
+ // 获取用户角色信息
+ List simpleRoleInfoList = loginUser.getSimpleRoleInfoList();
+
+ // 组装token和过期时间
+ loginDetailsResponse.setToken(loginResponse.getToken());
+ loginDetailsResponse.setExpireAt(loginResponse.getExpireAt());
+
+ // 组装用户信息
+ SimpleUserDetail simpleUserDetail = new SimpleUserDetail();
+ simpleUserDetail.setUserId(loginUser.getUserId());
+ simpleUserDetail.setName(simpleUserInfo.getRealName());
+
+ // todo 地址信息
+ simpleUserDetail.setAddress("北京市");
+ simpleUserDetail.setPosition("总经理");
+
+ // 设置头像,并获取头像的url
+ Long avatarFileId = loginResponse.getLoginUser().getSimpleUserInfo().getAvatar();
+ String userAvatarUrl = sysUserService.getUserAvatarUrl(avatarFileId, loginResponse.getToken());
+
+ simpleUserDetail.setAvatar(userAvatarUrl);
+ loginDetailsResponse.setUser(simpleUserDetail);
+
+ // 组装权限
+ ArrayList authInfos = new ArrayList<>();
+ for (SimpleRoleInfo simpleRoleInfo : simpleRoleInfoList) {
+ SimpleAuthDetail simpleAuthDetail = new SimpleAuthDetail();
+ simpleAuthDetail.setId(simpleRoleInfo.getRoleCode());
+ // todo 没有按钮信息
+ simpleAuthDetail.setOperation(null);
+ authInfos.add(simpleAuthDetail);
+ }
+ loginDetailsResponse.setPermissions(authInfos);
+ loginDetailsResponse.setRoles(authInfos);
+
+ // 登录人的ws-url
+ loginDetailsResponse.setWsUrl(loginUser.getWsUrl());
+
+ return loginDetailsResponse;
+ }
+
+}
diff --git a/kernel-s-system/system-spring-boot-starter/pom.xml b/kernel-s-system/system-spring-boot-starter/pom.xml
index 02dd12a07..053dc4eb3 100644
--- a/kernel-s-system/system-spring-boot-starter/pom.xml
+++ b/kernel-s-system/system-spring-boot-starter/pom.xml
@@ -72,13 +72,6 @@
7.0.2
-
-
- cn.stylefeng.roses
- log-business-login-log
- 7.0.2
-
-
diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/system/starter/init/InitAdminService.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/system/starter/init/InitAdminService.java
new file mode 100644
index 000000000..471896bc8
--- /dev/null
+++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/system/starter/init/InitAdminService.java
@@ -0,0 +1,71 @@
+package cn.stylefeng.roses.kernel.system.starter.init;
+
+import cn.stylefeng.roses.kernel.system.api.constants.SystemConstants;
+import cn.stylefeng.roses.kernel.system.modular.resource.entity.SysResource;
+import cn.stylefeng.roses.kernel.system.modular.resource.service.SysResourceService;
+import cn.stylefeng.roses.kernel.system.modular.role.entity.SysRole;
+import cn.stylefeng.roses.kernel.system.modular.role.entity.SysRoleResource;
+import cn.stylefeng.roses.kernel.system.modular.role.service.SysRoleResourceService;
+import cn.stylefeng.roses.kernel.system.modular.role.service.SysRoleService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 初始化admin管理员的服务
+ *
+ * @author fengshuonan
+ * @date 2020/12/17 21:56
+ */
+@Service
+public class InitAdminService {
+
+ @Resource
+ private SysRoleService sysRoleService;
+
+ @Resource
+ private SysResourceService sysResourceService;
+
+ @Resource
+ private SysRoleResourceService sysRoleResourceService;
+
+ /**
+ * 初始化超级管理员,超级管理员拥有最高权限
+ *
+ * @author fengshuonan
+ * @date 2020/12/17 21:57
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public void initSuperAdmin() {
+
+ // 找到超级管理员的角色id
+ LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
+ queryWrapper.eq(SysRole::getRoleCode, SystemConstants.SUPER_ADMIN_ROLE_CODE);
+ SysRole superAdminRole = sysRoleService.getOne(queryWrapper);
+
+ // 删除这个角色绑定的所有资源
+ LambdaUpdateWrapper sysRoleResourceLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
+ sysRoleResourceLambdaUpdateWrapper.eq(SysRoleResource::getRoleId, superAdminRole.getRoleId());
+ sysRoleResourceService.remove(sysRoleResourceLambdaUpdateWrapper);
+
+ // 找到所有Resource,将所有资源赋给这个角色
+ LambdaQueryWrapper sysResourceLambdaQueryWrapper = new LambdaQueryWrapper<>();
+ sysResourceLambdaQueryWrapper.select(SysResource::getResourceCode);
+ List resources = sysResourceService.list(sysResourceLambdaQueryWrapper);
+
+ ArrayList sysRoleResources = new ArrayList<>();
+ for (SysResource resource : resources) {
+ SysRoleResource sysRoleResource = new SysRoleResource();
+ sysRoleResource.setResourceCode(resource.getResourceCode());
+ sysRoleResource.setRoleId(superAdminRole.getRoleId());
+ sysRoleResources.add(sysRoleResource);
+ }
+ sysRoleResourceService.saveBatch(sysRoleResources, sysRoleResources.size());
+ }
+
+}
diff --git a/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/system/starter/listener/SuperAdminInitListener.java b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/system/starter/listener/SuperAdminInitListener.java
new file mode 100644
index 000000000..bf6d4fbb4
--- /dev/null
+++ b/kernel-s-system/system-spring-boot-starter/src/main/java/cn/stylefeng/roses/kernel/system/starter/listener/SuperAdminInitListener.java
@@ -0,0 +1,36 @@
+package cn.stylefeng.roses.kernel.system.starter.listener;
+
+import cn.stylefeng.roses.kernel.system.api.constants.SystemConstants;
+import cn.stylefeng.roses.kernel.system.starter.init.InitAdminService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.core.Ordered;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * 项目启动后初始化超级管理员
+ *
+ * @author fengshuonan
+ * @date 2020/12/17 21:44
+ */
+@Component
+@Slf4j
+public class SuperAdminInitListener implements ApplicationListener, Ordered {
+
+ @Resource
+ private InitAdminService initAdminService;
+
+ @Override
+ public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
+ initAdminService.initSuperAdmin();
+ }
+
+ @Override
+ public int getOrder() {
+ return SystemConstants.SUPER_ADMIN_INIT_LISTENER_SORT;
+ }
+
+}