瀏覽代碼

:art: #3449【视频号】订单详情和分类详情接口增加部分字段,并增加新增库存不足、团购优惠发放的回调通知处理方法

Zeyes Lee 4 月之前
父節點
當前提交
6840722947

+ 25 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/BaseWxChannelMessageService.java

@@ -20,11 +20,13 @@ import me.chanjar.weixin.channel.bean.message.order.OrderStatusMessage;
 import me.chanjar.weixin.channel.bean.message.product.BrandMessage;
 import me.chanjar.weixin.channel.bean.message.product.CategoryAuditMessage;
 import me.chanjar.weixin.channel.bean.message.product.SpuAuditMessage;
+import me.chanjar.weixin.channel.bean.message.product.SpuStockMessage;
 import me.chanjar.weixin.channel.bean.message.store.CloseStoreMessage;
 import me.chanjar.weixin.channel.bean.message.store.NicknameUpdateMessage;
 import me.chanjar.weixin.channel.bean.message.supplier.SupplierItemMessage;
 import me.chanjar.weixin.channel.bean.message.vip.ExchangeInfoMessage;
 import me.chanjar.weixin.channel.bean.message.vip.UserInfoMessage;
+import me.chanjar.weixin.channel.bean.message.voucher.VoucherMessage;
 import me.chanjar.weixin.channel.message.WxChannelMessage;
 import me.chanjar.weixin.channel.message.WxChannelMessageRouterRule;
 import me.chanjar.weixin.common.session.WxSessionManager;
@@ -198,6 +200,18 @@ public interface BaseWxChannelMessageService {
     final WxSessionManager sessionManager);
 
   /**
+   * 商品库存不足通知
+   *
+   * @param message        消息
+   * @param content        消息原始内容
+   * @param appId          appId
+   * @param context        上下文
+   * @param sessionManager session管理器
+   */
+  void stockNoEnough(SpuStockMessage message, final String content, final String appId,
+    final Map<String, Object> context, final WxSessionManager sessionManager);
+
+  /**
    * 类目审核结果
    *
    * @param message        消息
@@ -354,6 +368,17 @@ public interface BaseWxChannelMessageService {
     final Map<String, Object> context, final WxSessionManager sessionManager);
 
   /**
+   * 发放团购优惠成功回调
+   *
+   * @param message        消息
+   * @param content        消息原始内容
+   * @param appId          appId
+   * @param context        上下文
+   * @param sessionManager session管理器
+   */
+  void voucherSendSucc(VoucherMessage message, final String content, final String appId,
+    final Map<String, Object> context, final WxSessionManager sessionManager);
+  /**
    * 结算账户变更回调
    *
    * @param message        消息

+ 19 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelMessageServiceImpl.java

@@ -23,12 +23,14 @@ import me.chanjar.weixin.channel.bean.message.order.OrderStatusMessage;
 import me.chanjar.weixin.channel.bean.message.product.BrandMessage;
 import me.chanjar.weixin.channel.bean.message.product.CategoryAuditMessage;
 import me.chanjar.weixin.channel.bean.message.product.SpuAuditMessage;
+import me.chanjar.weixin.channel.bean.message.product.SpuStockMessage;
 import me.chanjar.weixin.channel.bean.message.sharer.SharerChangeMessage;
 import me.chanjar.weixin.channel.bean.message.store.CloseStoreMessage;
 import me.chanjar.weixin.channel.bean.message.store.NicknameUpdateMessage;
 import me.chanjar.weixin.channel.bean.message.supplier.SupplierItemMessage;
 import me.chanjar.weixin.channel.bean.message.vip.ExchangeInfoMessage;
 import me.chanjar.weixin.channel.bean.message.vip.UserInfoMessage;
+import me.chanjar.weixin.channel.bean.message.voucher.VoucherMessage;
 import me.chanjar.weixin.channel.message.WxChannelMessage;
 import me.chanjar.weixin.channel.message.WxChannelMessageRouter;
 import me.chanjar.weixin.channel.message.WxChannelMessageRouterRule;
@@ -64,6 +66,8 @@ public abstract class BaseWxChannelMessageServiceImpl implements BaseWxChannelMe
     this.addRule(SpuAuditMessage.class, PRODUCT_SPU_STATUS_UPDATE, this::spuStatusUpdate);
     /* 商品更新 */
     this.addRule(SpuAuditMessage.class, PRODUCT_SPU_UPDATE, this::spuUpdate);
+    /* 商品库存不足 */
+    this.addRule(SpuStockMessage.class, PRODUCT_STOCK_NO_ENOUGH, this::stockNoEnough);
     /* 类目审核结果 */
     this.addRule(CategoryAuditMessage.class, PRODUCT_CATEGORY_AUDIT, this::categoryAudit);
     /* 订单下单 */
