Administrator
2024-05-27 f5a7f6c30bc5fb13eb538b5856a663b1ba0667b6
2024-05-27 朱宝民 远程开关阀、RTU在线情况
3 文件已重命名
10个文件已添加
16个文件已修改
1658 ■■■■ 已修改文件
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoBa/BaSettingsMapper.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrWaterPriceMapper.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmCommandHistoryMapper.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoSe/SeVirtualCardMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoBa/BaSettings.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrWaterPrice.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmCommandHistory.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoSe/SeVirtualCard.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voRm/VoUnclosedValve.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voSe/VoVirtualCard.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaSettingsMapper.xml 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrWaterPriceMapper.xml 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmCommandHistoryMapper.xml 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeVirtualCardMapper.xml 57 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/pom.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/PipIrrRemoteApplication.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/ComSupport.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandResultCtrl.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandSv.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/Addr.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/DtoBase.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/ValveClose.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/ValveOpen.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/result/RemoteResultCode.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/rtu/RtuCtrl.java 73 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java 296 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/virtualCard/VirtualCardCtrl.java 377 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/virtualCard/VirtualCardSv.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/virtualCard/enums/LastOperateENUM.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoBa/BaSettingsMapper.java
New file
@@ -0,0 +1,35 @@
package com.dy.pipIrrGlobal.daoBa;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoBa.BaSettings;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * @author ZhuBaoMin
 * @date 2024-05-27 9:17
 * @LastEditTime 2024-05-27 9:17
 * @Description
 */
