Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/1.6.2-postgresql

This commit is contained in:
YunaiV 2022-05-02 15:24:24 +08:00
commit c845f3f012
8 changed files with 5028 additions and 20 deletions

4848
sql/ruoyi-vue-pro.sql Normal file

File diff suppressed because one or more lines are too long

View File

@ -160,7 +160,7 @@
</el-form-item> </el-form-item>
#elseif($column.htmlType == "datetime")## 时间框 #elseif($column.htmlType == "datetime")## 时间框
<el-form-item label="${comment}" prop="${javaField}"> <el-form-item label="${comment}" prop="${javaField}">
<el-date-picker clearable v-model="form.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${comment}" /> <el-date-picker clearable v-model="form.${javaField}" type="date" value-format="timestamp" placeholder="选择${comment}" />
</el-form-item> </el-form-item>
#elseif($column.htmlType == "textarea")## 文本框 #elseif($column.htmlType == "textarea")## 文本框
<el-form-item label="${comment}" prop="${javaField}"> <el-form-item label="${comment}" prop="${javaField}">

View File

@ -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;
}

View File

@ -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));
}
}

View File

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

View File

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

View File

@ -148,6 +148,20 @@ CREATE TABLE IF NOT EXISTS "system_post" (
PRIMARY KEY ("id") PRIMARY KEY ("id")
) COMMENT '岗位信息表'; ) 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" ( CREATE TABLE IF NOT EXISTS "system_notice" (
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"title" varchar(50) NOT NULL COMMENT '公告标题', "title" varchar(50) NOT NULL COMMENT '公告标题',

View File

@ -39,7 +39,7 @@ export default {
simulation: true, simulation: true,
labelEditing: false, labelEditing: false,
labelVisible: false, labelVisible: false,
prefix: "activiti", prefix: "flowable",
headerButtonSize: "mini", headerButtonSize: "mini",
additionalModel: [CustomContentPadProvider, CustomPaletteProvider] additionalModel: [CustomContentPadProvider, CustomPaletteProvider]
}, },