添加 README.md

This commit is contained in:
TanJ 2024-12-04 11:29:07 +08:00
parent 19228b0412
commit 5edeb439c1
23 changed files with 283 additions and 64 deletions

120
README.md
View File

@ -0,0 +1,120 @@
# 项目概述
- 项目名称Orgmanax“Org” 代表 `organization组织``man` 表示 “人”,`ax` 象征对这些元素进行整合.
- 项目简介:维护单位、部门、人员、岗位相关的业务及数据,比如:通讯录、项目添加人员、添加班组、更换班组长等
# 项目约束
- 引用外部其它域、第三方SDK时需要与Leader确认禁止私自引入
- service分为`basic`(基础功能)与`biz`(业务功能)。`basic`不可依赖`biz``biz`应依赖`basic`完成部分功能。原则上`biz`与`biz`也不应该互相依赖
- 代码风格:
- 命名规范:采用驼峰命名法,如:`orgmanaxDomain`
- 代码注释:
- 类注释:类名、功能、作者、创建时间、修改时间等
- 方法注释:方法名、功能、参数、返回值、作者、创建时间、修改时间等
- 代码风格:
- 缩进4个空格
- 换行每行不超过120个字符
- 空格:
- 关键字前后:`if`、`for`、`while`、`switch`、`case`等前后各一个空格
# 项目结构
## 模块层级
![img.png](img.png)
## 模块描述
模块名称 | 功能 | 依赖
------ |-----------------------------------------------------| ----
`orgmanax-api` | API层提供给二方的SDK方便二方快速接入人岗架相关功能 |无
`orgmanax-common`| 公共组件、UTIL等 |无
`orgmanax-domain`| 领域层,核心业务逻辑 | 无
`orgmanax-infra` | 基础设施层,隔离非业务变化,防止外部变化引起内部业务变更。<br/>对接二方依赖数据库MQ等中件间 | `orgmanax-domain` `orgmanax-common`
`orgmanax-server`| 业务层调用domain与infra实现业务逻辑的编排 | `orgmanax-api` `orgmanax-common` `orgmanax-infra` `orgmanax-domain`
## 目录层级
```
.
├── orgmanax-api #提供给二方的功能,包括基础功能、业务功能。
│   └── src
│   ├── main
│   │   └── java
│   │   └── cn
│   │   └── axzo
│   │   └── orgmanax
│   │   └── api
│   │   ├── config #配置将Feign接口托管至spring
│   │   ├── node #部门相关接口
│   │   │   ├── feign #API
│   │   │   │   ├── basic #部门基础API创建部门、通过ID查询部门、更新部门、删除部门
│   │   │   │   └── biz #部门业务相关API具体的实现可以依赖基础API的功能如创建班组部门依赖创建部门等
│   │   │   ├── req #请求入参
│   │   │   └── resp #请求出参
│   │   └── unit #单位相关接口
│   │   └── feign #API
│   │   ├── basic #单位基础API
│   │   └── biz #单位业务相关API
│   └── resources
│   └── META-INF #SPIservice provider interface)
|
├── orgmanax-common #公共包
│   └── src
│   └── main
│   └── java
│   └── cn
│   └── axzo
│   └── orgmanax
│   └── common
│   ├── config
│   └── entity
|
├── orgmanax-domain #领域层
│   └── src
│   ├── main
│   │   └── java
│   │   └── cn
│   │   └── axzo
│   │   └── orgmanax
│   │   └── domain
│   │   └── node #部门域
│   │   ├── entity #实体 可以提供部门的属性(字段)及业务行为(接口),注意:会发生属性变更的操作才适合定义为行为
│   │   └── gateway #部门相关的操作接口只定义接口具体的实现由infra层实现
│   │   └── addregate #聚合多个实体的对象和业务操作可以放到该目录下
├── orgmanax-infra #基础设施层主要是对接二方依赖数据库MQ等中件间。依赖domain层
│   └── src
│   ├── main
│   │   ├── java
│   │   │   └── cn
│   │   │   └── axzo
│   │   │   └── orgmanax
│   │   │   └── infra
│   │   │   ├── config #基础配置如MYBATISPLUS的配置
│   │   │   └── dao #数据访问层
│   │   │   └── node #部门相关
│   │   │   ├── convert #数据转换相关比如将entity转换为数据实体do
│   │   │   ├── dao #mybatisplus的service实现用于CRUD可与Lambda表达式配合使用。
│   │   │   ├── DO #数据实体
│   │   │   ├── gateway # 业务查询防腐层提供给service层使用用于隔离service层与dao层
│   │   │   │   └── impl #gateway的具体实现可以调用dao完成相关功能,也可以作为聚合根获取数据的实现
│   │   │   └── mapper
|
└── orgmanax-server #包含mvc的controller与service
└── src
├── main
│   ├── java
│   │   └── cn
│   │   └── axzo
│   │   └── orgmanax
│   │   └── server
│   │   ├── controller #API
│   │   │   ├── node #部门API
│   │   │   └── unit #单位API
│   │   └── service #业务层调用infra层与domain层完成业务流程的编排
│   │   └── node #部门相关业务
│   │   ├── basic #基础的公共相关业务功能实现
│   │   ├── biz #基础的业务功能可以依赖basic里面的接口
│   │   ├── check #业务校验相关
│   │   └── convert #数据转换如将请求REQ转换为领域对象
│   └── resources
└── test
└── java
```

