refactor: 重构组织架构

pull/9/head
Carina 4 years ago
parent 2c4f706b62
commit 4afe983ff5

File diff suppressed because one or more lines are too long

@ -47,28 +47,29 @@ public interface SysOrgRestApi {
/** /**
* By *
* @param parentId ID * @param parentId ID
* @param id ID
* @return ResultVo * @return ResultVo
*/ */
@GetMapping("/findTreeLazyByUser") @GetMapping("/findTreeLazy")
ResultVo<?> findTreeLazyByUser(String parentId); ResultVo<?> findTreeLazy(String parentId, String id);
/** /**
* *
* @param parentId ID * @param isGen
* @param id ID
* @return ResultVo * @return ResultVo
*/ */
@GetMapping("/findTreeLazy") @GetMapping("/findTreeByDef")
ResultVo<?> findTreeLazy(String parentId); ResultVo<?> findTreeByDef(boolean isGen, String id);
/** /**
* *
* @param parentId ID
* @return ResultVo * @return ResultVo
*/ */
@GetMapping("/findGridTree") @GetMapping("/findTreeByDefWithUserToLike")
ResultVo<?> findGridTree(String parentId); ResultVo<?> findTreeByDefWithUserToLike();
// ================ // ================
@ -80,14 +81,6 @@ public interface SysOrgRestApi {
@GetMapping("/get") @GetMapping("/get")
ResultVo<SysOrgModel> get(SysOrgModel model); ResultVo<SysOrgModel> get(SysOrgModel model);
/**
*
* @param request request
* @return ResultVo
*/
@GetMapping("/findTree")
ResultVo<?> findTree( HttpServletRequest request );
/** /**
* *
* @param model * @param model

@ -19,7 +19,7 @@ import org.opsli.api.base.result.ResultVo;
import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.api.wrapper.system.user.UserInfo; import org.opsli.api.wrapper.system.user.UserInfo;
import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel; import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
import org.opsli.api.wrapper.system.user.UserPassword; import org.opsli.api.wrapper.system.user.UserPassword;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
@ -72,7 +72,7 @@ public interface UserApi {
* @return ResultVo * @return ResultVo
*/ */
@GetMapping("/getOrg") @GetMapping("/getOrg")
ResultVo<UserOrgRefModel> getOrg(); ResultVo<?> getOrg();
/** /**
* *
@ -81,7 +81,7 @@ public interface UserApi {
* @return ResultVo * @return ResultVo
*/ */
@GetMapping("/getOrgByUserId") @GetMapping("/getOrgByUserId")
ResultVo<UserOrgRefModel> getOrgByUserId(String userId); ResultVo<?> getOrgByUserId(String userId);
/** /**
* userId Id * userId Id
@ -94,6 +94,7 @@ public interface UserApi {
/** /**
* *
* @param userPassword
* @return ResultVo * @return ResultVo
*/ */
@PostMapping("/updatePassword") @PostMapping("/updatePassword")
@ -148,7 +149,7 @@ public interface UserApi {
* *
* @param pageNo * @param pageNo
* @param pageSize * @param pageSize
* @param org * @param orgIdGroup ID
* @param request request * @param request request
* @return ResultVo * @return ResultVo
*/ */
@ -156,7 +157,7 @@ public interface UserApi {
ResultVo<?> findPage( ResultVo<?> findPage(
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
UserOrgRefModel org, @RequestParam(name = "orgIdGroup") String orgIdGroup,
HttpServletRequest request HttpServletRequest request
); );
@ -265,7 +266,7 @@ public interface UserApi {
* @param userId ID * @param userId ID
* @return ResultVo * @return ResultVo
*/ */
ResultVo<UserOrgRefModel> getOrgInfoByUserId(String userId); ResultVo<UserOrgRefWebModel> getOrgInfoByUserId(String userId);
} }

@ -17,9 +17,12 @@ package org.opsli.api.web.system.user;
import org.opsli.api.base.result.ResultVo; import org.opsli.api.base.result.ResultVo;
import org.opsli.api.wrapper.system.user.UserOrgRefModel; import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/** /**
* API * API
@ -46,6 +49,13 @@ public interface UserOrgRefApi {
* @return ResultVo * @return ResultVo
*/ */
@PostMapping("/setOrg") @PostMapping("/setOrg")
ResultVo<?> setOrg(@RequestBody UserOrgRefModel model); ResultVo<?> setOrg(@RequestBody UserOrgRefWebModel model);
/**
* ID
* @param userId ID
* @return List
*/
ResultVo<List<UserOrgRefModel>> findListByUserId(String userId);
} }

@ -37,6 +37,7 @@ import org.opsli.plugins.excel.annotation.ExcelInfo;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class SysOrgModel extends ApiWrapper { public class SysOrgModel extends ApiWrapper {
/** 父级主键 */ /** 父级主键 */
@ApiModelProperty(value = "父级主键") @ApiModelProperty(value = "父级主键")
@ExcelProperty(value = "父级主键", order = 1) @ExcelProperty(value = "父级主键", order = 1)
@ -44,9 +45,15 @@ public class SysOrgModel extends ApiWrapper {
@ValidatorLenMax(19) @ValidatorLenMax(19)
private String parentId; private String parentId;
/** 父级主键集合 xxx,xxx */
@ApiModelProperty(value = "父级主键集合")
@ExcelProperty(value = "父级主键集合", order = 2)
@ExcelInfo
private String parentIds;
/** 组织机构编号 */ /** 组织机构编号 */
@ApiModelProperty(value = "组织机构编号") @ApiModelProperty(value = "组织机构编号")
@ExcelProperty(value = "组织机构编号", order = 2) @ExcelProperty(value = "组织机构编号", order = 3)
@ExcelInfo @ExcelInfo
@Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_GENERAL}) @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_GENERAL})
@ValidatorLenMax(120) @ValidatorLenMax(120)
@ -54,20 +61,12 @@ public class SysOrgModel extends ApiWrapper {
/** 组织机构名称 */ /** 组织机构名称 */
@ApiModelProperty(value = "组织机构名称") @ApiModelProperty(value = "组织机构名称")
@ExcelProperty(value = "组织机构名称", order = 3) @ExcelProperty(value = "组织机构名称", order = 4)
@ExcelInfo @ExcelInfo
@Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_GENERAL_WITH_CHINESE}) @Validator({ValidatorType.IS_NOT_NULL, ValidatorType.IS_GENERAL_WITH_CHINESE})
@ValidatorLenMax(120) @ValidatorLenMax(120)
private String orgName; private String orgName;
/** 组织机构类型 1-公司 2-部门 3-岗位*/
@ApiModelProperty(value = "组织机构类型")
@ExcelProperty(value = "组织机构类型", order = 4)
@ExcelInfo( dictType = "org_type")
@Validator({ValidatorType.IS_NOT_NULL})
@ValidatorLenMax(3)
private String orgType;
/** 排序 */ /** 排序 */
@ApiModelProperty(value = "排序") @ApiModelProperty(value = "排序")
@ExcelProperty(value = "排序", order = 5) @ExcelProperty(value = "排序", order = 5)
@ -75,6 +74,13 @@ public class SysOrgModel extends ApiWrapper {
@ValidatorLenMax(10) @ValidatorLenMax(10)
private Integer sortNo; private Integer sortNo;
/** 备注 */
@ApiModelProperty(value = "备注")
@ExcelProperty(value = "备注", order = 6)
@ExcelInfo
@ValidatorLenMax(255)
private String remark;
/** 多租户字段 */ /** 多租户字段 */
@ApiModelProperty(value = "多租户ID") @ApiModelProperty(value = "多租户ID")
@ExcelIgnore @ExcelIgnore

@ -17,6 +17,7 @@ package org.opsli.api.wrapper.system.user;
import com.alibaba.excel.annotation.ExcelIgnore; import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@ -135,5 +136,11 @@ public class UserModel extends ApiWrapper {
@ValidatorLenMax(20) @ValidatorLenMax(20)
private String tenantId; private String tenantId;
/** 是否存在组织 */
@JsonIgnore
@ExcelIgnore
@ValidatorLenMax(1)
private String izExistOrg;
} }

@ -16,17 +16,20 @@
package org.opsli.api.wrapper.system.user; package org.opsli.api.wrapper.system.user;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.opsli.api.wrapper.system.org.SysOrgModel;
import org.opsli.common.annotation.validator.Validator; import org.opsli.common.annotation.validator.Validator;
import org.opsli.common.annotation.validator.ValidatorLenMax; import org.opsli.common.annotation.validator.ValidatorLenMax;
import org.opsli.common.enums.ValidatorType; import org.opsli.common.enums.ValidatorType;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* *
* *
* @author Parker * @author Parker
* @date 2020-09-16 17:33 * @date 2020-09-16 17:33
@ -36,32 +39,26 @@ import java.io.Serializable;
@ExcelIgnoreUnannotated @ExcelIgnoreUnannotated
public class UserOrgRefModel implements Serializable { public class UserOrgRefModel implements Serializable {
/** ID */
@ApiModelProperty(value = "ID")
private String id;
/** 用户ID */ /** 用户ID */
@ApiModelProperty(value = "用户ID") @ApiModelProperty(value = "用户ID")
@Validator({ValidatorType.IS_NOT_NULL}) @Validator({ValidatorType.IS_NOT_NULL})
@ValidatorLenMax(50) @ValidatorLenMax(50)
private String userId; private String userId;
@ApiModelProperty(value = "公司") /** 当前组织 */
@Validator({ValidatorType.IS_NOT_NULL}) @ApiModelProperty(value = "当前组织")
@ValidatorLenMax(19) private String orgId;
private String companyId;
@ApiModelProperty(value = "公司名称")
private String companyName;
@ApiModelProperty(value = "部门ID")
@ValidatorLenMax(19)
private String departmentId;
@ApiModelProperty(value = "部门名称")
private String departmentName;
@ApiModelProperty(value = "岗位ID") /** 组织ID集合 xxx,xxx */
@ValidatorLenMax(19) @ApiModelProperty(value = "组织ID集合")
private String postId; private String orgIds;
@ApiModelProperty(value = "岗位名称") /** 是否默认 */
private String postName; @ApiModelProperty(value = "是否默认")
private String izDef;
} }

@ -0,0 +1,53 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.opsli.api.wrapper.system.user;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.opsli.api.wrapper.system.org.SysOrgModel;
import org.opsli.common.annotation.validator.Validator;
import org.opsli.common.annotation.validator.ValidatorLenMax;
import org.opsli.common.enums.ValidatorType;
import java.io.Serializable;
import java.util.List;
/**
*
*
* @author Parker
* @date 2020-09-16 17:33
*/
@Data
@EqualsAndHashCode(callSuper = false)
@ExcelIgnoreUnannotated
public class UserOrgRefWebModel implements Serializable {
/** 用户ID */
@ApiModelProperty(value = "用户ID")
@Validator({ValidatorType.IS_NOT_NULL})
@ValidatorLenMax(50)
private String userId;
@ApiModelProperty(value = "默认组织")
private SysOrgModel defModel;
@ApiModelProperty(value = "组织机构")
private List<SysOrgModel> orgModelList;
}

