From 28f6b7736ce087fb766a4966b32602d69e4ee69f Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 5 Mar 2025 13:53:19 +0800 Subject: [PATCH 01/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20?= =?UTF-8?q?=E8=80=83=E5=8B=A4=E8=AE=B0=E5=BD=95=E4=BA=8B=E4=BB=B6MQ?= =?UTF-8?q?=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../event/config/RocketMQEventConfig.java | 18 +- .../event/outer/AttendanceEventEnum.java | 24 ++ .../handler/AttendanceRecordEventHandler.java | 103 +++++++++ .../payload/AttendanceRecordPayload.java | 206 ++++++++++++++++++ 4 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/AttendanceEventEnum.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/handler/AttendanceRecordEventHandler.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/payload/AttendanceRecordPayload.java diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/event/config/RocketMQEventConfig.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/event/config/RocketMQEventConfig.java index 47e853e..1f095d6 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/event/config/RocketMQEventConfig.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/event/config/RocketMQEventConfig.java @@ -1,6 +1,11 @@ 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; @@ -72,6 +77,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() diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/AttendanceEventEnum.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/AttendanceEventEnum.java new file mode 100644 index 0000000..d6e8a45 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/AttendanceEventEnum.java @@ -0,0 +1,24 @@ +package cn.axzo.orgmanax.server.orguser.event.outer; + +import cn.axzo.foundation.event.support.Event; +import lombok.Getter; + +/** + * @author luofu + * @version 1.0 + * @description 考勤事件枚举 + * @date 2025/3/5 + */ +@Getter +public enum AttendanceEventEnum { + + ATTENDANCE_RECORD("ATTENDANCE", "attendance_record", "发送新增考勤记录"); + + private final Event.EventCode eventCode; + private final String desc; + + AttendanceEventEnum(String module, String tag, String desc) { + this.eventCode = Event.EventCode.builder().module(module).name(tag).build(); + this.desc = desc; + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/handler/AttendanceRecordEventHandler.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/handler/AttendanceRecordEventHandler.java new file mode 100644 index 0000000..9f53a19 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/handler/AttendanceRecordEventHandler.java @@ -0,0 +1,103 @@ +package cn.axzo.orgmanax.server.orguser.event.outer.handler; + +import cn.axzo.foundation.event.support.Event; +import cn.axzo.foundation.event.support.EventHandler; +import cn.axzo.foundation.event.support.consumer.EventConsumer; +import cn.axzo.orgmanax.dto.common.util.NumberUtil; +import cn.axzo.orgmanax.server.orguser.event.outer.AttendanceEventEnum; +import cn.axzo.orgmanax.server.orguser.event.outer.payload.AttendanceRecordPayload; +import com.google.common.collect.ImmutableList; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +/** + * @author luofu + * @version 1.0 + * @description 考勤新增记录事件处理器 + * @date 2025/3/5 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class AttendanceRecordEventHandler implements EventHandler, InitializingBean { + + private static final String HANDLER_ALIAS = "ATTENDANCE_RECORD_EVENT_HANDLER"; + private static final String LOG_PREFIX = "[" + HANDLER_ALIAS + "] "; + + private static final ImmutableList EXPECTED_CLOCK_TYPES = ImmutableList.of( + AttendanceRecordPayload.CLOCK_TYPE_ENTRY, + AttendanceRecordPayload.CLOCK_TYPE_EXIT + ); + + private final EventConsumer eventConsumer; + + @Override + public void onEvent(Event event, EventConsumer.Context context) { + info("received the event. msgId:{}", context.getMsgId()); + AttendanceRecordPayload payload = parsePayload(event); + if (Objects.isNull(payload)) { + info("the event data is invalid. msgId:{}", context.getMsgId()); + return; + } + if (invalidPayload(payload)) { + error("invalid payload. msgId:{}, data:{}", context.getMsgId(), payload); + return; + } + if (unexpectedPayload(payload)) { + info("unexpected payload. msgId:{}, data:{}", context.getMsgId(), payload); + return; + } + info("started to handle the event. msgId:{}", context.getMsgId()); + handle(payload, context.getMsgId()); + info("completed to handle the event. msgId:{}", context.getMsgId()); + } + + private AttendanceRecordPayload parsePayload(Event event) { + try { + return event.normalizedData(AttendanceRecordPayload.class); + } catch (Exception e) { + error("broke out some exception while parsing payload.", e); + return null; + } + } + + private boolean invalidPayload(AttendanceRecordPayload payload) { + return NumberUtil.isNotPositiveNumber(payload.getPersonId()) + || NumberUtil.isNotPositiveNumber(payload.getOuId()) + || NumberUtil.isNotPositiveNumber(payload.getWorkspaceId()) + || Objects.isNull(payload.getUserType()) + || Objects.isNull(payload.getClockType()) + || Objects.isNull(payload.getClockAt()) + // 非从业人员,需要通过teamId去获取其真实的单位id + || (payload.isNotPractitioner() && NumberUtil.isNotPositiveNumber(payload.getTeamId())); + } + + private boolean unexpectedPayload(AttendanceRecordPayload payload) { + return EXPECTED_CLOCK_TYPES.stream().noneMatch(e -> e.equals(payload.getClockType())); + } + + private void handle(AttendanceRecordPayload payload, String msgId) { + // FIXME: cold_blade 暂时废弃通过接MQ来实现标签取消的方案,改用XXL-JOB方式实现 + // 缘由:考勤MQ的消息集中在上下班的高峰,且有暂离标签的用户是少数,因此大多数的MQ消息都是空转 + } + + @Override + public void afterPropertiesSet() throws Exception { + eventConsumer.registerHandler(AttendanceEventEnum.ATTENDANCE_RECORD.getEventCode(), this, HANDLER_ALIAS); + } + + private static void info(String msgFormat, Object... args) { + msgFormat = LOG_PREFIX + msgFormat; + log.info(msgFormat, args); + } + + private static void error(String msgFormat, Object... args) { + msgFormat = LOG_PREFIX + msgFormat; + // FIXME: cold_blade 基于MQ方案暂时不考虑的前提,此处就不用告警出来了 + log.warn(msgFormat, args); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/payload/AttendanceRecordPayload.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/payload/AttendanceRecordPayload.java new file mode 100644 index 0000000..755470b --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/event/outer/payload/AttendanceRecordPayload.java @@ -0,0 +1,206 @@ +package cn.axzo.orgmanax.server.orguser.event.outer.payload; + +import com.alibaba.fastjson.JSON; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; +import java.util.Objects; +import java.util.Set; + +/** + * @author luofu + * @version 1.0 + * @description 新增考勤记录事件数据 + * @date 2025/3/5 + */ +@Data +public class AttendanceRecordPayload implements Serializable { + + public static final int CLOCK_TYPE_ENTRY = 1; + public static final int CLOCK_TYPE_EXIT = 2; + + private static final int USER_TYPE_PRACTITIONER = 2; + + /** + * 考勤记录主键 + */ + private Long id; + /** + * 分包机构Id + */ + private Long ouId; + + /** + * 分包机构名称 + */ + private String ouName; + /** + * 项目部id + */ + private Long workspaceId; + /** + * 项目部名称 + */ + private String workspaceName; + /** + * 考勤归属项目json数组,可以为null + */ + private Set projectIds; + /** + * 项目内班组id + */ + private Long teamId; + /** + * 小组Id + */ + private Long groupId; + /** + * 用户类型:用户类型: + * 1工人, + * 2从业人员, + * 3突击工 + * 4班组长 + */ + private Integer userType; + /** + * 用户identityId + */ + private Long userId; + /** + * 用户名称 + */ + private String userName; + /** + * 用户手机号 + */ + private String userPhone; + /** + * 用户身份证号 + */ + private String userIdCard; + /** + * 性别:0-未知 1-男 2-女 + */ + private Integer userSex; + /** + * 班组名称 + */ + private String teamName; + /** + * 工种id + */ + private String professionId; + /** + * 工种名称 + */ + private String professionName; + /** + * 岗位名称 + */ + private String jobName; + /** + * 岗位标签码 + */ + private String jobCode; + /** + * personId + */ + private Long personId; + /** + * 本次打卡归属日期(为满足跨夜考勤) + */ + private Date dataDate; + /** + * 打卡时间 + */ + private Date clockAt; + /** + * 设备名称 + */ + private String deviceSn; + + /** + * 设备序列号 + */ + private String deviceName; + /** + * 打卡类型:1进场,2出场,3抓拍 + */ + private Integer clockType; + /** + * 打卡方式:0-闸机 1-电子围栏 2-考勤补卡 + */ + private Integer clockMethod; + /** + * 考勤时的抓拍图片 可能为空未获取到 + */ + private String capturePhoto; + + /** + * 考勤时的抓拍图片key 可能为空未获取到 + */ + private String capturePhotoKey; + /** + * 创建时间 + */ + private Date createAt; + /** + * 修改时间 + */ + private Date updateAt; + /** + * 打卡地址 + */ + private String address; + /** + * 打卡经度 + */ + private BigDecimal longitude; + /** + * 打卡纬度 + */ + private BigDecimal latitude; + + /** + * 企业id + */ + private Long entId; + + /** + * 企业名称 + */ + private String entName; + + /** + * 小组名称 + */ + private String groupName; + + /** + * 小组类型 0-直属小组 1-合作小组 + */ + private Integer groupType; + + /** + * 0:内部部门 1:总包部门 2:建设单位 3:监理单位 4:劳务分包 5:专业分包 + */ + private Integer ouType; + + /** + * 设备位置信息 + */ + private String deviceAddress; + + private String dataSource; + + public boolean isNotPractitioner() { + return !Objects.equals(USER_TYPE_PRACTITIONER, userType); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} From 01e2b0544312dc84c84eb57f8bfb68cc95f168f1 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 5 Mar 2025 14:46:42 +0800 Subject: [PATCH 02/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20?= =?UTF-8?q?=E8=80=83=E5=8B=A4=E8=AE=B0=E5=BD=95API=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../attendance/AttendanceRecordClient.java | 23 ++++++ .../dto/AttendanceClockRecordListReq.java | 71 +++++++++++++++++++ .../dto/AttendanceClockRecordResp.java | 53 ++++++++++++++ orgmanax-integration/pom.xml | 6 ++ .../AttendanceRecordClientImpl.java | 39 ++++++++++ 5 files changed, 192 insertions(+) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/AttendanceRecordClient.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordListReq.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordResp.java create mode 100644 orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/attendance/AttendanceRecordClientImpl.java diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/AttendanceRecordClient.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/AttendanceRecordClient.java new file mode 100644 index 0000000..a7cd6c2 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/AttendanceRecordClient.java @@ -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 listClockRecords(AttendanceClockRecordListReq request); +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordListReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordListReq.java new file mode 100644 index 0000000..36d46df --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordListReq.java @@ -0,0 +1,71 @@ +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 { + + /** + * 项目部id - 必传 + */ + @NonNull + private Long workspaceId; + + /** + * personId列表 + */ + private List personIds; + + /** + * 用户类型:用户类型: + * 1工人, + * 2从业人员, + * 4班组长 + */ + private Integer userType; + + /** + * 班组id集合 + */ + private List 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); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordResp.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordResp.java new file mode 100644 index 0000000..beae051 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordResp.java @@ -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); + } +} diff --git a/orgmanax-integration/pom.xml b/orgmanax-integration/pom.xml index 1e42e50..285fc7e 100644 --- a/orgmanax-integration/pom.xml +++ b/orgmanax-integration/pom.xml @@ -62,6 +62,12 @@ + + + cn.axzo.attendance + attendance-api + ${project.version} + \ No newline at end of file diff --git a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/attendance/AttendanceRecordClientImpl.java b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/attendance/AttendanceRecordClientImpl.java new file mode 100644 index 0000000..dae3662 --- /dev/null +++ b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/attendance/AttendanceRecordClientImpl.java @@ -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 listClockRecords(AttendanceClockRecordListReq request) { + AttendancePersonQueryReq req = new AttendancePersonQueryReq(); + BeanUtils.copyProperties(request, req); + List records = RpcWrapper.commonRes(() -> attendanceRecordApi.listExistAttendancePerson(req)); + return CollUtil.map(records, record -> BeanUtil.copyProperties(record, AttendanceClockRecordResp.class), true); + } +} From e7380710a7df49a91617e25da1ac38b55b24f786 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 5 Mar 2025 16:14:21 +0800 Subject: [PATCH 03/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E7=B3=BB=E7=BB=9FAPI=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/datatagger/DataTagClient.java | 20 ++++++ .../datatagger/dto/DataTagQueryProperty.java | 50 +++++++++++++++ .../datatagger/dto/RevokeDataTagReq.java | 62 +++++++++++++++++++ .../datatagger/enums/DataTagTypeEnum.java | 57 +++++++++++++++++ orgmanax-integration/pom.xml | 10 ++- .../sdk/datatagger/DataTagClientImpl.java | 56 +++++++++++++++++ 6 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/DataTagClient.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagQueryProperty.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/RevokeDataTagReq.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/enums/DataTagTypeEnum.java create mode 100644 orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/datatagger/DataTagClientImpl.java diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/DataTagClient.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/DataTagClient.java new file mode 100644 index 0000000..d43c362 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/DataTagClient.java @@ -0,0 +1,20 @@ +package cn.axzo.orgmanax.infra.client.datatagger; + +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); +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagQueryProperty.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagQueryProperty.java new file mode 100644 index 0000000..f2a47dd --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagQueryProperty.java @@ -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 DataTagQueryProperty { + + /** + * 单位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); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/RevokeDataTagReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/RevokeDataTagReq.java new file mode 100644 index 0000000..22c8948 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/RevokeDataTagReq.java @@ -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 tagCodes; + + /** + * 标签值编码 + */ + private List tagValueCodes; + + /** + * 对象ID + */ + private List objectIds; + + /** + * 查询对象 + */ + @Builder.Default + private DataTagQueryProperty queryProperties = new DataTagQueryProperty(); + + /** + * 严格模式 + */ + private boolean restrictMode = true; + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/enums/DataTagTypeEnum.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/enums/DataTagTypeEnum.java new file mode 100644 index 0000000..3aaa469 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/enums/DataTagTypeEnum.java @@ -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; +} diff --git a/orgmanax-integration/pom.xml b/orgmanax-integration/pom.xml index 285fc7e..4ae327f 100644 --- a/orgmanax-integration/pom.xml +++ b/orgmanax-integration/pom.xml @@ -62,12 +62,20 @@ - + + cn.axzo.attendance attendance-api ${project.version} + + + + cn.axzo.data-tagger + data-tagger-api + 1.0.0-SNAPSHOT + \ No newline at end of file diff --git a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/datatagger/DataTagClientImpl.java b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/datatagger/DataTagClientImpl.java new file mode 100644 index 0000000..5073b1e --- /dev/null +++ b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/datatagger/DataTagClientImpl.java @@ -0,0 +1,56 @@ +package cn.axzo.orgmanax.integration.sdk.datatagger; + +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.common.enums.TagObjectType; +import cn.axzo.orgmanax.infra.client.datatagger.DataTagClient; +import cn.axzo.orgmanax.infra.client.datatagger.dto.DataTagQueryProperty; +import cn.axzo.orgmanax.infra.client.datatagger.dto.RevokeDataTagReq; +import cn.axzo.orgmanax.integration.core.RpcWrapper; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +/** + * @author luofu + * @version 1.0 + * @description 标签系统相关API + * @date 2025/3/5 + */ +@Component +@RequiredArgsConstructor +public class DataTagClientImpl implements DataTagClient { + + private final ObjectTagClient objectTagClient; + + @Override + public boolean revokeDataTags(RevokeDataTagReq request) { + return RpcWrapper.commonRes(() -> objectTagClient.revokeObjectTags(toRevokeRequest(request))); + } + + 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.getQueryProperties())); + return req; + } + + private static ObjectTagQueryProperties toQueryProperties(DataTagQueryProperty queryProperties) { + ObjectTagQueryProperties properties = new ObjectTagQueryProperties(); + // ouId + Optional.ofNullable(queryProperties.getOuId()).ifPresent(properties::setOuId); + // workspaceId + Optional.ofNullable(queryProperties.getWorkspaceId()).ifPresent(properties::setWorkspaceId); + // projectTeamNodeId + Optional.ofNullable(queryProperties.getPlatTeamNodeId()).ifPresent(properties::setPlatTeamNodeId); + // projectTeamNodeId + Optional.ofNullable(queryProperties.getProjectTeamNodeId()).ifPresent(properties::setProjectTeamNodeId); + // groupNodeId + Optional.ofNullable(queryProperties.getGroupNodeId()).ifPresent(properties::setGroupNodeId); + return properties; + } +} From 442d0ef53d2e793b809d3d24bafe800841cfd58f Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 6 Mar 2025 16:29:00 +0800 Subject: [PATCH 04/75] =?UTF-8?q?feat(REQ-3714):=20=E5=BA=95=E5=BA=A7?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4node=5Fuser=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/nodeuser/req/ProcessNodeUserReq.java | 11 +- .../worker/req/ListOrgProjectWorkerReq.java | 43 +++++ .../repository/NodeUserUpsertRepository.java | 2 + .../impl/NodeUserUpsertRepositoryImpl.java | 16 +- .../repository/OrgUserUpsertRepository.java | 11 +- .../impl/OrgUserUpsertRepositoryImpl.java | 14 +- .../worker/dao/OrgProjectWorkerDao.java | 16 ++ .../worker/entity/OrgProjectWorker.java | 148 ++++++++++++++++++ .../worker/mapper/OrgProjectWorkerMapper.java | 10 ++ .../OrgProjectWorkerQueryRepository.java | 100 ++++++++++++ .../OrgProjectWorkerUpsertRepository.java | 13 ++ .../OrgProjectWorkerQueryRepositoryImpl.java | 40 +++++ .../OrgProjectWorkerUpsertRepositoryImpl.java | 28 ++++ ...OrganizationalNodeUserUpsertedPayload.java | 62 ++++++++ .../orgmanax/server/mq/enums/MQEventEnum.java | 65 ++++++++ .../producer/OrgUserChangedEventProducer.java | 71 +++++++++ .../foundation/NodeUserFoundationService.java | 13 +- .../impl/NodeUserFoundationServiceImpl.java | 89 ++++++++++- .../foundation/req/NodeUserDelete.java | 35 +++++ .../foundation/req/NodeUserUnitDelete.java | 34 ++++ .../req/NodeUserWorkspaceDelete.java | 34 ++++ .../impl/UnitDeleteNodeUserProcessor.java | 34 ++++ .../WorkspaceDeleteNodeUserProcessor.java | 32 ++++ .../foundation/OrgUserFoundationService.java | 11 ++ .../impl/OrgUserFoundationServiceImpl.java | 115 ++++++++++++++ .../req/OrgUserWithdrawOrQuitReq.java | 26 +++ .../OrgProjectWorkerFoundationService.java | 10 ++ ...OrgProjectWorkerFoundationServiceImpl.java | 52 ++++++ .../req/OrgProjectWorkerWithdrawReq.java | 20 +++ .../server/service/OperateLogService.java | 51 ++++++ 30 files changed, 1189 insertions(+), 17 deletions(-) create mode 100644 orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/project/worker/req/ListOrgProjectWorkerReq.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/dao/OrgProjectWorkerDao.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/entity/OrgProjectWorker.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/mapper/OrgProjectWorkerMapper.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerQueryRepository.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerUpsertRepository.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/impl/OrgProjectWorkerQueryRepositoryImpl.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/impl/OrgProjectWorkerUpsertRepositoryImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/OrganizationalNodeUserUpsertedPayload.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/enums/MQEventEnum.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserUnitDelete.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/UnitDeleteNodeUserProcessor.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/WorkspaceDeleteNodeUserProcessor.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/OrgUserFoundationService.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/req/OrgUserWithdrawOrQuitReq.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/OrgProjectWorkerFoundationService.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/req/OrgProjectWorkerWithdrawReq.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/service/OperateLogService.java diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ProcessNodeUserReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ProcessNodeUserReq.java index 893820c..9f72966 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ProcessNodeUserReq.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ProcessNodeUserReq.java @@ -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,9 @@ public class ProcessNodeUserReq { @Getter public enum Action { CREATE("创建", "createNodeUserProcessor"), - UPDATE("普通更新", "updateNodeUserProcessor"); + UPDATE("普通更新", "updateNodeUserProcessor"), + UNIT_DELETE("删除单位人员", "unitDeleteNodeUserProcessor"), + WORKSPACE_DELETE("删除项目人员", "workspaceDeleteNodeUserProcessor"); private final String desc; private final String processor; diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/project/worker/req/ListOrgProjectWorkerReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/project/worker/req/ListOrgProjectWorkerReq.java new file mode 100644 index 0000000..b3a434e --- /dev/null +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/project/worker/req/ListOrgProjectWorkerReq.java @@ -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 workerPersonIds; + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserUpsertRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserUpsertRepository.java index 9796e77..2e76d83 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserUpsertRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserUpsertRepository.java @@ -18,6 +18,8 @@ public interface NodeUserUpsertRepository { OrganizationalNodeUser update(UpdateReq node); + void batchDelete(Set ids); + @EqualsAndHashCode(callSuper = true) @NoArgsConstructor @AllArgsConstructor diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserUpsertRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserUpsertRepositoryImpl.java index 91ea35c..294eeff 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserUpsertRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserUpsertRepositoryImpl.java @@ -5,11 +5,15 @@ 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.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.Set; + @Service @RequiredArgsConstructor @Slf4j @@ -32,4 +36,14 @@ public class NodeUserUpsertRepositoryImpl implements NodeUserUpsertRepository { wrapper.update(req); return nodeUserDao.getById(req.getId()); } -} + + @Override + public void batchDelete(Set 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(); + } + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/OrgUserUpsertRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/OrgUserUpsertRepository.java index b29379f..4bba255 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/OrgUserUpsertRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/OrgUserUpsertRepository.java @@ -1,4 +1,13 @@ 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; + public interface OrgUserUpsertRepository { -} + + @Transactional(rollbackFor = Throwable.class) + void batchUpdate(List orgUsers); + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserUpsertRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserUpsertRepositoryImpl.java index 8fdc804..7975b88 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserUpsertRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserUpsertRepositoryImpl.java @@ -1,10 +1,22 @@ 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 lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import java.util.List; + @Service @RequiredArgsConstructor public class OrgUserUpsertRepositoryImpl implements OrgUserUpsertRepository { -} + + private final OrgUserDao orgUserDao; + + @Override + public void batchUpdate(List orgUsers) { + orgUserDao.updateBatchById(orgUsers); + } + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/dao/OrgProjectWorkerDao.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/dao/OrgProjectWorkerDao.java new file mode 100644 index 0000000..abda69e --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/dao/OrgProjectWorkerDao.java @@ -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 { + + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/entity/OrgProjectWorker.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/entity/OrgProjectWorker.java new file mode 100644 index 0000000..48fbbd9 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/entity/OrgProjectWorker.java @@ -0,0 +1,148 @@ +package cn.axzo.orgmanax.infra.dao.project.worker.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +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; + + + @TableField("id") + 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; + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/mapper/OrgProjectWorkerMapper.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/mapper/OrgProjectWorkerMapper.java new file mode 100644 index 0000000..cd829fb --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/mapper/OrgProjectWorkerMapper.java @@ -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 { + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerQueryRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerQueryRepository.java new file mode 100644 index 0000000..0016707 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerQueryRepository.java @@ -0,0 +1,100 @@ +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 page(ListReq req); + + default List list(ListReq req) { + return page(req).getData(); + } + + default OrgProjectWorkerResp one(OneReq req) { + return oneOpt(req).orElse(null); + } + + default Optional 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 ids; + + public void check() { + Preconditions.checkArgument(id != null || CollUtil.isNotEmpty(ids), "参数异常"); + } + } + + @EqualsAndHashCode(callSuper = true) + @NoArgsConstructor + @AllArgsConstructor + @Data + @SuperBuilder + class ListReq extends PageReqV2 { + + /** + * 工作台ID + */ + @CriteriaField + private Long workspaceId; + + /** + * 所属单位id + */ + @CriteriaField + private Long organizationalUnitId; + + /** + * 状态 + */ + @CriteriaField + private Integer status; + + /** + * 工人personId + */ + @CriteriaField(field = "workerPersonId", operator = Operator.IN) + private List workerPersonIds; + + @CriteriaField(ignore = true) + private Boolean includeDeleted; + } + + @EqualsAndHashCode(callSuper = true) + @NoArgsConstructor + @AllArgsConstructor + @Data + @SuperBuilder + class OrgProjectWorkerResp extends OrgProjectWorker { + + // 按需扩展字段,占个位。避免报错 + private String todo; + } + +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerUpsertRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerUpsertRepository.java new file mode 100644 index 0000000..66f23bb --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerUpsertRepository.java @@ -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 orgProjectWorkers); + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/impl/OrgProjectWorkerQueryRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/impl/OrgProjectWorkerQueryRepositoryImpl.java new file mode 100644 index 0000000..b381d3d --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/impl/OrgProjectWorkerQueryRepositoryImpl.java @@ -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 page(ListReq req) { + IPage page = PageConverter.toMybatis(req, OrgProjectWorker.class); + QueryWrapper wrapper = QueryWrapperHelper.fromBean(req, OrgProjectWorker.class); + if (!BooleanUtil.isTrue(req.getIncludeDeleted())) { + wrapper.eq("is_delete", 0); + } + IPage results = orgProjectWorkerDao.page(page, wrapper) + .convert(e -> BeanUtil.toBean(e, OrgProjectWorkerQueryRepository.OrgProjectWorkerResp.class)); + return (PageResp) PageConverter.toResp(results); + } + +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/impl/OrgProjectWorkerUpsertRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/impl/OrgProjectWorkerUpsertRepositoryImpl.java new file mode 100644 index 0000000..beacbcb --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/impl/OrgProjectWorkerUpsertRepositoryImpl.java @@ -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 orgProjectWorkers) { + orgProjectWorkerDao.updateBatchById(orgProjectWorkers); + } + +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/OrganizationalNodeUserUpsertedPayload.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/OrganizationalNodeUserUpsertedPayload.java new file mode 100644 index 0000000..ce8897b --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/OrganizationalNodeUserUpsertedPayload.java @@ -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(); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/enums/MQEventEnum.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/enums/MQEventEnum.java new file mode 100644 index 0000000..8162b29 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/enums/MQEventEnum.java @@ -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 事件会将 old,new发出来 + 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; + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java new file mode 100644 index 0000000..648aeb3 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java @@ -0,0 +1,71 @@ +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 cn.hutool.extra.spring.SpringUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.Objects; + +/** + * @author luofu + * @version 1.0 + * @date 2024/10/31 + */ +@Slf4j +@Component +public class OrgUserChangedEventProducer implements InitializingBean { + + private static final String EVENT_INVALID = "the event is invalid. {}"; + + private static EventProducer eventProducer; + + public static void sendStatusEvent(OrgUserStatusChangedEvent event) { + if (isInvalid(event)) { + log.info(EVENT_INVALID, event); + return; + } + //生产消息 + eventProducer.send(map(event)); + } + + public static void batchSendStatusEvents(Collection events) { + if (CollUtil.isEmpty(events)) { + log.info("the events is empty."); + return; + } + events.forEach(OrgUserChangedEventProducer::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())) + .targetType(mqEvent.getModel()) + .eventCode(mqEvent.getEventCode()) + .data(event) + .build(); + } + + @Override + public void afterPropertiesSet() throws Exception { + eventProducer = SpringUtil.getBean(EventProducer.class); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java index 5ee1cc3..ee98c9e 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java @@ -1,12 +1,10 @@ package cn.axzo.orgmanax.server.nodeuser.foundation; -import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO; import cn.axzo.orgmanax.dto.nodeuser.req.SearchEntNodeUserReq; import cn.axzo.orgmanax.dto.nodeuser.resp.SearchEntNodeUserResp; import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser; -import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository; -import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJob; 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 +30,15 @@ public interface NodeUserFoundationService { @Transactional(rollbackFor = Throwable.class) OrganizationalNodeUser update(NodeUserUpdate req); + /** + * 该接口为更新的收口接口,业务使用的时候,需要自行做业务判断 + * + * @param req + * @return + */ + @Transactional(rollbackFor = Throwable.class) + List delete(NodeUserDelete req); + /** * 根据岗位进行过滤 * @param nodeUsers diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index 771752b..b147285 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -1,15 +1,19 @@ 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.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; @@ -20,21 +24,30 @@ import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository; import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserUpsertRepository; import cn.axzo.orgmanax.infra.dao.orgjob.entity.OrgJob; 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.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 +65,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 +158,71 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService return nodeUserUpsertRepository.update(updateReq); } + @Override + public List delete(NodeUserDelete req) { + checkDeleteReq(req); + List list = nodeUserQueryRepository.list(NodeUserQueryRepository.ListReq.builder().organizationalUnitId(req.getOuId()) + .workspaceId(req.getWorkspaceId()).personIds(req.getPersonIds()).build()); + if (CollUtil.isEmpty(list)) { + return CollUtil.newArrayList(); + } + //批量删除node_user + nodeUserUpsertRepository.batchDelete(list.stream().map(NodeUserQueryRepository.NodeUserResp::getId).collect(Collectors.toSet())); + List nodeUserList = list.stream().map(e -> BeanUtil.toBean(e, OrganizationalNodeUser.class)).collect(Collectors.toList()); + nodeUserList.forEach(this::sendNodeUserDeleteMq); + + //处理orgUser退场或离职逻辑 + Map> 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.setOuId(req.getOuId()); + if (req.isUnitDelete()) { + quitReq.setWorkspaceId(nodeUserList.get(0).getWorkspaceId()); + } + quitReq.setTopNodeIdAndPersonIds(quitMap); + orgUserFoundationService.batchWithdrawOrQuit(quitReq); + + //项目内工人退场 + OrgProjectWorkerWithdrawReq workerReq = new OrgProjectWorkerWithdrawReq(); + workerReq.setOuId(req.getOuId()); + workerReq.setWorkspaceId(req.getWorkspaceId()); + if (req.isUnitDelete()) { + 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))); + } + + 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 void filterByJobs(Collection nodeUsers, Collection jobCodes) { List orgJobs = orgJobQueryRepository.list(OrgJobQueryRepository.ListReq.builder() diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java new file mode 100644 index 0000000..2af228e --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java @@ -0,0 +1,35 @@ +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 personIds; + + /** + * 是否企业删除 + */ + private boolean isUnitDelete; + + public OrganizationalNodeUser toEntity() { + return BeanUtil.toBean(this, OrganizationalNodeUser.class); + } + +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserUnitDelete.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserUnitDelete.java new file mode 100644 index 0000000..d5e5863 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserUnitDelete.java @@ -0,0 +1,34 @@ +package cn.axzo.orgmanax.server.nodeuser.foundation.req; + +import cn.axzo.foundation.exception.Axssert; +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 NodeUserUnitDelete { + + private Long ouId; + + private Long operatorId; + + private List personIds; + + public void check() { + Axssert.checkNonNull(operatorId, "操作人不能为空"); + Axssert.checkNonNull(ouId, "单位不能为空"); + Axssert.checkNonNull(personIds, "用户id列表不能都为空"); + } + + public OrganizationalNodeUser toEntity() { + return BeanUtil.toBean(this, OrganizationalNodeUser.class); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java new file mode 100644 index 0000000..688f4f1 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java @@ -0,0 +1,34 @@ +package cn.axzo.orgmanax.server.nodeuser.foundation.req; + +import cn.axzo.foundation.exception.Axssert; +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 NodeUserWorkspaceDelete { + + private Long workspaceId; + + private Long operatorId; + + private List personIds; + + public void check() { + Axssert.checkNonNull(operatorId, "操作人不能为空"); + Axssert.checkNonNull(workspaceId, "项目不能为空"); + Axssert.checkNonNull(personIds, "用户id列表不能都为空"); + } + + public OrganizationalNodeUser toEntity() { + return BeanUtil.toBean(this, OrganizationalNodeUser.class); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/UnitDeleteNodeUserProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/UnitDeleteNodeUserProcessor.java new file mode 100644 index 0000000..6bbb603 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/UnitDeleteNodeUserProcessor.java @@ -0,0 +1,34 @@ +package cn.axzo.orgmanax.server.nodeuser.service.processor.impl; + +import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser; +import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; +import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete; +import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 删除单位人员 + */ +@Component +@Slf4j +@RequiredArgsConstructor +public class UnitDeleteNodeUserProcessor implements NodeUserProcessor { + + private final NodeUserFoundationService nodeUserFoundationService; + + @Override + public ProcessResult process(ProcessContext context) { + // 转成该处理器关注的参数对象 + NodeUserDelete nodeUserDelete = context.getParams().toJavaObject(NodeUserDelete.class); + nodeUserDelete.setUnitDelete(true); + List nodeUserList = nodeUserFoundationService.delete(nodeUserDelete); + + // 返回数据 + return ProcessResult.success((JSONObject) JSONObject.toJSON(nodeUserList)); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/WorkspaceDeleteNodeUserProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/WorkspaceDeleteNodeUserProcessor.java new file mode 100644 index 0000000..ddb0408 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/WorkspaceDeleteNodeUserProcessor.java @@ -0,0 +1,32 @@ +package cn.axzo.orgmanax.server.nodeuser.service.processor.impl; + +import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser; +import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; +import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete; +import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * 删除项目人员 + */ +@Component +@Slf4j +@RequiredArgsConstructor +public class WorkspaceDeleteNodeUserProcessor implements NodeUserProcessor { + private final NodeUserFoundationService nodeUserFoundationService; + + @Override + public ProcessResult process(ProcessContext context) { + // 转成该处理器关注的参数对象 + NodeUserDelete nodeUserDelete = context.getParams().toJavaObject(NodeUserDelete.class); + List nodeUserList = nodeUserFoundationService.delete(nodeUserDelete); + + // 返回数据 + return ProcessResult.success((JSONObject) JSONObject.toJSON(nodeUserList)); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/OrgUserFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/OrgUserFoundationService.java new file mode 100644 index 0000000..f011c51 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/OrgUserFoundationService.java @@ -0,0 +1,11 @@ +package cn.axzo.orgmanax.server.orguser.foundation; + +import cn.axzo.orgmanax.server.orguser.foundation.req.OrgUserWithdrawOrQuitReq; +import org.springframework.transaction.annotation.Transactional; + +public interface OrgUserFoundationService { + + @Transactional(rollbackFor = Throwable.class) + void batchWithdrawOrQuit(OrgUserWithdrawOrQuitReq req); + +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java new file mode 100644 index 0000000..8e16d83 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java @@ -0,0 +1,115 @@ +package cn.axzo.orgmanax.server.orguser.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.orgmanax.dto.nodeuser.enums.OrgUserStatusEnum; +import cn.axzo.orgmanax.dto.orguser.dto.OrgUserDTO; +import cn.axzo.orgmanax.dto.orguser.event.OrgUserStatusChangedEvent; +import cn.axzo.orgmanax.dto.orguser.req.ListOrgUserReq; +import cn.axzo.orgmanax.infra.client.workspace.WorkspaceGateway; +import cn.axzo.orgmanax.infra.client.workspace.dto.Workspace; +import cn.axzo.orgmanax.infra.dao.orguser.entity.OrgUser; +import cn.axzo.orgmanax.infra.dao.orguser.repository.OrgUserQueryRepository; +import cn.axzo.orgmanax.infra.dao.orguser.repository.OrgUserUpsertRepository; +import cn.axzo.orgmanax.server.mq.producer.OrgUserChangedEventProducer; +import cn.axzo.orgmanax.server.orguser.foundation.OrgUserFoundationService; +import cn.axzo.orgmanax.server.orguser.foundation.req.OrgUserWithdrawOrQuitReq; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Pair; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2025/3/6 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { + + private final WorkspaceGateway workspaceGateway; + private final OrgUserQueryRepository orgUserQueryRepository; + private final OrgUserUpsertRepository orgUserUpsertRepository; + + @Override + public void batchWithdrawOrQuit(OrgUserWithdrawOrQuitReq req) { + OrgUserStatusEnum status; + if (req.isUnitUpdate()) { + WorkspaceDetailReq workspaceDetailReq = new WorkspaceDetailReq(); + workspaceDetailReq.setId(req.getWorkspaceId()); + WorkspaceDetailResp detail = workspaceGateway.getDetail(workspaceDetailReq); + status = Integer.valueOf(Workspace.WorkspaceTypeEnum.GENERAL_PROJECT.value).equals(detail.getWorkspaceType()) ? + OrgUserStatusEnum.WITHDRAW : OrgUserStatusEnum.QUIT; + } else { + status = OrgUserStatusEnum.WITHDRAW; + } + ListOrgUserReq listOrgUserReq = new ListOrgUserReq(); + listOrgUserReq.setOuId(req.getOuId()); + listOrgUserReq.setWorkspaceId(req.getWorkspaceId()); + Set personIds = req.getTopNodeIdAndPersonIds().values().stream().flatMap(Set::stream).collect(Collectors.toSet()); + listOrgUserReq.setPersonIds(personIds); + List list = orgUserQueryRepository.list(listOrgUserReq); + if (CollUtil.isEmpty(list)) { + return; + } + Pair operator = Pair.of(-1L, "系统"); + Date now = new Date(); + List orgUsers = list.stream().map(orgUserResp -> { + OrgUser orgUser = new OrgUser(); + orgUser.setId(orgUserResp.getId()); + orgUser.setOperatorId(operator.getKey()); + orgUser.setOperatorName(operator.getValue()); + orgUser.setTransferTime(now); + orgUser.setStatus(status.getCode()); + return orgUser; + }).collect(Collectors.toList()); + orgUserUpsertRepository.batchUpdate(orgUsers); + Map orgUserMap = orgUsers.stream().collect(Collectors.toMap(OrgUser::getPersonId, orgUser -> orgUser)); + for (Map.Entry> setEntry : req.getTopNodeIdAndPersonIds().entrySet()) { + Long topNodeId = setEntry.getKey(); + Set personIdSet = setEntry.getValue(); + List orgUserList = orgUserMap.entrySet().stream() + .filter(personIdOrgUserEntry -> personIdSet.contains(personIdOrgUserEntry.getKey())) + .map(Map.Entry::getValue).collect(Collectors.toList()); + List dtoList = CollUtil.map(orgUsers, this::toOrgUserDTO, true); + // 发送用户状态变更事件 + batchSendStatusEvents(dtoList, topNodeId); + } + } + + private void batchSendStatusEvents(Collection orgUsers, Long topNodeId) { + if (CollUtil.isEmpty(orgUsers)) { + return; + } + // 事务提交之后发送MQ + Function eventMapper = e -> toOrgUserStatusChangedEvent(e, topNodeId); + List events = CollUtil.map(orgUsers, eventMapper, true); + OrgUserChangedEventProducer.batchSendStatusEvents(events); + } + + public static OrgUserStatusChangedEvent toOrgUserStatusChangedEvent(OrgUserDTO orgUser, Long topNodeId) { + return OrgUserStatusChangedEvent.builder() + .personId(orgUser.getPersonId()) + .ouId(orgUser.getOuId()) + .workspaceId(orgUser.getWorkspaceId()) + .topNodeId(topNodeId) + .statusCode(orgUser.getStatus()) + .transferTimestamp(orgUser.getTransferTime().getTime()) + .operatorId(orgUser.getOperatorId()) + .build(); + } + + private OrgUserDTO toOrgUserDTO(OrgUser orgUser) { + OrgUserDTO dto = OrgUserDTO.builder().build(); + BeanUtils.copyProperties(orgUser, dto); + return dto; + } + +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/req/OrgUserWithdrawOrQuitReq.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/req/OrgUserWithdrawOrQuitReq.java new file mode 100644 index 0000000..4745578 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/req/OrgUserWithdrawOrQuitReq.java @@ -0,0 +1,26 @@ +package cn.axzo.orgmanax.server.orguser.foundation.req; + +import lombok.Data; + +import java.util.Map; +import java.util.Set; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2025/3/6 + */ +@Data +public class OrgUserWithdrawOrQuitReq { + + private Long ouId; + + private Long workspaceId; + + private Map> topNodeIdAndPersonIds; + + /** + * 是否单位更新 + */ + private boolean isUnitUpdate; + +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/OrgProjectWorkerFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/OrgProjectWorkerFoundationService.java new file mode 100644 index 0000000..2291a9c --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/OrgProjectWorkerFoundationService.java @@ -0,0 +1,10 @@ +package cn.axzo.orgmanax.server.project.worker.foundation; + +import cn.axzo.orgmanax.server.project.worker.foundation.req.OrgProjectWorkerWithdrawReq; +import org.springframework.transaction.annotation.Transactional; + +public interface OrgProjectWorkerFoundationService { + + @Transactional(rollbackFor = Throwable.class) + void batchWithdraw(OrgProjectWorkerWithdrawReq req); +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java new file mode 100644 index 0000000..ea60426 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java @@ -0,0 +1,52 @@ +package cn.axzo.orgmanax.server.project.worker.foundation.impl; + +import cn.axzo.orgmanax.dto.project.worker.enums.ProjectWorkerStatusEnum; +import cn.axzo.orgmanax.infra.dao.project.worker.entity.OrgProjectWorker; +import cn.axzo.orgmanax.infra.dao.project.worker.repositrory.OrgProjectWorkerQueryRepository; +import cn.axzo.orgmanax.infra.dao.project.worker.repositrory.OrgProjectWorkerUpsertRepository; +import cn.axzo.orgmanax.server.project.worker.foundation.OrgProjectWorkerFoundationService; +import cn.axzo.orgmanax.server.project.worker.foundation.req.OrgProjectWorkerWithdrawReq; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2025/3/6 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class OrgProjectWorkerFoundationServiceImpl implements OrgProjectWorkerFoundationService { + + private final OrgProjectWorkerQueryRepository orgProjectWorkerQueryRepository; + private final OrgProjectWorkerUpsertRepository orgProjectWorkerUpsertRepository; + + @Override + public void batchWithdraw(OrgProjectWorkerWithdrawReq req) { + OrgProjectWorkerQueryRepository.ListReq listReq = new OrgProjectWorkerQueryRepository.ListReq(); + listReq.setOrganizationalUnitId(req.getOuId()); + listReq.setWorkspaceId(req.getWorkspaceId()); + listReq.setWorkerPersonIds(req.getPersonIds()); + listReq.setStatus(ProjectWorkerStatusEnum.ACTIVE.getValue()); + List projectWorkerResps = orgProjectWorkerQueryRepository.list(listReq); + if (CollUtil.isEmpty(projectWorkerResps)) { + return; + } + Date now = new Date(); + List orgProjectWorkers = projectWorkerResps.stream().map(e -> { + OrgProjectWorker orgProjectWorker = BeanUtil.toBean(e, OrgProjectWorker.class); + e.setStatus(ProjectWorkerStatusEnum.WITHDRAW.getValue()); + e.setResignAt(now); + e.setUpdateAt(now); + return orgProjectWorker; + }).collect(Collectors.toList()); + orgProjectWorkerUpsertRepository.batchUpdate(orgProjectWorkers); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/req/OrgProjectWorkerWithdrawReq.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/req/OrgProjectWorkerWithdrawReq.java new file mode 100644 index 0000000..08a24e8 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/req/OrgProjectWorkerWithdrawReq.java @@ -0,0 +1,20 @@ +package cn.axzo.orgmanax.server.project.worker.foundation.req; + +import lombok.Data; + +import java.util.List; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2025/3/6 + */ +@Data +public class OrgProjectWorkerWithdrawReq { + + private Long ouId; + + private Long workspaceId; + + private List personIds; + +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/service/OperateLogService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/service/OperateLogService.java new file mode 100644 index 0000000..f79411d --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/service/OperateLogService.java @@ -0,0 +1,51 @@ +package cn.axzo.orgmanax.server.service; + +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.Preconditions; +import lombok.*; + +public interface OperateLogService { + /** + * 保存操作日志 + * + * @return + */ + void save(SaveParam param); + + @NoArgsConstructor + @Data + @Builder + @AllArgsConstructor + class SaveParam { + private static final Long UNKNOWN_OPERATOR_ID = -1L; + private Long operatorId; + private String operatorName; + private String apiCaller; + private Long resourceId; + private ResourceType resourceType; + private OperateType operateType; + private Object oldValue; + private Object newValue; + private String summary; + private JSONObject ext; + + public void check() { + Preconditions.checkArgument(resourceType != null && resourceId != null, "操作资源类型和资源id不能为空"); + } + } + + @Getter + @AllArgsConstructor(access = AccessLevel.PRIVATE) + enum ResourceType { + ORGANIZATIONAL_UNIT("organizational_unit", "单位"), + ORGANIZATIONAL_NODE("organizational_node", "部门"), + ORGANIZATIONAL_NODE_USER("organizational_node_user", "部门人员"), + SAAS_COOPERATE_SHIP("saas_cooperate_ship", "协同关系"); + private final String tableName; + private final String desc; + } + + enum OperateType { + ADD, UPDATE, DELETE; + } +} From 230b2fc6b253686f4b617f15a01c1d60a4024e4f Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 6 Mar 2025 19:04:16 +0800 Subject: [PATCH 05/75] =?UTF-8?q?feat(REQ-3714):=20=E5=BA=95=E5=BA=A7?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E6=8E=A5=E5=8F=A3=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/feign/OrgNodeUserCheckApi.java | 41 +++++++++++++++++++ .../req/BatchDeleteNodeUserCheckReq.java | 30 ++++++++++++++ .../resp/BatchDeleteNodeUserCheckResp.java | 25 +++++++++++ .../OrgNodeUserCheckController.java | 32 +++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 orgmanax-api/src/main/java/cn/axzo/orgmanax/api/nodeuser/feign/OrgNodeUserCheckApi.java create mode 100644 orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java create mode 100644 orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/OrgNodeUserCheckController.java diff --git a/orgmanax-api/src/main/java/cn/axzo/orgmanax/api/nodeuser/feign/OrgNodeUserCheckApi.java b/orgmanax-api/src/main/java/cn/axzo/orgmanax/api/nodeuser/feign/OrgNodeUserCheckApi.java new file mode 100644 index 0000000..12901b8 --- /dev/null +++ b/orgmanax-api/src/main/java/cn/axzo/orgmanax/api/nodeuser/feign/OrgNodeUserCheckApi.java @@ -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> checkUnit(@RequestBody @Validated BatchDeleteNodeUserCheckReq req); + + /** + * 根据条件聚合查询节点用户 + * + * @param req + * @return + */ + @PostMapping("/api/node-user/batchDelete/check/workspace") + ApiResult> checkWorkspace(@RequestBody @Validated BatchDeleteNodeUserCheckReq req); +} diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java new file mode 100644 index 0000000..b155739 --- /dev/null +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java @@ -0,0 +1,30 @@ +package cn.axzo.orgmanax.dto.nodeuser.req; + +import lombok.Data; + +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2025/3/6 + */ +@Data +public class BatchDeleteNodeUserCheckReq { + + /** + * personIds + */ + @NotNull(message = "personIds不可以为空!") + private List personIds; + + private Long workspaceId; + + private Long ouId; + + /** + * 删除项目人员的时候传入 + * 节点ID + */ + private Long nodeId; +} diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java new file mode 100644 index 0000000..5b0b3a4 --- /dev/null +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java @@ -0,0 +1,25 @@ +package cn.axzo.orgmanax.dto.nodeuser.resp; + +import lombok.Data; + +import java.util.List; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2025/3/6 + */ +@Data +public class BatchDeleteNodeUserCheckResp { + + private Long personId; + + private List failInfos; + + @Data + public static class CheckFailInfo { + + private Integer type; + + private Integer count; + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/OrgNodeUserCheckController.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/OrgNodeUserCheckController.java new file mode 100644 index 0000000..0b98c20 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/OrgNodeUserCheckController.java @@ -0,0 +1,32 @@ +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 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 OrgNodeUserCheckController implements OrgNodeUserCheckApi { + + + @Override + public ApiResult> checkUnit(BatchDeleteNodeUserCheckReq req) { + return null; + } + + @Override + public ApiResult> checkWorkspace(BatchDeleteNodeUserCheckReq req) { + return null; + } +} \ No newline at end of file From 346d99646e50acba477c4fdc526e467b1c97e0b1 Mon Sep 17 00:00:00 2001 From: "honghao.zhang" Date: Fri, 7 Mar 2025 00:08:10 +0800 Subject: [PATCH 06/75] =?UTF-8?q?feat(REQ-3714):=20=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E5=8D=95=E4=BD=8D=E9=98=BB=E6=96=AD=E6=A0=A1=E9=AA=8C=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/nodeuser/enums/CheckInfoTypeEnum.java | 17 ++ .../req/BatchDeleteNodeUserCheckReq.java | 8 +- .../resp/BatchDeleteNodeUserCheckResp.java | 3 +- .../client/workspace/WorkspaceGateway.java | 13 ++ ...ller.java => NodeUserCheckController.java} | 8 +- .../impl/NodeUserFoundationServiceImpl.java | 5 +- .../foundation/req/NodeUserDelete.java | 5 + .../service/NodeUserCheckService.java | 13 ++ .../impl/NodeUserCheckServiceImpl.java | 190 ++++++++++++++++++ 9 files changed, 255 insertions(+), 7 deletions(-) create mode 100644 orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java rename orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/{OrgNodeUserCheckController.java => NodeUserCheckController.java} (71%) create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/NodeUserCheckService.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java new file mode 100644 index 0000000..a75c4b3 --- /dev/null +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java @@ -0,0 +1,17 @@ +package cn.axzo.orgmanax.dto.nodeuser.enums; + +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public enum CheckInfoTypeEnum { + + SUPER_ADMIN(1, "超级管理员"), + IN_PROJECT(2, "在项目中"), + TEAM_LEADER(3, "班组长"); + + private final Integer value; + private final String desc; +} diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java index b155739..ccb36b2 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java @@ -4,6 +4,7 @@ import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; +import java.util.Set; /** * @author : zhanghonghao@axzo.cn @@ -16,7 +17,7 @@ public class BatchDeleteNodeUserCheckReq { * personIds */ @NotNull(message = "personIds不可以为空!") - private List personIds; + private Set personIds; private Long workspaceId; @@ -27,4 +28,9 @@ public class BatchDeleteNodeUserCheckReq { * 节点ID */ private Long nodeId; + + /** + * 操作者ID + */ + private Long operatorId; } diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java index 5b0b3a4..a109440 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java @@ -1,5 +1,6 @@ package cn.axzo.orgmanax.dto.nodeuser.resp; +import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum; import lombok.Data; import java.util.List; @@ -18,7 +19,7 @@ public class BatchDeleteNodeUserCheckResp { @Data public static class CheckFailInfo { - private Integer type; + private CheckInfoTypeEnum type; private Integer count; } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workspace/WorkspaceGateway.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workspace/WorkspaceGateway.java index 5fa8f27..3ffa262 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workspace/WorkspaceGateway.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workspace/WorkspaceGateway.java @@ -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; @@ -15,6 +18,7 @@ import org.springframework.stereotype.Component; import java.util.List; /** + * */ @RequiredArgsConstructor @Component @@ -23,8 +27,11 @@ public class WorkspaceGateway { private final WorkspaceV2Api workspaceV2Api; + private final ParticipatingUnitV2Api participatingUnitV2Api; + /** * 更新和新增 + * * @param request * @return */ @@ -34,6 +41,7 @@ public class WorkspaceGateway { /** * 获取详情 + * * @param request * @return */ @@ -43,10 +51,15 @@ public class WorkspaceGateway { /** * 获取详情 + * * @param request * @return */ public List list(ListWorkspaceReq request) { return RpcWrapper.wrapApiResult(() -> workspaceV2Api.listV2(request)); } + + public List listParticipatingUnits(ParticipatingUnitListReq unitListReq) { + return RpcWrapper.wrapApiResult(() -> participatingUnitV2Api.list(unitListReq)); + } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/OrgNodeUserCheckController.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/NodeUserCheckController.java similarity index 71% rename from orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/OrgNodeUserCheckController.java rename to orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/NodeUserCheckController.java index 0b98c20..cdcddc2 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/OrgNodeUserCheckController.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/controller/NodeUserCheckController.java @@ -4,6 +4,7 @@ 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; @@ -17,16 +18,17 @@ import java.util.List; @RestController @RequestMapping @RequiredArgsConstructor -public class OrgNodeUserCheckController implements OrgNodeUserCheckApi { +public class NodeUserCheckController implements OrgNodeUserCheckApi { + private final NodeUserCheckService nodeUserCheckService; @Override public ApiResult> checkUnit(BatchDeleteNodeUserCheckReq req) { - return null; + return ApiResult.success(nodeUserCheckService.checkUnit(req)); } @Override public ApiResult> checkWorkspace(BatchDeleteNodeUserCheckReq req) { - return null; + return ApiResult.success(nodeUserCheckService.checkWorkspace(req)); } } \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index b147285..1b5246d 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -161,8 +161,9 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService @Override public List delete(NodeUserDelete req) { checkDeleteReq(req); - List list = nodeUserQueryRepository.list(NodeUserQueryRepository.ListReq.builder().organizationalUnitId(req.getOuId()) - .workspaceId(req.getWorkspaceId()).personIds(req.getPersonIds()).build()); + List list = nodeUserQueryRepository.list( + NodeUserQueryRepository.ListReq.builder().organizationalUnitId(req.getOuId()) + .workspaceId(req.getWorkspaceId()).personIds(req.getPersonIds()).identityType(req.getIdentityType()).build()); if (CollUtil.isEmpty(list)) { return CollUtil.newArrayList(); } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java index 2af228e..689f1f4 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java @@ -28,6 +28,11 @@ public class NodeUserDelete { */ private boolean isUnitDelete; + /** + * 身份类型 按照项目删除的时候 传 + */ + private Integer identityType; + public OrganizationalNodeUser toEntity() { return BeanUtil.toBean(this, OrganizationalNodeUser.class); } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/NodeUserCheckService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/NodeUserCheckService.java new file mode 100644 index 0000000..fcc1211 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/NodeUserCheckService.java @@ -0,0 +1,13 @@ +package cn.axzo.orgmanax.server.nodeuser.service; + +import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq; +import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp; + +import java.util.List; + +public interface NodeUserCheckService { + + List checkUnit(BatchDeleteNodeUserCheckReq req); + + List checkWorkspace(BatchDeleteNodeUserCheckReq req); +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java new file mode 100644 index 0000000..9af7e32 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -0,0 +1,190 @@ +package cn.axzo.orgmanax.server.nodeuser.service.impl; + +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.basics.common.exception.ServiceException; +import cn.axzo.basics.common.util.NumberUtil; +import cn.axzo.foundation.exception.Axssert; +import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.orgmanax.dto.cooperateship.dto.OrgCooperateShipDTO; +import cn.axzo.orgmanax.dto.cooperateship.req.ListOrgCooperateShipReq; +import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO; +import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum; +import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq; +import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq; +import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp; +import cn.axzo.orgmanax.infra.client.profile.PersonProfileGateway; +import cn.axzo.orgmanax.infra.client.profile.dto.model.PersonProfileDto; +import cn.axzo.orgmanax.infra.client.tyr.RoleUserGateway; +import cn.axzo.orgmanax.infra.client.workspace.WorkspaceGateway; +import cn.axzo.orgmanax.infra.client.workspace.dto.Workspace; +import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip; +import cn.axzo.orgmanax.server.cooperateship.service.CooperateShipService; +import cn.axzo.orgmanax.server.nodeuser.service.NodeUserCheckService; +import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService; +import cn.axzo.tyr.feign.enums.IdentityTypeEnum; +import cn.axzo.tyr.feign.enums.RoleTypeEnum; +import cn.axzo.tyr.feign.req.PageRoleUserReq; +import cn.axzo.tyr.feign.resp.RoleUserResp; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.BooleanUtil; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; + +@Slf4j +@Service +@RequiredArgsConstructor +public class NodeUserCheckServiceImpl implements NodeUserCheckService { + + private final WorkspaceGateway workspaceGateway; + + private final RoleUserGateway roleUserGateway; + + private final PersonProfileGateway profileGateway; + + private final CooperateShipService cooperateShipService; + + private final NodeUserService nodeUserService; + + // 企业内班组长岗位编码 + @Value("${entTeamLeader:entTeamLeader}") + private String entTeamLeader; + + // 班组管理员岗位编码 + @Value("${entTeamManager:entTeamManager}") + private String entTeamManager; + + // 企业内班组工人岗位编码 + @Value("${entWorker:entWorker}") + private String entWorker; + + + @Override + public List checkUnit(BatchDeleteNodeUserCheckReq req) { + List resultList = new ArrayList<>(); + Map> failInfoMap = new HashMap<>(); + Long ouId = req.getOuId(); + Long workspaceId = req.getWorkspaceId(); + Set personIds = req.getPersonIds(); + ParticipatingUnitListReq participatingUnitListReq = new ParticipatingUnitListReq(); + participatingUnitListReq.setLevels(ListUtil.of(Workspace.WorkspaceTypeEnum.GENERAL_ENT.value, Workspace.WorkspaceTypeEnum.GENERAL_PROJECT.value)); + participatingUnitListReq.setWorkspaceId(workspaceId); + participatingUnitListReq.setOrganizationUnitId(ouId); + List participatingUnitList = workspaceGateway.listParticipatingUnits(participatingUnitListReq); + Axssert.checkNotEmpty(participatingUnitList, "当前单位未参建任何项目,获取详细信息失败"); + Long topNodeId = participatingUnitList.get(0).getOrganizationNodeId(); + //1 单位联系人(超管)不能删除 + PageRoleUserReq param = new PageRoleUserReq(); + PageRoleUserReq.WorkspaceOuPair workspaceOuPair = new PageRoleUserReq.WorkspaceOuPair(); + workspaceOuPair.setWorkspaceId(workspaceId); + workspaceOuPair.setOuId(ouId); + param.setWorkspaceOuPairs(Collections.singletonList(workspaceOuPair)); + param.setRoleTypes(Collections.singleton(RoleTypeEnum.SUPER_ADMIN)); + List superAminInfoResult = roleUserGateway.pageAll(param); + superAminInfoResult.forEach(e -> { + if (personIds.contains(e.getPersonId())) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.SUPER_ADMIN); + addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); + } + }); + + ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); + listOrgCooperateShipReq.setOuIds(Collections.singleton(ouId)); + listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); + List listPersonJoinedWorkspace = cooperateShipService.list(listOrgCooperateShipReq); + Set inProjectPersonIds = filterByPerson(listPersonJoinedWorkspace, personIds); + if (CollectionUtil.isNotEmpty(inProjectPersonIds)) { + inProjectPersonIds.forEach(e -> { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.IN_PROJECT); + addFailInfo(failInfoMap, e, checkFailInfo); + }); + } + + ListNodeUserReq nodeUserQueryVO = new ListNodeUserReq(); + nodeUserQueryVO.setPersonIds(personIds); + nodeUserQueryVO.setOrganizationalUnitId(ouId); + nodeUserQueryVO.setTopNodeIds(Collections.singletonList(topNodeId)); + nodeUserQueryVO.setNeeds(ListNodeUserReq.Needs.builder().job(true).build()); + //查询人所在的部门节点列表 + List organizationalNodeUserList = nodeUserService.list(nodeUserQueryVO); + AtomicBoolean isWorker = new AtomicBoolean(false); + AtomicBoolean isPractitioner = new AtomicBoolean(false); + List teamLeader = Lists.newArrayList(); + List workerOrgNodeIds = Lists.newArrayList(); + organizationalNodeUserList.forEach(organizationalNodeUserVO -> { + if (IdentityTypeEnum.WORKER_LEADER.getCode().equals(organizationalNodeUserVO.getIdentityType()) || + entTeamLeader.equals(organizationalNodeUserVO.getJob().getCode())) { + teamLeader.add(organizationalNodeUserVO.getPersonId()); + } + if (IdentityTypeEnum.WORKER.getCode().equals(organizationalNodeUserVO.getIdentityType()) || + entWorker.equals(organizationalNodeUserVO.getJob().getCode())) { + isWorker.set(true); + workerOrgNodeIds.add(organizationalNodeUserVO.getOrganizationalNodeId()); + } + if (IdentityTypeEnum.PRACTITIONER.getCode().equals(organizationalNodeUserVO.getIdentityType())) { + isPractitioner.set(true); + } + }); + if (CollUtil.isNotEmpty(teamLeader)) { + teamLeader.forEach(e -> { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER); + addFailInfo(failInfoMap, e, checkFailInfo); + }); + } + if (CollUtil.isNotEmpty(failInfoMap)) { + failInfoMap.forEach((personId, checkFailInfos) -> { + BatchDeleteNodeUserCheckResp batchDeleteNodeUserCheckVO = new BatchDeleteNodeUserCheckResp(); + batchDeleteNodeUserCheckVO.setPersonId(personId); + batchDeleteNodeUserCheckVO.setFailInfos(checkFailInfos); + resultList.add(batchDeleteNodeUserCheckVO); + }); + } + return resultList; + } + + private Set filterByPerson(List result, Set personIds) { + if (CollUtil.isEmpty(personIds)) { + return personIds; + } + Set filterResult = new HashSet<>(); + List topNodeIds = result.stream() + .map(OrgCooperateShipDTO::getOrganizationalNodeId) + .distinct() + .collect(Collectors.toList()); + ListNodeUserReq nodeUserReq = new ListNodeUserReq(); + nodeUserReq.setTopNodeIds(topNodeIds); + nodeUserReq.setPersonIds(personIds); + List nodeUserDTOS = nodeUserService.list(nodeUserReq); + Map personNodeMap = nodeUserDTOS.stream().collect(Collectors.toMap(NodeUserDTO::getPersonId, NodeUserDTO::getTopNodeId)); + Set shipNodeIds = result.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).collect(Collectors.toSet()); + for (Map.Entry entry : personNodeMap.entrySet()) { + if (shipNodeIds.contains(entry.getValue())) { + filterResult.add(entry.getKey()); + } + } + return filterResult; + } + + private void addFailInfo(Map> failInfoMap, Long personId, BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo) { + failInfoMap.computeIfAbsent(personId, k -> new ArrayList<>()).add(checkFailInfo); + } + + @Override + public List checkWorkspace(BatchDeleteNodeUserCheckReq req) { + return new ArrayList<>(); + } +} From d911db51664fd9b367956fc303fb2a5121f45efb Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 7 Mar 2025 14:40:29 +0800 Subject: [PATCH 07/75] =?UTF-8?q?feat(REQ-3714):=20=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=BA=E5=91=98=E6=A3=80=E6=9F=A5=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orgmanax/dto/node/dto/OrgNodeDTO.java | 17 + .../dto/nodeuser/enums/CheckInfoTypeEnum.java | 30 +- .../resp/BatchDeleteNodeUserCheckResp.java | 4 + .../client/karma/KarmaThirdApiClient.java | 10 + .../client/karma/ThirdCheckFailResp.java | 17 + .../sdk/karma/KarmaThirdApiClientImpl.java | 50 +++ .../nodeuser/dto/CheckUserOperateParam.java | 30 ++ .../impl/NodeUserCheckServiceImpl.java | 412 ++++++++++++++++-- .../util/constants/JobCodeConstants.java | 34 ++ 9 files changed, 556 insertions(+), 48 deletions(-) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaThirdApiClient.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/ThirdCheckFailResp.java create mode 100644 orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/karma/KarmaThirdApiClientImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/util/constants/JobCodeConstants.java diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/node/dto/OrgNodeDTO.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/node/dto/OrgNodeDTO.java index 81da898..af94bc4 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/node/dto/OrgNodeDTO.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/node/dto/OrgNodeDTO.java @@ -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 @@ -154,4 +157,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; + } } diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java index a75c4b3..fd0a3c9 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java @@ -4,14 +4,34 @@ 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, "超级管理员"), - IN_PROJECT(2, "在项目中"), - TEAM_LEADER(3, "班组长"); - + 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 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); + } + +} \ No newline at end of file diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java index a109440..44cab36 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/resp/BatchDeleteNodeUserCheckResp.java @@ -1,7 +1,9 @@ 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; @@ -17,6 +19,8 @@ public class BatchDeleteNodeUserCheckResp { private List failInfos; @Data + @AllArgsConstructor + @NoArgsConstructor public static class CheckFailInfo { private CheckInfoTypeEnum type; diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaThirdApiClient.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaThirdApiClient.java new file mode 100644 index 0000000..9890002 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/KarmaThirdApiClient.java @@ -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> getThirdCheckFail(Long workspaceId, Set personIds); +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/ThirdCheckFailResp.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/ThirdCheckFailResp.java new file mode 100644 index 0000000..78bc4a3 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/karma/ThirdCheckFailResp.java @@ -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; + +} \ No newline at end of file diff --git a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/karma/KarmaThirdApiClientImpl.java b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/karma/KarmaThirdApiClientImpl.java new file mode 100644 index 0000000..e1910bb --- /dev/null +++ b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/karma/KarmaThirdApiClientImpl.java @@ -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> getThirdCheckFail(Long workspaceId, Set personIds) { + ThirdApiPersonNormalCheckReq checkReq = new ThirdApiPersonNormalCheckReq(); + checkReq.setWorkspaceId(workspaceId); + checkReq.setPersonIdList(new ArrayList<>(personIds)); + Map> checkMap = RpcWrapper.commonRes(() -> thirdApiCheckServiceApi.thirdApiNormalCheckPerson(checkReq)); + if (CollUtil.isEmpty(checkMap)) { + return Collections.emptyMap(); + } + Map> failInfoMap = new HashMap<>(); + checkMap.forEach((key, opFailVOs) -> { + List 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; + } +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java new file mode 100644 index 0000000..3d1c95a --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java @@ -0,0 +1,30 @@ +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.Set; + +/** + * @author : zhanghonghao@axzo.cn + * @since : 2025/3/7 + */ +@NoArgsConstructor +@AllArgsConstructor +@Data +@Builder +public class CheckUserOperateParam { + private Long operatorId; + private Set personIds; + private Long workspaceId; + + public void check() { + if (ObjectUtils.anyNull(personIds, workspaceId, operatorId)) { + throw ResultCode.INVALID_PARAMS.toException("参数异常,您暂无权限!"); + } + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 9af7e32..d8a563d 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -1,28 +1,33 @@ package cn.axzo.orgmanax.server.nodeuser.service.impl; -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.basics.common.exception.ServiceException; -import cn.axzo.basics.common.util.NumberUtil; import cn.axzo.foundation.exception.Axssert; -import cn.axzo.framework.domain.web.result.ApiResult; +import cn.axzo.foundation.result.ResultCode; +import cn.axzo.orgmanax.dto.common.IdentityType; +import cn.axzo.orgmanax.dto.common.util.NumberUtil; import cn.axzo.orgmanax.dto.cooperateship.dto.OrgCooperateShipDTO; +import cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum; import cn.axzo.orgmanax.dto.cooperateship.req.ListOrgCooperateShipReq; +import cn.axzo.orgmanax.dto.node.dto.OrgNodeDTO; +import cn.axzo.orgmanax.dto.node.enums.NodeTypeEnum; +import cn.axzo.orgmanax.dto.node.req.ListNodeReq; import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO; import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum; import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq; import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq; import cn.axzo.orgmanax.dto.nodeuser.resp.BatchDeleteNodeUserCheckResp; -import cn.axzo.orgmanax.infra.client.profile.PersonProfileGateway; -import cn.axzo.orgmanax.infra.client.profile.dto.model.PersonProfileDto; +import cn.axzo.orgmanax.infra.client.karma.KarmaThirdApiClient; +import cn.axzo.orgmanax.infra.client.karma.ThirdCheckFailResp; import cn.axzo.orgmanax.infra.client.tyr.RoleUserGateway; import cn.axzo.orgmanax.infra.client.workspace.WorkspaceGateway; import cn.axzo.orgmanax.infra.client.workspace.dto.Workspace; -import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip; import cn.axzo.orgmanax.server.cooperateship.service.CooperateShipService; +import cn.axzo.orgmanax.server.node.service.NodeService; +import cn.axzo.orgmanax.server.nodeuser.dto.CheckUserOperateParam; import cn.axzo.orgmanax.server.nodeuser.service.NodeUserCheckService; import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService; +import cn.axzo.orgmanax.server.util.constants.JobCodeConstants; import cn.axzo.tyr.feign.enums.IdentityTypeEnum; import cn.axzo.tyr.feign.enums.RoleTypeEnum; import cn.axzo.tyr.feign.req.PageRoleUserReq; @@ -30,7 +35,9 @@ import cn.axzo.tyr.feign.resp.RoleUserResp; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.ListUtil; -import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; @@ -39,7 +46,8 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Function; +import java.util.function.ToIntFunction; import java.util.stream.Collectors; @Slf4j @@ -51,25 +59,32 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { private final RoleUserGateway roleUserGateway; - private final PersonProfileGateway profileGateway; - private final CooperateShipService cooperateShipService; private final NodeUserService nodeUserService; + private final NodeService nodeService; + + private final KarmaThirdApiClient karmaThirdApiClient; + + // 单位类型默认角色关系,后面可以座位管理员的逻辑进行迭代 + @Value("#{${participateUnitDefaultRoleId:{}}}") + public Map participateUnitDefaultRoleId; + + /** + * 小组长角色分组编码 + */ + @Value("${projectTeamGPLeader:projectTeamGPLeader}") + private String projectTeamGPLeader; + // 企业内班组长岗位编码 @Value("${entTeamLeader:entTeamLeader}") private String entTeamLeader; - // 班组管理员岗位编码 - @Value("${entTeamManager:entTeamManager}") - private String entTeamManager; - // 企业内班组工人岗位编码 @Value("${entWorker:entWorker}") private String entWorker; - @Override public List checkUnit(BatchDeleteNodeUserCheckReq req) { List resultList = new ArrayList<>(); @@ -120,23 +135,11 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { nodeUserQueryVO.setNeeds(ListNodeUserReq.Needs.builder().job(true).build()); //查询人所在的部门节点列表 List organizationalNodeUserList = nodeUserService.list(nodeUserQueryVO); - AtomicBoolean isWorker = new AtomicBoolean(false); - AtomicBoolean isPractitioner = new AtomicBoolean(false); - List teamLeader = Lists.newArrayList(); - List workerOrgNodeIds = Lists.newArrayList(); + Set teamLeader = Sets.newHashSet(); organizationalNodeUserList.forEach(organizationalNodeUserVO -> { - if (IdentityTypeEnum.WORKER_LEADER.getCode().equals(organizationalNodeUserVO.getIdentityType()) || - entTeamLeader.equals(organizationalNodeUserVO.getJob().getCode())) { + if (IdentityTypeEnum.WORKER_LEADER.getCode().equals(organizationalNodeUserVO.getIdentityType()) || entTeamLeader.equals(organizationalNodeUserVO.getJob().getCode())) { teamLeader.add(organizationalNodeUserVO.getPersonId()); } - if (IdentityTypeEnum.WORKER.getCode().equals(organizationalNodeUserVO.getIdentityType()) || - entWorker.equals(organizationalNodeUserVO.getJob().getCode())) { - isWorker.set(true); - workerOrgNodeIds.add(organizationalNodeUserVO.getOrganizationalNodeId()); - } - if (IdentityTypeEnum.PRACTITIONER.getCode().equals(organizationalNodeUserVO.getIdentityType())) { - isPractitioner.set(true); - } }); if (CollUtil.isNotEmpty(teamLeader)) { teamLeader.forEach(e -> { @@ -145,14 +148,11 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { addFailInfo(failInfoMap, e, checkFailInfo); }); } - if (CollUtil.isNotEmpty(failInfoMap)) { - failInfoMap.forEach((personId, checkFailInfos) -> { - BatchDeleteNodeUserCheckResp batchDeleteNodeUserCheckVO = new BatchDeleteNodeUserCheckResp(); - batchDeleteNodeUserCheckVO.setPersonId(personId); - batchDeleteNodeUserCheckVO.setFailInfos(checkFailInfos); - resultList.add(batchDeleteNodeUserCheckVO); - }); + //判断当前人是否有操作权限 + if (NumberUtil.isPositiveNumber(req.getOperatorId())) { + } + transformFailMap(failInfoMap, resultList); return resultList; } @@ -161,10 +161,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { return personIds; } Set filterResult = new HashSet<>(); - List topNodeIds = result.stream() - .map(OrgCooperateShipDTO::getOrganizationalNodeId) - .distinct() - .collect(Collectors.toList()); + List topNodeIds = result.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList()); ListNodeUserReq nodeUserReq = new ListNodeUserReq(); nodeUserReq.setTopNodeIds(topNodeIds); nodeUserReq.setPersonIds(personIds); @@ -185,6 +182,335 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { @Override public List checkWorkspace(BatchDeleteNodeUserCheckReq req) { - return new ArrayList<>(); + Long personId = req.getOperatorId(); + List resultList = new ArrayList<>(); + Map> failInfoMap = new HashMap<>(); + ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); + listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); + listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); + listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); + List cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq); + Axssert.checkNotEmpty(cooperateShipRespList, "操作失败,获取协同组织失败"); + // 协同节点关联的顶级部门节点列表 + List nodeIds = cooperateShipRespList.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList()); + List nodePersonIds = Lists.newArrayList(req.getPersonIds()); + nodePersonIds.add(personId); + ListNodeUserReq query = ListNodeUserReq.builder() + .topNodeIds(nodeIds) + .personIds(nodePersonIds) + .findByAncestorNodeId(true) + .build(); + // 查询当前登录及待删除人员在当前项目中的参与记录(仅限当前登录单位) + List nodeUsers = nodeUserService.list(query); + // 校验当前入参 + checkPermission(nodeUsers, personId); + // 过滤当前操作人员 + nodeUsers = nodeUsers.stream() + .filter(e -> req.getPersonIds().contains(e.getPersonId())) + .collect(Collectors.toList()); + if (CollectionUtil.isEmpty(nodeUsers)) { + req.getPersonIds().forEach(e -> { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, e, checkFailInfo); + }); + } + nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).findAny().ifPresent(e -> { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER); + addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); + }); + + // 判断是否合作小组小组长,合作小组小组长不允许删除 + checkIndependentGroupLeader(nodeUsers, failInfoMap); + + // 判断是否拥有admin角色 判断是否是分包管理员 + List adminRoleIds = getSpecialRole(); + PageRoleUserReq roleUserParam = PageRoleUserReq.builder().build(); + PageRoleUserReq.WorkspaceOuPair workspaceOuPair = new PageRoleUserReq.WorkspaceOuPair(); + workspaceOuPair.setWorkspaceId(req.getWorkspaceId()); + workspaceOuPair.setOuId(req.getOuId()); + roleUserParam.setWorkspaceOuPairs(Collections.singletonList(workspaceOuPair)); + roleUserParam.setPersonIds(req.getPersonIds()); + roleUserParam.setNeedRole(true); + + List saasRoleUserInfo = roleUserGateway.pageAll(roleUserParam); + saasRoleUserInfo.forEach(e -> { + Optional roleTypeEnumOptional = RoleTypeEnum.fromValue(e.getRole().getRoleType()); + RoleTypeEnum roleTypeEnum = RoleTypeEnum.AUTO_OWN; + if (roleTypeEnumOptional.isPresent()) { + roleTypeEnum = roleTypeEnumOptional.get(); + } + boolean anyAdminRole = adminRoleIds.contains(e.getRoleId()) || roleTypeEnum.isAdmin(); + if (anyAdminRole) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN); + addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); + } + }); + // 检查班组节点权限 + checkUserOperate(CheckUserOperateParam.builder() + .operatorId(req.getOperatorId()) + .personIds(req.getPersonIds()) + .workspaceId(req.getWorkspaceId()) + .build(), failInfoMap); + // 三方阻断校验 + thirdApiCheckPerson(req.getWorkspaceId(), req.getPersonIds(), failInfoMap); + transformFailMap(failInfoMap, resultList); + return resultList; } -} + + private static void transformFailMap(Map> failInfoMap, List resultList) { + if (CollUtil.isNotEmpty(failInfoMap)) { + failInfoMap.forEach((failPerson, checkFailInfos) -> { + // Use a LinkedHashMap to keep track of the last count for each type + Map lastCounts = new LinkedHashMap<>(); + for (BatchDeleteNodeUserCheckResp.CheckFailInfo info : checkFailInfos) { + lastCounts.put(info.getType(), info.getCount()); + } + + // Create a new list of CheckFailInfo objects with unique types and their last counts + List uniqueFailInfos = new ArrayList<>(); + for (Map.Entry entry : lastCounts.entrySet()) { + uniqueFailInfos.add(new BatchDeleteNodeUserCheckResp.CheckFailInfo(entry.getKey(), entry.getValue())); + } + BatchDeleteNodeUserCheckResp batchDeleteNodeUserCheckVO = new BatchDeleteNodeUserCheckResp(); + batchDeleteNodeUserCheckVO.setPersonId(failPerson); + batchDeleteNodeUserCheckVO.setFailInfos(uniqueFailInfos); + resultList.add(batchDeleteNodeUserCheckVO); + }); + } + } + + private void thirdApiCheckPerson(Long workspaceId, Set personIds, Map> failInfoMap) { + Map> thirdCheckFail = karmaThirdApiClient.getThirdCheckFail(workspaceId, personIds); + if (CollUtil.isEmpty(thirdCheckFail)) { + return; + } + thirdCheckFail.forEach((key, value) -> value.forEach(thirdCheckFailResp -> { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(thirdCheckFailResp.getType()); + checkFailInfo.setCount(thirdCheckFailResp.getCount()); + addFailInfo(failInfoMap, key, checkFailInfo); + })); + } + + private void checkIndependentGroupLeader(List nodeUsers, Map> failInfoMap) { + Set nodeIdList = nodeUsers.stream().map(NodeUserDTO::getOrganizationalNodeId).collect(Collectors.toSet()); + ListNodeReq nodeBatchQueryVO = new ListNodeReq(); + nodeBatchQueryVO.setIds(nodeIdList); + List nodeVOList = nodeService.list(nodeBatchQueryVO); + if (CollectionUtil.isEmpty(nodeVOList)) { + throw ResultCode.INVALID_PARAMS.toException("操作失败:获取部门节点信息失败"); + } + Map nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(OrgNodeDTO::getId, Function.identity())); + for (NodeUserDTO u : nodeUsers) { + if (projectTeamGPLeader.equals(u.getJob().getCode())) { + OrgNodeDTO nodeVO = nodeVOMap.getOrDefault(u.getOrganizationalNodeId(), null); + if (Objects.nonNull(nodeVO) && NodeTypeEnum.PROJECT_GROUP.getValue().equals(nodeVO.getNodeType()) + && Objects.nonNull(nodeVO.independentGroup()) && nodeVO.independentGroup()) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.PROJECT_GROUP_LEADER); + addFailInfo(failInfoMap, u.getPersonId(), checkFailInfo); + } + } + } + } + + private void checkPermission(List nodeUsers, Long personId) { + if (CollUtil.isEmpty(nodeUsers) + || nodeUsers.stream().noneMatch(e -> Objects.equals(e.getPersonId(), personId))) { + throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目"); + } + } + + private List getSpecialRole() { + if (participateUnitDefaultRoleId != null && !participateUnitDefaultRoleId.isEmpty()) { + return new ArrayList<>(participateUnitDefaultRoleId.values()); + } else { + return new ArrayList<>(); + } + } + + public void checkUserOperate(CheckUserOperateParam param, Map> failInfoMap) { + if (NumberUtil.isNotPositiveNumber(param.getOperatorId())) { + return; + } + param.check(); + List nodePersonIds = Lists.newArrayList(param.getPersonIds()); + nodePersonIds.add(param.getOperatorId()); + ListNodeUserReq nodeUserReq = ListNodeUserReq.builder() + .personIds(nodePersonIds) + .workspaceId(param.getWorkspaceId()) + .needs(ListNodeUserReq.Needs.builder().job(true).node(true).build()) + .build(); + List nodeUsers = nodeUserService.list(nodeUserReq); + NodeUserDTO operator = nodeUsers.stream().filter(nu -> Objects.equals(nu.getPersonId(), param.getOperatorId())) + .filter(nu -> StrUtil.isNotBlank(nu.getJob().getCode())) + .min(Comparator.comparingInt(NODE_USER_PRIORITY_RESOLVER)).orElse(null); + List targets = param.getPersonIds().stream() + .map(personId -> nodeUsers.stream() + .filter(nu -> Objects.equals(nu.getPersonId(), personId)) + .min(Comparator.comparingInt(NODE_USER_PRIORITY_RESOLVER)) + .orElse(null)) + .collect(Collectors.toList()); + + log.info("## checkUserOperate, param = {}, operator = {}, targets = {}, nodeUsers = {} " + , JSON.toJSONString(param), JSON.toJSONString(operator), JSON.toJSONString(targets), JSON.toJSONString(nodeUsers)); + if (operator == null) { + throw ResultCode.INVALID_PARAMS.toException("你已经被移出该企业/项目,请及时联系管理员;你可以退出登录或切换到其他企业/项目使用"); + } + if (CollUtil.isEmpty(targets)) { + throw ResultCode.INVALID_PARAMS.toException("操作对象已经被移出该企业/项目,请刷新页面重新操作"); + } + + // 如果只有工人身份,则直接提示无权限 + if (isProjectWorker(operator)) { + throw ResultCode.INVALID_PARAMS.toException("操作失败,您暂无权限!"); + } + if (param.getPersonIds().size() == 1 && param.getPersonIds().contains(param.getOperatorId())) { + return; + } + // 如果 操作人是 从业人员 直接返回 + if (isPractitioner(operator)) { + return; + } + // 操作人是 班组长或者带班长, 则被操作人,只能是 自己,或者自己班组 及 小组的工人 + if (isProjectTeamLeader(operator) || isProjectTeamManager(operator)) { + targets.forEach(target -> teamManagerCheck(target, operator, failInfoMap)); + } + if (isProjectGroupManager(operator)) { + targets.forEach(target -> groupManagerCheck(target, operator, nodeUsers, failInfoMap)); + } + } + + private void groupManagerCheck(NodeUserDTO target, NodeUserDTO operator, List nodeUsers, Map> failInfoMap) { + if (isPractitioner(target)) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + return; + } + // 工人必须仅在自己小组 + boolean isSameGroup = nodeUsers.stream() + .filter(nu -> Objects.equals(nu.getPersonId(), target.getPersonId())) + .anyMatch(nu -> Objects.equals(nu.getOrganizationalNodeId(), operator.getOrganizationalNodeId())); + if (!isSameGroup) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + } + } + + private void teamManagerCheck(NodeUserDTO target, NodeUserDTO operator, Map> failInfoMap) { + if (isPractitioner(target)) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + return; + } + boolean isSameTeam = Objects.equals(target.getOrganizationalNodeId(), operator.getOrganizationalNodeId()); + if (isSameTeam) { + return; + } + // 否则,自己下级小组,也可以。 + boolean isGroup = target.getNode() != null + && Objects.equals(target.getNode().getNodeType(), NodeTypeEnum.PROJECT_GROUP.getCode()); + if (!isGroup) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + return; + } + Long belongProjectTeamNodeId = resolveProjectTeamNodeId(target.getOrganizationalNodeId()); + if (Objects.equals(belongProjectTeamNodeId, operator.getOrganizationalNodeId())) { + return; + } + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + } + + private boolean isPractitioner(NodeUserDTO nodeUser) { + if (nodeUser == null) { + return false; + } + return Objects.equals(nodeUser.getIdentityType(), IdentityType.PRACTITIONER.getCode()); + } + + private boolean isProjectWorker(NodeUserDTO nodeUser) { + if (nodeUser == null) { + return false; + } + return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJECT_TEAM_WORKER); + } + + private boolean isProjectTeamLeader(NodeUserDTO nodeUser) { + if (nodeUser == null) { + return false; + } + return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJ_TEAM_LEADER); + } + + private boolean isProjectTeamManager(NodeUserDTO nodeUser) { + if (nodeUser == null) { + return false; + } + return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJ_TEAM_MANAGER); + } + + private boolean isProjectGroupManager(NodeUserDTO nodeUser) { + if (nodeUser == null) { + return false; + } + return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJECT_TEAM_GROUP_LEADER); + } + + private static final ToIntFunction NODE_USER_PRIORITY_RESOLVER = nodeUser -> { + if (nodeUser == null) { + return 9999; + } + if (Objects.equals(nodeUser.getIdentityType(), IdentityType.PRACTITIONER.getCode())) { + return 20; + } + if (StrUtil.isBlank(nodeUser.getJob().getCode())) { + return 9999; + } + switch (nodeUser.getJob().getCode()) { + case JobCodeConstants.PROJECT_TEAM_WORKER: + // 工人 + return 100; + case JobCodeConstants.PROJECT_TEAM_GROUP_LEADER: + // 小组长 + return 90; + case JobCodeConstants.PROJ_TEAM_MANAGER: + // 带班长 + return 80; + case JobCodeConstants.PROJ_TEAM_LEADER: + // 班组长 + return 70; + case JobCodeConstants.ENT_TEAM_WORK: + // 平台工人 + return 60; + case JobCodeConstants.ENT_TEAM_MANAGER: + // 平台班组管理员 + return 50; + case JobCodeConstants.ENT_TEAM_LEADER: + // 平台班组长 + return 40; + default: + return 20; + } + }; + + private Long resolveProjectTeamNodeId(Long nodeId) { + ListOrgCooperateShipReq saasCooperateShipQueryReq = ListOrgCooperateShipReq.builder() + .organizationNodeIds(ImmutableSet.of(nodeId)) + .includeAncestors(true) + .build(); + List nodes = cooperateShipService.list(saasCooperateShipQueryReq); + return nodes.stream().filter(n -> Objects.equals(n.getCooperateType(), CooperateShipTypeEnum.PROJ_TEAM.getCode())).findFirst() + .map(OrgCooperateShipDTO::getOrganizationalNodeId).orElse(0L); + } + +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/util/constants/JobCodeConstants.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/util/constants/JobCodeConstants.java new file mode 100644 index 0000000..d1d15b3 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/util/constants/JobCodeConstants.java @@ -0,0 +1,34 @@ +package cn.axzo.orgmanax.server.util.constants; + +/** + * 岗位编码常量 + * + * @version V1.0 + * @author: ZhanSiHu + * @date: 2024/1/25 14:03 + */ +public class JobCodeConstants { + /** 企业内班组长 **/ + public static final String ENT_TEAM_LEADER = "entTeamLeader"; + /** 企业内班组管理员 **/ + public static final String ENT_TEAM_MANAGER = "entTeamManager"; + /** 企业内工人 **/ + public static final String ENT_TEAM_WORK = "entWorker"; + + /** 项目内班组 班组长 **/ + public static final String PROJ_TEAM_LEADER = "projTeamLeader"; + + /** + * 项目 - 带班长 + */ + public static final String PROJ_TEAM_MANAGER = "projectTeamManager"; + /** + * 项目 - 小组长 + */ + public static final String PROJECT_TEAM_GROUP_LEADER = "projectTeamGPLeader"; + + + public static final String PROJECT_TEAM_WORKER = "projWorker"; + + +} From 9ec0d538d3791920399ce2630ac5dd7ff342f43f Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 7 Mar 2025 14:52:04 +0800 Subject: [PATCH 08/75] =?UTF-8?q?feat(REQ-3714):=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E5=8F=91=E9=80=81mq?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../producer/OrgUserChangedEventProducer.java | 18 +++++++----------- .../impl/OrgUserFoundationServiceImpl.java | 3 ++- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java index 648aeb3..0f99987 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java @@ -6,9 +6,8 @@ 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 cn.hutool.extra.spring.SpringUtil; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Component; import java.util.Collection; @@ -21,13 +20,14 @@ import java.util.Objects; */ @Slf4j @Component -public class OrgUserChangedEventProducer implements InitializingBean { +@RequiredArgsConstructor +public class OrgUserChangedEventProducer { private static final String EVENT_INVALID = "the event is invalid. {}"; - private static EventProducer eventProducer; + private final EventProducer eventProducer; - public static void sendStatusEvent(OrgUserStatusChangedEvent event) { + public void sendStatusEvent(OrgUserStatusChangedEvent event) { if (isInvalid(event)) { log.info(EVENT_INVALID, event); return; @@ -36,12 +36,12 @@ public class OrgUserChangedEventProducer implements InitializingBean { eventProducer.send(map(event)); } - public static void batchSendStatusEvents(Collection events) { + public void batchSendStatusEvents(Collection events) { if (CollUtil.isEmpty(events)) { log.info("the events is empty."); return; } - events.forEach(OrgUserChangedEventProducer::sendStatusEvent); + events.forEach(this::sendStatusEvent); } @@ -64,8 +64,4 @@ public class OrgUserChangedEventProducer implements InitializingBean { .build(); } - @Override - public void afterPropertiesSet() throws Exception { - eventProducer = SpringUtil.getBean(EventProducer.class); - } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java index 8e16d83..8d91c9c 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java @@ -37,6 +37,7 @@ public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { private final WorkspaceGateway workspaceGateway; private final OrgUserQueryRepository orgUserQueryRepository; private final OrgUserUpsertRepository orgUserUpsertRepository; + private final OrgUserChangedEventProducer orgUserChangedEventProducer; @Override public void batchWithdrawOrQuit(OrgUserWithdrawOrQuitReq req) { @@ -91,7 +92,7 @@ public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { // 事务提交之后发送MQ Function eventMapper = e -> toOrgUserStatusChangedEvent(e, topNodeId); List events = CollUtil.map(orgUsers, eventMapper, true); - OrgUserChangedEventProducer.batchSendStatusEvents(events); + orgUserChangedEventProducer.batchSendStatusEvents(events); } public static OrgUserStatusChangedEvent toOrgUserStatusChangedEvent(OrgUserDTO orgUser, Long topNodeId) { From 61626a7a73ac70a5b31fb82915e55092e22c65f2 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 7 Mar 2025 15:20:24 +0800 Subject: [PATCH 09/75] =?UTF-8?q?feat(REQ-3714):=20=E8=B0=83=E6=95=B4org?= =?UTF-8?q?=5Fuser=E7=9A=84mq=E5=8F=91=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orguser/foundation/impl/OrgUserFoundationServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java index 8d91c9c..ca291a3 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java @@ -79,7 +79,7 @@ public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { List orgUserList = orgUserMap.entrySet().stream() .filter(personIdOrgUserEntry -> personIdSet.contains(personIdOrgUserEntry.getKey())) .map(Map.Entry::getValue).collect(Collectors.toList()); - List dtoList = CollUtil.map(orgUsers, this::toOrgUserDTO, true); + List dtoList = CollUtil.map(orgUserList, this::toOrgUserDTO, true); // 发送用户状态变更事件 batchSendStatusEvents(dtoList, topNodeId); } From ddeb46cccbf5ee8f140d6b26132ce282f0024f82 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 7 Mar 2025 15:24:26 +0800 Subject: [PATCH 10/75] =?UTF-8?q?feat(REQ-3714):=20=E6=9E=9A=E4=B8=BE?= =?UTF-8?q?=E5=8A=A0=E4=B8=8A=E6=98=AF=E5=90=A6=E4=B8=89=E6=96=B9=E7=9A=84?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java index fd0a3c9..41bbc11 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java @@ -34,4 +34,8 @@ public enum CheckInfoTypeEnum { return thirdTypeMap.get(type); } + public static boolean isThirdType(CheckInfoTypeEnum type) { + return type.getThirdType() > 0; + } + } \ No newline at end of file From ee114b0a5e5d3ed393c4dd6dbb262fda9978a52a Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 7 Mar 2025 16:55:58 +0800 Subject: [PATCH 11/75] =?UTF-8?q?feat(REQ-3714):=20=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=8A=A0=E4=B8=8AouId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java index 688f4f1..fe90294 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java @@ -16,6 +16,8 @@ import java.util.List; @SuperBuilder public class NodeUserWorkspaceDelete { + private Long ouId; + private Long workspaceId; private Long operatorId; From 6870c7857b78d5554de8f9f036c05d6ffd9186a4 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 7 Mar 2025 17:35:29 +0800 Subject: [PATCH 12/75] =?UTF-8?q?feat(REQ-3714):=20=E5=8D=95=E4=BD=8D?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E4=BA=BA=E6=9D=83=E9=99=90=E5=88=A4=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/dto/CheckUserOperateParam.java | 1 + .../foundation/req/NodeUserUnitDelete.java | 34 ------------------ .../req/NodeUserWorkspaceDelete.java | 36 ------------------- .../impl/NodeUserCheckServiceImpl.java | 15 ++++---- 4 files changed, 10 insertions(+), 76 deletions(-) delete mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserUnitDelete.java delete mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java index 3d1c95a..e0ab5b4 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java @@ -21,6 +21,7 @@ public class CheckUserOperateParam { private Long operatorId; private Set personIds; private Long workspaceId; + private boolean isWorkspace; public void check() { if (ObjectUtils.anyNull(personIds, workspaceId, operatorId)) { diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserUnitDelete.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserUnitDelete.java deleted file mode 100644 index d5e5863..0000000 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserUnitDelete.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.axzo.orgmanax.server.nodeuser.foundation.req; - -import cn.axzo.foundation.exception.Axssert; -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 NodeUserUnitDelete { - - private Long ouId; - - private Long operatorId; - - private List personIds; - - public void check() { - Axssert.checkNonNull(operatorId, "操作人不能为空"); - Axssert.checkNonNull(ouId, "单位不能为空"); - Axssert.checkNonNull(personIds, "用户id列表不能都为空"); - } - - public OrganizationalNodeUser toEntity() { - return BeanUtil.toBean(this, OrganizationalNodeUser.class); - } -} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java deleted file mode 100644 index fe90294..0000000 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserWorkspaceDelete.java +++ /dev/null @@ -1,36 +0,0 @@ -package cn.axzo.orgmanax.server.nodeuser.foundation.req; - -import cn.axzo.foundation.exception.Axssert; -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 NodeUserWorkspaceDelete { - - private Long ouId; - - private Long workspaceId; - - private Long operatorId; - - private List personIds; - - public void check() { - Axssert.checkNonNull(operatorId, "操作人不能为空"); - Axssert.checkNonNull(workspaceId, "项目不能为空"); - Axssert.checkNonNull(personIds, "用户id列表不能都为空"); - } - - public OrganizationalNodeUser toEntity() { - return BeanUtil.toBean(this, OrganizationalNodeUser.class); - } -} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index d8a563d..06e95de 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -148,10 +148,12 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { addFailInfo(failInfoMap, e, checkFailInfo); }); } - //判断当前人是否有操作权限 - if (NumberUtil.isPositiveNumber(req.getOperatorId())) { - - } + // 检查节点权限 + checkUserOperate(CheckUserOperateParam.builder() + .operatorId(req.getOperatorId()) + .personIds(req.getPersonIds()) + .workspaceId(req.getWorkspaceId()) + .build(), failInfoMap); transformFailMap(failInfoMap, resultList); return resultList; } @@ -248,11 +250,12 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); } }); - // 检查班组节点权限 + // 检查节点权限 checkUserOperate(CheckUserOperateParam.builder() .operatorId(req.getOperatorId()) .personIds(req.getPersonIds()) .workspaceId(req.getWorkspaceId()) + .isWorkspace(true) .build(), failInfoMap); // 三方阻断校验 thirdApiCheckPerson(req.getWorkspaceId(), req.getPersonIds(), failInfoMap); @@ -365,7 +368,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } // 如果只有工人身份,则直接提示无权限 - if (isProjectWorker(operator)) { + if (isProjectWorker(operator) && param.isWorkspace()) { throw ResultCode.INVALID_PARAMS.toException("操作失败,您暂无权限!"); } if (param.getPersonIds().size() == 1 && param.getPersonIds().contains(param.getOperatorId())) { From f3bb97428833df7ddff9b160d7e028c3e32ab822 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 7 Mar 2025 17:42:05 +0800 Subject: [PATCH 13/75] =?UTF-8?q?feat(REQ-3714):=20=E5=8A=A0=E4=B8=8AnodeI?= =?UTF-8?q?d=E7=9A=84=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/service/impl/NodeUserCheckServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 06e95de..00dbc6c 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -191,6 +191,9 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); + if (NumberUtil.isPositiveNumber(req.getNodeId())) { + listOrgCooperateShipReq.setOrganizationNodeIds(Collections.singleton(req.getNodeId())); + } List cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq); Axssert.checkNotEmpty(cooperateShipRespList, "操作失败,获取协同组织失败"); // 协同节点关联的顶级部门节点列表 From 7f16ae4d00afd8d1b7e0ff5b7ed96dea8cf4330a Mon Sep 17 00:00:00 2001 From: zhangran Date: Mon, 10 Mar 2025 10:14:02 +0800 Subject: [PATCH 14/75] =?UTF-8?q?add(feature/REQ-3714)=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E7=8F=AD=E7=BB=84=E6=88=90=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/nodeuser/req/DeleteNodeUserReq.java | 31 +++++++ .../dto/nodeuser/req/ProcessNodeUserReq.java | 4 +- .../infra/dao/node/dao/TeamOuRelationDao.java | 10 ++ .../entity/OrganizationalTeamOuRelation.java | 66 ++++++++++++++ .../OrganizationalTeamOuRelationMapper.java | 9 ++ .../repository/TeamOuRelationRepository.java | 64 +++++++++++++ .../impl/TeamOuRelationRepositoryImpl.java | 36 ++++++++ .../impl/DeletePlatTeamWorkerProcessor.java | 91 +++++++++++++++++++ 8 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/DeleteNodeUserReq.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/dao/TeamOuRelationDao.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalTeamOuRelation.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/mapper/OrganizationalTeamOuRelationMapper.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/repository/TeamOuRelationRepository.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/repository/impl/TeamOuRelationRepositoryImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/DeleteNodeUserReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/DeleteNodeUserReq.java new file mode 100644 index 0000000..4057869 --- /dev/null +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/DeleteNodeUserReq.java @@ -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.List; + +/** + * @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 List personIds; +} diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ProcessNodeUserReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ProcessNodeUserReq.java index 9f72966..ad56f38 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ProcessNodeUserReq.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/ProcessNodeUserReq.java @@ -21,7 +21,9 @@ public class ProcessNodeUserReq { CREATE("创建", "createNodeUserProcessor"), UPDATE("普通更新", "updateNodeUserProcessor"), UNIT_DELETE("删除单位人员", "unitDeleteNodeUserProcessor"), - WORKSPACE_DELETE("删除项目人员", "workspaceDeleteNodeUserProcessor"); + WORKSPACE_DELETE("删除项目人员", "workspaceDeleteNodeUserProcessor"), + DELETE_PLAT_TAM_WORKER("平台班组删除人员", "deletePlatTeamWorkerProcessor"), + ; private final String desc; private final String processor; diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/dao/TeamOuRelationDao.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/dao/TeamOuRelationDao.java new file mode 100644 index 0000000..0cfbc3b --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/dao/TeamOuRelationDao.java @@ -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 { +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalTeamOuRelation.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalTeamOuRelation.java new file mode 100644 index 0000000..dc37da1 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalTeamOuRelation.java @@ -0,0 +1,66 @@ +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 Long createBy; + protected Date updateAt; + protected Long updateBy; + @TableField("is_delete") + protected Long isDelete = 0L; +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/mapper/OrganizationalTeamOuRelationMapper.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/mapper/OrganizationalTeamOuRelationMapper.java new file mode 100644 index 0000000..54dc273 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/mapper/OrganizationalTeamOuRelationMapper.java @@ -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 { +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/repository/TeamOuRelationRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/repository/TeamOuRelationRepository.java new file mode 100644 index 0000000..f53ba2b --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/repository/TeamOuRelationRepository.java @@ -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 list(ListReq req); + + default OrganizationalTeamOuRelation one(OneReq req) { + return oneOpt(req).orElse(null); + } + + default Optional 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; + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/repository/impl/TeamOuRelationRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/repository/impl/TeamOuRelationRepositoryImpl.java new file mode 100644 index 0000000..9355677 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/repository/impl/TeamOuRelationRepositoryImpl.java @@ -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 list(ListReq req) { + QueryWrapper wrapper = QueryWrapperHelper.fromBean(req, OrganizationalTeamOuRelation.class); + return teamOuRelationDao.list(wrapper); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java new file mode 100644 index 0000000..3604277 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -0,0 +1,91 @@ +package cn.axzo.orgmanax.server.nodeuser.service.processor.impl; + +import cn.axzo.foundation.exception.Axssert; +import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO; +import cn.axzo.orgmanax.dto.nodeuser.req.DeleteNodeUserReq; +import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq; +import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalTeamOuRelation; +import cn.axzo.orgmanax.infra.dao.node.repository.TeamOuRelationRepository; +import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser; +import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; +import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete; +import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService; +import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor; +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @Author zr + * @Date 2025/3/7 15:54 + * @Description + **/ + +@Component +@Slf4j +@RequiredArgsConstructor +public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { + + private final TeamOuRelationRepository teamOuRelationRepository; + private final NodeUserService nodeUserService; + private final NodeUserFoundationService nodeUserFoundationService; + + @Override + public ProcessResult process(ProcessContext context) { + log.info("DeletePlatTeamWorkerProcessor process context:{}", JSON.toJSONString(context)); + Axssert.checkNonNull(context.getParams(), "参数不能为空"); + DeleteNodeUserReq param = context.getParams().toJavaObject(DeleteNodeUserReq.class); + ListNodeUserReq nodeUserReq = ListNodeUserReq.builder() + .workspaceId(param.getWorkspaceId()) + .organizationalUnitId(param.getOuId()) + .personIds(param.getPersonIds()).build(); + List nodeUserDTOS = nodeUserService.list(nodeUserReq); + List nodeIds = nodeUserDTOS.stream().map(NodeUserDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList()); + Map> nodeUserMap = nodeUserDTOS.stream().collect(Collectors.groupingBy(NodeUserDTO::getOrganizationalNodeId)); + + // 获取teamouRelation数据 + Map teamOuRelationMap = nodeIds.stream().map(item -> { + TeamOuRelationRepository.ListReq build = TeamOuRelationRepository.ListReq.builder().nodeId(item).build(); + return teamOuRelationRepository.list(build); + }).filter(Objects::nonNull).flatMap(Collection::stream) + .collect(Collectors.toMap(OrganizationalTeamOuRelation::getNodeId, Function.identity(), (x, y) -> x)); + // 获取平台班组下的工人 + if (CollUtil.isNotEmpty(teamOuRelationMap)) { + nodeUserMap.forEach((k, vs) -> { + OrganizationalTeamOuRelation ouRelation = teamOuRelationMap.get(k); + if (Objects.nonNull(ouRelation)) { + List deleteTeamWorkerPersonIds = vs.stream().map(NodeUserDTO::getPersonId).collect(Collectors.toList()); + NodeUserDelete nodeUserDelete = NodeUserDelete.builder() + .ouId(ouRelation.getTeamOuId()) + .personIds(deleteTeamWorkerPersonIds) + .isUnitDelete(Boolean.TRUE) + .build(); + nodeUserFoundationService.delete(nodeUserDelete); + return ; + } + log.error("获取企业下班组与平台班组关系失败, nodeId:{}", k); + }); + } + // 调用统用删除逻辑 + NodeUserDelete nodeUserDelete = NodeUserDelete.builder().ouId(param.getOuId()) + .workspaceId(param.getWorkspaceId()) + .personIds(param.getPersonIds()) + .operatorId(context.getOperatorId()) + .isUnitDelete(Boolean.TRUE) + .build(); + List delete = nodeUserFoundationService.delete(nodeUserDelete); + return ProcessResult.success((JSONObject) JSON.toJSON(delete)); + } + + +} From 0cbf35f1be4e9149caa0422e3deb8281419e1c6f Mon Sep 17 00:00:00 2001 From: zhangran Date: Mon, 10 Mar 2025 10:54:49 +0800 Subject: [PATCH 15/75] =?UTF-8?q?add(feature/REQ-3714)=20=E5=BC=95?= =?UTF-8?q?=E7=94=A8redisson?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orgmanax-server/pom.xml | 4 ++++ pom.xml | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/orgmanax-server/pom.xml b/orgmanax-server/pom.xml index 46c00a7..ad5bb74 100644 --- a/orgmanax-server/pom.xml +++ b/orgmanax-server/pom.xml @@ -50,5 +50,9 @@ org.springframework.cloud spring-cloud-starter-bootstrap + + com.baomidou + lock4j-redisson-spring-boot-starter + \ No newline at end of file diff --git a/pom.xml b/pom.xml index e88513d..fac5dd9 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,7 @@ 2.2.3 2.0.0-SNAPSHOT 2.0.0-SNAPSHOT + 2.2.7 @@ -81,6 +82,11 @@ rocketmq-spring-boot-starter ${rocket-mq.version} + + com.baomidou + lock4j-redisson-spring-boot-starter + ${redisson.version} + From d2433d7fa2067c5b14b50848e14c929ec8cb0932 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Mon, 10 Mar 2025 13:42:50 +0800 Subject: [PATCH 16/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86pom?= =?UTF-8?q?=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dao/project/worker/entity/OrgProjectWorker.java | 7 +++++-- orgmanax-server/pom.xml | 8 ++++---- .../service/impl/NodeUserCheckServiceImpl.java | 2 +- pom.xml | 10 +++++----- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/entity/OrgProjectWorker.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/entity/OrgProjectWorker.java index 48fbbd9..bd4ad50 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/entity/OrgProjectWorker.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/entity/OrgProjectWorker.java @@ -1,6 +1,8 @@ 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; @@ -27,8 +29,9 @@ public class OrgProjectWorker implements Serializable { private static final long serialVersionUID = 260206461965825922L; - - @TableField("id") + @TableId( + type = IdType.AUTO + ) private Long id; /** diff --git a/orgmanax-server/pom.xml b/orgmanax-server/pom.xml index ad5bb74..bfdf316 100644 --- a/orgmanax-server/pom.xml +++ b/orgmanax-server/pom.xml @@ -50,9 +50,9 @@ org.springframework.cloud spring-cloud-starter-bootstrap - - com.baomidou - lock4j-redisson-spring-boot-starter - + + + + \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 00dbc6c..6a9fa41 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -168,7 +168,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { nodeUserReq.setTopNodeIds(topNodeIds); nodeUserReq.setPersonIds(personIds); List nodeUserDTOS = nodeUserService.list(nodeUserReq); - Map personNodeMap = nodeUserDTOS.stream().collect(Collectors.toMap(NodeUserDTO::getPersonId, NodeUserDTO::getTopNodeId)); + Map personNodeMap = nodeUserDTOS.stream().collect(Collectors.toMap(NodeUserDTO::getPersonId, NodeUserDTO::getTopNodeId, (v1, v2) -> v2)); Set shipNodeIds = result.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).collect(Collectors.toSet()); for (Map.Entry entry : personNodeMap.entrySet()) { if (shipNodeIds.contains(entry.getValue())) { diff --git a/pom.xml b/pom.xml index fac5dd9..fd7323d 100644 --- a/pom.xml +++ b/pom.xml @@ -82,11 +82,11 @@ rocketmq-spring-boot-starter ${rocket-mq.version} - - com.baomidou - lock4j-redisson-spring-boot-starter - ${redisson.version} - + + + + + From fb365d27cdd2673e4d1f23a0392f29894ba0b3c1 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Mon, 10 Mar 2025 14:11:11 +0800 Subject: [PATCH 17/75] =?UTF-8?q?feat(REQ-3714):=20=E5=8D=8F=E5=90=8C?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/service/impl/NodeUserCheckServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 6a9fa41..b4b421b 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -118,6 +118,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); listOrgCooperateShipReq.setOuIds(Collections.singleton(ouId)); listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); + listOrgCooperateShipReq.setWorkspaceTypes(CollUtil.newHashSet(2)); List listPersonJoinedWorkspace = cooperateShipService.list(listOrgCooperateShipReq); Set inProjectPersonIds = filterByPerson(listPersonJoinedWorkspace, personIds); if (CollectionUtil.isNotEmpty(inProjectPersonIds)) { From a5c6bf29deb9ab54a4a742c4e18c1dcbc106c9c5 Mon Sep 17 00:00:00 2001 From: zhangran Date: Mon, 10 Mar 2025 15:02:03 +0800 Subject: [PATCH 18/75] =?UTF-8?q?add(feature/REQ-3714)=20=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E5=B9=B3=E5=8F=B0=E5=B7=A5=E4=BA=BA=E5=B7=A5=E7=A7=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/nodeuser/req/DeleteNodeUserReq.java | 4 +- .../WorkerProfessionHistoryRepository.java | 2 + .../WorkerProfessionSkillTagRepository.java | 2 + .../WorkerProfessionTagRepository.java | 6 + ...WorkerProfessionHistoryRepositoryImpl.java | 5 + ...orkerProfessionSkillTagRepositoryImpl.java | 7 + .../WorkerProfessionTagRepositoryImpl.java | 7 + .../impl/DeletePlatTeamWorkerProcessor.java | 26 +++- ...jectWorkerProfessionFoundationService.java | 13 ++ .../OrgWorkerHistoryFoundationService.java | 18 +++ .../OrgWorkerSkillTagFoundationService.java | 17 +++ .../dto/DeleteWorkerProfession.java | 48 +++++++ ...WorkerProfessionFoundationServiceImpl.java | 90 +++++++++++++ ...OrgWorkerHistoryFoundationServiceImpl.java | 121 ++++++++++++++++++ ...rgWorkerSkillTagFoundationServiceImpl.java | 51 ++++++++ .../foundation/vo/ProfessionValidEnum.java | 27 ++++ 16 files changed, 436 insertions(+), 8 deletions(-) create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgProjectWorkerProfessionFoundationService.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgWorkerHistoryFoundationService.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgWorkerSkillTagFoundationService.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/dto/DeleteWorkerProfession.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerSkillTagFoundationServiceImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/vo/ProfessionValidEnum.java diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/DeleteNodeUserReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/DeleteNodeUserReq.java index 4057869..c2c5925 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/DeleteNodeUserReq.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/DeleteNodeUserReq.java @@ -4,7 +4,7 @@ import lombok.Data; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; -import java.util.List; +import java.util.Set; /** * @Author zr @@ -27,5 +27,5 @@ public class DeleteNodeUserReq { * 自然人id */ @NotEmpty(message = "人员不能为空") - private List personIds; + private Set personIds; } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionHistoryRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionHistoryRepository.java index cd874c8..c6c1605 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionHistoryRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionHistoryRepository.java @@ -26,6 +26,8 @@ import java.util.stream.Collectors; public interface WorkerProfessionHistoryRepository { PageResp page(PageReq req); + void saveBatch(List history); + default List list(PageReq req) { return page(req).getData(); } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionSkillTagRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionSkillTagRepository.java index cf18f6c..bbcc0ee 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionSkillTagRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionSkillTagRepository.java @@ -21,6 +21,8 @@ import java.util.Set; public interface WorkerProfessionSkillTagRepository { PageResp page(PageReq req); + void removeByIds(List ids); + default List list(PageReq req) { return page(req).getData(); } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionTagRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionTagRepository.java index 53cca1b..644c0c4 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionTagRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionTagRepository.java @@ -20,6 +20,12 @@ import java.util.Set; public interface WorkerProfessionTagRepository { PageResp page(PageReq req); + /** + * 物理删除数据 + * @param ids + */ + void removeByIds(List ids); + default List list(PageReq req) { return page(req).getData(); } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionHistoryRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionHistoryRepositoryImpl.java index 99af303..4e8213a 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionHistoryRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionHistoryRepositoryImpl.java @@ -61,4 +61,9 @@ public class WorkerProfessionHistoryRepositoryImpl implements WorkerProfessionHi } return PageConverter.toResp(results); } + + @Override + public void saveBatch(List histories) { + workerProfessionHistoryDao.saveBatch(histories); + } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java index fb6b441..8b8e1a4 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java @@ -17,6 +17,8 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; +import java.util.List; + /** * @author zhanghongbo * @date 2025/1/6 @@ -45,4 +47,9 @@ public class WorkerProfessionSkillTagRepositoryImpl implements WorkerProfessionS } return PageConverter.toResp(results); } + + @Override + public void removeByIds(List ids) { + workerProfessionSkillTagDao.removeByIds(ids); + } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java index 07308f9..8ae8827 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java @@ -16,6 +16,8 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; +import java.util.List; + /** * @author zhanghongbo * @date 2025/1/3 @@ -44,4 +46,9 @@ public class WorkerProfessionTagRepositoryImpl implements WorkerProfessionTagRep } return PageConverter.toResp(results); } + + @Override + public void removeByIds(List ids){ + workerProfessionTagDao.removeByIds(ids); + } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index 3604277..bf49146 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -4,6 +4,7 @@ import cn.axzo.foundation.exception.Axssert; import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO; import cn.axzo.orgmanax.dto.nodeuser.req.DeleteNodeUserReq; import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq; +import cn.axzo.orgmanax.dto.project.team.enums.TeamSceneEnum; import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalTeamOuRelation; import cn.axzo.orgmanax.infra.dao.node.repository.TeamOuRelationRepository; import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser; @@ -11,9 +12,12 @@ import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete; import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService; import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor; +import cn.axzo.orgmanax.server.workerprofession.foundation.OrgProjectWorkerProfessionFoundationService; +import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; import cn.hutool.core.collection.CollUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Lists; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -39,6 +43,7 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { private final TeamOuRelationRepository teamOuRelationRepository; private final NodeUserService nodeUserService; private final NodeUserFoundationService nodeUserFoundationService; + private final OrgProjectWorkerProfessionFoundationService workerProfessionFoundationService; @Override public ProcessResult process(ProcessContext context) { @@ -53,7 +58,7 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { List nodeIds = nodeUserDTOS.stream().map(NodeUserDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList()); Map> nodeUserMap = nodeUserDTOS.stream().collect(Collectors.groupingBy(NodeUserDTO::getOrganizationalNodeId)); - // 获取teamouRelation数据 + // 获取teamOuRelation数据 Map teamOuRelationMap = nodeIds.stream().map(item -> { TeamOuRelationRepository.ListReq build = TeamOuRelationRepository.ListReq.builder().nodeId(item).build(); return teamOuRelationRepository.list(build); @@ -61,9 +66,10 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { .collect(Collectors.toMap(OrganizationalTeamOuRelation::getNodeId, Function.identity(), (x, y) -> x)); // 获取平台班组下的工人 if (CollUtil.isNotEmpty(teamOuRelationMap)) { - nodeUserMap.forEach((k, vs) -> { - OrganizationalTeamOuRelation ouRelation = teamOuRelationMap.get(k); + nodeUserMap.forEach((nodeId, vs) -> { + OrganizationalTeamOuRelation ouRelation = teamOuRelationMap.get(nodeId); if (Objects.nonNull(ouRelation)) { + // 删除平台工人 List deleteTeamWorkerPersonIds = vs.stream().map(NodeUserDTO::getPersonId).collect(Collectors.toList()); NodeUserDelete nodeUserDelete = NodeUserDelete.builder() .ouId(ouRelation.getTeamOuId()) @@ -71,21 +77,29 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { .isUnitDelete(Boolean.TRUE) .build(); nodeUserFoundationService.delete(nodeUserDelete); + // 删除平台工人工种和技能标签 + DeleteWorkerProfession workerProfession = DeleteWorkerProfession.builder() + .scene(TeamSceneEnum.PROJECT_TEAM.name()) + .personIds(param.getPersonIds()) + .isResign(Boolean.TRUE) + .orgNodeId(nodeId) + .build(); + workerProfessionFoundationService.delete(workerProfession); return ; } - log.error("获取企业下班组与平台班组关系失败, nodeId:{}", k); + log.error("获取企业下班组与平台班组关系失败, nodeId:{}", nodeId); }); } // 调用统用删除逻辑 NodeUserDelete nodeUserDelete = NodeUserDelete.builder().ouId(param.getOuId()) .workspaceId(param.getWorkspaceId()) - .personIds(param.getPersonIds()) + .personIds(Lists.newArrayList(param.getPersonIds())) .operatorId(context.getOperatorId()) .isUnitDelete(Boolean.TRUE) .build(); List delete = nodeUserFoundationService.delete(nodeUserDelete); + return ProcessResult.success((JSONObject) JSON.toJSON(delete)); } - } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgProjectWorkerProfessionFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgProjectWorkerProfessionFoundationService.java new file mode 100644 index 0000000..ad4d933 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgProjectWorkerProfessionFoundationService.java @@ -0,0 +1,13 @@ +package cn.axzo.orgmanax.server.workerprofession.foundation; + +import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; + +/** + * @Author zr + * @Date 2025/3/10 10:22 + * @Description + **/ +public interface OrgProjectWorkerProfessionFoundationService { + + void delete(DeleteWorkerProfession req); +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgWorkerHistoryFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgWorkerHistoryFoundationService.java new file mode 100644 index 0000000..856baeb --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgWorkerHistoryFoundationService.java @@ -0,0 +1,18 @@ +package cn.axzo.orgmanax.server.workerprofession.foundation; + + +import cn.axzo.orgmanax.infra.dao.workerprofession.entity.WorkerProfessionHistory; +import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; + +import java.util.List; + +/** + * @Author zr + * @Date 2025/3/10 11:41 + * @Description + **/ +public interface OrgWorkerHistoryFoundationService { + void saveBatch(List history); + + void recordHistory(DeleteWorkerProfession req); +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgWorkerSkillTagFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgWorkerSkillTagFoundationService.java new file mode 100644 index 0000000..f4f95d2 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/OrgWorkerSkillTagFoundationService.java @@ -0,0 +1,17 @@ +package cn.axzo.orgmanax.server.workerprofession.foundation; + +import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; + +import java.util.List; + +/** + * @Author zr + * @Date 2025/3/10 14:15 + * @Description + **/ +public interface OrgWorkerSkillTagFoundationService { + + void removeByIds(List ids); + + void remove(DeleteWorkerProfession req); +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/dto/DeleteWorkerProfession.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/dto/DeleteWorkerProfession.java new file mode 100644 index 0000000..5dec67d --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/dto/DeleteWorkerProfession.java @@ -0,0 +1,48 @@ +package cn.axzo.orgmanax.server.workerprofession.foundation.dto; + +import cn.axzo.orgmanax.dto.common.util.NumberUtil; +import cn.hutool.core.collection.CollUtil; +import lombok.Builder; +import lombok.Data; + +import java.util.Set; + +/** + * @Author zr + * @Date 2025/3/10 10:26 + * @Description + **/ +@Data +@Builder +public class DeleteWorkerProfession { + + /** + * 部门id + */ + private Long orgNodeId; + + /** + * personId + */ + private Set personIds; + + /** + * 工种id + */ + private Set professionIds; + + /** + * PLAT_TEAM:平台班组,PROJECT_TEAM:项目内班组 + */ + private String scene; + + /** + * 是否离开单位或项目内 + */ + private Boolean isResign; + + public boolean isInvalid() { + return NumberUtil.isNotPositiveNumber(orgNodeId) + || CollUtil.isEmpty(personIds); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java new file mode 100644 index 0000000..b5a7004 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java @@ -0,0 +1,90 @@ +package cn.axzo.orgmanax.server.workerprofession.foundation.impl; + +import cn.axzo.orgmanax.infra.dao.workerprofession.entity.WorkerProfessionTag; +import cn.axzo.orgmanax.infra.dao.workerprofession.repository.WorkerProfessionTagRepository; +import cn.axzo.orgmanax.server.util.AssertUtil; +import cn.axzo.orgmanax.server.workerprofession.foundation.OrgProjectWorkerProfessionFoundationService; +import cn.axzo.orgmanax.server.workerprofession.foundation.OrgWorkerHistoryFoundationService; +import cn.axzo.orgmanax.server.workerprofession.foundation.OrgWorkerSkillTagFoundationService; +import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; +import cn.hutool.core.collection.CollUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Author zr + * @Date 2025/3/10 10:30 + * @Description + **/ +@Service +@Slf4j +@RequiredArgsConstructor +public class OrgProjectWorkerProfessionFoundationServiceImpl implements OrgProjectWorkerProfessionFoundationService { + private final WorkerProfessionTagRepository professionTagRepository; + private final OrgWorkerHistoryFoundationService historyFoundationService; + private final OrgWorkerSkillTagFoundationService skillTagFoundationService; + + + @Override + @Transactional(rollbackFor = Exception.class) + public void delete(DeleteWorkerProfession req) { + AssertUtil.isFalse(req.isInvalid(), String.format("无效的参数%s", req)); + // 记录工人当前的工种&技能标签历史 + historyFoundationService.recordHistory(req); + // 删除本身工种和技能标签 + doUpdateValid(req); + } + + + private void doUpdateValid(DeleteWorkerProfession req) { + // 校验当前待更新工种是否存在 + WorkerProfessionTagRepository.PageReq professionTagList = WorkerProfessionTagRepository.PageReq.builder() + .personIds(req.getPersonIds()) + .orgNodeId(req.getOrgNodeId()) + .professionIds(req.getProfessionIds()) + .scene(req.getScene()).build(); + List professionTagResps = professionTagRepository.list(professionTagList); + if (CollUtil.isEmpty(professionTagResps)) { + return; + } + // 记录工人当前的工种&技能标签历史 + historyFoundationService.recordHistory(req); + // 删除技能标签 + absoluteRemoveSkillTags(req); + // 删除工种 + absoluteRemoveProfession(req); + } + + + /** + * 删除工种 + * @param req + */ + private void absoluteRemoveProfession(DeleteWorkerProfession req) { + WorkerProfessionTagRepository.PageReq professionTagList = WorkerProfessionTagRepository.PageReq.builder() + .personIds(req.getPersonIds()) + .orgNodeId(req.getOrgNodeId()) + .professionIds(req.getProfessionIds()) + .scene(req.getScene()).build(); + List professionTagResps = professionTagRepository.list(professionTagList); + if (CollUtil.isEmpty(professionTagResps)) { + return; + } + List ids = professionTagResps.stream().map(WorkerProfessionTag::getId).collect(Collectors.toList()); + professionTagRepository.removeByIds(ids); + } + + /** + * 删除技能标签 + * @param req + */ + private void absoluteRemoveSkillTags(DeleteWorkerProfession req) { + skillTagFoundationService.remove(req); + } + +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java new file mode 100644 index 0000000..1a9bde2 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java @@ -0,0 +1,121 @@ +package cn.axzo.orgmanax.server.workerprofession.foundation.impl; + +import cn.axzo.orgmanax.dto.common.util.NumberUtil; +import cn.axzo.orgmanax.infra.dao.workerprofession.entity.WorkerProfessionHistory; +import cn.axzo.orgmanax.infra.dao.workerprofession.entity.WorkerProfessionSkillTag; +import cn.axzo.orgmanax.infra.dao.workerprofession.entity.WorkerProfessionTag; +import cn.axzo.orgmanax.infra.dao.workerprofession.repository.WorkerProfessionHistoryRepository; +import cn.axzo.orgmanax.infra.dao.workerprofession.repository.WorkerProfessionSkillTagRepository; +import cn.axzo.orgmanax.infra.dao.workerprofession.repository.WorkerProfessionTagRepository; +import cn.axzo.orgmanax.server.workerprofession.foundation.OrgWorkerHistoryFoundationService; +import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; +import cn.axzo.orgmanax.server.workerprofession.foundation.vo.ProfessionValidEnum; +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson.JSON; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static cn.axzo.orgmanax.infra.dao.workerprofession.repository.WorkerProfessionHistoryRepository.WorkerProfessionHistoryResp.DATA_FLAG_PROFESSION; +import static cn.axzo.orgmanax.infra.dao.workerprofession.repository.WorkerProfessionHistoryRepository.WorkerProfessionHistoryResp.DATA_FLAG_SKILL; + +/** + * @Author zr + * @Date 2025/3/10 11:44 + * @Description + **/ +@Service +@Slf4j +@RequiredArgsConstructor +public class OrgWorkerHistoryFoundationServiceImpl implements OrgWorkerHistoryFoundationService { + + private final WorkerProfessionHistoryRepository historyRepository; + private final WorkerProfessionTagRepository professionTagRepository; + private final WorkerProfessionSkillTagRepository skillTagRepository; + + + @Override + public void saveBatch(List histories) { + if (CollUtil.isEmpty(histories)) { + return; + } + historyRepository.saveBatch(histories); + } + + @Override + public void recordHistory(DeleteWorkerProfession req) { + if (NumberUtil.isNotPositiveNumber(req.getOrgNodeId()) || CollectionUtil.isEmpty(req.getPersonIds())) { + log.info("the param is invalid. orgNodeId:[{}], personIds:{}", req.getOrgNodeId(), req.getProfessionIds()); + return; + } + + // 查询批量用户当前的拥用的工种列表 + WorkerProfessionTagRepository.PageReq professionTagReq = WorkerProfessionTagRepository.PageReq.builder() + .personIds(req.getPersonIds()) + .orgNodeId(req.getOrgNodeId()) + .scene(req.getScene()).build(); + List professionTagResps = professionTagRepository.list(professionTagReq); + professionTagResps.forEach(w -> { + w.setIsDelete(w.getId()); + w.setValid(req.getIsResign().equals(Boolean.FALSE) ? ProfessionValidEnum.INVALID.getCode() : w.getValid()); + }); + if (CollUtil.isEmpty(professionTagResps)) { + log.info("the is not any profession of worker. orgNodeId:[{}], personIds:{}", req.getOrgNodeId(), req.getPersonIds()); + return; + } + + // 查询批量用户当前的技能标签列表 + WorkerProfessionSkillTagRepository.PageReq skillTagReq = WorkerProfessionSkillTagRepository.PageReq.builder() + .personIds(req.getPersonIds()) + .scene(req.getScene()) + .orgNodeIds(Sets.newHashSet(req.getOrgNodeId())).build(); + List skillTagResps = skillTagRepository.list(skillTagReq); + skillTagResps.forEach(w -> { + w.setIsDelete(w.getId()); + w.setValid(req.getIsResign().equals(Boolean.FALSE) ? ProfessionValidEnum.INVALID.getCode() : w.getValid()); + }); + + // 工种groupBy: personId + Map> professionGroupingByPerson = professionTagResps.stream() + .collect(Collectors.groupingBy(WorkerProfessionTag::getPersonId)); + // 技能标签groupBy: personId + Map> skillGroupingByPerson = skillTagResps.stream() + .collect(Collectors.groupingBy(WorkerProfessionSkillTag::getPersonId)); + // 数据压缩 + List histories = professionGroupingByPerson.entrySet().stream() + .map(e -> zipData(e.getValue(), skillGroupingByPerson.get(e.getKey()))) + .collect(Collectors.toList()); + // 记录历史 + saveBatch(histories); + } + + private WorkerProfessionHistory zipData(List professionTags, List professionSkillTags) { + WorkerProfessionTag first = professionTags.get(0); + log.info("zipData first :{}", first); + List> historyDataList = Lists.newArrayList(); + historyDataList.add(WorkerProfessionHistoryRepository.WorkerProfessionHistoryResp.HistoryData.builder() + .dataFlag(DATA_FLAG_PROFESSION) + .jsonStrData(professionTags) + .build()); + if (CollectionUtil.isNotEmpty(professionSkillTags)) { + historyDataList.add(WorkerProfessionHistoryRepository.WorkerProfessionHistoryResp.HistoryData.builder() + .dataFlag(DATA_FLAG_SKILL) + .jsonStrData(professionSkillTags) + .build()); + } + return WorkerProfessionHistory.builder() + .personId(first.getPersonId()) + .orgNodeId(first.getOrgNodeId()) + .workspaceId(first.getWorkspaceId()) + .bizData(first.getBizData()) + .jsonContent(JSON.toJSONString(historyDataList)) + .build(); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerSkillTagFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerSkillTagFoundationServiceImpl.java new file mode 100644 index 0000000..38a68db --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerSkillTagFoundationServiceImpl.java @@ -0,0 +1,51 @@ +package cn.axzo.orgmanax.server.workerprofession.foundation.impl; + +import cn.axzo.orgmanax.infra.dao.workerprofession.entity.WorkerProfessionSkillTag; +import cn.axzo.orgmanax.infra.dao.workerprofession.repository.WorkerProfessionSkillTagRepository; +import cn.axzo.orgmanax.server.workerprofession.foundation.OrgWorkerSkillTagFoundationService; +import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; +import cn.hutool.core.collection.CollUtil; +import com.google.common.collect.Sets; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Author zr + * @Date 2025/3/10 14:16 + * @Description + **/ + +@Service +@Slf4j +@RequiredArgsConstructor +public class OrgWorkerSkillTagFoundationServiceImpl implements OrgWorkerSkillTagFoundationService { + + private final WorkerProfessionSkillTagRepository skillTagRepository; + + @Override + public void removeByIds(List ids) { + if (CollUtil.isEmpty(ids)) { + return; + } + skillTagRepository.removeByIds(ids); + } + + @Override + public void remove(DeleteWorkerProfession req) { + WorkerProfessionSkillTagRepository.PageReq pageReq = WorkerProfessionSkillTagRepository.PageReq.builder() + .personIds(req.getPersonIds()) + .orgNodeIds(Sets.newHashSet(req.getOrgNodeId())) + .professionIds(CollUtil.isEmpty(req.getProfessionIds()) ? null : req.getProfessionIds()) + .scene(req.getScene()).build(); + List skillTagResps = skillTagRepository.list(pageReq); + if (CollUtil.isEmpty(skillTagResps)) { + return; + } + List ids = skillTagResps.stream().map(WorkerProfessionSkillTag::getId).collect(Collectors.toList()); + removeByIds(ids); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/vo/ProfessionValidEnum.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/vo/ProfessionValidEnum.java new file mode 100644 index 0000000..4bfb497 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/vo/ProfessionValidEnum.java @@ -0,0 +1,27 @@ +package cn.axzo.orgmanax.server.workerprofession.foundation.vo; + +import lombok.Getter; + +/** + * @Author zr + * @Date 2024/1/19 15:14 + * @Description + **/ +@Getter +public enum ProfessionValidEnum { + + EFFECTIVE(1,"有效"), + + INVALID(0,"无效"), + + ALL(2,"所有"), + ; + + public Integer code; + public String desc; + + ProfessionValidEnum(Integer code, String desc) { + this.code = code; + this.desc = desc; + } +} From 87355af0bebb2d3f09165a94098762bb37e429dd Mon Sep 17 00:00:00 2001 From: zhangran Date: Mon, 10 Mar 2025 15:09:48 +0800 Subject: [PATCH 19/75] =?UTF-8?q?add(feature/REQ-3714)=20=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E9=80=9A=E7=94=A8=E5=88=A0=E9=99=A4=E4=BA=BA=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../processor/impl/DeletePlatTeamWorkerProcessor.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index bf49146..88c504b 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -90,16 +90,8 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { log.error("获取企业下班组与平台班组关系失败, nodeId:{}", nodeId); }); } - // 调用统用删除逻辑 - NodeUserDelete nodeUserDelete = NodeUserDelete.builder().ouId(param.getOuId()) - .workspaceId(param.getWorkspaceId()) - .personIds(Lists.newArrayList(param.getPersonIds())) - .operatorId(context.getOperatorId()) - .isUnitDelete(Boolean.TRUE) - .build(); - List delete = nodeUserFoundationService.delete(nodeUserDelete); - return ProcessResult.success((JSONObject) JSON.toJSON(delete)); + return ProcessResult.success(); } } From 4cde75d0301104b38eb9266979659ed9367e3652 Mon Sep 17 00:00:00 2001 From: zhangran Date: Mon, 10 Mar 2025 15:12:02 +0800 Subject: [PATCH 20/75] =?UTF-8?q?add(feature/REQ-3714)=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=89=93=E5=8D=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/processor/impl/DeletePlatTeamWorkerProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index 88c504b..b80150a 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -66,6 +66,7 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { .collect(Collectors.toMap(OrganizationalTeamOuRelation::getNodeId, Function.identity(), (x, y) -> x)); // 获取平台班组下的工人 if (CollUtil.isNotEmpty(teamOuRelationMap)) { + log.info("DeletePlatTeamWorkerProcessor process teamOuRelationMap:{}", JSON.toJSONString(teamOuRelationMap)); nodeUserMap.forEach((nodeId, vs) -> { OrganizationalTeamOuRelation ouRelation = teamOuRelationMap.get(nodeId); if (Objects.nonNull(ouRelation)) { From 4a6dfe15273752421be2c67d294abea288756fa1 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Mon, 10 Mar 2025 15:35:00 +0800 Subject: [PATCH 21/75] =?UTF-8?q?feat(REQ-3714):=20=E5=8D=8F=E5=90=8C?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/service/impl/NodeUserCheckServiceImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index b4b421b..ce880a2 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -514,6 +514,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { ListOrgCooperateShipReq saasCooperateShipQueryReq = ListOrgCooperateShipReq.builder() .organizationNodeIds(ImmutableSet.of(nodeId)) .includeAncestors(true) + .workspaceTypes(CollUtil.newHashSet(2)) .build(); List nodes = cooperateShipService.list(saasCooperateShipQueryReq); return nodes.stream().filter(n -> Objects.equals(n.getCooperateType(), CooperateShipTypeEnum.PROJ_TEAM.getCode())).findFirst() From 179d6a391449f091e253cc731f7db03c2a73b4fb Mon Sep 17 00:00:00 2001 From: zhangran Date: Mon, 10 Mar 2025 15:58:48 +0800 Subject: [PATCH 22/75] =?UTF-8?q?add(feature/REQ-3714)=20=E9=80=80?= =?UTF-8?q?=E5=87=BA=E7=8F=AD=E7=BB=84=E6=97=B6=EF=BC=8C=E5=8C=BA=E5=88=86?= =?UTF-8?q?=E5=B7=A5=E7=A7=8D=E9=9C=80=E8=A6=81=E7=89=A9=E7=90=86=E5=88=A0?= =?UTF-8?q?=E6=88=96=E9=80=BB=E8=BE=91=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WorkerProfessionSkillTagRepository.java | 2 ++ .../WorkerProfessionTagRepository.java | 6 ++++++ ...WorkerProfessionSkillTagRepositoryImpl.java | 18 +++++++++++++++++- .../WorkerProfessionTagRepositoryImpl.java | 15 +++++++++++++++ ...tWorkerProfessionFoundationServiceImpl.java | 6 ++++++ ...OrgWorkerSkillTagFoundationServiceImpl.java | 6 ++++++ 6 files changed, 52 insertions(+), 1 deletion(-) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionSkillTagRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionSkillTagRepository.java index bbcc0ee..4d0d9a4 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionSkillTagRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionSkillTagRepository.java @@ -23,6 +23,8 @@ public interface WorkerProfessionSkillTagRepository { void removeByIds(List ids); + void deleteByIds(List ids); + default List list(PageReq req) { return page(req).getData(); } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionTagRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionTagRepository.java index 644c0c4..a7e5f59 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionTagRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/WorkerProfessionTagRepository.java @@ -26,6 +26,12 @@ public interface WorkerProfessionTagRepository { */ void removeByIds(List ids); + /** + * 软删 + * @param ids + */ + void deleteByIds(List ids); + default List list(PageReq req) { return page(req).getData(); } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java index 8b8e1a4..4f1ff6d 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java @@ -18,6 +18,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.stream.Collectors; /** * @author zhanghongbo @@ -49,7 +50,22 @@ public class WorkerProfessionSkillTagRepositoryImpl implements WorkerProfessionS } @Override - public void removeByIds(List ids) { + public void removeByIds(List ids) { workerProfessionSkillTagDao.removeByIds(ids); } + + @Override + public void deleteByIds(List ids) { + if (CollUtil.isEmpty(ids)) { + return; + } + + List delete = ids.stream().map(id -> { + WorkerProfessionSkillTag workerProfessionSkillTag = new WorkerProfessionSkillTag(); + workerProfessionSkillTag.setId(id); + workerProfessionSkillTag.setIsDelete(id); + return workerProfessionSkillTag; + }).collect(Collectors.toList()); + workerProfessionSkillTagDao.updateBatchById(delete); + } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java index 8ae8827..e4fc239 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java @@ -17,6 +17,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.stream.Collectors; /** * @author zhanghongbo @@ -51,4 +52,18 @@ public class WorkerProfessionTagRepositoryImpl implements WorkerProfessionTagRep public void removeByIds(List ids){ workerProfessionTagDao.removeByIds(ids); } + + @Override + public void deleteByIds(List ids){ + if (CollUtil.isEmpty(ids)) { + return ; + } + List delete = ids.stream().map(id -> { + WorkerProfessionTag workerProfessionTag = new WorkerProfessionTag(); + workerProfessionTag.setId(id); + workerProfessionTag.setIsDelete(id); + return workerProfessionTag; + }).collect(Collectors.toList()); + workerProfessionTagDao.updateBatchById(delete); + } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java index b5a7004..a9f4ec6 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java @@ -76,6 +76,12 @@ public class OrgProjectWorkerProfessionFoundationServiceImpl implements OrgProje return; } List ids = professionTagResps.stream().map(WorkerProfessionTag::getId).collect(Collectors.toList()); + // 工人离开平台班组、项目内班组软删工种 + if (Boolean.TRUE.equals(req.getIsResign())){ + professionTagRepository.deleteByIds(ids); + return ; + } + // 物理删除工种 professionTagRepository.removeByIds(ids); } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerSkillTagFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerSkillTagFoundationServiceImpl.java index 38a68db..1046c5e 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerSkillTagFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerSkillTagFoundationServiceImpl.java @@ -46,6 +46,12 @@ public class OrgWorkerSkillTagFoundationServiceImpl implements OrgWorkerSkillTag return; } List ids = skillTagResps.stream().map(WorkerProfessionSkillTag::getId).collect(Collectors.toList()); + // 退出平台班组、项目内班组时,技能标签软删 + if (Boolean.TRUE.equals(req.getIsResign())){ + skillTagRepository.deleteByIds(ids); + return ; + } + removeByIds(ids); } } From 2b4dfa50a8a8adf9d7c21abb67d523e8d1c68cc8 Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 10 Mar 2025 16:27:55 +0800 Subject: [PATCH 23/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20or?= =?UTF-8?q?ganizational=5Fnode=5Fuser=5Fextra=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OrganizationalNodeUserStatusEnum.java | 102 ++++++++ .../dto/nodeuser/enums/TagOperateEnum.java | 17 ++ .../dto/nodeuser/req/TagOperateReq.java | 46 ++++ .../orgmanax/dto/orguser/dto/OrgUserDTO.java | 7 + .../config/type/LongListTypeHandler.java | 12 + .../config/type/StringSetTypeHandler.java | 12 + .../dao/nodeuser/dao/NodeUserExtraDao.java | 32 +++ .../entity/OrganizationalNodeUserExtra.java | 223 ++++++++++++++++++ .../OrganizationalNodeUserExtraMapper.java | 15 ++ .../infra/dao/orguser/dao/OrgUserDao.java | 15 ++ .../infra/dao/orguser/entity/OrgUser.java | 11 +- 11 files changed, 491 insertions(+), 1 deletion(-) create mode 100644 orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/OrganizationalNodeUserStatusEnum.java create mode 100644 orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/TagOperateEnum.java create mode 100644 orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/TagOperateReq.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/type/LongListTypeHandler.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/type/StringSetTypeHandler.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/dao/NodeUserExtraDao.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/mapper/OrganizationalNodeUserExtraMapper.java diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/OrganizationalNodeUserStatusEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/OrganizationalNodeUserStatusEnum.java new file mode 100644 index 0000000..b53fa01 --- /dev/null +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/OrganizationalNodeUserStatusEnum.java @@ -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 onDutyStatus() { + return Lists.newArrayList(ON_DUTY_STATUS); + } + + public static Set parseStatus(Collection 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 ON_DUTY_STATUS = ImmutableList.of( + OrganizationalNodeUserStatusEnum.ON_DUTY, + OrganizationalNodeUserStatusEnum.JOINED, + OrganizationalNodeUserStatusEnum.ACTIVE + ); + + public OrgUserStatusEnum toOrgUserStatusEnum() { + return OrgUserStatusEnum.valueOf(this.name()); + } +} \ No newline at end of file diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/TagOperateEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/TagOperateEnum.java new file mode 100644 index 0000000..c312f40 --- /dev/null +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/TagOperateEnum.java @@ -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; +} diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/TagOperateReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/TagOperateReq.java new file mode 100644 index 0000000..f4790c9 --- /dev/null +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/TagOperateReq.java @@ -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 personIds; + + /** + * 分组标签编码 + */ + @NotNull(message = "分组标签编码不能为空") + private String tagNodeCode; + + /** + * 标签值编码 + */ + @NotNull(message = "标签值编码不能为空") + private String tagValueCode; + + /** + * 操作类型 + */ + private TagOperateEnum operateType; + +} \ No newline at end of file diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/orguser/dto/OrgUserDTO.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/orguser/dto/OrgUserDTO.java index 1fbe9bd..e03cb75 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/orguser/dto/OrgUserDTO.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/orguser/dto/OrgUserDTO.java @@ -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 tags; } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/type/LongListTypeHandler.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/type/LongListTypeHandler.java new file mode 100644 index 0000000..a54431e --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/type/LongListTypeHandler.java @@ -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 { +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/type/StringSetTypeHandler.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/type/StringSetTypeHandler.java new file mode 100644 index 0000000..ab7d55a --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/type/StringSetTypeHandler.java @@ -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 { +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/dao/NodeUserExtraDao.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/dao/NodeUserExtraDao.java new file mode 100644 index 0000000..c21da7c --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/dao/NodeUserExtraDao.java @@ -0,0 +1,32 @@ +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; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; +import java.util.Set; + +/** + * @author luofu + * @date 2025/3/10 + */ +@Repository("organizationalNodeUserExtraDao") +public class NodeUserExtraDao extends ServiceImpl { + + @Transactional(rollbackFor = Exception.class) + public void updateTagsMap(Map> idTagsMap) { + for (Map.Entry> setEntry : idTagsMap.entrySet()) { + updateTagsSet(setEntry.getKey(), setEntry.getValue()); + } + } + + private void updateTagsSet(Long id, Set tagsSet) { + OrganizationalNodeUserExtra entity = new OrganizationalNodeUserExtra(); + entity.setId(id); + entity.setTags(tagsSet); + updateById(entity); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java new file mode 100644 index 0000000..2056d67 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java @@ -0,0 +1,223 @@ +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.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; +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 +@EqualsAndHashCode(callSuper = false) +@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 topNodeIds; + + /** + * 直属主管ID + */ + @TableField("direct_manager_person_id") + private Long directManagerPersonId; + + /** + * 部门ID + */ + @TableField(value = "node_ids", typeHandler = LongListTypeHandler.class) + private List nodeIds; + + /** + * 岗位IDs + */ + @TableField(value = "job_ids", typeHandler = LongListTypeHandler.class) + private List jobIds; + + /** + * 标签 + */ + @TableField(value = "tags", typeHandler = StringSetTypeHandler.class) + private Set tags; + + /** + * 部门信息 + */ + @TableField(value = "node_info", typeHandler = ListOrganizationNodeUserExtraNodeInfoHandler.class) + private List 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; + + public List determineJobIds() { + if (CollectionUtils.isEmpty(jobIds)) + return Collections.emptyList(); + return jobIds; + } + + public List 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 { + } + +} + diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/mapper/OrganizationalNodeUserExtraMapper.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/mapper/OrganizationalNodeUserExtraMapper.java new file mode 100644 index 0000000..d327e05 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/mapper/OrganizationalNodeUserExtraMapper.java @@ -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 { +} \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/dao/OrgUserDao.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/dao/OrgUserDao.java index b2cf4e1..82fd572 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/dao/OrgUserDao.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/dao/OrgUserDao.java @@ -4,8 +4,23 @@ import cn.axzo.orgmanax.infra.dao.orguser.entity.OrgUser; import cn.axzo.orgmanax.infra.dao.orguser.mapper.OrgUserMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; +import java.util.Set; @Repository public class OrgUserDao extends ServiceImpl { + @Transactional(rollbackFor = Exception.class) + public void updateTagsMap(Map> idTagsMap) { + for (Map.Entry> setEntry : idTagsMap.entrySet()) { + updateTagsSet(setEntry.getKey(), setEntry.getValue()); + } + } + + private void updateTagsSet(Long id, Set tagsSet) { + OrgUser entity = OrgUser.builder().id(id).tags(tagsSet).build(); + updateById(entity); + } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/entity/OrgUser.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/entity/OrgUser.java index 97b798d..267936a 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/entity/OrgUser.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/entity/OrgUser.java @@ -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 tags; } From f9cc9d050c50ff21f098315708f3ab4dc6ad6e9c Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Mon, 10 Mar 2025 17:43:34 +0800 Subject: [PATCH 24/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86works?= =?UTF-8?q?paceCheck?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index ce880a2..bd38b66 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -204,6 +204,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { ListNodeUserReq query = ListNodeUserReq.builder() .topNodeIds(nodeIds) .personIds(nodePersonIds) + .needs(ListNodeUserReq.Needs.builder().job(true).build()) .findByAncestorNodeId(true) .build(); // 查询当前登录及待删除人员在当前项目中的参与记录(仅限当前登录单位) @@ -212,7 +213,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { checkPermission(nodeUsers, personId); // 过滤当前操作人员 nodeUsers = nodeUsers.stream() - .filter(e -> req.getPersonIds().contains(e.getPersonId())) + .filter(e -> !req.getPersonIds().contains(personId)) .collect(Collectors.toList()); if (CollectionUtil.isEmpty(nodeUsers)) { req.getPersonIds().forEach(e -> { @@ -303,6 +304,9 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } private void checkIndependentGroupLeader(List nodeUsers, Map> failInfoMap) { + if (CollUtil.isEmpty(nodeUsers)) { + return; + } Set nodeIdList = nodeUsers.stream().map(NodeUserDTO::getOrganizationalNodeId).collect(Collectors.toSet()); ListNodeReq nodeBatchQueryVO = new ListNodeReq(); nodeBatchQueryVO.setIds(nodeIdList); From 3729d623ed369c44d902eabf82e9453f34986aab Mon Sep 17 00:00:00 2001 From: luofu Date: Mon, 10 Mar 2025 17:48:33 +0800 Subject: [PATCH 25/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20or?= =?UTF-8?q?ganizational=5Fnode=5Fuser=5Fextra=20repository=20impl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/orguser/req/ListOrgUserReq.java | 14 +- .../dao/nodeuser/dao/NodeUserExtraDao.java | 18 -- .../entity/OrganizationalNodeUserExtra.java | 10 +- .../NodeUserExtraQueryRepository.java | 187 ++++++++++++++++++ .../NodeUserExtraUpsertRepository.java | 45 +++++ .../NodeUserExtraQueryRepositoryImpl.java | 84 ++++++++ .../NodeUserExtraUpsertRepositoryImpl.java | 61 ++++++ .../infra/dao/orguser/dao/OrgUserDao.java | 16 -- .../repository/OrgUserUpsertRepository.java | 8 + .../impl/OrgUserQueryRepositoryImpl.java | 7 +- .../impl/OrgUserUpsertRepositoryImpl.java | 18 ++ 11 files changed, 427 insertions(+), 41 deletions(-) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserExtraQueryRepository.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserExtraUpsertRepository.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserExtraQueryRepositoryImpl.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserExtraUpsertRepositoryImpl.java diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/orguser/req/ListOrgUserReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/orguser/req/ListOrgUserReq.java index 2e43797..fbfc4c8 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/orguser/req/ListOrgUserReq.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/orguser/req/ListOrgUserReq.java @@ -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 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; } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/dao/NodeUserExtraDao.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/dao/NodeUserExtraDao.java index c21da7c..885d790 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/dao/NodeUserExtraDao.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/dao/NodeUserExtraDao.java @@ -4,10 +4,6 @@ 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; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Map; -import java.util.Set; /** * @author luofu @@ -15,18 +11,4 @@ import java.util.Set; */ @Repository("organizationalNodeUserExtraDao") public class NodeUserExtraDao extends ServiceImpl { - - @Transactional(rollbackFor = Exception.class) - public void updateTagsMap(Map> idTagsMap) { - for (Map.Entry> setEntry : idTagsMap.entrySet()) { - updateTagsSet(setEntry.getKey(), setEntry.getValue()); - } - } - - private void updateTagsSet(Long id, Set tagsSet) { - OrganizationalNodeUserExtra entity = new OrganizationalNodeUserExtra(); - entity.setId(id); - entity.setTags(tagsSet); - updateById(entity); - } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java index 2056d67..c0fd5bb 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java @@ -13,7 +13,6 @@ import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; -import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import lombok.experimental.Accessors; import org.apache.commons.collections4.CollectionUtils; @@ -31,7 +30,9 @@ import java.util.Set; * @since 2025/3/7 */ @Data -@EqualsAndHashCode(callSuper = false) +@Builder +@NoArgsConstructor +@AllArgsConstructor @Accessors(chain = true) @TableName(value = "organizational_node_user_extra", autoResultMap = true) public class OrganizationalNodeUserExtra implements Serializable { @@ -162,6 +163,11 @@ public class OrganizationalNodeUserExtra implements Serializable { */ private Date updateAt; + /** + * 状态 0正常 其它删除 + */ + private Long isDelete = 0L; + public List determineJobIds() { if (CollectionUtils.isEmpty(jobIds)) return Collections.emptyList(); diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserExtraQueryRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserExtraQueryRepository.java new file mode 100644 index 0000000..153afc6 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserExtraQueryRepository.java @@ -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 page(ListReq req); + + default List list(ListReq req) { + req.setSearchCount(false); + return page(req).getData(); + } + + default NodeUserExtraResp one(OneReq req) { + return oneOpt(req).orElse(null); + } + + default Optional 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 ids; + + /** + * 自然人id + */ + @CriteriaField + private Long personId; + @CriteriaField(field = "personId", operator = Operator.IN) + private Collection personIds; + @CriteriaField(field = "personId", operator = Operator.NOT_IN) + private Collection excludePersonIds; + + /** + * 主电话 + */ + @CriteriaField + private String phone; + @CriteriaField(field = "phone", operator = Operator.NOT_IN) + private Collection 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 idNumbers; + + /** + * 单位id + */ + @CriteriaField + private Long organizationalUnitId; + @CriteriaField(field = "organizationalUnitId", operator = Operator.IN) + private Collection organizationalUnitIds; + + /** + * 工作台ID + */ + @CriteriaField + private Long workspaceId; + @CriteriaField(field = "workspaceId", operator = Operator.IN) + private Collection 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。用 idNumber,phone,jobNumber精确匹配,或者realName模糊匹配 + */ + @CriteriaField(ignore = true) + private String keyword; + + @CriteriaField(field = "extra", operator = Operator.JSON_QUERY) + private Collection extraQueries; + + + @CriteriaField(ignore = true) + private List> 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 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; + } + +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserExtraUpsertRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserExtraUpsertRepository.java new file mode 100644 index 0000000..f6f1353 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserExtraUpsertRepository.java @@ -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> idTagsMap); + + @EqualsAndHashCode(callSuper = true) + @NoArgsConstructor + @AllArgsConstructor + @Data + @SuperBuilder + class UpdateReq extends OrganizationalNodeUserExtra { + /** + * 由于updateById不支持将值设置为null,这里提供这个 + */ + Set> setNullFields = new HashSet<>(); + + public void check() { + Axssert.checkNonNull(getId(), "要更新的部门id不能为空"); + } + } + +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserExtraQueryRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserExtraQueryRepositoryImpl.java new file mode 100644 index 0000000..2cfe1ba --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserExtraQueryRepositoryImpl.java @@ -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 page(ListReq req) { + IPage page = PageConverter.toMybatis(req, OrganizationalNodeUserExtra.class); + PageResp emptyPage = PageResp.builder() + .size(req.getPageSize()) + .current(req.getPage()).total(0L) + .data(ImmutableList.of()) + .build(); + LambdaQueryWrapper 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 results = nodeUserExtraDao.page(page, wrapper) + .convert(e -> BeanUtil.toBean(e, NodeUserExtraQueryRepository.NodeUserExtraResp.class)); + if (CollUtil.isEmpty(results.getRecords())) { + return emptyPage; + } + PageResp resp = PageConverter.toResp(results); + List records = resp.getData(); + if (CollUtil.isEmpty(records)) { + return resp; + } + return resp; + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserExtraUpsertRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserExtraUpsertRepositoryImpl.java new file mode 100644 index 0000000..89c5b26 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserExtraUpsertRepositoryImpl.java @@ -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 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> idTagsMap) { + if (CollUtil.isEmpty(idTagsMap)) { + return; + } + List updateEntities = idTagsMap.entrySet().stream() + .map(e -> OrganizationalNodeUserExtra.builder() + .id(e.getKey()) + .tags(e.getValue()) + .build()) + .collect(Collectors.toList()); + nodeUserExtraDao.updateBatchById(updateEntities); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/dao/OrgUserDao.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/dao/OrgUserDao.java index 82fd572..d1b14e6 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/dao/OrgUserDao.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/dao/OrgUserDao.java @@ -4,23 +4,7 @@ import cn.axzo.orgmanax.infra.dao.orguser.entity.OrgUser; import cn.axzo.orgmanax.infra.dao.orguser.mapper.OrgUserMapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; - -import java.util.Map; -import java.util.Set; @Repository public class OrgUserDao extends ServiceImpl { - - @Transactional(rollbackFor = Exception.class) - public void updateTagsMap(Map> idTagsMap) { - for (Map.Entry> setEntry : idTagsMap.entrySet()) { - updateTagsSet(setEntry.getKey(), setEntry.getValue()); - } - } - - private void updateTagsSet(Long id, Set tagsSet) { - OrgUser entity = OrgUser.builder().id(id).tags(tagsSet).build(); - updateById(entity); - } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/OrgUserUpsertRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/OrgUserUpsertRepository.java index 4bba255..accc538 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/OrgUserUpsertRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/OrgUserUpsertRepository.java @@ -4,10 +4,18 @@ 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 orgUsers); + /** + * 批量设置用户标签 + * + * @param idTagsMap key:id, value:标签集合 + */ + void updateTagsMap(Map> idTagsMap); } \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserQueryRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserQueryRepositoryImpl.java index 0ae7e7f..55605a3 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserQueryRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserQueryRepositoryImpl.java @@ -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 results = orgUserDao.page(page, wrapper) .convert(e -> BeanUtil.toBean(e, OrgUserResp.class)); diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserUpsertRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserUpsertRepositoryImpl.java index 7975b88..f97d8a8 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserUpsertRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/orguser/repository/impl/OrgUserUpsertRepositoryImpl.java @@ -3,10 +3,14 @@ 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 @@ -19,4 +23,18 @@ public class OrgUserUpsertRepositoryImpl implements OrgUserUpsertRepository { orgUserDao.updateBatchById(orgUsers); } + @Override + public void updateTagsMap(Map> idTagsMap) { + if (CollUtil.isEmpty(idTagsMap)) { + return; + } + List updateEntities = idTagsMap.entrySet().stream() + .map(e -> OrgUser.builder() + .id(e.getKey()) + .tags(e.getValue()) + .build()) + .collect(Collectors.toList()); + batchUpdate(updateEntities); + } + } \ No newline at end of file From f4b9603c232d886b9246c1574ab00a2c38e47d91 Mon Sep 17 00:00:00 2001 From: zhangran Date: Mon, 10 Mar 2025 20:40:09 +0800 Subject: [PATCH 26/75] =?UTF-8?q?add(feature/REQ-3714)=20=E5=88=A4?= =?UTF-8?q?=E6=96=ADnodeuser=E4=B8=BA=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/processor/impl/DeletePlatTeamWorkerProcessor.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index b80150a..5b1e0c8 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -55,6 +55,9 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { .organizationalUnitId(param.getOuId()) .personIds(param.getPersonIds()).build(); List nodeUserDTOS = nodeUserService.list(nodeUserReq); + if (CollUtil.isEmpty(nodeUserDTOS)) { + return ProcessResult.success(); + } List nodeIds = nodeUserDTOS.stream().map(NodeUserDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList()); Map> nodeUserMap = nodeUserDTOS.stream().collect(Collectors.groupingBy(NodeUserDTO::getOrganizationalNodeId)); From 8a57412191581e848110f5717ee5496d018ab2f9 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Mon, 10 Mar 2025 20:43:22 +0800 Subject: [PATCH 27/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java index c0fd5bb..e87d9e8 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/entity/OrganizationalNodeUserExtra.java @@ -15,6 +15,7 @@ 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; @@ -30,7 +31,7 @@ import java.util.Set; * @since 2025/3/7 */ @Data -@Builder +@SuperBuilder @NoArgsConstructor @AllArgsConstructor @Accessors(chain = true) From 2bc32fd0d73a8cb9f067d17695d1004a5ce3def9 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Mon, 10 Mar 2025 20:52:27 +0800 Subject: [PATCH 28/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86node?= =?UTF-8?q?=5Fuser=E6=89=B9=E9=87=8F=E5=88=A0=E9=99=A4=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/processor/NodeUserProcessor.java | 17 +++++++++++------ .../impl/UnitDeleteNodeUserProcessor.java | 7 ++++--- .../impl/WorkspaceDeleteNodeUserProcessor.java | 7 ++++--- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/NodeUserProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/NodeUserProcessor.java index 68c21e9..a8b39a8 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/NodeUserProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/NodeUserProcessor.java @@ -2,13 +2,9 @@ package cn.axzo.orgmanax.server.nodeuser.service.processor; import cn.axzo.orgmanax.dto.nodeuser.req.ProcessNodeUserReq; import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository; +import com.alibaba.fastjson.JSONArray; 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 org.springframework.transaction.annotation.Transactional; import java.util.Optional; @@ -44,6 +40,8 @@ public interface NodeUserProcessor { JSONObject context; + JSONArray arrayContext; + public static ProcessResult success() { return success(null); } @@ -55,6 +53,13 @@ public interface NodeUserProcessor { .build(); } + public static ProcessResult arraySuccess(JSONArray context) { + return ProcessResult.builder() + .success(true) + .arrayContext(Optional.ofNullable(context).orElse(new JSONArray(0))) + .build(); + } + public static ProcessResult fail() { return fail(null); } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/UnitDeleteNodeUserProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/UnitDeleteNodeUserProcessor.java index 6bbb603..b30ca8f 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/UnitDeleteNodeUserProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/UnitDeleteNodeUserProcessor.java @@ -4,7 +4,8 @@ import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser; import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete; import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor; -import com.alibaba.fastjson.JSONObject; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSONArray; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -27,8 +28,8 @@ public class UnitDeleteNodeUserProcessor implements NodeUserProcessor { NodeUserDelete nodeUserDelete = context.getParams().toJavaObject(NodeUserDelete.class); nodeUserDelete.setUnitDelete(true); List nodeUserList = nodeUserFoundationService.delete(nodeUserDelete); - + JSONArray jsonArray = JSONArray.parseArray(JSONUtil.toJsonStr(nodeUserList)); // 返回数据 - return ProcessResult.success((JSONObject) JSONObject.toJSON(nodeUserList)); + return ProcessResult.arraySuccess(jsonArray); } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/WorkspaceDeleteNodeUserProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/WorkspaceDeleteNodeUserProcessor.java index ddb0408..56b904e 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/WorkspaceDeleteNodeUserProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/WorkspaceDeleteNodeUserProcessor.java @@ -4,7 +4,8 @@ import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser; import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete; import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor; -import com.alibaba.fastjson.JSONObject; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSONArray; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; @@ -25,8 +26,8 @@ public class WorkspaceDeleteNodeUserProcessor implements NodeUserProcessor { // 转成该处理器关注的参数对象 NodeUserDelete nodeUserDelete = context.getParams().toJavaObject(NodeUserDelete.class); List nodeUserList = nodeUserFoundationService.delete(nodeUserDelete); - + JSONArray jsonArray = JSONArray.parseArray(JSONUtil.toJsonStr(nodeUserList)); // 返回数据 - return ProcessResult.success((JSONObject) JSONObject.toJSON(nodeUserList)); + return ProcessResult.arraySuccess(jsonArray); } } From 680a081cb448f3bdb77af5109228d2e924defebc Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 09:39:34 +0800 Subject: [PATCH 29/75] =?UTF-8?q?feat(REQ-3714):=20=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=86=85=E5=B7=A5=E4=BA=BA=E9=80=80=E5=9C=BA=EF=BC=8C=E4=B8=8D?= =?UTF-8?q?=E6=9F=A5ouId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java | 1 - 1 file changed, 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index 1b5246d..8a28e4c 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -187,7 +187,6 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService //项目内工人退场 OrgProjectWorkerWithdrawReq workerReq = new OrgProjectWorkerWithdrawReq(); - workerReq.setOuId(req.getOuId()); workerReq.setWorkspaceId(req.getWorkspaceId()); if (req.isUnitDelete()) { workerReq.setWorkspaceId(nodeUserList.get(0).getWorkspaceId()); From 472b124888d81ea7c6a99a5f8507ce8ff3df04a9 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 09:46:04 +0800 Subject: [PATCH 30/75] =?UTF-8?q?feat(REQ-3714):=20=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java index 41bbc11..3c83dde 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java @@ -13,7 +13,7 @@ import java.util.stream.Collectors; @AllArgsConstructor(access = AccessLevel.PRIVATE) public enum CheckInfoTypeEnum { - SUPER_ADMIN(1, "超级管理员", "【%s】是超级管理员,无法删除!", 0), + SUPER_ADMIN(1, "超级管理员", "【%s】,是超级管理员,无法删除!", 0), IN_PROJECT(2, "在项目中", "【%s】,在项目中,无法删除!", 0), TEAM_LEADER(3, "班组长", "【%s】,是班组长,无法删除!", 0), PROJECT_GROUP_LEADER(4, "合作小组小组长", "【%s】,是项目组组长,无法删除!", 0), From 452dabd55a58284d66f538607c1bc728dfeb5b9e Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 10:22:27 +0800 Subject: [PATCH 31/75] =?UTF-8?q?feat(REQ-3714):=20=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java index 3c83dde..e2df81e 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java @@ -13,11 +13,11 @@ import java.util.stream.Collectors; @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), + 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), From bd1367bf01378404fd8d4ca52390fa5e129c6da6 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 10:23:10 +0800 Subject: [PATCH 32/75] =?UTF-8?q?feat(REQ-3714):=20=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/foundation/NodeUserFoundationService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java index ee98c9e..59781fd 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java @@ -31,7 +31,7 @@ public interface NodeUserFoundationService { OrganizationalNodeUser update(NodeUserUpdate req); /** - * 该接口为更新的收口接口,业务使用的时候,需要自行做业务判断 + * 该接口为删除的收口接口,业务使用的时候,需要自行做业务判断 * * @param req * @return From 15997039a86e7a00b6140af1a03152c6a3f310bd Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 11:12:03 +0800 Subject: [PATCH 33/75] =?UTF-8?q?feat(REQ-3714):=20=E4=BD=BF=E7=94=A8topNo?= =?UTF-8?q?deIds=E6=9F=A5=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foundation/impl/NodeUserFoundationServiceImpl.java | 9 ++++++--- .../server/nodeuser/foundation/req/NodeUserDelete.java | 5 +++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index 8a28e4c..e73b7c2 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -161,9 +161,12 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService @Override public List delete(NodeUserDelete req) { checkDeleteReq(req); - List list = nodeUserQueryRepository.list( - NodeUserQueryRepository.ListReq.builder().organizationalUnitId(req.getOuId()) - .workspaceId(req.getWorkspaceId()).personIds(req.getPersonIds()).identityType(req.getIdentityType()).build()); + List 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(); } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java index 689f1f4..9244213 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/req/NodeUserDelete.java @@ -33,6 +33,11 @@ public class NodeUserDelete { */ private Integer identityType; + /** + * 顶级节点 + */ + private List topNodeIds; + public OrganizationalNodeUser toEntity() { return BeanUtil.toBean(this, OrganizationalNodeUser.class); } From de4f798cc0c6665709c00be2b6caad591dab03de Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 13:38:22 +0800 Subject: [PATCH 34/75] =?UTF-8?q?feat(REQ-3714):=20=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E4=BA=BA=E5=91=98=E5=89=8D=E7=BD=AE=E8=AF=B7?= =?UTF-8?q?=E6=B1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/NodeUserCheckServiceImpl.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index bd38b66..827bbe1 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -210,18 +210,22 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { // 查询当前登录及待删除人员在当前项目中的参与记录(仅限当前登录单位) List nodeUsers = nodeUserService.list(query); // 校验当前入参 - checkPermission(nodeUsers, personId); + checkPermission(nodeUsers, personId, failInfoMap); // 过滤当前操作人员 nodeUsers = nodeUsers.stream() - .filter(e -> !req.getPersonIds().contains(personId)) + .filter(e -> !Objects.equals(e.getPersonId(), personId)) .collect(Collectors.toList()); - if (CollectionUtil.isEmpty(nodeUsers)) { + if (CollUtil.isEmpty(nodeUsers)) { req.getPersonIds().forEach(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); addFailInfo(failInfoMap, e, checkFailInfo); }); } + if (CollUtil.isEmpty(nodeUsers)) { + transformFailMap(failInfoMap, resultList); + return resultList; + } nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).findAny().ifPresent(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER); @@ -328,10 +332,10 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } } - private void checkPermission(List nodeUsers, Long personId) { + private void checkPermission(List nodeUsers, Long personId, Map> failInfoMap) { if (CollUtil.isEmpty(nodeUsers) || nodeUsers.stream().noneMatch(e -> Objects.equals(e.getPersonId(), personId))) { - throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目"); + throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目,请刷新后重试当前操作!"); } } From e7544c7b35f424f0a008bbc64e7111da4f388110 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 13:48:56 +0800 Subject: [PATCH 35/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E7=8F=AD=E7=BB=84=E5=88=A0=E9=99=A4=E4=BA=BA?= =?UTF-8?q?=E5=91=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/dao/node/entity/OrganizationalTeamOuRelation.java | 2 -- .../orguser/foundation/impl/OrgUserFoundationServiceImpl.java | 4 ++++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalTeamOuRelation.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalTeamOuRelation.java index dc37da1..dc66eec 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalTeamOuRelation.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalTeamOuRelation.java @@ -58,9 +58,7 @@ public class OrganizationalTeamOuRelation { private JSONObject extra; protected Date createAt; - protected Long createBy; protected Date updateAt; - protected Long updateBy; @TableField("is_delete") protected Long isDelete = 0L; } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java index ca291a3..7c3ddf8 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java @@ -2,6 +2,7 @@ package cn.axzo.orgmanax.server.orguser.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.orgmanax.dto.common.util.NumberUtil; import cn.axzo.orgmanax.dto.nodeuser.enums.OrgUserStatusEnum; import cn.axzo.orgmanax.dto.orguser.dto.OrgUserDTO; import cn.axzo.orgmanax.dto.orguser.event.OrgUserStatusChangedEvent; @@ -42,6 +43,9 @@ public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { @Override public void batchWithdrawOrQuit(OrgUserWithdrawOrQuitReq req) { OrgUserStatusEnum status; + if (NumberUtil.isNotPositiveNumber(req.getWorkspaceId())) { + return; + } if (req.isUnitUpdate()) { WorkspaceDetailReq workspaceDetailReq = new WorkspaceDetailReq(); workspaceDetailReq.setId(req.getWorkspaceId()); From 49167a2ee126f2080fc8dd041b7ef9c53911074c Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 14:15:44 +0800 Subject: [PATCH 36/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E4=BC=A0=E4=BA=86nodeId=E5=B0=B1=E7=94=A8=E4=BC=A0=E8=BF=9B?= =?UTF-8?q?=E6=9D=A5=E7=9A=84ouId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 827bbe1..63bfac9 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -189,7 +189,9 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { List resultList = new ArrayList<>(); Map> failInfoMap = new HashMap<>(); ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); - listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); + if (NumberUtil.isPositiveNumber(req.getNodeId())) { + listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); + } listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); if (NumberUtil.isPositiveNumber(req.getNodeId())) { From db6eaf84cc12c5b49ef9d51205343bdb9847d994 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 14:53:53 +0800 Subject: [PATCH 37/75] =?UTF-8?q?feat(REQ-3714):=20orgUser=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=A1=AB=E5=85=85=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orguser/foundation/impl/OrgUserFoundationServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java index 7c3ddf8..31f6c02 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java @@ -68,7 +68,10 @@ public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { Date now = new Date(); List orgUsers = list.stream().map(orgUserResp -> { OrgUser orgUser = new OrgUser(); + orgUser.setOuId(orgUserResp.getOuId()); + orgUser.setWorkspaceId(orgUserResp.getWorkspaceId()); orgUser.setId(orgUserResp.getId()); + orgUser.setPersonId(orgUserResp.getPersonId()); orgUser.setOperatorId(operator.getKey()); orgUser.setOperatorName(operator.getValue()); orgUser.setTransferTime(now); From 9b4dfab87f5d300ea58d9a1a96303229610ad10d Mon Sep 17 00:00:00 2001 From: luofu Date: Tue, 11 Mar 2025 15:37:44 +0800 Subject: [PATCH 38/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20?= =?UTF-8?q?=E4=BA=BA=E5=91=98=E6=89=93=E6=A0=87=E7=AD=BE=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../client/datatagger/DataTagClient.java | 8 ++ .../client/datatagger/dto/DataTagNode.java | 43 +++++++ ...ueryProperty.java => DataTagProperty.java} | 2 +- .../datatagger/dto/OperateDataTagReq.java | 56 ++++++++ .../datatagger/dto/RevokeDataTagReq.java | 2 +- .../sdk/datatagger/DataTagClientImpl.java | 62 +++++++-- .../orguser/service/OrgUserService.java | 5 +- .../service/impl/OrgUserServiceImpl.java | 121 +++++++++++++++++- 8 files changed, 284 insertions(+), 15 deletions(-) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagNode.java rename orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/{DataTagQueryProperty.java => DataTagProperty.java} (95%) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/OperateDataTagReq.java diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/DataTagClient.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/DataTagClient.java index d43c362..a59b646 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/DataTagClient.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/DataTagClient.java @@ -1,5 +1,6 @@ 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; /** @@ -17,4 +18,11 @@ public interface DataTagClient { * @return 结果,成功返回 {@code true},否则返回 {@code false} */ boolean revokeDataTags(RevokeDataTagReq request); + + /** + * 标签操作 + * + * @param tagsRequest 入参 + */ + void operateDataTags(OperateDataTagReq tagsRequest); } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagNode.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagNode.java new file mode 100644 index 0000000..2831e47 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagNode.java @@ -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 valueCodes; + + public boolean invalid() { + return StringUtils.isBlank(nodeCode) || CollUtil.isEmpty(valueCodes); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagQueryProperty.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagProperty.java similarity index 95% rename from orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagQueryProperty.java rename to orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagProperty.java index f2a47dd..d1f07de 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagQueryProperty.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/DataTagProperty.java @@ -16,7 +16,7 @@ import lombok.NoArgsConstructor; @Builder @NoArgsConstructor @AllArgsConstructor -public class DataTagQueryProperty { +public class DataTagProperty { /** * 单位id diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/OperateDataTagReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/OperateDataTagReq.java new file mode 100644 index 0000000..7e41544 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/OperateDataTagReq.java @@ -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 tagNodes; + + /** + * 对象ID + */ + @NonNull + private List objectIds; + + /** + * 查询对象 + */ + @Builder.Default + private DataTagProperty property = new DataTagProperty(); + + @Override + public String toString() { + return JSON.toJSONString(this); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/RevokeDataTagReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/RevokeDataTagReq.java index 22c8948..a5fd7ed 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/RevokeDataTagReq.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/datatagger/dto/RevokeDataTagReq.java @@ -48,7 +48,7 @@ public class RevokeDataTagReq { * 查询对象 */ @Builder.Default - private DataTagQueryProperty queryProperties = new DataTagQueryProperty(); + private DataTagProperty properties = new DataTagProperty(); /** * 严格模式 diff --git a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/datatagger/DataTagClientImpl.java b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/datatagger/DataTagClientImpl.java index 5073b1e..cc8e180 100644 --- a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/datatagger/DataTagClientImpl.java +++ b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/datatagger/DataTagClientImpl.java @@ -1,18 +1,26 @@ 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.DataTagQueryProperty; +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 @@ -25,32 +33,66 @@ import java.util.Optional; 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.getQueryProperties())); + req.setQueryProperties(toQueryProperties(request.getProperties())); return req; } - private static ObjectTagQueryProperties toQueryProperties(DataTagQueryProperty queryProperties) { - ObjectTagQueryProperties properties = new ObjectTagQueryProperties(); + 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 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(queryProperties.getOuId()).ifPresent(properties::setOuId); + Optional.ofNullable(properties.getOuId()).ifPresent(fields::setOuId); // workspaceId - Optional.ofNullable(queryProperties.getWorkspaceId()).ifPresent(properties::setWorkspaceId); + Optional.ofNullable(properties.getWorkspaceId()).ifPresent(fields::setWorkspaceId); // projectTeamNodeId - Optional.ofNullable(queryProperties.getPlatTeamNodeId()).ifPresent(properties::setPlatTeamNodeId); + Optional.ofNullable(properties.getPlatTeamNodeId()).ifPresent(fields::setPlatTeamNodeId); // projectTeamNodeId - Optional.ofNullable(queryProperties.getProjectTeamNodeId()).ifPresent(properties::setProjectTeamNodeId); + Optional.ofNullable(properties.getProjectTeamNodeId()).ifPresent(fields::setProjectTeamNodeId); // groupNodeId - Optional.ofNullable(queryProperties.getGroupNodeId()).ifPresent(properties::setGroupNodeId); - return properties; + Optional.ofNullable(properties.getGroupNodeId()).ifPresent(fields::setGroupNodeId); + return tagProperties; } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/service/OrgUserService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/service/OrgUserService.java index 7b8e43e..ed36c2a 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/service/OrgUserService.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/service/OrgUserService.java @@ -1,8 +1,9 @@ package cn.axzo.orgmanax.server.orguser.service; import cn.axzo.foundation.page.PageResp; -import cn.axzo.orgmanax.dto.orguser.req.ListOrgUserReq; +import cn.axzo.orgmanax.dto.nodeuser.req.TagOperateReq; import cn.axzo.orgmanax.dto.orguser.dto.OrgUserDTO; +import cn.axzo.orgmanax.dto.orguser.req.ListOrgUserReq; import java.util.List; @@ -14,5 +15,5 @@ public interface OrgUserService { return page(req).getData(); } - + void operateTag(TagOperateReq param); } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/service/impl/OrgUserServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/service/impl/OrgUserServiceImpl.java index 3174b2c..455dc3c 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/service/impl/OrgUserServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/service/impl/OrgUserServiceImpl.java @@ -1,16 +1,33 @@ package cn.axzo.orgmanax.server.orguser.service.impl; import cn.axzo.foundation.page.PageResp; -import cn.axzo.orgmanax.dto.orguser.req.ListOrgUserReq; +import cn.axzo.orgmanax.dto.nodeuser.enums.TagOperateEnum; +import cn.axzo.orgmanax.dto.nodeuser.req.TagOperateReq; import cn.axzo.orgmanax.dto.orguser.dto.OrgUserDTO; +import cn.axzo.orgmanax.dto.orguser.req.ListOrgUserReq; +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.infra.client.datatagger.enums.DataTagTypeEnum; +import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository; +import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraUpsertRepository; import cn.axzo.orgmanax.infra.dao.orguser.repository.OrgUserQueryRepository; +import cn.axzo.orgmanax.infra.dao.orguser.repository.OrgUserUpsertRepository; import cn.axzo.orgmanax.server.orguser.service.OrgUserService; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.collection.CollUtil; +import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.Collections; import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; import java.util.stream.Collectors; @Slf4j @@ -19,6 +36,11 @@ import java.util.stream.Collectors; public class OrgUserServiceImpl implements OrgUserService { private final OrgUserQueryRepository orgUserQueryRepository; + private final OrgUserUpsertRepository orgUserUpsertRepository; + private final NodeUserExtraQueryRepository nodeUserExtraQueryRepository; + private final NodeUserExtraUpsertRepository nodeUserExtraUpsertRepository; + + private final DataTagClient dataTagClient; @Override public PageResp page(ListOrgUserReq req) { @@ -27,4 +49,101 @@ public class OrgUserServiceImpl implements OrgUserService { // assemble data if needed return new PageResp<>(page.getTotal(), page.getSize(), page.getCurrent(), records); } + + @Override + public void operateTag(TagOperateReq param) { + String operateTagPair = param.getTagNodeCode() + ":" + param.getTagValueCode(); + boolean isRemove = param.getOperateType() == TagOperateEnum.REMOVE; + boolean update = false; + List nodeUserExtraList = listNodeUserExtra(param); + nodeUserExtraList.forEach(e -> e.setTags(dealTagPair(isRemove, e.getTags(), operateTagPair))); + List orgUserList = listOrgUsers(param); + orgUserList.forEach(e -> e.setTags(dealTagPair(isRemove, e.getTags(), operateTagPair))); + if (CollUtil.isNotEmpty(nodeUserExtraList)) { + Map> idTagsMap = nodeUserExtraList.stream() + .collect(Collectors.toMap(NodeUserExtraQueryRepository.NodeUserExtraResp::getId, + NodeUserExtraQueryRepository.NodeUserExtraResp::getTags)); + nodeUserExtraUpsertRepository.updateTagsMap(idTagsMap); + update = true; + } + if (CollUtil.isNotEmpty(orgUserList)) { + Map> idTagsMap = orgUserList.stream() + .collect(Collectors.toMap(OrgUserQueryRepository.OrgUserResp::getId, OrgUserQueryRepository.OrgUserResp::getTags)); + orgUserUpsertRepository.updateTagsMap(idTagsMap); + update = true; + } + if (update) { + if (isRemove) { + RevokeDataTagReq revokeObjectTagRequest = toRevokeDataTagReq(param); + dataTagClient.revokeDataTags(revokeObjectTagRequest); + } else { + OperateDataTagReq operateTagsRequest = toOperateTagsRequest(param); + dataTagClient.operateDataTags(operateTagsRequest); + } + } + } + + private List listNodeUserExtra(TagOperateReq param) { + NodeUserExtraQueryRepository.ListReq nodeUserExtraReq = NodeUserExtraQueryRepository.ListReq.builder() + .personIds(param.getPersonIds()) + .workspaceId(param.getLoginWorkspaceId()) + .build(); + return nodeUserExtraQueryRepository.list(nodeUserExtraReq); + } + + private List listOrgUsers(TagOperateReq param) { + ListOrgUserReq request = ListOrgUserReq.builder() + .personIds(Optional.ofNullable(param.getPersonIds()).map(Sets::newHashSet).orElseGet(Sets::newHashSet)) + .workspaceId(param.getLoginWorkspaceId()) + .build(); + return orgUserQueryRepository.list(request); + } + + /** + * 处理标签对 + */ + private Set dealTagPair(boolean isRemove, Set tags, String operateTagPair) { + if (CollUtil.isEmpty(tags)) { + if (isRemove) { + return Collections.emptySet(); + } else { + return Collections.singleton(operateTagPair); + } + } + if (isRemove) { + tags.remove(operateTagPair); + } else { + tags.add(operateTagPair); + } + return tags; + } + + private static OperateDataTagReq toOperateTagsRequest(TagOperateReq param) { + OperateDataTagReq operateTag = new OperateDataTagReq(); + operateTag.setApp("maokai"); + operateTag.setObjectType(DataTagTypeEnum.PROJECT_PERSON); + operateTag.setObjectIds(param.getPersonIds()); + // properties + DataTagProperty property = new DataTagProperty(); + property.setWorkspaceId(param.getLoginWorkspaceId()); + operateTag.setProperty(property); + // tag node + DataTagNode tagNode = new DataTagNode(); + tagNode.setNodeCode(param.getTagNodeCode()); + tagNode.setValueCodes(Collections.singletonList(param.getTagValueCode())); + operateTag.setTagNodes(Collections.singletonList(tagNode)); + return operateTag; + } + + private static RevokeDataTagReq toRevokeDataTagReq(TagOperateReq param) { + RevokeDataTagReq revokeDataTag = new RevokeDataTagReq(); + revokeDataTag.setObjectIds(param.getPersonIds()); + revokeDataTag.setTagCodes(Collections.singletonList(param.getTagNodeCode())); + revokeDataTag.setTagValueCodes(Collections.singletonList(param.getTagValueCode())); + revokeDataTag.setObjectType(DataTagTypeEnum.PROJECT_PERSON); + DataTagProperty tagQueryProperties = new DataTagProperty(); + tagQueryProperties.setWorkspaceId(param.getLoginWorkspaceId()); + revokeDataTag.setProperties(tagQueryProperties); + return revokeDataTag; + } } From e5a9252ce7a5fc0a4f79b18cabe7287a8de910ef Mon Sep 17 00:00:00 2001 From: zhangran Date: Tue, 11 Mar 2025 15:56:44 +0800 Subject: [PATCH 39/75] =?UTF-8?q?add(feature/REQ-3714)=20=E5=B7=A5?= =?UTF-8?q?=E4=BA=BA=E9=80=80=E5=87=BA=E7=8F=AD=E7=BB=84=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E3=80=81=E5=8E=BB=E6=8E=89=E6=9D=83=E9=99=90=E3=80=81=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=B2=97=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orgmanax-infra/pom.xml | 5 + .../infra/client/msg/MsgCenterGateway.java | 20 ++ .../infra/client/msg/vo/JoinLeaveEnum.java | 14 ++ .../infra/client/msg/vo/MessageCodeEnum.java | 48 ++++ .../msg/vo/MessageVariableNameEnum.java | 52 ++++ .../infra/client/tyr/SaasRoleUserClient.java | 13 + .../dto/OrgManaxWorkerManagerRoleUserReq.java | 94 ++++++++ .../tyr/dto/PlatWorkTeamGrantPositionReq.java | 45 ++++ .../repository/NodeUserUpsertRepository.java | 3 + .../impl/NodeUserUpsertRepositoryImpl.java | 16 ++ .../sdk/tyr/SaasRoleUserClientImpl.java | 31 +++ .../foundation/NodeUserFoundationService.java | 3 + .../impl/NodeUserFoundationServiceImpl.java | 11 + .../impl/DeletePlatTeamWorkerProcessor.java | 223 +++++++++++++++++- 14 files changed, 576 insertions(+), 2 deletions(-) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/MsgCenterGateway.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/JoinLeaveEnum.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/MessageCodeEnum.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/MessageVariableNameEnum.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/SaasRoleUserClient.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/PlatWorkTeamGrantPositionReq.java create mode 100644 orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/tyr/SaasRoleUserClientImpl.java diff --git a/orgmanax-infra/pom.xml b/orgmanax-infra/pom.xml index 9f422d9..a4e24bf 100644 --- a/orgmanax-infra/pom.xml +++ b/orgmanax-infra/pom.xml @@ -120,5 +120,10 @@ tyr-client ${revision} + + cn.axzo.msgcenter + msg-center-api-v2 + 1.0.1-SNAPSHOT + \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/MsgCenterGateway.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/MsgCenterGateway.java new file mode 100644 index 0000000..324dce3 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/MsgCenterGateway.java @@ -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); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/JoinLeaveEnum.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/JoinLeaveEnum.java new file mode 100644 index 0000000..95fdbbd --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/JoinLeaveEnum.java @@ -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; +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/MessageCodeEnum.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/MessageCodeEnum.java new file mode 100644 index 0000000..d5a5bdc --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/MessageCodeEnum.java @@ -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); + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/MessageVariableNameEnum.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/MessageVariableNameEnum.java new file mode 100644 index 0000000..22efc74 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/msg/vo/MessageVariableNameEnum.java @@ -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; + } +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/SaasRoleUserClient.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/SaasRoleUserClient.java new file mode 100644 index 0000000..0083481 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/SaasRoleUserClient.java @@ -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); +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java new file mode 100644 index 0000000..63b1ec4 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java @@ -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 managerInfos; + /** + * 这个字段在设置后续产品重构了班组管理员、代班长相关功能的时候,要替换成ROLE ID。 + * 现在保留权限集ID是因为只是做统一权限角色,查询链路先暂时不变(REQ-2046) + */ + private List permissionGroupId; + + /** + * 角色ID 会与权限集ID取并集 + */ + private Collection 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 identityInfos = new ArrayList<>(); + } + + @AllArgsConstructor + @NoArgsConstructor + @Builder + @Data + public class IdentityInfo { + private Long personId; + + private Long identityId; + + private IdentityType identityType; + + } + +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/PlatWorkTeamGrantPositionReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/PlatWorkTeamGrantPositionReq.java new file mode 100644 index 0000000..eadaa0c --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/PlatWorkTeamGrantPositionReq.java @@ -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 workerIdentityId; + + /** + * Flag 是取消授权、还是授权。 + */ + @NotNull + private Boolean ungrant = false; + + /** + * 职位Code {@link SaasPositionEnum} + */ + @NotNull + private String positionCode; + + + +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserUpsertRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserUpsertRepository.java index 2e76d83..878ba8b 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserUpsertRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserUpsertRepository.java @@ -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,8 @@ public interface NodeUserUpsertRepository { OrganizationalNodeUser update(UpdateReq node); + List updateBatchById(List req) ; + void batchDelete(Set ids); @EqualsAndHashCode(callSuper = true) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserUpsertRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserUpsertRepositoryImpl.java index 294eeff..364bf60 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserUpsertRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/impl/NodeUserUpsertRepositoryImpl.java @@ -1,9 +1,11 @@ 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; @@ -12,7 +14,11 @@ 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 @@ -37,6 +43,16 @@ public class NodeUserUpsertRepositoryImpl implements NodeUserUpsertRepository { return nodeUserDao.getById(req.getId()); } + @Override + public List updateBatchById(List req) { + Optional first = req.stream().filter(item -> Objects.isNull(item.getId())).findFirst(); + Axssert.check(!first.isPresent(), ResultCode.INVALID_PARAMS, "更新部门人员,部门人员不能为空"); + List updateNodeUsers = BeanUtil.copyToList(req, OrganizationalNodeUser.class); + List ids = req.stream().map(OrganizationalNodeUser::getId).collect(Collectors.toList()); + nodeUserDao.updateBatchById(updateNodeUsers); + return nodeUserDao.listByIds(ids); + } + @Override public void batchDelete(Set ids) { Date date = new Date(); diff --git a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/tyr/SaasRoleUserClientImpl.java b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/tyr/SaasRoleUserClientImpl.java new file mode 100644 index 0000000..aa2db0c --- /dev/null +++ b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/tyr/SaasRoleUserClientImpl.java @@ -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)); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java index 59781fd..9806e56 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java @@ -30,6 +30,9 @@ public interface NodeUserFoundationService { @Transactional(rollbackFor = Throwable.class) OrganizationalNodeUser update(NodeUserUpdate req); + @Transactional(rollbackFor = Throwable.class) + List updateBatchById(List req); + /** * 该接口为删除的收口接口,业务使用的时候,需要自行做业务判断 * diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index e73b7c2..1ce877f 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -158,6 +158,17 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService return nodeUserUpsertRepository.update(updateReq); } + @Override + public List updateBatchById(List req) { + List nodeUserIds = req.stream().map(NodeUserUpdate::getId).collect(Collectors.toList()); + List dbNodeUsers = nodeUserQueryRepository.list(NodeUserQueryRepository.ListReq.builder() + .ids(nodeUserIds).build()); + Axssert.checkNotEmpty(dbNodeUsers,"部门人员不存在 {}",nodeUserIds); + + List updateReqs = BeanUtil.copyToList(req, NodeUserUpsertRepository.UpdateReq.class); + return nodeUserUpsertRepository.updateBatchById(updateReqs); + } + @Override public List delete(NodeUserDelete req) { checkDeleteReq(req); diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index 5b1e0c8..6ad28e2 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -1,31 +1,58 @@ package cn.axzo.orgmanax.server.nodeuser.service.processor.impl; import cn.axzo.foundation.exception.Axssert; +import cn.axzo.framework.rocketmq.EventProduceTemplate; +import cn.axzo.framework.rocketmq.RocketConfigProperties; +import cn.axzo.karma.client.model.request.PlatWorkTeamGrantPositionReq; +import cn.axzo.msg.center.api.v2.message.req.MessageSendV2Req; +import cn.axzo.msg.center.api.v2.message.req.PersonV2DTO; +import cn.axzo.orgmanax.dto.common.IdentityType; import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO; import cn.axzo.orgmanax.dto.nodeuser.req.DeleteNodeUserReq; import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq; import cn.axzo.orgmanax.dto.project.team.enums.TeamSceneEnum; +import cn.axzo.orgmanax.infra.client.eventhub.dto.OrganizationTypeEnum; +import cn.axzo.orgmanax.infra.client.msg.MsgCenterGateway; +import cn.axzo.orgmanax.infra.client.tyr.SaasRoleUserClient; +import cn.axzo.orgmanax.infra.client.tyr.dto.OrgManaxWorkerManagerRoleUserReq; +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.OrganizationalTeamOuRelation; import cn.axzo.orgmanax.infra.dao.node.repository.TeamOuRelationRepository; -import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser; +import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobQueryRepository; +import cn.axzo.orgmanax.infra.dao.unit.repository.UnitQueryRepository; import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete; +import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserUpdate; import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService; import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor; +import cn.axzo.orgmanax.infra.client.msg.vo.JoinLeaveEnum; +import cn.axzo.orgmanax.infra.client.msg.vo.MessageCodeEnum; +import cn.axzo.orgmanax.infra.client.msg.vo.MessageVariableNameEnum; +import cn.axzo.orgmanax.server.util.AssertUtil; import cn.axzo.orgmanax.server.workerprofession.foundation.OrgProjectWorkerProfessionFoundationService; import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; +import cn.axzo.tyr.client.common.enums.RoleResourceTypeEnum; +import cn.axzo.tyr.client.common.enums.SaasPositionEnum; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; 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.Optional; +import java.util.Set; +import java.util.concurrent.CompletableFuture; import java.util.function.Function; import java.util.stream.Collectors; @@ -44,6 +71,28 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { private final NodeUserService nodeUserService; private final NodeUserFoundationService nodeUserFoundationService; private final OrgProjectWorkerProfessionFoundationService workerProfessionFoundationService; + private final UnitQueryRepository unitQueryRepository; + private final MsgCenterGateway msgCenterGateway; + private final CooperateShipQueryRepository cooperateShipQueryRepository; + private final OrgJobQueryRepository orgJobQueryRepository; + private final SaasRoleUserClient saasRoleUserClient; + private final EventProduceTemplate eventProduceTemplate; + private final RocketConfigProperties rocketConfigProperties; + private static final String PROMISE_GROUP_EVENT_MODULE = "promise-group"; + private static final String PROMISE_GROUP_EVENT_NAME = "promise-group-remove"; + + + + /** + * 班组管理员的默认CODE + */ + @Value("${job.code.team.entTeamManager:entTeamManager}") + public String entManagerCode; + /** + * 工人默认CODE + */ + @Value("${job.code.team.entWorker:entWorker}") + public String entWorkerCode; @Override public ProcessResult process(ProcessContext context) { @@ -73,6 +122,8 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { nodeUserMap.forEach((nodeId, vs) -> { OrganizationalTeamOuRelation ouRelation = teamOuRelationMap.get(nodeId); if (Objects.nonNull(ouRelation)) { + // 移除代班长权限 + removePlatTeamManager(ouRelation, vs); // 删除平台工人 List deleteTeamWorkerPersonIds = vs.stream().map(NodeUserDTO::getPersonId).collect(Collectors.toList()); NodeUserDelete nodeUserDelete = NodeUserDelete.builder() @@ -89,13 +140,181 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { .orgNodeId(nodeId) .build(); workerProfessionFoundationService.delete(workerProfession); - return ; + // 发送消息 + sendWorkerMessage(ouRelation, vs); + return; } log.error("获取企业下班组与平台班组关系失败, nodeId:{}", nodeId); }); + } return ProcessResult.success(); } + private void removePlatTeamManager(OrganizationalTeamOuRelation ouRelation, List nodeUserDTOS) { + //若该工人是班组管理员,则一并移除平台管理员、项目级权限等。 + SaasCooperateShip saasCooperateShip = getSaasCooperateShip(ouRelation.getNodeId()); + // 获取岗位 + List jobs = getJob(Sets.newHashSet(entManagerCode, entWorkerCode)); + Optional entWorkerJob = jobs.stream().filter(item -> Objects.equals(item.getCode(), entWorkerCode)).findFirst(); + AssertUtil.isTrue(entWorkerJob.isPresent(), "获取工人岗位失败"); + // 修改平台班组下工人岗位 + updateWorkerNodeJob(entWorkerJob.get(), nodeUserDTOS); + // 去掉权限 + grantOrUngrantWorkerManager(saasCooperateShip, ouRelation, nodeUserDTOS); + // 目前已知需要发送消息的场景: + // 1.平台代班长若被移出时,需要将招工发布的信息同步清理掉 + sendMQ(ouRelation, nodeUserDTOS); + } + + private void sendMQ(OrganizationalTeamOuRelation ouRelation, List nodeUserDTOS){ + PlatWorkTeamGrantPositionReq build = PlatWorkTeamGrantPositionReq.builder() + .platWorkTeamOuId(ouRelation.getTeamOuId()) + .workerIdentityId(nodeUserDTOS.stream().map(NodeUserDTO::getIdentityId).collect(Collectors.toSet())) + .ungrant(Boolean.TRUE) + .positionCode(SaasPositionEnum.PLAT_ACTING_MONITOR.getCode()) + .build(); + + eventProduceTemplate.send( + rocketConfigProperties.getProduces().get("tyr"), + PROMISE_GROUP_EVENT_MODULE, + PROMISE_GROUP_EVENT_NAME, + JSON.toJSONString(build), + String.valueOf(ouRelation.getTeamOuId()), + String.valueOf(ouRelation.getTeamOuId()), + "platWorkTeamOuId" + ); + } + + private SaasCooperateShip getSaasCooperateShip(Long nodeId) { + CooperateShipQueryRepository.OneReq build = CooperateShipQueryRepository.OneReq.builder() + .organizationalNodeId(nodeId) + .build(); + return cooperateShipQueryRepository.one(build); + } + + private void updateWorkerNodeJob(OrgJobQueryRepository.JobResp jobResp, List nodeUserDTOS) { + List nodeUserUpdates = nodeUserDTOS.stream().map(item -> { + return NodeUserUpdate.builder() + .id(item.getId()) + .organizationalJobId(jobResp.getId()) + .build(); + }).collect(Collectors.toList()); + nodeUserFoundationService.updateBatchById(nodeUserUpdates); + } + + private void grantOrUngrantWorkerManager(SaasCooperateShip saasCooperateShip, OrganizationalTeamOuRelation ouRelation, List nodeUserDTOS) { + List identityInfos = nodeUserDTOS.stream().map(item -> { + return OrgManaxWorkerManagerRoleUserReq.IdentityInfo.builder() + .identityId(item.getIdentityId()) + .personId(item.getPersonId()) + .build(); + }).collect(Collectors.toList()); + + OrgManaxWorkerManagerRoleUserReq.ManagerInfo managerInfo = OrgManaxWorkerManagerRoleUserReq.ManagerInfo.builder() + .identityInfos(identityInfos) + .ouId(saasCooperateShip.getOrganizationalUnitId()) + .workspaceId(saasCooperateShip.getWorkspaceId()) + .resourceId(ouRelation.getTeamOuId()) + .build(); + + OrgManaxWorkerManagerRoleUserReq orgManaxWorkerManagerRoleUserReq = OrgManaxWorkerManagerRoleUserReq.builder() + .managerInfos(Lists.newArrayList(managerInfo)) + .identityType(IdentityType.WORKER) + .resourceType(RoleResourceTypeEnum.UNIT.getCode()) + .ungrant(true) + .isUngrantAll(true) + .roleGroupCategoryCode(SaasPositionEnum.PLAT_ACTING_MONITOR.getCode()) + .build(); + + saasRoleUserClient.grantOrUngrantWorkerManager(orgManaxWorkerManagerRoleUserReq); + } + + private List getJob(Set jobCode) { + OrgJobQueryRepository.ListReq build = OrgJobQueryRepository.ListReq.builder() + .codes(jobCode) + .build(); + List jobResps = orgJobQueryRepository.list(build); + if (CollUtil.isNotEmpty(jobResps)) + return jobResps; + return Collections.emptyList(); + } + + private void sendWorkerMessage(OrganizationalTeamOuRelation ouRelation, List nodeUserDTOS) { + + ListNodeUserReq listNodeUserReq = ListNodeUserReq.builder() + .identityType(IdentityType.WORKER_LEADER.getCode()) + .organizationalNodeId(nodeUserDTOS.get(0).getOrganizationalNodeId()) + .build(); + List nodeUserDTOList = nodeUserService.list(listNodeUserReq); + if (CollUtil.isEmpty(nodeUserDTOList)) { + log.error("获取班组负责人失败, listNodeUserReq:{}", JSON.toJSONString(listNodeUserReq)); + return; + } + NodeUserDTO teamLeader = nodeUserDTOList.get(0); + + // 发消息 + CompletableFuture.runAsync(() -> { + UnitQueryRepository.UnitResp unitResp = unitQueryRepository.getById(ouRelation.getOuId()); + if (Objects.isNull(unitResp)) { + log.error("获取企业失败, ouRelation:{}", JSON.toJSONString(ouRelation)); + return; + } + nodeUserDTOS.forEach(item -> { + // 班组长消息 + sendLeaderWorkerJoinLeaveMsg(JoinLeaveEnum.LEAVE, ouRelation, item, teamLeader, unitResp.getName()); + // 工人消息 + sendWorkerMsg(ouRelation.getOuId(), teamLeader.getRealName(), unitResp.getName(), item); + }); + }); + + } + + private void sendWorkerMsg(Long ouId, String teamLeaderName, String unitName, NodeUserDTO item) { + // 发给工人消息通知 发送通知消息 + MessageSendV2Req msgReq = new MessageSendV2Req(); + PersonV2DTO receiver = new PersonV2DTO(item.getPersonId(), item.getRealName()); + msgReq.setReceivers(Collections.singletonList(receiver)); + msgReq.setReceiversOuId(ouId); + msgReq.setReceiversOrgType(OrganizationTypeEnum.ENT.getCode()); + JSONObject jsonObject = new JSONObject(); + jsonObject.put(MessageVariableNameEnum.TEAM_LEADER_NAME.getName(), teamLeaderName); + jsonObject.put(MessageVariableNameEnum.ORGANIZATIONAL_UNIT_NAME.getName(), unitName); + jsonObject.put(MessageVariableNameEnum.DATE.getName(), DateUtil.now()); + msgReq.setBizExtParams(jsonObject); + msgReq.setBizEventMappingCode(MessageCodeEnum.UNIT_TEAM_REMOVE_WORKER.getCode()); + + String bizCode = String.format(MessageCodeEnum.UNIT_TEAM_REMOVE_WORKER.getBizCodeTemplate(), item.getPersonId(), item.getOrganizationalNodeId()); + msgReq.setBizCode(bizCode); + msgCenterGateway.sendMsg(msgReq); + } + + private void sendLeaderWorkerJoinLeaveMsg(JoinLeaveEnum joinLeaveEnum, + OrganizationalTeamOuRelation resp, + NodeUserDTO profile, + NodeUserDTO teamLeader, + String unitName) { + MessageSendV2Req message = new MessageSendV2Req(); + JSONObject jsonObject = new JSONObject(); + message.setBizEventMappingCode(MessageCodeEnum.WORKER_JOIN_LEAVE_UNIT_TEAM.getCode()); + + message.setReceiversOuId(resp.getOuId()); + message.setReceiversOrgType(OrganizationTypeEnum.ENT.getCode()); + String bizCode = String.format(MessageCodeEnum.WORKER_JOIN_LEAVE_UNIT_TEAM.getBizCodeTemplate(), joinLeaveEnum.name().toLowerCase(), + resp.getNodeId(), profile.getPersonId()); + message.setBizCode(bizCode); + jsonObject.put(MessageVariableNameEnum.ACTION.getName(), joinLeaveEnum.getValue()); + + jsonObject.put(MessageVariableNameEnum.TEAM_LEADER_NAME.getName(), teamLeader.getRealName()); + jsonObject.put(MessageVariableNameEnum.ORGANIZATIONAL_UNIT_NAME.getName(), unitName); + jsonObject.put(MessageVariableNameEnum.DATE.getName(), DateUtil.now()); + jsonObject.put(MessageVariableNameEnum.WORKER_NAME.getName(), profile.getRealName()); + message.setBizExtParams(jsonObject); + + PersonV2DTO receiver = new PersonV2DTO(teamLeader.getPersonId(), teamLeader.getRealName()); + message.setReceivers(Collections.singletonList(receiver)); + msgCenterGateway.sendMsg(message); + } + } From 40852c840a150fff74b76b8b587801db8956f633 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 18:05:13 +0800 Subject: [PATCH 40/75] =?UTF-8?q?feat(REQ-3714):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java index e2df81e..913adf8 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java @@ -16,7 +16,7 @@ public enum CheckInfoTypeEnum { SUPER_ADMIN(1, "超级管理员", "【%s】是超级管理员,无法删除!", 0), IN_PROJECT(2, "在项目中", "【%s】在项目中,无法删除!", 0), TEAM_LEADER(3, "班组长", "【%s】是班组长,无法删除!", 0), - PROJECT_GROUP_LEADER(4, "合作小组小组长", "【%s】是项目组组长,无法删除!", 0), + PROJECT_GROUP_LEADER(4, "合作小组小组长", "【%s】是小组长,无法删除!", 0), NOT_IN_JURISDICTION(5, "不在管辖范围", "【%s】不在你的管辖范围,无法删除!", 0), ANY_ADMIN(6, "单位负责人", "【%s】是项目单位负责人,无法删除!", 0), TASK_ORDER(7, "任务单", "当前人员有未完成的任务单:%d单。无法删除!", 2), From 73f158b4fbe92977fcf054451087e713b0af15cb Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 18:49:05 +0800 Subject: [PATCH 41/75] =?UTF-8?q?feat(REQ-3714):=20=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java index 63b1ec4..32b3df3 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/tyr/dto/OrgManaxWorkerManagerRoleUserReq.java @@ -82,7 +82,7 @@ public class OrgManaxWorkerManagerRoleUserReq { @NoArgsConstructor @Builder @Data - public class IdentityInfo { + public static class IdentityInfo { private Long personId; private Long identityId; From cf1fef29ee395a7b80ab222878fb58c2b22103ba Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 18:58:30 +0800 Subject: [PATCH 42/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/event/config/RocketMQEventConfig.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/event/config/RocketMQEventConfig.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/event/config/RocketMQEventConfig.java index 1f095d6..78e40c4 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/event/config/RocketMQEventConfig.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/event/config/RocketMQEventConfig.java @@ -10,6 +10,9 @@ 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; @@ -25,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; @@ -139,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); + } } From 6571282886c852604e25b9de147296bf47434394 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 19:37:34 +0800 Subject: [PATCH 43/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E4=BA=BA=E5=91=98=E5=88=A0=E9=99=A4=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/service/impl/NodeUserCheckServiceImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 63bfac9..47fb67d 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -194,9 +194,6 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); - if (NumberUtil.isPositiveNumber(req.getNodeId())) { - listOrgCooperateShipReq.setOrganizationNodeIds(Collections.singleton(req.getNodeId())); - } List cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq); Axssert.checkNotEmpty(cooperateShipRespList, "操作失败,获取协同组织失败"); // 协同节点关联的顶级部门节点列表 From 4187120b6bf9acdee68cf336eb7e6855d39cb784 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Tue, 11 Mar 2025 19:45:37 +0800 Subject: [PATCH 44/75] =?UTF-8?q?feat(REQ-3714):=20=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E6=98=AF=E5=B0=8F=E7=BB=84=E9=95=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/NodeUserCheckServiceImpl.java | 27 +++++-------------- 1 file changed, 6 insertions(+), 21 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 47fb67d..588645f 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -9,9 +9,7 @@ import cn.axzo.orgmanax.dto.common.util.NumberUtil; import cn.axzo.orgmanax.dto.cooperateship.dto.OrgCooperateShipDTO; import cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum; import cn.axzo.orgmanax.dto.cooperateship.req.ListOrgCooperateShipReq; -import cn.axzo.orgmanax.dto.node.dto.OrgNodeDTO; import cn.axzo.orgmanax.dto.node.enums.NodeTypeEnum; -import cn.axzo.orgmanax.dto.node.req.ListNodeReq; import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO; import cn.axzo.orgmanax.dto.nodeuser.enums.CheckInfoTypeEnum; import cn.axzo.orgmanax.dto.nodeuser.req.BatchDeleteNodeUserCheckReq; @@ -46,7 +44,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.util.*; -import java.util.function.Function; import java.util.function.ToIntFunction; import java.util.stream.Collectors; @@ -231,8 +228,8 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); }); - // 判断是否合作小组小组长,合作小组小组长不允许删除 - checkIndependentGroupLeader(nodeUsers, failInfoMap); + // 判断小组长,小组长不允许删除 + checkGroupLeader(nodeUsers, failInfoMap); // 判断是否拥有admin角色 判断是否是分包管理员 List adminRoleIds = getSpecialRole(); @@ -306,27 +303,15 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { })); } - private void checkIndependentGroupLeader(List nodeUsers, Map> failInfoMap) { + private void checkGroupLeader(List nodeUsers, Map> failInfoMap) { if (CollUtil.isEmpty(nodeUsers)) { return; } - Set nodeIdList = nodeUsers.stream().map(NodeUserDTO::getOrganizationalNodeId).collect(Collectors.toSet()); - ListNodeReq nodeBatchQueryVO = new ListNodeReq(); - nodeBatchQueryVO.setIds(nodeIdList); - List nodeVOList = nodeService.list(nodeBatchQueryVO); - if (CollectionUtil.isEmpty(nodeVOList)) { - throw ResultCode.INVALID_PARAMS.toException("操作失败:获取部门节点信息失败"); - } - Map nodeVOMap = nodeVOList.stream().collect(Collectors.toMap(OrgNodeDTO::getId, Function.identity())); for (NodeUserDTO u : nodeUsers) { if (projectTeamGPLeader.equals(u.getJob().getCode())) { - OrgNodeDTO nodeVO = nodeVOMap.getOrDefault(u.getOrganizationalNodeId(), null); - if (Objects.nonNull(nodeVO) && NodeTypeEnum.PROJECT_GROUP.getValue().equals(nodeVO.getNodeType()) - && Objects.nonNull(nodeVO.independentGroup()) && nodeVO.independentGroup()) { - BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); - checkFailInfo.setType(CheckInfoTypeEnum.PROJECT_GROUP_LEADER); - addFailInfo(failInfoMap, u.getPersonId(), checkFailInfo); - } + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.PROJECT_GROUP_LEADER); + addFailInfo(failInfoMap, u.getPersonId(), checkFailInfo); } } } From 59a0daf3bf558f11f312d715cbcc4f8170b96e01 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 09:48:34 +0800 Subject: [PATCH 45/75] =?UTF-8?q?feat(REQ-3714):=20=E6=9B=B4=E6=94=B9?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java index 913adf8..068ecc7 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/enums/CheckInfoTypeEnum.java @@ -17,7 +17,7 @@ public enum CheckInfoTypeEnum { IN_PROJECT(2, "在项目中", "【%s】在项目中,无法删除!", 0), TEAM_LEADER(3, "班组长", "【%s】是班组长,无法删除!", 0), PROJECT_GROUP_LEADER(4, "合作小组小组长", "【%s】是小组长,无法删除!", 0), - NOT_IN_JURISDICTION(5, "不在管辖范围", "【%s】不在你的管辖范围,无法删除!", 0), + NOT_IN_JURISDICTION(5, "不在管辖范围", "【%s】不在您的管辖范围,无法删除!", 0), ANY_ADMIN(6, "单位负责人", "【%s】是项目单位负责人,无法删除!", 0), TASK_ORDER(7, "任务单", "当前人员有未完成的任务单:%d单。无法删除!", 2), RECTIFY_ORDERS(8, "整改单", "当前人员有未完成的整改单:%d单。无法删除!", 6), From 2ad2378ab1274c815376f708fe721d1163ec6723 Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 12 Mar 2025 09:49:45 +0800 Subject: [PATCH 46/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20?= =?UTF-8?q?=E5=B7=A5=E4=BA=BA=E8=87=AA=E5=8A=A8=E6=89=93=E7=A6=BB=E5=9C=BA?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E4=BB=A5=E5=8F=8A=E5=8F=96=E6=B6=88=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E7=9A=84XXL-JOB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orgmanax-infra/pom.xml | 5 + .../orgmanax/infra/client/RpcWrapper.java | 18 ++ .../client/workspace/WorkspaceGateway.java | 71 ++++++ .../repository/NodeUserQueryRepository.java | 11 +- .../CooperateShipFoundationService.java | 10 +- .../CooperateShipFoundationServiceImpl.java | 5 + .../NodeUserExtraFoundationService.java | 31 +++ .../foundation/NodeUserFoundationService.java | 11 + .../NodeUserExtraFoundationServiceImpl.java | 38 ++++ .../impl/NodeUserFoundationServiceImpl.java | 14 +- .../orguser/config/PersonTagConfig.java | 59 +++++ .../xxl/AutoAddWorkerLeavedTagJob.java | 212 ++++++++++++++++++ .../xxl/AutoClearPersonLeavedTagJob.java | 136 +++++++++++ .../BaseAutoOperatePersonLeavedTagJob.java | 172 ++++++++++++++ 14 files changed, 790 insertions(+), 3 deletions(-) create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserExtraFoundationService.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserExtraFoundationServiceImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/config/PersonTagConfig.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoClearPersonLeavedTagJob.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java diff --git a/orgmanax-infra/pom.xml b/orgmanax-infra/pom.xml index a4e24bf..d5331bc 100644 --- a/orgmanax-infra/pom.xml +++ b/orgmanax-infra/pom.xml @@ -125,5 +125,10 @@ msg-center-api-v2 1.0.1-SNAPSHOT + + + com.xuxueli + xxl-job-core + \ No newline at end of file diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/RpcWrapper.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/RpcWrapper.java index 3a87ad0..45dc765 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/RpcWrapper.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/RpcWrapper.java @@ -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 + */ + public static T commonRes(Supplier> t) { + CommonResponse 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 返回 * diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workspace/WorkspaceGateway.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workspace/WorkspaceGateway.java index 3ffa262..8ad227d 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workspace/WorkspaceGateway.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workspace/WorkspaceGateway.java @@ -10,12 +10,26 @@ 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; /** * @@ -25,9 +39,15 @@ import java.util.List; @Slf4j public class WorkspaceGateway { + private static final ImmutableList 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; /** * 更新和新增 @@ -62,4 +82,55 @@ public class WorkspaceGateway { public List listParticipatingUnits(ParticipatingUnitListReq unitListReq) { return RpcWrapper.wrapApiResult(() -> participatingUnitV2Api.list(unitListReq)); } + + /** + * 查询项目相关配置项 + * + * @param request 入参 + * @return 配置项列表 + */ + @MethodAroundLog(source = "orgmanax", target = "workspace", value = "查询项目相关配置项") + public List listConfigs(WorkspaceSceneConfigListReq request) { + return RpcWrapper.commonRes(() -> workspaceSceneConfigApi.listConfigs(request)); + } + + /** + * 获取人员自动离场的天数配置(连续多少天没有打卡记录) + * + * @param workspaceIds 项目id列表 + * @return 配置项的map + */ + @MethodAroundLog(source = "orgmanax", target = "workspace", value = "获取人员自动离场的天数配置") + public Map listAutoLeaveDaysConfig(Collection workspaceIds) { + if (CollUtil.isEmpty(workspaceIds)) { + return Collections.emptyMap(); + } + WorkspaceSceneConfigListReq request = WorkspaceSceneConfigListReq.builder() + .workspaceIds(CollUtil.distinct(workspaceIds)) + .types(AUTO_LEAVE_CONFIG_TYPES) + .build(); + // list + List sceneConfigs = listConfigs(request); + if (CollUtil.isEmpty(sceneConfigs)) { + return Collections.emptyMap(); + } + // grouping + Map> groupingByWorkspaceId = sceneConfigs.stream() + .collect(Collectors.groupingBy(SceneConfigRes::getWorkspaceId)); + // mapper function + Function, 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)); + } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserQueryRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserQueryRepository.java index 5c98268..513dda7 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserQueryRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/nodeuser/repository/NodeUserQueryRepository.java @@ -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 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 workspaceIds; diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/cooperateship/foundation/CooperateShipFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/cooperateship/foundation/CooperateShipFoundationService.java index 4f41b66..f5e027a 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/cooperateship/foundation/CooperateShipFoundationService.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/cooperateship/foundation/CooperateShipFoundationService.java @@ -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 list(ListReq req); } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/cooperateship/foundation/impl/CooperateShipFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/cooperateship/foundation/impl/CooperateShipFoundationServiceImpl.java index dc65725..130f65e 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/cooperateship/foundation/impl/CooperateShipFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/cooperateship/foundation/impl/CooperateShipFoundationServiceImpl.java @@ -217,4 +217,9 @@ public class CooperateShipFoundationServiceImpl implements CooperateShipFoundati return savedCooperateShip; } + @Override + public List list(CooperateShipQueryRepository.ListReq req) { + return cooperateShipQueryRepository.list(req); + } + } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserExtraFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserExtraFoundationService.java new file mode 100644 index 0000000..1b5ed62 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserExtraFoundationService.java @@ -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 page(ListReq req); + + /** + * 批量设置用户标签 + * + * @param idTagsMap key:id, value:标签集合 + */ + void updateTagsMap(Map> idTagsMap); +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java index 9806e56..6cf3bd2 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/NodeUserFoundationService.java @@ -1,8 +1,11 @@ package cn.axzo.orgmanax.server.nodeuser.foundation; +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.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; @@ -55,4 +58,12 @@ public interface NodeUserFoundationService { * @return */ List searchEntUser(SearchEntNodeUserReq req); + + /** + * 通用分页查询 + * + * @param req 入参 + * @return node_user列表 + */ + PageResp page(ListReq req); } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserExtraFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserExtraFoundationServiceImpl.java new file mode 100644 index 0000000..275e2ce --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserExtraFoundationServiceImpl.java @@ -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 page(ListReq req) { + return queryRepository.page(req); + } + + @Override + public void updateTagsMap(Map> idTagsMap) { + upsertRepository.updateTagsMap(idTagsMap); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index 1ce877f..148ee8d 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -5,6 +5,7 @@ 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; @@ -21,6 +22,8 @@ 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; @@ -46,7 +49,11 @@ import org.apache.commons.lang3.ObjectUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.*; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; /** @@ -258,6 +265,11 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService return organizationalNodeUserMapper.searchEntUser(req); } + @Override + public PageResp page(ListReq req) { + return nodeUserQueryRepository.page(req); + } + private Long resolveWorkspaceId(OrganizationalNode node) { if (Objects.equals(node.getNodeType(), NodeUserTypeEnum.TEAM.getValue())) { return 0L; diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/config/PersonTagConfig.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/config/PersonTagConfig.java new file mode 100644 index 0000000..45685c6 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/config/PersonTagConfig.java @@ -0,0 +1,59 @@ +package cn.axzo.orgmanax.server.orguser.config; + +import com.alibaba.fastjson.JSON; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +import java.io.Serializable; + +/** + * @author luofu + * @version 1.0 + * @description 人员标签配置 + * @date 2025/3/6 + */ +@Data +@RefreshScope +@Configuration +@ConfigurationProperties(prefix = "person-tag") +public class PersonTagConfig { + + /** + * 离场标签 + */ + private TagNode leaveTagNode = TagNode.of("station", "leave proj"); + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class TagNode implements Serializable { + + private static final long serialVersionUID = -8933389377639107477L; + + private String nodeCode; + + private String valueCode; + + public String format(String spliter) { + return this.nodeCode + spliter + this.valueCode; + } + + private static TagNode of(String nodeCode, String valueCode) { + return TagNode.builder() + .nodeCode(nodeCode) + .valueCode(valueCode) + .build(); + } + + @Override + public String toString() { + return JSON.toJSONString(this); + } + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java new file mode 100644 index 0000000..49030bd --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java @@ -0,0 +1,212 @@ +package cn.axzo.orgmanax.server.orguser.xxl; + +import cn.axzo.foundation.page.PageResp; +import cn.axzo.orgmanax.dto.common.IdentityType; +import cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipStatusEnum; +import cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum; +import cn.axzo.orgmanax.dto.nodeuser.enums.TagOperateEnum; +import cn.axzo.orgmanax.dto.nodeuser.req.TagOperateReq; +import cn.axzo.orgmanax.infra.client.workspace.dto.Workspace; +import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip; +import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRepository; +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.cooperateship.foundation.CooperateShipFoundationService; +import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; +import cn.hutool.core.collection.CollUtil; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * @author luofu + * @version 1.0 + * @description 自动退场OR标记为离场人员的JOB + * @date 2025/3/6 + */ +@Slf4j +@Component +public class AutoAddWorkerLeavedTagJob extends BaseAutoOperatePersonLeavedTagJob { + + private static final String LOG_PREFIX = "[ADD_WORKER_LEAVED_TAG ] "; + + private static final ImmutableList INCLUDE_WORKSPACE_TYPES = ImmutableList.of(Workspace.WorkspaceTypeEnum.GENERAL_PROJECT.getValue()); + private static final ImmutableList INCLUDE_COOPERATE_TYPES = ImmutableList.of(CooperateShipTypeEnum.PROJ_TEAM.getCode(), + CooperateShipTypeEnum.PROJ_GROUP.getCode()); + private static final ImmutableList INCLUDE_STATUS = ImmutableList.of(CooperateShipStatusEnum.PRESENT.getCode()); + + @Resource + private NodeUserFoundationService nodeUserFoundationService; + @Resource + private CooperateShipFoundationService cooperateShipFoundationService; + + private Context context; + + @Override + @XxlJob("autoAddWorkerLeavedTagJob") + public ReturnT execute(String param) { + // init context of job + initContext(); + if (context.invalid()) { + // failed to init context. + error("failed to init context."); + return ReturnT.FAIL; + } + // start to execute + doExecute(param); + return ReturnT.SUCCESS; + } + + @Override + String logPrefix() { + return LOG_PREFIX; + } + + @Override + LocalDateTime startDateTimeOfJobExecution() { + return context.getStartDateTime(); + } + + @Override + List scrollList(long scrollIndex) { + ListReq page = new ListReq(); + page.setIdLt(scrollIndex); + page.setIdentityType(IdentityType.WORKER.getCode()); + page.setWorkspaceIdGt(0L); + PageResp pageResult = nodeUserFoundationService.page(page); + return Optional.ofNullable(pageResult.getData()).orElseGet(Collections::emptyList); + } + + @Override + Long extractId(NodeUserResp record) { + return record.getId(); + } + + @Override + Long extractPersonId(NodeUserResp record) { + return record.getPersonId(); + } + + @Override + Long extractWorkspaceId(NodeUserResp record) { + return record.getWorkspaceId(); + } + + @Override + void handle(Long workspaceId, List records, List clockedPersonIds) { + Date joinedAtLe = context.getJoinedAtLe(workspaceId); + if (Objects.isNull(joinedAtLe)) { + return; + } + List withoutClockedPersonIds = records.stream() + // filter join_at condition + .filter(e -> Objects.nonNull(e.getJoinAt()) && joinedAtLe.after(e.getJoinAt())) + .map(NodeUserResp::getPersonId) + .filter(personId -> !clockedPersonIds.contains(personId)) + .distinct().collect(Collectors.toList()); + if (CollUtil.isEmpty(withoutClockedPersonIds)) { + // all person contains clocked record. + return; + } + // auto add leaved tag + addLeavedTag(workspaceId, withoutClockedPersonIds); + } + + @Override + Integer listAutoLeaveDaysConfig(Long workspaceId) { + return context.getWorkspaceDaysConfig().get(workspaceId); + } + + private void initContext() { + context = new Context(); + assembleDataScope(context); + assembleWorkspaceConfig(context); + } + + private void assembleDataScope(Context context) { + CooperateShipQueryRepository.ListReq listReq = new CooperateShipQueryRepository.ListReq(); + listReq.setWorkspaceTypes(INCLUDE_WORKSPACE_TYPES); + listReq.setIncludeCooperateTypes(INCLUDE_COOPERATE_TYPES); + listReq.setStatuses(INCLUDE_STATUS); + Map> dataScope = cooperateShipFoundationService.list(listReq).stream() + .collect(Collectors.groupingBy(SaasCooperateShip::getWorkspaceId)); + context.setActiveProjectTeamAndGroups(dataScope); + } + + private void assembleWorkspaceConfig(Context context) { + if (context.invalid()) { + return; + } + Map workspaceDaysConfig = Maps.newHashMap(); + context.setWorkspaceDaysConfig(workspaceDaysConfig); + Set workspaceIds = context.getWorkspaceDaysConfig().keySet(); + List> partition = Lists.partition(Lists.newArrayList(workspaceIds), 20); + for (List sub : partition) { + Map autoLeaveDaysConfigMap = workspaceGateway.listAutoLeaveDaysConfig(sub); + if (CollUtil.isEmpty(autoLeaveDaysConfigMap)) { + continue; + } + workspaceDaysConfig.putAll(autoLeaveDaysConfigMap); + } + } + + private void addLeavedTag(Long workspaceId, List personIds) { + TagOperateReq param = new TagOperateReq(); + param.setPersonIds(personIds); + param.setLoginWorkspaceId(workspaceId); + param.setTagNodeCode(personTagConfig.getLeaveTagNode().getNodeCode()); + param.setTagValueCode(personTagConfig.getLeaveTagNode().getValueCode()); + param.setOperateType(TagOperateEnum.ADD); + orgUserService.operateTag(param); + } + + @Data + private static class Context { + + private LocalDateTime startDateTime = LocalDateTime.now(); + + /** + * 在场的项目内班组和小组节点 + * key: workspaceId + * value: 在场的项目内班组和小组节点列表 + */ + private Map> activeProjectTeamAndGroups; + + /** + * 开关开启的项目id集合 + * key: workspaceId + * value: days + */ + private Map workspaceDaysConfig; + + boolean invalid() { + return CollUtil.isEmpty(activeProjectTeamAndGroups); + } + + Date getJoinedAtLe(Long workspaceId) { + Integer days = workspaceDaysConfig.get(workspaceId); + if (Objects.isNull(days)) { + return null; + } + LocalDateTime le = startDateTime.minusDays(days); + return Date.from(le.atZone(ZoneId.systemDefault()).toInstant()); + } + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoClearPersonLeavedTagJob.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoClearPersonLeavedTagJob.java new file mode 100644 index 0000000..34af79a --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoClearPersonLeavedTagJob.java @@ -0,0 +1,136 @@ +package cn.axzo.orgmanax.server.orguser.xxl; + +import cn.axzo.foundation.page.PageResp; +import cn.axzo.orgmanax.dto.nodeuser.enums.TagOperateEnum; +import cn.axzo.orgmanax.dto.nodeuser.req.TagOperateReq; +import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository; +import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository.NodeUserExtraResp; +import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserExtraFoundationService; +import cn.hutool.core.collection.CollUtil; +import com.google.common.collect.Maps; +import com.xxl.job.core.biz.model.ReturnT; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +/** + * @author luofu + * @version 1.0 + * @description 自动清除人员离场标签的JOB + * @date 2025/3/6 + */ +@Slf4j +@Component +public class AutoClearPersonLeavedTagJob extends BaseAutoOperatePersonLeavedTagJob { + + private static final String LOG_PREFIX = "[CLEAR_PERSON_LEAVED_TAG] "; + + @Resource + private NodeUserExtraFoundationService nodeUserExtraFoundationService; + + private Context context; + + @Override + @XxlJob("autoClearPersonLeavedTagJob") + public ReturnT execute(String param) { + // init context + context = new Context(); + doExecute(param); + return ReturnT.SUCCESS; + } + + @Override + String logPrefix() { + return LOG_PREFIX; + } + + @Override + LocalDateTime startDateTimeOfJobExecution() { + return context.getStartDateTime(); + } + + @Override + List scrollList(long scrollIndex) { + String tag = personTagConfig.getLeaveTagNode().format(":"); + NodeUserExtraQueryRepository.ListReq page = new NodeUserExtraQueryRepository.ListReq(); + page.setIdLt(scrollIndex); + page.setTag(tag); + page.setPageSize(MAX_CNT_ONCE); + page.setSort(Collections.singletonList(sortDesc("id"))); + PageResp pageResult = nodeUserExtraFoundationService.page(page); + return Optional.ofNullable(pageResult.getData()).orElseGet(Collections::emptyList); + } + + @Override + Long extractId(NodeUserExtraResp record) { + return record.getId(); + } + + @Override + Long extractPersonId(NodeUserExtraResp record) { + return record.getPersonId(); + } + + @Override + Long extractWorkspaceId(NodeUserExtraResp record) { + return record.getWorkspaceId(); + } + + @Override + void handle(Long workspaceId, List records, List clockedPersonIds) { + if (CollUtil.isEmpty(clockedPersonIds)) { + // none clocked person. + return; + } + TagOperateReq param = new TagOperateReq(); + param.setPersonIds(clockedPersonIds); + param.setLoginWorkspaceId(workspaceId); + param.setTagNodeCode(personTagConfig.getLeaveTagNode().getNodeCode()); + param.setTagValueCode(personTagConfig.getLeaveTagNode().getValueCode()); + param.setOperateType(TagOperateEnum.REMOVE); + orgUserService.operateTag(param); + } + + @Override + Integer listAutoLeaveDaysConfig(Long workspaceId) { + // fetch from local cache first. + Integer days = context.getWorkspaceDaysConfig().get(workspaceId); + if (Objects.nonNull(days)) { + return days; + } + // fetch from attendance service. + Map map = workspaceGateway.listAutoLeaveDaysConfig(Collections.singletonList(workspaceId)); + if (CollUtil.isEmpty(map)) { + return null; + } + // cache the config of this workspace + context.getWorkspaceDaysConfig().putAll(map); + // return days config + return context.getWorkspaceDaysConfig().get(workspaceId); + } + + @Data + private static class Context { + + /** + * start time of job execute + */ + private LocalDateTime startDateTime = LocalDateTime.now(); + + /** + * days configuration for add person tag of workspace. + * key: workspaceId + * value: days + */ + private Map workspaceDaysConfig = Maps.newHashMap(); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java new file mode 100644 index 0000000..577d9fb --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java @@ -0,0 +1,172 @@ +package cn.axzo.orgmanax.server.orguser.xxl; + +import cn.axzo.foundation.page.IPageReq; +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.infra.client.workspace.WorkspaceGateway; +import cn.axzo.orgmanax.server.orguser.config.PersonTagConfig; +import cn.axzo.orgmanax.server.orguser.service.OrgUserService; +import cn.hutool.core.collection.CollUtil; +import com.alibaba.fastjson.JSON; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.xxl.job.core.handler.IJobHandler; +import com.xxl.job.core.log.XxlJobLogger; +import lombok.extern.slf4j.Slf4j; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author luofu + * @version 1.0 + * @date 2025/3/6 + */ +@Slf4j +public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { + + static final int MAX_CNT_ONCE = 4; + + @Resource + PersonTagConfig personTagConfig; + @Resource + OrgUserService orgUserService; + + @Resource + AttendanceRecordClient attendanceRecordApiClient; + @Resource + WorkspaceGateway workspaceGateway; + + void doExecute(String param) { + long scrollIndex = Long.MAX_VALUE; + info("start to scan org_user."); + // key: workspaceId value: records + Map> localCache = Maps.newHashMap(); + List records = scrollList(scrollIndex); + while (CollUtil.isNotEmpty(records)) { + // the min id of records. + scrollIndex = records.stream().mapToLong(this::extractId).min().orElse(0); + // cache first, then trigger if enough. + cacheAndTrigger(localCache, records); + // the next + records = scrollList(scrollIndex); + } + // scan cached records + localCache.forEach(this::trigger); + info("completed to scan org_user."); + } + + abstract String logPrefix(); + + abstract LocalDateTime startDateTimeOfJobExecution(); + + abstract List scrollList(long scrollIndex); + + abstract Long extractId(T record); + + abstract Long extractPersonId(T record); + + abstract Long extractWorkspaceId(T record); + + abstract void handle(Long workspaceId, List records, List clockedPersonIds); + + abstract Integer listAutoLeaveDaysConfig(Long workspaceId); + + private void cacheAndTrigger(Map> localCache, List records) { + // grouping by workspaceId + Map> groupingByWorkspaceId = records.stream().collect(Collectors.groupingBy(this::extractWorkspaceId)); + // scan for cache and trigger + groupingByWorkspaceId.forEach((k, v) -> cacheAndTrigger(localCache, k, v)); + } + + private void cacheAndTrigger(Map> localCache, Long workspaceId, List sub) { + List cacheRecords = localCache.computeIfAbsent(workspaceId, k -> Lists.newArrayList()); + // merge cur records and cached records + cacheRecords.addAll(sub); + if (cacheRecords.size() < MAX_CNT_ONCE) { + // return if not matched + return; + } + // remove from local cache + localCache.remove(workspaceId); + // deal matched partitions and cache not matched + List> partitions = Lists.partition(cacheRecords, MAX_CNT_ONCE); + for (List partition : partitions) { + if (partition.size() < MAX_CNT_ONCE) { + // cache + localCache.put(workspaceId, partition); + continue; + } + // trigger + trigger(workspaceId, partition); + } + } + + public static String sortDesc(String field) { + return field + IPageReq.SORT_DELIMITER + IPageReq.SORT_DESC; + } + + private void trigger(Long workspaceId, List records) { + try { + // list days config of cur workspace. + Integer days = listAutoLeaveDaysConfig(workspaceId); + if (Objects.isNull(days)) { + info("lack of days config for this workspace. workspaceId:[{}]", workspaceId); + return; + } + // in try ... catch block for continue the next ... + // find persons which contains clocked record during specified time. + List personIds = findClockedPersons(workspaceId, days, records); + info("start to remove person tag of workspace. [{}]", workspaceId); + // begin to handle the personIds. + handle(workspaceId, records, personIds); + info("completed to remove person tag of workspace. [{}]", workspaceId); + } catch (Exception e) { + error("broke out some exception. workspaceId:[{}]", workspaceId, e); + } + } + + private List findClockedPersons(Long workspaceId, Integer days, List records) { + List personIds = CollUtil.map(records, this::extractPersonId, true); + if (CollUtil.isEmpty(personIds)) { + List ids = CollUtil.map(records, this::extractId, true); + error("invalid records, lack of personId. workspaceId:[{}], recordIds:{}", workspaceId, JSON.toJSONString(ids)); + return Collections.emptyList(); + } + // list persons which clocked during the range of specified time. + List clockRecords = listClockRecords(workspaceId, days, personIds); + // extract personId + return CollUtil.map(clockRecords, AttendanceClockRecordResp::getPersonId, true); + } + + private List listClockRecords(Long workspaceId, Integer days, List personIds) { + LocalDateTime to = startDateTimeOfJobExecution(); + LocalDateTime from = to.minusDays(days); + AttendanceClockRecordListReq request = new AttendanceClockRecordListReq(); + request.setPersonIds(personIds); + request.setWorkspaceId(workspaceId); + request.setClockAtFrom(Date.from(from.atZone(ZoneOffset.systemDefault()).toInstant())); + request.setClockAtTo(Date.from(to.atZone(ZoneOffset.systemDefault()).toInstant())); + return attendanceRecordApiClient.listClockRecords(request); + } + + void info(String msgFormat, Object... args) { + msgFormat = logPrefix() + msgFormat; + log.info(msgFormat, args); + XxlJobLogger.log(msgFormat, args); + } + + void error(String msgFormat, Object... args) { + msgFormat = logPrefix() + msgFormat; + log.error(msgFormat, args); + XxlJobLogger.log(msgFormat, args); + } +} From 8e111ebbae8df964f7daf63deb9313d178520c84 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 10:24:37 +0800 Subject: [PATCH 47/75] =?UTF-8?q?feat(REQ-3714):=20=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E4=B8=8D=E5=9C=A8=E7=AE=A1=E8=BE=96=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/NodeUserCheckServiceImpl.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 588645f..4d29c52 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -317,10 +317,16 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } private void checkPermission(List nodeUsers, Long personId, Map> failInfoMap) { - if (CollUtil.isEmpty(nodeUsers) - || nodeUsers.stream().noneMatch(e -> Objects.equals(e.getPersonId(), personId))) { + if (CollUtil.isEmpty(nodeUsers)) { throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目,请刷新后重试当前操作!"); } + if (nodeUsers.stream().noneMatch(e -> Objects.equals(e.getPersonId(), personId))) { + nodeUsers.forEach(e -> { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); + }); + } } private List getSpecialRole() { From 04a13c97412804fc940f42a2967b0213b9218dde Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 11:40:00 +0800 Subject: [PATCH 48/75] =?UTF-8?q?feat(REQ-3714):=20=E4=BA=BA=E5=91=98?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=E5=BC=82=E5=B8=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/NodeUserCheckServiceImpl.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 4d29c52..72ff149 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -206,7 +206,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { // 查询当前登录及待删除人员在当前项目中的参与记录(仅限当前登录单位) List nodeUsers = nodeUserService.list(query); // 校验当前入参 - checkPermission(nodeUsers, personId, failInfoMap); + checkPermission(nodeUsers); // 过滤当前操作人员 nodeUsers = nodeUsers.stream() .filter(e -> !Objects.equals(e.getPersonId(), personId)) @@ -316,17 +316,10 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } } - private void checkPermission(List nodeUsers, Long personId, Map> failInfoMap) { + private void checkPermission(List nodeUsers) { if (CollUtil.isEmpty(nodeUsers)) { throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目,请刷新后重试当前操作!"); } - if (nodeUsers.stream().noneMatch(e -> Objects.equals(e.getPersonId(), personId))) { - nodeUsers.forEach(e -> { - BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); - checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); - addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); - }); - } } private List getSpecialRole() { From 90ff9f1f706f68a9ebe48562ca2303d308980fab Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 12 Mar 2025 11:50:23 +0800 Subject: [PATCH 49/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20?= =?UTF-8?q?=E5=B7=A5=E4=BA=BA=E8=87=AA=E5=8A=A8=E6=89=93=E7=A6=BB=E5=9C=BA?= =?UTF-8?q?=E6=A0=87=E7=AD=BE=E4=BB=A5=E5=8F=8A=E5=8F=96=E6=B6=88=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E7=9A=84XXL-JOB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/AttendanceClockRecordListReq.java | 4 + .../xxl/AutoAddWorkerLeavedTagJob.java | 110 +----------------- .../xxl/AutoClearPersonLeavedTagJob.java | 49 +------- .../BaseAutoOperatePersonLeavedTagJob.java | 72 +++++++++++- 4 files changed, 74 insertions(+), 161 deletions(-) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordListReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordListReq.java index 36d46df..556dab0 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordListReq.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/attendance/dto/AttendanceClockRecordListReq.java @@ -22,6 +22,10 @@ import java.util.List; @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 - 必传 */ diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java index 49030bd..acb396d 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java @@ -2,37 +2,23 @@ package cn.axzo.orgmanax.server.orguser.xxl; import cn.axzo.foundation.page.PageResp; import cn.axzo.orgmanax.dto.common.IdentityType; -import cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipStatusEnum; -import cn.axzo.orgmanax.dto.cooperateship.enums.CooperateShipTypeEnum; import cn.axzo.orgmanax.dto.nodeuser.enums.TagOperateEnum; import cn.axzo.orgmanax.dto.nodeuser.req.TagOperateReq; -import cn.axzo.orgmanax.infra.client.workspace.dto.Workspace; -import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip; -import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRepository; 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.cooperateship.foundation.CooperateShipFoundationService; import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; import cn.hutool.core.collection.CollUtil; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.annotation.XxlJob; -import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.Resource; -import java.time.LocalDateTime; -import java.time.ZoneId; import java.util.Collections; import java.util.Date; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.Set; import java.util.stream.Collectors; /** @@ -47,29 +33,12 @@ public class AutoAddWorkerLeavedTagJob extends BaseAutoOperatePersonLeavedTagJob private static final String LOG_PREFIX = "[ADD_WORKER_LEAVED_TAG ] "; - private static final ImmutableList INCLUDE_WORKSPACE_TYPES = ImmutableList.of(Workspace.WorkspaceTypeEnum.GENERAL_PROJECT.getValue()); - private static final ImmutableList INCLUDE_COOPERATE_TYPES = ImmutableList.of(CooperateShipTypeEnum.PROJ_TEAM.getCode(), - CooperateShipTypeEnum.PROJ_GROUP.getCode()); - private static final ImmutableList INCLUDE_STATUS = ImmutableList.of(CooperateShipStatusEnum.PRESENT.getCode()); - @Resource private NodeUserFoundationService nodeUserFoundationService; - @Resource - private CooperateShipFoundationService cooperateShipFoundationService; - - private Context context; @Override @XxlJob("autoAddWorkerLeavedTagJob") public ReturnT execute(String param) { - // init context of job - initContext(); - if (context.invalid()) { - // failed to init context. - error("failed to init context."); - return ReturnT.FAIL; - } - // start to execute doExecute(param); return ReturnT.SUCCESS; } @@ -79,17 +48,15 @@ public class AutoAddWorkerLeavedTagJob extends BaseAutoOperatePersonLeavedTagJob return LOG_PREFIX; } - @Override - LocalDateTime startDateTimeOfJobExecution() { - return context.getStartDateTime(); - } - @Override List scrollList(long scrollIndex) { ListReq page = new ListReq(); page.setIdLt(scrollIndex); page.setIdentityType(IdentityType.WORKER.getCode()); page.setWorkspaceIdGt(0L); + page.setPageSize(MAX_CNT_ONCE); + page.setWorkspaceIds(context.getWorkspaceIds()); + page.setSort(Collections.singletonList(sortDesc("id"))); PageResp pageResult = nodeUserFoundationService.page(page); return Optional.ofNullable(pageResult.getData()).orElseGet(Collections::emptyList); } @@ -129,44 +96,6 @@ public class AutoAddWorkerLeavedTagJob extends BaseAutoOperatePersonLeavedTagJob addLeavedTag(workspaceId, withoutClockedPersonIds); } - @Override - Integer listAutoLeaveDaysConfig(Long workspaceId) { - return context.getWorkspaceDaysConfig().get(workspaceId); - } - - private void initContext() { - context = new Context(); - assembleDataScope(context); - assembleWorkspaceConfig(context); - } - - private void assembleDataScope(Context context) { - CooperateShipQueryRepository.ListReq listReq = new CooperateShipQueryRepository.ListReq(); - listReq.setWorkspaceTypes(INCLUDE_WORKSPACE_TYPES); - listReq.setIncludeCooperateTypes(INCLUDE_COOPERATE_TYPES); - listReq.setStatuses(INCLUDE_STATUS); - Map> dataScope = cooperateShipFoundationService.list(listReq).stream() - .collect(Collectors.groupingBy(SaasCooperateShip::getWorkspaceId)); - context.setActiveProjectTeamAndGroups(dataScope); - } - - private void assembleWorkspaceConfig(Context context) { - if (context.invalid()) { - return; - } - Map workspaceDaysConfig = Maps.newHashMap(); - context.setWorkspaceDaysConfig(workspaceDaysConfig); - Set workspaceIds = context.getWorkspaceDaysConfig().keySet(); - List> partition = Lists.partition(Lists.newArrayList(workspaceIds), 20); - for (List sub : partition) { - Map autoLeaveDaysConfigMap = workspaceGateway.listAutoLeaveDaysConfig(sub); - if (CollUtil.isEmpty(autoLeaveDaysConfigMap)) { - continue; - } - workspaceDaysConfig.putAll(autoLeaveDaysConfigMap); - } - } - private void addLeavedTag(Long workspaceId, List personIds) { TagOperateReq param = new TagOperateReq(); param.setPersonIds(personIds); @@ -176,37 +105,4 @@ public class AutoAddWorkerLeavedTagJob extends BaseAutoOperatePersonLeavedTagJob param.setOperateType(TagOperateEnum.ADD); orgUserService.operateTag(param); } - - @Data - private static class Context { - - private LocalDateTime startDateTime = LocalDateTime.now(); - - /** - * 在场的项目内班组和小组节点 - * key: workspaceId - * value: 在场的项目内班组和小组节点列表 - */ - private Map> activeProjectTeamAndGroups; - - /** - * 开关开启的项目id集合 - * key: workspaceId - * value: days - */ - private Map workspaceDaysConfig; - - boolean invalid() { - return CollUtil.isEmpty(activeProjectTeamAndGroups); - } - - Date getJoinedAtLe(Long workspaceId) { - Integer days = workspaceDaysConfig.get(workspaceId); - if (Objects.isNull(days)) { - return null; - } - LocalDateTime le = startDateTime.minusDays(days); - return Date.from(le.atZone(ZoneId.systemDefault()).toInstant()); - } - } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoClearPersonLeavedTagJob.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoClearPersonLeavedTagJob.java index 34af79a..a4a58fd 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoClearPersonLeavedTagJob.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoClearPersonLeavedTagJob.java @@ -7,19 +7,14 @@ import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryReposito import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserExtraQueryRepository.NodeUserExtraResp; import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserExtraFoundationService; import cn.hutool.core.collection.CollUtil; -import com.google.common.collect.Maps; import com.xxl.job.core.biz.model.ReturnT; import com.xxl.job.core.handler.annotation.XxlJob; -import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import javax.annotation.Resource; -import java.time.LocalDateTime; import java.util.Collections; import java.util.List; -import java.util.Map; -import java.util.Objects; import java.util.Optional; /** @@ -37,13 +32,9 @@ public class AutoClearPersonLeavedTagJob extends BaseAutoOperatePersonLeavedTagJ @Resource private NodeUserExtraFoundationService nodeUserExtraFoundationService; - private Context context; - @Override @XxlJob("autoClearPersonLeavedTagJob") public ReturnT execute(String param) { - // init context - context = new Context(); doExecute(param); return ReturnT.SUCCESS; } @@ -53,17 +44,13 @@ public class AutoClearPersonLeavedTagJob extends BaseAutoOperatePersonLeavedTagJ return LOG_PREFIX; } - @Override - LocalDateTime startDateTimeOfJobExecution() { - return context.getStartDateTime(); - } - @Override List scrollList(long scrollIndex) { String tag = personTagConfig.getLeaveTagNode().format(":"); NodeUserExtraQueryRepository.ListReq page = new NodeUserExtraQueryRepository.ListReq(); page.setIdLt(scrollIndex); page.setTag(tag); + page.setWorkspaceIds(context.getWorkspaceIds()); page.setPageSize(MAX_CNT_ONCE); page.setSort(Collections.singletonList(sortDesc("id"))); PageResp pageResult = nodeUserExtraFoundationService.page(page); @@ -99,38 +86,4 @@ public class AutoClearPersonLeavedTagJob extends BaseAutoOperatePersonLeavedTagJ param.setOperateType(TagOperateEnum.REMOVE); orgUserService.operateTag(param); } - - @Override - Integer listAutoLeaveDaysConfig(Long workspaceId) { - // fetch from local cache first. - Integer days = context.getWorkspaceDaysConfig().get(workspaceId); - if (Objects.nonNull(days)) { - return days; - } - // fetch from attendance service. - Map map = workspaceGateway.listAutoLeaveDaysConfig(Collections.singletonList(workspaceId)); - if (CollUtil.isEmpty(map)) { - return null; - } - // cache the config of this workspace - context.getWorkspaceDaysConfig().putAll(map); - // return days config - return context.getWorkspaceDaysConfig().get(workspaceId); - } - - @Data - private static class Context { - - /** - * start time of job execute - */ - private LocalDateTime startDateTime = LocalDateTime.now(); - - /** - * days configuration for add person tag of workspace. - * key: workspaceId - * value: days - */ - private Map workspaceDaysConfig = Maps.newHashMap(); - } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java index 577d9fb..30ba35f 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java @@ -11,18 +11,23 @@ import cn.hutool.core.collection.CollUtil; import com.alibaba.fastjson.JSON; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.xxl.job.core.handler.IJobHandler; import com.xxl.job.core.log.XxlJobLogger; +import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang.StringUtils; import javax.annotation.Resource; import java.time.LocalDateTime; +import java.time.ZoneId; import java.time.ZoneOffset; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.stream.Collectors; /** @@ -33,7 +38,7 @@ import java.util.stream.Collectors; @Slf4j public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { - static final int MAX_CNT_ONCE = 4; + static final int MAX_CNT_ONCE = 200; @Resource PersonTagConfig personTagConfig; @@ -45,7 +50,11 @@ public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { @Resource WorkspaceGateway workspaceGateway; + Context context; + void doExecute(String param) { + // init context + context = Context.instance(param); long scrollIndex = Long.MAX_VALUE; info("start to scan org_user."); // key: workspaceId value: records @@ -66,8 +75,6 @@ public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { abstract String logPrefix(); - abstract LocalDateTime startDateTimeOfJobExecution(); - abstract List scrollList(long scrollIndex); abstract Long extractId(T record); @@ -78,8 +85,6 @@ public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { abstract void handle(Long workspaceId, List records, List clockedPersonIds); - abstract Integer listAutoLeaveDaysConfig(Long workspaceId); - private void cacheAndTrigger(Map> localCache, List records) { // grouping by workspaceId Map> groupingByWorkspaceId = records.stream().collect(Collectors.groupingBy(this::extractWorkspaceId)); @@ -134,6 +139,23 @@ public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { } } + private Integer listAutoLeaveDaysConfig(Long workspaceId) { + // fetch from local cache first. + Integer days = context.getWorkspaceDaysConfig().get(workspaceId); + if (Objects.nonNull(days)) { + return days; + } + // fetch from attendance service. + Map map = workspaceGateway.listAutoLeaveDaysConfig(Collections.singletonList(workspaceId)); + if (CollUtil.isEmpty(map)) { + return null; + } + // cache the config of this workspace + context.getWorkspaceDaysConfig().putAll(map); + // return days config + return context.getWorkspaceDaysConfig().get(workspaceId); + } + private List findClockedPersons(Long workspaceId, Integer days, List records) { List personIds = CollUtil.map(records, this::extractPersonId, true); if (CollUtil.isEmpty(personIds)) { @@ -148,10 +170,12 @@ public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { } private List listClockRecords(Long workspaceId, Integer days, List personIds) { - LocalDateTime to = startDateTimeOfJobExecution(); + LocalDateTime to = context.getStartDateTime(); LocalDateTime from = to.minusDays(days); AttendanceClockRecordListReq request = new AttendanceClockRecordListReq(); request.setPersonIds(personIds); + // only list worker clocked records + request.setUserType(AttendanceClockRecordListReq.USER_TYPE_WORKER); request.setWorkspaceId(workspaceId); request.setClockAtFrom(Date.from(from.atZone(ZoneOffset.systemDefault()).toInstant())); request.setClockAtTo(Date.from(to.atZone(ZoneOffset.systemDefault()).toInstant())); @@ -169,4 +193,40 @@ public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { log.error(msgFormat, args); XxlJobLogger.log(msgFormat, args); } + + @Data + static class Context { + + /** + * param of job + */ + private Set workspaceIds = Sets.newHashSet(); + + private LocalDateTime startDateTime = LocalDateTime.now(); + + /** + * days configuration for add person tag of workspace. + * key: workspaceId + * value: days + */ + private Map workspaceDaysConfig = Maps.newHashMap(); + + static Context instance(String param) { + Context context = new Context(); + if (StringUtils.isNotBlank(param)) { + Context contextParam = JSON.parseObject(param, Context.class); + context.setWorkspaceIds(contextParam.getWorkspaceIds()); + } + return context; + } + + Date getJoinedAtLe(Long workspaceId) { + Integer days = workspaceDaysConfig.get(workspaceId); + if (Objects.isNull(days)) { + return null; + } + LocalDateTime le = startDateTime.minusDays(days); + return Date.from(le.atZone(ZoneId.systemDefault()).toInstant()); + } + } } From 89f2f8169287ba584dd5f981f4de591e99351a04 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 14:08:10 +0800 Subject: [PATCH 50/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86job?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 72ff149..f99246f 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -135,7 +135,10 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { List organizationalNodeUserList = nodeUserService.list(nodeUserQueryVO); Set teamLeader = Sets.newHashSet(); organizationalNodeUserList.forEach(organizationalNodeUserVO -> { - if (IdentityTypeEnum.WORKER_LEADER.getCode().equals(organizationalNodeUserVO.getIdentityType()) || entTeamLeader.equals(organizationalNodeUserVO.getJob().getCode())) { + if (IdentityTypeEnum.WORKER_LEADER.getCode().equals(organizationalNodeUserVO.getIdentityType())) { + teamLeader.add(organizationalNodeUserVO.getPersonId()); + } + if (Objects.nonNull(organizationalNodeUserVO.getJob()) && entTeamLeader.equals(organizationalNodeUserVO.getJob().getCode())) { teamLeader.add(organizationalNodeUserVO.getPersonId()); } }); @@ -471,7 +474,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { if (Objects.equals(nodeUser.getIdentityType(), IdentityType.PRACTITIONER.getCode())) { return 20; } - if (StrUtil.isBlank(nodeUser.getJob().getCode())) { + if (Objects.isNull(nodeUser.getJob()) || StrUtil.isBlank(nodeUser.getJob().getCode())) { return 9999; } switch (nodeUser.getJob().getCode()) { From 12f3d89efda5eb743eb049033c18426f95dae8e8 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 14:50:24 +0800 Subject: [PATCH 51/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=91=98=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/NodeUserCheckServiceImpl.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index f99246f..c09e086 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -237,14 +237,13 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { // 判断是否拥有admin角色 判断是否是分包管理员 List adminRoleIds = getSpecialRole(); PageRoleUserReq roleUserParam = PageRoleUserReq.builder().build(); - PageRoleUserReq.WorkspaceOuPair workspaceOuPair = new PageRoleUserReq.WorkspaceOuPair(); - workspaceOuPair.setWorkspaceId(req.getWorkspaceId()); - workspaceOuPair.setOuId(req.getOuId()); - roleUserParam.setWorkspaceOuPairs(Collections.singletonList(workspaceOuPair)); + List workspaceOuPairList = transformWorkspaceOuPair(nodeUsers); + roleUserParam.setWorkspaceOuPairs(workspaceOuPairList); roleUserParam.setPersonIds(req.getPersonIds()); roleUserParam.setNeedRole(true); List saasRoleUserInfo = roleUserGateway.pageAll(roleUserParam); + saasRoleUserInfo = saasRoleUserInfo.stream().filter(e -> Objects.nonNull(e.getRole())).collect(Collectors.toList()); saasRoleUserInfo.forEach(e -> { Optional roleTypeEnumOptional = RoleTypeEnum.fromValue(e.getRole().getRoleType()); RoleTypeEnum roleTypeEnum = RoleTypeEnum.AUTO_OWN; @@ -271,6 +270,15 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { return resultList; } + private List transformWorkspaceOuPair(List nodeUsers) { + return nodeUsers.stream().map(e -> { + PageRoleUserReq.WorkspaceOuPair ouPair = new PageRoleUserReq.WorkspaceOuPair(); + ouPair.setWorkspaceId(e.getWorkspaceId()); + ouPair.setOuId(e.getOrganizationalUnitId()); + return ouPair; + }).collect(Collectors.toList()); + } + private static void transformFailMap(Map> failInfoMap, List resultList) { if (CollUtil.isNotEmpty(failInfoMap)) { failInfoMap.forEach((failPerson, checkFailInfos) -> { From 517a5c25bc0ae34d48059a736ba66269640c5aab Mon Sep 17 00:00:00 2001 From: luofu Date: Wed, 12 Mar 2025 15:08:00 +0800 Subject: [PATCH 52/75] =?UTF-8?q?feat(REQ-3714)=20=E5=B7=A5=E4=BA=BA?= =?UTF-8?q?=E9=80=80=E5=9C=BA=E6=B5=81=E7=A8=8B=E4=BC=98=E5=8C=96=20-=20xx?= =?UTF-8?q?l-job=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orgmanax/infra/config/XxlJobConfig.java | 66 +++++++++++++++++++ .../xxl/AutoAddWorkerLeavedTagJob.java | 2 +- .../BaseAutoOperatePersonLeavedTagJob.java | 2 +- 3 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/XxlJobConfig.java diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/XxlJobConfig.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/XxlJobConfig.java new file mode 100644 index 0000000..5001f5e --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/XxlJobConfig.java @@ -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; + } + +} + diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java index acb396d..a0bc1f0 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/AutoAddWorkerLeavedTagJob.java @@ -24,7 +24,7 @@ import java.util.stream.Collectors; /** * @author luofu * @version 1.0 - * @description 自动退场OR标记为离场人员的JOB + * @description 自动给工人打离场标签的JOB * @date 2025/3/6 */ @Slf4j diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java index 30ba35f..5d9f4eb 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/xxl/BaseAutoOperatePersonLeavedTagJob.java @@ -56,7 +56,7 @@ public abstract class BaseAutoOperatePersonLeavedTagJob extends IJobHandler { // init context context = Context.instance(param); long scrollIndex = Long.MAX_VALUE; - info("start to scan org_user."); + info("start to scan data records."); // key: workspaceId value: records Map> localCache = Maps.newHashMap(); List records = scrollList(scrollIndex); From 796108914b34ba46ac86e033b0eccc40fc8f7f73 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 15:38:47 +0800 Subject: [PATCH 53/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=86=85=E5=B7=A5=E4=BA=BA=E9=80=80=E5=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foundation/impl/NodeUserFoundationServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index 148ee8d..6ec91db 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -199,8 +199,8 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService OrgUserWithdrawOrQuitReq quitReq = new OrgUserWithdrawOrQuitReq(); quitReq.setUnitUpdate(req.isUnitDelete()); quitReq.setWorkspaceId(req.getWorkspaceId()); - quitReq.setOuId(req.getOuId()); if (req.isUnitDelete()) { + quitReq.setOuId(req.getOuId()); quitReq.setWorkspaceId(nodeUserList.get(0).getWorkspaceId()); } quitReq.setTopNodeIdAndPersonIds(quitMap); @@ -210,6 +210,7 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService OrgProjectWorkerWithdrawReq workerReq = new OrgProjectWorkerWithdrawReq(); workerReq.setWorkspaceId(req.getWorkspaceId()); if (req.isUnitDelete()) { + quitReq.setOuId(req.getOuId()); workerReq.setWorkspaceId(nodeUserList.get(0).getWorkspaceId()); } workerReq.setPersonIds(req.getPersonIds()); From 25e15131683b284d1d3d114b8e7c9f7ed25718f8 Mon Sep 17 00:00:00 2001 From: zhangran Date: Wed, 12 Mar 2025 15:44:11 +0800 Subject: [PATCH 54/75] =?UTF-8?q?add(feature/REQ-3714)=20=E5=88=A4?= =?UTF-8?q?=E7=A9=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/DeletePlatTeamWorkerProcessor.java | 24 +++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index 6ad28e2..24ccbc8 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -17,7 +17,9 @@ import cn.axzo.orgmanax.infra.client.tyr.SaasRoleUserClient; import cn.axzo.orgmanax.infra.client.tyr.dto.OrgManaxWorkerManagerRoleUserReq; 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; import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalTeamOuRelation; +import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository; import cn.axzo.orgmanax.infra.dao.node.repository.TeamOuRelationRepository; import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobQueryRepository; import cn.axzo.orgmanax.infra.dao.unit.repository.UnitQueryRepository; @@ -78,6 +80,7 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { private final SaasRoleUserClient saasRoleUserClient; private final EventProduceTemplate eventProduceTemplate; private final RocketConfigProperties rocketConfigProperties; + private final NodeQueryRepository nodeQueryRepository; private static final String PROMISE_GROUP_EVENT_MODULE = "promise-group"; private static final String PROMISE_GROUP_EVENT_NAME = "promise-group-remove"; @@ -155,6 +158,7 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { private void removePlatTeamManager(OrganizationalTeamOuRelation ouRelation, List nodeUserDTOS) { //若该工人是班组管理员,则一并移除平台管理员、项目级权限等。 SaasCooperateShip saasCooperateShip = getSaasCooperateShip(ouRelation.getNodeId()); + AssertUtil.isFalse(Objects.isNull(saasCooperateShip), "获取班组协同关系失败"); // 获取岗位 List jobs = getJob(Sets.newHashSet(entManagerCode, entWorkerCode)); Optional entWorkerJob = jobs.stream().filter(item -> Objects.equals(item.getCode(), entWorkerCode)).findFirst(); @@ -187,11 +191,23 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { ); } - private SaasCooperateShip getSaasCooperateShip(Long nodeId) { - CooperateShipQueryRepository.OneReq build = CooperateShipQueryRepository.OneReq.builder() - .organizationalNodeId(nodeId) + private SaasCooperateShip getSaasCooperateShip(Long ouRelationNodeId) { + NodeQueryRepository.ListReq nodeQuery = NodeQueryRepository.ListReq.builder() + .ids(Lists.newArrayList(ouRelationNodeId)) .build(); - return cooperateShipQueryRepository.one(build); + List organizationalNodes = nodeQueryRepository.list(nodeQuery); + if (Objects.isNull(organizationalNodes)){ + return null; + } + OrganizationalNode organizationalNode = organizationalNodes.get(0); + CooperateShipQueryRepository.ListReq build = CooperateShipQueryRepository.ListReq.builder() + .organizationNodeIds(Lists.newArrayList(organizationalNode.getTopNodeId())) + .build(); + List saasCooperateShips = cooperateShipQueryRepository.list(build); + if(CollUtil.isEmpty(saasCooperateShips)){ + return null; + } + return saasCooperateShips.get(0); } private void updateWorkerNodeJob(OrgJobQueryRepository.JobResp jobResp, List nodeUserDTOS) { From a3bce5367ec4fcb666efb2d61b036995c7eac142 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 16:23:58 +0800 Subject: [PATCH 55/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=86=85=E5=B7=A5=E4=BA=BA=E9=80=80=E5=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/NodeUserFoundationServiceImpl.java | 14 +++++++++++--- .../impl/OrgUserFoundationServiceImpl.java | 3 +++ .../foundation/req/OrgUserWithdrawOrQuitReq.java | 2 ++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index 6ec91db..ede35b9 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -170,7 +170,7 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService List nodeUserIds = req.stream().map(NodeUserUpdate::getId).collect(Collectors.toList()); List dbNodeUsers = nodeUserQueryRepository.list(NodeUserQueryRepository.ListReq.builder() .ids(nodeUserIds).build()); - Axssert.checkNotEmpty(dbNodeUsers,"部门人员不存在 {}",nodeUserIds); + Axssert.checkNotEmpty(dbNodeUsers, "部门人员不存在 {}", nodeUserIds); List updateReqs = BeanUtil.copyToList(req, NodeUserUpsertRepository.UpdateReq.class); return nodeUserUpsertRepository.updateBatchById(updateReqs); @@ -188,6 +188,8 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService if (CollUtil.isEmpty(list)) { return CollUtil.newArrayList(); } + Map> 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 nodeUserList = list.stream().map(e -> BeanUtil.toBean(e, OrganizationalNodeUser.class)).collect(Collectors.toList()); @@ -199,12 +201,18 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService 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> unitPersonIds : ouPersonIdsMap.entrySet()) { + quitReq.setOuId(unitPersonIds.getKey()); + quitReq.setPersonIds(unitPersonIds.getValue()); + orgUserFoundationService.batchWithdrawOrQuit(quitReq); + } } - quitReq.setTopNodeIdAndPersonIds(quitMap); - orgUserFoundationService.batchWithdrawOrQuit(quitReq); //项目内工人退场 OrgProjectWorkerWithdrawReq workerReq = new OrgProjectWorkerWithdrawReq(); diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java index 31f6c02..921f729 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java @@ -60,6 +60,9 @@ public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { listOrgUserReq.setWorkspaceId(req.getWorkspaceId()); Set personIds = req.getTopNodeIdAndPersonIds().values().stream().flatMap(Set::stream).collect(Collectors.toSet()); listOrgUserReq.setPersonIds(personIds); + if (CollUtil.isNotEmpty(req.getPersonIds())) { + listOrgUserReq.setPersonIds(req.getPersonIds()); + } List list = orgUserQueryRepository.list(listOrgUserReq); if (CollUtil.isEmpty(list)) { return; diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/req/OrgUserWithdrawOrQuitReq.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/req/OrgUserWithdrawOrQuitReq.java index 4745578..a4ee7d8 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/req/OrgUserWithdrawOrQuitReq.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/req/OrgUserWithdrawOrQuitReq.java @@ -18,6 +18,8 @@ public class OrgUserWithdrawOrQuitReq { private Map> topNodeIdAndPersonIds; + private Set personIds; + /** * 是否单位更新 */ From f4a85a986f3f3255e76a5c6132386ed794b5bd7e Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 17:17:14 +0800 Subject: [PATCH 56/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E5=86=85=E5=B7=A5=E4=BA=BA=E9=80=80=E5=9C=BA?= =?UTF-8?q?=E5=92=8C=E5=8F=91=E9=80=81mq=E5=88=A0=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../producer/OrgUserChangedEventProducer.java | 1 + .../impl/NodeUserFoundationServiceImpl.java | 18 ++++++++++++------ .../OrgProjectWorkerFoundationServiceImpl.java | 6 +++--- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java index 0f99987..166e24e 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/mq/producer/OrgUserChangedEventProducer.java @@ -58,6 +58,7 @@ public class OrgUserChangedEventProducer { 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) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index ede35b9..268a4f3 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -29,6 +29,7 @@ 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; @@ -49,11 +50,7 @@ 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.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; /** @@ -218,7 +215,7 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService OrgProjectWorkerWithdrawReq workerReq = new OrgProjectWorkerWithdrawReq(); workerReq.setWorkspaceId(req.getWorkspaceId()); if (req.isUnitDelete()) { - quitReq.setOuId(req.getOuId()); + workerReq.setOuId(req.getOuId()); workerReq.setWorkspaceId(nodeUserList.get(0).getWorkspaceId()); } workerReq.setPersonIds(req.getPersonIds()); @@ -239,6 +236,15 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService .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) { diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java index ea60426..eeaf5a7 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java @@ -42,9 +42,9 @@ public class OrgProjectWorkerFoundationServiceImpl implements OrgProjectWorkerFo Date now = new Date(); List orgProjectWorkers = projectWorkerResps.stream().map(e -> { OrgProjectWorker orgProjectWorker = BeanUtil.toBean(e, OrgProjectWorker.class); - e.setStatus(ProjectWorkerStatusEnum.WITHDRAW.getValue()); - e.setResignAt(now); - e.setUpdateAt(now); + orgProjectWorker.setStatus(ProjectWorkerStatusEnum.WITHDRAW.getValue()); + orgProjectWorker.setResignAt(now); + orgProjectWorker.setUpdateAt(now); return orgProjectWorker; }).collect(Collectors.toList()); orgProjectWorkerUpsertRepository.batchUpdate(orgProjectWorkers); From 04bf864e9366482654cb545abd7ae7d2c45e0ef9 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 21:14:43 +0800 Subject: [PATCH 57/75] =?UTF-8?q?feat(REQ-3714):=20=E4=B8=8D=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=BD=93=E5=89=8D=E6=93=8D=E4=BD=9C=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index c09e086..6c0c2ba 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -210,21 +210,17 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { List nodeUsers = nodeUserService.list(query); // 校验当前入参 checkPermission(nodeUsers); - // 过滤当前操作人员 - nodeUsers = nodeUsers.stream() - .filter(e -> !Objects.equals(e.getPersonId(), personId)) - .collect(Collectors.toList()); + if (CollUtil.isEmpty(nodeUsers)) { req.getPersonIds().forEach(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); addFailInfo(failInfoMap, e, checkFailInfo); }); - } - if (CollUtil.isEmpty(nodeUsers)) { transformFailMap(failInfoMap, resultList); return resultList; } + nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).findAny().ifPresent(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER); From cae7d05157b1f24b8e53cf16c5981971d8c1e88d Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Wed, 12 Mar 2025 21:28:18 +0800 Subject: [PATCH 58/75] =?UTF-8?q?feat(REQ-3714):=20=E4=B8=8D=E8=BF=87?= =?UTF-8?q?=E6=BB=A4=E5=BD=93=E5=89=8D=E6=93=8D=E4=BD=9C=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/NodeUserCheckServiceImpl.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 6c0c2ba..28e518b 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -199,17 +199,17 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { // 协同节点关联的顶级部门节点列表 List nodeIds = cooperateShipRespList.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList()); List nodePersonIds = Lists.newArrayList(req.getPersonIds()); - nodePersonIds.add(personId); ListNodeUserReq query = ListNodeUserReq.builder() .topNodeIds(nodeIds) .personIds(nodePersonIds) .needs(ListNodeUserReq.Needs.builder().job(true).build()) .findByAncestorNodeId(true) .build(); - // 查询当前登录及待删除人员在当前项目中的参与记录(仅限当前登录单位) + // 查询待删除人员在当前项目中的参与记录(仅限当前登录单位) List nodeUsers = nodeUserService.list(query); - // 校验当前入参 - checkPermission(nodeUsers); + + // 校验当前操作人 + checkPermission(nodeUsers, personId, nodePersonIds); if (CollUtil.isEmpty(nodeUsers)) { req.getPersonIds().forEach(e -> { @@ -217,10 +217,12 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); addFailInfo(failInfoMap, e, checkFailInfo); }); + } + + if (CollUtil.isEmpty(nodeUsers)) { transformFailMap(failInfoMap, resultList); return resultList; } - nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).findAny().ifPresent(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER); @@ -323,9 +325,11 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } } - private void checkPermission(List nodeUsers) { + private void checkPermission(List nodeUsers, Long personId, List nodePersonIds) { if (CollUtil.isEmpty(nodeUsers)) { - throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目,请刷新后重试当前操作!"); + if (nodePersonIds.size() == 1 && Objects.equals(personId, nodePersonIds.get(0))) { + throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目,请刷新后重试当前操作!"); + } } } From 35bca706443fc1d927beea7a34c585118534ba8c Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 13 Mar 2025 11:40:48 +0800 Subject: [PATCH 59/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E6=9D=83=E9=99=90=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/NodeUserCheckServiceImpl.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 28e518b..acbb540 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -189,9 +189,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { List resultList = new ArrayList<>(); Map> failInfoMap = new HashMap<>(); ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); - if (NumberUtil.isPositiveNumber(req.getNodeId())) { - listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); - } + listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); List cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq); @@ -223,6 +221,16 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { transformFailMap(failInfoMap, resultList); return resultList; } + + Set inJurisdictionPersonIds = nodeUsers.stream().map(NodeUserDTO::getPersonId).collect(Collectors.toSet()); + for (Long reqPersonIds : req.getPersonIds()) { + if (!inJurisdictionPersonIds.contains(reqPersonIds)) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, reqPersonIds, checkFailInfo); + } + } + nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).findAny().ifPresent(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER); From 56bfc838cb3491f8a268327269cc749d09043b55 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 13 Mar 2025 12:45:48 +0800 Subject: [PATCH 60/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=BB=84=E7=BB=87=E6=9D=83=E9=99=90=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index acbb540..9e5b2f2 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -189,7 +189,9 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { List resultList = new ArrayList<>(); Map> failInfoMap = new HashMap<>(); ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); - listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); + if (NumberUtil.isPositiveNumber(req.getNodeId())) { + listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); + } listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); List cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq); From 4c54f73e884776a9e4bb0656d202327c0fee61b1 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 13 Mar 2025 12:48:28 +0800 Subject: [PATCH 61/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=93=8D=E4=BD=9C=E7=BB=84=E7=BB=87=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 9e5b2f2..acbb540 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -189,9 +189,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { List resultList = new ArrayList<>(); Map> failInfoMap = new HashMap<>(); ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); - if (NumberUtil.isPositiveNumber(req.getNodeId())) { - listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); - } + listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); List cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq); From 743b36fd4eebca0d51ef21cae32ec64ad25c2bbe Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 13 Mar 2025 12:50:52 +0800 Subject: [PATCH 62/75] =?UTF-8?q?feat(REQ-3714):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E4=B8=8D=E5=9C=A8=E7=BB=84=E7=BB=87=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/service/impl/NodeUserCheckServiceImpl.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index acbb540..5b7605e 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -215,9 +215,6 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); addFailInfo(failInfoMap, e, checkFailInfo); }); - } - - if (CollUtil.isEmpty(nodeUsers)) { transformFailMap(failInfoMap, resultList); return resultList; } From 2ed02cd04cec5c757e3102d1efe56b96193f87ff Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 13 Mar 2025 14:38:36 +0800 Subject: [PATCH 63/75] =?UTF-8?q?feat(REQ-3714):=20=E5=8D=8F=E5=90=8C?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E6=9F=A5=E8=AF=A2=E4=B8=8B=E7=BA=A7=E8=8A=82?= =?UTF-8?q?=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/service/impl/NodeUserCheckServiceImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 5b7605e..963bb37 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -192,14 +192,17 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); + listOrgCooperateShipReq.setIncludeChildren(true); List cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq); Axssert.checkNotEmpty(cooperateShipRespList, "操作失败,获取协同组织失败"); + // 协同节点关联的顶级部门节点列表 List nodeIds = cooperateShipRespList.stream().map(OrgCooperateShipDTO::getOrganizationalNodeId).distinct().collect(Collectors.toList()); List nodePersonIds = Lists.newArrayList(req.getPersonIds()); ListNodeUserReq query = ListNodeUserReq.builder() .topNodeIds(nodeIds) .personIds(nodePersonIds) + .findByTopNodeId(true) .needs(ListNodeUserReq.Needs.builder().job(true).build()) .findByAncestorNodeId(true) .build(); From 15648e026fbe1e276994e234908e5d8833096043 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 13 Mar 2025 15:56:42 +0800 Subject: [PATCH 64/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=8F=AD=E7=BB=84=E9=95=BF=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 963bb37..33a28c1 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -231,10 +231,12 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } } + Set teamLeadPersonSet = new HashSet<>(); nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).findAny().ifPresent(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER); addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); + teamLeadPersonSet.add(e.getPersonId()); }); // 判断小组长,小组长不允许删除 @@ -251,6 +253,10 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { List saasRoleUserInfo = roleUserGateway.pageAll(roleUserParam); saasRoleUserInfo = saasRoleUserInfo.stream().filter(e -> Objects.nonNull(e.getRole())).collect(Collectors.toList()); saasRoleUserInfo.forEach(e -> { + // 班组长不用校验,因为班组长也会有管理员角色 + if (teamLeadPersonSet.contains(e.getPersonId())) { + return; + } Optional roleTypeEnumOptional = RoleTypeEnum.fromValue(e.getRole().getRoleType()); RoleTypeEnum roleTypeEnum = RoleTypeEnum.AUTO_OWN; if (roleTypeEnumOptional.isPresent()) { From ad22076462d72fef7827174757c34f4ea035fdf1 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 13 Mar 2025 18:09:05 +0800 Subject: [PATCH 65/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E7=AE=A1=E8=BE=96=E8=8C=83=E5=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/req/BatchDeleteNodeUserCheckReq.java | 14 ++++++++++++-- .../service/impl/NodeUserCheckServiceImpl.java | 3 --- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java index ccb36b2..18b64b9 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/nodeuser/req/BatchDeleteNodeUserCheckReq.java @@ -3,7 +3,6 @@ package cn.axzo.orgmanax.dto.nodeuser.req; import lombok.Data; import javax.validation.constraints.NotNull; -import java.util.List; import java.util.Set; /** @@ -33,4 +32,15 @@ public class BatchDeleteNodeUserCheckReq { * 操作者ID */ private Long operatorId; -} + + /** + * 登录单位 + */ + private Long loginOuId; + + /** + * 单位类型 + */ + private Integer ouType; + +} \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 33a28c1..920f20f 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -114,7 +114,6 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); listOrgCooperateShipReq.setOuIds(Collections.singleton(ouId)); - listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); listOrgCooperateShipReq.setWorkspaceTypes(CollUtil.newHashSet(2)); List listPersonJoinedWorkspace = cooperateShipService.list(listOrgCooperateShipReq); Set inProjectPersonIds = filterByPerson(listPersonJoinedWorkspace, personIds); @@ -191,8 +190,6 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { ListOrgCooperateShipReq listOrgCooperateShipReq = new ListOrgCooperateShipReq(); listOrgCooperateShipReq.setOuIds(Collections.singleton(req.getOuId())); listOrgCooperateShipReq.setWorkspaceIds(Collections.singleton(req.getWorkspaceId())); - listOrgCooperateShipReq.setStatuses(CollUtil.newHashSet(0, 1)); - listOrgCooperateShipReq.setIncludeChildren(true); List cooperateShipRespList = cooperateShipService.list(listOrgCooperateShipReq); Axssert.checkNotEmpty(cooperateShipRespList, "操作失败,获取协同组织失败"); From 8f1cc335beb3bc44188cd97ec84fe5f112e3d998 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 14 Mar 2025 10:20:16 +0800 Subject: [PATCH 66/75] =?UTF-8?q?feat(REQ-3714):=20=E6=9B=B4=E6=96=B0org?= =?UTF-8?q?=5Fuser=E5=8A=A0=E4=B8=8A=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orgmanax-server/pom.xml | 4 + .../impl/OrgUserFoundationServiceImpl.java | 20 ++++- .../orgmanax/server/util/RedisLockUtil.java | 87 +++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/util/RedisLockUtil.java diff --git a/orgmanax-server/pom.xml b/orgmanax-server/pom.xml index bfdf316..2f840f4 100644 --- a/orgmanax-server/pom.xml +++ b/orgmanax-server/pom.xml @@ -50,6 +50,10 @@ org.springframework.cloud spring-cloud-starter-bootstrap + + cn.axzo.pokonyan + pokonyan + diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java index 921f729..7d0d49a 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/orguser/foundation/impl/OrgUserFoundationServiceImpl.java @@ -15,6 +15,7 @@ import cn.axzo.orgmanax.infra.dao.orguser.repository.OrgUserUpsertRepository; import cn.axzo.orgmanax.server.mq.producer.OrgUserChangedEventProducer; import cn.axzo.orgmanax.server.orguser.foundation.OrgUserFoundationService; import cn.axzo.orgmanax.server.orguser.foundation.req.OrgUserWithdrawOrQuitReq; +import cn.axzo.orgmanax.server.util.RedisLockUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Pair; import lombok.RequiredArgsConstructor; @@ -35,6 +36,13 @@ import java.util.stream.Collectors; @RequiredArgsConstructor public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { + private static final String LOG_PREFIX = "[ORG_USER_OP] "; + + private static final long OP_LOCK_TIMEOUT = 1000 * 5; + private static final String OP_LOCK_PREFIX = "ORG_USER"; + private static final String OP_SINGLETON_UPSERT = "SINGLETON_UPSERT"; + private static final String OP_BATCH_UPSERT = "BATCH_UPSERT"; + private final WorkspaceGateway workspaceGateway; private final OrgUserQueryRepository orgUserQueryRepository; private final OrgUserUpsertRepository orgUserUpsertRepository; @@ -42,10 +50,16 @@ public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { @Override public void batchWithdrawOrQuit(OrgUserWithdrawOrQuitReq req) { - OrgUserStatusEnum status; if (NumberUtil.isNotPositiveNumber(req.getWorkspaceId())) { return; } + // 优先获取批量写操作的锁,成功获取后再执行单个的写操作 + String redisKey = generateBatchOperationKey(req.getOuId(), req.getWorkspaceId()); + RedisLockUtil.tryLock(redisKey, OP_LOCK_TIMEOUT, () -> dealUpdate(req)); + } + + private void dealUpdate(OrgUserWithdrawOrQuitReq req) { + OrgUserStatusEnum status; if (req.isUnitUpdate()) { WorkspaceDetailReq workspaceDetailReq = new WorkspaceDetailReq(); workspaceDetailReq.setId(req.getWorkspaceId()); @@ -123,4 +137,8 @@ public class OrgUserFoundationServiceImpl implements OrgUserFoundationService { return dto; } + private static String generateBatchOperationKey(Long ouId, Long workspaceId) { + return RedisLockUtil.formatKey(OP_LOCK_PREFIX, OP_BATCH_UPSERT, ouId, workspaceId); + } + } \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/util/RedisLockUtil.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/util/RedisLockUtil.java new file mode 100644 index 0000000..b0df1f4 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/util/RedisLockUtil.java @@ -0,0 +1,87 @@ +package cn.axzo.orgmanax.server.util; + +import cn.axzo.basics.common.util.AssertUtil; +import cn.axzo.maokai.common.enums.ErrorCodeEnum; +import cn.axzo.pokonyan.config.redis.RedisClient; +import cn.hutool.core.lang.UUID; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import java.util.Arrays; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +/** + * @author luofu + * @version 1.0 + * @date 2024/6/3 + */ +@Slf4j +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class RedisLockUtil { + + /** + * redis key format + * + * @param prefix 前缀 + * @param params 参数 + * @return 格式化后的字符串 + */ + public static String formatKey(String prefix, Object... params) { + AssertUtil.notEmpty(prefix, "prefix can not be empty"); + if (Objects.isNull(params) || 0 == params.length) { + return prefix; + } + String strParams = Arrays.stream(params).map(Object::toString) + .collect(Collectors.joining(REDIS_LOCK_SPLITER)); + return APP_NAME + ":" + prefix + REDIS_LOCK_SPLITER + strParams; + } + + /** + * do some thing while successfully fetch lock + * + * @param key 锁 + * @param tryTimeoutMills 超时时间,单位毫秒 + * @param executor 执行器 + */ + public static void tryLock(String key, long tryTimeoutMills, Runnable executor) { + AssertUtil.notEmpty(key, "key can not be empty"); + AssertUtil.notNull(executor, "executor can not be null"); + String requestId = UUID.randomUUID().toString(); + try { + long keyTimeoutMills = tryTimeoutMills * 2; + Boolean lockResult = RedisClient.LockOps.getLockUntilTimeout(key, requestId, keyTimeoutMills, TimeUnit.MILLISECONDS, tryTimeoutMills); + AssertUtil.isTrue(Boolean.TRUE.equals(lockResult), ErrorCodeEnum.SYSTEM_BUSY.getMessage()); + executor.run(); + } finally { + RedisClient.LockOps.releaseLock(key, requestId); + } + } + + /** + * do some thing while successfully fetch lock + * + * @param key 锁 + * @param tryTimeoutMills 超时时间,单位毫秒 + * @param executor 执行器 + */ + public static T tryLock(String key, long tryTimeoutMills, Supplier executor) { + AssertUtil.notEmpty(key, "key can not be empty"); + AssertUtil.notNull(executor, "executor can not be null"); + String requestId = UUID.randomUUID().toString(); + try { + long keyTimeoutMills = tryTimeoutMills * 2; + Boolean lockResult = RedisClient.LockOps.getLockUntilTimeout(key, requestId, keyTimeoutMills, TimeUnit.MILLISECONDS, tryTimeoutMills); + AssertUtil.isTrue(Boolean.TRUE.equals(lockResult), ErrorCodeEnum.SYSTEM_BUSY.getMessage()); + return executor.get(); + } finally { + RedisClient.LockOps.releaseLock(key, requestId); + } + } + + private static final String REDIS_LOCK_SPLITER = ":"; + private static final String APP_NAME = "[maokai]"; +} From c9309f5ad7ca6c2ed160a4b7be9f92c644e24bd6 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 14 Mar 2025 11:44:48 +0800 Subject: [PATCH 67/75] =?UTF-8?q?feat(REQ-3714):=20=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=A4=9A=E4=B8=AA=E7=8F=AD=E7=BB=84=E9=95=BF=E7=9A=84=E6=83=85?= =?UTF-8?q?=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/nodeuser/service/impl/NodeUserCheckServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 920f20f..8f0f769 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -229,7 +229,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } Set teamLeadPersonSet = new HashSet<>(); - nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).findAny().ifPresent(e -> { + nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).forEach(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.TEAM_LEADER); addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); From 333f7825547c12910357f7c41ddc726ad2d7d224 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 14 Mar 2025 16:30:39 +0800 Subject: [PATCH 68/75] =?UTF-8?q?feat(REQ-3714):=20=E4=B8=8D=E5=9C=A8?= =?UTF-8?q?=E7=AE=A1=E8=BE=96=E8=8C=83=E5=9B=B4=E4=BC=98=E5=85=88=E6=8F=90?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/dto/CheckUserOperateParam.java | 2 + .../impl/NodeUserCheckServiceImpl.java | 106 ++++++++++++------ 2 files changed, 71 insertions(+), 37 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java index e0ab5b4..deee942 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/dto/CheckUserOperateParam.java @@ -7,6 +7,7 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.apache.commons.lang3.ObjectUtils; +import java.util.List; import java.util.Set; /** @@ -22,6 +23,7 @@ public class CheckUserOperateParam { private Set personIds; private Long workspaceId; private boolean isWorkspace; + private List topNodeIds; public void check() { if (ObjectUtils.anyNull(personIds, workspaceId, operatorId)) { diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 8f0f769..484ff37 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -153,6 +153,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { .operatorId(req.getOperatorId()) .personIds(req.getPersonIds()) .workspaceId(req.getWorkspaceId()) + .topNodeIds(Collections.singletonList(topNodeId)) .build(), failInfoMap); transformFailMap(failInfoMap, resultList); return resultList; @@ -207,7 +208,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { List nodeUsers = nodeUserService.list(query); // 校验当前操作人 - checkPermission(nodeUsers, personId, nodePersonIds); + checkPermission(nodeUsers, personId, req.getPersonIds()); if (CollUtil.isEmpty(nodeUsers)) { req.getPersonIds().forEach(e -> { @@ -228,6 +229,25 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } } + // 检查节点权限 + boolean noTInJurisdiction = checkUserOperate(CheckUserOperateParam.builder() + .operatorId(req.getOperatorId()) + .personIds(req.getPersonIds()) + .workspaceId(req.getWorkspaceId()) + .isWorkspace(true) + .topNodeIds(nodeIds) + .build(), failInfoMap); + + if (!noTInJurisdiction) { + req.getPersonIds().forEach(e -> { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, e, checkFailInfo); + }); + transformFailMap(failInfoMap, resultList); + return resultList; + } + Set teamLeadPersonSet = new HashSet<>(); nodeUsers.stream().filter(e -> e.getIdentityType().equals(IdentityType.WORKER_LEADER.getCode())).forEach(e -> { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); @@ -246,6 +266,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { roleUserParam.setWorkspaceOuPairs(workspaceOuPairList); roleUserParam.setPersonIds(req.getPersonIds()); roleUserParam.setNeedRole(true); + roleUserParam.setPageSize(1000); List saasRoleUserInfo = roleUserGateway.pageAll(roleUserParam); saasRoleUserInfo = saasRoleUserInfo.stream().filter(e -> Objects.nonNull(e.getRole())).collect(Collectors.toList()); @@ -266,13 +287,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { addFailInfo(failInfoMap, e.getPersonId(), checkFailInfo); } }); - // 检查节点权限 - checkUserOperate(CheckUserOperateParam.builder() - .operatorId(req.getOperatorId()) - .personIds(req.getPersonIds()) - .workspaceId(req.getWorkspaceId()) - .isWorkspace(true) - .build(), failInfoMap); + // 三方阻断校验 thirdApiCheckPerson(req.getWorkspaceId(), req.getPersonIds(), failInfoMap); transformFailMap(failInfoMap, resultList); @@ -280,10 +295,11 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } private List transformWorkspaceOuPair(List nodeUsers) { - return nodeUsers.stream().map(e -> { + Map worspaceOuPairMap = nodeUsers.stream().collect(Collectors.toMap(NodeUserDTO::getWorkspaceId, NodeUserDTO::getOrganizationalUnitId, (e1, e2) -> e1)); + return worspaceOuPairMap.entrySet().stream().map(e -> { PageRoleUserReq.WorkspaceOuPair ouPair = new PageRoleUserReq.WorkspaceOuPair(); - ouPair.setWorkspaceId(e.getWorkspaceId()); - ouPair.setOuId(e.getOrganizationalUnitId()); + ouPair.setWorkspaceId(e.getKey()); + ouPair.setOuId(e.getValue()); return ouPair; }).collect(Collectors.toList()); } @@ -328,6 +344,9 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { return; } for (NodeUserDTO u : nodeUsers) { + if (Objects.isNull(u.getJob())) { + continue; + } if (projectTeamGPLeader.equals(u.getJob().getCode())) { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.PROJECT_GROUP_LEADER); @@ -336,9 +355,9 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } } - private void checkPermission(List nodeUsers, Long personId, List nodePersonIds) { + private void checkPermission(List nodeUsers, Long personId, Set nodePersonIds) { if (CollUtil.isEmpty(nodeUsers)) { - if (nodePersonIds.size() == 1 && Objects.equals(personId, nodePersonIds.get(0))) { + if (nodePersonIds.size() == 1 && Objects.equals(personId, nodePersonIds.stream().findFirst().orElse(null))) { throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目,请刷新后重试当前操作!"); } } @@ -352,9 +371,9 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } } - public void checkUserOperate(CheckUserOperateParam param, Map> failInfoMap) { + public boolean checkUserOperate(CheckUserOperateParam param, Map> failInfoMap) { if (NumberUtil.isNotPositiveNumber(param.getOperatorId())) { - return; + return false; } param.check(); List nodePersonIds = Lists.newArrayList(param.getPersonIds()); @@ -363,9 +382,12 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { .personIds(nodePersonIds) .workspaceId(param.getWorkspaceId()) .needs(ListNodeUserReq.Needs.builder().job(true).node(true).build()) + .topNodeIds(param.getTopNodeIds()) + .findByTopNodeId(true) .build(); List nodeUsers = nodeUserService.list(nodeUserReq); NodeUserDTO operator = nodeUsers.stream().filter(nu -> Objects.equals(nu.getPersonId(), param.getOperatorId())) + .filter(nu -> Objects.nonNull(nu.getJob())) .filter(nu -> StrUtil.isNotBlank(nu.getJob().getCode())) .min(Comparator.comparingInt(NODE_USER_PRIORITY_RESOLVER)).orElse(null); List targets = param.getPersonIds().stream() @@ -378,6 +400,14 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { log.info("## checkUserOperate, param = {}, operator = {}, targets = {}, nodeUsers = {} " , JSON.toJSONString(param), JSON.toJSONString(operator), JSON.toJSONString(targets), JSON.toJSONString(nodeUsers)); if (operator == null) { + if (CollUtil.isNotEmpty(targets)) { + targets.forEach(target -> { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + }); + return false; + } throw ResultCode.INVALID_PARAMS.toException("你已经被移出该企业/项目,请及时联系管理员;你可以退出登录或切换到其他企业/项目使用"); } if (CollUtil.isEmpty(targets)) { @@ -389,11 +419,11 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { throw ResultCode.INVALID_PARAMS.toException("操作失败,您暂无权限!"); } if (param.getPersonIds().size() == 1 && param.getPersonIds().contains(param.getOperatorId())) { - return; + return true; } // 如果 操作人是 从业人员 直接返回 if (isPractitioner(operator)) { - return; + return true; } // 操作人是 班组长或者带班长, 则被操作人,只能是 自己,或者自己班组 及 小组的工人 if (isProjectTeamLeader(operator) || isProjectTeamManager(operator)) { @@ -402,15 +432,10 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { if (isProjectGroupManager(operator)) { targets.forEach(target -> groupManagerCheck(target, operator, nodeUsers, failInfoMap)); } + return true; } private void groupManagerCheck(NodeUserDTO target, NodeUserDTO operator, List nodeUsers, Map> failInfoMap) { - if (isPractitioner(target)) { - BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); - checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN); - addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); - return; - } // 工人必须仅在自己小组 boolean isSameGroup = nodeUsers.stream() .filter(nu -> Objects.equals(nu.getPersonId(), target.getPersonId())) @@ -419,10 +444,25 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + return; + } + if (isPractitioner(target)) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); } } private void teamManagerCheck(NodeUserDTO target, NodeUserDTO operator, Map> failInfoMap) { + // 否则,自己下级小组,也可以。 + boolean isGroup = target.getNode() != null + && Objects.equals(target.getNode().getNodeType(), NodeTypeEnum.PROJECT_GROUP.getCode()); + if (!isGroup) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + return; + } if (isPractitioner(target)) { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN); @@ -433,15 +473,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { if (isSameTeam) { return; } - // 否则,自己下级小组,也可以。 - boolean isGroup = target.getNode() != null - && Objects.equals(target.getNode().getNodeType(), NodeTypeEnum.PROJECT_GROUP.getCode()); - if (!isGroup) { - BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); - checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); - addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); - return; - } + Long belongProjectTeamNodeId = resolveProjectTeamNodeId(target.getOrganizationalNodeId()); if (Objects.equals(belongProjectTeamNodeId, operator.getOrganizationalNodeId())) { return; @@ -452,35 +484,35 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { } private boolean isPractitioner(NodeUserDTO nodeUser) { - if (nodeUser == null) { + if (nodeUser == null || Objects.isNull(nodeUser.getJob())) { return false; } return Objects.equals(nodeUser.getIdentityType(), IdentityType.PRACTITIONER.getCode()); } private boolean isProjectWorker(NodeUserDTO nodeUser) { - if (nodeUser == null) { + if (nodeUser == null || Objects.isNull(nodeUser.getJob())) { return false; } return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJECT_TEAM_WORKER); } private boolean isProjectTeamLeader(NodeUserDTO nodeUser) { - if (nodeUser == null) { + if (nodeUser == null || Objects.isNull(nodeUser.getJob())) { return false; } return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJ_TEAM_LEADER); } private boolean isProjectTeamManager(NodeUserDTO nodeUser) { - if (nodeUser == null) { + if (nodeUser == null || Objects.isNull(nodeUser.getJob())) { return false; } return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJ_TEAM_MANAGER); } private boolean isProjectGroupManager(NodeUserDTO nodeUser) { - if (nodeUser == null) { + if (nodeUser == null || Objects.isNull(nodeUser.getJob())) { return false; } return Objects.equals(nodeUser.getJob().getCode(), JobCodeConstants.PROJECT_TEAM_GROUP_LEADER); From 0985708ba710b57963d07cdd88ece57d8841bd33 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Fri, 14 Mar 2025 16:55:29 +0800 Subject: [PATCH 69/75] =?UTF-8?q?feat(REQ-3714):=20=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=9A=84=E5=BC=95=E5=85=A5=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../foundation/impl/NodeUserFoundationServiceImpl.java | 3 --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 7 ------- 2 files changed, 10 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java index 268a4f3..228b217 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/foundation/impl/NodeUserFoundationServiceImpl.java @@ -271,9 +271,6 @@ public class NodeUserFoundationServiceImpl implements NodeUserFoundationService /** * 根据条件聚合查询节点用户 - * - * @param req - * @return */ @Override public List searchEntUser(SearchEntNodeUserReq req) { diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 484ff37..3ca98dc 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -21,7 +21,6 @@ import cn.axzo.orgmanax.infra.client.tyr.RoleUserGateway; import cn.axzo.orgmanax.infra.client.workspace.WorkspaceGateway; import cn.axzo.orgmanax.infra.client.workspace.dto.Workspace; import cn.axzo.orgmanax.server.cooperateship.service.CooperateShipService; -import cn.axzo.orgmanax.server.node.service.NodeService; import cn.axzo.orgmanax.server.nodeuser.dto.CheckUserOperateParam; import cn.axzo.orgmanax.server.nodeuser.service.NodeUserCheckService; import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService; @@ -60,8 +59,6 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { private final NodeUserService nodeUserService; - private final NodeService nodeService; - private final KarmaThirdApiClient karmaThirdApiClient; // 单位类型默认角色关系,后面可以座位管理员的逻辑进行迭代 @@ -78,10 +75,6 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { @Value("${entTeamLeader:entTeamLeader}") private String entTeamLeader; - // 企业内班组工人岗位编码 - @Value("${entWorker:entWorker}") - private String entWorker; - @Override public List checkUnit(BatchDeleteNodeUserCheckReq req) { List resultList = new ArrayList<>(); From bc999a5035706c0cf5e559e69a177a9c9a88a438 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Mon, 17 Mar 2025 10:48:09 +0800 Subject: [PATCH 70/75] =?UTF-8?q?feat(REQ-3714):=20=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E7=8F=AD=E7=BB=84=E9=95=BF=E5=88=A4=E6=96=AD=E9=A1=BA=E5=BA=8F?= =?UTF-8?q?=EF=BC=8C=E5=92=8C=E5=BD=93=E5=89=8D=E4=BA=BA=E7=9A=84=E5=88=A4?= =?UTF-8?q?=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/NodeUserCheckServiceImpl.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index 3ca98dc..d511b84 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -350,7 +350,7 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { private void checkPermission(List nodeUsers, Long personId, Set nodePersonIds) { if (CollUtil.isEmpty(nodeUsers)) { - if (nodePersonIds.size() == 1 && Objects.equals(personId, nodePersonIds.stream().findFirst().orElse(null))) { + if (nodePersonIds.size() == 1 && nodePersonIds.contains(personId)) { throw ResultCode.INVALID_PARAMS.toException("你已被移除当前项目,请刷新后重试当前操作!"); } } @@ -450,12 +450,6 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { // 否则,自己下级小组,也可以。 boolean isGroup = target.getNode() != null && Objects.equals(target.getNode().getNodeType(), NodeTypeEnum.PROJECT_GROUP.getCode()); - if (!isGroup) { - BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); - checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); - addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); - return; - } if (isPractitioner(target)) { BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); checkFailInfo.setType(CheckInfoTypeEnum.ANY_ADMIN); @@ -466,6 +460,12 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { if (isSameTeam) { return; } + if (!isGroup) { + BatchDeleteNodeUserCheckResp.CheckFailInfo checkFailInfo = new BatchDeleteNodeUserCheckResp.CheckFailInfo(); + checkFailInfo.setType(CheckInfoTypeEnum.NOT_IN_JURISDICTION); + addFailInfo(failInfoMap, target.getPersonId(), checkFailInfo); + return; + } Long belongProjectTeamNodeId = resolveProjectTeamNodeId(target.getOrganizationalNodeId()); if (Objects.equals(belongProjectTeamNodeId, operator.getOrganizationalNodeId())) { From 0f213baf6acc8599018cb29a838f3f63c7e54346 Mon Sep 17 00:00:00 2001 From: zhangran Date: Thu, 20 Mar 2025 11:09:47 +0800 Subject: [PATCH 71/75] =?UTF-8?q?add(feature/REQ-3714)=20=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=E5=B9=B3=E5=8F=B0=E5=B7=A5=E4=BA=BA=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E5=90=8C=E6=97=B6=E7=BB=88=E6=AD=A2=E5=B7=A5=E4=BA=BA=E5=85=A5?= =?UTF-8?q?=E5=9C=BA=E7=94=B3=E8=AF=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orgmanax/dto/node/dto/OrgNodeDTO.java | 4 + .../client/workflow/WorkflowCoreClient.java | 16 ++ .../dto/BatchOperationResultResp.java | 63 ++++++ .../dto/BpmnProcessInstanceAbortReq.java | 34 +++ .../ProjectWorkerInviteRepository.java | 213 ++++++++++++++++++ .../ProjectWorkerInviteRepositoryImpl.java | 32 +++ .../dao/node/entity/OrganizationalNode.java | 11 + .../OrgProjectWorkerQueryRepository.java | 2 + orgmanax-integration/pom.xml | 13 ++ .../sdk/workflow/WorkflowCoreClientImpl.java | 37 +++ .../ProjectWorkerInviteFoundationService.java | 16 ++ .../dto/ProjectWorkerInviteCreator.java | 143 ++++++++++++ ...jectWorkerInviteFoundationServiceImpl.java | 30 +++ .../impl/DeletePlatTeamWorkerProcessor.java | 81 +++++++ .../OrgProjectWorkerFoundationService.java | 4 + ...OrgProjectWorkerFoundationServiceImpl.java | 17 ++ .../req/DeleteOrgProjectWorkerReq.java | 17 ++ 17 files changed, 733 insertions(+) create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/WorkflowCoreClient.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/dto/BatchOperationResultResp.java create mode 100644 orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/dto/BpmnProcessInstanceAbortReq.java create mode 100644 orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/workflow/WorkflowCoreClientImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/ProjectWorkerInviteFoundationService.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/dto/ProjectWorkerInviteCreator.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/impl/ProjectWorkerInviteFoundationServiceImpl.java create mode 100644 orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/req/DeleteOrgProjectWorkerReq.java diff --git a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/node/dto/OrgNodeDTO.java b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/node/dto/OrgNodeDTO.java index af94bc4..559c25d 100644 --- a/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/node/dto/OrgNodeDTO.java +++ b/orgmanax-dto/src/main/java/cn/axzo/orgmanax/dto/node/dto/OrgNodeDTO.java @@ -103,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; diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/WorkflowCoreClient.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/WorkflowCoreClient.java new file mode 100644 index 0000000..7d8362a --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/WorkflowCoreClient.java @@ -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 reqs); +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/dto/BatchOperationResultResp.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/dto/BatchOperationResultResp.java new file mode 100644 index 0000000..3823eb6 --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/dto/BatchOperationResultResp.java @@ -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 details; +} + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +class BatchOperationItemResultResp { + /** + * 被处理数据的 ID + * 可以是实例 ID,也可以是任务 ID,根据调用的 API 不同而不同 + */ + private String id; + + /** + * 处理的数据类型: 业务审批, 流程审批 + */ + private String type; + + /** + * 该流程实例处理过程中是否发生错误 + */ + private Boolean hasError = false; + + /** + * 具体的错误信息 + */ + private String errorMessage; +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/dto/BpmnProcessInstanceAbortReq.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/dto/BpmnProcessInstanceAbortReq.java new file mode 100644 index 0000000..d9b0f6a --- /dev/null +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/client/workflow/dto/BpmnProcessInstanceAbortReq.java @@ -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; +} diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/invite/repository/ProjectWorkerInviteRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/invite/repository/ProjectWorkerInviteRepository.java index ead505e..8948171 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/invite/repository/ProjectWorkerInviteRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/invite/repository/ProjectWorkerInviteRepository.java @@ -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 page(ListReq req); + + /** + * 列表查询 + * + * @param req + * @return + */ + default List list(ListReq req) { + PageResp page = page(req); + if (page == null) { + return Collections.emptyList(); + } + return CollUtil.emptyIfNull(page.getData()); + } + + void updateBatchById(List 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 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 projectTeamIds; + + + /** + * 工人ID + */ + + @CriteriaField(field = "workerIdentityId", operator = Operator.EQ) + private Long workerIdentityId; + @CriteriaField(field = "workerIdentityId", operator = Operator.IN) + private List workerIdentityIds; + + /** + * 状态:1、待班组审批  2、待劳务审批  3、通过 4、拒绝 + */ + @CriteriaField(field = "status", operator = Operator.EQ) + private Integer status; + @CriteriaField(field = "status", operator = Operator.IN) + private List statusList; + + + /** + * 工作流流程实例id + */ + @CriteriaField(field = "processInstanceId", operator = Operator.EQ) + private String processInstanceId; + @CriteriaField(field = "processInstanceId", operator = Operator.IN) + private List 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; + } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/invite/repository/impl/ProjectWorkerInviteRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/invite/repository/impl/ProjectWorkerInviteRepositoryImpl.java index 7053803..b927242 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/invite/repository/impl/ProjectWorkerInviteRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/invite/repository/impl/ProjectWorkerInviteRepositoryImpl.java @@ -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 page(ListReq req) { + IPage page = PageConverter.toMybatis(req, ProjectWorkerInvite.class); + QueryWrapper wrapper = QueryWrapperHelper.fromBean(req, ProjectWorkerInvite.class); + if (BooleanUtils.isNotTrue(req.getIncludeDeleted())) { + wrapper.eq("is_delete", 0); + } + IPage results = projectWorkerInviteDao.page(page, wrapper) + .convert(e -> BeanUtil.toBean(e, ProjectWorkerInviteResp.class)); + + PageResp resp = PageConverter.toResp(results); + return resp; + } + + @Override + public void updateBatchById(List invites){ + projectWorkerInviteDao.updateBatchById(invites); + } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalNode.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalNode.java index 5b49ffa..88cb4b7 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalNode.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/node/entity/OrganizationalNode.java @@ -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; diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerQueryRepository.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerQueryRepository.java index 0016707..130f8d8 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerQueryRepository.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/project/worker/repositrory/OrgProjectWorkerQueryRepository.java @@ -57,6 +57,8 @@ public interface OrgProjectWorkerQueryRepository { @Data @SuperBuilder class ListReq extends PageReqV2 { + @CriteriaField(field = "id", operator = Operator.IN) + private List ids; /** * 工作台ID diff --git a/orgmanax-integration/pom.xml b/orgmanax-integration/pom.xml index 4ae327f..4e6a86e 100644 --- a/orgmanax-integration/pom.xml +++ b/orgmanax-integration/pom.xml @@ -76,6 +76,19 @@ data-tagger-api 1.0.0-SNAPSHOT + + + + cn.axzo.data-tagger + data-tagger-api + 1.0.0-SNAPSHOT + + + + cn.axzo.workflow + workflow-engine-spring-boot-starter + 1.5.2-SNAPSHOT + \ No newline at end of file diff --git a/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/workflow/WorkflowCoreClientImpl.java b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/workflow/WorkflowCoreClientImpl.java new file mode 100644 index 0000000..de87e05 --- /dev/null +++ b/orgmanax-integration/src/main/java/cn/axzo/orgmanax/integration/sdk/workflow/WorkflowCoreClientImpl.java @@ -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 reqs) { + List abortDTOS = BeanUtil.copyToList(reqs, BpmnProcessInstanceAbortDTO.class); + BatchOperationResultVO resultVO = workflowCoreService.async().batchAbortProcessInstance(abortDTOS); + return BeanUtil.copyProperties(resultVO,BatchOperationResultResp.class); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/ProjectWorkerInviteFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/ProjectWorkerInviteFoundationService.java new file mode 100644 index 0000000..627307a --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/ProjectWorkerInviteFoundationService.java @@ -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 updateBatchById(List req); +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/dto/ProjectWorkerInviteCreator.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/dto/ProjectWorkerInviteCreator.java new file mode 100644 index 0000000..5efe849 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/dto/ProjectWorkerInviteCreator.java @@ -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); + } + + +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/impl/ProjectWorkerInviteFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/impl/ProjectWorkerInviteFoundationServiceImpl.java new file mode 100644 index 0000000..7d3a8af --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/invite/foundation/impl/ProjectWorkerInviteFoundationServiceImpl.java @@ -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 updateBatchById(List req) { + List projectWorkerInvites = req.stream().map(item -> item.toEntity()).collect(Collectors.toList()); + projectWorkerInviteRepository.updateBatchById(projectWorkerInvites); + return BeanUtil.copyToList(projectWorkerInvites, ProjectWorkerInviteRepository.ProjectWorkerInviteResp.class); + } +} diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index 24ccbc8..6f39e87 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -4,9 +4,12 @@ import cn.axzo.foundation.exception.Axssert; import cn.axzo.framework.rocketmq.EventProduceTemplate; import cn.axzo.framework.rocketmq.RocketConfigProperties; import cn.axzo.karma.client.model.request.PlatWorkTeamGrantPositionReq; +import cn.axzo.maokai.api.labour.common.enums.WorkerInviteStatusEnum; import cn.axzo.msg.center.api.v2.message.req.MessageSendV2Req; import cn.axzo.msg.center.api.v2.message.req.PersonV2DTO; import cn.axzo.orgmanax.dto.common.IdentityType; +import cn.axzo.orgmanax.dto.node.dto.OrgNodeDTO; +import cn.axzo.orgmanax.dto.node.req.ListNodeReq; import cn.axzo.orgmanax.dto.nodeuser.dto.NodeUserDTO; import cn.axzo.orgmanax.dto.nodeuser.req.DeleteNodeUserReq; import cn.axzo.orgmanax.dto.nodeuser.req.ListNodeUserReq; @@ -15,14 +18,20 @@ import cn.axzo.orgmanax.infra.client.eventhub.dto.OrganizationTypeEnum; import cn.axzo.orgmanax.infra.client.msg.MsgCenterGateway; import cn.axzo.orgmanax.infra.client.tyr.SaasRoleUserClient; import cn.axzo.orgmanax.infra.client.tyr.dto.OrgManaxWorkerManagerRoleUserReq; +import cn.axzo.orgmanax.infra.client.workflow.WorkflowCoreClient; +import cn.axzo.orgmanax.infra.client.workflow.dto.BpmnProcessInstanceAbortReq; import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip; import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRepository; +import cn.axzo.orgmanax.infra.dao.invite.repository.ProjectWorkerInviteRepository; import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNode; import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalTeamOuRelation; import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository; import cn.axzo.orgmanax.infra.dao.node.repository.TeamOuRelationRepository; import cn.axzo.orgmanax.infra.dao.orgjob.repository.OrgJobQueryRepository; import cn.axzo.orgmanax.infra.dao.unit.repository.UnitQueryRepository; +import cn.axzo.orgmanax.server.invite.foundation.ProjectWorkerInviteFoundationService; +import cn.axzo.orgmanax.server.invite.foundation.dto.ProjectWorkerInviteCreator; +import cn.axzo.orgmanax.server.node.service.NodeService; import cn.axzo.orgmanax.server.nodeuser.foundation.NodeUserFoundationService; import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserDelete; import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserUpdate; @@ -31,11 +40,14 @@ import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor; import cn.axzo.orgmanax.infra.client.msg.vo.JoinLeaveEnum; import cn.axzo.orgmanax.infra.client.msg.vo.MessageCodeEnum; import cn.axzo.orgmanax.infra.client.msg.vo.MessageVariableNameEnum; +import cn.axzo.orgmanax.server.project.worker.foundation.OrgProjectWorkerFoundationService; +import cn.axzo.orgmanax.server.project.worker.foundation.req.DeleteOrgProjectWorkerReq; import cn.axzo.orgmanax.server.util.AssertUtil; import cn.axzo.orgmanax.server.workerprofession.foundation.OrgProjectWorkerProfessionFoundationService; import cn.axzo.orgmanax.server.workerprofession.foundation.dto.DeleteWorkerProfession; import cn.axzo.tyr.client.common.enums.RoleResourceTypeEnum; import cn.axzo.tyr.client.common.enums.SaasPositionEnum; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import com.alibaba.fastjson.JSON; @@ -44,9 +56,13 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.util.StringUtils; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -81,6 +97,12 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { private final EventProduceTemplate eventProduceTemplate; private final RocketConfigProperties rocketConfigProperties; private final NodeQueryRepository nodeQueryRepository; + private final NodeService nodeService; + private final ProjectWorkerInviteRepository projectWorkerInviteRepository; + private final ProjectWorkerInviteFoundationService projectWorkerInviteFoundationService; + private final OrgProjectWorkerFoundationService orgProjectWorkerFoundationService; + private final TransactionTemplate transactionTemplate; + private final WorkflowCoreClient workflowCoreClient; private static final String PROMISE_GROUP_EVENT_MODULE = "promise-group"; private static final String PROMISE_GROUP_EVENT_NAME = "promise-group-remove"; @@ -127,6 +149,8 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { if (Objects.nonNull(ouRelation)) { // 移除代班长权限 removePlatTeamManager(ouRelation, vs); + // 终止项目内正在申请中的邀约记录 + removeWorkerInvite(ouRelation, vs); // 删除平台工人 List deleteTeamWorkerPersonIds = vs.stream().map(NodeUserDTO::getPersonId).collect(Collectors.toList()); NodeUserDelete nodeUserDelete = NodeUserDelete.builder() @@ -172,6 +196,63 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { sendMQ(ouRelation, nodeUserDTOS); } + private void removeWorkerInvite(OrganizationalTeamOuRelation ouRelation, List nodeUserDTOS){ + List orgNodeDTOS = listProjectTeam(ouRelation); + if (CollUtil.isEmpty(orgNodeDTOS)) { + return ; + } + + List identityIds = nodeUserDTOS.stream().map(NodeUserDTO::getIdentityId).distinct().collect(Collectors.toList()); + + List projectTeamIds = orgNodeDTOS.stream().map(OrgNodeDTO::getProjectTeamId).filter(Objects::nonNull).collect(Collectors.toList()); + + ProjectWorkerInviteRepository.ListReq queryBo = new ProjectWorkerInviteRepository.ListReq(); + queryBo.setProjectTeamIds(projectTeamIds); + queryBo.setWorkerIdentityIds(identityIds); + queryBo.setStatusList(Arrays.asList(WorkerInviteStatusEnum.WAIT_LEADER_APPROVE.getValue(), WorkerInviteStatusEnum.WAIT_LABOUR_APPROVE.getValue())); + queryBo.setIncludeDeleted(Boolean.FALSE); + List workerInvites = projectWorkerInviteRepository.list(queryBo); + List inviteIds = workerInvites.stream().map(ProjectWorkerInviteRepository.ProjectWorkerInviteResp::getId).collect(Collectors.toList()); + List processInstanceIds = workerInvites.stream().map(ProjectWorkerInviteRepository.ProjectWorkerInviteResp::getProcessInstanceId).filter(StringUtils::hasText).collect(Collectors.toList()); + + List inviteCreators = workerInvites.stream().map(item -> { + ProjectWorkerInviteCreator projectWorkerInviteCreator = BeanUtil.copyProperties(item, ProjectWorkerInviteCreator.class); + projectWorkerInviteCreator.setStatus(WorkerInviteStatusEnum.TEAM_OWNER_REFUSE.getValue()); + return projectWorkerInviteCreator; + }).collect(Collectors.toList()); + + List projectWorkerIds = workerInvites.stream().map(ProjectWorkerInviteRepository.ProjectWorkerInviteResp::getProjectWorkerId).collect(Collectors.toList()); + + transactionTemplate.executeWithoutResult(status -> { + projectWorkerInviteFoundationService.updateBatchById(inviteCreators); + log.info("拒绝未完成的工人申请记录, workerInvites:{}", JSON.toJSONString(workerInvites)); + orgProjectWorkerFoundationService.deleteByParam(DeleteOrgProjectWorkerReq.builder().projectWorkerIds(projectWorkerIds).build()); + if (CollUtil.isNotEmpty(inviteIds)) { + log.info("撤销未加入项目的工人审批记录 inviteIds:{}", inviteIds); + List abortReqs = processInstanceIds.stream().map(processInstanceId -> { + return BpmnProcessInstanceAbortReq.builder() + .processInstanceId(processInstanceId) + .reason("班组长已将工人移除班组") + .build(); + }).collect(Collectors.toList()); + workflowCoreClient.batchAbortProcessInstance(abortReqs); + } + // 现在工人退出平台班组,需先从项目内班组退出 + }); + } + + private List listProjectTeam(OrganizationalTeamOuRelation ouRelation){ + ListNodeReq listNodeReq = ListNodeReq.builder().platTeamIds(Sets.newHashSet(ouRelation.getTeamOuId())).build(); + List orgNodeDTOS = nodeService.list(listNodeReq); + + if (CollectionUtils.isEmpty(orgNodeDTOS)) { + log.info("忽略平台班组长移除工人操作,平台班组platTeamId=【{}】未加入项目", ouRelation.getTeamOuId()); + return Collections.emptyList(); + } + return orgNodeDTOS; + } + + private void sendMQ(OrganizationalTeamOuRelation ouRelation, List nodeUserDTOS){ PlatWorkTeamGrantPositionReq build = PlatWorkTeamGrantPositionReq.builder() .platWorkTeamOuId(ouRelation.getTeamOuId()) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/OrgProjectWorkerFoundationService.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/OrgProjectWorkerFoundationService.java index 2291a9c..0303ae9 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/OrgProjectWorkerFoundationService.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/OrgProjectWorkerFoundationService.java @@ -1,5 +1,6 @@ package cn.axzo.orgmanax.server.project.worker.foundation; +import cn.axzo.orgmanax.server.project.worker.foundation.req.DeleteOrgProjectWorkerReq; import cn.axzo.orgmanax.server.project.worker.foundation.req.OrgProjectWorkerWithdrawReq; import org.springframework.transaction.annotation.Transactional; @@ -7,4 +8,7 @@ public interface OrgProjectWorkerFoundationService { @Transactional(rollbackFor = Throwable.class) void batchWithdraw(OrgProjectWorkerWithdrawReq req); + + @Transactional(rollbackFor = Throwable.class) + void deleteByParam(DeleteOrgProjectWorkerReq req); } \ No newline at end of file diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java index ea60426..60e7b0a 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/impl/OrgProjectWorkerFoundationServiceImpl.java @@ -5,6 +5,7 @@ import cn.axzo.orgmanax.infra.dao.project.worker.entity.OrgProjectWorker; import cn.axzo.orgmanax.infra.dao.project.worker.repositrory.OrgProjectWorkerQueryRepository; import cn.axzo.orgmanax.infra.dao.project.worker.repositrory.OrgProjectWorkerUpsertRepository; import cn.axzo.orgmanax.server.project.worker.foundation.OrgProjectWorkerFoundationService; +import cn.axzo.orgmanax.server.project.worker.foundation.req.DeleteOrgProjectWorkerReq; import cn.axzo.orgmanax.server.project.worker.foundation.req.OrgProjectWorkerWithdrawReq; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; @@ -49,4 +50,20 @@ public class OrgProjectWorkerFoundationServiceImpl implements OrgProjectWorkerFo }).collect(Collectors.toList()); orgProjectWorkerUpsertRepository.batchUpdate(orgProjectWorkers); } + + @Override + public void deleteByParam(DeleteOrgProjectWorkerReq req) { + OrgProjectWorkerQueryRepository.ListReq listReq = new OrgProjectWorkerQueryRepository.ListReq(); + listReq.setIds(req.getProjectWorkerIds()); + List projectWorkerResps = orgProjectWorkerQueryRepository.list(listReq); + if (CollUtil.isEmpty(projectWorkerResps)) { + return; + } + List orgProjectWorkers = projectWorkerResps.stream().map(e -> { + OrgProjectWorker orgProjectWorker = BeanUtil.toBean(e, OrgProjectWorker.class); + e.setIsDelete(e.getId()); + return orgProjectWorker; + }).collect(Collectors.toList()); + orgProjectWorkerUpsertRepository.batchUpdate(orgProjectWorkers); + } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/req/DeleteOrgProjectWorkerReq.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/req/DeleteOrgProjectWorkerReq.java new file mode 100644 index 0000000..51ecef1 --- /dev/null +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/project/worker/foundation/req/DeleteOrgProjectWorkerReq.java @@ -0,0 +1,17 @@ +package cn.axzo.orgmanax.server.project.worker.foundation.req; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * @Author zr + * @Date 2025/3/19 20:00 + * @Description + **/ +@Builder +@Data +public class DeleteOrgProjectWorkerReq { + private List projectWorkerIds; +} From 664d5694d2c4d2c6e97121762e8cd2a989e50531 Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 20 Mar 2025 15:19:28 +0800 Subject: [PATCH 72/75] =?UTF-8?q?feat(REQ-3714):=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=A7=92=E8=89=B2=E5=90=8E=E4=BD=BF=E7=94=A8=E8=BA=AB=E4=BB=BD?= =?UTF-8?q?id=E5=81=9A=E4=B8=80=E6=AC=A1=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nodeuser/service/impl/NodeUserCheckServiceImpl.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java index d511b84..deba245 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/impl/NodeUserCheckServiceImpl.java @@ -261,8 +261,11 @@ public class NodeUserCheckServiceImpl implements NodeUserCheckService { roleUserParam.setNeedRole(true); roleUserParam.setPageSize(1000); + Set identityIds = nodeUsers.stream().map(NodeUserDTO::getIdentityId).collect(Collectors.toSet()); + List saasRoleUserInfo = roleUserGateway.pageAll(roleUserParam); - saasRoleUserInfo = saasRoleUserInfo.stream().filter(e -> Objects.nonNull(e.getRole())).collect(Collectors.toList()); + saasRoleUserInfo = saasRoleUserInfo.stream().filter(e -> Objects.nonNull(e.getRole())) + .filter(e -> identityIds.contains(e.getIdentityId())).collect(Collectors.toList()); saasRoleUserInfo.forEach(e -> { // 班组长不用校验,因为班组长也会有管理员角色 if (teamLeadPersonSet.contains(e.getPersonId())) { From 00d124580fcf36ed277a29ab2e741a2818f07038 Mon Sep 17 00:00:00 2001 From: zhangran Date: Fri, 21 Mar 2025 10:30:23 +0800 Subject: [PATCH 73/75] =?UTF-8?q?add(feature/REQ-3714)=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=88=A0=E9=99=A4=E5=B7=A5=E7=A7=8Dredis=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...jectWorkerProfessionFoundationServiceImpl.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java index a9f4ec6..40ee78c 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java @@ -3,6 +3,7 @@ package cn.axzo.orgmanax.server.workerprofession.foundation.impl; import cn.axzo.orgmanax.infra.dao.workerprofession.entity.WorkerProfessionTag; import cn.axzo.orgmanax.infra.dao.workerprofession.repository.WorkerProfessionTagRepository; import cn.axzo.orgmanax.server.util.AssertUtil; +import cn.axzo.orgmanax.server.util.RedisLockUtil; import cn.axzo.orgmanax.server.workerprofession.foundation.OrgProjectWorkerProfessionFoundationService; import cn.axzo.orgmanax.server.workerprofession.foundation.OrgWorkerHistoryFoundationService; import cn.axzo.orgmanax.server.workerprofession.foundation.OrgWorkerSkillTagFoundationService; @@ -29,15 +30,21 @@ public class OrgProjectWorkerProfessionFoundationServiceImpl implements OrgProje private final OrgWorkerHistoryFoundationService historyFoundationService; private final OrgWorkerSkillTagFoundationService skillTagFoundationService; + private static final String CONFIGURE_REDIS_LOCK_PRE = "WORKER_PROFESSION_CONFIGURE"; + private static final long PROFESSION_CONFIGURE_RETRY_TIMEOUT = 1000L; + @Override @Transactional(rollbackFor = Exception.class) public void delete(DeleteWorkerProfession req) { AssertUtil.isFalse(req.isInvalid(), String.format("无效的参数%s", req)); - // 记录工人当前的工种&技能标签历史 - historyFoundationService.recordHistory(req); - // 删除本身工种和技能标签 - doUpdateValid(req); + String redisKey = RedisLockUtil.formatKey(CONFIGURE_REDIS_LOCK_PRE, req.getOrgNodeId()); + RedisLockUtil.tryLock(redisKey, PROFESSION_CONFIGURE_RETRY_TIMEOUT, () -> { + // 记录工人当前的工种&技能标签历史 + historyFoundationService.recordHistory(req); + // 删除本身工种和技能标签 + doUpdateValid(req); + }); } From ddacfb236cc17c6a63cde191f1ff3d2a46ee4069 Mon Sep 17 00:00:00 2001 From: zhangran Date: Fri, 21 Mar 2025 11:55:28 +0800 Subject: [PATCH 74/75] =?UTF-8?q?add(feature/REQ-3714)=20=E5=88=A4?= =?UTF-8?q?=E7=A9=BA=EF=BC=8C=E5=88=A0=E9=99=A4=E5=B7=A5=E7=A7=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...orkerProfessionSkillTagRepositoryImpl.java | 19 ++++++++++-------- .../WorkerProfessionTagRepositoryImpl.java | 20 +++++++++++-------- .../impl/DeletePlatTeamWorkerProcessor.java | 5 ++++- ...OrgWorkerHistoryFoundationServiceImpl.java | 4 ++++ 4 files changed, 31 insertions(+), 17 deletions(-) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java index 4f1ff6d..955fcbc 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java @@ -17,8 +17,8 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; +import java.util.Date; import java.util.List; -import java.util.stream.Collectors; /** * @author zhanghongbo @@ -60,12 +60,15 @@ public class WorkerProfessionSkillTagRepositoryImpl implements WorkerProfessionS return; } - List delete = ids.stream().map(id -> { - WorkerProfessionSkillTag workerProfessionSkillTag = new WorkerProfessionSkillTag(); - workerProfessionSkillTag.setId(id); - workerProfessionSkillTag.setIsDelete(id); - return workerProfessionSkillTag; - }).collect(Collectors.toList()); - workerProfessionSkillTagDao.updateBatchById(delete); + List skillTags = workerProfessionSkillTagDao.listByIds(ids); + if (CollUtil.isEmpty(skillTags)) { + return ; + } + Date date = new Date(); + skillTags.forEach(skillTag -> { + skillTag.setIsDelete(skillTag.getId()); + skillTag.setUpdateAt(date); + }); + workerProfessionSkillTagDao.updateBatchById(skillTags); } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java index e4fc239..56cba0c 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java @@ -16,8 +16,8 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; +import java.util.Date; import java.util.List; -import java.util.stream.Collectors; /** * @author zhanghongbo @@ -58,12 +58,16 @@ public class WorkerProfessionTagRepositoryImpl implements WorkerProfessionTagRep if (CollUtil.isEmpty(ids)) { return ; } - List delete = ids.stream().map(id -> { - WorkerProfessionTag workerProfessionTag = new WorkerProfessionTag(); - workerProfessionTag.setId(id); - workerProfessionTag.setIsDelete(id); - return workerProfessionTag; - }).collect(Collectors.toList()); - workerProfessionTagDao.updateBatchById(delete); + List workerProfessionTags = workerProfessionTagDao.listByIds(ids); + if (CollUtil.isEmpty(workerProfessionTags)) { + return ; + } + + Date date = new Date(); + workerProfessionTags.forEach(workerProfessionTag -> { + workerProfessionTag.setIsDelete(workerProfessionTag.getId()); + workerProfessionTag.setUpdateAt(date); + }); + workerProfessionTagDao.updateBatchById(workerProfessionTags); } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index 6f39e87..17b1389 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -161,7 +161,7 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { nodeUserFoundationService.delete(nodeUserDelete); // 删除平台工人工种和技能标签 DeleteWorkerProfession workerProfession = DeleteWorkerProfession.builder() - .scene(TeamSceneEnum.PROJECT_TEAM.name()) + .scene(TeamSceneEnum.PLAT_TEAM.name()) .personIds(param.getPersonIds()) .isResign(Boolean.TRUE) .orgNodeId(nodeId) @@ -212,6 +212,9 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { queryBo.setStatusList(Arrays.asList(WorkerInviteStatusEnum.WAIT_LEADER_APPROVE.getValue(), WorkerInviteStatusEnum.WAIT_LABOUR_APPROVE.getValue())); queryBo.setIncludeDeleted(Boolean.FALSE); List workerInvites = projectWorkerInviteRepository.list(queryBo); + if (CollUtil.isEmpty(workerInvites)) { + return ; + } List inviteIds = workerInvites.stream().map(ProjectWorkerInviteRepository.ProjectWorkerInviteResp::getId).collect(Collectors.toList()); List processInstanceIds = workerInvites.stream().map(ProjectWorkerInviteRepository.ProjectWorkerInviteResp::getProcessInstanceId).filter(StringUtils::hasText).collect(Collectors.toList()); diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java index 1a9bde2..1c35f13 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java @@ -19,6 +19,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.Date; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -110,12 +111,15 @@ public class OrgWorkerHistoryFoundationServiceImpl implements OrgWorkerHistoryFo .jsonStrData(professionSkillTags) .build()); } + Date date = new Date(); return WorkerProfessionHistory.builder() .personId(first.getPersonId()) .orgNodeId(first.getOrgNodeId()) .workspaceId(first.getWorkspaceId()) .bizData(first.getBizData()) .jsonContent(JSON.toJSONString(historyDataList)) + .createAt(date) + .updateAt(date) .build(); } } From 2bf1462388b7eb5b0f79830c7f04f01a88511188 Mon Sep 17 00:00:00 2001 From: zhangran Date: Fri, 21 Mar 2025 14:29:39 +0800 Subject: [PATCH 75/75] =?UTF-8?q?add(feature/REQ-3714)=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96update,=E5=87=8F=E5=B0=91=E5=8E=86=E5=8F=B2=E5=B7=A5?= =?UTF-8?q?=E7=A7=8D=E9=87=8D=E5=A4=8D=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infra/config/MybatisPlusConfig.java | 31 ++++++++++++++++++- ...orkerProfessionSkillTagRepositoryImpl.java | 15 +++------ .../WorkerProfessionTagRepositoryImpl.java | 20 +++++------- .../impl/DeletePlatTeamWorkerProcessor.java | 2 +- ...WorkerProfessionFoundationServiceImpl.java | 2 +- ...OrgWorkerHistoryFoundationServiceImpl.java | 3 -- 6 files changed, 43 insertions(+), 30 deletions(-) diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/MybatisPlusConfig.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/MybatisPlusConfig.java index ee286b5..ad68f85 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/MybatisPlusConfig.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/config/MybatisPlusConfig.java @@ -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); + } + + } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java index 955fcbc..4db198b 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionSkillTagRepositoryImpl.java @@ -59,16 +59,9 @@ public class WorkerProfessionSkillTagRepositoryImpl implements WorkerProfessionS if (CollUtil.isEmpty(ids)) { return; } - - List skillTags = workerProfessionSkillTagDao.listByIds(ids); - if (CollUtil.isEmpty(skillTags)) { - return ; - } - Date date = new Date(); - skillTags.forEach(skillTag -> { - skillTag.setIsDelete(skillTag.getId()); - skillTag.setUpdateAt(date); - }); - workerProfessionSkillTagDao.updateBatchById(skillTags); + workerProfessionSkillTagDao.lambdaUpdate() + .in(WorkerProfessionSkillTag::getId, ids) + .setSql(" is_delete = id") + .update(); } } diff --git a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java index 56cba0c..916b9aa 100644 --- a/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java +++ b/orgmanax-infra/src/main/java/cn/axzo/orgmanax/infra/dao/workerprofession/repository/impl/WorkerProfessionTagRepositoryImpl.java @@ -49,25 +49,19 @@ public class WorkerProfessionTagRepositoryImpl implements WorkerProfessionTagRep } @Override - public void removeByIds(List ids){ + public void removeByIds(List ids) { workerProfessionTagDao.removeByIds(ids); } @Override - public void deleteByIds(List ids){ + public void deleteByIds(List ids) { if (CollUtil.isEmpty(ids)) { - return ; - } - List workerProfessionTags = workerProfessionTagDao.listByIds(ids); - if (CollUtil.isEmpty(workerProfessionTags)) { - return ; + return; } - Date date = new Date(); - workerProfessionTags.forEach(workerProfessionTag -> { - workerProfessionTag.setIsDelete(workerProfessionTag.getId()); - workerProfessionTag.setUpdateAt(date); - }); - workerProfessionTagDao.updateBatchById(workerProfessionTags); + workerProfessionTagDao.lambdaUpdate() + .in(WorkerProfessionTag::getId, ids) + .setSql(" is_delete = id") + .update(); } } diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java index 17b1389..ef9cc36 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/nodeuser/service/processor/impl/DeletePlatTeamWorkerProcessor.java @@ -162,7 +162,7 @@ public class DeletePlatTeamWorkerProcessor implements NodeUserProcessor { // 删除平台工人工种和技能标签 DeleteWorkerProfession workerProfession = DeleteWorkerProfession.builder() .scene(TeamSceneEnum.PLAT_TEAM.name()) - .personIds(param.getPersonIds()) + .personIds(Sets.newHashSet(deleteTeamWorkerPersonIds)) .isResign(Boolean.TRUE) .orgNodeId(nodeId) .build(); diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java index 40ee78c..00af5de 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgProjectWorkerProfessionFoundationServiceImpl.java @@ -60,7 +60,7 @@ public class OrgProjectWorkerProfessionFoundationServiceImpl implements OrgProje return; } // 记录工人当前的工种&技能标签历史 - historyFoundationService.recordHistory(req); +// historyFoundationService.recordHistory(req); // 删除技能标签 absoluteRemoveSkillTags(req); // 删除工种 diff --git a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java index 1c35f13..ab4cfb8 100644 --- a/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java +++ b/orgmanax-server/src/main/java/cn/axzo/orgmanax/server/workerprofession/foundation/impl/OrgWorkerHistoryFoundationServiceImpl.java @@ -111,15 +111,12 @@ public class OrgWorkerHistoryFoundationServiceImpl implements OrgWorkerHistoryFo .jsonStrData(professionSkillTags) .build()); } - Date date = new Date(); return WorkerProfessionHistory.builder() .personId(first.getPersonId()) .orgNodeId(first.getOrgNodeId()) .workspaceId(first.getWorkspaceId()) .bizData(first.getBizData()) .jsonContent(JSON.toJSONString(historyDataList)) - .createAt(date) - .updateAt(date) .build(); } }