目录层级调整

This commit is contained in:
TanJ 2024-12-05 11:45:49 +08:00
parent 5edeb439c1
commit 1ae4a9bc0a
41 changed files with 393 additions and 390 deletions

107
README.md
View File

@ -4,17 +4,13 @@
# 项目约束
- 引用外部其它域、第三方SDK时需要与Leader确认禁止私自引入
- service分为`basic`(基础功能)与`biz`(业务功能)。`basic`不可依赖`biz``biz`应依赖`basic`完成部分功能。原则上`biz`与`biz`也不应该互相依赖
- 代码风格:
- 命名规范:采用驼峰命名法,如:`orgmanaxDomain`
- 代码注释:
- 类注释:类名、功能、作者、创建时间、修改时间等
- 方法注释:方法名、功能、参数、返回值、作者、创建时间、修改时间等
- 代码风格:
- 缩进4个空格
- 换行每行不超过120个字符
- 空格:
- 关键字前后:`if`、`for`、`while`、`switch`、`case`等前后各一个空格
- service分为`foundation`(基础功能)与`biz`(业务功能)。`foundation`不可依赖`biz``biz`应依赖`foundation`完成部分功能。原则上`biz`与`biz`也不应该互相依赖
- 枚举不要做成参数的返回值。防止使用方不发布版本,解析失败的问题。
- 为每个接口定义自己的出入参,不要复用出入参
- 所有接口统一采用POST列表接口需要带上分页且设置默认大小1000条
- 接口URL使用 【-】符号进行分割,比如: /orgmanax/node/create-team
- service层提供的出参与入参不能包含ApiResult
- 提供出去的feign api要自己注入spring容器
# 项目结构
## 模块层级
@ -22,13 +18,12 @@
## 模块描述
模块名称 | 功能 | 依赖
------ |-----------------------------------------------------| ----
`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` | API层提供给二方的SDK方便二方快速接入人岗架相关功能 |无
`orgmanax-common`| 公共组件、UTIL等 |无
`orgmanax-infra` | 基础设施层,隔离非业务变化,防止外部变化引起内部业务变更。<br/>对接外部依赖数据库MQ等中件间 | `orgmanax-common`
`orgmanax-server`| 业务层,核心分为两层:<br/>1、基础业务层:`foundation`<br/>2、业务层`biz` <br/>`foundation`依赖`biz`完成业务编排 | `orgmanax-api` `orgmanax-common` `orgmanax-infra`
## 目录层级
```
@ -42,16 +37,20 @@
│   │   └── orgmanax
│   │   └── api
│   │   ├── config #配置将Feign接口托管至spring
│   │   ├── node #部门相关接口
│   │   │   ├── feign #API
│   │   │   │   ├── basic #部门基础API创建部门、通过ID查询部门、更新部门、删除部门
│   │   │   │   └── biz #部门业务相关API具体的实现可以依赖基础API的功能如创建班组部门依赖创建部门等
│   │   │   ├── req #请求入参
│   │   │   └── resp #请求出参
│   │   └── unit #单位相关接口
│   │   └── feign #API
│   │   ├── basic #单位基础API
│   │   └── biz #单位业务相关API
│   │   ├── foundation # 人岗架通用接口
│   │   |   ├── node #部门相关接口
│   │   │   |   ├── feign #API
│   │   │   |   ├── req #请求入参
│   │   │   |   └── resp #请求出参
│   │   |   ├── unit #单位相关接口
│   │   │   |   ├── feign #API
│   │   │   |   ├── req #请求入参
│   │   │   |   └── resp #请求出参
│   │   ├── biz # 人岗架业务相关接口
│   │   |   ├── team #班组业务相关接口
│   │   │   |   ├── feign #API
│   │   │   |   ├── req #请求入参
│   │   │   |   └── resp #请求出参
│   └── resources
│   └── META-INF #SPIservice provider interface)
|
@ -64,21 +63,7 @@
│   └── orgmanax
│   └── common
│   ├── config
│   └── entity
|
├── orgmanax-domain #领域层
│   └── src
│   ├── main
│   │   └── java
│   │   └── cn
│   │   └── axzo
│   │   └── orgmanax
│   │   └── domain
│   │   └── node #部门域
│   │   ├── entity #实体 可以提供部门的属性(字段)及业务行为(接口),注意:会发生属性变更的操作才适合定义为行为
│   │   └── gateway #部门相关的操作接口只定义接口具体的实现由infra层实现
│   │   └── addregate #聚合多个实体的对象和业务操作可以放到该目录下
├── orgmanax-infra #基础设施层主要是对接二方依赖数据库MQ等中件间。依赖domain层
│   └── src
│   ├── main
@ -87,17 +72,18 @@
│   │   │   └── axzo
│   │   │   └── orgmanax
│   │   │   └── infra
│   │   │   ├── config #基础配置如MYBATISPLUS的配置
│   │   │   └── dao #数据访问层
│   │   │   ├── client #外部API防腐层
│   │   │   ├── config #基础配置如mybatis_plus的配置
│   │   │   └── dao #数据访问层
│   │   │   └── node #部门相关
│   │   │   ├── convert #数据转换相关比如将entity转换为数据实体do
│   │   │   ├── dao #mybatisplus的service实现用于CRUD可与Lambda表达式配合使用。
│   │   │   ├── DO #数据实体
│   │   │   ├── gateway # 业务查询防腐层提供给service层使用用于隔离service层与dao层
│   │   │   ├── repos # 业务查询防腐层提供给service层使用用于隔离service层与dao层
│   │   │   │   └── impl #gateway的具体实现可以调用dao完成相关功能,也可以作为聚合根获取数据的实现
│   │   │   └── mapper
|
└── orgmanax-server #包含mvc的controller与service
└── orgmanax-server
└── src
├── main
│   ├── java
@ -105,16 +91,19 @@
│   │   └── axzo
│   │   └── orgmanax
│   │   └── server
│   │   ├── controller #API
│   │   │   ├── node #部门API
│   │   │   └── unit #单位API
│   │   └── service #业务层调用infra层与domain层完成业务流程的编排
│   │   └── node #部门相关业务
│   │   ├── basic #基础的公共相关业务功能实现
│   │   ├── biz #基础的业务功能可以依赖basic里面的接口
│   │   ├── check #业务校验相关
│   │   └── convert #数据转换如将请求REQ转换为领域对象
│   └── resources
└── test
└── java
```
│   │   ├── controller# 继承API实现
│   │   │   ├── biz #业务接口
│   │   │   │   └── team #班组业务接口
│   │   │   └── foundation #基础接口
│   │   │   ├── node #部门基础接口
│   │   │   └── unit #单位基础接口
│   │   └── service # 业务实现
│   │   ├── biz #业务接口
│   │   │   └── team # 班组相关API
│   │   └── foundation #基础接口
│   │   └── node #部门
│   │   ├── check #校验
│   │   ├── convert # 转换
│   │   ├── entity #foundation的业务入参指定为XXXQuery、XXXCreate
│   │   └── service #基础接口的业务实现

