添加同步信息功能实现分页查询接口

main
zhangyue 2026-04-24 11:44:35 +08:00
parent 43ab42ae90
commit 76d0b5f0b7
30 changed files with 1236 additions and 0 deletions

View File

@ -30,5 +30,9 @@
<groupId>com.jjb.saas</groupId>
<artifactId>jjb-saas-framework-job</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,221 @@
package com.zcloud.basic.info.aspect;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zcloud.basic.info.persistence.dataobject.CorpInfoKeyDO;
import com.zcloud.basic.info.service.CorpInfoKeyService;
import com.zcloud.basic.info.utils.SyncPageResponse;
import com.zcloud.gbscommon.utils.Sm2Util;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
//@Aspect
//@Component
@Slf4j
public class SyncResponseEncryptAspect {
@Autowired
private CorpInfoKeyService corpInfoKeyService;
private static final long TIMESTAMP_TOLERANCE = 5 * 60 * 1000L;
@Pointcut("execution(* com.zcloud.basic.info.web.sync.SyncController.*(..))")
public void syncControllerPointcut() {}
@Around("syncControllerPointcut()")
public Object encrypt(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = getHttpServletRequest();
String corpinfoId = request.getHeader("X-CORPINFO-ID");
String timestamp = request.getHeader("X-TIMESTAMP");
String signature = request.getHeader("X-SIGNATURE");
if (corpinfoId == null || timestamp == null || signature == null) {
throw new SecurityException("缺少必要的认证头信息");
}
long requestTime = Long.parseLong(timestamp);
// if (Math.abs(System.currentTimeMillis() - requestTime) > TIMESTAMP_TOLERANCE) {
// throw new SecurityException("请求已过期");
// }
CorpInfoKeyDO keyDO = corpInfoKeyService.getByCorpinfoId(Long.parseLong(corpinfoId));
if (keyDO == null) {
throw new SecurityException("未找到对应的密钥配置");
}
if (keyDO.getPublicKey() == null || keyDO.getSignKey() == null) {
throw new SecurityException("密钥配置不完整");
}
String body = getRequestBody(joinPoint);
if (!sm2Verify(signature, corpinfoId, timestamp, body, keyDO)) {
throw new SecurityException("签名验证失败");
}
Object result = joinPoint.proceed();
if (result == null) {
return result;
}
String className = result.getClass().getName();
if (className.contains("SingleResponse")) {
SingleResponse response = (SingleResponse) result;
Object data = response.getData();
if (data != null) {
response.setData(encryptData(data, keyDO.getPublicKey()));
}
} else if (className.contains("SyncPageResponse") || className.contains("PageResponse") || className.contains("MultiResponse")) {
SyncPageResponse response = (SyncPageResponse) result;
Object data = response.getData();
if (data != null) {
response.setData(encryptData(data, keyDO.getPublicKey()));
}
}
return result;
}
private HttpServletRequest getHttpServletRequest() {
return ((org.springframework.web.context.request.ServletRequestAttributes)
org.springframework.web.context.request.RequestContextHolder.getRequestAttributes())
.getRequest();
}
private String getRequestBody(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
if (args != null && args.length > 0) {
for (Object arg : args) {
if (arg != null && !(arg instanceof HttpServletRequest)) {
return JSON.toJSONString(arg);
}
}
}
return "";
}
private boolean sm2Verify(String signature, String corpinfoId, String timestamp, String body, CorpInfoKeyDO keyDO) {
try {
String decrypted = Sm2Util.decryptBase64(signature, keyDO.getSignPrivateKey());
JSONObject json = JSON.parseObject(decrypted);
String jsonCorpinfoId = json.getString("corpinfoId");
String jsonTimestamp = json.getString("timestamp");
String jsonBody = json.getString("body");
if (!corpinfoId.equals(jsonCorpinfoId)) {
log.warn("corpinfoId不匹配: expected={}, actual={}", corpinfoId, jsonCorpinfoId);
return false;
}
if (!timestamp.equals(jsonTimestamp)) {
log.warn("timestamp不匹配: expected={}, actual={}", timestamp, jsonTimestamp);
return false;
}
// 将body 和 jsonBody 都转换成 JSONObject 并比较其中的字段是否相同,值是否相同
JSONObject jsonBodyObject = JSON.parseObject(jsonBody);
JSONObject bodyObject = JSON.parseObject(body);
if (!isJsonEqualsIgnoreArrayOrder(jsonBodyObject, bodyObject)) {
log.warn("body不匹配: expected={}, actual={}", body, jsonBody);
return false;
}
return true;
} catch (Exception e) {
log.error("SM2解密或验证异常: {}", e.getMessage());
return false;
}
}
private Object encryptData(Object data, String publicKey) {
return Sm2Util.encryptHex(JSON.toJSONString(data), publicKey);
}
private boolean isJsonEqualsIgnoreArrayOrder(Object obj1, Object obj2) {
// 都是 null
if (obj1 == null && obj2 == null) {
return true;
}
// 一个 null 一个不是
if (obj1 == null || obj2 == null) {
return false;
}
// 类型不一样
if (!obj1.getClass().equals(obj2.getClass())) {
return false;
}
// 如果是 JSONObject
if (obj1 instanceof JSONObject) {
JSONObject json1 = (JSONObject) obj1;
JSONObject json2 = (JSONObject) obj2;
// 对比 key 集合是否一致
if (!json1.keySet().equals(json2.keySet())) {
return false;
}
// 递归对比每个 value
for (String key : json1.keySet()) {
Object val1 = json1.get(key);
Object val2 = json2.get(key);
if (!isJsonEqualsIgnoreArrayOrder(val1, val2)) {
return false;
}
}
return true;
} else if (obj1 instanceof JSONArray) {
JSONArray arr1 = (JSONArray) obj1;
JSONArray arr2 = (JSONArray) obj2;
if (arr1.size() != arr2.size()) {
return false;
}
// 转成 List 后排序
List<Object> list1 = new ArrayList<>(arr1);
List<Object> list2 = new ArrayList<>(arr2);
// 排序(基础类型、对象都能排)
sortJsonList(list1);
sortJsonList(list2);
// 递归对比每一个元素
for (int i = 0; i < list1.size(); i++) {
if (!isJsonEqualsIgnoreArrayOrder(list1.get(i), list2.get(i))) {
return false;
}
}
return true;
}
// 普通值字符串、数字、布尔、null直接对比
else {
return Objects.equals(obj1, obj2);
}
}
/**
* JSON
*/
private void sortJsonList(List<Object> list) {
list.sort((o1, o2) -> {
if (o1 == null && o2 == null) return 0;
if (o1 == null) return -1;
if (o2 == null) return 1;
// 转成字符串比较(保证任何类型都能排序)
return o1.toString().compareTo(o2.toString());
});
}
}

