feat(REQ-3282): 新的岗位分页接口实现

This commit is contained in:
songyuanlun 2024-12-23 22:23:58 +08:00
parent 433f763ac3
commit 22d1ab0f05
41 changed files with 1648 additions and 109 deletions

View File

@ -2,11 +2,12 @@ package cn.axzo.orgmanax.api.orgjob.feign;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import cn.axzo.orgmanax.dto.job.req.CreateOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.DeleteOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.ListOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.PageOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.UpdateOrgJobReq;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
@ -28,4 +29,11 @@ public interface OrgJobApi {
@PostMapping("/api/job/list")
ApiResult<PageResp<OrgJobDTO>> list(@RequestBody @Validated ListOrgJobReq req);
/**
* 分页列表接口
* XXX本接口默认分页单页最多返回1000条数据调用方使用时需注意
*/
@PostMapping("/api/job/page")
ApiResult<PageResp<OrgJobDTO>> page(@RequestBody @Validated PageOrgJobReq req);
}

View File

@ -43,4 +43,15 @@ Accept: application/json
"name": "项目负责人"
}
###
###
# 查询
POST {{host}}/api/job/page
Content-Type: application/json
Accept: application/json
{
"jobIds": [3103, 3104, 3105],
"jobCodes": ["coTheprojectmanager", "cosurveyor"],
"needSaasRole": true,
"needJobGroup": true
}

View File

@ -0,0 +1,39 @@
package cn.axzo.orgmanax.dto.job.dto;
/**
* @description
* 岗位编码厂里
* @author luofu
* @date 2024/2/27
* @version 1.0
*/
public interface OrgJobCodeConstants {
/** 项目内工人 **/
String PROJ_WORKER = "projWorker";
/** 企业内班组长 **/
String ENT_TEAM_LEADER = "entTeamLeader";
/** 企业内班组管理员 **/
String ENT_TEAM_MANAGER = "entTeamManager";
/** 企业内工人 **/
String ENT_TEAM_WORKER = "entWorker";
/** 项目内班组长 **/
String PROJ_TEAM_LEADER = "projTeamLeader";
/** 项目内带班长 **/
String PROJ_TEAM_MANAGER = "projectTeamManager";
/** 项目内小组长 **/
String PROJ_GROUP_LEADER = "projectTeamGPLeader";
/**
* org_job.record_ext 的数据key
* 罗福那边确认需要保留
*/
String OLD_CONFIG = "oldJobConfigs";
String CODE_KEY = "code";
String OLD_NEW_JOB_CODE_MAP_KEY = "job_code_mapping";
}

View File

@ -1,11 +1,31 @@
package cn.axzo.orgmanax.dto.job.dto;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import static cn.axzo.orgmanax.dto.job.dto.OrgJobCodeConstants.CODE_KEY;
import static cn.axzo.orgmanax.dto.job.dto.OrgJobCodeConstants.OLD_CONFIG;
import cn.axzo.orgmanax.dto.job.enums.OrgJobFlagEnum;
import cn.axzo.orgmanax.dto.job.enums.OrgJobTypeEnum;
import cn.axzo.orgmanax.dto.job.enums.VisibilityEnum;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobDTO {
/**
@ -31,7 +51,7 @@ public class OrgJobDTO {
/**
* 可见性: SHOW-可见,HIDE-隐藏
*/
private String visible;
private VisibilityEnum visible;
/**
* 是否为默认岗的标识: 0-非默认,1-默认
@ -46,12 +66,11 @@ public class OrgJobDTO {
/**
* 岗位类型SYSTEM - 系统CUSTOM - 自定义
*/
private String type;
private OrgJobTypeEnum type;
/**
* 岗位标签SYSTEM - 系统岗BUSINESS - 业务岗
*/
private String flag;
private OrgJobFlagEnum flag;
/**
* 单位id,自定义类型时该值才有意义
@ -76,12 +95,12 @@ public class OrgJobDTO {
/**
* 默认角色id列表
*/
private JSONObject defRoleIds;
private List<Long> defRoleIds;
/**
* 待排除的角色id列表
*/
private JSONObject excludeRoleIds;
private List<Long> excludeRoleIds;
/**
* 扩展字段
@ -108,4 +127,47 @@ public class OrgJobDTO {
*/
private Long isDelete;
/**
* 岗位分组
*/
private OrgJobGroupDTO jobGroup;
/**
* 角色信息
*/
private List<RoleDTO> saasRoles;
public Set<Long> mergeAndDistinctRolesIds() {
Set<Long> roleIds = Sets.newHashSet();
if (CollectionUtils.isNotEmpty(defRoleIds)) {
roleIds.addAll(defRoleIds);
}
if (CollectionUtils.isNotEmpty(excludeRoleIds)) {
roleIds.addAll(excludeRoleIds);
}
return roleIds;
}
public boolean isEqual(String code) {
if (StringUtils.isBlank(code)) {
return false;
}
if (Objects.equals(code, this.code)) {
return true;
}
// 旧的岗位code比较
return Objects.nonNull(recordExt) && contains(recordExt, code);
}
public boolean contains(JSONObject recordExt, String oldJobCode) {
JSONArray oldJobConfigs = recordExt.getJSONArray(OLD_CONFIG);
if (CollectionUtils.isEmpty(oldJobConfigs)) {
return false;
}
return IntStream.range(0, oldJobConfigs.size())
.mapToObj(oldJobConfigs::getJSONObject)
.collect(Collectors.toList()).stream()
.map(e -> e.getString(CODE_KEY))
.anyMatch(c -> Objects.equals(c, oldJobCode));
}
}

View File

