人员信息同步

This commit is contained in:
pengjie 2024-07-26 18:55:21 +08:00
parent 151b71a930
commit af1194e4b4
9 changed files with 619 additions and 2 deletions

View File

@ -0,0 +1,257 @@
package com.zhgd.xmgl.modules.basicdata.controller;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zhgd.jeecg.common.api.vo.Result;
import com.zhgd.redis.lock.RedisRepository;
import com.zhgd.xmgl.modules.basicdata.entity.OrganizationDept;
import com.zhgd.xmgl.modules.basicdata.entity.OrganizationJob;
import com.zhgd.xmgl.modules.basicdata.entity.SystemUser;
import com.zhgd.xmgl.modules.basicdata.service.IOrganizationDeptService;
import com.zhgd.xmgl.modules.basicdata.service.IOrganizationJobService;
import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.*;
@RestController
@RequestMapping("/xmgl/baseData")
@Slf4j
@Api(tags = "九柱主数据同步")
public class BaseDataController {
@Value("${jiuzhu.appId}")
private final String APPID = "991cefd2-0592-4734-8055-60ae8dd4005c";
@Value("${jiuzhu.address}")
private final String ADDRESS = "http://218.95.151.122:18000";
@Autowired
private RedisRepository redisRepository;
@Autowired
private IOrganizationJobService organizationJobService;
@Autowired
private IOrganizationDeptService organizationDeptService;
@Autowired
private ISystemUserService systemUserService;
@ApiOperation(value = "获取分部数据进行同步", notes = "获取分部数据进行同步", httpMethod="POST")
@PostMapping(value = "/getSubCompanyData")
public Result<Map<String, Object>> getSubCompanyData(@RequestBody Map<String, Object> map) {
Map<String, Object> jsonParams = new HashMap<>();
Map<String, Object> params = new HashMap<>();
params.put("pagesize", 1000);
params.put("curpage", 1);
jsonParams.put("params", params);
String result = testRestful(ADDRESS, "/api/hrm/resful/getHrmsubcompanyWithPage", JSONObject.toJSONString(jsonParams));
if (StringUtils.isNotBlank(result)) {
JSONObject obj = JSONObject.parseObject(result);
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("dataList");
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject subCompany = jsonArray.getJSONObject(i);
}
}
return Result.success(null);
}
@ApiOperation(value = "获取岗位数据进行同步", notes = "获取岗位数据进行同步", httpMethod="POST")
@PostMapping(value = "/getJobData")
public Result<Map<String, Object>> getJobData(@RequestBody Map<String, Object> map) {
Map<String, Object> jsonParams = new HashMap<>();
Map<String, Object> params = new HashMap<>();
params.put("pagesize", 1000);
params.put("curpage", 1);
jsonParams.put("params", params);
String result = testRestful(ADDRESS, "/api/hrm/resful/getJobtitleInfoWithPage", JSONObject.toJSONString(jsonParams));
if (StringUtils.isNotBlank(result)) {
JSONObject obj = JSONObject.parseObject(result);
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("dataList");
List<OrganizationDept> deptList = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject dept = jsonArray.getJSONObject(i);
OrganizationDept organizationDept = new OrganizationDept();
organizationDept.setId(Long.valueOf(dept.getString("id")));
organizationDept.setDeptName(dept.getString("jobtitlename"));
deptList.add(organizationDept);
}
organizationDeptService.saveBatch(deptList);
}
return Result.success(null);
}
@ApiOperation(value = "获取部门数据进行同步", notes = "获取部门数据进行同步", httpMethod="POST")
@PostMapping(value = "/getDeptData")
public Result<Map<String, Object>> getDeptData(@RequestBody Map<String, Object> map) {
Map<String, Object> jsonParams = new HashMap<>();
Map<String, Object> params = new HashMap<>();
params.put("pagesize", 1000);
params.put("curpage", 1);
jsonParams.put("params", params);
String result = testRestful(ADDRESS, "/api/hrm/resful/getHrmdepartmentWithPage", JSONObject.toJSONString(jsonParams));
if (StringUtils.isNotBlank(result)) {
JSONObject obj = JSONObject.parseObject(result);
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("dataList");
List<OrganizationJob> jobList = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject dept = jsonArray.getJSONObject(i);
OrganizationJob organizationJob = new OrganizationJob();
organizationJob.setId(Long.valueOf(dept.getString("id")));
organizationJob.setJobName(dept.getString("departmentname"));
jobList.add(organizationJob);
}
organizationJobService.saveBatch(jobList);
}
return Result.success(null);
}
@ApiOperation(value = "获取人员数据进行同步", notes = "获取人员数据进行同步", httpMethod="POST")
@PostMapping(value = "/getUserData")
public Result<Map<String, Object>> getUserData(@RequestBody Map<String, Object> map) {
Map<String, Object> jsonParams = new HashMap<>();
Map<String, Object> params = new HashMap<>();
jsonParams.put("params", params);
String result = testRestful(ADDRESS, "/api/hrm/resful/getHrmUserInfoWithPage", JSONObject.toJSONString(jsonParams));
if (StringUtils.isNotBlank(result)) {
JSONObject obj = JSONObject.parseObject(result);
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("dataList");
List<SystemUser> userList = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject dept = jsonArray.getJSONObject(i);
SystemUser systemUser = new SystemUser();
systemUser.setUserId(Long.valueOf(dept.getString("id")));
systemUser.setAccount(dept.getString("loginid"));
systemUser.setRealName(dept.getString("lastname"));
systemUser.setJobId(Long.valueOf(dept.getString("departmentid")));
systemUser.setDepartment(dept.getString("jobtitle"));
userList.add(systemUser);
}
systemUserService.saveBatch(userList);
}
return Result.success(null);
}
private String testRestful(String address,String api,String jsonParams){
//ECOLOGY返回的token
String token= (String) redisRepository.get("JIUZHU_SERVER_TOKEN");
if (StrUtil.isEmpty(token)){
token = (String) testGetoken(address).get("token");
}
String spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY");
//封装请求头参数
RSA rsa = new RSA(null,spk);
//对用户信息进行加密传输,暂仅支持传输OA用户ID
String encryptUserid = rsa.encryptBase64("1",CharsetUtil.CHARSET_UTF_8,KeyType.PublicKey);
//调用ECOLOGY系统接口
String data = HttpRequest.post(address + api)
.header("appid",APPID)
.header("token",token)
.header("userid",encryptUserid)
.body(jsonParams)
.execute().body();
System.out.println("testRestful()"+data);
return data;
}
/**
* 第一步
*
* 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息
*/
private Map<String,Object> testRegist(String address){
//获取当前系统RSA加密的公钥
RSA rsa = new RSA();
String publicKey = rsa.getPublicKeyBase64();
String privateKey = rsa.getPrivateKeyBase64();
// 客户端RSA私钥
redisRepository.set("JIUZHU_LOCAL_PRIVATE_KEY",privateKey);
// 客户端RSA公钥
redisRepository.set("JIUZHU_LOCAL_PUBLIC_KEY",publicKey);
//调用ECOLOGY系统接口进行注册
String data = HttpRequest.post(address + "/api/ec/dev/auth/regist")
.header("appid",APPID)
.header("cpk",publicKey)
.timeout(2000)
.execute().body();
// 打印ECOLOGY响应信息
System.out.println("testRegist()"+data);
Map<String,Object> datas = JSONUtil.parseObj(data);
//ECOLOGY返回的系统公钥
redisRepository.set("JIUZHU_SERVER_PUBLIC_KEY", StrUtil.nullToEmpty((String)datas.get("spk")));
//ECOLOGY返回的系统密钥
redisRepository.set("JIUZHU_SERVER_SECRET",StrUtil.nullToEmpty((String)datas.get("secrit")));
return datas;
}
/**
* 第二步
*
* 通过第一步中注册系统返回信息进行获取token信息
*/
private Map<String,Object> testGetoken(String address){
// 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
String secret = (String) redisRepository.get("JIUZHU_SERVER_SECRET");
String spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY");
// 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
if (Objects.isNull(secret)||Objects.isNull(spk)){
testRegist(address);
// 重新获取最新ECOLOGY系统公钥和Secret信息
secret = (String) redisRepository.get("JIUZHU_SERVER_SECRET");
spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY");
}
// 公钥加密,所以RSA对象私钥为null
RSA rsa = new RSA(null,spk);
//对秘钥进行加密传输防止篡改数据
String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
//调用ECOLOGY系统接口进行注册
String data = HttpRequest.post(address+ "/api/ec/dev/auth/applytoken")
.header("appid",APPID)
.header("secret",encryptSecret)
.header("time","3600")
.execute().body();
System.out.println("testGetoken()"+data);
Map<String,Object> datas = JSONUtil.parseObj(data);
//ECOLOGY返回的token
// TODO 为Token缓存设置过期时间
redisRepository.set("JIUZHU_SERVER_TOKEN",StrUtil.nullToEmpty((String)datas.get("token")));
return datas;
}
}