View File

@ -0,0 +1,38 @@
package com.zcloud.basic.info.web.sync;
import com.zcloud.basic.info.api.sync.SyncServiceI;
import com.zcloud.basic.info.dto.sync.SyncDepartmentQryPageCmd;
import com.zcloud.basic.info.dto.sync.SyncUserQryPageCmd;
import com.zcloud.basic.info.utils.SyncPageResponse;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author zhangyue
* @date 2026/4/23 9:45
*/
@Api(tags = "同步信息")
@RequestMapping("/${application.gateway}/sync")
@RestController
@AllArgsConstructor
public class SyncController {
private final SyncServiceI syncServiceI;
@ApiOperation("获取用户数据")
@PostMapping("/user/listPage")
public SyncPageResponse listPageSyncUser(@Validated @RequestBody SyncUserQryPageCmd cmd) {
return syncServiceI.listPageSyncUser(cmd);
}
@ApiOperation("获取部门数据")
@PostMapping("/department/listPage")
public SyncPageResponse listPageSyncDepartment(@Validated @RequestBody SyncDepartmentQryPageCmd cmd) {
return syncServiceI.listPageSyncDepartment(cmd);
}
}

View File

@ -0,0 +1,25 @@
package com.zcloud.basic.info.command.convertor.sync;
import com.zcloud.basic.info.dto.clientobject.sync.SyncDepartmentCO;
import com.zcloud.basic.info.dto.clientobject.sync.SyncUserCO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncDepartmentDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import org.mapstruct.Mapper;
import java.util.List;
/**
* web-app
* @Author zhangyue
* @Date 2025-11-04 14:07:34
*/
@Mapper(componentModel = "spring")
public interface SyncDepartmentCoConvertor {
/**
* @param userDOs
* @return
*/
List<SyncDepartmentCO> converDOsToCOs(List<SyncDepartmentDO> departmentDOs);
}

