feature(REQ-3282): NodeUser,SaasCooperateShip的基础接口实现。

This commit is contained in:
周敏 2024-12-13 15:59:47 +08:00
parent 9f86ad450b
commit 43d7b0a12e
65 changed files with 2302 additions and 114 deletions

View File

@ -0,0 +1,33 @@
package cn.axzo.orgmanax.api.cooperateship.feign;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.cooperateship.req.ListOrgCooperateShipReq;
import cn.axzo.orgmanax.api.cooperateship.resp.OrgCooperateShipDTO;
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 OrgCooperateShipApi {
/**
* 列表接口
*
* @param req
* @return
*/
@PostMapping("/api/org/cooperate-ship/list")
ApiResult<List<OrgCooperateShipDTO>> list(@RequestBody @Validated ListOrgCooperateShipReq req);
}

View File

@ -0,0 +1,81 @@
package cn.axzo.orgmanax.api.cooperateship.req;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.foundation.page.IPageReq;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Set;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class ListOrgCooperateShipReq implements IPageReq {
@CriteriaField
private Long id;
@CriteriaField(field = "id", operator = Operator.IN)
private Set<Long> ids;
@CriteriaField
private Long parentId;
@CriteriaField(field = "parentId", operator = Operator.IN)
private Set<Long> parentIds;
/**
* 用于遍历数据
*/
@CriteriaField(field = "id", operator = Operator.GT)
private Long idGt;
/**
* 工作台ID
*/
@CriteriaField
private Long workspaceId;
@CriteriaField(field = "workspaceId", operator = Operator.IN)
private Long workspaceIds;
@CriteriaField
private Integer workspaceType;
@CriteriaField(field = "workspaceType", operator = Operator.IN)
private Set<Integer> workspaceTypes;
@CriteriaField
private Integer status;
@CriteriaField(field = "status", operator = Operator.IN)
private Set<Integer> statuses;
@CriteriaField
private Integer cooperateType;
@CriteriaField(field = "cooperateType", operator = Operator.IN)
private Set<Integer> cooperateTypes;
@CriteriaField
private Integer partnerShip;
@CriteriaField(field = "partnerShip", operator = Operator.IN)
private Set<Integer> partnerShips;
/**
* 组织节点id
*/
@CriteriaField
private Long organizationalNodeId;
@CriteriaField(field = "organizationalNodeId", operator = Operator.IN)
private Set<Long> organizationalNodeIds;
@CriteriaField
private Long organizationalUnitId;
@CriteriaField(field = "organizationalUnitId", operator = Operator.IN)
private Long organizationalUnitIds;
@CriteriaField(ignore = true)
private Long personId;
@CriteriaField(ignore = true)
private Boolean needParent;
}

View File

@ -0,0 +1,16 @@
package cn.axzo.orgmanax.api.cooperateship.resp;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum CooperateShipStatusEnum {
PRESENT(1, "在场"),
LEFT(2, "离场");
private final Integer code;
private final String desc;
}

View File

@ -0,0 +1,28 @@
package cn.axzo.orgmanax.api.cooperateship.resp;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum CooperateShipTypeEnum {
PROJ_PRIMARY_CONTRACTING_UNIT(1, "施工总承包"),
PROJ_CONSTRUCTION_UNIT(2, "建设单位"),
PROJ_SUPERVISION_UNIT(3, "监理单位"),
PROJ_LABOR_SUBCONTRACTING(4, "劳务分包"),
PROJ_PROFESSIONAL_SUBCONTRACTING(5, "专业承包"),
OMS(6, "OMS"),
ENT_COMMON(7, "企业通用"),
ENT_TEAM(8, "企业内班组"),
PROJ_TEAM(9, "项目内班组"),
ENT_GROUP(10, "企业内小组"),
PROJ_GROUP(11, "项目内小组"),
SURVEY_UNIT(12, "地勘单位"),
DESIGN_UNIT(13, "设计单位"),
OTHER(30, "其他");
private final Integer code;
private final String desc;
}

View File

@ -0,0 +1,117 @@
package cn.axzo.orgmanax.api.cooperateship.resp;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class OrgCooperateShipDTO implements Serializable {
/**
* 主健
*/
private Long id;
/**
* 上级协同关系id
*/
private Long parentId;
/**
* 工作台id
*/
private Long workspaceId;
/**
* 工作台类型
*/
private Integer workspaceType;
/**
* 工作台名称
*/
private String workspaceName;
/**
* 1-在场0-退场
*/
private Integer status;
/**
* 入场时间
*/
private Date joinAt;
/**
* 退场时间
*/
private Date resignAt;
/**
* 单位id(如果是班组则插入队伍id)
*/
private Long organizationalUnitId;
/**
* 单位名称
*/
private String organizationalUnitName;
/**
* 协同关系类型 1.总包 2.建设单位 3监理单位 4劳务分包5专业分包6 OMS 7企业通用8企业内班组9项目内班组10企业内小组11项目内小组 30其它
*/
private Integer cooperateType;
/**
* 组织架构的节点id
*/
private Long organizationalNodeId;
/**
* 节点路径
*/
private String path;
/**
* 合作关系 1.合作 2.直属
*/
private Integer partnerShip;
/**
* 扩展字段
*/
private JSONObject ext;
/**
* 创建时间
*/
private Date createAt;
/**
* 修改时间
*/
private Date updateAt;
/**
* 创建人
*/
private Long createBy;
/**
* 修改人
*/
private Long updateBy;
/**
* 是否删除
*/
private Long isDelete = 0L;
}

View File

