From 1be31c64d0d9730453b7dd0ab0b8041c3206f1f7 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 31 May 2026 14:20:31 +0000
Subject: [PATCH 1/2] Initial plan
From 22a6f33fbec30e499c7029dcca8c02f9a0df1f37 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 1 Jun 2026 01:58:16 +0000
Subject: [PATCH 2/2] =?UTF-8?q?feat(channel):=20=E5=AE=9E=E7=8E=B0?=
=?UTF-8?q?=E8=A7=86=E9=A2=91=E5=8F=B7=E5=B0=8F=E5=BA=97=E7=BC=BA=E5=A4=B1?=
=?UTF-8?q?=E7=9A=8414=E4=B8=AA=E5=95=86=E5=93=81=E7=9B=B8=E5=85=B3API?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../channel/api/WxChannelGiftService.java | 81 +++++++++++++++++
.../channel/api/WxChannelProductService.java | 87 +++++++++++++++++++
.../weixin/channel/api/WxChannelService.java | 7 ++
.../api/impl/BaseWxChannelServiceImpl.java | 9 ++
.../api/impl/WxChannelGiftServiceImpl.java | 84 ++++++++++++++++++
.../api/impl/WxChannelProductServiceImpl.java | 78 +++++++++++++++++
.../channel/bean/gift/GiftGetResponse.java | 29 +++++++
.../channel/bean/gift/GiftListParam.java | 34 ++++++++
.../weixin/channel/bean/gift/GiftProduct.java | 84 ++++++++++++++++++
.../channel/bean/gift/GiftProductInfo.java | 65 ++++++++++++++
.../bean/gift/GiftProductListResponse.java | 33 +++++++
.../bean/gift/GiftProductResponse.java | 32 +++++++
.../channel/bean/gift/GiftProductSku.java | 42 +++++++++
.../channel/bean/gift/GiftProductSkuInfo.java | 36 ++++++++
.../bean/gift/GiftProductUpdateInfo.java | 65 ++++++++++++++
.../bean/gift/GiftProductUpdateSkuInfo.java | 29 +++++++
.../channel/bean/gift/GiftSetParam.java | 30 +++++++
.../channel/bean/gift/GiftSetSkuParam.java | 28 ++++++
.../channel/bean/gift/GiftSkuStockDiff.java | 28 ++++++
.../channel/bean/limit/LimitSkuUpdate.java | 30 +++++++
.../bean/limit/LimitTaskUpdateParam.java | 46 ++++++++++
.../bean/limit/LimitTaskUpdateResponse.java | 28 ++++++
.../product/CategoryPreCheckResponse.java | 30 +++++++
.../bean/product/ExternalAttribute.java | 28 ++++++
.../ExternalProductMappingNewParam.java | 46 ++++++++++
.../ExternalProductMappingNewResponse.java | 25 ++++++
.../product/ExternalProductMappingParam.java | 37 ++++++++
.../ExternalProductMappingResponse.java | 37 ++++++++
.../product/ProductBrandRecommendParam.java | 38 ++++++++
.../ProductBrandRecommendResponse.java | 32 +++++++
.../bean/product/StockFlowExtInfo.java | 49 +++++++++++
.../channel/bean/product/StockFlowInfo.java | 55 ++++++++++++
.../channel/bean/product/StockFlowParam.java | 66 ++++++++++++++
.../bean/product/StockFlowResponse.java | 43 +++++++++
.../constant/WxChannelApiUrlConstants.java | 33 +++++++
35 files changed, 1504 insertions(+)
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelGiftService.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelGiftServiceImpl.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftGetResponse.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftListParam.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProduct.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductInfo.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductListResponse.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductResponse.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductSku.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductSkuInfo.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductUpdateInfo.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductUpdateSkuInfo.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSetParam.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSetSkuParam.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSkuStockDiff.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitSkuUpdate.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskUpdateParam.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskUpdateResponse.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/CategoryPreCheckResponse.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalAttribute.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingNewParam.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingNewResponse.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingParam.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingResponse.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductBrandRecommendParam.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductBrandRecommendResponse.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowExtInfo.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowInfo.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowParam.java
create mode 100644 weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowResponse.java
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelGiftService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelGiftService.java
new file mode 100644
index 0000000000..0c142c761d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelGiftService.java
@@ -0,0 +1,81 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.gift.GiftGetResponse;
+import me.chanjar.weixin.channel.bean.gift.GiftProductInfo;
+import me.chanjar.weixin.channel.bean.gift.GiftProductListResponse;
+import me.chanjar.weixin.channel.bean.gift.GiftProductResponse;
+import me.chanjar.weixin.channel.bean.gift.GiftProductUpdateInfo;
+import me.chanjar.weixin.channel.bean.gift.GiftSetParam;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 赠品管理服务接口
+ *
+ * @author GitHub Copilot
+ * @see 赠品管理接口文档
+ */
+public interface WxChannelGiftService {
+
+ /**
+ * 添加非卖商品(赠品)
+ *
+ * @param info 赠品信息
+ * @return GiftProductResponse
+ * @throws WxErrorException 异常
+ */
+ GiftProductResponse addGiftProduct(GiftProductInfo info) throws WxErrorException;
+
+ /**
+ * 更新非卖商品(赠品)
+ *
+ * @param info 赠品更新信息
+ * @return GiftProductResponse
+ * @throws WxErrorException 异常
+ */
+ GiftProductResponse updateGiftProduct(GiftProductUpdateInfo info) throws WxErrorException;
+
+ /**
+ * 在售商品转赠品(设置在售商品为赠品)
+ *
+ * @param param 请求参数(product_id + skus 列表)
+ * @return GiftProductListResponse
+ * @throws WxErrorException 异常
+ */
+ GiftProductListResponse setProductAsGift(GiftSetParam param) throws WxErrorException;
+
+ /**
+ * 获取赠品详情
+ *
+ * @param productId 赠品商品ID
+ * @param dataType 数据类型。1: 仅获取线上数据;2: 仅获取草稿数据;3: 同时获取(默认)
+ * @return GiftGetResponse
+ * @throws WxErrorException 异常
+ */
+ GiftGetResponse getGiftProduct(String productId, Integer dataType) throws WxErrorException;
+
+ /**
+ * 获取赠品列表
+ *
+ * @param pageSize 每页数量
+ * @param nextKey 翻页上下文,不传默认获取第一页
+ * @param status 赠品状态过滤
+ * @return GiftProductListResponse
+ * @throws WxErrorException 异常
+ */
+ GiftProductListResponse listGiftProduct(Integer pageSize, String nextKey, Integer status)
+ throws WxErrorException;
+
+ /**
+ * 更新赠品库存
+ *
+ * @param productId 赠品商品ID
+ * @param skuId SKU ID
+ * @param diffType 差量类型。1: 增加;2: 减少
+ * @param num 变更数量
+ * @return WxChannelBaseResponse
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateGiftStock(String productId, String skuId, Integer diffType, Integer num)
+ throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelProductService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelProductService.java
index 7064adf70f..b083d3ed6a 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelProductService.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelProductService.java
@@ -6,6 +6,15 @@
import me.chanjar.weixin.channel.bean.limit.LimitTaskAddResponse;
import me.chanjar.weixin.channel.bean.limit.LimitTaskListResponse;
import me.chanjar.weixin.channel.bean.limit.LimitTaskParam;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskUpdateParam;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskUpdateResponse;
+import me.chanjar.weixin.channel.bean.product.CategoryPreCheckResponse;
+import me.chanjar.weixin.channel.bean.product.ExternalProductMappingNewParam;
+import me.chanjar.weixin.channel.bean.product.ExternalProductMappingNewResponse;
+import me.chanjar.weixin.channel.bean.product.ExternalProductMappingParam;
+import me.chanjar.weixin.channel.bean.product.ExternalProductMappingResponse;
+import me.chanjar.weixin.channel.bean.product.ProductBrandRecommendParam;
+import me.chanjar.weixin.channel.bean.product.ProductBrandRecommendResponse;
import me.chanjar.weixin.channel.bean.product.SkuStockBatchResponse;
import me.chanjar.weixin.channel.bean.product.SkuStockResponse;
import me.chanjar.weixin.channel.bean.product.SpuFastInfo;
@@ -14,6 +23,8 @@
import me.chanjar.weixin.channel.bean.product.SpuListResponse;
import me.chanjar.weixin.channel.bean.product.SpuUpdateInfo;
import me.chanjar.weixin.channel.bean.product.SpuUpdateResponse;
+import me.chanjar.weixin.channel.bean.product.StockFlowParam;
+import me.chanjar.weixin.channel.bean.product.StockFlowResponse;
import me.chanjar.weixin.channel.bean.product.link.ProductH5UrlResponse;
import me.chanjar.weixin.channel.bean.product.link.ProductQrCodeResponse;
import me.chanjar.weixin.channel.bean.product.link.ProductTagLinkResponse;
@@ -247,4 +258,80 @@ WxChannelBaseResponse updateStock(String productId, String skuId, Integer diffTy
* @throws WxErrorException 异常
*/
WxChannelBaseResponse deleteLimitTask(String taskId) throws WxErrorException;
+
+ /**
+ * 更新限时抢购任务
+ *
+ * @param param 更新参数
+ * @return LimitTaskUpdateResponse
+ * @throws WxErrorException 异常
+ */
+ LimitTaskUpdateResponse updateLimitTask(LimitTaskUpdateParam param) throws WxErrorException;
+
+ /**
+ * 获取库存流水
+ *
+ * @param param 查询参数
+ * @return StockFlowResponse
+ * @throws WxErrorException 异常
+ */
+ StockFlowResponse getStockFlow(StockFlowParam param) throws WxErrorException;
+
+ /**
+ * 发品前校验(校验当前商家是否具备在指定类目发品的资质)
+ *
+ * @param catId 叶子类目id
+ * @return CategoryPreCheckResponse
+ * @throws WxErrorException 异常
+ */
+ CategoryPreCheckResponse categoryPreCheck(Long catId) throws WxErrorException;
+
+ /**
+ * 商品品牌推荐(根据商品信息推荐品牌)
+ *
+ * @param param 请求参数
+ * @return ProductBrandRecommendResponse
+ * @throws WxErrorException 异常
+ */
+ ProductBrandRecommendResponse getProductBrandRecommend(ProductBrandRecommendParam param)
+ throws WxErrorException;
+
+ /**
+ * 站内外商品属性映射
+ *
+ * @param param 请求参数
+ * @return ExternalProductMappingResponse
+ * @throws WxErrorException 异常
+ */
+ ExternalProductMappingResponse externalProductMapping(ExternalProductMappingParam param)
+ throws WxErrorException;
+
+ /**
+ * 站内外商品属性映射(新版)
+ *
+ * @param param 请求参数
+ * @return ExternalProductMappingNewResponse
+ * @throws WxErrorException 异常
+ */
+ ExternalProductMappingNewResponse externalProductMappingNew(ExternalProductMappingNewParam param)
+ throws WxErrorException;
+
+ /**
+ * 商品立即开售(结束预售)
+ *
+ * @param productId 商品ID
+ * @param taskId 预售任务ID
+ * @return WxChannelBaseResponse
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse beginTimingSale(String productId, String taskId) throws WxErrorException;
+
+ /**
+ * 取消商品开售(取消预售)
+ *
+ * @param productId 商品ID
+ * @return WxChannelBaseResponse
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse cancelTimingSale(String productId) 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..5eb782d20c 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 赠品管理服务
+ */
+ WxChannelGiftService getGiftService();
+
}
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..ddeeee668d 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 WxChannelGiftService giftService = null;
protected WxChannelConfig config;
private int retrySleepMillis = 1000;
@@ -473,4 +474,12 @@ public synchronized WxChannelLiveDashboardService getLiveDashboardService() {
return liveDashboardService;
}
+ @Override
+ public synchronized WxChannelGiftService getGiftService() {
+ if (giftService == null) {
+ giftService = new WxChannelGiftServiceImpl(this);
+ }
+ return giftService;
+ }
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelGiftServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelGiftServiceImpl.java
new file mode 100644
index 0000000000..2635f82e11
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelGiftServiceImpl.java
@@ -0,0 +1,84 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Gift.ADD_GIFT_PRODUCT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Gift.GET_GIFT_PRODUCT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Gift.LIST_GIFT_PRODUCT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Gift.SET_PRODUCT_AS_GIFT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Gift.UPDATE_GIFT_PRODUCT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Gift.UPDATE_GIFT_STOCK_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelGiftService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.gift.GiftGetResponse;
+import me.chanjar.weixin.channel.bean.gift.GiftListParam;
+import me.chanjar.weixin.channel.bean.gift.GiftProductInfo;
+import me.chanjar.weixin.channel.bean.gift.GiftProductListResponse;
+import me.chanjar.weixin.channel.bean.gift.GiftProductResponse;
+import me.chanjar.weixin.channel.bean.gift.GiftProductUpdateInfo;
+import me.chanjar.weixin.channel.bean.gift.GiftSetParam;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号小店 赠品管理服务实现
+ *
+ * @author GitHub Copilot
+ */
+@Slf4j
+public class WxChannelGiftServiceImpl implements WxChannelGiftService {
+
+ /** 微信商店服务 */
+ private final BaseWxChannelServiceImpl, ?> shopService;
+
+ public WxChannelGiftServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
+ this.shopService = shopService;
+ }
+
+ @Override
+ public GiftProductResponse addGiftProduct(GiftProductInfo info) throws WxErrorException {
+ String reqJson = JsonUtils.encode(info);
+ String resJson = shopService.post(ADD_GIFT_PRODUCT_URL, reqJson);
+ return ResponseUtils.decode(resJson, GiftProductResponse.class);
+ }
+
+ @Override
+ public GiftProductResponse updateGiftProduct(GiftProductUpdateInfo info) throws WxErrorException {
+ String reqJson = JsonUtils.encode(info);
+ String resJson = shopService.post(UPDATE_GIFT_PRODUCT_URL, reqJson);
+ return ResponseUtils.decode(resJson, GiftProductResponse.class);
+ }
+
+ @Override
+ public GiftProductListResponse setProductAsGift(GiftSetParam param) throws WxErrorException {
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(SET_PRODUCT_AS_GIFT_URL, reqJson);
+ return ResponseUtils.decode(resJson, GiftProductListResponse.class);
+ }
+
+ @Override
+ public GiftGetResponse getGiftProduct(String productId, Integer dataType) throws WxErrorException {
+ String reqJson = "{\"product_id\":\"" + productId + "\",\"data_type\":" + dataType + "}";
+ String resJson = shopService.post(GET_GIFT_PRODUCT_URL, reqJson);
+ return ResponseUtils.decode(resJson, GiftGetResponse.class);
+ }
+
+ @Override
+ public GiftProductListResponse listGiftProduct(Integer pageSize, String nextKey, Integer status)
+ throws WxErrorException {
+ GiftListParam param = new GiftListParam(pageSize, nextKey, status);
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(LIST_GIFT_PRODUCT_URL, reqJson);
+ return ResponseUtils.decode(resJson, GiftProductListResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updateGiftStock(String productId, String skuId, Integer diffType, Integer num)
+ throws WxErrorException {
+ String reqJson = "{\"product_id\":\"" + productId + "\",\"sku_id\":\"" + skuId
+ + "\",\"diff_type\":" + diffType + ",\"num\":" + num + "}";
+ String resJson = shopService.post(UPDATE_GIFT_STOCK_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImpl.java
index 08c9638f0c..54be01bcb6 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImpl.java
@@ -2,14 +2,21 @@
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.ADD_LIMIT_TASK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.BEGIN_TIMING_SALE_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.CANCEL_AUDIT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.CANCEL_TIMING_SALE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.CATEGORY_PRE_CHECK_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.DELETE_LIMIT_TASK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.EXTERNAL_PRODUCT_MAPPING_NEW_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.EXTERNAL_PRODUCT_MAPPING_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.LIST_LIMIT_TASK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.PRODUCT_BRAND_RECOMMEND_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_ADD_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_AUDIT_FREE_UPDATE_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_DELISTING_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_DEL_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_GET_STOCK_BATCH_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_GET_STOCK_FLOW_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_GET_STOCK_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_GET_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_H5URL_URL;
@@ -20,6 +27,7 @@
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_UPDATE_STOCK_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_UPDATE_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.STOP_LIMIT_TASK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.UPDATE_LIMIT_TASK_URL;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@@ -29,6 +37,15 @@
import me.chanjar.weixin.channel.bean.limit.LimitTaskListParam;
import me.chanjar.weixin.channel.bean.limit.LimitTaskListResponse;
import me.chanjar.weixin.channel.bean.limit.LimitTaskParam;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskUpdateParam;
+import me.chanjar.weixin.channel.bean.limit.LimitTaskUpdateResponse;
+import me.chanjar.weixin.channel.bean.product.CategoryPreCheckResponse;
+import me.chanjar.weixin.channel.bean.product.ExternalProductMappingNewParam;
+import me.chanjar.weixin.channel.bean.product.ExternalProductMappingNewResponse;
+import me.chanjar.weixin.channel.bean.product.ExternalProductMappingParam;
+import me.chanjar.weixin.channel.bean.product.ExternalProductMappingResponse;
+import me.chanjar.weixin.channel.bean.product.ProductBrandRecommendParam;
+import me.chanjar.weixin.channel.bean.product.ProductBrandRecommendResponse;
import me.chanjar.weixin.channel.bean.product.SkuStockBatchParam;
import me.chanjar.weixin.channel.bean.product.SkuStockBatchResponse;
import me.chanjar.weixin.channel.bean.product.SkuStockParam;
@@ -40,6 +57,8 @@
import me.chanjar.weixin.channel.bean.product.SpuListResponse;
import me.chanjar.weixin.channel.bean.product.SpuUpdateInfo;
import me.chanjar.weixin.channel.bean.product.SpuUpdateResponse;
+import me.chanjar.weixin.channel.bean.product.StockFlowParam;
+import me.chanjar.weixin.channel.bean.product.StockFlowResponse;
import me.chanjar.weixin.channel.bean.product.link.ProductH5UrlResponse;
import me.chanjar.weixin.channel.bean.product.link.ProductQrCodeResponse;
import me.chanjar.weixin.channel.bean.product.link.ProductTagLinkResponse;
@@ -240,4 +259,63 @@ public WxChannelBaseResponse deleteLimitTask(String taskId) throws WxErrorExcept
String resJson = shopService.post(DELETE_LIMIT_TASK_URL, reqJson);
return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
}
+
+ @Override
+ public LimitTaskUpdateResponse updateLimitTask(LimitTaskUpdateParam param) throws WxErrorException {
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(UPDATE_LIMIT_TASK_URL, reqJson);
+ return ResponseUtils.decode(resJson, LimitTaskUpdateResponse.class);
+ }
+
+ @Override
+ public StockFlowResponse getStockFlow(StockFlowParam param) throws WxErrorException {
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(SPU_GET_STOCK_FLOW_URL, reqJson);
+ return ResponseUtils.decode(resJson, StockFlowResponse.class);
+ }
+
+ @Override
+ public CategoryPreCheckResponse categoryPreCheck(Long catId) throws WxErrorException {
+ String reqJson = "{\"cat_id\":" + catId + "}";
+ String resJson = shopService.post(CATEGORY_PRE_CHECK_URL, reqJson);
+ return ResponseUtils.decode(resJson, CategoryPreCheckResponse.class);
+ }
+
+ @Override
+ public ProductBrandRecommendResponse getProductBrandRecommend(ProductBrandRecommendParam param)
+ throws WxErrorException {
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(PRODUCT_BRAND_RECOMMEND_URL, reqJson);
+ return ResponseUtils.decode(resJson, ProductBrandRecommendResponse.class);
+ }
+
+ @Override
+ public ExternalProductMappingResponse externalProductMapping(ExternalProductMappingParam param)
+ throws WxErrorException {
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(EXTERNAL_PRODUCT_MAPPING_URL, reqJson);
+ return ResponseUtils.decode(resJson, ExternalProductMappingResponse.class);
+ }
+
+ @Override
+ public ExternalProductMappingNewResponse externalProductMappingNew(ExternalProductMappingNewParam param)
+ throws WxErrorException {
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(EXTERNAL_PRODUCT_MAPPING_NEW_URL, reqJson);
+ return ResponseUtils.decode(resJson, ExternalProductMappingNewResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse beginTimingSale(String productId, String taskId) throws WxErrorException {
+ String reqJson = "{\"product_id\":\"" + productId + "\",\"task_id\":\"" + taskId + "\"}";
+ String resJson = shopService.post(BEGIN_TIMING_SALE_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse cancelTimingSale(String productId) throws WxErrorException {
+ String reqJson = "{\"product_id\":\"" + productId + "\"}";
+ String resJson = shopService.post(CANCEL_TIMING_SALE_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftGetResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftGetResponse.java
new file mode 100644
index 0000000000..cc3b6b4ec3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftGetResponse.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+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
+ * @see 获取赠品
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class GiftGetResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 赠品线上数据(data_type!=2 时返回) */
+ @JsonProperty("product")
+ private GiftProduct product;
+
+ /** 赠品草稿数据(data_type!=1 时返回) */
+ @JsonProperty("edit_product")
+ private GiftProduct editProduct;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftListParam.java
new file mode 100644
index 0000000000..d6a78272d3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftListParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+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.StreamPageParam;
+
+/**
+ * 获取赠品列表 请求参数
+ *
+ * @author GitHub Copilot
+ * @see 获取赠品列表
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GiftListParam extends StreamPageParam {
+
+ private static final long serialVersionUID = -1L;
+
+ /**
+ * 商品状态,不填默认拉全部商品(不包含回收站)。
+ * 5: 上架;6: 回收站;11: 所有下架
+ */
+ @JsonProperty("status")
+ private Integer status;
+
+ public GiftListParam(Integer pageSize, String nextKey, Integer status) {
+ this.pageSize = pageSize;
+ this.nextKey = nextKey;
+ this.status = status;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProduct.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProduct.java
new file mode 100644
index 0000000000..8717714ac4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProduct.java
@@ -0,0 +1,84 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AttrInfo;
+import me.chanjar.weixin.channel.bean.product.DescriptionInfo;
+import me.chanjar.weixin.channel.bean.product.SpuCategory;
+
+/**
+ * 赠品详情数据(线上数据或草稿数据)
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+public class GiftProduct implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 小店内部赠品ID */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 外部平台自定义赠品ID */
+ @JsonProperty("out_product_id")
+ private String outProductId;
+
+ /** 标题 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 主图列表 */
+ @JsonProperty("head_imgs")
+ private List headImgs;
+
+ /** 赠品详情 */
+ @JsonProperty("desc_info")
+ private DescriptionInfo descInfo;
+
+ /** 赠品线上状态 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 赠品草稿状态 */
+ @JsonProperty("edit_status")
+ private Integer editStatus;
+
+ /** 新类目树结构 */
+ @JsonProperty("cats_v2")
+ private List catsV2;
+
+ /** 商品参数 */
+ @JsonProperty("attrs")
+ private List attrs;
+
+ /** 商家自定义赠品编码 */
+ @JsonProperty("spu_code")
+ private String spuCode;
+
+ /** 品牌id */
+ @JsonProperty("brand_id")
+ private String brandId;
+
+ /** sku 列表 */
+ @JsonProperty("skus")
+ private List skus;
+
+ /**
+ * 赠品类型。4: 在售赠品;5: 非卖赠品
+ */
+ @JsonProperty("product_type")
+ private Integer productType;
+
+ /** 赠品草稿最近一次修改时间 */
+ @JsonProperty("edit_time")
+ private Long editTime;
+
+ /** 在售赠品的来源商品id */
+ @JsonProperty("src_product_id")
+ private Long srcProductId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductInfo.java
new file mode 100644
index 0000000000..8798f131fa
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductInfo.java
@@ -0,0 +1,65 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AttrInfo;
+import me.chanjar.weixin.channel.bean.product.DescriptionInfo;
+import me.chanjar.weixin.channel.bean.product.SpuCategory;
+
+/**
+ * 添加非卖赠品请求参数
+ *
+ * @author GitHub Copilot
+ * @see 添加非卖商品
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GiftProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 外部平台自定义非卖商品ID,最多128字符,一旦添加成功后该字段无法修改 */
+ @JsonProperty("out_product_id")
+ private String outProductId;
+
+ /** 标题,最多60字符 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 主图,最少3张,最多9张 */
+ @JsonProperty("head_imgs")
+ private List headImgs;
+
+ /** 赠品详情 */
+ @JsonProperty("desc_info")
+ private DescriptionInfo descInfo;
+
+ /** 非卖商品类目,新类目树结构 */
+ @JsonProperty("cats_v2")
+ private List catsV2;
+
+ /** 非卖商品参数 */
+ @JsonProperty("attrs")
+ private List attrs;
+
+ /** 商家自定义的非卖商品编码 */
+ @JsonProperty("spu_code")
+ private String spuCode;
+
+ /** 品牌id,无品牌为"2100000000" */
+ @JsonProperty("brand_id")
+ private String brandId;
+
+ /** 仅支持单sku,长度固定为1 */
+ @JsonProperty("skus")
+ private List skus;
+
+ /** 添加完成后是否立即上架。1:是;0:否;默认0 */
+ @JsonProperty("listing")
+ private Integer listing;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductListResponse.java
new file mode 100644
index 0000000000..9e4302cc9f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductListResponse.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+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 GiftProductListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 赠品ID列表 */
+ @JsonProperty("product_ids")
+ private List productIds;
+
+ /** 本次翻页的上下文,用于请求下一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 赠品总数 */
+ @JsonProperty("total_num")
+ private Integer totalNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductResponse.java
new file mode 100644
index 0000000000..3d0bf7f6bb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductResponse.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+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 GiftProductResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 非卖商品ID */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 创建时间 */
+ @JsonProperty("create_time")
+ private String createTime;
+
+ /** 更新时间 */
+ @JsonProperty("update_time")
+ private String updateTime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductSku.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductSku.java
new file mode 100644
index 0000000000..e75e2ce3ba
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductSku.java
@@ -0,0 +1,42 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 赠品 SKU 详情(获取赠品时返回)
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+public class GiftProductSku implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** sku ID */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 外部平台自定义 sku ID */
+ @JsonProperty("out_sku_id")
+ private String outSkuId;
+
+ /** 售卖价格,以分为单位 */
+ @JsonProperty("sale_price")
+ private Integer salePrice;
+
+ /** sku 库存 */
+ @JsonProperty("stock_num")
+ private Integer stockNum;
+
+ /** 商家自定义 sku 编码 */
+ @JsonProperty("sku_code")
+ private String skuCode;
+
+ /** sku 状态 */
+ @JsonProperty("status")
+ private Integer status;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductSkuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductSkuInfo.java
new file mode 100644
index 0000000000..746744755c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductSkuInfo.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 赠品 SKU 信息(用于添加非卖赠品)
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GiftProductSkuInfo implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 外部平台自定义 sku_id,最多128字符,一旦添加成功后该字段无法修改 */
+ @JsonProperty("out_sku_id")
+ private String outSkuId;
+
+ /** 售卖价格,以分为单位 */
+ @JsonProperty("sale_price")
+ private Integer salePrice;
+
+ /** 创建非卖商品时初始化设置的库存 */
+ @JsonProperty("stock_num")
+ private Integer stockNum;
+
+ /** 商家自定义 sku 编码,最多100字符 */
+ @JsonProperty("sku_code")
+ private String skuCode;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductUpdateInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductUpdateInfo.java
new file mode 100644
index 0000000000..854aad12d3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductUpdateInfo.java
@@ -0,0 +1,65 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AttrInfo;
+import me.chanjar.weixin.channel.bean.product.DescriptionInfo;
+import me.chanjar.weixin.channel.bean.product.SpuCategory;
+
+/**
+ * 更新非卖赠品请求参数
+ *
+ * @author GitHub Copilot
+ * @see 更新非卖商品
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GiftProductUpdateInfo implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 商品ID(更新时必填) */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 外部平台自定义非卖商品ID */
+ @JsonProperty("out_product_id")
+ private String outProductId;
+
+ /** 标题,最多60字符 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 主图,最少3张,最多9张 */
+ @JsonProperty("head_imgs")
+ private List headImgs;
+
+ /** 赠品详情 */
+ @JsonProperty("desc_info")
+ private DescriptionInfo descInfo;
+
+ /** 非卖商品类目,新类目树结构 */
+ @JsonProperty("cats_v2")
+ private List catsV2;
+
+ /** 非卖商品参数 */
+ @JsonProperty("attrs")
+ private List attrs;
+
+ /** 商家自定义的非卖商品编码 */
+ @JsonProperty("spu_code")
+ private String spuCode;
+
+ /** 品牌id,无品牌为"2100000000" */
+ @JsonProperty("brand_id")
+ private String brandId;
+
+ /** 仅支持单sku,长度固定为1(支持 sku_id 和 stock_diff) */
+ @JsonProperty("skus")
+ private List skus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductUpdateSkuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductUpdateSkuInfo.java
new file mode 100644
index 0000000000..4e1ef94946
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftProductUpdateSkuInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 赠品 SKU 信息(用于更新非卖赠品,在 {@link GiftProductSkuInfo} 基础上增加 sku_id 和 stock_diff)
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GiftProductUpdateSkuInfo extends GiftProductSkuInfo {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 若填了已存在 sku_id 则进行更新,否则新增 */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 库存差值信息,更新时建议使用,避免高并发问题 */
+ @JsonProperty("stock_diff")
+ private GiftSkuStockDiff stockDiff;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSetParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSetParam.java
new file mode 100644
index 0000000000..8f3975e74f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSetParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 在售商品转赠品 请求参数
+ *
+ * @author GitHub Copilot
+ * @see 在售商品转赠品
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GiftSetParam implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 原始商品ID */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** sku 列表(目前仅支持单品商品) */
+ @JsonProperty("skus")
+ private List skus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSetSkuParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSetSkuParam.java
new file mode 100644
index 0000000000..cff4ffac4a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSetSkuParam.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 在售商品转赠品时,sku 划拨参数
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GiftSetSkuParam implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 原始商品 sku ID(目前仅支持单品商品) */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 划拨给赠品的库存数量,将直接从原始商品库存中扣除 */
+ @JsonProperty("stock_num")
+ private Integer stockNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSkuStockDiff.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSkuStockDiff.java
new file mode 100644
index 0000000000..d191e41bf4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/gift/GiftSkuStockDiff.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.gift;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 赠品 SKU 库存差值信息(更新时使用)
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class GiftSkuStockDiff implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 库存修改类型。1: 增加;2: 减少 */
+ @JsonProperty("diff_type")
+ private Integer diffType;
+
+ /** 增加或减少的库存值 */
+ @JsonProperty("num")
+ private Integer num;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitSkuUpdate.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitSkuUpdate.java
new file mode 100644
index 0000000000..6b401151e8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitSkuUpdate.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 限时抢购 SKU 信息(更新时使用,在 {@link LimitSku} 基础上增加 product_id)
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class LimitSkuUpdate extends LimitSku {
+
+ private static final long serialVersionUID = -1L;
+
+ /** SKU 所属商品ID(修改SKU时必传) */
+ @JsonProperty("product_id")
+ private String productId;
+
+ public LimitSkuUpdate(String productId, String skuId, Integer salePrice, Integer saleStock) {
+ super(skuId, salePrice, saleStock);
+ this.productId = productId;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskUpdateParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskUpdateParam.java
new file mode 100644
index 0000000000..a86ec64e14
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskUpdateParam.java
@@ -0,0 +1,46 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 更新限时抢购任务 请求参数
+ *
+ * @author GitHub Copilot
+ * @see 更新限时抢购任务
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class LimitTaskUpdateParam implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 限时抢购任务ID */
+ @JsonProperty("task_id")
+ private String taskId;
+
+ /** 当前活动状态(乐观锁校验)。0: 待开始;1: 进行中 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 限时抢购任务开始时间(秒级时间戳) */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+ /** 限时抢购任务结束时间(秒级时间戳) */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 活动名称(仅商家可见,最长50个字符) */
+ @JsonProperty("title")
+ private String title;
+
+ /** SKU 抢购信息列表,修改 SKU 时必须传入 product_id */
+ @JsonProperty("limited_discount_skus")
+ private List skus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskUpdateResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskUpdateResponse.java
new file mode 100644
index 0000000000..961e176d15
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/limit/LimitTaskUpdateResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.limit;
+
+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 LimitTaskUpdateResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 限时抢购任务ID */
+ @JsonProperty("task_id")
+ private String taskId;
+
+ /** 活动名称 */
+ @JsonProperty("title")
+ private String title;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/CategoryPreCheckResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/CategoryPreCheckResponse.java
new file mode 100644
index 0000000000..7e9e0241c6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/CategoryPreCheckResponse.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 发品前校验 响应
+ *
+ * @author GitHub Copilot
+ * @see 发品前校验
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CategoryPreCheckResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 检查类目是否可用。true: 类目正常;false: 类目不可用 */
+ @JsonProperty("all_pass")
+ private Boolean allPass;
+
+ /** 校验不通过的原因列表 */
+ @JsonProperty("fail_reasons")
+ private List failReasons;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalAttribute.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalAttribute.java
new file mode 100644
index 0000000000..d87472ec7f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalAttribute.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 外部属性键值对
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ExternalAttribute implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 属性名称(key) */
+ @JsonProperty("key")
+ private String key;
+
+ /** 属性值(value) */
+ @JsonProperty("value")
+ private String value;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingNewParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingNewParam.java
new file mode 100644
index 0000000000..67947e28e8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingNewParam.java
@@ -0,0 +1,46 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 站内外商品属性映射(新版) 请求参数
+ *
+ * @author GitHub Copilot
+ * @see 站内外商品属性映射(新版)
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ExternalProductMappingNewParam implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 叶子类目id(必填) */
+ @JsonProperty("cat_id")
+ private Long catId;
+
+ /** 外部商品类目名称 */
+ @JsonProperty("external_category_name")
+ private String externalCategoryName;
+
+ /** 主图列表 */
+ @JsonProperty("head_imgs")
+ private List headImgs;
+
+ /** 详情图列表 */
+ @JsonProperty("detail_imgs")
+ private List detailImgs;
+
+ /** 商品标题 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 外部商品属性列表 */
+ @JsonProperty("external_attributes")
+ private List externalAttributes;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingNewResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingNewResponse.java
new file mode 100644
index 0000000000..1427bc0671
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingNewResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+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 ExternalProductMappingNewResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 内部商品属性列表 */
+ @JsonProperty("attributes")
+ private List attributes;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingParam.java
new file mode 100644
index 0000000000..683115b758
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingParam.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 站内外商品属性映射 请求参数
+ *
+ * @author GitHub Copilot
+ * @see 站内外商品属性映射
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ExternalProductMappingParam implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 叶子类目id(必填) */
+ @JsonProperty("cat_id")
+ private Long catId;
+
+ /** 外部商品属性key(必填) */
+ @JsonProperty("external_attribute_name")
+ private String externalAttributeName;
+
+ /** 外部商品属性值 */
+ @JsonProperty("external_attribute_value")
+ private String externalAttributeValue;
+
+ /** 外部商品类目名称 */
+ @JsonProperty("external_category_name")
+ private String externalCategoryName;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingResponse.java
new file mode 100644
index 0000000000..de460032f9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExternalProductMappingResponse.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+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 ExternalProductMappingResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 外部商品属性key */
+ @JsonProperty("external_attribute_name")
+ private String externalAttributeName;
+
+ /** 外部商品属性值 */
+ @JsonProperty("external_attribute_value")
+ private String externalAttributeValue;
+
+ /** 内部商品属性key */
+ @JsonProperty("internal_attribute_name")
+ private String internalAttributeName;
+
+ /** 内部商品属性值(可能多选) */
+ @JsonProperty("internal_attribute_value")
+ private List internalAttributeValue;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductBrandRecommendParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductBrandRecommendParam.java
new file mode 100644
index 0000000000..a913980fdd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductBrandRecommendParam.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品品牌推荐 请求参数
+ *
+ * @author GitHub Copilot
+ * @see 商品品牌推荐
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ProductBrandRecommendParam implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 叶子类目id(必填) */
+ @JsonProperty("cat_id")
+ private Long catId;
+
+ /** 主图列表,至少传一张(必填) */
+ @JsonProperty("head_imgs")
+ private List headImgs;
+
+ /** 详情图列表 */
+ @JsonProperty("detail_imgs")
+ private List detailImgs;
+
+ /** 商品标题(必填) */
+ @JsonProperty("title")
+ private String title;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductBrandRecommendResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductBrandRecommendResponse.java
new file mode 100644
index 0000000000..a578bbf264
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductBrandRecommendResponse.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.product;
+
+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 ProductBrandRecommendResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 推荐的品牌ID */
+ @JsonProperty("brand_id")
+ private Long brandId;
+
+ /** 品牌中文名称 */
+ @JsonProperty("brand_name_chinese")
+ private String brandNameChinese;
+
+ /** 品牌英文名称 */
+ @JsonProperty("brand_name_english")
+ private String brandNameEnglish;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowExtInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowExtInfo.java
new file mode 100644
index 0000000000..f2b437f4d0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowExtInfo.java
@@ -0,0 +1,49 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 库存流水 额外信息
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+public class StockFlowExtInfo implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 归还的源库存子类型(仅对 op_type=7 生效) */
+ @JsonProperty("unmove_from_stock_sub_type")
+ private Integer unmoveFromStockSubType;
+
+ /** 分配的目标库存子类型(仅对 op_type=6 生效) */
+ @JsonProperty("move_to_stock_sub_type")
+ private Integer moveToStockSubType;
+
+ /**
+ * 操作来源(仅对 op_type=1/2/3 生效)。
+ * 2: API(开发者调用);3: API(服务商代调用);5: 手机端;6: web端
+ */
+ @JsonProperty("upload_source")
+ private Integer uploadSource;
+
+ /** 订单id(仅对 op_type=4/5 生效) */
+ @JsonProperty("order_id")
+ private Long orderId;
+
+ /** 区域仓库id(仅对 stock_sub_type=3 生效) */
+ @JsonProperty("out_warehouse_id")
+ private String outWarehouseId;
+
+ /** 限时抢购任务id(仅对 stock_sub_type=2 生效) */
+ @JsonProperty("limited_discount_id")
+ private Long limitedDiscountId;
+
+ /** 达人的视频号finder_id(对 move_to_stock_sub_type=4 和 unmove_from_stock_sub_type=4 生效) */
+ @JsonProperty("finder_id")
+ private String finderId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowInfo.java
new file mode 100644
index 0000000000..d49fd97a1f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowInfo.java
@@ -0,0 +1,55 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 单条库存流水信息
+ *
+ * @author GitHub Copilot
+ */
+@Data
+@NoArgsConstructor
+public class StockFlowInfo implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 操作数量 */
+ @JsonProperty("amount")
+ private Integer amount;
+
+ /** 开始数量 */
+ @JsonProperty("beginning_amount")
+ private Integer beginningAmount;
+
+ /** 结束数量 */
+ @JsonProperty("ending_amount")
+ private Integer endingAmount;
+
+ /**
+ * 本次开始结束数量的库存子类型。
+ * 1: 普通/通用库存;2: 限时抢购库存;3: 自营区域库存;4: 达人专属计划营销库存;
+ * 5: 直播预热专属库存;6: 赠品库存;7: B2C活动库存;8: 活动库存;
+ * 9: 限时抢购2.0库存;10: 不可售库存
+ */
+ @JsonProperty("stock_sub_type")
+ private Integer stockSubType;
+
+ /**
+ * 库存事件类型。
+ * 0: 设置库存;2: 增加库存;3: 减少库存;4: 下单扣除库存;5: 取消订单释放库存;
+ * 6: 分配库存;7: 归还库存;8: 售后换货扣除库存;9: 售后换货取消释放库存;10: 系统转移
+ */
+ @JsonProperty("op_type")
+ private Integer opType;
+
+ /** 流水发生时间(秒级时间戳) */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /** 额外信息 */
+ @JsonProperty("ext_info")
+ private StockFlowExtInfo extInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowParam.java
new file mode 100644
index 0000000000..6b44580b60
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowParam.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 获取库存流水 请求参数
+ *
+ * @author GitHub Copilot
+ * @see 获取库存流水
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class StockFlowParam implements Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 内部商品ID */
+ @JsonProperty("product_id")
+ private Long productId;
+
+ /** 内部 sku_id */
+ @JsonProperty("sku_id")
+ private Long skuId;
+
+ /**
+ * 库存类型。
+ * 0: 普通/通用库存;1: 达人专属计划营销库存;2: B2C活动;
+ * 3: 同城配送门店库存;4: 活动库存;5: 限时抢购2.0库存
+ */
+ @JsonProperty("stock_type")
+ private Integer stockType;
+
+ /** 达人的视频号finder_id,若 stock_type 为1则必填 */
+ @JsonProperty("finder_id")
+ private String finderId;
+
+ /** 时间范围开始时间戳(秒级) */
+ @JsonProperty("begin_time")
+ private Long beginTime;
+
+ /** 时间范围结束时间戳(秒级) */
+ @JsonProperty("end_time")
+ private Long endTime;
+
+ /** 库存事件类型列表(可选过滤条件) */
+ @JsonProperty("op_type_list")
+ private List opTypeList;
+
+ /** 每页数量 */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 翻页上下文,不传默认获取第一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+
+ /** 库存类型id,若 stock_type 不为0且不为1则必填 */
+ @JsonProperty("stock_type_id")
+ private String stockTypeId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowResponse.java
new file mode 100644
index 0000000000..db8d958dec
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/StockFlowResponse.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+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 StockFlowResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 返回数据 */
+ @JsonProperty("data")
+ private StockFlowData data;
+
+ /**
+ * 库存流水数据
+ */
+ @Data
+ @NoArgsConstructor
+ public static class StockFlowData implements java.io.Serializable {
+
+ private static final long serialVersionUID = -1L;
+
+ /** 库存流水列表 */
+ @JsonProperty("stock_flow_info_list")
+ private List stockFlowInfoList;
+
+ /** 本次翻页的上下文,用于请求下一页 */
+ @JsonProperty("next_key")
+ private String nextKey;
+ }
+}
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..2f8d1bfc8b 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
@@ -155,12 +155,45 @@ public interface Spu {
String SPU_UPDATE_STOCK_URL = "https://api.weixin.qq.com/channels/ec/product/stock/update";
/** 添加限时抢购任务 */
String ADD_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/add";
+ /** 更新限时抢购任务 */
+ String UPDATE_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/update";
/** 拉取限时抢购任务列表 */
String LIST_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/list/get";
/** 停止限时抢购任务 */
String STOP_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/stop";
/** 删除限时抢购任务 */
String DELETE_LIMIT_TASK_URL = "https://api.weixin.qq.com/channels/ec/product/limiteddiscounttask/delete";
+ /** 获取库存流水 */
+ String SPU_GET_STOCK_FLOW_URL = "https://api.weixin.qq.com/channels/ec/product/stock/getflow";
+ /** 发品前校验 */
+ String CATEGORY_PRE_CHECK_URL = "https://api.weixin.qq.com/channels/ec/product/categoryprecheck";
+ /** 商品品牌推荐 */
+ String PRODUCT_BRAND_RECOMMEND_URL = "https://api.weixin.qq.com/channels/ec/product/productbrandrecommend";
+ /** 站内外商品属性映射 */
+ String EXTERNAL_PRODUCT_MAPPING_URL = "https://api.weixin.qq.com/channels/ec/product/externalproductmapping";
+ /** 站内外商品属性映射v2 */
+ String EXTERNAL_PRODUCT_MAPPING_NEW_URL = "https://api.weixin.qq.com/channels/ec/product/externalproductmappingnew";
+ /** 商品立即开售 */
+ String BEGIN_TIMING_SALE_URL = "https://api.weixin.qq.com/channels/ec/product/begintimingsale";
+ /** 取消商品开售 */
+ String CANCEL_TIMING_SALE_URL = "https://api.weixin.qq.com/channels/ec/product/canceltimingsale";
+ }
+
+ /** 赠品管理相关接口 */
+ public interface Gift {
+
+ /** 添加非卖商品(赠品) */
+ String ADD_GIFT_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/product/gift/add";
+ /** 更新非卖商品(赠品) */
+ String UPDATE_GIFT_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/product/gift/update";
+ /** 在售商品转赠品 */
+ String SET_PRODUCT_AS_GIFT_URL = "https://api.weixin.qq.com/channels/ec/product/gift/onsale/set";
+ /** 获取赠品 */
+ String GET_GIFT_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/product/gift/get";
+ /** 获取赠品列表 */
+ String LIST_GIFT_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/product/gift/list/get";
+ /** 更新赠品库存 */
+ String UPDATE_GIFT_STOCK_URL = "https://api.weixin.qq.com/channels/ec/product/gift/stock/update";
}
/** 区域仓库 */