BIN
img.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 470 KiB

After

Width:  |  Height:  |  Size: 146 KiB

View File

@ -0,0 +1,29 @@
package cn.axzo.orgmanax.api.biz.team;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.orgmanax.api.biz.team.req.OrgCreateTeamReq;
import cn.axzo.orgmanax.api.biz.team.resp.OrgCreateTeamResp;
import org.springframework.cloud.openfeign.FeignClient;
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 OrgTeamApi {
/**
* 创建项目班组
* @param organizationalNodeCreateReq
* @return
*/
@PostMapping("/api/org/project/create-team")
ApiResult<OrgCreateTeamResp> createProjectTeam(@RequestBody OrgCreateTeamReq organizationalNodeCreateReq);
}

View File

@ -0,0 +1,44 @@
package cn.axzo.orgmanax.api.biz.team.req;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 创建班组请求实体
* @author tanjie@axzo.cn
* @date 2024/12/5 10:46
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class OrgCreateTeamReq {
/**
*
*/
private String name;
/**
*
*/
private Long teamLeaderPersonId;
private Long inviteOuId;
private Long inviteWorkspaceId;
/**
* 单位班组的节点ID
*/
private Long ouTeamNodeId;
/**
* 操作人ID: person id
*/
private Long operatorId;
}

View File

@ -0,0 +1,14 @@
package cn.axzo.orgmanax.api.biz.team.resp;
/**
* @author tanjie@axzo.cn
* @date 2024/12/5 10:55
*/
public class OrgCreateTeamResp {
private Long projectTeamId;
private String teamName;
private Long organizationalNodeId;
}

View File

