1、实现万用token(0000-0000-1234-9876-5);
2、web端单独实现命令结果等待器,并修改相关部分;
3、web端实现透传命令;
4、修改一些不当注释;
5、优化一些代码。
14个文件已修改
4个文件已添加
535 ■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Data.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1/DataV1.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V2/DataV2.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/DataV202404.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComResultWait.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComSupport.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/CommandSv.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/rtuMw/Web2RtuMw.java 62 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/local/ReturnCommand.java 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/web/com/CommandCtrl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandResultCtrl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/ComTransCtrl.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/ComTransDto.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/ComTransParam.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/ComTransSv.java 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandResultCtrl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Data.java
@@ -18,7 +18,7 @@
    public String protocol ;//数据所对应的协议名称
    public Short  protocolVer;//数据所对应的协议版本号(1~255)
    public String code ;//数据所对应的功能码:
    public Object subData ;//对应各个功能码的具体数据
    public Object subData ;//对应各个协议数据
    public String hex ;//上报数据的十六进制
    public String toString() {
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1/DataV1.java
@@ -9,7 +9,7 @@
    
    public String rtuAddr ;//RtuAddr
    public Object subData ;
    public Object subData ;;//功能码数据
    public String dt ;//通信中间件产生的收报时间(yyyy-MM-dd hh:mm:ss)
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V2/DataV2.java
@@ -9,7 +9,7 @@
    
    public String rtuAddr ;//RtuAddr
    public Object subData ;
    public Object subData ;//功能码数据
    public String dt ;//通信中间件产生的收报时间(yyyy-MM-dd hh:mm:ss)
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/DataV202404.java
@@ -9,7 +9,7 @@
    
    public String rtuAddr ;//RtuAddr
    public Object subData ;
    public Object subData ;//功能码数据
    public String dt ;//通信中间件产生的收报时间(yyyy-MM-dd hh:mm:ss)
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComResultWait.java
New file
@@ -0,0 +1,28 @@
package com.dy.pipIrrGlobal.command;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
/**
 * @Author: liurunyu
 * @Date: 2025/5/6 16:33
 * @Description
 */
public class ComResultWait {
    //ConcurrentHashMap是线程安全的
    private static final Map<Long, CompletableFuture> features = new ConcurrentHashMap<>();
    public static void put(Long key, CompletableFuture value) {
        features.put(key, value);
    }
    public static CompletableFuture get(Long key) {
        return features.get(key);
    }
    public static void remove(Long key){
        features.remove(key) ;
    }
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/ComSupport.java
@@ -66,10 +66,6 @@
    protected String commandTypeOuter = CommandType.outerCommand;
    // 存储实例化的 CompletableFuture<Data> 对象
    protected static Map<Long, Object> features = new HashMap<>();
    //protected static Boolean setuped = false;
    @Autowired
    private RestTemplate restTemplate;
@@ -212,19 +208,19 @@
     */
    protected BaseResponse<Data> dealWithCallBack(Long comId, Command com) {
        CompletableFuture<JSONObject> feature = new CompletableFuture<>();
        features.put(comId, feature);
        ComResultWait.put(comId, feature);
        try {
            // 发送命令
            JSONObject response_SendCom = (JSONObject) JSON.toJSON(sendCom2Mw(com));
            if (response_SendCom == null || !response_SendCom.getString("code").equals("0001")) {
                // 请求失败,RTU未上线,清除feature
                features.remove(comId);
                ComResultWait.remove(comId);
                JSONObject job_param = response_SendCom.getJSONObject("content").getJSONObject("param");
                return BaseResponseUtils.buildErrorMsg(job_param.getString("message"));
            }
            JSONObject resultData = feature.get(180, TimeUnit.SECONDS);
            features.remove(comId);
            ComResultWait.remove(comId);
            Long commandId = resultData.getLong("commandId");
            if (commandId.equals(comId)) {
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/CommandSv.java
New file
@@ -0,0 +1,146 @@
package com.dy.pipIrrGlobal.command;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol.CommandBackParam;
import com.dy.common.mw.protocol.p206V1.CodeV1;
import com.dy.common.mw.protocol.p206V1.ProtocolConstantV206V1;
import com.dy.common.mw.protocol.p206V2.CodeV2;
import com.dy.common.mw.protocol.p206V2.ProtocolConstantV206V2;
import com.dy.common.mw.protocol.p206V202404.CodeV202404;
import com.dy.common.mw.protocol.p206V202404.ProtocolConstantV206V202404;
import com.dy.common.webUtil.BaseResponse;
import com.dy.pipIrrGlobal.daoPr.PrControllerMapper;
import com.dy.pipIrrGlobal.daoRm.RmCommandHistoryMapper;
import com.dy.pipIrrGlobal.pojoPr.PrController;
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import com.dy.pipIrrGlobal.rtuMw.Web2RtuMw;
import java.util.Date;
/**
 * @Author: liurunyu
 * @Date: 2025/5/6 11:41
 * @Description
 */
public class CommandSv extends Web2RtuMw {
    /**
     * 从数据库中查询控制器对象
     * @param prControllerDao
     * @param intakeId
     * @return
     */
    public PrController getRtu(PrControllerMapper prControllerDao, Long intakeId){
        return prControllerDao.getRtu(intakeId, null);
    }
    /**
     * 检查协议是否支持
     * @param ctrlPo
     * @return
     */
    public String checkProtocol(PrController ctrlPo){
        if(!ctrlPo.getProtocol().equals(ProtocolConstantV206V1.protocolName)
                && !ctrlPo.getProtocol().equals(ProtocolConstantV206V2.protocolName)
                && !ctrlPo.getProtocol().equals(ProtocolConstantV206V202404.protocolName)) {
            return "对应控制器协议" + ctrlPo.getProtocol() + "未实现命令发送逻辑" ;
        }
        return null ;
    }
    /**
     * 根据协议获取命令名称
     * @param nowComCode
     * @param ctrlPo
     * @return
     */
    public String getCommandName(String nowComCode, PrController ctrlPo){
        if(ctrlPo.getProtocol().equals(ProtocolConstantV206V1.protocolName)) {
            return CodeV1.getCodeName(nowComCode) ;
        }else if(ctrlPo.getProtocol().equals(ProtocolConstantV206V2.protocolName)) {
            return CodeV2.getCodeName(nowComCode) ;
        }else if(ctrlPo.getProtocol().equals(ProtocolConstantV206V202404.protocolName)) {
            return CodeV202404.getCodeName(nowComCode) ;
        }
        return null ;
    }
    /**
     * 保存命令历史记录
     * @param rmCommandHistoryDao
     * @param comId
     * @param protocol
     * @param commandCode
     * @param commandName
     * @param intakeId
     * @param rtuAddr
     * @param param
     * @param operator
     * @return
     */
    public RmCommandHistory saveComHistoryPo(RmCommandHistoryMapper rmCommandHistoryDao,
                                             Long comId,
                                             String protocol,
                                             String commandCode,
                                             String commandName,
                                             Long intakeId,
                                             String rtuAddr,
                                             Object param,
                                             Long operator) {
        RmCommandHistory po = new RmCommandHistory();
        po.setComId(comId);
        po.setCommandCode(commandCode);
        po.setCommandName(commandName);
        po.setIntakeId(intakeId);
        po.setRtuAddr(rtuAddr);
        po.setProtocol(protocol);
        po.setParam((JSONObject) JSON.toJSON(param));
        po.setSendTime(new Date());
        po.setOperator(operator);
        rmCommandHistoryDao.insertSelective(po) ;
        return po;
    }
    /**
     * 处理通信中间件返回的命令处理结果
     * @param res
     * @return
     */
    public String dealMwDealResponse(BaseResponse res){
        if(res != null){
            Command reCom = JSON.parseObject(res.getContent() == null ? null : JSON.toJSONString(res.getContent()), Command.class) ;
            CommandBackParam bakParam = JSON.parseObject((reCom== null || reCom.param == null) ? null : JSON.toJSONString(reCom.param), CommandBackParam.class) ;
            if(res.isSuccess()){
                if(bakParam != null){
                    if(bakParam.getSuccess().booleanValue()){
                        //通信中间件成功处理了命令
                        //等待控制器接收并执行命令后的应答,然后通信中间件通知本模块
                        return null ;
                    }else{
                        return "通信中间件处理命令失败,失败信息:" + bakParam.getMessage();
                    }
                }else{
                    return "通信中间件返回命令结果中不包含CommandBackParam类型参数";
                }
            }else{
                if(bakParam != null){
                    if(bakParam.getSuccess().booleanValue()){
                        //通信中间件成功处理了命令
                        //等待控制器接收并执行命令后的应答,然后通信中间件通知本模块
                        return "通信中间件处理命令失败,失败信息:" + (res.getMsg() == null? "" : ("," + res.getMsg())) ;
                    }else{
                        return "通信中间件处理命令失败,失败信息:" + bakParam.getMessage();
                    }
                }else{
                    return "通信中间件处理命令失败,失败信息:" + (res.getMsg() == null? "" : ("," + res.getMsg())) ;
                }
            }
        }else{
            return "通信中间件返回命令结果为null";
        }
    }
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/rtuMw/Web2RtuMw.java
@@ -31,20 +31,20 @@
    private static final String pro_mw = "mw";
    private static final String pro_url = "url";
    protected static final String ContextComSend = "/rtuMw/com/send";
    public static final String ContextComSend = "/rtuMw/com/send";
    protected static final String ContextRtuLogFile = "/rtuMw/com/rtuLogFile";
    protected static final String ContextRtuLogText = "/rtuMw/com/rtuLogText";
    public static final String ContextRtuLogFile = "/rtuMw/com/rtuLogFile";
    public static final String ContextRtuLogText = "/rtuMw/com/rtuLogText";
    protected static final String ContextRegisterMsReceiverWebUrl = "/rtuMw/com/registerMsReceiverWebUrl";
    protected static final String ContextUgTaskSend = "/rtuMw/com/upgradeRtu";
    protected static final String ContextUgForceOver = "/rtuMw/com/ugForceOver";
    public static final String ContextRegisterMsReceiverWebUrl = "/rtuMw/com/registerMsReceiverWebUrl";
    public static final String ContextUgTaskSend = "/rtuMw/com/upgradeRtu";
    public static final String ContextUgForceOver = "/rtuMw/com/ugForceOver";
    /**
     * 得到向通信中间件发送数据的URL
     * @param env
     * @return
     */
    protected String get2MwUrl(Environment env) {
    public String get2MwUrl(Environment env) {
        return env.getProperty(pro_mw + "." + DataSourceContext.get() + "." + pro_url);
    }
    /**
@@ -53,76 +53,76 @@
     * @param orgTag
     * @return
     */
    protected String get2MwUrl(Environment env, String orgTag) {
    public String get2MwUrl(Environment env, String orgTag) {
        return env.getProperty(pro_mw + "." + orgTag + "." + pro_url);
    }
    /**
     * 得到向通信中间件发送强制停止升级的命令URL
     * 得到向通信中间件发送数据的URL
     * @param env
     * @param context
     * @return
     */
    protected String get2MwRequestUrl(Environment env, String context) {
    public String get2MwRequestUrl(Environment env, String context) {
        return get2MwUrl(env) + context;
    }
    /**
     * 得到向通信中间件发送强制停止升级的命令URL
     * 得到向通信中间件发送数据的URL
     * @param env
     * @param orgTag
     * @param context
     * @return
     */
    protected String get2MwRequestUrl(Environment env, String orgTag, String context) {
    public String get2MwRequestUrl(Environment env, String orgTag, String context) {
        return get2MwUrl(env, orgTag) + context;
    }
    /**
     * 向通信中间件发送rtu远程升级任务
     * 向通信中间件发送Post请求
     * @param restTemplate SpringBoot的RestTemplate
     * @param toMwUrl 到通信中间件的web请求Url
     * @param body 请求数据
     * @param body 数据
     * @return
     */
    protected BaseResponse sendPostRequest2Mw(RestTemplate restTemplate, String toMwUrl, Object body) {
    public BaseResponse sendPostRequest2Mw(RestTemplate restTemplate, String toMwUrl, Object body) {
        String url = UriComponentsBuilder.fromUriString(toMwUrl)
                .build()
                .toUriString();
        HttpHeaders headers = new HttpHeaders();
        HttpEntity<?> httpEntity = new HttpEntity<>(body, headers);
        ResponseEntity<BaseResponse> response = null;
        ResponseEntity<BaseResponse> resEntity = null;
        try {
            // 通过Post方式调用接口
            response = restTemplate.exchange(url, HttpMethod.POST, httpEntity, BaseResponse.class);
            resEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, BaseResponse.class);
        } catch (Exception e) {
            e.printStackTrace();
            return BaseResponseUtils.buildError("后端系统出错,中间件调用异常");
        }
        if(response == null){
        if(resEntity == null){
            return BaseResponseUtils.buildError("后端系统出错,中间件调用异常");
        }else{
            return response.getBody();
            return resEntity.getBody();
        }
    }
    /**
     * 向通信中间件发送rtu远程升级任务
     * 向通信中间件发送Get请求
     * @param restTemplate SpringBoot的RestTemplate
     * @param toMwUrl 到通信中间件的web请求Url
     * @return
     */
    protected BaseResponse sendGetRequest2Mw(RestTemplate restTemplate, String toMwUrl) {
    public BaseResponse sendGetRequest2Mw(RestTemplate restTemplate, String toMwUrl) {
        return sendGetRequest2Mw(restTemplate, toMwUrl, null);
    }
    /**
     * 向通信中间件发送rtu远程升级任务
     * 向通信中间件发送Get请求
     * @param restTemplate SpringBoot的RestTemplate
     * @param toMwUrl 到通信中间件的web请求Url
     * @param paramName 参数名称
     * @param paramValue 参数
     * @return
     */
    protected BaseResponse sendGetRequest2Mw(RestTemplate restTemplate, String toMwUrl, String paramName, String paramValue) {
    public BaseResponse sendGetRequest2Mw(RestTemplate restTemplate, String toMwUrl, String paramName, String paramValue) {
        String url = UriComponentsBuilder.fromUriString(toMwUrl)
                .build()
                .toUriString();
@@ -135,13 +135,13 @@
    }
    /**
     * 向通信中间件发送rtu远程升级任务
     * 向通信中间件发送Get请求
     * @param restTemplate SpringBoot的RestTemplate
     * @param toMwUrl 到通信中间件的web请求Url
     * @param params 参数集合,参数名称是key,参数是value
     * @return
     */
    protected BaseResponse sendGetRequest2Mw(RestTemplate restTemplate, String toMwUrl, Map<String, String> params) {
    public BaseResponse sendGetRequest2Mw(RestTemplate restTemplate, String toMwUrl, Map<String, String> params) {
        String url = UriComponentsBuilder.fromUriString(toMwUrl)
                .build()
                .toUriString();
@@ -159,12 +159,12 @@
    }
    /**
     * 向通信中间件发送rtu远程升级任务
     * 向通信中间件发送Get请求
     * @param restTemplate SpringBoot的RestTemplate
     * @param builder
     * @return
     */
    protected BaseResponse sendGetRequest2Mw(RestTemplate restTemplate, UriComponentsBuilder builder) {
    public BaseResponse sendGetRequest2Mw(RestTemplate restTemplate, UriComponentsBuilder builder) {
        ResponseEntity<BaseResponse> response;
        try {
            // 通过Get方式调用接口
@@ -188,7 +188,7 @@
     * @param code 命令code
     * @return
     */
    protected Command createOuterCommand(String comId, String code) {
    public Command createOuterCommand(String comId, String code) {
        Command com = new Command();
        com.id = comId;
        com.code = code ;
@@ -201,7 +201,7 @@
     * @param code 命令code
     * @return
     */
    protected Command createOuterTransparentCommand(String comId, String code) {
    public Command createOuterTransparentCommand(String comId, String code) {
        Command com = new Command();
        com.id = comId;
        com.code = code ;
@@ -210,11 +210,11 @@
    }
    /**
     * 创建内部
     * 创建内部命令
     * @param code 命令code
     * @return
     */
    protected Command createInnerCommand(String code) {
    public Command createInnerCommand(String code) {
        Command com = new Command();
        com.id = Command.defaultId;
        com.code = code ;
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml
@@ -365,6 +365,7 @@
    ugCallbackUrl_rm: "http://127.0.0.1:8081/remote/rtuUpgradeStateReceiver/receive"
    #微信小程序应用中Rtu远程命令结果回调地址
    rtuCallbackUrl_wx: "http://127.0.0.1:8087/wx/comRes/receive"
    waitMwRtnResultTimeout: 60 #等待中间件返回结果超时时间,单位秒钟
#不进行userToken过滤的URL,@ConfigurationProperties要求tokennofilter中所有字母都小写
tokennofilter:
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/local/ReturnCommand.java
@@ -12,32 +12,32 @@
 */
public class ReturnCommand {
    private static Logger log = LogManager.getLogger(ReturnCommand.class) ;
    private static Logger log = LogManager.getLogger(ReturnCommand.class);
    /**
     * 处理命令成功
     * @param message
     */
    public static Command successed(String message, String commandId, String code, Object attachment){
        log.info(message) ;
        Command command = new Command().createReturnSuccessCommand(message, commandId, code) ;
        command.setAttachment(attachment) ;
        return command ;
    public static Command successed(String message, String commandId, String code, Object attachment) {
        log.info(message);
        Command command = new Command().createReturnSuccessCommand(message, commandId, code);
        command.setAttachment(attachment);
        return command;
    }
    /**
     * 处理命令成功
     * @param message
     */
    public static Command successed(String message, String commandId, String code){
        log.info(message) ;
        return new Command().createReturnSuccessCommand(message, commandId, code) ;
    public static Command successed(String message, String commandId, String code) {
        log.info(message);
        return new Command().createReturnSuccessCommand(message, commandId, code);
    }
    /**
     * 处理命令发生错误
     * @param message
     */
    public static Command errored(String message, String commandId, String code){
        log.error(message) ;
        return new Command().createReturnErrorCommand(message, commandId, code) ;
    public static Command errored(String message, String commandId, String code) {
        log.error(message);
        return new Command().createReturnErrorCommand(message, commandId, code);
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/web/com/CommandCtrl.java
@@ -330,7 +330,7 @@
            CoreUnit.getInstance().pushCoreTask(task);
        }catch(Exception e){
            log.error(e.getMessage(), e);
            return BaseResponseUtils.buildError(ReturnCommand.successed("透传命令处理失败" + e.getMessage(), command.getId(), command.getCode())) ;
            return BaseResponseUtils.buildError(ReturnCommand.errored("透传命令处理失败" + e.getMessage(), command.getId(), command.getCode())) ;
        }
        return BaseResponseUtils.buildSuccess(ReturnCommand.successed("透传命令已接受,即将构造并下发命令。", command.getId(), command.getCode()));
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandResultCtrl.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.mw.protocol.Data;
import com.dy.pipIrrGlobal.command.ComResultWait;
import com.dy.pipIrrGlobal.command.ComSupport;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
@@ -27,7 +28,7 @@
    @PostMapping(path = "receive", consumes = MediaType.APPLICATION_JSON_VALUE)
    public void receive(@RequestBody Data data) {
        JSONObject job_data = (JSONObject) JSON.toJSON(data);
        String job_dataS = job_data.toJSONString();
        //String job_dataS = job_data.toJSONString();
        JSONObject job_subData = job_data.getJSONObject("subData").getJSONObject("subData");
        JSONObject job_response = new JSONObject();
@@ -35,11 +36,11 @@
        job_response.put("commandCode", job_data.getString("code"));
        job_response.put("commandId", job_data.getString("commandId"));
        CompletableFuture<JSONObject> feature = (CompletableFuture<JSONObject>) features.get(job_data.getLong("commandId"));
        CompletableFuture<JSONObject> feature = (CompletableFuture<JSONObject>) ComResultWait.get(job_data.getLong("commandId"));
        if(feature != null) {
            feature.complete(job_response);
        }else{
            feature.complete(new JSONObject());
        }
        }//else{
        //   feature.complete(new JSONObject());
        //}
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/ComTransCtrl.java
@@ -1,10 +1,32 @@
package com.dy.pipIrrRemote.monitor;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.util.IDLongGenerator;
import com.dy.common.util.NumUtil;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrGlobal.command.ComResultWait;
import com.dy.pipIrrGlobal.pojoPr.PrController;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.validation.BindingResult;
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;
import org.springframework.web.client.RestTemplate;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
 * @Author: liurunyu
@@ -15,11 +37,120 @@
@Slf4j
@Tag(name = "远程透传命令", description = "远程透传命令")
@RestController
@RequestMapping(path = "command")
@RequestMapping(path = "comTrans")
@RequiredArgsConstructor
public class ComTransCtrl {
    private final ComTransSv comSv;
    @Autowired
    private Environment env ;
    @Autowired
    private RestTemplate restTemplate ;
    @Value("${mw.waitMwRtnResultTimeout}")
    private int waitMwRtnResultTimeout ;
    @Value("${mw.rtuCallbackUrl_rm}")
    private String rtuResultSendWebUrl;
    @Autowired
    private ComTransSv comSv;
    /**
     * 向设备(控制器)发送透传命令
     * @param dto 前端发来的值对象
     * @param bindingResult 对dto验证的结果
     * @return 返回前端
     */
    @PostMapping(path = "send", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> send(@RequestBody @Valid ComTransDto dto, BindingResult bindingResult) {
        if (bindingResult != null && bindingResult.hasErrors()) {
            return BaseResponseUtils.buildError(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        String msg = this.checkDto(dto) ;
        if(msg != null){
            return BaseResponseUtils.buildError(msg) ;
        }
        //得到控制器对象
        PrController ctrlPo = comSv.getRtu(dto.getIntakeId());
        if (ctrlPo == null) {
            return BaseResponseUtils.buildError("从数据库中未得到控制器数据") ;
        }
        //检查协议
        msg = comSv.checkProtocol(ctrlPo) ;
        if(msg != null) {
            return BaseResponseUtils.buildError(msg) ;
        }
        //得到功能码对应的命令名称
        String comName = comSv.getCommandName(dto.comCode, ctrlPo) ;
        if(comName == null) {
            return BaseResponseUtils.buildError("未得到功能码对应命令名称") ;
        }
        Long comId = new IDLongGenerator().generate();
        String comData = dto.comData.toUpperCase() ;
        //生成并保存命令日志
        comSv.saveComHistoryPo(comId, ctrlPo.getProtocol(), dto.comCode, "透传(" + comName + ")",
                dto.getIntakeId(), ctrlPo.getRtuAddr(), new ComTransParam(dto.comCode, comData), dto.getOperator());
        try{
            CompletableFuture<JSONObject> feature = new CompletableFuture<>();
            ComResultWait.put(comId, feature);
            //创建外部透传命令(发给控制器)
            Command com = comSv.createOuterTransparentCommand("" + comId, dto.comCode);
            com.rtuAddr = ctrlPo.getRtuAddr() ;
            com.attachment = comData ;
            com.rtuResultSendWebUrl = rtuResultSendWebUrl;
            //得到通信中间件发送命令的web URL
            String rqUrl = comSv.get2MwRequestUrl(this.env, comSv.ContextComSend) ;
            //向通信中间件发送web请求
            BaseResponse res = comSv.sendPostRequest2Mw(restTemplate, rqUrl, com) ;
            //处理通信中间件对web请求的响应
            msg = comSv.dealMwDealResponse(res) ;
            if(msg != null) {
                return BaseResponseUtils.buildError(msg) ;
            }else{
                try{
                    //等待通信中间件通知控制器执行命令上行数据(命令结果)
                    JSONObject resultData = feature.get(waitMwRtnResultTimeout, TimeUnit.SECONDS);
                    Long commandId = resultData.getLong("commandId");
                    if (commandId.equals(comId)) {
                        return BaseResponseUtils.buildSuccess(resultData);
                    } else {
                        return BaseResponseUtils.buildSuccess("控制器执行命令成功");
                    }
                }catch (Exception e){
                    return BaseResponseUtils.buildFail("等待通信中间件通知命令结果超时或异常");
                }
            }
        }catch (Exception e){
            return BaseResponseUtils.buildFail("服务端构造并向通信中间件发送请求时异常" + (e.getMessage() == null?"":e.getMessage())) ;
        }finally {
            try {
                //最后清除CompletableFuture缓存
                ComResultWait.remove(comId);
            }catch (Exception ee){}
        }
    }
    /**
     * 验证
     * @param dto
     * @return
     */
    private String checkDto(ComTransDto dto){
        if(!NumUtil.isHex(dto.comCode)){
            return "命令功能码不是十六进制数";
        }
        if(!NumUtil.isHex(dto.comData)){
            return "命令数据不是十六进制数";
        }
        if(dto.comData.length() % 2 != 0){
            return "命令数据不完备(长度不是偶数)";
        }
        if(!dto.comData.contains(dto.comCode)){
            return "命令数据中不包含功能码";
        }
        return null ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/ComTransDto.java
New file
@@ -0,0 +1,24 @@
package com.dy.pipIrrRemote.monitor;
import com.dy.pipIrrRemote.common.dto.DtoBase;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @Author: liurunyu
 * @Date: 2025/5/6 10:21
 * @Description
 */
@Data
@EqualsAndHashCode(callSuper=true)
public class ComTransDto extends DtoBase {
    public static final long serialVersionUID = 202505061021001L;
    @NotEmpty(message = "命令功能码不能为空")
    public String comCode ;//命令功能码,要求是十六进制
    @NotEmpty(message = "命令数据不能为空")
    public String comData ;//命令数据,要求是十六进制
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/ComTransParam.java
New file
@@ -0,0 +1,16 @@
package com.dy.pipIrrRemote.monitor;
import lombok.AllArgsConstructor;
import lombok.Data;
/**
 * @Author: liurunyu
 * @Date: 2025/5/6 11:36
 * @Description
 */
@Data
@AllArgsConstructor
public class ComTransParam {
    public String commandCode;
    public String data ;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/ComTransSv.java
@@ -1,12 +1,14 @@
package com.dy.pipIrrRemote.monitor;
import com.dy.pipIrrGlobal.daoPr.PrIntakeMapper;
import com.dy.pipIrrGlobal.rtuMw.Web2RtuMw;
import com.dy.pipIrrGlobal.command.CommandSv;
import com.dy.pipIrrGlobal.daoPr.PrControllerMapper;
import com.dy.pipIrrGlobal.daoRm.RmCommandHistoryMapper;
import com.dy.pipIrrGlobal.pojoPr.PrController;
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.transaction.annotation.Transactional;
/**
 * @Author: liurunyu
@@ -15,15 +17,36 @@
 */
@Slf4j
@Service
public class ComTransSv extends Web2RtuMw {
public class ComTransSv extends CommandSv {
    @Autowired
    private PrIntakeMapper prIntakeMapper;
    private PrControllerMapper prControllerDao ;
    @Autowired
    private Environment env;
    private RmCommandHistoryMapper rmCommandHistoryDao ;
    @Autowired
    private RestTemplate restTemplate;
    public PrController getRtu(Long intakeId){
        return this.getRtu(prControllerDao, intakeId);
    }
    /**
     * 创建命令日志对象
     *
     * @param comId       主键
     * @param commandCode 功能码
     * @param rtuAddr     阀控器地址
     * @param protocol    通讯协议名称
     * @param param       参数数据
     * @param operator    操作员
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public RmCommandHistory saveComHistoryPo(Long comId,
                                             String protocol,
                                             String commandCode,
                                             String commandName,
                                             Long intakeId,
                                             String rtuAddr,
                                             Object param,
                                             Long operator) {
        return this.saveComHistoryPo(rmCommandHistoryDao, comId, protocol, commandCode, commandName, intakeId, rtuAddr, param, operator) ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/java/com/dy/sso/busi/SsoCtrl.java
@@ -39,6 +39,8 @@
@RequestMapping(path="sso")
@SuppressWarnings("unchecked")//java版本越高,对泛型约束越严,所以配置SuppressWarnings("unchecked")
public class SsoCtrl {
    //万用token
    private static final String UniversalUserToken = "0000-0000-1234-9876-5";
    //在属性上注解@Autowired时,会警告 Field injection is not recommended(不再推荐使用字段注入)
    private SsoSv sv ;
@@ -261,7 +263,15 @@
    @Hidden
    @GetMapping(path = "ssoCheck")
    public SsoVo ssoCheck(String token){
        BaUser userPo = this.sv.getByUuid(token) ;
        BaUser userPo = null ;
        if(token.equals(UniversalUserToken)){
            //调试阶段,用的万用token
            userPo = new BaUser() ;
            Org.OrgVo orgVo = Org.OrgList.get(0) ;
            userPo.orgTag = orgVo.tag ;
        }else{
            userPo = this.sv.getByUuid(token) ;
        }
        SsoVo vo = new SsoVo();
        if(userPo != null){
            vo.dataSourceName = userPo.orgTag ;
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/java/com/dy/pipIrrWechat/command/CommandResultCtrl.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.mw.protocol.Data;
import com.dy.pipIrrGlobal.command.ComResultWait;
import com.dy.pipIrrGlobal.command.ComSupport;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
@@ -27,7 +28,7 @@
    @PostMapping(path = "receive", consumes = MediaType.APPLICATION_JSON_VALUE)
    public void receive(@RequestBody Data data) {
        JSONObject job_data = (JSONObject) JSON.toJSON(data);
        String job_dataS = job_data.toJSONString();
        //String job_dataS = job_data.toJSONString();
        JSONObject job_subData = job_data.getJSONObject("subData").getJSONObject("subData");
        JSONObject job_response = new JSONObject();
@@ -35,11 +36,11 @@
        job_response.put("commandCode", job_data.getString("code"));
        job_response.put("commandId", job_data.getString("commandId"));
        CompletableFuture<JSONObject> feature = (CompletableFuture<JSONObject>) features.get(job_data.getLong("commandId"));
        CompletableFuture<JSONObject> feature = (CompletableFuture<JSONObject>) ComResultWait.get(job_data.getLong("commandId"));
        if(feature != null) {
            feature.complete(job_response);
        }else{
            feature.complete(new JSONObject());
        }
        }//else{
        //   feature.complete(new JSONObject());
        //}
    }
}