1、实现用水户日用水量水费统计;
2、靳总IC卡结构中卡号(用户号)由10位改为17位,相应协议也变化。
19个文件已修改
7个文件已添加
1385 ■■■■■ 已修改文件
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultFromRtu.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultToRtu.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CommonV1_0_1.java 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_83_Up.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_84_Up.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Down.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Up.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Down.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Up.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_99_Down.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_A0_Down.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlCreate.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlParse.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmClientAmountDayLastMapper.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmClientAmountDayMapper.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmClientAmountDay.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmClientAmountDayLast.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmClientAmountDayLastMapper.xml 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmClientAmountDayMapper.xml 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/forTcp/MidResultActionFromRtu.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/dbSv/DbSv.java 100 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealClientAmountDay.java 327 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealIntakeAmountDay.java 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealLoss.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/RtuDataDealTree.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/src/main/java/com/dy/pipIrrMwTestWeb/p206V1_0_0/ComSupportP206V1_0_0.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultFromRtu.java
@@ -1,9 +1,5 @@
package com.dy.common.mw.protocol;
import com.dy.common.mw.protocol.p206V1_0_0.*;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd97Vo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd98Vo;
/**
 * 从RTU收到数据
 */
@@ -30,11 +26,12 @@
        ProtocolUnit.getInstance().adapter.getSingleActionFromRtu(this.protocolName).doAction(this); 
    }
    
    public void matchedCommand(String commandId, Object toRtuMidResultParam, String rtuResultSendWebUrl){
    public void matchedCommand(String commandId, String rtuResultSendWebUrl){
        this.commandId = commandId ;
        if(this.data != null){
            this.data.setCommandId(commandId);
        }
        /*
        if(toRtuMidResultParam != null){
            if(protocolName != null && protocolName.equals(ProtocolConstantV206V1_0_0.protocolName)){
                if(upCode != null && upCode.equals(CodeV1_0_1.cd_97)){
@@ -60,6 +57,7 @@
                }
            }
        }
         */
        this.rtuResultSendWebUrl = rtuResultSendWebUrl ;
        if(this.data != null){
            this.data.setRtuResultSendWebUrl(rtuResultSendWebUrl);
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/MidResultToRtu.java
@@ -24,7 +24,7 @@
    public boolean isSendFirst;//优先其他发送,例如各命令的应答
    public boolean isQuickSend;//速发命令,即不受下发数据时间间隔限制
    public Object param ;//缓存一些数据,例如为兼容王工(江海)协议与靳总协议(虚拟IC卡编号长度不一致),把不兼容的虚拟IC卡编号的前半部分放入此处
    //public Object param ;//缓存一些数据,例如为兼容王工(江海)协议与靳总协议(虚拟IC卡编号长度不一致),把不兼容的虚拟IC卡编号的前半部分放入此处
    public MidResultToRtu(){
        hasResponse = true ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/CommonV1_0_1.java
@@ -202,25 +202,25 @@
        };
    }
    /**
     * 处理IC卡编号,靳总制定的协议要求10位IC卡编号
     * @param icCardNo
     * @return
     */
    public static String[] dealIcCardNo(String icCardNo){
        if(icCardNo.length() > 10){
            String tail = icCardNo.substring(icCardNo.length() - 10) ;
            String head = icCardNo.substring(0, icCardNo.length() - 10) ;
            return new String[]{head , tail} ;
        }else if(icCardNo.length() < 10){
            while(icCardNo.length() != 10){
                icCardNo = "0" + icCardNo ;
            }
            return new String[]{null , icCardNo} ;
        }else{
            return new String[]{null , icCardNo} ;
        }
    }
//    /**
//     * 处理IC卡编号,靳总制定的协议要求10位IC卡编号
//     * @param icCardNo
//     * @return
//     */
//    public static String[] dealIcCardNo(String icCardNo){
//        if(icCardNo.length() > 10){
//            String tail = icCardNo.substring(icCardNo.length() - 10) ;
//            String head = icCardNo.substring(0, icCardNo.length() - 10) ;
//            return new String[]{head , tail} ;
//        }else if(icCardNo.length() < 10){
//            while(icCardNo.length() != 10){
//                icCardNo = "0" + icCardNo ;
//            }
//            return new String[]{null , icCardNo} ;
//        }else{
//            return new String[]{null , icCardNo} ;
//        }
//    }
    
    /*
     * 分析版本号
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_83_Up.java
@@ -105,10 +105,10 @@
        cdData.totalAmount = tpInt/100.0 ;
        index += 5 ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.icCardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        //用水户号数据格式:8字节低位在前高位在后。
        cdData.icCardNo = GlParse.parseIcCardNo(bs, index) ;
        index += 5 ;
        index += 8 ;
        //IC卡号格式:4字节HEX码低位在前高位在后。
        cdData.icCardAddr = ByteUtil.bytes2Hex_LE(bs, false,  index, 4) ;
@@ -156,10 +156,10 @@
        cdData.totalAmount = tpInt/100.0 ;
        index += 5 ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.icCardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        //用水户号数据格式:8字节低位在前高位在后。
        cdData.icCardNo = GlParse.parseIcCardNo(bs, index) ;
        index += 5 ;
        index += 8 ;
        //IC卡号格式:4字节HEX码低位在前高位在后。
        cdData.icCardAddr = ByteUtil.bytes2Hex_LE(bs, false,  index, 4) ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_84_Up.java
@@ -97,10 +97,10 @@
        cdData.cardAddr = ByteUtil.bytes2Hex_LE(bs, false,  index, 4) ;
        index += 4 ;
        //用水户号数据格式:5字节BCD码低位在前高位在后。
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, index, index + 4) ;
        //用水户号数据格式:8字节低位在前高位在后。
        cdData.cardNo = GlParse.parseIcCardNo(bs, index) ;
        index += 5 ;
        index += 8 ;
        //用水户余额:用户余额4字节BCD码,取值范围0.00~999999.99,单位为元。
        int tpInt = ByteUtil.BCD2Int_LE(bs, index, index + 3) ;
        cdData.remainMoney = tpInt/100.0 ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Down.java
@@ -92,16 +92,17 @@
            throw new Exception("水价不能为空") ;
        }
        String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        if(icCardNoGrp[0] != null){
            midRs.param = icCardNoGrp[0] ;
        }
        //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        //if(icCardNoGrp[0] != null){
        //    midRs.param = icCardNoGrp[0] ;
        //}
        byte[] bs = new byte[11] ;
        byte[] bs = new byte[14] ;
        index = 0 ;
        ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        GlCreate.createIcCardNo(cvo.icCardNo, bs, index);
        //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        index += 5 ;
        index += 8 ;
        Integer money = Double.valueOf(cvo.moneyRemain * 100.0D).intValue() ;
        byte[] bTemp = ByteUtil.int2BCD_LE(money) ;
        int bTempLen = bTemp.length ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_97_Up.java
@@ -2,6 +2,7 @@
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.*;
import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlParse;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd97Vo;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
@@ -62,8 +63,9 @@
        DataCd97Vo cdData = new DataCd97Vo() ;
        dV1.subData = cdData ;
        //虚拟卡号
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, ProtocolConstantV206V1_0_0.dataIndex, ProtocolConstantV206V1_0_0.dataIndex+4) ;
        if(bs[ProtocolConstantV206V1_0_0.dataIndex + 5] == (byte)0xAA){
        cdData.cardNo = GlParse.parseIcCardNo(bs, ProtocolConstantV206V1_0_0.dataIndex) ;
        if(bs[ProtocolConstantV206V1_0_0.dataIndex + 8] == (byte)0xAA){
            cdData.success = true ;
        }else{
            cdData.success = false ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Down.java
@@ -86,12 +86,15 @@
            throw new Exception("虚拟IC卡编号不能为空") ;
        }
        String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        if(icCardNoGrp[0] != null){
            midRs.param = icCardNoGrp[0] ;
        }
        byte[] bs = new byte[5] ;
        ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], 0) ;
        //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        //if(icCardNoGrp[0] != null){
        //    midRs.param = icCardNoGrp[0] ;
        //}
        //byte[] bs = new byte[5] ;
        //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], 0) ;
        byte[] bs = new byte[8] ;
        GlCreate.createIcCardNo(cvo.icCardNo, bs, 0);
        bytes = ByteUtil.bytesMerge(bsHead, bs) ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_98_Up.java
@@ -2,6 +2,7 @@
import com.dy.common.mw.protocol.*;
import com.dy.common.mw.protocol.p206V1_0_0.*;
import com.dy.common.mw.protocol.p206V1_0_0.parse.global.GlParse;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd98Vo;
import com.dy.common.util.ByteUtil;
import org.apache.logging.log4j.LogManager;
@@ -62,8 +63,9 @@
        DataCd98Vo cdData = new DataCd98Vo() ;
        dV1.subData = cdData ;
        //虚拟卡号
        cdData.cardNo = ByteUtil.BCD2String_LE(bs, ProtocolConstantV206V1_0_0.dataIndex, ProtocolConstantV206V1_0_0.dataIndex+4) ;
        if(bs[ProtocolConstantV206V1_0_0.dataIndex + 5] == (byte)0xAA){
        cdData.cardNo = GlParse.parseIcCardNo(bs, ProtocolConstantV206V1_0_0.dataIndex) ;
        if(bs[ProtocolConstantV206V1_0_0.dataIndex + 8] == (byte)0xAA){
            cdData.success = true ;
        }else{
            cdData.success = false ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_99_Down.java
@@ -97,14 +97,16 @@
            throw new Exception("用水时长取值范围是0~9999分钟") ;
        }
        String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        if(icCardNoGrp[0] != null){
            midRs.param = icCardNoGrp[0] ;
        }
        //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        //if(icCardNoGrp[0] != null){
        //    midRs.param = icCardNoGrp[0] ;
        //}
        //byte[] bs = new byte[13] ;
        //index = 0 ;
        //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        byte[] bs = new byte[8] ;
        GlCreate.createIcCardNo(cvo.icCardNo, bs, 0);
        byte[] bs = new byte[13] ;
        index = 0 ;
        ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        index += 5 ;
        Integer money = Double.valueOf(cvo.moneyRemain * 100.0D).intValue() ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/Cd_A0_Down.java
@@ -97,14 +97,14 @@
            throw new Exception("预用水量取值范围是0~9999m3") ;
        }
        String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        if(icCardNoGrp[0] != null){
            midRs.param = icCardNoGrp[0] ;
        }
        byte[] bs = new byte[13] ;
        //String[] icCardNoGrp = CommonV1_0_1.dealIcCardNo(cvo.icCardNo) ;
        //if(icCardNoGrp[0] != null){
        //    midRs.param = icCardNoGrp[0] ;
        //}
        byte[] bs = new byte[16] ;
        index = 0 ;
        ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        //ByteUtil.string2BCD_LE(bs, icCardNoGrp[1], index) ;
        GlCreate.createIcCardNo(cvo.icCardNo, bs, 0);
        index += 5 ;
        Integer money = Double.valueOf(cvo.moneyRemain * 100.0D).intValue() ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlCreate.java
@@ -33,6 +33,26 @@
        bsNoTail[ProtocolConstantV206V1_0_0.dataLenIndex] = (byte)len ;
    }
    /**
     * 生成IC卡编码
     * 6字节BCD码(12位行政区划) + 2字节HEX
     * @param icCardNo
     * @param bs
     * @param index
     * @throws Exception
     */
    public static void createIcCardNo(String icCardNo, byte[] bs, int index) throws Exception {
        String icCardNo1 = icCardNo.substring(0, 12) ;
        String icCardNo2 = icCardNo.substring(12) ;
        Integer icCardNo2Int = Integer.parseInt(icCardNo2) ;
        ByteUtilUnsigned.short2Bytes_LE(bs, icCardNo2Int.shortValue(), index);
        index += 2 ;
        ByteUtil.string2BCD_LE(bs, icCardNo1, index) ;
    }
    public static byte[] createCrcTail(byte[] bsNoTail) throws Exception {
        int crc = new CRC8_for_2_0().CRC8(bsNoTail, ProtocolConstantV206V1_0_0.ctrlIndex, bsNoTail.length -1) ;
        byte[] bytes = new byte[ProtocolConstantV206V1_0_0.lenTail] ;
pipIrr-platform/pipIrr-common/src/main/java/com/dy/common/mw/protocol/p206V1_0_0/parse/global/GlParse.java
@@ -3,6 +3,7 @@
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataAlarmVo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataStateVo;
import com.dy.common.util.ByteUtil;
import com.dy.common.util.ByteUtilUnsigned;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -39,6 +40,24 @@
        return avo ;
    }
    /**
     * 分析IC卡编号
     * @param bs 上行字节数组
     * @param index 启始位
     * @return 控制器地址
     * @throws Exception 异常
     */
    public static String parseIcCardNo(byte[] bs, int index)throws Exception{
        String rtuAddrStr = "" + ByteUtilUnsigned.bytes2Short_LE(bs, index) ;
        String rtuAddrBCD = "" + ByteUtil.BCD2Long_LE(bs, index + 2, index + 7) ;
        while(rtuAddrStr.length() < 5){
            rtuAddrStr = "0" + rtuAddrStr ;
        }
        return rtuAddrBCD + rtuAddrStr ;
    }
    public static String parseTp(byte[] bs, short index){
        String dt = "" ;
        try{
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmClientAmountDayLastMapper.java
New file
@@ -0,0 +1,65 @@
package com.dy.pipIrrGlobal.daoRm;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 14:33
 * @Description
 */
@Mapper
public interface RmClientAmountDayLastMapper extends BaseMapper<RmClientAmountDayLast> {
    /**
     * delete by primary key
     *
     * @param id primaryKey
     * @return deleteCount
     */
    int deleteByPrimaryKey(Long id);
    List<RmClientAmountDayLast> selectByClientId(Long clientId) ;
    /**
     * insert record to table
     *
     * @param record the record
     * @return insert count
     */
    int insert(RmClientAmountDayLast record);
    /**
     * insert record to table selective
     *
     * @param record the record
     * @return insert count
     */
    int insertSelective(RmClientAmountDayLast record);
    /**
     * select by primary key
     *
     * @param id primary key
     * @return object by primary key
     */
    RmClientAmountDayLast selectByPrimaryKey(Long id);
    /**
     * update record selective
     *
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKeySelective(RmClientAmountDayLast record);
    /**
     * update record
     *
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKey(RmClientAmountDayLast record);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmClientAmountDayMapper.java
New file
@@ -0,0 +1,74 @@
package com.dy.pipIrrGlobal.daoRm;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.Date;
import java.util.List;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 14:33
 * @Description
 */
@Mapper
public interface RmClientAmountDayMapper  extends BaseMapper<RmClientAmountDay> {
    /**
     * delete by primary key
     *
     * @param id primaryKey
     * @return deleteCount
     */
    int deleteByPrimaryKey(Long id);
    /**
     * insert record to table
     *
     * @param record the record
     * @return insert count
     */
    int insert(RmClientAmountDay record);
    /**
     * insert record to table selective
     *
     * @param record the record
     * @return insert count
     */
    int insertSelective(RmClientAmountDay record);
    /**
     * select by primary key
     *
     * @param id primary key
     * @return object by primary key
     */
    RmClientAmountDay selectByPrimaryKey(Long id);
    /**
     * select by primary key
     *
     * @param clientId clientId
     * @param dt dt
     * @return objects by ByClientAndDate
     */
    List<RmClientAmountDay> selectByClientAndDate(@Param("clientId")Long clientId, @Param("dt")Date dt) ;
    /**
     * update record selective
     *
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKeySelective(RmClientAmountDay record);
    /**
     * update record
     *
     * @param record the updated record
     * @return update count
     */
    int updateByPrimaryKey(RmClientAmountDay record);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmClientAmountDay.java
New file
@@ -0,0 +1,94 @@
package com.dy.pipIrrGlobal.pojoRm;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson2.writer.ObjectWriterImplToString;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.dy.common.po.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.Date;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 14:33
 * @Description 农户日用水量统计
 */
@TableName(value="rm_client_amount_day", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "农户日用水量统计")
public class RmClientAmountDay implements BaseEntity {
    public static final long serialVersionUID = 2024007091435002L;
    /**
     * 主键
     */
    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED)
    @JSONField(serializeUsing= ObjectWriterImplToString.class)
    @TableId(type = IdType.INPUT)
    public Long id;
    /**
     * 农户id
     */
    public Long clientId;
    /**
     * 日取水量
     */
    public Double amount;
    /**
     * 日取花费金额
     */
    public Double money;
    /**
     * 统计日期(yyyy-mm-dd)
     */
    @Schema(description = "统计日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @JsonFormat(pattern = "yyyy-MM-dd")
    public Date dt;
    /**
     * 统计日最后一次开阀日期时间(yyyy-mm-dd HH:MM:SS)
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date openDtLast;
    /**
     * 统计日最后一次关阀日期时间(yyyy-mm-dd HH:MM:SS)
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date closeDtLast;
    /**
     * 统计日最后一次开阀取水量
     */
    public Double thisAmountLast;
    /**
     * 统计日最后一次开阀花费金额
     */
    public Double thisMoneyLast;
    /**
     * 统计日最后一次开阀取水时长(分钟)
     */
    public Integer thisTimeLast;
    /**
     * 统计日最后一次关阀上报控制器时钟
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date rtuDtLast;
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmClientAmountDayLast.java
New file
@@ -0,0 +1,102 @@
package com.dy.pipIrrGlobal.pojoRm;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson2.writer.ObjectWriterImplToString;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.dy.common.po.BaseEntity;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.Date;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 14:33
 * @Description 农户日用水量统计
 */
@TableName(value="rm_client_amount_day_last", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "农户日用水量统计")
public class RmClientAmountDayLast implements BaseEntity {
    public static final long serialVersionUID = 2024007091435001L;
    /**
     * 主键
     */
    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED)
    @JSONField(serializeUsing= ObjectWriterImplToString.class)
    @TableId(type = IdType.INPUT)
    public Long id;
    /**
     * 由最新数据持有历史数据中的最新记录ID,以方便快速查询
     * json不序列化此属性,即不向前端页面发送及显示
     */
    @Schema(hidden=true)
    @JSONField(serialize = false)
    public Long lastHistoryId;
    /**
     * 农户id
     */
    public Long clientId;
    /**
     * 日取水量
     */
    public Double amount;
    /**
     * 日取花费金额
     */
    public Double money;
    /**
     * 统计日期(yyyy-mm-dd)
     */
    @Schema(description = "统计日期", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @JsonFormat(pattern = "yyyy-MM-dd")
    public Date dt;
    /**
     * 统计日最后一次开阀日期时间(yyyy-mm-dd HH:MM:SS)
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date openDtLast;
    /**
     * 统计日最后一次关阀日期时间(yyyy-mm-dd HH:MM:SS)
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date closeDtLast;
    /**
     * 统计日最后一次开阀取水量
     */
    public Double thisAmountLast;
    /**
     * 统计日最后一次开阀花费金额
     */
    public Double thisMoneyLast;
    /**
     * 统计日最后一次开阀取水时长(分钟)
     */
    public Integer thisTimeLast;
    /**
     * 统计日最后一次关阀上报控制器时钟
     */
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:SS")
    public Date rtuDtLast;
}
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmClientAmountDayLastMapper.xml
New file
@@ -0,0 +1,191 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dy.pipIrrGlobal.daoRm.RmClientAmountDayLastMapper">
  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    <!--@Table rm_client_amount_day_last-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="last_history_id" jdbcType="BIGINT" property="lastHistoryId" />
    <result column="client_id" jdbcType="BIGINT" property="clientId" />
    <result column="amount" jdbcType="FLOAT" property="amount" />
    <result column="money" jdbcType="FLOAT" property="money" />
    <result column="dt" jdbcType="DATE" property="dt" />
    <result column="open_dt_last" jdbcType="TIMESTAMP" property="openDtLast" />
    <result column="close_dt_last" jdbcType="TIMESTAMP" property="closeDtLast" />
    <result column="this_amount_last" jdbcType="FLOAT" property="thisAmountLast" />
    <result column="this_money_last" jdbcType="FLOAT" property="thisMoneyLast" />
    <result column="this_time_last" jdbcType="INTEGER" property="thisTimeLast" />
    <result column="rtu_dt_last" jdbcType="TIMESTAMP" property="rtuDtLast" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, last_history_id, client_id, amount, money, dt, open_dt_last, close_dt_last, this_amount_last,
    this_money_last, this_time_last, rtu_dt_last
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from rm_client_amount_day_last
    where id = #{id,jdbcType=BIGINT}
  </select>
  <select id="selectByClientId" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from rm_client_amount_day_last
    where client_id = #{ClientId,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from rm_client_amount_day_last
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    insert into rm_client_amount_day_last (id, last_history_id, client_id,
      amount, money, dt, open_dt_last,
      close_dt_last, this_amount_last, this_money_last,
      this_time_last, rtu_dt_last)
    values (#{id,jdbcType=BIGINT}, #{lastHistoryId,jdbcType=BIGINT}, #{clientId,jdbcType=BIGINT},
    #{amount,jdbcType=FLOAT}, #{money,jdbcType=FLOAT}, #{dt,jdbcType=DATE}, #{openDtLast,jdbcType=TIMESTAMP},
      #{closeDtLast,jdbcType=TIMESTAMP}, #{thisAmountLast,jdbcType=FLOAT}, #{thisMoneyLast,jdbcType=FLOAT},
      #{thisTimeLast,jdbcType=INTEGER}, #{rtuDtLast,jdbcType=TIMESTAMP})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    insert into rm_client_amount_day_last
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="lastHistoryId != null">
        last_history_id,
      </if>
      <if test="clientId != null">
        client_id,
      </if>
      <if test="amount != null">
        amount,
      </if>
      <if test="money != null">
        money,
      </if>
      <if test="dt != null">
        dt,
      </if>
      <if test="openDtLast != null">
        open_dt_last,
      </if>
      <if test="closeDtLast != null">
        close_dt_last,
      </if>
      <if test="thisAmountLast != null">
        this_amount_last,
      </if>
      <if test="thisMoneyLast != null">
        this_money_last,
      </if>
      <if test="thisTimeLast != null">
        this_time_last,
      </if>
      <if test="rtuDtLast != null">
        rtu_dt_last,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="lastHistoryId != null">
        #{lastHistoryId,jdbcType=BIGINT},
      </if>
      <if test="clientId != null">
        #{clientId,jdbcType=BIGINT},
      </if>
      <if test="amount != null">
        #{amount,jdbcType=FLOAT},
      </if>
      <if test="money != null">
        #{money,jdbcType=FLOAT},
      </if>
      <if test="dt != null">
        #{dt,jdbcType=DATE},
      </if>
      <if test="openDtLast != null">
        #{openDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="closeDtLast != null">
        #{closeDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="thisAmountLast != null">
        #{thisAmountLast,jdbcType=FLOAT},
      </if>
      <if test="thisMoneyLast != null">
        #{thisMoneyLast,jdbcType=FLOAT},
      </if>
      <if test="thisTimeLast != null">
        #{thisTimeLast,jdbcType=INTEGER},
      </if>
      <if test="rtuDtLast != null">
        #{rtuDtLast,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    update rm_client_amount_day_last
    <set>
      <if test="lastHistoryId != null">
        last_history_id = #{lastHistoryId,jdbcType=BIGINT},
      </if>
      <if test="clientId != null">
        client_id = #{clientId,jdbcType=BIGINT},
      </if>
      <if test="amount != null">
        amount = #{amount,jdbcType=FLOAT},
      </if>
      <if test="money != null">
        money = #{money,jdbcType=FLOAT},
      </if>
      <if test="dt != null">
        dt = #{dt,jdbcType=DATE},
      </if>
      <if test="openDtLast != null">
        open_dt_last = #{openDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="closeDtLast != null">
        close_dt_last = #{closeDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="thisAmountLast != null">
        this_amount_last = #{thisAmountLast,jdbcType=FLOAT},
      </if>
      <if test="thisMoneyLast != null">
        this_money_last = #{thisMoneyLast,jdbcType=FLOAT},
      </if>
      <if test="thisTimeLast != null">
        this_time_last = #{thisTimeLast,jdbcType=INTEGER},
      </if>
      <if test="rtuDtLast != null">
        rtu_dt_last = #{rtuDtLast,jdbcType=TIMESTAMP},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast">
    <!--@mbg.generated-->
    update rm_client_amount_day_last
    set last_history_id = #{lastHistoryId,jdbcType=BIGINT},
      client_id = #{clientId,jdbcType=BIGINT},
      amount = #{amount,jdbcType=FLOAT},
      money = #{money,jdbcType=FLOAT},
      dt = #{dt,jdbcType=DATE},
      open_dt_last = #{openDtLast,jdbcType=TIMESTAMP},
      close_dt_last = #{closeDtLast,jdbcType=TIMESTAMP},
      this_amount_last = #{thisAmountLast,jdbcType=FLOAT},
      this_money_last = #{thisMoneyLast,jdbcType=FLOAT},
      this_time_last = #{thisTimeLast,jdbcType=INTEGER},
      rtu_dt_last = #{rtuDtLast,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmClientAmountDayMapper.xml
New file
@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dy.pipIrrGlobal.daoRm.RmClientAmountDayMapper">
  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    <!--@Table rm_client_amount_day-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="client_id" jdbcType="BIGINT" property="clientId" />
    <result column="amount" jdbcType="FLOAT" property="amount" />
    <result column="money" jdbcType="FLOAT" property="money" />
    <result column="dt" jdbcType="DATE" property="dt" />
    <result column="open_dt_last" jdbcType="TIMESTAMP" property="openDtLast" />
    <result column="close_dt_last" jdbcType="TIMESTAMP" property="closeDtLast" />
    <result column="this_amount_last" jdbcType="FLOAT" property="thisAmountLast" />
    <result column="this_money_last" jdbcType="FLOAT" property="thisMoneyLast" />
    <result column="this_time_last" jdbcType="INTEGER" property="thisTimeLast" />
    <result column="rtu_dt_last" jdbcType="TIMESTAMP" property="rtuDtLast" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, client_id, amount, money, dt, open_dt_last, close_dt_last, this_amount_last, this_money_last,
    this_time_last, rtu_dt_last
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from rm_client_amount_day
    where id = #{id,jdbcType=BIGINT}
  </select>
  <select id="selectByClientAndDate" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from rm_client_amount_day
    where client_id = #{clientId,jdbcType=BIGINT} and dt = #{dt,jdbcType=DATE}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from rm_client_amount_day
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    insert into rm_client_amount_day (id, client_id, amount, money,
      dt, open_dt_last, close_dt_last,
      this_amount_last, this_money_last, this_time_last,
      rtu_dt_last)
    values (#{id,jdbcType=BIGINT}, #{clientId,jdbcType=BIGINT}, #{amount,jdbcType=FLOAT}, #{money,jdbcType=FLOAT},
      #{dt,jdbcType=DATE}, #{openDtLast,jdbcType=TIMESTAMP}, #{closeDtLast,jdbcType=TIMESTAMP},
      #{thisAmountLast,jdbcType=FLOAT}, #{thisMoneyLast,jdbcType=FLOAT}, #{thisTimeLast,jdbcType=INTEGER},
      #{rtuDtLast,jdbcType=TIMESTAMP})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    insert into rm_client_amount_day
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="clientId != null">
        client_id,
      </if>
      <if test="amount != null">
        amount,
      </if>
      <if test="money != null">
        money,
      </if>
      <if test="dt != null">
        dt,
      </if>
      <if test="openDtLast != null">
        open_dt_last,
      </if>
      <if test="closeDtLast != null">
        close_dt_last,
      </if>
      <if test="thisAmountLast != null">
        this_amount_last,
      </if>
      <if test="thisMoneyLast != null">
        this_money_last,
      </if>
      <if test="thisTimeLast != null">
        this_time_last,
      </if>
      <if test="rtuDtLast != null">
        rtu_dt_last,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="clientId != null">
        #{clientId,jdbcType=BIGINT},
      </if>
      <if test="amount != null">
        #{amount,jdbcType=FLOAT},
      </if>
      <if test="money != null">
        #{money,jdbcType=FLOAT},
      </if>
      <if test="dt != null">
        #{dt,jdbcType=DATE},
      </if>
      <if test="openDtLast != null">
        #{openDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="closeDtLast != null">
        #{closeDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="thisAmountLast != null">
        #{thisAmountLast,jdbcType=FLOAT},
      </if>
      <if test="thisMoneyLast != null">
        #{thisMoneyLast,jdbcType=FLOAT},
      </if>
      <if test="thisTimeLast != null">
        #{thisTimeLast,jdbcType=INTEGER},
      </if>
      <if test="rtuDtLast != null">
        #{rtuDtLast,jdbcType=TIMESTAMP},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    update rm_client_amount_day
    <set>
      <if test="clientId != null">
        client_id = #{clientId,jdbcType=BIGINT},
      </if>
      <if test="amount != null">
        amount = #{amount,jdbcType=FLOAT},
      </if>
      <if test="money != null">
        money = #{money,jdbcType=FLOAT},
      </if>
      <if test="dt != null">
        dt = #{dt,jdbcType=DATE},
      </if>
      <if test="openDtLast != null">
        open_dt_last = #{openDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="closeDtLast != null">
        close_dt_last = #{closeDtLast,jdbcType=TIMESTAMP},
      </if>
      <if test="thisAmountLast != null">
        this_amount_last = #{thisAmountLast,jdbcType=FLOAT},
      </if>
      <if test="thisMoneyLast != null">
        this_money_last = #{thisMoneyLast,jdbcType=FLOAT},
      </if>
      <if test="thisTimeLast != null">
        this_time_last = #{thisTimeLast,jdbcType=INTEGER},
      </if>
      <if test="rtuDtLast != null">
        rtu_dt_last = #{rtuDtLast,jdbcType=TIMESTAMP},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay">
    <!--@mbg.generated-->
    update rm_client_amount_day
    set client_id = #{clientId,jdbcType=BIGINT},
      amount = #{amount,jdbcType=FLOAT},
      money = #{money,jdbcType=FLOAT},
      dt = #{dt,jdbcType=DATE},
      open_dt_last = #{openDtLast,jdbcType=TIMESTAMP},
      close_dt_last = #{closeDtLast,jdbcType=TIMESTAMP},
      this_amount_last = #{thisAmountLast,jdbcType=FLOAT},
      this_money_last = #{thisMoneyLast,jdbcType=FLOAT},
      this_time_last = #{thisTimeLast,jdbcType=INTEGER},
      rtu_dt_last = #{rtuDtLast,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/forTcp/MidResultActionFromRtu.java
@@ -30,7 +30,7 @@
                MidResultToRtu resToRtu = TcpDownCommandCache.matchFromHead(resFromRtu) ;
                if(resToRtu != null){
                    //匹配到下发的命令
                    resFromRtu.matchedCommand(resToRtu.commandId, resToRtu.param, resToRtu.rtuResultSendWebUrl) ;
                    resFromRtu.matchedCommand(resToRtu.commandId, resToRtu.rtuResultSendWebUrl) ;
                    this.nextDealRtuData(false, resFromRtu);
                    this.nextDealRtuComResult(resFromRtu);
                }else{
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/dbSv/DbSv.java
@@ -50,9 +50,13 @@
    @Autowired
    private RmWorkReportHistoryMapper rmWorkReportHistoryMapperDao ;//控制器历史工作报数据DAO
    @Autowired
    private RmIntakeAmountDayLastMapper rmIntakeAmountDayLastMapperDao ;//取水口取水和漏损统计最新数据DAO
    private RmIntakeAmountDayLastMapper rmIntakeAmountDayLastMapperDao ;//取水口取水统计最新数据DAO
    @Autowired
    private RmIntakeAmountDayMapper rmIntakeAmountDayMapperDao ;//取水口取水和漏损统计DAO
    @Autowired
    private RmClientAmountDayLastMapper rmClientAmountDayLastMapperDao ;//农户日用水量统计最新数据DAO
    @Autowired
    private RmClientAmountDayMapper rmClientAmountDayMapperDao ;//农户日用水量统计数据DAO
    @Autowired
    private RmLossLastMapper rmLossLastMapperDao ;//控制器漏损水量统计最新数据DAO
    @Autowired
@@ -417,7 +421,7 @@
    //
    ////////////////////////////////////////////////
    /**
     * 得到控制器漏损水量统计最新记录
     * 得到最新记录
     * @param intakeId
     * @return
     */
@@ -429,7 +433,7 @@
        return null ;
    }
    /**
     * 保存控制器漏损水量统计最新记录
     * 保存最新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
@@ -437,7 +441,7 @@
        this.rmIntakeAmountDayLastMapperDao.insert(po) ;
    }
  /**
     * 保存控制器漏损水量统计最新记录
     * 保存记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
@@ -445,15 +449,15 @@
        this.rmIntakeAmountDayMapperDao.insert(po) ;
    }
    /**
     * 保存控制器漏损水量统计最新记录
     * 保存最新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRmIntakeAmountLast(RmIntakeAmountDay po){
        this.rmIntakeAmountDayMapperDao.updateByPrimaryKey(po) ;
    public void updateRmIntakeAmountLast(RmIntakeAmountDayLast po){
        this.rmIntakeAmountDayLastMapperDao.updateByPrimaryKey(po) ;
    }
    /**
     * 保存控制器漏损水量统计最新记录
     * 保存历史记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
@@ -462,7 +466,7 @@
    }
    /**
     * 得到控制器漏损水量统计历史记录中的最新记录
     * 得到符合条件的历史记录
     * @param id
     * @return
     */
@@ -470,32 +474,80 @@
        return rmIntakeAmountDayMapperDao.selectByPrimaryKey(id) ;
    }
    /////////////////////////////////////////////////
    //
    // 农户日用水量及花费统计功能
    //
    ////////////////////////////////////////////////
    /**
     * 得到最新记录
     * @param clientId
     * @return
     */
    public RmClientAmountDayLast getRmClientAmountLast(Long clientId){
        List<RmClientAmountDayLast> list = rmClientAmountDayLastMapperDao.selectByClientId(clientId) ;
        if(list != null && list.size() > 0){
            return list.get(0) ;
        }
        return null ;
    }
    /**
     * 保存最新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveRmClientAmountLast(RmClientAmountDayLast po){
        this.rmClientAmountDayLastMapperDao.insert(po) ;
    }
    /**
     * 保存记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveRmClientAmountDay(RmClientAmountDay po){
        this.rmClientAmountDayMapperDao.insert(po) ;
    }
    /**
     * 更新最新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRmClientAmountLast(RmClientAmountDayLast po){
        this.rmClientAmountDayLastMapperDao.updateByPrimaryKey(po) ;
    }
    /**
     * 更新记录
     * @param po
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateRmClientAmountDay(RmClientAmountDay po){
        this.rmClientAmountDayMapperDao.updateByPrimaryKey(po) ;
    }
    /**
     * 得到控制器漏损水量统计最新记录
     * 得到符合条件的历史记录
     * @param id
     * @return
     */
    public RmClientAmountDay getRmClientAmountDay(Long id){
        return rmClientAmountDayMapperDao.selectByPrimaryKey(id) ;
    }
    /**
     * 得到符合条件的历史记录
     * @param clientId
     * @param dt
     * @return
     */
    public RmIntakeAmountDay getRmIntakeAmountLastByDate(Date dt){
        List<RmIntakeAmountDay> list = rmIntakeAmountDayMapperDao.selectByDate(dt) ;
    public RmClientAmountDay getRmClientAmountByClientAndDate(Long clientId, Date dt){
        List<RmClientAmountDay> list = rmClientAmountDayMapperDao.selectByClientAndDate(clientId, dt) ;
        if(list != null && list.size() > 0){
            return list.get(0) ;
        }
        return null ;
    }
    /**
     * 得到控制器漏损水量统计历史记录中的某日记录
     * @param dt
     * @return
     */
    public RmIntakeAmountDay getRmIntakeAmountDayByDate(Date dt){
        List<RmIntakeAmountDay> list = rmIntakeAmountDayMapperDao.selectByDate(dt) ;
        if(list != null && list.size() > 0){
            return list.get(0) ;
        }
        return null ;
    }
    /////////////////////////////////////////////////
    //
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealClientAmountDay.java
New file
@@ -0,0 +1,327 @@
package com.dy.rtuMw.server.rtuData.p206V1_0_0;
import com.dy.common.mw.protocol.Data;
import com.dy.common.mw.protocol.p206V1_0_0.DataV1_0_1;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd83CloseVo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd83OpenVo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCd84Vo;
import com.dy.common.mw.protocol.p206V1_0_0.upVos.DataCdC0Vo;
import com.dy.common.util.DateTime;
import com.dy.pipIrrGlobal.pojoPr.PrController;
import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDay;
import com.dy.pipIrrGlobal.pojoRm.RmClientAmountDayLast;
import com.dy.pipIrrGlobal.pojoRm.RmIntakeAmountDay;
import com.dy.pipIrrGlobal.pojoRm.RmIntakeAmountDayLast;
import com.dy.pipIrrGlobal.pojoSe.SeClient;
import com.dy.rtuMw.server.rtuData.TaskSurpport;
import com.dy.rtuMw.server.rtuData.dbSv.DbSv;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.Date;
/**
 * @Author: liurunyu
 * @Date: 2024/7/9 10:00
 * @Description 农户日用水量统计
 */
public class TkDealClientAmountDay  extends TaskSurpport {
    private static final Logger log = LogManager.getLogger(TkDealClientAmountDay.class.getName());
    //类ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkDealClientAmountDay";
    /**
     * 执行节点任务: 取水口日用水量和漏损量
     *
     * @param data 需要处理的数据
     */
    @Override
    public void execute(Object data) {
        Data d = (Data) data;
        DataV1_0_1 dV1_0_1 = (DataV1_0_1) d.getSubData();//前面任务已经判断不为null
        Object cdObj = dV1_0_1.subData;
        if (cdObj != null && cdObj instanceof DataCd83CloseVo) {
            /*
            只能采用DataCd83CloseVo来计算农户日用水量的原因:
            1、如果采用DataCd84Vo来计算农户日用水量,必须采用本次累计流量减上次累流量的差值作为阶段农户用水量,
               然后各个阶段相加,得到本次农户用水量,这个用水量还没加到农户日用水量中,因为只有收不到DataCd83CloseVo
               上报数据时才能加到农户用水量中,否则就会重复计算,但什么时候及能否收到DataCd83CloseVo不可预知。
            2、如果农户有多张IC卡,同时在多个取水口取水,将会是更复杂的计算,许多情形更不可预测,且时间复杂度
               必然很高,这样程序运行时间更长,将会造成上行数据堵塞现象。
            3、所以只采用上报数据DataCd83CloseVo作为计算农户用水量的数据来源,这时必然会有漏报缺失情况发生,采用补报机制可以弥补一些。
             */
            /*
             补报DataCd83CloseVo处理方法:
             采用DataCd83CloseVo数据中的关阀时间closeDt计算出农户用水日期,不能用数据接收日期时间作为农户用水日期,
             但这种计算方法可能会有重复上报情况发生,即重复计算了,如果要判断重复,必然要增加一个关阀时间数据库表,增加时间
             复杂度,计算用时将会长,本系统假设只要RTU上报上来数据了,说明当前网络较好,必然能收到下行应答,不会发行重复补报。
             */
            Object[] objs = this.getTaskResults(TkPreGenObjs.taskId);
            DbSv sv = (DbSv) objs[0];
            PrController controller = (PrController) objs[1];
            SeClient clientVo = (SeClient)objs[3] ;//这个值对象中只有id和name会有值
            if(clientVo != null && clientVo.getId() != null)
            try {
                this.doDeal(sv, clientVo, controller, d.getRtuAddr(), dV1_0_1, (DataCd83CloseVo) cdObj);
            } catch (Exception e) {
                log.error("保存取水口日用水量和漏损量数据时发生异常", e);
            }
        }
    }
    /**
     * 业务处理
     *
     * @param sv         服务
     * @param clientVo   农户对象
     * @param controller 控制器对象
     * @param rtuAddr    控制器地址
     * @param dV1_0_1    上报数据
     * @param cdData     上报关阀数据对象
     */
    private void doDeal(DbSv sv, SeClient clientVo, PrController controller, String rtuAddr, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData) throws Exception {
        RmClientAmountDayLast poLast = sv.getRmClientAmountLast(clientVo.getId());
        if (poLast == null) {
            //数据库中不存在该农户的日取水量数据
            //首先生成最新数据及历史数据,并先保存
            poLast = this.newRmClientAmountLast(clientVo, dV1_0_1, cdData);
            this.newAndSaveHistoryDataDeal(sv, clientVo, dV1_0_1, cdData, poLast);
            sv.saveRmClientAmountLast(poLast);
        } else {
            if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt).equals(poLast.rtuDtLast)){
                //RTU时钟等于本地最新数据中的RTU时钟,重复上报数据,不进行任何处理
            }else if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt).after(poLast.rtuDtLast)){
                //RTU时钟晚于本地最新数据中的RTU时钟,是新上报数据
                Date upYmd = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
                if(upYmd.equals(poLast.dt)){
                    //同一天数据
                    poLast = this.updateRmClientAmountLastBySameDateNewData(clientVo, dV1_0_1, cdData, poLast);
                    RmClientAmountDay poHistory = null ;
                    if(poLast.lastHistoryId != null){
                        poHistory = sv.getRmClientAmountDay(poLast.lastHistoryId) ;
                    }
                    if(poHistory == null){
                        this.newAndSaveHistoryDataDeal(sv, clientVo, dV1_0_1, cdData, poLast);
                    }else{
                        poHistory = this.updateRmClientAmountBySameDateNewData(clientVo, poHistory, poLast, dV1_0_1, cdData);
                        sv.updateRmClientAmountDay(poHistory);
                    }
                    sv.saveRmClientAmountLast(poLast);
                }else if(upYmd.after(poLast.dt)){
                    //新的日期
                    poLast = this.updateRmClientAmountLastByNewDateNewData(clientVo, dV1_0_1, cdData, poLast);
                    this.newAndSaveHistoryDataDeal(sv, clientVo, dV1_0_1, cdData, poLast);
                    sv.saveRmClientAmountLast(poLast);
                }else{
                    //这种情况不存在
                }
                sv.updateRmClientAmountLast(poLast);
            }else{
                //RTU时钟早于本地最新数据中的RTU时钟,是补报数据
                Date upYmd = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
                RmClientAmountDay poHistory = sv.getRmClientAmountByClientAndDate(clientVo.getId(), upYmd) ;
                if(poHistory == null){
                    //无历史数据
                    this.newAndSaveHistoryDataDeal(sv, clientVo, dV1_0_1, cdData, null);
                }else{
                    poHistory = this.updateOldRmClientAmountBySupplyData(clientVo, poHistory, dV1_0_1, cdData);
                    sv.updateRmClientAmountDay(poHistory);
                }
            }
        }
    }
    /**
     * 生成新的控制器漏损日统计最新记录
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @return
     * @throws Exception
     */
    private RmClientAmountDayLast newRmClientAmountLast(SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData)throws Exception {
        RmClientAmountDayLast po = new RmClientAmountDayLast() ;
        po.clientId = clientVo.getId();
        po.amount = cdData.thisAmount ;
        po.money = cdData.thisMoney ;
        po.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
        po.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt);
        po.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt);
        po.thisAmountLast = cdData.thisAmount ;
        po.thisMoneyLast = cdData.thisMoney ;
        po.thisTimeLast = cdData.thisTime ;
        po.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        return po ;
    }
    /**
     * 生成新的控制器漏损日统计历史记录
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @return
     * @throws Exception
     */
    private RmClientAmountDay newRmClientAmountDay(SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData, RmClientAmountDayLast lastPo)throws Exception {
        RmClientAmountDay poHistory = new RmClientAmountDay() ;
        poHistory.clientId = clientVo.getId();
        if(lastPo != null){
            poHistory.amount += lastPo.amount ;
            poHistory.money += lastPo.money ;
            poHistory.dt = lastPo.dt ;
            poHistory.openDtLast = lastPo.openDtLast ;
            poHistory.closeDtLast = lastPo.closeDtLast ;
            poHistory.thisAmountLast = lastPo.thisAmountLast ;
            poHistory.thisMoneyLast = lastPo.thisMoneyLast ;
            poHistory.thisTimeLast = lastPo.thisTimeLast ;
            poHistory.rtuDtLast = lastPo.rtuDtLast ;
        }else{
            poHistory.amount = cdData.thisAmount ;
            poHistory.money = cdData.thisMoney ;
            poHistory.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
            poHistory.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt);
            poHistory.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt);
            poHistory.thisAmountLast = cdData.thisAmount ;
            poHistory.thisMoneyLast = cdData.thisMoney ;
            poHistory.thisTimeLast = cdData.thisTime ;
            poHistory.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        }
        return poHistory ;
    }
    /**
     * 保存新的历史数据记录,并把ID赋值给最新记录的 lastHistoryId
     * @param sv
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @throws Exception
     * @return RmIntakeAmountDay
     */
    private RmClientAmountDay newAndSaveHistoryDataDeal(DbSv sv, SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData, RmClientAmountDayLast lastPo)throws Exception {
        RmClientAmountDay poHistory = this.newRmClientAmountDay(clientVo, dV1_0_1, cdData, lastPo) ;
        sv.saveRmClientAmountDay(poHistory);
        //由最新数据持有历史数据中的最新记录ID,以方便快速查询
        lastPo.lastHistoryId = poHistory == null ? null: poHistory.id ;
        return poHistory ;
    }
    /**
     * 更新最新数据
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @return
     * @throws Exception
     */
    private RmClientAmountDayLast updateRmClientAmountLastBySameDateNewData(SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData, RmClientAmountDayLast lastPo)throws Exception {
        lastPo.clientId = clientVo.getId();
        if(lastPo.amount != null){
            lastPo.amount += cdData.thisAmount ;
        }else{
            lastPo.amount = cdData.thisAmount ;
        }
       if(lastPo.money != null){
            lastPo.money += cdData.thisMoney ;
        }else{
            lastPo.money = cdData.thisMoney ;
        }
        lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
        lastPo.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt);
        lastPo.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt);
        lastPo.thisAmountLast = cdData.thisAmount ;
        lastPo.thisMoneyLast = cdData.thisMoney ;
        lastPo.thisTimeLast = cdData.thisTime ;
        lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        return lastPo ;
    }
    /**
     * 更新最新数据
     * @param clientVo
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @return
     * @throws Exception
     */
    private RmClientAmountDayLast updateRmClientAmountLastByNewDateNewData(SeClient clientVo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData, RmClientAmountDayLast lastPo)throws Exception {
        lastPo.clientId = clientVo.getId();
        lastPo.amount = cdData.thisAmount ;
        lastPo.money = cdData.thisMoney ;
        lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
        lastPo.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt);
        lastPo.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt);
        lastPo.thisAmountLast = cdData.thisAmount ;
        lastPo.thisMoneyLast = cdData.thisMoney ;
        lastPo.thisTimeLast = cdData.thisTime ;
        lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        return lastPo ;
    }
    /**
     * 更新最新数据
     * @param clientVo
     * @param poHistory
     * @param dV1_0_1
     * @param cdData
     * @param lastPo
     * @return
     * @throws Exception
     */
    private RmClientAmountDay updateRmClientAmountBySameDateNewData(SeClient clientVo, RmClientAmountDay poHistory, RmClientAmountDayLast lastPo, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData)throws Exception {
        poHistory.clientId = clientVo.getId();
        poHistory.amount += lastPo.amount ;
        poHistory.money += lastPo.money ;
        poHistory.dt = lastPo.dt ;
        poHistory.openDtLast = lastPo.openDtLast ;
        poHistory.closeDtLast = lastPo.closeDtLast ;
        poHistory.thisAmountLast = lastPo.thisAmountLast ;
        poHistory.thisMoneyLast = lastPo.thisMoneyLast ;
        poHistory.thisTimeLast = lastPo.thisTimeLast ;
        poHistory.rtuDtLast = lastPo.rtuDtLast ;
        return poHistory ;
    }
    /**
     * 更新最新数据
     * @param clientVo
     * @param poHistory
     * @param dV1_0_1
     * @param cdData
     * @return
     * @throws Exception
     */
    private RmClientAmountDay updateOldRmClientAmountBySupplyData(SeClient clientVo, RmClientAmountDay poHistory, DataV1_0_1 dV1_0_1, DataCd83CloseVo cdData)throws Exception {
        poHistory.clientId = clientVo.getId();
        if(poHistory.amount != null){
            poHistory.amount += cdData.thisAmount ;
        }else{
            poHistory.amount = cdData.thisAmount ;
        }
        if(poHistory.money != null){
            poHistory.money += cdData.thisMoney ;
        }else{
            poHistory.money = cdData.thisMoney ;
        }
        poHistory.dt = DateTime.dateFrom_yyyy_MM_dd1(cdData.closeDt);//采用关阀日期作为统计日期
        poHistory.openDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.openDt) ;
        poHistory.closeDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.closeDt) ;
        poHistory.thisAmountLast = cdData.thisAmount ;
        poHistory.thisMoneyLast = cdData.thisMoney ;
        poHistory.thisTimeLast = cdData.thisTime ;
        poHistory.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt) ;
        return poHistory ;
    }
}
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealIntakeAmountDay.java
@@ -22,7 +22,7 @@
 */
