1
0
mirror of synced 2026-10-09 08:16:39 +08:00

🆕 #4039 【视频号】新增微信小店质检管理模块接口与模型支持

This commit is contained in:
Copilot
2026-07-11 15:26:51 +08:00
committed by GitHub
parent b3a9ee7d0b
commit 1fa901286c
11 changed files with 665 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -182,4 +182,11 @@ public interface WxChannelService extends BaseWxChannelService {
*/
WxChannelLiveDashboardService getLiveDashboardService();
/**
* 质检管理服务.
*
* @return 质检管理服务
*/
WxChannelQicService getQicService();
}

View File

@@ -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;
@@ -473,4 +474,12 @@ public abstract class BaseWxChannelServiceImpl<H, P> implements WxChannelService
return liveDashboardService;
}
@Override
public synchronized WxChannelQicService getQicService() {
if (qicService == null) {
qicService = new WxChannelQicServiceImpl(this);
}
return qicService;
}
}

View File

@@ -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);
}
@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;
}
}

View File

@@ -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")
private String backupDeliveryId;
@JsonProperty("backupDeliveryName")
private String backupDeliveryName;
@JsonProperty("boxDTOList")
private List<BoxInfo> boxInfoList;
@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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,98 @@
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 SubmitConfigResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = 2456553692263326158L;
@JsonProperty("submit_config")
private SubmitConfig submitConfig;
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class SubmitConfig implements Serializable {
private static final long serialVersionUID = 3286213539172123945L;
@JsonProperty("delivery_list")
private List<Delivery> deliveryList;
@JsonProperty("inspect_org_list")
private List<InspectOrg> inspectOrgList;
@JsonProperty("charge_url")
private String chargeUrl;
}
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class Delivery implements Serializable {
private static final long serialVersionUID = -9209694824619490683L;
private String id;
private String name;
@JsonProperty("delivery_products")
private List<DeliveryProduct> deliveryProducts;
}
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class DeliveryProduct implements Serializable {
private static final long serialVersionUID = 6527277159948670769L;
private Long id;
private String name;
@JsonProperty("enable_insure")
private Integer enableInsure;
@JsonProperty("insure_type_list")
private List<InsureType> insureTypeList;
}
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class InsureType implements Serializable {
private static final long serialVersionUID = -7788541278375899098L;
private String id;
private String name;
@JsonProperty("upper_limit_type")
private Integer upperLimitType;
@JsonProperty("upper_limit_amount")
private Long upperLimitAmount;
}
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class InspectOrg implements Serializable {
private static final long serialVersionUID = 1723422231048685194L;
private String id;
private String name;
@JsonProperty("org_category")
private Integer orgCategory;
}
}

View File

@@ -0,0 +1,85 @@
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;
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public class SubmitInspectRequest implements Serializable {
private static final long serialVersionUID = 6396115469552098613L;
@JsonProperty("order_id")
private String orderId;
@JsonProperty("inspect_info")
private InspectInfo inspectInfo;
@Data
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class InspectInfo implements Serializable {
private static final long serialVersionUID = -3502982646296821525L;
@JsonProperty("delivery_id")
private String deliveryId;
@JsonProperty("backup_delivery_id")
private String backupDeliveryId;
@JsonProperty("express_insure")
private Boolean expressInsure;
@JsonProperty("express_insure_amount")
private Long expressInsureAmount;
@JsonProperty("express_merge")
private Boolean expressMerge;
@JsonProperty("inspect_org_id")
private String inspectOrgId;
@JsonProperty("refund_intercept")
private Integer refundIntercept;
@JsonProperty("inspect_org_name")
private String inspectOrgName;
@JsonProperty("warehouse_name")
private String warehouseName;
@JsonProperty("warehouse_addr")
private String warehouseAddr;
@JsonProperty("delivery_product_id")
private Long deliveryProductId;
@JsonProperty("delivery_insure_id")
private String deliveryInsureId;
@JsonProperty("backup_delivery_product_id")
private Long backupDeliveryProductId;
@JsonProperty("backup_delivery_insure_id")
private String backupDeliveryInsureId;
@JsonProperty("backup_express_insure")
private Boolean backupExpressInsure;
@JsonProperty("backup_express_insure_amount")
private Long backupExpressInsureAmount;
@JsonProperty("remark")
private String remark;
@JsonProperty("agarwood_inspect_org_id")
private String agarwoodInspectOrgId;
@JsonProperty("agarwood_inspect_org_name")
private String agarwoodInspectOrgName;
}
}

