2021与蓝度共同重构项目,服务端
liuhaonan
2022-01-18 9f4c4e77bd7936645d174f21a6abf8951b533e8d
Merge remote-tracking branch 'origin/master'

# Conflicts:
# ximon-admin/src/main/java/com/sandu/ximon/admin/controller/AdminController.java
# ximon-admin/src/main/java/com/sandu/ximon/admin/controller/MenuController.java
# ximon-admin/src/main/java/com/sandu/ximon/admin/security/SecurityUtils.java
# ximon-admin/src/main/java/com/sandu/ximon/admin/service/MenuService.java
已添加6个文件
已修改10个文件
679 ■■■■ 文件已修改
dao/src/main/java/com/sandu/ximon/dao/domain/RoleDetail.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/mapper/RoleMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/resources/mapper/RoleMapper.xml 41 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/enums/RoleLevelStatus.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/AdminController.java 124 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/MenuController.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/RoleController.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/AdminParam.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PwdParam.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/param/RoleParam.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/security/PermissionConfig.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/security/SecurityUtils.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/AdminService.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/MenuService.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/RoleMenuRelationService.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/service/RoleService.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
dao/src/main/java/com/sandu/ximon/dao/domain/RoleDetail.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,13 @@
package com.sandu.ximon.dao.domain;
import lombok.Data;
import java.util.List;
@Data
public class RoleDetail extends Role {
    private List<Long> menuIdList;
}
dao/src/main/java/com/sandu/ximon/dao/mapper/RoleMapper.java
@@ -2,7 +2,10 @@
import com.sandu.ximon.dao.domain.Role;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sandu.ximon.dao.domain.RoleDetail;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * @Entity com.sandu.ximon.dao.domain.Role
@@ -10,6 +13,7 @@
@Mapper
public interface RoleMapper extends BaseMapper<Role> {
    List<RoleDetail> listRole(List<Long> roleIdList);
}
dao/src/main/resources/mapper/RoleMapper.xml
@@ -5,18 +5,35 @@
<mapper namespace="com.sandu.ximon.dao.mapper.RoleMapper">
    <resultMap id="BaseResultMap" type="com.sandu.ximon.dao.domain.Role">
            <id property="id" column="id" jdbcType="BIGINT"/>
            <result property="name" column="name" jdbcType="VARCHAR"/>
            <result property="remark" column="remark" jdbcType="VARCHAR"/>
            <result property="level" column="level" jdbcType="INTEGER"/>
            <result property="permission" column="permission" jdbcType="VARCHAR"/>
            <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
        <id property="id" column="id" jdbcType="BIGINT"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="remark" column="remark" jdbcType="VARCHAR"/>
        <result property="level" column="level" jdbcType="INTEGER"/>
        <result property="permission" column="permission" jdbcType="VARCHAR"/>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
        <result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
    </resultMap>
    <sql id="Base_Column_List">
        id,name,remark,
        level,permission,create_time,
        update_time
    </sql>
    <resultMap id="RoleDetail" type="com.sandu.ximon.dao.domain.RoleDetail" extends="BaseResultMap">
        <collection property="menuIdList" columnPrefix="menu_" ofType="java.lang.Long">
            <constructor>
                <arg column="menu_id" javaType="long"/>
            </constructor>
        </collection>
    </resultMap>
    <select id="listRole" resultMap="RoleDetail">
        SELECT t1.*,
               t2.menu_id AS menu_menu_id
        FROM role t1
        LEFT JOIN role_menu_relation t2 ON t1.id = t2.role_id
        <where>
            t1.id IN
            <foreach collection="roleIdList" separator="," item="roleId" open="(" close=")">
                #{roleId}
            </foreach>
        </where>
    </select>
</mapper>
sandu-common/src/main/java/com/sandu/common/enums/RoleLevelStatus.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,29 @@
package com.sandu.common.enums;
/**
 * @author chenjiantian
 */