@Mapper
public interface BaSettingsMapper extends BaseMapper<BaSettings> {
    int deleteByPrimaryKey(Long id);
    int insert(BaSettings record);
    int insertSelective(BaSettings record);
    BaSettings selectByPrimaryKey(Long id);
    int updateByPrimaryKeySelective(BaSettings record);
    int updateByPrimaryKey(BaSettings record);
    /**
     * 根据配置项获取配置项值
     * @param itemName
     * @return
     */
    String getItemValue(@Param("itemName") String itemName);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoPr/PrWaterPriceMapper.java
New file
@@ -0,0 +1,33 @@
package com.dy.pipIrrGlobal.daoPr;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoPr.PrWaterPrice;
import org.apache.ibatis.annotations.Mapper;
/**
 * @author ZhuBaoMin
 * @date 2024-05-24 9:28
 * @LastEditTime 2024-05-24 9:28
 * @Description
 */
@Mapper
public interface PrWaterPriceMapper extends BaseMapper<PrWaterPrice> {
    int deleteByPrimaryKey(Long id);
    int insert(PrWaterPrice record);
    int insertSelective(PrWaterPrice record);
    PrWaterPrice selectByPrimaryKey(Long id);
    int updateByPrimaryKeySelective(PrWaterPrice record);
    int updateByPrimaryKey(PrWaterPrice record);
    /**
     * 获取水价
     * @return
     */
    Double getPrice();
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoRm/RmCommandHistoryMapper.java
@@ -2,12 +2,15 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import com.dy.pipIrrGlobal.voRm.VoUnclosedValve;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * @author ZhuBaoMin
 * @date 2024-05-22 14:29
 * @LastEditTime 2024-05-22 14:29
 * @date 2024-05-24 10:46
 * @LastEditTime 2024-05-24 10:46
 * @Description
 */
@@ -24,4 +27,11 @@
    int updateByPrimaryKeySelective(RmCommandHistory record);
    int updateByPrimaryKey(RmCommandHistory record);
    /**
     * 根据操作员ID获取未关阀记录
     * @param operator 操作员ID
     * @return 未关阀记录
     */
    List<VoUnclosedValve> getUnclosedValves(Long operator);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/daoSe/SeVirtualCardMapper.java
@@ -2,13 +2,16 @@
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
import com.dy.pipIrrGlobal.voSe.VoVirtualCard;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author ZhuBaoMin
 * @date 2024-04-22 9:38
 * @LastEditTime 2024-04-22 9:38
 * @date 2024-05-23 16:44
 * @LastEditTime 2024-05-23 16:44
 * @Description
 */
@@ -33,4 +36,24 @@
     * @return 符合条件记录数
     */
    int getRecordCountByName(@Param("clientId") Long clientId, @Param("vcName") String vcName);
    /**
     * 获取全部虚拟卡
     * @return
     */
    List<VoVirtualCard> getVCs();
    /**
     * 根据虚拟卡ID获取虚拟卡对象
     * @param vcId
     * @return
     */
    VoVirtualCard getVcById(@Param("vcId") Long vcId);
    /**
     * 根据虚拟卡编号获取虚拟卡ID
     * @param vcNum
     * @return
     */
    Long getVcIdByNum(@Param("vcNum") String vcNum);
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoBa/BaSettings.java
New file
@@ -0,0 +1,61 @@
package com.dy.pipIrrGlobal.pojoBa;
/**
 * @author ZhuBaoMin
 * @date 2024-05-27 9:17
 * @LastEditTime 2024-05-27 9:17
 * @Description
 */
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 io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import lombok.*;
/**
 * 系统配置表
 */
@TableName(value="ba_settings", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "系统配置实体")
public class BaSettings implements BaseEntity {
    public static final long serialVersionUID = 202405271036001L;
    /**
    * 主键
    */
    @JSONField(serializeUsing= ObjectWriterImplToString.class)
    @TableId(type = IdType.INPUT)
    @Schema(description = "实体id", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private Long id;
    /**
    * 配置项
    */
    @Schema(description = "配置项", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "配置项不能为空")
    private String itemName;
    /**
    * 配置项值
    */
    @Schema(description = "配置项值", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "配置项值不能为空")
    private String itemValue;
    /**
    * 备注信息
    */
    @Schema(description = "备注信息", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private String remarks;
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoPr/PrWaterPrice.java
New file
@@ -0,0 +1,75 @@
package com.dy.pipIrrGlobal.pojoPr;
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 io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import java.util.Date;
/**
 * @author ZhuBaoMin
 * @date 2024-05-24 9:28
 * @LastEditTime 2024-05-24 9:28
 * @Description
 */
/**
 * 水价表
 */
@TableName(value="pr_water_price", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "水价实体")
public class PrWaterPrice implements BaseEntity {
    public static final long serialVersionUID = 202405240934001L;
    /**
    * 主键
    */
    @JSONField(serializeUsing= ObjectWriterImplToString.class)
    @TableId(type = IdType.INPUT)
    @Schema(description = "实体id", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private Long id;
    /**
    * 水价
    */
    @Schema(description = "水价", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotNull(message = "水价不能为空")
    private Double price;
    /**
    * 项目编号
    */
    @Schema(description = "项目编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private Long projectId;
    /**
    * 操作人编号
    */
    @Schema(description = "操作人ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotNull(message = "操作人ID不能为空")
    private Long operator;
    /**
    * 操作时间
    */
    @Schema(description = "操作时间", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private Date operateTime;
    /**
    * 逻辑删除标识;0-未删除,1-删除
    */
    @Schema(description = "删除标识", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    private Byte deleted;
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoRm/RmCommandHistory.java
@@ -1,5 +1,12 @@
package com.dy.pipIrrGlobal.pojoRm;
/**
 * @author ZhuBaoMin
 * @date 2024-05-24 10:46
 * @LastEditTime 2024-05-24 10:46
 * @Description
 */
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.annotation.JSONField;
import com.alibaba.fastjson2.writer.ObjectWriterImplToString;
@@ -16,22 +23,15 @@
import java.util.Date;
/**
 * @author ZhuBaoMin
 * @date 2024-05-21 16:53
 * @LastEditTime 2024-05-21 16:53
 * @Description 命令日志实体类
 */
/**
 * 命令日志表
 */
    * 命令日志表
    */
@TableName(value = "rm_command_history", autoResultMap = true)
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class RmCommandHistory implements BaseEntity{
public class RmCommandHistory implements BaseEntity {
    public static final long serialVersionUID = 202401151517005L;
    /**
@@ -64,18 +64,6 @@
     */
    @NotBlank(message = "通讯协议不能为空")
    private String protocol;
    /**
     * 命令类型
     */
    @NotBlank(message = "命令类型不能为空")
    private String commandType;
    /**
     * 回调URL
     */
    @NotBlank(message = "回调URL不能为空")
    private String callback;
    /**
     * 参数数据
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/pojoSe/SeVirtualCard.java
@@ -9,7 +9,6 @@
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.*;
@@ -17,9 +16,12 @@
/**
 * @author ZhuBaoMin
 * @date 2024-03-05 20:45
 * @LastEditTime 2024-03-05 20:45
 * @date 2024-05-23 16:44
 * @LastEditTime 2024-05-23 16:44
 * @Description
 */
/**
 * 虚拟卡表
 */
@TableName(value="se_virtual_card", autoResultMap = true)
@@ -41,11 +43,11 @@
    private Long id;
    /**
     * 虚拟卡名称
     * 虚拟卡编号
     */
    @Schema(description = "农户ID", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotBlank(message = "虚拟卡名称不能为空")
    private String vcName;
    @Schema(description = "虚拟卡编号", requiredMode = Schema.RequiredMode.NOT_REQUIRED)
    @NotNull(message = "虚拟卡编号不能为空")
    private Long vcNum;
    /**
     * 农户ID
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voRm/VoUnclosedValve.java
New file
@@ -0,0 +1,30 @@
package com.dy.pipIrrGlobal.voRm;
import com.dy.common.po.BaseEntity;
import lombok.Data;
import java.util.Date;
/**
 * @author ZhuBaoMin
 * @date 2024-05-24 16:30
 * @LastEditTime 2024-05-24 16:30
 * @Description 未关阀对象视图
 */
@Data
public class VoUnclosedValve implements BaseEntity {
    private static final long serialVersionUID = 202405241634001L;
    private String commandCode;
    private String intakeNum;
    private String rtuAddr;
    private String orderNo;
    private String vcNum;
    private Date openTime;
}
pipIrr-platform/pipIrr-global/src/main/java/com/dy/pipIrrGlobal/voSe/VoVirtualCard.java
New file
@@ -0,0 +1,27 @@
package com.dy.pipIrrGlobal.voSe;
import com.dy.common.po.BaseEntity;
import lombok.Data;
/**
 * @author ZhuBaoMin
 * @date 2024-05-24 8:14
 * @LastEditTime 2024-05-24 8:14
 * @Description 虚拟卡视图对象
 */
@Data
public class VoVirtualCard implements BaseEntity {
    private static final long serialVersionUID = 202405240815001L;
    private String id;
    private String vcNum;
    private Double money;
    private Byte inUse;
    private String inUseName;
}
pipIrr-platform/pipIrr-global/src/main/resources/mapper/BaSettingsMapper.xml
New file
@@ -0,0 +1,96 @@
<?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.daoBa.BaSettingsMapper">
  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoBa.BaSettings">
    <!--@mbg.generated-->
    <!--@Table ba_settings-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="item_name" jdbcType="VARCHAR" property="itemName" />
    <result column="item_value" jdbcType="VARCHAR" property="itemValue" />
    <result column="remarks" jdbcType="VARCHAR" property="remarks" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, item_name, item_value, remarks
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from ba_settings
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from ba_settings
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoBa.BaSettings">
    <!--@mbg.generated-->
    insert into ba_settings (id, item_name, item_value,
      remarks)
    values (#{id,jdbcType=BIGINT}, #{itemName,jdbcType=VARCHAR}, #{itemValue,jdbcType=VARCHAR},
      #{remarks,jdbcType=VARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoBa.BaSettings">
    <!--@mbg.generated-->
    insert into ba_settings
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="itemName != null">
        item_name,
      </if>
      <if test="itemValue != null">
        item_value,
      </if>
      <if test="remarks != null">
        remarks,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="itemName != null">
        #{itemName,jdbcType=VARCHAR},
      </if>
      <if test="itemValue != null">
        #{itemValue,jdbcType=VARCHAR},
      </if>
      <if test="remarks != null">
        #{remarks,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoBa.BaSettings">
    <!--@mbg.generated-->
    update ba_settings
    <set>
      <if test="itemName != null">
        item_name = #{itemName,jdbcType=VARCHAR},
      </if>
      <if test="itemValue != null">
        item_value = #{itemValue,jdbcType=VARCHAR},
      </if>
      <if test="remarks != null">
        remarks = #{remarks,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoBa.BaSettings">
    <!--@mbg.generated-->
    update ba_settings
    set item_name = #{itemName,jdbcType=VARCHAR},
      item_value = #{itemValue,jdbcType=VARCHAR},
      remarks = #{remarks,jdbcType=VARCHAR}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <!--根据配置项获取配置项值-->
  <select id="getItemValue" resultType="java.lang.String">
    SELECT IFNULL(item_value, '') AS itemValue FROM ba_settings WHERE item_name = #{itemName} LIMIT 0,1
  </select>
</mapper>
pipIrr-platform/pipIrr-global/src/main/resources/mapper/PrWaterPriceMapper.xml
New file
@@ -0,0 +1,120 @@
<?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.daoPr.PrWaterPriceMapper">
  <resultMap id="BaseResultMap" type="com.dy.pipIrrGlobal.pojoPr.PrWaterPrice">
    <!--@mbg.generated-->
    <!--@Table pr_water_price-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="price" jdbcType="FLOAT" property="price" />
    <result column="project_id" jdbcType="BIGINT" property="projectId" />
    <result column="operator" jdbcType="BIGINT" property="operator" />
    <result column="operate_time" jdbcType="TIMESTAMP" property="operateTime" />
    <result column="deleted" jdbcType="TINYINT" property="deleted" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, price, project_id, `operator`, operate_time, deleted
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
    select
    <include refid="Base_Column_List" />
    from pr_water_price
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--@mbg.generated-->
    delete from pr_water_price
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoPr.PrWaterPrice">
    <!--@mbg.generated-->
    insert into pr_water_price (id, price, project_id,
      `operator`, operate_time, deleted
      )
    values (#{id,jdbcType=BIGINT}, #{price,jdbcType=FLOAT}, #{projectId,jdbcType=BIGINT},
      #{operator,jdbcType=BIGINT}, #{operateTime,jdbcType=TIMESTAMP}, #{deleted,jdbcType=TINYINT}
      )
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrWaterPrice">
    <!--@mbg.generated-->
    insert into pr_water_price
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="price != null">
        price,
      </if>
      <if test="projectId != null">
        project_id,
      </if>
      <if test="operator != null">
        `operator`,
      </if>
      <if test="operateTime != null">
        operate_time,
      </if>
      <if test="deleted != null">
        deleted,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="price != null">
        #{price,jdbcType=FLOAT},
      </if>
      <if test="projectId != null">
        #{projectId,jdbcType=BIGINT},
      </if>
      <if test="operator != null">
        #{operator,jdbcType=BIGINT},
      </if>
      <if test="operateTime != null">
        #{operateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="deleted != null">
        #{deleted,jdbcType=TINYINT},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.dy.pipIrrGlobal.pojoPr.PrWaterPrice">
    <!--@mbg.generated-->
    update pr_water_price
    <set>
      <if test="price != null">
        price = #{price,jdbcType=FLOAT},
      </if>
      <if test="projectId != null">
        project_id = #{projectId,jdbcType=BIGINT},
      </if>
      <if test="operator != null">
        `operator` = #{operator,jdbcType=BIGINT},
      </if>
      <if test="operateTime != null">
        operate_time = #{operateTime,jdbcType=TIMESTAMP},
      </if>
      <if test="deleted != null">
        deleted = #{deleted,jdbcType=TINYINT},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoPr.PrWaterPrice">
    <!--@mbg.generated-->
    update pr_water_price
    set price = #{price,jdbcType=FLOAT},
      project_id = #{projectId,jdbcType=BIGINT},
      `operator` = #{operator,jdbcType=BIGINT},
      operate_time = #{operateTime,jdbcType=TIMESTAMP},
      deleted = #{deleted,jdbcType=TINYINT}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <!--获取水价-->
  <select id="getPrice" resultType="java.lang.Double">
    SELECT IFNULL(price,0.0)   FROM pr_water_price WHERE deleted = 0 LIMIT 0,1
  </select>
</mapper>
pipIrr-platform/pipIrr-global/src/main/resources/mapper/RmCommandHistoryMapper.xml
@@ -9,11 +9,7 @@
    <result column="command_name" jdbcType="VARCHAR" property="commandName" />
    <result column="rtuAddr" jdbcType="VARCHAR" property="rtuaddr" />
    <result column="protocol" jdbcType="VARCHAR" property="protocol" />
    <result column="command_type" jdbcType="VARCHAR" property="commandType" />
    <result column="callBack" jdbcType="VARCHAR" property="callback" />
<!--    <result column="param" jdbcType="VARCHAR" property="param" />-->
    <result column="param" property="param" jdbcType="JAVA_OBJECT" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
    <result column="send_time" jdbcType="TIMESTAMP" property="sendTime" />
    <result column="operator" jdbcType="BIGINT" property="operator" />
    <result column="result" jdbcType="TINYINT" property="result" />
@@ -22,8 +18,8 @@
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, command_code, command_name, rtuAddr, protocol, command_type, callBack, param,
    send_time, `operator`, `result`, result_time, result_text
    id, command_code, command_name, rtuAddr, protocol, param, send_time, `operator`,
    `result`, result_time, result_text
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
@@ -40,15 +36,13 @@
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoRm.RmCommandHistory">
    <!--@mbg.generated-->
    insert into rm_command_history (id, command_code, command_name, 
      rtuAddr, protocol, command_type,
      callBack, param, send_time,
      `operator`, `result`, result_time,
      result_text)
      rtuAddr, protocol, param,
      send_time, `operator`, `result`,
      result_time, result_text)
    values (#{id,jdbcType=BIGINT}, #{commandCode,jdbcType=VARCHAR}, #{commandName,jdbcType=VARCHAR}, 
      #{rtuaddr,jdbcType=VARCHAR}, #{protocol,jdbcType=VARCHAR}, #{commandType,jdbcType=VARCHAR},
      #{callback,jdbcType=VARCHAR}, #{param,jdbcType= JAVA_OBJECT, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler}, #{sendTime,jdbcType=TIMESTAMP},
      #{operator,jdbcType=BIGINT}, #{result,jdbcType=TINYINT}, #{resultTime,jdbcType=TIMESTAMP},
      #{resultText,jdbcType= JAVA_OBJECT, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler})
      #{rtuaddr,jdbcType=VARCHAR}, #{protocol,jdbcType=VARCHAR}, #{param,jdbcType= JAVA_OBJECT, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler},
      #{sendTime,jdbcType=TIMESTAMP}, #{operator,jdbcType=BIGINT}, #{result,jdbcType=TINYINT},
      #{resultTime,jdbcType=TIMESTAMP}, #{resultText,jdbcType= JAVA_OBJECT, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler})
  </insert>
  <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoRm.RmCommandHistory">
    <!--@mbg.generated-->
@@ -68,12 +62,6 @@
      </if>
      <if test="protocol != null">
        protocol,
      </if>
      <if test="commandType != null">
        command_type,
      </if>
      <if test="callback != null">
        callBack,
      </if>
      <if test="param != null">
        param,
@@ -109,12 +97,6 @@
      </if>
      <if test="protocol != null">
        #{protocol,jdbcType=VARCHAR},
      </if>
      <if test="commandType != null">
        #{commandType,jdbcType=VARCHAR},
      </if>
      <if test="callback != null">
        #{callback,jdbcType=VARCHAR},
      </if>
      <if test="param != null">
        #{param,jdbcType= JAVA_OBJECT, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler},
@@ -152,12 +134,6 @@
      <if test="protocol != null">
        protocol = #{protocol,jdbcType=VARCHAR},
      </if>
      <if test="commandType != null">
        command_type = #{commandType,jdbcType=VARCHAR},
      </if>
      <if test="callback != null">
        callBack = #{callback,jdbcType=VARCHAR},
      </if>
      <if test="param != null">
        param = #{param,jdbcType= JAVA_OBJECT, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler},
      </if>
@@ -186,8 +162,6 @@
      command_name = #{commandName,jdbcType=VARCHAR},
      rtuAddr = #{rtuaddr,jdbcType=VARCHAR},
      protocol = #{protocol,jdbcType=VARCHAR},
      command_type = #{commandType,jdbcType=VARCHAR},
      callBack = #{callback,jdbcType=VARCHAR},
      param = #{param,jdbcType= JAVA_OBJECT, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler},
      send_time = #{sendTime,jdbcType=TIMESTAMP},
      `operator` = #{operator,jdbcType=BIGINT},
@@ -196,4 +170,21 @@
      result_text = #{resultText,jdbcType= JAVA_OBJECT, typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler}
    where id = #{id,jdbcType=BIGINT}
  </update>
  <!--根据操作员ID获取未关阀记录-->
  <select id="getUnclosedValves" resultType="com.dy.pipIrrGlobal.voRm.VoUnclosedValve">
    SELECT
      com.command_code AS commandCode,
      inta.name AS intakeNum,
      com.rtuAddr,
      com.param ->>'$.orderNo' AS orderNo,
      com.param ->>'$.icCardNo' AS vcNum,
      com.send_time AS openTime
    FROM rm_command_history com
      INNER JOIN pr_controller con ON com.rtuAddr = con.rtuAddr
      INNER JOIN pr_intake inta ON con.intakeId = inta.id
    WHERE (com.command_code = '92' OR com.command_code = 'A2') AND com.operator = #{operator}
      AND NOT EXISTS (SELECT * FROM rm_command_history WHERE (command_code = '93' OR command_code = 'A3') AND param ->>'$.orderNo' = com.param ->>'$.orderNo')
    ORDER BY com.send_time DESC
  </select>
</mapper>
pipIrr-platform/pipIrr-global/src/main/resources/mapper/SeVirtualCardMapper.xml
@@ -5,7 +5,7 @@
    <!--@mbg.generated-->
    <!--@Table se_virtual_card-->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="vc_name" jdbcType="VARCHAR" property="vcName" />
    <result column="vc_num" jdbcType="BIGINT" property="vcNum" />
    <result column="client_id" jdbcType="BIGINT" property="clientId" />
    <result column="money" jdbcType="FLOAT" property="money" />
    <result column="last_operate" jdbcType="TINYINT" property="lastOperate" />
@@ -15,7 +15,7 @@
  </resultMap>
  <sql id="Base_Column_List">
    <!--@mbg.generated-->
    id, vc_name, client_id, money, last_operate, last_operate_time, in_use, create_time
    id, vc_num, client_id, money, last_operate, last_operate_time, in_use, create_time
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--@mbg.generated-->
@@ -31,10 +31,10 @@
  </delete>
  <insert id="insert" parameterType="com.dy.pipIrrGlobal.pojoSe.SeVirtualCard">
    <!--@mbg.generated-->
    insert into se_virtual_card (id, vc_name, client_id,
    insert into se_virtual_card (id, vc_num, client_id,
      money, last_operate, last_operate_time, 
      in_use, create_time)
    values (#{id,jdbcType=BIGINT}, #{vcName,jdbcType=VARCHAR}, #{clientId,jdbcType=BIGINT},
    values (#{id,jdbcType=BIGINT}, #{vcNum,jdbcType=BIGINT}, #{clientId,jdbcType=BIGINT},
      #{money,jdbcType=FLOAT}, #{lastOperate,jdbcType=TINYINT}, #{lastOperateTime,jdbcType=TIMESTAMP}, 
      #{inUse,jdbcType=TINYINT}, #{createTime,jdbcType=TIMESTAMP})
  </insert>
@@ -45,8 +45,8 @@
      <if test="id != null">
        id,
      </if>
      <if test="vcName != null">
        vc_name,
      <if test="vcNum != null">
        vc_num,
      </if>
      <if test="clientId != null">
        client_id,
@@ -71,8 +71,8 @@
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="vcName != null">
        #{vcName,jdbcType=VARCHAR},
      <if test="vcNum != null">
        #{vcNum,jdbcType=BIGINT},
      </if>
      <if test="clientId != null">
        #{clientId,jdbcType=BIGINT},
@@ -98,8 +98,8 @@
    <!--@mbg.generated-->
    update se_virtual_card
    <set>
      <if test="vcName != null">
        vc_name = #{vcName,jdbcType=VARCHAR},
      <if test="vcNum != null">
        vc_num = #{vcNum,jdbcType=BIGINT},
      </if>
      <if test="clientId != null">
        client_id = #{clientId,jdbcType=BIGINT},
@@ -125,7 +125,7 @@
  <update id="updateByPrimaryKey" parameterType="com.dy.pipIrrGlobal.pojoSe.SeVirtualCard">
    <!--@mbg.generated-->
    update se_virtual_card
    set vc_name = #{vcName,jdbcType=VARCHAR},
    set vc_num = #{vcNum,jdbcType=BIGINT},
      client_id = #{clientId,jdbcType=BIGINT},
      money = #{money,jdbcType=FLOAT},
      last_operate = #{lastOperate,jdbcType=TINYINT},
@@ -149,4 +149,39 @@
      </if>
    </where>
  </select>
  <!--获取全部虚拟卡-->
  <select id="getVCs" resultType="com.dy.pipIrrGlobal.voSe.VoVirtualCard">
    SELECT
      CAST(id AS char) AS id,
      vc_num AS vcNum,
      money,
      in_use AS inUse,
      (CASE
        WHEN in_use = 0 THEN "未使用"
        WHEN in_use = 1 THEN "使用中"
      END) AS inUseName
    FROM se_virtual_card
    ORDER BY in_use, money
  </select>
  <!--根据虚拟卡ID获取虚拟卡对象-->
  <select id="getVcById" resultType="com.dy.pipIrrGlobal.voSe.VoVirtualCard">
    SELECT
        CAST(id AS char) AS id,
        vc_num AS vcNum,
        money,
        in_use AS inUse,
        (CASE
            WHEN in_use = 0 THEN "未使用"
            WHEN in_use = 1 THEN "使用中"
        END) AS inUseName
    FROM se_virtual_card
    WHERE id = #{vcId}
  </select>
  <!--根据虚拟卡编号获取虚拟卡ID-->
  <select id="getVcIdByNum" resultType="java.lang.Long">
    SELECT id FROM se_virtual_card WHERE vc_num = #{vcNum}
  </select>
</mapper>
pipIrr-platform/pipIrr-web/pipIrr-web-remote/pom.xml
@@ -9,6 +9,12 @@
            <version>1.0.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.dy</groupId>
            <artifactId>pipIrr-web-sell</artifactId>
            <version>1.0.0</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
    <parent>
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/PipIrrRemoteApplication.java
@@ -18,7 +18,7 @@
                })
        }
)
@MapperScan(basePackages={"com.dy.pipIrrGlobal.daoRm", "com.dy.pipIrrGlobal.daoPr"})
@MapperScan(basePackages={"com.dy.pipIrrGlobal.daoRm", "com.dy.pipIrrGlobal.daoPr", "com.dy.pipIrrGlobal.daoSe", "com.dy.pipIrrGlobal.daoBa"})
public class PipIrrRemoteApplication {
    public static void main(String[] args) {
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/ComSupport.java
@@ -4,20 +4,32 @@
import com.alibaba.fastjson2.JSONObject;
import com.dy.common.mw.protocol.Command;
import com.dy.common.mw.protocol.CommandType;
import com.dy.common.mw.protocol.Data;
import com.dy.common.mw.protocol.p206V202404.CodeV202404;
import com.dy.common.mw.protocol.p206V202404.ProtocolConstantV206V202404;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCdXyVo;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.pipIrrGlobal.daoBa.BaSettingsMapper;
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import com.dy.pipIrrRemote.result.RemoteResultCode;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
 * @author ZhuBaoMin
@@ -25,7 +37,8 @@
 * @LastEditTime 2024-05-21 15:30
 * @Description
 */
//@RequiredArgsConstructor
@Component
public class ComSupport {
    //@NotNull
    //private final CommandSv commandSv;
@@ -37,17 +50,44 @@
    protected static String rtuResultSendWebUrl = "http://127.0.0.1:8081/remote/comRes/receive" ;
    protected static String controllerType = "57" ;//控制器类型
    protected static Integer projectNo = 10 ;//项目编码
    protected static Integer projectNo = 100 ;//项目编码
    protected static String icCardAddr = "04BEA5BB" ;//IC卡地址
    protected static String icCardNo = "37142501020500001" ;//IC卡编号(用户卡序列号)
    protected String protocolName = ProtocolConstantV206V202404.protocolName;
    protected String commandTypeInner = CommandType.innerCommand;
    protected String commandTypeOuter = CommandType.outerCommand;
    // 存储实例化的 CompletableFuture<Data> 对象
    protected static Map<String, Object> features = new HashMap<>();
    protected static Boolean setuped = false;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private BaSettingsMapper baSettingsMapper;
    public static ComSupport comSupport;
    /**
     * 引入BaSettingsMapper
     */
    @PostConstruct
    public void init() {
        comSupport = this;
        comSupport.baSettingsMapper = this.baSettingsMapper;
    }
    /**
     * 获取系统配置参数
     */
    public void setUp() {
        protocolName = comSupport.baSettingsMapper.getItemValue("protocolName");
        controllerType = comSupport.baSettingsMapper.getItemValue("controllerType");
        projectNo = Integer.parseInt(comSupport.baSettingsMapper.getItemValue("projectNo"));
        setuped = true;
    }
    protected ComCdXyVo comCdXyVo(){
        ComCdXyVo comVo = new ComCdXyVo() ;
@@ -70,8 +110,6 @@
        rmCommandHistory.setCommandName(CodeV202404.getCodeName(commandCode));
        rmCommandHistory.setRtuaddr(rtuAddr);
        rmCommandHistory.setProtocol(protocolName);
        rmCommandHistory.setCommandType(commandTypeOuter);
        rmCommandHistory.setCallback(rtuResultSendWebUrl);
        rmCommandHistory.setParam((JSONObject) JSON.toJSON(param));
        rmCommandHistory.setSendTime(new Date());
        rmCommandHistory.setOperator(operator);
@@ -99,6 +137,36 @@
        com.param = param ;
        return com ;
    }
    /**
     * 处理回调内容
     * @param comId
     * @return
     */
    protected BaseResponse<Data> dealWithCallBack(String comId) {
        CompletableFuture<Data> featureObject = new CompletableFuture<>();
        features.put(comId, featureObject);
        try {
            CompletableFuture<Data> feature = (CompletableFuture<Data>) features.get(comId);
            System.out.println("receive result ID:" + comId);
            Data resultData = feature.get(30, TimeUnit.SECONDS);
            features.remove(comId);
            String commandId = resultData.getCommandId();
            if(commandId.equals(comId)) {
                return BaseResponseUtils.buildSuccess(resultData);
            }else {
                return BaseResponseUtils.buildSuccess();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            return BaseResponseUtils.buildFail(RemoteResultCode.GET_RESULT_ERROR.getMessage());
        } catch (ExecutionException e) {
            e.printStackTrace();
            return BaseResponseUtils.buildFail(RemoteResultCode.GET_RESULT_ERROR.getMessage());
        } catch (TimeoutException e) {
            return BaseResponseUtils.buildFail(RemoteResultCode.GET_RESULT_IN_ONE_MINUTE.getMessage());
        }
    }
    /**
@@ -140,4 +208,5 @@
        }
        return response.getBody();
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandResultCtrl.java
File was renamed from pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/rtu/CommandResultCtrl.java
@@ -1,4 +1,4 @@
package com.dy.pipIrrRemote.rtu;
package com.dy.pipIrrRemote.common;
import com.dy.common.mw.protocol.Data;
import com.dy.common.webUtil.BaseResponse;
@@ -10,6 +10,8 @@
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
@@ -20,10 +22,17 @@
@Slf4j
@RestController
@RequestMapping(path="comRes")
public class CommandResultCtrl {
public class CommandResultCtrl extends ComSupport {
    @PostMapping(path = "receive", consumes = MediaType.APPLICATION_JSON_VALUE)
    public BaseResponse<String> receive(@RequestBody Data data) {
        log.info(data.toString()) ;
        String comId = "0";
        if(data.getCommandId() != null) {
            comId = data.getCommandId();
        }
        CompletableFuture<Data> feature = (CompletableFuture<Data>) features.get(comId);
        if(feature != null) {
            feature.complete(data);
        }
        return BaseResponseUtils.buildSuccess("ok");
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/CommandSv.java
@@ -2,10 +2,14 @@
import com.dy.pipIrrGlobal.daoPr.PrControllerMapper;
import com.dy.pipIrrGlobal.daoRm.RmCommandHistoryMapper;
import com.dy.pipIrrGlobal.daoSe.SeVirtualCardMapper;
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import com.dy.pipIrrGlobal.voRm.VoUnclosedValve;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * @author ZhuBaoMin
@@ -20,6 +24,7 @@
public class CommandSv {
    private final RmCommandHistoryMapper rmCommandHistoryMapper;
    private final PrControllerMapper prControllerMapper;
    private final SeVirtualCardMapper seVirtualCardMapper;
    /**
     * 根据取水口ID获取阀控器地址
@@ -48,4 +53,16 @@
    public Integer update(RmCommandHistory po) {
        return rmCommandHistoryMapper.updateByPrimaryKeySelective(po);
    }
    /**
     * 根据操作员ID获取未关阀记录
     * @param operator
     * @return
     */
    public List<VoUnclosedValve> getUnclosedValves(Long operator) {
        return rmCommandHistoryMapper.getUnclosedValves(operator);
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/Addr.java
File was renamed from pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/rtu/dto/Addr.java
@@ -1,4 +1,4 @@
package com.dy.pipIrrRemote.rtu.dto;
package com.dy.pipIrrRemote.common.dto;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@@ -7,7 +7,7 @@
 * @author ZhuBaoMin
 * @date 2024-05-22 16:56
 * @LastEditTime 2024-05-22 16:56
 * @Description
 * @Description 设置命令子类-设置设备终端地址
 */
@Data
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/DtoBase.java
File was renamed from pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/rtu/dto/DtoBase.java
@@ -1,4 +1,4 @@
package com.dy.pipIrrRemote.rtu.dto;
package com.dy.pipIrrRemote.common.dto;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -7,7 +7,7 @@
 * @author ZhuBaoMin
 * @date 2024-05-22 16:54
 * @LastEditTime 2024-05-22 16:54
 * @Description
 * @Description 设置命令基类
 */
@Data
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/ValveClose.java
New file
@@ -0,0 +1,46 @@
package com.dy.pipIrrRemote.common.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
 * @author ZhuBaoMin
 * @date 2024-05-24 17:25
 * @LastEditTime 2024-05-24 17:25
 * @Description 设置命令子类-远程关阀传输对象
 */
@Data
public class ValveClose {
    public static final long serialVersionUID = 202405241727001L;
    /**
     * 阀控器地址
     */
    @NotBlank(message = "阀控器地址不能为空")
    private String rtuAddr;
    /**
     * 虚拟卡编号
     */
    @NotBlank(message = "虚拟卡编号不能为空")
    private String vcNum;
    /**
     * 开阀时生成的订单号
     */
    @NotBlank(message = "订单号不能为空")
    private String orderNo;
    /**
     * 用户类型 1-平台,2-APP
     */
    @NotNull(message = "操作类型不能为空")
    private Integer userType;
    /**
     * 操作人
     */
    @NotNull(message = "操作人不能为空")
    private Long operator;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/common/dto/ValveOpen.java
New file
@@ -0,0 +1,27 @@
package com.dy.pipIrrRemote.common.dto;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
/**
 * @author ZhuBaoMin
 * @date 2024-05-23 15:30
 * @LastEditTime 2024-05-23 15:30
 * @Description 设置命令子类-远程开阀传输对象
 */
@Data
public class ValveOpen extends DtoBase{
    public static final long serialVersionUID = 202405231531001L;
    /**
     * 虚拟卡ID
     */
    private Long vcId;
    /**
     * 用户类型 1-平台,2-APP
     */
    @NotNull(message = "操作类型不能为空")
    private Integer userType;
}
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/result/RemoteResultCode.java
@@ -13,11 +13,10 @@
@AllArgsConstructor
public enum RemoteResultCode {
    /**
     * 远程操作
     * Valve
     */
    DIVIDE_FAIL(10001, "分水房添加失败"),
    DELETE_DIVIDE_FAIL(10001, "分水房删除失败"),
    NO_DIVIDES(10001, "无符合条件的分水房记录"),
    GET_RESULT_IN_ONE_MINUTE(10001,"1分钟后去查看结果"),
    GET_RESULT_ERROR(10002, "获取结果异常"),
    /**
     * RTU
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/rtu/RtuCtrl.java
@@ -1,7 +1,10 @@
package com.dy.pipIrrRemote.rtu;
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.Data;
import com.dy.common.mw.protocol.p206V202404.CodeV202404;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCd10Vo;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCdXyVo;
@@ -10,21 +13,22 @@
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import com.dy.pipIrrRemote.common.ComSupport;
import com.dy.pipIrrRemote.common.CommandSv;
import com.dy.pipIrrRemote.common.dto.Addr;
import com.dy.pipIrrRemote.common.dto.DtoBase;
import com.dy.pipIrrRemote.result.RemoteResultCode;
import com.dy.pipIrrRemote.rtu.dto.Addr;
import com.dy.pipIrrRemote.rtu.dto.DtoBase;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
 * @author ZhuBaoMin
@@ -43,6 +47,24 @@
    protected static String controllerType = "57";
    /**
     * 查询所有RTU在线情况
     * @return
     */
    @GetMapping(path = "get_online")
    @SsoAop()
    public BaseResponse<Boolean> get_online() {
        Command com = new Command() ;
        com.id = Command.defaultId;
        com.code = "LCD0001";
        com.type = "innerCommand";
        JSONObject response = (JSONObject)JSON.toJSON(sendCom2Mw(com));
        JSONObject attachment = response.getJSONObject("content").getJSONObject("attachment");
        return BaseResponseUtils.buildSuccess(attachment) ;
    }
    /**
     * 设置设备终端地址
     * @param addr 设置设备终端地址传入对象
     * @param bindingResult
@@ -56,10 +78,10 @@
            return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        String commandCode = CodeV202404.cd_10;
        Long intakeId = addr.getIntakeId();
        String newRtuAddr = addr.getNewRtuAddr();
        Long operator = addr.getOperator();
        String commandCode = CodeV202404.cd_10;
        // 取水口ID换阀控器地址
        String rtuAddr = commandSv.getRtuAddrByIntakeId(intakeId);
@@ -70,18 +92,49 @@
        // 创建视图
        ComCd10Vo param = new ComCd10Vo() ;
        param.controllerType = controllerType;
        param.projectNo = Integer.parseInt(commandCode);
        param.projectNo =projectNo;
        param.rtuNewAddr = newRtuAddr;
        // 创建命令日志对象并添加到数据库中
        RmCommandHistory rmCommandHistory = getComHistory(commandCode, rtuAddr, param, operator);
        String comId = commandSv.insert(rmCommandHistory);
        System.out.println(comId);
        // 构造命令
        Command com = command(comId, commandCode, rtuAddr, param);
        return sendCom2Mw(com);
        sendCom2Mw(com);
        CompletableFuture<Data> featureObject = new CompletableFuture<>();
        features.put(comId, featureObject);
        try {
            CompletableFuture<Data> feature = (CompletableFuture<Data>) features.get(comId);
            Data resultData = feature.get(30, TimeUnit.SECONDS);
            features.remove(comId);
            String commandId = resultData.getCommandId();
            if(commandId.equals(comId)) {
                //futureValue = new CompletableFuture<>();
                return BaseResponseUtils.buildSuccess((JSONObject)JSON.toJSON(resultData.subData));
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            return BaseResponseUtils.buildFail("1分钟后去查看结果");
        }
        //return BaseResponseUtils.buildSuccess(resultData.toJson());
        return BaseResponseUtils.buildSuccess() ;
    }
    /**
     * 清除设备终端用水记录
     * @param po
     * @param bindingResult
     * @return
     */
    @PostMapping(path = "clear_usage_record", consumes = MediaType.APPLICATION_JSON_VALUE)
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
@@ -103,7 +156,7 @@
        // 创建视图
        ComCdXyVo param = new ComCdXyVo();
        param.controllerType = controllerType;
        param.projectNo = Integer.parseInt(commandCode);
        param.projectNo = projectNo;
        // 创建命令日志对象并添加到数据库中
        RmCommandHistory rmCommandHistory = getComHistory(commandCode, rtuAddr, param, operator);
pipIrr-platform/pipIrr-web/pipIrr-web-remote/src/main/java/com/dy/pipIrrRemote/valve/ValveCtrl.java
@@ -1,18 +1,27 @@
package com.dy.pipIrrRemote.valve;
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.Data;
import com.dy.common.mw.protocol.p206V202404.CodeV202404;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCd92_A2Vo;
import com.dy.common.mw.protocol.p206V202404.downVos.ComCd93_A3Vo;
import com.dy.common.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.common.webUtil.ResultCodeMsg;
import com.dy.pipIrrGlobal.daoPr.PrWaterPriceMapper;
import com.dy.pipIrrGlobal.daoRm.RmCommandHistoryMapper;
import com.dy.pipIrrGlobal.daoSe.SeVirtualCardMapper;
import com.dy.pipIrrGlobal.pojoRm.RmCommandHistory;
import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
import com.dy.pipIrrGlobal.voRm.VoUnclosedValve;
import com.dy.pipIrrGlobal.voSe.VoVirtualCard;
import com.dy.pipIrrRemote.common.ComSupport;
import com.dy.pipIrrRemote.common.CommandSv;
import com.dy.pipIrrRemote.common.dto.ValveClose;
import com.dy.pipIrrRemote.common.dto.ValveOpen;
import com.dy.pipIrrRemote.result.RemoteResultCode;
import com.dy.pipIrrRemote.utils.RestTemplateUtils;
import com.dy.pipIrrRemote.valve.dto.DTOValve;
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 com.dy.pipIrrSell.virtualCard.enums.LastOperateENUM;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
@@ -22,13 +31,12 @@
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.Random;
/**
 * @author ZhuBaoMin
@@ -42,67 +50,241 @@
@RestController
@RequestMapping(path="valve")
@RequiredArgsConstructor
public class ValveCtrl {
public class ValveCtrl extends ComSupport {
    private final RestTemplateUtils restTemplateUtils;
    private CompletableFuture<String> futureValue = new CompletableFuture<>();
    private final CommandSv commandSv;
    private final SeVirtualCardMapper seVirtualCardMapper;
    private final PrWaterPriceMapper prWaterPriceMapper;
    private final RmCommandHistoryMapper rmCommandHistoryMapper;
    /**
     * 远程开关阀
     * @param po 开关阀传入对象
     * 远程开阀(平台、APP)
     * @param valve
     * @param bindingResult
     * @return
     */
    @Operation(summary = "远程开关阀", description = "远程开关阀")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "操作结果:true:成功,false:失败(BaseResponse.content)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = Boolean.class))}
            )
    })
    @PostMapping(path = "operate", consumes = MediaType.APPLICATION_JSON_VALUE)
    @PostMapping(path = "open", consumes = MediaType.APPLICATION_JSON_VALUE)
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
    public BaseResponse<Boolean> open(@RequestBody @Valid DTOValve po, BindingResult bindingResult) throws ExecutionException, InterruptedException {
    public BaseResponse<Boolean> open(@RequestBody @Valid ValveOpen valve, BindingResult bindingResult) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyMMddHHmmss");
        if(bindingResult != null && bindingResult.hasErrors()){
            return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        String a = null;
        try {
            a = futureValue.get(10, TimeUnit.SECONDS);
        } catch (TimeoutException e) {
            return BaseResponseUtils.buildFail("1分钟后去查看结果");
        Long intakeId = valve.getIntakeId();
        Long vcId = valve.getVcId();
        Integer userType = valve.getUserType();
        Long operator = valve.getOperator();
        String comId = null;
        // 获取系统参数
        if(!setuped) {
            setUp();
        }
        futureValue = new CompletableFuture<>();
        Map<String, Object> param = new HashMap<>();
        param.put("controllerType", "01");
        param.put("projectNo", 100);
        param.put("rtuNewAddr", "202405061656120001");
        // 虚拟卡ID换虚拟卡对象
        VoVirtualCard vc = seVirtualCardMapper.getVcById(vcId);
        // 获取水价
        Double waterPrice = prWaterPriceMapper.getPrice();
        Map<String, Object> postParams = new HashMap<>();
        postParams.put("id", 2024050616450001L);
        postParams.put("protocol", "p1");
        postParams.put("rtuAddr", "20001");
        postParams.put("type", "outerCommand");
        postParams.put("code", "10");
        postParams.put("noRtMwDealRes", false);
        postParams.put("rtuResultSendWebUrl", "127.0.0.1/remote/");
        postParams.put("param", param);
        // 取水口ID换阀控器地址
        String rtuAddr = commandSv.getRtuAddrByIntakeId(intakeId);
        if(rtuAddr == null || rtuAddr.length() == 0) {
            return BaseResponseUtils.buildError(RemoteResultCode.RTU_ADDR_CANNOT_BE_NULL.getMessage());
        }
        Map<String, String> headerParams = new HashMap<>();
        // 生成订单号
        LocalDateTime dateTime = LocalDateTime.now();
        Random random = new Random();
        String CHARACTERS = "0123456789";
        StringBuilder sb = new StringBuilder(4);
        for (int i = 0; i < 4; i++) {
            int index = random.nextInt(CHARACTERS.length());
            sb.append(CHARACTERS.charAt(index));
        }
        String orderNo = dtf.format(dateTime) + sb.toString();
        JSONObject job_result = restTemplateUtils.post("http://localhost:8070/accMw/com/send", JSON.toJSONString(postParams), headerParams);
        String commandCode = null;
        if(protocolName.equals("p206V202404")) {
            // 获取功能码
            if(userType == 1) {
                // 平台开阀
                commandCode = CodeV202404.cd_92;
            }else {
                // APP开阀
                commandCode = CodeV202404.cd_A2;
            }
        return BaseResponseUtils.buildSuccess(a) ;
            // 创建视图
            ComCd92_A2Vo param = new ComCd92_A2Vo();
            param.controllerType = controllerType;
            param.projectNo = projectNo;
            param.icCardNo = vc.getVcNum();
            param.waterRemain = 0.0;
            param.moneyRemain = vc.getMoney();
            param.waterPrice = waterPrice;
            param.elePrice = 0.0;
            param.orderNo = orderNo;
            // 创建命令日志对象并添加到数据库中
            RmCommandHistory rmCommandHistory = getComHistory(commandCode, rtuAddr, param, operator);
            comId = commandSv.insert(rmCommandHistory);
            // 构造并发送命令
            Command com = command(comId, commandCode, rtuAddr, param);
            sendCom2Mw(com);
        } else {
            // 获取功能码
            if(userType == 1) {
                // 平台开阀
                commandCode = "92";
            }else {
                // APP开阀
                commandCode = "97";
            }
            // 创建视图
            ComCd92_A2Vo param = new ComCd92_A2Vo();
            // 创建命令日志对象并添加到数据库中
            RmCommandHistory rmCommandHistory = getComHistory(commandCode, rtuAddr, param, operator);
            comId = commandSv.insert(rmCommandHistory);
            // 构造并发送命令
            Command com = command(comId, commandCode, rtuAddr, param);
            sendCom2Mw(com);
        }
        // 处理回调
        BaseResponse response = dealWithCallBack(comId);
        if(!response.getCode().equals("0001")) {
            return BaseResponseUtils.buildError(RemoteResultCode.GET_RESULT_ERROR.getMessage());
        }
        // 更改虚拟卡状态:是否使用中、最后操作、最后操作时间
        SeVirtualCard virtualCard = new SeVirtualCard();
        virtualCard.setId(vcId);
        virtualCard.setInUse((byte) 1);
        virtualCard.setLastOperate(LastOperateENUM.OPEN_VALVE.getCode());
        virtualCard.setLastOperateTime(new Date());
        seVirtualCardMapper.updateByPrimaryKeySelective(virtualCard);
        Data myData = (Data)response.getContent();
        return BaseResponseUtils.buildSuccess(myData) ;
    }
    @GetMapping("/setValue")
    public String setValue(String name) {
        futureValue.complete(name);
        return "Value set";
    /**
     * 远程关阀(平台、APP)
     * @param valve
     * @param bindingResult
     * @return
     */
    @PostMapping(path = "close", consumes = MediaType.APPLICATION_JSON_VALUE)
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
    public BaseResponse<Boolean> close(@RequestBody @Valid ValveClose valve, BindingResult bindingResult) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyMMddHHmmss");
        if(bindingResult != null && bindingResult.hasErrors()){
            return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        String rtuAddr = valve.getRtuAddr();
        String vcNum = valve.getVcNum();
        String orderNo = valve.getOrderNo();
        Integer userType = valve.getUserType();
        Long operator = valve.getOperator();
        String comId = null;
        // 获取系统参数
        if(!setuped) {
            setUp();
        }
        String commandCode = null;
        if(protocolName.equals("p206V202404")) {
            // 获取功能码
            if (userType == 1) {
                // 平台关阀
                commandCode = CodeV202404.cd_93;
            } else {
                // APP关阀
                commandCode = CodeV202404.cd_A3;
            }
            // 创建视图
            ComCd93_A3Vo param = new ComCd93_A3Vo();
            param.controllerType = controllerType;
            param.projectNo = projectNo;
            param.icCardNo = vcNum;
            param.orderNo = orderNo;
            // 创建命令日志对象并添加到数据库中
            RmCommandHistory rmCommandHistory = getComHistory(commandCode, rtuAddr, param, operator);
            comId = commandSv.insert(rmCommandHistory);
            // 构造并发送命令
            Command com = command(comId, commandCode, rtuAddr, param);
            sendCom2Mw(com);
        } else {
            // 获取功能码
            if (userType == 1) {
                // 平台关阀
                commandCode = "93";
            } else {
                // APP关阀
                commandCode = "98";
            }
            // 创建视图
            ComCd93_A3Vo param = new ComCd93_A3Vo();
            param.controllerType = controllerType;
            param.projectNo = projectNo;
            param.icCardNo = vcNum;
            param.orderNo = orderNo;
            // 创建命令日志对象并添加到数据库中
            RmCommandHistory rmCommandHistory = getComHistory(commandCode, rtuAddr, param, operator);
            comId = commandSv.insert(rmCommandHistory);
            // 构造并发送命令
            Command com = command(comId, commandCode, rtuAddr, param);
            sendCom2Mw(com);
        }
        // 处理回调
        BaseResponse response = dealWithCallBack(comId);
        if(!response.getCode().equals("0001")) {
            return BaseResponseUtils.buildError(RemoteResultCode.GET_RESULT_ERROR.getMessage());
        }
        // 更改虚拟卡状态:是否使用中、最后操作、最后操作时间
        Long vcId = seVirtualCardMapper.getVcIdByNum(vcNum);
        SeVirtualCard virtualCard = new SeVirtualCard();
        virtualCard.setId(vcId);
        virtualCard.setInUse((byte) 0);
        virtualCard.setLastOperate(LastOperateENUM.CLOSE_VALVE.getCode());
        virtualCard.setLastOperateTime(new Date());
        seVirtualCardMapper.updateByPrimaryKeySelective(virtualCard);
        Data myData = (Data)response.getContent();
        return BaseResponseUtils.buildSuccess(myData) ;
    }
    /**
     * 根据操作员ID获取未关阀记录
     * @param operator
     * @return
     */
    @GetMapping(path = "/get")
    @SsoAop()
    public BaseResponse<List<VoUnclosedValve>> getUnclosedValves(@RequestParam Long operator){
        try {
            List<VoUnclosedValve> res = rmCommandHistoryMapper.getUnclosedValves(operator);
            return BaseResponseUtils.buildSuccess(res);
        } catch (Exception e) {
            log.error("获取未关阀记录异常", e);
            return BaseResponseUtils.buildException(e.getMessage()) ;
        }
    }
}
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/virtualCard/VirtualCardCtrl.java
@@ -1,52 +1,17 @@
package com.dy.pipIrrSell.virtualCard;
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.webUtil.BaseResponse;
import com.dy.common.webUtil.BaseResponseUtils;
import com.dy.common.webUtil.ResultCodeMsg;
import com.dy.pipIrrGlobal.pojoSe.SeVcRefund;
import com.dy.pipIrrGlobal.pojoSe.SeVcRefundItem;
import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
import com.dy.pipIrrSell.result.SellResultCode;
import com.dy.pipIrrGlobal.voSe.VoVirtualCard;
import com.dy.pipIrrSell.util.PayHelper;
import com.dy.pipIrrSell.virtualCard.dto.DtoAudit;
import com.dy.pipIrrSell.virtualCard.dto.DtoRefund;
import com.dy.pipIrrSell.virtualCard.dto.DtoRegist;
import com.dy.pipIrrSell.virtualCard.enums.LastOperateENUM;
import com.dy.pipIrrSell.virtualCard.enums.RefundItemStateENUM;
import com.dy.pipIrrSell.virtualCard.enums.RefundStateENUM;
import com.dy.pipIrrSell.wechatpay.dto.Refund;
import com.dy.pipIrrSell.wechatpay.dto.ToRefund;
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 io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import javax.crypto.NoSuchPaddingException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * @author ZhuBaoMin
@@ -66,51 +31,81 @@
    private final PayHelper payHelper;
    /**
     * 获取全部虚拟卡
     * @return
     */
    @GetMapping(path = "/get")
    @SsoAop()
    public BaseResponse<List<VoVirtualCard>> getVCs(){
        try {
            List<VoVirtualCard> res = virtualCardSv.getVCs();
            return BaseResponseUtils.buildSuccess(res);
        } catch (Exception e) {
            log.error("获取支付方式记录异常", e);
            return BaseResponseUtils.buildException(e.getMessage()) ;
        }
    }
    /**
     * 根据虚拟卡ID获取虚拟卡对象
     * @param vcId
     * @return
     */
    @GetMapping(path = "/getVcById")
    @SsoAop()
    public BaseResponse<VoVirtualCard> getVcById(@RequestParam Long vcId){
        try {
            return BaseResponseUtils.buildSuccess(virtualCardSv.getVcById(vcId));
        } catch (Exception e) {
            log.error("获取支付方式记录异常", e);
            return BaseResponseUtils.buildException(e.getMessage()) ;
        }
    }
    /**
     * 虚拟卡账号注册
     * @param po
     * @param bindingResult
     * @return
     */
    @Operation(summary = "注册虚拟卡", description = "注册虚拟卡")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "操作结果:true:成功,false:失败(BaseResponse.content)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = Boolean.class))}
            )
    })
    @PostMapping(path = "add_vc")
    @SsoAop()
    //public BaseResponse<Boolean> addVC(@RequestParam("clientId") @NotNull(message = "农户编号不能为空") Long clientId){
    public BaseResponse<Boolean> addVC(@RequestBody @Valid DtoRegist po, BindingResult bindingResult){
        if(bindingResult != null && bindingResult.hasErrors()){
            return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        Long clientId = po.getClientId();
        String vcName = po.getVcName();
        // 名称验重
        Integer rc = virtualCardSv.getRecordCountByName(po);
        if(rc != null && rc > 0) {
            return BaseResponseUtils.buildFail(SellResultCode.CARD_NAME_ESIST.getMessage());
        }
        SeVirtualCard seVirtualCard = new SeVirtualCard();
        seVirtualCard.setVcName(vcName);
        seVirtualCard.setClientId(clientId);
        seVirtualCard.setMoney(0d);
        seVirtualCard.setLastOperate(LastOperateENUM.OPEN_ACCOUNT.getCode());
        seVirtualCard.setLastOperateTime(new Date());
        seVirtualCard.setInUse((byte) 0);
        seVirtualCard.setCreateTime(new Date());
        Long rec = virtualCardSv.insertVirtualCard(seVirtualCard);
        if(rec == null) {
            return BaseResponseUtils.buildFail(SellResultCode.WALLET_OPEN_ACCOUNT_FAIL.getMessage());
        }
        return BaseResponseUtils.buildSuccess(true) ;
    }
    //@Operation(summary = "注册虚拟卡", description = "注册虚拟卡")
    //@ApiResponses(value = {
    //        @ApiResponse(
    //                responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
    //                description = "操作结果:true:成功,false:失败(BaseResponse.content)",
    //                content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
    //                        schema = @Schema(implementation = Boolean.class))}
    //        )
    //})
    //@PostMapping(path = "add_vc")
    //@SsoAop()
    //public BaseResponse<Boolean> addVC(@RequestBody @Valid DtoRegist po, BindingResult bindingResult){
    //    if(bindingResult != null && bindingResult.hasErrors()){
    //        return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    //    }
    //    Long clientId = po.getClientId();
    //    String vcName = po.getVcName();
    //
    //    // 名称验重
    //    Integer rc = virtualCardSv.getRecordCountByName(po);
    //    if(rc != null && rc > 0) {
    //        return BaseResponseUtils.buildFail(SellResultCode.CARD_NAME_ESIST.getMessage());
    //    }
    //
    //    SeVirtualCard seVirtualCard = new SeVirtualCard();
    //    seVirtualCard.setVcName(vcName);
    //    seVirtualCard.setClientId(clientId);
    //    seVirtualCard.setMoney(0d);
    //    seVirtualCard.setLastOperate(LastOperateENUM.OPEN_ACCOUNT.getCode());
    //    seVirtualCard.setLastOperateTime(new Date());
    //    seVirtualCard.setInUse((byte) 0);
    //    seVirtualCard.setCreateTime(new Date());
    //    Long rec = virtualCardSv.insertVirtualCard(seVirtualCard);
    //    if(rec == null) {
    //        return BaseResponseUtils.buildFail(SellResultCode.WALLET_OPEN_ACCOUNT_FAIL.getMessage());
    //    }
    //    return BaseResponseUtils.buildSuccess(true) ;
    //}
    /**
     * 用户申请退款
@@ -118,57 +113,57 @@
     * @param bindingResult
     * @return
     */
    @Operation(summary = "虚拟卡申请退款", description = "虚拟卡申请退款")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "操作结果:true:成功,false:失败(BaseResponse.content)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = Boolean.class))}
            )
    })
    @PostMapping(path = "add_refund", consumes = MediaType.APPLICATION_JSON_VALUE)
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
    public BaseResponse<Boolean> addRefund(@RequestBody @Valid DtoRefund po, BindingResult bindingResult){
        if(bindingResult != null && bindingResult.hasErrors()){
            return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        Long virtualId = po.getVirtualId();
        Integer refundAmount = po.getRefundAmount();
        // 根据虚拟卡ID获取虚拟卡对象
        SeVirtualCard seVirtualCard = virtualCardSv.selectVirtuCardById(virtualId);
        if(seVirtualCard == null) {
            return BaseResponseUtils.buildFail(SellResultCode.VIRTUAL_CARD_NOT_EXIST.getMessage());
        }
        Long clientId = seVirtualCard.getClientId();
        Double money = seVirtualCard.getMoney();
        // 验证退款金额是否大于余额
        if(refundAmount > money) {
            return BaseResponseUtils.buildFail(SellResultCode.REFUND_AMOUNT_CANNOT_GREATER_THAN_MONEY.getMessage());
        }
        // 计算消费后余额
        Double afterRefund = money - refundAmount;
        SeVcRefund seVcRefund = new SeVcRefund();
        seVcRefund.setVcId(virtualId);
        seVcRefund.setClientId(clientId);
        seVcRefund.setMoney(money);
        seVcRefund.setRefundAmount(refundAmount);
        seVcRefund.setAfterRefund(afterRefund);
        seVcRefund.setApplicationTime(new Date());
        seVcRefund.setRefundStatus(RefundStateENUM.TO_AUDIT.getCode());
        Long rec = virtualCardSv.addRefund(seVcRefund);
        if(rec == 0) {
            return BaseResponseUtils.buildFail(SellResultCode.APPLICATION_REFUND_FAIL.getMessage());
        }
        return BaseResponseUtils.buildSuccess(true) ;
    }
    //@Operation(summary = "虚拟卡申请退款", description = "虚拟卡申请退款")
    //@ApiResponses(value = {
    //        @ApiResponse(
    //                responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
    //                description = "操作结果:true:成功,false:失败(BaseResponse.content)",
    //                content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
    //                        schema = @Schema(implementation = Boolean.class))}
    //        )
    //})
    //@PostMapping(path = "add_refund", consumes = MediaType.APPLICATION_JSON_VALUE)
    //@Transactional(rollbackFor = Exception.class)
    //@SsoAop()
    //public BaseResponse<Boolean> addRefund(@RequestBody @Valid DtoRefund po, BindingResult bindingResult){
    //    if(bindingResult != null && bindingResult.hasErrors()){
    //        return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    //    }
    //
    //    Long virtualId = po.getVirtualId();
    //    Integer refundAmount = po.getRefundAmount();
    //
    //    // 根据虚拟卡ID获取虚拟卡对象
    //    SeVirtualCard seVirtualCard = virtualCardSv.selectVirtuCardById(virtualId);
    //    if(seVirtualCard == null) {
    //        return BaseResponseUtils.buildFail(SellResultCode.VIRTUAL_CARD_NOT_EXIST.getMessage());
    //    }
    //    Long clientId = seVirtualCard.getClientId();
    //    Double money = seVirtualCard.getMoney();
    //
    //    // 验证退款金额是否大于余额
    //    if(refundAmount > money) {
    //        return BaseResponseUtils.buildFail(SellResultCode.REFUND_AMOUNT_CANNOT_GREATER_THAN_MONEY.getMessage());
    //    }
    //
    //    // 计算消费后余额
    //    Double afterRefund = money - refundAmount;
    //
    //    SeVcRefund seVcRefund = new SeVcRefund();
    //    seVcRefund.setVcId(virtualId);
    //    seVcRefund.setClientId(clientId);
    //    seVcRefund.setMoney(money);
    //    seVcRefund.setRefundAmount(refundAmount);
    //    seVcRefund.setAfterRefund(afterRefund);
    //    seVcRefund.setApplicationTime(new Date());
    //    seVcRefund.setRefundStatus(RefundStateENUM.TO_AUDIT.getCode());
    //
    //    Long rec = virtualCardSv.addRefund(seVcRefund);
    //    if(rec == 0) {
    //        return BaseResponseUtils.buildFail(SellResultCode.APPLICATION_REFUND_FAIL.getMessage());
    //    }
    //    return BaseResponseUtils.buildSuccess(true) ;
    //}
    /**
     * 审核退款申请
@@ -176,68 +171,68 @@
     * @param bindingResult
     * @return
     */
    @Operation(summary = "审核退款申请", description = "审核退款申请")
    @ApiResponses(value = {
            @ApiResponse(
                    responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
                    description = "操作结果:true:成功,false:失败(BaseResponse.content)",
                    content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
                            schema = @Schema(implementation = Boolean.class))}
            )
    })
    @PostMapping(path = "audit_refund", consumes = MediaType.APPLICATION_JSON_VALUE)
    @Transactional(rollbackFor = Exception.class)
    @SsoAop()
    public BaseResponse<Boolean> auditRefund(@RequestBody @Valid DtoAudit po, BindingResult bindingResult) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException {
        if(bindingResult != null && bindingResult.hasErrors()){
            return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        // 根据退款ID获取退款对象,并更新审核人、审核时间、审核备注、退款状态字段
        SeVcRefund seVcRefund = virtualCardSv.selectRefundByRefundId(po.getRefundId());
        Long virtualId = seVcRefund.getVcId();
        Integer refundAmount = seVcRefund.getRefundAmount();
        seVcRefund.setAuditor(po.getAuditor());
        seVcRefund.setAuditTime(new Date());
        seVcRefund.setRemarks(po.getRemarks());
        seVcRefund.setRefundStatus(RefundStateENUM.TO_REFUND.getCode());
        Integer rec = virtualCardSv.updateRefund(seVcRefund);
        if(rec == 0) {
            return BaseResponseUtils.buildFail(SellResultCode.AUDIT_REFUND_FAIL.getMessage());
        }
        // 完成审核后获取待退款订单列表
        List<ToRefund> list_ToRefund = payHelper.getToRefunds(virtualId, refundAmount);
        if(list_ToRefund == null || list_ToRefund.size() <=0)
            return BaseResponseUtils.buildFail(SellResultCode.NOT_SUFFICIENT_FUNDS.getMessage());
        //遍历待退款列表
        JSONArray array_ToRefund = (JSONArray) JSON.toJSON(list_ToRefund);
        for(int i = 0; i < array_ToRefund.size(); i++) {
            JSONObject job_ToRefund = array_ToRefund.getJSONObject(i);
            String orderNumber_ToRefund = job_ToRefund.getString("orderNumber");
            Integer refundAmount_ToRefund = job_ToRefund.getInteger("refundAmount");
            // 生成退款分项记录
            SeVcRefundItem seVcRefundItem = new SeVcRefundItem();
            seVcRefundItem.setRefundId(po.getRefundId());
            seVcRefundItem.setOrderNumber(orderNumber_ToRefund);
            String refundNumber = virtualCardSv.generateRefundNumber(orderNumber_ToRefund);
            seVcRefundItem.setRefundNumber(refundNumber);
            seVcRefundItem.setRefundAmount(refundAmount_ToRefund);
            seVcRefundItem.setCreateTime(new Date());
            seVcRefundItem.setRefundStatus(RefundItemStateENUM.NO_REFUND.getCode());
            Long refundItemId = virtualCardSv.addRefundItem(seVcRefundItem);
            // 调用微信退款申请接口
            Refund refund = new Refund();
            refund.setTradeNo(orderNumber_ToRefund);
            refund.setRefundNo(refundNumber);
            refund.setRefund(refundAmount_ToRefund);
            BaseResponse rep = payHelper.refunds(refund);
        }
        return BaseResponseUtils.buildSuccess(true) ;
    }
    //@Operation(summary = "审核退款申请", description = "审核退款申请")
    //@ApiResponses(value = {
    //        @ApiResponse(
    //                responseCode = ResultCodeMsg.RsCode.SUCCESS_CODE,
    //                description = "操作结果:true:成功,false:失败(BaseResponse.content)",
    //                content = {@Content(mediaType = MediaType.APPLICATION_JSON_VALUE,
    //                        schema = @Schema(implementation = Boolean.class))}
    //        )
    //})
    //@PostMapping(path = "audit_refund", consumes = MediaType.APPLICATION_JSON_VALUE)
    //@Transactional(rollbackFor = Exception.class)
    //@SsoAop()
    //public BaseResponse<Boolean> auditRefund(@RequestBody @Valid DtoAudit po, BindingResult bindingResult) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, IOException, SignatureException, InvalidKeyException {
    //    if(bindingResult != null && bindingResult.hasErrors()){
    //        return BaseResponseUtils.buildFail(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
    //    }
    //
    //    // 根据退款ID获取退款对象,并更新审核人、审核时间、审核备注、退款状态字段
    //    SeVcRefund seVcRefund = virtualCardSv.selectRefundByRefundId(po.getRefundId());
    //    Long virtualId = seVcRefund.getVcId();
    //    Integer refundAmount = seVcRefund.getRefundAmount();
    //    seVcRefund.setAuditor(po.getAuditor());
    //    seVcRefund.setAuditTime(new Date());
    //    seVcRefund.setRemarks(po.getRemarks());
    //    seVcRefund.setRefundStatus(RefundStateENUM.TO_REFUND.getCode());
    //    Integer rec = virtualCardSv.updateRefund(seVcRefund);
    //    if(rec == 0) {
    //        return BaseResponseUtils.buildFail(SellResultCode.AUDIT_REFUND_FAIL.getMessage());
    //    }
    //
    //    // 完成审核后获取待退款订单列表
    //    List<ToRefund> list_ToRefund = payHelper.getToRefunds(virtualId, refundAmount);
    //    if(list_ToRefund == null || list_ToRefund.size() <=0)
    //        return BaseResponseUtils.buildFail(SellResultCode.NOT_SUFFICIENT_FUNDS.getMessage());
    //
    //    //遍历待退款列表
    //    JSONArray array_ToRefund = (JSONArray) JSON.toJSON(list_ToRefund);
    //    for(int i = 0; i < array_ToRefund.size(); i++) {
    //        JSONObject job_ToRefund = array_ToRefund.getJSONObject(i);
    //        String orderNumber_ToRefund = job_ToRefund.getString("orderNumber");
    //        Integer refundAmount_ToRefund = job_ToRefund.getInteger("refundAmount");
    //
    //        // 生成退款分项记录
    //        SeVcRefundItem seVcRefundItem = new SeVcRefundItem();
    //        seVcRefundItem.setRefundId(po.getRefundId());
    //        seVcRefundItem.setOrderNumber(orderNumber_ToRefund);
    //        String refundNumber = virtualCardSv.generateRefundNumber(orderNumber_ToRefund);
    //        seVcRefundItem.setRefundNumber(refundNumber);
    //        seVcRefundItem.setRefundAmount(refundAmount_ToRefund);
    //        seVcRefundItem.setCreateTime(new Date());
    //        seVcRefundItem.setRefundStatus(RefundItemStateENUM.NO_REFUND.getCode());
    //        Long refundItemId = virtualCardSv.addRefundItem(seVcRefundItem);
    //
    //        // 调用微信退款申请接口
    //        Refund refund = new Refund();
    //        refund.setTradeNo(orderNumber_ToRefund);
    //        refund.setRefundNo(refundNumber);
    //        refund.setRefund(refundAmount_ToRefund);
    //        BaseResponse rep = payHelper.refunds(refund);
    //    }
    //
    //    return BaseResponseUtils.buildSuccess(true) ;
    //}
}
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/virtualCard/VirtualCardSv.java
@@ -11,6 +11,7 @@
import com.dy.pipIrrGlobal.pojoSe.SeVcRefundItem;
import com.dy.pipIrrGlobal.pojoSe.SeVirtualCard;
import com.dy.pipIrrGlobal.voSe.VoOrders;
import com.dy.pipIrrGlobal.voSe.VoVirtualCard;
import com.dy.pipIrrSell.result.SellResultCode;
import com.dy.pipIrrSell.virtualCard.dto.DtoRegist;
import com.dy.pipIrrSell.virtualCard.dto.DtoVirtualCard;
@@ -46,6 +47,24 @@
    @Autowired
    private SeVcRefundItemMapper seVcRefundItemMapper;
    /**
     * 获取全部虚拟卡
     * @return
     */
    public List<VoVirtualCard> getVCs() {
        return seVirtualCardMapper.getVCs();
    }
    /**
     * 根据虚拟卡ID获取虚拟卡对象
     * @param vcId
     * @return
     */
    public VoVirtualCard getVcById(Long vcId) {
        return seVirtualCardMapper.getVcById(vcId);
    }
    /**
     * 注册虚拟卡
     * @param po
pipIrr-platform/pipIrr-web/pipIrr-web-sell/src/main/java/com/dy/pipIrrSell/virtualCard/enums/LastOperateENUM.java
@@ -18,7 +18,9 @@
    CONSUME((byte)3, "消费"),
    APPLY_REFUND((byte)4, "申请退款"),
    AUDIT_REFUND((byte)5, "退款审核"),
    REFUND((byte)6, "退款");
    REFUND((byte)6, "退款"),
    OPEN_VALVE((byte)7, "开阀"),
    CLOSE_VALVE((byte)8, "关阀");
    private final Byte code;
    private final String message;