View File

@@ -510,6 +510,20 @@ public class WxChannelApiUrlConstants {
String GRADE_UPDATE_URL = "https://api.weixin.qq.com/channels/ec/vip/user/grade/update";
}
/** 质检管理相关接口 */
public interface Qic {
/** 查询质检仓配置 */
String GET_INSPECT_CONFIG_URL = "https://api.weixin.qq.com/channels/ec/qic/inspect/config/get";
/** 查询送检配置模板信息 */
String GET_SUBMIT_CONFIG_URL = "https://api.weixin.qq.com/channels/ec/qic/inspect/submitconfig/get";
/** 打印质检码 */
String PRINT_INSPECT_CODE_URL = "https://api.weixin.qq.com/channels/ec/qic/inspect/code/print";
/** 绑定送检信息 */
String SUBMIT_INSPECT_INFO_URL = "https://api.weixin.qq.com/channels/ec/qic/inspect/submit";
/** 自寄快递送检 */
String REGISTER_LOGISTICS_URL = "https://api.weixin.qq.com/channels/ec/qic/inspect/register_logistics";
}
/**
* 直播大屏数据
*/

View File

@@ -0,0 +1,93 @@
package me.chanjar.weixin.channel.api.impl;
import com.google.inject.Inject;
import me.chanjar.weixin.channel.api.WxChannelQicService;
import me.chanjar.weixin.channel.api.WxChannelService;
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.test.ApiTestModule;
import me.chanjar.weixin.common.error.WxErrorException;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import java.util.Collections;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
@Guice(modules = ApiTestModule.class)
public class WxChannelQicServiceImplTest {
@Inject
private WxChannelService channelService;
@Test
public void testGetInspectConfig() throws WxErrorException {
WxChannelQicService qicService = channelService.getQicService();
InspectConfigResponse response = qicService.getInspectConfig();
assertNotNull(response);
assertTrue(response.isSuccess());
}
@Test
public void testGetSubmitConfig() throws WxErrorException {
WxChannelQicService qicService = channelService.getQicService();
SubmitConfigResponse response = qicService.getSubmitConfig("123456");
assertNotNull(response);
assertTrue(response.isSuccess());
}
@Test
public void testPrintInspectCode() throws WxErrorException {
WxChannelQicService qicService = channelService.getQicService();
InspectCodeResponse response = qicService.printInspectCode("123456");
assertNotNull(response);
assertTrue(response.isSuccess());
}
@Test
public void testSubmitInspectInfo() throws WxErrorException {
WxChannelQicService qicService = channelService.getQicService();
SubmitInspectRequest request = new SubmitInspectRequest();
request.setOrderId("123456");
SubmitInspectRequest.InspectInfo inspectInfo = new SubmitInspectRequest.InspectInfo();
inspectInfo.setDeliveryId("YTO");
inspectInfo.setBackupDeliveryId("SF");
inspectInfo.setExpressInsure(Boolean.FALSE);
inspectInfo.setExpressMerge(Boolean.FALSE);
inspectInfo.setInspectOrgId("ORG_1");
inspectInfo.setRefundIntercept(0);
inspectInfo.setInspectOrgName("机构A");
inspectInfo.setWarehouseName("质检仓");
inspectInfo.setWarehouseAddr("质检仓地址");
inspectInfo.setDeliveryProductId(1L);
inspectInfo.setBackupDeliveryProductId(2L);
request.setInspectInfo(inspectInfo);
WxChannelBaseResponse response = qicService.submitInspectInfo(request);
assertNotNull(response);
assertTrue(response.isSuccess());
}
@Test
public void testRegisterLogistics() throws WxErrorException {
WxChannelQicService qicService = channelService.getQicService();
RegisterLogisticsRequest request = new RegisterLogisticsRequest();
request.setOrderIdList(Collections.singletonList("123456"));
RegisterLogisticsRequest.LogisticsInfo logisticsInfo = new RegisterLogisticsRequest.LogisticsInfo();
logisticsInfo.setWaybillId("YT1234567890");
logisticsInfo.setDeliveryId("YTO");
logisticsInfo.setDeliveryName("圆通速递");
logisticsInfo.setDeliveryType(1);
request.setLogisticsInfo(logisticsInfo);
WxChannelBaseResponse response = qicService.registerLogistics(request);
assertNotNull(response);
assertTrue(response.isSuccess());
}
}