@ -35,7 +35,7 @@ import org.opsli.plugins.excel.annotation.ExcelInfo;
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class UserAndOrgModel extends ApiWrapper { public class UserWebModel extends ApiWrapper {
/** 登录账户 */ /** 登录账户 */
@ -137,10 +137,4 @@ public class UserAndOrgModel extends ApiWrapper {
@ValidatorLenMax(20) @ValidatorLenMax(20)
private String tenantId; private String tenantId;
/** 组织机构 */
@ApiModelProperty(value = "组织机构")
@ExcelIgnore
private UserOrgRefModel org;
} }

@ -36,6 +36,8 @@ public interface MyBatisConstants {
String FIELD_ID = "id"; String FIELD_ID = "id";
/** PID */ /** PID */
String FIELD_PARENT_ID = "parentId"; String FIELD_PARENT_ID = "parentId";
/** PIDs */
String FIELD_PARENT_IDS = "parentIds";
/** 创建人 */ /** 创建人 */
String FIELD_CREATE_BY = "createBy"; String FIELD_CREATE_BY = "createBy";
/** 更新时间 */ /** 更新时间 */
@ -50,4 +52,6 @@ public interface MyBatisConstants {
String FIELD_OPTIMISTIC_LOCK = "version"; String FIELD_OPTIMISTIC_LOCK = "version";
/** 多租户字段 */ /** 多租户字段 */
String FIELD_TENANT = "tenantId"; String FIELD_TENANT = "tenantId";
/** 组织字段 */
String FIELD_ORG_GROUP = "org_group";
} }

@ -0,0 +1,33 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.opsli.common.constants;
/**
*
*
* @author Parker
* @date 202131015:50:16
*/
public interface TreeConstants {
/** 是否包含子集 */
String HAS_CHILDREN = "hasChildren";
/** 是否是叶子节点 */
String IS_LEAF = "isLeaf";
}

@ -17,13 +17,19 @@ package org.opsli.core.base.controller;
import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval; import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.support.ExcelTypeEnum; import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.result.ResultVo; import org.opsli.api.base.result.ResultVo;
@ -32,6 +38,7 @@ import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.annotation.hotdata.EnableHotData; import org.opsli.common.annotation.hotdata.EnableHotData;
import org.opsli.common.constants.CacheConstants; import org.opsli.common.constants.CacheConstants;
import org.opsli.common.constants.TreeConstants;
import org.opsli.common.enums.ExcelOperate; import org.opsli.common.enums.ExcelOperate;
import org.opsli.common.exception.ServiceException; import org.opsli.common.exception.ServiceException;
import org.opsli.common.exception.TokenException; import org.opsli.common.exception.TokenException;
@ -40,6 +47,7 @@ import org.opsli.common.utils.OutputStreamUtil;
import org.opsli.common.utils.WrapperUtil; import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.autoconfigure.properties.GlobalProperties; import org.opsli.core.autoconfigure.properties.GlobalProperties;
import org.opsli.core.base.entity.BaseEntity; import org.opsli.core.base.entity.BaseEntity;
import org.opsli.core.base.entity.HasChildren;
import org.opsli.core.base.service.interfaces.CrudServiceInterface; import org.opsli.core.base.service.interfaces.CrudServiceInterface;
import org.opsli.core.cache.local.CacheUtil; import org.opsli.core.cache.local.CacheUtil;
import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.CoreMsg;
@ -60,9 +68,8 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Date; import java.util.*;
import java.util.Iterator; import java.util.function.Function;
import java.util.List;
/** /**
* Service CRUD * Service CRUD
@ -353,6 +360,67 @@ public abstract class BaseRestController <T extends BaseEntity, E extends ApiWra
} }
} }
/**
*
* @param treeNodes
*/
protected List<Tree<Object>> handleTreeHasChildren(List<Tree<Object>> treeNodes,
Function<Set<String>, List<HasChildren>> callback) {
if(CollUtil.isEmpty(treeNodes) || callback == null){
return treeNodes;
}
Set<String> parentIds = Sets.newHashSet();
for (Tree<Object> treeNode : treeNodes) {
parentIds.add(Convert.toStr(treeNode.getId()));
}
// 数据排查是否存在下级
List<HasChildren> hasChildrenList = callback.apply(parentIds);
if(CollUtil.isEmpty(hasChildrenList)){
hasChildrenList = ListUtil.empty();
}
// 字典
Map<String, Boolean> hasChildrenDict = Maps.newHashMap();
for (HasChildren hasChildren : hasChildrenList) {
if (hasChildren.getCount() != null && hasChildren.getCount() > 0) {
hasChildrenDict.put(hasChildren.getParentId(), true);
}
}
// 处理节点
this.handleTreeHasChildren(treeNodes, hasChildrenDict);
return treeNodes;
}
/**
*
* @param treeNodes
* @param hasChildrenDict
*/
private void handleTreeHasChildren(List<Tree<Object>> treeNodes,
Map<String, Boolean> hasChildrenDict){
for (Tree<Object> treeNode : treeNodes) {
Boolean tmpFlag = hasChildrenDict.get(Convert.toStr(treeNode.getId()));
if (tmpFlag != null && tmpFlag) {
treeNode.putExtra(TreeConstants.IS_LEAF, false);
treeNode.putExtra(TreeConstants.HAS_CHILDREN, true);
}else {
treeNode.putExtra(TreeConstants.IS_LEAF, true);
treeNode.putExtra(TreeConstants.HAS_CHILDREN, false);
}
// 如果不为空 则继续递归处理
if(CollUtil.isNotEmpty(treeNode.getChildren())){
handleTreeHasChildren(treeNode.getChildren(), hasChildrenDict);
}
}
}
// ================================================= // =================================================
@PostConstruct @PostConstruct

@ -43,7 +43,7 @@ public abstract class BaseEntity extends ApiWrapper {
/** /**
@TableLogic @TableLogic
private Integer deleted; private String deleted;
**/ **/

@ -32,7 +32,8 @@ import org.opsli.core.base.service.interfaces.CrudServiceInterface;
import org.opsli.core.persistence.Page; import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.chain.TenantHandler; import org.opsli.core.persistence.querybuilder.chain.QueryOrgHandler;
import org.opsli.core.persistence.querybuilder.chain.QueryTenantHandler;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
@ -210,17 +211,24 @@ public abstract class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseEnt
@Override @Override
public List<T> findList(QueryWrapper<T> queryWrapper) { public List<T> findList(QueryWrapper<T> queryWrapper) {
// 多租户处理 // 数据处理责任链
QueryWrapper<T> qWrapper = new TenantHandler().handler(entityClazz, queryWrapper); queryWrapper = new QueryTenantHandler(
return super.list(qWrapper); new QueryOrgHandler()
).handler(entityClazz, queryWrapper);
return super.list(queryWrapper);
} }
@Override @Override
public List<T> findAllList() { public List<T> findAllList() {
QueryBuilder<T> queryBuilder = new GenQueryBuilder<>(); QueryBuilder<T> queryBuilder = new GenQueryBuilder<>();
// 多租户处理 QueryWrapper<T> queryWrapper = queryBuilder.build();
QueryWrapper<T> qWrapper = new TenantHandler().handler(entityClazz, queryBuilder.build()); // 数据处理责任链
return super.list(qWrapper); queryWrapper = new QueryTenantHandler(
new QueryOrgHandler()
).handler(entityClazz, queryWrapper);
return super.list(queryWrapper);
} }
@Override @Override
@ -251,7 +259,6 @@ public abstract class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseEnt
return page; return page;
} }
// ======================== 对象转化 ======================== // ======================== 对象转化 ========================
/** /**

@ -18,8 +18,7 @@ package org.opsli.core.cache.pushsub.msgs;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.core.cache.pushsub.enums.MsgArgsType; import org.opsli.core.cache.pushsub.enums.MsgArgsType;
import org.opsli.core.cache.pushsub.enums.PushSubType; import org.opsli.core.cache.pushsub.enums.PushSubType;
import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver;
@ -45,7 +44,7 @@ public final class OrgMsgFactory extends BaseSubMessage{
* @param orgRefModel * @param orgRefModel
* @return * @return
*/ */
public static BaseSubMessage createOrgMsg(UserOrgRefModel orgRefModel){ public static BaseSubMessage createOrgMsg(UserOrgRefWebModel orgRefModel){
BaseSubMessage baseSubMessage = new BaseSubMessage(); BaseSubMessage baseSubMessage = new BaseSubMessage();
// 数据 // 数据
JSONObject jsonObj = new JSONObject(); JSONObject jsonObj = new JSONObject();

@ -19,7 +19,6 @@ import com.alibaba.fastjson.JSONObject;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import org.opsli.api.wrapper.system.tenant.TenantModel; import org.opsli.api.wrapper.system.tenant.TenantModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.core.cache.pushsub.enums.MsgArgsType; import org.opsli.core.cache.pushsub.enums.MsgArgsType;
import org.opsli.core.cache.pushsub.enums.PushSubType; import org.opsli.core.cache.pushsub.enums.PushSubType;
import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver; import org.opsli.core.cache.pushsub.receiver.RedisPushSubReceiver;

@ -38,6 +38,10 @@ public class WebQueryBuilder<T extends BaseEntity> implements QueryBuilder<T>{
private static final String EQ = "EQ"; private static final String EQ = "EQ";
/** 模糊匹配 */ /** 模糊匹配 */
private static final String LIKE = "LIKE"; private static final String LIKE = "LIKE";
/** 左模糊匹配 */
private static final String LIKE_LEFT = "LIKEL";
/** 右模糊匹配 */
private static final String LIKE_RIGHT = "LIKER";
/** 日期匹配 */ /** 日期匹配 */
private static final String BEGIN = "BEGIN"; private static final String BEGIN = "BEGIN";
private static final String END = "END"; private static final String END = "END";
@ -217,6 +221,14 @@ public class WebQueryBuilder<T extends BaseEntity> implements QueryBuilder<T>{
// 模糊匹配 // 模糊匹配
queryWrapper.like(key, value); queryWrapper.like(key, value);
break; break;
case LIKE_LEFT:
// 模糊匹配 左
queryWrapper.likeLeft(key, value);
break;
case LIKE_RIGHT:
// 模糊匹配 右
queryWrapper.likeRight(key, value);
break;
case BEGIN: case BEGIN:
// 大于等于 // 大于等于
queryWrapper.ge(key, value); queryWrapper.ge(key, value);
@ -282,6 +294,8 @@ public class WebQueryBuilder<T extends BaseEntity> implements QueryBuilder<T>{
case EQ: case EQ:
case END: case END:
case LIKE: case LIKE:
case LIKE_LEFT:
case LIKE_RIGHT:
case BEGIN: case BEGIN:
return true; return true;
default: default:

@ -0,0 +1,71 @@
/**
* Copyright 2020 OPSLI https://www.opsli.com
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.opsli.core.persistence.querybuilder.chain;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.utils.FieldUtil;
import org.opsli.core.base.entity.BaseEntity;
import org.opsli.core.utils.UserUtil;
/**
*
*
* @author Parker
* @date 2020-09-13 19:36
*/
public class QueryOrgHandler implements QueryBuilderChain{
/**
*
*/
private QueryBuilderChain queryBuilderChain;
public QueryOrgHandler(){}
/**
*
* @param queryBuilderChain
*/
public QueryOrgHandler(QueryBuilderChain queryBuilderChain){
this.queryBuilderChain = queryBuilderChain;
}
@Override
public <T extends BaseEntity> QueryWrapper<T> handler(Class<T> entityClazz, QueryWrapper<T> wrapper) {
// 执行 子 责任链
if(queryBuilderChain != null){
wrapper = queryBuilderChain.handler(entityClazz, wrapper);
}
// 自身责任 -- 判断组织
boolean flag = ReflectUtil.hasField(entityClazz, MyBatisConstants.FIELD_ORG_GROUP);
if(flag) {
// 1. 获得 用户 数据权限
// 2. 获得 角色 数据权限
}
return wrapper;
}
}

@ -30,7 +30,7 @@ import org.opsli.core.utils.UserUtil;
* @author Parker * @author Parker
* @date 2020-09-13 19:36 * @date 2020-09-13 19:36
*/ */
public class TenantHandler implements QueryBuilderChain{ public class QueryTenantHandler implements QueryBuilderChain{
/** /**
* *
@ -38,18 +38,23 @@ public class TenantHandler implements QueryBuilderChain{
private QueryBuilderChain queryBuilderChain; private QueryBuilderChain queryBuilderChain;
public TenantHandler(){} public QueryTenantHandler(){}
/** /**
* *
* @param queryBuilderChain * @param queryBuilderChain
*/ */
public TenantHandler(QueryBuilderChain queryBuilderChain){ public QueryTenantHandler(QueryBuilderChain queryBuilderChain){
this.queryBuilderChain = queryBuilderChain; this.queryBuilderChain = queryBuilderChain;
} }
@Override @Override
public <T extends BaseEntity> QueryWrapper<T> handler(Class<T> entityClazz, QueryWrapper<T> wrapper) { public <T extends BaseEntity> QueryWrapper<T> handler(Class<T> entityClazz, QueryWrapper<T> wrapper) {
// 执行 子 责任链
if(queryBuilderChain != null){
wrapper = queryBuilderChain.handler(entityClazz, wrapper);
}
// 自身责任 -- 判断多租户 // 自身责任 -- 判断多租户
boolean tenantFlag = ReflectUtil.hasField(entityClazz, MyBatisConstants.FIELD_TENANT); boolean tenantFlag = ReflectUtil.hasField(entityClazz, MyBatisConstants.FIELD_TENANT);
if(tenantFlag) { if(tenantFlag) {
@ -62,11 +67,6 @@ public class TenantHandler implements QueryBuilderChain{
wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_TENANT), tenantId); wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_TENANT), tenantId);
} }
} }
// 执行 子 责任链
if(queryBuilderChain != null){
wrapper = queryBuilderChain.handler(entityClazz, wrapper);
}
return wrapper; return wrapper;
} }

@ -15,11 +15,24 @@
*/ */
package org.opsli.core.utils; package org.opsli.core.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.result.ResultVo; import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.user.UserApi; import org.opsli.api.web.system.user.UserApi;
import org.opsli.api.web.system.user.UserOrgRefApi;
import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.api.wrapper.system.org.SysOrgModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel; import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
import org.opsli.common.enums.DictType;
import org.opsli.common.utils.FieldUtil;
import org.opsli.common.utils.ListDistinctUtil;
import org.opsli.core.cache.local.CacheUtil; import org.opsli.core.cache.local.CacheUtil;
import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.CoreMsg;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -27,6 +40,8 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.core.annotation.Order; import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List;
import static org.opsli.common.constants.OrderConstants.UTIL_ORDER; import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
/** /**
@ -44,18 +59,25 @@ public class OrgUtil {
/** 前缀 */ /** 前缀 */
public static final String PREFIX_CODE = "org:userId:"; public static final String PREFIX_CODE = "org:userId:";
/** 用户 Api */ /** 用户表 是否分配组织 状态标识 */
private static UserApi userApi; public static final String USER_ORG_FIELD = "iz_exist_org";
/** 显示全部 */
public static final String ORG_ALL = "org_all";
/** 未分组 */
public static final String ORG_NULL = "org_null";
/** 用户组织 Api */
private static UserOrgRefApi userOrgRefApi;
/** 增加初始状态开关 防止异常使用 */ /** 增加初始状态开关 防止异常使用 */
private static boolean IS_INIT; private static boolean IS_INIT;
/** /**
* userId * userId
* @param userId ID * @param userId ID
* @return model * @return List
*/ */
public static UserOrgRefModel getOrgByUserId(String userId){ public static List<UserOrgRefModel> getOrgListByUserId(String userId){
// 判断 工具类是否初始化完成 // 判断 工具类是否初始化完成
ThrowExceptionUtil.isThrowException(!IS_INIT, ThrowExceptionUtil.isThrowException(!IS_INIT,
CoreMsg.OTHER_EXCEPTION_UTILS_INIT); CoreMsg.OTHER_EXCEPTION_UTILS_INIT);
@ -63,56 +85,160 @@ public class OrgUtil {
// 缓存Key // 缓存Key
String cacheKey = PREFIX_CODE + userId; String cacheKey = PREFIX_CODE + userId;
List<UserOrgRefModel> orgList;
// 先从缓存里拿 // 先从缓存里拿
UserOrgRefModel orgRefModel = CacheUtil.getTimed(UserOrgRefModel.class, cacheKey); Object obj = CacheUtil.getTimed(cacheKey);
if (orgRefModel != null){ orgList = Convert.toList(UserOrgRefModel.class, obj);
return orgRefModel; if(CollUtil.isNotEmpty(orgList)){
return orgList;
} }
// 拿不到 -------- // 拿不到 --------
// 防止缓存穿透判断 // 防止缓存穿透判断
boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey); boolean hasNilFlag = CacheUtil.hasNilFlag(cacheKey);
if(hasNilFlag){ if(hasNilFlag){
return null; return ListUtil.empty();
} }
try { try {
// 分布式加锁 // 分布式加锁
if(!DistributedLockUtil.lock(cacheKey)){ if(!DistributedLockUtil.lock(cacheKey)){
// 无法申领分布式锁 // 无法申领分布式锁
log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage()); log.error(CoreMsg.REDIS_EXCEPTION_LOCK.getMessage());
return null; return ListUtil.empty();
} }
// 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求 // 如果获得锁 则 再次检查缓存里有没有, 如果有则直接退出, 没有的话才发起数据库请求
orgRefModel = CacheUtil.getTimed(UserOrgRefModel.class, cacheKey); obj = CacheUtil.getTimed(cacheKey);
if (orgRefModel != null){ orgList = Convert.toList(UserOrgRefModel.class, obj);
return orgRefModel; if(CollUtil.isNotEmpty(orgList)){
return orgList;
} }
// 查询数据库 // 查询数据库
ResultVo<UserOrgRefModel> resultVo = userApi.getOrgInfoByUserId(userId); ResultVo<List<UserOrgRefModel>> resultVo = userOrgRefApi.findListByUserId(userId);
if(resultVo.isSuccess()){ if(resultVo.isSuccess()){
orgRefModel = resultVo.getData(); orgList = resultVo.getData();
// 存入缓存 // 存入缓存
CacheUtil.put(cacheKey, orgRefModel); CacheUtil.put(cacheKey, orgList);
} }
}catch (Exception e){ }catch (Exception e){
log.error(e.getMessage(),e); log.error(e.getMessage(), e);
}finally { }finally {
// 释放锁 // 释放锁
DistributedLockUtil.unlock(cacheKey); DistributedLockUtil.unlock(cacheKey);
} }
if(orgRefModel == null){ if(CollUtil.isEmpty(orgList)){
// 设置空变量 用于防止穿透判断 // 设置空变量 用于防止穿透判断
CacheUtil.putNilFlag(cacheKey); CacheUtil.putNilFlag(cacheKey);
return null; return ListUtil.empty();
} }
return orgRefModel; return orgList;
} }
/**
*
* @param parentId ID
* @param orgModelList
* @return List
*/
public static List<SysOrgModel> createDefShowNodes(String parentId, List<SysOrgModel> orgModelList) {
// 显示全部
SysOrgModel orgAll = new SysOrgModel();
orgAll.setId(ORG_ALL);
orgAll.setOrgName("全部");
orgAll.setParentId(parentId);
orgAll.setSortNo(-2);
orgModelList.add(orgAll);
// 未分组
SysOrgModel orgNull = new SysOrgModel();
orgNull.setId(ORG_NULL);
orgNull.setOrgName("未分组");
orgNull.setParentId(parentId);
orgNull.setSortNo(-1);
orgModelList.add(orgNull);
return orgModelList;
}
/**
* ID
* @param orgIdGroup ID
* @param queryWrapper
*/
public static void handleOrgIdGroupCondition(String orgIdGroup, QueryWrapper<?> queryWrapper) {
String userRefOrgField = "b.org_ids";
queryWrapper.and(wra -> {
if(!ORG_NULL.equals(orgIdGroup)){
wra.and(wraConfine -> {
// 增加自身 组织限制
UserModel currUser = UserUtil.getUser();
List<UserOrgRefModel> orgListByUserId = OrgUtil.getOrgListByUserId(currUser.getId());
if(CollUtil.isEmpty(orgListByUserId)){
// 如果为空 则默认 不查询
wraConfine.eq("1", "2");
}else {
List<String> parentIdList = Lists.newArrayListWithCapacity(orgListByUserId.size());
// 处理ParentId数据
for (UserOrgRefModel userOrgRefModel : orgListByUserId) {
parentIdList.add(userOrgRefModel.getOrgIds());
}
// 去重
parentIdList = ListDistinctUtil.distinct(parentIdList);
// 增加右模糊 查询条件
for (int i = 0; i < parentIdList.size(); i++) {
// 右模糊匹配
wraConfine.likeRight(
userRefOrgField,
parentIdList.get(i));
if(i < parentIdList.size() - 1){
wraConfine.or();
}
}
}
});
}
// 放在后面 前面会报错
switch (orgIdGroup){
case ORG_ALL:
wra.and(wraAll -> {
wraAll.eq(FieldUtil.humpToUnderline(USER_ORG_FIELD),
DictType.NO_YES_YES.getValue());
});
wra.or(wraAll -> {
wraAll.eq(FieldUtil.humpToUnderline(USER_ORG_FIELD),
DictType.NO_YES_NO.getValue());
});
break;
case ORG_NULL:
wra.and(wraNo -> {
wraNo.eq(FieldUtil.humpToUnderline(USER_ORG_FIELD),
DictType.NO_YES_NO.getValue());
});
break;
default:
// 右模糊匹配
wra.likeRight(
userRefOrgField, orgIdGroup);
wra.and(wraYes -> {
wraYes.eq(FieldUtil.humpToUnderline(USER_ORG_FIELD),
DictType.NO_YES_YES.getValue());
});
break;
}
});
}
// ============== 刷新缓存 ============== // ============== 刷新缓存 ==============
@ -133,7 +259,7 @@ public class OrgUtil {
// 计数器 // 计数器
int count = 0; int count = 0;
UserOrgRefModel orgRefModel = CacheUtil.getTimed(UserOrgRefModel.class, PREFIX_CODE + userId); UserOrgRefWebModel orgRefModel = CacheUtil.getTimed(UserOrgRefWebModel.class, PREFIX_CODE + userId);
boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE + userId); boolean hasNilFlag = CacheUtil.hasNilFlag(PREFIX_CODE + userId);
// 只要不为空 则执行刷新 // 只要不为空 则执行刷新
@ -164,8 +290,8 @@ public class OrgUtil {
* *
*/ */
@Autowired @Autowired
public void init(UserApi userApi) { public void init(UserOrgRefApi userOrgRefApi) {
OrgUtil.userApi = userApi; OrgUtil.userOrgRefApi = userOrgRefApi;
IS_INIT = true; IS_INIT = true;
} }

@ -49,6 +49,6 @@ public class SysArea extends BaseEntity {
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
} }

@ -42,6 +42,7 @@ import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.annotation.EnableLog; import org.opsli.common.annotation.EnableLog;
import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.constants.TreeConstants;
import org.opsli.common.utils.FieldUtil; import org.opsli.common.utils.FieldUtil;
import org.opsli.core.base.controller.BaseRestController; import org.opsli.core.base.controller.BaseRestController;
import org.opsli.core.base.entity.HasChildren; import org.opsli.core.base.entity.HasChildren;
@ -74,8 +75,6 @@ import java.util.Set;
public class SysAreaRestController extends BaseRestController<SysArea, SysAreaModel, ISysAreaService> public class SysAreaRestController extends BaseRestController<SysArea, SysAreaModel, ISysAreaService>
implements SysAreaRestApi { implements SysAreaRestApi {
/** 是否包含子集 */
private static final String HAS_CHILDREN = "hasChildren";
/** 排序字段 */ /** 排序字段 */
private static final String SORT_FIELD = "sortNo"; private static final String SORT_FIELD = "sortNo";
@ -122,7 +121,8 @@ public class SysAreaRestController extends BaseRestController<SysArea, SysAreaMo
List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(beanMapList, parentId, treeNodeConfig); List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(beanMapList, parentId, treeNodeConfig);
// 处理是否包含子集 // 处理是否包含子集
this.handleTreeHasChildren(treeNodes); super.handleTreeHasChildren(treeNodes,
(parentIds)-> IService.hasChildren(parentIds));
return ResultVo.success(treeNodes); return ResultVo.success(treeNodes);
} }
@ -156,7 +156,8 @@ public class SysAreaRestController extends BaseRestController<SysArea, SysAreaMo
List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(beanMapList, treeNodeConfig); List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(beanMapList, treeNodeConfig);
// 处理是否包含子集 // 处理是否包含子集
this.handleTreeHasChildren(treeNodes); super.handleTreeHasChildren(treeNodes,
(parentIds)-> IService.hasChildren(parentIds));
return ResultVo.success(treeNodes); return ResultVo.success(treeNodes);
} }
@ -309,39 +310,6 @@ public class SysAreaRestController extends BaseRestController<SysArea, SysAreaMo
return beanMapList; return beanMapList;
} }
/**
*
* @param treeNodes
*/
private void handleTreeHasChildren(List<Tree<Object>> treeNodes) {
if(CollUtil.isEmpty(treeNodes)){
return;
}
Set<String> parentIds = Sets.newHashSet();
for (Tree<Object> treeNode : treeNodes) {
parentIds.add(Convert.toStr(treeNode.getId()));
}
// 数据排查是否存在下级
List<HasChildren> hasChildrenList = IService.hasChildren(parentIds);
if (CollUtil.isNotEmpty(hasChildrenList)) {
Map<String, Boolean> tmp = Maps.newHashMap();
for (HasChildren hasChildren : hasChildrenList) {
if (hasChildren.getCount() != null && hasChildren.getCount() > 0) {
tmp.put(hasChildren.getParentId(), true);
}
}
for (Tree<Object> treeNode : treeNodes) {
Boolean tmpFlag = tmp.get(Convert.toStr(treeNode.getId()));
if (tmpFlag != null && tmpFlag) {
treeNode.putExtra(HAS_CHILDREN, true);
}
}
}
}
/** /**
* *

@ -52,6 +52,6 @@ public class SysDict extends BaseEntity {
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
} }

@ -60,6 +60,6 @@ public class SysDictDetail extends BaseEntity {
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
} }

@ -74,6 +74,6 @@ public class SysMenu extends BaseEntity {
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
} }

@ -25,7 +25,6 @@ import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -41,10 +40,10 @@ import org.opsli.common.annotation.EnableLog;
import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.constants.MenuConstants; import org.opsli.common.constants.MenuConstants;
import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.enums.DictType;
import org.opsli.common.utils.FieldUtil; import org.opsli.common.utils.FieldUtil;
import org.opsli.common.utils.WrapperUtil; import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.base.controller.BaseRestController; import org.opsli.core.base.controller.BaseRestController;
import org.opsli.core.base.entity.HasChildren;
import org.opsli.core.general.StartPrint; import org.opsli.core.general.StartPrint;
import org.opsli.core.persistence.Page; import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
@ -63,7 +62,6 @@ import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
@ -83,10 +81,6 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
/** 排序字段 */ /** 排序字段 */
private static final String SORT_FIELD = "order"; private static final String SORT_FIELD = "order";
/** 是否包含子集 */
private static final String HAS_CHILDREN = "hasChildren";
/** 是否是叶子节点 */
private static final String IS_LEAF = "isLeaf";
/** 虚拟总节点 ID */ /** 虚拟总节点 ID */
private static final String VIRTUAL_TOTAL_NODE = "-1"; private static final String VIRTUAL_TOTAL_NODE = "-1";
@ -114,7 +108,8 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
// 这里有坑 如果 为 菜单数据 且 组件(Component)地址为空 不会跳转到主页 也不报错 // 这里有坑 如果 为 菜单数据 且 组件(Component)地址为空 不会跳转到主页 也不报错
// 修复菜单问题导致无法跳转主页 // 修复菜单问题导致无法跳转主页
menuModelList.removeIf(menuModel -> MenuConstants.MENU.equals(menuModel.getType()) && menuModelList.removeIf(
menuModel -> MenuConstants.MENU.equals(menuModel.getType()) &&
(StringUtils.isEmpty(menuModel.getComponent()) || (StringUtils.isEmpty(menuModel.getComponent()) ||
StringUtils.isEmpty(menuModel.getUrl()) StringUtils.isEmpty(menuModel.getUrl())
)); ));
@ -142,7 +137,8 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
// 这里有坑 如果 为 菜单数据 且 组件(Component)地址为空 不会跳转到主页 也不报错 // 这里有坑 如果 为 菜单数据 且 组件(Component)地址为空 不会跳转到主页 也不报错
// 修复菜单问题导致无法跳转主页 // 修复菜单问题导致无法跳转主页
menuModelList.removeIf(menuModel -> MenuConstants.MENU.equals(menuModel.getType()) && menuModelList.removeIf(
menuModel -> MenuConstants.MENU.equals(menuModel.getType()) &&
(StringUtils.isEmpty(menuModel.getComponent()) || (StringUtils.isEmpty(menuModel.getComponent()) ||
StringUtils.isEmpty(menuModel.getUrl()) StringUtils.isEmpty(menuModel.getUrl())
)); ));
@ -167,14 +163,8 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
List<MenuModel> menuModelList; List<MenuModel> menuModelList;
if(StringUtils.isEmpty(parentId)){ if(StringUtils.isEmpty(parentId)){
menuModelList = Lists.newArrayList(); menuModelList = Lists.newArrayList();
parentId = VIRTUAL_TOTAL_NODE; // 生成根节点菜单
MenuModel model = new MenuModel(); MenuModel model = getGenMenuModel();
model.setId(MenuConstants.GEN_ID);
model.setMenuName("根节点");
model.setHidden("0");
model.setSortNo(-1);
model.setType("1");
model.setParentId(parentId);
menuModelList.add(model); menuModelList.add(model);
}else{ }else{
// 只查菜单 // 只查菜单
@ -182,7 +172,7 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
QueryWrapper<SysMenu> queryWrapper = queryBuilder.build(); QueryWrapper<SysMenu> queryWrapper = queryBuilder.build();
queryWrapper.eq( queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId); FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId);
queryWrapper.eq("type", "1"); queryWrapper.eq("type", MenuConstants.MENU);
// 如果传入ID 则不包含自身 // 如果传入ID 则不包含自身
if(StringUtils.isNotEmpty(id)){ if(StringUtils.isNotEmpty(id)){
@ -200,7 +190,8 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
List<Tree<Object>> treeNodes = getMenuTrees(menuModelList, parentId,1); List<Tree<Object>> treeNodes = getMenuTrees(menuModelList, parentId,1);
// 处理是否包含子集 // 处理是否包含子集
this.handleTreeIsLeafByChoose(treeNodes); super.handleTreeHasChildren(treeNodes,
(parentIds)-> IService.hasChildrenByChoose(parentIds));
return ResultVo.success(treeNodes); return ResultVo.success(treeNodes);
} }
@ -216,14 +207,8 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
List<MenuModel> menuModelList; List<MenuModel> menuModelList;
if(StringUtils.isEmpty(parentId)){ if(StringUtils.isEmpty(parentId)){
menuModelList = Lists.newArrayList(); menuModelList = Lists.newArrayList();
parentId = VIRTUAL_TOTAL_NODE; // 生成根节点菜单
MenuModel model = new MenuModel(); MenuModel model = getGenMenuModel();
model.setId(MenuConstants.GEN_ID);
model.setMenuName("根节点");
model.setHidden("0");
model.setSortNo(-1);
model.setType("1");
model.setParentId(parentId);
menuModelList.add(model); menuModelList.add(model);
}else{ }else{
QueryBuilder<SysMenu> queryBuilder = new GenQueryBuilder<>(); QueryBuilder<SysMenu> queryBuilder = new GenQueryBuilder<>();
@ -238,7 +223,8 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
List<Tree<Object>> treeNodes = getMenuTrees(menuModelList, parentId,1); List<Tree<Object>> treeNodes = getMenuTrees(menuModelList, parentId,1);
// 处理是否包含子集 // 处理是否包含子集
this.handleTreeHasChildren(treeNodes); super.handleTreeHasChildren(treeNodes,
(parentIds)-> IService.hasChildren(parentIds));
return ResultVo.success(treeNodes); return ResultVo.success(treeNodes);
} }
@ -251,11 +237,9 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
@RequiresPermissions("system_menu_select") @RequiresPermissions("system_menu_select")
@Override @Override
public ResultVo<?> findMenuTreePage(HttpServletRequest request) { public ResultVo<?> findMenuTreePage(HttpServletRequest request) {
QueryBuilder<SysMenu> queryBuilder = new WebQueryBuilder<>(entityClazz, QueryBuilder<SysMenu> queryBuilder = new WebQueryBuilder<>(entityClazz,
request.getParameterMap()); request.getParameterMap());
// 获得菜单 // 获得菜单
List<SysMenu> menuList = IService.findList(queryBuilder.build()); List<SysMenu> menuList = IService.findList(queryBuilder.build());
List<MenuModel> menuModelList = WrapperUtil.transformInstance(menuList, MenuModel.class); List<MenuModel> menuModelList = WrapperUtil.transformInstance(menuList, MenuModel.class);
@ -292,11 +276,8 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
public ResultVo<MenuModel> get(MenuModel model) { public ResultVo<MenuModel> get(MenuModel model) {
if(model != null){ if(model != null){
if(StringUtils.equals(MenuConstants.GEN_ID, model.getId())){ if(StringUtils.equals(MenuConstants.GEN_ID, model.getId())){
model.setMenuName("根节点"); // 生成根节点菜单
model.setHidden("0"); model = getGenMenuModel();
model.setSortNo(-1);
model.setType("1");
model.setParentId(VIRTUAL_TOTAL_NODE);
}else{ }else{
// 如果系统内部调用 则直接查数据库 // 如果系统内部调用 则直接查数据库
if (model.getIzApi() != null && model.getIzApi()){ if (model.getIzApi() != null && model.getIzApi()){
@ -589,72 +570,19 @@ public class MenuRestController extends BaseRestController<SysMenu, MenuModel, I
return TreeBuildUtil.INSTANCE.build(beanMapList, treeNodeConfig); return TreeBuildUtil.INSTANCE.build(beanMapList, treeNodeConfig);
} }
/** /**
* *
* @param treeNodes * @return MenuModel
*/ */
private void handleTreeHasChildren(List<Tree<Object>> treeNodes) { private MenuModel getGenMenuModel() {
if(CollUtil.isEmpty(treeNodes)){ MenuModel model = new MenuModel();
return; model.setId(MenuConstants.GEN_ID);
} model.setMenuName("根菜单");
model.setHidden(DictType.NO_YES_NO.getValue());
Set<String> parentIds = Sets.newHashSet(); model.setSortNo(-1);
for (Tree<Object> treeNode : treeNodes) { model.setType(MenuConstants.MENU);
parentIds.add(Convert.toStr(treeNode.getId())); model.setParentId(VIRTUAL_TOTAL_NODE);
} return model;
// 数据排查是否存在下级
List<HasChildren> hasChildrenList = IService.hasChildren(parentIds);
if (CollUtil.isNotEmpty(hasChildrenList)) {
Map<String, Boolean> tmp = Maps.newHashMap();
for (HasChildren hasChildren : hasChildrenList) {
if (hasChildren.getCount() != null && hasChildren.getCount() > 0) {
tmp.put(hasChildren.getParentId(), true);
}
}
for (Tree<Object> treeNode : treeNodes) {
Boolean tmpFlag = tmp.get(Convert.toStr(treeNode.getId()));
if (tmpFlag != null && tmpFlag) {
treeNode.putExtra(HAS_CHILDREN, true);
}
}
}
}
/**
*
* @param treeNodes
*/
private void handleTreeIsLeafByChoose(List<Tree<Object>> treeNodes) {
if(CollUtil.isEmpty(treeNodes)){
return;
}
Set<String> parentIds = Sets.newHashSet();
for (Tree<Object> treeNode : treeNodes) {
parentIds.add(Convert.toStr(treeNode.getId()));
}
// 数据排查是否存在下级
List<HasChildren> hasChildrenList = IService.hasChildrenByChoose(parentIds);
Map<String, Boolean> tmp = Maps.newHashMap();
for (HasChildren hasChildren : hasChildrenList) {
if (hasChildren.getCount() != null && hasChildren.getCount() > 0) {
tmp.put(hasChildren.getParentId(), false);
}
}
for (Tree<Object> treeNode : treeNodes) {
Boolean tmpFlag = tmp.get(Convert.toStr(treeNode.getId()));
if (tmpFlag == null || tmpFlag) {
treeNode.putExtra(IS_LEAF, true);
}else {
treeNode.putExtra(IS_LEAF, false);
}
}
} }
/** /**

@ -33,29 +33,31 @@ import org.opsli.core.base.entity.BaseEntity;
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class SysOrg extends BaseEntity { public class SysOrg extends BaseEntity {
/** 父级主键 */ /** 父级主键 */
private String parentId; private String parentId;
/** 父级主键集合 xxx,xxx */
private String parentIds;
/** 组织机构编号 */ /** 组织机构编号 */
private String orgCode; private String orgCode;
/** 组织机构名称 */ /** 组织机构名称 */
private String orgName; private String orgName;
/** 组织机构类型: 1-公司 2-部门 3-岗位 */
private String orgType;
/** 排序 */ /** 排序 */
private Integer sortNo; private Integer sortNo;
/** 备注 */
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String remark;
// ======================================== // ========================================
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
/** 多租户字段 */ /** 多租户字段 */
private String tenantId; private String tenantId;

@ -1,23 +1,24 @@
/** /**
* Copyright 2020 OPSLI https://www.opsli.com * Copyright 2020 OPSLI https://www.opsli.com
* <p> * <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not * Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of * use this file except in compliance with the License. You may obtain a copy of
* the License at * the License at
* <p> * <p>
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* <p> * <p>
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under * License for the specific language governing permissions and limitations under
* the License. * the License.
*/ */
package org.opsli.modulars.system.org.service.impl; package org.opsli.modulars.system.org.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert; import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -30,7 +31,7 @@ import org.opsli.core.base.entity.HasChildren;
import org.opsli.core.base.service.impl.CrudServiceImpl; import org.opsli.core.base.service.impl.CrudServiceImpl;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.chain.TenantHandler; import org.opsli.core.persistence.querybuilder.chain.QueryTenantHandler;
import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.SystemMsg;
import org.opsli.modulars.system.org.entity.SysOrg; import org.opsli.modulars.system.org.entity.SysOrg;
import org.opsli.modulars.system.org.mapper.SysOrgMapper; import org.opsli.modulars.system.org.mapper.SysOrgMapper;
@ -52,10 +53,12 @@ import java.util.Set;
*/ */
@Service @Service
public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, SysOrgModel> public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, SysOrgModel>
implements ISysOrgService { implements ISysOrgService {
/** 顶级ID */ /** 顶级ID */
private static final String TOP_PARENT_ID = "0"; private static final String TOP_PARENT_ID = "0";
/** 分割符 */
private static final String DELIMITER = ",";
@Autowired(required = false) @Autowired(required = false)
private SysOrgMapper mapper; private SysOrgMapper mapper;
@ -67,6 +70,8 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
return null; return null;
} }
model.setParentIds(null);
// 唯一验证 // 唯一验证
Integer count = this.uniqueVerificationByCode(model); Integer count = this.uniqueVerificationByCode(model);
if(count != null && count > 0){ if(count != null && count > 0){
@ -77,15 +82,23 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
// 如果上级ID 为空 则默认为 0 // 如果上级ID 为空 则默认为 0
if(StringUtils.isEmpty(model.getParentId())){ if(StringUtils.isEmpty(model.getParentId())){
model.setParentId(TOP_PARENT_ID); model.setParentId(TOP_PARENT_ID);
model.setParentIds(TOP_PARENT_ID);
} }
// 如果上级ID不为空 且 不等于顶级ID // 如果上级ID不为空 且 不等于顶级ID
if(StringUtils.isNotEmpty(model.getParentId()) && if(StringUtils.isNotEmpty(model.getParentId()) &&
!TOP_PARENT_ID.equals(model.getParentId()) !TOP_PARENT_ID.equals(model.getParentId())
){ ){
// 下级沿用上级租户ID
SysOrgModel sysOrgModel = super.get(model.getParentId()); SysOrgModel sysOrgModel = super.get(model.getParentId());
// 下级沿用上级租户ID
model.setTenantId(sysOrgModel.getTenantId()); model.setTenantId(sysOrgModel.getTenantId());
// 下级沿用上级ParentIds
model.setParentIds(
StrUtil.appendIfMissing(
sysOrgModel.getParentIds(), DELIMITER) +
sysOrgModel.getId());
} }
return super.insert(model); return super.insert(model);
@ -98,6 +111,8 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
return null; return null;
} }
model.setParentIds(null);
// 唯一验证 // 唯一验证
Integer count = this.uniqueVerificationByCode(model); Integer count = this.uniqueVerificationByCode(model);
if(count != null && count > 0){ if(count != null && count > 0){
@ -108,13 +123,22 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
// 如果上级ID不为空 且 不等于顶级ID // 如果上级ID不为空 且 不等于顶级ID
if(StringUtils.isNotEmpty(model.getParentId()) && if(StringUtils.isNotEmpty(model.getParentId()) &&
!TOP_PARENT_ID.equals(model.getParentId()) !TOP_PARENT_ID.equals(model.getParentId())
){ ){
// 下级沿用上级租户ID
SysOrgModel sysOrgModel = super.get(model.getParentId()); SysOrgModel sysOrgModel = super.get(model.getParentId());
// 下级沿用上级租户ID
model.setTenantId(sysOrgModel.getTenantId()); model.setTenantId(sysOrgModel.getTenantId());
// 下级沿用上级ParentIds
model.setParentIds(
StrUtil.appendIfMissing(
sysOrgModel.getParentIds(), DELIMITER) +
sysOrgModel.getId());
} }
SysOrgModel sysOrgModel = super.get(model); SysOrgModel sysOrgModel = super.get(model);
SysOrgModel updateRet = super.update(model);
// 如果 TenantId 发生变化 则需要更改 下级数据 租户ID // 如果 TenantId 发生变化 则需要更改 下级数据 租户ID
if(sysOrgModel != null && !sysOrgModel.getTenantId().equals( if(sysOrgModel != null && !sysOrgModel.getTenantId().equals(
model.getTenantId())){ model.getTenantId())){
@ -125,8 +149,18 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
this.updateTenantByParentId(sysOrgModel.getId(), model.getTenantId()); this.updateTenantByParentId(sysOrgModel.getId(), model.getTenantId());
} }
// 如果 parentId 发生变化 则需要更改 下级数据 租户ID
if(sysOrgModel != null && !sysOrgModel.getParentId().equals(
model.getParentId())){
// 如果有组织还在被引用 则不允许操作该组织
this.validationUsedByDel(Collections.singletonList(sysOrgModel.getId()));
// 如果没有被引用 则逐级修改
this.updateChildrenParentIdsByParentId(sysOrgModel.getId());
}
// 修改 // 修改
return super.update(model); return updateRet;
} }
@ -172,7 +206,8 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
public void updateTenantByParentId(String parentId, String tenantId) { public void updateTenantByParentId(String parentId, String tenantId) {
QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>(); QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>();
QueryWrapper<SysOrg> queryWrapper = queryBuilder.build(); QueryWrapper<SysOrg> queryWrapper = queryBuilder.build();
queryWrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId); queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId);
List<SysOrg> entityList = super.findList(queryWrapper); List<SysOrg> entityList = super.findList(queryWrapper);
for (SysOrg sysOrg : entityList) { for (SysOrg sysOrg : entityList) {
sysOrg.setTenantId(tenantId); sysOrg.setTenantId(tenantId);
@ -182,6 +217,32 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
} }
} }
/**
*
* @param parentId ID
*/
@Transactional(rollbackFor = Exception.class)
public void updateChildrenParentIdsByParentId(String parentId) {
QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>();
QueryWrapper<SysOrg> queryWrapper = queryBuilder.build();
queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId);
List<SysOrg> entityList = super.findList(queryWrapper);
for (SysOrg sysOrg : entityList) {
SysOrgModel sysOrgModel = super.get(parentId);
// 下级沿用上级ParentIds
sysOrg.setParentIds(
StrUtil.appendIfMissing(
sysOrgModel.getParentIds(), DELIMITER) +
sysOrgModel.getId());
super.updateById(sysOrg);
// 逐级删除子数据
this.updateChildrenParentIdsByParentId(sysOrg.getId());
}
}
/** /**
* *
* @param parentId ID * @param parentId ID
@ -190,7 +251,8 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
public void deleteByParentId(String parentId) { public void deleteByParentId(String parentId) {
QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>(); QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>();
QueryWrapper<SysOrg> queryWrapper = queryBuilder.build(); QueryWrapper<SysOrg> queryWrapper = queryBuilder.build();
queryWrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId); queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId);
List<SysOrg> entityList = super.findList(queryWrapper); List<SysOrg> entityList = super.findList(queryWrapper);
for (SysOrg sysOrg : entityList) { for (SysOrg sysOrg : entityList) {
super.delete(sysOrg.getId()); super.delete(sysOrg.getId());
@ -219,7 +281,7 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
} }
// 租户检测 // 租户检测
wrapper = new TenantHandler().handler(super.entityClazz, wrapper); wrapper = new QueryTenantHandler().handler(super.entityClazz, wrapper);
return super.count(wrapper); return super.count(wrapper);
} }
@ -237,7 +299,6 @@ public class SysOrgServiceImpl extends CrudServiceImpl<SysOrgMapper, SysOrg, Sys
return null; return null;
} }
QueryWrapper<SysOrg> wrapper = new QueryWrapper<>(); QueryWrapper<SysOrg> wrapper = new QueryWrapper<>();
wrapper.in(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentIds) wrapper.in(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentIds)
.eq(MyBatisConstants.FIELD_DELETE_LOGIC, DictType.NO_YES_NO.getValue()) .eq(MyBatisConstants.FIELD_DELETE_LOGIC, DictType.NO_YES_NO.getValue())
.groupBy(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID)); .groupBy(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID));

@ -20,28 +20,34 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig; import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Maps; import com.google.common.collect.Lists;
import com.google.common.collect.Sets; import com.google.common.collect.Sets;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.opsli.api.base.result.ResultVo; import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.org.SysOrgRestApi; import org.opsli.api.web.system.org.SysOrgRestApi;
import org.opsli.api.wrapper.system.org.SysOrgModel; import org.opsli.api.wrapper.system.org.SysOrgModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.common.annotation.ApiRestController; import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.annotation.EnableLog; import org.opsli.common.annotation.EnableLog;
import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.utils.FieldUtil; import org.opsli.common.utils.FieldUtil;
import org.opsli.common.utils.ListDistinctUtil;
import org.opsli.common.utils.WrapperUtil; import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.base.controller.BaseRestController; import org.opsli.core.base.controller.BaseRestController;
import org.opsli.core.base.entity.HasChildren;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
import org.opsli.core.utils.OrgUtil;
import org.opsli.core.utils.TreeBuildUtil; import org.opsli.core.utils.TreeBuildUtil;
import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.org.entity.SysOrg; import org.opsli.modulars.system.org.entity.SysOrg;
import org.opsli.modulars.system.org.service.ISysOrgService; import org.opsli.modulars.system.org.service.ISysOrgService;
import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.multipart.MultipartHttpServletRequest;
@ -50,7 +56,6 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
@ -65,117 +70,161 @@ import java.util.Set;
public class SysOrgRestController extends BaseRestController<SysOrg, SysOrgModel, ISysOrgService> public class SysOrgRestController extends BaseRestController<SysOrg, SysOrgModel, ISysOrgService>
implements SysOrgRestApi { implements SysOrgRestApi {
/** 虚拟总节点 ID */
private static final String VIRTUAL_TOTAL_NODE = "-1";
/** 父节点ID */ /** 父节点ID */
private static final String PARENT_ID = "0"; private static final String PARENT_ID = "0";
/** 显示全部 */
public static final String ORG_ALL = "all";
/** 未分组 */
public static final String ORG_NULL = "org_null";
/** 排序字段 */ /** 排序字段 */
private static final String SORT_FIELD = "sortNo"; private static final String SORT_FIELD = "sortNo";
/** 是否包含子集 */ /** 分割符 */
private static final String HAS_CHILDREN = "hasChildren"; private static final String DELIMITER = ",";
/** /**
* *
* @return ResultVo * @return ResultVo
*/ */
@ApiOperation(value = "获得组织树 懒加载", notes = "获得组织树 懒加载") @ApiOperation(value = "获得当前用户下 组织", notes = "获得当前用户下 组织")
@Override @Override
public ResultVo<?> findTreeLazyByUser(String parentId) { public ResultVo<?> findTreeByDefWithUserToLike() {
// 生成 全部/未分组
String parentId = PARENT_ID;
List<SysOrgModel> orgModelList = OrgUtil.createDefShowNodes(parentId, Lists.newArrayList());
QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>(); QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>();
QueryWrapper<SysOrg> wrapper = queryBuilder.build(); QueryWrapper<SysOrg> wrapper = queryBuilder.build();
wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId); UserModel currUser = UserUtil.getUser();
List<UserOrgRefModel> orgListByUserId = OrgUtil.getOrgListByUserId(currUser.getId());
// 获得用户 对应菜单 if(!CollUtil.isEmpty(orgListByUserId)){
List<SysOrg> dataList = IService.findList(wrapper); List<String> parentIdList = Lists.newArrayListWithCapacity(orgListByUserId.size());
List<SysOrgModel> orgModelList = WrapperUtil.transformInstance(dataList, modelClazz);
// 处理ParentId数据
// 处理展示节点 for (UserOrgRefModel userOrgRefModel : orgListByUserId) {
this.handleShowNodes(parentId, orgModelList); String orgId = userOrgRefModel.getOrgId();
String orgIds = userOrgRefModel.getOrgIds();
//配置 // 减掉 结尾自身 orgId 得到 org表中 parentIds
TreeNodeConfig treeNodeConfig = new TreeNodeConfig(); String parentIds =
// 自定义属性名 都要默认值的 StrUtil.replace(orgIds, StrUtil.prependIfMissing(orgId, DELIMITER), "");
treeNodeConfig.setWeightKey(SORT_FIELD); parentIdList.add(parentIds);
// 最大递归深度 最多支持4层菜单 }
treeNodeConfig.setDeep(3);
//转换器
List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(orgModelList, parentId, treeNodeConfig);
// 处理是否包含子集 // 去重
this.handleTreeHasChildren(treeNodes); parentIdList = ListDistinctUtil.distinct(parentIdList);
List<String> finalParentIdList = parentIdList;
wrapper.and(wra -> {
// 增加右模糊 查询条件
for (int i = 0; i < finalParentIdList.size(); i++) {
// 右模糊匹配
wra.likeRight(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_IDS),
finalParentIdList.get(i));
if(i < finalParentIdList.size() - 1){
wra.or();
}
}
});
// 获得组织
List<SysOrg> dataList = IService.findList(wrapper);
if(CollUtil.isNotEmpty(dataList)){
for (SysOrg sysOrg : dataList) {
// 如果父级ID 与 当前检索父级ID 一致 则默认初始化ID为主ID
if(!CollUtil.contains(parentIdList, sysOrg.getParentIds())){
continue;
}
sysOrg.setParentId(parentId);
}
orgModelList.addAll(
WrapperUtil.transformInstance(dataList, modelClazz)
);
}
}
return ResultVo.success(treeNodes); // 处理组织树
return handleOrgTree(parentId, orgModelList, false);
} }
/** /**
* *
* @return ResultVo * @return ResultVo
*/ */
@ApiOperation(value = "获得组织树 懒加载", notes = "获得组织树 懒加载") @ApiOperation(value = "获得组织树 懒加载", notes = "获得组织树 懒加载")
@Override @Override
public ResultVo<?> findTreeLazy(String parentId) { public ResultVo<?> findTreeLazy(String parentId, String id) {
List<SysOrgModel> orgModelList;
QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>(); if(StringUtils.isEmpty(parentId)){
QueryWrapper<SysOrg> wrapper = queryBuilder.build(); orgModelList = Lists.newArrayList();
wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId); parentId = VIRTUAL_TOTAL_NODE;
// 生成根节点组织
// 获得用户 对应菜单 SysOrgModel model = getGenOrgModel();
List<SysOrg> dataList = IService.findList(wrapper); orgModelList.add(model);
List<SysOrgModel> orgModelList = WrapperUtil.transformInstance(dataList, modelClazz); }else{
QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>();
QueryWrapper<SysOrg> wrapper = queryBuilder.build();
//配置 wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId);
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的 // 如果传入ID 则不包含自身
treeNodeConfig.setWeightKey(SORT_FIELD); if(StringUtils.isNotEmpty(id)){
// 最大递归深度 最多支持4层菜单 wrapper.notIn(
treeNodeConfig.setDeep(3); FieldUtil.humpToUnderline(MyBatisConstants.FIELD_ID), id);
//转换器 }
List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(orgModelList, parentId, treeNodeConfig);
// 处理是否包含子集 // 获得组织
this.handleTreeHasChildren(treeNodes); List<SysOrg> dataList = IService.findList(wrapper);
orgModelList = WrapperUtil.transformInstance(dataList, modelClazz);
}
return ResultVo.success(treeNodes); // 处理组织树
return handleOrgTree(parentId, orgModelList, true);
} }
/** /**
* *
* @return ResultVo * @return ResultVo
*/ */
@ApiOperation(value = "获得组织树", notes = "获得组织树") @ApiOperation(value = "获得组织树", notes = "获得组织树")
@RequiresPermissions("system_org_select")
@Override @Override
public ResultVo<?> findGridTree(String parentId) { public ResultVo<?> findTreeByDef(boolean isGen, String id) {
List<SysOrgModel> orgModelList = Lists.newArrayList();
String parentId = PARENT_ID;
if(isGen){
parentId = VIRTUAL_TOTAL_NODE;
// 生成根节点组织
SysOrgModel model = getGenOrgModel();
orgModelList.add(model);
}
QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>(); QueryBuilder<SysOrg> queryBuilder = new GenQueryBuilder<>();
QueryWrapper<SysOrg> wrapper = queryBuilder.build(); QueryWrapper<SysOrg> wrapper = queryBuilder.build();
wrapper.eq(FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), parentId); // // 左模糊匹配
// wrapper.likeLeft(
// FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_IDS), parentId);
// 如果传入ID 则不包含自身
if(StringUtils.isNotEmpty(id)){
wrapper.notIn(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_ID), id);
}
// 获得用户 对应菜单 // 获得组织
List<SysOrg> dataList = IService.findList(wrapper); List<SysOrg> dataList = IService.findList(wrapper);
List<SysOrgModel> orgModelList = WrapperUtil.transformInstance(dataList, modelClazz); if(CollUtil.isNotEmpty(dataList)){
orgModelList.addAll(
WrapperUtil.transformInstance(dataList, modelClazz)
);
}
// 处理组织树
return handleOrgTree(parentId, orgModelList, false);
}
//配置
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的
treeNodeConfig.setWeightKey(SORT_FIELD);
// 最大递归深度 最多支持4层菜单
treeNodeConfig.setDeep(3);
//转换器
List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(orgModelList, parentId, treeNodeConfig);
return ResultVo.success(treeNodes);
}
// ============== // ==============
@ -188,40 +237,19 @@ public class SysOrgRestController extends BaseRestController<SysOrg, SysOrgModel
@RequiresPermissions("system_org_select") @RequiresPermissions("system_org_select")
@Override @Override
public ResultVo<SysOrgModel> get(SysOrgModel model) { public ResultVo<SysOrgModel> get(SysOrgModel model) {
// 如果系统内部调用 则直接查数据库 if(model != null){
if(model != null && model.getIzApi() != null && model.getIzApi()){ if(StringUtils.equals(PARENT_ID, model.getId())){
model = IService.get(model); // 生成根节点组织
model = getGenOrgModel();
}else{
// 如果系统内部调用 则直接查数据库
if (model.getIzApi() != null && model.getIzApi()){
model = IService.get(model);
}
}
} }
return ResultVo.success(model);
}
/**
*
* @return ResultVo
*/
@ApiOperation(value = "获得菜单树", notes = "获得菜单树")
@RequiresPermissions("system_org_select")
@Override
public ResultVo<?> findTree(HttpServletRequest request) {
QueryBuilder<SysOrg> queryBuilder = new WebQueryBuilder<>(entityClazz,
request.getParameterMap());
// 获得用户 对应菜单
List<SysOrg> dataList = IService.findList(queryBuilder.build());
//配置 return ResultVo.success(model);
TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的
treeNodeConfig.setWeightKey(SORT_FIELD);
// 最大递归深度 最多支持4层菜单
treeNodeConfig.setDeep(3);
//转换器
List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(dataList, treeNodeConfig);
return ResultVo.success(treeNodes);
} }
/** /**
@ -342,68 +370,56 @@ public class SysOrgRestController extends BaseRestController<SysOrg, SysOrgModel
// ============================== // ==============================
/** /**
* * ID
* @param parentId ID * @return SysOrgModel
* @param orgModelList
*/ */
private void handleShowNodes(String parentId, List<SysOrgModel> orgModelList) { private SysOrgModel getGenOrgModel() {
// 0 为初始值 SysOrgModel model = new SysOrgModel();
if(PARENT_ID.equals(parentId)){ model.setId(PARENT_ID);
// 显示全部 model.setOrgName("组织架构");
SysOrgModel orgAll = new SysOrgModel(); model.setSortNo(-1);
orgAll.setId(ORG_ALL); model.setParentId(VIRTUAL_TOTAL_NODE);
orgAll.setOrgCode("-2"); return model;
orgAll.setOrgName("全部");
orgAll.setOrgType("-2");
orgAll.setParentId("0");
orgAll.setSortNo(-2);
orgModelList.add(orgAll);
// 未分组
SysOrgModel orgNull = new SysOrgModel();
orgNull.setId(ORG_NULL);
orgNull.setOrgCode("-1");
orgNull.setOrgName("未分组");
orgNull.setOrgType("-1");
orgNull.setParentId("0");
orgNull.setSortNo(-1);
orgModelList.add(orgNull);
}
} }
/** /**
* *
* @param treeNodes * @param parentId ID
* @param orgModelList
* @param izLazy
* @return ResultVo
*/ */
private void handleTreeHasChildren(List<Tree<Object>> treeNodes) { private ResultVo<?> handleOrgTree(String parentId, List<SysOrgModel> orgModelList, boolean izLazy) {
if(CollUtil.isEmpty(treeNodes)){ //配置
return; TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
} // 自定义属性名 都要默认值的
treeNodeConfig.setWeightKey(SORT_FIELD);
// 最大递归深度 最多支持4层
treeNodeConfig.setDeep(4);
Set<String> parentIds = Sets.newHashSet(); //转换器
for (Tree<Object> treeNode : treeNodes) { List<Tree<Object>> treeNodes = TreeBuildUtil.INSTANCE.build(orgModelList, parentId, treeNodeConfig);
parentIds.add(Convert.toStr(treeNode.getId()));
}
// 数据排查是否存在下级 // 是否懒加载
List<HasChildren> hasChildrenList = IService.hasChildren(parentIds); if(izLazy){
if (CollUtil.isNotEmpty(hasChildrenList)) { // 处理是否包含子集
Map<String, Boolean> tmp = Maps.newHashMap(); super.handleTreeHasChildren(treeNodes,
for (HasChildren hasChildren : hasChildrenList) { (parentIds)-> IService.hasChildren(parentIds));
if (hasChildren.getCount() != null && hasChildren.getCount() > 0) { }else{
tmp.put(hasChildren.getParentId(), true); Set<String> parentIdSet = Sets.newHashSet();
} for (SysOrgModel sysOrgModel : orgModelList) {
parentIdSet.add(sysOrgModel.getParentId());
} }
for (Tree<Object> treeNode : treeNodes) { // 处理是否包含子集
Boolean tmpFlag = tmp.get(Convert.toStr(treeNode.getId())); super.handleTreeHasChildren(treeNodes,
if (tmpFlag != null && tmpFlag) { (parentIds)-> IService.hasChildren(parentIdSet));
treeNode.putExtra(HAS_CHILDREN, true);
}
}
} }
return ResultVo.success(treeNodes);
} }
} }