@@ -106,6 +110,8 @@ public abstract class BaseWxChannelMessageServiceImpl implements BaseWxChannelMe
     this.addRule(UserCouponExpireMessage.class, USER_COUPON_UNUSE, this::userCouponUnuse);
     /* 优惠券返还通知 */
     this.addRule(UserCouponExpireMessage.class, USER_COUPON_USE, this::userCouponUse);
+    /* 发放团购优惠成功通知 */
+    this.addRule(VoucherMessage.class, VOUCHER_SEND_SUCC, this::voucherSendSucc);
     /* 结算账户变更回调 */
     this.addRule(AccountNotifyMessage.class, ACCOUNT_NOTIFY, this::accountNotify);
     /* 提现回调 */
@@ -151,6 +157,7 @@ public abstract class BaseWxChannelMessageServiceImpl implements BaseWxChannelMe
       consumer.accept(message, content, appId, context, sessionManager);
       return "success";
     });
+    rule.setNext(true);
     this.addRule(rule);
   }
 
@@ -243,6 +250,12 @@ public abstract class BaseWxChannelMessageServiceImpl implements BaseWxChannelMe
   }
 
   @Override
+  public void stockNoEnough(SpuStockMessage message, String content, String appId,
+          Map<String, Object> context, WxSessionManager sessionManager) {
+    log.info("商品库存不足:{}", JsonUtils.encode(message));
+  }
+
+  @Override
   public void categoryAudit(CategoryAuditMessage message, String content, String appId,
     Map<String, Object> context, WxSessionManager sessionManager) {
     log.info("分类审核:{}", JsonUtils.encode(message));
@@ -321,6 +334,12 @@ public abstract class BaseWxChannelMessageServiceImpl implements BaseWxChannelMe
   }
 
   @Override
