فهرست منبع

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

芋道源码 3 سال پیش
والد
کامیت
7d87be8b7d

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 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 '公告标题',

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است