Sfoglia il codice sorgente

!113 新建一个关联表,维护用户和岗位的关系
Merge pull request !113 from anzhen-tech/master

芋道源码 3 anni fa
parent
commit
7d87be8b7d

File diff suppressed because it is too large
+ 43 - 0
sql/ruoyi-vue-pro.sql


+ 35 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/UserPostDO.java

@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.module.system.dal.dataobject.dept;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 用户和岗位关联
+ *
+ * @author ruoyi
+ */
+@TableName("system_user_post")
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class UserPostDO extends BaseDO {
+
+    /**
+     * 自增主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 用户 ID
+     */
+    private Long userId;
+    /**
+     * 角色 ID
+     */
+    private Long postId;
+
+}

+ 34 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java

@@ -0,0 +1,34 @@
+package cn.iocoder.yudao.module.system.dal.mysql.dept;
+
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.Collection;
+import java.util.List;
+
+@Mapper
+public interface UserPostMapper extends BaseMapperX<UserPostDO> {
+
+    default List<UserPostDO> selectIdList(Long id) {
+        return selectList(new LambdaQueryWrapperX<UserPostDO>()
+                .eq(UserPostDO::getUserId, id));
+    }
+
+    default void deleteByUserIdAndPostId(Long userId, Collection<Long> postIds) {
+        delete(new LambdaQueryWrapperX<UserPostDO>()
+                .eq(UserPostDO::getUserId, userId)
+                .in(UserPostDO::getPostId, postIds));
+    }
+
+    default List<UserPostDO> selectListByPostIds(Collection<Long> postIds) {
+        return selectList(new LambdaQueryWrapperX<UserPostDO>()
+                .in(UserPostDO::getPostId, postIds));
+    }
+
+    default void deleteByUserId(Long userId){
+        delete(Wrappers.lambdaUpdate(UserPostDO.class).eq(UserPostDO::getUserId, userId));
+    }
+}

+ 94 - 18
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.system.service.user;
 
 import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
@@ -10,10 +11,17 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdatePasswordReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfileUpdateReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserCreateReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserExportReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportExcelVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserImportRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.UserUpdateReqVO;
 import cn.iocoder.yudao.module.system.convert.user.UserConvert;
 import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
+import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import cn.iocoder.yudao.module.system.service.dept.PostService;
@@ -28,14 +36,28 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.io.InputStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_COUNT_MAX;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_EMAIL_EXISTS;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IMPORT_LIST_IS_EMPTY;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_IS_DISABLE;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_MOBILE_EXISTS;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_NOT_EXISTS;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_PASSWORD_FAILED;
+import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.USER_USERNAME_EXISTS;
 
 /**
  * 后台用户 Service 实现类
- *
  * @author 芋道源码
  */
 @Service("adminUserService")
@@ -59,11 +81,14 @@ public class AdminUserServiceImpl implements AdminUserService {
     @Resource
     private TenantService tenantService;
 
+    @Resource
+    private UserPostMapper userPostMapper;
+
     @Resource
     private FileApi fileApi;
 
     @Override
-
+    @Transactional(rollbackFor = Exception.class)
     public Long createUser(UserCreateReqVO reqVO) {
         // 校验账户配合
         tenantService.handleTenantInfo(tenant -> {
@@ -74,23 +99,69 @@ public class AdminUserServiceImpl implements AdminUserService {
         });
         // 校验正确性
         this.checkCreateOrUpdate(null, reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
-            reqVO.getDeptId(), reqVO.getPostIds());
+                reqVO.getDeptId(), reqVO.getPostIds());
         // 插入用户
         AdminUserDO user = UserConvert.INSTANCE.convert(reqVO);
         user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
         user.setPassword(passwordEncoder.encode(reqVO.getPassword())); // 加密密码
         userMapper.insert(user);
+        Set<Long> postIds = user.getPostIds();
+        if (CollectionUtil.isNotEmpty(postIds)) {
+            List<UserPostDO> insertUserPostList = CollectionUtils.convertList(postIds, postId -> {
+                UserPostDO entity = new UserPostDO();
+                entity.setUserId(user.getId());
+                entity.setPostId(postId);
+                return entity;
+            });
+            userPostMapper.insertBatch(insertUserPostList);
+        }
         return user.getId();
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateUser(UserUpdateReqVO reqVO) {
         // 校验正确性
         this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
-            reqVO.getDeptId(), reqVO.getPostIds());
+                reqVO.getDeptId(), reqVO.getPostIds());
         // 更新用户
         AdminUserDO updateObj = UserConvert.INSTANCE.convert(reqVO);
         userMapper.updateById(updateObj);
+        // 更新岗位
+        updateUserPost(reqVO, updateObj);
+
+    }
+
+    private void updateUserPost(UserUpdateReqVO reqVO, AdminUserDO updateObj) {
+        Set<Long> postIds = updateObj.getPostIds();
+        Long userId = reqVO.getId();
+        List<Long> dbPostIds = userPostMapper.selectIdList(userId)
+                .stream()
+                .map(UserPostDO::getPostId)
+                .collect(Collectors.toList());
+        // 计算新增和删除的岗位编号
+        Collection<Long> createPostIds = CollUtil.subtract(postIds, dbPostIds);
+        Collection<Long> deletePostIds = CollUtil.subtract(dbPostIds, postIds);
+        // 执行新增和删除。对于已经授权的菜单,不用做任何处理
+        if (!CollectionUtil.isEmpty(createPostIds)) {
+            List<UserPostDO> list = createUserPost(userId, createPostIds);
+            userPostMapper.insertBatch(list);
+        }
+        if (!CollectionUtil.isEmpty(deletePostIds)) {
+            userPostMapper.deleteByUserIdAndPostId(userId, deletePostIds);
+        }
+    }
+
+    private List<UserPostDO> createUserPost(Long userId, Collection<Long> createPostIds) {
+        return createPostIds
+                .stream()
+                .map(postId -> {
+                    UserPostDO entity = new UserPostDO();
+                    entity.setUserId(userId);
+                    entity.setPostId(postId);
+                    return entity;
+                })
+                .collect(Collectors.toList());
     }
 
     @Override