BIN
img.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

View File

@ -8,6 +8,6 @@ import org.springframework.context.annotation.Configuration;
* @date 2022/4/25 10:48 * @date 2022/4/25 10:48
*/ */
@Configuration @Configuration
@EnableFeignClients(basePackages = "cn.axzo.orgmanax.api.feign") @EnableFeignClients(basePackages = "cn.axzo.orgmanax.api.**.feign")
public class OrgmanaxApiConfig { public class OrgmanaxApiConfig {
} }

View File

@ -7,8 +7,6 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
/** /**
* 部门相关基础API * 部门相关基础API
* @author tanjie@axzo.cn * @author tanjie@axzo.cn

View File

@ -1,6 +1,9 @@
package cn.axzo.orgmanax.api.node.resp; package cn.axzo.orgmanax.api.node.resp;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date; import java.util.Date;
@ -10,7 +13,15 @@ import java.util.Date;
* @date 2024/12/2 16:20 * @date 2024/12/2 16:20
*/ */
@Data @Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class OrganizationalNodeInfoResp { public class OrganizationalNodeInfoResp {
/**
* 部门ID
*/
private Long id;
/** /**
* 单位id * 单位id
*/ */
@ -55,4 +66,5 @@ public class OrganizationalNodeInfoResp {
* 创建时间 * 创建时间
*/ */
private Date createAt; private Date createAt;
} }

View File

@ -0,0 +1,8 @@
package cn.axzo.orgmanax.api.unit.req;
/**
* @author tanjie@axzo.cn
* @date 2024/12/3 14:23
*/
public class OrganizationalUnitQueryReq {
}

View File

@ -0,0 +1,23 @@
package cn.axzo.orgmanax.common.entity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 业务异常信息
* @author tanjie@axzo.cn
* @date 2024/12/2 20:20
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BizErrorInfo {
private boolean isSuccess;
private String errorMsg;
}

View File

@ -0,0 +1,8 @@
package cn.axzo.orgmanax.domain.addregate;
/**
* @(package: cn.axzo.orgmanax.domain.addregate)
*
* 聚合多个实体的根对象
* NodeUnit聚合了OrganizationalNodeOrganizationalUnit
*
*/

View File

@ -8,6 +8,7 @@ import cn.axzo.foundation.web.support.exception.AbstractExceptionHandler;
import cn.axzo.foundation.web.support.log.RequestLogAspect; import cn.axzo.foundation.web.support.log.RequestLogAspect;
import cn.axzo.foundation.web.support.rpc.RpcClient; import cn.axzo.foundation.web.support.rpc.RpcClient;
import cn.axzo.foundation.web.support.rpc.RpcClientImpl; import cn.axzo.foundation.web.support.rpc.RpcClientImpl;
import cn.axzo.orgmanax.infra.event.config.RocketMQEventConfig;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@ -1,13 +1,17 @@
package cn.axzo.orgmanax.infra.dao.node.entity; package cn.axzo.orgmanax.infra.dao.node.DO;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler; import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import lombok.*; import lombok.*;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date;
/** /**
* 组织节点表表实体类 * 组织节点表表实体类
@ -17,12 +21,19 @@ import java.io.Serializable;
*/ */
@TableName(value = "organizational_node", autoResultMap = true) @TableName(value = "organizational_node", autoResultMap = true)
@Data @Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true) @Accessors(chain = true)
public class OrganizationalNodeDo extends BaseEntity<OrganizationalNodeDo> implements Serializable { @NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public class OrganizationalNodeDo implements Serializable {
private static final long serialVersionUID = -14708237380609631L; private static final long serialVersionUID = -14708237380609631L;
@TableId(
type = IdType.AUTO
)
protected Long id;
/** /**
* 上级id,为0时为顶级节点 * 上级id,为0时为顶级节点
*/ */
@ -113,15 +124,13 @@ public class OrganizationalNodeDo extends BaseEntity<OrganizationalNodeDo> imple
private JSONObject profile; private JSONObject profile;
/** protected Date createAt;
* 获取主键值 protected Long createBy;
* protected Date updateAt;
* @return 主键值 protected Long updateBy;
*/ @TableField("is_delete")
@Override protected Long isDelete = 0L;
protected Serializable pkVal() {
return this.id;
}
} }