@ -1,8 +1,8 @@
package cn.axzo.orgmanax.api.node.feign.basic;
package cn.axzo.orgmanax.api.foundation.node.feign;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.orgmanax.api.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.api.node.resp.OrganizationalNodeInfoResp;
import cn.axzo.orgmanax.api.foundation.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.api.foundation.node.resp.OrganizationalNodeInfoResp;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

View File

@ -1,4 +1,4 @@
package cn.axzo.orgmanax.api.node.req;
package cn.axzo.orgmanax.api.foundation.node.req;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -0,0 +1 @@
package cn.axzo.orgmanax.api.foundation.node.req;

View File

@ -1,4 +1,4 @@
package cn.axzo.orgmanax.api.node.resp;
package cn.axzo.orgmanax.api.foundation.node.resp;
import lombok.AllArgsConstructor;
import lombok.Builder;

View File

@ -1,18 +0,0 @@
package cn.axzo.orgmanax.api.node.feign.biz;
import org.springframework.cloud.openfeign.FeignClient;
/**
* business-oriented api related to node
* @author tanjie@axzo.cn
* @date 2024/12/2 15:40
*/
@FeignClient(
value = "orgmanax",
url = "${axzo.service.orgmanax:http://orgmanax:8080}")
public interface OrganizationalNodeBizApi {
}

View File

@ -1 +0,0 @@
package cn.axzo.orgmanax.api.node.req;

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.axzo.orgmanax</groupId>
<artifactId>orgmanax</artifactId>
<version>${revision}</version>
</parent>
<artifactId>orgmanax-domain</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
</project>

View File

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

View File

@ -1,80 +0,0 @@
package cn.axzo.orgmanax.domain.node.entity;
import cn.hutool.core.lang.Assert;
import lombok.Data;
import java.util.Date;
import java.util.Objects;
/**
* 领域对象
* @author tanjie@axzo.cn
* @date 2024/12/2 17:08
*/
@Data
public class OrganizationalNode {
private Long id;
/**
* 单位id
*/
private Long organizationalUnitId;
/**
* 部门名称
*/
private String organizationalNodeName;
/**
* 节点类型 节点类型 1.部门 2.班组 3.小组
*/
private Integer nodeType;
/**
* 上级部门ID
*/
private Long parentId;
/**
* 顶级部门ID
*/
private Long topNodeId;
/**
* 层级信息
*/
private String path;
/**
* 状态
*/
private Integer status;
/**
* 扩展信息
*/
private String extra;
/**
* 创建人自然人ID
*/
private Long createBy;
/**
* 创建时间
*/
private Date createAt;
/**
* 计算pathtopNodeId等信息
*
* @param parentNode 父节点
*/
public void calcPath(OrganizationalNode parentNode) {
if (Objects.equals(this.getParentId(), 0L)) {
this.topNodeId = id;
this.path = id + ",";
return;
}
Assert.notNull(parentNode, "重置路径时,父节点不能为空");
this.topNodeId = parentNode.getTopNodeId();
this.path = parentNode.path + id + ",";
}
}

View File

@ -1,4 +0,0 @@
/**
* @#{(#)package-info.java }
* 领域层
*/

View File

@ -17,11 +17,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.axzo.orgmanax</groupId>
<artifactId>orgmanax-domain</artifactId>
<version>${project.version}</version>
</dependency>
<!-- rocket相关的包 -->
<dependency>
<groupId>org.apache.rocketmq</groupId>
@ -36,7 +32,10 @@
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<!-- TODO 根据项目需要, 使用不同的组件-->
@ -82,5 +81,9 @@
<artifactId>mapstruct-processor</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,39 +0,0 @@
package cn.axzo.orgmanax.infra.client;
import cn.axzo.foundation.web.support.apps.AppCenter;
import cn.axzo.foundation.web.support.rpc.RpcClient;
import cn.axzo.foundation.web.support.rpc.RpcClientWrapper;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@Component
@RequiredArgsConstructor
public class RpcClientHolder {
final AppCenter appCenter;
private final RpcClient rpcClient;
private final LoadingCache<String, RpcClient> rpcClientCache = CacheBuilder.newBuilder()
.maximumSize(50)
.expireAfterAccess(10, TimeUnit.MINUTES)
.build(new CacheLoader<String, RpcClient>() {
@Override
public RpcClient load(String key) {
return RpcClientWrapper.builder()
.normalRpcClient(rpcClient)
.appResolver(() -> appCenter.getByName(key))
.build();
}
});
public RpcClient getRpcClient(String appName) {
RpcClient result = rpcClientCache.getUnchecked(appName);
Objects.requireNonNull(result);
return result;
}
}

