Compare commits

..

5 Commits

Author SHA1 Message Date
FCL
b3e11fe92e Merge remote-tracking branch 'origin/test' into test 2025-11-04 18:05:20 +08:00
FCL
536f971e8e feat:tio集群逻辑优化 2025-11-04 18:05:11 +08:00
FCL
e75217009f Merge remote-tracking branch 'origin/test' into test 2025-11-04 08:41:22 +08:00
FCL
b2e275a2d8 fix:报告流程回调优化 2025-11-03 14:00:36 +08:00
FCL
d218383a9a fix:报告流程回调优化 2025-11-03 11:54:58 +08:00
22 changed files with 1025 additions and 327 deletions

View File

@@ -11,6 +11,9 @@ public class QmsBpmConstant {
* 流程回调时使用的ActivityId Key
* */
public static final String BPM_CALLBACK_ACTIVITY_ID = "bpmCallbackActivityId";
public static final String BPM_FIELD_EXTENSIONS = "bpmFieldExtensions";
public static final String BPM_FIRST_ACTIVITY_FLAG = "firstActivityFlag";
public static final String BPM_LAST_ACTIVITY_FLAG = "lastActivityFlag";
//驳回标记前缀
public static final String BPM_CALLBACK_RETURN_FLAG_PREFIX_KEY = "RETURN_FLAG_";

View File

@@ -1,6 +1,7 @@
package com.zt.plat.module.qms.business.reportdoc.service;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.framework.common.pojo.PageResult;
@@ -304,32 +305,50 @@ public class ReportDocumentMainServiceImpl implements ReportDocumentMainService,
public CommonResult<JSONObject> callback(QmsBpmDTO reqDTO) {
JSONObject variables = reqDTO.getVariables();
//流程状态 3-拒绝 1-通过 2-完成 4-取消流程
//流程状态 1-提交(含退回) 4-取消流程
String PROCESS_STATUS = variables.getString(QmsBpmConstant.PROCESS_INSTANCE_VARIABLE_STATUS);
String mainId = variables.getString("mainId");
JSONArray fieldExtensions = new JSONArray();
if(variables.containsKey(QmsBpmConstant.BPM_FIELD_EXTENSIONS)){
fieldExtensions = variables.getJSONArray(QmsBpmConstant.BPM_FIELD_EXTENSIONS);
}
ReportDocumentMainDO entity = getReportDocumentMain(Long.valueOf(mainId));
log.error("流程回调:{}", JSONObject.toJSONString(reqDTO));
String currentActivityId = variables.getString(QmsBpmConstant.BPM_CALLBACK_ACTIVITY_ID);
String RETURN_FLAG_PREFIX_KEY = variables.getString(QmsBpmConstant.BPM_CALLBACK_RETURN_FLAG_PREFIX_KEY);
String RETURN_FLAG_PREFIX_KEY = QmsBpmConstant.BPM_CALLBACK_RETURN_FLAG_PREFIX_KEY;
String returnFlagKey = RETURN_FLAG_PREFIX_KEY + "Activity_001";
// if("3".equals(PROCESS_STATUS)){
//判断是否最后一个节点
String lastActivityFlag = "0";
String firstActivityFlag = "0";
if(!fieldExtensions.isEmpty()){
for(int i = 0; i < fieldExtensions.size(); i++){
JSONObject fieldExtension = fieldExtensions.getJSONObject(i);
if(fieldExtension.getString("fieldName").equals(QmsBpmConstant.BPM_LAST_ACTIVITY_FLAG)){
lastActivityFlag = "1";
}
if(fieldExtension.getString("fieldName").equals(QmsBpmConstant.BPM_FIRST_ACTIVITY_FLAG)){
firstActivityFlag = "1";
}
}
}
//"RETURN_FLAG_Activity_001": true 标识驳回到发起环节
if(variables.containsKey(returnFlagKey) && variables.getString(returnFlagKey).equals("true")){
//拒绝(重制)
entity.setFlowStatus(QmsCommonConstant.REJECTED);
//驳回。流程需要配置退回到发起节点
entity.setFlowStatus(QmsCommonConstant.VOID);
entity.setDocumentSignature("");
}
else if("2".equals(PROCESS_STATUS)){
//完成
entity.setFlowStatus(QmsCommonConstant.COMPLETED);
assembleSignature(currentActivityId, entity);
}
else if("4".equals(PROCESS_STATUS)){
}else if("4".equals(PROCESS_STATUS)){
//作废
entity.setFlowStatus(QmsCommonConstant.VOID);
entity.setDocumentSignature("");
}else if("1".equals(PROCESS_STATUS)){
entity.setDocumentSignature("");
//通过
assembleSignature(currentActivityId, entity);
if("1".equals(firstActivityFlag))
entity.setFlowStatus(QmsCommonConstant.IN_PROGRESS); //驳回后重新提交
if("1".equals(lastActivityFlag))
entity.setFlowStatus(QmsCommonConstant.COMPLETED); //结束审批
}
reportDocumentMainMapper.updateById(entity);
JSONObject ret = new JSONObject();
@@ -337,12 +356,14 @@ public class ReportDocumentMainServiceImpl implements ReportDocumentMainService,
}
private void assembleSignature(String currentActivityId, ReportDocumentMainDO entity){
if(ObjectUtils.isEmpty(currentActivityId) || "null".equals(currentActivityId))
return;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String sign = entity.getDocumentSignature();
JSONObject signObj = new JSONObject();
if(!ObjectUtils.isEmpty( sign))
signObj = JSONObject.parseObject(sign);
if(!signObj.containsKey(currentActivityId))
if(signObj.containsKey(currentActivityId))
return;
JSONObject obj = new JSONObject();
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
@@ -350,6 +371,7 @@ public class ReportDocumentMainServiceImpl implements ReportDocumentMainService,
//当前登录用户昵称
String nickName = SecurityFrameworkUtils.getLoginUserNickname();
ConfigUserSignatureDO configUserSignatureDO = configUserSignatureService.getByUserId(userId);
obj.put("signatureId", "");
if(configUserSignatureDO != null)
obj.put("signatureId", configUserSignatureDO.getId());
obj.put("userId", userId);

View File

@@ -0,0 +1,80 @@
package com.zt.plat.module.qms.iot.service;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.qms.iot.tcpserver.cluster.TioServerMessageConfig;
import com.zt.plat.module.qms.iot.tcpserver.cluster.TioServerMessagePublisher;
import com.zt.plat.module.qms.iot.tcpserver.cluster.TioServerMessageVo;
import com.zt.plat.module.qms.iot.tcpserver.core.IotDeviceSessionContext;
import com.zt.plat.module.qms.iot.tcpserver.device.RedisSessionComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestParam;
import tech.zzjc.tio.core.ChannelContext;
import tech.zzjc.tio.core.Tio;
import tech.zzjc.tio.starter.TioServerBootstrap;
import static java.lang.Thread.sleep;
@Service
public class IotConnectManagerStatsService {
@Autowired
private TioServerBootstrap tioServerBootstrap;
@Autowired public RedisSessionComponent redisSessionComponent;
@Autowired private TioServerMessagePublisher tioServerMessagePublisher;
public CommonResult<?> close(String id, String fromSubscribe) throws InterruptedException {
ChannelContext channelContext = Tio.getByChannelContextId(tioServerBootstrap.getServerTioConfig(), id);
if(channelContext == null){
if("1".equals(fromSubscribe))
return CommonResult.success("ok");
//广播消息处理
TioServerMessageVo message = new TioServerMessageVo();
message.setServerClusterMsgType(TioServerMessageConfig.MESSAGE_TYPE_CLOSE_MANUAL);
message.setChannelId(id);
tioServerMessagePublisher.publish(message);
//延迟0.5秒返回
sleep(500);
return CommonResult.success("ok");
}
IotDeviceSessionContext sessionContext = (IotDeviceSessionContext) channelContext.get(IotDeviceSessionContext.DEFAULT_DEVICE_SESSION_CONTEXT_KEY);
String deviceId = sessionContext.getDeviceId();
if(!ObjectUtils.isEmpty(deviceId))
redisSessionComponent.deleteByDeviceId(deviceId);
Tio.IpBlacklist.clear();//清空全局黑名单
Tio.close(channelContext, "控制端主动关闭连接");
return CommonResult.success("ok");
}
public CommonResult<?> clearDeviceControl(String id, String fromSubscribe) throws InterruptedException {
ChannelContext channelContext = Tio.getByChannelContextId(tioServerBootstrap.getServerTioConfig(), id);
Tio.IpBlacklist.clear();//清空全局黑名单
if(channelContext == null){
if("1".equals(fromSubscribe))
return CommonResult.success("ok");
//广播消息处理
TioServerMessageVo message = new TioServerMessageVo();
message.setServerClusterMsgType(TioServerMessageConfig.MESSAGE_TYPE_CLEAR_MANUAL);
message.setChannelId(id);
tioServerMessagePublisher.publish(message);
//延迟0.5秒返回
sleep(500);
return CommonResult.success("ok");
}
IotDeviceSessionContext deviceSessionContext = (IotDeviceSessionContext) channelContext.get(IotDeviceSessionContext.DEFAULT_DEVICE_SESSION_CONTEXT_KEY);
String deviceId = deviceSessionContext.getDeviceId();
if(!ObjectUtils.isEmpty(deviceId)){
redisSessionComponent.clearControlByDeviceId(deviceId, channelContext);
}
// if(channelContext != null) {
//设置控制点的channelContext
// deviceSessionContext.setControlChannelContext(null);
// deviceSessionContext.setControlRealName("");
// channelContext.set(ChannelContextConstant.CONTROL_DEVICE_ID, "");
// }
return CommonResult.success("ok");
}
}

View File

@@ -86,7 +86,6 @@ public class IotServerAioListener implements ServerAioListener {
if(!ObjectUtils.isEmpty(deviceCode)){
redisSessionComponent.clearControlByDeviceCode(deviceCode.toString(), channelContext);
}
//解绑业务ID
Tio.unbindBsId(channelContext);
//解绑群组

View File

@@ -1,16 +1,19 @@
package com.zt.plat.module.qms.iot.tcpserver.caaclient;
import com.alibaba.fastjson.JSON;
import com.fhs.common.spring.SpringContextUtil;
import com.zt.plat.module.qms.iot.tcpserver.IotPacket;
import com.zt.plat.module.qms.iot.tcpserver.consoleclient.bean.Register;
import com.zt.plat.module.qms.iot.tcpserver.core.ClientType;
import com.zt.plat.module.qms.iot.tcpserver.core.Command;
import com.zt.plat.module.qms.iot.tcpserver.core.ReplyResult;
import com.zt.plat.module.qms.iot.tcpserver.device.RedisSessionComponent;
import com.zt.plat.module.qms.iot.tcpserver.handler.IotDataHander;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import tech.zzjc.tio.core.ChannelContext;
import tech.zzjc.tio.core.Tio;
import tech.zzjc.tio.utils.SystemTimer;
import java.nio.charset.Charset;
import java.util.Date;
@@ -34,11 +37,7 @@ public class IotCaaClientRegisterHander implements IotDataHander {
@Override
public Object hander(String msgId, String data, ChannelContext channelContext) throws Exception {
Register register = JSON.parseObject(data, Register.class);
//获取客户端连接信息
String realClientIp = channelContext.get("realClientIp") == null ? channelContext.getClientNode().getIp() : channelContext.get("realClientIp").toString();
String realClientPort = channelContext.get("realClientPort") == null ? channelContext.getClientNode().getPort() + "" : channelContext.get("realClientPort").toString();
String realClient = realClientIp + ":" + realClientPort;
log.info("{}, APP客户端注册租户ID{}用户ID{}", realClient, register.getTenantId(), register.getUserId());
Tio.bindUser(channelContext, register.getUserId());
Tio.bindToken(channelContext, register.getUserId());
channelContext.set("regTime", new Date());
@@ -49,6 +48,15 @@ public class IotCaaClientRegisterHander implements IotDataHander {
Tio.send(channelContext, resppacket);
//绑定群组
Tio.bindGroup(channelContext, CAA_ALL_CLIENT);
//在redis记录客户端信息
// RedisSessionComponent redisSessionComponent = (RedisSessionComponent) SpringContextUtil.getBean("redisSessionComponent");
// redisSessionComponent.regClient(channelContext);
//
return null;
}

View File

@@ -24,7 +24,8 @@ public class ControlDevice implements Serializable {
/** 控制者姓名 **/
private String controlRealName;
private String controlUserId;
/** 是否控制 **/
private Boolean isControl;
@@ -33,4 +34,7 @@ public class ControlDevice implements Serializable {
/** 回复app时使用 消息 **/
private String msg;
/** 来自消息订阅 **/
private String fromSubscribe;
}

View File

@@ -0,0 +1,20 @@
package com.zt.plat.module.qms.iot.tcpserver.cluster;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component
public class InstanceIdProvider {
private final String instanceId;
public InstanceIdProvider() {
//使用随机 UUID每次重启会变
this.instanceId = UUID.randomUUID().toString();
}
public String getInstanceId() {
return instanceId;
}
}

View File

@@ -0,0 +1,16 @@
package com.zt.plat.module.qms.iot.tcpserver.cluster;
public class TioServerMessageConfig {
public static final String SERVER_CLUSTER_TOPIC_CHANNEL = "zzjc-cluster-tio-server";
public static final String MESSAGE_TYPE_CONTROL = "control"; //设备控制消息
public static final String MESSAGE_TYPE_CLEAR_MANUAL = "clearControlManual"; //手动清除控制
public static final String MESSAGE_TYPE_CLOSE_MANUAL = "closeManual"; //手动断开连接
public static final String MESSAGE_TYPE_NOTICE = "notice"; //通知消息。应该用不到。
}

Some files were not shown because too many files have changed in this diff Show More