public class TkDealIntakeAmountDay extends TaskSurpport {
    private static final Logger log = LogManager.getLogger(TkDealLoss.class.getName());
    private static final Logger log = LogManager.getLogger(TkDealIntakeAmountDay.class.getName());
    //类ID,一定与Tree.xml配置文件中配置一致
    public static final String taskId = "TkDealIntakeAmountDay";
@@ -73,23 +73,40 @@
    private void doDeal(DbSv sv, PrController controller, String rtuAddr, DataV1_0_1 dV1_0_1, UpDataVo dataVo) throws Exception {
        RmIntakeAmountDayLast poLast = sv.getRmIntakeAmountLast(controller.getIntakeId());
        if (poLast == null) {
            //数据库中不存在该取水口的漏损数据
            //数据库中不存在该取水口的日取水量数据
            //首先生成最新数据及历史数据,并先保存
            poLast = this.newRmIntakeAmountLast(controller, rtuAddr, dV1_0_1, dataVo);
            this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV1_0_1, dataVo, poLast);
            sv.saveRmIntakeAmountLast(poLast);
        } else {
            if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataVo.rtuDt).before(poLast.rtuDtLast)){
                //RTU时钟早于本地RTU时钟,是补报,补报没法计算取水口日累计取水量,因为采用的是累计流量相差的计算方法
                //RTU时钟早于本地RTU时钟,是补报,不用补报来计算取水口日累计取水量,因为采用的是累计流量相差的计算方法,
                //其实补报的量值,基于前面上报数据已经计算包含了,只是量值归结的日期不正确罢了。
            }else if(DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dataVo.rtuDt).equals(poLast.rtuDtLast)){
                //RTU时钟等于本地RTU时钟,重复上报数据,不进行任何处理
            }else{
                //上行数据中的日期时间符合可计算的条件
                //上行数据中的日期时间符合计算的条件
                if(!rtuAddr.equals(poLast.rtuAddrLast)){
                    //更换了控制器,只更换控制器地址,不进行水量计算
                    poLast = this.updateRmIntakeAmountLastByControllerChange(poLast, controller, rtuAddr, dV1_0_1, dataVo);
                    //因为上行数据中的日期时间是可进行计算的,所以新生成一个历史记录
                    this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV1_0_1, dataVo, poLast);
                    //更换了控制器,处理方法:只更换控制器地址,不进行水量计算
                    //因为上行数据中的日期时间是可进行计算的
                    if(DateTime.dateFrom_yyyy_MM_dd1(dV1_0_1.dt).equals(poLast.dt)){
                        //同一天数据
                        poLast = this.updateRmIntakeAmountLastByControllerChange(poLast, controller, rtuAddr, dV1_0_1, dataVo);
                        RmIntakeAmountDay poHistory = null ;
                        if(poLast.lastHistoryId != null){
                            poHistory = sv.getRmIntakeAmountDay(poLast.lastHistoryId) ;
                        }
                        if(poHistory == null){
                            this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV1_0_1, dataVo, poLast);
                        }else{
                            poHistory = this.updateRmIntakeAmountByControllerChange(poHistory, poLast, controller, rtuAddr, dV1_0_1, dataVo);
                            sv.updateRmIntakeAmountDay(poHistory);
                        }
                    }else{
                        //非同一天,所以新生成一个历史记录
                        poLast = this.updateRmIntakeAmountLastByControllerChange(poLast, controller, rtuAddr, dV1_0_1, dataVo);
                        this.newAndSaveHistoryDataDeal(sv, controller, rtuAddr, dV1_0_1, dataVo, poLast);
                    }
                    sv.saveRmIntakeAmountLast(poLast);
                }else{
                    //未更换控制器
@@ -117,6 +134,8 @@
                    }
                }
            }
            //更新最新数据
            sv.updateRmIntakeAmountLast(poLast);
        }
    }