View File

@ -35,22 +35,11 @@ import static org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfi
MybatisPlusConfig.class,
RocketMQEventConfig.class})
public class Config {
@Value("${web.debug.host:}")
private String debugHost;
@Bean
public ScheduledThreadPoolExecutor scheduledThreadPoolExecutor(AppRuntime appRuntime) {
// bfs-client会使用这个scheduler
ScheduledThreadPoolExecutor scheduledThreadPoolExecutor =
new ScheduledThreadPoolExecutor(1, new ThreadFactoryBuilder()
.setNameFormat(appRuntime.getAppName() + "-%d").build());
scheduledThreadPoolExecutor.setMaximumPoolSize(8);
return scheduledThreadPoolExecutor;
}
/**
* XXX Spring默认配置当有Executor的bean后不再装载TaskExecutor, 这里因为手动注册了
* {@link #scheduledThreadPoolExecutor}会导致spring不再自动注册TaskExecutor, 因此需要去掉ConditionalOnMissingBean的限制.
* 参考{@link TaskExecutionAutoConfiguration#applicationTaskExecutor}
*/
@Bean(name = {APPLICATION_TASK_EXECUTOR_BEAN_NAME,
@ -64,22 +53,11 @@ public class Config {
return executor;
}
@Bean
AppRuntime appRuntime(ApplicationContext applicationContext) {
return AppRuntime.builder().applicationContext(applicationContext).build();
}
@Bean
public RequestLogAspect requestLogAspect() {
return RequestLogAspect.builder().build();
}
@Bean
@Primary
public RpcClient rpcClient() {
return RpcClientImpl.builder().build();
}
@Bean
@Profile({"!unittest && !local"})
AbstractExceptionHandler.ExceptionHandlerHook exceptionHandlerHook() {
@ -92,13 +70,4 @@ public class Config {
};
}
@Bean
AppCenter appCenter(ScheduledThreadPoolExecutor scheduledThreadPoolExecutor) {
return AppCenterImpl.builder()
.executor(scheduledThreadPoolExecutor)
.debugHost(debugHost)
//本地调试 需要特殊映射的路径 key=服务名 value = host后的映射的服务路径
.debugAppRoutes(ImmutableMap.of("data-collection", "dataCollection"))
.build();
}
}

View File

@ -1,7 +1,7 @@
package cn.axzo.orgmanax.infra.dao.node.DO;
import cn.hutool.core.lang.Assert;
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.TableId;
@ -12,6 +12,7 @@ import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
import java.util.Objects;
/**
* 组织节点表表实体类
@ -27,7 +28,7 @@ import java.util.Date;
@Builder
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = false)
public class OrganizationalNodeDo implements Serializable {
public class OrganizationalNode implements Serializable {
private static final long serialVersionUID = -14708237380609631L;
@TableId(
@ -132,5 +133,21 @@ public class OrganizationalNodeDo implements Serializable {
protected Long isDelete = 0L;
/**
* 计算节点路径
* @param parentNode
*/
public void calcPath(OrganizationalNode parentNode) {
if (Objects.equals(this.getParentId(), 0L)) {
this.topNodeId = id;
this.path = id + ",";
return;
}
Assert.notNull(parentNode, "重置路径时,父节点不能为空");
this.topNodeId = parentNode.getTopNodeId();
this.path = parentNode.path + id + ",";
}
}

View File

@ -1,7 +1,5 @@
package cn.axzo.orgmanax.infra.dao.node.convert;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNodeDo;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@ -14,7 +12,4 @@ public interface NodeInfraConvert {
NodeInfraConvert INSTANCE = Mappers.getMapper(NodeInfraConvert.class);
OrganizationalNode toDomain(OrganizationalNodeDo doo);
OrganizationalNodeDo toEntity(OrganizationalNode doo);
}

View File

@ -1,8 +1,7 @@
package cn.axzo.orgmanax.infra.dao.node.dao;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.convert.NodeInfraConvert;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNodeDo;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.mapper.OrganizationalNodeMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository;
@ -12,10 +11,10 @@ import org.springframework.stereotype.Repository;
* @date 2024/12/2 18:10
*/
@Repository
public class NodeDao extends ServiceImpl<OrganizationalNodeMapper, OrganizationalNodeDo> {
public class NodeDao extends ServiceImpl<OrganizationalNodeMapper, OrganizationalNode> {
public OrganizationalNode findById(Long id) {
return NodeInfraConvert.INSTANCE.toDomain(getById(id));
return (getById(id));
}
}

View File

@ -1,6 +1,7 @@
package cn.axzo.orgmanax.infra.dao.node.gateway;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNode;
/**
* @author tanjie@axzo.cn

View File

@ -1,13 +1,13 @@
package cn.axzo.orgmanax.domain.node.gateway;
package cn.axzo.orgmanax.infra.dao.node.gateway;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNode;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 18:21
* @date 2024/12/4 18:25
*/
public interface NodeUpsertGateway {
OrganizationalNode create(OrganizationalNode node);
OrganizationalNode update(OrganizationalNode node);

View File

@ -1,8 +1,6 @@
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.infra.client.RpcClientHolder;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.dao.NodeDao;
import cn.axzo.orgmanax.infra.dao.node.gateway.NodeQueryGateway;
import lombok.RequiredArgsConstructor;

View File

@ -1,10 +1,9 @@
package cn.axzo.orgmanax.infra.dao.node.gateway.impl;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.domain.node.gateway.NodeUpsertGateway;
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.DO.OrganizationalNodeDo;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNode;
import cn.axzo.orgmanax.infra.dao.node.gateway.NodeUpsertGateway;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
@ -20,16 +19,14 @@ public class NodeUpsertGatewayImpl implements NodeUpsertGateway {
private final NodeDao nodeDao;
@Override
public OrganizationalNode create(OrganizationalNode node) {
OrganizationalNodeDo nodeEntity = NodeInfraConvert.INSTANCE.toEntity(node);
nodeDao.save(nodeEntity);
node.setId(nodeEntity.getId());
nodeDao.save(node);
node.setId(node.getId());
return node;
}
@Override
public OrganizationalNode update(OrganizationalNode node) {
OrganizationalNodeDo nodeEntity = NodeInfraConvert.INSTANCE.toEntity(node);
nodeDao.updateById(nodeEntity);
nodeDao.updateById(node);
return node;
}
}

View File

@ -1,7 +1,7 @@
package cn.axzo.orgmanax.infra.dao.node.mapper;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNodeDo;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNode;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@ -13,7 +13,7 @@ import org.apache.ibatis.annotations.Mapper;
* @since 2022-05-21 18:53:19
*/
@Mapper
public interface OrganizationalNodeMapper extends BaseMapper<OrganizationalNodeDo> {
public interface OrganizationalNodeMapper extends BaseMapper<OrganizationalNode> {
}

View File

@ -19,11 +19,6 @@
<dependencies>
<!--内部依赖-->
<dependency>
<groupId>cn.axzo.orgmanax</groupId>
<artifactId>orgmanax-domain</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.axzo.orgmanax</groupId>

View File

@ -0,0 +1,44 @@
package cn.axzo.orgmanax.server.controller.biz.team;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.orgmanax.api.biz.team.OrgTeamApi;
import cn.axzo.orgmanax.api.biz.team.req.OrgCreateTeamReq;
import cn.axzo.orgmanax.api.biz.team.resp.OrgCreateTeamResp;
import cn.axzo.orgmanax.server.service.foundation.node.service.NodeFoundationServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
/**
* @author tanjie@axzo.cn
* @date 2024/12/5 10:59
*/
@Component
@RequiredArgsConstructor
public class OrgCreateTeamController implements OrgTeamApi{
// 部门基础方法
private final NodeFoundationServiceImpl nodeBasicService;
// 协同关系基础方法
// private final CooperShipFoundationService cooperShipFoundateionService;
// 消息发送器
@Override
public ApiResult<OrgCreateTeamResp> createProjectTeam(OrgCreateTeamReq organizationalNodeCreateReq) {
// 校验
// 创建部门
nodeBasicService.create(null);
// 创建协同关系
// 设置角色
// 发送消息
// 返回结果
return null;
}
}

View File

@ -0,0 +1,37 @@
package cn.axzo.orgmanax.server.controller.foundation.node;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.orgmanax.api.foundation.node.feign.OrganizationalNodeBasicApi;
import cn.axzo.orgmanax.api.foundation.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.api.foundation.node.resp.OrganizationalNodeInfoResp;
import cn.axzo.orgmanax.server.controller.foundation.node.convert.NodeApiConvert;
import cn.axzo.orgmanax.server.service.foundation.node.service.NodeFoundationServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 16:47
*/
@RestController
@RequestMapping
@RequiredArgsConstructor
public class OrganizationalNodeBasicController implements OrganizationalNodeBasicApi {
private final NodeFoundationServiceImpl nodeBasicService;
/**
* 创建部门
*
* @param organizationalNodeCreateReq 创建部门参数
* @return
*/
@Override
public ApiResult<OrganizationalNodeInfoResp> create(OrganizationalNodeCreateReq organizationalNodeCreateReq) {
return ApiResult.ok(nodeBasicService.create(NodeApiConvert.INSTANCE.toFoundation(organizationalNodeCreateReq)));
}
}

View File

@ -0,0 +1,17 @@
package cn.axzo.orgmanax.server.controller.foundation.node.convert;
import cn.axzo.orgmanax.api.foundation.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.server.service.foundation.node.entity.OrganizationalNodeCreate;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author tanjie@axzo.cn
* @date 2024/12/5 10:32
*/
@Mapper
public interface NodeApiConvert {
NodeApiConvert INSTANCE = Mappers.getMapper(NodeApiConvert.class);
OrganizationalNodeCreate toFoundation(OrganizationalNodeCreateReq req);
}

View File

@ -1,4 +1,4 @@
package cn.axzo.orgmanax.server.controller.unit;
package cn.axzo.orgmanax.server.controller.foundation.unit;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

View File

@ -1,34 +0,0 @@
package cn.axzo.orgmanax.server.controller.node;
import cn.axzo.framework.domain.web.result.ApiResult;
import cn.axzo.orgmanax.api.node.feign.basic.OrganizationalNodeBasicApi;
import cn.axzo.orgmanax.api.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.api.node.resp.OrganizationalNodeInfoResp;
import cn.axzo.orgmanax.server.service.node.basic.NodeBasicService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 16:47
*/
@RestController
@RequestMapping
@RequiredArgsConstructor
public class OrganizationalNodeBasicController implements OrganizationalNodeBasicApi {
private final NodeBasicService nodeBasicService;
/**
* 创建部门
* @param organizationalNodeCreateReq 创建部门参数
* @return
*/
@Override
public ApiResult<OrganizationalNodeInfoResp> create(OrganizationalNodeCreateReq organizationalNodeCreateReq) {
return ApiResult.ok(nodeBasicService.create(organizationalNodeCreateReq));
}
}

View File

@ -0,0 +1,6 @@
package cn.axzo.orgmanax.server.service.biz;
/**
* 业务层
*
*
*/

View File

@ -0,0 +1,12 @@
package cn.axzo.orgmanax.server.service.biz.team.service;
import org.springframework.stereotype.Service;
/**
* @author tanjie@axzo.cn
* @date 2024/12/4 18:07
*/
@Service
public class TeamServiceImpl {
}

View File

@ -1,14 +1,11 @@
package cn.axzo.orgmanax.server.service.node.check;
package cn.axzo.orgmanax.server.service.foundation.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 cn.axzo.orgmanax.server.service.foundation.node.entity.OrganizationalNodeCreate;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 20:17
@ -23,7 +20,7 @@ public class NodeBasicCheck {
* @param organizationalNode
* @return
*/
public BizErrorInfo createNodeCheck(OrganizationalNode organizationalNode) {
public BizErrorInfo createNodeCheck(OrganizationalNodeCreate organizationalNode) {
// 重名校验
// nodeQueryGateway.find(organizationalNode.getOrganizationalNodeName());

View File

@ -0,0 +1,18 @@
package cn.axzo.orgmanax.server.service.foundation.node.convert;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNode;
import cn.axzo.orgmanax.server.service.foundation.node.entity.OrganizationalNodeCreate;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 17:26
*/
@Mapper
public interface NodeConvert {
NodeConvert INSTANCE = Mappers.getMapper(NodeConvert.class);
OrganizationalNode toDo(OrganizationalNodeCreate req);
}

View File

@ -0,0 +1,42 @@
package cn.axzo.orgmanax.server.service.foundation.node.entity;
/**
* 部门相关操作
* @author tanjie@axzo.cn
* @date 2024/12/5 10:28
*/
public class OrganizationalNodeCreate {
/**
* 单位ID
*/
private Long organizationalUnitId;
/**
* 部门名称
*/
private String organizationalNodeName;
/**
* 部门类型
*/
private Integer nodeType;
/**
* 上级部门ID
*/
private Long parentId;
/**
* 简介
*/
private String remark;
/**
* 创建人
*/
private Long crateBy;
}

View File

@ -1,13 +1,13 @@
package cn.axzo.orgmanax.server.service.node.basic;
package cn.axzo.orgmanax.server.service.foundation.node.service;
import cn.axzo.orgmanax.api.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.api.node.resp.OrganizationalNodeInfoResp;
import cn.axzo.orgmanax.api.foundation.node.resp.OrganizationalNodeInfoResp;
import cn.axzo.orgmanax.common.entity.BizErrorInfo;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import cn.axzo.orgmanax.domain.node.gateway.NodeUpsertGateway;
import cn.axzo.orgmanax.infra.dao.node.DO.OrganizationalNode;
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.infra.dao.node.gateway.NodeUpsertGateway;
import cn.axzo.orgmanax.server.service.foundation.node.check.NodeBasicCheck;
import cn.axzo.orgmanax.server.service.foundation.node.convert.NodeConvert;
import cn.axzo.orgmanax.server.service.foundation.node.entity.OrganizationalNodeCreate;
import cn.hutool.core.lang.Assert;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@ -19,7 +19,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@Service
@RequiredArgsConstructor
public class NodeBasicService {
public class NodeFoundationServiceImpl {
private final NodeBasicCheck nodeBasicCheck;
private final NodeQueryGateway nodeQueryGateway;
@ -27,37 +27,37 @@ public class NodeBasicService {
/**
* 创建部门
* 创建部门标准接口
*
* @param organizationalNodeCreateReq 创建部门参数
* @param
* @return
*/
@Transactional
public OrganizationalNodeInfoResp create(OrganizationalNodeCreateReq organizationalNodeCreateReq) {
OrganizationalNode node = NodeConvert.INSTANCE.toNodeDomain(organizationalNodeCreateReq);
public OrganizationalNodeInfoResp create(OrganizationalNodeCreate organizationalNodeCreate) {
// 业务校验
BizErrorInfo bizErrorInfo = nodeBasicCheck.createNodeCheck(node);
BizErrorInfo bizErrorInfo = nodeBasicCheck.createNodeCheck(organizationalNodeCreate);
Assert.isTrue(bizErrorInfo.isSuccess(), bizErrorInfo.getErrorMsg());
// 转换为领域对象
// 持久化
nodeUpsertGateway.create(node);
OrganizationalNode organizationalNode = NodeConvert.INSTANCE.toDo(organizationalNodeCreate);
nodeUpsertGateway.create(organizationalNode);
// 获取上级节点为了重新计算pathtopNodeId等数据
OrganizationalNode parentNode = nodeQueryGateway.findById(node.getParentId());
OrganizationalNode parentNode = nodeQueryGateway.findById(organizationalNode.getParentId());
// 重新计算pathtopNodeId等数据 未来也可以添加workspaceId等信息
node.calcPath(parentNode);
organizationalNode.calcPath(parentNode);
//更新数据
nodeUpsertGateway.update(node);
nodeUpsertGateway.update(organizationalNode);
// 发送消息
// 返回结果
return OrganizationalNodeInfoResp.builder()
.id(node.getId())
.id(organizationalNode.getId())
// ....
.build();
}

View File

@ -0,0 +1,8 @@
package cn.axzo.orgmanax.server.service.foundation;
/**
* 基础方法层
* 涉及到单域的业务操作都封装到该层
* 所以的读写操作都需要经过该层
*/

View File

@ -1,18 +0,0 @@
package cn.axzo.orgmanax.server.service.node.convert;
import cn.axzo.orgmanax.api.node.req.OrganizationalNodeCreateReq;
import cn.axzo.orgmanax.domain.node.entity.OrganizationalNode;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
/**
* @author tanjie@axzo.cn
* @date 2024/12/2 17:26
*/
@Mapper
public interface NodeConvert {
NodeConvert INSTANCE = Mappers.getMapper(NodeConvert.class);
OrganizationalNode toNodeDomain(OrganizationalNodeCreateReq req);
}

View File

@ -117,7 +117,6 @@
<modules>
<module>orgmanax-api</module>
<module>orgmanax-common</module>
<module>orgmanax-domain</module>
<module>orgmanax-server</module>
<module>orgmanax-infra</module>
</modules>