diff --git a/tyr-server/pom.xml b/tyr-server/pom.xml
index 1a4cc423..3c2ab346 100644
--- a/tyr-server/pom.xml
+++ b/tyr-server/pom.xml
@@ -95,6 +95,12 @@
feign-httpclient
${feign-httpclient.version}
+
+
+ cn.axzo.maokai
+ maokai-api
+
+
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/job/UserRoleRelationCleanJob.java b/tyr-server/src/main/java/cn/axzo/tyr/server/job/UserRoleRelationCleanJob.java
index 253fe135..d4a191f9 100644
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/job/UserRoleRelationCleanJob.java
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/job/UserRoleRelationCleanJob.java
@@ -1,8 +1,17 @@
package cn.axzo.tyr.server.job;
+import cn.axzo.basics.common.BeanMapper;
+import cn.axzo.maokai.api.client.CooperateShipQueryApi;
+import cn.axzo.maokai.api.vo.request.PersonIdentityCheckReq;
+import cn.axzo.pokonyan.config.redis.RedisUtil;
+import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao;
+import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
+import cn.axzo.tyr.server.util.RpcInternalUtil;
import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.XxlJob;
@@ -17,11 +26,9 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.TimeUnit;
/**
* 用户角色关系清理任务
@@ -33,38 +40,59 @@ import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class UserRoleRelationCleanJob extends IJobHandler {
+
+ private static final String CACHE_KEY = "tyr:job:u-r-r-c";
private volatile boolean runFlag = false;
@Qualifier("userRoleCleanExecutor")
@Autowired
private ExecutorService userRoleCleanExecutor;
+ @Autowired
+ private SaasRoleUserRelationDao roleUserRelationDao;
+
+ @Autowired
+ private CooperateShipQueryApi cooperateShipQueryApi;
+
@XxlJob("userRoleRelationCleanJob")
@Override
public ReturnT execute(String param) throws Exception {
+ StopWatch watch = new StopWatch("userRoleRelationCleanJob");
XxlJobLogger.log("start user role relation clean job param:{}", param);
CleanTarget cleanParam = parseParam(param);
+ //加载待处理数据
+ watch.start("load data");
+ loadCleanTarget(cleanParam);
+ watch.stop();
+ watch.start("check clean");
runFlag = true;
- Integer page = 1;
while (runFlag) {
- List targetList = pullCleanTarget(cleanParam, page);
- if (CollectionUtil.isEmpty(targetList)) {
- XxlJobLogger.log("no target need to clean");
- break;
- }
- for (CleanTarget target : targetList) {
- CompletableFuture.runAsync(() -> doClean(target), userRoleCleanExecutor);
+ CleanTarget target = getTarget();
+ if (target == null) {
+ XxlJobLogger.log("all clean target are processed");
}
+ //数据库并发锁?
+ CompletableFuture.runAsync(() -> doClean(target), userRoleCleanExecutor);
}
+ watch.stop();
-
- XxlJobLogger.log("user role relation clean job finish");
+ XxlJobLogger.log("user role relation clean job finish, cost:{} s", watch.getTotalTimeSeconds());
return ReturnT.SUCCESS;
}
+ private CleanTarget getTarget() {
+ try {
+ String cacheTarget = RedisUtil.ListOps.lRightPop(CACHE_KEY);
+ return StrUtil.isBlank(cacheTarget) ? null : JSON.parseObject(cacheTarget, CleanTarget.class);
+ } catch (Exception ex) {
+ XxlJobLogger.log("get cached data error:{}", ex.getMessage());
+ }
+ return null;
+ }
+
@Override
public void destroy() throws InvocationTargetException, IllegalAccessException {
this.runFlag = false;
@@ -73,16 +101,49 @@ public class UserRoleRelationCleanJob extends IJobHandler {
private void doClean(CleanTarget target) {
try {
- TimeUnit.SECONDS.sleep(5);
+ //检查person profile是否存在 ?
+ //检查人是否还在工作台
+ PersonIdentityCheckReq checkReq = BeanMapper.copyBean(target, PersonIdentityCheckReq.class);
+ Boolean exists = RpcInternalUtil.rpcProcessor(() -> cooperateShipQueryApi.checkPersonIdentity(checkReq),
+ "check identity in workspace", checkReq).getData();
+ if (exists) {
+ return;
+ }
+ XxlJobLogger.log("---------> user role relation need to clean for:{} <----------", JSON.toJSONString(target));
+ roleUserRelationDao.cleanTargetRelation(target);
} catch (Exception ex) {
XxlJobLogger.log("clean target:{} error", JSON.toJSONString(target));
log.warn("clean target:{} error", JSON.toJSONString(target), ex);
}
}
- private List pullCleanTarget(CleanTarget cleanParam, Integer page) {
- XxlJobLogger.log("get bat clean target, page:{}", page);
- return Collections.singletonList(new CleanTarget());
+ private void loadCleanTarget(CleanTarget cleanParam) {
+ XxlJobLogger.log("clear cache data");
+ RedisUtil.KeyOps.delete(CACHE_KEY);
+ XxlJobLogger.log("load all clean target data from db");
+ SaasRoleUserRelation condition = new SaasRoleUserRelation();
+ condition.setOuId(cleanParam.getOuId());
+ condition.setWorkspaceId(cleanParam.getWorkspaceId());
+ condition.setNaturalPersonId(cleanParam.getPersonId());
+ int page = 1;
+ int count = 0;
+ while (true) {
+ Page pageResult = roleUserRelationDao.batListCleanRelation(condition, new Page<>(page++, 20));
+ List records = pageResult.getRecords();
+ if (CollectionUtil.isEmpty(records)) {
+ break;
+ }
+ count += records.size();
+ records.forEach(r -> RedisUtil.ListOps.lLeftPush("key", JSON.toJSONString(CleanTarget.builder()
+ .ouId(r.getOuId())
+ .workspaceId(r.getWorkspaceId())
+ .personId(r.getNaturalPersonId())
+ .identityId(r.getIdentityId())
+ .identityType(r.getIdentityType())
+ .build())));
+ }
+
+ XxlJobLogger.log("all target need to check count:{}", count);
}
private CleanTarget parseParam(String param) {
@@ -98,10 +159,14 @@ public class UserRoleRelationCleanJob extends IJobHandler {
@AllArgsConstructor
public static class CleanTarget {
- private Long personId;
-
private Long ouId;
private Long workspaceId;
+
+ private Long personId;
+
+ private Long identityId;
+
+ private Integer identityType;
}
}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleUserRelationDao.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleUserRelationDao.java
index 0bdd62a3..4f3994e6 100644
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleUserRelationDao.java
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/dao/SaasRoleUserRelationDao.java
@@ -6,12 +6,16 @@ import cn.axzo.tyr.client.common.enums.RoleResourceTypeEnum;
import cn.axzo.tyr.client.model.BaseWorkspaceModel;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.roleuser.dto.IdentityInfo;
+import cn.axzo.tyr.server.job.UserRoleRelationCleanJob;
import cn.axzo.tyr.server.model.RoleUserInfo;
import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository;
@@ -166,5 +170,17 @@ public class SaasRoleUserRelationDao extends ServiceImpl batListCleanRelation(SaasRoleUserRelation cleanParam, IPage page) {
+
+ return this.baseMapper.batListCleanRelation(page, cleanParam);
+ }
+
+ public void cleanTargetRelation(UserRoleRelationCleanJob.CleanTarget target) {
+ this.remove(new LambdaQueryWrapper()
+ .eq(SaasRoleUserRelation::getOuId, target.getOuId())
+ .eq(SaasRoleUserRelation::getWorkspaceId, target.getWorkspaceId())
+ .eq(SaasRoleUserRelation::getIdentityId, target.getIdentityId())
+ .eq(SaasRoleUserRelation::getIdentityType, target.getIdentityType()));
+ }
}
diff --git a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleUserRelationMapper.java b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleUserRelationMapper.java
index 60dd9d61..7547cf51 100644
--- a/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleUserRelationMapper.java
+++ b/tyr-server/src/main/java/cn/axzo/tyr/server/repository/mapper/SaasRoleUserRelationMapper.java
@@ -1,12 +1,15 @@
package cn.axzo.tyr.server.repository.mapper;
-import cn.axzo.tyr.server.repository.entity.SaasRole;
import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
@Mapper
public interface SaasRoleUserRelationMapper extends BaseMapper {
+ Page batListCleanRelation(IPage page, @Param("param") SaasRoleUserRelation cleanParam);
}
diff --git a/tyr-server/src/main/resources/mapper/SaasRoleUserRelationMapper.xml b/tyr-server/src/main/resources/mapper/SaasRoleUserRelationMapper.xml
new file mode 100644
index 00000000..7a559ebe
--- /dev/null
+++ b/tyr-server/src/main/resources/mapper/SaasRoleUserRelationMapper.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
\ No newline at end of file