View File

@ -0,0 +1,31 @@
package com.zcloud.basic.info.command.convertor.sync;
import com.jjb.saas.system.client.user.request.FacadeUserAddCmd;
import com.zcloud.basic.info.domain.model.UserE;
import com.zcloud.basic.info.dto.clientobject.UserCO;
import com.zcloud.basic.info.dto.clientobject.UserXmfCO;
import com.zcloud.basic.info.dto.clientobject.sync.SyncUserCO;
import com.zcloud.basic.info.persistence.dataobject.UserDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import com.zcloud.gbscommon.excelEntity.UserExcelExportEntity;
import com.zcloud.gbscommon.excelEntity.UserExcelImportEntity;
import com.zcloud.gbscommon.zclouduser.response.ZcloudUserCo;
import org.mapstruct.Mapper;
import java.util.List;
/**
* web-app
* @Author zhangyue
* @Date 2025-11-04 14:07:34
*/
@Mapper(componentModel = "spring")
public interface SyncUserCoConvertor {
/**
* @param userDOs
* @return
*/
List<SyncUserCO> converDOsToCOs(List<SyncUserDO> userDOs);
}

View File

@ -0,0 +1,52 @@
package com.zcloud.basic.info.command.query.sync;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.fastjson.JSON;
import com.zcloud.basic.info.command.convertor.sync.SyncDepartmentCoConvertor;
import com.zcloud.basic.info.command.convertor.sync.SyncUserCoConvertor;
import com.zcloud.basic.info.dto.clientobject.sync.SyncDepartmentCO;
import com.zcloud.basic.info.dto.clientobject.sync.SyncUserCO;
import com.zcloud.basic.info.dto.sync.SyncDepartmentQryPageCmd;
import com.zcloud.basic.info.dto.sync.SyncUserQryPageCmd;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncDepartmentDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import com.zcloud.basic.info.persistence.repository.sync.SyncDepartmentRepository;
import com.zcloud.basic.info.persistence.repository.sync.SyncUserRepository;
import com.zcloud.basic.info.utils.SyncPageResponse;
import com.zcloud.gbscommon.utils.PageQueryHelper;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
/**
* web-app
*
* @Author zhangyue
* @Date 2025-11-04 14:07:36
*/
@Component
@AllArgsConstructor
public class SyncQueryExe {
private final SyncUserRepository syncUserRepository;
private final SyncUserCoConvertor syncUserCoConvertor;
private final SyncDepartmentRepository syncDepartmentRepository;
private final SyncDepartmentCoConvertor syncDepartmentCoConvertor;
public SyncPageResponse listPageSyncUser(SyncUserQryPageCmd cmd) {
Map<String, Object> params = PageQueryHelper.toHashMap(cmd);
PageResponse<SyncUserDO> pageResponse = syncUserRepository.listPageSyncUser(params);
List<SyncUserCO> userCOList = syncUserCoConvertor.converDOsToCOs(pageResponse.getData());
return SyncPageResponse.of(userCOList, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
}
public SyncPageResponse listPageSyncDepartment(SyncDepartmentQryPageCmd cmd) {
Map<String, Object> params = PageQueryHelper.toHashMap(cmd);
PageResponse<SyncDepartmentDO> pageResponse = syncDepartmentRepository.listPageSyncDepartment(params);
List<SyncDepartmentCO> userCOList = syncDepartmentCoConvertor.converDOsToCOs(pageResponse.getData());
return SyncPageResponse.of(userCOList, pageResponse.getTotalCount(), pageResponse.getPageSize(), pageResponse.getPageIndex());
}
}

View File

@ -0,0 +1,17 @@
package com.zcloud.basic.info.service;
import com.zcloud.basic.info.persistence.dataobject.CorpInfoKeyDO;
import com.zcloud.basic.info.persistence.repository.CorpInfoKeyRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@Service
@RequiredArgsConstructor
public class CorpInfoKeyService {
private final CorpInfoKeyRepository corpInfoKeyRepository;
public CorpInfoKeyDO getByCorpinfoId(Long corpinfoId) {
return corpInfoKeyRepository.getByCorpinfoId(corpinfoId);
}
}

View File

@ -0,0 +1,38 @@
package com.zcloud.basic.info.service.sync;
import com.alibaba.cola.dto.PageResponse;
import com.zcloud.basic.info.api.sync.SyncServiceI;
import com.zcloud.basic.info.command.query.sync.SyncQueryExe;
import com.zcloud.basic.info.dto.clientobject.sync.SyncUserCO;
import com.zcloud.basic.info.dto.sync.SyncDepartmentQryPageCmd;
import com.zcloud.basic.info.dto.sync.SyncUserQryCmd;
import com.zcloud.basic.info.dto.sync.SyncUserQryPageCmd;
import com.zcloud.basic.info.utils.SyncPageResponse;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* web-app
*
* @Author zhangyue
* @Date 2025-11-04 14:07:37
*/
@Service
@AllArgsConstructor
public class SyncServiceImpl implements SyncServiceI {
private final SyncQueryExe syncQueryExe;
@Override
public SyncPageResponse listPageSyncUser(SyncUserQryPageCmd cmd) {
return syncQueryExe.listPageSyncUser(cmd);
}
@Override
public SyncPageResponse listPageSyncDepartment(SyncDepartmentQryPageCmd cmd) {
return syncQueryExe.listPageSyncDepartment(cmd);
}
}

View File

@ -46,5 +46,13 @@
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>com.zcloud.basic.info</groupId>
<artifactId>web-infrastructure</artifactId>
</dependency>
<dependency>
<groupId>com.zcloud.basic.info</groupId>
<artifactId>web-infrastructure</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,19 @@
package com.zcloud.basic.info.api.sync;
import com.zcloud.basic.info.dto.sync.SyncDepartmentQryPageCmd;
import com.zcloud.basic.info.dto.sync.SyncUserQryPageCmd;
import com.zcloud.basic.info.utils.SyncPageResponse;
/**
* web-client
* @Author zhangyue
* @Date 2025-11-04 14:07:37
*/
public interface SyncServiceI {
SyncPageResponse listPageSyncUser(SyncUserQryPageCmd cmd);
SyncPageResponse listPageSyncDepartment(SyncDepartmentQryPageCmd cmd);
}

View File

@ -0,0 +1,25 @@
package com.zcloud.basic.info.dto.clientobject.sync;
import com.alibaba.cola.dto.ClientObject;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* web-client
*
* @Author zhangyue
* @Date 2025-11-04 14:07:33
*/
@Data
public class SyncDepartmentCO extends ClientObject {
@ApiModelProperty(value = "部门id")
private Long id;
@ApiModelProperty(value = "部门名称")
private String name;
@ApiModelProperty(value = "父部门id")
private Long parentId;
}

View File

@ -0,0 +1,61 @@
package com.zcloud.basic.info.dto.clientobject.sync;
import com.alibaba.cola.dto.ClientObject;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* web-client
*
* @Author zhangyue
* @Date 2025-11-04 14:07:33
*/
@Data
public class SyncUserCO extends ClientObject {
@ApiModelProperty(value = "用户id")
private Long id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "部门id")
private Long departmentId;
@ApiModelProperty(value = "部门名称")
private String departmentName;
@ApiModelProperty(value = "岗位名称")
private String postName;
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "手机号")
private String phone;
@ApiModelProperty(value = "人员类型翻译")
private String personnelTypeName;
@ApiModelProperty(value = "民族名称")
private String nationName;
@ApiModelProperty(value = "身份证号")
private String userIdCard;
@ApiModelProperty(value = "年龄")
private Integer age;
@ApiModelProperty(value = "生日")
private String birthday;
@ApiModelProperty(value = "性别")
private String sex;
}

