From 3cd135850ec0f6d5d43027870de03a2b191388e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=89=E8=B4=9E?= <anzhenemail@163.com>
Date: Wed, 30 Mar 2022 17:21:24 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=BB=BA=E4=B8=80=E4=B8=AA=E5=85=B3?=
 =?UTF-8?q?=E8=81=94=E8=A1=A8=E7=BB=B4=E6=8A=A4=E7=94=A8=E6=88=B7=E5=B2=97?=
 =?UTF-8?q?=E4=BD=8D=E5=85=B3=E7=B3=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 sql/ruoyi-vue-pro.sql                         | 19 ++++++
 .../dal/dataobject/dept/UserPostDO.java       | 35 +++++++++++
 .../system/dal/mysql/dept/UserPostMapper.java | 10 ++++
 .../dal/mysql/user/AdminUserMapper.java       |  3 +
 .../system/service/dept/UserPostService.java  | 16 +++++
 .../service/dept/UserPostServiceImpl.java     | 19 ++++++
 .../service/user/AdminUserServiceImpl.java    | 58 +++++++++++++++++--
 7 files changed, 154 insertions(+), 6 deletions(-)
 create mode 100644 yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/UserPostDO.java
 create mode 100644 yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java
 create mode 100644 yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostService.java
 create mode 100644 yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostServiceImpl.java

diff --git a/sql/ruoyi-vue-pro.sql b/sql/ruoyi-vue-pro.sql
index 96183a703..cee359d62 100644
--- a/sql/ruoyi-vue-pro.sql
+++ b/sql/ruoyi-vue-pro.sql
@@ -2414,6 +2414,25 @@ CREATE TABLE `pay_refund` (
 BEGIN;
 COMMIT;
 
+
+-- ----------------------------
+-- Table structure for system_user_post
+-- ----------------------------
+DROP TABLE IF EXISTS `system_user_post`;
+CREATE TABLE `system_user_post` (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `user_id` bigint NOT NULL DEFAULT '0' COMMENT '用户ID',
+  `post_id` bigint NOT NULL DEFAULT '0' COMMENT '岗位ID',
+  `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
+  `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
+  `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
+  `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
+  PRIMARY KEY (`id`) USING BTREE
+) ENGINE=InnoDB AUTO_INCREMENT=112 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='部门表';
+
+
 -- ----------------------------
 -- Table structure for system_dept
 -- ----------------------------
diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/UserPostDO.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/dept/UserPostDO.java
new file mode 100644
index 000000000..02401977e
--- /dev/null
+++ b/yudao-module-system/yudao-module-system-impl/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;
+
+}
diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java
new file mode 100644
index 000000000..0e9345a86
--- /dev/null
+++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/UserPostMapper.java
@@ -0,0 +1,10 @@
+package cn.iocoder.yudao.module.system.dal.mysql.dept;
+
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface UserPostMapper extends BaseMapperX<UserPostDO> {
+
+}
diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java
index be4b5ea21..68acb7dcd 100644
--- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java
+++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/user/AdminUserMapper.java
@@ -61,5 +61,8 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
         return selectList(AdminUserDO::getDeptId, deptIds);
     }
 
+    default List<AdminUserDO> selectListByIds(List<Long> userIdList) {
+        return selectList(new LambdaQueryWrapperX<AdminUserDO>().in(AdminUserDO::getId, userIdList));
+    }
 }
 
diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostService.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostService.java
new file mode 100644
index 000000000..4299c5cbe
--- /dev/null
+++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostService.java
@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.module.system.service.dept;
+
+import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 工作流的表单定义 Mapper 接口
+ * </p>
+ *
+ * @author anzhen
+ * @since 2022-03-03
+ */
+public interface UserPostService extends IService<UserPostDO> {
+
+}
diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostServiceImpl.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostServiceImpl.java
new file mode 100644
index 000000000..5be2e17d0
--- /dev/null
+++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/dept/UserPostServiceImpl.java
@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.system.service.dept;
+
+import cn.iocoder.yudao.module.system.dal.dataobject.dept.UserPostDO;
+import cn.iocoder.yudao.module.system.dal.mysql.dept.UserPostMapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 工作流的表单定义 Mapper 接口
+ * </p>
+ *
+ * @author anzhen
+ * @since 2022-03-03
+ */
+@Service
+public class UserPostServiceImpl extends ServiceImpl<UserPostMapper, UserPostDO> implements UserPostService {
+
+}
diff --git a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
index 32f0a8e8c..6457e84e8 100644
--- a/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
+++ b/yudao-module-system/yudao-module-system-impl/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
@@ -13,12 +13,15 @@ import cn.iocoder.yudao.module.system.controller.admin.user.vo.profile.UserProfi
 import cn.iocoder.yudao.module.system.controller.admin.user.vo.user.*;
 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.user.AdminUserMapper;
 import cn.iocoder.yudao.module.system.service.dept.DeptService;
 import cn.iocoder.yudao.module.system.service.dept.PostService;