@@ -154,6 +225,7 @@ public class AdminUserServiceImpl implements AdminUserService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void deleteUser(Long id) {
         // 校验用户存在
         this.checkUserExists(id);
@@ -161,6 +233,8 @@ public class AdminUserServiceImpl implements AdminUserService {
         userMapper.deleteById(id);
         // 删除用户关联数据
         permissionService.processUserDeleted(id);
+        // 删除用户岗位
+        userPostMapper.deleteByUserId(id);
     }
 
     @Override
@@ -191,11 +265,15 @@ public class AdminUserServiceImpl implements AdminUserService {
         if (CollUtil.isEmpty(postIds)) {
             return Collections.emptyList();
         }
-        // 过滤不符合条件的
-        // TODO 芋艿:暂时只能内存过滤。解决方案:1、新建一个关联表;2、基于 where + 函数;3、json 字段,适合 mysql 8+ 版本
-        List<AdminUserDO> users = userMapper.selectList();
-        users.removeIf(user -> !CollUtil.containsAny(user.getPostIds(), postIds));
-        return users;
+        List<Long> userIdList = userPostMapper.selectListByPostIds(postIds)
+                .stream()
+                .map(UserPostDO::getUserId)
+                .distinct()
+                .collect(Collectors.toList());;
+        if (userIdList.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return userMapper.selectBatchIds(userIdList);
     }
 
     @Override
@@ -243,7 +321,6 @@ public class AdminUserServiceImpl implements AdminUserService {
 
     /**
      * 获得部门条件:查询指定部门的子部门编号们,包括自身
-     *
      * @param deptId 部门编号
      * @return 部门编号集合
      */
@@ -252,7 +329,7 @@ public class AdminUserServiceImpl implements AdminUserService {
             return Collections.emptySet();
         }
         Set<Long> deptIds = CollectionUtils.convertSet(deptService.getDeptsByParentIdFromCache(
-            deptId, true), DeptDO::getId);
+                deptId, true), DeptDO::getId);
         deptIds.add(deptId); // 包括自身
         return deptIds;
     }
@@ -340,7 +417,6 @@ public class AdminUserServiceImpl implements AdminUserService {
 
     /**
      * 校验旧密码
-     *
      * @param id          用户 id
      * @param oldPassword 旧密码
      */
@@ -362,12 +438,12 @@ public class AdminUserServiceImpl implements AdminUserService {
             throw exception(USER_IMPORT_LIST_IS_EMPTY);
         }
         UserImportRespVO respVO = UserImportRespVO.builder().createUsernames(new ArrayList<>())
-            .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
+                .updateUsernames(new ArrayList<>()).failureUsernames(new LinkedHashMap<>()).build();
         importUsers.forEach(importUser -> {
             // 校验,判断是否有不符合的原因
             try {
                 checkCreateOrUpdate(null, null, importUser.getMobile(), importUser.getEmail(),
-                    importUser.getDeptId(), null);
+                        importUser.getDeptId(), null);
             } catch (ServiceException ex) {
                 respVO.getFailureUsernames().put(importUser.getUsername(), ex.getMessage());
                 return;
@@ -376,7 +452,7 @@ public class AdminUserServiceImpl implements AdminUserService {
             AdminUserDO existUser = userMapper.selectByUsername(importUser.getUsername());
             if (existUser == null) {
                 userMapper.insert(UserConvert.INSTANCE.convert(importUser)
-                    .setPassword(passwordEncoder.encode(userInitPassword))); // 设置默认密码
+                        .setPassword(passwordEncoder.encode(userInitPassword))); // 设置默认密码
                 respVO.getCreateUsernames().add(importUser.getUsername());
                 return;
             }

+ 1 - 0
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/clean.sql

@@ -4,6 +4,7 @@ DELETE FROM "system_role";
 DELETE FROM "system_role_menu";
 DELETE FROM "system_menu";
 DELETE FROM "system_user_role";
+DELETE FROM "system_user_post";
 DELETE FROM "system_dict_type";
 DELETE FROM "system_user_session";
 DELETE FROM "system_post";

+ 14 - 0
yudao-module-system/yudao-module-system-biz/src/test/resources/sql/create_tables.sql

@@ -147,6 +147,20 @@ CREATE TABLE IF NOT EXISTS "system_post" (
     PRIMARY KEY ("id")
 ) COMMENT '岗位信息表';
 
+CREATE TABLE IF NOT EXISTS `system_user_post`(
+    "id"          bigint    NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "user_id"     bigint             DEFAULT NULL,
+    "post_id"     bigint             DEFAULT NULL,
+    "creator"     varchar(64)        DEFAULT '',
+    "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater"     varchar(64)        DEFAULT '',
+    "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "deleted"     bit       NOT NULL DEFAULT FALSE,
+    "tenant_id"   bigint    not null default '0',
+    PRIMARY KEY (`id`)
+) COMMENT ='用户岗位表';
+
+
 CREATE TABLE IF NOT EXISTS "system_notice" (
 	"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
 	"title" varchar(50) NOT NULL COMMENT '公告标题',

Some files were not shown because too many files changed in this diff