View File

@ -0,0 +1,36 @@
package com.zcloud.basic.info.dto.sync;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* web-client
*
* @Author zhangyue
* @Date 2025-11-04 14:07:36
*/
@Data
public class SyncDepartmentQryPageCmd {
private int pageSize = 10;
private int pageIndex = 1;
/**
* ,
* - `like`: SQLLIKE
* - `eq`: SQL=
* - `gt`:
* - `lt`:
* - `ge`:
* - `le`:
* - `ne`: SQL!=
*/
@NotNull(message = "corpinfoId不能为空")
private Long corpinfoId;
private String name;
private String parentId; // 父部门id
}

View File

@ -0,0 +1,48 @@
package com.zcloud.basic.info.dto.sync;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* web-client
*
* @Author zhangyue
* @Date 2025-11-04 14:07:36
*/
@Data
public class SyncUserQryCmd {
/**
* ,
* - `like`: SQLLIKE
* - `eq`: SQL=
* - `gt`:
* - `lt`:
* - `ge`:
* - `le`:
* - `ne`: SQL!=
*/
private String eqCorpinfoId;
private String eqDepartmentId;
private String eqPostId;
private Long corpinfoId;
private Long departmentId;
private Long postId;
private String username;
private Integer noMain;
private String isMyCorp;
@ApiModelProperty(value = "是否流动人员1-流动0-固定人员", name = "flowFlag")
private Integer flowFlag;
// 入职状态
@ApiModelProperty(value = "入职状态 入职状态0-离职, 1-在职, 2-信息变更中, 3-未入职, 4-实习生, 5-实习结束, 6-退休, 7-劳务派遣, 8-劳务派遣结束, 11-入职待审核, 10-离职待审核")
private Integer employmentFlag;
@ApiModelProperty(value = "是否存在人资系统, 1-是, 0-否")
private Integer rzFlag;
@ApiModelProperty(value = "是否有人脸, 1-是, 0-否")
private Integer faceFlag;
}

