package com.dy.pipIrrRemote.monitor.p202404V201.cd36; 
 | 
  
 | 
import com.alibaba.fastjson2.JSON; 
 | 
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.DataCd92_A2Vo; 
 | 
import com.dy.common.util.Callback; 
 | 
import com.dy.common.webUtil.BaseResponse; 
 | 
import com.dy.common.webUtil.BaseResponseUtils; 
 | 
import com.dy.pipIrrGlobal.pojoRm.RmCommandOpen; 
 | 
import com.dy.pipIrrGlobal.voSe.VoVirtualCard; 
 | 
import com.dy.pipIrrRemote.common.dto.DtoBase; 
 | 
import com.dy.pipIrrRemote.monitor.common.ComCtrl; 
 | 
import io.swagger.v3.oas.annotations.tags.Tag; 
 | 
import jakarta.validation.Valid; 
 | 
import lombok.RequiredArgsConstructor; 
 | 
import lombok.extern.slf4j.Slf4j; 
 | 
import org.apache.commons.lang3.RandomStringUtils; 
 | 
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.util.Date; 
 | 
  
 | 
/** 
 | 
 * @Author: liurunyu 
 | 
 * @Date: 2025/6/30 9:01 
 | 
 * @Description 
 | 
 */ 
 | 
@Slf4j 
 | 
@Tag(name = "远程命令", description = "APP端远程定量开启水泵/阀门") 
 | 
@RestController("p202404V201Cd36Ctrl") 
 | 
@RequestMapping(path = "p202404V201/cd36") 
 | 
@RequiredArgsConstructor 
 | 
@Scope("prototype") //因为有对象类属性,所以采用原型模式,每次请求新建一个实例对象 
 | 
public class CdCtrl extends ComCtrl { 
 | 
  
 | 
    private static final String RtuSuccessMsg = "控制器接收并执行命令成功,无返回数据"; 
 | 
  
 | 
    private static final String ComCode = "36" ; 
 | 
  
 | 
    private static final Double MaxRemainMoney = com.dy.pipIrrRemote.monitor.p202404V201.cd92.CdCtrl.MaxRemainMoney;//协议支持的剩余金额最大值 
 | 
  