+import cn.iocoder.yudao.module.system.service.dept.UserPostService;
 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
 import cn.iocoder.yudao.module.system.service.tenant.TenantService;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.google.common.annotations.VisibleForTesting;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
@@ -29,6 +32,7 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import java.io.InputStream;
 import java.util.*;
+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.*;
@@ -59,11 +63,14 @@ public class AdminUserServiceImpl implements AdminUserService {
     @Resource
     private TenantService tenantService;
 
+    @Resource
+    private UserPostService userPostService;
+
     @Resource
     private FileApi fileApi;
 
     @Override
-
+    @Transactional(rollbackFor = Exception.class)
     public Long createUser(UserCreateReqVO reqVO) {
         // 校验账户配合
         tenantService.handleTenantInfo(tenant -> {
@@ -80,10 +87,22 @@ public class AdminUserServiceImpl implements AdminUserService {
         user.setStatus(CommonStatusEnum.ENABLE.getStatus()); // 默认开启
         user.setPassword(passwordEncoder.encode(reqVO.getPassword())); // 加密密码
         userMapper.insert(user);
+        Set<Long> postIds = user.getPostIds();
+        if (!org.springframework.util.CollectionUtils.isEmpty(postIds)) {
+            ArrayList<UserPostDO> userPostList = new ArrayList<>();
+            for (Long postId : postIds) {
+                UserPostDO entity = new UserPostDO();
+                entity.setUserId(entity.getUserId());
+                entity.setPostId(postId);
+                userPostList.add(entity);
+            }
+            userPostService.saveBatch(userPostList);
+        }
         return user.getId();
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void updateUser(UserUpdateReqVO reqVO) {
         // 校验正确性
         this.checkCreateOrUpdate(reqVO.getId(), reqVO.getUsername(), reqVO.getMobile(), reqVO.getEmail(),
@@ -91,6 +110,19 @@ public class AdminUserServiceImpl implements AdminUserService {
         // 更新用户
         AdminUserDO updateObj = UserConvert.INSTANCE.convert(reqVO);
         userMapper.updateById(updateObj);
+        Set<Long> postIds = updateObj.getPostIds();
+        if (!org.springframework.util.CollectionUtils.isEmpty(postIds)) {
+            for (Long postId : postIds) {
+                UserPostDO entity = new UserPostDO();
+                entity.setUserId(reqVO.getId());
+                entity.setPostId(postId);
+                userPostService.saveOrUpdate(entity,
+                        Wrappers.lambdaUpdate(UserPostDO.class)
+                                .eq(UserPostDO::getUserId, entity.getUserId())
+                                .eq(UserPostDO::getPostId, entity.getPostId())
+                );
+            }
+        }
     }
 
     @Override
@@ -154,6 +186,7 @@ public class AdminUserServiceImpl implements AdminUserService {
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void deleteUser(Long id) {
         // 校验用户存在
         this.checkUserExists(id);
@@ -161,6 +194,8 @@ public class AdminUserServiceImpl implements AdminUserService {
         userMapper.deleteById(id);
         // 删除用户关联数据
         permissionService.processUserDeleted(id);
+
+        userPostService.remove(Wrappers.lambdaUpdate(UserPostDO.class).eq(UserPostDO::getUserId, id));
     }
 
     @Override
@@ -191,11 +226,22 @@ 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 = userPostService
+                .lambdaQuery()
+                .in(UserPostDO::getPostId, postIds)
+                .list()
+                .stream()
+                .map(UserPostDO::getUserId)
+                .distinct()
+                .collect(Collectors.toList());
+        if (userIdList.isEmpty()) {
+            return Collections.emptyList();
+        }
+        return userMapper
+                .selectListByIds(userIdList)
+                .stream()
+                .peek(user -> user.setPassword(null))
+                .collect(Collectors.toList());
     }
 
     @Override