@ -51,7 +51,7 @@ public class SysRole extends BaseEntity {
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
/** 多租户字段 */ /** 多租户字段 */
private String tenantId; private String tenantId;

@ -26,7 +26,8 @@ import org.opsli.common.exception.ServiceException;
import org.opsli.core.base.service.impl.CrudServiceImpl; import org.opsli.core.base.service.impl.CrudServiceImpl;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.chain.TenantHandler; import org.opsli.core.persistence.querybuilder.chain.QueryOrgHandler;
import org.opsli.core.persistence.querybuilder.chain.QueryTenantHandler;
import org.opsli.core.utils.UserUtil; import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.SystemMsg;
import org.opsli.modulars.system.role.entity.SysRole; import org.opsli.modulars.system.role.entity.SysRole;
@ -144,9 +145,10 @@ public class RoleServiceImpl extends CrudServiceImpl<RoleMapper, SysRole, RoleMo
public List<SysRole> findList(QueryWrapper<SysRole> queryWrapper) { public List<SysRole> findList(QueryWrapper<SysRole> queryWrapper) {
// 如果没有租户修改能力 则默认增加租户限制 // 如果没有租户修改能力 则默认增加租户限制
if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){ if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){
// 多租户处理 // 数据处理责任链
TenantHandler tenantHandler = new TenantHandler(); queryWrapper = new QueryTenantHandler(
tenantHandler.handler(entityClazz, queryWrapper); new QueryOrgHandler()
).handler(entityClazz, queryWrapper);
} }
return super.list(queryWrapper); return super.list(queryWrapper);
@ -159,9 +161,10 @@ public class RoleServiceImpl extends CrudServiceImpl<RoleMapper, SysRole, RoleMo
// 如果没有租户修改能力 则默认增加租户限制 // 如果没有租户修改能力 则默认增加租户限制
if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){ if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){
// 多租户处理 // 数据处理责任链
TenantHandler tenantHandler = new TenantHandler(); queryWrapper = new QueryTenantHandler(
tenantHandler.handler(entityClazz, queryWrapper); new QueryOrgHandler()
).handler(entityClazz, queryWrapper);
} }
return super.list(queryWrapper); return super.list(queryWrapper);
@ -188,8 +191,10 @@ public class RoleServiceImpl extends CrudServiceImpl<RoleMapper, SysRole, RoleMo
wrapper.notIn(MyBatisConstants.FIELD_ID, model.getId()); wrapper.notIn(MyBatisConstants.FIELD_ID, model.getId());
} }
// 租户检测 // 数据处理责任链
wrapper = new TenantHandler().handler(super.entityClazz, wrapper); wrapper = new QueryTenantHandler(
new QueryOrgHandler()
).handler(entityClazz, wrapper);
return super.count(wrapper); return super.count(wrapper);
} }