public enum RoleLevelStatus {
    /**
     *
     */
    SUPER(1, "超级管理员"),
    COMMON(2, "普通管理员"),
    ;
    private final Integer code;
    private final String message;
    RoleLevelStatus(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
    public Integer getCode() {
        return code;
    }
    public String getMessage() {
        return message;
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/AdminController.java
@@ -7,8 +7,8 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.sandu.common.domain.ResponseVO;
import com.sandu.common.enums.AdminStatusStatus;
import com.sandu.common.enums.ResponseStatusEnums;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.security.LoginUserInfo;
import com.sandu.common.security.annotation.AnonymousAccess;
@@ -16,8 +16,9 @@
import com.sandu.common.security.token.TokenProvider;
import com.sandu.common.util.IpUtil;
import com.sandu.common.util.ResponseUtil;
import com.sandu.ximon.admin.dto.AdminJwtUser;
import com.sandu.ximon.admin.param.AdminLoginParam;
import com.sandu.ximon.admin.param.AdminParam;
import com.sandu.ximon.admin.param.PwdParam;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.admin.service.AdminService;
import com.sandu.ximon.admin.service.MenuService;
@@ -28,21 +29,22 @@
import com.sandu.ximon.dao.enums.AdministratorEnums;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
 * @author hupeng
 * @date 2018-11-23
 * æŽˆæƒã€æ ¹æ®token获取用户详细信息
 * @author chenjiantian
 * @date 2022/1/18 16:04
 * ç®¡ç†å‘˜æŽ§åˆ¶ç±»
 */
@Slf4j
@RestController
@@ -68,10 +70,11 @@
        if (!passwordEncoder.matches(loginParam.getPassword(), admin.getPassword())) {
            return ResponseUtil.error(ResponseStatusEnums.BAD_CREDENTIALS.getCode(), ResponseStatusEnums.BAD_CREDENTIALS.getMessage());
        }
        UserDetails userJwtUser = new AdminJwtUser(admin, roleService.mapToGrantedAuthorities(admin.getId()));
        if (!userJwtUser.isEnabled()) {
        if (AdminStatusStatus.DISABLE.getCode().equals(admin.getStatus())) {
            return ResponseUtil.error(ResponseStatusEnums.DISABLE_ACCOUNT.getCode(), ResponseStatusEnums.DISABLE_ACCOUNT.getMessage());
        }
        Collection<GrantedAuthority> grantedAuthorities = roleService.mapToGrantedAuthorities(admin.getId());
        LoginUserInfo loginUserInfo = new LoginUserInfo();
        loginUserInfo.setUserId(admin.getId());
@@ -80,8 +83,7 @@
        loginUserInfo.setStatus(admin.getStatus());
        loginUserInfo.setIp(IpUtil.getRealIp());
        loginUserInfo.setAdministratorType(AdministratorEnums.ADMIN.getCode());
        loginUserInfo.setPermission("tenant");
        loginUserInfo.setPermission(grantedAuthorities.stream().map(GrantedAuthority::getAuthority).collect(Collectors.joining(",")));
        // ç”Ÿæˆä»¤ç‰Œ
        String token = tokenProvider.createToken(loginUserInfo);
@@ -105,7 +107,7 @@
        Long userId = SecurityUtils.getUserId();
        Admin admin = adminService.getById(userId);
        List<Role> roles = roleService.listByAdminId(admin.getId());
        if(CollectionUtil.isEmpty(roles)){
        if (CollectionUtil.isEmpty(roles)) {
            return ResponseUtil.fail("用户没有角色,无法获取数据");
        }
        List<Menu> menus = menuService.listByRoleIds(roles.stream().map(Role::getId).collect(Collectors.toList()));
@@ -131,33 +133,43 @@
        return ResponseUtil.successPage(list);
    }
//    @PreAuthorize("@el.check('admin:add')")
//    @PostMapping("/register")
//    public ResponseVO<Object> register(@Validated @RequestBody AdminParam adminParam) {
//        Admin admin = adminService.register(adminParam);
//        return ResponseUtil.success(admin);
//    }
    @PostMapping("/register")
    public ResponseVO<Object> register(@Validated @RequestBody AdminParam param) {
        boolean result = adminService.register(param);
        if (result) {
            return ResponseUtil.success("注册用户成功");
        } else {
            return ResponseUtil.fail("注册用户失败");
        }
    }
//    /**
//     * ä¿®æ”¹ç®¡ç†å‘˜ä¿¡æ¯
//     *
//     * @param resources
//     * @return
//     */
//    @PutMapping("/{id}")
//    @PreAuthorize("@el.check('admin:edit')")
//    public ResponseVO<Object> update(@RequestBody AdminParam resources, @PathVariable Long id) {
//        checkLevel(id);
//        adminService.updateAdmin(id, resources);
//        return ResponseUtil.success(null);
//    }
//
//    @PutMapping("/updatePassword")
//    public ResponseVO<Object> updatePassword(@Validated @RequestBody PwdParam param) {
//        Long userId = SecurityUtils.getUserId();
//        adminService.updatePassword(userId, param);
//        return ResponseUtil.success(null);
//    }
    /**
     * ä¿®æ”¹ç®¡ç†å‘˜ä¿¡æ¯
     */
    @PostMapping("/update/{adminId}")
    public ResponseVO<Object> updateAdmin(@RequestBody AdminParam param, @PathVariable Long adminId) {
        boolean result = adminService.updateAdmin(adminId, param);
        if (result) {
            return ResponseUtil.success("修改成功");
        } else {
            return ResponseUtil.fail("修改失败");
        }
    }
    /**
     * ä¿®æ”¹æˆ‘的密码
     */
    @PutMapping("/updateMyPassword")
    public ResponseVO<Object> updateMyPassword(@Validated @RequestBody PwdParam param) {
        boolean result = adminService.updateMyPassword(param);
        if (result) {
            return ResponseUtil.success("修改成功");
        } else {
            return ResponseUtil.fail("修改失败");
        }
    }
//    @PutMapping("/updateStatus/{id}")
//    public ResponseVO<Object> updateStatus(@PathVariable Long id, @RequestParam(value = "status") Integer status) {
@@ -169,13 +181,15 @@
//        return ResponseUtil.success(null);
//    }
//    @DeleteMapping("/{id}")
//    @PreAuthorize("@el.check('admin:del')")
//    public ResponseVO<Object> delete(@PathVariable Long id) {
//        checkLevel(id);
//        adminService.deleteAdmin(id);
//        return ResponseUtil.success(null);
//    }
    @PostMapping("/del/{adminId}")
    public ResponseVO<Object> deleteAdmin(@PathVariable Long adminId) {
        boolean result = adminService.deleteAdmin(adminId);
        if (result) {
            return ResponseUtil.success("修改成功");
        } else {
            return ResponseUtil.fail("修改失败");
        }
    }
//    /**
//     * ç»™ç®¡ç†å‘˜åˆ†é…è§’色
@@ -191,28 +205,6 @@
//        return ResponseUtil.success("");
//    }
    /**
     * å¦‚果当前用户的角色级别低于创建用户的角色级别,则抛出权限不足的错误
     *
     * @param updateId è¢«æ“ä½œäººçš„id
     */
    private void checkLevel(Long updateId) {
        Admin admin = adminService.findByUserName(SecurityUtils.getUsername());
        // èŽ·å–æ“ä½œè€…æœ€å¤§æƒé™
        Integer currentLevel = Collections.min(roleService.listByAdminId(admin.getId()).stream().map(Role::getLevel).collect(Collectors.toList()));
        // èŽ·å–è¢«ç¼–è¾‘äººçš„æœ€å¤§æƒé™
        List<Integer> optList = roleService.listByAdminId(updateId).stream().map(Role::getLevel).collect(Collectors.toList());
        // æ²¡æƒé™ éšä¾¿æ“ä½œ
        if (CollectionUtil.isEmpty(optList)) {
            return;
        }
        Integer optLevel = Collections.min(optList);
        if (optLevel != null) {
            if (currentLevel > optLevel) {
                throw new BusinessException("权限不足,你的角色级别:" + currentLevel + ",低于操作的角色级别:" + optLevel);
            }
        }
    }
//    /**
//     * ç¼–辑我的信息
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/MenuController.java
@@ -41,13 +41,24 @@
        boolean result = menuService.updateMenu(menuId,param);
        if (result) {
            return ResponseUtil.success("添加成功");
            return ResponseUtil.success("编辑成功");
        } else {
            return ResponseUtil.fail("添加失败");
            return ResponseUtil.fail("编辑失败");
        }
    }
    @PostMapping
    @PostMapping("/del/{menuId}")
    public ResponseVO<Object> delMenu(@PathVariable Long menuId) {
        boolean result = menuService.delMenu(menuId);
        if (result) {
            return ResponseUtil.success("删除成功");
        } else {
            return ResponseUtil.fail("删除失败");
        }
    }
    @PostMapping("/add")
    public ResponseVO<Object> addMenu(@Validated @RequestBody MenuParam param) {
        boolean result = menuService.addMenu(param);
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/RoleController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,74 @@
package com.sandu.ximon.admin.controller;
import com.github.pagehelper.PageHelper;
import com.sandu.common.domain.ResponseVO;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.util.ResponseUtil;
import com.sandu.ximon.admin.param.RoleParam;
import com.sandu.ximon.admin.service.RoleService;
import com.sandu.ximon.dao.domain.Role;
import com.sandu.ximon.dao.domain.RoleDetail;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
 * @author chenjiantian
 * @date 2021/4/27 18:47
 */
@AllArgsConstructor
@RestController
@RequestMapping("/v1/role")
public class RoleController {
    private final RoleService roleService;
    /**
     * èŽ·å–ç®¡ç†å‘˜çš„è§’è‰²
     */
    @GetMapping("/getRoleListByAdmin/{adminId}")
    public ResponseVO<Object> getRoleListByAdmin(@PathVariable Long adminId) {
        List<Role> roles = roleService.listByAdminId(adminId);
        return ResponseUtil.success(roles);
    }
    @GetMapping("/list")
    public ResponseVO<Object> listRole(BaseConditionVO conditionVO) {
        List<RoleDetail> roleDetails = roleService.listRole(conditionVO.getPageNo(), conditionVO.getPageSize());
        return ResponseUtil.success(roleDetails);
    }
    @PostMapping("/add")
    public ResponseVO<Object> addRole(@Validated @RequestBody RoleParam param) {
        boolean result = roleService.addRole(param);
        if (result) {
            return ResponseUtil.success("添加成功");
        } else {
            return ResponseUtil.success("添加失败");
        }
    }
    @PostMapping("/update/{roleId}")
    public ResponseVO<Object> updateRole(@PathVariable Long roleId, @Validated @RequestBody RoleParam param) {
        boolean result = roleService.updateRole(roleId, param);
        if (result) {
            return ResponseUtil.success("编辑成功");
        } else {
            return ResponseUtil.success("编辑失败");
        }
    }
    @PostMapping("/del/{roleId}")
    public ResponseVO<Object> delRole(@PathVariable Long roleId) {
        boolean result = roleService.delRole(roleId);
        if (result) {
            return ResponseUtil.success("删除成功");
        } else {
            return ResponseUtil.success("删除失败");
        }
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/param/AdminParam.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,26 @@
package com.sandu.ximon.admin.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
 * @author chenjiantian
 * @date 2022/1/18 15:56
 */
@Data
public class AdminParam {
    @NotBlank(message = "账号不能为空")
    private String username;
    @NotBlank(message = "密码不能为空")
    private String password;
    private String mobile;
    @NotBlank(message = "用户名不能为空")
    private String nickName;
    private String note;
    @NotNull(message = "角色id不能为空")
    private Long roleId;
}
ximon-admin/src/main/java/com/sandu/ximon/admin/param/PwdParam.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package com.sandu.ximon.admin.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.Size;
/**
 * @author chenjiantian
 * @date 2022/1/18 16:21
 */
@Data
public class PwdParam {
    @NotBlank(message = "旧密码不能为空")
    private String oldPass;
    @NotBlank(message = "新密码不能为空")
    @Size(min = 6,message = "密码最短必须是6位")
    private String newPass;
    @NotBlank(message = "确认密码不能为空")
    @Size(min = 6,message = "密码最短必须是6位")
    private String confirmPass;
}
ximon-admin/src/main/java/com/sandu/ximon/admin/param/RoleParam.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,28 @@
package com.sandu.ximon.admin.param;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
/**
 * @author chenjiantian
 * @date 2022/1/18 11:38
 */
@Data
public class RoleParam {
    /**
     * åç§°
     */
    @NotBlank(message = "角色名称不能为空")
    private String name;
    /**
     * å¤‡æ³¨
     */
    private String remark;
    private List<Long> menuIdList;
}
ximon-admin/src/main/java/com/sandu/ximon/admin/security/PermissionConfig.java
@@ -1,5 +1,7 @@
package com.sandu.ximon.admin.security;
import com.sandu.common.security.LoginUserInfo;
import com.sandu.ximon.dao.enums.AdministratorEnums;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
@@ -12,14 +14,22 @@
 * @date 2021/8/27 18:28
 * æƒé™æŽ§åˆ¶
 */
@Service(value = "p")
@Service(value = "el")
public class PermissionConfig {
//    public Boolean check(String... permissions) {
//
//        // èŽ·å–å½“å‰ç”¨æˆ·çš„æ‰€æœ‰æƒé™
//        List<String> elPermissions = SecurityUtils.getUserDetails().getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
//        // åˆ¤æ–­å½“前用户的所有权限是否包含接口上定义的权限
//        return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
//    }
    public Boolean check(String... permissions) {
        LoginUserInfo loginUserInfo = SecurityUtils.getUserDetails();
        if (loginUserInfo == null || loginUserInfo.getPermission() == null) {
            return false;
        }
        // å®¢æˆ·æ²¡æœ‰æƒé™ç®¡ç†
        if(AdministratorEnums.CUSTOMER.getCode().equals(loginUserInfo.getAdministratorType())){
            return true;
        }
        String[] split = loginUserInfo.getPermission().split(",");
        // èŽ·å–å½“å‰ç”¨æˆ·çš„æ‰€æœ‰æƒé™
        List<String> elPermissions = Arrays.stream(split).collect(Collectors.toList());
        // åˆ¤æ–­å½“前用户的所有权限是否包含接口上定义的权限
        return elPermissions.contains("admin") || Arrays.stream(permissions).anyMatch(elPermissions::contains);
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/security/SecurityUtils.java
@@ -18,7 +18,7 @@
    /**
     * èŽ·å–å½“å‰ç™»å½•ç”¨æˆ·ä¿¡æ¯
     */
    private static LoginUserInfo getUserDetails() {
    public static LoginUserInfo getUserDetails() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
            throw new BusinessException(ResponseStatusEnums.TOKEN_INVALID.getCode(), ResponseStatusEnums.TOKEN_INVALID.getMessage());
ximon-admin/src/main/java/com/sandu/ximon/admin/service/AdminService.java
@@ -1,18 +1,145 @@
package com.sandu.ximon.admin.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sandu.common.enums.RoleLevelStatus;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.ximon.admin.param.AdminParam;
import com.sandu.ximon.admin.param.PwdParam;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.dao.domain.Admin;
import com.sandu.ximon.dao.domain.AdminRoleRelation;
import com.sandu.ximon.dao.domain.Role;
import com.sandu.ximon.dao.mapper.AdminMapper;
import lombok.AllArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author chenjiantian
 * @date 2021/11/24 11:02
 */
@Service
@AllArgsConstructor
public class AdminService extends BaseServiceImpl<AdminMapper, Admin> {
    private final PasswordEncoder passwordEncoder;
    private final AdminRoleRelationService adminRoleRelationService;
    private final RoleService roleService;
    public Admin findByUserName(String username) {
        return getOne(Wrappers.lambdaQuery(Admin.class).eq(Admin::getUsername, username).last("limit 1"));
    }
    @Transactional(rollbackFor = Exception.class)
    public boolean register(AdminParam param) {
        Admin admin = findByUserName(param.getUsername());
        if (admin != null) {
            throw new BusinessException("当前账号" + param.getUsername() + "已经存在");
        }
        Admin save = new Admin();
        save.setUsername(param.getUsername());
        save.setPassword(passwordEncoder.encode(param.getPassword()));
        save.setNickName(param.getNickName());
        save.setMobile(param.getMobile());
        save.setNote(param.getNote());
        if (!save(save)) {
            throw new BusinessException("注册管理员失败");
        }
        Role role = roleService.getById(param.getRoleId());
        if (role == null) {
            throw new BusinessException("角色不存在");
        }
        if (RoleLevelStatus.SUPER.getCode().equals(role.getLevel())) {
            throw new BusinessException("无法添加超级管理员");
        }
        AdminRoleRelation adminRoleRelation = new AdminRoleRelation();
        adminRoleRelation.setAdminId(save.getId());
        adminRoleRelation.setRoleId(param.getRoleId());
        if (!adminRoleRelationService.save(adminRoleRelation)) {
            throw new BusinessException("添加管理员角色失败");
        }
        return true;
    }
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAdmin(Long adminId, AdminParam param) {
        Admin admin = getById(adminId);
        if (admin == null) {
            throw new BusinessException("找不到管理员");
        }
        List<Role> roles = roleService.listByAdminId(admin.getId());
        if (CollectionUtil.isEmpty(roles)) {
            throw new BusinessException("当前用户没有角色");
        }
        List<Integer> levels = roles.stream().map(Role::getLevel).collect(Collectors.toList());
        int min = Collections.min(levels);
        roleService.assertLevels(min);
        Admin update = new Admin();
        update.setId(adminId);
        update.setPassword(passwordEncoder.encode(param.getPassword()));
        update.setNickName(param.getNickName());
        update.setMobile(param.getMobile());
        update.setNote(param.getNote());
        if (!updateById(update)) {
            throw new BusinessException("编辑管理员失败");
        }
        adminRoleRelationService.remove(Wrappers.lambdaQuery(AdminRoleRelation.class).eq(AdminRoleRelation::getAdminId,admin));
        AdminRoleRelation adminRoleRelation = new AdminRoleRelation();
        adminRoleRelation.setAdminId(adminId);
        adminRoleRelation.setRoleId(param.getRoleId());
        if (!adminRoleRelationService.save(adminRoleRelation)) {
            throw new BusinessException("添加管理员角色失败");
        }
        return true;
    }
    public boolean updateMyPassword(PwdParam param) {
        if (!StrUtil.equals(param.getNewPass(), param.getConfirmPass())) {
            throw new BusinessException("两次密码不一致");
        }
        Long userId = SecurityUtils.getUserId();
        Admin admin = getById(userId);
        if (admin == null) {
            throw new BusinessException("用户不存在");
        }
        if (!passwordEncoder.matches(param.getOldPass(), admin.getPassword())) {
            throw new BusinessException("旧密码不正确");
        }
        Admin update = new Admin();
        update.setId(userId);
        update.setPassword(passwordEncoder.encode(param.getNewPass()));
        return updateById(update);
    }
    public boolean deleteAdmin(Long adminId) {
        Admin admin = getById(adminId);
        if (admin == null) {
            throw new BusinessException("找不到管理员");
        }
        List<Role> roles = roleService.listByAdminId(admin.getId());
        if (CollectionUtil.isEmpty(roles)) {
            throw new BusinessException("当前用户没有角色");
        }
        List<Integer> levels = roles.stream().map(Role::getLevel).collect(Collectors.toList());
        int min = Collections.min(levels);
        int maxLevel = roleService.assertLevels(min);
        if(!RoleLevelStatus.SUPER.getCode().equals(maxLevel)){
            throw new BusinessException("只有超级管理员才能删除用户");
        }
        return removeById(adminId);
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/service/MenuService.java
@@ -3,13 +3,17 @@
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sandu.common.enums.RoleLevelStatus;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.execption.EntityExistException;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.common.util.SpringContextHolder;
import com.sandu.ximon.admin.param.MenuParam;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.dao.bo.MenuNode;
import com.sandu.ximon.dao.domain.AdminRoleRelation;
import com.sandu.ximon.dao.domain.Menu;
import com.sandu.ximon.dao.domain.Role;
import com.sandu.ximon.dao.domain.RoleMenuRelation;
import com.sandu.ximon.dao.mapper.AdminRoleRelationMapper;
import com.sandu.ximon.dao.mapper.MenuMapper;
@@ -17,6 +21,7 @@
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -79,6 +84,12 @@
            throw new BusinessException("找不到菜单信息");
        }
        List<Role> roles = SpringContextHolder.getBean(RoleService.class).listByAdminId(SecurityUtils.getUserId());
        Integer roleLevel = roles.stream().map(Role::getLevel).min(Integer::compareTo).orElse(RoleLevelStatus.COMMON.getCode());
        if(!RoleLevelStatus.SUPER.getCode().equals(roleLevel)){
            throw new BusinessException("超级管理员才可以编辑菜单");
        }
        Menu menu = new Menu();
        BeanUtils.copyProperties(param,menu);
        menu.setId(menuId);
@@ -91,4 +102,18 @@
                .filter(menu -> menu.getPid().equals(0L))
                .map(menu -> covertMenuNode(menu, list)).collect(Collectors.toList());
    }
    public boolean delMenu(Long menuId) {
        Menu one = getById(menuId);
        if (one == null) {
            throw new BusinessException("找不到菜单信息");
        }
        List<Role> roles = SpringContextHolder.getBean(RoleService.class).listByAdminId(SecurityUtils.getUserId());
        Integer roleLevel = roles.stream().map(Role::getLevel).min(Integer::compareTo).orElse(RoleLevelStatus.COMMON.getCode());
        if(!RoleLevelStatus.SUPER.getCode().equals(roleLevel)){
            throw new BusinessException("超级管理员才可以删除菜单");
        }
        return removeById(menuId);
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/service/RoleMenuRelationService.java
@@ -1,9 +1,14 @@
package com.sandu.ximon.admin.service;
import cn.hutool.core.collection.CollectionUtil;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.ximon.dao.domain.RoleMenuRelation;
import com.sandu.ximon.dao.mapper.RoleMenuRelationMapper;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
 * @author chenjiantian
@@ -11,4 +16,20 @@
 */
@Service
public class RoleMenuRelationService extends BaseServiceImpl<RoleMenuRelationMapper, RoleMenuRelation> {
    public boolean addRoleMenuList(Long roleId, List<Long> menuIdList) {
        if (CollectionUtil.isNotEmpty(menuIdList)) {
            List<RoleMenuRelation> roleMenuRelationList = new ArrayList<>();
            for (Long menuId : menuIdList) {
                RoleMenuRelation roleMenuRelation = new RoleMenuRelation();
                roleMenuRelation.setMenuId(menuId);
                roleMenuRelation.setRoleId(roleId);
                roleMenuRelationList.add(roleMenuRelation);
            }
            if (!saveBatch(roleMenuRelationList)) {
                throw new BusinessException("编辑角色菜单失败");
            }
        }
        return true;
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/service/RoleService.java
@@ -3,22 +3,23 @@
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageHelper;
import com.sandu.common.enums.RoleLevelStatus;
import com.sandu.common.execption.BusinessException;
import com.sandu.common.execption.EntityExistException;
import com.sandu.common.service.impl.BaseServiceImpl;
import com.sandu.ximon.dao.domain.AdminRoleRelation;
import com.sandu.ximon.dao.domain.Menu;
import com.sandu.ximon.dao.domain.Role;
import com.sandu.ximon.dao.domain.RoleMenuRelation;
import com.sandu.common.util.BeanConvertUtil;
import com.sandu.ximon.admin.param.RoleParam;
import com.sandu.ximon.admin.security.SecurityUtils;
import com.sandu.ximon.dao.domain.*;
import com.sandu.ximon.dao.mapper.RoleMapper;
import lombok.AllArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.stream.Collectors;
/**
@@ -73,8 +74,88 @@
        List<AdminRoleRelation> list = adminRoleRelationService.list(Wrappers.lambdaQuery(AdminRoleRelation.class).eq(AdminRoleRelation::getAdminId, adminId).select(AdminRoleRelation::getRoleId));
        List<Long> roleIdList = list.stream().map(AdminRoleRelation::getRoleId).collect(Collectors.toList());
        if (CollectionUtil.isEmpty(roleIdList)) {
            throw new BusinessException("当前用户没有角色");
            return null;
        }
        return listByIds(roleIdList);
    }
    @Transactional(rollbackFor = Exception.class)
    public boolean addRole(RoleParam param) {
        Role role = new Role();
        role.setName(param.getName());
        role.setRemark(param.getRemark());
        role.setLevel(RoleLevelStatus.COMMON.getCode());
        if(!save(role)){
            throw new BusinessException("添加角色失败");
        }
        roleMenuRelationService.addRoleMenuList(role.getId(),param.getMenuIdList());
        return true;
    }
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRole(Long roleId, RoleParam param) {
        Role role = getById(roleId);
        if (role == null) {
            throw new BusinessException("找不到角色信息");
        }
        assertLevels(role.getLevel());
        Role update = new Role();
        update.setId(roleId);
        update.setName(param.getName());
        update.setRemark(param.getRemark());
        if(!updateById(update)){
            throw new BusinessException("编辑角色失败");
        }
        roleMenuRelationService.remove(Wrappers.lambdaQuery(RoleMenuRelation.class).eq(RoleMenuRelation::getRoleId,roleId));
        roleMenuRelationService.addRoleMenuList(role.getId(),param.getMenuIdList());
        return true;
    }
    /**
     * åˆ¤æ–­å½“前角色能不能操作目标用户 ä¸è¡Œçš„话直接抛出异常
     * @param roleLevel ç›®æ ‡ç”¨æˆ·çš„æœ€é«˜è§’色等级
     * @return æ“ä½œäººçš„æœ€é«˜è§’色等级
     */
    public int assertLevels(Integer roleLevel) {
        Long userId = SecurityUtils.getUserId();
        List<Role> roles = listByAdminId(userId);
        if(CollectionUtil.isEmpty(roles)){
            throw new BusinessException("当前用户没有角色");
        }
        List<Integer> levels = roles.stream().map(Role::getLevel).collect(Collectors.toList());
        int min = Collections.min(levels);
        if (roleLevel != null) {
            if (roleLevel < min) {
                throw new BusinessException("权限不足,你的角色级别:" + min + ",低于操作的角色级别:" + roleLevel);
            }
        }
        return min;
    }
    public boolean delRole(Long roleId) {
        Role role = getById(roleId);
        if (role == null) {
            throw new BusinessException("找不到角色");
        }
        assertLevels(role.getLevel());
        List<AdminRoleRelation> list = adminRoleRelationService.list(Wrappers.lambdaQuery(AdminRoleRelation.class).eq(AdminRoleRelation::getRoleId, role));
        if(CollectionUtil.isNotEmpty(list)){
            throw new BusinessException("当前角色有管理员使用,无法删除");
        }
        roleMenuRelationService.remove(Wrappers.lambdaQuery(RoleMenuRelation.class).eq(RoleMenuRelation::getRoleId,roleId));
        return removeById(roleId);
    }
    public List<RoleDetail> listRole(int pageNo, int pageSize) {
        PageHelper.startPage(pageNo, pageSize);
        List<Long> roleIdList = list().stream().map(Role::getId).collect(Collectors.toList());
        if(CollectionUtil.isEmpty(roleIdList)){
            return null;
        }
        return baseMapper.listRole(roleIdList);
    }
}