From 442d0ef53d2e793b809d3d24bafe800841cfd58f Mon Sep 17 00:00:00 2001 From: zhanghonghao Date: Thu, 6 Mar 2025 16:29:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(REQ-3714):=20=E5=BA=95=E5=BA=A7=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E5=88=A0=E9=99=A4node=5Fuser=E5=A4=84=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; + } +}