feat(REQ-3282): 新增节点用户代码

This commit is contained in:
zhanghongbo 2024-12-25 14:35:06 +08:00
parent b393b75ae2
commit 31aa1b00a7
11 changed files with 237 additions and 3 deletions

View File

@ -5,12 +5,16 @@ import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO;
import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/**
* 部门相关基础API
*
@ -42,4 +46,12 @@ public interface OrgNodeUserApi {
@PostMapping("/api/node-user/list")
ApiResult<PageResp<NodeUserDTO>> list(@RequestBody @Validated ListNodeUserReq req);
/**
* 根据条件聚合查询节点用户
* @param req
* @return
*/
@PostMapping("/api/node-user/searchEntUser")
ApiResult<List<SearchEntNodeUserResp>> searchEntUser(@RequestBody @Validated SearchEntNodeUserReq req);
}

View File

@ -36,6 +36,10 @@
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.trade</groupId>
<artifactId>trade-data-security-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,48 @@
package cn.axzo.orgmanax.dto.nodeuser.req;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.util.Set;
/**
* @author zhanghongbo
* @date 2024/12/24
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class SearchEntNodeUserReq {
private Long workspaceId;
/** 企业组织节点ID - 不一定是topNodeId **/
@NotNull
private Long entNodeId;
/** 搜索关键字 - 为空直接返空 **/
private String keyword;
/** 加密关键字 **/
private String encryptKeyword;
/** 隐私设置排除的人员 **/
private Set<Long> excludePersonIds;
/** 隐私设置排除的部门 **/
private Set<Long> excludeNodeIds;
/**
* 数据权限缓存数据key
*/
private String dataPermissionCacheKey;
/**
* 数据权限解析后的节点ID(不作接口的查询条件)
*/
private Set<Long> dataPermissionNodeIds;
/**
* 数据权限解析后的人员ID(不作接口的查询条件)
*/
private Set<Long> dataPermissionPersonIds;
}

View File

@ -0,0 +1,45 @@
package cn.axzo.orgmanax.dto.nodeuser.resp;
import cn.axzo.trade.datasecurity.core.annotation.CryptField;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 通讯录用户搜索结果
*
* @version V1.0
* @author: ZhanSiHu
* @date: 2024/1/18 17:44
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SearchEntNodeUserResp {
private Long nodeUserId;
private Long personId;
private Long identityId;
private Integer identityType;
private String realName;
@CryptField
private String phone;
private Long orgNodeId;
private String orgNodeName;
private Long jobId;
private String jobName;
private boolean primaryJob;
}

View File