View File

@ -1,7 +1,7 @@
package cn.axzo.orgmanax.infra.dao.node.convert; package cn.axzo.orgmanax.infra.dao.node.convert;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode; import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNodeDo; import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNodeDo;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;

View File

@ -2,7 +2,7 @@ package cn.axzo.orgmanax.infra.dao.node.dao;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode; import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.convert.NodeInfraConvert; import cn.axzo.orgmanax.infra.dao.node.convert.NodeInfraConvert;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNodeDo; import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNodeDo;
import cn.axzo.orgmanax.infra.dao.node.mapper.OrganizationalNodeMapper; import cn.axzo.orgmanax.infra.dao.node.mapper.OrganizationalNodeMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;

View File

@ -1,37 +0,0 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package cn.axzo.orgmanax.infra.dao.node.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;
import java.io.Serializable;
import java.util.Date;
@Data
public abstract class BaseEntity<T extends Model<T>> extends Model<T> implements Serializable {
@TableId(
type = IdType.AUTO
)
protected Long id;
@TableField(
fill = FieldFill.INSERT
)
protected Date createAt;
@TableField(
fill = FieldFill.UPDATE
)
protected Date updateAt;
@TableField("is_delete")
protected Long isDelete = 0L;
}

View File

@ -1,6 +1,8 @@
package cn.axzo.orgmanax.infra.dao.node.gateway.impl; package cn.axzo.orgmanax.infra.dao.node.gateway.impl;
import cn.axzo.foundation.web.support.rpc.RpcClient;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode; import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.client.RpcClientHolder;
import cn.axzo.orgmanax.infra.dao.node.dao.NodeDao; import cn.axzo.orgmanax.infra.dao.node.dao.NodeDao;
import cn.axzo.orgmanax.infra.dao.node.gateway.NodeQueryGateway; import cn.axzo.orgmanax.infra.dao.node.gateway.NodeQueryGateway;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -17,6 +19,8 @@ public class NodeQueryGatewayImpl implements NodeQueryGateway {
private final NodeDao nodeDao; private final NodeDao nodeDao;
@Override @Override
public OrganizationalNode findById(Long id) { public OrganizationalNode findById(Long id) {
return nodeDao.findById(id); return nodeDao.findById(id);
} }
} }

View File

@ -4,7 +4,7 @@ import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.domain.node.gateway.NodeUpsertGateway; import cn.axzo.orgmanax.domain.node.gateway.NodeUpsertGateway;
import cn.axzo.orgmanax.infra.dao.node.convert.NodeInfraConvert; import cn.axzo.orgmanax.infra.dao.node.convert.NodeInfraConvert;
import cn.axzo.orgmanax.infra.dao.node.dao.NodeDao; import cn.axzo.orgmanax.infra.dao.node.dao.NodeDao;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNodeDo; import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNodeDo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;

View File

@ -1,7 +1,7 @@
package cn.axzo.orgmanax.infra.dao.node.mapper; package cn.axzo.orgmanax.infra.dao.node.mapper;
import cn.axzo.orgmanax.infra.dao.node.entity.OrganizationalNodeDo; import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNodeDo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;

View File

@ -0,0 +1,23 @@
package cn.axzo.orgmanax.infra.event.config;
import cn.axzo.foundation.event.support.producer.EventProducer;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
/**
* @author tanjie@axzo.cn
* @date 2024/12/3 14:27
*/
@Component
@RequiredArgsConstructor
public class MQEventProducer {
/**
* rocket
*/
private final EventProducer eventProducer;
}

View File

@ -1,4 +1,4 @@
package cn.axzo.orgmanax.infra.config; package cn.axzo.orgmanax.infra.event.config;
import cn.axzo.foundation.event.support.consumer.*; import cn.axzo.foundation.event.support.consumer.*;
import cn.axzo.foundation.event.support.producer.EventProducer; import cn.axzo.foundation.event.support.producer.EventProducer;

View File

@ -35,6 +35,11 @@
<artifactId>orgmanax-api</artifactId> <artifactId>orgmanax-api</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>cn.axzo.orgmanax</groupId>
<artifactId>orgmanax-common</artifactId>
<version>${project.version}</version>
</dependency>
<!----> <!---->
<dependency> <dependency>
<groupId>com.alibaba.cloud</groupId> <groupId>com.alibaba.cloud</groupId>