View File

@ -0,0 +1,43 @@
package com.zcloud.basic.info.dto.sync;
import com.alibaba.cola.dto.PageQuery;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* web-client
*
* @Author zhangyue
* @Date 2025-11-04 14:07:36
*/
@Data
public class SyncUserQryPageCmd {
private int pageSize = 10;
private int pageIndex = 1;
/**
* ,
* - `like`: SQLLIKE
* - `eq`: SQL=
* - `gt`:
* - `lt`:
* - `ge`:
* - `le`:
* - `ne`: SQL!=
*/
@NotNull(message = "corpinfoId不能为空")
private Long corpinfoId;
private String name;
private Long departmentId;
private String departmentName;
private String postName;
private String phone;
private String userIdCard;
}

View File

@ -0,0 +1,29 @@
package com.zcloud.basic.info.persistence.dataobject;
import com.baomidou.mybatisplus.annotation.TableField;
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;
@Data
@TableName("corp_info_key")
@EqualsAndHashCode(callSuper = true)
public class CorpInfoKeyDO extends BaseDO {
@ApiModelProperty(value = "企业id")
private Long corpinfoId;
@ApiModelProperty(value = "公钥")
private String publicKey;
@ApiModelProperty(value = "私钥")
private String privateKey;
@ApiModelProperty(value = "签名密钥公钥")
private String signKey;
@ApiModelProperty(value = "签名密钥私钥")
private String signPrivateKey;
}

View File

@ -0,0 +1,33 @@
package com.zcloud.basic.info.persistence.dataobject.sync;
import com.baomidou.mybatisplus.annotation.TableField;
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 zhangyue
* @Date 2025-11-04 14:07:35
*/
@Data
@TableName("department")
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SyncDepartmentDO extends BaseDO {
@ApiModelProperty(value = "部门id")
private Long id;
@ApiModelProperty(value = "部门名称")
private String name;
@ApiModelProperty(value = "父部门id")
private Long parentId;
}

View File

@ -0,0 +1,73 @@
package com.zcloud.basic.info.persistence.dataobject.sync;
import com.baomidou.mybatisplus.annotation.TableField;
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 zhangyue
* @Date 2025-11-04 14:07:35
*/
@Data
@TableName("user")
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class SyncUserDO extends BaseDO {
@ApiModelProperty(value = "用户id")
private Long id;
@ApiModelProperty(value = "姓名")
private String name;
@ApiModelProperty(value = "部门id")
private Long departmentId;
@ApiModelProperty(value = "部门名称")
@TableField(exist = false)
private String departmentName;
@ApiModelProperty(value = "岗位名称")
@TableField(exist = false)
private String postName;
@ApiModelProperty(value = "邮箱")
private String email;
@ApiModelProperty(value = "手机号")
private String phone;
@ApiModelProperty(value = "人员类型翻译")
private String personnelTypeName;
@ApiModelProperty(value = "民族名称")
private String nationName;
@ApiModelProperty(value = "身份证号")
private String userIdCard;
@ApiModelProperty(value = "年龄")
@TableField(exist = false)
private Integer age;
@ApiModelProperty(value = "生日")
@TableField(exist = false)
private String birthday;
@ApiModelProperty(value = "性别")
@TableField(exist = false)
private String sex;
}

View File

