zhubaomin
2025-06-24 62afcbeaa5cc328bff01ae1facb18a6b8c03c5bc
Merge branch 'master' of http://8.140.179.55:20000/r/pipIrr-SV
31个文件已添加
5个文件已删除
70个文件已修改
3130 ■■■■ 已修改文件
README.md 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Command.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_26_Down.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/MqttMsgParser.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/MqttPubMsg.java 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/MqttSubMsg.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/MqttTopic.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/CodeSdV1.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/MqttPubMsgSdV1.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/MqttSubMsgSdV1.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/ProtocolConstantSdV1.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/ProtocolParserSdV1.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/downVos/ParamSetVo.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/upVos/ManureVo.java 92 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/upVos/SoilVo.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/upVos/StateVo.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/upVos/WeatherVo.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/Command4MqttSv.java 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmCommandHistoryMapper.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoSe/SeClientCardMapper.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrStManure.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrStSoil.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrStWeather.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/rtuMw/Web2RtuMw.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voSe/VoCardByClientNum.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-common-mw.yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-common-web(121服务器).yml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-database-jyg.yml 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global(166web文件花生壳).yml 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/init-config(121服务器).xml 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrStManureMapper.xml 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrStSoilMapper.xml 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrStWeatherMapper.xml 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmCommandHistoryMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeClientCardMapper.xml 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/Server.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/mqtt/DevStatusDealer.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/mqtt/MqttPubMsgNode.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/mqtt/MqttUnitConfigVo.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/TkMqttData.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/pSdV1/TkFindPSdV1.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/web/com/CommandCtrl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/config.properties 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/config.xml 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-param-set/src/main/java/com/dy/pipIrrParamSet/console/Command.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-param-set/src/main/java/com/dy/pipIrrParamSet/paramSet/ParamKey.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-param-set/src/main/java/com/dy/pipIrrParamSet/paramSet/ParamSetMw.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-param-set/src/main/resources/application-params.yml 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-app/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-base/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-gis/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-irrigate/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-operation/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/PipIrrRemoteApplication.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandResultCtrl.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/MqttResultCtrl.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/Dto4MqttBase.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/common/Cd4MqttParameter.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/common/Com4MqttCtrl.java 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/common/Com4MqttSv.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/common/ComSv.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdCtrl.java 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdDto.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdParam.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdStartCtrl.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdStopCtrl.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdSv.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/inject/CdCtrl.java 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/inject/CdDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/inject/CdParam.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/inject/CdSv.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/irr/CdCtrl.java 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/irr/CdDto.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/irr/CdParam.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/irr/CdSv.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/paramSet/CdCtrl.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/paramSet/CdDto.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/paramSet/CdParam.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/paramSet/CdSv.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/stir/CdCtrl.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/stir/CdDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/stir/CdParam.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/stir/CdSv.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd55/CdCtrl.java 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd5C/CdCtrl.java 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd65/CdCtrl.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-temp/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/CardCtrl.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/CardSv.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/dto/DtoReissue.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/qo/QoCards.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/qo/QoLostCards.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/resources/application(121服务器).yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/文档/SaaS/增加一个单位(orgTag).docx 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/文档/SaaS/端口、IP、标签配置.docx 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/文档/水肥气象墒情/FlexManager软件配置参数.docx 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/文档/水肥气象墒情/MQTT指令不执行.docx 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/文档/水肥气象墒情/MQTT设定时间参数.docx 补丁 | 查看 | 原始文档 | blame | 历史
README.md
New file
@@ -0,0 +1,124 @@
# pipIrr æ™ºèƒ½çŒæº‰ç³»ç»Ÿ
## é¡¹ç›®æ¦‚è¿°
pipIrr是一套基于Java的智能管道灌溉系统解决方案,用于实现水资源的智能化管理与灌溉控制。系统集成了远程终端控制、GIS地理信息、水资源监测与分析、微信接入等多种功能,为智慧农业和水利工程提供全面的技术支持。
## ç³»ç»Ÿæž¶æž„
系统采用微服务架构,基于Spring Boot 3构建,主要包括以下几个核心部分:
- **前端应用层**:提供Web界面、移动应用、微信公众号等多种交互方式
- **业务服务层**:处理核心业务逻辑,包括灌溉管理、项目管理、数据统计等
- **中间件层**:提供RTU(远程终端单元)通信、第三方系统集成等功能
- **基础设施层**:提供数据存储、缓存、消息队列等基础服务
## æ¨¡å—说明
### çˆ¶æ¨¡å— (pipIrr-platform)
作为整个项目的父模块,管理依赖版本和构建配置。
### æ ¸å¿ƒå­æ¨¡å—
- **pipIrr-common**: å…¬å…±ç»„件,提供工具类、通用配置等
- **pipIrr-global**: å…¨å±€é…ç½®å’ŒæœåŠ¡
- **pipIrr-web**: Web应用模块集合
  - pipIrr-web-base: åŸºç¡€æ•°æ®æœåŠ¡
  - pipIrr-web-sso: å•点登录服务
  - pipIrr-web-irrigate: çŒæº‰ç®¡ç†
  - pipIrr-web-gis: GIS地理信息服务
  - pipIrr-web-project: é¡¹ç›®ç®¡ç†
  - pipIrr-web-statistics: æ•°æ®ç»Ÿè®¡åˆ†æž
  - pipIrr-web-remote: è¿œç¨‹æŽ§åˆ¶
  - pipIrr-web-wechat: å¾®ä¿¡é›†æˆ
  - pipIrr-web-app: ç§»åŠ¨åº”ç”¨æœåŠ¡
  - pipIrr-web-file: æ–‡ä»¶ç®¡ç†
  - pipIrr-web-operation: è¿ç»´ç®¡ç†
  - pipIrr-web-sell: é”€å”®ç®¡ç†
  - pipIrr-web-temp: ä¸´æ—¶æ¨¡å—
- **pipIrr-mw**: ä¸­é—´ä»¶æœåŠ¡
  - pipIrr-mw-rtu: RTU设备通信
  - pipIrr-mw-rtu3rd: ç¬¬ä¸‰æ–¹RTU集成
  - pipIrr-mw-simulate-rtu: RTU模拟器
  - pipIrr-mwTest-server: æµ‹è¯•服务器
  - pipIrr-mwTest-client: æµ‹è¯•客户端
## æŠ€æœ¯æ ˆ
- **基础框架**: Spring Boot 3.1.3
- **JDK版本**: Java 20
- **Web服务**: Tomcat 10.1.12
- **数据库**: MySQL 8.0.33
- **ORM框架**: MyBatis-Plus 3.5.3.2
- **数据库连接池**: Druid 1.2.20
- **API文档**: SpringDoc OpenAPI 2.2.0
- **JSON处理**: FastJSON 2.0.40
- **对象映射**: MapStruct 1.5.5.Final
- **工具集**: Hutool 5.8.22
- **日志框架**: Log4j2 2.20.0
## å¼€å‘环境搭建
### å‰ç½®æ¡ä»¶
- JDK 20
- Maven 3.8+
- MySQL 8.0+
- IDE推荐: IntelliJ IDEA
### æž„建步骤
1. å…‹éš†ä»£ç åº“
   ```bash
   git clone <repository-url>
   ```
2. å¯¼å…¥é¡¹ç›®åˆ°IDE
   ä½¿ç”¨IDEA导入Maven项目
3. é…ç½®æ•°æ®åº“
   åœ¨ç›¸åº”配置文件中设置数据库连接信息
4. ç¼–译项目
   ```bash
   mvn clean package
   ```
## éƒ¨ç½²è¯´æ˜Ž
### å¼€å‘环境
```bash
mvn spring-boot:run -Dspring.profiles.active=dev
```
### ç”Ÿäº§çŽ¯å¢ƒ
1. æ‰“包应用
   ```bash
   mvn clean package -Dspring.profiles.active=prod
   ```
2. è¿è¡Œjar包
   ```bash
   java -jar <模块名>-<版本号>.jar
   ```
## é¡¹ç›®æ–‡æ¡£
详细的项目文档位于 `pipIrr-platform/文档/` ç›®å½•下,包括:
- API接口文档
- æ•°æ®åº“设计
- éƒ¨ç½²æŒ‡å—
- ç¼–码规范
## ç‰ˆæœ¬ä¿¡æ¯
当前版本: 1.0.0
## è´¡çŒ®æŒ‡å—
1. Fork æœ¬ä»“库
2. åˆ›å»ºåŠŸèƒ½åˆ†æ”¯ (`git checkout -b feature/AmazingFeature`)
3. æäº¤å˜æ›´ (`git commit -m 'Add some AmazingFeature'`)
4. æŽ¨é€åˆ°åˆ†æ”¯ (`git push origin feature/AmazingFeature`)
5. åˆ›å»ºPull Request
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/Command.java
@@ -41,7 +41,7 @@
    public Short protocolVersion;
    /**
     * RTU åœ°å€
     * RTU地址 å’Œ FBox设备号
     */
    public String rtuAddr ;
@@ -76,7 +76,12 @@
        s += (protocol == null ? "" : ("协议=" + protocol + "\n"));
        s += (protocolVersion == null ? "" : ("协议版本号=" + protocolVersion + "\n"));
        s += (rtuAddr == null ? "" : ("Rtu地址=" + rtuAddr + "\n"));
        s += "命令类型=" + (type.equals(CommandType.innerCommand)?"内部命令":(type.equals(CommandType.outerCommand)?"RTU命令":"透传命令")) + "\n" ;
        s += "命令类型=" + (
                type.equals(CommandType.innerCommand)?"内部命令":(
                        type.equals(CommandType.outerCommand)?"RTU命令":(
                                type.equals(CommandType.mqttCommand)?"MQTT命令":(
                                        type.equals(CommandType.outerTransCommand)?"透传命令":
                                                "")))) + "\n" ;
        s += (code == null ? "" : ("功能码=" + code + "\n")) ;
        s += (rtuResultSendWebUrl == null ? "" : ("回调网址=" + rtuResultSendWebUrl + "\n"));
        if(param != null){
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V202404/parse/Cd_26_Down.java
@@ -61,7 +61,7 @@
                throw new Exception("设备终端年用水量必须是0~99999999范围内的整数") ;
            }
            byte[] bs = new byte[14] ;
            byte[] bs = new byte[13] ;
            int index = 0 ;
            bs[index] = (byte)(Integer.parseInt(cvo.controllerType, 16));
@@ -84,7 +84,6 @@
                bs[index++] = 0 ;
            }
            index ++ ;
            GlCreate.createPw(bs, index);
            index += 2 ;
@@ -105,6 +104,5 @@
        return bytes ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/MqttMsgParser.java