View File

@ -0,0 +1,158 @@
package com.zhgd.xmgl.modules.basicdata.controller;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Token认证测试
*
* 认证过程主要采用RSA非对称加密算法
*
* @author tzf 2020/6/9
*/
public class MainTest {
/**
* 模拟缓存服务
*/
private static final Map<String,String> SYSTEM_CACHE = new HashMap <>();
/**
* ecology系统发放的授权许可证(appid)
*/
private static final String APPID = "991cefd2-0592-4734-8055-60ae8dd4005c";
public static void main(String[] args) {
Map<String, Object> jsonParams = new HashMap<>();
Map<String, Object> params = new HashMap<>();
// params.put("pagesize", 20);
// params.put("curpage", 1);
jsonParams.put("params", params);
testRestful("http://218.95.151.122:18000","/api/hrm/resful/getJobtitleInfoWithPage", JSONObject.toJSONString(jsonParams));
}
/**
* 第一步
*
* 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息
*/
public static Map<String,Object> testRegist(String address){
//获取当前系统RSA加密的公钥
RSA rsa = new RSA();
String publicKey = rsa.getPublicKeyBase64();
String privateKey = rsa.getPrivateKeyBase64();
// 客户端RSA私钥
SYSTEM_CACHE.put("LOCAL_PRIVATE_KEY",privateKey);
// 客户端RSA公钥
SYSTEM_CACHE.put("LOCAL_PUBLIC_KEY",publicKey);
//调用ECOLOGY系统接口进行注册
String data = HttpRequest.post(address + "/api/ec/dev/auth/regist")
.header("appid",APPID)
.header("cpk",publicKey)
.timeout(2000)
.execute().body();
// 打印ECOLOGY响应信息
System.out.println("testRegist()"+data);
Map<String,Object> datas = JSONUtil.parseObj(data);
//ECOLOGY返回的系统公钥
SYSTEM_CACHE.put("SERVER_PUBLIC_KEY",StrUtil.nullToEmpty((String)datas.get("spk")));
//ECOLOGY返回的系统密钥
SYSTEM_CACHE.put("SERVER_SECRET",StrUtil.nullToEmpty((String)datas.get("secrit")));
return datas;
}
/**
* 第二步
*
* 通过第一步中注册系统返回信息进行获取token信息
*/
public static Map<String,Object> testGetoken(String address){
// 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
String secret = SYSTEM_CACHE.get("SERVER_SECRET");
String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
// 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
if (Objects.isNull(secret)||Objects.isNull(spk)){
testRegist(address);
// 重新获取最新ECOLOGY系统公钥和Secret信息
secret = SYSTEM_CACHE.get("SERVER_SECRET");
spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
}
// 公钥加密,所以RSA对象私钥为null
RSA rsa = new RSA(null,spk);
//对秘钥进行加密传输防止篡改数据
String encryptSecret = rsa.encryptBase64(secret,CharsetUtil.CHARSET_UTF_8,KeyType.PublicKey);
//调用ECOLOGY系统接口进行注册
String data = HttpRequest.post(address+ "/api/ec/dev/auth/applytoken")
.header("appid",APPID)
.header("secret",encryptSecret)
.header("time","3600")
.execute().body();
System.out.println("testGetoken()"+data);
Map<String,Object> datas = JSONUtil.parseObj(data);
//ECOLOGY返回的token
// TODO 为Token缓存设置过期时间
SYSTEM_CACHE.put("SERVER_TOKEN",StrUtil.nullToEmpty((String)datas.get("token")));
return datas;
}
/**
* 第三步
*
* 调用ecology系统的rest接口请求头部带上token和用户标识认证信息
*
* @param address ecology系统地址
* @param api rest api 接口地址(该测试代码仅支持GET请求)
* @param jsonParams 请求参数json串
*
* 注意ECOLOGY系统所有POST接口调用请求头请设置 "Content-Type","application/x-www-form-urlencoded; charset=utf-8"
*/
public static String testRestful(String address,String api,String jsonParams){
//ECOLOGY返回的token
String token= SYSTEM_CACHE.get("SERVER_TOKEN");
if (StrUtil.isEmpty(token)){
token = (String) testGetoken(address).get("token");
}
String spk = SYSTEM_CACHE.get("SERVER_PUBLIC_KEY");
//封装请求头参数
RSA rsa = new RSA(null,spk);
//对用户信息进行加密传输,暂仅支持传输OA用户ID
String encryptUserid = rsa.encryptBase64("1",CharsetUtil.CHARSET_UTF_8,KeyType.PublicKey);
//调用ECOLOGY系统接口
String data = HttpRequest.post(address + api)
.header("appid",APPID)
.header("token",token)
.header("userid",encryptUserid)
.body(jsonParams)
.execute().body();
System.out.println("testRestful()"+data);
return data;
}
}

