Merge branch 'feature/REQ-3714' into 'master'

Feature/req 3714

See merge request universal/infrastructure/backend/orgmanax!274
This commit is contained in:
谭杰 2025-03-26 03:46:51 +00:00
commit b2c4a7c1ee
134 changed files with 7112 additions and 40 deletions

View File

@ -0,0 +1,41 @@
package cn.axzo.orgmanax.api.nodeuser.feign;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp;
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
*
* @author tanjie@axzo.cn
* @date 2024/12/2 15:40
*/
@FeignClient(
value = "orgmanax",
url = "${axzo.service.orgmanax:http://orgmanax:8080}")
public interface OrgNodeUserCheckApi {
/**
* 根据条件聚合查询节点用户
*
* @param req
* @return
*/
@PostMapping("/api/node-user/batchDelete/check/unit")
ApiResult<List<BatchDeleteNodeUserCheckResp>> checkUnit(@RequestBody @Validated BatchDeleteNodeUserCheckReq req);
/**
* 根据条件聚合查询节点用户
*
* @param req
* @return
*/
@PostMapping("/api/node-user/batchDelete/check/workspace")
ApiResult<List<BatchDeleteNodeUserCheckResp>> checkWorkspace(@RequestBody @Validated BatchDeleteNodeUserCheckReq req);
}

View File

@ -1,6 +1,8 @@
package cn.axzo.orgmanax.dto.node.dto;
import cn.axzo.foundation.result.ResultCode;
import cn.axzo.orgmanax.dto.cooperateship.dto.OrgCooperateShipDTO;
import cn.axzo.orgmanax.dto.node.enums.NodeTypeEnum;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
@ -10,6 +12,7 @@ import lombok.experimental.SuperBuilder;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@NoArgsConstructor
@ -100,6 +103,10 @@ public class OrgNodeDTO implements Serializable {
*/
private JSONObject profile;
private Long platTeamId;
private Long projectTeamId;
private Date createAt;
private Long createBy;
private Date updateAt;
@ -154,4 +161,18 @@ public class OrgNodeDTO implements Serializable {
}
return (T) Optional.ofNullable(profile).map(p -> JSONObject.parseObject(p.toString(), clazz)).orElse(null);
}
/**
* 获取项目内小组节点配置信息
* @return 是否合作小组true 独立false 非独立
*/
public Boolean independentGroup() {
if (!Objects.equals(this.nodeType, NodeTypeEnum.PROJECT_GROUP.getValue())) {
throw ResultCode.INVALID_PARAMS.toException("小组节点类型错误");
}
if (Objects.nonNull(this.profile) && !this.profile.isEmpty()) {
return this.profile.getBooleanValue("independentGroup");
}
return null;
}
}

View File

@ -0,0 +1,41 @@
package cn.axzo.orgmanax.dto.nodeuser.enums;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum CheckInfoTypeEnum {
SUPER_ADMIN(1, "超级管理员", "【%s】是超级管理员无法删除", 0),
IN_PROJECT(2, "在项目中", "【%s】在项目中无法删除", 0),
TEAM_LEADER(3, "班组长", "【%s】是班组长无法删除", 0),
PROJECT_GROUP_LEADER(4, "合作小组小组长", "【%s】是小组长无法删除", 0),
NOT_IN_JURISDICTION(5, "不在管辖范围", "【%s】不在您的管辖范围无法删除", 0),
ANY_ADMIN(6, "单位负责人", "【%s】是项目单位负责人无法删除", 0),
TASK_ORDER(7, "任务单", "当前人员有未完成的任务单:%d单。无法删除", 2),
RECTIFY_ORDERS(8, "整改单", "当前人员有未完成的整改单:%d单。无法删除", 6),
ACCEPTANCE_PROCESS(9, "验收流程", "当前人员有未完成的验收单:%d单。无法删除", 7);
private final Integer value;
private final String desc;
private final String msg;
private final Integer thirdType;
private static final Map<Integer, CheckInfoTypeEnum> thirdTypeMap = Arrays.stream(CheckInfoTypeEnum.values())
.collect(Collectors.toMap(CheckInfoTypeEnum::getThirdType, Function.identity(), (key1, key2) -> key2));
public static CheckInfoTypeEnum getByThirdType(Integer type) {
return thirdTypeMap.get(type);
}
public static boolean isThirdType(CheckInfoTypeEnum type) {
return type.getThirdType() > 0;
}
}

View File

@ -0,0 +1,102 @@
package cn.axzo.orgmanax.dto.nodeuser.enums;
import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author haiyangjin
* @date 2024/3/3
*/
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum OrganizationalNodeUserStatusEnum implements Serializable {
/**
* 在岗 -> ACTIVE
*/
@Deprecated
ON_DUTY("在岗"),
/**
* 退场
*/
QUIT("退场"),
INACTIVE("入场中"),
ACTIVE("已入场"),
LEAVE("离场"),
WITHDRAW("退场"),
JOINED("在职"),
NONE("非法值")
;
private final String desc;
public static OrganizationalNodeUserStatusEnum from(OrgUserStatusEnum status) {
switch (status) {
case ACTIVE:
return OrganizationalNodeUserStatusEnum.ACTIVE;
case LEAVE:
return OrganizationalNodeUserStatusEnum.LEAVE;
case WITHDRAW:
return OrganizationalNodeUserStatusEnum.WITHDRAW;
case JOINED:
return OrganizationalNodeUserStatusEnum.JOINED;
case QUIT:
return OrganizationalNodeUserStatusEnum.QUIT;
default:
return OrganizationalNodeUserStatusEnum.NONE;
}
}
public static boolean onDuty(OrganizationalNodeUserStatusEnum status) {
return status == ON_DUTY
|| status == ACTIVE
|| status == JOINED;
}
public static List<OrganizationalNodeUserStatusEnum> onDutyStatus() {
return Lists.newArrayList(ON_DUTY_STATUS);
}
public static Set<OrganizationalNodeUserStatusEnum> parseStatus(Collection<OrganizationalNodeUserStatusEnum> status) {
if (CollUtil.isEmpty(status)) {
return Collections.emptySet();
}
return status.stream()
.flatMap(e -> {
if (ON_DUTY == e) {
return onDutyStatus().stream();
} else if (QUIT == e) {
return Stream.of(e, WITHDRAW);
}
return Stream.of(e);
})
.collect(Collectors.toSet());
}
private static final ImmutableList<OrganizationalNodeUserStatusEnum> ON_DUTY_STATUS = ImmutableList.of(
OrganizationalNodeUserStatusEnum.ON_DUTY,
OrganizationalNodeUserStatusEnum.JOINED,
OrganizationalNodeUserStatusEnum.ACTIVE
);
public OrgUserStatusEnum toOrgUserStatusEnum() {
return OrgUserStatusEnum.valueOf(this.name());
}
}

View File

@ -0,0 +1,17 @@
package cn.axzo.orgmanax.dto.nodeuser.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum TagOperateEnum {
// 添加标签
ADD("ADD", "添加标签"),
// 移除标签
REMOVE("REMOVE", "移除标签"),
;
private final String code;
private final String desc;
}

View File

@ -0,0 +1,46 @@
package cn.axzo.orgmanax.dto.nodeuser.req;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.Set;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/6
*/
@Data
public class BatchDeleteNodeUserCheckReq {
/**
* personIds
*/
@NotNull(message = "personIds不可以为空")
private Set<Long> personIds;
private Long workspaceId;
private Long ouId;
/**
* 删除项目人员的时候传入
* 节点ID
*/
private Long nodeId;
/**
* 操作者ID
*/
private Long operatorId;
/**
* 登录单位
*/
private Long loginOuId;
/**
* 单位类型
*/
private Integer ouType;
}

View File

@ -0,0 +1,31 @@
package cn.axzo.orgmanax.dto.nodeuser.req;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Set;
/**
* @Author zr
* @Date 2025/3/7 14:26
* @Description
**/
@Data
public class DeleteNodeUserReq {
/**
* 项目部id
*/
@NotNull(message = "项目部不能为空")
private Long workspaceId;
/**
* 单位id
*/
@NotNull(message = "单位不能为空")
private Long ouId;
/**
* 自然人id
*/
@NotEmpty(message = "人员不能为空")
private Set<Long> personIds;
}

View File

