Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package me.chanjar.weixin.channel.api;

import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
import me.chanjar.weixin.channel.bean.qic.InspectCodeResponse;
import me.chanjar.weixin.channel.bean.qic.InspectConfigResponse;
import me.chanjar.weixin.channel.bean.qic.RegisterLogisticsRequest;
import me.chanjar.weixin.channel.bean.qic.SubmitConfigResponse;
import me.chanjar.weixin.channel.bean.qic.SubmitInspectRequest;
import me.chanjar.weixin.common.error.WxErrorException;

/**
* 视频号小店 质检管理接口.
*/
public interface WxChannelQicService {

/**
* 查询质检仓配置.
*
* @return 质检仓配置
* @throws WxErrorException 异常
*/
InspectConfigResponse getInspectConfig() throws WxErrorException;

/**
* 查询送检配置模板信息.
*
* @param orderId 订单号(可选)
* @return 送检配置模板信息
* @throws WxErrorException 异常
*/
SubmitConfigResponse getSubmitConfig(String orderId) throws WxErrorException;

/**
* 查询送检配置模板信息.
*
* @return 送检配置模板信息
* @throws WxErrorException 异常
*/
SubmitConfigResponse getSubmitConfig() throws WxErrorException;

/**
* 打印质检码.
*
* @param orderId 订单号
* @return 质检码详情
* @throws WxErrorException 异常
*/
InspectCodeResponse printInspectCode(String orderId) throws WxErrorException;

/**
* 绑定送检信息.
*
* @param request 送检信息请求
* @return 基础响应
* @throws WxErrorException 异常
*/
WxChannelBaseResponse submitInspectInfo(SubmitInspectRequest request) throws WxErrorException;

/**
* 自寄快递送检.
*
* @param request 自寄快递请求
* @return 基础响应
* @throws WxErrorException 异常
*/
WxChannelBaseResponse registerLogistics(RegisterLogisticsRequest request) throws WxErrorException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,11 @@ public interface WxChannelService extends BaseWxChannelService {
*/
WxChannelLiveDashboardService getLiveDashboardService();

/**
* 质检管理服务.
*
* @return 质检管理服务
*/
WxChannelQicService getQicService();

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public abstract class BaseWxChannelServiceImpl<H, P> implements WxChannelService
private WxChannelVipService vipService = null;
private WxChannelCompassFinderService compassFinderService = null;
private WxChannelLiveDashboardService liveDashboardService = null;
private WxChannelQicService qicService = null;

protected WxChannelConfig config;
private int retrySleepMillis = 1000;
Expand Down Expand Up @@ -473,4 +474,12 @@ public synchronized WxChannelLiveDashboardService getLiveDashboardService() {
return liveDashboardService;
}

@Override
public synchronized WxChannelQicService getQicService() {
if (qicService == null) {
qicService = new WxChannelQicServiceImpl(this);
}
return qicService;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package me.chanjar.weixin.channel.api.impl;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import me.chanjar.weixin.channel.api.WxChannelQicService;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
import me.chanjar.weixin.channel.bean.qic.InspectCodeResponse;
import me.chanjar.weixin.channel.bean.qic.InspectConfigResponse;
import me.chanjar.weixin.channel.bean.qic.RegisterLogisticsRequest;
import me.chanjar.weixin.channel.bean.qic.SubmitConfigResponse;
import me.chanjar.weixin.channel.bean.qic.SubmitInspectRequest;
import me.chanjar.weixin.channel.util.ResponseUtils;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;

import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Qic.GET_INSPECT_CONFIG_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Qic.GET_SUBMIT_CONFIG_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Qic.PRINT_INSPECT_CODE_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Qic.REGISTER_LOGISTICS_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Qic.SUBMIT_INSPECT_INFO_URL;

/**
* 视频号小店 质检管理服务实现.
*/
public class WxChannelQicServiceImpl implements WxChannelQicService {
private final BaseWxChannelServiceImpl<?, ?> shopService;

public WxChannelQicServiceImpl(BaseWxChannelServiceImpl<?, ?> shopService) {
this.shopService = shopService;
}

@Override
public InspectConfigResponse getInspectConfig() throws WxErrorException {
String respJson = shopService.get(GET_INSPECT_CONFIG_URL, null);
return ResponseUtils.decode(respJson, InspectConfigResponse.class);
}

@Override
public SubmitConfigResponse getSubmitConfig(String orderId) throws WxErrorException {
String queryParam = StringUtils.isBlank(orderId) ? null : "order_id=" + orderId;
String respJson = shopService.get(GET_SUBMIT_CONFIG_URL, queryParam);
return ResponseUtils.decode(respJson, SubmitConfigResponse.class);
}
Comment thread
Copilot marked this conversation as resolved.

@Override
public SubmitConfigResponse getSubmitConfig() throws WxErrorException {
return getSubmitConfig(null);
}

@Override
public InspectCodeResponse printInspectCode(String orderId) throws WxErrorException {
String respJson = shopService.post(PRINT_INSPECT_CODE_URL, new PrintInspectCodeRequest(orderId));
return ResponseUtils.decode(respJson, InspectCodeResponse.class);
}

@Override
public WxChannelBaseResponse submitInspectInfo(SubmitInspectRequest request) throws WxErrorException {
String respJson = shopService.post(SUBMIT_INSPECT_INFO_URL, request);
return ResponseUtils.decode(respJson, WxChannelBaseResponse.class);
}

@Override
public WxChannelBaseResponse registerLogistics(RegisterLogisticsRequest request) throws WxErrorException {
String respJson = shopService.post(REGISTER_LOGISTICS_URL, request);
return ResponseUtils.decode(respJson, WxChannelBaseResponse.class);
}

@Data
@AllArgsConstructor
private static class PrintInspectCodeRequest {
@JsonProperty("order_id")
private String orderId;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package me.chanjar.weixin.channel.bean.qic;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;

import java.io.Serializable;
import java.util.List;

@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class InspectCodeResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = -6242555695898612990L;

private DataPayload data;

@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class DataPayload implements Serializable {
private static final long serialVersionUID = 684071509005627272L;

@JsonProperty("backupDeliveryId")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Map inspect-code fields to the API payload names

The print-inspect-code response DTO starts annotating every returned field with camelCase names such as backupDeliveryId/boxDTOList, unlike the QIC API payload naming used by the other new DTOs. When WeChat returns the documented snake_case response fields, Jackson will silently leave these properties null, so a successful printInspectCode call won't expose the inspection code details to callers. Please align these @JsonProperty values with the actual response field names.

Useful? React with 👍 / 👎.

private String backupDeliveryId;

@JsonProperty("backupDeliveryName")
private String backupDeliveryName;

@JsonProperty("boxDTOList")
Comment on lines +26 to +32

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 使用官方字段名解析质检码响应

printInspectCode 成功返回 QIC 文档中的 snake_case 字段(如 backup_delivery_idbox_dto_listinspect_code)时,这里从第一个字段开始全部标成 camelCase/boxDTOList,而 JsonUtils 没有启用命名策略且会忽略未知字段,Jackson 会静默把质检码、箱规、打印信息等核心内容都留空;调用方只能看到成功响应却拿不到质检码详情。请将这些 @JsonProperty 与实际响应字段名对齐。

Useful? React with 👍 / 👎.

private List<BoxInfo> boxInfoList;
Comment on lines +23 to +33

@JsonProperty("channelAppId")
private String channelAppId;

@JsonProperty("deliveryId")
private String deliveryId;

@JsonProperty("deliveryName")
private String deliveryName;

@JsonProperty("embedGoodsMaterial")
private String embedGoodsMaterial;

@JsonProperty("goodsDesc")
private String goodsDesc;

@JsonProperty("expressMerge")
private Boolean expressMerge;

@JsonProperty("goodsMainMaterial")
private String goodsMainMaterial;

@JsonProperty("goodsName")
private String goodsName;

@JsonProperty("goodsNum")
private Integer goodsNum;

@JsonProperty("goodsPartsMaterial")
private String goodsPartsMaterial;

@JsonProperty("inspectBaseId")
private String inspectBaseId;

@JsonProperty("inspectBaseName")
private String inspectBaseName;

@JsonProperty("inspectCode")
private String inspectCode;

@JsonProperty("inspectOrgId")
private String inspectOrgId;

@JsonProperty("inspectOrgName")
private String inspectOrgName;

@JsonProperty("inspectOrgShortName")
private String inspectOrgShortName;

@JsonProperty("merchantName")
private String merchantName;

@JsonProperty("orderId")
private String orderId;

@JsonProperty("urgentOrder")
private Boolean urgentOrder;

@JsonProperty("printInfo")
private String printInfo;

@JsonProperty("needLabel")
private Boolean needLabel;
}

@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class BoxInfo implements Serializable {
private static final long serialVersionUID = 4074623844069371776L;

@JsonProperty("boxId")
private Long boxId;

@JsonProperty("boxName")
private String boxName;

@JsonProperty("boxNum")
private Integer boxNum;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package me.chanjar.weixin.channel.bean.qic;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;

import java.io.Serializable;

@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class InspectConfigResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = 6463651966377955876L;

@JsonProperty("inspect_config")
private InspectConfig inspectConfig;

@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class InspectConfig implements Serializable {
private static final long serialVersionUID = 5829846300579243328L;

@JsonProperty("warehouse_id")
private String warehouseId;

@JsonProperty("delivery_address")
private Address deliveryAddress;

@JsonProperty("return_address")
private Address returnAddress;

@JsonProperty("warehouse_name")
private String warehouseName;

@JsonProperty("warehouse_addr")
private String warehouseAddr;
}

@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class Address implements Serializable {
private static final long serialVersionUID = -664266740472865991L;

@JsonProperty("contact_name")
private String contactName;

@JsonProperty("contact_phone")
private String contactPhone;

private String province;

private String city;

private String county;

private String detail;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package me.chanjar.weixin.channel.bean.qic;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class RegisterLogisticsRequest implements Serializable {
private static final long serialVersionUID = 4346443649534209624L;

@JsonProperty("order_id_list")
private List<String> orderIdList;

@JsonProperty("logistics_info")
private LogisticsInfo logisticsInfo;

@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class LogisticsInfo implements Serializable {
private static final long serialVersionUID = 8677143207727485993L;

@JsonProperty("waybill_id")
private String waybillId;

@JsonProperty("delivery_id")
private String deliveryId;

@JsonProperty("delivery_name")
private String deliveryName;

@JsonProperty("delivery_type")
private Integer deliveryType;
}
}
Loading