View File

@ -0,0 +1,106 @@
package com.zhgd.xmgl.modules.basicdata.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
import java.util.List;
/**
* @Description: 九柱-项目组织机构
* @author pds
* @date 2024-04-08
* @version V1.0
*/
@Data
@TableName("organization_dept")
@ApiModel(value = "OrganizationDept实体类", description = "OrganizationDept")
public class OrganizationDept implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(type = IdType.INPUT)
@ApiModelProperty(value = "id")
private Long id;
/**
* 父部门id
*/
@Excel(name = "父部门id", width = 15)
@ApiModelProperty(value = "父部门id")
private Long parentId;
/**
* 祖级列表
*/
@Excel(name = "祖级列表", width = 15)
@ApiModelProperty(value = "祖级列表")
private String ancestors;
/**
* 部门名称
*/
@Excel(name = "部门名称", width = 15)
@ApiModelProperty(value = "部门名称")
private String deptName;
/**
* 显示顺序
*/
@Excel(name = "显示顺序", width = 15)
@ApiModelProperty(value = "显示顺序")
private Integer orderNum;
/**
* 主管id
*/
@Excel(name = "主管id", width = 15)
@ApiModelProperty(value = "主管id")
private Long leader;
/**
* 联系电话
*/
@Excel(name = "联系电话", width = 15)
@ApiModelProperty(value = "联系电话")
private String phone;
/**
* 邮箱
*/
@Excel(name = "邮箱", width = 15)
@ApiModelProperty(value = "邮箱")
private String email;
/**
* 部门状态0正常 1停用
*/
@Excel(name = "部门状态0正常 1停用", width = 15)
@ApiModelProperty(value = "部门状态0正常 1停用")
private Integer status;
/**
* 创建时间 yyyy-MM-dd HH:mm:ss
*/
@Excel(name = "创建时间 yyyy-MM-dd HH:mm:ss", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建时间 yyyy-MM-dd HH:mm:ss")
private java.util.Date createTime;
/**
* 更新时间 yyyy-MM-dd HH:mm:ss
*/
@Excel(name = "更新时间 yyyy-MM-dd HH:mm:ss", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新时间 yyyy-MM-dd HH:mm:ss")
private java.util.Date updateTime;
private String projectSn;
@ApiModelProperty(value = "父级的对象")
private String parentObj;
@TableField(exist = false)
private List<OrganizationDept> children;
}

View File

@ -24,7 +24,7 @@ public class OrganizationJob implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**id*/ /**id*/
@TableId(type = IdType.ASSIGN_ID) @TableId(type = IdType.INPUT)
@ApiModelProperty(value="id") @ApiModelProperty(value="id")
private java.lang.Long id ; private java.lang.Long id ;
/**企业sn*/ /**企业sn*/

View File

@ -31,7 +31,7 @@ public class SystemUser implements Serializable {
* userId * userId
*/ */
@Excel(name = "userId", width = 15) @Excel(name = "userId", width = 15)
@TableId(type = IdType.ASSIGN_ID) @TableId(type = IdType.INPUT)
@ApiModelProperty(value = "userId") @ApiModelProperty(value = "userId")
private java.lang.Long userId; private java.lang.Long userId;
/** /**

View File

@ -0,0 +1,21 @@
package com.zhgd.xmgl.modules.basicdata.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wflow.bean.vo.OrgTreeVo;
import com.zhgd.xmgl.modules.basicdata.entity.OrganizationDept;
import com.zhgd.xmgl.modules.xz.entity.XzProjectOrg;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @Description: 星纵-项目组织机构
* @author pds
* @date 2024-04-08
* @version V1.0
*/
@Mapper
public interface OrganizationDeptMapper extends BaseMapper<OrganizationDept> {
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhgd.xmgl.modules.basicdata.mapper.OrganizationDeptMapper">
</mapper>

View File

@ -0,0 +1,19 @@
package com.zhgd.xmgl.modules.basicdata.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zhgd.xmgl.modules.basicdata.entity.OrganizationDept;
import com.zhgd.xmgl.modules.xz.entity.XzProjectOrg;
import java.util.HashMap;
import java.util.List;
/**
* @Description: 九柱-项目组织机构
* @author pds
* @date 2024-04-08
* @version V1.0
*/
public interface IOrganizationDeptService extends IService<OrganizationDept> {
}

View File

@ -0,0 +1,51 @@
package com.zhgd.xmgl.modules.basicdata.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wflow.bean.entity.WflowModels;
import com.wflow.mapper.WflowModelsMapper;
import com.zhgd.exception.CustomException;
import com.zhgd.jeecg.common.execption.OpenAlertException;
import com.zhgd.jeecg.common.system.query.QueryGenerator;
import com.zhgd.xmgl.modules.basicdata.entity.OrganizationDept;
import com.zhgd.xmgl.modules.basicdata.entity.SystemUser;
import com.zhgd.xmgl.modules.basicdata.mapper.OrganizationDeptMapper;
import com.zhgd.xmgl.modules.basicdata.mapper.SystemUserMapper;
import com.zhgd.xmgl.modules.basicdata.service.IOrganizationDeptService;
import com.zhgd.xmgl.modules.xz.entity.XzProjectOrg;
import com.zhgd.xmgl.modules.xz.mapper.XzProjectOrgMapper;
import com.zhgd.xmgl.modules.xz.service.IXzProjectOrgService;
import com.zhgd.xmgl.util.PageUtil;
import com.zhgd.xmgl.util.RefUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
* @Description: 九柱-项目组织机构
* @author pds
* @date 2024-04-08
* @version V1.0
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class OrganizationDeptServiceImpl extends ServiceImpl<OrganizationDeptMapper, OrganizationDept> implements IOrganizationDeptService {
}