@ -1,12 +1,7 @@
package cn.axzo.orgmanax.dto.nodeuser.req;
import com.alibaba.fastjson.JSONObject;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.*;
import lombok.experimental.SuperBuilder;
@NoArgsConstructor
@ -24,7 +19,11 @@ public class ProcessNodeUserReq {
@Getter
public enum Action {
CREATE("创建", "createNodeUserProcessor"),
UPDATE("普通更新", "updateNodeUserProcessor");
UPDATE("普通更新", "updateNodeUserProcessor"),
UNIT_DELETE("删除单位人员", "unitDeleteNodeUserProcessor"),
WORKSPACE_DELETE("删除项目人员", "workspaceDeleteNodeUserProcessor"),
DELETE_PLAT_TAM_WORKER("平台班组删除人员", "deletePlatTeamWorkerProcessor"),
;
private final String desc;
private final String processor;

View File

@ -0,0 +1,46 @@
package cn.axzo.orgmanax.dto.nodeuser.req;
import cn.axzo.orgmanax.dto.nodeuser.enums.TagOperateEnum;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
* 人员打标签接口
*
* @author : zhanghonghao@axzo.cn
* @since : 2025/2/18
*/
@Data
public class TagOperateReq {
private Long loginWorkspaceId;
private Long loginOuId;
/**
* 人员列表
*/
@NotEmpty(message = "人员列表不能为空")
private List<Long> personIds;
/**
* 分组标签编码
*/
@NotNull(message = "分组标签编码不能为空")
private String tagNodeCode;
/**
* 标签值编码
*/
@NotNull(message = "标签值编码不能为空")
private String tagValueCode;
/**
* 操作类型
*/
private TagOperateEnum operateType;
}

View File

@ -0,0 +1,30 @@
package cn.axzo.orgmanax.dto.nodeuser.resp;
import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/6
*/
@Data
public class BatchDeleteNodeUserCheckResp {
private Long personId;
private List<CheckFailInfo> failInfos;
@Data
@AllArgsConstructor
@NoArgsConstructor
public static class CheckFailInfo {
private CheckInfoTypeEnum type;
private Integer count;
}
}

View File

@ -7,6 +7,7 @@ import lombok.experimental.SuperBuilder;
import java.io.Serializable;
import java.util.Date;
import java.util.Set;
@NoArgsConstructor
@SuperBuilder
@ -14,6 +15,8 @@ import java.util.Date;
@AllArgsConstructor
public class OrgUserDTO implements Serializable {
private static final long serialVersionUID = 2687034361751211136L;
private Long id;
/**
@ -91,4 +94,8 @@ public class OrgUserDTO implements Serializable {
*/
private Long isDelete = 0L;
/**
* 标签
*/
private Set<String> tags;
}

View File

@ -3,11 +3,13 @@ package cn.axzo.orgmanax.dto.orguser.req;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.foundation.page.PageReqV2;
import lombok.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.Date;
import java.util.List;
import java.util.Set;
@EqualsAndHashCode(callSuper = true)
@ -16,10 +18,13 @@ import java.util.Set;
@Data
@SuperBuilder
public class ListOrgUserReq extends PageReqV2 {
@CriteriaField
private Long id;
@CriteriaField(field = "id", operator = Operator.IN)
private Set<Long> ids;
@CriteriaField(field = "id", operator = Operator.LT)
private Long idLt;
@CriteriaField
private Long personId;
@CriteriaField(field = "personId", operator = Operator.IN)
@ -103,7 +108,7 @@ public class ListOrgUserReq extends PageReqV2 {
/**
* 离职时间筛选起始
* 离职时间筛选起始
*/
@CriteriaField(field = "transferTime", operator = Operator.GE)
private Date leaveAtStart;
@ -119,4 +124,7 @@ public class ListOrgUserReq extends PageReqV2 {
*/
@CriteriaField(ignore = true)
private Boolean includeDeleted;
@CriteriaField(ignore = true)
private String tag;
}

View File

@ -0,0 +1,43 @@
package cn.axzo.orgmanax.dto.project.worker.req;
import cn.axzo.foundation.page.PageReqV2;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/6
*/
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public class ListOrgProjectWorkerReq extends PageReqV2 {
/**
* 工作台ID
*/
private Long workspaceId;
/**
* 总包ID
*/
private Long entId;
/**
* 所属单位id
*/
private Long organizationalUnitId;
/**
* 工人personId
*/
private List<Long> workerPersonIds;
}

View File

@ -120,5 +120,15 @@
<artifactId>tyr-client</artifactId>
<version>${revision}</version>
</dependency>
<dependency>
<groupId>cn.axzo.msgcenter</groupId>
<artifactId>msg-center-api-v2</artifactId>
<version>1.0.1-SNAPSHOT</version>
</dependency>
<!--xxl-job-->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -4,6 +4,7 @@ import cn.axzo.foundation.exception.BusinessException;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.foundation.util.TraceUtils;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.core.convert.Convert;
import cn.hutool.http.HttpStatus;
import com.alibaba.fastjson.JSON;
@ -39,6 +40,23 @@ public class RpcWrapper {
return wrapApiResult(supplier, desc, params, true);
}
/**
* common res 返回
* @param t
* @return
* @param <T>
*/
public static <T> T commonRes(Supplier<CommonResponse<T>> t) {
CommonResponse<T> result = t.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();
}
/**
* Api result 返回
*

View File

@ -0,0 +1,23 @@
package cn.axzo.orgmanax.infra.client.attendance;
import cn.axzo.orgmanax.infra.client.attendance.dto.AttendanceClockRecordListReq;
import cn.axzo.orgmanax.infra.client.attendance.dto.AttendanceClockRecordResp;
import java.util.List;
/**
* @author luofu
* @version 1.0
* @description 考勤记录相关的API
* @date 2025/3/5
*/
public interface AttendanceRecordClient {
/**
* 考勤打卡记录通用查询
*
* @param request 入参
* @return 打卡记录列表
*/
List<AttendanceClockRecordResp> listClockRecords(AttendanceClockRecordListReq request);
}

View File

@ -0,0 +1,75 @@
package cn.axzo.orgmanax.infra.client.attendance.dto;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import java.util.Date;
import java.util.List;
/**
* @author luofu
* @version 1.0
* @description 考勤打卡记录列表查询参数
* @date 2025/3/5
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttendanceClockRecordListReq {
public static final int USER_TYPE_WORKER = 1;
public static final int USER_TYPE_PRACTITIONER = 2;
public static final int USER_TYPE_WORKER_LEADER = 4;
/**
* 项目部id - 必传
*/
@NonNull
private Long workspaceId;
/**
* personId列表
*/
private List<Long> personIds;
/**
* 用户类型用户类型
* 1工人
* 2从业人员
* 4班组长
*/
private Integer userType;
/**
* 班组id集合
*/
private List<Long> teamIds;
/**
* 打卡开始时间
*/
private Date clockAtFrom;
/**
* 打卡结束时间
*/
private Date clockAtTo;
/**
* 打卡类型1进场2出场
*/
private Integer clockType;
/**
* 打卡方式0-闸机 1-电子围栏 2-考勤补卡
*/
private Integer clockMethod;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,53 @@
package cn.axzo.orgmanax.infra.client.attendance.dto;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author luofu
* @version 1.0
* @description 考勤打卡记录
* @date 2025/3/5
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class AttendanceClockRecordResp {
/**
* 项目部id
*/
private Long workspaceId;
/**
* 用户类型用户类型
* 1工人
* 2从业人员
* 4班组长
*/
private Integer userType;
/**
* 用户名称
*/
private String userName;
/**
* personId
*/
private Long personId;
/**
* 班组id
*/
private Long teamId;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,28 @@
package cn.axzo.orgmanax.infra.client.datatagger;
import cn.axzo.orgmanax.infra.client.datatagger.dto.OperateDataTagReq;
import cn.axzo.orgmanax.infra.client.datatagger.dto.RevokeDataTagReq;
/**
* @author luofu
* @version 1.0
* @description 标签系统的相关API
* @date 2025/3/5
*/
public interface DataTagClient {
/**
* 撤销标签
*
* @param request 入参
* @return 结果成功返回 {@code true}否则返回 {@code false}
*/
boolean revokeDataTags(RevokeDataTagReq request);
/**
* 标签操作
*
* @param tagsRequest 入参
*/
void operateDataTags(OperateDataTagReq tagsRequest);
}

View File

@ -0,0 +1,43 @@
package cn.axzo.orgmanax.infra.client.datatagger.dto;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang.StringUtils;
import java.util.List;
import java.util.Map;
/**
* @author luofu
* @version 1.0
* @date 2025/3/10
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DataTagNode {
/**
* 节点编码
*/
private String nodeCode;
/**
* 标签值的编码
*/
private List<String> valueCodes;
public boolean invalid() {
return StringUtils.isBlank(nodeCode) || CollUtil.isEmpty(valueCodes);
}
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,50 @@
package cn.axzo.orgmanax.infra.client.datatagger.dto;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author luofu
* @version 1.0
* @description 标签系统查询属性
* @date 2025/3/5
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class DataTagProperty {
/**
* 单位id
*/
private Long ouId;
/**
* 项目id
*/
private Long workspaceId;
/**
* 平台班组的nodeId
*/
private Long platTeamNodeId;
/**
* 项目班组的nodeId
*/
private Long projectTeamNodeId;
/**
* 小组的nodeId
*/
private Long groupNodeId;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,56 @@
package cn.axzo.orgmanax.infra.client.datatagger.dto;
import cn.axzo.orgmanax.infra.client.datatagger.enums.DataTagTypeEnum;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import java.util.List;
/**
* @author luofu
* @version 1.0
* @description 添加数据标签入参
* @date 2025/3/10
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OperateDataTagReq {
@NonNull
private String app;
/**
* 对象类型 - 必传
*/
@NonNull
private DataTagTypeEnum objectType;
/**
* 标签编码 - 必传
*/
@NonNull
private List<DataTagNode> tagNodes;
/**
* 对象ID
*/
@NonNull
private List<Long> objectIds;
/**
* 查询对象
*/
@Builder.Default
private DataTagProperty property = new DataTagProperty();
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,62 @@
package cn.axzo.orgmanax.infra.client.datatagger.dto;
import cn.axzo.orgmanax.infra.client.datatagger.enums.DataTagTypeEnum;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import java.util.List;
/**
* @author luofu
* @version 1.0
* @description 撤销数据标签入参
* @date 2025/3/5
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class RevokeDataTagReq {
/**
* 对象类型 - 必传
*/
@NonNull
private DataTagTypeEnum objectType;
/**
* 标签编码 - 必传
*/
@NonNull
private List<String> tagCodes;
/**
* 标签值编码
*/
private List<String> tagValueCodes;
/**
* 对象ID
*/
private List<Long> objectIds;
/**
* 查询对象
*/
@Builder.Default
private DataTagProperty properties = new DataTagProperty();
/**
* 严格模式
*/
private boolean restrictMode = true;
@Override
public String toString() {
return JSON.toJSONString(this);
}
}

View File

@ -0,0 +1,57 @@
package cn.axzo.orgmanax.infra.client.datatagger.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* @author luofu
* @version 1.0
* @description 对象类型 - 与标签系统的枚举对应 {@see cn.axzo.datatagger.common.enums.TagObjectType}
* @date 2025/3/5
*/
@Getter
@AllArgsConstructor
public enum DataTagTypeEnum {
// queryFields = [], objectId = personId
PLAT_PERSON("平台用户"),
// queryFields = [ouId], objectId = personId
UNIT_PERSON("单位用户"),
// queryFields = [workspaceId], objectId = personId
PROJECT_PERSON("项目用户"),
// queryFields = [workspaceId, ouId], objectId = personId
PROJECT_UNIT_PERSON("项目单位用户"),
// queryFields = [ouId, platTeamNodeId], objectId = personId
UNIT_TERM_PERSON("单位班组用户"),
// queryFields = [workspaceId, projectTeamNodeId], objectId = personId
PROJECT_TERM_PERSON("项目班组用户"),
// queryFields = [workspaceId, groupNodeId], objectId = personId
PROJECT_GROUP_PERSON("项目小组用户"),
// queryFields = [workspaceId?], objectId = ouId
PLAT_OR_PROJECT_UNIT("全部"),
// queryFields = [], objectId = ouId
PLAT_UNIT("平台单位"),
// queryFields = [workspaceId], objectId = ouId
PROJECT_UNIT("项目单位"),
WORKSPACE("租户"),
// queryFields = [], objectId = workspaceId
PROJECT("项目"),
// !! 班组
// queryFields = [], objectId = platTeamNodeId / projectTeamNodeId
PLAT_OR_PROJECT_TEAM("全部"),
// queryFields = [], objectId = platTeamNodeId
PLAT_TEAM("平台班组"),
// queryFields = [], objectId = projectTeamNodeId
PROJECT_TEAM("项目班组"),
// !! 小组
// queryFields = [], objectId = groupNodeId
GROUP("小组"),
// !! 部门
// queryFields = [ouId], objectId = departmentNodeId
UNIT_DEPARTMENT("单位普通部门"),
// queryFields = [workspaceId], objectId = departmentNodeId
PROJECT_DEPARTMENT("项目普通部门"),
;
private final String desc;
}

View File

@ -0,0 +1,10 @@
package cn.axzo.orgmanax.infra.client.karma;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface KarmaThirdApiClient {
Map<Long, List<ThirdCheckFailResp>> getThirdCheckFail(Long workspaceId, Set<Long> personIds);
}

View File

@ -0,0 +1,17 @@
package cn.axzo.orgmanax.infra.client.karma;
import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum;
import lombok.Data;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/7
*/
@Data
public class ThirdCheckFailResp {
private CheckInfoTypeEnum type;
private Integer count;
}

View File

@ -0,0 +1,20 @@
package cn.axzo.orgmanax.infra.client.msg;
import cn.axzo.msg.center.api.v2.message.feign.MessageApiV2;
import cn.axzo.msg.center.api.v2.message.req.MessageSendV2Req;
import cn.axzo.orgmanax.infra.client.RpcWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
@RequiredArgsConstructor
public class MsgCenterGateway {
private final MessageApiV2 messageApiV2;
public void sendMsg(MessageSendV2Req req) {
RpcWrapper.wrapApiResult(() ->messageApiV2.send(req),"发送消息、待办", req);
}
}

View File

@ -0,0 +1,14 @@
package cn.axzo.orgmanax.infra.client.msg.vo;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum JoinLeaveEnum {
JOIN("加入"),
LEAVE("退出"),
;
private final String value;
}

View File

@ -0,0 +1,48 @@
package cn.axzo.orgmanax.infra.client.msg.vo;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 新版消息
*/
@Getter
@AllArgsConstructor
public enum MessageCodeEnum {
// // bizCodeTemplate: worker:apply:leave:unit:workerIdentityId:platTeamNodeId
// WORKER_APPLY_LEAVE_UNIT("worker_leaving_unit_team", "worker:apply:leave:unit:%d:%d"),
// 加入单位班组申请提交/结果通知 您申请加入${teamLeaderName}的班组,${action} -> 工人 bizCodeTemplate: worker:apply:unit:team:platInviteId
WORKER_APPLY_UNIT_TEAM("worker_apply_for_companyclass_station", "worker:apply:unit:team:%d"),
// bizCodeTemplate: change:team:leader:new:platTeamNodeId:newTeamLeaderPersonId
CHANGE_TEAM_LEADER_TO_NEW_LEADER_MSG("companyclass_trade_for_classowner", "change:team:leader:new:%d:%d"),
// 移除单位班组通知 您已被移除${teamLeaderName}的班组,请知悉 -> 工人 bizCodeTemplate: unit:team:remove:worker:workerIdentityId:platTeamNodeId
UNIT_TEAM_REMOVE_WORKER("delete_worker_companyclass", "unit:team:remove:worker:%d:%d"),
// bizCodeTemplate: unit:profession:add/delete:platTeamNodeId:workerIdentityId
UNIT_WORKER_PROFESSION_CHANGE("companyworker_change_professionName", "unit:profession:%s:%d:%d"),
// bizCodeTemplate: unit:team:dissolve:platTeamNodeId
UNIT_TEAM_DISSOLVE("dissolution_companyclass", "unit:team:dissolve:%d"),
// ${workerName}已${action}您的班组请知悉 -> 班组长 bizCodeTemplate: worker:join/leave:unit:team:platTeamNodeId:workerPersonId
WORKER_JOIN_LEAVE_UNIT_TEAM("worker_station_companytclass_to_classowner", "worker:%s:unit:team:%d:%d"),
// 工人加入项目失败 -> 班组长 bizCodeTemplate: worker:join:workspace:failed:processInstanceId
WORKER_JOIN_WORKSPACE_FAILED("worker_fail_add_project_toclassowner", "worker:join:workspace:failed:%d"),
// 成功加入单位班组通知(手动添加班组长扫工人码加项目加入单位班组) -> 工人 bizCodeTemplate: passive:join:unit:team:platTeamNodeId:workerIdentityId
PASSIVE_JOIN_UNIT_TEAM_MSG("worker_add_to_companyclass", "passive:join:unit:team:%d:%d"),
// 带班长${action} ${realName}${action}您担任}${workspaceName}${teamLeaderName}的带班长 -> 工人 bizCodeTemplate: project:agent:leader:grant/ungrant:projectTeamId
PROJECT_AGENT_LEADER_GRANT_MSG("projectclassmanger_station_to_self", "project:agent:leader:%s:%d"),
// 班组长管理员${action} ${realName}${action}您担任${teamLeaderName}的班组管理员 -> 工人 bizCodeTemplate: project:agent:leader:grant/ungrant:teamId
UNIT_AGENT_LEADER_GRANT_MSG("classmanger_station_to_self", "unit:agent:leader:%s:%d"),
// 工人申请 ${workerName}申请加入您的班组请及时处理点击查看详情 -> 班组长 bizCodeTemplate: apply:unit:team:2leader:platInviteId
APPLY_UNIT_TEAM_MSG_2LEADER("worker_apply_company_class", "apply:unit:team:2leader:%d"),
// 班组解散 ${teamName}已解散请知悉 -> 班组长/单位负责人 bizCodeTemplate: dismiss:unit:team:2leader:nodeId
DISMISS_TEAM_2_LEADER("dismiss_team_to_leader", "dismiss:unit:team:2leader:%d"),
// 班组解散 ${teamName}已解散请知悉 -> 班组长/单位负责人 bizCodeTemplate: dismiss:unit:team:2leader:nodeId
FAIL_DISMISS_TEAM_2_INITIATOR("fail_dismiss_team", "dismiss:unit:team:fail:%d"),
;
private final String code;
private final String bizCodeTemplate;
public String buildBizCode(Object... objects) {
return String.format(bizCodeTemplate, objects);
}
}

View File

@ -0,0 +1,52 @@
package cn.axzo.orgmanax.infra.client.msg.vo;
import cn.hutool.core.text.CharSequenceUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum MessageVariableNameEnum {
// 工作台名
WORKSPACE_NAME("workspaceName"),
ORGANIZATIONAL_UNIT_NAME("organizationalUnitName"),
ORGANIZATIONAL_UNIT_TYPE("organizationalUnitType"),
PRIMARY_CONTRACTOR_OU_NAME("primaryContractorOuName"),
SUB_CONTRACTOR_OU_NAME("subContractorOuName"),
WORKER_NAME("workerName"),
TEAM_LEADER_NAME("teamLeaderName"),
PRACTITIONER_NAME("practitionerName"),
REAL_NAME("realName"),
TEAM_NAME("teamName"),
TEAM_CATEGORY_NAME("teamCategoryName"),
PROFESSION_NAME("professionName"),
ACTION("action"),
SKILL_TAG_NAME("skillTagName"),
DATE("date"),
INVITE_ID("inviteId"),
WORKER_REAL_NAME("workerRealName"),
NODE_ID("nodeId"),
TEAM_ID("teamId"),
WORKFLOW_PROCESS_TYPE("workflowProcessType"),
// 待办id
IDENTITY_CODE("identityCode"),
;
private final String name;
public static String prefix(String prefix, MessageVariableNameEnum nameEnum) {
return prefix + CharSequenceUtil.upperFirst(nameEnum.getName());
}
public static String postFix(String postFix, MessageVariableNameEnum nameEnum) {
return nameEnum.getName() + postFix;
}
@Getter
@AllArgsConstructor
public enum CommonPrefix {
NEW("new"),
OLD("old"),
;
private final String value;
}
}

View File

@ -0,0 +1,13 @@
package cn.axzo.orgmanax.infra.client.tyr;
import cn.axzo.orgmanax.infra.client.tyr.dto.OrgManaxWorkerManagerRoleUserReq;
/**
* @Author zr
* @Date 2025/3/11 14:26
* @Description
**/
public interface SaasRoleUserClient {
void grantOrUngrantWorkerManager(OrgManaxWorkerManagerRoleUserReq req);
}

View File

@ -0,0 +1,94 @@
package cn.axzo.orgmanax.infra.client.tyr.dto;
import cn.axzo.orgmanax.dto.common.IdentityType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* @Author zr
* @Date 2025/3/11 14:27
* @Description
**/
@Data
@Builder
public class OrgManaxWorkerManagerRoleUserReq {
private List<ManagerInfo> managerInfos;
/**
* 这个字段在设置后续产品重构了班组管理员代班长相关功能的时候要替换成ROLE ID
* 现在保留权限集ID是因为只是做统一权限角色查询链路先暂时不变REQ-2046)
*/
private List<Long> permissionGroupId;
/**
* 角色ID 会与权限集ID取并集
*/
private Collection<Long> roleId;
private IdentityType identityType;
@NotNull
private Integer resourceType;
// -------------
/**
* 是否取消授权
*/
@Builder.Default
private boolean ungrant = false;
/**
* 是否取消所有权限是的话则不消费permissionGroupId
*/
@Builder.Default
private boolean isUngrantAll = false;
/**
* 取消所有授权的角色分组 saas role group 上的categoryCode;
* 只有在isUngrantAll时生效
* #{@link cn.axzo.tyr.client.common.enums.SaasPositionEnum}
*/
private String roleGroupCategoryCode;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public static class ManagerInfo {
@NotNull
private Long ouId;
@NotNull
private Long workspaceId;
/**
* #{@link cn.axzo.tyr.client.common.enums.RoleResourceTypeEnum }
*/
@NotNull
private Long resourceId;
@Builder.Default
private List<IdentityInfo> identityInfos = new ArrayList<>();
}
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public static class IdentityInfo {
private Long personId;
private Long identityId;
private IdentityType identityType;
}
}

View File

@ -0,0 +1,45 @@
package cn.axzo.orgmanax.infra.client.tyr.dto;
import cn.axzo.tyr.client.common.enums.SaasPositionEnum;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.Set;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PlatWorkTeamGrantPositionReq implements Serializable {
/**
* 平台班组-单位id
*/
@NotNull
private Long platWorkTeamOuId;
/**
* 工人身份ID
*/
@NotNull
private Set<Long> workerIdentityId;
/**
* Flag 是取消授权还是授权
*/
@NotNull
private Boolean ungrant = false;
/**
* 职位Code {@link SaasPositionEnum}
*/
@NotNull
private String positionCode;
}

View File

@ -0,0 +1,16 @@
package cn.axzo.orgmanax.infra.client.workflow;
import cn.axzo.orgmanax.infra.client.workflow.dto.BatchOperationResultResp;
import cn.axzo.orgmanax.infra.client.workflow.dto.BpmnProcessInstanceAbortReq;
import java.util.List;
/**
* @Author zr
* @Date 2025/3/20 09:37
* @Description
**/
public interface WorkflowCoreClient {
BatchOperationResultResp batchAbortProcessInstance(List<BpmnProcessInstanceAbortReq> reqs);
}

View File

@ -0,0 +1,63 @@
package cn.axzo.orgmanax.infra.client.workflow.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* @Author zr
* @Date 2025/3/20 09:44
* @Description
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class BatchOperationResultResp {
/**
* 请求数量
*/
private Integer requestCount = 0;
/**
* 失败数量
*/
private Integer failCount = 0;
/**
* 批量操作处理详情
*/
private List<BatchOperationItemResultResp> details;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class BatchOperationItemResultResp {
/**
* 被处理数据的 ID
* 可以是实例 ID,也可以是任务 ID,根据调用的 API 不同而不同
*/
private String id;
/**
* 处理的数据类型: 业务审批, 流程审批
*/
private String type;
/**
* 该流程实例处理过程中是否发生错误
*/
private Boolean hasError = false;
/**
* 具体的错误信息
*/
private String errorMessage;
}

View File

@ -0,0 +1,34 @@
package cn.axzo.orgmanax.infra.client.workflow.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
/**
* @Author zr
* @Date 2025/3/20 09:39
* @Description
**/
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BpmnProcessInstanceAbortReq {
/**
* 中止原因
*/
@NotBlank(message = "中止原因不能为空")
@Length(max = 100, message = "中止原因长度不能超过 100 个字符")
private String reason;
/**
* 流程实例 ID
*/
@NotBlank(message = "流程实例 ID 不能为空")
private String processInstanceId;
}

View File

@ -1,5 +1,8 @@
package cn.axzo.orgmanax.infra.client.workspace;
import cn.axzo.apollo.workspace.api.v2.participating.feign.ParticipatingUnitV2Api;
import cn.axzo.apollo.workspace.api.v2.participating.req.ParticipatingUnitListReq;
import cn.axzo.apollo.workspace.api.v2.participating.resp.ParticipatingUnitResp;
import cn.axzo.apollo.workspace.api.v2.workspace.feign.WorkspaceV2Api;
import cn.axzo.apollo.workspace.api.v2.workspace.req.ListWorkspaceReq;
import cn.axzo.apollo.workspace.api.v2.workspace.req.WorkspaceDetailReq;
@ -7,24 +10,48 @@ import cn.axzo.apollo.workspace.api.v2.workspace.req.WorkspaceUpsertReq;
import cn.axzo.apollo.workspace.api.v2.workspace.resp.WorkspaceDTO;
import cn.axzo.apollo.workspace.api.v2.workspace.resp.WorkspaceDetailResp;
import cn.axzo.apollo.workspace.api.v2.workspace.resp.WorkspaceUpsertResp;
import cn.axzo.apollo.workspace.api.workspace.WorkspaceSceneConfigApi;
import cn.axzo.apollo.workspace.api.workspace.req.scene.WorkspaceSceneConfigListReq;
import cn.axzo.apollo.workspace.api.workspace.res.scene.SceneConfigRes;
import cn.axzo.apollo.workspace.common.enums.SceneConfigSwitch;
import cn.axzo.apollo.workspace.common.enums.WorkspaceSceneConfigType;
import cn.axzo.orgmanax.infra.client.RpcWrapper;
import cn.azxo.framework.common.logger.MethodAroundLog;
import cn.hutool.core.collection.CollUtil;
import com.google.common.collect.ImmutableList;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
*/
@RequiredArgsConstructor
@Component
@Slf4j
public class WorkspaceGateway {
private static final ImmutableList<WorkspaceSceneConfigType> AUTO_LEAVE_CONFIG_TYPES = ImmutableList.of(
WorkspaceSceneConfigType.WORKER_AUTO_LEAVE,
WorkspaceSceneConfigType.WORKER_AUTO_LEAVE_DAYS
);
private final WorkspaceV2Api workspaceV2Api;
private final ParticipatingUnitV2Api participatingUnitV2Api;
private final WorkspaceSceneConfigApi workspaceSceneConfigApi;
/**
* 更新和新增
*
* @param request
* @return
*/
@ -34,6 +61,7 @@ public class WorkspaceGateway {
/**
* 获取详情
*
* @param request
* @return
*/
@ -43,10 +71,66 @@ public class WorkspaceGateway {
/**
* 获取详情
*
* @param request
* @return
*/
public List<WorkspaceDTO> list(ListWorkspaceReq request) {
return RpcWrapper.wrapApiResult(() -> workspaceV2Api.listV2(request));
}
public List<ParticipatingUnitResp> listParticipatingUnits(ParticipatingUnitListReq unitListReq) {
return RpcWrapper.wrapApiResult(() -> participatingUnitV2Api.list(unitListReq));
}
/**
* 查询项目相关配置项
*
* @param request 入参
* @return 配置项列表
*/
@MethodAroundLog(source = "orgmanax", target = "workspace", value = "查询项目相关配置项")
public List<SceneConfigRes> listConfigs(WorkspaceSceneConfigListReq request) {
return RpcWrapper.commonRes(() -> workspaceSceneConfigApi.listConfigs(request));
}
/**
* 获取人员自动离场的天数配置连续多少天没有打卡记录
*
* @param workspaceIds 项目id列表
* @return 配置项的map
*/
@MethodAroundLog(source = "orgmanax", target = "workspace", value = "获取人员自动离场的天数配置")
public Map<Long, Integer> listAutoLeaveDaysConfig(Collection<Long> workspaceIds) {
if (CollUtil.isEmpty(workspaceIds)) {
return Collections.emptyMap();
}
WorkspaceSceneConfigListReq request = WorkspaceSceneConfigListReq.builder()
.workspaceIds(CollUtil.distinct(workspaceIds))
.types(AUTO_LEAVE_CONFIG_TYPES)
.build();
// list
List<SceneConfigRes> sceneConfigs = listConfigs(request);
if (CollUtil.isEmpty(sceneConfigs)) {
return Collections.emptyMap();
}
// grouping
Map<Long, List<SceneConfigRes>> groupingByWorkspaceId = sceneConfigs.stream()
.collect(Collectors.groupingBy(SceneConfigRes::getWorkspaceId));
// mapper function
Function<List<SceneConfigRes>, SceneConfigRes> mapper = list -> {
if (list.stream().anyMatch(e -> WorkspaceSceneConfigType.WORKER_AUTO_LEAVE.name().equals(e.getType())
&& Objects.equals(e.getValue(), SceneConfigSwitch.OPEN.getValue()))) {
return list.stream()
.filter(e -> WorkspaceSceneConfigType.WORKER_AUTO_LEAVE_DAYS.name().equals(e.getType()))
.findFirst().orElse(null);
}
// switch not exist or closed
return null;
};
return groupingByWorkspaceId.values().stream()
.map(mapper)
.filter(Objects::nonNull)
.collect(Collectors.toMap(SceneConfigRes::getWorkspaceId, e -> Integer.valueOf(e.getValue()), (oldVal, newVal) -> oldVal));
}
}

View File

@ -3,17 +3,21 @@ package cn.axzo.orgmanax.infra.config;
import cn.axzo.foundation.dao.support.mysql.plugins.LimitInterceptor;
import cn.axzo.foundation.enums.AppEnvEnum;
import cn.axzo.foundation.web.support.AppRuntime;
import cn.axzo.foundation.web.support.conditional.LocalCondition;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.reflection.MetaObject;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.util.Date;
@Slf4j
@EnableTransactionManagement
@MapperScan("cn.axzo.orgmanax.**.mapper")
@ -50,4 +54,29 @@ public class MybatisPlusConfig {
}
};
}
@Bean
@Primary
public EntityMetaObjectHandler entityMetaObjectHandler() {
return new EntityMetaObjectHandler();
}
public static class EntityMetaObjectHandler implements MetaObjectHandler {
public EntityMetaObjectHandler() {
}
@Override
public void insertFill(MetaObject metaObject) {
this.fillStrategy(metaObject, "createAt", new Date());
this.fillStrategy(metaObject, "updateAt", new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateAt", new Date(), metaObject);
}
}
}

View File

@ -0,0 +1,66 @@
package cn.axzo.orgmanax.infra.config;
import cn.azxo.framework.common.annotation.OnlyPodsEnvironment;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@OnlyPodsEnvironment
@Configuration(value = "xxlJobConfig1")
public class XxlJobConfig {
Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
/**
* //@Value("http://dev-xxl-job.axzo.cn/xxl-job-admin")
*/
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.executor.appname}")
private String appName;
@Value("")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
/**
* // @Value("${xxl.job.accessToken}")
*/
@Value("")
private String accessToken;
@Value("")
private String logPath;
@Value("-1")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appName);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}

View File

@ -0,0 +1,12 @@
package cn.axzo.orgmanax.infra.config.type;
import cn.axzo.foundation.dao.support.mysql.type.BaseListTypeHandler;
/**
* @author luofu
* @version 1.0
* @description 实体 Long列表的字段类型处理器
* @date 2025/3/10
*/
public class LongListTypeHandler extends BaseListTypeHandler<Long> {
}

View File

@ -0,0 +1,12 @@
package cn.axzo.orgmanax.infra.config.type;
import cn.axzo.foundation.dao.support.mysql.type.BaseSetTypeHandler;
/**
* @author luofu
* @version 1.0
* @description 实体 String哈希类型字段处理器
* @date 2025/3/10
*/
public class StringSetTypeHandler extends BaseSetTypeHandler<String> {
}

View File

@ -1,8 +1,221 @@
package cn.axzo.orgmanax.infra.dao.invite.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.invite.entity.ProjectWorkerInvite;
import cn.axzo.trade.datasecurity.core.annotation.CryptField;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
* @author zhanghongbo
* @date 2025/1/8
*/
public interface ProjectWorkerInviteRepository {
PageResp<ProjectWorkerInviteResp> page(ListReq req);
/**
* 列表查询
*
* @param req
* @return
*/
default List<ProjectWorkerInviteResp> list(ListReq req) {
PageResp<ProjectWorkerInviteResp> page = page(req);
if (page == null) {
return Collections.emptyList();
}
return CollUtil.emptyIfNull(page.getData());
}
void updateBatchById(List<ProjectWorkerInvite> req);
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class ListReq extends PageReqV2 {
@CriteriaField(field = "id", operator = Operator.EQ)
private Long id;
@CriteriaField(field = "id", operator = Operator.IN)
private List<Long> ids;
/**
* 工作台ID
*/
@CriteriaField(field = "workspaceId", operator = Operator.EQ)
private Long workspaceId;
/**
* 项目内班组ID
*/
@CriteriaField(field = "projectTeamId", operator = Operator.EQ)
private Long projectTeamId;
@CriteriaField(field = "projectTeamId", operator = Operator.IN)
private List<Long> projectTeamIds;
/**
* 工人ID
*/
@CriteriaField(field = "workerIdentityId", operator = Operator.EQ)
private Long workerIdentityId;
@CriteriaField(field = "workerIdentityId", operator = Operator.IN)
private List<Long> workerIdentityIds;
/**
* 状态1待班组审批  2待劳务审批  3通过 4拒绝
*/
@CriteriaField(field = "status", operator = Operator.EQ)
private Integer status;
@CriteriaField(field = "status", operator = Operator.IN)
private List<Integer> statusList;
/**
* 工作流流程实例id
*/
@CriteriaField(field = "processInstanceId", operator = Operator.EQ)
private String processInstanceId;
@CriteriaField(field = "processInstanceId", operator = Operator.IN)
private List<String> processInstanceIds;
/**
* 查询返回数据包含逻辑删除数据即查询未删除和已删除的数据
*/
@CriteriaField(ignore = true)
private Boolean includeDeleted;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class ProjectWorkerInviteResp {
private Long id;
/**
* 工作台ID
*/
private Long workspaceId;
/**
* 总包ID
*/
private Long entId;
/**
* 项目内班组ID
*/
private Long projectTeamId;
/**
* 项目内工人id
*/
private Long projectWorkerId;
/**
* 所属单位ID
*/
private Long organizationalUnitId;
/**
* 所属单位类型: 1:总包 4:专业分包 5:劳务分包
*/
private Integer organizationalUnitType;
/**
* 工人ID
*/
private Long workerIdentityId;
/**
* 状态1待班组审批  2待劳务审批  3通过 4拒绝
*/
private Integer status;
/**
* 类型1班组长邀请 2二维码邀请 3:派单
*/
private Integer source;
/**
* 邀请人id
*/
private Long inviterId;
/**
* 邀请人名称
*/
private String inviterName;
/**
* 是否删除 0:未删除 其他:已删除
*/
private Long isDelete;
private Date createAt;
private Date updateAt;
/**
* 工种类别 技工 普工
*/
private String professionCategoryName;
/**
* 审批人的从业人员身份id
*/
private Long approverIdentityId;
/**
* 班组长审批时间,REQ-598
*/
private Date teamLeaderAuditDate;
/**
* source = 4合作小组派单记录甲方的班组id
*/
private Long belongProjectTeamId;
/**
* 工人名称
*/
private String workerName;
/**
* 工人电话号码
*/
@CryptField
private String workerPhone;
/**
* 工作流流程实例id
*/
private String processInstanceId;
/**
* 邀请的工种
*/
private JSONObject professionExt;
/**
* 扩展字段
*/
private JSONObject extra;
}
}

View File

@ -1,10 +1,21 @@
package cn.axzo.orgmanax.infra.dao.invite.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.invite.dao.ProjectWorkerInviteDao;
import cn.axzo.orgmanax.infra.dao.invite.entity.ProjectWorkerInvite;
import cn.axzo.orgmanax.infra.dao.invite.repository.ProjectWorkerInviteRepository;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author zhanghongbo
* @date 2025/1/8
@ -13,4 +24,25 @@ import org.springframework.stereotype.Repository;
@Slf4j
@AllArgsConstructor
public class ProjectWorkerInviteRepositoryImpl implements ProjectWorkerInviteRepository {
private final ProjectWorkerInviteDao projectWorkerInviteDao;
@Override
public PageResp<ProjectWorkerInviteResp> page(ListReq req) {
IPage<ProjectWorkerInvite> page = PageConverter.toMybatis(req, ProjectWorkerInvite.class);
QueryWrapper<ProjectWorkerInvite> wrapper = QueryWrapperHelper.fromBean(req, ProjectWorkerInvite.class);
if (BooleanUtils.isNotTrue(req.getIncludeDeleted())) {
wrapper.eq("is_delete", 0);
}
IPage<ProjectWorkerInviteResp> results = projectWorkerInviteDao.page(page, wrapper)
.convert(e -> BeanUtil.toBean(e, ProjectWorkerInviteResp.class));
PageResp<ProjectWorkerInviteResp> resp = PageConverter.toResp(results);
return resp;
}
@Override
public void updateBatchById(List<ProjectWorkerInvite> invites){
projectWorkerInviteDao.updateBatchById(invites);
}
}

View File

@ -0,0 +1,10 @@
package cn.axzo.orgmanax.infra.dao.node.dao;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalTeamOuRelation;
import cn.axzo.orgmanax.infra.dao.node.mapper.OrganizationalTeamOuRelationMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Component;
@Component
public class TeamOuRelationDao extends ServiceImpl<OrganizationalTeamOuRelationMapper, OrganizationalTeamOuRelation> {
}

View File

@ -137,6 +137,17 @@ public class OrganizationalNode implements Serializable {
@TableField(value = "profile", typeHandler = FastjsonTypeHandler.class)
private JSONObject profile;
/**
* 平台班组id
*/
@TableField("__vc_plat_team_id")
private Long platTeamId;
/**
* 项目班组id
*/
@TableField("__vc_project_team_id")
private Long projectTeamId;
protected Date createAt;
protected Long createBy;
protected Date updateAt;

View File

@ -0,0 +1,64 @@
package cn.axzo.orgmanax.infra.dao.node.entity;
import com.alibaba.fastjson.JSONObject;
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 com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import java.util.Date;
@TableName(value = "organizational_team_ou_relation")
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public class OrganizationalTeamOuRelation {
@TableId(
type = IdType.AUTO
)
protected Long id;
/**
* 平台班组ID
*/
@TableField("team_ou_id")
private Long teamOuId;
/**
* 平台班组默认节点ID
*/
@TableField("team_node_id")
private Long teamNodeId;
/**
* 企业/团队单位ID
*/
@TableField("ou_id")
private Long ouId;
/**
* 企业/团队单位下班组节点ID
*/
@TableField("node_id")
private Long nodeId;
/**
* 扩展字段
*/
@TableField(value = "extra", typeHandler = FastjsonTypeHandler.class)
private JSONObject extra;
protected Date createAt;
protected Date updateAt;
@TableField("is_delete")
protected Long isDelete = 0L;
}

View File

@ -0,0 +1,9 @@
package cn.axzo.orgmanax.infra.dao.node.mapper;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalTeamOuRelation;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface OrganizationalTeamOuRelationMapper extends BaseMapper<OrganizationalTeamOuRelation> {
}

View File

@ -0,0 +1,64 @@
package cn.axzo.orgmanax.infra.dao.node.repository;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalTeamOuRelation;
import cn.hutool.core.bean.BeanUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
import java.util.Optional;
public interface TeamOuRelationRepository {
/**
* 保存
* @param teamOuRelation
*/
void save(OrganizationalTeamOuRelation teamOuRelation);
/**
* 根据nodeId获取
* @param id
* @return
*/
OrganizationalTeamOuRelation getByNodeId(Long id);
List<OrganizationalTeamOuRelation> list(ListReq req);
default OrganizationalTeamOuRelation one(OneReq req) {
return oneOpt(req).orElse(null);
}
default Optional<OrganizationalTeamOuRelation> oneOpt(OneReq req) {
ListReq page = BeanUtil.toBean(req, ListReq.class);
return list(page).stream().findFirst();
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class ListReq {
@CriteriaField
private Long nodeId;
@CriteriaField
private Long teamNodeId;
@CriteriaField
private Long teamOuId;
@CriteriaField
private Long ouId;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class OneReq {
private Long nodeId;
private Long teamNodeId;
private Long teamOuId;
}
}

View File

@ -0,0 +1,36 @@
package cn.axzo.orgmanax.infra.dao.node.repository.impl;
import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper;
import cn.axzo.orgmanax.infra.dao.node.dao.TeamOuRelationDao;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalTeamOuRelation;
import cn.axzo.orgmanax.infra.dao.node.repository.TeamOuRelationRepository;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
@RequiredArgsConstructor
@Component
public class TeamOuRelationRepositoryImpl implements TeamOuRelationRepository {
private final TeamOuRelationDao teamOuRelationDao;
@Override
public void save(OrganizationalTeamOuRelation teamOuRelation) {
teamOuRelationDao.save(teamOuRelation);
}
@Override
public OrganizationalTeamOuRelation getByNodeId(Long id) {
return teamOuRelationDao.lambdaQuery()
.eq(OrganizationalTeamOuRelation::getId, id)
.one();
}
@Override
public List<OrganizationalTeamOuRelation> list(ListReq req) {
QueryWrapper<OrganizationalTeamOuRelation> wrapper = QueryWrapperHelper.fromBean(req, OrganizationalTeamOuRelation.class);
return teamOuRelationDao.list(wrapper);
}
}

View File

@ -0,0 +1,14 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.dao;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUserExtra;
import cn.axzo.orgmanax.infra.dao.nodeuser.mapper.OrganizationalNodeUserExtraMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository;
/**
* @author luofu
* @date 2025/3/10
*/
@Repository("organizationalNodeUserExtraDao")
public class NodeUserExtraDao extends ServiceImpl<OrganizationalNodeUserExtraMapper, OrganizationalNodeUserExtra> {
}

View File

@ -0,0 +1,230 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.entity;
import cn.axzo.foundation.dao.support.mysql.type.BaseListTypeHandler;
import cn.axzo.orgmanax.dto.nodeuser.enums.OrganizationalNodeUserStatusEnum;
import cn.axzo.orgmanax.infra.config.type.LongListTypeHandler;
import cn.axzo.orgmanax.infra.config.type.StringSetTypeHandler;
import cn.axzo.trade.datasecurity.core.annotation.CryptField;
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 com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import org.apache.commons.collections4.CollectionUtils;
import java.io.Serializable;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* 组织人员扩展表
*
* @author luofu
* @since 2025/3/7
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@TableName(value = "organizational_node_user_extra", autoResultMap = true)
public class OrganizationalNodeUserExtra implements Serializable {
private static final long serialVersionUID = -2582195210622831819L;
/**
* 主键
*/
@TableId(
type = IdType.AUTO
)
private Long id;
/**
* 自然人id
*/
@TableField("person_id")
private Long personId;
/**
* 主电话
*/
@CryptField
@TableField("phone")
private String phone;
/**
* 名字
*/
@TableField("real_name")
private String realName;
/**
* 身份证号
*/
@CryptField
@TableField("id_number")
private String idNumber;
/**
* 单位id
*/
@TableField("organizational_unit_id")
private Long organizationalUnitId;
/**
* 当前所在组织节点id
*/
@TableField(value = "top_node_ids", typeHandler = LongListTypeHandler.class)
private List<Long> topNodeIds;
/**
* 直属主管ID
*/
@TableField("direct_manager_person_id")
private Long directManagerPersonId;
/**
* 部门ID
*/
@TableField(value = "node_ids", typeHandler = LongListTypeHandler.class)
private List<Long> nodeIds;
/**
* 岗位IDs
*/
@TableField(value = "job_ids", typeHandler = LongListTypeHandler.class)
private List<Long> jobIds;
/**
* 标签
*/
@TableField(value = "tags", typeHandler = StringSetTypeHandler.class)
private Set<String> tags;
/**
* 部门信息
*/
@TableField(value = "node_info", typeHandler = ListOrganizationNodeUserExtraNodeInfoHandler.class)
private List<OrganizationNodeUserExtraNodeInfo> nodeInfo;
/**
* 加入时间
*/
@TableField("join_at")
private Date joinAt;
/**
* 离开时间
*/
@TableField("leave_at")
private Date leaveAt;
/**
* workspace id
*/
@TableField("workspace_id")
private Long workspaceId;
/**
* workspace_type
*/
@TableField("workspace_type")
private Integer workspaceType;
/**
* 状态
*
* @see OrganizationalNodeUserStatusEnum
*/
@TableField(value = "status")
private OrganizationalNodeUserStatusEnum status;
/**
* 扩展字段
**/
@TableField(value = "extra", typeHandler = FastjsonTypeHandler.class)
private UserExtra extra;
/**
* 创建时间
*/
private Date createAt;
/**
* 更新时间
*/
private Date updateAt;
/**
* 状态 0正常 其它删除
*/
private Long isDelete = 0L;
public List<Long> determineJobIds() {
if (CollectionUtils.isEmpty(jobIds))
return Collections.emptyList();
return jobIds;
}
public List<Long> determineNodeIds() {
if (CollectionUtils.isEmpty(nodeIds))
return Collections.emptyList();
return nodeIds;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class UserExtra implements Serializable {
private String desc;
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class OrganizationNodeUserExtraNodeInfo implements Serializable {
/**
* nodeId
*/
private Long nodeId;
/**
* organization node user id
*/
private Long nodeUserId;
/**
* 是否是部门管理员
*/
private Boolean manager;
/**
* 是否是主岗位
* 0:普通岗位1:主岗位
*/
private Integer primaryJob;
/**
* job id
*/
private Long jobId;
}
public static class ListOrganizationNodeUserExtraNodeInfoHandler extends BaseListTypeHandler<OrganizationNodeUserExtraNodeInfo> {
}
}

View File

@ -0,0 +1,15 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.mapper;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUserExtra;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 组织人员扩展表数据库访问层
*
* @author luofu
* @since 2025/3/10
*/
@Mapper
public interface OrganizationalNodeUserExtraMapper extends BaseMapper<OrganizationalNodeUserExtra> {
}

View File

@ -0,0 +1,187 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository;
import cn.axzo.foundation.dao.support.mysql.MybatisPlusOperatorProcessor;
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.nodeuser.entity.OrganizationalNodeUserExtra;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.google.common.base.Preconditions;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface NodeUserExtraQueryRepository {
PageResp<NodeUserExtraResp> page(ListReq req);
default List<NodeUserExtraResp> list(ListReq req) {
req.setSearchCount(false);
return page(req).getData();
}
default NodeUserExtraResp one(OneReq req) {
return oneOpt(req).orElse(null);
}
default Optional<NodeUserExtraResp> oneOpt(OneReq req) {
req.check();
ListReq page = BeanUtil.toBean(req, ListReq.class);
page.setPage(1);
page.setPageSize(1);
page.setSearchCount(false);
return page(page).getData().stream().findFirst();
}
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class ListReq extends PageReqV2 {
@CriteriaField
private Long id;
@CriteriaField(field = "id", operator = Operator.LT)
private Long idLt;
@CriteriaField(field = "id", operator = Operator.IN)
private Collection<Long> ids;
/**
* 自然人id
*/
@CriteriaField
private Long personId;
@CriteriaField(field = "personId", operator = Operator.IN)
private Collection<Long> personIds;
@CriteriaField(field = "personId", operator = Operator.NOT_IN)
private Collection<Long> excludePersonIds;
/**
* 主电话
*/
@CriteriaField
private String phone;
@CriteriaField(field = "phone", operator = Operator.NOT_IN)
private Collection<String> phones;
/**
* 名字
*/
@CriteriaField
private String realName;
@CriteriaField(field = "realName", operator = Operator.LIKE)
private String realNameLike;
/**
* 身份证号
*/
@CriteriaField
private String idNumber;
@CriteriaField(field = "idNumber", operator = Operator.IN)
private Collection<String> idNumbers;
/**
* 单位id
*/
@CriteriaField
private Long organizationalUnitId;
@CriteriaField(field = "organizationalUnitId", operator = Operator.IN)
private Collection<Long> organizationalUnitIds;
/**
* 工作台ID
*/
@CriteriaField
private Long workspaceId;
@CriteriaField(field = "workspaceId", operator = Operator.IN)
private Collection<Long> workspaceIds;
/**
* 更新时间大于等于
*/
@CriteriaField(field = "updateAt", operator = Operator.GE)
private Date updateAtGe;
/**
* 更新时间小于等于
*/
@CriteriaField(field = "updateAt", operator = Operator.LE)
private Date updateAtLe;
/**
* 查询返回数据包含逻辑删除数据即查询未删除和已删除的数据
*/
@CriteriaField(ignore = true)
private Boolean includeDeleted;
/**
* 仅查询已删除的数据
*/
@CriteriaField(ignore = true)
private Boolean deletedOnly;
/**
* keyword idNumberphonejobNumber精确匹配或者realName模糊匹配
*/
@CriteriaField(ignore = true)
private String keyword;
@CriteriaField(field = "extra", operator = Operator.JSON_QUERY)
private Collection<MybatisPlusOperatorProcessor.JSONQuery> extraQueries;
@CriteriaField(ignore = true)
private List<SFunction<OrganizationalNodeUserExtra, ?>> selects;
@CriteriaField(ignore = true)
private String tag;
/**
* 增加ext搜索条件
*
* @param jsonQuery
*/
public void addExtraQueries(MybatisPlusOperatorProcessor.JSONQuery jsonQuery) {
if (this.extraQueries == null) {
this.extraQueries = new ArrayList<>();
}
this.extraQueries.add(jsonQuery);
}
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class OneReq {
private Long id;
private Set<Long> ids;
public void check() {
Preconditions.checkArgument(id != null || CollUtil.isNotEmpty(ids), "参数异常");
}
}
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class NodeUserExtraResp extends OrganizationalNodeUserExtra {
private static final long serialVersionUID = -2380536050710759553L;
private String xx;
}
}

View File

@ -0,0 +1,45 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUserExtra;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public interface NodeUserExtraUpsertRepository {
OrganizationalNodeUserExtra create(OrganizationalNodeUserExtra nodeUserExtra);
OrganizationalNodeUserExtra update(UpdateReq node);
/**
* 批量设置用户标签
*
* @param idTagsMap key:id, value:标签集合
*/
void updateTagsMap(Map<Long, Set<String>> idTagsMap);
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class UpdateReq extends OrganizationalNodeUserExtra {
/**
* 由于updateById不支持将值设置为null这里提供这个
*/
Set<SFunction<OrganizationalNodeUserExtra, ?>> setNullFields = new HashSet<>();
public void check() {
Axssert.checkNonNull(getId(), "要更新的部门id不能为空");
}
}
}

View File

@ -18,7 +18,12 @@ import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface NodeUserQueryRepository {
@ -52,6 +57,8 @@ public interface NodeUserQueryRepository {
private Long id;
@CriteriaField(field = "id", operator = Operator.GT)
private Long idGt;
@CriteriaField(field = "id", operator = Operator.LT)
private Long idLt;
@CriteriaField(field = "id", operator = Operator.IN)
private Collection<Long> ids;
@ -156,6 +163,8 @@ public interface NodeUserQueryRepository {
*/
@CriteriaField
private Long workspaceId;
@CriteriaField(field = "workspaceId", operator = Operator.GT)
private Long workspaceIdGt;
@CriteriaField(field = "workspaceId", operator = Operator.IN)
private Collection<Long> workspaceIds;

View File

@ -10,6 +10,7 @@ import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public interface NodeUserUpsertRepository {
@ -18,6 +19,10 @@ public interface NodeUserUpsertRepository {
OrganizationalNodeUser update(UpdateReq node);
List<OrganizationalNodeUser> updateBatchById(List<UpdateReq> req) ;
void batchDelete(Set<Long> ids);
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor

View File

@ -0,0 +1,84 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.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.nodeuser.dao.NodeUserExtraDao;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUserExtra;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository;
import cn.axzo.trade.datasecurity.core.util.DataSecurityHelper;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.google.common.collect.ImmutableList;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author luofu
* @version 1.0
* @date 2025/3/10
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class NodeUserExtraQueryRepositoryImpl implements NodeUserExtraQueryRepository {
private final NodeUserExtraDao nodeUserExtraDao;
@Override
public PageResp<NodeUserExtraResp> page(ListReq req) {
IPage<OrganizationalNodeUserExtra> page = PageConverter.toMybatis(req, OrganizationalNodeUserExtra.class);
PageResp<NodeUserExtraQueryRepository.NodeUserExtraResp> emptyPage = PageResp.<NodeUserExtraQueryRepository.NodeUserExtraResp>builder()
.size(req.getPageSize())
.current(req.getPage()).total(0L)
.data(ImmutableList.of())
.build();
LambdaQueryWrapper<OrganizationalNodeUserExtra> wrapper = QueryWrapperHelper.fromBean(req, OrganizationalNodeUserExtra.class).lambda();
// 查询参数处理 ~
// keyword
if (StrUtil.isNotBlank(req.getKeyword())) {
String encryptedKeyword = DataSecurityHelper.encrypt(req.getKeyword());
wrapper.and(w -> w.like(OrganizationalNodeUserExtra::getRealName, req.getKeyword())
.or().eq(OrganizationalNodeUserExtra::getPhone, encryptedKeyword)
.or().eq(OrganizationalNodeUserExtra::getIdNumber, encryptedKeyword));
}
// tag query
if (StringUtils.isNotBlank(req.getTag())) {
wrapper.and(w -> w.apply("JSON_CONTAINS(tags, {0})", "\"" + req.getTag() + "\""));
}
// 处理删除标记
if (BooleanUtil.isTrue(req.getDeletedOnly())) {
wrapper.ne(OrganizationalNodeUserExtra::getIsDelete, 0);
}
if (!BooleanUtil.isTrue(req.getIncludeDeleted())) {
wrapper.eq(OrganizationalNodeUserExtra::getIsDelete, 0);
}
// selects
if (ArrayUtil.isNotEmpty(req.getSelects())) {
wrapper.select(req.getSelects().toArray(new SFunction[0]));
}
IPage<NodeUserExtraQueryRepository.NodeUserExtraResp> results = nodeUserExtraDao.page(page, wrapper)
.convert(e -> BeanUtil.toBean(e, NodeUserExtraQueryRepository.NodeUserExtraResp.class));
if (CollUtil.isEmpty(results.getRecords())) {
return emptyPage;
}
PageResp<NodeUserExtraQueryRepository.NodeUserExtraResp> resp = PageConverter.toResp(results);
List<NodeUserExtraQueryRepository.NodeUserExtraResp> records = resp.getData();
if (CollUtil.isEmpty(records)) {
return resp;
}
return resp;
}
}

View File

@ -0,0 +1,61 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository.impl;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.orgmanax.infra.dao.nodeuser.dao.NodeUserExtraDao;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUserExtra;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraUpsertRepository;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author luofu
* @version 1.0
* @date 2025/3/10
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class NodeUserExtraUpsertRepositoryImpl implements NodeUserExtraUpsertRepository {
private final NodeUserExtraDao nodeUserExtraDao;
@Override
public OrganizationalNodeUserExtra create(OrganizationalNodeUserExtra nodeUserExtra) {
nodeUserExtraDao.save(nodeUserExtra);
return nodeUserExtraDao.getById(nodeUserExtra.getId());
}
@Override
public OrganizationalNodeUserExtra update(UpdateReq req) {
Axssert.checkNonNull(req.getId(), "更新项目人员,项目人员不能为空");
LambdaUpdateChainWrapper<OrganizationalNodeUserExtra> wrapper = nodeUserExtraDao.lambdaUpdate()
.eq(OrganizationalNodeUserExtra::getId, req.getId());
if (CollUtil.isNotEmpty(req.getSetNullFields())) {
req.getSetNullFields().forEach(e -> wrapper.set(e, null));
}
wrapper.update(req);
return nodeUserExtraDao.getById(req.getId());
}
@Override
public void updateTagsMap(Map<Long, Set<String>> idTagsMap) {
if (CollUtil.isEmpty(idTagsMap)) {
return;
}
List<OrganizationalNodeUserExtra> updateEntities = idTagsMap.entrySet().stream()
.map(e -> OrganizationalNodeUserExtra.builder()
.id(e.getKey())
.tags(e.getValue())
.build())
.collect(Collectors.toList());
nodeUserExtraDao.updateBatchById(updateEntities);
}
}

View File

@ -1,15 +1,25 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository.impl;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.foundation.result.ResultCode;
import cn.axzo.orgmanax.infra.dao.nodeuser.dao.NodeUserDao;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserUpsertRepository;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@Slf4j
@ -32,4 +42,24 @@ public class NodeUserUpsertRepositoryImpl implements NodeUserUpsertRepository {
wrapper.update(req);
return nodeUserDao.getById(req.getId());
}
}
@Override
public List<OrganizationalNodeUser> updateBatchById(List<UpdateReq> req) {
Optional<UpdateReq> first = req.stream().filter(item -> Objects.isNull(item.getId())).findFirst();
Axssert.check(!first.isPresent(), ResultCode.INVALID_PARAMS, "更新部门人员,部门人员不能为空");
List<OrganizationalNodeUser> updateNodeUsers = BeanUtil.copyToList(req, OrganizationalNodeUser.class);
List<Long> ids = req.stream().map(OrganizationalNodeUser::getId).collect(Collectors.toList());
nodeUserDao.updateBatchById(updateNodeUsers);
return nodeUserDao.listByIds(ids);
}
@Override
public void batchDelete(Set<Long> ids) {
Date date = new Date();
nodeUserDao.lambdaUpdate().in(OrganizationalNodeUser::getId, ids)
.eq(OrganizationalNodeUser::getIsDelete, 0)
.setSql("is_delete = id, leave_at = CASE WHEN leave_at IS NULL THEN '" + DateUtil.formatDateTime(date) + "' ELSE leave_at END")
.update();
}
}

View File

@ -7,5 +7,4 @@ import org.springframework.stereotype.Repository;
@Repository
public class OrgUserDao extends ServiceImpl<OrgUserMapper, OrgUser> {
}

View File

@ -1,7 +1,9 @@
package cn.axzo.orgmanax.infra.dao.orguser.entity;
import cn.axzo.orgmanax.infra.config.type.StringSetTypeHandler;
import cn.axzo.trade.datasecurity.core.annotation.CryptField;
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.AllArgsConstructor;
@ -14,6 +16,7 @@ import lombok.experimental.SuperBuilder;
import java.io.Serializable;
import java.util.Date;
import java.util.Set;
/**
* 人员组织(OrgUser)表实体类
@ -31,6 +34,8 @@ import java.util.Date;
@EqualsAndHashCode(callSuper = false)
public class OrgUser implements Serializable {
private static final long serialVersionUID = -6974404117487874584L;
/**
* 主键
*/
@ -116,6 +121,10 @@ public class OrgUser implements Serializable {
*/
private Long isDelete = 0L;
/**
* 标签
*/
@TableField(value = "tags", typeHandler = StringSetTypeHandler.class)
private Set<String> tags;
}

View File

@ -1,4 +1,21 @@
package cn.axzo.orgmanax.infra.dao.orguser.repository;
import cn.axzo.orgmanax.infra.dao.orguser.entity.OrgUser;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface OrgUserUpsertRepository {
}
@Transactional(rollbackFor = Throwable.class)
void batchUpdate(List<OrgUser> orgUsers);
/**
* 批量设置用户标签
*
* @param idTagsMap key:id, value:标签集合
*/
void updateTagsMap(Map<Long, Set<String>> idTagsMap);
}

View File

@ -16,12 +16,11 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
@ -55,6 +54,10 @@ public class OrgUserQueryRepositoryImpl implements OrgUserQueryRepository {
.or().eq(OrgUser::getPhone, encryptStr)
.or().eq(OrgUser::getIdNumber, encryptStr));
}
// tag query
if (StringUtils.isNotBlank(req.getTag())) {
wrapper.and(w -> w.apply("JSON_CONTAINS(tags, {0})", "\"" + req.getTag() + "\""));
}
IPage<OrgUserResp> results = orgUserDao.page(page, wrapper)
.convert(e -> BeanUtil.toBean(e, OrgUserResp.class));

View File

@ -1,10 +1,40 @@
package cn.axzo.orgmanax.infra.dao.orguser.repository.impl;
import cn.axzo.orgmanax.infra.dao.orguser.dao.OrgUserDao;
import cn.axzo.orgmanax.infra.dao.orguser.entity.OrgUser;
import cn.axzo.orgmanax.infra.dao.orguser.repository.OrgUserUpsertRepository;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class OrgUserUpsertRepositoryImpl implements OrgUserUpsertRepository {
}
private final OrgUserDao orgUserDao;
@Override
public void batchUpdate(List<OrgUser> orgUsers) {
orgUserDao.updateBatchById(orgUsers);
}
@Override
public void updateTagsMap(Map<Long, Set<String>> idTagsMap) {
if (CollUtil.isEmpty(idTagsMap)) {
return;
}
List<OrgUser> updateEntities = idTagsMap.entrySet().stream()
.map(e -> OrgUser.builder()
.id(e.getKey())
.tags(e.getValue())
.build())
.collect(Collectors.toList());
batchUpdate(updateEntities);
}
}

View File

@ -0,0 +1,16 @@
package cn.axzo.orgmanax.infra.dao.project.worker.dao;
import cn.axzo.orgmanax.infra.dao.project.worker.entity.OrgProjectWorker;
import cn.axzo.orgmanax.infra.dao.project.worker.mapper.OrgProjectWorkerMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/1/8
*/
@Repository
public class OrgProjectWorkerDao extends ServiceImpl<OrgProjectWorkerMapper, OrgProjectWorker> {
}

View File

@ -0,0 +1,151 @@
package cn.axzo.orgmanax.infra.dao.project.worker.entity;
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.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.io.Serializable;
import java.util.Date;
/**
* 项目内工人表实体类
*
* @author chenliang@axzo.cn
* @since 2022-07-20 15:01:43
*/
@TableName(value = "org_project_worker", autoResultMap = true)
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class OrgProjectWorker implements Serializable {
private static final long serialVersionUID = 260206461965825922L;
@TableId(
type = IdType.AUTO
)
private Long id;
/**
* 工作台ID
*/
@TableField("workspace_id")
private Long workspaceId;
/**
* 总包ID
*/
@TableField("ent_id")
private Long entId;
/**
* 所属单位id
*/
@TableField("organizational_unit_id")
private Long organizationalUnitId;
/**
* 所属单位类型: 1:总包 4:专业分包 5:劳务分包
*/
@TableField("organizational_unit_type")
private Integer organizationalUnitType;
/**
* 项目内班组ID
*/
@TableField("project_team_id")
private Long projectTeamId;
/**
* 工人personId
*/
@TableField("worker_person_id")
private Long workerPersonId;
/**
* 工人身份ID
*/
@TableField("worker_identity_id")
private Long workerIdentityId;
/**
* 状态0未激活 1已激活 3已退场
*/
@TableField("status")
private Integer status;
/**
* 工种类别
*/
@TableField("profession_category_name")
private String professionCategoryName;
/**
* 入场时间
*/
@TableField("join_at")
private Date joinAt;
/**
* 离场时间
*/
@TableField("resign_at")
private Date resignAt;
/**
* 是否删除 0:未删除 其他:已删除
*/
@TableField("is_delete")
private Long isDelete;
/**
* 创建时间
*/
@TableField("create_at")
private Date createAt;
@TableField("update_at")
private Date updateAt;
/**
* 最后一次进工地的时间进场打卡更新
* 进场打卡更新
*/
@TableField("last_check_in_time")
private Date lastCheckInTime;
/**
* 最后一次出工地的时间出场打卡更新
*/
@TableField("last_check_out_time")
private Date lastCheckOutTime;
/**
* 工人施工开始时间工人所有任务单中最早开始时间
*/
private Date constructionStartTime;
/**
* 工人施工结束时间
*/
private Date constructionEndTime;
/**
* 在岗待岗
*/
private Integer occupyStatus;
/**
* 推送未备案消息次数
*/
@TableField("push_supervision_msg_count")
private Integer pushSupervisionMsgCount;
}

View File

@ -0,0 +1,10 @@
package cn.axzo.orgmanax.infra.dao.project.worker.mapper;
import cn.axzo.orgmanax.infra.dao.project.worker.entity.OrgProjectWorker;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface OrgProjectWorkerMapper extends BaseMapper<OrgProjectWorker> {
}

View File

@ -0,0 +1,102 @@
package cn.axzo.orgmanax.infra.dao.project.worker.repositrory;
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.project.worker.entity.OrgProjectWorker;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.google.common.base.Preconditions;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public interface OrgProjectWorkerQueryRepository {
PageResp<OrgProjectWorkerResp> page(ListReq req);
default List<OrgProjectWorkerResp> list(ListReq req) {
return page(req).getData();
}
default OrgProjectWorkerResp one(OneReq req) {
return oneOpt(req).orElse(null);
}
default Optional<OrgProjectWorkerResp> oneOpt(OneReq req) {
req.check();
ListReq page = BeanUtil.toBean(req, ListReq.class);
page.setPage(1);
page.setPageSize(1);
return page(page).getData().stream().findFirst();
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class OneReq {
private Long id;
private Set<Long> ids;
public void check() {
Preconditions.checkArgument(id != null || CollUtil.isNotEmpty(ids), "参数异常");
}
}
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class ListReq extends PageReqV2 {
@CriteriaField(field = "id", operator = Operator.IN)
private List<Long> ids;
/**
* 工作台ID
*/
@CriteriaField
private Long workspaceId;
/**
* 所属单位id
*/
@CriteriaField
private Long organizationalUnitId;
/**
* 状态
*/
@CriteriaField
private Integer status;
/**
* 工人personId
*/
@CriteriaField(field = "workerPersonId", operator = Operator.IN)
private List<Long> workerPersonIds;
@CriteriaField(ignore = true)
private Boolean includeDeleted;
}
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class OrgProjectWorkerResp extends OrgProjectWorker {
// 按需扩展字段占个位避免报错
private String todo;
}
}

View File

@ -0,0 +1,13 @@
package cn.axzo.orgmanax.infra.dao.project.worker.repositrory;
import cn.axzo.orgmanax.infra.dao.project.worker.entity.OrgProjectWorker;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
public interface OrgProjectWorkerUpsertRepository {
@Transactional(rollbackFor = Throwable.class)
void batchUpdate(List<OrgProjectWorker> orgProjectWorkers);
}

View File

@ -0,0 +1,40 @@
package cn.axzo.orgmanax.infra.dao.project.worker.repositrory.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.project.worker.dao.OrgProjectWorkerDao;
import cn.axzo.orgmanax.infra.dao.project.worker.entity.OrgProjectWorker;
import cn.axzo.orgmanax.infra.dao.project.worker.repositrory.OrgProjectWorkerQueryRepository;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.BooleanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/6
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class OrgProjectWorkerQueryRepositoryImpl implements OrgProjectWorkerQueryRepository {
private final OrgProjectWorkerDao orgProjectWorkerDao;
@Override
public PageResp<OrgProjectWorkerResp> page(ListReq req) {
IPage<OrgProjectWorker> page = PageConverter.toMybatis(req, OrgProjectWorker.class);
QueryWrapper<OrgProjectWorker> wrapper = QueryWrapperHelper.fromBean(req, OrgProjectWorker.class);
if (!BooleanUtil.isTrue(req.getIncludeDeleted())) {
wrapper.eq("is_delete", 0);
}
IPage<OrgProjectWorkerQueryRepository.OrgProjectWorkerResp> results = orgProjectWorkerDao.page(page, wrapper)
.convert(e -> BeanUtil.toBean(e, OrgProjectWorkerQueryRepository.OrgProjectWorkerResp.class));
return (PageResp<OrgProjectWorkerQueryRepository.OrgProjectWorkerResp>) PageConverter.toResp(results);
}
}

View File

@ -0,0 +1,28 @@
package cn.axzo.orgmanax.infra.dao.project.worker.repositrory.impl;
import cn.axzo.orgmanax.infra.dao.project.worker.dao.OrgProjectWorkerDao;
import cn.axzo.orgmanax.infra.dao.project.worker.entity.OrgProjectWorker;
import cn.axzo.orgmanax.infra.dao.project.worker.repositrory.OrgProjectWorkerUpsertRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/6
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class OrgProjectWorkerUpsertRepositoryImpl implements OrgProjectWorkerUpsertRepository {
private final OrgProjectWorkerDao orgProjectWorkerDao;
@Override
public void batchUpdate(List<OrgProjectWorker> orgProjectWorkers) {
orgProjectWorkerDao.updateBatchById(orgProjectWorkers);
}
}

View File

@ -26,6 +26,8 @@ import java.util.stream.Collectors;
public interface WorkerProfessionHistoryRepository {
PageResp<WorkerProfessionHistoryResp> page(PageReq req);
void saveBatch(List<WorkerProfessionHistory> history);
default List<WorkerProfessionHistoryResp> list(PageReq req) {
return page(req).getData();
}

View File

@ -21,6 +21,10 @@ import java.util.Set;
public interface WorkerProfessionSkillTagRepository {
PageResp<WorkerProfessionSkillTagResp> page(PageReq req);
void removeByIds(List<Long> ids);
void deleteByIds(List<Long> ids);
default List<WorkerProfessionSkillTagResp> list(PageReq req) {
return page(req).getData();
}

View File

@ -20,6 +20,18 @@ import java.util.Set;
public interface WorkerProfessionTagRepository {
PageResp<WorkerProfessionTagResp> page(PageReq req);
/**
* 物理删除数据
* @param ids
*/
void removeByIds(List<Long> ids);
/**
* 软删
* @param ids
*/
void deleteByIds(List<Long> ids);
default List<WorkerProfessionTagResp> list(PageReq req) {
return page(req).getData();
}

View File

@ -61,4 +61,9 @@ public class WorkerProfessionHistoryRepositoryImpl implements WorkerProfessionHi
}
return PageConverter.toResp(results);
}
@Override
public void saveBatch(List<WorkerProfessionHistory> histories) {
workerProfessionHistoryDao.saveBatch(histories);
}
}

View File

@ -17,6 +17,9 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
/**
* @author zhanghongbo
* @date 2025/1/6
@ -45,4 +48,20 @@ public class WorkerProfessionSkillTagRepositoryImpl implements WorkerProfessionS
}
return PageConverter.toResp(results);
}
@Override
public void removeByIds(List<Long> ids) {
workerProfessionSkillTagDao.removeByIds(ids);
}
@Override
public void deleteByIds(List<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
workerProfessionSkillTagDao.lambdaUpdate()
.in(WorkerProfessionSkillTag::getId, ids)
.setSql(" is_delete = id")
.update();
}
}

View File

@ -16,6 +16,9 @@ import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import java.util.Date;
import java.util.List;
/**
* @author zhanghongbo
* @date 2025/1/3
@ -44,4 +47,21 @@ public class WorkerProfessionTagRepositoryImpl implements WorkerProfessionTagRep
}
return PageConverter.toResp(results);
}
@Override
public void removeByIds(List<Long> ids) {
workerProfessionTagDao.removeByIds(ids);
}
@Override
public void deleteByIds(List<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
workerProfessionTagDao.lambdaUpdate()
.in(WorkerProfessionTag::getId, ids)
.setSql(" is_delete = id")
.update();
}
}

View File

@ -1,10 +1,18 @@
package cn.axzo.orgmanax.infra.event.config;
import cn.axzo.foundation.event.support.consumer.*;
import cn.axzo.foundation.event.support.consumer.DefaultEventConsumer;
import cn.axzo.foundation.event.support.consumer.DefaultRocketMQListener;
import cn.axzo.foundation.event.support.consumer.EventConsumer;
import cn.axzo.foundation.event.support.consumer.EventHandlerRepository;
import cn.axzo.foundation.event.support.consumer.RetryableEventConsumer;
import cn.axzo.foundation.event.support.consumer.RocketRetryableEventConsumer;
import cn.axzo.foundation.event.support.producer.EventProducer;
import cn.axzo.foundation.event.support.producer.RocketMQEventProducer;
import cn.axzo.foundation.web.support.AppRuntime;
import cn.axzo.foundation.web.support.conditional.NonLocalCondition;
import cn.axzo.framework.rocketmq.EventProduceTemplate;
import cn.axzo.framework.rocketmq.RockerEventProduceFactory;
import cn.axzo.framework.rocketmq.RocketConfigProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
@ -20,6 +28,8 @@ import org.springframework.stereotype.Component;
public class RocketMQEventConfig {
public static final String DEFAULT_MODULE = "orgmanax-server";
public static final String DEFAULT_NAME = "orgmanax-server";
@Value("topic_organizational_${spring.profiles.active}")
private String currentTopic;
@ -72,6 +82,17 @@ public class RocketMQEventConfig {
}
}
@NonLocalCondition.Conditional
@Component
@RocketMQMessageListener(topic = "topic_attendance_common_${spring.profiles.active}",
consumerGroup = "GID_${spring.application.name}_attendance_common_${spring.profiles.active}",
consumeMode = ConsumeMode.ORDERLY, maxReconsumeTimes = 20)
public static class AttendanceListener extends DefaultRocketMQListener {
public AttendanceListener(EventConsumer eventConsumer) {
super(eventConsumer);
}
}
@Bean
EventHandlerRepository eventHandlerRepository() {
return EventHandlerRepository.builder()
@ -123,5 +144,15 @@ public class RocketMQEventConfig {
//发送后回调 可以处理事件发送统计
});
}
@Bean
RockerEventProduceFactory rockerEventProduceFactory(RocketConfigProperties rocketMQProperties, RocketMQTemplate rocketMQTemplate) {
return new RockerEventProduceFactory(rocketMQProperties, rocketMQTemplate, DEFAULT_MODULE, DEFAULT_NAME);
}
@Bean
EventProduceTemplate eventProduceTemplate(RockerEventProduceFactory rockerEventProduceFactory) {
return new EventProduceTemplate(rockerEventProduceFactory, DEFAULT_MODULE, DEFAULT_NAME);
}
}

View File

@ -62,6 +62,33 @@
</exclusion>
</exclusions>
</dependency>
<!-- 考勤依赖 -->
<dependency>
<groupId>cn.axzo.attendance</groupId>
<artifactId>attendance-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 标签系统依赖 -->
<dependency>
<groupId>cn.axzo.data-tagger</groupId>
<artifactId>data-tagger-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<!-- 标签系统依赖 -->
<dependency>
<groupId>cn.axzo.data-tagger</groupId>
<artifactId>data-tagger-api</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
<!-- 工作流依赖 -->
<dependency>
<groupId>cn.axzo.workflow</groupId>
<artifactId>workflow-engine-spring-boot-starter</artifactId>
<version>1.5.2-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,39 @@
package cn.axzo.orgmanax.integration.sdk.attendance;
import cn.axzo.attendance.api.AttendanceRecordApi;
import cn.axzo.attendance.req.AttendancePersonQueryReq;
import cn.axzo.attendance.res.AttendancePersonInfoRes;
import cn.axzo.orgmanax.infra.client.attendance.AttendanceRecordClient;
import cn.axzo.orgmanax.infra.client.attendance.dto.AttendanceClockRecordListReq;
import cn.axzo.orgmanax.infra.client.attendance.dto.AttendanceClockRecordResp;
import cn.axzo.orgmanax.integration.core.RpcWrapper;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author luofu
* @version 1.0
* @description 考勤打卡记录相关API
* @date 2025/3/5
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class AttendanceRecordClientImpl implements AttendanceRecordClient {
private final AttendanceRecordApi attendanceRecordApi;
@Override
public List<AttendanceClockRecordResp> listClockRecords(AttendanceClockRecordListReq request) {
AttendancePersonQueryReq req = new AttendancePersonQueryReq();
BeanUtils.copyProperties(request, req);
List<AttendancePersonInfoRes> records = RpcWrapper.commonRes(() -> attendanceRecordApi.listExistAttendancePerson(req));
return CollUtil.map(records, record -> BeanUtil.copyProperties(record, AttendanceClockRecordResp.class), true);
}
}

View File

@ -0,0 +1,98 @@
package cn.axzo.orgmanax.integration.sdk.datatagger;
import cn.axzo.datatagger.api.JsonQueryFields;
import cn.axzo.datatagger.api.objecttag.ObjectTagClient;
import cn.axzo.datatagger.api.objecttag.request.ObjectTagQueryProperties;
import cn.axzo.datatagger.api.objecttag.request.RevokeObjectTagRequest;
import cn.axzo.datatagger.api.tagope.TagOperateClient;
import cn.axzo.datatagger.api.tagope.request.OperateTagsRequest;
import cn.axzo.datatagger.common.enums.TagObjectType;
import cn.axzo.orgmanax.infra.client.datatagger.DataTagClient;
import cn.axzo.orgmanax.infra.client.datatagger.dto.DataTagNode;
import cn.axzo.orgmanax.infra.client.datatagger.dto.DataTagProperty;
import cn.axzo.orgmanax.infra.client.datatagger.dto.OperateDataTagReq;
import cn.axzo.orgmanax.infra.client.datatagger.dto.RevokeDataTagReq;
import cn.axzo.orgmanax.integration.core.RpcWrapper;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import java.util.Optional;
import java.util.function.Function;
/**
* @author luofu
* @version 1.0
* @description 标签系统相关API
* @date 2025/3/5
*/
@Component
@RequiredArgsConstructor
public class DataTagClientImpl implements DataTagClient {
private final ObjectTagClient objectTagClient;
private final TagOperateClient tagOperateClient;
@Override
public boolean revokeDataTags(RevokeDataTagReq request) {
return RpcWrapper.commonRes(() -> objectTagClient.revokeObjectTags(toRevokeRequest(request)));
}
@Override
public void operateDataTags(OperateDataTagReq tagsRequest) {
RpcWrapper.commonRes(() -> tagOperateClient.operateTags(toOperateTagsRequest(tagsRequest)));
}
private static RevokeObjectTagRequest toRevokeRequest(RevokeDataTagReq request) {
RevokeObjectTagRequest req = new RevokeObjectTagRequest();
BeanUtils.copyProperties(request, req);
req.setObjectType(TagObjectType.valueOf(request.getObjectType().name()));
req.setQueryProperties(toQueryProperties(request.getProperties()));
return req;
}
private static OperateTagsRequest toOperateTagsRequest(OperateDataTagReq param) {
OperateTagsRequest operateTagsRequest = new OperateTagsRequest();
operateTagsRequest.setApp(param.getApp());
operateTagsRequest.setObjectType(TagObjectType.valueOf(param.getObjectType().name()));
operateTagsRequest.setRuntimeFields(toProperties(param.getProperty()));
operateTagsRequest.setObjectIds(param.getObjectIds());
operateTagsRequest.setTagInfos(CollUtil.map(param.getTagNodes(), DataTagClientImpl::toTagValueInfo, true));
return operateTagsRequest;
}
private static ObjectTagQueryProperties toQueryProperties(DataTagProperty properties) {
ObjectTagQueryProperties queryProperties = new ObjectTagQueryProperties();
queryProperties.setProps(toProperties(properties));
return queryProperties;
}
private static OperateTagsRequest.TagValueInfo toTagValueInfo(DataTagNode tagNode) {
OperateTagsRequest.TagValueInfo tagValueInfo = new OperateTagsRequest.TagValueInfo();
// tag node code
tagValueInfo.setTagNodeCode(tagNode.getNodeCode());
// tag value mapper
Function<String, OperateTagsRequest.ObjectTagValueInfo> tagValueMapper = e ->
OperateTagsRequest.ObjectTagValueInfo.builder().tagValueCode(e).build();
tagValueInfo.setObjectTagValues(CollUtil.map(tagNode.getValueCodes(), tagValueMapper, true));
return tagValueInfo;
}
private static JSONObject toProperties(DataTagProperty properties) {
JSONObject tagProperties = new JSONObject();
JsonQueryFields fields = JsonQueryFields.create(tagProperties);
// ouId
Optional.ofNullable(properties.getOuId()).ifPresent(fields::setOuId);
// workspaceId
Optional.ofNullable(properties.getWorkspaceId()).ifPresent(fields::setWorkspaceId);
// projectTeamNodeId
Optional.ofNullable(properties.getPlatTeamNodeId()).ifPresent(fields::setPlatTeamNodeId);
// projectTeamNodeId
Optional.ofNullable(properties.getProjectTeamNodeId()).ifPresent(fields::setProjectTeamNodeId);
// groupNodeId
Optional.ofNullable(properties.getGroupNodeId()).ifPresent(fields::setGroupNodeId);
return tagProperties;
}
}

View File

@ -0,0 +1,50 @@
package cn.axzo.orgmanax.integration.sdk.karma;
import cn.axzo.karma.client.feign.team.ThirdApiCheckServiceApi;
import cn.axzo.karma.client.model.request.ThirdApiPersonNormalCheckReq;
import cn.axzo.karma.client.model.vo.OpFailVO;
import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum;
import cn.axzo.orgmanax.infra.client.karma.KarmaThirdApiClient;
import cn.axzo.orgmanax.infra.client.karma.ThirdCheckFailResp;
import cn.axzo.orgmanax.integration.core.RpcWrapper;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/7
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class KarmaThirdApiClientImpl implements KarmaThirdApiClient {
private final ThirdApiCheckServiceApi thirdApiCheckServiceApi;
@Override
public Map<Long, List<ThirdCheckFailResp>> getThirdCheckFail(Long workspaceId, Set<Long> personIds) {
ThirdApiPersonNormalCheckReq checkReq = new ThirdApiPersonNormalCheckReq();
checkReq.setWorkspaceId(workspaceId);
checkReq.setPersonIdList(new ArrayList<>(personIds));
Map<Long, List<OpFailVO>> checkMap = RpcWrapper.commonRes(() -> thirdApiCheckServiceApi.thirdApiNormalCheckPerson(checkReq));
if (CollUtil.isEmpty(checkMap)) {
return Collections.emptyMap();
}
Map<Long, List<ThirdCheckFailResp>> failInfoMap = new HashMap<>();
checkMap.forEach((key, opFailVOs) -> {
List<ThirdCheckFailResp> personList = opFailVOs.stream().map(opFailVO -> {
ThirdCheckFailResp thirdCheckFailResp = new ThirdCheckFailResp();
thirdCheckFailResp.setType(CheckInfoTypeEnum.getByThirdType(opFailVO.getType()));
thirdCheckFailResp.setCount(opFailVO.getCount());
return thirdCheckFailResp;
}).collect(Collectors.toList());
failInfoMap.put(key, personList);
});
return failInfoMap;
}
}

View File

@ -0,0 +1,31 @@
package cn.axzo.orgmanax.integration.sdk.tyr;
import cn.axzo.orgmanax.infra.client.tyr.SaasRoleUserClient;
import cn.axzo.orgmanax.infra.client.tyr.dto.OrgManaxWorkerManagerRoleUserReq;
import cn.axzo.orgmanax.integration.core.RpcWrapper;
import cn.axzo.tyr.client.feign.TyrSaasRoleUserApi;
import cn.axzo.tyr.client.model.roleuser.req.WorkerManagerRoleUserReq;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* @Author zr
* @Date 2025/3/11 14:33
* @Description
**/
@AllArgsConstructor
@Component
@Slf4j
public class SaasRoleUserClientImpl implements SaasRoleUserClient {
private final TyrSaasRoleUserApi tyrSaasRoleUserApi;
@Override
public void grantOrUngrantWorkerManager(OrgManaxWorkerManagerRoleUserReq req) {
log.info("授权或者取消授权班组管理员或者项目代班长、小组长", JSON.toJSONString(req));
WorkerManagerRoleUserReq managerRoleUserReq = BeanUtil.copyProperties(req, WorkerManagerRoleUserReq.class);
RpcWrapper.wrapApiResult(() -> tyrSaasRoleUserApi.grantOrUngrantWorkerManager(managerRoleUserReq));
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.orgmanax.integration.sdk.workflow;
import cn.axzo.orgmanax.infra.client.workflow.WorkflowCoreClient;
import cn.axzo.orgmanax.infra.client.workflow.dto.BatchOperationResultResp;
import cn.axzo.orgmanax.infra.client.workflow.dto.BpmnProcessInstanceAbortReq;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceAbortDTO;
import cn.axzo.workflow.common.model.response.bpmn.BatchOperationResultVO;
import cn.axzo.workflow.starter.api.WorkflowCoreService;
import cn.azxo.framework.common.logger.MethodAroundLog;
import cn.hutool.core.bean.BeanUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @Author zr
* @Date 2025/3/20 09:41
* @Description
**/
@AllArgsConstructor
@Component
@Slf4j
public class WorkflowCoreClientImpl implements WorkflowCoreClient {
@Autowired
private final WorkflowCoreService workflowCoreService;
@Override
@MethodAroundLog(source = "orgmanax", target = "workflow", value = "批量驳回流程实例")
public BatchOperationResultResp batchAbortProcessInstance(List<BpmnProcessInstanceAbortReq> reqs) {
List<BpmnProcessInstanceAbortDTO> abortDTOS = BeanUtil.copyToList(reqs, BpmnProcessInstanceAbortDTO.class);
BatchOperationResultVO resultVO = workflowCoreService.async().batchAbortProcessInstance(abortDTOS);
return BeanUtil.copyProperties(resultVO,BatchOperationResultResp.class);
}
}

View File

@ -50,5 +50,13 @@
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.pokonyan</groupId>
<artifactId>pokonyan</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.baomidou</groupId>-->
<!-- <artifactId>lock4j-redisson-spring-boot-starter</artifactId>-->
<!-- </dependency>-->
</dependencies>
</project>

View File

@ -1,11 +1,11 @@
package cn.axzo.orgmanax.server.cooperateship.foundation;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRepository.ListReq;
import cn.axzo.orgmanax.server.cooperateship.foundation.dto.CooperateShipCreator;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
public interface CooperateShipFoundationService {
@ -76,4 +76,12 @@ public interface CooperateShipFoundationService {
* 创建协同关系通用方法
*/
SaasCooperateShip create(CooperateShipCreator creator);
/**
* 协同关系通用查询
*
* @param req 入参
* @return 协同关系节点列表
*/
List<SaasCooperateShip> list(ListReq req);
}

View File

@ -217,4 +217,9 @@ public class CooperateShipFoundationServiceImpl implements CooperateShipFoundati
return savedCooperateShip;
}
@Override
public List<SaasCooperateShip> list(CooperateShipQueryRepository.ListReq req) {
return cooperateShipQueryRepository.list(req);
}
}

View File

@ -0,0 +1,16 @@
package cn.axzo.orgmanax.server.invite.foundation;
import cn.axzo.orgmanax.infra.dao.invite.repository.ProjectWorkerInviteRepository;
import cn.axzo.orgmanax.server.invite.foundation.dto.ProjectWorkerInviteCreator;
import java.util.List;
/**
* @Author zr
* @Date 2025/3/19 18:05
* @Description
**/
public interface ProjectWorkerInviteFoundationService {
List<ProjectWorkerInviteRepository.ProjectWorkerInviteResp> updateBatchById(List<ProjectWorkerInviteCreator> req);
}

View File

@ -0,0 +1,143 @@
package cn.axzo.orgmanax.server.invite.foundation.dto;
import cn.axzo.orgmanax.infra.dao.invite.entity.ProjectWorkerInvite;
import cn.axzo.trade.datasecurity.core.annotation.CryptField;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* @Author zr
* @Date 2025/3/19 18:07
* @Description
**/
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ProjectWorkerInviteCreator {
private Long id;
/**
* 工作台ID
*/
private Long workspaceId;
/**
* 总包ID
*/
private Long entId;
/**
* 项目内班组ID
*/
private Long projectTeamId;
/**
* 项目内工人id
*/
private Long projectWorkerId;
/**
* 所属单位ID
*/
private Long organizationalUnitId;
/**
* 所属单位类型: 1:总包 4:专业分包 5:劳务分包
*/
private Integer organizationalUnitType;
/**
* 工人ID
*/
private Long workerIdentityId;
/**
* 状态1待班组审批  2待劳务审批  3通过 4拒绝
*/
private Integer status;
/**
* 类型1班组长邀请 2二维码邀请 3:派单
*/
private Integer source;
/**
* 邀请人id
*/
private Long inviterId;
/**
* 邀请人名称
*/
private String inviterName;
/**
* 是否删除 0:未删除 其他:已删除
*/
private Long isDelete;
private Date createAt;
private Date updateAt;
/**
* 工种类别 技工 普工
*/
private String professionCategoryName;
/**
* 审批人的从业人员身份id
*/
private Long approverIdentityId;
/**
* 班组长审批时间,REQ-598
*/
private Date teamLeaderAuditDate;
/**
* source = 4合作小组派单记录甲方的班组id
*/
private Long belongProjectTeamId;
/**
* 工人名称
*/
private String workerName;
/**
* 工人电话号码
*/
@CryptField
private String workerPhone;
/**
* 工作流流程实例id
*/
private String processInstanceId;
/**
* 邀请的工种
*/
private JSONObject professionExt;
/**
* 扩展字段
*/
private JSONObject extra;
/**
* 构建实体
* @return
*/
public ProjectWorkerInvite toEntity() {
return BeanUtil.copyProperties(this, ProjectWorkerInvite.class);
}
}

View File

@ -0,0 +1,30 @@
package cn.axzo.orgmanax.server.invite.foundation.impl;
import cn.axzo.orgmanax.infra.dao.invite.entity.ProjectWorkerInvite;
import cn.axzo.orgmanax.infra.dao.invite.repository.ProjectWorkerInviteRepository;
import cn.axzo.orgmanax.server.invite.foundation.ProjectWorkerInviteFoundationService;
import cn.axzo.orgmanax.server.invite.foundation.dto.ProjectWorkerInviteCreator;
import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author zr
* @Date 2025/3/19 18:10
* @Description
**/
@RequiredArgsConstructor
@Service
public class ProjectWorkerInviteFoundationServiceImpl implements ProjectWorkerInviteFoundationService {
private final ProjectWorkerInviteRepository projectWorkerInviteRepository;
@Override
public List<ProjectWorkerInviteRepository.ProjectWorkerInviteResp> updateBatchById(List<ProjectWorkerInviteCreator> req) {
List<ProjectWorkerInvite> projectWorkerInvites = req.stream().map(item -> item.toEntity()).collect(Collectors.toList());
projectWorkerInviteRepository.updateBatchById(projectWorkerInvites);
return BeanUtil.copyToList(projectWorkerInvites, ProjectWorkerInviteRepository.ProjectWorkerInviteResp.class);
}
}

View File

@ -0,0 +1,62 @@
package cn.axzo.orgmanax.server.mq;
import cn.axzo.foundation.event.support.Event;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import cn.axzo.orgmanax.server.mq.enums.MQEventEnum;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Preconditions;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import java.io.Serializable;
/**
* OrganizationalNodeUser 变更事件(新增/修改/删除)
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrganizationalNodeUserUpsertedPayload implements Serializable {
private OrganizationalNodeUser newValue;
private OrganizationalNodeUser oldValue;
private JSONObject ext;
public Long getTopNodeId() {
return ObjectUtils.firstNonNull(oldValue, newValue).getTopNodeId();
}
public Long getPersonId() {
return ObjectUtils.firstNonNull(oldValue, newValue).getPersonId();
}
public Long getIdentityId() {
return ObjectUtils.firstNonNull(oldValue, newValue).getIdentityId();
}
public Integer getIdentityType() {
return ObjectUtils.firstNonNull(oldValue, newValue).getIdentityType();
}
public static Event from(OrganizationalNodeUser newValue,
OrganizationalNodeUser oldValue,
String operator, JSONObject ext) {
Preconditions.checkArgument(ObjectUtils.anyNotNull(newValue, oldValue));
return Event.builder()
.shardingKey(ObjectUtils.firstNonNull(newValue, oldValue).getId() + "")
.targetId(ObjectUtils.firstNonNull(newValue, oldValue).getId() + "")
.targetType(MQEventEnum.NODE_USER_UPSERTED.getModel())
.eventCode(new Event.EventCode(MQEventEnum.NODE_USER_UPSERTED.getModel(), MQEventEnum.NODE_USER_UPSERTED.getTag()))
.operatorId(operator)
.data(OrganizationalNodeUserUpsertedPayload.builder()
.newValue(newValue)
.oldValue(oldValue)
.ext(ext)
.build())
.build();
}
}

View File

@ -0,0 +1,65 @@
package cn.axzo.orgmanax.server.mq.enums;
import cn.axzo.foundation.event.support.Event;
import lombok.Getter;
@Getter
public enum MQEventEnum {
NODE_CREATE("node", "node-create", "节点创建"),
NODE_UPDATE("node", "node-update", "节点修改"),
NODE_DELETE("node", "node-delete", "节点删除"),
NODE_USER_CREATE("node-user", "node-user-create", "节点用户创建"),
NODE_USER_UPDATE("node-user", "node-user-update", "节点用户修改"),
NODE_USER_DELETE("node-user", "node-user-delete", "节点用户删除"),
NODE_USER_UPSERTED("node-user", "node-user-upserted", "节点用户更新"),
NODE_USER_VERIFY("profile", "verify-success", "节点用户实名认证"),
WORKSPACE_USER_CHANGED("workspace-user", "workspace-user-changed", "项目用户变更"),
UNIT_CREATE("unit", "unit-create", "单位创建"),
UNIT_UPDATE("unit", "unit-update", "单位修改"),
// updated 事件会将 oldnew发出来
UNIT_UPDATED("unit", "unit-updated", "单位修改"),
UNIT_DELETE("unit", "unit-delete", "单位删除"),
INDUSTRY_DICT_CHANGE("industry-dict", "industry-dict-change", "行业字典变更"),
COOPERATE_SHIP_CREATE_OR_UPDATE("cooperate-ship", "cooperate-ship-create-or-update", "创建或更新协作关系"),
COOPERATE_SHIP_RESIGN("cooperate-ship", "cooperate-ship-resign", "退场"),
PERSON_TAG_BATCH_UPDATED("person-tag", "person-tag-batch-upserted", "批量修改用户标签"),
PROJECT_WORKER_RESIGN("project-worker", "project-worker-resign", "工人退场"),
ORG_USER_MOVEMENT("org-user", "org-user-movement", "用户组织异动"),
ORG_NODE_USER_CHANGED("org-user", "org-node-user-change", "用户人岗架异动"),
COOPERATE_SHIP_UPSERT("cooperate-ship", "cooperate-ship-upsert", "创建或更新协作关系"),
SAAS_ROLE_UPSERT("saas-role", "saas-role-upsert", "更新角色信息"),
/**
* 小组
*/
PROJECT_GROUP_CHANGE_LEADER("group","project-group-chang-leader","项目小组更换小组长"),
GROUP_CREATE("group","group-create","项目小组组创建"),
GROUP_DISSOLVE("group","group-dissolve","项目小组组解散")
;
private final String model;
private final String tag;
private final String desc;
private final Event.EventCode eventCode;
MQEventEnum(String model, String tag, String desc) {
this.eventCode = Event.EventCode.builder()
.module(model)
.name(tag)
.build();
this.model = model;
this.tag = tag;
this.desc = desc;
}
}

View File

@ -0,0 +1,68 @@
package cn.axzo.orgmanax.server.mq.producer;
import cn.axzo.foundation.event.support.Event;
import cn.axzo.foundation.event.support.producer.EventProducer;
import cn.axzo.orgmanax.dto.common.util.NumberUtil;
import cn.axzo.orgmanax.dto.orguser.event.OrgUserStatusChangedEvent;
import cn.axzo.orgmanax.server.mq.enums.MQEventEnum;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Objects;
/**
* @author luofu
* @version 1.0
* @date 2024/10/31
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class OrgUserChangedEventProducer {
private static final String EVENT_INVALID = "the event is invalid. {}";
private final EventProducer eventProducer;
public void sendStatusEvent(OrgUserStatusChangedEvent event) {
if (isInvalid(event)) {
log.info(EVENT_INVALID, event);
return;
}
//生产消息
eventProducer.send(map(event));
}
public void batchSendStatusEvents(Collection<OrgUserStatusChangedEvent> events) {
if (CollUtil.isEmpty(events)) {
log.info("the events is empty.");
return;
}
events.forEach(this::sendStatusEvent);
}
public static boolean isInvalid(OrgUserStatusChangedEvent eventData) {
return Objects.isNull(eventData)
|| NumberUtil.isNotPositiveNumber(eventData.getPersonId())
|| NumberUtil.isNotPositiveNumber(eventData.getOuId())
|| NumberUtil.isNotPositiveNumber(eventData.getWorkspaceId())
|| Objects.isNull(eventData.getStatusCode())
|| NumberUtil.isNotPositiveNumber(eventData.getTransferTimestamp());
}
private static Event map(OrgUserStatusChangedEvent event) {
MQEventEnum mqEvent = MQEventEnum.ORG_USER_MOVEMENT;
return Event.builder()
.shardingKey(String.valueOf(event.getPersonId()))
.targetId(String.valueOf(event.getPersonId()))
.targetType(mqEvent.getModel())
.eventCode(mqEvent.getEventCode())
.data(event)
.build();
}
}

View File

@ -0,0 +1,34 @@
package cn.axzo.orgmanax.server.nodeuser.controller;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.nodeuser.feign.OrgNodeUserCheckApi;
import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq;
import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserCheckService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/6
*/
@RestController
@RequestMapping
@RequiredArgsConstructor
public class NodeUserCheckController implements OrgNodeUserCheckApi {
private final NodeUserCheckService nodeUserCheckService;
@Override
public ApiResult<List<BatchDeleteNodeUserCheckResp>> checkUnit(BatchDeleteNodeUserCheckReq req) {
return ApiResult.success(nodeUserCheckService.checkUnit(req));
}
@Override
public ApiResult<List<BatchDeleteNodeUserCheckResp>> checkWorkspace(BatchDeleteNodeUserCheckReq req) {
return ApiResult.success(nodeUserCheckService.checkWorkspace(req));
}
}

View File

@ -0,0 +1,33 @@
package cn.axzo.orgmanax.server.nodeuser.dto;
import cn.axzo.foundation.result.ResultCode;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import java.util.List;
import java.util.Set;
/**
* @author : zhanghonghao@axzo.cn
* @since : 2025/3/7
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class CheckUserOperateParam {
private Long operatorId;
private Set<Long> personIds;
private Long workspaceId;
private boolean isWorkspace;
private List<Long> topNodeIds;
public void check() {
if (ObjectUtils.anyNull(personIds, workspaceId, operatorId)) {
throw ResultCode.INVALID_PARAMS.toException("参数异常,您暂无权限!");
}
}
}

View File

@ -0,0 +1,31 @@
package cn.axzo.orgmanax.server.nodeuser.foundation;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository.ListReq;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository.NodeUserExtraResp;
import java.util.Map;
import java.util.Set;
/**
* @author luofu
* @version 1.0
* @date 2025/3/11
*/
public interface NodeUserExtraFoundationService {
/***
* 分页查询
*
* @param req 入参
* @return node_user_extra 列表
*/
PageResp<NodeUserExtraResp> page(ListReq req);
/**
* 批量设置用户标签
*
* @param idTagsMap key:id, value:标签集合
*/
void updateTagsMap(Map<Long, Set<String>> idTagsMap);
}

View File

@ -1,12 +1,13 @@
package cn.axzo.orgmanax.server.nodeuser.foundation;
import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO;
import cn.axzo.foundation.page.PageResp;
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;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository.ListReq;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository.NodeUserResp;
import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserCreate;
import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete;
import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserUpdate;
import org.springframework.transaction.annotation.Transactional;
@ -32,6 +33,18 @@ public interface NodeUserFoundationService {
@Transactional(rollbackFor = Throwable.class)
OrganizationalNodeUser update(NodeUserUpdate req);
@Transactional(rollbackFor = Throwable.class)
List<OrganizationalNodeUser> updateBatchById(List<NodeUserUpdate> req);
/**
* 该接口为删除的收口接口业务使用的时候需要自行做业务判断
*
* @param req
* @return
*/
@Transactional(rollbackFor = Throwable.class)
List<OrganizationalNodeUser> delete(NodeUserDelete req);
/**
* 根据岗位进行过滤
* @param nodeUsers
@ -45,4 +58,12 @@ public interface NodeUserFoundationService {
* @return
*/
List<SearchEntNodeUserResp> searchEntUser(SearchEntNodeUserReq req);
/**
* 通用分页查询
*
* @param req 入参
* @return node_user列表
*/
PageResp<NodeUserResp> page(ListReq req);
}

View File

@ -0,0 +1,38 @@
package cn.axzo.orgmanax.server.nodeuser.foundation.impl;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository.ListReq;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository.NodeUserExtraResp;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraUpsertRepository;
import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserExtraFoundationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.Set;
/**
* @author luofu
* @version 1.0
* @date 2025/3/11
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class NodeUserExtraFoundationServiceImpl implements NodeUserExtraFoundationService {
private final NodeUserExtraQueryRepository queryRepository;
private final NodeUserExtraUpsertRepository upsertRepository;
@Override
public PageResp<NodeUserExtraResp> page(ListReq req) {
return queryRepository.page(req);
}
@Override
public void updateTagsMap(Map<Long, Set<String>> idTagsMap) {
upsertRepository.updateTagsMap(idTagsMap);
}
}

View File

@ -1,15 +1,20 @@
package cn.axzo.orgmanax.server.nodeuser.foundation.impl;
import cn.axzo.apollo.workspace.api.v2.workspace.req.WorkspaceDetailReq;
import cn.axzo.apollo.workspace.api.v2.workspace.resp.WorkspaceDetailResp;
import cn.axzo.foundation.event.support.Event;
import cn.axzo.foundation.event.support.producer.EventProducer;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.axzo.orgmanax.dto.common.util.NumberUtil;
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.ProfileGetIdentityProfileLiteResp;
import cn.axzo.orgmanax.infra.client.profile.dto.ProfilePersonResp;
import cn.axzo.orgmanax.infra.client.workspace.WorkspaceGateway;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRepository;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNode;
@ -17,24 +22,36 @@ 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.NodeUserQueryRepository.ListReq;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository.NodeUserResp;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserUpsertRepository;
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.repository.UnitQueryRepository;
import cn.axzo.orgmanax.server.mq.OrganizationalNodeUserUpsertedPayload;
import cn.axzo.orgmanax.server.mq.enums.MQEventEnum;
import cn.axzo.orgmanax.server.node.event.inner.NodeEventType;
import cn.axzo.orgmanax.server.nodeuser.event.inner.payload.NodeUserUpsertedPayload;
import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService;
import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserCreate;
import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete;
import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserUpdate;
import cn.axzo.orgmanax.server.orguser.foundation.OrgUserFoundationService;
import cn.axzo.orgmanax.server.orguser.foundation.req.OrgUserWithdrawOrQuitReq;
import cn.axzo.orgmanax.server.project.worker.foundation.OrgProjectWorkerFoundationService;
import cn.axzo.orgmanax.server.project.worker.foundation.req.OrgProjectWorkerWithdrawReq;
import cn.axzo.orgmanax.server.service.OperateLogService;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.BooleanUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author tanjie@axzo.cn
@ -52,7 +69,10 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService
private final PersonProfileGateway profileGateway;
private final OrganizationalNodeUserMapper organizationalNodeUserMapper;
private final OrgJobQueryRepository orgJobQueryRepository;
private final UnitQueryRepository unitQueryRepository;
private final WorkspaceGateway workspaceGateway;
private final OrgUserFoundationService orgUserFoundationService;
private final OrgProjectWorkerFoundationService orgProjectWorkerFoundationService;
/**
* 创建部门标准接口
@ -142,6 +162,103 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService
return nodeUserUpsertRepository.update(updateReq);
}
@Override
public List<OrganizationalNodeUser> updateBatchById(List<NodeUserUpdate> req) {
List<Long> nodeUserIds = req.stream().map(NodeUserUpdate::getId).collect(Collectors.toList());
List<NodeUserQueryRepository.NodeUserResp> dbNodeUsers = nodeUserQueryRepository.list(NodeUserQueryRepository.ListReq.builder()
.ids(nodeUserIds).build());
Axssert.checkNotEmpty(dbNodeUsers, "部门人员不存在 {}", nodeUserIds);
List<NodeUserUpsertRepository.UpdateReq> updateReqs = BeanUtil.copyToList(req, NodeUserUpsertRepository.UpdateReq.class);
return nodeUserUpsertRepository.updateBatchById(updateReqs);
}
@Override
public List<OrganizationalNodeUser> delete(NodeUserDelete req) {
checkDeleteReq(req);
List<NodeUserQueryRepository.NodeUserResp> list =
nodeUserQueryRepository.list(
NodeUserQueryRepository.ListReq.builder()
.organizationalUnitId(req.isUnitDelete() ? req.getOuId() : null)
.workspaceId(req.isUnitDelete() ? null : req.getWorkspaceId()).personIds(req.getPersonIds())
.topNodeIds(req.getTopNodeIds()).identityType(req.getIdentityType()).build());
if (CollUtil.isEmpty(list)) {
return CollUtil.newArrayList();
}
Map<Long, Set<Long>> ouPersonIdsMap = list.stream().collect(Collectors.groupingBy(NodeUserQueryRepository.NodeUserResp::getOrganizationalUnitId,
Collectors.mapping(OrganizationalNodeUser::getPersonId, Collectors.toSet())));
//批量删除node_user
nodeUserUpsertRepository.batchDelete(list.stream().map(NodeUserQueryRepository.NodeUserResp::getId).collect(Collectors.toSet()));
List<OrganizationalNodeUser> nodeUserList = list.stream().map(e -> BeanUtil.toBean(e, OrganizationalNodeUser.class)).collect(Collectors.toList());
nodeUserList.forEach(this::sendNodeUserDeleteMq);
//处理orgUser退场或离职逻辑
Map<Long, Set<Long>> quitMap = nodeUserList.stream().collect(Collectors.groupingBy(OrganizationalNodeUser::getTopNodeId,
Collectors.mapping(OrganizationalNodeUser::getPersonId, Collectors.toSet())));
OrgUserWithdrawOrQuitReq quitReq = new OrgUserWithdrawOrQuitReq();
quitReq.setUnitUpdate(req.isUnitDelete());
quitReq.setWorkspaceId(req.getWorkspaceId());
quitReq.setTopNodeIdAndPersonIds(quitMap);
if (req.isUnitDelete()) {
quitReq.setOuId(req.getOuId());
quitReq.setWorkspaceId(nodeUserList.get(0).getWorkspaceId());
orgUserFoundationService.batchWithdrawOrQuit(quitReq);
} else {
for (Map.Entry<Long, Set<Long>> unitPersonIds : ouPersonIdsMap.entrySet()) {
quitReq.setOuId(unitPersonIds.getKey());
quitReq.setPersonIds(unitPersonIds.getValue());
orgUserFoundationService.batchWithdrawOrQuit(quitReq);
}
}
//项目内工人退场
OrgProjectWorkerWithdrawReq workerReq = new OrgProjectWorkerWithdrawReq();
workerReq.setWorkspaceId(req.getWorkspaceId());
if (req.isUnitDelete()) {
workerReq.setOuId(req.getOuId());
workerReq.setWorkspaceId(nodeUserList.get(0).getWorkspaceId());
}
workerReq.setPersonIds(req.getPersonIds());
orgProjectWorkerFoundationService.batchWithdraw(workerReq);
return nodeUserList;
}
private void sendNodeUserDeleteMq(OrganizationalNodeUser e) {
String summary = "部门人员删除";
// 方便记录操作日志
OperateLogService.OperateType operateType = OperateLogService.OperateType.DELETE;
OperateLogService.SaveParam saveParam = OperateLogService.SaveParam.builder()
.summary(summary)
.resourceType(OperateLogService.ResourceType.ORGANIZATIONAL_NODE_USER)
.resourceId(ObjectUtils.firstNonNull(e, null).getId())
.operateType(operateType)
.apiCaller("orgmanax")
.build();
eventProducer.send(OrganizationalNodeUserUpsertedPayload.from(null, e, "-1",
new JSONObject().fluentPut("operateLogSaveParam", saveParam)));
MQEventEnum mqEvent = MQEventEnum.NODE_USER_DELETE;
Event nodeUserDelete = Event.builder()
.shardingKey(String.valueOf(e.getPersonId()))
.targetId(String.valueOf(e.getPersonId()))
.targetType(mqEvent.getModel())
.eventCode(mqEvent.getEventCode())
.data(e)
.build();
eventProducer.send(nodeUserDelete);
}
private void checkDeleteReq(NodeUserDelete req) {
if (NumberUtil.isPositiveNumber(req.getOuId())) {
UnitQueryRepository.UnitResp one = unitQueryRepository.oneOpt(UnitQueryRepository.OneReq.builder().id(req.getOuId()).build())
.orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("单位不存在{}", req.getOuId()));
}
if (NumberUtil.isPositiveNumber(req.getWorkspaceId())) {
WorkspaceDetailReq workspaceDetailReq = WorkspaceDetailReq.builder().id(req.getWorkspaceId()).build();
WorkspaceDetailResp workspaceDetailResp = workspaceGateway.getDetail(workspaceDetailReq);
Axssert.checkNonNull(workspaceDetailResp, "项目不存在");
}
}
@Override
public <T extends OrganizationalNodeUser> void filterByJobs(Collection<T> nodeUsers, Collection<String> jobCodes) {
List<OrgJobQueryRepository.JobResp> orgJobs = orgJobQueryRepository.list(OrgJobQueryRepository.ListReq.builder()
@ -154,15 +271,17 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService
/**
* 根据条件聚合查询节点用户
*
* @param req
* @return
*/
@Override
public List<SearchEntNodeUserResp> searchEntUser(SearchEntNodeUserReq req) {
return organizationalNodeUserMapper.searchEntUser(req);
}
@Override
public PageResp<NodeUserResp> page(ListReq req) {
return nodeUserQueryRepository.page(req);
}
private Long resolveWorkspaceId(OrganizationalNode node) {
if (Objects.equals(node.getNodeType(), NodeUserTypeEnum.TEAM.getValue())) {
return 0L;

View File

@ -0,0 +1,45 @@
package cn.axzo.orgmanax.server.nodeuser.foundation.req;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import cn.hutool.core.bean.BeanUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public class NodeUserDelete {
private Long ouId;
private Long operatorId;
private Long workspaceId;
private List<Long> personIds;
/**
* 是否企业删除
*/
private boolean isUnitDelete;
/**
* 身份类型 按照项目删除的时候
*/
private Integer identityType;
/**
* 顶级节点
*/
private List<Long> topNodeIds;
public OrganizationalNodeUser toEntity() {
return BeanUtil.toBean(this, OrganizationalNodeUser.class);
}
}

Some files were not shown because too many files have changed in this diff Show More