 | 
    @Autowired 
 | 
    private CdSv sv ; 
 | 
    /** 
 | 
     * 向设备(控制器)发送命令 
 | 
     * @param dto 前端发来的值对象 
 | 
     * @param bindingResult 对dto验证的结果 
 | 
     * @return 返回前端 
 | 
     */ 
 | 
    @PostMapping(path = "send", 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, ComCode, dto, bindingResult); 
 | 
            if (res == null) { 
 | 
                if(dto.vtCardId == null || "".equals(dto.vtCardId.trim())){ 
 | 
                    Long vtId = sv.selectVcIdByIntakeId(dto.getIntakeId()) ; 
 | 
                    if(vtId == null) { 
 | 
                        return BaseResponseUtils.buildErrorMsg("请选择一张虚拟卡"); 
 | 
                    }else{ 
 | 
                        dto.vtCardId = vtId.toString() ; 
 | 
                    } 
 | 
                } 
 | 
                VoVirtualCard vcPo = sv.selectClientVtCardById(Long.parseLong(dto.vtCardId.trim())) ; 
 | 
                if(vcPo == null){ 
 | 
                    return BaseResponseUtils.buildErrorMsg("服务端出错,未得到农户虚拟卡") ; 
 | 
                } 
 | 
                if(vcPo.getInUse().booleanValue()){ 
 | 
                    return BaseResponseUtils.buildErrorMsg("农户该虚拟卡已经被占用,不能再应用其开阀") ; 
 | 
                } 
 | 
                if(vcPo.getMoney() <= 0.0){ 
 | 
                    return BaseResponseUtils.buildErrorMsg("农户该虚拟卡中剩余金额为0,不能再应用其开阀") ; 
 | 
                } 
 | 
                if(vcPo.getMoney() >= MaxRemainMoney){ 
 | 
                    return BaseResponseUtils.buildErrorMsg("农户该虚拟卡中剩余金额大于协议支持的最大值" + MaxRemainMoney + ",不能再应用其开阀") ; 
 | 
                } 
 | 
                Double waterPrice = sv.selectWaterPrice() ; 
 | 
                if(waterPrice == null){ 
 | 
                    return BaseResponseUtils.buildErrorMsg("服务端出错,未得到水价") ; 
 | 
                } 
 | 
                String orderNo = RandomStringUtils.randomNumeric(16) ; 
 | 
                CdParam comParam = CdParam.builder().commandCode(ComCode).projectNo(projectNo).controllerType(controllerType) 
 | 
                        .icCardNo("" + vcPo.getVcNum())//用户卡序列号(17位数字)(6字节BCD,2字节HEX) 
 | 
                        .waterRemain(0.0)//用户剩余水量, 两个小数点, 单位m3, 0~99999999.99 
 | 
                        .moneyRemain(vcPo.getMoney())//用户剩余水量, 两个小数点, 单位m3, 0~99999999.99 
 | 
                        .waterPrice(waterPrice)//水量单价 单位:元, 2个小数点 
 | 
                        .elePrice(0.0)//电量单价 单位:元, 2个小数点 
 | 
                        .orderNo(orderNo)//订单号(16位数字) 
 | 
                        .waterAmount(dto.waterAmount)//预用水量(0~9999 m3) 
 | 
                        .build(); 
 | 
                //发送命令前-3:保存命令日志 
 | 
                res = super.pre3(sv, dto.getIntakeId(), dto.getOperator(), ComCode, comParam); 
 | 
                if (res == null) { 
 | 
                    //发送命令前-4:准备Feature 
 | 
                    super.pre4(); 
 | 
                    try { 
 | 
                        //创建外部命令(发给控制器) 
 | 
                        Command com = sv.createOuterCommand(ctrlPo.getRtuAddr(), "" + comId, ComCode); 
 | 
                        com.rtuResultSendWebUrl = rtuResultSendWebUrl; 
 | 
                        com.param = comParam; 
 | 
                        //发送命令 
 | 
                        res = super.doSend(sv, com); 
 | 
                        if (res == null) { 
 | 
                            //发送命令后 
 | 
                            res = super.after(ComCode, new Callback() { 
 | 
                                @Override 
 | 
                                public void call(Object obj) { 
 | 
                                    Boolean success = (Boolean) obj; 
 | 
                                    if(success){ 
 | 
                                        // 添加常用取水口或更新使用信息 
 | 
                                        sv.addOrUpdateOftenUseIntake(dto.getOperator(), dto.getIntakeId()) ; 
 | 
                                        //开阀成功,虚拟卡记录上标记已被占用 
 | 
                                        sv.setVcUsed(vcPo.getId(), dto.getIntakeId()); 
 | 
                                        //记录开阀命令,以备远程关阀 
 | 
                                        RmCommandOpen comOpen = sv.getCommandOpen(dto.getIntakeId()); 
 | 
                                        if(comOpen == null){ 
 | 
                                            RmCommandOpen po = newRmCommandOpen(comId, ctrlPo.getProtocol(), ComCode, comName, dto.getIntakeId(), ctrlPo.getRtuAddr(), vcPo.getVcNum(), orderNo, dto.getOperator()) ; 
 | 
                                            sv.saveCommandOpen(po); 
 | 
                                        }else{ 
 | 
                                            setRmCommandOpen(comOpen, comId, ctrlPo.getProtocol(), ComCode, comName, dto.getIntakeId(), ctrlPo.getRtuAddr(), vcPo.getVcNum(), orderNo, dto.getOperator()) ; 
 | 
                                            sv.updateCommandOpen(comOpen); 
 | 
                                        } 
 | 
                                    } 
 | 
                                } 
 | 
                                @Override 
 | 
                                public void call(Object... objs) { 
 | 
                                } 
 | 
                                @Override 
 | 
                                public void exception(Exception e) { 
 | 
                                } 
 | 
                            }); 
 | 
                        } 
 | 
                    } catch (Exception e) { 
 | 
                        res = BaseResponseUtils.buildFail("服务端构造并向通信中间件发送请求时异常" + (e.getMessage() == null ? "" : e.getMessage())); 
 | 
                    } finally { 
 | 
                        //最终 
 | 
                        super.end(); 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        return res ; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    protected String checkDto(DtoBase dto) { 
 | 
        return null; 
 | 
    } 
 | 
  
 | 
    @Override 
 | 
    protected String dealComResult(String code, JSONObject resultData, Callback callback){ 
 | 
        String msg; 
 | 
        if(resultData != null){ 
 | 
            JSONObject codeData = resultData.getJSONObject("data") ; 
 | 
            if(codeData == null){ 
 | 
                msg = RtuSuccessMsg ; 
 | 
            }else { 
 | 
                String json = codeData.toJSONString(); 
 | 
                DataCd92_A2Vo cvo = JSON.parseObject(json, DataCd92_A2Vo.class) ; 
 | 
                if(cvo != null){ 
 | 
                    if(callback != null){ 
 | 
                        if(cvo.opResult != null && cvo.opResult.byteValue() == (byte)1){ 
 | 
                            callback.call(true);//开阀成功 
 | 
                        }else{ 
 | 
                            callback.call(false);//开阀失败 
 | 
                        } 
 | 
                    } 
 | 
                    msg = cvo.toStr(false) ; 
 | 
                }else{ 
 | 
                    msg = RtuSuccessMsg ; 
 | 
                } 
 | 
            } 
 | 
        }else{ 
 | 
            msg = RtuSuccessMsg ; 
 | 
        } 
 | 
        return msg; 
 | 
    } 
 | 
  
 | 
    private RmCommandOpen newRmCommandOpen(Long comId, 
 | 
                                           String protocol, 
 | 
                                           String comCode, 
 | 
                                           String comName, 
 | 
                                           Long intakeId, 
 | 
                                           String rtuAddr, 
 | 
                                           Long vcNum, 
 | 
                                           String orderNo, 
 | 
                                           Long operator){ 
 | 
        RmCommandOpen po = new RmCommandOpen() ; 
 | 
        this.setRmCommandOpen(po, comId, protocol, comCode, comName, intakeId, rtuAddr, vcNum, orderNo, operator); 
 | 
        return po ; 
 | 
    } 
 | 
    private void setRmCommandOpen(RmCommandOpen po, 
 | 
                                  Long comId, 
 | 
                                  String protocol, 
 | 
                                  String comCode, 
 | 
                                  String comName, 
 | 
                                  Long intakeId, 
 | 
                                  String rtuAddr, 
 | 
                                  Long vcNum, 
 | 
                                  String orderNo, 
 | 
                                  Long operator){ 
 | 
        po.comId = comId ; 
 | 
        po.protocol = protocol ; 
 | 
        po.commandCode = comCode ; 
 | 
        po.commandName = comName ; 
 | 
        po.intakeId = intakeId ; 
 | 
        po.rtuAddr = rtuAddr ; 
 | 
        po.vcNum = vcNum ; 
 | 
        po.orderNo = orderNo ; 
 | 
        po.operator = operator ; 
 | 
        po.sendTime = new Date() ; 
 | 
    } 
 | 
} 
 |