@@ -18,7 +18,7 @@
            if(topicGrp.length != 5){
                throw new Exception("接收的mqtt消息主题不可识别") ;
            }else{
                if(NumUtil.isPlusIntNumber(topicGrp[4])){
                if(!NumUtil.isPlusIntNumber(topicGrp[4])){
                    throw new Exception("接收的mqtt消息主题不可识别") ;
                }
                if(Integer.parseInt(topicGrp[4]) <= 0){
@@ -57,7 +57,7 @@
        if(com.protocolVersion == null){
            throw new Exception("接收到MQTT命令,但未提供协议版本号") ;
        }
        if(com.code != null && com.code.trim().length() != 0){
        if(com.code == null || com.code.trim().length() == 0){
            throw new Exception("接收到MQTT命令,但未提供功能码") ;
        }
        if(com.protocol.equals(ProtocolConstantSdV1.protocolName)){
@@ -73,7 +73,7 @@
    public static void main(String[] args) {
        String s = "ym/sd1/10000/control/m1" ;
        String s = "jyg/sd1/2430002404000840/weather/1" ;
        String[] ss = s.split("/") ;
        for (String s1 : ss) {
            System.out.println(s1);
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/MqttPubMsg.java
@@ -1,12 +1,18 @@
package com.dy.common.mw.protocol4Mqtt;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @Author: liurunyu
 * @Date: 2025/6/5 11:44
 * @Description
 */
public abstract class MqttPubMsg {
@Data
public class MqttPubMsg {
    public String commandId ;//命令ID
    public String cd ;//功能码
    public String deviceId ;//设备ID
@@ -18,6 +24,14 @@
    public boolean isCacheForOffLine ;//下行命令控制,消息中间件不在线是否缓存命令
    public boolean hasResponse ;//下行命令控制,命令是否有应答
    public abstract boolean valid();
    public boolean valid(){
        if (topic == null || topic.isEmpty()) {
            return false;
        }
        if (msg == null || msg.isEmpty()) {
            return false;
        }
        return true;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/MqttSubMsg.java
@@ -1,14 +1,16 @@
package com.dy.common.mw.protocol4Mqtt;
import com.dy.common.mw.protocol4Mqtt.pSdV1.upVos.ManureVo;
import com.dy.common.util.Callback;
import lombok.Data;
/**
 * @Author: liurunyu
 * @Date: 2025/6/5 11:44
 * @Description
 */
public abstract class MqttSubMsg {
@Data
public class MqttSubMsg {
    public String commandId ;//命令ID
    public String mqttResultSendWebUrl ;//Mtt返回命令结果 å‘向目的地web URL
@@ -18,9 +20,58 @@
    public MqttTopic topic ;//消息主题
    public String metaData;//MQTT推送来的元数据
    public abstract boolean valid();
    public Vo4Up vo4Up;//订阅的消息数据值对象
    public MqttSubMsg() {
    }
    public MqttSubMsg(MqttTopic subTopic, String msg) {
        this.deviceId = subTopic.devId ;
        this.protocol = subTopic.protocol ;
        this.topic = subTopic ;
        this.metaData = msg ;
    }
    public abstract boolean subMsgMatchPubMsg(MqttPubMsg pubMsg);
    public boolean valid() {
        if (topic == null || topic.isEmpty()) {
            return false;
        }
        if (metaData == null || metaData.isEmpty()) {
            return false;
        }
        return true;
    }
    public abstract void action(Callback callback);
    public boolean subMsgMatchPubMsg(MqttPubMsg pubMsg){
        if(this.vo4Up != null && this.vo4Up instanceof ManureVo){
            //只要上报的是状态数据,说明设备响应了命令
            return true ;
        }
        return false ;
    }
    public void action(Callback callback){
        callback.call(this) ;
    }
    public String toString(){
        StringBuilder sb = new StringBuilder();
        if(commandId != null){
            sb.append("commandId:")
                    .append(commandId)
                    .append("\n") ;
        }
        sb.append("主题:")
                .append(topic.longName())
                .append("\n") ;
        if(vo4Up != null){
            sb.append("数据:")
                    .append(vo4Up.toString())
                    .append("\n") ;
        }else{
            sb.append("元数据:")
                    .append(metaData)
                    .append("\n") ;
        }
        return sb.toString() ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/MqttTopic.java
@@ -16,7 +16,7 @@
    public String orgTag ;//组织标识
    public String protocol ;//协议名称
    public String devId ;//设备(FBox)ID
    public String type;//测站类型
    public String type;//数据(命令)类型
    public Integer no;//测站编号
    public boolean isEmpty(){
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/CodeSdV1.java
@@ -10,5 +10,18 @@
    public static final String cd_Stir = "01" ;//搅拌启停命令
    public static final String cd_Inject = "02" ;//注肥启停命令
    public static final String cd_Irr = "03" ;//灌溉启停命令
    public static final String cd_Param = "10" ;//设定参数
    public static final String cd_Param = "10" ;//设置参数
    public static String getCodeName(String code) {
        String name = (code.equals(cd_Fault) ? "故障解除" :
                (code.equals(cd_Stir) ? "搅拌启停" :
                (code.equals(cd_Inject) ? "注肥启停" :
                (code.equals(cd_Irr) ? "灌溉启停" :
                (code.equals(cd_Param) ? "设置参数" :
                 ""))))) ;
        if(name == null || name.equals("")){
            name = code ;
        }
        return name ;
    }
}
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/MqttPubMsgSdV1.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/MqttSubMsgSdV1.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/ProtocolConstantSdV1.java
@@ -13,7 +13,6 @@
    public static final String SubTopicWeather = "weather" ;//气象
    public static final String SubTopicSoil = "soil" ;//土壤墒情
    public static final String SubTopicManure = "manure" ;//水肥
    public static final String SubTopicState = "state" ;//状态
    //发布的主题
    public static final String PubTopicFault = "ctrlFault" ;//故障解除
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/ProtocolParserSdV1.java
@@ -3,9 +3,7 @@
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol4Mqtt.MqttCallback;
import com.dy.common.mw.protocol4Mqtt.MqttTopic;
import com.dy.common.mw.protocol4Mqtt.Vo4Up;
import com.dy.common.mw.protocol4Mqtt.*;
import com.dy.common.mw.protocol4Mqtt.pSdV1.comParam.ComCtrlVo;
import com.dy.common.mw.protocol4Mqtt.pSdV1.comParam.ComSetParamVo;
import com.dy.common.mw.protocol4Mqtt.pSdV1.downVos.FaultClearVo;
@@ -22,37 +20,53 @@
 * @Description
 */
public class ProtocolParserSdV1 {
    public MqttSubMsgSdV1 parseSubMsg(MqttTopic subTopic, MqttMessage mqttMsg, MqttCallback callback) throws Exception {
    public MqttSubMsg parseSubMsg(MqttTopic subTopic, MqttMessage mqttMsg, MqttCallback callback) throws Exception {
        String strTxt = new String(mqttMsg.getPayload(), "UTF-8");
        if(!JSON.isValid(strTxt)){
            throw new Exception("接收到MQTT消息,协议" + subTopic.protocol + ",设备ID" + subTopic.devId + ",主题" + subTopic.longName() + "消息格式非json数据(" + strTxt + ")") ;
        }
        MqttSubMsgSdV1 msg = new MqttSubMsgSdV1(subTopic, strTxt);
        MqttSubMsg msg = new MqttSubMsg(subTopic, strTxt);
        Vo4Up vo ;
        DevRunInfo stInfo = null ;
        switch (subTopic.type) {
            case ProtocolConstantSdV1.SubTopicWeather -> {
                vo = JSON.parseObject(strTxt, WeatherVo.class);
                WeatherVo wvo = JSON.parseObject(strTxt, WeatherVo.class);
                //调整小数
                wvo.airTemperature = (wvo.airTemperature == null ? null: (wvo.airTemperature / 10.0F)) ;
                wvo.airHumidity = (wvo.airHumidity == null ? null: (wvo.airHumidity / 10.0F)) ;
                wvo.rainfall = (wvo.rainfall == null ? null: (wvo.rainfall / 10.0F)) ;
                wvo.windSpeed = (wvo.windSpeed == null ? null: (wvo.windSpeed / 10.0F)) ;
                vo = wvo ;
                break;
            }
            case ProtocolConstantSdV1.SubTopicSoil -> {
                vo = JSON.parseObject(strTxt, SoilVo.class);
                SoilVo svo = JSON.parseObject(strTxt, SoilVo.class);
                //调整小数
                svo.soilHumidity1 = (svo.soilHumidity1 == null ? null: (svo.soilHumidity1 / 10.0F)) ;
                svo.soilHumidity2 = (svo.soilHumidity2 == null ? null: (svo.soilHumidity2 / 10.0F)) ;
                svo.soilHumidity3 = (svo.soilHumidity3 == null ? null: (svo.soilHumidity3 / 10.0F)) ;
                svo.soilHumidity4 = (svo.soilHumidity4 == null ? null: (svo.soilHumidity4 / 10.0F)) ;
                svo.soilHumidity5 = (svo.soilHumidity5 == null ? null: (svo.soilHumidity5 / 10.0F)) ;
                svo.soilTemperature1 = (svo.soilTemperature1 == null ? null: (svo.soilTemperature1 / 10.0F)) ;
                svo.soilTemperature2 = (svo.soilTemperature2 == null ? null: (svo.soilTemperature2 / 10.0F)) ;
                svo.soilTemperature3 = (svo.soilTemperature3 == null ? null: (svo.soilTemperature3 / 10.0F)) ;
                svo.soilTemperature4 = (svo.soilTemperature4 == null ? null: (svo.soilTemperature4 / 10.0F)) ;
                svo.soilTemperature5 = (svo.soilTemperature5 == null ? null: (svo.soilTemperature5 / 10.0F)) ;
                vo = svo ;
                break;
            }
            case ProtocolConstantSdV1.SubTopicManure -> {
                vo = JSON.parseObject(strTxt, ManureVo.class);
                break;
            }
            case ProtocolConstantSdV1.SubTopicState -> {
                //此处未完成,应该产生一些通信的info,供下面callback.notify(objs)通知出去
                vo = JSON.parseObject(strTxt, StateVo.class);
                StateVo stVo = (StateVo)vo ;
                ManureVo mvo = JSON.parseObject(strTxt, ManureVo.class);
                //调整小数
                mvo.manureFlow = (mvo.manureFlow == null ? null: (mvo.manureFlow / 10.0F)) ;
                vo = mvo ;
                stInfo = new DevRunInfo() ;
                stInfo.devId = msg.deviceId ;
                stInfo.stirRunning = (stVo.stirRunning==null?false:(stVo.stirRunning.byteValue()==1?true:false)) ; //搅拌运行 true是 false否
                stInfo.injectRunning = (stVo.injectRunning==null?false:(stVo.injectRunning.byteValue()==1?true:false)) ; //注肥运行 true是 false否
                stInfo.irrRunning = (stVo.irrRunning==null?false:(stVo.irrRunning.byteValue()==1?true:false)) ; //灌溉运行 true是 false否
                stInfo.alarm = (stVo.alarm==null?false:(stVo.alarm.byteValue()==1?true:false)) ; //报警 true是 false否
                stInfo.stirRunning = (mvo.stirRunning1 ==null?false:(mvo.stirRunning1.byteValue()==1?true:false)) ; //搅拌运行 true是 false否
                stInfo.injectRunning = (mvo.injectRunning==null?false:(mvo.injectRunning.byteValue()==1?true:false)) ; //注肥运行 true是 false否
                stInfo.irrRunning = (mvo.irrRunning==null?false:(mvo.irrRunning.byteValue()==1?true:false)) ; //灌溉运行 true是 false否
                stInfo.alarm = (mvo.alarm==null?false:(mvo.alarm.byteValue()==1?true:false)) ; //报警 true是 false否
                break;
            }
            default -> {
@@ -66,8 +80,8 @@
        return msg;
    }
    public MqttPubMsgSdV1 createPubMsg(String orgTag, Command com) throws Exception {
        MqttPubMsgSdV1 msg ;
    public MqttPubMsg createPubMsg(String orgTag, Command com) throws Exception {
        MqttPubMsg msg ;
        switch (com.code) {
            case CodeSdV1.cd_Fault -> {
                //故障解除命令
@@ -120,89 +134,89 @@
            throw new Exception("接收到MQTT命令,协议" + com.protocol + "版本" + com.protocolVersion + "功能码" + com.code + "命令结果回收URL为空") ;
        }
    }
    private MqttPubMsgSdV1 createPubMsgOfFault(String orgTag, Command com) throws Exception {
    private MqttPubMsg createPubMsgOfFault(String orgTag, Command com) throws Exception {
        JSONObject obj = (JSONObject) com.param;
        String json = obj.toJSONString();
        ComCtrlVo cvo = JSON.parseObject(json, ComCtrlVo.class);
        if(cvo == null){
            throw new Exception("json转ComCtrlVo为null") ;
        }
        MqttPubMsgSdV1 msg = new MqttPubMsgSdV1() ;
        MqttPubMsg msg = new MqttPubMsg() ;
        this.setPubMsgBase(com, msg);
        msg.isCacheForOffLine = false ;
        msg.hasResponse = true ;
        msg.cd = CodeSdV1.cd_Fault ;
        msg.topic = new MqttTopic(orgTag, com.protocol, com.rtuAddr, ProtocolConstantSdV1.PubTopicFault, cvo.no) ;
        msg.topic = new MqttTopic(orgTag, com.protocol + com.protocolVersion, com.rtuAddr, ProtocolConstantSdV1.PubTopicFault, cvo.no) ;
        msg.msg = JSON.toJSONString(new FaultClearVo(cvo.startTrueStopFalse ?(byte)1:0)) ;
        return msg ;
    }
    private MqttPubMsgSdV1 createPubMsgOfStir(String orgTag, Command com) throws Exception {
    private MqttPubMsg createPubMsgOfStir(String orgTag, Command com) throws Exception {
        JSONObject obj = (JSONObject) com.param;
        String json = obj.toJSONString();
        ComCtrlVo cvo = JSON.parseObject(json, ComCtrlVo.class);
        if(cvo == null){
            throw new Exception("json转ComCtrlVo为null") ;
        }
        MqttPubMsgSdV1 msg = new MqttPubMsgSdV1() ;
        MqttPubMsg msg = new MqttPubMsg() ;
        this.setPubMsgBase(com, msg);
        msg.isCacheForOffLine = false ;
        msg.hasResponse = true ;
        msg.cd = CodeSdV1.cd_Fault ;
        msg.topic = new MqttTopic(orgTag, com.protocol, com.rtuAddr, ProtocolConstantSdV1.PubTopicStir, cvo.no) ;
        msg.topic = new MqttTopic(orgTag, com.protocol + com.protocolVersion, com.rtuAddr, ProtocolConstantSdV1.PubTopicStir, cvo.no) ;
        msg.msg = JSON.toJSONString(new StirStartVo(cvo.startTrueStopFalse ?(byte)1:0)) ;
        return msg ;
    }
    private MqttPubMsgSdV1 createPubMsgOfInject(String orgTag, Command com) throws Exception {
    private MqttPubMsg createPubMsgOfInject(String orgTag, Command com) throws Exception {
        JSONObject obj = (JSONObject) com.param;
        String json = obj.toJSONString();
        ComCtrlVo cvo = JSON.parseObject(json, ComCtrlVo.class);
        if(cvo == null){
            throw new Exception("json转ComCtrlVo为null") ;
        }
        MqttPubMsgSdV1 msg = new MqttPubMsgSdV1() ;
        MqttPubMsg msg = new MqttPubMsg() ;
        this.setPubMsgBase(com, msg);
        msg.isCacheForOffLine = false ;
        msg.hasResponse = true ;
        msg.cd = CodeSdV1.cd_Fault ;
        msg.topic = new MqttTopic(orgTag, com.protocol, com.rtuAddr, ProtocolConstantSdV1.PubTopicInject, cvo.no) ;
        msg.topic = new MqttTopic(orgTag, com.protocol + com.protocolVersion, com.rtuAddr, ProtocolConstantSdV1.PubTopicInject, cvo.no) ;
        msg.msg = JSON.toJSONString(new InjectStartVo(cvo.startTrueStopFalse ?(byte)1:0)) ;
        return msg ;
    }
    private MqttPubMsgSdV1 createPubMsgOfIrr(String orgTag, Command com) throws Exception {
    private MqttPubMsg createPubMsgOfIrr(String orgTag, Command com) throws Exception {
        JSONObject obj = (JSONObject) com.param;
        String json = obj.toJSONString();
        ComCtrlVo cvo = JSON.parseObject(json, ComCtrlVo.class);
        if(cvo == null){
            throw new Exception("json转ComCtrlVo为null") ;
        }
        MqttPubMsgSdV1 msg = new MqttPubMsgSdV1() ;
        MqttPubMsg msg = new MqttPubMsg() ;
        this.setPubMsgBase(com, msg);
        msg.isCacheForOffLine = false ;
        msg.hasResponse = true ;
        msg.cd = CodeSdV1.cd_Fault ;
        msg.topic = new MqttTopic(orgTag, com.protocol, com.rtuAddr, ProtocolConstantSdV1.PubTopicIrr, cvo.no) ;
        msg.topic = new MqttTopic(orgTag, com.protocol + com.protocolVersion, com.rtuAddr, ProtocolConstantSdV1.PubTopicIrr, cvo.no) ;
        msg.msg = JSON.toJSONString(new StirStartVo(cvo.startTrueStopFalse ?(byte)1:0)) ;
        return msg ;
    }
    private MqttPubMsgSdV1 createPubMsgOfParam(String orgTag, Command com) throws Exception {
    private MqttPubMsg createPubMsgOfParam(String orgTag, Command com) throws Exception {
        JSONObject obj = (JSONObject) com.param;
        String json = obj.toJSONString();
        ComSetParamVo cvo = JSON.parseObject(json, ComSetParamVo.class);
        if(cvo == null){
            throw new Exception("json转ComSetParamVo为null") ;
        }
        MqttPubMsgSdV1 msg = new MqttPubMsgSdV1() ;
        MqttPubMsg msg = new MqttPubMsg() ;
        this.setPubMsgBase(com, msg);
        msg.isCacheForOffLine = false ;
        msg.hasResponse = false ;
        msg.hasResponse = true ;
        msg.cd = CodeSdV1.cd_Param ;
        msg.topic = new MqttTopic(orgTag, com.protocol, com.rtuAddr, ProtocolConstantSdV1.PubTopicParam, cvo.no) ;
        msg.topic = new MqttTopic(orgTag, com.protocol + com.protocolVersion, com.rtuAddr, ProtocolConstantSdV1.PubTopicParam, cvo.no) ;
        msg.msg = JSON.toJSONString(new ParamSetVo(cvo.stirDuration, cvo.injectDuration)) ;
        return msg ;
    }
    private void setPubMsgBase(Command com, MqttPubMsgSdV1 msg){
    private void setPubMsgBase(Command com, MqttPubMsg msg){
        msg.commandId = com.id ;
        msg.deviceId = com.rtuAddr ;
        msg.mqttResultSendWebUrl = com.rtuResultSendWebUrl ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/downVos/ParamSetVo.java
@@ -15,9 +15,15 @@
@NoArgsConstructor
@AllArgsConstructor
public class ParamSetVo implements Vo4Down {
    /**
     * å•位秒
     */
    @JSONField(name = "搅拌设定时间")
    public Integer stirDuration ;
    /**
     * å•位秒
     */
    @JSONField(name = "注肥设定时间")
    public Integer injectDuration ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/upVos/ManureVo.java
@@ -15,16 +15,77 @@
    @JSONField(name = "flexem_message_id")
    public Integer messageId ;//消息ID
    public Integer no ;//测站编号,其不在JSON数据中,其中主题中
    public Integer no ;//测站编号,其不在JSON数据中,其在主题中
    @JSONField(name = "肥料流量")
    public Float manureFlow ;//肥料流量
    /**
     * æ…拌机1是否运行;(水肥机还可存在搅拌机2、搅拌机3、搅拌机4 ......) è¿è¡Œæ—¶1,停止0.
     */
    @JSONField(alternateNames = {"搅拌运行1", "stirRunning1"})
    public Byte stirRunning1;//搅拌1运行状态
    /**
     * æ…拌机2是否运行;(水肥机还可存在搅拌机2、搅拌机3、搅拌机4 ......) è¿è¡Œæ—¶1,停止0.
     * (当前大禹应用不存在)
     */
    @JSONField(alternateNames = {"搅拌运行2", "stirRunning2"})
    public Byte stirRunning2;//搅拌2运行状态
    /**
     * æ…拌机3是否运行;(水肥机还可存在搅拌机2、搅拌机3、搅拌机4 ......) è¿è¡Œæ—¶1,停止0.
     * (当前大禹应用不存在)
     */
    @JSONField(alternateNames = {"搅拌运行3", "stirRunning3"})
    public Byte stirRunning3;//搅拌3运行状态
    /**
     * æ…拌机4是否运行;(水肥机还可存在搅拌机2、搅拌机3、搅拌机4 ......) è¿è¡Œæ—¶1,停止0.
     * (当前大禹应用不存在)
     */
    @JSONField(alternateNames = {"搅拌运行4", "stirRunning4"})
    public Byte stirRunning4;//搅拌4运行状态
    @JSONField(name = "注肥时长")
    public Integer manureTime ;//注肥时长
    /**
     * ä¸€ä¸ªæ°´è‚¥æœºåªæœ‰ä¸€ä¸ªæ³¨è‚¥æ³µ
     */
    @JSONField(alternateNames = {"注肥运行", "injectRunning"})
    public Byte injectRunning ;//注肥运行状态
    @JSONField(name = "搅拌时长")
    public Integer stirTime ;//搅拌时长
    @JSONField(alternateNames = {"灌溉运行", "irrRunning"})
    public Byte irrRunning ;//灌溉运行状态
    /**
     *  1:注肥泵有故障。0:注肥泵没有故障
     */
    @JSONField(alternateNames = {"报警", "alarm"})
    public Byte alarm ;//注肥泵故障
    /**
     * è‚¥æ–™æµé‡ï¼Œå•位升
     */
    @JSONField(alternateNames = {"肥料流量", "manureFlow"})
    public Float manureFlow ;
    /**
     * å•位秒
     */
    @JSONField(alternateNames = {"注肥经过时间", "manureTime"})
    public Integer manureTime ;
    /**
     * å•位秒
     */
    @JSONField(alternateNames = {"搅拌经过时间", "stirTime"})
    public Integer stirTime ;
    /**
     * å•位秒
     */
    @JSONField(alternateNames = {"搅拌设定时间", "stirDuration"})
    public Integer stirDuration ;
    /**
     * å•位秒
     */
    @JSONField(alternateNames = {"注肥设定时间", "injectDuration"})
    public Integer injectDuration ;
    @JSONField(name = "flexem_timestamp")
    public Long devDt ;//设备时间
@@ -37,7 +98,7 @@
    }
    public String getDevDtStr() {
        if(devDt == null){
        if(devDt != null){
            return DateTime.yyyy_MM_dd_HH_mm_ss(DateTime.getDate(devDt)) ;
        }else{
            return "" ;
@@ -49,11 +110,20 @@
        StringBuilder sb = new StringBuilder();
        sb.append("水肥数据=>") ;
        sb.append(" æ¶ˆæ¯ID:" + messageId + ", ") ;
        sb.append(" æ…拌运行1:" + stirRunning1 + ", ") ;
        sb.append(" æ…拌运行2:" + stirRunning2 + ", ") ;
        sb.append(" æ…拌运行3:" + stirRunning3 + ", ") ;
        sb.append(" æ…拌运行4:" + stirRunning4 + ", ") ;
        sb.append(" æ³¨è‚¥è¿è¡Œï¼š" + injectRunning + ", ") ;
        sb.append(" çŒæº‰è¿è¡Œï¼š" + irrRunning + ", ") ;
        sb.append(" æŠ¥è­¦ï¼š" + alarm + ", ") ;
        sb.append(" è‚¥æ–™æµé‡ï¼š" + manureFlow + ", ") ;
        sb.append(" æ³¨è‚¥æ—¶é•¿ï¼š" + manureTime + ", ") ;
        sb.append(" æ…拌时长:" + stirTime + ", ") ;
        sb.append(" æ³¨è‚¥ç»è¿‡æ—¶é—´ï¼š" + manureTime + ", ") ;
        sb.append(" æ…拌经过时间:" + stirTime + ", ") ;
        sb.append(" æ³¨è‚¥è®¾å®šæ—¶é—´ï¼š" + injectDuration + ", ") ;
        sb.append(" æ…拌设定时间:" + stirDuration + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" + devDt + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" +  this.getDevDtStr() + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" +  this.getDevDtStr()) ;
        sb.append("\n") ;
        return sb.toString() ;
    }
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/upVos/SoilVo.java
@@ -15,31 +15,37 @@
    @JSONField(name = "flexem_message_id")
    public Integer messageId ;//消息ID
    public Integer no ;//测站编号,其不在JSON数据中,其中主题中
    public Integer no ;//测站编号,其不在JSON数据中,其在主题中
    @JSONField(name = "土壤湿度1")
    public Float soilHumidity1 ;//土壤湿度1
    public Float soilHumidity1 ;
    @JSONField(name = "土壤湿度2")
    public Float soilHumidity2 ;//土壤湿度2
    public Float soilHumidity2 ;
    @JSONField(name = "土壤湿度3")
    public Float soilHumidity3 ;//土壤湿度3
    public Float soilHumidity3 ;
    @JSONField(name = "土壤湿度4")
    public Float soilHumidity4 ;//土壤湿度4
    public Float soilHumidity4 ;
    @JSONField(name = "土壤湿度5")
    public Float soilHumidity5 ;
    @JSONField(name = "土壤湿度1")
    public Float soilTemperature1 ;//土壤温度1
    public Float soilTemperature1 ;
    @JSONField(name = "土壤温度2")
    public Float soilTemperature2 ;//土壤温度2
    public Float soilTemperature2 ;
    @JSONField(name = "土壤温度3")
    public Float soilTemperature3 ;//土壤温度3
    public Float soilTemperature3 ;
    @JSONField(name = "土壤温度4")
    public Float soilTemperature4 ;//土壤温度4
    public Float soilTemperature4 ;
    @JSONField(name = "土壤温度5")
    public Float soilTemperature5 ;
    @JSONField(name = "flexem_timestamp")
    public Long devDt ;//设备时间
@@ -52,7 +58,7 @@
    }
    public String getDevDtStr() {
        if(devDt == null){
        if(devDt != null){
            return DateTime.yyyy_MM_dd_HH_mm_ss(DateTime.getDate(devDt)) ;
        }else{
            return "" ;
@@ -73,7 +79,7 @@
        sb.append(" åœŸå£¤æ¸©åº¦3:" + soilTemperature3 + ", ") ;
        sb.append(" åœŸå£¤æ¸©åº¦4:" + soilTemperature4 + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" + devDt + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" +  this.getDevDtStr() + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" +  this.getDevDtStr()) ;
        sb.append("\n") ;
        return sb.toString() ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/upVos/StateVo.java
File was deleted
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol4Mqtt/pSdV1/upVos/WeatherVo.java
@@ -16,28 +16,34 @@
    @JSONField(name = "flexem_message_id")
    public Integer messageId ;//消息ID
    public Integer no ;//测站编号,其不在JSON数据中,其中主题中
    public Integer no ;//测站编号,其不在JSON数据中,其在主题中
    @JSONField(name = "二氧化碳")
    public Integer carbonDioxide ;//二氧化碳
    //@JSONField(name = "二氧化碳")
    //public Integer carbonDioxide ;
    @JSONField(name = "光照强度")
    public Integer lightIntensity ;//光照强度
    @JSONField(name = "大气压力")
    public Integer atmosphericPressure ;//大气压力
    //@JSONField(name = "大气压力")
    //public Integer atmosphericPressure ;
    @JSONField(name = "空气温度")
    public Integer airTemperature ;//空气温度
    public Float airTemperature ;
    @JSONField(name = "空气湿度")
    public Integer airHumidity ;//空气湿度
    public Float airHumidity ;
    @JSONField(name = "PM2.5")
    public Integer pm25 ;//PM2.5
    @JSONField(name = "紫外线")
    public Integer ultraviolet ;
    @JSONField(name = "PM10")
    public Integer pm10 ;//PM10
    @JSONField(name = "光照强度")
    public Integer lightIntensity ;
    @JSONField(name = "雨量")
    public Float rainfall ;
    @JSONField(name = "风速")
    public Float windSpeed ;
    @JSONField(name = "风向")
    public Integer windDirection ;
    @JSONField(name = "flexem_timestamp")
@@ -62,16 +68,18 @@
    public String toString(){
        StringBuilder sb = new StringBuilder();
        sb.append("气象数据=>") ;
        //sb.append(" äºŒæ°§åŒ–碳:" + carbonDioxide + ", ") ;
        //sb.append(" å¤§æ°”压力:" + atmosphericPressure + ", ") ;
        sb.append(" æ¶ˆæ¯ID:" + messageId + ", ") ;
        sb.append(" äºŒæ°§åŒ–碳:" + carbonDioxide + ", ") ;
        sb.append(" å…‰ç…§å¼ºåº¦ï¼š" + lightIntensity + ", ") ;
        sb.append(" å¤§æ°”压力:" + atmosphericPressure + ", ") ;
        sb.append(" ç©ºæ°”温度:" + airTemperature + ", ") ;
        sb.append(" ç©ºæ°”湿度:" + airHumidity + ", ") ;
        sb.append(" PM2.5:" + pm25 + ", ") ;
        sb.append(" PM10:" + pm10 + ", ") ;
        sb.append(" ç´«å¤–线:" + ultraviolet + ", ") ;
        sb.append(" å…‰ç…§å¼ºåº¦ï¼š" + lightIntensity + ", ") ;
        sb.append(" é›¨é‡ï¼š" + rainfall + ", ") ;
        sb.append(" é£Žé€Ÿï¼š" + windSpeed + ", ") ;
        sb.append(" é£Žå‘:" + windDirection + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" + devDt + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" +  this.getDevDtStr() + ", ") ;
        sb.append(" è®¾å¤‡æ—¶é—´ï¼š" +  this.getDevDtStr() ) ;
        sb.append("\n") ;
        return sb.toString() ;
    }
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/command/Command4MqttSv.java
New file
@@ -0,0 +1,137 @@
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.protocol4Mqtt.pSdV1.CodeSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.ProtocolConstantSdV1;
import com.dy.common.webUtil.BaseResponse;
import com.dy.pipIrrGlobal.daoPr.PrStManureMapper;
import com.dy.pipIrrGlobal.daoRm.RmCommandHistoryMapper;
import com.dy.pipIrrGlobal.pojoPr.PrStManure;
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 Command4MqttSv extends Web2RtuMw {
    /**
     * ä»Žæ•°æ®åº“中查询水肥机对象
     * @param prStManureDao
     * @param manureId
     * @return
     */
    public PrStManure getManure(PrStManureMapper prStManureDao, Long manureId){
        return prStManureDao.selectByPrimaryKey(manureId);
    }
    /**
     * æ£€æŸ¥åè®®æ˜¯å¦æ”¯æŒ
     * @param ctrlPo
     * @return
     */
    public String checkProtocol(PrStManure ctrlPo){
        return null ;
    }
    /**
     * æ ¹æ®åè®®èŽ·å–å‘½ä»¤åç§°
     * @param nowComCode
     * @param protocol
     * @return
     */
    public String getCommandName(String nowComCode, String protocol, Short protocolVer){
        if(protocol.equals(ProtocolConstantSdV1.protocolName)
            && protocolVer.equals(ProtocolConstantSdV1.protocolVer)) {
            return CodeSdV1.getCodeName(nowComCode) ;
        }
        return null ;
    }
    /**
     * ä¿å­˜å‘½ä»¤åŽ†å²è®°å½•
     * @param rmCommandHistoryDao
     * @param comId
     * @param protocol
     * @param commandCode
     * @param commandName
     * @param manureId
     * @param rtuAddr
     * @param param
     * @param operator
     * @return
     */
    public RmCommandHistory saveComHistoryPo(RmCommandHistoryMapper rmCommandHistoryDao,
                                             Long comId,
                                             String protocol,
                                             String commandCode,
                                             String commandName,
                                             Long manureId,
                                             String rtuAddr,
                                             Object param,
                                             Long operator) {
        RmCommandHistory po = new RmCommandHistory();
        po.setComId(comId);
        po.setCommandCode(commandCode);
        po.setCommandName(commandName);
        po.setIntakeId(manureId);
        po.setRtuAddr(rtuAddr);
        po.setProtocol(protocol);
        po.setParam((JSONObject) JSON.toJSON(param));
        po.setSendTime(new Date());
        po.setOperator(operator);
        int count = rmCommandHistoryDao.insertSelective(po) ;
        if(count == 0){
            po = null ;
        }
        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/daoRm/RmCommandHistoryMapper.java
@@ -61,6 +61,14 @@
     */
    VoUnclosedParam getUncloseParam(@Param("onLineMap") String onLineMap, @Param("intakeId")Long intakeId);
    /**
     * æ ¹æ®å–水口ID获取该取水口未关阀参数,平台选择取水口关阀使用
     * @param intakeId
     * @return
     */
    VoUnclosedParam getUncloseParamByCd(@Param("onLineMap") String onLineMap, @Param("intakeId")Long intakeId, @Param("code")String code);
    /**
     * æ ¹æ®æŒ‡å®šæ¡ä»¶èŽ·å–å‘½ä»¤æ—¥å¿—åŽ†å²è®°å½•æ€»æ•°
     * @param params
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoSe/SeClientCardMapper.java
@@ -268,4 +268,25 @@
     * @return
     */
    VoTermCard getTermCardInfo(@Param("cardAddr")String cardAddr);
    /**
     * èŽ·å–å·²æŒ‚å¤±æ°´å¡åˆ—è¡¨è®°å½•æ•°é‡
     * @param params
     * @return
     */
    Long getLostCardsCount(Map<?, ?> params);
    /**
     * èŽ·å–å·²æŒ‚å¤±æ°´å¡åˆ—è¡¨
     * @param params
     * @return
     */
    List<VoCards> getLostCards(Map<?, ?> params);
    /**
     * æ ¹æ®æ°´å¡ç¼–号获取卡信息
     * @param cardNum
     * @return
     */
    VoCardByClientNum getCardByCardNum(@Param("cardNum") String cardNum);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrStManure.java
@@ -37,6 +37,12 @@
    public Long id;
    /**
     * FBox序列号
     */
    @Schema(description = "FBox序列号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    public String fboxId ;
    /**
     * æ°´è‚¥ç«™ç¼–号
     */
    @Schema(description = "水肥站编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrStSoil.java
@@ -37,6 +37,12 @@
    public Long id;
    /**
     * FBox序列号
     */
    @Schema(description = "FBox序列号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    public String fboxId ;
    /**
     * å¢’情站编号
     */
    @Schema(description = "墒情站编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrStWeather.java
@@ -37,6 +37,12 @@
    public Long id;
    /**
     * FBox序列号
     */
    @Schema(description = "FBox序列号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    public String fboxId ;
    /**
     * æ°”象站编号
     */
    @Schema(description = "气象站编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/rtuMw/Web2RtuMw.java
@@ -214,6 +214,24 @@
    }
    /**
     * åˆ›å»ºå¤–部命令(发给控制器)
     * @param fboxId FBox设备序列号
     * @param comId å‘½ä»¤ID
     * @param code å‘½ä»¤code
     * @return
     */
    public Command createMQTTCommand(String fboxId, String comId, String protocol, Short protocolVer, String code) {
        Command com = new Command();
        com.id = comId;
        com.rtuAddr = fboxId;
        com.code = code ;
        com.protocol = protocol ;
        com.protocolVersion = protocolVer ;
        com.type = CommandType.mqttCommand;
        return com ;
    }
    /**
     * åˆ›å»ºå¤–部透传命令(发给控制器)
     * @param comId å‘½ä»¤ID
     * @param code å‘½ä»¤code
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voSe/VoCardByClientNum.java
New file
@@ -0,0 +1,46 @@
package com.dy.pipIrrGlobal.voSe;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
/**
 * @author ZhuBaoMin
 * @date 2025-01-15
 * @LastEditTime 2025-01-15
 * @Description æ ¹æ®å†œæˆ·ç¼–号获取卡信息返回对象
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Schema(name = "根据农户编号获取卡信息返回对象")
public class VoCardByClientNum {
    @Schema(description = "水卡编号")
    private String cardNum;
    @Schema(description = "卡状态码")
    private Integer cardState;
    @Schema(description = "卡类型")
    private String cardType;
    @Schema(description = "农户姓名")
    private String clientName;
    @Schema(description = "农户编号")
    private String clientNum;
    @Schema(description = "身份证号")
    private Long idCard;
    @Schema(description = "余额")
    private String money;
    @Schema(description = "手机号")
    private Long phone;
    @Schema(description = "状态名称")
    private String stateName;
}
pipIrr-platform/pipIrr-global/src/main/resources/application-common-mw.yml
@@ -11,6 +11,7 @@
  #   gz: 8103  9103
  #   lz: 8104  9104
  #   jc: 8105  9105
  #   jyg: 8106  9106
  pipIrr_mw_webPort: 8070 #通信中间件中应用,不能在web模块系统中应用
  pipIrr_mw_actutorPort: 9070 #通信中间件中应用,不能在web模块系统中应用
@@ -26,4 +27,5 @@
  #   gz: pipIrr_gz
  #   lz: pipIrr_lz
  #   jc: pipIrr_jc
  #   jyg: pipIrr_jyg
  spring_datasource_url_dbname: pipIrr_ym #数据库名称
pipIrr-platform/pipIrr-global/src/main/resources/application-common-web(121·þÎñÆ÷).yml
@@ -1,7 +1,7 @@
common:
  # 233服务器:ym,mj,sp,test
  # 121服务器:mq,yq,hlj,gz,lz,jc
  spring_main_datasource_names: mq,yq,hlj,gz,lz,jc
  # 121服务器:mq,yq,hlj,gz,lz,jc,jyg
  spring_main_datasource_names: mq,yq,hlj,gz,lz,jc,jyg
  # è™šæ‹Ÿå¡è¡¨:
  #      å­—段in_use意为占用状态,当为true时统一设置值为0
pipIrr-platform/pipIrr-global/src/main/resources/application-database-jyg.yml
New file
@@ -0,0 +1,69 @@
# æ•°æ®æºé…ç½®
spring:
    datasource: #配置数据源
        jyg:
            #name: ym
            type: com.alibaba.druid.pool.DruidDataSource
            driverClassName: com.mysql.cj.jdbc.Driver
#            url: jdbc:mysql://192.168.40.166:3306/pipIrr_jyg?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
#            url: jdbc:mysql://8.130.130.233:3306/pipIrr_jyg?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
            url: jdbc:mysql://127.0.0.1:3306/pipIrr_jyg?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&zeroDateTimeBehavior=convertToNull
            username: root
            password: dysql,;.abc!@#
            druid:
                # æ•°æ®æºåç§°ï¼šå½“存在多个数据源时,设置名字可以很方便的来进行区分,默认自动生成名称,格式是:"DataSource-" + System.identityHashCode(this)
                name: druid-mysql-jyg
                #配置初始化大小、最小、最大
                initialSize: 10
                minIdle: 10
                maxActive: 100
                # èŽ·å–è¿žæŽ¥æ—¶æœ€å¤§ç­‰å¾…æ—¶é—´,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁
                maxWait: 60000
                #配置间隔多久进行一次检测,检测需要关闭的空闲连接,单位毫秒。 é»˜è®¤æ˜¯60s,太长可能会导致无法及时检测到连接中断
                timeBetweenEvictionRunsMillis: 60000
                #配置一个连接在连接池中的最小生存时间、最大生存时间,超过最大生存时间会被移除,单位毫秒。
                minEvictableIdleTimeMillis: 300000
                maxEvictableIdleTimeMillis: 900000
                #探活、验证链接有效性的查询,新版本默认使用mysqlPing代替
                #validation-query: select 1 #注释掉,采用默认的mysqlPing
                #配置从连接池获取连接时,当连接空闲时间大于timeBetweenEvictionRunsMillis时是否检查连接有效性,true每次都检查;false不检查。
                testWhileIdle: true
                #配置从连接池获取连接时和向连接池归还连接时,是否检查连接有效性
                #每次获取或归还连接都检测太频繁,除非特别重要或网络特别不可靠等情况,建议用testWhileIdle + timeBetweenEvictionRunsMillis代替。-->
                testOnBorrow: false
                testOnReturn: false
                #配置是否定期探活、探活间隔, é»˜è®¤120s
                keepAlive: true
                #keepAliveBetweenTimeMillis must be greater than timeBetweenEvictionRunsMillis
                keepAliveBetweenTimeMillis: 1200000
                #配置一个连接最大使用次数,避免长时间使用相同连接造成服务器端负载不均衡。
                phyMaxUseCount: 1000
                #是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
                poolPreparedStatements: false
                #要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
                maxOpenPreparedStatements: -1
                #指定每个连接上PSCache的大小
                maxPoolPreparedStatementPerConnectionSize: 20
                #属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
                #监控统计用的filter:stat,日志用的filter:log4j,防御sql注入的filter:wall
                #filters: stat,wall,config
                filters: wall,config
                webStatFilter:
                    # æ·»åŠ è¿‡æ»¤è§„åˆ™
                    urlPattern: /*
                    # å¿½ç•¥è¿‡æ»¤æ ¼å¼
                    exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
                    statViewServlet:
                        # è®¾ç½®ip白名单
                        # allow: 127.0.0.1
                        # è®¾ç½®ip黑名单,优先级高于白名单
                        deny:
                        # è®¾ç½®æŽ§åˆ¶å°ç®¡ç†ç”¨æˆ·
                        #  loginUsername: root
                        #  loginPassword: root
                        # æ˜¯å¦å¯ä»¥é‡ç½®æ•°æ®
                        resetEnable: false
                        # å¼€å¯druid监控页面
                        #enabled: true
                        enabled: false
pipIrr-platform/pipIrr-global/src/main/resources/application-global(166webÎļþ»¨Éú¿Ç).yml
@@ -363,6 +363,8 @@
        comSendUrl: "http://127.0.0.1:8105/rtuMw/com/send"
    #Rtu远程命令结果回调地址
    rtuCallbackUrl_rm: "http://127.0.0.1:8081/remote/comRes/receive"
    #MQTT远程命令结果回调地址
    mqttCallbackUrl_rm: "http://127.0.0.1:8081/remote/mqttRes/receive"
    #接收通信中间件消息中心消息的地址
    mwMsCenterReceiveUrl_rm: "http://127.0.0.1:8081/remote/msCenter/receive"
    #rtu远程升级状态信息回调地址
pipIrr-platform/pipIrr-global/src/main/resources/application-global.yml
@@ -361,8 +361,13 @@
    jc:
        url: "http://127.0.0.1:8105"
        comSendUrl: "http://127.0.0.1:8105/rtuMw/com/send"
    jyg:
        url: "http://127.0.0.1:8106"
        comSendUrl: "http://127.0.0.1:8106/rtuMw/com/send"
    #Rtu远程命令结果回调地址
    rtuCallbackUrl_rm: "http://127.0.0.1:8081/remote/comRes/receive"
    #MQTT远程命令结果回调地址
    mqttCallbackUrl_rm: "http://127.0.0.1:8081/remote/mqttRes/receive"
    #接收通信中间件消息中心消息的地址
    mwMsCenterReceiveUrl_rm: "http://127.0.0.1:8081/remote/msCenter/receive"
    #rtu远程升级状态信息回调地址
@@ -471,6 +476,14 @@
            secret: SEC6042bc964d08899a5853eb321eb5a4d842a395982777f815bd07451c879228b7
        at-all: true
        mobile: 18602657034
    jyg:
        enable: false #是否启用
        robot:
            url: https://oapi.dingtalk.com/robot/send
            access-token: fecef8e7725998f8912af05419580861aafc73413c4920036c07c050fa33055f
            secret: SEC6042bc964d08899a5853eb321eb5a4d842a395982777f815bd07451c879228b7
        at-all: true
        mobile: 18602657034
#视频监控相关
video:
pipIrr-platform/pipIrr-global/src/main/resources/init-config(121·þÎñÆ÷).xml
@@ -380,5 +380,68 @@
                <item3 typeName="设备保养"/>
            </taskType>
        </org6>
        <org7 tag="jyg" name="嘉峪关" enable="true">
            <districts>
                <province name="甘肃省" num="62" level="0">
                    <city name="嘉峪关市" num="02" level="1">
                        <country name="新城镇" num="01" level="2" />
                    </city>
                </province>
            </districts>
            <dictionaries>
                <dict code="icProtocol" title="IC卡协议" valueType="2">
                    <dictItem>
                        <!-- é³å»ºä¼Ÿç‰ˆæœ¬IC卡协议 å¡ä¸­ç¼–号已经加长(与王江海版本一致),与纯老版本协议不同 -->
                        <item1 dictCode="icProtocol" value="icP202203" name="老卡协议" status="1" sort="0" />
                        <!-- çŽ‹æ±Ÿæµ·ç‰ˆæœ¬IC卡协议 -->
                        <item2 dictCode="icProtocol" value="icP202404" name="新卡协议" status="0" sort="1" />
                    </dictItem>
                </dict>
            </dictionaries>
            <user name="超级管理员" phone="admin" password="dyyjy" supperAdmin="1" />
            <payments>
                <item1 name="现金"/>
                <item2 name="POS机"/>
                <item3 name="银行转账"/>
            </payments>
            <settings>
                <item1 item_name="lng" item_value="98.28875541687012" remarks="经度"/>
                <item2 item_name="lat" item_value="39.77140971937612" remarks="纬度"/>
                <item3 item_name="zoomMp" item_value="12" remarks="手机地图缩放级别"/>
                <item4 item_name="zoomPc" item_value="19" remarks="PC机地图缩放级别"/>
                <item5 item_name="projectName" item_value="高效智慧管灌微灌云服务管理平台" remarks="项目名称"/>
            </settings>
            <waterTypes>
                <item1 typeName="灌溉用水"/>
                <item2 typeName="工业用水"/>
                <item3 typeName="生活用水"/>
                <item4 typeName="养殖用水"/>
                <item5 typeName="绿化用水"/>
            </waterTypes>
            <waterPrice price="0.90" />
            <irrigateProfile>
                <item1 defaultValue = "10" unit = "2" sort = "1" type = "1"/>
                <item2 defaultValue = "20" unit = "2" sort = "2" type = "1" />
                <item3 defaultValue = "1" unit = "1" sort = "3" type = "1"/>
                <item4 defaultValue = "2" unit = "1" sort = "4" type = "1"/>
                <item5 defaultValue = "20" unit = "3" sort = "1" type = "2"/>
                <item6 defaultValue = "30" unit = "3" sort = "2" type = "2"/>
                <item7 defaultValue = "50" unit = "3" sort = "3" type = "2"/>
                <item8 defaultValue = "80" unit = "3" sort = "4" type = "2"/>
            </irrigateProfile>
            <rechargeProfile>
                <item1 rechargeAmount = "50" sort = "1"/>
                <item2 rechargeAmount = "100" sort = "2" />
                <item3 rechargeAmount = "200" sort = "3"/>
                <item4 rechargeAmount = "300" sort = "4"/>
                <item5 rechargeAmount = "500" sort = "5"/>
                <item6 rechargeAmount = "1000" sort = "6"/>
            </rechargeProfile>
            <taskType>
                <item1 typeName="设备安装"/>
                <item2 typeName="设备维修"/>
                <item3 typeName="设备保养"/>
            </taskType>
        </org7>
    </orgs>
</config>
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrStManureMapper.xml
@@ -6,6 +6,7 @@
    <!--@Table pr_st_manure-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="no" jdbcType="INTEGER" property="no" />
    <result column="fbox_id" jdbcType="VARCHAR" property="fboxId" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="lng" jdbcType="DOUBLE" property="lng" />
    <result column="lat" jdbcType="DOUBLE" property="lat" />
@@ -14,11 +15,11 @@
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, `no`, `name`, lng, lat, remark, deleted
    id, fbox_id,`no`, `name`, lng, lat, remark, deleted
  </sql>
  <sql id="part_Column_List">
    <!--@mbg.generated-->
    id, `no`, `name`, lng, lat, remark
    id, fbox_id, `no`, `name`, lng, lat, remark
  </sql>
  <sql id="simple_Column_List">
    <!--@mbg.generated-->
@@ -50,11 +51,11 @@
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStManure">
    <!--@mbg.generated-->
    insert into pr_st_manure (id, `no`, `name`, lng,
    insert into pr_st_manure (id, fbox_id, `no`, `name`, lng,
      lat, remark, deleted)
    values (#{id,jdbcType=BIGINT}, #{no,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
        #{lng,jdbcType=DOUBLE}, #{lat,jdbcType=DOUBLE}, #{remark,jdbcType=VARCHAR},
        #{deleted,jdbcType=TINYINT})
    values (#{id,jdbcType=BIGINT}, #{fboxId,jdbcType=BIGINT}, #{no,jdbcType=INTEGER},
        #{name,jdbcType=VARCHAR}, #{lng,jdbcType=DOUBLE}, #{lat,jdbcType=DOUBLE},
        #{remark,jdbcType=VARCHAR},#{deleted,jdbcType=TINYINT})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStManure">
    <!--@mbg.generated-->
@@ -62,6 +63,9 @@
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="fboxId != null">
        fbox_id,
      </if>
      <if test="no != null">
        `no`,
@@ -85,6 +89,9 @@
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="fboxId != null">
        #{fboxId,jdbcType=BIGINT},
      </if>
      <if test="no != null">
        #{no,jdbcType=INTEGER},
@@ -110,6 +117,9 @@
    <!--@mbg.generated-->
    update pr_st_manure
    <set>
      <if test="fboxId != null">
        fbox_id = #{fboxId,jdbcType=BIGINT},
      </if>
      <if test="no != null">
        `no` = #{no,jdbcType=INTEGER},
      </if>
@@ -134,7 +144,8 @@
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStManure">
    <!--@mbg.generated-->
    update pr_st_manure
    set `no` = #{no,jdbcType=INTEGER},
    set fbox_id = #{fboxId,jdbcType=INTEGER},
      `no` = #{no,jdbcType=INTEGER},
      `name` = #{name,jdbcType=VARCHAR},
      lng = #{lng,jdbcType=DOUBLE},
      lat = #{lat,jdbcType=DOUBLE},
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrStSoilMapper.xml
@@ -6,6 +6,7 @@
    <!--@Table pr_st_soil-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="no" jdbcType="INTEGER" property="no" />
    <result column="fbox_id" jdbcType="VARCHAR" property="fboxId" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="lng" jdbcType="DOUBLE" property="lng" />
    <result column="lat" jdbcType="DOUBLE" property="lat" />
@@ -14,11 +15,11 @@
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, `no`, `name`, lng, lat, remark, deleted
    id, fbox_id,`no`, `name`, lng, lat, remark, deleted
  </sql>
  <sql id="part_Column_List">
    <!--@mbg.generated-->
    id, `no`, `name`, lng, lat, remark
    id, fbox_id, `no`, `name`, lng, lat, remark
  </sql>
  <sql id="simple_Column_List">
    <!--@mbg.generated-->
@@ -50,11 +51,11 @@
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStSoil">
    <!--@mbg.generated-->
    insert into pr_st_soil (id, `no`, `name`, lng,
    insert into pr_st_soil (id, fbox_id, `no`, `name`, lng,
    lat, remark, deleted)
    values (#{id,jdbcType=BIGINT}, #{no,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
    #{lng,jdbcType=DOUBLE}, #{lat,jdbcType=DOUBLE}, #{remark,jdbcType=VARCHAR},
    #{deleted,jdbcType=TINYINT})
    values (#{id,jdbcType=BIGINT}, #{fboxId,jdbcType=BIGINT}, #{no,jdbcType=INTEGER},
    #{name,jdbcType=VARCHAR}, #{lng,jdbcType=DOUBLE}, #{lat,jdbcType=DOUBLE},
    #{remark,jdbcType=VARCHAR},#{deleted,jdbcType=TINYINT})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStSoil">
    <!--@mbg.generated-->
@@ -62,6 +63,9 @@
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="fboxId != null">
        fbox_id,
      </if>
      <if test="no != null">
        `no`,
@@ -85,6 +89,9 @@
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="fboxId != null">
        #{fboxId,jdbcType=BIGINT},
      </if>
      <if test="no != null">
        #{no,jdbcType=INTEGER},
@@ -110,6 +117,9 @@
    <!--@mbg.generated-->
    update pr_st_soil
    <set>
      <if test="fboxId != null">
        fbox_id = #{fboxId,jdbcType=BIGINT},
      </if>
      <if test="no != null">
        `no` = #{no,jdbcType=INTEGER},
      </if>
@@ -134,7 +144,8 @@
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStSoil">
    <!--@mbg.generated-->
    update pr_st_soil
    set `no` = #{no,jdbcType=INTEGER},
    set fbox_id = #{fboxId,jdbcType=INTEGER},
    `no` = #{no,jdbcType=INTEGER},
    `name` = #{name,jdbcType=VARCHAR},
    lng = #{lng,jdbcType=DOUBLE},
    lat = #{lat,jdbcType=DOUBLE},
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrStWeatherMapper.xml
@@ -6,6 +6,7 @@
    <!--@Table pr_st_weather-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="no" jdbcType="INTEGER" property="no" />
    <result column="fbox_id" jdbcType="VARCHAR" property="fboxId" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="lng" jdbcType="DOUBLE" property="lng" />
    <result column="lat" jdbcType="DOUBLE" property="lat" />
@@ -14,11 +15,11 @@
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, `no`, `name`, lng, lat, remark, deleted
    id, fbox_id,`no`, `name`, lng, lat, remark, deleted
  </sql>
  <sql id="part_Column_List">
    <!--@mbg.generated-->
    id, `no`, `name`, lng, lat, remark
    id, fbox_id, `no`, `name`, lng, lat, remark
  </sql>
  <sql id="simple_Column_List">
    <!--@mbg.generated-->
@@ -50,11 +51,11 @@
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStWeather">
    <!--@mbg.generated-->
    insert into pr_st_weather (id, `no`, `name`, lng,
    insert into pr_st_weather (id, fbox_id, `no`, `name`, lng,
    lat, remark, deleted)
    values (#{id,jdbcType=BIGINT}, #{no,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},
    #{lng,jdbcType=DOUBLE}, #{lat,jdbcType=DOUBLE}, #{remark,jdbcType=VARCHAR},
    #{deleted,jdbcType=TINYINT})
    values (#{id,jdbcType=BIGINT}, #{fboxId,jdbcType=BIGINT}, #{no,jdbcType=INTEGER},
    #{name,jdbcType=VARCHAR}, #{lng,jdbcType=DOUBLE}, #{lat,jdbcType=DOUBLE},
    #{remark,jdbcType=VARCHAR},#{deleted,jdbcType=TINYINT})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStWeather">
    <!--@mbg.generated-->
@@ -62,6 +63,9 @@
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="fboxId != null">
        fbox_id,
      </if>
      <if test="no != null">
        `no`,
@@ -85,6 +89,9 @@
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="fboxId != null">
        #{fboxId,jdbcType=BIGINT},
      </if>
      <if test="no != null">
        #{no,jdbcType=INTEGER},
@@ -110,6 +117,9 @@
    <!--@mbg.generated-->
    update pr_st_weather
    <set>
      <if test="fboxId != null">
        fbox_id = #{fboxId,jdbcType=BIGINT},
      </if>
      <if test="no != null">
        `no` = #{no,jdbcType=INTEGER},
      </if>
@@ -134,7 +144,8 @@
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoPr.PrStWeather">
    <!--@mbg.generated-->
    update pr_st_weather
    set `no` = #{no,jdbcType=INTEGER},
    set fbox_id = #{fboxId,jdbcType=INTEGER},
    `no` = #{no,jdbcType=INTEGER},
    `name` = #{name,jdbcType=VARCHAR},
    lng = #{lng,jdbcType=DOUBLE},
    lat = #{lat,jdbcType=DOUBLE},
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmCommandHistoryMapper.xml
@@ -323,6 +323,35 @@
        LIMIT 0,1
    </select>
    <!--根据取水口ID获取该取水口未关阀参数-->
    <select id="getUncloseParamByCd" resultType="com.dy.pipIrrGlobal.voRm.VoUnclosedParam">
        SELECT com.rtu_addr               AS rtuAddr,
               com.param ->> '$.orderNo'  AS orderNo,
               com.param ->> '$.icCardNo' AS vcNum
        FROM rm_command_history com
            INNER JOIN pr_controller con ON com.rtu_addr = con.rtuAddr
            INNER JOIN pr_intake inta ON con.intakeId = inta.id
            INNER JOIN JSON_TABLE(
        <!--      '[{"rtuAddr":"620201000029","isOnLine":true},{"rtuAddr":"4000004","isOnLine":true},{"rtuAddr":"dy20240325","isOnLine":false}]',-->
        #{onLineMap},
        '$[*]' COLUMNS (
            rtuAddr VARCHAR(20) PATH '$.rtuAddr',
            isOnLine BOOLEAN PATH '$.isOnLine'
            )
            ) rtus ON com.rtu_addr = rtus.rtuAddr
        WHERE com.command_code = #{code}
          AND con.intakeId = #{intakeId}
          AND NOT EXISTS(
                SELECT *
                FROM rm_command_history
                WHERE (result IS NULL OR result = 1)
                  AND (command_code = '93' OR command_code = 'A3' OR command_code = '98')
                  AND param ->> '$.orderNo' = com.param ->> '$.orderNo'
            )
        ORDER BY com.send_time DESC
        LIMIT 0,1
    </select>
    <!--根据指定条件获取命令日志历史记录总数-->
    <select id="getCommandHistoriesCount" resultType="java.lang.Long">
        SELECT COUNT(*) AS recordCount
pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeClientCardMapper.xml
@@ -808,4 +808,60 @@
    ORDER BY card.createDt DESC
    LIMIT 1
  </select>
  <!--获取已挂失水卡列表记录数量-->
  <select id="getLostCardsCount" parameterType="java.util.Map" resultType="java.lang.Long">
    SELECT COUNT(*) AS recordCount
    FROM se_client_card card
    LEFT JOIN se_client cli ON card.clientId = cli.id
    WHERE card.state = 3
  </select>
  <!--获取已挂失水卡列表-->
  <select id="getLostCards" resultType="com.dy.pipIrrGlobal.voSe.VoCards">
    SELECT cli.clientNum,
    cli.name AS clientName,
    card.cardNum,
    cli.phone,
    cli.idCard,
    card.state AS cardState,
    '已挂失' AS stateName,
    '农户卡' AS cardType,
    FORMAT(card.money, 2) AS money
    FROM se_client_card card
    LEFT JOIN se_client cli ON card.clientId = cli.id
    WHERE card.state = 3
    ORDER BY card.lossDtDt DESC
    <trim prefix="limit ">
      <if test="start != null and count != null">
        #{start,javaType=Integer,jdbcType=INTEGER}, #{count,javaType=Integer,jdbcType=INTEGER}
      </if>
    </trim>
  </select>
  <!--根据水卡编号获取卡信息-->
  <select id="getCardByCardNum" resultType="com.dy.pipIrrGlobal.voSe.VoCardByClientNum">
    SELECT
        card.cardNum,
        card.state AS cardState,
        '农户卡' AS cardType,
        cli.name AS clientName,
        cli.clientNum,
        cli.idCard,
        FORMAT(card.money, 1) AS money,
        cli.phone,
        (CASE
            WHEN card.state = 1 THEN '正常'
            WHEN card.state = 2 THEN '已注销'
            WHEN card.state = 3 THEN '已挂失'
            WHEN card.state = 4 THEN '无效'
            ELSE '未知'
        END) AS stateName
    FROM se_client_card card
    INNER JOIN se_client cli ON card.clientId = cli.id
    WHERE card.cardNum = #{cardNum}
      AND card.state != 4
    ORDER BY card.createDt DESC
    LIMIT 1
  </select>
</mapper>
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/Server.java
@@ -470,10 +470,14 @@
                }else{
                    mqVo.svUserPassword = mqVo.svUserPassword.trim() ;
                }
                mqVo.poolMaxSize = conf.getSetAttrPlusInt(doc, "config.mqtt", "poolMaxSize", null, 5, 360000, null);
                if(mqVo.poolMaxSize <= 1 || mqVo.poolMaxSize > 1000){
                    throw new Exception("config.mqtt.poolMaxSize配置的连接池连接最大数量不合法") ;
                }
                mqVo.poolMaxSize = conf.getSetAttrPlusInt(doc, "config.mqtt", "poolMaxSize", null, 1, 1000, null);
                mqVo.sendInterval = conf.getSetAttrPlusInt(doc, "config.mqtt", "sendInterval", null, 1, 3600, null) * 1000L ;
                mqVo.reSendTimesByNoResult = conf.getSetAttrPlusInt(doc, "config.mqtt", "reSendTimesByNoResult", null, 0, 100, null);
                mqVo.comCacheTimeout = conf.getSetAttrPlusInt(doc, "config.mqtt", "comCacheTimeout", null, 1, 3600, null) * 1000L ;
                mqVo.useMemoryPersistence = conf.getSetAttrBoolean(doc, "config.mqtt", "useMemoryPersistence", null, null) ;
                String proAndDevIds = conf.getSetAttrTxt(doc, "config.mqtt", "protocolAndDeviceIds", null, false, null) ;
                if(proAndDevIds == null || proAndDevIds.trim().equals("")){
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/mqtt/DevStatusDealer.java
@@ -43,6 +43,16 @@
            return rsMap ;
        }
    }
    public static Boolean oneOnLine(String devId){
        synchronized (map){
            DevStatus st = map.get(devId) ;
            if(st != null){
                return st.onLine ;
            }
            return false ;
        }
    }
    /**
     * ç»Ÿè®¡åœ¨çº¿ä¸Žä¸åœ¨çº¿æƒ…况
     */
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/mqtt/MqttPubMsgNode.java
@@ -20,12 +20,16 @@
    public MqttPubMsg result ;//下行命令
    public Long cachTime ;//缓存时刻
    public boolean onceReceivedResult ;//已经收到命令应答
    public long lastSendTime = 0 ;//上次发送时间
    public int sendTimes = 0 ;//发送次数
    public MqttPubMsgNode(MqttPubMsg result){
        this.result = result ;
        this.cachTime = System.currentTimeMillis() ;
        this.onceReceivedResult = false ;
        this.lastSendTime = 0L ;
        this.sendTimes = 0 ;
    }
    /**
@@ -36,9 +40,13 @@
    public boolean dealSelf(Long now){
        if(this.onceReceivedResult){
            //已经收到命令结果
            //记录状态
            //RtuStatusDealer.commandSuccess(this.result.rtuAddr, this.result.downCode, this.result.downCodeName);
            return true ;
        }
        if(this.sendTimes >= (1 + MqttUnit.confVo.reSendTimesByNoResult)){
            return this.decideRemoveNodeFromCach(now, null) ;
        }
        if(this.lastSendTime != 0 && now - this.lastSendTime >= MqttUnit.confVo.sendInterval){
            return this.decideRemoveNodeFromCach(now, null) ;
        }
        boolean noConnect2MqSv = false ;
        MqttManager mqttManager = MqttManager.getInstance() ;
@@ -47,7 +55,7 @@
        noConnect2MqSv = mqttManager.poolIsClose() ;
        if(noConnect2MqSv){
            //未曾连接MQTT服务器
            return this.decideRemoveNodeFromCach(now) ;
            return this.decideRemoveNodeFromCach(now, null) ;
        }else{
            try {
                //如果网络不好或断网,此处用时较长
@@ -61,16 +69,18 @@
        }
        if(noConnect2MqSv){
            //未曾连接MQTT服务器
            return this.decideRemoveNodeFromCach(now) ;
            return this.decideRemoveNodeFromCach(now, null) ;
        }else{
            if(mqttClient != null && mqttClient.isConnected()){
                try {
                    mqttManager.publishMsg(mqttClient, this.result.topic.longName(), this.result.msg);
                    this.sendTimes ++ ;
                    this.lastSendTime = System.currentTimeMillis() ;
                    DevStatusDealer.afterSendPubMessage(this.result.deviceId);
                    RtuLogDealer.log4Mqtt(this.result.deviceId, "发布消息    ä¸»é¢˜ï¼š" + this.result.topic + "   æ¶ˆæ¯ï¼š" + this.result.msg);
                    log.info("发布MQTT消息(主题=" + this.result.topic + ")" + this.result.msg);
                    RtuLogDealer.log4Mqtt(this.result.deviceId, "发布消息    ä¸»é¢˜ï¼š" + this.result.topic.longName() + "   æ¶ˆæ¯ï¼š" + this.result.msg);
                    log.info("发布MQTT消息(主题=" + this.result.topic.longName() + ")" + this.result.msg);
                }catch (Exception e){
                    log.error("MQTT发布消息失败(主题=" + this.result.topic + ")" , e);
                    log.error("MQTT发布消息失败(主题=" + this.result.topic.longName() + ")" , e);
                }finally {
                    mqttManager.pushMqttClient(mqttClient);
                }
@@ -81,18 +91,18 @@
                }
            }else{
                //未曾连接MQTT服务器
                return this.decideRemoveNodeFromCach(now) ;
                return this.decideRemoveNodeFromCach(now, false) ;
            }
        }
    }
    private boolean decideRemoveNodeFromCach(Long now){
        if(!this.result.isCacheForOffLine){
    private boolean decideRemoveNodeFromCach(Long now, Boolean isOffLine){
        if(isOffLine != null && isOffLine.booleanValue() && !this.result.isCacheForOffLine){
            //不在线命令不缓存
            return true ;
        }else{
            //不在线命令缓存
            if(now - this.cachTime >= ServerProperties.offLineCacheTimeout){
            if(now - this.cachTime >= MqttUnit.confVo.comCacheTimeout){
                //缓存超时
                return true ;
            }
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/mqtt/MqttUnitConfigVo.java
@@ -13,6 +13,9 @@
    public String svUserName ;//
    public String svUserPassword ;//
    public Integer poolMaxSize ;//
    public Long sendInterval ;//
    public Integer reSendTimesByNoResult ;//
    public Long comCacheTimeout ;//
    public Boolean useMemoryPersistence ;
    public String[] protocolAndDeviceIds ;//设备协议与ID(FBox)id
    public String[] deviceIds ;//设备(FBox)id
@@ -28,7 +31,10 @@
        this.svUserName = "dyyjy" ;
        this.svUserPassword = "Dyyjy2025,;.abc!@#" ;
        this.poolMaxSize = 10 ;
        useMemoryPersistence = true ;
        this.sendInterval = 60000L ;
        this.reSendTimesByNoResult = 0 ;
        this.comCacheTimeout = 60000L ;
        this.useMemoryPersistence = true ;
        this.pubTopicQos = 1 ;
        this.noSubThenOff = 10 * 60 * 10000L ;
    }
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/TkMqttData.java
@@ -1,6 +1,6 @@
package com.dy.rtuMw.server.rtuData;
import com.dy.common.mw.protocol4Mqtt.pSdV1.MqttSubMsgSdV1;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.rtuMw.server.rtuData.pSdV1.TkFindPSdV1;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -26,7 +26,7 @@
        if(data == null){
            log.error("严重错误,Mqtt订阅消息数据为空!" );
        }else{
            if(data instanceof MqttSubMsgSdV1){
            if(data instanceof MqttSubMsg){
                this.toNextOneTask(data, TkFindPSdV1.taskId);
            }else{
                log.error("严重错误,该数据类型(" + data.getClass().getName() + "),接收数据任务还未实现!" );
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/pSdV1/TkFindPSdV1.java
@@ -1,6 +1,6 @@
package com.dy.rtuMw.server.rtuData.pSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.MqttSubMsgSdV1;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.rtuMw.server.rtuData.TaskSurpport;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -24,7 +24,7 @@
    @Override
    public void execute(Object data) {
        //前面的任务已经判断了data不为空
        MqttSubMsgSdV1 msg = (MqttSubMsgSdV1)data ;
        MqttSubMsg msg = (MqttSubMsg)data ;
        log.info(msg.toString());
    }
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/web/com/CommandCtrl.java
@@ -7,6 +7,7 @@
import com.dy.rtuMw.server.forTcp.TcpSessionCache;
import com.dy.rtuMw.server.local.CommandInnerDeaLer;
import com.dy.rtuMw.server.local.ReturnCommand;
import com.dy.rtuMw.server.mqtt.DevStatusDealer;
import com.dy.rtuMw.server.mqtt.MqttManager;
import com.dy.rtuMw.server.msCenter.MsCenterUnit;
import com.dy.rtuMw.server.tasks.WebDownCom4MqttTask;
@@ -375,15 +376,18 @@
     * @return ç»“æžœ
     */
    private BaseResponse<Command> dealMqttCommand(Command command){
        String rtuAddr = command.getRtuAddr() ;
        if(rtuAddr == null || rtuAddr.trim().equals("")){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,设备ID为空!", command.getId(), command.getCode())) ;
        String mqttDevId = command.getRtuAddr() ;//FBox设备号
        if(mqttDevId == null || mqttDevId.trim().equals("")){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,FBox设备ID为空!", command.getId(), command.getCode())) ;
        }
        if(!ServerProperties.mqttUnitEnable.booleanValue()){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,MQTT连接模块配置未启动!", command.getId(), command.getCode())) ;
        }
        if(MqttManager.getInstance().poolIsClose()){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,MQTT连接池水创建成功!", command.getId(), command.getCode())) ;
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,MQTT连接池未创建成功!", command.getId(), command.getCode())) ;
        }
        if(!DevStatusDealer.oneOnLine(mqttDevId)){
            return BaseResponseUtils.buildError(ReturnCommand.errored("出错,FBox设备未在线!", command.getId(), command.getCode())) ;
        }
        //生成异步任务
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/config.properties
@@ -10,6 +10,7 @@
#   ç”˜å·žï¼š gz
#   å‡‰å·žï¼š lz
#   é‡‘川: jc
#   å˜‰å³ªå…³ï¼š jyg
base.orgTag=ym
# 233服务器:
@@ -24,7 +25,8 @@
#   ç”˜å·žï¼š 60103
#   å‡‰å·žï¼š 60104
#   é‡‘川: 60105
tcp.port=60000ba_divide
#   å˜‰å³ªå…³ï¼š 60106
tcp.port=60000
#RTU上行数据最小间隔,大于这个间隔认为设备离线了,测控一体阀是3,表阀一体机是6,默认采用时间最长的6
base.upData.min.interval=6
@@ -45,8 +47,13 @@
#   ç”˜å·žï¼š mqtt.enable=false  mqtt.protocolAndDeviceIds= mqtt.topicAndQos=
#   å‡‰å·žï¼š mqtt.enable=false  mqtt.protocolAndDeviceIds= mqtt.topicAndQos=
#   é‡‘川: mqtt.enable=true  mqtt.protocolAndDeviceIds=? mqtt.topicAndQos=weather/1,1;soil/1,1;manure/1,1;state/1,1
#   å˜‰å³ªå…³ï¼š mqtt.enable=true  mqtt.protocolAndDeviceIds=? mqtt.topicAndQos=weather/1,1;soil/1,1;manure/1,1;state/1,1
mqtt.enable=false
mqtt.protocolAndDeviceIds=sd1/338220031439,sd1/338220031440
mqtt.subTopicAndQos=weather/1,1;soil/1,1;manure/1,1;state/1,1
mqtt.ip=127.0.0.1
mqtt.port=1883
mqtt.user=dyyjy
mqtt.password=Dyyjy2025,;.abc!@#
mqtt.protocolAndDeviceIds=
mqtt.subTopicAndQos=
#MQtt设备在一定时间(分钟)后未发布消息,认为设备离线
mqtt.noSubThenOff=10
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/config.xml
@@ -171,6 +171,9 @@
    svUserName MQTT服务器用户名
    svUserPassword MQTT服务器用户密码
    poolMaxSize è¿žæŽ¥æ± æœ€å¤§è¿žæŽ¥æ•°
    sendInterval å‘½ä»¤å‘送间隔(单位秒),取值范围是1~3600
    reSendTimesByNoResult æœªæ”¶åˆ°å‘½ä»¤ç»“果时,最大重复发送次数,取值范围是0~100, 0时表示不重复发送
    comCacheTimeout: å‘½ä»¤æœ€å¤§ç¼“存时长(秒),取值范围是1~3600
    useMemoryPersistence ä½¿ç”¨å†…存持久化而非默认的文件持久化(true是 false否)
    protocolAndDeviceIds åœ¨å­ç³»ç»Ÿï¼ˆorgTag)中接入的设备(FBox)所用协议及设备id集合,多个用逗号隔开,协议与ID用正斜杠隔开,例如:sd1/338220031439,sd1/338220031440
    subTopicAndQos: è®¢é˜…主题与Qos,主题名与其Qos用逗号隔开,多个主题及Qos用分号隔开,例如:ym/topic1,1;ym/topic2,1;ym/topic3,1,如果有多个OrgTag,主题前缀用其OrgTag
@@ -181,11 +184,14 @@
    noSubThenOff: MQtt设备在一定时间(分钟)后未发布消息,认为设备离线
     -->
    <mqtt enable="${mqtt.enable}"
          svIp="121.199.41.121"
          svPort="1883"
          svUserName="dyyjy"
          svUserPassword="Dyyjy2025,;.abc!@#"
          svIp="${mqtt.ip}"
          svPort="${mqtt.port}"
          svUserName="${mqtt.user}"
          svUserPassword="${mqtt.password}"
          poolMaxSize="10"
          sendInterval="60"
          reSendTimesByNoResult="0"
          comCacheTimeout="30"
          useMemoryPersistence="true"
          protocolAndDeviceIds="${mqtt.protocolAndDeviceIds}"
          subTopicAndQos="${mqtt.subTopicAndQos}"
pipIrr-platform/pipIrr-mw/pipIrr-param-set/src/main/java/com/dy/pipIrrParamSet/console/Command.java
@@ -21,8 +21,8 @@
    static{
        commands = new String[]{
                "config æŸ¥çœ‹é…ç½®ä¿¡æ¯",    
                "mw 121 [tag] å‘½ä»¤å«ä¹‰ï¼šé€šä¿¡ä¸­é—´ä»¶åœ¨äº‘服务器(121.199.41.121)上的[tag](元谋ym,沙盘sp测试test,梅江mj,民勤mq,延庆yq,黑龙江hlj,甘州gz,凉州lz,金川jc)系统配置",
                "mw 233 [tag] å‘½ä»¤å«ä¹‰ï¼šé€šä¿¡ä¸­é—´ä»¶åœ¨äº‘服务器(8.130.130.233)上的[tag](元谋ym,沙盘sp测试test,梅江mj,民勤mq,延庆yq,黑龙江hlj,甘州gz,凉州lz,金川jc)系统配置",
                "mw 121 [tag] å‘½ä»¤å«ä¹‰ï¼šé€šä¿¡ä¸­é—´ä»¶åœ¨äº‘服务器(121.199.41.121)上的[tag](元谋ym,沙盘sp测试test,梅江mj,民勤mq,延庆yq,黑龙江hlj,甘州gz,凉州lz,金川jc,嘉峪关jyg)系统配置",
                "mw 233 [tag] å‘½ä»¤å«ä¹‰ï¼šé€šä¿¡ä¸­é—´ä»¶åœ¨äº‘服务器(8.130.130.233)上的[tag](元谋ym,沙盘sp测试test,梅江mj,民勤mq,延庆yq,黑龙江hlj,甘州gz,凉州lz,金川jc,嘉峪关jyg)系统配置",
                "web 121 å‘½ä»¤å«ä¹‰ï¼šweb模块在云服务器(121.199.41.121)上的配置",
                "web 233 å‘½ä»¤å«ä¹‰ï¼šweb模块在云服务器(8.130.130.233)上的配置",
                "exit é€€å‡º",
pipIrr-platform/pipIrr-mw/pipIrr-param-set/src/main/java/com/dy/pipIrrParamSet/paramSet/ParamKey.java
@@ -31,8 +31,12 @@
    public static final String TcpPort = "tcpPort" ;
    public static final String UpDataMinInterval = "upDataMinInterval" ;
    public static final String WebPort = "webPort" ;
    public static final String MqttEnable = "mqttEnable" ;
    public static final String MqttNoSubThenOff = "noSubThenOff" ;
    public static final String ActutorPort = "actutorPort" ;
    public static final String DbName = "dbName" ;
    public static final String MqttEnable = "mqttEnable" ;
    public static final String MqttNoSubThenOff = "mqttNoSubThenOff" ;
    public static final String mqttServerIp = "mqttServerIp" ;
    public static final String mqttServerPort = "mqttServerPort" ;
    public static final String mqttProtocolAndDeviceIds = "mqttProtocolAndDeviceIds" ;
    public static final String mqttSubTopicAndQos = "mqttSubTopicAndQos" ;
}
pipIrr-platform/pipIrr-mw/pipIrr-param-set/src/main/java/com/dy/pipIrrParamSet/paramSet/ParamSetMw.java
@@ -123,6 +123,14 @@
                    newLine = "base.upData.min.interval=" + paramMap.get(ParamKey.UpDataMinInterval);
                }else if(newLine != null && newLine.trim().startsWith("mqtt.enable=")){
                    newLine = "mqtt.enable=" + paramMap.get(ParamKey.MqttEnable);
                }else if(newLine != null && newLine.trim().startsWith("mqtt.ip=")){
                    newLine = "mqtt.ip=" + paramMap.get(ParamKey.mqttServerIp);
                }else if(newLine != null && newLine.trim().startsWith("mqtt.port=")){
                    newLine = "mqtt.port=" + paramMap.get(ParamKey.mqttServerPort);
                }else if(newLine != null && newLine.trim().startsWith("mqtt.protocolAndDeviceIds=")){
                    newLine = "mqtt.protocolAndDeviceIds=" + paramMap.get(ParamKey.mqttProtocolAndDeviceIds);
                }else if(newLine != null && newLine.trim().startsWith("mqtt.subTopicAndQos=")){
                    newLine = "mqtt.subTopicAndQos=" + paramMap.get(ParamKey.mqttSubTopicAndQos);
                }else if(newLine != null && newLine.trim().startsWith("mqtt.noSubThenOff=")){
                    newLine = "mqtt.noSubThenOff=" + paramMap.get(ParamKey.MqttNoSubThenOff);
                }
@@ -154,16 +162,28 @@
        key = ParamKey.WebPort;
        this.getConfig(env, map, paramNamePre + key, key);
        key = ParamKey.ActutorPort;
        this.getConfig(env, map, paramNamePre + key, key);
        key = ParamKey.DbName;
        this.getConfig(env, map, paramNamePre + key, key);
        key = ParamKey.MqttEnable;
        this.getConfig(env, map, paramNamePre + key, key);
        key = ParamKey.MqttNoSubThenOff;
        this.getConfig(env, map, paramNamePre + key, key);
        key = ParamKey.ActutorPort;
        key = ParamKey.mqttProtocolAndDeviceIds;
        this.getConfig(env, map, paramNamePre + key, key);
        key = ParamKey.DbName;
        key = ParamKey.mqttServerIp;
        this.getConfig(env, map, paramNamePre + key, key);
        key = ParamKey.mqttServerPort;
        this.getConfig(env, map, paramNamePre + key, key);
        key = ParamKey.mqttSubTopicAndQos;
        this.getConfig(env, map, paramNamePre + key, key);
        return map ;
pipIrr-platform/pipIrr-mw/pipIrr-param-set/src/main/resources/application-params.yml
@@ -4,90 +4,143 @@
            orgTag: ym
            tcpPort: 60000
            upDataMinInterval: 6
            mqttEnable: false
            noSubThenOff: 10
            webPort: 8070
            actutorPort: 9070
            dbName: pipIrr_ym
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        sp:
            orgTag: sp
            tcpPort: 62000
            upDataMinInterval: 6
            mqttEnable: false
            noSubThenOff: 10
            webPort: 8073
            actutorPort: 9073
            dbName: pipIrr_sp
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        test:
            orgTag: test
            tcpPort: 65000
            upDataMinInterval: 6
            mqttEnable: false
            noSubThenOff: 10
            webPort: 8072
            actutorPort: 9072
            dbName: pipIrr_test
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        mj:
            orgTag: mj
            tcpPort: 61000
            upDataMinInterval: 6
            mqttEnable: false
            noSubThenOff: 10
            webPort: 8071
            actutorPort: 9071
            dbName: pipIrr_mj
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
    sv121:
        mq:
            orgTag: mq
            tcpPort: 60100
            upDataMinInterval: 6
            mqttEnable: true
            noSubThenOff: 10
            webPort: 8100
            actutorPort: 9100
            dbName: pipIrr_mq
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        yq:
            orgTag: yq
            tcpPort: 60101
            upDataMinInterval: 6
            mqttEnable: false
            noSubThenOff: 10
            webPort: 8101
            actutorPort: 9101
            dbName: pipIrr_yq
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        hlj:
            orgTag: hlj
            tcpPort: 60102
            upDataMinInterval: 6
            mqttEnable: false
            noSubThenOff: 10
            webPort: 8102
            actutorPort: 9102
            dbName: pipIrr_hlj
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        gz:
            orgTag: gz
            tcpPort: 60103
            upDataMinInterval: 6
            mqttEnable: false
            noSubThenOff: 10
            webPort: 8103
            actutorPort: 9103
            dbName: pipIrr_gz
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        lz:
            orgTag: lz
            tcpPort: 60104
            upDataMinInterval: 6
            mqttEnable: false
            noSubThenOff: 10
            webPort: 8104
            actutorPort: 9104
            dbName: pipIrr_lz
            mqttEnable: false
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        jc:
            orgTag: jc
            tcpPort: 60105
            upDataMinInterval: 6
            mqttEnable: true
            noSubThenOff: 10
            webPort: 8105
            actutorPort: 9105
            dbName: pipIrr_jc
            mqttEnable: true
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds:
            mqttSubTopicAndQos:
        jyg:
            orgTag: jyg
            tcpPort: 60106
            upDataMinInterval: 6
            webPort: 8106
            actutorPort: 9106
            dbName: pipIrr_jyg
            mqttEnable: true
            mqttNoSubThenOff: 10
            mqttServerIp: 127.0.0.1
            mqttServerPort: 1883
            mqttProtocolAndDeviceIds: sd1/2430002404000840,sd1/2430002404000840
            mqttSubTopicAndQos: weather/1,1;soil/1,1;manure/1,1
pipIrr-platform/pipIrr-web/pipIrr-web-app/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-base/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-file/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-gis/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-irrigate/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-operation/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-project/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/PipIrrRemoteApplication.java
@@ -1,7 +1,9 @@
package com.dy.pipIrrRemote;
import com.dy.common.multiDataSource.EnableMultiDataSource;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
@@ -10,7 +12,7 @@
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
@Slf4j
@SpringBootApplication
@EnableScheduling //启动定时任务,本模块websocket发送心跳
@ServletComponentScan //扫描servlet,本模块中启动websocket
@@ -40,3 +42,18 @@
    }
}
//public class PipIrrRemoteApplication implements CommandLineRunner {
//
//    public static void main(String[] args) {
//        SpringApplication.run(PipIrrRemoteApplication.class, args);
//    }
//    //验证log是否输出
//    @Override
//    public void run(String... args) throws Exception {
//        log.trace("Trace level log");
//        log.debug("Debug level log");
//        log.info("Info level log");
//        log.warn("Warn level log");
//        log.error("Error level log");
//    }
//}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandResultCtrl.java
@@ -35,9 +35,9 @@
        if(codeDataObj != null){
            if(codeDataObj instanceof JSONObject){
                codeData = protocolData == null ? null : (protocolData.getJSONObject("subData")) ; //协议功能码数据
            }else if(codeDataObj instanceof JSONArray){{
            }else if(codeDataObj instanceof JSONArray){
                codeArrayData = protocolData == null ? null : (protocolData.getJSONArray("subData")) ; //协议功能码数据
            }}
            }
        }
        JSONObject job_response = new JSONObject();
        job_response.put("data", codeData!=null?codeData:(codeArrayData!=null?codeArrayData:null));
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/MqttResultCtrl.java
New file
@@ -0,0 +1,40 @@
package com.dy.pipIrrRemote.common;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.pipIrrGlobal.command.ComResultWait;
import com.dy.pipIrrGlobal.command.ComSupport;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
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 java.util.concurrent.CompletableFuture;
/**
 * @author ZhuBaoMin
 * @date 2024-05-23 8:19
 * @LastEditTime 2024-05-23 8:19
 * @Description
 */
@Slf4j
@RestController
@RequestMapping(path="mqttRes")
public class MqttResultCtrl extends ComSupport {
    @PostMapping(path = "receive", consumes = MediaType.APPLICATION_JSON_VALUE)
    public void receive(@RequestBody MqttSubMsg subMsg) {
        if(subMsg != null){
            CompletableFuture<MqttSubMsg> feature = (CompletableFuture<MqttSubMsg>) ComResultWait.get(Long.parseLong(subMsg.commandId));
            if(feature != null) {
                feature.complete(subMsg);
            }else{
                //超时,feature被清除了
            }
        }else{
            log.error("mqtt协议消息为空");
        }
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/Dto4MqttBase.java
New file
@@ -0,0 +1,33 @@
package com.dy.pipIrrRemote.common.dto;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
 * @author ZhuBaoMin
 * @date 2024-05-22 16:54
 * @LastEditTime 2024-05-22 16:54
 * @Description è®¾ç½®å‘½ä»¤åŸºç±»
 */
@Data
public class Dto4MqttBase {
    public static final long serialVersionUID = 202506201459001L;
    /**
     * æ°´è‚¥æœºID
     */
    @NotNull(message = "水肥机不能为空")
    public Long manureId;
    /**
     * æ°´è‚¥æœºåç§°
     */
    public String manureName;
    /**
     * æ“ä½œäºº
     */
    @NotNull(message = "操作人不能为空")
    public Long operator;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/common/Cd4MqttParameter.java
New file
@@ -0,0 +1,15 @@
package com.dy.pipIrrRemote.monitor.common;
import lombok.Data;
import lombok.experimental.SuperBuilder;
/**
 * @Author: liurunyu
 * @Date: 2025/5/9 16:11
 * @Description
 */
@Data
@SuperBuilder
public class Cd4MqttParameter {
    public Integer no ;//设备编号
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/common/Com4MqttCtrl.java
New file
@@ -0,0 +1,194 @@
package com.dy.pipIrrRemote.monitor.common;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.common.util.Callback;
import com.dy.common.util.IDLongGenerator;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrGlobal.command.ComResultWait;
import com.dy.pipIrrGlobal.pojoPr.PrStManure;
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.validation.BindingResult;
import org.springframework.web.client.RestTemplate;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
/**
 * @Author: liurunyu
 * @Date: 2025/5/9 14:53
 * @Description
 */
public abstract class Com4MqttCtrl {
    @Autowired
    protected Environment env ;
    @Autowired
    protected RestTemplate restTemplate ;
    @Value("${mw.waitMwRtnResultTimeout}")
    protected int waitMwRtnResultTimeout ;
    @Value("${mw.mqttCallbackUrl_rm}")
    protected String mqttResultSendWebUrl;
    //水肥机对象
    protected PrStManure ctrlPo ;
    //异步等待器
    protected CompletableFuture<MqttSubMsg> feature;
    //命令名称
    protected String comName ;
    //命令日志id
    protected Long comId ;
    /**
     * å‘送命令前-1:验证
     * @param comSv
     * @param comCode
     * @param dto
     * @param bindingResult
     * @return
     */
    public BaseResponse<Object> pre1(Com4MqttSv comSv, String comCode, Dto4MqttBase 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) ;
        }
        return  null ;
    }
    /**
     * å‘送命令前-2:获得数据
     * @param comSv
     * @param protocol
     * @param protocolVer
     * @param comCode
     * @param dto
     * @param bindingResult
     * @return
     */
    public BaseResponse<Object> pre2(Com4MqttSv comSv, String protocol, Short protocolVer, String comCode, Dto4MqttBase dto, BindingResult bindingResult) {
        //得到水肥机对象
        ctrlPo = comSv.getManure(dto.getManureId());
        if (ctrlPo == null) {
            return BaseResponseUtils.buildError("服务端出错,从数据库中未得到水肥机数据") ;
        }
        //检查协议
        String msg = comSv.checkProtocol(ctrlPo) ;
        if(msg != null) {
            return BaseResponseUtils.buildError("服务端出错," + msg) ;
        }
        //得到功能码对应的命令名称
        comName = comSv.getCommandName(comCode, protocol, protocolVer) ;
        if(comName == null) {
            return BaseResponseUtils.buildError("服务端出错,未得到功能码对应命令名称") ;
        }
        return  null ;
    }
    /**
     * å‘送命令前-3:保存命令日志
     * @param comSv sv对象
     * @param manureId æ°´è‚¥æœºID
     * @param operator å½“前用登录用户id(操作人)
     * @param protocol åè®®
     * @param protocolVerion åè®®
     * @param comCode åŠŸèƒ½ç 
     * @param param å‘½ä»¤å‚æ•°
     * @return
     */
    public BaseResponse<Object> pre3(Com4MqttSv comSv, Long manureId, Long operator, String protocol, Short protocolVerion, String comCode, Cd4MqttParameter param) {
        comId = new IDLongGenerator().generate();
        //生成并保存命令日志
        RmCommandHistory po = comSv.saveComHistoryPo(comId,
                protocol + protocolVerion ,
                comCode,
                comName,
                manureId,
                ctrlPo.fboxId ,
                param,
                operator);
        if(po == null){
            return BaseResponseUtils.buildError("服务端出错,未能生成并保存命令日志") ;
        }
        return  null ;
    }
    /**
     * å‘送命令前-4:准备Feature
     * @return
     */
    public void pre4() {
        feature = new CompletableFuture<>();
        ComResultWait.put(comId, feature);
    }
    /**
     * å‘送命令
     * @param comSv
     * @param com
     * @return
     */
    public BaseResponse<Object> doSend(Com4MqttSv comSv, Command com){
        //得到通信中间件发送命令的web URL
        String rqUrl = comSv.get2MwRequestUrl(env, comSv.ContextComSend) ;
        //向通信中间件发送web请求
        BaseResponse res = comSv.sendPostRequest2Mw(restTemplate, rqUrl, com) ;
        //处理通信中间件对web请求的响应
        String msg = comSv.dealMwDealResponse(res) ;
        if(msg != null) {
            return BaseResponseUtils.buildError(msg) ;
        }else{
            return null ;
        }
    }
    /**
     * å‘送命令后
     * @return
     */
    public BaseResponse<Object> after(String comCode, Callback callback) {
        try{
            //等待通信中间件通知水肥机执行命令上行数据(命令结果)
            MqttSubMsg subMsg = feature.get(waitMwRtnResultTimeout, TimeUnit.SECONDS);
            return BaseResponseUtils.buildSuccess(this.dealComResult(comCode, subMsg, callback));
        }catch (Exception e){
            return BaseResponseUtils.buildFail("等待通信中间件通知命令结果超时");
        }
    }
    /**
     * å‘送命令最后
     * @return
     */
    public void end(){
        try {
            //最后清除CompletableFuture缓存
            if(ComResultWait.contain(comId)){
                ComResultWait.remove(comId);
            }
        }catch (Exception ee){}
    }
    /**
     * éªŒè¯
     * @param dto
     * @return
     */
    protected abstract String checkDto(Dto4MqttBase dto) ;
    /**
     * ç”Ÿæˆå‘½ä»¤è¿”回信息
     */
    protected abstract String dealComResult(String code, MqttSubMsg subMsg, Callback callback);
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/common/Com4MqttSv.java
New file
@@ -0,0 +1,50 @@
package com.dy.pipIrrRemote.monitor.common;
import com.dy.pipIrrGlobal.command.Command4MqttSv;
import com.dy.pipIrrGlobal.daoPr.PrStManureMapper;
import com.dy.pipIrrGlobal.daoRm.RmCommandHistoryMapper;
import com.dy.pipIrrGlobal.pojoPr.PrStManure;
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
/**
 * @Author: liurunyu
 * @Date: 2025/5/9 14:45
 * @Description
 */
public class Com4MqttSv extends Command4MqttSv {
    @Autowired
    protected PrStManureMapper prStManureDao ;
    @Autowired
    protected RmCommandHistoryMapper rmCommandHistoryDao ;
    public PrStManure getManure(Long manureId){
        return this.getManure(prStManureDao, manureId);
    }
    /**
     * åˆ›å»ºå‘½ä»¤æ—¥å¿—对象
     *
     * @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 manureId,
                                             String rtuAddr,
                                             Object param,
                                             Long operator) {
        return this.saveComHistoryPo(rmCommandHistoryDao, comId, protocol, commandCode, commandName, manureId, rtuAddr, param, operator) ;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/common/ComSv.java
@@ -93,4 +93,20 @@
        jsonArr.add(jsonObj);
        return rmCommandHistoryDao.getUncloseParam(jsonArr.toJSONString(), intakeId);
    }
    /**
     * æ ¹æ®å–水口ID获取该取水口未关阀参数,平台选择取水口关阀使用
     * @param intakeId
     * @param rtuAddr
     * @param code
     * @return
     */
    public VoUnclosedParam selectUncloseParamByCd(Long intakeId, String rtuAddr, String code) {
        JSONArray jsonArr = new JSONArray();
        JSONObject jsonObj = new JSONObject();
        jsonObj.put("rtuAddr", rtuAddr);
        jsonObj.put("isOnLine", true);
        jsonArr.add(jsonObj);
        return rmCommandHistoryDao.getUncloseParamByCd(jsonArr.toJSONString(), intakeId, code);
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdCtrl.java
New file
@@ -0,0 +1,121 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.fault;
import com.alibaba.fastjson2.JSON;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.common.mw.protocol4Mqtt.pSdV1.CodeSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.ProtocolConstantSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.upVos.ManureVo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import com.dy.pipIrrRemote.monitor.common.Com4MqttCtrl;
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.context.annotation.Scope;
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 java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:35
 * @Description
 */
@Slf4j
@Tag(name = "远程命令", description = "清除故障")
@RestController("mqttSd1FaultCtrl")
@RequestMapping(path = "mqttSd1/fault")
@RequiredArgsConstructor
@Scope("prototype") //因为有对象类属性,所以采用原型模式,每次请求新建一个实例对象
public class CdCtrl extends Com4MqttCtrl {
    private static final String RtuSuccessMsg = "控制器接收并执行命令成功,无返回数据";
    private static final String Protocol = ProtocolConstantSdV1.protocolName ;
    private static final Short ProtocolVersion = ProtocolConstantSdV1.protocolVer ;
    private static final String ComCode = CodeSdV1.cd_Fault ;
    @Autowired
    private CdSv sv ;
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    @PostMapping(path = "clear", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> send(@RequestBody @Valid CdDto dto, BindingResult bindingResult) {
        BaseResponse<Object> res ;
        //发送命令前-1:验证
        res = super.pre1(sv, ComCode, dto, bindingResult);
        if(res == null) {
            //发送命令前-2:获得数据
            res = super.pre2(sv, Protocol, ProtocolVersion, ComCode, dto, bindingResult);
            if (res == null) {
                //发送命令前-3:保存命令日志
                CdParam comParam = CdParam.builder().no(ctrlPo.no).startTrueStopFalse(true).build();
                res = super.pre3(sv, dto.manureId, dto.getOperator(), Protocol, ProtocolVersion, ComCode, comParam);
                if (res == null) {
                    //发送命令前-4:准备Feature
                    super.pre4();
                    try {
                        //创建外部命令(发给MQTT->FBox)
                        Command com = sv.createMQTTCommand(ctrlPo.fboxId, "" + comId, Protocol, ProtocolVersion, ComCode);
                        com.rtuResultSendWebUrl = mqttResultSendWebUrl;
                        com.param = comParam ;
                        //发送命令
                        res = super.doSend(sv, com);
                        if (res == null) {
                            //发送命令后
                            res = super.after(ComCode, null);
                        }
                    } catch (Exception e) {
                        res = BaseResponseUtils.buildFail("服务端构造并向通信中间件发送请求时异常" + (e.getMessage() == null ? "" : e.getMessage()));
                    } finally {
                        //最终
                        super.end();
                    }
                }
            }
        }
        return res ;
    }
    @Override
    protected String checkDto(Dto4MqttBase dto) {
        return null;
    }
    @Override
    protected String dealComResult(String code, MqttSubMsg subMsg, Callback callback){
        String msg;
        if(subMsg != null){
            if(subMsg.vo4Up != null && Proxy.isProxyClass(subMsg.vo4Up.getClass())){
                // èŽ·å–ä»£ç†çš„ InvocationHandler
                InvocationHandler handler = Proxy.getInvocationHandler(subMsg.vo4Up);
                String json = JSON.toJSONString(handler) ;
                ManureVo vo = JSON.parseObject(json, ManureVo.class);
                msg = vo.toString() ;
            }else{
                msg = RtuSuccessMsg ;
            }
        }else{
            msg = RtuSuccessMsg ;
        }
        return msg;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdDto.java
@@ -1,6 +1,6 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.fault;
import com.dy.pipIrrRemote.common.dto.DtoBase;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -11,6 +11,6 @@
 */
@Data
@EqualsAndHashCode(callSuper=true)
public class CdDto extends DtoBase {
    public static final long serialVersionUID = 202506161739001L;
public class CdDto extends Dto4MqttBase {
    public static final long serialVersionUID = 202506501650001L;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdParam.java
@@ -1,9 +1,23 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.fault;
import com.dy.pipIrrRemote.monitor.common.Cd4MqttParameter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
public class CdParam {
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class CdParam extends Cd4MqttParameter {
    //启停动作,true是,false否
    //可以执行功能码 00,01,02,03的动作
    public boolean startTrueStopFalse;//
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdStartCtrl.java
File was deleted
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdStopCtrl.java
File was deleted
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/fault/CdSv.java
@@ -1,6 +1,6 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.fault;
import com.dy.pipIrrRemote.monitor.common.ComSv;
import com.dy.pipIrrRemote.monitor.common.Com4MqttSv;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -10,6 +10,6 @@
 * @Description
 */
@Slf4j
@Service("faultSv")
public class CdSv extends ComSv {
@Service("mqttSd1FaultSv")
public class CdSv extends Com4MqttSv {
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/inject/CdCtrl.java
New file
@@ -0,0 +1,145 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.inject;
import com.alibaba.fastjson2.JSON;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.common.mw.protocol4Mqtt.pSdV1.CodeSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.ProtocolConstantSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.upVos.ManureVo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import com.dy.pipIrrRemote.monitor.common.Com4MqttCtrl;
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.context.annotation.Scope;
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 java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:35
 * @Description
 */
@Slf4j
@Tag(name = "远程命令", description = "注肥启停")
@RestController("mqttSd1InjectCtrl")
@RequestMapping(path = "mqttSd1/inject")
@RequiredArgsConstructor
@Scope("prototype") //因为有对象类属性,所以采用原型模式,每次请求新建一个实例对象
public class CdCtrl extends Com4MqttCtrl {
    private static final String RtuSuccessMsg = "控制器接收并执行命令成功,无返回数据";
    private static final String Protocol = ProtocolConstantSdV1.protocolName ;
    private static final Short ProtocolVersion = ProtocolConstantSdV1.protocolVer ;
    private static final String ComCode = CodeSdV1.cd_Inject ;
    @Autowired
    private CdSv sv ;
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    @PostMapping(path = "start", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> start(@RequestBody @Valid CdDto dto, BindingResult bindingResult) {
        return this.send(dto, bindingResult, true) ;
    }
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    @PostMapping(path = "stop", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> stop(@RequestBody @Valid CdDto dto, BindingResult bindingResult) {
        return this.send(dto, bindingResult, false) ;
    }
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    private BaseResponse<Object> send(CdDto dto, BindingResult bindingResult, boolean startTrueStopFalse) {
        BaseResponse<Object> res ;
        //发送命令前-1:验证
        res = super.pre1(sv, ComCode, dto, bindingResult);
        if(res == null) {
            //发送命令前-2:获得数据
            res = super.pre2(sv, Protocol, ProtocolVersion, ComCode, dto, bindingResult);
            if (res == null) {
                //发送命令前-3:保存命令日志
                CdParam comParam = CdParam.builder().no(ctrlPo.no).startTrueStopFalse(startTrueStopFalse).build();
                res = super.pre3(sv, dto.manureId, dto.getOperator(), Protocol, ProtocolVersion, ComCode, comParam);
                if (res == null) {
                    //发送命令前-4:准备Feature
                    super.pre4();
                    try {
                        //创建外部命令(发给MQTT->FBox)
                        Command com = sv.createMQTTCommand(ctrlPo.fboxId, "" + comId, Protocol, ProtocolVersion, ComCode);
                        com.rtuResultSendWebUrl = mqttResultSendWebUrl;
                        com.param = comParam ;
                        //发送命令
                        res = super.doSend(sv, com);
                        if (res == null) {
                            //发送命令后
                            res = super.after(ComCode, null);
                        }
                    } catch (Exception e) {
                        res = BaseResponseUtils.buildFail("服务端构造并向通信中间件发送请求时异常" + (e.getMessage() == null ? "" : e.getMessage()));
                    } finally {
                        //最终
                        super.end();
                    }
                }
            }
        }
        return res ;
    }
    @Override
    protected String checkDto(Dto4MqttBase dto) {
        return null;
    }
    @Override
    protected String dealComResult(String code, MqttSubMsg subMsg, Callback callback){
        String msg;
        if(subMsg != null){
            if(subMsg.vo4Up != null && Proxy.isProxyClass(subMsg.vo4Up.getClass())){
                // èŽ·å–ä»£ç†çš„ InvocationHandler
                InvocationHandler handler = Proxy.getInvocationHandler(subMsg.vo4Up);
                String json = JSON.toJSONString(handler) ;
                ManureVo vo = JSON.parseObject(json, ManureVo.class);
                msg = vo.toString() ;
            }else{
                msg = RtuSuccessMsg ;
            }
        }else{
            msg = RtuSuccessMsg ;
        }
        return msg;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/inject/CdDto.java
New file
@@ -0,0 +1,16 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.inject;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Data
@EqualsAndHashCode(callSuper=true)
public class CdDto extends Dto4MqttBase {
    public static final long serialVersionUID = 202506201653001L;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/inject/CdParam.java
New file
@@ -0,0 +1,23 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.inject;
import com.dy.pipIrrRemote.monitor.common.Cd4MqttParameter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class CdParam extends Cd4MqttParameter {
    //启停动作,true是,false否
    //可以执行功能码 00,01,02,03的动作
    public boolean startTrueStopFalse;//
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/inject/CdSv.java
New file
@@ -0,0 +1,15 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.inject;
import com.dy.pipIrrRemote.monitor.common.Com4MqttSv;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Slf4j
@Service("mqttSd1InjectSv")
public class CdSv extends Com4MqttSv {
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/irr/CdCtrl.java
New file
@@ -0,0 +1,147 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.irr;
import com.alibaba.fastjson2.JSON;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.common.mw.protocol4Mqtt.pSdV1.CodeSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.ProtocolConstantSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.upVos.ManureVo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import com.dy.pipIrrRemote.monitor.common.Com4MqttCtrl;
import com.dy.pipIrrRemote.monitor.mqttSd1.stir.CdDto;
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.context.annotation.Scope;
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 java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:35
 * @Description
 * å¤§ç¦¹å°†æ°´è‚¥æœºåº”用于管灌系统,所以水肥机上未安装灌溉阀门,相应此功能也不应用了
 */
@Slf4j
@Tag(name = "远程命令", description = "灌溉启停")
@RestController("mqttSd1IrrCtrl")
@RequestMapping(path = "mqttSd1/irr")
@RequiredArgsConstructor
@Scope("prototype") //因为有对象类属性,所以采用原型模式,每次请求新建一个实例对象
public class CdCtrl extends Com4MqttCtrl {
    private static final String RtuSuccessMsg = "控制器接收并执行命令成功,无返回数据";
    private static final String Protocol = ProtocolConstantSdV1.protocolName ;
    private static final Short ProtocolVersion = ProtocolConstantSdV1.protocolVer ;
    private static final String ComCode = CodeSdV1.cd_Irr ;
    @Autowired
    private CdSv sv ;
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    @PostMapping(path = "start", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> start(@RequestBody @Valid com.dy.pipIrrRemote.monitor.mqttSd1.stir.CdDto dto, BindingResult bindingResult) {
        return this.send(dto, bindingResult, true) ;
    }
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    @PostMapping(path = "stop", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> stop(@RequestBody @Valid com.dy.pipIrrRemote.monitor.mqttSd1.stir.CdDto dto, BindingResult bindingResult) {
        return this.send(dto, bindingResult, false) ;
    }
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    private BaseResponse<Object> send(CdDto dto, BindingResult bindingResult, boolean startTrueStopFalse) {
        BaseResponse<Object> res ;
        //发送命令前-1:验证
        res = super.pre1(sv, ComCode, dto, bindingResult);
        if(res == null) {
            //发送命令前-2:获得数据
            res = super.pre2(sv, Protocol, ProtocolVersion, ComCode, dto, bindingResult);
            if (res == null) {
                //发送命令前-3:保存命令日志
                CdParam comParam = CdParam.builder().no(ctrlPo.no).startTrueStopFalse(true).build();
                res = super.pre3(sv, dto.manureId, dto.getOperator(), Protocol, ProtocolVersion, ComCode, comParam);
                if (res == null) {
                    //发送命令前-4:准备Feature
                    super.pre4();
                    try {
                        //创建外部命令(发给MQTT->FBox)
                        Command com = sv.createMQTTCommand(ctrlPo.fboxId, "" + comId, Protocol, ProtocolVersion, ComCode);
                        com.rtuResultSendWebUrl = mqttResultSendWebUrl;
                        com.param = comParam ;
                        //发送命令
                        res = super.doSend(sv, com);
                        if (res == null) {
                            //发送命令后
                            res = super.after(ComCode, null);
                        }
                    } catch (Exception e) {
                        res = BaseResponseUtils.buildFail("服务端构造并向通信中间件发送请求时异常" + (e.getMessage() == null ? "" : e.getMessage()));
                    } finally {
                        //最终
                        super.end();
                    }
                }
            }
        }
        return res ;
    }
    @Override
    protected String checkDto(Dto4MqttBase dto) {
        return null;
    }
    @Override
    protected String dealComResult(String code, MqttSubMsg subMsg, Callback callback){
        String msg;
        if(subMsg != null){
            if(subMsg.vo4Up != null && Proxy.isProxyClass(subMsg.vo4Up.getClass())){
                // èŽ·å–ä»£ç†çš„ InvocationHandler
                InvocationHandler handler = Proxy.getInvocationHandler(subMsg.vo4Up);
                String json = JSON.toJSONString(handler) ;
                ManureVo vo = JSON.parseObject(json, ManureVo.class);
                msg = vo.toString() ;
            }else{
                msg = RtuSuccessMsg ;
            }
        }else{
            msg = RtuSuccessMsg ;
        }
        return msg;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/irr/CdDto.java
New file
@@ -0,0 +1,16 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.irr;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Data
@EqualsAndHashCode(callSuper=true)
public class CdDto extends Dto4MqttBase {
    public static final long serialVersionUID = 202506201654001L;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/irr/CdParam.java
New file
@@ -0,0 +1,23 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.irr;
import com.dy.pipIrrRemote.monitor.common.Cd4MqttParameter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class CdParam extends Cd4MqttParameter {
    //启停动作,true是,false否
    //可以执行功能码 00,01,02,03的动作
    public boolean startTrueStopFalse;//
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/irr/CdSv.java
New file
@@ -0,0 +1,15 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.irr;
import com.dy.pipIrrRemote.monitor.common.Com4MqttSv;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Slf4j
@Service("mqttSd1IrrSv")
public class CdSv extends Com4MqttSv {
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/paramSet/CdCtrl.java
New file
@@ -0,0 +1,123 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.paramSet;
import com.alibaba.fastjson2.JSON;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.common.mw.protocol4Mqtt.pSdV1.CodeSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.ProtocolConstantSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.upVos.ManureVo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import com.dy.pipIrrRemote.monitor.common.Com4MqttCtrl;
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.context.annotation.Scope;
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 java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:35
 * @Description
 */
@Slf4j
@Tag(name = "远程命令", description = "设置参数")
@RestController("mqttSd1ParamCtrl")
@RequestMapping(path = "mqttSd1/param")
@RequiredArgsConstructor
@Scope("prototype") //因为有对象类属性,所以采用原型模式,每次请求新建一个实例对象
public class CdCtrl extends Com4MqttCtrl {
    private static final String RtuSuccessMsg = "控制器接收并执行命令成功,无返回数据";
    private static final String Protocol = ProtocolConstantSdV1.protocolName ;
    private static final Short ProtocolVersion = ProtocolConstantSdV1.protocolVer ;
    private static final String ComCode = CodeSdV1.cd_Param ;
    @Autowired
    private CdSv sv ;
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    @PostMapping(path = "set", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> set(@RequestBody @Valid CdDto dto, BindingResult bindingResult) {
        BaseResponse<Object> res ;
        //发送命令前-1:验证
        res = super.pre1(sv, ComCode, dto, bindingResult);
        if(res == null) {
            //发送命令前-2:获得数据
            res = super.pre2(sv, Protocol, ProtocolVersion, ComCode, dto, bindingResult);
            if (res == null) {
                //发送命令前-3:保存命令日志
                CdParam comParam = CdParam.builder().no(ctrlPo.no).injectDuration(dto.injectDuration).stirDuration(dto.stirDuration).build();
                res = super.pre3(sv, dto.manureId, dto.getOperator(), Protocol, ProtocolVersion, ComCode, comParam);
                if (res == null) {
                    //发送命令前-4:准备Feature
                    super.pre4();
                    try {
                        //创建外部命令(发给MQTT->FBox)
                        Command com = sv.createMQTTCommand(ctrlPo.fboxId, "" + comId, Protocol, ProtocolVersion, ComCode);
                        com.rtuResultSendWebUrl = mqttResultSendWebUrl;
                        com.param = comParam ;
                        //发送命令
                        res = super.doSend(sv, com);
                        if (res == null) {
                            //发送命令后
                            res = super.after(ComCode, null);
                        }
                    } catch (Exception e) {
                        res = BaseResponseUtils.buildFail("服务端构造并向通信中间件发送请求时异常" + (e.getMessage() == null ? "" : e.getMessage()));
                    } finally {
                        //最终
                        super.end();
                    }
                }
            }
        }
        return res ;
    }
    @Override
    protected String checkDto(Dto4MqttBase dto) {
        return null;
    }
    @Override
    protected String dealComResult(String code, MqttSubMsg subMsg, Callback callback){
        String msg;
        if(subMsg != null){
            if(subMsg.vo4Up != null && Proxy.isProxyClass(subMsg.vo4Up.getClass())){
                // èŽ·å–ä»£ç†çš„ InvocationHandler
                InvocationHandler handler = Proxy.getInvocationHandler(subMsg.vo4Up);
                String json = JSON.toJSONString(handler) ;
                ManureVo vo = JSON.parseObject(json, ManureVo.class);
                msg = vo.toString() ;
            }else{
                msg = RtuSuccessMsg ;
            }
        }else{
            msg = RtuSuccessMsg ;
        }
        return msg;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/paramSet/CdDto.java
New file
@@ -0,0 +1,25 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.paramSet;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Data
@EqualsAndHashCode(callSuper=true)
public class CdDto extends Dto4MqttBase {
    public static final long serialVersionUID = 202506201656001L;
    // æ…拌设定时间 å•位秒
    @NotNull(message = "搅拌设定时间不能为空")
    public Integer stirDuration ;
    // æ³¨è‚¥è®¾å®šæ—¶é—´ å•位秒
    @NotNull(message = "注肥设定时间不能为空")
    public Integer injectDuration ;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/paramSet/CdParam.java
New file
@@ -0,0 +1,25 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.paramSet;
import com.dy.pipIrrRemote.monitor.common.Cd4MqttParameter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class CdParam extends Cd4MqttParameter {
    // æ…拌设定时间
    public Integer stirDuration ;
    // æ³¨è‚¥è®¾å®šæ—¶é—´
    public Integer injectDuration ;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/paramSet/CdSv.java
New file
@@ -0,0 +1,15 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.paramSet;
import com.dy.pipIrrRemote.monitor.common.Com4MqttSv;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Slf4j
@Service("mqttSd1ParamSv")
public class CdSv extends Com4MqttSv {
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/stir/CdCtrl.java
New file
@@ -0,0 +1,142 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.stir;
import com.alibaba.fastjson2.JSON;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol4Mqtt.MqttSubMsg;
import com.dy.common.mw.protocol4Mqtt.pSdV1.CodeSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.ProtocolConstantSdV1;
import com.dy.common.mw.protocol4Mqtt.pSdV1.upVos.ManureVo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import com.dy.pipIrrRemote.monitor.common.Com4MqttCtrl;
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.context.annotation.Scope;
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 java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:35
 * @Description
 */
@Slf4j
@Tag(name = "远程命令", description = "搅拌启停")
@RestController("mqttSd1StirCtrl")
@RequestMapping(path = "mqttSd1/stir")
@RequiredArgsConstructor
@Scope("prototype") //因为有对象类属性,所以采用原型模式,每次请求新建一个实例对象
public class CdCtrl extends Com4MqttCtrl {
    private static final String RtuSuccessMsg = "控制器接收并执行命令成功,无返回数据";
    private static final String Protocol = ProtocolConstantSdV1.protocolName ;
    private static final Short ProtocolVersion = ProtocolConstantSdV1.protocolVer ;
    private static final String ComCode = CodeSdV1.cd_Stir ;
    @Autowired
    private CdSv sv ;
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    @PostMapping(path = "start", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> start(@RequestBody @Valid CdDto dto, BindingResult bindingResult) {
        return this.send(dto, bindingResult, true) ;
    }
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    @PostMapping(path = "stop", consumes = MediaType.APPLICATION_JSON_VALUE)
    @SsoAop()
    public BaseResponse<Object> stop(@RequestBody @Valid CdDto dto, BindingResult bindingResult) {
        return this.send(dto, bindingResult, false) ;
    }
    /**
     * å‘设备(Mqtt中间件->FBox)发送命令
     * @param dto å‰ç«¯å‘来的值对象
     * @param bindingResult å¯¹dto验证的结果
     * @return è¿”回前端
     */
    private BaseResponse<Object> send(CdDto dto, BindingResult bindingResult, boolean startTrueStopFalse) {
        BaseResponse<Object> res ;
        //发送命令前-1:验证
        res = super.pre1(sv, ComCode, dto, bindingResult);
        if(res == null) {
            //发送命令前-2:获得数据
            res = super.pre2(sv, Protocol, ProtocolVersion, ComCode, dto, bindingResult);
            if (res == null) {
                //发送命令前-3:保存命令日志
                CdParam comParam = CdParam.builder().no(ctrlPo.no).startTrueStopFalse(startTrueStopFalse).build();
                res = super.pre3(sv, dto.manureId, dto.getOperator(), Protocol, ProtocolVersion, ComCode, comParam);
                if (res == null) {
                    //发送命令前-4:准备Feature
                    super.pre4();
                    try {
                        //创建外部命令(发给MQTT->FBox)
                        Command com = sv.createMQTTCommand(ctrlPo.fboxId, "" + comId, Protocol, ProtocolVersion, ComCode);
                        com.rtuResultSendWebUrl = mqttResultSendWebUrl;
                        com.param = comParam ;
                        //发送命令
                        res = super.doSend(sv, com);
                        if (res == null) {
                            //发送命令后
                            res = super.after(ComCode, null);
                        }
                    } catch (Exception e) {
                        res = BaseResponseUtils.buildFail("服务端构造并向通信中间件发送请求时异常" + (e.getMessage() == null ? "" : e.getMessage()));
                    } finally {
                        //最终
                        super.end();
                    }
                }
            }
        }
        return res ;
    }
    @Override
    protected String checkDto(Dto4MqttBase dto) {
        return null;
    }
    @Override
    protected String dealComResult(String code, MqttSubMsg subMsg, Callback callback){
        String msg;
        if(subMsg != null){
            if(subMsg.vo4Up != null && Proxy.isProxyClass(subMsg.vo4Up.getClass())){
                // èŽ·å–ä»£ç†çš„ InvocationHandler
                InvocationHandler handler = Proxy.getInvocationHandler(subMsg.vo4Up);
                String json = JSON.toJSONString(handler) ;
                ManureVo vo = JSON.parseObject(json, ManureVo.class);
                msg = vo.toString() ;
            }else{
                msg = RtuSuccessMsg ;
            }
        }else{
            msg = RtuSuccessMsg ;
        }
        return msg;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/stir/CdDto.java
New file
@@ -0,0 +1,18 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.stir;
import com.dy.pipIrrRemote.common.dto.Dto4MqttBase;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Data
@EqualsAndHashCode(callSuper=true)
public class CdDto extends Dto4MqttBase {
    public static final long serialVersionUID = 202506201655001L;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/stir/CdParam.java
New file
@@ -0,0 +1,23 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.stir;
import com.dy.pipIrrRemote.monitor.common.Cd4MqttParameter;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class CdParam extends Cd4MqttParameter {
    //启停动作,true是,false否
    //可以执行功能码 00,01,02,03的动作
    public boolean startTrueStopFalse;//
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/mqttSd1/stir/CdSv.java
New file
@@ -0,0 +1,15 @@
package com.dy.pipIrrRemote.monitor.mqttSd1.stir;
import com.dy.pipIrrRemote.monitor.common.Com4MqttSv;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
 * @Author: liurunyu
 * @Date: 2025/6/16 17:36
 * @Description
 */
@Slf4j
@Service("mqttSd1StirSv")
public class CdSv extends Com4MqttSv {
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd55/CdCtrl.java
@@ -6,6 +6,7 @@
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd55Vo;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd65Vo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
@@ -100,16 +101,26 @@
    protected String dealComResult(String code, JSONObject resultData, Callback callback){
        String msg;
        if(resultData != null){
            JSONArray codeData = resultData.getJSONArray("data") ;
            JSONObject codeData = resultData.getJSONObject("data") ;
            JSONArray codeDataArray = null ;
            if(codeData == null){
                codeDataArray = resultData.getJSONArray("data") ;
            }
            if(codeData == null && codeDataArray == null){
                msg = RtuSuccessMsg ;
            }else {
                String json = codeData.toJSONString();
                String json = null ;
                if(codeData != null){
                    json = codeData.toJSONString() ;
                }else if(codeDataArray != null){
                    json = codeDataArray.toJSONString() ;
                }
                List<DataCd55Vo> list = JSON.parseArray(json, DataCd55Vo.class) ;
                if(list != null && list.size() > 0){
                    msg = "" ;
                    msg = "\n" ;
                    for(DataCd55Vo cvo : list){
                        msg += cvo.toStr(false) + "\n";
                        msg += cvo.toStr(false) ;
                        msg += "\n" ;
                    }
                }else{
                    msg = RtuSuccessMsg ;
@@ -120,4 +131,5 @@
        }
        return msg;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd5C/CdCtrl.java
@@ -1,9 +1,11 @@
package com.dy.pipIrrRemote.monitor.p202404V201.cd5C;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd55Vo;
import com.dy.common.mw.protocol.p206V202404.upVos.DataCd5CVo;
import com.dy.common.util.Callback;
import com.dy.common.webUtil.BaseResponse;
@@ -100,15 +102,25 @@
        String msg;
        if(resultData != null){
            JSONObject codeData = resultData.getJSONObject("data") ;
            JSONArray codeDataArray = null ;
            if(codeData == null){
                codeDataArray = resultData.getJSONArray("data") ;
            }
            if(codeData == null && codeDataArray == null){
                msg = RtuSuccessMsg ;
            }else {
                String json = codeData.toJSONString();
                String json = null ;
                if(codeData != null){
                    json = codeData.toJSONString() ;
                }else if(codeDataArray != null){
                    json = codeDataArray.toJSONString() ;
                }
                List<DataCd5CVo> list = JSON.parseArray(json, DataCd5CVo.class) ;
                if(list != null && list.size() > 0){
                    msg = "" ;
                    msg = "\n" ;
                    for(DataCd5CVo cvo : list){
                        msg += cvo.toStr(false) + "\n";
                        msg += cvo.toStr(false) ;
                        msg += "\n" ;
                    }
                }else{
                    msg = RtuSuccessMsg ;
@@ -119,4 +131,5 @@
        }
        return msg;
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/monitor/p202404V201/cd65/CdCtrl.java
@@ -1,6 +1,7 @@
package com.dy.pipIrrRemote.monitor.p202404V201.cd65;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.aop.SsoAop;
import com.dy.common.mw.protocol.Command;
@@ -22,7 +23,6 @@
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
@@ -100,15 +100,25 @@
        String msg;
        if(resultData != null){
            JSONObject codeData = resultData.getJSONObject("data") ;
            JSONArray codeDataArray = null ;
            if(codeData == null){
                codeDataArray = resultData.getJSONArray("data") ;
            }
            if(codeData == null && codeDataArray == null){
                msg = RtuSuccessMsg ;
            }else {
                String json = codeData.toJSONString();
                String json = null ;
                if(codeData != null){
                    json = codeData.toJSONString() ;
                }else if(codeDataArray != null){
                    json = codeDataArray.toJSONString() ;
                }
                List<DataCd65Vo> list = JSON.parseArray(json, DataCd65Vo.class) ;
                if(list != null && list.size() > 0){
                    msg = "" ;
                    msg = "\n" ;
                    for(DataCd65Vo cvo : list){
                        msg += cvo.toStr(false) ;
                        msg += "\n" ;
                    }
                }else{
                    msg = RtuSuccessMsg ;
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-sso/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-statistics/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-temp/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/CardCtrl.java
@@ -4,8 +4,16 @@
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.common.webUtil.QueryResultVo;
import com.dy.common.webUtil.ResultCodeMsg;
import com.dy.pipIrrGlobal.voSe.*;
import com.dy.pipIrrTerminal.card.dto.*;
import com.dy.pipIrrTerminal.card.qo.QoCards;
import com.dy.pipIrrTerminal.card.qo.QoLostCards;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -256,4 +264,84 @@
        }
    }
    /**
     * æ ¹æ®æŒ‡å®šæ¡ä»¶èŽ·å–æ°´å¡åˆ—è¡¨ï¼Œç»ˆç«¯åº”ç”¨ç¨‹åºä½¿ç”¨
     * @param vo
     * @return
     */
    @Operation(summary = "获得一页水卡记录", description = "返回一页水卡数据")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "返回一页水卡数据(BaseResponse.content:QueryResultVo[{}])",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = VoCards.class))}
            )
    })
    @GetMapping(path = "getcards")
    @SsoAop()
    public BaseResponse<QueryResultVo<List<VoCards>>> getcards(QoCards vo){
        try {
            QueryResultVo<List<VoCards>> res = cardSv.getCards(vo);
            return BaseResponseUtils.buildSuccess(res);
        } catch (Exception e) {
            log.error("查询水卡异常", e);
            return BaseResponseUtils.buildException(e.getMessage()) ;
        }
    }
    /**
     * èŽ·å–å·²æŒ‚å¤±çš„æ°´å¡åˆ—è¡¨ï¼Œç»ˆç«¯åº”ç”¨ç¨‹åºä½¿ç”¨
     * @param vo
     * @return
     */
    @Operation(summary = "获得一页已挂失水卡记录", description = "返回一页已挂失水卡数据")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "返回一页已挂失水卡数据(BaseResponse.content:QueryResultVo[{}])",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = VoCards.class))}
            )
    })
    @GetMapping(path = "getlostcards")
    @SsoAop()
    public BaseResponse<QueryResultVo<List<VoCards>>> getLostCards(QoLostCards vo){
        try {
            QueryResultVo<List<VoCards>> res = cardSv.getLostCards(vo);
            return BaseResponseUtils.buildSuccess(res);
        } catch (Exception e) {
            log.error("查询已挂失水卡异常", e);
            return BaseResponseUtils.buildException(e.getMessage()) ;
        }
    }
    /**
     * æ ¹æ®æ°´å¡ç¼–号获取卡信息
     * @param cardNum æ°´å¡ç¼–号
     * @return
     */
    @Operation(summary = "根据水卡编号获取卡信息", description = "根据水卡编号获取对应的卡信息")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "返回卡信息(BaseResponse.content:VoCardByClientNum)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = VoCardByClientNum.class))}
            )
    })
    @GetMapping(path = "getcardbycardnum")
    @SsoAop()
    public BaseResponse<VoCardByClientNum> getCardByCardNum(@RequestParam String cardNum){
        try {
            VoCardByClientNum res = cardSv.getCardByCardNum(cardNum);
            if (res == null) {
                return BaseResponseUtils.buildFail("未找到对应的卡信息");
            }
            return BaseResponseUtils.buildSuccess(res);
        } catch (Exception e) {
            log.error("根据水卡编号查询卡信息异常", e);
            return BaseResponseUtils.buildException(e.getMessage()) ;
        }
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/CardSv.java
@@ -1,6 +1,7 @@
package com.dy.pipIrrTerminal.card;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.common.webUtil.QueryResultVo;
import com.dy.pipIrrGlobal.daoPr.PrWaterPriceMapper;
import com.dy.pipIrrGlobal.daoSe.*;
import com.dy.pipIrrGlobal.pojoSe.SeCardOperate;
@@ -8,11 +9,14 @@
import com.dy.pipIrrGlobal.pojoSe.SeRechargeHistory;
import com.dy.pipIrrGlobal.voSe.*;
import com.dy.pipIrrTerminal.card.dto.*;
import com.dy.pipIrrTerminal.card.qo.QoCards;
import com.dy.pipIrrTerminal.card.qo.QoLostCards;
import com.dy.pipIrrTerminal.card.enums.CardStateENUM;
import com.dy.pipIrrTerminal.card.enums.LastOperateENUM;
import com.dy.pipIrrTerminal.card.enums.OperateTypeENUM;
import com.dy.pipIrrTerminal.card.enums.RechargeTypeENUM;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.PojoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@@ -1182,4 +1186,67 @@
        return null;
    }
    /**
     * æ ¹æ®æŒ‡å®šæ¡ä»¶èŽ·å–æ°´å¡åˆ—è¡¨
     * @param vo æŸ¥è¯¢æ¡ä»¶
     * @return æ°´å¡åˆ—表
     */
    public QueryResultVo<List<VoCards>> getCards(QoCards vo) {
        Map<String, Object> params = (Map<String, Object>) PojoUtils.generalize(vo);
        Long itemTotal = seClientCardMapper.getCardsCount(params);
        QueryResultVo<List<VoCards>> rsVo = new QueryResultVo<>();
        rsVo.pageSize = vo.pageSize;
        rsVo.pageCurr = vo.pageCurr;
        if (itemTotal > 0) {
            rsVo.calculateAndSet(itemTotal, params);
            List<VoCards> list = seClientCardMapper.getCards(params);
            rsVo.obj = list;
        } else {
            rsVo.obj = new ArrayList<>();
            rsVo.itemTotal = 0L;
        }
        return rsVo;
    }
    /**
     * èŽ·å–å·²æŒ‚å¤±çš„æ°´å¡åˆ—è¡¨
     * @param vo æŸ¥è¯¢æ¡ä»¶
     * @return å·²æŒ‚失的水卡列表
     */
    public QueryResultVo<List<VoCards>> getLostCards(QoLostCards vo) {
        Map<String, Object> params = new HashMap<>();
        params.put("pageCurr", vo.pageCurr);
        params.put("pageSize", vo.pageSize);
        params.put("state", 2); // æŒ‚失状态
        Long itemTotal = seClientCardMapper.getLostCardsCount(params);
        QueryResultVo<List<VoCards>> rsVo = new QueryResultVo<>();
        rsVo.pageSize = vo.pageSize;
        rsVo.pageCurr = vo.pageCurr;
        if (itemTotal > 0) {
            rsVo.calculateAndSet(itemTotal, params);
            List<VoCards> list = seClientCardMapper.getLostCards(params);
            rsVo.obj = list;
        } else {
            rsVo.obj = new ArrayList<>();
            rsVo.itemTotal = 0L;
        }
        return rsVo;
    }
    /**
     * æ ¹æ®æ°´å¡ç¼–号获取卡信息
     * @param cardNum æ°´å¡ç¼–号
     * @return å¡ä¿¡æ¯
     */
    public VoCardByClientNum getCardByCardNum(String cardNum) {
        return seClientCardMapper.getCardByCardNum(cardNum);
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/dto/DtoReissue.java
@@ -44,7 +44,6 @@
    /**
     * æ”¯ä»˜æ–¹å¼
     */
    @NotNull(message = "支付方式不能为空")
    private Long paymentId;
    /**
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/qo/QoCards.java
New file
@@ -0,0 +1,31 @@
package com.dy.pipIrrTerminal.card.qo;
import com.dy.common.webUtil.QueryConditionVo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
/**
 * @author ZhuBaoMin
 * @date 2025-01-15
 * @LastEditTime 2025-01-15
 * @Description ç»ˆç«¯æ¨¡å—水卡记录查询条件
 */
@Data
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Schema(name = "水卡记录查询条件")
public class QoCards extends QueryConditionVo {
    @Schema(description = "农户编号")
    public Long clientNum;
    @Schema(description = "农户姓名")
    private String clientName;
    @Schema(description = "水卡编号")
    public Long cardNum;
}
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/java/com/dy/pipIrrTerminal/card/qo/QoLostCards.java
New file
@@ -0,0 +1,28 @@
package com.dy.pipIrrTerminal.card.qo;
import com.dy.common.webUtil.QueryConditionVo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
/**
 * @author ZhuBaoMin
 * @date 2025-01-15
 * @LastEditTime 2025-01-15
 * @Description ç»ˆç«¯æ¨¡å—已挂失水卡查询条件
 */
@Data
@EqualsAndHashCode(callSuper = false)
@ToString(callSuper = true)
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Schema(name = "已挂失水卡查询条件")
public class QoLostCards extends QueryConditionVo {
    @Schema(description = "页码", example = "1")
    public Integer pageCurr;
    @Schema(description = "每页数量", example = "10")
    public Integer pageSize;
}
pipIrr-platform/pipIrr-web/pipIrr-web-terminal/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/pipIrr-web/pipIrr-web-wechat/src/main/resources/application(121·þÎñÆ÷).yml
@@ -1,3 +1,3 @@
spring:
    profiles:
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, self
        include: common-web, global, database, database-mq, database-yq, database-hlj, database-gz, database-lz, database-jc, database-jyg, self
pipIrr-platform/Îĵµ/SaaS/Ôö¼ÓÒ»¸öµ¥Î»£¨orgTag£©.docx
Binary files differ
pipIrr-platform/Îĵµ/SaaS/¶Ë¿Ú¡¢IP¡¢±êÇ©ÅäÖÃ.docx
Binary files differ
pipIrr-platform/Îĵµ/Ë®·ÊÆøÏóÉÊÇé/FlexManagerÈí¼þÅäÖòÎÊý.docx
Binary files differ
pipIrr-platform/Îĵµ/Ë®·ÊÆøÏóÉÊÇé/MQTTÖ¸Áî²»Ö´ÐÐ.docx
Binary files differ
pipIrr-platform/Îĵµ/Ë®·ÊÆøÏóÉÊÇé/MQTTÉ趨ʱ¼ä²ÎÊý.docx
Binary files differ