feat(card): 添加管理类型卡写卡功能并优化卡片相关逻辑- 在 OperateTypeENUM 中添加 SUPPLEMENT 和 MANAGEMENT_CARD_WRITE 枚举值
- 在 SeManagementCard 中添加 cancelTime 和 state 字段
- 更新相关 mapper 和 XML 文件以支持新增字段
- 修改 CardSv 中的回调处理逻辑,支持管理类型卡写卡
- 优化 CreateManagementCardDto 中识别码的示例值
|  |  |  | 
|---|
|  |  |  | import com.alibaba.fastjson2.annotation.JSONField; | 
|---|
|  |  |  | import com.alibaba.fastjson2.writer.ObjectWriterImplToString; | 
|---|
|  |  |  | import com.baomidou.mybatisplus.annotation.IdType; | 
|---|
|  |  |  | import com.baomidou.mybatisplus.annotation.TableField; | 
|---|
|  |  |  | import com.baomidou.mybatisplus.annotation.TableId; | 
|---|
|  |  |  | import com.baomidou.mybatisplus.annotation.TableName; | 
|---|
|  |  |  | import com.dy.common.po.BaseEntity; | 
|---|
|  |  |  | 
|---|
|  |  |  | * 注销时间 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") | 
|---|
|  |  |  | private Date cancelDt; | 
|---|
|  |  |  | @TableField("cancel_time") | 
|---|
|  |  |  | private Date cancelTime; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 卡片状态;1-正常,2-已注销,3-已挂失,4-未写卡 | 
|---|
|  |  |  | 
|---|
|  |  |  | <result column="domain" jdbcType="VARCHAR" property="domain" /> | 
|---|
|  |  |  | <result column="open_clost_time" jdbcType="INTEGER" property="openClostTime" /> | 
|---|
|  |  |  | <result column="remarks" jdbcType="VARCHAR" property="remarks" /> | 
|---|
|  |  |  | <result column="cancel_time" jdbcType="TIMESTAMP" property="cancelTime" /> | 
|---|
|  |  |  | <result column="state" jdbcType="TINYINT" property="state" /> | 
|---|
|  |  |  | </resultMap> | 
|---|
|  |  |  | <sql id="Base_Column_List"> | 
|---|
|  |  |  | <!--@mbg.generated--> | 
|---|
|  |  |  | id, protocol, card_addr, security_code, card_type, create_time, order_no, district_code, | 
|---|
|  |  |  | project_no, ip, `domain`, open_clost_time, remarks | 
|---|
|  |  |  | project_no, ip, `domain`, open_clost_time, remarks, cancel_time, state | 
|---|
|  |  |  | </sql> | 
|---|
|  |  |  | <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap"> | 
|---|
|  |  |  | <!--@mbg.generated--> | 
|---|
|  |  |  | 
|---|
|  |  |  | security_code, card_type, create_time, | 
|---|
|  |  |  | order_no, district_code, project_no, | 
|---|
|  |  |  | ip, `domain`, open_clost_time, | 
|---|
|  |  |  | remarks) | 
|---|
|  |  |  | remarks, cancel_time, state) | 
|---|
|  |  |  | values (#{id,jdbcType=BIGINT}, #{protocol,jdbcType=VARCHAR}, #{cardAddr,jdbcType=VARCHAR}, | 
|---|
|  |  |  | #{securityCode,jdbcType=VARCHAR}, #{cardType,jdbcType=TINYINT}, #{createTime,jdbcType=TIMESTAMP}, | 
|---|
|  |  |  | #{orderNo,jdbcType=VARCHAR}, #{districtCode,jdbcType=VARCHAR}, #{projectNo,jdbcType=INTEGER}, | 
|---|
|  |  |  | #{ip,jdbcType=VARCHAR}, #{domain,jdbcType=VARCHAR}, #{openClostTime,jdbcType=INTEGER}, | 
|---|
|  |  |  | #{remarks,jdbcType=VARCHAR}) | 
|---|
|  |  |  | #{remarks,jdbcType=VARCHAR}, #{cancelTime,jdbcType=TIMESTAMP}, #{state,jdbcType=TINYINT}) | 
|---|
|  |  |  | </insert> | 
|---|
|  |  |  | <insert id="insertSelective" parameterType="com.dy.pipIrrGlobal.pojoSe.SeManagementCard"> | 
|---|
|  |  |  | <!--@mbg.generated--> | 
|---|
|  |  |  | 
|---|
|  |  |  | <if test="remarks != null"> | 
|---|
|  |  |  | remarks, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | <if test="cancelTime != null"> | 
|---|
|  |  |  | cancel_time, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | <if test="state != null"> | 
|---|
|  |  |  | state, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | </trim> | 
|---|
|  |  |  | <trim prefix="values (" suffix=")" suffixOverrides=","> | 
|---|
|  |  |  | <if test="id != null"> | 
|---|
|  |  |  | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | <if test="remarks != null"> | 
|---|
|  |  |  | #{remarks,jdbcType=VARCHAR}, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | <if test="cancelTime != null"> | 
|---|
|  |  |  | #{cancelTime,jdbcType=TIMESTAMP}, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | <if test="state != null"> | 
|---|
|  |  |  | #{state,jdbcType=TINYINT}, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | </trim> | 
|---|
|  |  |  | </insert> | 
|---|
|  |  |  | 
|---|
|  |  |  | <if test="remarks != null"> | 
|---|
|  |  |  | remarks = #{remarks,jdbcType=VARCHAR}, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | <if test="cancelTime != null"> | 
|---|
|  |  |  | cancel_time = #{cancelTime,jdbcType=TIMESTAMP}, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | <if test="state != null"> | 
|---|
|  |  |  | state = #{state,jdbcType=TINYINT}, | 
|---|
|  |  |  | </if> | 
|---|
|  |  |  | </set> | 
|---|
|  |  |  | where id = #{id,jdbcType=BIGINT} | 
|---|
|  |  |  | </update> | 
|---|
|  |  |  | 
|---|
|  |  |  | ip = #{ip,jdbcType=VARCHAR}, | 
|---|
|  |  |  | `domain` = #{domain,jdbcType=VARCHAR}, | 
|---|
|  |  |  | open_clost_time = #{openClostTime,jdbcType=INTEGER}, | 
|---|
|  |  |  | remarks = #{remarks,jdbcType=VARCHAR} | 
|---|
|  |  |  | remarks = #{remarks,jdbcType=VARCHAR}, | 
|---|
|  |  |  | cancel_time = #{cancelTime,jdbcType=TIMESTAMP}, | 
|---|
|  |  |  | state = #{state,jdbcType=TINYINT} | 
|---|
|  |  |  | where id = #{id,jdbcType=BIGINT} | 
|---|
|  |  |  | </update> | 
|---|
|  |  |  | </mapper> | 
|---|
|  |  |  | 
|---|
|  |  |  | seCardOperate.setClientId(clientId); | 
|---|
|  |  |  | seCardOperate.setMoney(po.getBalance()); | 
|---|
|  |  |  | seCardOperate.setRefundAmount(po.getSupplementMoney()); | 
|---|
|  |  |  | seCardOperate.setOperateType(OperateTypeENUM.WRITE_BACK.getCode()); | 
|---|
|  |  |  | seCardOperate.setOperateType(OperateTypeENUM.SUPPLEMENT.getCode()); | 
|---|
|  |  |  | seCardOperate.setRemarks(po.getRemarks()); | 
|---|
|  |  |  | seCardOperate.setOperator(po.getOperator()); | 
|---|
|  |  |  | seCardOperate.setOperateDt(operateTime); | 
|---|
|  |  |  | 
|---|
|  |  |  | Integer operateType = po.getOperateType(); | 
|---|
|  |  |  | String orderNumber = po.getOrderNumber(); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 先检查是否为管理卡 | 
|---|
|  |  |  | if (operateType.equals(OperateTypeENUM.MANAGEMENT_CARD_WRITE.getCode().intValue())) { | 
|---|
|  |  |  | // 管理类型卡写卡逻辑 | 
|---|
|  |  |  | return handleManagementCardWrite(cardAddr, orderNumber); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 处理农户卡逻辑 | 
|---|
|  |  |  | Long cardId = seClientCardMapper.getCardIdByAddr(cardAddr); | 
|---|
|  |  |  | if (cardId == null || cardId.equals(0)) { | 
|---|
|  |  |  | map.put("msg", "您指定的水卡不存在"); | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (operateType == 1) { | 
|---|
|  |  |  | if (operateType.equals(OperateTypeENUM.ACTIVE.getCode().intValue())) { | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 开卡操作执行通知 | 
|---|
|  |  |  | * 1.依据订单号将无效状态的操作记录改为有效 | 
|---|
|  |  |  | 
|---|
|  |  |  | turnRechargeHistoryValidByOrderNumber(orderNumber); | 
|---|
|  |  |  | updateCard(cardId, orderNumber + "p"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else if (operateType == 2) { | 
|---|
|  |  |  | } else if (operateType.equals(OperateTypeENUM.RECHARGE.getCode().intValue())) { | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 充值操作执行通知 | 
|---|
|  |  |  | * 1. 操作记录改为有效 | 
|---|
|  |  |  | 
|---|
|  |  |  | turnOperateValidByOrderNumber(orderNumber + "p"); | 
|---|
|  |  |  | turnRechargeHistoryValidByOrderNumber(orderNumber); | 
|---|
|  |  |  | updateCard(cardId, orderNumber + "p"); | 
|---|
|  |  |  | } else if (operateType == 3) { | 
|---|
|  |  |  | } else if (operateType.equals(OperateTypeENUM.CANCEL.getCode().intValue())) { | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 销卡操作执行通知 | 
|---|
|  |  |  | * 1. 操作记录改为有效 | 
|---|
|  |  |  | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | } else if (operateType == 4) { | 
|---|
|  |  |  | } else if (operateType.equals(OperateTypeENUM.REISSUE.getCode().intValue())) { | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 补卡操作执行通知 | 
|---|
|  |  |  | * 1. 新水卡记录改为有效 | 
|---|
|  |  |  | 
|---|
|  |  |  | map.put("msg", "补卡回调失败"); | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else if (operateType == 5) { | 
|---|
|  |  |  | } else if (operateType.equals(OperateTypeENUM.REFUND.getCode().intValue())) { | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 补扣操作执行通知 | 
|---|
|  |  |  | * 1. 操作记录改为有效 | 
|---|
|  |  |  | 
|---|
|  |  |  | map.put("msg", "补扣回调失败"); | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } else if (operateType == 6) { | 
|---|
|  |  |  | } else if (operateType.equals(OperateTypeENUM.SUPPLEMENT.getCode().intValue())) { | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 返还操作执行通知 | 
|---|
|  |  |  | * 1. 操作记录改为有效 | 
|---|
|  |  |  | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 处理管理类型卡写卡回调 | 
|---|
|  |  |  | * | 
|---|
|  |  |  | * @param cardAddr    卡地址 | 
|---|
|  |  |  | * @param orderNumber 订单号 | 
|---|
|  |  |  | * @return 处理结果 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | private Map<String, Object> handleManagementCardWrite(String cardAddr, String orderNumber) { | 
|---|
|  |  |  | Map<String, Object> map = new HashMap<>(); | 
|---|
|  |  |  | map.put("success", false); | 
|---|
|  |  |  | map.put("content", null); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | try { | 
|---|
|  |  |  | // 根据卡地址和订单号查找管理卡 | 
|---|
|  |  |  | SeManagementCard managementCard = seManagementCardMapper.selectOne( | 
|---|
|  |  |  | com.baomidou.mybatisplus.core.toolkit.Wrappers.<SeManagementCard>lambdaQuery() | 
|---|
|  |  |  | .eq(SeManagementCard::getCardAddr, cardAddr) | 
|---|
|  |  |  | .eq(SeManagementCard::getOrderNo, orderNumber)); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | if (managementCard == null) { | 
|---|
|  |  |  | map.put("msg", "未找到对应的管理卡记录"); | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 更新管理卡状态为正常 | 
|---|
|  |  |  | managementCard.setState(ManagementCardStateENUM.NORMAL.getCode()); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | int updateResult = seManagementCardMapper.updateByPrimaryKeySelective(managementCard); | 
|---|
|  |  |  | if (updateResult > 0) { | 
|---|
|  |  |  | map.put("success", true); | 
|---|
|  |  |  | map.put("msg", "管理卡写卡完成,状态已更新为正常"); | 
|---|
|  |  |  | } else { | 
|---|
|  |  |  | map.put("msg", "管理卡状态更新失败"); | 
|---|
|  |  |  | } | 
|---|
|  |  |  | } catch (Exception e) { | 
|---|
|  |  |  | log.error("处理管理卡写卡回调异常", e); | 
|---|
|  |  |  | map.put("msg", "处理管理卡写卡回调时发生异常:" + e.getMessage()); | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | return map; | 
|---|
|  |  |  | } | 
|---|
|  |  |  |  | 
|---|
|  |  |  | // 根据订单号将操作记录改为有效 | 
|---|
|  |  |  | public Integer turnOperateValidByOrderNumber(String orderNumber) { | 
|---|
|  |  |  | return seCardOperateMapper.turnOperateValidByOrderNumber(orderNumber); | 
|---|
|  |  |  | 
|---|
|  |  |  | * 识别码 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @NotBlank(message = "识别码不能为空") | 
|---|
|  |  |  | @Schema(description = "识别码", example = "123456") | 
|---|
|  |  |  | @Schema(description = "识别码", example = "A0B1C289") | 
|---|
|  |  |  | private String securityCode; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | 
|---|
|  |  |  | @NotNull(message = "卡片类型不能为空") | 
|---|
|  |  |  | @Schema(description = "卡片类型", example = "2", allowableValues = { "2", "3", "4", "5", "6", "7", "8", "9", "10" }) | 
|---|
|  |  |  | private Byte cardType; | 
|---|
|  |  |  |  | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 5级行政区划编码 | 
|---|
|  |  |  | 
|---|
|  |  |  | private String orderNumber; | 
|---|
|  |  |  |  | 
|---|
|  |  |  | /** | 
|---|
|  |  |  | * 操作类型:1-开卡,2-充值,3-销卡,4-补卡,5-补扣 | 
|---|
|  |  |  | * 操作类型:1-开卡,2-充值,3-销卡,4-补卡,5-补扣,6-返还,7-管理类型卡写卡 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  | @NotNull(message = "操作类型不能为空") | 
|---|
|  |  |  | private Integer operateType; | 
|---|
|  |  |  | 
|---|
|  |  |  | * @author ZhuBaoMin | 
|---|
|  |  |  | * @date 2025-05-08 11:45 | 
|---|
|  |  |  | * @LastEditTime 2025-05-08 11:45 | 
|---|
|  |  |  | * @Description | 
|---|
|  |  |  | * @Description 操作类型枚举 | 
|---|
|  |  |  | */ | 
|---|
|  |  |  |  | 
|---|
|  |  |  | @Getter | 
|---|
|  |  |  | @AllArgsConstructor | 
|---|
|  |  |  | public enum OperateTypeENUM { | 
|---|
|  |  |  | ACTIVE((byte)1, "开卡"), | 
|---|
|  |  |  | RECHARGE((byte)2, "充值"), | 
|---|
|  |  |  | CANCEL((byte)3, "销卡"), | 
|---|
|  |  |  | REISSUE((byte)4, "补卡"), | 
|---|
|  |  |  | REFUND((byte)5, "补扣"), | 
|---|
|  |  |  | LOSS((byte)6, "挂失"), | 
|---|
|  |  |  | REVERSAL((byte)7, "冲正"), | 
|---|
|  |  |  | UNLOCK((byte)8, "解锁"), | 
|---|
|  |  |  | CONSUME((byte)9, "消费"), | 
|---|
|  |  |  | WRITE_BACK((byte)10, "反写"); | 
|---|
|  |  |  | ACTIVE((byte) 1, "开卡"), | 
|---|
|  |  |  | RECHARGE((byte) 2, "充值"), | 
|---|
|  |  |  | CANCEL((byte) 3, "销卡"), | 
|---|
|  |  |  | REISSUE((byte) 4, "补卡"), | 
|---|
|  |  |  | REFUND((byte) 5, "补扣"), | 
|---|
|  |  |  | SUPPLEMENT((byte) 6, "返还"), | 
|---|
|  |  |  | MANAGEMENT_CARD_WRITE((byte) 7, "管理类型卡写卡"), | 
|---|
|  |  |  | // 保留其他系统使用的枚举值 | 
|---|
|  |  |  | LOSS((byte) 8, "挂失"), | 
|---|
|  |  |  | UNLOCK((byte) 9, "解锁"), | 
|---|
|  |  |  | REVERSAL((byte) 10, "冲正"), | 
|---|
|  |  |  | CONSUME((byte) 11, "消费"), | 
|---|
|  |  |  | WRITE_BACK((byte) 12, "反写"); | 
|---|
|  |  |  |  | 
|---|
|  |  |  | private final Byte code; | 
|---|
|  |  |  | private final String message; | 
|---|