View File

@ -4,7 +4,7 @@ import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.orgmanax.api.node.feign.basic.OrganizationalNodeBasicApi; import cn.axzo.orgmanax.api.node.feign.basic.OrganizationalNodeBasicApi;
import cn.axzo.orgmanax.api.node.req.OrganizationalNodeCreateReq; import cn.axzo.orgmanax.api.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.api.node.resp.OrganizationalNodeInfoResp; import cn.axzo.orgmanax.api.node.resp.OrganizationalNodeInfoResp;
import cn.axzo.orgmanax.server.service.node.NodeBasicService; import cn.axzo.orgmanax.server.service.node.basic.NodeBasicService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;

View File

@ -1,11 +1,14 @@
package cn.axzo.orgmanax.server.service.node; package cn.axzo.orgmanax.server.service.node.basic;
import cn.axzo.orgmanax.api.node.req.OrganizationalNodeCreateReq; import cn.axzo.orgmanax.api.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.api.node.resp.OrganizationalNodeInfoResp; import cn.axzo.orgmanax.api.node.resp.OrganizationalNodeInfoResp;
import cn.axzo.orgmanax.common.entity.BizErrorInfo;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode; import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.domain.node.gateway.NodeUpsertGateway; import cn.axzo.orgmanax.domain.node.gateway.NodeUpsertGateway;
import cn.axzo.orgmanax.infra.dao.node.gateway.NodeQueryGateway; import cn.axzo.orgmanax.infra.dao.node.gateway.NodeQueryGateway;
import cn.axzo.orgmanax.server.service.node.check.NodeBasicCheck;
import cn.axzo.orgmanax.server.service.node.convert.NodeConvert; import cn.axzo.orgmanax.server.service.node.convert.NodeConvert;
import cn.hutool.core.lang.Assert;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -18,6 +21,7 @@ import org.springframework.transaction.annotation.Transactional;
@RequiredArgsConstructor @RequiredArgsConstructor
public class NodeBasicService { public class NodeBasicService {
private final NodeBasicCheck nodeBasicCheck;
private final NodeQueryGateway nodeQueryGateway; private final NodeQueryGateway nodeQueryGateway;
private final NodeUpsertGateway nodeUpsertGateway; private final NodeUpsertGateway nodeUpsertGateway;
@ -30,9 +34,12 @@ public class NodeBasicService {
*/ */
@Transactional @Transactional
public OrganizationalNodeInfoResp create(OrganizationalNodeCreateReq organizationalNodeCreateReq) { public OrganizationalNodeInfoResp create(OrganizationalNodeCreateReq organizationalNodeCreateReq) {
OrganizationalNode node = NodeConvert.INSTANCE.toNode(organizationalNodeCreateReq); OrganizationalNode node = NodeConvert.INSTANCE.toNodeDomain(organizationalNodeCreateReq);
// 业务校验
// 业务校验
BizErrorInfo bizErrorInfo = nodeBasicCheck.createNodeCheck(node);
Assert.isTrue(bizErrorInfo.isSuccess(), bizErrorInfo.getErrorMsg());
// 转换为领域对象
// 持久化 // 持久化
nodeUpsertGateway.create(node); nodeUpsertGateway.create(node);
@ -49,6 +56,10 @@ public class NodeBasicService {
// 返回结果 // 返回结果
return null; return OrganizationalNodeInfoResp.builder()
.id(node.getId())
// ....
.build();
} }
} }

View File

@ -0,0 +1,34 @@
package cn.axzo.orgmanax.server.service.node.check;
import cn.axzo.framework.domain.web.BizException;
import cn.axzo.orgmanax.common.entity.BizErrorInfo;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.gateway.NodeQueryGateway;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 20:17
*/
@Service
@RequiredArgsConstructor
public class NodeBasicCheck {
private final NodeQueryGateway nodeQueryGateway;
/** 返回值也可以封装成对象
* @param organizationalNode
* @return
*/
public BizErrorInfo createNodeCheck(OrganizationalNode organizationalNode) {
// 重名校验
// nodeQueryGateway.find(organizationalNode.getOrganizationalNodeName());
return BizErrorInfo.builder()
.isSuccess(true)
.build();
}
}

View File

@ -13,6 +13,6 @@ import org.mapstruct.factory.Mappers;
public interface NodeConvert { public interface NodeConvert {
NodeConvert INSTANCE = Mappers.getMapper(NodeConvert.class); NodeConvert INSTANCE = Mappers.getMapper(NodeConvert.class);
OrganizationalNode toNode(OrganizationalNodeCreateReq req); OrganizationalNode toNodeDomain(OrganizationalNodeCreateReq req);
} }