@ -0,0 +1,9 @@
package com.zcloud.basic.info.persistence.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zcloud.basic.info.persistence.dataobject.CorpInfoKeyDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CorpInfoKeyMapper extends BaseMapper<CorpInfoKeyDO> {
}

View File

@ -0,0 +1,23 @@
package com.zcloud.basic.info.persistence.mapper.sync;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncDepartmentDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Map;
/**
* web-infrastructure
*
* @Author zhangyue
* @Date 2025-11-04 14:07:36
*/
@Mapper
public interface SyncDepartmentMapper extends BaseMapper<SyncDepartmentDO> {
IPage<SyncDepartmentDO> listPageSyncDepartment(IPage<SyncDepartmentDO> page, @Param("params") Map<String, Object> params);
}

View File

@ -0,0 +1,30 @@
package com.zcloud.basic.info.persistence.mapper.sync;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jjb.saas.framework.datascope.annotation.DataScope;
import com.jjb.saas.framework.datascope.annotation.DataScopes;
import com.zcloud.basic.info.persistence.dataobject.DepartmentLeaderStatictiscDO;
import com.zcloud.basic.info.persistence.dataobject.UserCorpInfoDO;
import com.zcloud.basic.info.persistence.dataobject.UserDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
* web-infrastructure
*
* @Author zhangyue
* @Date 2025-11-04 14:07:36
*/
@Mapper
public interface SyncUserMapper extends BaseMapper<SyncUserDO> {
IPage<SyncUserDO> listPageSyncUser(IPage<SyncUserDO> page, @Param("params") Map<String, Object> params);
}

View File

@ -0,0 +1,9 @@
package com.zcloud.basic.info.persistence.repository;
import com.jjb.saas.framework.repository.repo.BaseRepository;
import com.zcloud.basic.info.persistence.dataobject.CorpInfoKeyDO;
public interface CorpInfoKeyRepository extends BaseRepository<CorpInfoKeyDO> {
CorpInfoKeyDO getByCorpinfoId(Long corpinfoId);
}

View File

@ -0,0 +1,19 @@
package com.zcloud.basic.info.persistence.repository.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
import com.zcloud.basic.info.persistence.dataobject.CorpInfoKeyDO;
import com.zcloud.basic.info.persistence.mapper.CorpInfoKeyMapper;
import com.zcloud.basic.info.persistence.repository.CorpInfoKeyRepository;
import org.springframework.stereotype.Service;
@Service
public class CorpInfoKeyRepositoryImpl extends BaseRepositoryImpl<CorpInfoKeyMapper, CorpInfoKeyDO> implements CorpInfoKeyRepository {
@Override
public CorpInfoKeyDO getByCorpinfoId(Long corpinfoId) {
QueryWrapper<CorpInfoKeyDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("corpinfo_id", corpinfoId);
return baseMapper.selectOne(queryWrapper);
}
}

View File

@ -0,0 +1,40 @@
package com.zcloud.basic.info.persistence.repository.impl.sync;
import com.alibaba.cola.dto.PageResponse;
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.basic.info.persistence.dataobject.sync.SyncDepartmentDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import com.zcloud.basic.info.persistence.mapper.sync.SyncDepartmentMapper;
import com.zcloud.basic.info.persistence.mapper.sync.SyncUserMapper;
import com.zcloud.basic.info.persistence.repository.sync.SyncDepartmentRepository;
import com.zcloud.basic.info.persistence.repository.sync.SyncUserRepository;
import com.zcloud.gbscommon.utils.Query;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* web-infrastructure
*
* @Author zhangyue
* @Date 2025-11-04 14:07:37
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class SyncDepartmentRepositoryImpl extends BaseRepositoryImpl<SyncDepartmentMapper, SyncDepartmentDO> implements SyncDepartmentRepository {
private final SyncDepartmentMapper syncDepartmentMapper;
@Override
public PageResponse<SyncDepartmentDO> listPageSyncDepartment(Map<String, Object> params) {
IPage<SyncDepartmentDO> iPage = new Query<SyncDepartmentDO>().getPage(params);
IPage<SyncDepartmentDO> result = syncDepartmentMapper.listPageSyncDepartment(iPage, params);
return PageHelper.pageToResponse(result, result.getRecords());
}
}

View File