@ -0,0 +1,72 @@
package cn.axzo.orgmanax.dto.job.dto;
import cn.axzo.orgmanax.dto.job.enums.OrgJobGroupFlagEnum;
import com.alibaba.fastjson.JSON;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description 岗位分组表
* @author luofu
* @version 1.0
* @date 2024/9/9
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobGroupDTO {
/**
* 主键
*/
private Long id;
/**
* 创建时间
*/
private Date createAt;
/**
* 更新时间
*/
private Date updateAt;
/**
* 逻辑删除标识(0未删除,其它已删除)
*/
private Long isDelete;
/**
* 父节点id
*/
private Long parentId;
/**
* 编码
*/
private String code;
/**
* 分组名称
*/
private String name;
/**
* 优先级,同一层级的分组优先级才有意义
*/
private Integer priority;
/**
* 分组标识其与工作台类型及参建类型在后端进行映射
*/
private OrgJobGroupFlagEnum flag;
/**
* 变更人的自然人id
*/
private Long operatorId;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,59 @@
package cn.axzo.orgmanax.dto.job.dto;
import com.alibaba.fastjson.JSON;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description 岗位与分组的关系表
* @author luofu
* @version 1.0
* @date 2024/9/9
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobGroupRelationDTO {
/**
* 主键
*/
private Long id;
/**
* 创建时间
*/
private Date createAt;
/**
* 更新时间
*/
private Date updateAt;
/**
* 逻辑删除标识(0未删除,其它已删除)
*/
private Long isDelete;
/**
* 分组编码
*/
private String groupCode;
/**
* 岗位编码
*/
private String jobCode;
/**
* 变更人的自然人id
*/
private Long operatorId;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,60 @@
package cn.axzo.orgmanax.dto.job.dto;
import com.alibaba.fastjson.JSON;
import java.util.Date;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description 岗位与分组的关系历史表
* @author luofu
* @version 1.0
* @date 2024/9/9
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobGroupRelationHistoryDTO {
/**
* 主键
*/
private Long id;
/**
* 创建时间
*/
private Date createAt;
/**
* 更新时间
*/
private Date updateAt;
/**
* 逻辑删除标识(0未删除,其它已删除)
*/
private Long isDelete;
/**
* 分组编码
*/
private String groupCode;
/**
* 岗位编码列表
*/
private List<String> jobCodes;
/**
* 变更人的自然人id
*/
private Long operatorId;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,64 @@
package cn.axzo.orgmanax.dto.job.dto;
import cn.axzo.orgmanax.dto.job.enums.OrgJobTypeEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @description 岗位变更历史表
* @author luofu
* @version 1.0
* @date 2024/9/9
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobHistoryDTO {
/**
* 主键ID
*/
private Long id;
/**
* 创建时间
*/
private Date createAt;
/**
* 更新时间
*/
private Date updateAt;
/**
* 逻辑删除标识(0未删除,其它已删除)
*/
private Long isDelete;
/**
* 编码
*/
private String code;
/**
* 岗位类型SYSTEM - 系统CUSTOM - 自定义
*/
private OrgJobTypeEnum type;
/**
* 变更人的自然人id
*/
private Long operatorId;
/**
* 岗位数据
*/
private JSONObject dataContent;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,92 @@
package cn.axzo.orgmanax.dto.job.dto;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RoleDTO {
/**
* 角色id
*/
private Long roleId;
/**
* 角色编码
*/
private String roleCode;
/**
* 角色名称
*/
private String name;
/**
* 角色描述
*/
private String description;
/**
* 角色类型common 普通角色 super_admin超级管理员(禁止删除) admin子管理员(禁止删除) init初始化内置角色
* @see RoleTypeEnum
*/
private String roleType;
/**
* 角色所属租户id预设角色的workspaceId <= 0
*/
private Long workspaceId;
/**
* 角色所属单位id预设角色的ouId <= 0
*/
private Long ouId;
/**
* 协同关系类型
* 1:总包 2:建设单位 3:监理单位 4:劳务分包 5:专业分包 6:OMS通用 7:企业通用 8:企业内班组 9:项目内班组
* @see cn.axzo.maokai.common.enums.SaasCooperateShipCooperateTypeEnum
*/
private Integer cooperateShipType;
/**
* 创建者
*/
private Long createBy;
/**
* 更新者
*/
private Long updateBy;
/**
* 是否显示
*/
private Boolean isDisplay;
/**
* 是否启用
*/
private Boolean enabled;
/**
* 排序
*/
private Integer sort;
/**
* 添加时间
*/
private Date createAt;
/**
* 更新时间
*/
private Date updateAt;
}

View File

@ -0,0 +1,24 @@
package cn.axzo.orgmanax.dto.job.enums;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @description 可见性的枚举
* @author luofu
* @version 1.0
* @date 2024/9/9
*/
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum VisibilityEnum {
SHOW("显示"), HIDE("隐藏");
private final String desc;
public String getCode() {
return name();
}
}

View File

@ -1,7 +1,12 @@
package cn.axzo.orgmanax.dto.job.req;
import cn.axzo.foundation.page.PageReqV2;
import lombok.*;
import cn.axzo.orgmanax.dto.job.enums.OrgJobTypeEnum;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@EqualsAndHashCode(callSuper = true)
@ -16,5 +21,22 @@ public class ListOrgJobReq extends PageReqV2 {
*/
private String name;
/**
* 岗位id集合
*/
private Set<Long> jobIds;
/**
* 岗位编码集合
*/
private Set<String> jobCodes;
/**
* 岗位类型
*/
private OrgJobTypeEnum type;
/**
* 搜索关键字
* Notice: 名称或别名的模糊搜索
*/
private String keyword;
}

View File

@ -1,14 +1,16 @@
package cn.axzo.orgmanax.dto.job.req;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.foundation.page.PageReqV2;
import cn.axzo.orgmanax.dto.job.enums.OrgJobGroupFlagEnum;
import lombok.*;
import lombok.experimental.SuperBuilder;
import cn.axzo.orgmanax.dto.job.enums.OrgJobTypeEnum;
import java.util.List;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@EqualsAndHashCode(callSuper = true)
@Data
@ -19,13 +21,11 @@ public class PageOrgJobReq extends PageReqV2 {
/**
* 岗位ids
*/
@CriteriaField(field = "id", operator = Operator.IN)
private Set<Long> jobIds;
/**
* 岗位codes
*/
@CriteriaField(field = "code", operator = Operator.IN)
private Set<String> jobCodes;
/**
@ -42,53 +42,21 @@ public class PageOrgJobReq extends PageReqV2 {
*/
@Builder.Default
private Boolean needSaasRole = false;
// 以上参数优先实现
// v1 版本接口入参兼容
/**
* 单位/团队 ID 列表
*/
private List<Long> unitIds;
/**
* 工作台id 列表
* 是否需要查询岗位分组信息
*/
private List<Long> workspaceIds;
/**
* 岗位类型 1总包单位 2建设单位 3监理单位 4劳务分包 5专业分包 6:OMS 7企业通用 9:班组项目内
*/
private List<Integer> types;
/**
* 可为空,即加载默认和自定义所有岗位 true预定义岗位 false 自定义岗位
*/
private Boolean readonly;
/**
* 岗位搜索关键字
*/
private String searchKey;
/**
* 全匹配
*/
private String equalSearchKey;
/** 是否需要推荐角色 默认false-不需要**/
private boolean needRole = false;
/** 是否需要推荐角色的详情(id和name) 默认false-不需要**/
private boolean needRoleDetail = false;
/**
* 是否让后端查询unit的workspaceId. 配合unitId使用
*/
private Boolean queryUnitWorkspaceId;
@Builder.Default
private Boolean needJobGroup = false;
/**
* 岗位搜索关键字
*/
private String keyword;
/**
* 岗位类型
*/
private OrgJobTypeEnum type;
}

View File

@ -114,5 +114,11 @@
<artifactId>apollo-workspace-api-v2</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.axzo.tyr</groupId>
<artifactId>tyr-client</artifactId>
<version>${revision}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,26 @@
package cn.axzo.orgmanax.infra.client.tyr;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.infra.client.util.RpcWrapper;
import cn.axzo.tyr.feign.api.RoleApi;
import cn.axzo.tyr.feign.req.PageRoleReq;
import cn.axzo.tyr.feign.resp.RoleResp;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @author syl
* @date 2024/12/23
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class RoleGateway {
private final RoleApi roleApi;
public PageResp<RoleResp> page(PageRoleReq req) {
return RpcWrapper.wrapApiResult(() -> roleApi.page(req));
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.orgmanax.infra.client.tyr.enums;
import java.util.Arrays;
import java.util.Objects;
import java.util.Optional;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
/**
* @author tanjie@axzo.cn
* @date 2023/9/13 16:35
*/
@Getter
@AllArgsConstructor
public enum RoleTypeEnum {
//角色类型common 自定义角色 super_admin超级管理员(禁止删除) admin子管理员(禁止删除) init初始化内置角色 auto_own自定义角色(禁止删除)<承载向用户单独分配的自定义权限>
COMMON("common", "自定义角色",false),
SUPER_ADMIN("super_admin", "超级管理员",true),
ADMIN("admin", "子管理员",true),
INIT("init", "初始化内置角色-标准角色",false),
AUTO_OWN("auto_own", "虚拟角色(自定义权限使用)",false);
private final String value;
private final String desc;
private final boolean isAdmin;
public static Optional<RoleTypeEnum> fromValue(String value) {
if (StringUtils.isBlank(value)) {
return Optional.empty();
}
return Arrays.stream(RoleTypeEnum.values())
.filter(e -> Objects.equals(e.getValue(), value))
.findFirst();
}
}

View File

@ -0,0 +1,30 @@
package cn.axzo.orgmanax.infra.client.util;
import cn.axzo.foundation.exception.BusinessException;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.hutool.core.convert.Convert;
import cn.hutool.http.HttpStatus;
import java.util.Objects;
import java.util.function.Supplier;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class RpcWrapper {
/**
* Api result 返回
* @param supplier
* @return
* @param <T>
*/
public static <T> T wrapApiResult(Supplier<cn.axzo.foundation.result.ApiResult<T>> supplier) {
cn.axzo.foundation.result.ApiResult<T> result = supplier.get();
if (result == null) {
throw new BusinessException(BizResultCode.RPC_ERROR);
}
if (!Objects.equals(result.getCode(), HttpStatus.HTTP_OK)) {
throw new BusinessException(Convert.toStr(result.getCode()), result.getMsg(), null);
}
return result.getData();
}
}

View File

@ -1,18 +1,22 @@
package cn.axzo.orgmanax.infra.dao.orgjob.entity;
import cn.axzo.foundation.dao.support.mysql.type.BaseListTypeHandler;
import com.alibaba.fastjson.JSONObject;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import java.io.Serializable;
/**
* 组织岗位表(OrgJob)表实体类
*
@ -29,9 +33,6 @@ import java.io.Serializable;
@EqualsAndHashCode(callSuper = false)
public class OrgJob implements Serializable {
/**
* 主键
*/
/**
* 主键
*/
@ -101,14 +102,16 @@ public class OrgJob implements Serializable {
private Integer identityType;
/**
* 默认角色id列表
* 默认角色id列表 todo
*/
private JSONObject defRoleIds;
@TableField(typeHandler = LongListTypeHandler.class)
private List<Long> defRoleIds;
/**
* 待排除的角色id列表
*/
private JSONObject excludeRoleIds;
@TableField(typeHandler = LongListTypeHandler.class)
private List<Long> excludeRoleIds;
/**
* 扩展字段
@ -134,5 +137,8 @@ public class OrgJob implements Serializable {
* 逻辑删除标识(0未删除,其它已删除)
*/
private Long isDelete;
public static class LongListTypeHandler<Long> extends BaseListTypeHandler<Long> {
}
}

View File

@ -28,10 +28,6 @@ public class OrgJobGroup implements Serializable {
private static final long serialVersionUID = 5424203030547622211L;
/**
* 主键
*/
/**
* 主键
*/

View File

@ -4,7 +4,6 @@ import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
@ -22,13 +21,8 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "org_job_group_relation", autoResultMap = true)
public class OrgJobGroupRelation implements Serializable {
public class OrgJobGroupRelation {
private static final long serialVersionUID = 2195750914706800541L;
/**
* 主键
*/
/**
* 主键
*/

View File

@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import lombok.AllArgsConstructor;
@ -25,11 +24,8 @@ import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@TableName(value = "org_job_group_relation_history", autoResultMap = true)
public class OrgJobGroupRelationHistory implements Serializable {
public class OrgJobGroupRelationHistory {
/**
* 主键
*/
/**
* 主键
*/

View File

@ -29,10 +29,6 @@ public class OrgJobHistory implements Serializable {
private static final long serialVersionUID = -273293135363926439L;
/**
* 主键
*/
/**
* 主键
*/

View File

@ -0,0 +1,50 @@
package cn.axzo.orgmanax.infra.dao.orgjob.repository;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.foundation.page.PageReqV2;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJobGroupRelation;
import cn.hutool.core.collection.CollUtil;
import java.util.Collection;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* @author syl
* @date 2024/12/23
*/
public interface OrgJobGroupRelationRepository {
PageResp<OrgJobGroupRelation> page(PageReq req);
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class PageReq extends PageReqV2 {
/**
* 分组id集合
*/
@CriteriaField(field = "id", operator = Operator.IN)
private Collection<Long> groupIds;
/**
* 岗位分组编码集合
*/
private Collection<String> groupCodes;
/**
* 岗位编码集合
*/
private Collection<String> jobCodes;
public boolean isInvalid() {
return CollUtil.isEmpty(groupIds)
&& CollUtil.isEmpty(groupCodes)
&& CollUtil.isEmpty(jobCodes);
}
}
}

View File

@ -0,0 +1,52 @@
package cn.axzo.orgmanax.infra.dao.orgjob.repository;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.foundation.page.PageReqV2;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.enums.OrgJobGroupFlagEnum;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJobGroup;
import cn.hutool.core.collection.CollUtil;
import java.util.Collection;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
public interface OrgJobGroupRepository {
PageResp<OrgJobGroup> page(PageReq req);
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class PageReq extends PageReqV2 {
/**
* 分组编码集合
*/
@CriteriaField(field = "id", operator = Operator.IN)
private Collection<Long> groupIds;
/**
* 分组编码集合
*/
@CriteriaField(field = "code", operator = Operator.IN)
private Collection<String> groupCodes;
/**
* 岗位分组标识集合
*/
@CriteriaField(field = "flag", operator = Operator.IN)
private Collection<OrgJobGroupFlagEnum> orgJobGroupFlags;
public boolean isInvalid() {
return CollUtil.isEmpty(groupIds)
&& CollUtil.isEmpty(groupCodes)
&& CollUtil.isEmpty(orgJobGroupFlags);
}
}
}

View File

@ -4,22 +4,18 @@ import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.foundation.page.PageReqV2;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.enums.OrgJobTypeEnum;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJob;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.Collection;
public interface OrgJobQueryRepository {
@ -55,6 +51,18 @@ public interface OrgJobQueryRepository {
@CriteriaField(field = "code", operator = Operator.IN)
private Collection<String> codes;
/**
* 岗位类型
*/
@CriteriaField
private OrgJobTypeEnum type;
/**
* 搜索关键字
* Notice: 名称或别名的模糊搜索
*/
@CriteriaField(ignore = true)
private String keyword;
}
@EqualsAndHashCode(callSuper = true)

View File

@ -0,0 +1,39 @@
package cn.axzo.orgmanax.infra.dao.orgjob.repository.impl;
import cn.axzo.foundation.dao.support.converter.PageConverter;
import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.infra.dao.orgjob.dao.OrgJobGroupRelationDao;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJobGroupRelation;
import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobGroupRelationRepository;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
/**
* @author syl
* @date 2024/12/23
*/
@RequiredArgsConstructor
@Repository
public class OrgJobGroupRelationRepositoryImpl implements OrgJobGroupRelationRepository {
private final OrgJobGroupRelationDao orgJobGroupRelationDao;
@Override
public PageResp<OrgJobGroupRelation> page(PageReq req) {
IPage<OrgJobGroupRelation> page = PageConverter.toMybatis(req, OrgJobGroupRelation.class);
QueryWrapper<OrgJobGroupRelation> wrapper = QueryWrapperHelper.fromBean(req, OrgJobGroupRelation.class);
IPage<OrgJobGroupRelation> results = orgJobGroupRelationDao.page(page, wrapper)
.convert(e -> BeanUtil.toBean(e, OrgJobGroupRelation.class));
PageResp<OrgJobGroupRelation> resp = PageConverter.toResp(results);
List<OrgJobGroupRelation> records = resp.getData();
if (CollUtil.isEmpty(records)) {
return resp;
}
return resp;
}
}

View File

@ -0,0 +1,40 @@
package cn.axzo.orgmanax.infra.dao.orgjob.repository.impl;
import cn.axzo.foundation.dao.support.converter.PageConverter;
import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.infra.dao.orgjob.dao.OrgJobGroupDao;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJobGroup;
import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobGroupRepository;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
/**
* @author syl
* @date 2024/12/23
*/
@RequiredArgsConstructor
@Repository
public class OrgJobGroupRepositoryImpl implements OrgJobGroupRepository {
private final OrgJobGroupDao orgJobGroupDao;
@Override
public PageResp<OrgJobGroup> page(PageReq req) {
IPage<OrgJobGroup> page = PageConverter.toMybatis(req, OrgJobGroup.class);
QueryWrapper<OrgJobGroup> wrapper = QueryWrapperHelper.fromBean(req, OrgJobGroup.class);
IPage<OrgJobGroup> results = orgJobGroupDao.page(page, wrapper)
.convert(e -> BeanUtil.toBean(e, OrgJobGroup.class));
PageResp<OrgJobGroup> resp = PageConverter.toResp(results);
List<OrgJobGroup> records = resp.getData();
if (CollUtil.isEmpty(records)) {
return resp;
}
return resp;
}
}

View File

@ -6,16 +6,14 @@ import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.infra.dao.orgjob.dao.OrgJobDao;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJob;
import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobQueryRepository;
import cn.axzo.orgmanax.infra.dao.unit.entity.OrganizationalUnit;
import cn.axzo.orgmanax.infra.dao.unit.repository.UnitQueryRepository;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Repository;
@RequiredArgsConstructor
@Repository
@ -28,6 +26,11 @@ public class OrgJobQueryRepositoryImpl implements OrgJobQueryRepository {
public PageResp<JobResp> page(ListReq req) {
IPage<OrgJob> page = PageConverter.toMybatis(req, OrgJob.class);
QueryWrapper<OrgJob> wrapper = QueryWrapperHelper.fromBean(req, OrgJob.class);
if (StringUtils.isNotBlank(req.getKeyword())) {
wrapper.and(wr -> wr.like("name", req.getKeyword())
.or()
.like("alias", req.getKeyword()));
}
if (wrapper.isEmptyOfWhere()) {
return PageResp.<JobResp>builder().build();
}

View File

@ -3,12 +3,15 @@ package cn.axzo.orgmanax.server.orgjob.controller;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.orgjob.feign.OrgJobApi;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import cn.axzo.orgmanax.dto.job.req.CreateOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.DeleteOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.ListOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.PageOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.UpdateOrgJobReq;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import cn.axzo.orgmanax.server.orgjob.service.OrgJobService;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobAggregatePageParam;
import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -40,4 +43,9 @@ public class OrgJobController implements OrgJobApi {
public ApiResult<PageResp<OrgJobDTO>> list(ListOrgJobReq req) {
return ApiResult.success(orgJobService.list(req));
}
@Override
public ApiResult<PageResp<OrgJobDTO>> page(PageOrgJobReq req) {
return ApiResult.success(orgJobService.page(BeanUtil.copyProperties(req, OrgJobAggregatePageParam.class)));
}
}

View File

@ -0,0 +1,27 @@
package cn.axzo.orgmanax.server.orgjob.foundation;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.dto.OrgJobGroupDTO;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobGroupPageParam;
import java.util.List;
/**
* @author syl
* @date 2024/12/23
*/
public interface OrgJobGroupFoundationService {
/**
* 查询岗位分组列表
*
* @param param 分组列表查询入参
* @return 分组列表
*/
PageResp<OrgJobGroupDTO> page(OrgJobGroupPageParam param);
/**
* 查询岗位分组
*/
List<OrgJobGroupDTO> whileQuery(OrgJobGroupPageParam param);
}

View File

@ -0,0 +1,26 @@
package cn.axzo.orgmanax.server.orgjob.foundation;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.dto.OrgJobGroupRelationDTO;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobGroupRelationPageParam;
import java.util.List;
/**
* @author syl
* @date 2024/12/23
*/
public interface OrgJobGroupRelationFoundationService {
/**
* 查询岗位分组列表
*
* @param param 分组列表查询入参
* @return 分组列表
*/
PageResp<OrgJobGroupRelationDTO> page(OrgJobGroupRelationPageParam param);
/**
* 查询岗位分组
*/
List<OrgJobGroupRelationDTO> whileQuery(OrgJobGroupRelationPageParam param);
}

View File

@ -1,8 +1,8 @@
package cn.axzo.orgmanax.server.orgjob.foundation.impl;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.req.ListOrgJobReq;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import cn.axzo.orgmanax.dto.job.req.ListOrgJobReq;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJob;
import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobQueryRepository;
import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobUpsertRepository;
@ -40,7 +40,7 @@ public class OrgJobFoundationServiceImpl implements OrgJobFoundationService {
@Override
public PageResp<OrgJobDTO> page(ListOrgJobReq req) {
PageResp<OrgJobQueryRepository.JobResp> page = orgJobQueryRepository.page(BeanUtil.copyProperties(req, OrgJobQueryRepository.ListReq.class));
PageResp<OrgJobQueryRepository.JobResp> page = orgJobQueryRepository.page(convert(req));
return PageResp.<OrgJobDTO>builder()
.size(page.getSize())
.current(page.getCurrent())
@ -49,4 +49,10 @@ public class OrgJobFoundationServiceImpl implements OrgJobFoundationService {
.build();
}
public OrgJobQueryRepository.ListReq convert(ListOrgJobReq req) {
OrgJobQueryRepository.ListReq param = BeanUtil.copyProperties(req, OrgJobQueryRepository.ListReq.class);
param.setIds(req.getJobIds());
param.setCodes(req.getJobCodes());
return param;
}
}

View File

@ -0,0 +1,55 @@
package cn.axzo.orgmanax.server.orgjob.foundation.impl;
import static cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobPageParam.JOB_PAGE_SIZE;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.dto.OrgJobGroupDTO;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJobGroup;
import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobGroupRepository;
import cn.axzo.orgmanax.server.orgjob.foundation.OrgJobGroupFoundationService;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobGroupPageParam;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* @author syl
* @date 2024/12/23
*/
@RequiredArgsConstructor
@Service
public class OrgJobGroupFoundationServiceImpl implements OrgJobGroupFoundationService {
private final OrgJobGroupRepository orgJobGroupRepository;
@Override
public PageResp<OrgJobGroupDTO> page(OrgJobGroupPageParam param) {
PageResp<OrgJobGroup> page = orgJobGroupRepository.page(
BeanUtil.copyProperties(param, OrgJobGroupRepository.PageReq.class));
return PageResp.<OrgJobGroupDTO>builder()
.size(page.getSize())
.current(page.getCurrent())
.total(page.getTotal())
.data(BeanUtil.copyToList(page.getData(), OrgJobGroupDTO.class))
.build();
}
@Override
public List<OrgJobGroupDTO> whileQuery(OrgJobGroupPageParam param) {
List<OrgJobGroupDTO> jobGroups = new ArrayList<>();
PageResp<OrgJobGroupDTO> jobGroupPage;
int pageNumber = 0;
param.setPageSize(JOB_PAGE_SIZE);
do {
param.setPage(++pageNumber);
jobGroupPage = this.page(param);
if (CollUtil.isNotEmpty(jobGroupPage.getData())) {
jobGroups.addAll(jobGroupPage.getData());
}
} while (jobGroupPage.hasNext());
return jobGroups;
}
}

View File

@ -0,0 +1,55 @@
package cn.axzo.orgmanax.server.orgjob.foundation.impl;
import static cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobPageParam.JOB_PAGE_SIZE;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.dto.OrgJobGroupRelationDTO;
import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJobGroupRelation;
import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobGroupRelationRepository;
import cn.axzo.orgmanax.server.orgjob.foundation.OrgJobGroupRelationFoundationService;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobGroupRelationPageParam;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import java.util.ArrayList;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
/**
* @author syl
* @date 2024/12/23
*/
@RequiredArgsConstructor
@Service
public class OrgJobGroupRelationFoundationServiceImpl implements OrgJobGroupRelationFoundationService {
private final OrgJobGroupRelationRepository orgJobGroupRelationRepository;
@Override
public PageResp<OrgJobGroupRelationDTO> page(OrgJobGroupRelationPageParam param) {
PageResp<OrgJobGroupRelation> page = orgJobGroupRelationRepository.page(
BeanUtil.copyProperties(param, OrgJobGroupRelationRepository.PageReq.class));
return PageResp.<OrgJobGroupRelationDTO>builder()
.size(page.getSize())
.current(page.getCurrent())
.total(page.getTotal())
.data(BeanUtil.copyToList(page.getData(), OrgJobGroupRelationDTO.class))
.build();
}
@Override
public List<OrgJobGroupRelationDTO> whileQuery(OrgJobGroupRelationPageParam param) {
List<OrgJobGroupRelationDTO> jobGroupRelations = new ArrayList<>();
PageResp<OrgJobGroupRelationDTO> jobGroupPage;
int pageNumber = 0;
param.setPageSize(JOB_PAGE_SIZE);
do {
param.setPage(++pageNumber);
jobGroupPage = this.page(param);
if (CollUtil.isNotEmpty(jobGroupPage.getData())) {
jobGroupRelations.addAll(jobGroupPage.getData());
}
} while (jobGroupPage.hasNext());
return jobGroupRelations;
}
}

View File

@ -0,0 +1,23 @@
package cn.axzo.orgmanax.server.orgjob.service;
public interface OrgJobBizService {
// List<JobGroupRes> groupAndJobTree();
// List<OrgJobRes> page(OrgJobListReq req);
// void createJob(OrgJobCreateReq req);
//
// void deleteJob(Long jobId, Long operatorId);
//
// void editJob(JobEditReq req);
//
// void setRoles(JobRoleSetReq req);
//
// void move(MoveJobReq req);
//
// OrgJobDTO getById(Long jobId, Boolean needJobGroup);
//
// OrgJobRes queryDefaultOrgJob(Long topNodeId);
}

View File

@ -1,11 +1,12 @@
package cn.axzo.orgmanax.server.orgjob.service;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import cn.axzo.orgmanax.dto.job.req.CreateOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.DeleteOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.ListOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.UpdateOrgJobReq;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobAggregatePageParam;
public interface OrgJobService {
@ -36,4 +37,9 @@ public interface OrgJobService {
* @return
*/
PageResp<OrgJobDTO> list(ListOrgJobReq req);
/**
* 聚合查询岗位
*/
PageResp<OrgJobDTO> page(OrgJobAggregatePageParam req);
}

View File

@ -0,0 +1,77 @@
package cn.axzo.orgmanax.server.orgjob.service.dto;
import cn.axzo.foundation.page.PageReqV2;
import cn.axzo.orgmanax.dto.job.enums.OrgJobGroupFlagEnum;
import cn.axzo.orgmanax.dto.job.enums.OrgJobTypeEnum;
import cn.hutool.core.collection.CollUtil;
import java.util.Objects;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @author luofu
* @version 1.0
* @date 2024/9/12
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobAggregatePageParam extends PageReqV2 {
/**
* 岗位分组标识集合
*/
private Set<OrgJobGroupFlagEnum> orgJobGroupFlags;
/**
* 分组编码集合
*/
private Set<String> orgJobGroupCodes;
/**
* 岗位id集合
*/
private Set<Long> jobIds;
/**
* 岗位编码集合
*/
private Set<String> jobCodes;
/**
* 岗位类型
*/
private OrgJobTypeEnum type;
/**
* 搜索关键字
* Notice: 名称或别名的模糊搜索
*/
private String keyword;
/**
* 是否需要查询角色信息
*/
@Builder.Default
private Boolean needSaasRole = false;
/**
* 是否需要查询岗位分组信息
*/
@Builder.Default
private Boolean needJobGroup = false;
public boolean isInvalid() {
return CollUtil.isEmpty(orgJobGroupFlags)
&& CollUtil.isEmpty(orgJobGroupCodes)
&& CollUtil.isEmpty(jobIds)
&& CollUtil.isEmpty(jobCodes)
&& Objects.isNull(type)
&& StringUtils.isBlank(keyword);
}
@Override
public String toString() {
return super.toString();
}
}

View File

@ -0,0 +1,47 @@
package cn.axzo.orgmanax.server.orgjob.service.dto;
import cn.axzo.foundation.page.PageReqV2;
import cn.axzo.orgmanax.dto.job.enums.OrgJobGroupFlagEnum;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import java.util.Collection;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* @author luofu
* @version 1.0
* @date 2024/9/12
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobGroupPageParam extends PageReqV2 {
/**
* 分组编码集合
*/
private Collection<Long> groupIds;
/**
* 分组编码集合
*/
private Collection<String> groupCodes;
/**
* 岗位分组标识集合
*/
private Collection<OrgJobGroupFlagEnum> orgJobGroupFlags;
public boolean isInvalid() {
return CollUtil.isEmpty(groupIds)
&& CollUtil.isEmpty(groupCodes)
&& CollUtil.isEmpty(orgJobGroupFlags);
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,45 @@
package cn.axzo.orgmanax.server.orgjob.service.dto;
import cn.axzo.foundation.page.PageReqV2;
import cn.hutool.core.collection.CollUtil;
import java.util.Collection;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* @author luofu
* @version 1.0
* @date 2024/9/13
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobGroupRelationPageParam extends PageReqV2 {
/**
* 分组id集合
*/
private Collection<Long> groupIds;
/**
* 岗位分组编码集合
*/
private Collection<String> groupCodes;
/**
* 岗位编码集合
*/
private Collection<String> jobCodes;
public boolean isInvalid() {
return CollUtil.isEmpty(groupCodes)
&& CollUtil.isEmpty(jobCodes)
&& CollUtil.isEmpty(groupIds);
}
@Override
public String toString() {
return super.toString();
}
}

View File

@ -0,0 +1,64 @@
//package cn.axzo.orgmanax.server.orgjob.service.dto;
//
//import cn.axzo.maokai.common.enums.OrgJobTypeEnum;
//import cn.hutool.core.collection.CollUtil;
//import java.util.Collection;
//import java.util.Objects;
//import lombok.AllArgsConstructor;
//import lombok.Builder;
//import lombok.Data;
//import lombok.NoArgsConstructor;
//import org.apache.commons.lang.StringUtils;
//
///**
// * @author luofu
// * @version 1.0
// * @date 2024/9/12
// */
//@Data
//@Builder
//@NoArgsConstructor
//@AllArgsConstructor
//public class OrgJobListParam {
//
// public static final OrgJobListParam EMPTY_INSTANCE = OrgJobListParam.builder().build();
//
// /**
// * 岗位id集合
// */
// private Collection<Long> jobIds;
// /**
// * 岗位编码集合
// */
// private Collection<String> jobCodes;
// /**
// * 岗位类型
// */
// private OrgJobTypeEnum type;
// /**
// * 搜索关键字
// * Notice: 名称或别名的模糊搜索
// */
// private String keyword;
//
// public static OrgJobListParam from(OrgJobAggregateListParam param) {
// return OrgJobListParam.builder()
// .jobIds(param.getJobIds())
// .jobCodes(param.getJobCodes())
// .type(param.getType())
// .keyword(param.getKeyword())
// .build();
// }
//
// public boolean isInvalid() {
// return CollUtil.isEmpty(jobIds)
// && CollUtil.isEmpty(jobCodes)
// && Objects.isNull(type)
// && StringUtils.isBlank(keyword);
// }
//
// @Override
// public String toString() {
// return super.toString();
// }
//}

View File

@ -0,0 +1,82 @@
package cn.axzo.orgmanax.server.orgjob.service.dto;
import cn.axzo.foundation.page.PageReqV2;
import cn.axzo.orgmanax.dto.job.enums.OrgJobTypeEnum;
import cn.axzo.orgmanax.dto.job.req.ListOrgJobReq;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import java.util.Objects;
import java.util.Set;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* @author luofu
* @version 1.0
* @date 2024/9/18
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class OrgJobPageParam extends PageReqV2 {
public static final OrgJobPageParam EMPTY_INSTANCE = new OrgJobPageParam();
public static final Integer JOB_PAGE_SIZE = 1000;
/**
* 岗位id集合
*/
private Set<Long> jobIds;
/**
* 岗位编码集合
*/
private Set<String> jobCodes;
/**
* 岗位类型
*/
private OrgJobTypeEnum type;
/**
* 搜索关键字
* Notice: 名称或别名的模糊搜索
*/
private String keyword;
public static OrgJobPageParam from(OrgJobAggregatePageParam param) {
OrgJobPageParam jobPageParam = new OrgJobPageParam();
jobPageParam.setType(param.getType());
jobPageParam.setKeyword(param.getKeyword());
jobPageParam.setJobIds(param.getJobIds());
jobPageParam.setJobCodes(param.getJobCodes());
jobPageParam.setPage(param.getPage());
jobPageParam.setPageSize(param.getPageSize());
return jobPageParam;
}
public boolean isInvalid() {
return CollUtil.isEmpty(jobIds)
&& CollUtil.isEmpty(jobCodes)
&& Objects.isNull(type)
&& StringUtils.isBlank(keyword);
}
public ListOrgJobReq convert() {
return BeanUtil.toBean(this, ListOrgJobReq.class);
}
// public Integer getPage() {
// return Optional.ofNullable(super.getPage()).orElse(1);
// }
//
// public Integer getPageSize() {
// return Optional.ofNullable(super.getPageSize()).orElse(20);
// }
@Override
public String toString() {
return super.toString();
}
}

View File

@ -1,23 +1,72 @@
package cn.axzo.orgmanax.server.orgjob.service.impl;
import static cn.axzo.orgmanax.dto.job.dto.OrgJobCodeConstants.CODE_KEY;
import static cn.axzo.orgmanax.dto.job.dto.OrgJobCodeConstants.OLD_CONFIG;
import static cn.axzo.orgmanax.dto.job.dto.OrgJobCodeConstants.OLD_NEW_JOB_CODE_MAP_KEY;
import static cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobPageParam.JOB_PAGE_SIZE;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import cn.axzo.orgmanax.dto.job.dto.RoleDTO;
import cn.axzo.orgmanax.dto.job.enums.OrgJobTypeEnum;
import cn.axzo.orgmanax.dto.job.req.CreateOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.DeleteOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.ListOrgJobReq;
import cn.axzo.orgmanax.dto.job.req.UpdateOrgJobReq;
import cn.axzo.orgmanax.dto.job.dto.OrgJobDTO;
import cn.axzo.orgmanax.dto.job.dto.OrgJobGroupDTO;
import cn.axzo.orgmanax.dto.job.dto.OrgJobGroupRelationDTO;
import cn.axzo.orgmanax.infra.client.tyr.RoleGateway;
import cn.axzo.orgmanax.server.orgjob.foundation.OrgJobFoundationService;
import cn.axzo.orgmanax.server.orgjob.foundation.OrgJobGroupFoundationService;
import cn.axzo.orgmanax.server.orgjob.foundation.OrgJobGroupRelationFoundationService;
import cn.axzo.orgmanax.server.orgjob.foundation.dto.OrgJobCreator;
import cn.axzo.orgmanax.server.orgjob.service.OrgJobService;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobAggregatePageParam;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobGroupPageParam;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobGroupRelationPageParam;
import cn.axzo.orgmanax.server.orgjob.service.dto.OrgJobPageParam;
import cn.axzo.tyr.feign.req.PageRoleReq;
import cn.axzo.tyr.feign.resp.RoleResp;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.stereotype.Service;
@Slf4j
@RequiredArgsConstructor
@Service
public class OrgJobServiceImpl implements OrgJobService {
private final OrgJobFoundationService foundationService;
private final OrgJobGroupFoundationService orgJobGroupService;
private final OrgJobGroupRelationFoundationService orgJobGroupRelationService;
private final RoleGateway roleGateway;
private final LoadingCache<String, ImmutableMap<String, String>> jobCodeMappingCache = CacheBuilder.newBuilder()
.expireAfterWrite(Duration.ofMinutes(30))
.build(CacheLoader.from(this::loadJobCodeMappingCache));
@Override
public OrgJobDTO create(CreateOrgJobReq req) {
@ -40,4 +89,213 @@ public class OrgJobServiceImpl implements OrgJobService {
public PageResp<OrgJobDTO> list(ListOrgJobReq req) {
return foundationService.page(req);
}
@Override
public PageResp<OrgJobDTO> page(OrgJobAggregatePageParam param) {
if (param.isInvalid()) {
log.info("org job page param is invalid. param:{}", JSONUtil.toJsonStr(param));
return PageResp.<OrgJobDTO>builder().build();
}
OrgJobPageParam orgJobPageParam = resolveJobPageParam(param);
PageResp<OrgJobDTO> orgJobs = foundationService.page(orgJobPageParam.convert());
if (CollUtil.isEmpty(orgJobs.getData())) {
log.info("org job page there is not any job. param:{}", JSONUtil.toJsonStr(orgJobPageParam));
return PageResp.<OrgJobDTO>builder().build();
}
if (BooleanUtils.isTrue(param.getNeedJobGroup())) {
// 设置岗位信息
buildOrgGroup4OrgJob(orgJobs.getData());
}
if (BooleanUtils.isTrue(param.getNeedSaasRole())) {
// 设置角色信息
buildSaasRole4OrgJob(orgJobs.getData());
}
return orgJobs;
}
private void buildSaasRole4OrgJob(List<OrgJobDTO> orgJobs) {
Set<Long> roleIds = orgJobs.stream()
.flatMap(e -> e.mergeAndDistinctRolesIds().stream())
.collect(Collectors.toSet());
Map<Long, RoleResp> saasRoleMap = listSaasRoles(roleIds);
if (CollUtil.isEmpty(saasRoleMap)) {
return;
}
orgJobs.forEach(e -> {
Set<Long> mergedRoleIds = e.mergeAndDistinctRolesIds();
if (CollUtil.isNotEmpty(mergedRoleIds)) {
List<RoleResp> roles = mergedRoleIds.stream()
.map(saasRoleMap::get)
.filter(Objects::nonNull)
.collect(Collectors.toList());
e.setSaasRoles(BeanUtil.copyToList(roles, RoleDTO.class));
}
});
}
private Map<Long, RoleResp> listSaasRoles(Set<Long> roleIds) {
if (CollUtil.isEmpty(roleIds)) {
return Collections.emptyMap();
}
List<RoleResp> roles = new ArrayList<>();
PageRoleReq param = PageRoleReq.builder().roleIds(roleIds).build();
PageResp<RoleResp> rolePage;
int pageNumber = 0;
param.setPageSize(JOB_PAGE_SIZE);
do {
param.setPage(++pageNumber);
rolePage = roleGateway.page(param);
if (CollUtil.isNotEmpty(rolePage.getData())) {
roles.addAll(rolePage.getData());
}
} while (rolePage.hasNext());
return roles.stream()
.collect(Collectors.toMap(RoleResp::getRoleId, Function.identity(), (oldVal, newVal) -> oldVal));
}
private void buildOrgGroup4OrgJob(List<OrgJobDTO> orgJobs) {
// 查询岗位与分组的关联关系
OrgJobGroupRelationPageParam relationPageParam = OrgJobGroupRelationPageParam.builder()
.jobCodes(orgJobs.stream().map(OrgJobDTO::getCode).collect(Collectors.toSet()))
.build();
Map<String, String> relationGroup = orgJobGroupRelationService.whileQuery(relationPageParam)
.stream()
.collect(Collectors.toMap(OrgJobGroupRelationDTO::getJobCode,
OrgJobGroupRelationDTO::getGroupCode, (oldVal, newVal) -> oldVal));
if (CollUtil.isEmpty(relationGroup)) {
log.info("buildOrgGroup4OrgJob orgJobGroupRelation without any group.");
return;
}
// 查询岗位分组列表
Set<String> groupCodes = Sets.newHashSet(relationGroup.values());
OrgJobGroupPageParam groupListParam = OrgJobGroupPageParam.builder().groupCodes(groupCodes).build();
Map<String, OrgJobGroupDTO> groupMap = orgJobGroupService.whileQuery(groupListParam).stream()
.collect(Collectors.toMap(OrgJobGroupDTO::getCode, Function.identity(), (oldVal, newVal) -> oldVal));
if (CollUtil.isEmpty(groupMap)) {
log.info("buildOrgGroup4OrgJob orgJobGroup without any group.");
return;
}
// 设置分组编码(自定义可能没有分组编码)
orgJobs.stream()
.filter(e -> relationGroup.containsKey(e.getCode()))
.forEach(e -> e.setJobGroup(groupMap.get(relationGroup.get(e.getCode()))));
}
private OrgJobPageParam resolveJobPageParam(OrgJobAggregatePageParam param) {
OrgJobPageParam jobPageParam = OrgJobPageParam.from(param);
jobPageParam.setJobCodes(resolveJobCodes(param.getJobCodes()));
if (CollUtil.isEmpty(param.getOrgJobGroupCodes())
&& CollUtil.isEmpty(param.getOrgJobGroupFlags())) {
return jobPageParam;
}
// 通过分组相关参数参数JOB
OrgJobGroupPageParam groupListParam = OrgJobGroupPageParam.builder()
.orgJobGroupFlags(param.getOrgJobGroupFlags())
.groupCodes(param.getOrgJobGroupCodes())
.build();
Set<String> jobCodes = resolveJobCodesByGroup(groupListParam);
if (CollUtil.isEmpty(jobCodes)) {
log.info("resolveJobPageParam the param of job group is invalid. param:{}",
JSONUtil.toJsonStr(groupListParam));
return OrgJobPageParam.EMPTY_INSTANCE;
}
if (CollUtil.isEmpty(jobPageParam.getJobCodes())) {
// 直接设置jobCodes入参
jobPageParam.setJobCodes(jobCodes);
} else {
// jobCodes取交集
Collection<String> intersection = CollUtil.intersection(jobPageParam.getJobCodes(), jobCodes);
if (CollUtil.isEmpty(intersection)) {
log.info("resolveJobPageParam the intersection is empty. param:{}",
JSONUtil.toJsonStr(groupListParam));
return OrgJobPageParam.EMPTY_INSTANCE;
}
jobPageParam.setJobCodes(Sets.newHashSet(intersection));
}
return jobPageParam;
}
private Set<String> resolveJobCodesByGroup(OrgJobGroupPageParam groupListParam) {
List<OrgJobGroupDTO> groups = orgJobGroupService.whileQuery(groupListParam);
if (CollUtil.isEmpty(groups)) {
log.info("resolveJobCodesByGroup there is not any job group. param:{}", JSONUtil.toJsonStr(groupListParam));
return Collections.emptySet();
}
Set<String> groupCodes = groups.stream().map(OrgJobGroupDTO::getCode).collect(Collectors.toSet());
OrgJobGroupRelationPageParam relationListParam = OrgJobGroupRelationPageParam.builder()
.groupCodes(groupCodes)
.build();
List<OrgJobGroupRelationDTO> relations = orgJobGroupRelationService.whileQuery(relationListParam);
if (CollUtil.isEmpty(relations)) {
log.info("resolveJobCodesByGroup there is not any job and group relation. param:{}",
JSONUtil.toJsonStr(relationListParam));
return Collections.emptySet();
}
return relations.stream().map(OrgJobGroupRelationDTO::getJobCode).collect(Collectors.toSet());
}
private ImmutableMap<String, String> loadJobCodeMappingCache() {
OrgJobPageParam listParam = OrgJobPageParam.builder().type(OrgJobTypeEnum.SYSTEM).build();
List<OrgJobDTO> orgJobs = this.whileQuery(listParam);
if (CollUtil.isEmpty(orgJobs)) {
return ImmutableMap.<String, String>builder().build();
}
Map<String, String> map = Maps.newHashMap();
orgJobs.stream()
.filter(e -> Objects.nonNull(e.getRecordExt()))
.filter(e -> CollUtil.isNotEmpty(e.getRecordExt().getJSONArray(OLD_CONFIG)))
.forEach(e -> cacheJobCodeMapping(e, map));
return ImmutableMap.copyOf(map);
}
public List<OrgJobDTO> whileQuery(OrgJobPageParam param) {
ListOrgJobReq listParam = ListOrgJobReq.builder().type(param.getType()).build();
List<OrgJobDTO> jobs = new ArrayList<>();
PageResp<OrgJobDTO> jobPage;
int pageNumber = 0;
param.setPageSize(JOB_PAGE_SIZE);
do {
param.setPage(++pageNumber);
jobPage = foundationService.page(listParam);
if (CollUtil.isNotEmpty(jobPage.getData())) {
jobs.addAll(jobPage.getData());
}
} while (jobPage.hasNext());
return jobs;
}
private Set<String> resolveJobCodes(Collection<String> jobCodes) {
if (CollUtil.isEmpty(jobCodes)) {
return Collections.emptySet();
}
ImmutableMap<String, String> jobCodeMapping = jobCodeMappingCache.getUnchecked(OLD_NEW_JOB_CODE_MAP_KEY);
if (CollUtil.isEmpty(jobCodeMapping)) {
return Sets.newHashSet(jobCodes);
}
Set<String> mergeJobCodes = Sets.newHashSet(jobCodes);
jobCodes.stream()
.filter(jobCodeMapping::containsKey)
.forEach(e -> mergeJobCodes.add(jobCodeMapping.get(e)));
return mergeJobCodes;
}
private void cacheJobCodeMapping(OrgJobDTO job, Map<String, String> map) {
JSONObject recordExt = job.getRecordExt();
if (Objects.isNull(recordExt)) {
return;
}
JSONArray oldJobConfigs = recordExt.getJSONArray(OLD_CONFIG);
if (CollUtil.isEmpty(oldJobConfigs)) {
return;
}
IntStream.range(0, oldJobConfigs.size())
.mapToObj(oldJobConfigs::getJSONObject)
.collect(Collectors.toList()).stream()
.filter(e -> e.containsKey(CODE_KEY))
.forEach(e -> map.put(e.getString(CODE_KEY), job.getCode()));
}
}