feat(sync): 优化人资数据同步功能并增加异常处理

master
zhaokai 2026-06-18 14:21:42 +08:00
parent 2e80b8f2ee
commit 0d89472b71
36 changed files with 2369 additions and 48 deletions

View File

@ -36,3 +36,6 @@ archives:
queueCapacity: 60
namePrefix: async-task-
keepAliveSeconds: 60
humanresources:
appKey: A5EF205479D2DFB5E621E159AA8FF34B
appSecret: 53130AAAAC791D5B7AFD6D89C51853510190C903405242C49B83DECBBA0ADA5E

View File

@ -0,0 +1,42 @@
package com.zcloud.human.user.plan;
import com.jjb.saas.framework.job.Job;
import com.jjb.saas.framework.job.annotation.JobRegister;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.zcloud.human.user.command.HumanDeptSyncExe;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
*
*
*/
@RequiredArgsConstructor
@Component
@Slf4j
public class HumanCorpDepartmentSyncJob implements Job {
private final HumanDeptSyncExe humanDeptSyncExe;
@Override
// @JobRegister(cron = "0 30 0 * * ?", jobDesc = "人资部门数据同步任务开始",triggerStatus = 1)
@JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资部门全量数据同步任务开始",triggerStatus = 1)
@XxlJob("com.zcloud.human.user.plan.HumanCorpDepartmentSyncJob")
public ReturnT<String> execute(String param) {
XxlJobHelper.log("============人资部门数据同步任务开始==========");
try {
param = "test";
String result = humanDeptSyncExe.CorpDepartmentSync(param);
XxlJobHelper.log("同步结果:{}", result);
XxlJobHelper.log("============人资部门数据同步任务结束==========");
return new ReturnT<>(ReturnT.SUCCESS_CODE, result);
} catch (Exception e) {
XxlJobHelper.log("同步任务执行失败:{}", e.getMessage());
return new ReturnT<>(ReturnT.FAIL_CODE, "同步任务执行失败:" + e.getMessage());
}
}
}

View File

@ -0,0 +1,40 @@
package com.zcloud.human.user.plan;
import com.jjb.saas.framework.job.Job;
import com.jjb.saas.framework.job.annotation.JobRegister;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.zcloud.human.user.command.HumanUserSyncExe;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
*
*/
@RequiredArgsConstructor
@Component
@Slf4j
public class HumanCorpUserChangeSyncJob implements Job {
private final HumanUserSyncExe humanUserSyncExe;
@Override
// @JobRegister(cron = "0 30 0 * * ?", jobDesc = "人资部门数据同步任务开始",triggerStatus = 1)
@JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资用户变更数据同步任务开始",triggerStatus = 1)
@XxlJob("com.zcloud.human.user.plan.HumanCorpUserChangeSyncJob")
public ReturnT<String> execute(String param) {
XxlJobHelper.log("============人资人员变更数据同步任务开始==========");
try {
String result = humanUserSyncExe.CorpUserChangeSync(param);
XxlJobHelper.log("同步结果:{}", result);
XxlJobHelper.log("============人资人员变更数据同步任务结束==========");
return new ReturnT<>(ReturnT.SUCCESS_CODE, result);
} catch (Exception e) {
XxlJobHelper.log("人资人员变更数据同步任务执行失败:{}", e.getMessage());
return new ReturnT<>(ReturnT.FAIL_CODE, "人资人员变更数据同步任务执行失败:" + e.getMessage());
}
}
}

View File

@ -0,0 +1,41 @@
package com.zcloud.human.user.plan;
import com.jjb.saas.framework.job.Job;
import com.jjb.saas.framework.job.annotation.JobRegister;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.zcloud.human.user.command.HumanUserSyncExe;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
*
*/
@RequiredArgsConstructor
@Component
@Slf4j
public class HumanCorpUserSyncJob implements Job {
private final HumanUserSyncExe humanUserSyncExe;
@Override
// @JobRegister(cron = "0 30 0 * * ?", jobDesc = "人资部门数据同步任务开始",triggerStatus = 1)
@JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资用户全量同步任务开始new",triggerStatus = 1)
@XxlJob("com.zcloud.human.user.plan.HumanCorpUserSyncJob")
public ReturnT<String> execute(String param) {
XxlJobHelper.log("============人资人员数据同步任务开始==========");
try {
param = "test";
String result = humanUserSyncExe.CorpUserSync(param);
XxlJobHelper.log("同步结果:{}", result);
XxlJobHelper.log("============人资人员数据同步任务结束==========");
return new ReturnT<>(ReturnT.SUCCESS_CODE, result);
} catch (Exception e) {
XxlJobHelper.log("同步任务执行失败:{}", e.getMessage());
return new ReturnT<>(ReturnT.FAIL_CODE, "同步任务执行失败:" + e.getMessage());
}
}
}

View File