@ -0,0 +1,38 @@
package com.zcloud.basic.info.persistence.repository.impl.sync;
import com.alibaba.cola.dto.PageResponse;
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.basic.info.persistence.dataobject.UserDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import com.zcloud.basic.info.persistence.mapper.sync.SyncUserMapper;
import com.zcloud.basic.info.persistence.repository.sync.SyncUserRepository;
import com.zcloud.gbscommon.utils.Query;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Map;
/**
* web-infrastructure
*
* @Author zhangyue
* @Date 2025-11-04 14:07:37
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class SyncUserRepositoryImpl extends BaseRepositoryImpl<SyncUserMapper, SyncUserDO> implements SyncUserRepository {
private final SyncUserMapper syncUserMapper;
@Override
public PageResponse<SyncUserDO> listPageSyncUser(Map<String, Object> params) {
IPage<SyncUserDO> iPage = new Query<SyncUserDO>().getPage(params);
IPage<SyncUserDO> result = syncUserMapper.listPageSyncUser(iPage, params);
return PageHelper.pageToResponse(result, result.getRecords());
}
}

View File

@ -0,0 +1,19 @@
package com.zcloud.basic.info.persistence.repository.sync;
import com.alibaba.cola.dto.PageResponse;
import com.jjb.saas.framework.repository.repo.BaseRepository;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncDepartmentDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import java.util.Map;
/**
* web-infrastructure
* @Author zhangyue
* @Date 2025-11-04 14:07:36
*/
public interface SyncDepartmentRepository extends BaseRepository<SyncDepartmentDO> {
PageResponse<SyncDepartmentDO> listPageSyncDepartment(Map<String,Object> params);
}

View File

@ -0,0 +1,25 @@
package com.zcloud.basic.info.persistence.repository.sync;
import com.alibaba.cola.dto.PageResponse;
import com.alibaba.cola.dto.Response;
import com.jjb.saas.framework.repository.repo.BaseRepository;
import com.zcloud.basic.info.domain.model.UserE;
import com.zcloud.basic.info.persistence.dataobject.UserCorpInfoDO;
import com.zcloud.basic.info.persistence.dataobject.UserDO;
import com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;
/**
* web-infrastructure
* @Author zhangyue
* @Date 2025-11-04 14:07:36
*/
public interface SyncUserRepository extends BaseRepository<SyncUserDO> {
PageResponse<SyncUserDO> listPageSyncUser(Map<String,Object> params);
}

View File

@ -0,0 +1,129 @@
package com.zcloud.basic.info.utils;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.cola.dto.Response;
import com.alibaba.fastjson.JSONObject;
import com.zcloud.gbscommon.utils.Sm2Util;
import org.slf4j.MDC;
import java.util.Collections;
/**
* @author zhangyue
* @date 2026/4/23 11:39
*/
public class SyncPageResponse extends Response {
private static final long serialVersionUID = 1L;
private int totalCount = 0;
private int pageSize = 1;
private int pageIndex = 1;
private Object data;
public SyncPageResponse() {
}
public int getTotalCount() {
return this.totalCount;
}
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
}
public int getPageSize() {
return this.pageSize < 1 ? 1 : this.pageSize;
}
public void setPageSize(int pageSize) {
if (pageSize < 1) {
this.pageSize = 1;
} else {
this.pageSize = pageSize;
}
}
public int getPageIndex() {
return this.pageIndex < 1 ? 1 : this.pageIndex;
}
public void setPageIndex(int pageIndex) {
if (pageIndex < 1) {
this.pageIndex = 1;
} else {
this.pageIndex = pageIndex;
}
}
public Object getData() {
return this.data;
}
public void setData(Object data) {
this.data = data;
}
public int getTotalPages() {
return this.totalCount % this.pageSize == 0 ? this.totalCount / this.pageSize : this.totalCount / this.pageSize + 1;
}
public boolean isEmpty() {
return ObjectUtil.isEmpty(this.data);
}
public boolean isNotEmpty() {
return !this.isEmpty();
}
public static SyncPageResponse buildSuccess() {
SyncPageResponse response = new SyncPageResponse();
response.setSuccess(true);
response.setTraceId(MDC.get("tlogTraceId"));
return response;
}
public static SyncPageResponse buildFailure(String errCode, String errMessage) {
SyncPageResponse response = new SyncPageResponse();
response.setSuccess(false);
response.setErrCode(errCode);
response.setErrMessage(errMessage);
response.setTraceId(MDC.get("tlogTraceId"));
return response;
}
public static <T> SyncPageResponse of(int pageSize, int pageIndex) {
SyncPageResponse response = new SyncPageResponse();
response.setSuccess(true);
response.setData(Collections.emptyList());
response.setTotalCount(0);
response.setPageSize(pageSize);
response.setPageIndex(pageIndex);
response.setTraceId(MDC.get("tlogTraceId"));
return response;
}
public static <T> SyncPageResponse of(Object data, int totalCount, int pageSize, int pageIndex) {
SyncPageResponse response = new SyncPageResponse();
response.setSuccess(true);
response.setData(data);
response.setTotalCount(totalCount);
response.setPageSize(pageSize);
response.setPageIndex(pageIndex);
response.setTraceId(MDC.get("tlogTraceId"));
return response;
}
public static void main(String[] args) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("corpinfoId", 2003302008103952384L);
jsonObject.put("timestamp", 1776902400000l);
JSONObject jsonbody = new JSONObject();
jsonbody.put("corpinfoId", 2003302008103952384L);
jsonbody.put("pageIndex", 1);
jsonbody.put("pageSize", 10);
jsonObject.put("body", jsonbody);
String str = jsonObject.toJSONString();
System.out.println(str);
}
}