+  public void voucherSendSucc(VoucherMessage message, String content, String appId,
+          Map<String, Object> context, WxSessionManager sessionManager) {
+    log.info("发放团购优惠成功:{}", JsonUtils.encode(message));
+  }
+
+  @Override
   public void accountNotify(AccountNotifyMessage message, String content, String appId,
     Map<String, Object> context, WxSessionManager sessionManager) {
     log.info("账户通知:{}", JsonUtils.encode(message));

+ 4 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java

@@ -99,6 +99,10 @@ public class CategoryDetailResult extends WxChannelBaseResponse {
     @JsonProperty("size_chart")
     private SizeChart sizeChart;
 
+    /** 放心买必须打开坏损包赔 */
+    @JsonProperty("is_confidence_require_bad_must_pay")
+    private Boolean confidenceRequireBadMustPay;
+
     /** 资质信息 */
     @JsonProperty("product_qua_list")
     private List<QualificationInfo> productQuaList;

+ 4 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualification.java

@@ -39,4 +39,8 @@ public class CategoryQualification implements Serializable {
   @JsonProperty("product_qua_list")
   private List<QualificationInfo> productQuaList;
 
+  /** 放心买必须打开坏损包赔 */
+  @JsonProperty("is_confidence_require_bad_must_pay")
+  private Boolean confidenceRequireBadMustPay;
+
 }

+ 88 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuStockMessage.java

@@ -0,0 +1,88 @@
+package me.chanjar.weixin.channel.bean.message.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * SPU库存不足消息
+ *
+ * @author <a href="https://github.com/lixize">Zeyes</a>
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class SpuStockMessage extends WxChannelMessage {
+
+  private static final long serialVersionUID = 2250860804161527363L;
+
+  /** 商品id */
+  @JsonProperty("product_id")
+  @JacksonXmlProperty(localName = "product_id")
+  private String productId;
+
+  /** 平台商品id */
+  @JsonProperty("sku_id")
+  @JacksonXmlProperty(localName = "sku_id")
+  private String skuId;
+
+  /** 剩余库存:当前实时库存数量 */
+  @JsonProperty("remaining_stock_amount")
+  @JacksonXmlProperty(localName = "remaining_stock_amount")
+  private Long remainingStockAmount;
+
+  /** 未发放的预存code数【该字段对code_source_type=2的团购优惠生效,其他类型该字段值为0】 */
+  @JsonProperty("remaining_code_amount")
+  @JacksonXmlProperty(localName = "remaining_code_amount")
+  private Long remainingCodeAmount;
+
+  /** ChannelsEcStockNoEnough */
+  @JsonProperty("channels_ec_stock_no_enough")
+  @JacksonXmlProperty(localName = "channels_ec_stock_no_enough")
+  private void stockNoEnough(Map<String, Object> map) {
+    this.unpackNameFromNestedObject(map);
+  }
+
+  /**
+   * 从嵌套对象中解析字段
+   *
+   * @param map 嵌套对象
+   */
+  protected void unpackNameFromNestedObject(Map<String, Object> map) {
+    if (map == null) {
+      return;
+    }
+    Object obj = null;
+    obj = map.get("product_id");
+    if (obj != null) {
+      this.productId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+    }
+    obj = map.get("sku_id");
+    if (obj != null) {
+      this.skuId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+    }
+
+    obj = map.get("remaining_stock_amount");
+    if (obj != null) {
+      if (obj instanceof Number) {
+        this.remainingStockAmount = ((Number) obj).longValue();
+      } else if (obj instanceof String) {
+        this.remainingStockAmount = Long.parseLong((String) obj);
+      }
+    }
+    obj = map.get("remaining_code_amount");
+    if (obj != null) {
+      if (obj instanceof Number) {
+        this.remainingCodeAmount = ((Number) obj).longValue();
+      } else if (obj instanceof String) {
+        this.remainingCodeAmount = Long.parseLong((String) obj);
+      }
+    }
+  }
+}

+ 106 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/voucher/VoucherInfo.java

@@ -0,0 +1,106 @@
+package me.chanjar.weixin.channel.bean.message.voucher;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author <a href="https://github.com/lixize">Zeyes</a>
+ */
+@Data
+@NoArgsConstructor
+public class VoucherInfo implements Serializable {
+  private static final long serialVersionUID = 6007964849358969438L;
+
+  /** 券code */
+  @JsonProperty("code")
+  @JacksonXmlProperty(localName = "code")
+  private String code;
+
+  /** 劵码类型,1商户实时code 2户预存 3平台生成 */
+  @JsonProperty("code_type")
+  @JacksonXmlProperty(localName = "code_type")
+  private Integer codeType;
+
+  /** 券状态 */
+  @JsonProperty("status")
+  @JacksonXmlProperty(localName = "status")
+  private Integer status;
+
+  /** 发放时间,时间戳 */
+  @JsonProperty("send_time")
+  @JacksonXmlProperty(localName = "send_time")
+  private Long sendTime;
+
+  /** 最近更新时间,时间戳 */
+  @JsonProperty("update_time")
+  @JacksonXmlProperty(localName = "update_time")
+  private Long updateTime;
+
+  /** 核销生效时间,时间戳 */
+  @JsonProperty("start_time")
+  @JacksonXmlProperty(localName = "start_time")
+  private Long startTime;
+
+  /** 核销结束时间,时间戳 */
+  @JsonProperty("end_time")
+  @JacksonXmlProperty(localName = "end_time")
+  private Long endTime;
+
+  /** 核销时间,时间戳。次卡时不返回此字段 */
+  @JsonProperty("consume_time")
+  @JacksonXmlProperty(localName = "consume_time")
+  private Long consumeTime;
+
+  /** 退券时间,时间戳。次卡时不返回此字段 */
+  @JsonProperty("refund_time")
+  @JacksonXmlProperty(localName = "refund_time")
+  private Long refundTime;
+
+  /** 核销门店名称 */
+  @JsonProperty("consume_store_name")
+  @JacksonXmlProperty(localName = "consume_store_name")
+  private String consumeStoreName;
+
+  /**  */
+  @JsonProperty("voucher_type")
+  @JacksonXmlProperty(localName = "voucher_type")
+  private Integer voucherType;
+
+  /** 券的售卖价格(分) */
+  @JsonProperty("voucher_buy_amount")
+  @JacksonXmlProperty(localName = "voucher_buy_amount")
+  private Integer voucherBuyAmount;
+
+  /** 券市场金额(分) */
+  @JsonProperty("voucher_actual_amount")
+  @JacksonXmlProperty(localName = "voucher_actual_amount")
+  private Integer voucherActualAmount;
+
+  /** 用户手机号 */
+  @JsonProperty("telphone_no")
+  @JacksonXmlProperty(localName = "telphone_no")
+  private String telPhoneNo;
+
+  /** 商品id */
+  @JsonProperty("product_id")
+  @JacksonXmlProperty(localName = "product_id")
+  private String productId;
+
+  /** 商品下的skuId */
+  @JsonProperty("sku_id")
+  @JacksonXmlProperty(localName = "sku_id")
+  private String skuId;
+
+  /** 购买券的订单id */
+  @JsonProperty("order_id")
+  @JacksonXmlProperty(localName = "order_id")
+  private String orderId;
+
+  /** 用户在商家品牌appid下的openid */
+  @JsonProperty("openid")
+  @JacksonXmlProperty(localName = "openid")
+  private String openId;
+}

+ 29 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/voucher/VoucherMessage.java

@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.message.voucher;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 发放团购优惠成功消息
+ *
+ * @author <a href="https://github.com/lixize">Zeyes</a>
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class VoucherMessage extends WxChannelMessage {
+
+  private static final long serialVersionUID = 975858675917036089L;
+
+  /** 发放团购优惠成功消息 */
+  @JsonProperty("voucher_list")
+  @JacksonXmlProperty(localName = "voucher_list")
+  private List<VoucherInfo> voucherInfo;
+}

+ 30 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAgentInfo.java

@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 授权账号信息
+ *
+ * @author <a href="https://github.com/lixize">Zeyes</a>
+ */
+@Data
+@NoArgsConstructor
+public class OrderAgentInfo implements Serializable {
+
+  private static final long serialVersionUID = 6396067079343033841L;
+
+  /**
+   * 授权视频号id
+   */
+  @JsonProperty("agent_finder_id")
+  private String agentFinderId;
+
+  /**
+   * 授权视频号昵称
+   */
+  @JsonProperty("agent_finder_nickname")
+  private String agentFinderNickname;
+}

+ 8 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDetailInfo.java

@@ -56,4 +56,12 @@ public class OrderDetailInfo implements Serializable {
   @JsonProperty("sku_sharer_infos")
   private List<OrderSkuShareInfo> skuSharerInfos;
 
+  /** 授权账号信息 */
+  @JsonProperty("agent_info")
+  private OrderAgentInfo agentInfo;
+
+  /** 订单来源信息 */
+  @JsonProperty("source_info")
+  private OrderSourceInfo sourceInfo;
+
 }

+ 48 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSourceInfo.java

@@ -0,0 +1,48 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单带货来源信息
+ *
+ * @author <a href="https://github.com/lixize">Zeyes</a>
+ */
+@Data
+@NoArgsConstructor
+public class OrderSourceInfo implements Serializable {
+
+  private static final long serialVersionUID = 3131907659419977296L;
+
+  /**
+   * sku_id
+   */
+  @JsonProperty("sku_id")
+  private String skuId;
+
+  /**
+   * 带货账户类型,1:视频号,2:公众号,3:小程序
+   */
+  @JsonProperty("account_type")
+  private Integer accountType;
+
+  /**
+   * 带货账户id,如果带货账户类型是视频号,此id为视频号id; 如果带货类型为 公众号/小程序, 此id 为对应 公众号/小程序 的appid
+   */
+  @JsonProperty("account_id")
+  private String accountId;
+
+  /**
+   * 销售渠道, 0:关联账号,1:合作账号,100:联盟达人带货
+   */
+  @JsonProperty("sale_channel")
+  private Integer saleChannel;
+
+  /**
+   * 带货账户昵称
+   */
+  @JsonProperty("account_nickname")
+  private String accountNickname;
+}

+ 4 - 0
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/MessageEventConstants.java

@@ -16,6 +16,8 @@ public interface MessageEventConstants {
     String PRODUCT_SPU_UPDATE = "product_spu_update";
     /** 类目审核结果 */
     String PRODUCT_CATEGORY_AUDIT = "product_category_audit";
+    /** 库存不足 */
+    String PRODUCT_STOCK_NO_ENOUGH = "channels_ec_stock_no_enough";
     /** 订单下单 */
     String ORDER_NEW = "channels_ec_order_new";
     /** 订单取消 */
@@ -57,6 +59,8 @@ public interface MessageEventConstants {
     String USER_COUPON_UNUSE = "channels_ec_user_coupon_unuse";
     /** 优惠券核销通知 */
     String USER_COUPON_USE = "channels_ec_user_coupon_use";
+    /** 发放团购优惠成功回调 */
+    String VOUCHER_SEND_SUCC = "channels_ec_voucher_send_succ";
     // 资金相关
     /** 结算账户变更回调 */
     String ACCOUNT_NOTIFY = "channels_ec_acct_notify";

+ 4 - 3
weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouter.java

@@ -121,6 +121,7 @@ public class WxChannelMessageRouter {
     final Map<String, Object> context, final WxChannelService service, final WxSessionManager sessionManager) {
     // 如果是重复消息,那么就不做处理
     if (isMsgDuplicated(message)) {
+      log.info("收到重复消息,{}", content);
       return null;
     }
 
@@ -211,10 +212,10 @@ public class WxChannelMessageRouter {
    *
    * @param sessionManager session管理器
    * @param message 消息
-   * @param sync 是否同步 打印log用
+   * @param async 是否异步 打印log用
    */
-  private void sessionEndAccess(WxSessionManager sessionManager, WxChannelMessage message, boolean sync) {
-    log.debug("End session access: async={}, sessionId={}", sync, message.getFromUser());
+  private void sessionEndAccess(WxSessionManager sessionManager, WxChannelMessage message, boolean async) {
+    log.debug("End session access: async={}, sessionId={}", async, message.getFromUser());
     InternalSession session = ((InternalSessionManager) sessionManager).findSession(message.getFromUser());
     if (session != null) {
       session.endAccess();