@ -48,6 +48,6 @@ public class SysTenant extends BaseEntity {
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
} }

@ -76,11 +76,14 @@ public class SysUser extends BaseEntity {
@TableField(updateStrategy = FieldStrategy.IGNORED) @TableField(updateStrategy = FieldStrategy.IGNORED)
private String sign; private String sign;
/** 是否存在组织 */
private String izExistOrg;
// ======================================== // ========================================
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
/** 多租户字段 */ /** 多租户字段 */
private String tenantId; private String tenantId;

@ -38,11 +38,13 @@ public class SysUserOrgRef implements Serializable {
/** 用户ID */ /** 用户ID */
private String userId; private String userId;
/** 组织ID */ /** 当前组织 */
private String orgId; private String orgId;
/** 组织类型 */ /** 组织ID集合 xxx,xxx */
private String orgType; private String orgIds;
/** 是否默认 */
private String izDef;
} }

@ -18,11 +18,8 @@ package org.opsli.modulars.system.user.entity;
import com.baomidou.mybatisplus.annotation.FieldStrategy; import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic; import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.core.base.entity.BaseEntity; import org.opsli.core.base.entity.BaseEntity;
/** /**
@ -33,7 +30,7 @@ import org.opsli.core.base.entity.BaseEntity;
*/ */
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class SysUserAndOrg extends BaseEntity { public class SysUserWeb extends BaseEntity {
/** 登录账户 */ /** 登录账户 */
@ -79,14 +76,11 @@ public class SysUserAndOrg extends BaseEntity {
@TableField(updateStrategy = FieldStrategy.IGNORED) @TableField(updateStrategy = FieldStrategy.IGNORED)
private String sign; private String sign;
/** 组织机构 */
private UserOrgRefModel org;
// ======================================== // ========================================
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
/** 多租户字段 */ /** 多租户字段 */
private String tenantId; private String tenantId;

@ -23,7 +23,7 @@ import org.apache.ibatis.annotations.Param;
import org.opsli.api.wrapper.system.user.UserPassword; import org.opsli.api.wrapper.system.user.UserPassword;
import org.opsli.modulars.system.menu.entity.SysMenu; import org.opsli.modulars.system.menu.entity.SysMenu;
import org.opsli.modulars.system.user.entity.SysUser; import org.opsli.modulars.system.user.entity.SysUser;
import org.opsli.modulars.system.user.entity.SysUserAndOrg; import org.opsli.modulars.system.user.entity.SysUserWeb;
import java.util.List; import java.util.List;
@ -99,5 +99,5 @@ public interface UserMapper extends BaseMapper<SysUser> {
* @param wrapper * @param wrapper
* @return List * @return List
*/ */
List<SysUserAndOrg> findList(@Param(Constants.WRAPPER) Wrapper<?> wrapper); List<SysUserWeb> findList(@Param(Constants.WRAPPER) Wrapper<?> wrapper);
} }

@ -29,18 +29,13 @@
</sql> </sql>
<sql id="joinsColumns"> <sql id="joinsColumns">
,b.org_id as 'org.companyId',
c.org_id as 'org.departmentId',
d.org_id as 'org.postId'
</sql> </sql>
<sql id="joins"> <sql id="joins">
left join sys_user_org_ref b on b.user_id = a.id and b.org_type = '1' left join sys_user_org_ref b on b.user_id = a.id
left join sys_user_org_ref c on c.user_id = a.id and c.org_type = '2'
left join sys_user_org_ref d on d.user_id = a.id and d.org_type = '3'
</sql> </sql>
<select id="findList" parameterType="SysUser" resultType="SysUserAndOrg"> <select id="findList" parameterType="SysUser" resultType="SysUserWeb">
select select
<include refid="columns"></include> <include refid="columns"></include>
<include refid="joinsColumns"></include> <include refid="joinsColumns"></include>

@ -16,6 +16,7 @@
package org.opsli.modulars.system.user.service; package org.opsli.modulars.system.user.service;
import org.opsli.api.wrapper.system.user.UserOrgRefModel; import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
import java.util.List; import java.util.List;
@ -33,6 +34,13 @@ public interface IUserOrgRefService {
* @param model * @param model
* @return boolean * @return boolean
*/ */
boolean setOrg(UserOrgRefModel model); boolean setOrg(UserOrgRefWebModel model);
/**
* ID
* @param userId ID
* @return List
*/
List<UserOrgRefModel> findListByUserId(String userId);
} }

@ -16,13 +16,13 @@
package org.opsli.modulars.system.user.service; package org.opsli.modulars.system.user.service;
import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.api.wrapper.system.user.UserAndOrgModel; import org.opsli.api.wrapper.system.user.UserWebModel;
import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserPassword; import org.opsli.api.wrapper.system.user.UserPassword;
import org.opsli.core.base.service.interfaces.CrudServiceInterface; import org.opsli.core.base.service.interfaces.CrudServiceInterface;
import org.opsli.core.persistence.Page; import org.opsli.core.persistence.Page;
import org.opsli.modulars.system.user.entity.SysUser; import org.opsli.modulars.system.user.entity.SysUser;
import org.opsli.modulars.system.user.entity.SysUserAndOrg; import org.opsli.modulars.system.user.entity.SysUserWeb;
import java.util.List; import java.util.List;
@ -122,5 +122,5 @@ public interface IUserService extends CrudServiceInterface<SysUser, UserModel> {
* @param page * @param page
* @return Page<T> * @return Page<T>
*/ */
Page<SysUserAndOrg, UserAndOrgModel> findPageByCus(Page<SysUserAndOrg,UserAndOrgModel> page); Page<SysUserWeb, UserWebModel> findPageByCus(Page<SysUserWeb, UserWebModel> page);
} }

