From 34981c30a78e8bbd7791131059a9210f9928b62c Mon Sep 17 00:00:00 2001
From: 刘光辉 <347230014@qq.com>
Date: 星期四, 17 九月 2026 09:24:09 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master' into master
---
jnpf-flowable/jnpf-flowable-biz/src/main/java/jnpf/flowable/job/AutoTransferJob.java | 242 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 242 insertions(+), 0 deletions(-)
diff --git a/jnpf-flowable/jnpf-flowable-biz/src/main/java/jnpf/flowable/job/AutoTransferJob.java b/jnpf-flowable/jnpf-flowable-biz/src/main/java/jnpf/flowable/job/AutoTransferJob.java
new file mode 100644
index 0000000..0a3b85e
--- /dev/null
+++ b/jnpf-flowable/jnpf-flowable-biz/src/main/java/jnpf/flowable/job/AutoTransferJob.java
@@ -0,0 +1,242 @@
+package jnpf.flowable.job;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import jnpf.base.ActionResult;
+import jnpf.base.UserInfo;
+import jnpf.config.ConfigValueUtil;
+import jnpf.database.util.TenantDataSourceUtil;
+import jnpf.flowable.entity.OperatorEntity;
+import jnpf.flowable.entity.RecordEntity;
+import jnpf.flowable.entity.TaskEntity;
+import jnpf.flowable.enums.OperatorEnum;
+import jnpf.flowable.enums.OperatorStateEnum;
+import jnpf.flowable.model.task.FlowModel;
+import jnpf.flowable.model.templatenode.nodejson.NodeModel;
+import jnpf.flowable.model.templatenode.nodejson.TemplateJsonModel;
+import jnpf.flowable.model.templatenode.nodejson.TimeConfig;
+import jnpf.flowable.model.time.FlowTimeModel;
+import jnpf.flowable.service.OperatorService;
+import jnpf.flowable.service.TaskService;
+import jnpf.flowable.util.*;
+import jnpf.permission.entity.UserEntity;
+import jnpf.util.AuthUtil;
+import jnpf.util.RedisUtil;
+import jnpf.util.StringUtil;
+import jnpf.util.UserProvider;
+import jnpf.util.context.SpringContext;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+/**
+ * 绫荤殑鎻忚堪
+ *
+ * @author JNPF@YinMai Info. Co., Ltd
+ * @version 5.0.x
+ * @since 2024/12/10 9:17
+ */
+@Slf4j
+public class AutoTransferJob extends QuartzJobBean {
+ private static RedisUtil redisUtil;
+ private static ConfigValueUtil configValueUtil;
+ private static OperatorService operatorService;
+ private static TaskService taskService;
+ private static ServiceUtil serviceUtil;
+ private static FlowUtil flowUtil;
+ private static RedisLock redisLock;
+ private static OperatorUtil operatorUtil;
+
+ static {
+ redisUtil = SpringContext.getBean(RedisUtil.class);
+ configValueUtil = SpringContext.getBean(ConfigValueUtil.class);
+ operatorService = SpringContext.getBean(OperatorService.class);
+ taskService = SpringContext.getBean(TaskService.class);
+ serviceUtil = SpringContext.getBean(ServiceUtil.class);
+ flowUtil = SpringContext.getBean(FlowUtil.class);
+ redisLock = SpringContext.getBean(RedisLock.class);
+ operatorUtil = SpringContext.getBean(OperatorUtil.class);
+ }
+
+ @Override
+ protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
+ List<FlowTimeModel> list = FlowJobUtil.getTransfer(redisUtil);
+ if (CollUtil.isNotEmpty(list)) {
+ Set<String> nodeCodes = new TreeSet<>();
+ for (FlowTimeModel timeModel : list) {
+ FlowModel flowModel = timeModel.getFlowModel();
+
+ UserInfo userInfo = flowModel.getUserInfo();
+ if (configValueUtil.isMultiTenancy()) {
+ TenantDataSourceUtil.switchTenant(userInfo.getTenantId());
+ }
+
+ String operatorId = timeModel.getOperatorId();
+
+ boolean lock = redisLock.lock("transfer-" + operatorId, operatorId, 5, TimeUnit.SECONDS);
+ if (lock) {
+
+
+ String nodeCode = flowModel.getNodeCode();
+
+ Map<String, Object> formData = flowModel.getFormData();
+ Map<String, NodeModel> nodes = flowModel.getNodes();
+
+ NodeModel nodeModel = nodes.get(nodeCode);
+ TimeConfig config = nodeModel.getOverTimeConfig();
+
+ OperatorEntity operator = operatorService.getById(operatorId);
+ if (null == operator || operator.getHandleStatus() != null) {
+ TimeUtil.deleteJob(timeModel.getId());
+ FlowJobUtil.remove(timeModel, redisUtil);
+ continue;
+ }
+ boolean next = true;
+ if (ObjectUtil.equals(config.getOverTimeType(), OperatorEnum.NOMINATOR.getCode()) || ObjectUtil.equals(config.getOverTimeType(), OperatorEnum.SERVE.getCode())) {
+ if (nodeCodes.contains(flowModel.getNodeCode())) {
+ log.info("鑷姩杞澶辫触锛岃缁忓姙宸插鐞嗭紙id锛�" + operatorId + "锛宑ode锛�" + nodeCode + "锛�");
+ FlowJobUtil.removeTransfer(timeModel, redisUtil);
+ next = false;
+ }
+ nodeCodes.add(nodeCode);
+ }
+
+ if (ObjectUtil.equals(operator.getStatus(), OperatorStateEnum.TRANSFER.getCode())) {
+ log.info("杞鐘舵�佺殑缁忓姙锛屼笉鎵ц: " + operator.getId());
+ FlowJobUtil.removeTransfer(timeModel, redisUtil);
+ next = false;
+ }
+ // 鎸囨淳绫诲瀷鐨勮浆瀹★紝鍒ゆ柇鏁翠釜鑺傜偣 鏄惁瀛樺湪杞绫诲瀷鐨勭粡鍔�
+ if (ObjectUtil.equals(config.getOverTimeType(), OperatorEnum.NOMINATOR.getCode()) || ObjectUtil.equals(config.getOverTimeType(), OperatorEnum.SERVE.getCode())) {
+ QueryWrapper<OperatorEntity> queryWrapper = new QueryWrapper<>();
+ queryWrapper.lambda().eq(OperatorEntity::getTaskId, operator.getTaskId()).eq(OperatorEntity::getNodeId, operator.getNodeId())
+ .eq(OperatorEntity::getStatus, OperatorStateEnum.TRANSFER.getCode());
+ long count = operatorService.count(queryWrapper);
+ if (count > 0) {
+ log.info("鑺傜偣瀛樺湪杞鐘舵�佺殑缁忓姙锛屼笉鎵ц: " + operator.getId() + " " + operator.getNodeId());
+ FlowJobUtil.removeTransfer(timeModel, redisUtil);
+ next = false;
+ }
+ }
+
+
+ String userId = operator.getHandleId();
+ UserEntity user = serviceUtil.getUserInfo(userId);
+ if (null != user) {
+ String token = AuthUtil.loginTempUser(userId, userInfo.getTenantId());
+ userInfo.setUserId(user.getId());
+ userInfo.setUserName(user.getRealName());
+ userInfo.setUserAccount(user.getAccount());
+ userInfo.setToken(token);
+ UserProvider.setLoginUser(userInfo);
+ UserProvider.setLocalLoginUser(userInfo);
+ }
+
+ try {
+ if (next) {
+ TaskEntity taskEntity = taskService.getById(operator.getTaskId());
+ if (null == taskEntity) {
+ taskEntity = flowModel.getTaskEntity();
+ }
+ String handleIds = null;
+ if (ObjectUtil.equals(config.getOverTimeType(), OperatorEnum.NOMINATOR.getCode())) {
+ // 鎸囧畾浜哄憳
+ // 349057407209541--user
+ if (CollUtil.isNotEmpty(config.getReApprovers())) {
+ String handleId = config.getReApprovers().get(0).split("--")[0];
+ UserEntity userEntity = serviceUtil.getUserInfo(handleId);
+ if (!ObjectUtil.equals(userId, handleId) && null != userEntity && ObjectUtil.equals(userEntity.getEnabledMark(), 1)) {
+ handleIds = handleId;
+ }
+ }
+ if (StringUtil.isNotEmpty(handleIds)) {
+ flowModel.setHandleIds(handleIds);
+ flowModel.setAutoTransferFlag(true);
+ taskService.assign(operator.getTaskId(), flowModel);
+ this.delete(timeModel);
+ }
+ } else if (ObjectUtil.equals(config.getOverTimeType(), OperatorEnum.SERVE.getCode())) {
+ // 鎺ュ彛
+ String interfaceId = config.getInterfaceId();
+ List<TemplateJsonModel> templateJson = config.getTemplateJson();
+ if (StringUtil.isNotEmpty(interfaceId)) {
+ RecordEntity recordEntity = new RecordEntity();
+ recordEntity.setTaskId(taskEntity.getId());
+ recordEntity.setNodeCode(operator.getNodeCode());
+ recordEntity.setHandleId(operator.getHandleId());
+ FlowModel parameterModel = new FlowModel();
+ parameterModel.setFormData(formData);
+ parameterModel.setRecordEntity(recordEntity);
+ parameterModel.setTaskEntity(taskEntity);
+ Map<String, String> parameterMap = flowUtil.parameterMap(parameterModel, templateJson);
+ ActionResult<Object> result = serviceUtil.infoToId(interfaceId, parameterMap);
+ if (Objects.equals(200, result.getCode())) {
+ Object data = result.getData();
+ if (data instanceof Map) {
+ JSONObject map = new JSONObject((Map) data);
+ List<String> handleId = StringUtil.isNotEmpty(map.getString("handleId")) ? Arrays.asList(map.getString("handleId").split(",")) : new ArrayList<>();
+ handleId = serviceUtil.getUserName(handleId, true)
+ .stream().map(UserEntity::getId).filter(e -> !ObjectUtil.equals(userId, e)).sorted().collect(Collectors.toList());
+ handleIds = CollUtil.isNotEmpty(handleId) ? handleId.get(0) : null;
+ }
+ }
+ if (StringUtil.isNotEmpty(handleIds)) {
+ flowModel.setHandleIds(handleIds);
+ flowModel.setAutoTransferFlag(true);
+ taskService.assign(operator.getTaskId(), flowModel);
+ this.delete(timeModel);
+ }
+ }
+ } else {
+ // 瓒呮椂瀹℃壒浜猴紝2.鍚屼竴閮ㄩ棬 7.鍚屼竴瑙掕壊 3.鍚屼竴宀椾綅 8.鍚屼竴鍒嗙粍
+ UserEntity userEntity = serviceUtil.getUserInfo(userId);
+ if (null != userEntity) {
+ Integer overTimeExtraRule = config.getOverTimeExtraRule();
+ List<String> userIds = new ArrayList<>();
+ operatorUtil.getByRule(userIds, userEntity, overTimeExtraRule);
+ userIds = serviceUtil.getUserName(userIds, true)
+ .stream().map(UserEntity::getId).filter(e -> !ObjectUtil.equals(userId, e)).sorted().collect(Collectors.toList());
+ if (CollUtil.isNotEmpty(userIds)) {
+ handleIds = userIds.get(0);
+ }
+ }
+ if (StringUtil.isNotEmpty(handleIds)) {
+ flowModel.setHandleIds(handleIds);
+ if (operator.getSignTime() == null) {
+ operator.setSignTime(new Date());
+ }
+ if (operator.getStartHandleTime() == null) {
+ operator.setStartHandleTime(new Date());
+ }
+ operatorService.updateById(operator);
+ flowModel.setAutoTransferFlag(true);
+ operatorService.transfer(operatorId, flowModel);
+ this.delete(timeModel);
+ operatorUtil.handleOperator();
+ operatorUtil.launchTrigger(flowModel);
+ }
+ }
+ }
+ } catch (Exception e) {
+ log.error("瓒呮椂鑷姩杞寮傚父", e);
+ this.delete(timeModel);
+ } finally {
+ FlowJobUtil.removeTransfer(timeModel, redisUtil);
+ }
+ }
+ }
+ }
+ }
+
+ private void delete(FlowTimeModel timeModel) {
+ TimeUtil.deleteJob(timeModel.getId());
+ FlowJobUtil.remove(timeModel, redisUtil);
+ }
+}
--
Gitblit v1.8.0