View File

@ -0,0 +1,27 @@
<?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.basic.info.persistence.mapper.sync.SyncDepartmentMapper">
<select id="listPageSyncDepartment" resultType="com.zcloud.basic.info.persistence.dataobject.sync.SyncDepartmentDO">
select
d.id,
d.name,
d.parent_id
from department d
<where>
and d.delete_enum = 'FALSE'
and d.corpinfo_id = #{params.corpinfoId}
<if test="params.name != null and params.name != ''">
and d.name like concat('%',#{params.name},'%')
</if>
<if test="params.parentId != null">
and d.parent_id = #{params.parentId}
</if>
</where>
order by d.parent_id,d.id
</select>
</mapper>

View File

@ -0,0 +1,67 @@
<?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.basic.info.persistence.mapper.sync.SyncUserMapper">
<select id="listPageSyncUser" resultType="com.zcloud.basic.info.persistence.dataobject.sync.SyncUserDO">
select
d.name as department_name,
p.post_name,
u.id,
u.name,
u.department_id,
u.email,
u.phone,
u.personnel_type_name,
u.nation_name,
FROM_BASE64(u.user_id_card) user_id_card,
CASE
WHEN LENGTH(FROM_BASE64(u.user_id_card)) > 0
AND MOD(SUBSTRING(FROM_BASE64(u.user_id_card), 17, 1), 2) = 1 THEN
'男'
WHEN LENGTH(FROM_BASE64(u.user_id_card)) > 0
AND MOD(SUBSTRING(FROM_BASE64(u.user_id_card), 17, 1), 2) = 0 THEN
'女'
END AS sex,
CASE
WHEN LENGTH(FROM_BASE64(u.user_id_card)) > 0 THEN
(YEAR(NOW()) - SUBSTRING(FROM_BASE64(u.user_id_card), 7, 4)) ELSE NULL
END AS age,
cast(substring(FROM_BASE64(u.user_id_card), 7, 8) AS DATE) AS birthday
from user u
left join corp_info c on c.id = u.corpinfo_id
left join department d on d.id = u.department_id
left join post p on p.id = u.post_id
<where>
and u.id != u.corpinfo_id
and u.delete_enum = 'FALSE'
and u.employment_flag in (1, 2)
and u.corpinfo_id = #{params.corpinfoId}
<if test="params.name != null and params.name != ''">
and u.name like concat('%',#{params.name},'%')
</if>
<if test="params.departmentId != null">
and u.department_id = #{params.departmentId}
</if>
<if test="params.departmentName != null and params.departmentName != ''">
and d.name like concat('%',#{params.departmentName},'%')
</if>
<if test="params.postName != null and params.postName != ''">
and p.post_name like concat('%',#{params.postName},'%')
</if>
<if test="params.phone != null and params.phone != ''">
and u.phone like concat('%',#{params.phone},'%')
</if>
<if test="params.userIdCard != null and params.userIdCard != ''">
and u.user_id_card = TO_BASE64(#{params.userIdCard})
</if>
</where>
order by u.sort ,
u.create_time desc
</select>
</mapper>