@ -11,7 +11,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
*
* ,
*
* @author zhaolei
* @Date 2026-06-02
@ -25,8 +25,8 @@ public class HumanDeptSyncJob implements Job {
@Override
// @JobRegister(cron = "0 30 0 * * ?", jobDesc = "人资部门数据同步任务开始",triggerStatus = 1)
@JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资部门数据同步任务开始",triggerStatus = 1)
@XxlJob("com.zcloud.human.user.plan.HumanDeptSyncJob")
// @JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资部门数据同步任务开始",triggerStatus = 1)
// @XxlJob("com.zcloud.human.user.plan.HumanDeptSyncJob")
public ReturnT<String> execute(String param) {
XxlJobHelper.log("============人资部门数据同步任务开始==========");

View File

@ -35,8 +35,8 @@ public class HumanUserDeptCompareSyncJob implements Job {
@Override
// @JobRegister(cron = "0 30 0 * * ?", jobDesc = "人资用户部门对比同步任务开始",triggerStatus = 1)
@JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资用户部门对比同步任务开始",triggerStatus = 1)
@XxlJob("com.zcloud.human.user.plan.HumanUserDeptCompareSyncJob")
// @JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资用户部门对比同步任务开始",triggerStatus = 1)
// @XxlJob("com.zcloud.human.user.plan.HumanUserDeptCompareSyncJob")
public ReturnT<String> execute(String param) {
XxlJobHelper.log("============人资用户部门对比同步任务开始==========");

View File

@ -28,12 +28,13 @@ public class HumanUserSyncJob implements Job {
@Override
// @JobRegister(cron = "0 30 0 * * ?", jobDesc = "人资人员数据同步任务开始",triggerStatus = 1)
@JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资人员数据同步任务开始",triggerStatus = 1)
@XxlJob("com.zcloud.human.user.plan.HumanUserSyncJob")
// @JobRegister(cron = "0 30 0 1 1 ?", jobDesc = "人资人员数据同步任务开始",triggerStatus = 1)
// @XxlJob("com.zcloud.human.user.plan.HumanUserSyncJob")
public ReturnT<String> execute(String param) {
XxlJobHelper.log("============人资人员数据同步任务开始==========");
try {
param = "test";
String result = humanUserSyncExe.execute(param);
XxlJobHelper.log("同步结果:{}", result);
XxlJobHelper.log("============人资人员数据同步任务结束==========");

View File

@ -0,0 +1,82 @@
package com.zcloud.human.user.web;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.jjb.saas.framework.auth.model.SSOUser;
import com.jjb.saas.framework.auth.utils.AuthContext;
import com.zcloud.human.user.api.HumanResourceCorpServiceI;
import com.zcloud.human.user.dto.HumanResourceCorpAddCmd;
import com.zcloud.human.user.dto.HumanResourceCorpPageQry;
import com.zcloud.human.user.dto.HumanResourceCorpUpdateCmd;
import com.zcloud.human.user.dto.clientobject.HumanResourceCorpCO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
/**
* web-adapter
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
@Api(tags = "人资企业部门信息")
@RequestMapping("/${application.gateway}/humanResourceCorp")
@RestController
@AllArgsConstructor
public class HumanResourceCorpController {
private final HumanResourceCorpServiceI humanResourceCorpService;
@ApiOperation("新增")
@PostMapping("/save")
public SingleResponse<HumanResourceCorpCO> add(@Validated @RequestBody HumanResourceCorpAddCmd cmd) {
SSOUser ssoUser = AuthContext.getCurrentUser();
return humanResourceCorpService.add(cmd);
}
@ApiOperation("分页")
@PostMapping("/list")
public PageResponse<HumanResourceCorpCO> page(@RequestBody HumanResourceCorpPageQry qry) {
return humanResourceCorpService.listPage(qry);
}
@ApiOperation("所有数据")
@GetMapping("/listAll")
public MultiResponse<HumanResourceCorpCO> listAll() {
return MultiResponse.of(new ArrayList<HumanResourceCorpCO>());
}
@ApiOperation("详情")
@GetMapping("/{id}")
public SingleResponse<HumanResourceCorpCO> getInfoById(@PathVariable("id") Long id) {
return SingleResponse.of(new HumanResourceCorpCO());
}
@ApiOperation("删除")
@DeleteMapping("/{id}")
public Response remove(@PathVariable("id") Long id) {
humanResourceCorpService.remove(id);
return SingleResponse.buildSuccess();
}
@ApiOperation("删除多个")
@DeleteMapping("/ids")
public Response removeBatch(@RequestParam Long[] ids) {
humanResourceCorpService.removeBatch(ids);
return SingleResponse.buildSuccess();
}
@ApiOperation("修改")
@PutMapping("/edit")
public SingleResponse edit(@Validated @RequestBody HumanResourceCorpUpdateCmd humanResourceCorpUpdateCmd) {
humanResourceCorpService.edit(humanResourceCorpUpdateCmd);
return SingleResponse.buildSuccess();
}
}

View File

@ -32,13 +32,20 @@ public class HumanUserController {
@PostMapping("/asyncSyncHumanUser")
public SingleResponse<String> asyncSyncHumanUser() {
log.info("开始同步用户信息");
asyncSyncService.asyncSyncHumanUser("manual");
asyncSyncService.asyncSyncHumanUser("test");
return SingleResponse.of("用户同步任务已提交,请查看日志了解进度");
}
@ApiOperation("同步用户信息-手动调用定时任务")
@PostMapping("/asyncSyncUserChange")
public SingleResponse<String> asyncSyncUserChange() {
log.info("开始同步用户变更信息");
asyncSyncService.asyncSyncUserChange("test");
return SingleResponse.of("同步用户变更已提交,请查看日志了解进度");
}
/**
/* *//**
*
*/
*//*
@ApiOperation("同步部门信息-手动调用定时任务")
@PostMapping("/asyncSyncHumanDept")
public SingleResponse<String> asyncSyncHumanDept() {
@ -47,15 +54,15 @@ public class HumanUserController {
return SingleResponse.of("部门同步任务已提交,请查看日志了解进度");
}
/**
*//**
*
*/
*//*
@ApiOperation("部门对比-手动调用定时任务")
@PostMapping("/asyncSyncDeptCompare")
public SingleResponse<String> asyncSyncDeptCompare() {
log.info("开始部门对比同步");
asyncSyncService.asyncSyncDeptCompare("manual");
return SingleResponse.of("部门对比同步任务已提交,请查看日志了解进度");
}
}*/
}

View File

@ -2,23 +2,35 @@ package com.zcloud.human.user.command;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.gbscommon.utils.Tools;
import com.zcloud.gbscommon.zcloudcorp.face.ZcloudCorpFacade;
import com.zcloud.gbscommon.zcloudcorp.response.ZcloudCorpInfoCO;
import com.zcloud.gbscommon.zclouddepartment.face.ZcloudDepartmentFacade;
import com.zcloud.gbscommon.zclouddepartment.request.ZcloudDepartmentAddCmd;
import com.zcloud.gbscommon.zclouddepartment.response.ZcloudDepartmentInfoCo;
import com.zcloud.human.user.config.HumanResourcesConfig;
import com.zcloud.human.user.domain.utils.SignUtil;
import com.zcloud.human.user.persistence.dataobject.HumanResourceCorpDO;
import com.zcloud.human.user.persistence.repository.HumanResourceCorpRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
*
@ -49,12 +61,36 @@ public class HumanDeptSyncExe {
*/
private static final String USER_INFO_URL = "http://192.168.10.56:8090";
/**
*
*/
private static final String HUMAN_RESOURCE_DEPT_URL = "https://192.168.195.249:28001/idatashare/api/remoteCall/v1/1057031106228944896";
/**
*
*/
private static final String HUMAN_RESOURCE_DEPT_API_ID = "1057031106228944896";
/**
*
*/
private static final int HUMAN_RESOURCE_DEPT_PAGE_SIZE = 1000;
/**
*
*/
private static final String HUMAN_RESOURCE_DEPT_TEST_FLAG = "test";
@DubboReference
private ZcloudDepartmentFacade zcloudDepartmentFacade;
@DubboReference
private ZcloudCorpFacade zcloudCorpFacade;
private final HumanResourceCorpRepository humanResourceCorpRepository;
private final HumanResourcesConfig humanResourcesConfig;
private final JSONConfig jsonConfig = JSONConfig.create().setIgnoreNullValue(true);
/**
*
*
@ -70,6 +106,11 @@ public class HumanDeptSyncExe {
log.warn("本系统不存在公司:{},终止同步", SYSTEM_CORP_NAME);
return "同步终止:本系统不存在公司" + SYSTEM_CORP_NAME;
}
Long gbsRootDeptId = findGbsRootDeptId(corpId);
if (gbsRootDeptId == null) {
log.warn("本系统公司:{} 下没有根部门,终止同步", SYSTEM_CORP_NAME);
return "同步终止:本系统公司" + SYSTEM_CORP_NAME + "下没有根部门";
}
String result = "";
if("manual".equals(param)){
@ -83,11 +124,6 @@ public class HumanDeptSyncExe {
return "同步终止:未找到公司" + SYSTEM_CORP_NAME + "的部门数据";
}
Long gbsRootDeptId = findGbsRootDeptId(corpId);
if (gbsRootDeptId == null) {
log.warn("本系统公司:{} 下没有根部门,终止同步", SYSTEM_CORP_NAME);
return "同步终止:本系统公司" + SYSTEM_CORP_NAME + "下没有根部门";
}
JSONArray children = rootDept.getJSONArray("children");
if (children == null || children.isEmpty()) {
@ -393,4 +429,249 @@ public class HumanDeptSyncExe {
"\t}]\n" +
"}";
}
@Transactional(rollbackFor = Exception.class)
public String CorpDepartmentSync(String param) {
log.info("============开始同步人资企业部门本地数据==========");
JSONArray sourceRows = pullAllCorpDepartmentRows(param);
if (sourceRows.isEmpty()) {
log.info("未获取到人资企业部门数据");
return "同步完成:未获取到人资企业部门数据";
}
List<HumanResourceCorpDO> corpList = buildHumanResourceCorpList(sourceRows);
if (corpList.isEmpty()) {
log.info("未解析到有效的人资企业部门数据");
return "同步完成:未解析到有效的人资企业部门数据";
}
humanResourceCorpRepository.replaceAll(corpList);
String message = String.format("同步完成:拉取 %d 条原始部门数据,落库 %d 条本地记录", sourceRows.size(), corpList.size());
log.info(message);
log.info("============结束同步人资企业部门本地数据==========");
return message;
}
private JSONArray pullAllCorpDepartmentRows(String param) {
if (useTestCorpDepartmentData(param)) {
log.info("人资企业部门同步使用测试JSON数据param={}", param);
return getTestCorpDepartmentRows();
}
JSONArray allRows = new JSONArray();
int pageNum = 1;
while (true) {
JSONArray pageRows = pullCorpDepartmentPage(pageNum);
if (pageRows.isEmpty()) {
break;
}
allRows.addAll(pageRows);
log.info("人资企业部门接口第 {} 页返回 {} 条数据", pageNum, pageRows.size());
if (pageRows.size() < HUMAN_RESOURCE_DEPT_PAGE_SIZE) {
break;
}
pageNum++;
}
return allRows;
}
private boolean useTestCorpDepartmentData(String param) {
return param != null && HUMAN_RESOURCE_DEPT_TEST_FLAG.equalsIgnoreCase(param.trim());
}
private JSONArray pullCorpDepartmentPage(int pageNum) {
SignUtil signUtil = buildSignUtil(pageNum);
JSONObject requestBody = buildCorpDepartmentRequest(signUtil);
log.info("开始调用人资企业部门接口,第 {} 页", pageNum);
String body = HttpRequest.post(HUMAN_RESOURCE_DEPT_URL)
.timeout(30000)
.header("Content-Type", "application/json")
.body(requestBody.toString())
.execute()
.body();
if (StringUtils.isEmpty(body)) {
log.warn("人资企业部门接口第 {} 页返回空响应", pageNum);
return new JSONArray();
}
JSONObject returnJson = JSONUtil.parseObj(body, jsonConfig);
Object bo = returnJson.get("bo");
if (bo == null) {
log.warn("人资企业部门接口第 {} 页未返回 bo 节点,响应:{}", pageNum, body);
return new JSONArray();
}
JSONObject boJson = JSONUtil.parseObj(bo);
Object rows = boJson.get("rows");
if (rows == null) {
return new JSONArray();
}
return JSONUtil.parseArray(rows);
}
private SignUtil buildSignUtil(int pageNum) {
SignUtil signUtil = new SignUtil();
signUtil.setAppKey(getAppKey());
signUtil.setAppSecret(getAppSecret());
signUtil.setEnvType("online");
signUtil.setPageNum(pageNum);
signUtil.setPageSize(HUMAN_RESOURCE_DEPT_PAGE_SIZE);
signUtil.setNonce(RandomStringUtils.randomAlphanumeric(5));
signUtil.setTimeStamp(System.currentTimeMillis());
signUtil.setParamMap(new HashMap<>());
signUtil.setOrderByList(new ArrayList<>());
signUtil.buildSignatureParam();
return signUtil;
}
private JSONObject buildCorpDepartmentRequest(SignUtil signUtil) {
String signature = SignUtil.getSignature(signUtil.getSignatureParam());
return new JSONObject()
.set("appKey", getAppKey())
.set("timeStamp", signUtil.getTimeStamp())
.set("nonce", signUtil.getNonce())
.set("signature", signature)
.set("signatureParam", null)
.set("apiid", HUMAN_RESOURCE_DEPT_API_ID)
.set("pageNum", signUtil.getPageNum())
.set("pageSize", signUtil.getPageSize())
.set("paramMap", signUtil.getParamMap())
.set("orderByList", signUtil.getOrderByList())
.set("hasTotal", "Y")
.set("envType", signUtil.getEnvType())
.set("empNo", "10262589")
.set("invokeLogId", null)
.set("versionType", "published")
.set("sdkType", "JAVA")
.set("sdkVersion", "1.0.13")
.set("accessIp", null);
}
private List<HumanResourceCorpDO> buildHumanResourceCorpList(JSONArray sourceRows) {
List<HumanResourceCorpDO> corpList = new ArrayList<>();
Set<String> deptCodeSet = new LinkedHashSet<>();
collectHumanResourceCorp(sourceRows, corpList, deptCodeSet);
return corpList;
}
private void collectHumanResourceCorp(JSONArray jsonArray, List<HumanResourceCorpDO> corpList, Set<String> deptCodeSet) {
for (Object item : jsonArray) {
collectHumanResourceCorp(JSONUtil.parseObj(item), corpList, deptCodeSet);
}
}
private void collectHumanResourceCorp(JSONObject jsonObject, List<HumanResourceCorpDO> corpList, Set<String> deptCodeSet) {
if (jsonObject == null) {
return;
}
String deptCode = jsonObject.getStr("dept_code");
if (StringUtils.isNotEmpty(deptCode) && deptCodeSet.add(deptCode)) {
corpList.add(buildHumanResourceCorpDO(jsonObject));
}
JSONArray children = jsonObject.getJSONArray("children");
if (children == null || children.isEmpty()) {
return;
}
collectHumanResourceCorp(children, corpList, deptCodeSet);
}
private HumanResourceCorpDO buildHumanResourceCorpDO(JSONObject jsonObject) {
HumanResourceCorpDO corpDO = new HumanResourceCorpDO();
corpDO.setHumanResourceCorpId(Tools.get32UUID());
corpDO.setCorpinfoId(resolveCorpinfoId(jsonObject));
corpDO.setCorporationCode(jsonObject.getStr("corporation_code"));
corpDO.setCorporationName(jsonObject.getStr("corporation_name"));
corpDO.setDeptName(jsonObject.getStr("dept_name"));
corpDO.setDeptCode(jsonObject.getStr("dept_code"));
corpDO.setDeptLevel(jsonObject.getStr("dept_level"));
corpDO.setDeptCodePath(jsonObject.getStr("dept_code_path"));
corpDO.setSuperiorOrganizationCode(jsonObject.getStr("superior_organization_code"));
return corpDO;
}
private String resolveCorpinfoId(JSONObject jsonObject) {
String corporationCode = jsonObject.getStr("corporation_code");
if (StringUtils.isNotEmpty(corporationCode)) {
return corporationCode;
}
return jsonObject.getStr("dept_code");
}
private JSONArray getTestCorpDepartmentRows() {
return JSONUtil.parseArray("[\n" +
" {\n" +
" \"corporation_code\": \"7f304de353c358egcfg267f023db8f25\",\n" +
" \"corporation_name\": \"河港集团\",\n" +
" \"dept_name\": \"子公司\",\n" +
" \"dept_code\": \"28bd895f27934aa7a9acf665d73ead8d\",\n" +
" \"dept_level\": \"1\",\n" +
" \"dept_code_path\": \"7f304de353c358egcfg267f023db8f25-28bd895f27934aa7a9acf665d73ead8d\",\n" +
" \"superior_organization_code\": \"7f304de353c358egcfg267f023db8f25\",\n" +
" \"children\": [\n" +
" {\n" +
" \"corporation_code\": \"fa91e56b6d0a47ee8e9d42a75cd97ed4\",\n" +
" \"corporation_name\": \"曹妃甸矿石储运\",\n" +
" \"dept_name\": \"曹妃甸矿石储运\",\n" +
" \"dept_code\": \"fa91e56b6d0a47ee8e9d42a75cd97ed4\",\n" +
" \"dept_level\": \"2\",\n" +
" \"dept_code_path\": \"7f304de353c358egcfg267f023db8f25-28bd895f27934aa7a9acf665d73ead8d-fa91e56b6d0a47ee8e9d42a75cd97ed4\",\n" +
" \"superior_organization_code\": \"28bd895f27934aa7a9acf665d73ead8d\",\n" +
" \"children\": [\n" +
" {\n" +
" \"corporation_code\": \"fa91e56b6d0a47ee8e9d42a75cd97ed4\",\n" +
" \"corporation_name\": \"曹妃甸矿石储运\",\n" +
" \"dept_name\": \"机关\",\n" +
" \"dept_code\": \"f96c45159b994489adf79a4ab92ac5cc\",\n" +
" \"dept_level\": \"3\",\n" +
" \"dept_code_path\": \"7f304de353c358egcfg267f023db8f25-28bd895f27934aa7a9acf665d73ead8d-fa91e56b6d0a47ee8e9d42a75cd97ed4-f96c45159b994489adf79a4ab92ac5cc\",\n" +
" \"superior_organization_code\": \"fa91e56b6d0a47ee8e9d42a75cd97ed4\",\n" +
" \"children\": [\n" +
" {\n" +
" \"corporation_code\": \"fa91e56b6d0a47ee8e9d42a75cd97ed4\",\n" +
" \"corporation_name\": \"曹妃甸矿石储运\",\n" +
" \"dept_name\": \"综合办公室\",\n" +
" \"dept_code\": \"9ba0f0faada74c18afb81d38e9fb6d24\",\n" +
" \"dept_level\": \"4\",\n" +
" \"dept_code_path\": \"7f304de353c358egcfg267f023db8f25-28bd895f27934aa7a9acf665d73ead8d-fa91e56b6d0a47ee8e9d42a75cd97ed4-f96c45159b994489adf79a4ab92ac5cc-9ba0f0faada74c18afb81d38e9fb6d24\",\n" +
" \"superior_organization_code\": \"f96c45159b994489adf79a4ab92ac5cc\",\n" +
" \"children\": []\n" +
" },\n" +
" {\n" +
" \"corporation_code\": \"fa91e56b6d0a47ee8e9d42a75cd97ed4\",\n" +
" \"corporation_name\": \"曹妃甸矿石储运\",\n" +
" \"dept_name\": \"财务部\",\n" +
" \"dept_code\": \"3ad24f7af17e4b149b693641e5d29ed3\",\n" +
" \"dept_level\": \"4\",\n" +
" \"dept_code_path\": \"7f304de353c358egcfg267f023db8f25-28bd895f27934aa7a9acf665d73ead8d-fa91e56b6d0a47ee8e9d42a75cd97ed4-f96c45159b994489adf79a4ab92ac5cc-3ad24f7af17e4b149b693641e5d29ed3\",\n" +
" \"superior_organization_code\": \"f96c45159b994489adf79a4ab92ac5cc\",\n" +
" \"children\": []\n" +
" }\n" +
" ]\n" +
" }\n" +
" ]\n" +
" },\n" +
" {\n" +
" \"corporation_code\": \"06414841dcf64b5e82673f561bef2b63\",\n" +
" \"corporation_name\": \"东方石油\",\n" +
" \"dept_name\": \"东方石油\",\n" +
" \"dept_code\": \"06414841dcf64b5e82673f561bef2b63\",\n" +
" \"dept_level\": \"2\",\n" +
" \"dept_code_path\": \"7f304de353c358egcfg267f023db8f25-28bd895f27934aa7a9acf665d73ead8d-06414841dcf64b5e82673f561bef2b63\",\n" +
" \"superior_organization_code\": \"28bd895f27934aa7a9acf665d73ead8d\",\n" +
" \"children\": []\n" +
" }\n" +
" ]\n" +
" }\n" +
"]");
}
private String getAppKey() {
return humanResourcesConfig.getAppKey();
}
private String getAppSecret() {
return humanResourcesConfig.getAppSecret();
}
}

View File

@ -0,0 +1,40 @@
package com.zcloud.human.user.command;
import com.alibaba.cola.exception.BizException;
import com.zcloud.human.user.domain.gateway.HumanResourceCorpGateway;
import com.zcloud.human.user.domain.model.HumanResourceCorpE;
import com.zcloud.human.user.dto.HumanResourceCorpAddCmd;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* web-app
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
@Component
@AllArgsConstructor
public class HumanResourceCorpAddExe {
private final HumanResourceCorpGateway humanResourceCorpGateway;
@Transactional(rollbackFor = Exception.class)
public boolean execute(HumanResourceCorpAddCmd cmd) {
HumanResourceCorpE humanResourceCorpE = new HumanResourceCorpE();
BeanUtils.copyProperties(cmd, humanResourceCorpE);
boolean res = false;
try {
res = humanResourceCorpGateway.add(humanResourceCorpE);
} catch (Exception e) {
throw new RuntimeException(e);
}
if (!res) {
throw new BizException("保存失败");
}
return true;
}
}

View File

@ -0,0 +1,39 @@
package com.zcloud.human.user.command;
import com.alibaba.cola.exception.BizException;
import com.zcloud.human.user.domain.gateway.HumanResourceCorpGateway;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* web-app
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
@Component
@AllArgsConstructor
public class HumanResourceCorpRemoveExe {
private final HumanResourceCorpGateway humanResourceCorpGateway;
@Transactional(rollbackFor = Exception.class)
public boolean execute(Long id) {
boolean res = humanResourceCorpGateway.deletedHumanResourceCorpById(id);
if (!res) {
throw new BizException("删除失败");
}
return true;
}
@Transactional(rollbackFor = Exception.class)
public boolean execute(Long[] ids) {
boolean res = humanResourceCorpGateway.deletedHumanResourceCorpByIds(ids);
if (!res) {
throw new BizException("删除失败");
}
return true;
}
}

View File

@ -0,0 +1,34 @@
package com.zcloud.human.user.command;
import com.alibaba.cola.exception.BizException;
import com.zcloud.human.user.domain.gateway.HumanResourceCorpGateway;
import com.zcloud.human.user.domain.model.HumanResourceCorpE;
import com.zcloud.human.user.dto.HumanResourceCorpUpdateCmd;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
/**
* web-app
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
@Component
@AllArgsConstructor
public class HumanResourceCorpUpdateExe {
private final HumanResourceCorpGateway humanResourceCorpGateway;
@Transactional(rollbackFor = Exception.class)
public void execute(HumanResourceCorpUpdateCmd humanResourceCorpUpdateCmd) {
HumanResourceCorpE humanResourceCorpE = new HumanResourceCorpE();
BeanUtils.copyProperties(humanResourceCorpUpdateCmd, humanResourceCorpE);
boolean res = humanResourceCorpGateway.update(humanResourceCorpE);
if (!res) {
throw new BizException("修改失败");
}
}
}

View File

@ -2,38 +2,49 @@ package com.zcloud.human.user.command;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONConfig;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.cola.dto.MultiResponse;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.jjb.saas.system.client.role.facade.RoleFacade;
import com.jjb.saas.system.client.role.response.RoleCO;
import com.jjb.saas.system.client.user.facade.UserFacade;
import com.jjb.saas.system.client.user.request.RoleDeptAddCmd;
import com.jjb.saas.system.client.user.request.UserAddCmd;
import com.jjb.saas.system.client.user.response.UserCO;
import com.jjb.saas.system.client.user.response.UserDetailCO;
import com.jjb.saas.system.client.user.response.UserRoleDeptCO;
import com.zcloud.gbscommon.zcloudcorp.face.ZcloudCorpFacade;
import com.zcloud.gbscommon.zcloudcorp.response.ZcloudCorpInfoCO;
import com.zcloud.gbscommon.zclouddepartment.face.ZcloudDepartmentFacade;
import com.zcloud.gbscommon.zclouddepartment.request.ZcloudDepartmentPageQry;
import com.zcloud.gbscommon.zclouddepartment.response.ZcloudDepartmentInfoCo;
import com.zcloud.gbscommon.zclouduser.facade.ZcloudUserFacade;
import com.zcloud.gbscommon.zclouduser.request.ZcloudUserAddCmd;
import com.zcloud.gbscommon.zclouduser.request.ZcloudUserInfoQry;
import com.zcloud.gbscommon.zclouduser.request.ZcloudUserUpdateCmd;
import com.zcloud.gbscommon.zclouduser.response.ZcloudUserCo;
import com.zcloud.human.user.config.HumanResourcesConfig;
import com.zcloud.human.user.domain.enums.UserEmploymentFlagEnum;
import com.zcloud.human.user.domain.gateway.HumanUserGateway;
import com.zcloud.human.user.domain.gateway.HumanUserRecordGateway;
import com.zcloud.human.user.domain.model.HumanUserE;
import com.zcloud.human.user.domain.model.HumanUserRecordE;
import com.zcloud.human.user.domain.utils.SignUtil;
import com.zcloud.human.user.persistence.dataobject.HumanUserDO;
import com.zcloud.human.user.persistence.repository.HumanUserRepository;
import jodd.util.Base64;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
/**
*
@ -51,7 +62,8 @@ public class HumanUserSyncExe {
/**
* ID
*/
private static final String SYSTEM_CORP_NAME = "秦皇岛港股份有限公司";
// private static final String SYSTEM_CORP_NAME = "秦皇岛港股份有限公司";
private static final String SYSTEM_CORP_NAME = "卓云企业";
/**
*
@ -63,8 +75,36 @@ public class HumanUserSyncExe {
*/
private static final String USER_INFO_URL = "http://192.168.10.56:8090";
@DubboReference
private UserFacade userFacade;
/**
*
*/
private static final String HUMAN_RESOURCE_USER_URL = "https://192.168.195.249:28001/idatashare/api/remoteCall/v1/1057412621613957120";
/**
*
*/
private static final String HUMAN_RESOURCE_USER_API_ID = "1057412621613957120";
/**
*
*/
private static final int HUMAN_RESOURCE_USER_PAGE_SIZE = 50;
/**
*
*/
private static final String HUMAN_RESOURCE_USER_TEST_FLAG = "test";
/**
*
*/
private static final String HUMAN_RESOURCE_USER_CHANGE_URL = "https://192.168.195.249:28001/idatashare/api/remoteCall/v1/1057031732824408064";
/**
*
*/
private static final String HUMAN_RESOURCE_USER_CHANGE_API_ID = "1057031732824408064";
@DubboReference
private RoleFacade roleFacade;
@ -77,9 +117,16 @@ public class HumanUserSyncExe {
@DubboReference
private ZcloudCorpFacade zcloudCorpFacade;
@DubboReference
private ZcloudDepartmentFacade zcloudDepartmentFacade;
private final HumanUserGateway humanUserGateway;
private final HumanUserRepository humanUserRepository;
private final HumanUserRecordGateway humanUserRecordGateway;
private final HumanResourcesConfig humanResourcesConfig;
private final JSONConfig jsonConfig = JSONConfig.create().setIgnoreNullValue(true);
/**
*
@ -91,7 +138,7 @@ public class HumanUserSyncExe {
public String execute(String param) {
log.info("============获取人资全量人员信息开始==========");
Long corpId = getTargetCorpId();
Long corpId = getTargetCorpId(SYSTEM_CORP_NAME);
if (corpId == null) {
log.warn("本系统不存在公司:{},终止同步", SYSTEM_CORP_NAME);
return "同步终止:本系统不存在公司" + SYSTEM_CORP_NAME;
@ -104,7 +151,7 @@ public class HumanUserSyncExe {
}
String result = "";
if("manual".equals(param)){
if("test".equals(param)){
result = getSimulationData();
}else{
result = getUserInfo();
@ -150,20 +197,20 @@ public class HumanUserSyncExe {
// TODO 岗位留白
if (StringUtils.isEmpty(employeeName) || StringUtils.isEmpty(corporationName) || StringUtils.isEmpty(deptName)) {
log.warn("跳过无效人员数据:公司、部门或姓名为空,原始数据:{}", jsonObject);
log.info("跳过无效人员数据:公司、部门或姓名为空,原始数据:{}", jsonObject);
skipCount++;
continue;
}
if (!TARGET_CORP_NAME.equals(corporationName)) {
log.debug("跳过非目标公司人员:{},公司:{}", employeeName, corporationName);
if (!SYSTEM_CORP_NAME.equals(corporationName)) {
log.info("跳过非目标公司人员:{},公司:{}", employeeName, corporationName);
skipCount++;
continue;
}
Long deptId = deptNameIdMap.get(deptName);
if (deptId == null) {
log.warn("跳过人员:{},本系统公司:{} 下不存在部门:{}", employeeName, SYSTEM_CORP_NAME, deptName);
log.info("跳过人员:{},本系统公司:{} 下不存在部门:{}", employeeName, SYSTEM_CORP_NAME, deptName);
skipCount++;
continue;
}
@ -194,13 +241,15 @@ public class HumanUserSyncExe {
continue;
}
// 步骤3判断统一用户管理(user表)是否存在该人员
Long existingUserId = isUserExists(deptId, employeeName);
// Long existingUserId = isUserExists(deptId, Base64.encodeToString(idCardNumber), null);
Long existingUserId = null;
log.info("统一用户管理已存在人员:{}用户ID{}", employeeName, existingUserId);
if (existingUserId != null) {
// 人员不存在于human_user表保存新人资用户
HumanUserE newHumanUser = buildHumanUser(jsonObject);
newHumanUser.setUserId(existingUserId);
humanUserGateway.add(newHumanUser);
log.debug("保存人资用户表:{},身份证号:{}", employeeName, idCardNumber);
log.info("保存人资用户表:{},身份证号:{}", employeeName, idCardNumber);
// 统一用户已存在保存变动记录关联已存在的用户ID
log.info("统一用户管理已存在人员:{}用户ID{},保存变动记录", employeeName, existingUserId);
HumanUserRecordE record = buildHumanUserRecord(jsonObject, existingUserId);
@ -214,7 +263,7 @@ public class HumanUserSyncExe {
HumanUserE newHumanUser = buildHumanUser(jsonObject);
newHumanUser.setUserId(newUserId);
humanUserGateway.add(newHumanUser);
log.debug("新增统一用户管理账号成功:{},身份证号:{}用户ID{}", employeeName, idCardNumber, newUserId);
log.info("新增统一用户管理账号成功:{},身份证号:{}用户ID{}", employeeName, idCardNumber, newUserId);
// 保存变动记录关联新创建的用户ID
HumanUserRecordE record = buildHumanUserRecord(jsonObject, newUserId);
humanUserRecordGateway.add(record);
@ -284,13 +333,13 @@ public class HumanUserSyncExe {
/**
* ID
*/
private Long getTargetCorpId() {
private Long getTargetCorpId(String corpName) {
MultiResponse<ZcloudCorpInfoCO> response = zcloudCorpFacade.getCorpList();
if (response == null || !response.isSuccess() || response.getData() == null) {
return null;
}
return response.getData().stream()
.filter(corp -> SYSTEM_CORP_NAME.equals(corp.getCorpName()))
.filter(corp -> corpName.equals(corp.getCorpName()))
.map(ZcloudCorpInfoCO::getId)
.findFirst()
.orElse(null);
@ -303,14 +352,18 @@ public class HumanUserSyncExe {
* @return ID
*/
private Map<String, Long> getTargetCorpDeptNameIdMap(Long corpId) {
MultiResponse<ZcloudDepartmentInfoCo> response = deptFacade.getDeptList();
if (response == null || !response.isSuccess() || response.getData() == null) {
ZcloudDepartmentPageQry qry = new ZcloudDepartmentPageQry();
qry.setEqCorpInfoId(corpId);
qry.setEqParentId(corpId);
qry.setPageSize(10000);
PageResponse<ZcloudDepartmentInfoCo> zcloudDepartmentInfoCoPageResponse = zcloudDepartmentFacade.pageByParentId(qry);
if (zcloudDepartmentInfoCoPageResponse == null || !zcloudDepartmentInfoCoPageResponse.isSuccess() || zcloudDepartmentInfoCoPageResponse.getData() == null) {
log.warn("获取部门列表失败");
return Collections.emptyMap();
}
Map<String, Long> result = new HashMap<>();
for (ZcloudDepartmentInfoCo dept : response.getData()) {
for (ZcloudDepartmentInfoCo dept : zcloudDepartmentInfoCoPageResponse.getData()) {
if (corpId.equals(dept.getCorpinfoId())) {
result.put(dept.getName(), dept.getId());
log.debug("找到企业[{}]下的部门:{} (ID: {})", corpId, dept.getName(), dept.getId());
@ -324,18 +377,20 @@ public class HumanUserSyncExe {
/**
* IDID
*
* @param deptId ID
* @param employeeName
* @param phoneNumber
* @return IDnull
*/
private Long isUserExists(Long deptId, String employeeName) {
MultiResponse<UserCO> response = userFacade.listByOrgId(deptId);
private Long isUserExists(String idCardNumber, String phoneNumber) {
ZcloudUserInfoQry qry = new ZcloudUserInfoQry();
qry.setUserIdCard(idCardNumber);
qry.setPhone(phoneNumber);
MultiResponse<ZcloudUserCo> response = zcloudUserFacade.listUserByInfo(qry);
if (response == null || !response.isSuccess() || response.getData() == null) {
return null;
}
return response.getData().stream()
.filter(user -> employeeName.equals(user.getName()))
.map(UserCO::getId)
.filter(user -> idCardNumber.equals(user.getUserIdCard()))
.map(ZcloudUserCo::getId)
.findFirst()
.orElse(null);
}
@ -423,6 +478,7 @@ public class HumanUserSyncExe {
humanUserE.initFromJson(jsonObject);
humanUserE.setCreateTime(LocalDateTime.now());
humanUserE.setUpdateTime(LocalDateTime.now());
humanUserE.setDeleteEnum("FALSE");
return humanUserE;
}
@ -437,6 +493,8 @@ public class HumanUserSyncExe {
HumanUserRecordE recordE = new HumanUserRecordE();
recordE.initFromJson(jsonObject);
recordE.setUserId(userId);
recordE.setCreateTime(LocalDateTime.now());
recordE.setUpdateTime(LocalDateTime.now());
return recordE;
}
@ -484,4 +542,557 @@ public class HumanUserSyncExe {
"\t}\n" +
"]";
}
@Transactional(rollbackFor = Exception.class)
public String CorpUserSync(String param) {
log.info("============开始同步人资人员本地数据==========");
JSONArray sourceRows = pullAllCorpUserRows(param);
if (sourceRows.isEmpty()) {
log.info("未获取到人资人员数据");
return "同步完成:未获取到人资人员数据";
}
int[] saveResult = saveCorpUserRows(sourceRows);
String message = String.format("同步完成:拉取 %d 条原始人员数据,新增 %d 条,更新 %d 条,跳过 %d 条",
sourceRows.size(), saveResult[0], saveResult[1], saveResult[2]);
log.info(message);
log.info("============结束同步人资人员本地数据==========");
return message;
}
private JSONArray pullAllCorpUserRows(String param) {
if (useTestCorpUserData(param)) {
log.info("人资人员同步使用测试JSON数据param={}", param);
return getTestCorpUserRows();
}
JSONArray allRows = new JSONArray();
int pageNum = 1;
while (true) {
JSONArray pageRows = pullCorpUserPage(pageNum);
if (pageRows.isEmpty()) {
break;
}
allRows.addAll(pageRows);
log.info("人资人员接口第 {} 页返回 {} 条数据", pageNum, pageRows.size());
if (pageRows.size() < HUMAN_RESOURCE_USER_PAGE_SIZE) {
break;
}
pageNum++;
}
return allRows;
}
private boolean useTestCorpUserData(String param) {
return param != null && HUMAN_RESOURCE_USER_TEST_FLAG.equalsIgnoreCase(param.trim());
}
private JSONArray pullCorpUserPage(int pageNum) {
SignUtil signUtil = buildUserSignUtil(pageNum);
JSONObject requestBody = buildCorpUserRequest(signUtil);
log.info("开始调用人资人员接口,第 {} 页", pageNum);
String body = HttpRequest.post(HUMAN_RESOURCE_USER_URL)
.timeout(30000)
.header("Content-Type", "application/json")
.body(requestBody.toString())
.execute()
.body();
if (StringUtils.isEmpty(body)) {
log.warn("人资人员接口第 {} 页返回空响应", pageNum);
return new JSONArray();
}
JSONObject returnJson = JSONUtil.parseObj(body, jsonConfig);
String code = returnJson.getStr("code");
if (StringUtils.isNotEmpty(code) && !"0000".equals(code)) {
log.warn("人资人员接口第 {} 页返回失败code={},响应={}", pageNum, code, body);
return new JSONArray();
}
Object bo = returnJson.get("bo");
if (bo == null) {
log.warn("人资人员接口第 {} 页未返回 bo 节点,响应:{}", pageNum, body);
return new JSONArray();
}
JSONObject boJson = JSONUtil.parseObj(bo);
Object rows = boJson.get("rows");
if (rows == null) {
return new JSONArray();
}
return JSONUtil.parseArray(rows);
}
private SignUtil buildUserSignUtil(int pageNum) {
SignUtil signUtil = new SignUtil();
signUtil.setAppKey(getAppKey());
signUtil.setAppSecret(getAppSecret());
signUtil.setEnvType("online");
signUtil.setPageNum(pageNum);
signUtil.setPageSize(HUMAN_RESOURCE_USER_PAGE_SIZE);
signUtil.setNonce(RandomStringUtils.randomAlphanumeric(5));
signUtil.setTimeStamp(System.currentTimeMillis());
signUtil.setParamMap(new HashMap<>());
List<String> orderByList = new ArrayList<>();
orderByList.add("id_card_number,DESC");
signUtil.setOrderByList(orderByList);
signUtil.buildSignatureParam();
return signUtil;
}
private JSONObject buildCorpUserRequest(SignUtil signUtil) {
String signature = SignUtil.getSignature(signUtil.getSignatureParam());
return new JSONObject()
.set("appKey", getAppKey())
.set("timeStamp", signUtil.getTimeStamp())
.set("nonce", signUtil.getNonce())
.set("signature", signature)
.set("signatureParam", null)
.set("apiid", HUMAN_RESOURCE_USER_API_ID)
.set("pageNum", signUtil.getPageNum())
.set("pageSize", signUtil.getPageSize())
.set("paramMap", signUtil.getParamMap())
.set("orderByList", signUtil.getOrderByList())
.set("hasTotal", "Y")
.set("envType", signUtil.getEnvType())
.set("empNo", "10262589")
.set("versionType", "published")
.set("invokeLogId", null)
.set("sdkType", "JAVA")
.set("sdkVersion", "1.0.13")
.set("accessIp", null);
}
private int[] saveCorpUserRows(JSONArray sourceRows) {
int addCount = 0;
int updateCount = 0;
int skipCount = 0;
for (Object item : sourceRows) {
JSONObject jsonObject = JSONUtil.parseObj(item);
String employeeName = jsonObject.getStr("employee_name");
String corporationName = jsonObject.getStr("corporation_name");
String deptName = jsonObject.getStr("dept_name");
String idCardNumber = jsonObject.getStr("id_card_number");
String phoneNumber = jsonObject.getStr("phone_number");
if (StringUtils.isEmpty(employeeName) || StringUtils.isEmpty(corporationName)
|| StringUtils.isEmpty(deptName) || StringUtils.isEmpty(idCardNumber)) {
log.warn("跳过无效人资人员数据:姓名、企业、部门或身份证号为空,原始数据:{}", jsonObject);
skipCount++;
continue;
}
HumanUserE existingHumanUser = humanUserGateway.getByIdCardNumber(idCardNumber);
if (existingHumanUser == null) {
// Long existingUserId = isUserExists( Base64.encodeToString(idCardNumber),phoneNumber);
HumanUserE newHumanUser = buildHumanUser(jsonObject);
// newHumanUser.setUserId(existingUserId);
humanUserGateway.add(newHumanUser);
addCount++;
continue;
}
mergeHumanUser(existingHumanUser, jsonObject);
humanUserGateway.update(existingHumanUser);
updateCount++;
}
return new int[]{addCount, updateCount, skipCount};
}
private void mergeHumanUser(HumanUserE existingHumanUser, JSONObject jsonObject) {
HumanUserE latestHumanUser = buildHumanUser(jsonObject);
latestHumanUser.setId(existingHumanUser.getId());
latestHumanUser.setUserId(existingHumanUser.getUserId());
latestHumanUser.setHumanUserId(existingHumanUser.getHumanUserId());
latestHumanUser.setIsConfirm(existingHumanUser.getIsConfirm());
latestHumanUser.setConfirmStatus(existingHumanUser.getConfirmStatus());
latestHumanUser.setCreateId(existingHumanUser.getCreateId());
latestHumanUser.setCreateName(existingHumanUser.getCreateName());
latestHumanUser.setCreateTime(existingHumanUser.getCreateTime());
latestHumanUser.setUpdateId(existingHumanUser.getUpdateId());
latestHumanUser.setUpdateName(existingHumanUser.getUpdateName());
latestHumanUser.setVersion(existingHumanUser.getVersion());
latestHumanUser.setDeleteEnum(existingHumanUser.getDeleteEnum());
latestHumanUser.setTenantId(existingHumanUser.getTenantId());
latestHumanUser.setOrgId(existingHumanUser.getOrgId());
latestHumanUser.setEnv(existingHumanUser.getEnv());
latestHumanUser.setRemarks(existingHumanUser.getRemarks());
latestHumanUser.setUpdateTime(LocalDateTime.now());
existingHumanUser.setEmployeeName(latestHumanUser.getEmployeeName());
existingHumanUser.setEmployeeGender(latestHumanUser.getEmployeeGender());
existingHumanUser.setEmployeeAge(latestHumanUser.getEmployeeAge());
existingHumanUser.setEntryTime(latestHumanUser.getEntryTime());
existingHumanUser.setEmployeeStatus(latestHumanUser.getEmployeeStatus());
existingHumanUser.setJobName(latestHumanUser.getJobName());
existingHumanUser.setJobLevel(latestHumanUser.getJobLevel());
existingHumanUser.setDeptName(latestHumanUser.getDeptName());
existingHumanUser.setDeptCode(latestHumanUser.getDeptCode());
existingHumanUser.setPositionName(latestHumanUser.getPositionName());
existingHumanUser.setPhoneNumber(latestHumanUser.getPhoneNumber());
existingHumanUser.setIdCardNumber(latestHumanUser.getIdCardNumber());
existingHumanUser.setEmployeeImagesCode(latestHumanUser.getEmployeeImagesCode());
existingHumanUser.setEmployeeImages(latestHumanUser.getEmployeeImages());
existingHumanUser.setCorporationCode(latestHumanUser.getCorporationCode());
existingHumanUser.setCorporationName(latestHumanUser.getCorporationName());
existingHumanUser.setUpdateTime(latestHumanUser.getUpdateTime());
}
private JSONArray getTestCorpUserRows() {
return JSONUtil.parseArray("[\n" +
" {\n" +
" \"dept_code\": \"132588b1871341acb51c5638a735dbe7\",\n" +
" \"corporation_code\": \"28f4eed3300b431c958bea4d93e49434\",\n" +
" \"entry_time\": \"2011-07-05 00:00:00\",\n" +
" \"employee_gender\": \"男\",\n" +
" \"position_name\": \"\t测试组长\",\n" +
" \"dept_name\": \"测试部\",\n" +
" \"employee_images_code\": \"a101bf6d844b43b9b85aeba419ff0458\",\n" +
" \"employee_name\": \"马兆华\",\n" +
" \"corporation_name\": \"卓云企业\",\n" +
" \"employee_images\": \"\",\n" +
" \"employee_age\": 45,\n" +
" \"job_name\": \"工艺技术员\",\n" +
" \"phone_number\": \"18700000009\",\n" +
" \"employee_status\": \"在职\",\n" +
" \"job_level\": \"M8\",\n" +
" \"id_card_number\": \"654201197901154618\"\n" +
" }\n" +
"]");
}
@Transactional(rollbackFor = Exception.class)
public String CorpUserChangeSync(String param) {
log.info("开始同步人资人员变更数据");
JSONArray sourceRows = pullAllCorpUserChangeRows(param);
if (sourceRows.isEmpty()) {
log.info("未获取到人资人员变更数据");
return "同步完成:未获取到人资人员变更数据";
}
log.info("拉取到 {} 条人员变更数据", sourceRows.size());
int[] syncResult = saveCorpUserChangeRows(sourceRows);
String message = String.format(
"同步完成:拉取 %d 条人员变更数据,新增变更记录 %d 条,更新本地人员 %d 条,更新统一用户 %d 条,跳过 %d 条,失败 %d 条",
sourceRows.size(), syncResult[0], syncResult[1], syncResult[2], syncResult[3], syncResult[4]);
log.info(message);
log.info("结束同步人资人员变更数据");
return message;
}
private JSONArray pullAllCorpUserChangeRows(String param) {
if (useTestCorpUserData(param)) {
log.info("人资人员变更同步使用测试JSON数据param={}", param);
return getTestCorpUserChangeRows();
}
return pullCorpUserChangeRows();
}
private JSONArray pullCorpUserChangeRows() {
SignUtil signUtil = buildUserChangeSignUtil();
JSONObject requestBody = buildCorpUserChangeRequest(signUtil);
log.info("开始调用人资人员变更接口");
String body = HttpRequest.post(HUMAN_RESOURCE_USER_CHANGE_URL)
.timeout(30000)
.header("Content-Type", "application/json")
.body(requestBody.toString())
.execute()
.body();
if (StringUtils.isEmpty(body)) {
log.warn("人资人员变更接口返回空响应");
return new JSONArray();
}
return extractRemoteRows(body, "人资人员变更接口");
}
private SignUtil buildUserChangeSignUtil() {
SignUtil signUtil = new SignUtil();
signUtil.setAppKey(getAppKey());
signUtil.setAppSecret(getAppSecret());
signUtil.setEnvType("online");
signUtil.setNonce(RandomStringUtils.randomAlphanumeric(5));
signUtil.setTimeStamp(System.currentTimeMillis());
signUtil.setParamMap(new HashMap<>());
signUtil.setOrderByList(new ArrayList<>());
signUtil.buildSignatureParam();
return signUtil;
}
private JSONObject buildCorpUserChangeRequest(SignUtil signUtil) {
String signature = SignUtil.getSignature(signUtil.getSignatureParam());
return new JSONObject()
.set("appKey", getAppKey())
.set("timeStamp", signUtil.getTimeStamp())
.set("nonce", signUtil.getNonce())
.set("signature", signature)
.set("signatureParam", null)
.set("apiid", HUMAN_RESOURCE_USER_CHANGE_API_ID)
.set("paramMap", signUtil.getParamMap())
.set("orderByList", signUtil.getOrderByList())
.set("envType", signUtil.getEnvType())
.set("empNo", "10262589")
.set("invokeLogId", null)
.set("versionType", "published")
.set("sdkType", "JAVA")
.set("sdkVersion", "1.0.13")
.set("accessIp", null);
}
private JSONArray extractRemoteRows(String body, String scene) {
JSONObject returnJson = JSONUtil.parseObj(body, jsonConfig);
String code = returnJson.getStr("code");
if (StringUtils.isNotEmpty(code) && !"0000".equals(code)) {
log.warn("{}返回失败code={},响应={}", scene, code, body);
return new JSONArray();
}
JSONArray rootRows = getArray(returnJson, "rows", "list", "records");
if (rootRows != null) {
return rootRows;
}
Object bo = returnJson.get("bo");
if (bo != null) {
if (bo instanceof JSONArray) {
return JSONUtil.parseArray(bo);
}
JSONObject boJson = JSONUtil.parseObj(bo);
JSONArray boRows = getArray(boJson, "rows", "list", "records");
if (boRows != null) {
return boRows;
}
JSONObject dataObject = boJson.getJSONObject("data");
if (dataObject != null) {
JSONArray dataRows = getArray(dataObject, "rows", "list", "records");
if (dataRows != null) {
return dataRows;
}
}
}
JSONArray parsedRows = parseUserArray(body);
if (!parsedRows.isEmpty()) {
return parsedRows;
}
log.warn("{}未解析到人员数据,响应={}", scene, body);
return new JSONArray();
}
private int[] saveCorpUserChangeRows(JSONArray sourceRows) {
int recordCount = 0;
int localUpdateCount = 0;
int userUpdateCount = 0;
int skipCount = 0;
int failCount = 0;
log.info("开始循环对比人员变更数据,{}",JSONUtil.toJsonStr(sourceRows));
for (Object item : sourceRows) {
try {
JSONObject jsonObject = JSONUtil.parseObj(item);
String employeeName = jsonObject.getStr("employee_name");
String idCardNumber = jsonObject.getStr("id_card_number");
String corporationName = jsonObject.getStr("corporation_name");
if (StringUtils.isEmpty(employeeName) || StringUtils.isEmpty(idCardNumber)) {
log.info("跳过无效人员变更数据:姓名或身份证号为空,原始数据:{}", jsonObject);
skipCount++;
continue;
}
HumanUserE existingHumanUser = humanUserGateway.getByIdCardNumber(idCardNumber);
if (existingHumanUser == null) {
log.info("跳过人员变更数据:本地未找到身份证号为 {} 的人员,原始数据:{}", idCardNumber, jsonObject);
skipCount++;
continue;
}
Long corpId = getTargetCorpId(corporationName);
log.info("目标企业ID{}", corpId);
Map<String, Long> deptNameIdMap = corpId == null ? Collections.emptyMap() : getTargetCorpDeptNameIdMap(corpId);
log.info("开始处理本地用户信息,{}",JSONUtil.toJsonStr(existingHumanUser));
HumanUserRecordE record = buildHumanUserRecord(jsonObject, existingHumanUser.getUserId());
humanUserRecordGateway.add(record);
recordCount++;
mergeHumanUser(existingHumanUser, jsonObject);
humanUserGateway.update(existingHumanUser);
localUpdateCount++;
String deptName = jsonObject.getStr("dept_name");
Long deptId = StringUtils.isEmpty(deptName) || deptNameIdMap == null ? null : deptNameIdMap.get(deptName);
if (existingHumanUser.getUserId() != null) {
log.info("开始统一用户更新,userId={}",existingHumanUser.getUserId() );
if (updateBasicInfodUser(existingHumanUser, deptId,corpId)) {
userUpdateCount++;
} else {
log.warn("统一用户更新未成功userId={},身份证号={}", existingHumanUser.getUserId(), idCardNumber);
}
}
} catch (Exception e) {
log.error("处理人员变更数据失败,原始数据:{}", item, e);
failCount++;
}
}
return new int[]{recordCount, localUpdateCount, userUpdateCount, skipCount, failCount};
}
private boolean updateBasicInfodUser(HumanUserE humanUser, Long deptId, Long corpId) {
if (humanUser.getUserId() == null) {
return false;
}
// SingleResponse<UserDetailCO> detailResponse = userFacade.getDetail(humanUser.getUserId());
String phoneNumber = StringUtils.isNotEmpty(humanUser.getPhoneNumber()) ? humanUser.getPhoneNumber() : null;
String idCardNumber = StringUtils.isNotEmpty(humanUser.getIdCardNumber()) ? Base64.encodeToString(humanUser.getIdCardNumber()) :null;
Long existingUserId = isUserExists(idCardNumber,phoneNumber);
SingleResponse<ZcloudUserCo> infoByUserId = zcloudUserFacade.getInfoByUserId(existingUserId);
if (infoByUserId == null || !infoByUserId.isSuccess() || infoByUserId.getData() == null) {
log.warn("获取统一用户详情失败userId={}", humanUser.getUserId());
return false;
}
ZcloudUserCo detail = infoByUserId.getData();
String employeeName = StringUtils.isNotEmpty(humanUser.getEmployeeName()) ? humanUser.getEmployeeName() : detail.getName();
String postName = StringUtils.isNotEmpty(humanUser.getPositionName()) ? humanUser.getPositionName() : humanUser.getJobName();
ZcloudUserUpdateCmd cmd = new ZcloudUserUpdateCmd();
cmd.setId(existingUserId);
cmd.setName(employeeName);
cmd.setPhone(phoneNumber);
cmd.setUserIdCard(idCardNumber);
if (corpId != null) {
cmd.setCorpinfoId(corpId);
}
if (deptId != null) {
cmd.setDepartmentId(deptId);
}
if (StringUtils.isNotEmpty(postName)) {
cmd.setPostName(postName);
}
cmd.setRzFlag(1);
UserEmploymentFlagEnum byDesc = UserEmploymentFlagEnum.getByDesc(humanUser.getEmployeeStatus());
cmd.setEmploymentFlag(byDesc==null?null:byDesc.getCode());
log.info("调用统一用户请求:{}",JSONUtil.toJsonStr(cmd));
SingleResponse<Long> updateResponse = zcloudUserFacade.updateHumanUser(cmd);
log.info("统一用户更新结果:{}",JSONUtil.toJsonStr(updateResponse));
return updateResponse != null && updateResponse.isSuccess();
}
private List<RoleDeptAddCmd> buildRoleDeptAddCmds(List<UserRoleDeptCO> roleDepts, Long deptId) {
List<RoleDeptAddCmd> result = new ArrayList<>();
if (roleDepts != null) {
for (UserRoleDeptCO roleDept : roleDepts) {
if (roleDept == null || roleDept.getRoleId() == null) {
continue;
}
RoleDeptAddCmd roleDeptAddCmd = new RoleDeptAddCmd();
roleDeptAddCmd.setRoleId(roleDept.getRoleId());
roleDeptAddCmd.setDeptId(deptId != null ? deptId : roleDept.getDeptId());
result.add(roleDeptAddCmd);
}
}
if (!result.isEmpty() || deptId == null) {
return result;
}
Long defaultRoleId = getDefaultRoleId();
if (defaultRoleId == null) {
return result;
}
RoleDeptAddCmd defaultRoleDept = new RoleDeptAddCmd();
defaultRoleDept.setRoleId(defaultRoleId);
defaultRoleDept.setDeptId(deptId);
result.add(defaultRoleDept);
return result;
}
private String resolveSexEnum(String employeeGender, String fallbackSexEnum) {
if (StringUtils.isEmpty(employeeGender)) {
return fallbackSexEnum;
}
String gender = employeeGender.trim();
if ((gender.length() == 1 && gender.charAt(0) == 30007)
|| "1".equals(gender) || "MALE".equalsIgnoreCase(gender)) {
return "MALE";
}
if ((gender.length() == 1 && gender.charAt(0) == 22899)
|| "2".equals(gender) || "FEMALE".equalsIgnoreCase(gender)) {
return "FEMALE";
}
return fallbackSexEnum;
}
private Long parseLongValue(String value) {
if (StringUtils.isEmpty(value)) {
return null;
}
try {
return Long.valueOf(value);
} catch (NumberFormatException e) {
log.warn("文件ID不是有效的数字value={}", value);
return null;
}
}
private JSONArray getTestCorpUserChangeRows() {
HumanUserDO byId = humanUserRepository.getById(1);
String remark = byId.getRemarks();
return JSONUtil.parseArray(remark);
/* JSONArray array = new JSONArray();
JSONObject first = new JSONObject();
first.set("dept_code", "132588b1871341acb51c5638a735dbe7");
first.set("corporation_code", "28f4eed3300b431c958bea4d93e49434");
first.set("entry_time", "2011-07-05 00:00:00");
first.set("employee_gender", "MALE");
first.set("position_name", "开发岗位");
first.set("dept_name", "开发部门");
first.set("employee_images_code", "a101bf6d844b43b9b85aeba419ff0458");
first.set("employee_name", "TEST_USER_B");
first.set("corporation_name", "zhk分公司");
first.set("employee_images", "");
first.set("employee_age", 45);
first.set("job_name", "TEST_JOB_A");
first.set("phone_number", "18700000009");
first.set("employee_status", "在职");
first.set("job_level", "M9");
first.set("id_card_number", "654201197901154618");
array.add(first);
*//*
JSONObject second = new JSONObject();
second.set("dept_code", "3cb898c954b947e3acfb8161d23103f7");
second.set("corporation_code", "5a472a9d94f84832bc83b93133832f55");
second.set("entry_time", "2024-11-01 00:00:00");
second.set("employee_gender", "FEMALE");
second.set("position_name", "TEST_POSITION_B");
second.set("dept_name", "TEST_DEPT_B");
second.set("employee_images_code", "de475a7601a9450fb4a1109f70d1f3be");
second.set("employee_name", "TEST_USER_B");
second.set("corporation_name", "TEST_CORP_B");
second.set("employee_images", "");
second.set("employee_age", 54);
second.set("job_name", "TEST_JOB_B");
second.set("phone_number", "16603390000");
second.set("employee_status", "劳务派遣");
second.set("id_card_number", "E64056788");
array.add(second);*//*
return array;*/
}
private String getAppKey() {
return humanResourcesConfig.getAppKey();
}
private String getAppSecret() {
return humanResourcesConfig.getAppSecret();
}
}

View File

@ -0,0 +1,24 @@
package com.zcloud.human.user.command.convertor;
import com.zcloud.human.user.dto.clientobject.HumanResourceCorpCO;
import com.zcloud.human.user.persistence.dataobject.HumanResourceCorpDO;
import org.mapstruct.Mapper;
import java.util.List;
/**
* web-app
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
@Mapper(componentModel = "spring")
public interface HumanResourceCorpCoConvertor {
/**
* @param humanResourceCorpDOs
* @return
*/
List<HumanResourceCorpCO> converDOsToCOs(List<HumanResourceCorpDO> humanResourceCorpDOs);
}

View File

@ -0,0 +1,42 @@
package com.zcloud.human.user.command.query;
import com.alibaba.cola.dto.PageResponse;
import com.zcloud.gbscommon.utils.PageQueryHelper;
import com.zcloud.human.user.command.convertor.HumanResourceCorpCoConvertor;
import com.zcloud.human.user.dto.HumanResourceCorpPageQry;
import com.zcloud.human.user.dto.clientobject.HumanResourceCorpCO;
import com.zcloud.human.user.persistence.dataobject.HumanResourceCorpDO;
import com.zcloud.human.user.persistence.repository.HumanResourceCorpRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* web-app
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
@Component
@AllArgsConstructor
public class HumanResourceCorpQueryExe {
private final HumanResourceCorpRepository humanResourceCorpRepository;
private final HumanResourceCorpCoConvertor humanResourceCorpCoConvertor;
/**
*
*
* @param humanResourceCorpPageQry
* @return
*/
public PageResponse<HumanResourceCorpCO> execute(HumanResourceCorpPageQry humanResourceCorpPageQry) {
Map<String, Object> params = PageQueryHelper.toHashMap(humanResourceCorpPageQry);
PageResponse<HumanResourceCorpDO> pageResponse = humanResourceCorpRepository.listPage(params);
List<HumanResourceCorpCO> examCenterCOS = humanResourceCorpCoConvertor.converDOsToCOs(pageResponse.getData());
return PageResponse.of(examCenterCOS, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
}
}

View File

@ -0,0 +1,26 @@
package com.zcloud.human.user.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
*
*/
@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "humanresources")
public class HumanResourcesConfig {
/**
*
*/
private String appKey;
/**
*
*/
private String appSecret;
}

View File

@ -21,12 +21,22 @@ public class AsyncSyncService {
public void asyncSyncHumanUser(String param) {
log.info("开始异步同步人资人员信息");
try {
String result = humanUserSyncExe.execute(param);
String result = humanUserSyncExe.CorpUserSync(param);
log.info("异步同步人资人员信息完成:{}", result);
} catch (Exception e) {
log.error("异步同步人资人员信息失败:{}", e.getMessage(), e);
}
}
public void asyncSyncUserChange(String test) {
log.info("开始异步同步人资人员变更信息");
try {
String result = humanUserSyncExe.CorpUserChangeSync(test);
log.info("异步同步人资人员信息完成:{}", result);
} catch (Exception e) {
log.error("异步同步人资人员信息失败:{}", e.getMessage(), e);
}
}
@Async("syncTaskExecutor")
public void asyncSyncHumanDept(String param) {
@ -49,4 +59,6 @@ public class AsyncSyncService {
log.error("异步同步人资部门对比失败:{}", e.getMessage(), e);
}
}
}

View File

@ -0,0 +1,59 @@
package com.zcloud.human.user.service;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.human.user.api.HumanResourceCorpServiceI;
import com.zcloud.human.user.command.HumanResourceCorpAddExe;
import com.zcloud.human.user.command.HumanResourceCorpRemoveExe;
import com.zcloud.human.user.command.HumanResourceCorpUpdateExe;
import com.zcloud.human.user.command.query.HumanResourceCorpQueryExe;
import com.zcloud.human.user.dto.HumanResourceCorpAddCmd;
import com.zcloud.human.user.dto.HumanResourceCorpPageQry;
import com.zcloud.human.user.dto.HumanResourceCorpUpdateCmd;
import com.zcloud.human.user.dto.clientobject.HumanResourceCorpCO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
/**
* web-app
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
@Service
@AllArgsConstructor
public class HumanResourceCorpServiceImpl implements HumanResourceCorpServiceI {
private final HumanResourceCorpAddExe humanResourceCorpAddExe;
private final HumanResourceCorpUpdateExe humanResourceCorpUpdateExe;
private final HumanResourceCorpRemoveExe humanResourceCorpRemoveExe;
private final HumanResourceCorpQueryExe humanResourceCorpQueryExe;
@Override
public PageResponse<HumanResourceCorpCO> listPage(HumanResourceCorpPageQry qry) {
return humanResourceCorpQueryExe.execute(qry);
}
@Override
public SingleResponse add(HumanResourceCorpAddCmd cmd) {
humanResourceCorpAddExe.execute(cmd);
return SingleResponse.buildSuccess();
}
@Override
public void edit(HumanResourceCorpUpdateCmd humanResourceCorpUpdateCmd) {
humanResourceCorpUpdateExe.execute(humanResourceCorpUpdateCmd);
}
@Override
public void remove(Long id) {
humanResourceCorpRemoveExe.execute(id);
}
@Override
public void removeBatch(Long[] ids) {
humanResourceCorpRemoveExe.execute(ids);
}
}

View File

@ -0,0 +1,27 @@
package com.zcloud.human.user.api;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.SingleResponse;
import com.zcloud.human.user.dto.HumanResourceCorpAddCmd;
import com.zcloud.human.user.dto.HumanResourceCorpPageQry;
import com.zcloud.human.user.dto.HumanResourceCorpUpdateCmd;
import com.zcloud.human.user.dto.clientobject.HumanResourceCorpCO;
/**
* web-client
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
public interface HumanResourceCorpServiceI {
PageResponse<HumanResourceCorpCO> listPage(HumanResourceCorpPageQry qry);
SingleResponse<HumanResourceCorpCO> add(HumanResourceCorpAddCmd cmd);
void edit(HumanResourceCorpUpdateCmd cmd);
void remove(Long id);
void removeBatch(Long[] ids);
}

View File

@ -0,0 +1,56 @@
package com.zcloud.human.user.dto;
import com.alibaba.cola.dto.Command;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
/**
* web-client
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HumanResourceCorpAddCmd extends Command {
@ApiModelProperty(value = "企业id", name = "corpinfoId", required = true)
@NotEmpty(message = "企业id不能为空")
private String corpinfoId;
@ApiModelProperty(value = "企业编码", name = "corporationCode", required = true)
@NotEmpty(message = "企业编码不能为空")
private String corporationCode;
@ApiModelProperty(value = "企业名称", name = "corporationName", required = true)
@NotEmpty(message = "企业名称不能为空")
private String corporationName;
@ApiModelProperty(value = "部门名称", name = "deptName", required = true)
@NotEmpty(message = "部门名称不能为空")
private String deptName;
@ApiModelProperty(value = "部门编码", name = "deptCode", required = true)
@NotEmpty(message = "部门编码不能为空")
private String deptCode;
@ApiModelProperty(value = "部门级别", name = "deptLevel", required = true)
@NotEmpty(message = "部门级别不能为空")
private String deptLevel;
@ApiModelProperty(value = "部门路径", name = "deptCodePath", required = true)
@NotEmpty(message = "部门路径不能为空")
private String deptCodePath;
@ApiModelProperty(value = "父级部门编码", name = "superiorOrganizationCode", required = true)
@NotEmpty(message = "父级部门编码不能为空")
private String superiorOrganizationCode;
}

View File

@ -0,0 +1,28 @@
package com.zcloud.human.user.dto;
import com.alibaba.cola.dto.PageQuery;
import lombok.Data;
/**
* web-client
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
@Data
public class HumanResourceCorpPageQry extends PageQuery {
/**
* ,
* - `like`: SQLLIKE
* - `eq`: SQL=
* - `gt`:
* - `lt`:
* - `ge`:
* - `le`:
* - `ne`: SQL!=
*/
private String likeHumanResourceCorpId;
}

View File

@ -0,0 +1,55 @@
package com.zcloud.human.user.dto;
import com.alibaba.cola.dto.Command;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* web-client
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
@EqualsAndHashCode(callSuper = true)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HumanResourceCorpUpdateCmd extends Command {
@ApiModelProperty(value = "主键", name = "id", required = true)
@NotNull(message = "主键不能为空")
private Long id;
@ApiModelProperty(value = "业务主键id", name = "humanResourceCorpId", required = true)
@NotEmpty(message = "业务主键id不能为空")
private String humanResourceCorpId;
@ApiModelProperty(value = "企业id", name = "corpinfoId", required = true)
@NotEmpty(message = "企业id不能为空")
private String corpinfoId;
@ApiModelProperty(value = "企业编码", name = "corporationCode", required = true)
@NotEmpty(message = "企业编码不能为空")
private String corporationCode;
@ApiModelProperty(value = "企业名称", name = "corporationName", required = true)
@NotEmpty(message = "企业名称不能为空")
private String corporationName;
@ApiModelProperty(value = "部门名称", name = "deptName", required = true)
@NotEmpty(message = "部门名称不能为空")
private String deptName;
@ApiModelProperty(value = "部门编码", name = "deptCode", required = true)
@NotEmpty(message = "部门编码不能为空")
private String deptCode;
@ApiModelProperty(value = "部门级别", name = "deptLevel", required = true)
@NotEmpty(message = "部门级别不能为空")
private String deptLevel;
@ApiModelProperty(value = "部门路径", name = "deptCodePath", required = true)
@NotEmpty(message = "部门路径不能为空")
private String deptCodePath;
@ApiModelProperty(value = "父级部门编码", name = "superiorOrganizationCode", required = true)
@NotEmpty(message = "父级部门编码不能为空")
private String superiorOrganizationCode;
}

View File

@ -0,0 +1,85 @@
package com.zcloud.human.user.dto.clientobject;
import com.alibaba.cola.dto.ClientObject;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
/**
* web-client
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
@Data
public class HumanResourceCorpCO extends ClientObject {
//主键
@ApiModelProperty(value = "主键")
private Long id;
//业务主键id
@ApiModelProperty(value = "业务主键id")
private String humanResourceCorpId;
//企业id
@ApiModelProperty(value = "企业id")
private String corpinfoId;
//企业编码
@ApiModelProperty(value = "企业编码")
private String corporationCode;
//企业名称
@ApiModelProperty(value = "企业名称")
private String corporationName;
//部门名称
@ApiModelProperty(value = "部门名称")
private String deptName;
//部门编码
@ApiModelProperty(value = "部门编码")
private String deptCode;
//部门级别
@ApiModelProperty(value = "部门级别")
private String deptLevel;
//部门路径
@ApiModelProperty(value = "部门路径")
private String deptCodePath;
//父级部门编码
@ApiModelProperty(value = "父级部门编码")
private String superiorOrganizationCode;
//乐观锁
@ApiModelProperty(value = "乐观锁")
private Integer version;
//创建人
@ApiModelProperty(value = "创建人")
private Long createId;
//创建人姓名
@ApiModelProperty(value = "创建人姓名")
private String createName;
//创建时间
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
//更新人
@ApiModelProperty(value = "更新人")
private Long updateId;
//修改人名称
@ApiModelProperty(value = "修改人名称")
private String updateName;
//更新时间
@ApiModelProperty(value = "更新时间")
private LocalDateTime updateTime;
//描述
@ApiModelProperty(value = "描述")
private String remarks;
//是否删除
@ApiModelProperty(value = "是否删除")
private String deleteEnum;
//租户ID
@ApiModelProperty(value = "租户ID")
private Long tenantId;
//机构ID
@ApiModelProperty(value = "机构ID")
private Long orgId;
//环境
@ApiModelProperty(value = "环境")
private String env;
}

View File

@ -0,0 +1,52 @@
package com.zcloud.human.user.domain.enums;
import lombok.Getter;
/**
* 0-, 1-, 2-, 3-, 4-, 5-, 6-退, 7-, 8-, 11-, 10-',
*
*/
@Getter
public enum UserEmploymentFlagEnum {
/**
*
*/
RESIGNATION(0, "离职"),
ON(1, "在职"),
INFO_CHANGE(2, "信息变更中"),
NOT_ON(3, "未入职"),
INTERN(4, "实习生"),
INTERNSHIP_ENDED(5, "实习结束"),
RETIREMENT(6, "退休"),
LABOR_DISPATCH(7, "劳务派遣"),
END_OF_LABOR_DISPATCH(8, "劳务派遣结束"),
ENTRY_AUDIT(11, "入职待审核"),
RESIGNATION_AUDIT(10, "离职待审核"),
;
private final Integer code;
private final String desc;
UserEmploymentFlagEnum(Integer code, String desc) {
this.code = code;
this.desc = desc;
}
//根据code获取枚举值
public static UserEmploymentFlagEnum getByCode(Integer code) {
for (UserEmploymentFlagEnum item : values()) {
if (item.getCode().equals(code)) {
return item;
}
}
return null;
}
//根据枚举获取code
public static UserEmploymentFlagEnum getByDesc(String desc) {
for (UserEmploymentFlagEnum item : values()) {
if (item.getDesc().equals(desc)) {
return item;
}
}
return null;
}
}

View File

@ -0,0 +1,30 @@
package com.zcloud.human.user.domain.gateway;
import com.zcloud.human.user.domain.model.HumanResourceCorpE;
/**
* web-domain
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
public interface HumanResourceCorpGateway {
/**
*
*/
Boolean add(HumanResourceCorpE humanResourceCorpE);
/**
*
*/
Boolean update(HumanResourceCorpE humanResourceCorpE);
/**
*
*/
Boolean deletedHumanResourceCorpById(Long id);
Boolean deletedHumanResourceCorpByIds(Long[] id);
}

View File

@ -0,0 +1,51 @@
package com.zcloud.human.user.domain.model;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.Data;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@Data
public class DeptEntity {
private static Set<String> processedDeptCodes = new HashSet<>();
private String corporation_code;
private String corporation_name;
private String dept_name;
private String dept_code;
private String dept_level;
private String dept_code_path;
private String superior_organization_code;
private List<DeptEntity> children;
public static List<DeptEntity> getList(Object x) {
List<DeptEntity> list = JSONObject.parseObject(JSONObject.toJSONString(x), new TypeReference<List<DeptEntity>>() {
});
List<DeptEntity> parent = list.stream()
.filter(n -> "1".equals(n.getDept_level()))
.collect(Collectors.toList());
for (DeptEntity m : parent) {
getList(m, list);
}
return parent;
}
private static void getList(DeptEntity parent, List<DeptEntity> list) {
if (processedDeptCodes.contains(parent.getDept_code())) {
return; // 避免重复处理
}
processedDeptCodes.add(parent.getDept_code());
List<DeptEntity> child = list.stream()
.filter(n -> parent.getDept_code().trim().equals(n.getSuperior_organization_code().trim()))
.collect(Collectors.toList());
parent.setChildren(child);
for (DeptEntity m : child) {
getList(m, list);
}
}
}

View File

@ -0,0 +1,61 @@
package com.zcloud.human.user.domain.model;
import com.jjb.saas.framework.domain.model.BaseE;
import lombok.Data;
import java.time.LocalDateTime;
/**
* web-domain
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
@Data
public class HumanResourceCorpE extends BaseE {
//主键
private Long id;
//业务主键id
private String humanResourceCorpId;
//企业id
private String corpinfoId;
//企业编码
private String corporationCode;
//企业名称
private String corporationName;
//部门名称
private String deptName;
//部门编码
private String deptCode;
//部门级别
private String deptLevel;
//部门路径
private String deptCodePath;
//父级部门编码
private String superiorOrganizationCode;
//乐观锁
private Integer version;
//创建人
private Long createId;
//创建人姓名
private String createName;
//创建时间
private LocalDateTime createTime;
//更新人
private Long updateId;
//修改人名称
private String updateName;
//更新时间
private LocalDateTime updateTime;
//描述
private String remarks;
//是否删除
private String deleteEnum;
//租户ID
private Long tenantId;
//机构ID
private Long orgId;
//环境
private String env;
}

View File

@ -0,0 +1,263 @@
package com.zcloud.human.user.domain.utils;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.util.CollectionUtils;
import java.security.MessageDigest;
import java.util.*;
/**
*
*/
public class SignUtil {
private String appKey;
private String appSecret;
private Integer pageNum;
private Integer pageSize;
private Map<String, String> paramMap;
private List<String> orderByList;
private Long timeStamp;
private String nonce;
private String envType;
private Map<String, Object> signatureParam;
public static void main(String[] args) {
SignUtil signUtil = new SignUtil();
signUtil.setAppKey("7401C9849D1BF3CAF796E146C7AE05AE");
signUtil.setAppSecret("29E60A33FC846468AFCCFD2576FA28120317AB8259E3D1EF9BD236422618613C");
signUtil.setPageNum(1);
signUtil.setPageSize(1000);
Map<String, String> paramMap = new HashMap<>();
//paramMap.put("status", "1");
signUtil.setParamMap(paramMap);
List<String> orderByList = new ArrayList<>();
//orderByList.add("version,DESC");
signUtil.setOrderByList(orderByList);
signUtil.setEnvType("online");
signUtil.setTimeStamp(System.currentTimeMillis());
signUtil.setNonce(RandomStringUtils.randomAlphanumeric(5));
signUtil.buildSignatureParam();
String signature = getSignature(signUtil.getSignatureParam());
System.out.println(signUtil.getTimeStamp());
System.out.println(signUtil.getNonce());
System.out.println(signature);
}
/**
* +++AppKey+AppSecret
* SHA-256
**/
public static String getSignature(Map<String, Object> map) {
if (CollectionUtils.isEmpty(map)) {
return "";
}
Set<Map.Entry<String, Object>> set = map.entrySet();
StringBuffer sb = new StringBuffer();
for (Iterator<Map.Entry<String, Object>> it = set.iterator();
it.hasNext(); ) {
Map.Entry<String, Object> me = it.next();
sb.append(me.getKey()).append(me.getValue());
}
String signString = sb.toString();
if (StrUtil.isNotBlank(signString)) {
return ShaUtils.encryptBySha256(signString).toUpperCase();
}
return "";
}
public void buildSignatureParam() {
Map<String, Object> argsMap = new TreeMap<>();
argsMap.put(SignatureParamName.APP_KEY.getParamName(),
this.getAppKey());
argsMap.put(SignatureParamName.APP_SECRET.getParamName(),
this.getAppSecret());
argsMap.put(SignatureParamName.PAGE_NUM.getParamName(),
this.getPageNum());
argsMap.put(SignatureParamName.PAGE_SIZE.getParamName(),
this.getPageSize());
argsMap.put(SignatureParamName.PARAM_MAP.getParamName(),
this.getParamMap());
argsMap.put(SignatureParamName.ORDER_BY_LIST.getParamName(),
this.getOrderByList());
argsMap.put(SignatureParamName.TIME_STAMP.getParamName(),
this.getTimeStamp());
argsMap.put(SignatureParamName.NONCE.getParamName(),
this.getNonce());
argsMap.put(SignatureParamName.ENV_TYPE.getParamName(),
this.getEnvType());
this.signatureParam = argsMap;
}
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
public String getAppSecret() {
return appSecret;
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
}
public Long getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(Long timeStamp) {
this.timeStamp = timeStamp;
}
public String getNonce() {
return nonce;
}
public void setNonce(String nonce) {
this.nonce = nonce;
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Map<String, String> getParamMap() {
return paramMap;
}
public void setParamMap(Map<String, String> paramMap) {
this.paramMap = paramMap;
}
public List<String> getOrderByList() {
return orderByList;
}
public void setOrderByList(List<String> orderByList) {
this.orderByList = orderByList;
}
public String getEnvType() {
return envType;
}
public void setEnvType(String envType) {
this.envType = envType;
}
public Map<String, Object> getSignatureParam() {
return signatureParam;
}
public void setSignatureParam(Map<String, Object> signatureParam) {
this.signatureParam = signatureParam;
}
public enum SignatureParamName {
/**
* appKey
*/
APP_KEY("appKey"),
/**
* pageNum
*/
PAGE_NUM("pageNum"),
/**
* pageSize
*/
PAGE_SIZE("pageSize"),
/**
* appSecret
*/
APP_SECRET("appSecret"),
/**
* paramMap
*/
PARAM_MAP("paramMap"),
/**
* orderByList
*/
ORDER_BY_LIST("orderByList"),
/**
* timeStamp
*/
TIME_STAMP("timeStamp"),
/**
* nonce
*/
NONCE("nonce"),
/**
* envType
*/
ENV_TYPE("envType");
private String paramName;
SignatureParamName(String paramName) {
this.paramName = paramName;
}
public String getParamName() {
return paramName;
}
}
}
class ShaUtils {
private final static String CHAR_SET_UTF8 = "UTF-8";
private final static String ALGORITHM_SHA256 = "SHA-256";
/**
*
**/
public static String encryptBySha256(String str) {
return encrypt(str, CHAR_SET_UTF8, ALGORITHM_SHA256);
}
public static String encrypt(String str, String charset, String
algorithm) {
if (StrUtil.isBlank(str)) {// throw new
throw new RuntimeException();
}
try {
MessageDigest messageDigest =
MessageDigest.getInstance(algorithm);
messageDigest.update(str.getBytes(charset));
return byte2Hex(messageDigest.digest());
} catch (Exception e) {// throw new
throw new RuntimeException();
}
}
/**
* SHA-256 byte 16
**/
private static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
String temp;
for (int i = 0; i < bytes.length; i++) {
temp = Integer.toHexString(bytes[i] & 0xFF);
if (temp.length() == 1) {
stringBuffer.append("0");
}
stringBuffer.append(temp);
}
return stringBuffer.toString();
}
}

View File

@ -0,0 +1,50 @@
package com.zcloud.human.user.gatewayimpl;
import com.zcloud.human.user.domain.gateway.HumanResourceCorpGateway;
import com.zcloud.human.user.domain.model.HumanResourceCorpE;
import com.zcloud.human.user.persistence.dataobject.HumanResourceCorpDO;
import com.zcloud.human.user.persistence.repository.HumanResourceCorpRepository;
import lombok.AllArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.Collections;
/**
* web-infrastructure
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
@Service
@AllArgsConstructor
public class HumanResourceCorpGatewayImpl implements HumanResourceCorpGateway {
private final HumanResourceCorpRepository humanResourceCorpRepository;
@Override
public Boolean add(HumanResourceCorpE humanResourceCorpE) {
HumanResourceCorpDO d = new HumanResourceCorpDO();
BeanUtils.copyProperties(humanResourceCorpE, d);
humanResourceCorpRepository.save(d);
return true;
}
@Override
public Boolean update(HumanResourceCorpE humanResourceCorpE) {
HumanResourceCorpDO d = new HumanResourceCorpDO();
BeanUtils.copyProperties(humanResourceCorpE, d);
humanResourceCorpRepository.updateById(d);
return true;
}
@Override
public Boolean deletedHumanResourceCorpById(Long id) {
return humanResourceCorpRepository.removeById(id);
}
@Override
public Boolean deletedHumanResourceCorpByIds(Long[] ids) {
return humanResourceCorpRepository.removeByIds(Collections.singletonList(ids));
}
}

View File

@ -0,0 +1,54 @@
package com.zcloud.human.user.persistence.dataobject;
import com.baomidou.mybatisplus.annotation.TableName;
import com.jjb.saas.framework.repository.basedo.BaseDO;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
/**
* web-infrastructure
*
* @Author zhaokai
* @Date 2026-06-16 09:00:22
*/
@Data
@TableName("human_resource_corp")
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class HumanResourceCorpDO extends BaseDO {
//业务主键id
@ApiModelProperty(value = "业务主键id")
private String humanResourceCorpId;
//企业id
@ApiModelProperty(value = "企业id")
private String corpinfoId;
//企业编码
@ApiModelProperty(value = "企业编码")
private String corporationCode;
//企业名称
@ApiModelProperty(value = "企业名称")
private String corporationName;
//部门名称
@ApiModelProperty(value = "部门名称")
private String deptName;
//部门编码
@ApiModelProperty(value = "部门编码")
private String deptCode;
//部门级别
@ApiModelProperty(value = "部门级别")
private String deptLevel;
//部门路径
@ApiModelProperty(value = "部门路径")
private String deptCodePath;
//父级部门编码
@ApiModelProperty(value = "父级部门编码")
private String superiorOrganizationCode;
public HumanResourceCorpDO(String humanResourceCorpId) {
this.humanResourceCorpId = humanResourceCorpId;
}
}

View File

@ -0,0 +1,17 @@
package com.zcloud.human.user.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zcloud.human.user.persistence.dataobject.HumanResourceCorpDO;
import org.apache.ibatis.annotations.Mapper;
/**
* web-infrastructure
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
@Mapper
public interface HumanResourceCorpMapper extends BaseMapper<HumanResourceCorpDO> {
}

View File

@ -0,0 +1,21 @@
package com.zcloud.human.user.persistence.repository;
import com.alibaba.cola.dto.PageResponse;
import com.jjb.saas.framework.repository.repo.BaseRepository;
import com.zcloud.human.user.persistence.dataobject.HumanResourceCorpDO;
import java.util.List;
import java.util.Map;
/**
* web-infrastructure
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
public interface HumanResourceCorpRepository extends BaseRepository<HumanResourceCorpDO> {
PageResponse<HumanResourceCorpDO> listPage(Map<String, Object> params);
void replaceAll(List<HumanResourceCorpDO> corpList);
}

View File

@ -0,0 +1,51 @@
package com.zcloud.human.user.persistence.repository.impl;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jjb.saas.framework.repository.common.PageHelper;
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
import com.zcloud.gbscommon.utils.PageQueryHelper;
import com.zcloud.gbscommon.utils.Query;
import com.zcloud.human.user.persistence.dataobject.HumanResourceCorpDO;
import com.zcloud.human.user.persistence.mapper.HumanResourceCorpMapper;
import com.zcloud.human.user.persistence.repository.HumanResourceCorpRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
/**
* web-infrastructure
*
* @Author zhaokai
* @Date 2026-06-16 09:00:23
*/
@Service
@RequiredArgsConstructor
public class HumanResourceCorpRepositoryImpl extends BaseRepositoryImpl<HumanResourceCorpMapper, HumanResourceCorpDO> implements HumanResourceCorpRepository {
private final HumanResourceCorpMapper humanResourceCorpMapper;
@Override
public PageResponse<HumanResourceCorpDO> listPage(Map<String, Object> params) {
IPage<HumanResourceCorpDO> iPage = new Query<HumanResourceCorpDO>().getPage(params);
QueryWrapper<HumanResourceCorpDO> queryWrapper = new QueryWrapper<>();
queryWrapper = PageQueryHelper.createPageQueryWrapper(queryWrapper, params);
queryWrapper.orderByDesc("create_time");
IPage<HumanResourceCorpDO> result = humanResourceCorpMapper.selectPage(iPage, queryWrapper);
return PageHelper.pageToResponse(result, result.getRecords());
}
@Override
@Transactional(rollbackFor = Exception.class)
public void replaceAll(List<HumanResourceCorpDO> corpList) {
humanResourceCorpMapper.delete(new QueryWrapper<>());
if (corpList == null || corpList.isEmpty()) {
return;
}
saveBatch(corpList, 500);
}
}

View File

@ -71,3 +71,32 @@ CREATE TABLE `human_user_record` (
`env` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '环境',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='人资每日变动记录';
CREATE TABLE `human_resource_corp` (
`id` bigint NOT NULL COMMENT '主键',
`human_resource_corp_id` varchar(35) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '业务主键id',
`corpinfo_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '企业id',
`corporation_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '企业编码',
`corporation_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '企业名称',
`dept_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '部门名称',
`dept_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '部门编码',
`dept_level` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '部门级别',
`dept_code_path` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '部门路径',
`superior_organization_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '父级部门编码',
`version` int DEFAULT NULL COMMENT '乐观锁',
`create_id` bigint DEFAULT NULL COMMENT '创建人',
`create_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '创建人姓名',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_id` bigint DEFAULT NULL COMMENT '更新人',
`update_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '修改人名称',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`remarks` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '描述',
`delete_enum` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '是否删除',
`tenant_id` bigint DEFAULT NULL COMMENT '租户ID',
`org_id` bigint DEFAULT NULL COMMENT '机构ID',
`env` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '环境',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_human_resource_corp_dept_code` (`dept_code`) USING BTREE,
KEY `idx_human_resource_corp_corporation_code` (`corporation_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='人资企业部门本地缓存表';

View File

@ -0,0 +1,7 @@
<?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.zcloud.human.user.persistence.mapper.HumanResourceCorpMapper">
</mapper>