@ -16,23 +16,44 @@
package org.opsli.modulars.system.user.service.impl; package org.opsli.modulars.system.user.service.impl;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.warpper.ApiWrapper;
import org.opsli.api.wrapper.system.org.SysOrgModel;
import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel; import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.enums.DictType;
import org.opsli.common.exception.ServiceException; import org.opsli.common.exception.ServiceException;
import org.opsli.common.utils.FieldUtil;
import org.opsli.common.utils.ListDistinctUtil;
import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.msg.CoreMsg; import org.opsli.core.msg.CoreMsg;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.utils.OrgUtil; import org.opsli.core.utils.OrgUtil;
import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.SystemMsg;
import org.opsli.modulars.system.menu.entity.SysMenu;
import org.opsli.modulars.system.org.entity.SysOrg;
import org.opsli.modulars.system.org.service.ISysOrgService;
import org.opsli.modulars.system.user.entity.SysUser;
import org.opsli.modulars.system.user.entity.SysUserOrgRef; import org.opsli.modulars.system.user.entity.SysUserOrgRef;
import org.opsli.modulars.system.user.mapper.UserOrgRefMapper; import org.opsli.modulars.system.user.mapper.UserOrgRefMapper;
import org.opsli.modulars.system.user.service.IUserOrgRefService; import org.opsli.modulars.system.user.service.IUserOrgRefService;
import org.opsli.modulars.system.user.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.List; import java.util.List;
@ -45,12 +66,62 @@ import java.util.List;
@Service @Service
public class UserOrgRefServiceImpl extends ServiceImpl<UserOrgRefMapper, SysUserOrgRef> implements IUserOrgRefService { public class UserOrgRefServiceImpl extends ServiceImpl<UserOrgRefMapper, SysUserOrgRef> implements IUserOrgRefService {
/** 分割符 */
private static final String DELIMITER = ",";
/** 父节点ID */
private static final String PARENT_ID = "0";
@Autowired(required = false) @Autowired(required = false)
private UserOrgRefMapper mapper; private UserOrgRefMapper mapper;
@Autowired
private IUserService iUserService;
@Autowired
private ISysOrgService iSysOrgService;
@Override
public List<UserOrgRefModel> findListByUserId(String userId) {
if(StrUtil.isEmpty(userId)){
return ListUtil.empty();
}
UserModel userModel = iUserService.get(userId);
if(userModel == null){
return ListUtil.empty();
}
String userIdField = "user_id";
QueryWrapper<SysUserOrgRef> wrapper = new QueryWrapper<>();
wrapper.eq(userIdField, userId);
List<SysUserOrgRef> orgRefList = super.list(wrapper);
if(CollUtil.isEmpty(orgRefList)){
// 判断是否是超级管理员 如果是超级管理员 则默认享有全部权限
if(StringUtils.equals(UserUtil.SUPER_ADMIN, userModel.getUsername())){
QueryWrapper<SysOrg> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_PARENT_ID), PARENT_ID
);
List<SysOrg> orgList = iSysOrgService.findList(queryWrapper);
List<SysOrgModel> sysOrgModels = WrapperUtil.transformInstance(orgList, SysOrgModel.class);
for (SysOrgModel orgModel : sysOrgModels) {
SysUserOrgRef orgRef = this.createOrgRef(userId, orgModel, DictType.NO_YES_NO.getValue());
orgRefList.add(orgRef);
}
}
}
return WrapperUtil.transformInstance(
orgRefList, UserOrgRefModel.class
);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean setOrg(UserOrgRefModel model) { public boolean setOrg(UserOrgRefWebModel model) {
// 非法验证 组织不可为空 // 非法验证 组织不可为空
if(model == null){ if(model == null){
throw new ServiceException(SystemMsg.EXCEPTION_ORG_NOT_NULL); throw new ServiceException(SystemMsg.EXCEPTION_ORG_NOT_NULL);
@ -60,41 +131,42 @@ public class UserOrgRefServiceImpl extends ServiceImpl<UserOrgRefMapper, SysUser
String userIdField = "user_id"; String userIdField = "user_id";
QueryWrapper<SysUserOrgRef> wrapper = new QueryWrapper<>(); QueryWrapper<SysUserOrgRef> wrapper = new QueryWrapper<>();
wrapper.eq(userIdField, model.getUserId()); wrapper.eq(userIdField, model.getUserId());
super.remove(wrapper); boolean removeFlag = super.remove(wrapper);
List<SysUserOrgRef> orgRefs = Lists.newArrayList(); // 设置组织
List<SysUserOrgRef> orgRefList = Lists.newArrayList();
// 设置公司 SysOrgModel defModel = model.getDefModel();
if(StringUtils.isNotEmpty(model.getCompanyId())){ if(defModel != null){
SysUserOrgRef tmp = new SysUserOrgRef(); SysUserOrgRef orgRef = createOrgRef(
tmp.setUserId(model.getUserId()); model.getUserId(), defModel, DictType.NO_YES_YES.getValue());
tmp.setOrgId(model.getCompanyId()); orgRefList.add(orgRef);
tmp.setOrgType("1");
orgRefs.add(tmp);
} }
List<SysOrgModel> orgModelList = model.getOrgModelList();
// 设置部门 if(!CollUtil.isEmpty(orgModelList)){
if(StringUtils.isNotEmpty(model.getDepartmentId())){ for (SysOrgModel orgModel : orgModelList) {
SysUserOrgRef tmp = new SysUserOrgRef(); SysUserOrgRef orgRef = createOrgRef(
tmp.setUserId(model.getUserId()); model.getUserId(), orgModel, DictType.NO_YES_NO.getValue());
tmp.setOrgId(model.getDepartmentId()); orgRefList.add(orgRef);
tmp.setOrgType("2"); }
orgRefs.add(tmp);
} }
// 设置岗位 boolean izExistOrg = false;
if(StringUtils.isNotEmpty(model.getPostId())){
SysUserOrgRef tmp = new SysUserOrgRef(); if(!CollUtil.isEmpty(orgRefList)){
tmp.setUserId(model.getUserId()); // 去重
tmp.setOrgId(model.getPostId()); orgRefList = ListDistinctUtil.distinct(
tmp.setOrgType("3"); orgRefList, Comparator.comparing(SysUserOrgRef::getId));
orgRefs.add(tmp);
// 批量保存
izExistOrg = super.saveBatch(orgRefList);
} }
boolean saveBatchFlag = super.saveBatch(orgRefs); // 修改用户组织状态
this.updateUserOrgFlag(model.getUserId(), izExistOrg);
// 清空缓存 // 清空缓存
if(saveBatchFlag){ if(removeFlag){
// 刷新用户缓存 // 刷新用户缓存
this.clearCache(Collections.singletonList(model.getUserId())); this.clearCache(Collections.singletonList(model.getUserId()));
} }
@ -102,6 +174,46 @@ public class UserOrgRefServiceImpl extends ServiceImpl<UserOrgRefMapper, SysUser
return true; return true;
} }
/**
*
* @param userId ID
* @param flag
*/
@Transactional(rollbackFor = Exception.class)
public void updateUserOrgFlag(String userId, boolean flag) {
String flagVal = DictType.NO_YES_NO.getValue();
if(flag){
flagVal = DictType.NO_YES_YES.getValue();
}
// 修改用户组织状态
UpdateWrapper<SysUser> updateUserWrapper = new UpdateWrapper<>();
updateUserWrapper.set("iz_exist_org", flagVal);
updateUserWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_ID), userId);
iUserService.update(updateUserWrapper);
}
/**
* Org
* @param userId ID
* @param orgModel
* @return ref
*/
private SysUserOrgRef createOrgRef(String userId, SysOrgModel orgModel, String izDef) {
String orgGroup =
StrUtil.appendIfMissing(
orgModel.getParentIds(), DELIMITER) +
orgModel.getId();
SysUserOrgRef orgRef = new SysUserOrgRef();
orgRef.setUserId(userId);
orgRef.setOrgId(orgModel.getId());
orgRef.setOrgIds(orgGroup);
orgRef.setIzDef(izDef);
return orgRef;
}
// ============ // ============
/** /**

@ -27,7 +27,7 @@ import org.apache.commons.lang3.StringUtils;
import org.opsli.api.base.warpper.ApiWrapper; import org.opsli.api.base.warpper.ApiWrapper;
import org.opsli.api.wrapper.system.menu.MenuModel; import org.opsli.api.wrapper.system.menu.MenuModel;
import org.opsli.api.wrapper.system.options.OptionsModel; import org.opsli.api.wrapper.system.options.OptionsModel;
import org.opsli.api.wrapper.system.user.UserAndOrgModel; import org.opsli.api.wrapper.system.user.UserWebModel;
import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserPassword; import org.opsli.api.wrapper.system.user.UserPassword;
import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.constants.MyBatisConstants;
@ -42,7 +42,8 @@ import org.opsli.core.msg.CoreMsg;
import org.opsli.core.persistence.Page; import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.chain.TenantHandler; import org.opsli.core.persistence.querybuilder.chain.QueryOrgHandler;
import org.opsli.core.persistence.querybuilder.chain.QueryTenantHandler;
import org.opsli.core.utils.OptionsUtil; import org.opsli.core.utils.OptionsUtil;
import org.opsli.core.utils.UserUtil; import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.SystemMsg;
@ -51,7 +52,7 @@ import org.opsli.modulars.system.menu.service.IMenuService;
import org.opsli.modulars.system.role.entity.SysRole; import org.opsli.modulars.system.role.entity.SysRole;
import org.opsli.modulars.system.role.service.IRoleService; import org.opsli.modulars.system.role.service.IRoleService;
import org.opsli.modulars.system.user.entity.SysUser; import org.opsli.modulars.system.user.entity.SysUser;
import org.opsli.modulars.system.user.entity.SysUserAndOrg; import org.opsli.modulars.system.user.entity.SysUserWeb;
import org.opsli.modulars.system.user.mapper.UserMapper; import org.opsli.modulars.system.user.mapper.UserMapper;
import org.opsli.modulars.system.user.service.IUserRoleRefService; import org.opsli.modulars.system.user.service.IUserRoleRefService;
import org.opsli.modulars.system.user.service.IUserService; import org.opsli.modulars.system.user.service.IUserService;
@ -116,6 +117,8 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
model.setLoginIp(null); model.setLoginIp(null);
// 默认用户状态为启用 // 默认用户状态为启用
model.setEnable(DictType.NO_YES_YES.getValue()); model.setEnable(DictType.NO_YES_YES.getValue());
// 默认未分配组织
model.setIzExistOrg(DictType.NO_YES_NO.getValue());
// 新增可以直接设置密码 // 新增可以直接设置密码
if(StringUtils.isNotEmpty(model.getPassword())){ if(StringUtils.isNotEmpty(model.getPassword())){
@ -208,6 +211,7 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
model.setSecretKey(null); model.setSecretKey(null);
model.setLoginIp(null); model.setLoginIp(null);
model.setEnable(null); model.setEnable(null);
model.setIzExistOrg(null);
UserModel update = super.update(model); UserModel update = super.update(model);
if(update != null){ if(update != null){
@ -545,9 +549,10 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
public List<SysUser> findList(QueryWrapper<SysUser> queryWrapper) { public List<SysUser> findList(QueryWrapper<SysUser> queryWrapper) {
// 如果没有租户修改能力 则默认增加租户限制 // 如果没有租户修改能力 则默认增加租户限制
if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){ if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){
// 多租户处理 // 数据处理责任链
TenantHandler tenantHandler = new TenantHandler(); queryWrapper = new QueryTenantHandler(
tenantHandler.handler(entityClazz, queryWrapper); new QueryOrgHandler()
).handler(entityClazz, queryWrapper);
} }
return super.list(queryWrapper); return super.list(queryWrapper);
@ -559,9 +564,10 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
QueryWrapper<SysUser> queryWrapper = queryBuilder.build(); QueryWrapper<SysUser> queryWrapper = queryBuilder.build();
// 如果没有租户修改能力 则默认增加租户限制 // 如果没有租户修改能力 则默认增加租户限制
if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){ if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){
// 多租户处理 // 数据处理责任链
TenantHandler tenantHandler = new TenantHandler(); queryWrapper = new QueryTenantHandler(
tenantHandler.handler(entityClazz, queryWrapper); new QueryOrgHandler()
).handler(entityClazz, queryWrapper);
} }
return super.list(queryWrapper); return super.list(queryWrapper);
} }
@ -689,37 +695,44 @@ public class UserServiceImpl extends CrudServiceImpl<UserMapper, SysUser, UserMo
} }
private List<SysUserAndOrg> findListByCus(QueryWrapper<SysUserAndOrg> queryWrapper) { private List<SysUserWeb> findListByCus(QueryWrapper<SysUserWeb> queryWrapper) {
// 如果没有租户修改能力 则默认增加租户限制 // 如果没有租户修改能力 则默认增加租户限制
if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){ if(!UserUtil.isHasUpdateTenantPerms(UserUtil.getUser())){
// 多租户处理 // 数据处理责任链
TenantHandler tenantHandler = new TenantHandler(); queryWrapper = new QueryTenantHandler(
tenantHandler.handler(SysUserAndOrg.class, queryWrapper); new QueryOrgHandler()
).handler(SysUserWeb.class, queryWrapper);
} }
// 逻辑删除 查询未删除数据 // 逻辑删除 查询未删除数据
queryWrapper.eq( queryWrapper.eq(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_DELETE_LOGIC), DictType.NO_YES_NO.getValue()); FieldUtil.humpToUnderline(MyBatisConstants.FIELD_DELETE_LOGIC), DictType.NO_YES_NO.getValue());
// 按照ID 分组
queryWrapper.groupBy("a.id","b.user_id");
return mapper.findList(queryWrapper); return mapper.findList(queryWrapper);
} }
@Override @Override
public Page<SysUserAndOrg,UserAndOrgModel> findPageByCus(Page<SysUserAndOrg,UserAndOrgModel> page) { public Page<SysUserWeb, UserWebModel> findPageByCus(Page<SysUserWeb, UserWebModel> page) {
UserModel currUser = UserUtil.getUser(); UserModel currUser = UserUtil.getUser();
QueryWrapper<SysUserWeb> queryWrapper = page.getQueryWrapper();
// 如果不是超级管理员则 无法看到超级管理员账户 // 如果不是超级管理员则 无法看到超级管理员账户
if(!UserUtil.SUPER_ADMIN.equals(currUser.getUsername())){ if(!UserUtil.SUPER_ADMIN.equals(currUser.getUsername())){
QueryWrapper<SysUserAndOrg> queryWrapper = page.getQueryWrapper();
queryWrapper.notIn("username", UserUtil.SUPER_ADMIN); queryWrapper.notIn("username", UserUtil.SUPER_ADMIN);
page.setQueryWrapper(queryWrapper); page.setQueryWrapper(queryWrapper);
} }
// 不能查看自身
queryWrapper.notIn("username", currUser.getUsername());
page.pageHelperBegin(); page.pageHelperBegin();
try{ try{
List<SysUserAndOrg> list = this.findListByCus(page.getQueryWrapper()); List<SysUserWeb> list = this.findListByCus(page.getQueryWrapper());
PageInfo<SysUserAndOrg> pageInfo = new PageInfo<>(list); PageInfo<SysUserWeb> pageInfo = new PageInfo<>(list);
List<UserAndOrgModel> es = WrapperUtil.transformInstance(pageInfo.getList(), UserAndOrgModel.class); List<UserWebModel> es = WrapperUtil.transformInstance(pageInfo.getList(), UserWebModel.class);
page.instance(pageInfo, es); page.instance(pageInfo, es);
} finally { } finally {
page.pageHelperEnd(); page.pageHelperEnd();

@ -23,6 +23,7 @@ import org.opsli.api.base.result.ResultVo;
import org.opsli.api.web.system.user.UserOrgRefApi; import org.opsli.api.web.system.user.UserOrgRefApi;
import org.opsli.api.wrapper.system.user.UserModel; import org.opsli.api.wrapper.system.user.UserModel;
import org.opsli.api.wrapper.system.user.UserOrgRefModel; import org.opsli.api.wrapper.system.user.UserOrgRefModel;
import org.opsli.api.wrapper.system.user.UserOrgRefWebModel;
import org.opsli.common.annotation.ApiRestController; import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.exception.ServiceException; import org.opsli.common.exception.ServiceException;
import org.opsli.core.autoconfigure.properties.GlobalProperties; import org.opsli.core.autoconfigure.properties.GlobalProperties;
@ -32,6 +33,8 @@ import org.opsli.modulars.system.SystemMsg;
import org.opsli.modulars.system.user.service.IUserOrgRefService; import org.opsli.modulars.system.user.service.IUserOrgRefService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
/** /**
* - Controller * - Controller
* *
@ -50,6 +53,11 @@ public class UserOrgRefRestController implements UserOrgRefApi {
@Autowired @Autowired
private IUserOrgRefService iUserOrgRefService; private IUserOrgRefService iUserOrgRefService;
@Override
public ResultVo<List<UserOrgRefModel>> findListByUserId(String userId) {
List<UserOrgRefModel> listByUserId = iUserOrgRefService.findListByUserId(userId);
return ResultVo.success(listByUserId);
}
/** /**
* *
@ -58,18 +66,16 @@ public class UserOrgRefRestController implements UserOrgRefApi {
*/ */
@Override @Override
@RequiresPermissions("system_user_setOrg") @RequiresPermissions("system_user_setOrg")
public ResultVo<?> setOrg(UserOrgRefModel model) { public ResultVo<?> setOrg(UserOrgRefWebModel model) {
// 演示模式 不允许操作 // 演示模式 不允许操作
this.demoError(); this.demoError();
boolean ret = iUserOrgRefService.setOrg(model); boolean ret = iUserOrgRefService.setOrg(model);
if(ret){ if(!ret){
return ResultVo.success(); // 权限设置失败
throw new ServiceException(SystemMsg.EXCEPTION_USER_ORG_ERROR);
} }
// 权限设置失败 return ResultVo.success();
return ResultVo.error(SystemMsg.EXCEPTION_USER_ORG_ERROR.getCode(),
SystemMsg.EXCEPTION_USER_ORG_ERROR.getMessage()
);
} }

