diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBasicService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBasicService.java index a687aaeb5c..4d2133a56d 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBasicService.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelBasicService.java @@ -5,7 +5,10 @@ import me.chanjar.weixin.channel.bean.image.ChannelImageInfo; import me.chanjar.weixin.channel.bean.image.ChannelImageResponse; import me.chanjar.weixin.channel.bean.image.QualificationFileResponse; +import me.chanjar.weixin.channel.bean.shop.ShopH5UrlResponse; import me.chanjar.weixin.channel.bean.shop.ShopInfoResponse; +import me.chanjar.weixin.channel.bean.shop.ShopQrCodeResponse; +import me.chanjar.weixin.channel.bean.shop.ShopTagLinkResponse; import me.chanjar.weixin.common.error.WxErrorException; /** @@ -22,6 +25,31 @@ public interface WxChannelBasicService { */ ShopInfoResponse getShopInfo() throws WxErrorException; + /** + * 获取店铺H5链接 + * + * @return 店铺H5链接 + * @throws WxErrorException 异常 + */ + ShopH5UrlResponse getShopH5Url() throws WxErrorException; + + /** + * 获取店铺二维码 + * + * @param qrcodeType 二维码类型,1:二维码;2:标准物料;3:送礼物物料 + * @return 店铺二维码 + * @throws WxErrorException 异常 + */ + ShopQrCodeResponse getShopQrCode(int qrcodeType) throws WxErrorException; + + /** + * 获取店铺口令 + * + * @return 店铺口令 + * @throws WxErrorException 异常 + */ + ShopTagLinkResponse getShopTagLink() throws WxErrorException; + /** * 上传图片 * diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFavoriteService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFavoriteService.java new file mode 100644 index 0000000000..c1c03cc615 --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelFavoriteService.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.channel.api; + +import me.chanjar.weixin.channel.bean.favorite.FavoriteCountResponse; +import me.chanjar.weixin.common.error.WxErrorException; + +/** + * 视频号小店 收藏管理接口 + * + * @author GitHub Copilot + * @link 收藏管理接口文档 + */ +public interface WxChannelFavoriteService { + + /** + * 获取店铺收藏的人数 + * + * @return 店铺收藏人数响应 + * @throws WxErrorException 异常 + */ + FavoriteCountResponse getFavoriteCount() throws WxErrorException; +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelService.java index 50a029c196..0b63f07cf7 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelService.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelService.java @@ -182,4 +182,11 @@ public interface WxChannelService extends BaseWxChannelService { */ WxChannelLiveDashboardService getLiveDashboardService(); + /** + * 收藏管理服务 + * + * @return 收藏管理服务 + */ + WxChannelFavoriteService getFavoriteService(); + } diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java index 1a608e1f6a..4e15e1534f 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelServiceImpl.java @@ -60,6 +60,7 @@ public abstract class BaseWxChannelServiceImpl implements WxChannelService private WxChannelVipService vipService = null; private WxChannelCompassFinderService compassFinderService = null; private WxChannelLiveDashboardService liveDashboardService = null; + private WxChannelFavoriteService favoriteService = null; protected WxChannelConfig config; private int retrySleepMillis = 1000; @@ -473,4 +474,12 @@ public synchronized WxChannelLiveDashboardService getLiveDashboardService() { return liveDashboardService; } + @Override + public synchronized WxChannelFavoriteService getFavoriteService() { + if (favoriteService == null) { + favoriteService = new WxChannelFavoriteServiceImpl(this); + } + return favoriteService; + } + } diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImpl.java index 6eb699da23..45a869216e 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImpl.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImpl.java @@ -2,7 +2,10 @@ import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_ADDRESS_CODE; import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_IMG_URL; +import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_SHOP_H5URL; import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_SHOP_INFO; +import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_SHOP_QRCODE; +import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.GET_SHOP_TAGLINK; import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.IMG_UPLOAD_URL; import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Basics.UPLOAD_QUALIFICATION_FILE; @@ -16,7 +19,10 @@ import me.chanjar.weixin.channel.bean.image.ChannelImageResponse; import me.chanjar.weixin.channel.bean.image.QualificationFileResponse; import me.chanjar.weixin.channel.bean.image.UploadImageResponse; +import me.chanjar.weixin.channel.bean.shop.ShopH5UrlResponse; import me.chanjar.weixin.channel.bean.shop.ShopInfoResponse; +import me.chanjar.weixin.channel.bean.shop.ShopQrCodeResponse; +import me.chanjar.weixin.channel.bean.shop.ShopTagLinkResponse; import me.chanjar.weixin.channel.executor.ChannelFileUploadRequestExecutor; import me.chanjar.weixin.channel.executor.ChannelMediaDownloadRequestExecutor; import me.chanjar.weixin.channel.util.ResponseUtils; @@ -93,4 +99,23 @@ public AddressCodeResponse getAddressCode(Integer code) throws WxErrorException return ResponseUtils.decode(resJson, AddressCodeResponse.class); } + @Override + public ShopH5UrlResponse getShopH5Url() throws WxErrorException { + String resJson = shopService.post(GET_SHOP_H5URL, "{}"); + return ResponseUtils.decode(resJson, ShopH5UrlResponse.class); + } + + @Override + public ShopQrCodeResponse getShopQrCode(int qrcodeType) throws WxErrorException { + String reqJson = "{\"qrcode_type\":" + qrcodeType + "}"; + String resJson = shopService.post(GET_SHOP_QRCODE, reqJson); + return ResponseUtils.decode(resJson, ShopQrCodeResponse.class); + } + + @Override + public ShopTagLinkResponse getShopTagLink() throws WxErrorException { + String resJson = shopService.post(GET_SHOP_TAGLINK, "{}"); + return ResponseUtils.decode(resJson, ShopTagLinkResponse.class); + } + } diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFavoriteServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFavoriteServiceImpl.java new file mode 100644 index 0000000000..8165f47987 --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFavoriteServiceImpl.java @@ -0,0 +1,29 @@ +package me.chanjar.weixin.channel.api.impl; + +import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Favorite.GET_FAVORITE_COUNT; + +import me.chanjar.weixin.channel.api.WxChannelFavoriteService; +import me.chanjar.weixin.channel.bean.favorite.FavoriteCountResponse; +import me.chanjar.weixin.channel.util.ResponseUtils; +import me.chanjar.weixin.common.error.WxErrorException; + +/** + * 视频号小店 收藏管理接口实现 + * + * @author GitHub Copilot + */ +public class WxChannelFavoriteServiceImpl implements WxChannelFavoriteService { + + /** 微信商店服务 */ + private final BaseWxChannelServiceImpl shopService; + + public WxChannelFavoriteServiceImpl(BaseWxChannelServiceImpl shopService) { + this.shopService = shopService; + } + + @Override + public FavoriteCountResponse getFavoriteCount() throws WxErrorException { + String resJson = shopService.post(GET_FAVORITE_COUNT, "{}"); + return ResponseUtils.decode(resJson, FavoriteCountResponse.class); + } +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/favorite/FavoriteCountResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/favorite/FavoriteCountResponse.java new file mode 100644 index 0000000000..9acdf93d75 --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/favorite/FavoriteCountResponse.java @@ -0,0 +1,38 @@ +package me.chanjar.weixin.channel.bean.favorite; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse; + +/** + * 店铺收藏人数 响应 + * + * @author GitHub Copilot + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class FavoriteCountResponse extends WxChannelBaseResponse { + + /** 店铺首页收藏用户数 */ + @JsonProperty("favor_uv_acc_shop_homepage") + private Long favorUvAccShopHomepage; + + /** 订单详情页收藏用户数 */ + @JsonProperty("favor_uv_acc_order_detail") + private Long favorUvAccOrderDetail; + + /** 商品详情页收藏用户数 */ + @JsonProperty("favor_uv_acc_product_detail") + private Long favorUvAccProductDetail; + + /** 其他场景收藏用户数 */ + @JsonProperty("favor_uv_acc_other_scene") + private Long favorUvAccOtherScene; + + /** 所有收藏用户数 */ + @JsonProperty("favor_uv_acc_all") + private Long favorUvAccAll; +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopH5UrlResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopH5UrlResponse.java new file mode 100644 index 0000000000..5700073c05 --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopH5UrlResponse.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.channel.bean.shop; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse; + +/** + * 店铺H5链接 响应 + * + * @author GitHub Copilot + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class ShopH5UrlResponse extends WxChannelBaseResponse { + + /** 店铺H5链接 */ + @JsonProperty("shop_h5url") + private String shopH5url; +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopQrCodeResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopQrCodeResponse.java new file mode 100644 index 0000000000..1859f2e3f4 --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopQrCodeResponse.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.channel.bean.shop; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse; + +/** + * 店铺二维码 响应 + * + * @author GitHub Copilot + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class ShopQrCodeResponse extends WxChannelBaseResponse { + + /** 店铺二维码链接 */ + @JsonProperty("shop_qrcode") + private String shopQrcode; +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopTagLinkResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopTagLinkResponse.java new file mode 100644 index 0000000000..8b82d21106 --- /dev/null +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/shop/ShopTagLinkResponse.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.channel.bean.shop; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse; + +/** + * 店铺口令 响应 + * + * @author GitHub Copilot + */ +@Data +@NoArgsConstructor +@EqualsAndHashCode(callSuper = true) +public class ShopTagLinkResponse extends WxChannelBaseResponse { + + /** 店铺微信口令 */ + @JsonProperty("shop_taglink") + private String shopTaglink; +} diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java index 6c2076d85b..18ab0cc792 100644 --- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java +++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/WxChannelApiUrlConstants.java @@ -34,6 +34,19 @@ public interface Basics { String GET_IMG_URL = "https://api.weixin.qq.com/channels/ec/basics/media/get"; /** 获取地址编码 */ String GET_ADDRESS_CODE = "https://api.weixin.qq.com/channels/ec/basics/addresscode/get"; + /** 获取店铺H5链接 */ + String GET_SHOP_H5URL = "https://api.weixin.qq.com/channels/ec/basics/shop/h5url/get"; + /** 获取店铺二维码 */ + String GET_SHOP_QRCODE = "https://api.weixin.qq.com/channels/ec/basics/shop/qrcode/get"; + /** 获取店铺口令 */ + String GET_SHOP_TAGLINK = "https://api.weixin.qq.com/channels/ec/basics/shop/taglink/get"; + } + + /** 收藏管理相关接口 */ + public interface Favorite { + + /** 获取店铺收藏的人数 */ + String GET_FAVORITE_COUNT = "https://api.weixin.qq.com/channels/ec/favorites/count/get"; } /** 商品类目相关接口 */ diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelFavoriteServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelFavoriteServiceImplTest.java new file mode 100644 index 0000000000..1e5dfd7c5d --- /dev/null +++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelFavoriteServiceImplTest.java @@ -0,0 +1,35 @@ +package me.chanjar.weixin.channel.api.impl; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import com.google.inject.Inject; +import me.chanjar.weixin.channel.api.WxChannelFavoriteService; +import me.chanjar.weixin.channel.api.WxChannelService; +import me.chanjar.weixin.channel.bean.favorite.FavoriteCountResponse; +import me.chanjar.weixin.channel.test.ApiTestModule; +import me.chanjar.weixin.channel.util.JsonUtils; +import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +/** + * 收藏管理接口 测试 + * + * @author GitHub Copilot + */ +@Guice(modules = ApiTestModule.class) +public class WxChannelFavoriteServiceImplTest { + + @Inject + private WxChannelService channelService; + + @Test + public void testGetFavoriteCount() throws WxErrorException { + WxChannelFavoriteService favoriteService = channelService.getFavoriteService(); + FavoriteCountResponse response = favoriteService.getFavoriteCount(); + assertNotNull(response); + assertTrue(response.isSuccess()); + System.out.println(JsonUtils.encode(response)); + } +} diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelShopLinkServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelShopLinkServiceImplTest.java new file mode 100644 index 0000000000..87785a5396 --- /dev/null +++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelShopLinkServiceImplTest.java @@ -0,0 +1,56 @@ +package me.chanjar.weixin.channel.api.impl; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import com.google.inject.Inject; +import me.chanjar.weixin.channel.api.WxChannelBasicService; +import me.chanjar.weixin.channel.api.WxChannelService; +import me.chanjar.weixin.channel.bean.shop.ShopH5UrlResponse; +import me.chanjar.weixin.channel.bean.shop.ShopQrCodeResponse; +import me.chanjar.weixin.channel.bean.shop.ShopTagLinkResponse; +import me.chanjar.weixin.channel.test.ApiTestModule; +import me.chanjar.weixin.channel.util.JsonUtils; +import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +/** + * 店铺链接接口 测试 + * + * @author GitHub Copilot + */ +@Guice(modules = ApiTestModule.class) +public class WxChannelShopLinkServiceImplTest { + + @Inject + private WxChannelService channelService; + + @Test + public void testGetShopH5Url() throws WxErrorException { + WxChannelBasicService basicService = channelService.getBasicService(); + ShopH5UrlResponse response = basicService.getShopH5Url(); + assertNotNull(response); + assertTrue(response.isSuccess()); + System.out.println(JsonUtils.encode(response)); + } + + @Test + public void testGetShopQrCode() throws WxErrorException { + WxChannelBasicService basicService = channelService.getBasicService(); + // qrcodeType: 1=二维码, 2=标准物料, 3=送礼物物料 + ShopQrCodeResponse response = basicService.getShopQrCode(1); + assertNotNull(response); + assertTrue(response.isSuccess()); + System.out.println(JsonUtils.encode(response)); + } + + @Test + public void testGetShopTagLink() throws WxErrorException { + WxChannelBasicService basicService = channelService.getBasicService(); + ShopTagLinkResponse response = basicService.getShopTagLink(); + assertNotNull(response); + assertTrue(response.isSuccess()); + System.out.println(JsonUtils.encode(response)); + } +}