@ -1,12 +1,18 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.mapper;
import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author liuyang
*/
@Mapper
public interface OrganizationalNodeUserMapper extends BaseMapper<OrganizationalNodeUser> {
List<SearchEntNodeUserResp> searchEntUser(@Param("query") SearchEntNodeUserReq req);
}

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.axzo.orgmanax.infra.dao.nodeuser.mapper.OrganizationalNodeUserMapper">
<select id="searchEntUser" resultType="cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp">
SELECT
u.id AS nodeUserId,
u.person_id AS personId,
u.identity_id AS identity_id,
u.identity_type AS identity_type,
u.real_name AS realName,
u.phone AS phone,
u.organizational_job_id AS jobId,
u.primary_job AS primary_job,
n.id AS orgNodeId,
n.node_name AS orgNodeName,
j.`name` AS jobName
FROM
organizational_node_user u
LEFT JOIN organizational_node n ON u.organizational_node_id = n.id AND n.is_delete = 0
LEFT JOIN org_job j ON u.organizational_job_id = j.id AND j.is_delete = 0
WHERE
u.is_delete = 0
AND FIND_IN_SET(#{query.entNodeId}, n.path)
<if test="query.excludePersonIds != null and query.excludePersonIds.size() > 0">
AND u.person_id NOT IN
<foreach collection="query.excludePersonIds" open="(" close=")" separator="," item="personId" index="i">
#{personId}
</foreach>
</if>
<if test="query.excludeNodeIds != null and query.excludeNodeIds.size() > 0">
AND n.id NOT IN
<foreach collection="query.excludeNodeIds" open="(" close=")" separator="," item="nodeId" index="i">
#{nodeId}
</foreach>
</if>
<choose>
<when test="query.dataPermissionPersonIds != null and query.dataPermissionPersonIds.size() > 0 and query.dataPermissionNodeIds != null and query.dataPermissionNodeIds.size() > 0">
AND (n.id IN
<foreach collection="query.dataPermissionNodeIds" open="(" close=")" separator="," item="nodeId"
index="i">
#{nodeId}
</foreach> OR
u.person_id IN
<foreach collection="query.dataPermissionPersonIds" open="(" close=")" separator="," item="personId" index="i">
#{personId}
</foreach>
)
</when>
<when test="query.dataPermissionPersonIds != null and query.dataPermissionPersonIds.size() > 0
and (query.dataPermissionNodeIds == null or query.dataPermissionNodeIds.size() == 0)">
AND u.person_id IN
<foreach collection="query.dataPermissionPersonIds" open="(" close=")" separator="," item="personId" index="i">
#{personId}
</foreach>
</when>
<when test="query.dataPermissionNodeIds != null and query.dataPermissionNodeIds.size() > 0
and (query.dataPermissionPersonIds == null or query.dataPermissionPersonIds.size() == 0)">
AND n.id IN
<foreach collection="query.dataPermissionNodeIds" open="(" close=")" separator="," item="nodeId" index="i">
#{nodeId}
</foreach>
</when>
</choose>
AND (
u.real_name LIKE CONCAT( '%', #{query.keyword}, '%' )
OR u.phone = #{query.encryptKeyword}
OR j.`name` LIKE CONCAT( '%', #{query.keyword}, '%' )
OR n.node_name LIKE CONCAT( '%', #{query.keyword}, '%' ))
</select>
</mapper>

View File

@ -7,6 +7,8 @@ import cn.axzo.orgmanax.api.nodeuser.feign.OrgNodeUserApi;
import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO;
import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService;
import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor;
import com.alibaba.fastjson.JSONObject;
@ -14,6 +16,8 @@ import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
import static cn.axzo.orgmanax.common.config.BizResultCode.NODE_USER_PROCESS_FAILED;
/**
@ -46,4 +50,9 @@ public class NodeUserController implements OrgNodeUserApi {
public ApiResult<PageResp<NodeUserDTO>> list(ListNodeUserReq req) {
return ApiResult.success(nodeUserService.page(req));
}
@Override
public ApiResult<List<SearchEntNodeUserResp>> searchEntUser(SearchEntNodeUserReq req) {
return ApiResult.success(nodeUserService.searchEntUser(req));
}
}

View File

@ -1,6 +1,8 @@
package cn.axzo.orgmanax.server.nodeuser.foundation;
import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO;
import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJob;
@ -35,4 +37,11 @@ public interface NodeUserFoundationService {
* @param orgJobs
*/
<T extends NodeUserQueryRepository.NodeUserResp, Job extends OrgJob> void filterByJobs(List<T> nodeUsers, List<Job> orgJobs);
/**
* 根据条件聚合查询节点用户
* @param req
* @return
*/
List<SearchEntNodeUserResp> searchEntUser(SearchEntNodeUserReq req);
}

View File

@ -4,8 +4,9 @@ import cn.axzo.foundation.event.support.Event;
import cn.axzo.foundation.event.support.producer.EventProducer;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO;
import cn.axzo.orgmanax.dto.nodeuser.enums.NodeUserTypeEnum;
import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp;
import cn.axzo.orgmanax.infra.client.profile.PersonProfileGateway;
import cn.axzo.orgmanax.infra.client.profile.dto.ProfileIdentityResp;
import cn.axzo.orgmanax.infra.client.profile.dto.ProfilePersonResp;
@ -14,6 +15,7 @@ import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRep
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import cn.axzo.orgmanax.infra.dao.nodeuser.mapper.OrganizationalNodeUserMapper;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserUpsertRepository;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJob;
@ -28,11 +30,9 @@ import cn.hutool.core.util.BooleanUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* @author tanjie@axzo.cn
@ -48,6 +48,8 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService
private final CooperateShipQueryRepository cooperateShipQueryRepository;
private final EventProducer eventProducer;
private final PersonProfileGateway profileGateway;
private final OrganizationalNodeUserMapper organizationalNodeUserMapper;
/**
* 创建部门标准接口
@ -142,6 +144,16 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService
nodeUsers.removeIf(e -> !jobIds.contains(e.getOrganizationalJobId()));
}
/**
* 根据条件聚合查询节点用户
* @param req
* @return
*/
@Override
public List<SearchEntNodeUserResp> searchEntUser(SearchEntNodeUserReq req) {
return organizationalNodeUserMapper.searchEntUser(req);
}
private Long resolveWorkspaceId(OrganizationalNode node) {
if (Objects.equals(node.getNodeType(), NodeUserTypeEnum.TEAM.getValue())) {
return 0L;

View File

@ -7,6 +7,8 @@ import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp;
import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
@ -26,6 +28,8 @@ public interface NodeUserService {
return page(req).getData();
}
List<SearchEntNodeUserResp> searchEntUser(SearchEntNodeUserReq req);
@NoArgsConstructor
@AllArgsConstructor
@Data

View File

@ -9,10 +9,13 @@ import cn.axzo.orgmanax.dto.node.req.ListNodeReq;
import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO;
import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp;
import cn.axzo.orgmanax.dto.unit.dto.OrgUnitDTO;
import cn.axzo.orgmanax.dto.unit.req.ListUnitReq;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository;
import cn.axzo.orgmanax.server.node.service.NodeService;
import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService;
import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor;
import cn.axzo.orgmanax.server.orgjob.service.OrgJobService;
@ -49,6 +52,9 @@ public class NodeUserServiceImpl implements NodeUserService {
@Autowired
private UnitService unitService;
private final ApplicationContext applicationContext;
private final NodeUserFoundationService nodeUserFoundationService;
@Override
public NodeUserProcessor.ProcessResult process(ProcessNodeUserReq req) {
@ -102,6 +108,11 @@ public class NodeUserServiceImpl implements NodeUserService {
return new PageResp<>(page.getTotal(), page.getSize(), page.getCurrent(), records);
}
@Override
public List<SearchEntNodeUserResp> searchEntUser(SearchEntNodeUserReq req) {
return nodeUserFoundationService.searchEntUser(req);
}
private void assembleUnit(ListNodeUserReq req, List<NodeUserDTO> records) {
if (CollUtil.isEmpty(records) || req.getNeeds() == null) {