同步功能编写完毕

This commit is contained in:
xuetao.li
2023-05-17 17:12:37 +08:00
parent 0c0567095a
commit 405d2d0828
15 changed files with 305 additions and 68 deletions
@@ -123,6 +123,8 @@ public class ShiroFilterConfiguration {
/* 流程需要 */
filterChainDefinitionMap.put(restPath + "/service/model/**", ANON);
filterChainDefinitionMap.put(restPath + "/service/editor/stencilset", ANON);
/* 同步需要 */
filterChainDefinitionMap.put(restPath + "/sync/**", ANON);
filterChainDefinitionMap.put(restPath + "/**", AUTHC);
@@ -132,17 +132,20 @@ huawei.OBS.fileMaxSize=10 #\u6587\u4EF6\u4E0A\u4F20\u6700\u5927M\u6570
logging.level.com.adc: debug
# CMP???????????
# CMP TEST ENV
cmp.url=https://cmp-uat.faw-vw.in/
cmp.appkey=TI062S001Uat
cmp.appSecret=ee493505524d4f628e52058f4df3a4fb
# CMP???????????
# CMP PROD ENV
#cmp.url=https://cmp.faw-vw.in/employee/v1/
#cmp.appkey=TI062S001Uat
#cmp.appSecret=ee493505524d4f628e52058f4df3a4fb
# SSO????
# SSO TEST ENV
sso.url=https://iamuat.faw-vw.com/
sso.clientId=43da19911e74a14dd5d9
sso.clientSecret=67da1e83183e854535cae9027cfbdb12cbc3
sso.clientSecret=67da1e83183e854535cae9027cfbdb12cbc3
# ROLE FIX USER
user.fix.role=wei.sheng,miao.qi
@@ -72,7 +72,6 @@ queue.capacity=8
mybatis-plus.configuration.map-underscore-to-camel-case=true
spring.activiti.database-schema-update=true
# ????????:true-???????false-??
spring.activiti.check-process-definitions=false
@@ -25,6 +25,7 @@ import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -40,15 +41,15 @@ public class SyncIAMTimer {
* IAM的前缀地址
*/
@Value("${cmp.url}")
private String cmpUrl="https://cmp-uat.faw-vw.in/";
private String cmpUrl;
@Value("${cmp.appkey}")
private String appkey = "TI062S001Uat";
private String appkey;
@Value("${cmp.appSecret}")
private String appSecret = "ee493505524d4f628e52058f4df3a4fb";
private String appSecret;
private String xCustom = "TI062S-001"; // 写死的
private final String xCustom = "TI062S-001"; // 写死的
/**
* 组织机构增量同步接口地址
@@ -71,7 +72,8 @@ public class SyncIAMTimer {
public static void main(String[] args) {
SyncIAMTimer syncIAMTimer = new SyncIAMTimer();
syncIAMTimer.syncOrgIncrData(1, 10);
// syncIAMTimer.syncOrgIncrData(1, 1000);
syncIAMTimer.syncUserIncrData(39, 1000, null);
}
/**
@@ -80,7 +82,7 @@ public class SyncIAMTimer {
* @Param pageIndex 页码,默认为1,小于1按1处理
* @Param pageSize 每页条数,默认10,小于1按1处 于1000按1000处理
*/
public void syncOrgIncrData(int pageIndex, int pageSize){
public CmpOrgResult syncOrgIncrData(int pageIndex, int pageSize){
String suffixUrl = ORG_INCREMENT_URL + "?pageIndex=" + pageIndex + "&pageSize=" + pageSize;
String syncUrl = this.cmpUrl + suffixUrl;
@@ -101,7 +103,7 @@ public class SyncIAMTimer {
CmpOrgResult cmpOrgResult = GsonUtil.json2T(orgDataStr, CmpOrgResult.class);
if (cmpOrgResult != null){
List<OrgVoIAM> orgVoIAMList = cmpOrgResult.getData();
List<OrgVoIAM> orgVoIAMList = cmpOrgResult.getData().getRecords();
// 同步的VO 转换成 数据库EO
List<OrgEO> orgEOList = new ArrayList<>();
@@ -114,13 +116,15 @@ public class SyncIAMTimer {
this.addSyncLog(null, new Date(), SyncTypeEnum.ORG_INCREMENT_DATA.getValue());
}
return cmpOrgResult;
}
/**
* 同步组织机构-增量数据并入库
* @Param syncModel 同步模式
*/
public void syncUserIncrData(int pageIndex, int pageSize, String enterTime){
public CmpUserResult syncUserIncrData(int pageIndex, int pageSize, String enterTime){
String suffixUrl = USER_INCREMENT_URL + "?pageIndex=" + pageIndex + "&pageSize=" + pageSize;
if (StringUtils.isNotEmpty(enterTime)){
suffixUrl += "&enterTime=" + enterTime;
@@ -129,9 +133,9 @@ public class SyncIAMTimer {
String syncUrl = this.cmpUrl + suffixUrl;
String gmtDate = SignUtils.getGMTDate();
String sign = SignUtils.generate(HttpMethod.GET, syncUrl, this.xCustom, this.appkey, gmtDate, this.appSecret);
String sign = SignUtils.generate(HttpMethod.GET, suffixUrl, this.xCustom, this.appkey, gmtDate, this.appSecret);
String userDataStr = HttpRequest.post(syncUrl)
String userDataStr = HttpRequest.get(syncUrl)
.header("Content-Type", "application/json")
.header("Date", gmtDate)
.header("X-HMAC-ACCESS-KEY", this.appkey)
@@ -144,32 +148,21 @@ public class SyncIAMTimer {
CmpUserResult cmpUserResult = GsonUtil.json2T(userDataStr, CmpUserResult.class);
if (cmpUserResult != null){
List<UserVoIAM> userVoIAMList =cmpUserResult.getData();
List<UserVoIAM> userVoIAMList =cmpUserResult.getData().getRecords();
List<UserEO> waitSaveUserList = new ArrayList<>();
// 同步的VO 转换成 数据库EO,并存库
for (UserVoIAM userVoIAM : userVoIAMList){
UserEO userEO = this.transUserIAMVoToUserEO(userVoIAM);
this.iUserEoService.syncSaveOrUpdate(userEO);
waitSaveUserList.add(userEO);
}
this.iUserEoService.syncSaveOrUpdate(waitSaveUserList);
this.addSyncLog(null, new Date(), SyncTypeEnum.USER_INCREMENT_DATA.getValue());
}
}
/**
* 根据key和secret获取JWT_TOKEN
* @param appKey
* @param appSecret
* @return
*/
public String getJwtToken(String appKey, String appSecret) {
String token = JWT.create()
.withIssuer(appKey)
.withIssuedAt(new Date())
.withJWTId(IdUtil.fastSimpleUUID())
.sign(Algorithm.HMAC256(appSecret));
return String.join(" ", "Bearer", token);
return cmpUserResult;
}
/**
@@ -223,7 +216,7 @@ public class SyncIAMTimer {
userEO.setAccount(userVoIAM.getAccount());
userEO.setCellPhoneNumber(userVoIAM.getMobile() == null ? EncryptUtil.encrypt("") : EncryptUtil.encrypt(userVoIAM.getMobile()));
userEO.setCreateTime(userVoIAM.getEnterTime());
userEO.setUpdateTime(userVoIAM.getEnterTime());
userEO.setUpdateTime(DateUtil.formatDateTime(new Date()));
userEO.setEmail(userVoIAM.getEmail() == null ? EncryptUtil.encrypt("") : EncryptUtil.encrypt(userVoIAM.getEmail()));
userEO.setUsname(userVoIAM.getCnName());
userEO.setStatus(userVoIAM.getStatus());
@@ -243,11 +236,12 @@ public class SyncIAMTimer {
// 固定角色数据
List<String> roleIdList = new ArrayList<>();
// TODO 根据level固定为一般管理人员 或 总监
// 配置文件写死几个账号作为管理员,不调整对应的角色
if ("1".equals(userEO.getLevelId()) || "2".equals(userEO.getLevelId()) || "3".equals(userEO.getLevelId()) || "4".equals(userEO.getLevelId())){
roleIdList.add("1");
roleIdList.add("4FWTB649DG");
} else {
roleIdList.add("2");
roleIdList.add("3QD37LZJD6");
}
userEO.setRoleIdList(roleIdList);
@@ -0,0 +1,95 @@
package com.adc.da.sync.service.controller;
import com.adc.da.sync.service.SyncIAMTimer;
import com.adc.da.sys.vo.DictQueryVo;
import com.adc.da.sys.vo.iam.CmpOrgResult;
import com.adc.da.sys.vo.iam.CmpUserResult;
import com.adc.da.util.http.ResponseMessage;
import com.adc.da.util.http.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
/**
* 数据同步测试服务
*/
@Slf4j
@RestController
@RequestMapping("/${restPath}/sync")
@Api(tags = {"数据同步"})
public class SyncController {
@Autowired
private SyncIAMTimer syncIAMTimer;
@ApiOperation(value = "全量同步orgs")
@GetMapping("/full/orgs")
public ResponseMessage syncFullOrgs() {
int pageIndex = 1;
int pageSize = 1000;
CmpOrgResult cmpOrgResult = this.syncIAMTimer.syncOrgIncrData(pageIndex, pageSize);
if (cmpOrgResult != null){
int totalPages = cmpOrgResult.getData().getPages();
for (int i = pageIndex + 1; i <= totalPages; i++){
this.syncIAMTimer.syncOrgIncrData(i, pageSize);
}
}
return Result.success();
}
@ApiOperation(value = "增量同步orgs")
@GetMapping("/incr/orgs")
public ResponseMessage syncIncrOrgs(@RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
if (pageIndex == null || pageIndex == 0){
pageIndex = 1;
}
if (pageSize == null || pageSize == 0){
pageSize = 1000;
}
CmpOrgResult cmpOrgResult = this.syncIAMTimer.syncOrgIncrData(pageIndex, pageSize);
return Result.success(cmpOrgResult);
}
@ApiOperation(value = "全量同步users")
@GetMapping("/full/users")
public ResponseMessage syncFullUsers() {
int pageIndex = 1;
int pageSize = 1000;
CmpUserResult cmpUserResult = this.syncIAMTimer.syncUserIncrData(pageIndex, pageSize, null);
if (cmpUserResult != null){
int totalPages = cmpUserResult.getData().getPages();
for (int i = pageIndex + 1; i <= totalPages; i++){
this.syncIAMTimer.syncUserIncrData(i, pageSize, null);
}
}
return Result.success();
}
@ApiOperation(value = "增量同步users")
@GetMapping("/incr/users")
public ResponseMessage syncIncrUsers(@RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
if (pageIndex == null || pageIndex == 0){
pageIndex = 1;
}
if (pageSize == null || pageSize == 0){
pageSize = 1000;
}
this.syncIAMTimer.syncUserIncrData(pageIndex, pageSize, null);
return Result.success();
}
}
@@ -19,4 +19,6 @@ public interface UserOrgEODao extends BaseMapper<UserOrgEO> {
int insertBatch(@Param("userOrgEOList") List<UserOrgEO> userOrgEOList);
void deleteBatchByUserIds(@Param("userIds") List<String> userIds);
}
@@ -19,4 +19,6 @@ import java.util.List;
public interface UserRoleEODao extends BaseMapper<UserRoleEO> {
int insertBatch(@Param("userRoleEOList") List<UserRoleEO> userRoleEOList);
void deleteBatchByUserIds(@Param("userIds") List<String> userIds);
}
@@ -14,14 +14,24 @@ import com.adc.da.util.exception.AdcDaBaseException;
import com.adc.da.util.utils.CollectionUtils;
import com.adc.da.util.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.session.SqlSession;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;
@@ -42,6 +52,9 @@ public class UserEOServiceImpl implements IUserEoService {
@Value("${isPassEncrypted}")
private boolean isPassEncrypted;
@Value("${user.fix.role}")
private String fixUserAccount; // 同步过来需要固定角色的账号
@Resource
private UserEODao dao;
@@ -128,41 +141,111 @@ public class UserEOServiceImpl implements IUserEoService {
/**
* 同步保存或更新
* @param eo
* @param eoList
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void syncSaveOrUpdate(UserEO eo) {
UserEO userEO = dao.selectById(eo.getUsid());
if (userEO == null) {
this.save(userEO);
} else {
//删除旧的角色
QueryWrapper<UserRoleEO> deleteRoleWapper =new QueryWrapper<>();
deleteRoleWapper.eq("user_id",userEO.getUsid());
userRoleEODao.delete(deleteRoleWapper);
//删除旧的角色
QueryWrapper<UserOrgEO> deleteOrgWapper =new QueryWrapper<>();
deleteOrgWapper.eq("user_id",userEO.getUsid());
userOrgEODao.delete(deleteOrgWapper);
public void syncSaveOrUpdate(List<UserEO> eoList) {
if (eoList == null || eoList.isEmpty()){
throw new AdcDaBaseException("无用户数据取回");
}
// 加入角色关联表
eo.getRoleIdList().forEach(c -> {
UserRoleEO userRoleEO = new UserRoleEO();
userRoleEO.setUserId(eo.getUsid());
userRoleEO.setRoleId(c);
userRoleEODao.insert(userRoleEO);
});
List<UserRoleEO> userRoleEOList = new ArrayList<>();
List<UserOrgEO> userOrgEOList = new ArrayList<>();
// 插入组织关联表
eo.getOrgEOList().forEach(c -> {
UserOrgEO userOrgEO = new UserOrgEO();
userOrgEO.setUserId(eo.getUsid());
userOrgEO.setOrgId(c.getId());
userOrgEODao.insert(userOrgEO);
});
List<String> userIds = new ArrayList<>();
String[] fixAccountArr = fixUserAccount.split(","); //处理固定的数据
List<String> fixAccountList = Arrays.asList(fixAccountArr);
for (UserEO userEO : eoList){
if (!fixAccountList.contains(userEO.getAccount())){
userIds.add(userEO.getUsid());
// 加入角色关联表
userEO.getRoleIdList().forEach(c -> {
UserRoleEO userRoleEO = new UserRoleEO();
userRoleEO.setUserId(userEO.getUsid());
userRoleEO.setRoleId(c);
if (StringUtils.isNotEmpty(userRoleEO.getRoleId())){
userRoleEOList.add(userRoleEO);
}
});
// 插入组织关联表
userEO.getOrgEOList().forEach(c -> {
UserOrgEO userOrgEO = new UserOrgEO();
userOrgEO.setUserId(userEO.getUsid());
userOrgEO.setOrgId(c.getId());
if (StringUtils.isNotEmpty(userOrgEO.getOrgId())){
userOrgEOList.add(userOrgEO);
}
});
}
}
this.saveOrUpdateBatch(eoList, 1000);
//删除旧的角色
userRoleEODao.deleteBatchByUserIds(userIds);
//删除旧的组织
userOrgEODao.deleteBatchByUserIds(userIds);
// 批量插入新角色关联
this.userRoleEODao.insertBatch(userRoleEOList);
// 批量插入新组织关联
this.userOrgEODao.insertBatch(userOrgEOList);
}
protected String sqlStatement(SqlMethod sqlMethod) {
return SqlHelper.table(UserEO.class).getSqlStatement(sqlMethod.getMethod());
}
private boolean saveOrUpdateBatch(List<UserEO> entityList, int batchSize) {
Assert.notEmpty(entityList, "error: entityList must not be empty", new Object[0]);
SqlSession batchSqlSession = SqlHelper.sqlSessionBatch(UserEO.class);
Throwable var7 = null;
try {
int i = 0;
for(UserEO userEO : entityList) {
if (!com.baomidou.mybatisplus.core.toolkit.StringUtils.checkValNull(userEO.getUsid()) && !Objects.isNull(this.getUserById((userEO.getUsid())))) {
MapperMethod.ParamMap<UserEO> param = new MapperMethod.ParamMap();
param.put("et", userEO);
batchSqlSession.update(this.sqlStatement(SqlMethod.UPDATE_BY_ID), param);
} else {
batchSqlSession.insert(this.sqlStatement(SqlMethod.INSERT_ONE), userEO);
}
if (i >= 1 && i % batchSize == 0) {
batchSqlSession.flushStatements();
}
}
batchSqlSession.flushStatements();
return true;
} catch (Throwable var20) {
var7 = var20;
throw var20;
} finally {
if (batchSqlSession != null) {
if (var7 != null) {
try {
batchSqlSession.close();
} catch (Throwable var19) {
var7.addSuppressed(var19);
}
} else {
batchSqlSession.close();
}
}
}
}
@Transactional(rollbackFor = Exception.class)
@@ -32,7 +32,7 @@ public interface IUserEoService {
* 从同步处新增或编辑用户
* @param eo
*/
void syncSaveOrUpdate(UserEO eo);
void syncSaveOrUpdate(List<UserEO> eoList);
UserEO getUserById(String usid);
@@ -0,0 +1,20 @@
package com.adc.da.sys.vo.iam;
import lombok.Data;
import java.util.List;
@Data
public class CmpOrgInnerResult {
private List<OrgVoIAM> records;
private int total; // 返回总条数
private int pageSize;
private int pageIndex;
private int pages; // 总页数
}
@@ -18,6 +18,6 @@ public class CmpOrgResult {
private String traceId;
private List<OrgVoIAM> data;
private CmpOrgInnerResult data;
}
@@ -0,0 +1,20 @@
package com.adc.da.sys.vo.iam;
import lombok.Data;
import java.util.List;
@Data
public class CmpUserInnerResult {
private List<UserVoIAM> records;
private int total; // 返回总条数
private int pageSize;
private int pageIndex;
private int pages; // 总页数
}
@@ -18,6 +18,6 @@ public class CmpUserResult {
private String traceId;
private List<UserVoIAM> data;
private CmpUserInnerResult data;
}
@@ -97,5 +97,13 @@
</foreach>
</insert>
<!-- 批量删除记录 -->
<delete id="deleteBatchByUserIds" parameterType="java.lang.String">
delete from TR_USER_ORG
where user_id in
<foreach collection="userIds" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
</mapper>
@@ -97,5 +97,14 @@
</foreach>
</insert>
<!-- 批量删除记录 -->
<delete id="deleteBatchByUserIds" parameterType="java.lang.String">
delete from TR_USER_ROLE
where user_id in
<foreach collection="userIds" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
</mapper>