@@ -164,14 +183,13 @@
        }else{
            po.amount = 0.0D ;
        }
        po.amount = lastPo==null?0.0D:lastPo.amount ;
        po.totalAmountLast = cdData.totalAmount ;
        return po ;
    }
    /**
     * 保存新的开阀上报历史数据记录,并把ID赋值给最新记录的 lastHistoryId
     * 保存新的历史数据记录,并把ID赋值给最新记录的 lastHistoryId
     * @param sv
     * @param controller
     * @param rtuAddr
@@ -206,7 +224,7 @@
        lastPo.dt = DateTime.dateFrom_yyyy_MM_dd1(dV1_0_1.dt);
        lastPo.dtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(dV1_0_1.dt);
        lastPo.rtuDtLast = DateTime.dateFrom_yyyy_MM_dd_HH_mm_ss(cdData.rtuDt);
        //lastPo.amount = lastPo.amount ; //累计取水量不变
        //lastPo.amount = lastPo.amount ; //日累计取水量不变
        lastPo.totalAmountLast = cdData.totalAmount ;
        return lastPo ;
    }
@@ -231,12 +249,11 @@
        if(difference > 0){
            lastPo.amount = difference;
        }else{
            //po.amount = po.amount ; //累计取水量不变
            //po.amount = po.amount ; //日累计取水量不变
        }
        lastPo.totalAmountLast = cdData.totalAmount ;
        return lastPo ;
    }
    /**
     * 更新最新记录
@@ -265,6 +282,29 @@
    }
    /**
     * 生成新的控制器漏损日统计最新记录
     * @param controller
     * @param rtuAddr
     * @param dV1_0_1
     * @param cdData
     * @return
     * @throws Exception
     */
    private RmIntakeAmountDay updateRmIntakeAmountByControllerChange(RmIntakeAmountDay po, RmIntakeAmountDayLast lastPo, PrController controller, String rtuAddr, DataV1_0_1 dV1_0_1, UpDataVo cdData)throws Exception {
        po.intakeId = controller==null?null:controller.getIntakeId();
        po.controllerIdLast = controller==null?null:controller.getId();
        po.rtuAddrLast = rtuAddr;
        po.dt = lastPo.dt ;
        po.dtLast = lastPo.dtLast;
        po.rtuDtLast = lastPo.rtuDtLast;
        po.amount = lastPo.amount ;
        po.totalAmountLast = lastPo.totalAmountLast ;
        return po ;
    }
    /**
     * 更新历史记录
     * @param controller
     * @param rtuAddr
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/java/com/dy/rtuMw/server/rtuData/p206V1_0_0/TkDealLoss.java
@@ -94,6 +94,7 @@
                    //这种情况不存在(RTU时钟早于本地记录中的RTU时钟(RTU穿越回过去了,可能时钟重置了),此种情况不处理)
                }
            }
            sv.updateRmLossLast(poLast);
        }
    }
pipIrr-platform/pipIrr-mw/pipIrr-mw-rtu/src/main/resources/RtuDataDealTree.xml
@@ -21,7 +21,8 @@
                            <task id="TkDealOpenValveReport" name="控制器开阀上报(功能码83)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealOpenValveReport" />
                            <task id="TkDealCloseValveReport" name="控制器关阀上报(功能码83)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealCloseValveReport" />
                            <task id="TkDealLoss" name="取水口日漏损量(功能码C0)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealLoss" />
                            <task id="TkDealIntakeAmountDay" name="取水口日用水量和漏损量(功能码84、功能码83、功能码C0)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealIntakeAmountDay" />
                            <task id="TkDealIntakeAmountDay" name="取水口日用水量(功能码84、功能码83、功能码C0)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealIntakeAmountDay" />
                            <task id="TkDealClientAmountDay" name="农户日用水量(功能码84、功能码83、功能码C0)" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkDealClientAmountDay" />
                        </task>
                        <!-- 识别命令响应数据 -->
                        <task id="TkFindComResponse" name="识别响应命令数据" enable="true" class="com.dy.rtuMw.server.rtuData.p206V1_0_0.TkFindComResponse">
pipIrr-platform/pipIrr-web/pipIrr-mwTest-web/src/main/java/com/dy/pipIrrMwTestWeb/p206V1_0_0/ComSupportP206V1_0_0.java
@@ -23,7 +23,7 @@
    protected static String rtuAddr = "532328059995" ;
    protected static String rtuResultSendWebUrl = "http://127.0.0.1:65535/test/comRes/receive" ;
    protected static String vsIcCardNo = "7044010666" ;//虚拟IC卡编号(用户虚拟卡序列号)
    protected static String vsIcCardNo = "61181622830147822" ;//虚拟IC卡编号(用户虚拟卡序列号)
    @Autowired