@ -22,7 +22,6 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.util.CollectionUtils; import com.alibaba.excel.util.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -37,9 +36,11 @@ import org.opsli.common.annotation.ApiRestController;
import org.opsli.common.annotation.EnableLog; import org.opsli.common.annotation.EnableLog;
import org.opsli.common.annotation.RequiresPermissionsCus; import org.opsli.common.annotation.RequiresPermissionsCus;
import org.opsli.common.constants.MyBatisConstants; import org.opsli.common.constants.MyBatisConstants;
import org.opsli.common.enums.DictType;
import org.opsli.common.exception.ServiceException; import org.opsli.common.exception.ServiceException;
import org.opsli.common.exception.TokenException; import org.opsli.common.exception.TokenException;
import org.opsli.common.utils.FieldUtil; import org.opsli.common.utils.FieldUtil;
import org.opsli.common.utils.ListDistinctUtil;
import org.opsli.common.utils.WrapperUtil; import org.opsli.common.utils.WrapperUtil;
import org.opsli.core.base.controller.BaseRestController; import org.opsli.core.base.controller.BaseRestController;
import org.opsli.core.msg.TokenMsg; import org.opsli.core.msg.TokenMsg;
@ -47,15 +48,14 @@ import org.opsli.core.persistence.Page;
import org.opsli.core.persistence.querybuilder.GenQueryBuilder; import org.opsli.core.persistence.querybuilder.GenQueryBuilder;
import org.opsli.core.persistence.querybuilder.QueryBuilder; import org.opsli.core.persistence.querybuilder.QueryBuilder;
import org.opsli.core.persistence.querybuilder.WebQueryBuilder; import org.opsli.core.persistence.querybuilder.WebQueryBuilder;
import org.opsli.core.persistence.querybuilder.conf.WebQueryConf;
import org.opsli.core.utils.OptionsUtil; import org.opsli.core.utils.OptionsUtil;
import org.opsli.core.utils.OrgUtil; import org.opsli.core.utils.OrgUtil;
import org.opsli.core.utils.UserUtil; import org.opsli.core.utils.UserUtil;
import org.opsli.modulars.system.SystemMsg; import org.opsli.modulars.system.SystemMsg;
import org.opsli.modulars.system.org.entity.SysOrg;
import org.opsli.modulars.system.org.service.ISysOrgService; import org.opsli.modulars.system.org.service.ISysOrgService;
import org.opsli.modulars.system.org.web.SysOrgRestController;
import org.opsli.modulars.system.user.entity.SysUser; import org.opsli.modulars.system.user.entity.SysUser;
import org.opsli.modulars.system.user.entity.SysUserAndOrg; import org.opsli.modulars.system.user.entity.SysUserWeb;
import org.opsli.modulars.system.user.service.IUserService; import org.opsli.modulars.system.user.service.IUserService;
import org.opsli.plugins.oss.OssStorageFactory; import org.opsli.plugins.oss.OssStorageFactory;
import org.opsli.plugins.oss.service.BaseOssStorageService; import org.opsli.plugins.oss.service.BaseOssStorageService;
@ -70,7 +70,6 @@ import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
@ -85,8 +84,6 @@ import java.util.Map;
public class UserRestController extends BaseRestController<SysUser, UserModel, IUserService> public class UserRestController extends BaseRestController<SysUser, UserModel, IUserService>
implements UserApi { implements UserApi {
@Autowired
private ISysOrgService iSysOrgService;
/** /**
* *
@ -133,7 +130,7 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
*/ */
@ApiOperation(value = "当前登陆用户组织机构", notes = "当前登陆用户组织机构") @ApiOperation(value = "当前登陆用户组织机构", notes = "当前登陆用户组织机构")
@Override @Override
public ResultVo<UserOrgRefModel> getOrg() { public ResultVo<?> getOrg() {
UserModel user = UserUtil.getUser(); UserModel user = UserUtil.getUser();
return this.getOrgByUserId(user.getId()); return this.getOrgByUserId(user.getId());
} }
@ -145,9 +142,9 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
*/ */
@ApiOperation(value = "用户组织机构", notes = "用户组织机构") @ApiOperation(value = "用户组织机构", notes = "用户组织机构")
@Override @Override
public ResultVo<UserOrgRefModel> getOrgByUserId(String userId) { public ResultVo<?> getOrgByUserId(String userId) {
UserOrgRefModel orgRef = OrgUtil.getOrgByUserId(userId); List<UserOrgRefModel> orgListByUserId = OrgUtil.getOrgListByUserId(userId);
return ResultVo.success(orgRef); return ResultVo.success(orgListByUserId);
} }
/** /**
@ -313,44 +310,31 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
* *
* @param pageNo * @param pageNo
* @param pageSize * @param pageSize
* @param orgIdGroup ID
* @param request request * @param request request
* @return ResultVo * @return ResultVo
*/ */
@ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器") @ApiOperation(value = "获得分页数据", notes = "获得分页数据 - 查询构造器")
@RequiresPermissions("system_user_select") @RequiresPermissions("system_user_select")
@Override @Override
public ResultVo<?> findPage(Integer pageNo, Integer pageSize, UserOrgRefModel org, HttpServletRequest request) { public ResultVo<?> findPage(Integer pageNo, Integer pageSize,
QueryBuilder<SysUserAndOrg> queryBuilder = new WebQueryBuilder<>(SysUserAndOrg.class, request.getParameterMap()); String orgIdGroup,
Page<SysUserAndOrg, UserAndOrgModel> page = new Page<>(pageNo, pageSize); HttpServletRequest request) {
QueryWrapper<SysUserAndOrg> queryWrapper = queryBuilder.build(); QueryBuilder<SysUserWeb> queryBuilder = new WebQueryBuilder<>(
if(org != null){ SysUserWeb.class, request.getParameterMap());
// 公司ID Page<SysUserWeb, UserWebModel> page = new Page<>(pageNo, pageSize);
if(StringUtils.isNotBlank(org.getCompanyId())){ QueryWrapper<SysUserWeb> queryWrapper = queryBuilder.build();
// 未分组判断
if(SysOrgRestController.ORG_NULL.equals(org.getCompanyId())){
queryWrapper.isNull("b.org_id");
}else{
queryWrapper.eq("b.org_id", org.getCompanyId());
}
}
// 部门ID // 处理组织权限
if(StringUtils.isNotBlank(org.getDepartmentId())){ OrgUtil.handleOrgIdGroupCondition(orgIdGroup, queryWrapper);
queryWrapper.eq("c.org_id", org.getDepartmentId());
}
// 岗位ID
if(StringUtils.isNotBlank(org.getPostId())){
queryWrapper.eq("d.org_id", org.getPostId());
}
}
page.setQueryWrapper(queryWrapper); page.setQueryWrapper(queryWrapper);
page = IService.findPageByCus(page); page = IService.findPageByCus(page);
// 密码防止分页泄露处理 // 密码防止分页泄露处理
for (UserAndOrgModel userModel : page.getList()) { for (UserWebModel userModel : page.getList()) {
userModel.setSecretKey(null); userModel.setSecretKey(null);
userModel.setPassword(null); userModel.setPassword(null);
userModel.setPasswordLevel(null);
} }
return ResultVo.success(page.getPageData()); return ResultVo.success(page.getPageData());
} }
@ -547,60 +531,60 @@ public class UserRestController extends BaseRestController<SysUser, UserModel, I
*/ */
@ApiOperation(value = "用户组织机构", notes = "用户组织机构") @ApiOperation(value = "用户组织机构", notes = "用户组织机构")
@Override @Override
public ResultVo<UserOrgRefModel> getOrgInfoByUserId(String userId) { public ResultVo<UserOrgRefWebModel> getOrgInfoByUserId(String userId) {
UserOrgRefModel org = null; UserOrgRefWebModel org = null;
// 不写SQL了 直接分页 第一页 取第一条 // 不写SQL了 直接分页 第一页 取第一条
QueryBuilder<SysUserAndOrg> queryBuilder = new GenQueryBuilder<>(); QueryBuilder<SysUserWeb> queryBuilder = new GenQueryBuilder<>();
Page<SysUserAndOrg, UserAndOrgModel> page = new Page<>(1, 1); Page<SysUserWeb, UserWebModel> page = new Page<>(1, 1);
QueryWrapper<SysUserAndOrg> queryWrapper = queryBuilder.build(); QueryWrapper<SysUserWeb> queryWrapper = queryBuilder.build();
queryWrapper.eq( queryWrapper.eq(
"a.id", "a.id",
userId userId
); );
page.setQueryWrapper(queryWrapper); page.setQueryWrapper(queryWrapper);
page = IService.findPageByCus(page); page = IService.findPageByCus(page);
List<UserAndOrgModel> list = page.getList(); List<UserWebModel> list = page.getList();
if(CollUtil.isNotEmpty(list)){ if(CollUtil.isNotEmpty(list)){
UserAndOrgModel userAndOrgModel = list.get(0); UserWebModel userWebModel = list.get(0);
if(userAndOrgModel != null){ if(userWebModel != null){
org = userAndOrgModel.getOrg(); // org = userAndOrgModel.getOrg();
if(org != null){ // if(org != null){
//
org.setUserId(userId); // org.setUserId(userId);
List<String> orgIds = Lists.newArrayListWithCapacity(3); // List<String> orgIds = Lists.newArrayListWithCapacity(3);
orgIds.add(org.getCompanyId()); // orgIds.add(org.getCompanyId());
orgIds.add(org.getDepartmentId()); // orgIds.add(org.getDepartmentId());
orgIds.add(org.getPostId()); // orgIds.add(org.getPostId());
QueryWrapper<SysOrg> orgQueryWrapper = new QueryWrapper<>(); // QueryWrapper<SysOrg> orgQueryWrapper = new QueryWrapper<>();
orgQueryWrapper.in( // orgQueryWrapper.in(
FieldUtil.humpToUnderline(MyBatisConstants.FIELD_ID), // FieldUtil.humpToUnderline(MyBatisConstants.FIELD_ID),
orgIds); // orgIds);
List<SysOrg> orgList = iSysOrgService.findList(orgQueryWrapper); // List<SysOrg> orgList = iSysOrgService.findList(orgQueryWrapper);
if(CollUtil.isNotEmpty(orgList)){ // if(CollUtil.isNotEmpty(orgList)){
Map<String, SysOrg> tmp = Maps.newHashMap(); // Map<String, SysOrg> tmp = Maps.newHashMap();
for (SysOrg sysOrg : orgList) { // for (SysOrg sysOrg : orgList) {
tmp.put(sysOrg.getId(), sysOrg); // tmp.put(sysOrg.getId(), sysOrg);
} // }
//
// 设置 名称 // // 设置 名称
SysOrg company = tmp.get(org.getCompanyId()); // SysOrg company = tmp.get(org.getCompanyId());
if(company != null){ // if(company != null){
org.setCompanyName(company.getOrgName()); // org.setCompanyName(company.getOrgName());
} // }
//
SysOrg department = tmp.get(org.getDepartmentId()); // SysOrg department = tmp.get(org.getDepartmentId());
if(department != null){ // if(department != null){
org.setDepartmentName(department.getOrgName()); // org.setDepartmentName(department.getOrgName());
} // }
//
SysOrg post = tmp.get(org.getPostId()); // SysOrg post = tmp.get(org.getPostId());
if(post != null){ // if(post != null){
org.setPostName(post.getOrgName()); // org.setPostName(post.getOrgName());
} // }
} // }
} // }
} }
} }
return ResultVo.success(org); return ResultVo.success(org);

@ -58,6 +58,6 @@ public class TestCar extends BaseEntity {
/** 逻辑删除字段 */ /** 逻辑删除字段 */
@TableLogic @TableLogic
private Integer deleted; private String deleted;
} }

@ -56,6 +56,6 @@ public class TestUser extends BaseEntity {
private String tenantId; private String tenantId;
/** 逻辑删除字段 */ /** 逻辑删除字段 */
private Integer deleted; private String deleted;
} }

@ -47,6 +47,6 @@ public class TestEntity extends BaseEntity {
/** 逻辑删除字段 */ /** 逻辑删除字段 */
//@TableLogic //@TableLogic
//private Integer deleted; //private String deleted;
} }

Loading…
Cancel
Save