@ -3,7 +3,7 @@ package cn.axzo.orgmanax.api.node.feign;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.node.req.ListNodeReq;
import cn.axzo.orgmanax.api.node.req.NodeProcessReq;
import cn.axzo.orgmanax.api.node.req.ProcessNodeReq;
import cn.axzo.orgmanax.api.node.resp.OrgNodeDTO;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.openfeign.FeignClient;
@ -29,7 +29,7 @@ public interface OrgNodeApi {
* @return
*/
@PostMapping("/api/org/node/process")
ApiResult<JSONObject> process(@RequestBody @Validated NodeProcessReq req);
ApiResult<JSONObject> process(@RequestBody @Validated ProcessNodeReq req);
/**
* 分页列表接口

View File

@ -12,7 +12,7 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
@Data
@Builder
public class NodeProcessReq {
public class ProcessNodeReq {
private Long id;
private Long operatorId;
private String description;

View File

@ -0,0 +1,45 @@
package cn.axzo.orgmanax.api.nodeuser.feign;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.api.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.api.nodeuser.resp.OrgNodeUserDTO;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* 部门相关基础API
*
* @author tanjie@axzo.cn
* @date 2024/12/2 15:40
*/
@FeignClient(
value = "orgmanax",
url = "${axzo.service.orgmanax:http://orgmanax:8080}")
public interface OrgNodeUserApi {
/**
* 处理部门人员相关的逻辑
*
* @param req
* @return
*/
@PostMapping("/api/org/node-user/process")
ApiResult<JSONObject> process(@RequestBody @Validated ProcessNodeUserReq req);
/**
* 分页列表接口
* XXX本接口默认分页单页最多返回1000条数据调用方使用时需注意
*
* @param req
* @return
* @see ListNodeUserReq#getPageSize()
*/
@PostMapping("/api/org/node-user/list")
ApiResult<PageResp<OrgNodeUserDTO>> list(@RequestBody @Validated ListNodeUserReq req);
}

View File

@ -0,0 +1,164 @@
package cn.axzo.orgmanax.api.nodeuser.req;
import cn.axzo.foundation.dao.support.wrapper.CriteriaField;
import cn.axzo.foundation.dao.support.wrapper.Operator;
import cn.axzo.foundation.page.IPageReq;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
import java.util.Set;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class ListNodeUserReq implements IPageReq {
@CriteriaField
private Long id;
@CriteriaField(field = "id", operator = Operator.IN)
private Set<Long> ids;
/**
* identity_id
*/
@CriteriaField
private Long identityId;
@CriteriaField(field = "identityId", operator = Operator.IN)
private Set<Long> identityIds;
/**
* 身份类型 0-无效类型, 1-工人, 2-班组长, 3-从业人员, 4-政务人员5-运营人员
*/
@CriteriaField
private Integer identityType;
@CriteriaField(field = "identityType", operator = Operator.IN)
private Set<Integer> identityTypes;
/**
* 自然人id
*/
@CriteriaField
private Long personId;
@CriteriaField(field = "personId", operator = Operator.IN)
private Set<Long> personIds;
/**
* 主电话
*/
@CriteriaField
private String phone;
/**
* 名字
*/
@CriteriaField
private String realName;
@CriteriaField(field = "realName", operator = Operator.LIKE)
private String realNameLike;
/**
* 身份证号
*/
@CriteriaField
private String idNumber;
@CriteriaField(field = "idNumber", operator = Operator.IN)
private Set<String> idNumbers;
/**
* 单位id
*/
@CriteriaField
private Long organizationalUnitId;
@CriteriaField(field = "organizationalUnitId", operator = Operator.IN)
private Set<Long> organizationalUnitIds;
/**
* 组织节点id
*/
@CriteriaField
private Long organizationalNodeId;
@CriteriaField(field = "organizationalNodeId", operator = Operator.IN)
private Set<Long> organizationalNodeIds;
/**
* 顶级节点id
*/
@CriteriaField
private Long topNodeId;
@CriteriaField(field = "topNodeId", operator = Operator.IN)
private Set<Long> topNodeIds;
/**
* 部门管理员 1是 0否
*/
@CriteriaField
private Boolean manager;
/**
* 岗位id
*/
@CriteriaField
private Long organizationalJobId;
@CriteriaField(field = "organizationalJobId", operator = Operator.IN)
private Set<Long> organizationalJobIds;
/**
* 工作台ID
*/
@CriteriaField
private Long workspaceId;
@CriteriaField(field = "workspaceId", operator = Operator.IN)
private Long workspaceIds;
/**
* 0:普通岗位1:主岗位
*/
@CriteriaField
private Integer primaryJob;
/**
* 是否允许进入工地 1.允许 2.不允许
*/
@CriteriaField
private Integer isAllowed;
/**
* 迁移数据临时源id
*/
@CriteriaField
private Long tempSourceId;
/**
* 数据同步ID
*/
@CriteriaField
private Long syncDataId;
/**
* 工号
*/
@CriteriaField
private String jobNumber;
@CriteriaField
private Integer activeFlag;
@CriteriaField(ignore = true)
private Boolean needNode;
@CriteriaField(ignore = true)
@Builder.Default
Integer page = 1;
/**
* 最大支持1000条数据不支持单页超过1000的查询接入方按需分页
*/
@Builder.Default
@CriteriaField(ignore = true)
Integer pageSize = 1000;
@CriteriaField(ignore = true)
List<String> sort;
}

View File

@ -0,0 +1,32 @@
package cn.axzo.orgmanax.api.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;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class ProcessNodeUserReq {
private Long id;
private Long operatorId;
private String description;
private Action action;
private JSONObject param;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public enum Action {
CREATE("创建", "createNodeUserProcessor"),
UPDATE("普通更新", "updateNodeUserProcessor");
private final String desc;
private final String processor;
}
}

View File

@ -0,0 +1,143 @@
package cn.axzo.orgmanax.api.nodeuser.resp;
import cn.axzo.orgmanax.api.node.resp.OrgNodeDTO;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class OrgNodeUserDTO implements Serializable {
private Long id;
/**
* identity_id
*/
private Long identityId;
/**
* 身份类型 0-无效类型, 1-工人, 2-班组长, 3-从业人员, 4-政务人员5-运营人员
*/
private Integer identityType;
/**
* 自然人id
*/
private Long personId;
/**
* 主电话
*/
private String phone;
/**
* 名字
*/
private String realName;
/**
* 身份证号
*/
private String idNumber;
/**
* 单位id
*/
private Long organizationalUnitId;
/**
* 组织节点id
*/
private Long organizationalNodeId;
/**
* 顶级节点id
*/
private Long topNodeId;
/**
* 部门管理员 1是 0否
*/
private Object manager;
/**
* 岗位id
*/
private Long organizationalJobId;
/**
* 工作台ID
*/
private Long workspaceId;
/**
* 0:普通岗位1:主岗位
*/
private Integer primaryJob;
/**
* 是否允许进入工地 1.允许 2.不允许
*/
private Integer isAllowed;
/**
* 加入时间
*/
private Date joinAt;
/**
* 离开时间
*/
private Date leaveAt;
/**
* 迁移数据临时源id
*/
private Long tempSourceId;
/**
* 数据同步ID
*/
private Long syncDataId;
/**
* 工号
*/
private String jobNumber;
/**
* 状态 0正常 其它删除
*/
private Long isDelete = 0L;
/**
* 扩展字段
*/
private JSONObject extra;
/**
* 创建时间
*/
private Date createAt;
/**
* 更新时间
*/
private Date updateAt;
/**
* 1-活跃用户0-非活跃用户
*/
private Integer activeFlag;
// ~ 聚合信息
private OrgNodeDTO node;
}

View File

@ -10,6 +10,8 @@ public enum BizResultCode implements IResultCode {
SUCCESS("200", "成功"),
// ~ 100 -> 199 Node相关的错误码
NODE_PROCESS_FAILED("100", "部门操作失败"),
//
NODE_USER_PROCESS_FAILED("200", "部门人员操作失败"),
INVALID_PARAM("400", "参数异常"),
ENTITY_NOT_FOUND("404", "实体不存在"),

View File

@ -0,0 +1,67 @@
package cn.axzo.orgmanax.infra.client.pudge;
import cn.axzo.orgmanax.infra.client.pudge.dto.IdentityPair;
import cn.axzo.orgmanax.infra.client.pudge.dto.IdentityProfile;
import cn.axzo.orgmanax.infra.client.pudge.dto.PersonProfile;
import com.google.common.collect.ImmutableList;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Set;
/**
* //TODO liuyang
* 封装对person的请求
*/
@Component
@Slf4j
public class PersonProfileGateway {
public PersonProfile getPersonProfile(Long personId) {
return listPersonProfiles(ListPersonProfileReq.builder().id(personId).build())
.stream().findFirst().orElse(null);
}
public List<PersonProfile> listPersonProfiles(ListPersonProfileReq req) {
// TODO
return ImmutableList.of();
}
public IdentityProfile getIdentityProfile(Long personId, Integer identityType) {
return listIdentityProfiles(ListIdentityProfileReq.builder()
.personId(personId)
.identityType(identityType)
.build()).stream().findFirst().orElse(null);
}
public List<IdentityProfile> listIdentityProfiles(ListIdentityProfileReq req) {
// TODO
return ImmutableList.of();
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public static class ListPersonProfileReq {
private Long id;
private Set<Long> ids;
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public static class ListIdentityProfileReq {
private Long personId;
private Long identityId;
private Integer identityType;
private Set<IdentityPair> identityPairs;
}
}

View File

@ -0,0 +1,15 @@
package cn.axzo.orgmanax.infra.client.pudge.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public class IdentityPair {
private Long identityId;
private Integer identityType;
}

View File

@ -0,0 +1,20 @@
package cn.axzo.orgmanax.infra.client.pudge.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* XXX尽量复用 client 对这个类的定义
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public class IdentityProfile {
private Long personId;
private Long identityId;
private Long identityType;
}

View File

@ -0,0 +1,20 @@
package cn.axzo.orgmanax.infra.client.pudge.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* XXX尽量复用 client 对这个类的定义
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public class PersonProfile {
private Long id;
private String phone;
private String realName;
private String idNumber;
}

View File

@ -0,0 +1,32 @@
package cn.axzo.orgmanax.infra.client.pudge.enums;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public enum IdentityType {
NOT_SUPPORT(0, "NOT_SUPPORT", "无效类型"),
WORKER(1, "WORKER", "工人"),
WORKER_LEADER(2, "WORKER_LEADER", "班组长"),
PRACTITIONER(3, "PRACTITIONER", "从业人员"),
REGULATOR(4, "REGULATOR", "监管人员"),
OPERATOR(5, "OPERATOR", "运营人员");
private final Integer code;
private final String message;
private final String desc;
public static IdentityType getIdentityType(Integer code) {
IdentityType[] values = values();
for (IdentityType item : values) {
if (item.getCode().equals(code)) {
return item;
}
}
return null;
}
}

View File

@ -0,0 +1,38 @@
package cn.axzo.orgmanax.infra.client.workspace;
import cn.axzo.orgmanax.infra.client.workspace.dto.Workspace;
import com.google.common.collect.ImmutableList;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* TODO liuyang
*/
@Component
@Slf4j
public class WorkspaceGateway {
public Workspace getWorkspace(Long id) {
return listWorkspaces(ListWorkspaceReq.builder().id(id).build()).stream().findFirst().orElse(null);
}
public List<Workspace> listWorkspaces(ListWorkspaceReq req) {
return ImmutableList.of();
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public static class ListWorkspaceReq {
private Long id;
private Long organizationalUnitId;
private Integer type;
}
}

View File

@ -0,0 +1,36 @@
package cn.axzo.orgmanax.infra.client.workspace.dto;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public class Workspace {
private Long id;
private Integer type;
private String name;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum WorkspaceTypeEnum {
// 目前只有1和2
GENERAL_ENT(1, "总包企业级", "企业"),
GENERAL_PROJECT(2, "总包项目级", "项目"),
GOVERNMENT(3, "政务监管平台", "政务"),
AGENCY_ENT(4, "分包企业级", "班组工作台"),
OMS(6, "OMS工作台", "OMS工作台");
public int value;
public String desc;
public String tenantDesc;
}
}

View File

@ -12,5 +12,4 @@ import org.springframework.stereotype.Repository;
@Repository
public class SaasCooperateShipDao extends ServiceImpl<SaasCooperateShipMapper, SaasCooperateShip> {
}

View File

@ -1,14 +1,17 @@
package cn.axzo.orgmanax.infra.dao.cooperateship.entity;
import cn.hutool.core.lang.Assert;
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.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
@ -16,6 +19,7 @@ import lombok.experimental.SuperBuilder;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
/**
* (SaasCooperateShip)表实体类
@ -103,6 +107,7 @@ public class SaasCooperateShip implements Serializable {
/**
* 合作关系 1.合作 2.直属
* @see ParterShipEnum
*/
private Integer partnerShip;
@ -138,5 +143,26 @@ public class SaasCooperateShip implements Serializable {
private Long isDelete = 0L;
/**
* 计算节点路径
*
* @param parent
*/
public void calcPath(SaasCooperateShip parent) {
if (Objects.equals(this.getParentId(), 0L)) {
this.path = id + ",";
}
Assert.notNull(parent, "重置路径时,父节点不能为空");
this.path = parent.path + id + ",";
}
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Getter
public enum ParterShipEnum {
COOPERATE(1, "合作"), OWNED(2, "直属");
private final Integer code;
private final String desc;
}
}

View File

@ -1,4 +1,53 @@
package cn.axzo.orgmanax.infra.dao.cooperateship.repository;
import cn.axzo.orgmanax.api.cooperateship.req.ListOrgCooperateShipReq;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.hutool.core.bean.BeanUtil;
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;
public interface CooperateShipQueryRepository {
List<CooperateShipResp> list(ListOrgCooperateShipReq req);
default CooperateShipResp one(OneReq req) {
return oneOpt(req).orElse(null);
}
default Optional<CooperateShipResp> oneOpt(OneReq req) {
req.check();
ListOrgCooperateShipReq listReq = BeanUtil.toBean(req, ListOrgCooperateShipReq.class);
return list(listReq).stream().findFirst();
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class OneReq {
private Long id;
private Long organizationalNodeId;
public void check() {
Preconditions.checkArgument(id != null || organizationalNodeId != null, "参数异常");
}
}
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class CooperateShipResp extends SaasCooperateShip {
// 按需扩展字段占个位避免报错
private String todo;
}
}

View File

@ -1,4 +1,38 @@
package cn.axzo.orgmanax.infra.dao.cooperateship.repository;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.repository.NodeUpsertRepository;
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.Set;
public interface CooperateShipUpsertRepository {
SaasCooperateShip create(SaasCooperateShip cooperateShip);
SaasCooperateShip update(UpdateReq node);
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class UpdateReq extends SaasCooperateShip {
/**
* 由于updateById不支持将值设置为null这里提供这个
*/
Set<SFunction<SaasCooperateShip, ?>> setNullFields = new HashSet<>();
public void check() {
Axssert.checkNonNull(getId(), "要更新的协同关系id不能为空");
}
}
}

View File

@ -1,10 +1,60 @@
package cn.axzo.orgmanax.infra.dao.cooperateship.repository.impl;
import cn.axzo.foundation.dao.support.mysql.QueryWrapperHelper;
import cn.axzo.orgmanax.api.cooperateship.req.ListOrgCooperateShipReq;
import cn.axzo.orgmanax.api.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.infra.dao.cooperateship.dao.SaasCooperateShipDao;
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;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@Slf4j
public class CooperateShipQueryRepositoryImpl implements CooperateShipQueryRepository {
private final SaasCooperateShipDao cooperateShipDao;
private final NodeUserQueryRepository nodeUserQueryRepository;
@Override
public List<CooperateShipResp> list(ListOrgCooperateShipReq req) {
QueryWrapper<SaasCooperateShip> wrapper = QueryWrapperHelper.fromBean(req, SaasCooperateShip.class);
if (wrapper.isEmptyOfWhere()) {
//
log.warn("CooperateShipResp empty of where query. return empty list. req = {}", req);
return Collections.emptyList();
}
List<CooperateShipResp> results = cooperateShipDao.list(wrapper)
.stream().map(e -> BeanUtil.toBean(e, CooperateShipResp.class)).collect(Collectors.toList());
results = filterByPersonIds(results, req);
return results;
}
private List<CooperateShipResp> filterByPersonIds(List<CooperateShipResp> results, ListOrgCooperateShipReq req) {
if (req.getPersonId() == null) {
// filter by personIds
return results;
}
Set<Long> organizationalNodeIds = results.stream().map(SaasCooperateShip::getOrganizationalNodeId).collect(Collectors.toSet());
Set<Long> personInNodeIds = nodeUserQueryRepository.list(ListNodeUserReq.builder()
.personId(req.getPersonId())
.organizationalNodeIds(organizationalNodeIds)
.build())
.stream().map(NodeUserQueryRepository.NodeUserResp::getTopNodeId).collect(Collectors.toSet());
return results.stream()
.filter(e -> personInNodeIds.contains(e.getOrganizationalNodeId()))
.collect(Collectors.toList());
}
}

View File

@ -1,10 +1,36 @@
package cn.axzo.orgmanax.infra.dao.cooperateship.repository.impl;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.orgmanax.infra.dao.cooperateship.dao.SaasCooperateShipDao;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipUpsertRepository;
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.Service;
@Service
@RequiredArgsConstructor
@Slf4j
public class CooperateShipUpsertRepositoryImpl implements CooperateShipUpsertRepository {
private final SaasCooperateShipDao cooperateShipDao;
@Override
public SaasCooperateShip create(SaasCooperateShip cooperateShip) {
cooperateShipDao.save(cooperateShip);
return cooperateShipDao.getById(cooperateShip.getId());
}
@Override
public SaasCooperateShip update(UpdateReq req) {
Axssert.checkNonNull(req.getId(), "更新协同部门协同id不能为空");
LambdaUpdateChainWrapper<SaasCooperateShip> wrapper = cooperateShipDao.lambdaUpdate().eq(SaasCooperateShip::getId, req.getId());
if (CollUtil.isNotEmpty(req.getSetNullFields())) {
req.getSetNullFields().forEach(e -> wrapper.set(e, null));
}
wrapper.update(req);
return cooperateShipDao.getById(req.getId());
}
}

View File

@ -18,6 +18,7 @@ import lombok.NoArgsConstructor;
import lombok.ToString;
import lombok.experimental.Accessors;
import lombok.experimental.SuperBuilder;
import org.springframework.data.annotation.Transient;
import java.io.Serializable;
import java.util.Arrays;
@ -139,7 +140,6 @@ public class OrganizationalNode implements Serializable {
@TableField(value = "profile", typeHandler = FastjsonTypeHandler.class)
private JSONObject profile;
protected Date createAt;
protected Long createBy;
protected Date updateAt;
@ -152,16 +152,19 @@ public class OrganizationalNode implements Serializable {
*
* @param parentNode
*/
public String calcPath(OrganizationalNode parentNode) {
public void calcPath(OrganizationalNode parentNode) {
if (Objects.equals(this.getParentId(), 0L)) {
this.topNodeId = id;
this.path = id + ",";
return this.path;
}
Assert.notNull(parentNode, "重置路径时,父节点不能为空");
this.topNodeId = parentNode.getTopNodeId();
this.path = parentNode.path + id + ",";
return this.path;
}
@Transient
public boolean isTopNode() {
return Objects.equals(topNodeId, id);
}
@Getter

View File

@ -5,7 +5,6 @@ import cn.axzo.foundation.exception.Axssert;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNode;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@ -23,26 +22,12 @@ public interface NodeUpsertRepository {
OrganizationalNode update(UpdateReq node);
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
class CreateReq {
private OrganizationalNode node;
/**
* 场景描述 添加普通部门添加班组
*/
private String scene;
private Long operatorId;
}
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class UpdateReq extends OrganizationalNode {
private String scene;
/**
* 由于updateById不支持将值设置为null这里提供这个
*/

View File

@ -29,7 +29,6 @@ public class NodeUpsertRepositoryImpl implements NodeUpsertRepository {
@Override
public OrganizationalNode update(UpdateReq req) {
Axssert.checkNonNull(req.getId(), "更新部门部门id不能为空");
LambdaUpdateChainWrapper<OrganizationalNode> wrapper = nodeDao.lambdaUpdate().eq(OrganizationalNode::getId, req.getId());
if (CollUtil.isNotEmpty(req.getSetNullFields())) {
req.getSetNullFields().forEach(e -> wrapper.set(e, null));

View File

@ -10,6 +10,6 @@ import org.springframework.stereotype.Repository;
* @date 2024/12/2 18:10
*/
@Repository
public class OrgNodeUserDao extends ServiceImpl<OrganizationalNodeUserMapper, OrganizationalNodeUser> {
public class NodeUserDao extends ServiceImpl<OrganizationalNodeUserMapper, OrganizationalNodeUser> {
}

View File

@ -89,7 +89,7 @@ public class OrganizationalNodeUser implements Serializable {
/**
* 部门管理员 1是 0否
*/
private Object manager;
private Boolean manager;
/**
* 岗位id
@ -162,6 +162,10 @@ public class OrganizationalNodeUser implements Serializable {
*/
private Integer activeFlag;
/**
* 部门人员信息json不同部门类型的部门用户格式不一
*/
@TableField(value = "profile", typeHandler = FastjsonTypeHandler.class)
private JSONObject profile;
}

View File

@ -0,0 +1,67 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.api.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
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 NodeUserQueryRepository {
PageResp<NodeUserResp> page(ListNodeUserReq req);
default List<NodeUserResp> list(ListNodeUserReq req) {
return page(req).getData();
}
default NodeUserResp one(OneReq req) {
return oneOpt(req).orElse(null);
}
default Optional<NodeUserResp> oneOpt(OneReq req) {
req.check();
ListNodeUserReq page = BeanUtil.toBean(req, ListNodeUserReq.class);
page.setPage(1);
page.setPageSize(1);
return page(page).getData().stream().findFirst();
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class OneReq {
private Long id;
private Set<Long> ids;
public void check() {
Preconditions.checkArgument(id != null || CollUtil.isNotEmpty(ids), "参数异常");
}
}
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class NodeUserResp extends OrganizationalNodeUser {
/**
* 查询参数指定 needNode = true才会返回
*
* @see ListNodeUserReq#getNeedNode()
*/
private NodeQueryRepository.NodeResp nodeResp;
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
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.Set;
public interface NodeUserUpsertRepository {
OrganizationalNodeUser create(OrganizationalNodeUser nodeUser);
OrganizationalNodeUser update(UpdateReq node);
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
class UpdateReq extends OrganizationalNodeUser {
/**
* 由于updateById不支持将值设置为null这里提供这个
*/
Set<SFunction<OrganizationalNodeUser, ?>> setNullFields = new HashSet<>();
public void check() {
Axssert.checkNonNull(getId(), "要更新的部门id不能为空");
}
}
}

View File

@ -1,4 +0,0 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository;
public interface OrgNodeUserQueryRepository {
}

View File

@ -1,4 +0,0 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository;
public interface OrgNodeUserUpsertRepository {
}

View File

@ -0,0 +1,68 @@
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.api.node.req.ListNodeReq;
import cn.axzo.orgmanax.api.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository;
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.NodeUserQueryRepository;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
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;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@Slf4j
public class NodeUserQueryRepositoryImpl implements NodeUserQueryRepository {
private final NodeUserDao nodeUserDao;
private final NodeQueryRepository nodeQueryRepository;
@Override
public PageResp<NodeUserResp> page(ListNodeUserReq req) {
IPage<OrganizationalNodeUser> page = PageConverter.toMybatis(req, OrganizationalNodeUser.class);
QueryWrapper<OrganizationalNodeUser> wrapper = QueryWrapperHelper.fromBean(req, OrganizationalNodeUser.class);
IPage<NodeUserResp> results = nodeUserDao.page(page, wrapper)
.convert(e -> BeanUtil.toBean(e, NodeUserResp.class));
PageResp<NodeUserResp> resp = PageConverter.toResp(results);
List<NodeUserResp> records = resp.getData();
if (CollUtil.isEmpty(records)) {
return resp;
}
// assemble node
assembleNode(req, records);
return resp;
}
private void assembleNode(ListNodeUserReq req, List<NodeUserResp> records) {
if (CollUtil.isEmpty(records)) {
return;
}
if (!BooleanUtil.isTrue(req.getNeedNode())) {
return;
}
Set<Long> nodeIds = records.stream().map(NodeUserResp::getOrganizationalNodeId).collect(Collectors.toSet());
// assemble parentNode
Map<Long, NodeQueryRepository.NodeResp> nodesById = nodeQueryRepository.list(ListNodeReq.builder()
.ids(nodeIds)
.build()).stream().collect(Collectors.toMap(NodeQueryRepository.NodeResp::getId, Function.identity()));
records.forEach(r -> r.setNodeResp(nodesById.get(r.getOrganizationalNodeId())));
}
}

View File

@ -0,0 +1,35 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository.impl;
import cn.axzo.foundation.exception.Axssert;
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 com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
@Slf4j
public class NodeUserUpsertRepositoryImpl implements NodeUserUpsertRepository {
private final NodeUserDao nodeUserDao;
@Override
public OrganizationalNodeUser create(OrganizationalNodeUser nodeUser) {
nodeUserDao.save(nodeUser);
return nodeUserDao.getById(nodeUser.getId());
}
@Override
public OrganizationalNodeUser update(UpdateReq req) {
Axssert.checkNonNull(req.getId(), "更新部门人员,部门人员不能为空");
LambdaUpdateChainWrapper<OrganizationalNodeUser> wrapper = nodeUserDao.lambdaUpdate().eq(OrganizationalNodeUser::getId, req.getId());
if (CollUtil.isNotEmpty(req.getSetNullFields())) {
req.getSetNullFields().forEach(e -> wrapper.set(e, null));
}
wrapper.update(req);
return nodeUserDao.getById(req.getId());
}
}

View File

@ -1,10 +0,0 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository.impl;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.OrgNodeUserQueryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class OrgNodeUserQueryRepositoryImpl implements OrgNodeUserQueryRepository {
}

View File

@ -1,10 +0,0 @@
package cn.axzo.orgmanax.infra.dao.nodeuser.repository.impl;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.OrgNodeUserUpsertRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class OrgNodeUserUpsertRepositoryImpl implements OrgNodeUserUpsertRepository {
}

View File

@ -0,0 +1,30 @@
package cn.axzo.orgmanax.server.cooperateship.controller;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.cooperateship.feign.OrgCooperateShipApi;
import cn.axzo.orgmanax.api.cooperateship.req.ListOrgCooperateShipReq;
import cn.axzo.orgmanax.api.cooperateship.resp.OrgCooperateShipDTO;
import cn.axzo.orgmanax.server.cooperateship.service.CooperateShipService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 16:47
*/
@RestController
@RequestMapping
@RequiredArgsConstructor
public class CooperateShipController implements OrgCooperateShipApi {
private final CooperateShipService cooperateShipService;
@Override
public ApiResult<List<OrgCooperateShipDTO>> list(ListOrgCooperateShipReq req) {
return ApiResult.success(cooperateShipService.list(req));
}
}

View File

@ -0,0 +1,25 @@
package cn.axzo.orgmanax.server.cooperateship.event.inner;
import cn.axzo.foundation.event.support.Event;
import cn.axzo.orgmanax.infra.event.config.RocketMQEventConfig;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum CooperateShipEventType {
COOPERATE_SHIP_UPSERTED("cooperate-ship-upserted", "协同部门新增/更新事件"),
;
CooperateShipEventType(String name, String desc) {
this.eventCode = Event.EventCode.builder()
.module(RocketMQEventConfig.DEFAULT_MODULE)
.name(name)
.build();
this.desc = desc;
}
private String desc;
private Event.EventCode eventCode;
}

View File

@ -0,0 +1,19 @@
package cn.axzo.orgmanax.server.cooperateship.event.inner.payload;
import cn.axzo.foundation.event.support.AbstractDiffablePayload;
import cn.axzo.orgmanax.infra.dao.cooperateship.entity.SaasCooperateShip;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class CoopeateShipUpsertedPayload extends AbstractDiffablePayload<SaasCooperateShip> {
private SaasCooperateShip oldValue;
private SaasCooperateShip newValue;
private JSONObject ext;
}

View File

@ -0,0 +1 @@
package cn.axzo.orgmanax.server.cooperateship.event;

View File

@ -0,0 +1,40 @@
package cn.axzo.orgmanax.server.cooperateship.service;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.orgmanax.api.cooperateship.req.ListOrgCooperateShipReq;
import cn.axzo.orgmanax.api.cooperateship.resp.OrgCooperateShipDTO;
import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipQueryRepository;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
public interface CooperateShipService {
CooperateShipQueryRepository.CooperateShipResp create(CreateReq req);
List<OrgCooperateShipDTO> list(ListOrgCooperateShipReq req);
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
class CreateReq {
private Long workspaceId;
private Long organizationalNodeId;
private Long parentId;
private Integer cooperateType;
private Integer partnerShip;
private Long operatorId;
public void check() {
Axssert.checkNonNull(workspaceId, "工作台id不能为空");
Axssert.checkNonNull(organizationalNodeId, "部门id不能为空");
Axssert.checkNonNull(parentId, "上级协同部门不能为空");
Axssert.checkNonNull(cooperateType, "参建类型不能为空");
Axssert.checkNonNull(operatorId, "操作人不能为空 ");
}
}
}

View File

@ -0,0 +1,126 @@
package cn.axzo.orgmanax.server.cooperateship.service.impl;
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.api.cooperateship.req.ListOrgCooperateShipReq;
import cn.axzo.orgmanax.api.cooperateship.resp.CooperateShipStatusEnum;
import cn.axzo.orgmanax.api.cooperateship.resp.CooperateShipTypeEnum;
import cn.axzo.orgmanax.api.cooperateship.resp.OrgCooperateShipDTO;
import cn.axzo.orgmanax.common.config.BizResultCode;
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.infra.dao.cooperateship.repository.CooperateShipQueryRepository;
import cn.axzo.orgmanax.infra.dao.cooperateship.repository.CooperateShipUpsertRepository;
import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository;
import cn.axzo.orgmanax.infra.dao.unit.repository.UnitQueryRepository;
import cn.axzo.orgmanax.server.cooperateship.event.inner.CooperateShipEventType;
import cn.axzo.orgmanax.server.cooperateship.event.inner.payload.CoopeateShipUpsertedPayload;
import cn.axzo.orgmanax.server.cooperateship.service.CooperateShipService;
import cn.hutool.core.bean.BeanUtil;
import com.google.common.collect.ImmutableSet;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class CooperateShipServiceImpl implements CooperateShipService {
private static final Set<Integer> ALLOWED_TOP_COOPERATE_TYPES = ImmutableSet.of(
CooperateShipTypeEnum.PROJ_PRIMARY_CONTRACTING_UNIT.getCode(),
CooperateShipTypeEnum.PROJ_CONSTRUCTION_UNIT.getCode(),
CooperateShipTypeEnum.PROJ_SUPERVISION_UNIT.getCode(),
CooperateShipTypeEnum.OMS.getCode(),
CooperateShipTypeEnum.ENT_COMMON.getCode(),
CooperateShipTypeEnum.SURVEY_UNIT.getCode(),
CooperateShipTypeEnum.DESIGN_UNIT.getCode(),
CooperateShipTypeEnum.OTHER.getCode()
);
private final CooperateShipQueryRepository cooperateShipQueryRepository;
private final CooperateShipUpsertRepository cooperateShipUpsertRepository;
private final NodeQueryRepository nodeQueryRepository;
private final UnitQueryRepository unitQueryRepository;
private final WorkspaceGateway workspaceGateway;
private final EventProducer eventProducer;
@Override
public CooperateShipQueryRepository.CooperateShipResp create(CreateReq req) {
// node check
NodeQueryRepository.NodeResp node = nodeQueryRepository.oneOpt(NodeQueryRepository.OneReq.builder().id(req.getOrganizationalNodeId()).build())
.orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("部门不存在{}", req.getOrganizationalNodeId()));
Axssert.check(node.isTopNode(), BizResultCode.INVALID_PARAM, "只有顶级节点才能添加协同关系");
// workspace check
Workspace workspace = workspaceGateway.getWorkspace(req.getWorkspaceId());
Axssert.checkNonNull(workspace, "工作台不存在{}", req.getWorkspaceId());
CooperateShipQueryRepository.CooperateShipResp parentShip = null;
if (!ALLOWED_TOP_COOPERATE_TYPES.contains(req.getCooperateType())) {
Axssert.check(req.getParentId() > 0L, BizResultCode.INVALID_PARAM, "父级协同类型不能为空");
parentShip = cooperateShipQueryRepository
.oneOpt(CooperateShipQueryRepository.OneReq.builder().id(req.getParentId()).build())
.orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("父级协同部门不存在{}", req.getOrganizationalNodeId()));
Axssert.check(Objects.equals(parentShip.getWorkspaceId(), req.getWorkspaceId()), BizResultCode.INVALID_PARAM, "父级协同部门和要加入部门不是同一个工作台");
}
UnitQueryRepository.UnitResp unit = unitQueryRepository.oneOpt(UnitQueryRepository.OneReq.builder()
.id(node.getId())
.build()).orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("单位不存在{}", node.getOrganizationalUnitId()));
SaasCooperateShip cooperateShip = SaasCooperateShip.builder()
.parentId(req.getParentId())
.workspaceId(workspace.getId())
.workspaceType(workspace.getType())
.workspaceName(workspace.getName())
.status(CooperateShipStatusEnum.PRESENT.getCode())
.joinAt(new Date())
.organizationalUnitId(node.getOrganizationalUnitId())
.organizationalUnitName(unit.getName())
.cooperateType(req.getCooperateType())
.organizationalNodeId(node.getId())
.partnerShip(req.getPartnerShip())
.createBy(req.getOperatorId())
.build();
SaasCooperateShip savedCooperateShip = cooperateShipUpsertRepository.create(cooperateShip);
// update path
savedCooperateShip.calcPath(parentShip);
SaasCooperateShip saved = cooperateShipUpsertRepository.update(CooperateShipUpsertRepository.UpdateReq.builder()
.id(savedCooperateShip.getId())
.path(savedCooperateShip.getPath())
.build());
// 发送数据变更基础MQ
eventProducer.send(Event.builder()
.eventCode(CooperateShipEventType.COOPERATE_SHIP_UPSERTED.getEventCode())
.operatorId(req.getOperatorId() + "")
.operatorType(getClass().getSimpleName())
.targetType("cooperate_ship_id")
.targetId(savedCooperateShip.getId() + "")
.shardingKey(saved.getOrganizationalNodeId() + "")
.data(CoopeateShipUpsertedPayload.builder()
.newValue(saved)
.oldValue(null)
.build())
.build());
// 返回结果
return cooperateShipQueryRepository.one(CooperateShipQueryRepository.OneReq.builder().id(saved.getId()).build());
}
@Override
public List<OrgCooperateShipDTO> list(ListOrgCooperateShipReq req) {
List<OrgCooperateShipDTO> results = cooperateShipQueryRepository.list(req).stream()
.map(e -> BeanUtil.toBean(e, OrgCooperateShipDTO.class)).collect(Collectors.toList());
// assemble other data
return results;
}
}

View File

@ -5,7 +5,7 @@ import cn.axzo.foundation.page.PageResp;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.node.feign.OrgNodeApi;
import cn.axzo.orgmanax.api.node.req.ListNodeReq;
import cn.axzo.orgmanax.api.node.req.NodeProcessReq;
import cn.axzo.orgmanax.api.node.req.ProcessNodeReq;
import cn.axzo.orgmanax.api.node.resp.OrgNodeDTO;
import cn.axzo.orgmanax.server.node.service.NodeService;
import cn.axzo.orgmanax.server.node.service.processor.NodeProcessor;
@ -36,7 +36,7 @@ public class NodeController implements OrgNodeApi {
* @return
*/
@Override
public ApiResult<JSONObject> process(NodeProcessReq req) {
public ApiResult<JSONObject> process(ProcessNodeReq req) {
NodeProcessor.ProcessResult processResult = nodeService.process(req);
Axssert.isTrue(processResult.getSuccess(), NODE_PROCESS_FAILED, processResult.getMsg());
return ApiResult.success(processResult.getContext());

View File

@ -9,7 +9,7 @@ import lombok.Getter;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum NodeEventType {
NODE_UPSERTED("node-upserted", "验收单新增/更新事件"),
NODE_UPSERTED("node-upserted", "部门新增/更新事件"),
;
NodeEventType(String name, String desc) {

View File

@ -53,15 +53,16 @@ public class NodeFoundationServiceImpl implements NodeFoundationService {
// 转换为领域对象
// 持久化 -> mapstruct?
OrganizationalNode organizationalNode = nodeCreate.toEntity();
nodeUpsertRepository.create(organizationalNode);
OrganizationalNode savedNode = nodeUpsertRepository.create(organizationalNode);
// 重新计算pathtopNodeId等数据 未来也可以添加workspaceId等信息
String path = organizationalNode.calcPath(parentNode);
savedNode.calcPath(parentNode);
// 更新path数据
nodeUpsertRepository.update(NodeUpsertRepository.UpdateReq.builder()
.id(organizationalNode.getId())
.path(path)
.id(savedNode.getId())
.topNodeId(savedNode.getTopNodeId())
.path(savedNode.getPath())
.build());
NodeQueryRepository.NodeResp saved = nodeQueryRepository.one(NodeQueryRepository.OneReq.builder().id(organizationalNode.getId()).build());

View File

@ -3,7 +3,7 @@ package cn.axzo.orgmanax.server.node.service;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.api.node.req.ListNodeReq;
import cn.axzo.orgmanax.api.node.req.NodeProcessReq;
import cn.axzo.orgmanax.api.node.req.ProcessNodeReq;
import cn.axzo.orgmanax.api.node.resp.OrgNodeDTO;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.axzo.orgmanax.server.node.service.processor.NodeProcessor;
@ -17,7 +17,7 @@ import java.util.List;
public interface NodeService {
NodeProcessor.ProcessResult process(NodeProcessReq req);
NodeProcessor.ProcessResult process(ProcessNodeReq req);
PageResp<OrgNodeDTO> page(ListNodeReq req);
@ -32,7 +32,7 @@ public interface NodeService {
class ProcessReq {
private Long id;
private Long operatorId;
private NodeProcessReq.Action action;
private ProcessNodeReq.Action action;
private JSONObject param;
/**

View File

@ -3,7 +3,7 @@ package cn.axzo.orgmanax.server.node.service.impl;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.api.node.req.ListNodeReq;
import cn.axzo.orgmanax.api.node.req.NodeProcessReq;
import cn.axzo.orgmanax.api.node.req.ProcessNodeReq;
import cn.axzo.orgmanax.api.node.resp.OrgNodeDTO;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository;
@ -27,7 +27,7 @@ public class NodeServiceImpl implements NodeService {
private final ApplicationContext applicationContext;
@Override
public NodeProcessor.ProcessResult process(NodeProcessReq req) {
public NodeProcessor.ProcessResult process(ProcessNodeReq req) {
// 通用check
Axssert.notNull(req.getAction(), BizResultCode.INVALID_PARAM, "执行行为不能为空");
Axssert.notNull(req.getOperatorId(), BizResultCode.INVALID_PARAM, "操作人不能为空");

View File

@ -1,6 +1,6 @@
package cn.axzo.orgmanax.server.node.service.processor;
import cn.axzo.orgmanax.api.node.req.NodeProcessReq;
import cn.axzo.orgmanax.api.node.req.ProcessNodeReq;
import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository;
import com.alibaba.fastjson.JSONObject;
import lombok.AccessLevel;
@ -24,7 +24,7 @@ public interface NodeProcessor {
@AllArgsConstructor
class ProcessContext {
NodeQueryRepository.NodeResp node;
NodeProcessReq.Action action;
ProcessNodeReq.Action action;
JSONObject params;

View File

@ -1,18 +1,22 @@
package cn.axzo.orgmanax.server.node.service.processor.impl;
import cn.axzo.orgmanax.api.cooperateship.resp.CooperateShipTypeEnum;
import cn.axzo.orgmanax.common.config.BizResultCode;
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.infra.dao.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.server.cooperateship.service.CooperateShipService;
import cn.axzo.orgmanax.server.node.foundation.NodeFoundationService;
import cn.axzo.orgmanax.server.node.foundation.req.NodeCreate;
import cn.axzo.orgmanax.server.node.service.processor.NodeProcessor;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Objects;
/**
* 创建普通部门
*/
@ -20,7 +24,10 @@ import org.springframework.stereotype.Component;
@Slf4j
@RequiredArgsConstructor
public class CreateNodeProcessor implements NodeProcessor {
private final NodeFoundationService nodeFoundationService;
private final CooperateShipService cooperateShipService;
private final WorkspaceGateway workspaceGateway;
@Override
public ProcessResult process(ProcessContext context) {
@ -29,50 +36,42 @@ public class CreateNodeProcessor implements NodeProcessor {
OrganizationalNode savedNode = nodeFoundationService.create(nodeCreate);
// 创建部门的通用MQ在create方法里面已经处理此处不用再发MQ
// 初始化协同关系
initCooperateShipIfNeeded(savedNode, nodeCreate);
// 返回数据
return ProcessResult.success((JSONObject) JSONObject.toJSON(savedNode));
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public static class Param {
protected void initCooperateShipIfNeeded(OrganizationalNode node, NodeCreate nodeCreate) {
if (node == null) {
return;
}
// 平台班组不需要创建协同关系
if (Objects.equals(node.getNodeType(), OrganizationalNode.TypeEnum.TEAM.getValue())) {
return;
}
/**
* 单位ID
*/
private Long organizationalUnitId;
// 非顶级节点不创建协同关系
if (node.getParentId() != null && node.getParentId() > 0L) {
return;
}
/**
* 部门名称
*/
private String organizationalNodeName;
// 查询单位工作台类型
Workspace workspace = workspaceGateway.listWorkspaces(WorkspaceGateway.ListWorkspaceReq.builder()
.type(Workspace.WorkspaceTypeEnum.GENERAL_ENT.value)
.organizationalUnitId(node.getOrganizationalUnitId())
.build()).stream().findFirst().orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("没有企业工作台"));
/**
* 部门类型
*/
private Integer nodeType;
/**
* 上级部门ID
*/
private Long parentId;
/**
* 简介
*/
private String remark;
/**
* 创建人
*/
private Long operatorId;
private JSONObject ext;
public void check() {
// checks
}
// 创建协同关系
cooperateShipService.create(CooperateShipService.CreateReq.builder()
.workspaceId(workspace.getId())
// TODO TOCHECK
.cooperateType(CooperateShipTypeEnum.ENT_COMMON.getCode())
.partnerShip(SaasCooperateShip.ParterShipEnum.OWNED.getCode())
.organizationalNodeId(node.getTopNodeId())
.parentId(0L)
.operatorId(nodeCreate.getOperatorId())
.build());
}
}

View File

@ -0,0 +1,49 @@
package cn.axzo.orgmanax.server.nodeuser.controller;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.foundation.result.ApiResult;
import cn.axzo.orgmanax.api.nodeuser.feign.OrgNodeUserApi;
import cn.axzo.orgmanax.api.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.api.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.api.nodeuser.resp.OrgNodeUserDTO;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService;
import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static cn.axzo.orgmanax.common.config.BizResultCode.NODE_USER_PROCESS_FAILED;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 16:47
*/
@RestController
@RequestMapping
@RequiredArgsConstructor
public class NodeUserController implements OrgNodeUserApi {
private final NodeUserService nodeUserService;
/**
* 创建部门
* <p>
* XXX: why json: 由于不同行为需要的参数和返回信息均不一致jsonObject用来统一接收参数和返回数据具体消费参数的地方serviceprocessor来定义具体的类型
*
* @param req 创建部门参数
* @return
*/
@Override
public ApiResult<JSONObject> process(ProcessNodeUserReq req) {
NodeUserProcessor.ProcessResult processResult = nodeUserService.process(req);
Axssert.isTrue(processResult.getSuccess(), NODE_USER_PROCESS_FAILED, processResult.getMsg());
return ApiResult.success(processResult.getContext());
}
@Override
public ApiResult<PageResp<OrgNodeUserDTO>> list(ListNodeUserReq req) {
return ApiResult.success(nodeUserService.page(req));
}
}

View File

@ -0,0 +1,25 @@
package cn.axzo.orgmanax.server.nodeuser.event.inner;
import cn.axzo.foundation.event.support.Event;
import cn.axzo.orgmanax.infra.event.config.RocketMQEventConfig;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum NodeUserEventType {
NODE_USER_UPSERTED("node-user-upserted", "部门人员新增/更新事件"),
;
NodeUserEventType(String name, String desc) {
this.eventCode = Event.EventCode.builder()
.module(RocketMQEventConfig.DEFAULT_MODULE)
.name(name)
.build();
this.desc = desc;
}
private String desc;
private Event.EventCode eventCode;
}

View File

@ -0,0 +1,34 @@
package cn.axzo.orgmanax.server.nodeuser.event.inner.payload;
import cn.axzo.foundation.event.support.AbstractDiffablePayload;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class NodeUserUpsertedPayload extends AbstractDiffablePayload<OrganizationalNodeUser> {
private OrganizationalNodeUser oldValue;
private OrganizationalNodeUser newValue;
private JSONObject ext;
/**
* 勿删除json序列化会使用
*
* @return
*/
public Long getPersonId() {
return ObjectUtils.firstNonNull(oldValue, newValue).getPersonId();
}
public Long getIdentityId() {
return ObjectUtils.firstNonNull(oldValue, newValue).getIdentityId();
}
}

View File

@ -0,0 +1 @@
package cn.axzo.orgmanax.server.nodeuser.event;

View File

@ -0,0 +1,27 @@
package cn.axzo.orgmanax.server.nodeuser.foundation;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserCreate;
import cn.axzo.orgmanax.server.nodeuser.foundation.req.NodeUserUpdate;
import org.springframework.transaction.annotation.Transactional;
public interface NodeUserFoundationService {
/**
* 创建部门
*
* @param param
* @return
*/
@Transactional(rollbackFor = Throwable.class)
OrganizationalNodeUser create(NodeUserCreate param);
/**
* 该接口为更新的收口接口业务使用的时候需要自行做业务判断
*
* @param req
* @return
*/
@Transactional(rollbackFor = Throwable.class)
OrganizationalNodeUser update(NodeUserUpdate req);
}

View File

@ -0,0 +1,141 @@
package cn.axzo.orgmanax.server.nodeuser.foundation.impl;
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.infra.client.pudge.PersonProfileGateway;
import cn.axzo.orgmanax.infra.client.pudge.dto.IdentityProfile;
import cn.axzo.orgmanax.infra.client.pudge.dto.PersonProfile;
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.repository.NodeQueryRepository;
import cn.axzo.orgmanax.infra.dao.nodeuser.entity.OrganizationalNodeUser;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserUpsertRepository;
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.NodeUserUpdate;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.BooleanUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Objects;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 16:55
*/
@Service
@RequiredArgsConstructor
public class NodeUserFoundationServiceImpl implements NodeUserFoundationService {
private final NodeUserQueryRepository nodeUserQueryRepository;
private final NodeUserUpsertRepository nodeUserUpsertRepository;
private final NodeQueryRepository nodeQueryRepository;
private final CooperateShipQueryRepository cooperateShipQueryRepository;
private final EventProducer eventProducer;
private final PersonProfileGateway profileGateway;
/**
* 创建部门标准接口
*
* @param
* @return
*/
@Transactional
@Override
public OrganizationalNodeUser create(NodeUserCreate param) {
param.check();
// 部门是否存在
NodeQueryRepository.NodeResp node = nodeQueryRepository.oneOpt(NodeQueryRepository.OneReq.builder().id(param.getNodeId()).build())
.orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("部门不存在{}", param.getNodeId()));
// 人是否存在
PersonProfile personProfile = profileGateway.getPersonProfile(param.getPersonId());
Axssert.checkNonNull(personProfile, "用户不存在");
// 人员身份是否存在
IdentityProfile identityProfile = profileGateway.getIdentityProfile(param.getPersonId(), param.getIdentityType());
Axssert.checkNonNull(personProfile, "用户身份不存在");
// 转换为领域对象
// 持久化 -> mapstruct?
OrganizationalNodeUser nodeUser = param.toEntity();
// assemble person info
nodeUser.setIdentityId(identityProfile.getIdentityId());
nodeUser.setPhone(personProfile.getPhone());
nodeUser.setRealName(personProfile.getRealName());
nodeUser.setIdNumber(personProfile.getIdNumber());
// assemble unit info
nodeUser.setOrganizationalUnitId(node.getOrganizationalUnitId());
// assemble node info
nodeUser.setTopNodeId(node.getTopNodeId());
// assemble workspace
nodeUser.setWorkspaceId(resolveWorkspaceId(node));
nodeUserUpsertRepository.create(nodeUser);
NodeUserQueryRepository.NodeUserResp saved = nodeUserQueryRepository.one(
NodeUserQueryRepository.OneReq.builder().id(nodeUser.getId()).build());
// 发送数据变更基础MQ
eventProducer.send(Event.builder()
.eventCode(NodeEventType.NODE_UPSERTED.getEventCode())
.operatorId(param.getOperatorId() + "")
.operatorType(getClass().getSimpleName())
.targetType("personId")
.targetId(saved.getId() + "")
.shardingKey(saved.getPersonId() + "")
.data(NodeUserUpsertedPayload.builder()
.newValue(saved)
.oldValue(null)
.ext(param.getExtra())
.build())
.build());
// 返回结果
return saved;
}
@Override
public OrganizationalNodeUser update(NodeUserUpdate req) {
NodeUserQueryRepository.NodeUserResp dbNodeUser = nodeUserQueryRepository.oneOpt(NodeUserQueryRepository.OneReq.builder().id(req.getId()).build())
.orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("部门人员不存在{}", req.getId()));
NodeUserUpsertRepository.UpdateReq updateReq = BeanUtil.toBean(req, NodeUserUpsertRepository.UpdateReq.class);
// 刷新用户基本资料
if (BooleanUtil.isTrue(req.getRefreshPersonProfile())) {
PersonProfile personProfile = profileGateway.getPersonProfile(dbNodeUser.getPersonId());
Axssert.checkNonNull(personProfile, "用户不存在");
// 人员身份是否存在
IdentityProfile identityProfile = profileGateway.getIdentityProfile(dbNodeUser.getPersonId(), dbNodeUser.getIdentityType());
Axssert.checkNonNull(personProfile, "用户身份不存在");
// 转换为领域对象
// 持久化 -> mapstruct?
// assemble person info
updateReq.setIdentityId(identityProfile.getIdentityId());
updateReq.setPhone(personProfile.getPhone());
updateReq.setRealName(personProfile.getRealName());
updateReq.setIdNumber(personProfile.getIdNumber());
}
return nodeUserUpsertRepository.update(updateReq);
}
private Long resolveWorkspaceId(NodeQueryRepository.NodeResp node) {
if (Objects.equals(node.getNodeType(), OrganizationalNode.TypeEnum.TEAM.getValue())) {
return 0L;
}
return cooperateShipQueryRepository.oneOpt(CooperateShipQueryRepository.OneReq.builder()
.organizationalNodeId(node.getOrganizationalUnitId())
.build()).map(CooperateShipQueryRepository.CooperateShipResp::getWorkspaceId)
.orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("部门人员所属项目未找到,请稍后重试"));
}
}

View File

@ -0,0 +1,76 @@
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 cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.ImmutableMap;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.Date;
import java.util.Optional;
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public class NodeUserCreate {
private Long personId;
private Long nodeId;
private Integer identityType;
private Long workspaceId;
private Boolean manager;
private Long organizationalJobId;
/**
* 0:普通岗位1:主岗位
*/
private Integer primaryJob;
/**
* 是否允许进入工地 1.允许 2.不允许
*/
private Integer isAllowed;
/**
* 数据同步ID
*/
private Long syncDataId;
/**
* 工号
*/
private String jobNumber;
private String joinScene;
private JSONObject extra;
/**
* 1-活跃用户0-非活跃用户
*/
private Integer activeFlag;
private Long operatorId;
/**
* 创建部门的端
*/
private String terminal;
/**
* 创建部门的页面需前端或调用方传入
*/
private String page;
private JSONObject profile;
public void check() {
Axssert.checkNonNull(operatorId, "操作人不能为空");
Axssert.checkNonNull(nodeId, "部门不能为空");
Axssert.checkNonNull(identityType, "人员身份不能为空");
Axssert.checkNonNull(personId, "用户id不能都为空");
}
public OrganizationalNodeUser toEntity() {
OrganizationalNodeUser nodeUser = BeanUtil.toBean(this, OrganizationalNodeUser.class);
nodeUser.setExtra(Optional.ofNullable(extra).orElseGet(JSONObject::new)
.fluentPut("createScene", ImmutableMap.of("terminal", StrUtil.firstNonBlank(terminal, "UNKNOWN"),
"page", StrUtil.firstNonBlank(page, "UNKNOWN"))));
nodeUser.setJoinAt(new Date());
return nodeUser;
}
}

View File

@ -0,0 +1,48 @@
package cn.axzo.orgmanax.server.nodeuser.foundation.req;
import cn.axzo.foundation.exception.Axssert;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@NoArgsConstructor
@AllArgsConstructor
@Data
@SuperBuilder
public class NodeUserUpdate {
private Long id;
private Boolean manager;
private Long organizationalJobId;
/**
* 0:普通岗位1:主岗位
*/
private Integer primaryJob;
/**
* 是否允许进入工地 1.允许 2.不允许
*/
private Integer isAllowed;
/**
* 数据同步ID
*/
private Long syncDataId;
/**
* 工号
*/
private String jobNumber;
private String joinScene;
private JSONObject extra;
/**
* 1-活跃用户0-非活跃用户
*/
private Integer activeFlag;
/**
* 指定为true的情况要刷新用户信息
*/
private Boolean refreshPersonProfile;
public void check() {
Axssert.checkNonNull(id, "部门人员不能为空");
}
}

View File

@ -0,0 +1,51 @@
package cn.axzo.orgmanax.server.nodeuser.service;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.api.node.req.ListNodeReq;
import cn.axzo.orgmanax.api.node.req.ProcessNodeReq;
import cn.axzo.orgmanax.api.node.resp.OrgNodeDTO;
import cn.axzo.orgmanax.api.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.api.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.api.nodeuser.resp.OrgNodeUserDTO;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.axzo.orgmanax.server.node.service.processor.NodeProcessor;
import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
public interface NodeUserService {
NodeUserProcessor.ProcessResult process(ProcessNodeUserReq req);
PageResp<OrgNodeUserDTO> page(ListNodeUserReq req);
default List<OrgNodeUserDTO> list(ListNodeUserReq req) {
return page(req).getData();
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
class ProcessReq {
private Long id;
private Long operatorId;
private ProcessNodeReq.Action action;
private JSONObject param;
/**
* 基于参数的通用逻辑判断
*/
public void check() {
Axssert.notNull(action, BizResultCode.INVALID_PARAM, "执行行为不能为空");
Axssert.notNull(operatorId, BizResultCode.INVALID_PARAM, "操作人不能为空");
}
}
}

View File

@ -0,0 +1,58 @@
package cn.axzo.orgmanax.server.nodeuser.service.impl;
import cn.axzo.foundation.exception.Axssert;
import cn.axzo.foundation.page.PageResp;
import cn.axzo.orgmanax.api.nodeuser.req.ListNodeUserReq;
import cn.axzo.orgmanax.api.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.api.nodeuser.resp.OrgNodeUserDTO;
import cn.axzo.orgmanax.common.config.BizResultCode;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository;
import cn.axzo.orgmanax.server.nodeuser.service.NodeUserService;
import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor;
import cn.hutool.core.bean.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class NodeUserServiceImpl implements NodeUserService {
private final NodeUserQueryRepository nodeUserQueryRepository;
private final ApplicationContext applicationContext;
@Override
public NodeUserProcessor.ProcessResult process(ProcessNodeUserReq req) {
// 通用check
Axssert.notNull(req.getAction(), BizResultCode.INVALID_PARAM, "执行行为不能为空");
Axssert.notNull(req.getOperatorId(), BizResultCode.INVALID_PARAM, "操作人不能为空");
// 如果指定了id校验部门人员是否存在并加载出node以便后续使用
NodeUserQueryRepository.NodeUserResp current = req.getId() == null ? null
: nodeUserQueryRepository.oneOpt(NodeUserQueryRepository.OneReq.builder().id(req.getId()).build())
.orElseThrow(() -> BizResultCode.ENTITY_NOT_FOUND.toException("要操作的部门人员不存在,{}", req.getId()));
// 构建processor所需上下文
NodeUserProcessor.ProcessContext processContext = NodeUserProcessor.ProcessContext.builder()
.nodeUser(current)
.action(req.getAction())
.operatorId(req.getOperatorId())
.params(req.getParam())
.build();
NodeUserProcessor processor = applicationContext.getBean(req.getAction().getProcessor(), NodeUserProcessor.class);
return processor.process(processContext);
}
@Override
public PageResp<OrgNodeUserDTO> page(ListNodeUserReq req) {
PageResp<NodeUserQueryRepository.NodeUserResp> page = nodeUserQueryRepository.page(req);
List<OrgNodeUserDTO> records = page.getData().stream().map(e -> BeanUtil.toBean(e, OrgNodeUserDTO.class)).collect(Collectors.toList());
// assemble data if needed
return new PageResp<>(page.getTotal(), page.getSize(), page.getCurrent(), records);
}
}

View File

@ -0,0 +1,72 @@
package cn.axzo.orgmanax.server.nodeuser.service.processor;
import cn.axzo.orgmanax.api.node.req.ProcessNodeReq;
import cn.axzo.orgmanax.api.nodeuser.req.ProcessNodeUserReq;
import cn.axzo.orgmanax.infra.dao.node.repository.NodeQueryRepository;
import cn.axzo.orgmanax.infra.dao.nodeuser.repository.NodeUserQueryRepository;
import com.alibaba.fastjson.JSONObject;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
public interface NodeUserProcessor {
@Transactional(rollbackFor = Throwable.class)
ProcessResult process(ProcessContext context);
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
class ProcessContext {
NodeUserQueryRepository.NodeUserResp nodeUser;
ProcessNodeUserReq.Action action;
JSONObject params;
String description;
Long operatorId;
String operatorName;
}
@Getter
@Builder(access = AccessLevel.PRIVATE)
@AllArgsConstructor
class ProcessResult {
@Builder.Default
Boolean success = Boolean.TRUE;
String msg;
JSONObject context;
public static ProcessResult success() {
return success(null);
}
public static ProcessResult success(JSONObject context) {
return ProcessResult.builder()
.success(true)
.context(Optional.ofNullable(context).orElse(new JSONObject(0)))
.build();
}
public static ProcessResult fail() {
return fail(null);
}
public static ProcessResult fail(String msg) {
return ProcessResult.builder()
.success(false)
.msg(msg)
.build();
}
}
}

View File

@ -0,0 +1,30 @@
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.NodeUserCreate;
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;
/**
* 添加普通部门人员
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class CreateNodeUserProcessor implements NodeUserProcessor {
private final NodeUserFoundationService nodeUserFoundationService;
@Override
public ProcessResult process(ProcessContext context) {
// 转成该处理器关注的参数对象
NodeUserCreate nodeCreate = context.getParams().toJavaObject(NodeUserCreate.class);
OrganizationalNodeUser nodeUser = nodeUserFoundationService.create(nodeCreate);
// 返回数据
return ProcessResult.success((JSONObject) JSONObject.toJSON(nodeUser));
}
}

View File

@ -0,0 +1,92 @@
package cn.axzo.orgmanax.server.nodeuser.service.processor.impl;
import cn.axzo.foundation.exception.Axssert;
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.NodeUserUpdate;
import cn.axzo.orgmanax.server.nodeuser.service.processor.NodeUserProcessor;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 更新部门人员普通信息
*/
@Component
@Slf4j
@RequiredArgsConstructor
public class UpdateNodeUserProcessor implements NodeUserProcessor {
private final NodeUserFoundationService nodeUserFoundationService;
@Override
public ProcessResult process(ProcessContext context) {
Axssert.checkNonNull(context.getParams(), "更新部门人员失败参数不能为null");
Axssert.checkNonNull(context.getNodeUser(), "要更新的部门人员不存在");
Param param = context.getParams().toJavaObject(Param.class);
param.setId(context.getNodeUser().getId());
NodeUserUpdate update = param.toNodeUpdate();
OrganizationalNodeUser updated = nodeUserFoundationService.update(update);
return ProcessResult.success((JSONObject) JSON.toJSON(updated));
}
/**
* 仅接收允许直接被编辑的字段
*/
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public static class Param {
private Long id;
/**
* 岗位id
*/
private Long organizationalJobId;
/**
* 是否管理员
*/
private String manager;
/**
* 离开时间
*/
private Date leaveAt;
/**
* 工号
*/
private String jobNumber;
/**
* 扩展字段
* XXX:不能简单更新后续要提供增量 更新 删除字段的功能
*/
private JSONObject extra;
/**
* 1-活跃用户0-非活跃用户
*/
private Integer activeFlag;
/**
* 部门人员信息json不同部门类型的部门用户格式不一
* XXX:不能简单更新后续要提供增量 更新 删除字段的功能
*/
private JSONObject profile;
private Boolean refreshPersonProfile;
public NodeUserUpdate toNodeUpdate() {
NodeUserUpdate update = BeanUtil.toBean(this, NodeUserUpdate.class);
return update;
}
}
}

View File

@ -9,7 +9,7 @@ import lombok.Getter;
@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum UnitEventType {
NODE_UPSERTED("unit-upserted", "验收单新增/更新事件"),
NODE_UPSERTED("unit-upserted", "新增/更新事件"),
;
UnitEventType(String name, String desc) {