diff --git a/.gitee/ISSUE_TEMPLATE.md b/.gitee/ISSUE_TEMPLATE.md
index cdae693d35..a0b60ba750 100644
--- a/.gitee/ISSUE_TEMPLATE.md
+++ b/.gitee/ISSUE_TEMPLATE.md
@@ -1,4 +1,4 @@
-强烈建议大家到 `github` 相关页面提交问题,方便统一查询管理,具体页面地址:https://github.com/Wechat-Group/WxJava/issues
+强烈建议大家到 `github` 相关页面提交问题,方便统一查询管理,具体页面地址:https://github.com/binarywang/WxJava/issues
当然如果必须在这里提问,请务必按以下格式填写,谢谢配合~
diff --git a/.github/agents/my-agent.agent.md b/.github/agents/my-agent.agent.md
new file mode 100644
index 0000000000..0c8481288a
--- /dev/null
+++ b/.github/agents/my-agent.agent.md
@@ -0,0 +1,14 @@
+---
+# Fill in the fields below to create a basic custom agent for your repository.
+# The Copilot CLI can be used for local testing: https://gh.io/customagents/cli
+# To make this agent available, merge this file into the default repository branch.
+# For format details, see: https://gh.io/customagents/config
+
+name: 全部用中文
+description: 需要用中文,包括PR标题和分析总结过程
+---
+
+# My Agent
+
+1、请使用中文输出思考过程和总结,包括PR标题,提交commit信息也要使用中文;
+2、生成代码时需要提供必要的单元测试代码。
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
new file mode 100644
index 0000000000..cad29d96d9
--- /dev/null
+++ b/.github/copilot-instructions.md
@@ -0,0 +1,202 @@
+# Copilot Instruction
+请始终使用中文生成 Pull Request 的标题、描述和提交信息
+
+
+# WxJava - 微信 Java SDK 开发说明
+
+WxJava 是一个支持多种微信平台的完整 Java SDK,包含公众号、小程序、微信支付、企业微信、开放平台、视频号、企点等多种功能模块。
+
+**请始终优先参考本说明,只有在遇到与此内容不一致的意外信息时,才退而使用搜索或 bash 命令。**
+
+## 高效开发指南
+
+### 前置条件与环境准备
+- **Java 要求**:JDK 8+(项目最低目标为 Java 8)
+- **Maven**:推荐 Maven 3.6+(已验证 Maven 3.9.11)
+- **IDE**:推荐使用 IntelliJ IDEA(项目针对 IDEA 优化)
+
+### 引导、构建与校验
+克隆仓库后按顺序执行以下命令:
+
+```bash
+# 1. 基础编译(请勿中断 - 约需 4-5 分钟)
+mvn clean compile -DskipTests=true --no-transfer-progress
+# 超时时间:建议设置 8 分钟以上。实际时间:约 4 分钟
+
+# 2. 完整打包(请勿中断 - 约需 2-3 分钟)
+mvn clean package -DskipTests=true --no-transfer-progress
+# 超时时间:建议设置 5 分钟以上。实际时间:约 2 分钟
+
+# 3. 代码质量校验(请勿中断 - 约需 45-60 秒)
+mvn checkstyle:check --no-transfer-progress
+# 超时时间:建议设置 3 分钟以上。实际时间:约 50 秒
+```
+
+重要时间说明:
+- 绝对不要中断任意 Maven 构建命令
+- 编译阶段耗时最长(约 4 分钟),原因是项目包含 34 个模块
+- 后续构建会更快,因为存在增量编译
+- 始终使用 `--no-transfer-progress` 以减少日志噪音
+
+### 测试结构
+- **测试框架**:TestNG(非 JUnit)
+- **测试文件**:共有 298 个测试文件
+- **默认行为**:pom.xml 中默认禁用测试(`
-
-
-
- |
- ||
-
-
-
- |
- ||
-
-
-
- |
-
-
-
-
- |
-
-
-
-
- |
-
{@link me.chanjar.weixin.channel.api.WxChannelService#setMaxRetryTimes(int)}
+ *{@link me.chanjar.weixin.channel.api.impl.BaseWxChannelServiceImpl#setMaxRetryTimes(int)}
+ */ + private int maxRetryTimes = 5; + + /** + * http 请求重试间隔 + * + *{@link me.chanjar.weixin.channel.api.WxChannelService#setRetrySleepMillis(int)}
+ *{@link me.chanjar.weixin.channel.api.impl.BaseWxChannelServiceImpl#setRetrySleepMillis(int)}
+ */ + private int retrySleepMillis = 1000; + } +} diff --git a/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelMultiRedisProperties.java b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelMultiRedisProperties.java new file mode 100644 index 0000000000..36c649b311 --- /dev/null +++ b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelMultiRedisProperties.java @@ -0,0 +1,63 @@ +package com.binarywang.solon.wxjava.channel.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * Redis配置 + * + * @author Winnie + * @date 2024/9/13 + */ +@Data +@NoArgsConstructor +public class WxChannelMultiRedisProperties implements Serializable { + private static final long serialVersionUID = 9061055444734277357L; + + /** + * 主机地址. + */ + private String host = "127.0.0.1"; + + /** + * 端口号. + */ + private int port = 6379; + + /** + * 密码. + */ + private String password; + + /** + * 超时. + */ + private int timeout = 2000; + + /** + * 数据库. + */ + private int database = 0; + + /** + * 最大活动连接数 + */ + private Integer maxActive; + + /** + * 最大空闲连接数 + */ + private Integer maxIdle; + + /** + * 最小空闲连接数 + */ + private Integer minIdle; + + /** + * 最大等待时间 + */ + private Integer maxWaitMillis; +} diff --git a/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelSingleProperties.java b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelSingleProperties.java new file mode 100644 index 0000000000..438c3ecb03 --- /dev/null +++ b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/properties/WxChannelSingleProperties.java @@ -0,0 +1,43 @@ +package com.binarywang.solon.wxjava.channel.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 微信视频号相关配置属性 + * + * @author Winnie + * @date 2024/9/13 + */ +@Data +@NoArgsConstructor +public class WxChannelSingleProperties implements Serializable { + private static final long serialVersionUID = 5306630351265124825L; + + /** + * 设置微信视频号的 appid. + */ + private String appId; + + /** + * 设置微信视频号的 secret. + */ + private String secret; + + /** + * 设置微信视频号的 token. + */ + private String token; + + /** + * 设置微信视频号的 EncodingAESKey. + */ + private String aesKey; + + /** + * 是否使用稳定版 Access Token + */ + private boolean useStableAccessToken = false; +} diff --git a/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/service/WxChannelMultiServices.java b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/service/WxChannelMultiServices.java new file mode 100644 index 0000000000..f12461e197 --- /dev/null +++ b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/service/WxChannelMultiServices.java @@ -0,0 +1,26 @@ +package com.binarywang.solon.wxjava.channel.service; + +import me.chanjar.weixin.channel.api.WxChannelService; + +/** + * 视频号 {@link WxChannelService} 所有实例存放类. + * + * @author Winnie + * @date 2024/9/13 + */ +public interface WxChannelMultiServices { + /** + * 通过租户 Id 获取 WxChannelService + * + * @param tenantId 租户 Id + * @return WxChannelService + */ + WxChannelService getWxChannelService(String tenantId); + + /** + * 根据租户 Id,从列表中移除一个 WxChannelService 实例 + * + * @param tenantId 租户 Id + */ + void removeWxChannelService(String tenantId); +} diff --git a/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/service/WxChannelMultiServicesImpl.java b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/service/WxChannelMultiServicesImpl.java new file mode 100644 index 0000000000..8420e29d73 --- /dev/null +++ b/solon-plugins/wx-java-channel-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/channel/service/WxChannelMultiServicesImpl.java @@ -0,0 +1,36 @@ +package com.binarywang.solon.wxjava.channel.service; + +import me.chanjar.weixin.channel.api.WxChannelService; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 视频号 {@link WxChannelMultiServices} 实现 + * + * @author Winnie + * @date 2024/9/13 + */ +public class WxChannelMultiServicesImpl implements WxChannelMultiServices { + private final Map
+ * {@link me.chanjar.weixin.channel.api.BaseWxChannelService#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+ /**
+ * http 请求最大重试次数
+ *
+ * {@link me.chanjar.weixin.channel.api.BaseWxChannelService#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+ }
+
+}
diff --git a/solon-plugins/wx-java-channel-solon-plugin/src/main/resources/META-INF/solon/wx-java-channel-solon-plugin.properties b/solon-plugins/wx-java-channel-solon-plugin/src/main/resources/META-INF/solon/wx-java-channel-solon-plugin.properties
new file mode 100644
index 0000000000..d8ec8f5112
--- /dev/null
+++ b/solon-plugins/wx-java-channel-solon-plugin/src/main/resources/META-INF/solon/wx-java-channel-solon-plugin.properties
@@ -0,0 +1,2 @@
+solon.plugin=com.binarywang.solon.wxjava.channel.integration.WxChannelPluginImpl
+solon.plugin.priority=10
diff --git a/solon-plugins/wx-java-channel-solon-plugin/src/test/java/features/test/LoadTest.java b/solon-plugins/wx-java-channel-solon-plugin/src/test/java/features/test/LoadTest.java
new file mode 100644
index 0000000000..d049f5a51a
--- /dev/null
+++ b/solon-plugins/wx-java-channel-solon-plugin/src/test/java/features/test/LoadTest.java
@@ -0,0 +1,15 @@
+package features.test;
+
+import org.junit.jupiter.api.Test;
+import org.noear.solon.test.SolonTest;
+
+/**
+ * @author noear 2024/9/4 created
+ */
+@SolonTest
+public class LoadTest {
+ @Test
+ public void load(){
+
+ }
+}
diff --git a/solon-plugins/wx-java-channel-solon-plugin/src/test/resources/app.yml b/solon-plugins/wx-java-channel-solon-plugin/src/test/resources/app.yml
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/solon-plugins/wx-java-cp-multi-solon-plugin/README.md b/solon-plugins/wx-java-cp-multi-solon-plugin/README.md
new file mode 100644
index 0000000000..97bcf0723f
--- /dev/null
+++ b/solon-plugins/wx-java-cp-multi-solon-plugin/README.md
@@ -0,0 +1,97 @@
+# wx-java-cp-multi-solon-plugin
+
+企业微信多账号配置
+
+- 实现多 WxCpService 初始化。
+- 未实现 WxCpTpService 初始化,需要的小伙伴可以参考多 WxCpService 配置的实现。
+- 未实现 WxCpCgService 初始化,需要的小伙伴可以参考多 WxCpService 配置的实现。
+
+## 快速开始
+
+1. 引入依赖
+ ```xml
+
+ * {@link me.chanjar.weixin.cp.api.WxCpService#setMaxRetryTimes(int)}
+ * {@link me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+
+ /**
+ * http 请求重试间隔
+ *
+ * {@link me.chanjar.weixin.cp.api.WxCpService#setRetrySleepMillis(int)}
+ * {@link me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+ }
+
+ public enum StorageType {
+ /**
+ * 内存
+ */
+ memory,
+ /**
+ * jedis
+ */
+ jedis,
+ /**
+ * redisson
+ */
+ redisson,
+ /**
+ * redistemplate
+ */
+ redistemplate
+ }
+
+ public enum HttpClientType {
+ /**
+ * HttpClient
+ */
+ HTTP_CLIENT,
+ /**
+ * HttpComponents
+ */
+ HTTP_COMPONENTS,
+ /**
+ * OkHttp
+ */
+ OK_HTTP,
+ /**
+ * JoddHttp
+ */
+ JODD_HTTP
+ }
+}
diff --git a/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpMultiRedisProperties.java b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpMultiRedisProperties.java
new file mode 100644
index 0000000000..14952d69d9
--- /dev/null
+++ b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpMultiRedisProperties.java
@@ -0,0 +1,48 @@
+package com.binarywang.solon.wxjava.cp_multi.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * Redis配置.
+ *
+ * @author yl
+ * created on 2023/10/16
+ */
+@Data
+@NoArgsConstructor
+public class WxCpMultiRedisProperties implements Serializable {
+ private static final long serialVersionUID = -5924815351660074401L;
+
+ /**
+ * 主机地址.
+ */
+ private String host;
+
+ /**
+ * 端口号.
+ */
+ private int port = 6379;
+
+ /**
+ * 密码.
+ */
+ private String password;
+
+ /**
+ * 超时.
+ */
+ private int timeout = 2000;
+
+ /**
+ * 数据库.
+ */
+ private int database = 0;
+
+ private Integer maxActive;
+ private Integer maxIdle;
+ private Integer maxWaitMillis;
+ private Integer minIdle;
+}
diff --git a/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpSingleProperties.java b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpSingleProperties.java
new file mode 100644
index 0000000000..e761a09062
--- /dev/null
+++ b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/properties/WxCpSingleProperties.java
@@ -0,0 +1,46 @@
+package com.binarywang.solon.wxjava.cp_multi.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 企业微信企业相关配置属性
+ *
+ * @author yl
+ * created on 2023/10/16
+ */
+@Data
+@NoArgsConstructor
+public class WxCpSingleProperties implements Serializable {
+ private static final long serialVersionUID = -7502823825007859418L;
+ /**
+ * 微信企业号 corpId
+ */
+ private String corpId;
+ /**
+ * 微信企业号 corpSecret
+ */
+ private String corpSecret;
+ /**
+ * 微信企业号应用 token
+ */
+ private String token;
+ /**
+ * 微信企业号应用 ID
+ */
+ private Integer agentId;
+ /**
+ * 微信企业号应用 EncodingAESKey
+ */
+ private String aesKey;
+ /**
+ * 微信企业号应用 会话存档私钥
+ */
+ private String msgAuditPriKey;
+ /**
+ * 微信企业号应用 会话存档类库路径
+ */
+ private String msgAuditLibPath;
+}
diff --git a/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/service/WxCpMultiServices.java b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/service/WxCpMultiServices.java
new file mode 100644
index 0000000000..c66c28233d
--- /dev/null
+++ b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/service/WxCpMultiServices.java
@@ -0,0 +1,26 @@
+package com.binarywang.solon.wxjava.cp_multi.service;
+
+import me.chanjar.weixin.cp.api.WxCpService;
+
+/**
+ * 企业微信 {@link WxCpService} 所有实例存放类.
+ *
+ * @author yl
+ * created on 2023/10/16
+ */
+public interface WxCpMultiServices {
+ /**
+ * 通过租户 Id 获取 WxCpService
+ *
+ * @param tenantId 租户 Id
+ * @return WxCpService
+ */
+ WxCpService getWxCpService(String tenantId);
+
+ /**
+ * 根据租户 Id,从列表中移除一个 WxCpService 实例
+ *
+ * @param tenantId 租户 Id
+ */
+ void removeWxCpService(String tenantId);
+}
diff --git a/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/service/WxCpMultiServicesImpl.java b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/service/WxCpMultiServicesImpl.java
new file mode 100644
index 0000000000..d7833a05f9
--- /dev/null
+++ b/solon-plugins/wx-java-cp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp_multi/service/WxCpMultiServicesImpl.java
@@ -0,0 +1,42 @@
+package com.binarywang.solon.wxjava.cp_multi.service;
+
+import me.chanjar.weixin.cp.api.WxCpService;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 企业微信 {@link WxCpMultiServices} 默认实现
+ *
+ * @author yl
+ * created on 2023/10/16
+ */
+public class WxCpMultiServicesImpl implements WxCpMultiServices {
+ private final Map
+ * {@link me.chanjar.weixin.cp.api.WxCpService#setMaxRetryTimes(int)}
+ * {@link me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+
+ /**
+ * http 请求重试间隔
+ *
+ * {@link me.chanjar.weixin.cp.api.WxCpService#setRetrySleepMillis(int)}
+ * {@link me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+ }
+
+ public enum StorageType {
+ /**
+ * 内存
+ */
+ memory,
+ /**
+ * jedis
+ */
+ jedis,
+ /**
+ * redisson
+ */
+ redisson,
+ /**
+ * redistemplate
+ */
+ redistemplate
+ }
+}
diff --git a/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/properties/WxCpRedisProperties.java b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/properties/WxCpRedisProperties.java
new file mode 100644
index 0000000000..43b8788d3f
--- /dev/null
+++ b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/properties/WxCpRedisProperties.java
@@ -0,0 +1,46 @@
+package com.binarywang.solon.wxjava.cp.properties;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Redis配置.
+ *
+ * @author yl
+ * created on 2023/04/23
+ */
+@Data
+public class WxCpRedisProperties implements Serializable {
+ private static final long serialVersionUID = -5924815351660074401L;
+
+ /**
+ * 主机地址.
+ */
+ private String host;
+
+ /**
+ * 端口号.
+ */
+ private int port = 6379;
+
+ /**
+ * 密码.
+ */
+ private String password;
+
+ /**
+ * 超时.
+ */
+ private int timeout = 2000;
+
+ /**
+ * 数据库.
+ */
+ private int database = 0;
+
+ private Integer maxActive;
+ private Integer maxIdle;
+ private Integer maxWaitMillis;
+ private Integer minIdle;
+}
diff --git a/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/AbstractWxCpConfigStorageConfiguration.java b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/AbstractWxCpConfigStorageConfiguration.java
new file mode 100644
index 0000000000..9fcdd5779a
--- /dev/null
+++ b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/AbstractWxCpConfigStorageConfiguration.java
@@ -0,0 +1,61 @@
+package com.binarywang.solon.wxjava.cp.storage;
+
+import com.binarywang.solon.wxjava.cp.properties.WxCpProperties;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * WxCpConfigStorage 抽象配置类
+ *
+ * @author yl & Wang_Wong
+ * created on 2021/12/6
+ */
+public abstract class AbstractWxCpConfigStorageConfiguration {
+
+ protected WxCpDefaultConfigImpl config(WxCpDefaultConfigImpl config, WxCpProperties properties) {
+ String corpId = properties.getCorpId();
+ String corpSecret = properties.getCorpSecret();
+ Integer agentId = properties.getAgentId();
+ String token = properties.getToken();
+ String aesKey = properties.getAesKey();
+ // 企业微信,私钥,会话存档路径
+ String msgAuditPriKey = properties.getMsgAuditPriKey();
+ String msgAuditLibPath = properties.getMsgAuditLibPath();
+
+ config.setCorpId(corpId);
+ config.setCorpSecret(corpSecret);
+ config.setAgentId(agentId);
+ if (StringUtils.isNotBlank(token)) {
+ config.setToken(token);
+ }
+ if (StringUtils.isNotBlank(aesKey)) {
+ config.setAesKey(aesKey);
+ }
+ if (StringUtils.isNotBlank(msgAuditPriKey)) {
+ config.setMsgAuditPriKey(msgAuditPriKey);
+ }
+ if (StringUtils.isNotBlank(msgAuditLibPath)) {
+ config.setMsgAuditLibPath(msgAuditLibPath);
+ }
+
+ WxCpProperties.ConfigStorage storage = properties.getConfigStorage();
+ String httpProxyHost = storage.getHttpProxyHost();
+ Integer httpProxyPort = storage.getHttpProxyPort();
+ String httpProxyUsername = storage.getHttpProxyUsername();
+ String httpProxyPassword = storage.getHttpProxyPassword();
+ if (StringUtils.isNotBlank(httpProxyHost)) {
+ config.setHttpProxyHost(httpProxyHost);
+ if (httpProxyPort != null) {
+ config.setHttpProxyPort(httpProxyPort);
+ }
+ if (StringUtils.isNotBlank(httpProxyUsername)) {
+ config.setHttpProxyUsername(httpProxyUsername);
+ }
+ if (StringUtils.isNotBlank(httpProxyPassword)) {
+ config.setHttpProxyPassword(httpProxyPassword);
+ }
+ }
+ return config;
+ }
+
+}
diff --git a/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInJedisConfigStorageConfiguration.java b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInJedisConfigStorageConfiguration.java
new file mode 100644
index 0000000000..f6f6931992
--- /dev/null
+++ b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInJedisConfigStorageConfiguration.java
@@ -0,0 +1,74 @@
+package com.binarywang.solon.wxjava.cp.storage;
+
+import com.binarywang.solon.wxjava.cp.properties.WxCpProperties;
+import com.binarywang.solon.wxjava.cp.properties.WxCpRedisProperties;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import me.chanjar.weixin.cp.config.impl.WxCpJedisConfigImpl;
+import org.apache.commons.lang3.StringUtils;
+import org.noear.solon.annotation.Bean;
+import org.noear.solon.annotation.Condition;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.core.AppContext;
+import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.JedisPoolConfig;
+
+/**
+ * 自动装配基于 jedis 策略配置
+ *
+ * @author yl
+ * created on 2023/04/23
+ */
+@Configuration
+@Condition(
+ onProperty = "${"+WxCpProperties.PREFIX + ".configStorage.type} = jedis",
+ onClass = JedisPool.class
+)
+@RequiredArgsConstructor
+public class WxCpInJedisConfigStorageConfiguration extends AbstractWxCpConfigStorageConfiguration {
+ private final WxCpProperties wxCpProperties;
+ private final AppContext applicationContext;
+
+ @Bean
+ @Condition(onMissingBean=WxCpConfigStorage.class)
+ public WxCpConfigStorage wxCpConfigStorage() {
+ WxCpDefaultConfigImpl config = getConfigStorage();
+ return this.config(config, wxCpProperties);
+ }
+
+ private WxCpJedisConfigImpl getConfigStorage() {
+ WxCpRedisProperties wxCpRedisProperties = wxCpProperties.getConfigStorage().getRedis();
+ JedisPool jedisPool;
+ if (wxCpRedisProperties != null && StringUtils.isNotEmpty(wxCpRedisProperties.getHost())) {
+ jedisPool = getJedisPool();
+ } else {
+ jedisPool = applicationContext.getBean(JedisPool.class);
+ }
+ return new WxCpJedisConfigImpl(jedisPool, wxCpProperties.getConfigStorage().getKeyPrefix());
+ }
+
+ private JedisPool getJedisPool() {
+ WxCpProperties.ConfigStorage storage = wxCpProperties.getConfigStorage();
+ WxCpRedisProperties redis = storage.getRedis();
+
+ JedisPoolConfig config = new JedisPoolConfig();
+ if (redis.getMaxActive() != null) {
+ config.setMaxTotal(redis.getMaxActive());
+ }
+ if (redis.getMaxIdle() != null) {
+ config.setMaxIdle(redis.getMaxIdle());
+ }
+ if (redis.getMaxWaitMillis() != null) {
+ config.setMaxWaitMillis(redis.getMaxWaitMillis());
+ }
+ if (redis.getMinIdle() != null) {
+ config.setMinIdle(redis.getMinIdle());
+ }
+ config.setTestOnBorrow(true);
+ config.setTestWhileIdle(true);
+
+ return new JedisPool(config, redis.getHost(), redis.getPort(),
+ redis.getTimeout(), redis.getPassword(), redis.getDatabase());
+ }
+}
diff --git a/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInMemoryConfigStorageConfiguration.java b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInMemoryConfigStorageConfiguration.java
new file mode 100644
index 0000000000..2776fea368
--- /dev/null
+++ b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInMemoryConfigStorageConfiguration.java
@@ -0,0 +1,31 @@
+package com.binarywang.solon.wxjava.cp.storage;
+
+import com.binarywang.solon.wxjava.cp.properties.WxCpProperties;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import org.noear.solon.annotation.Bean;
+import org.noear.solon.annotation.Condition;
+import org.noear.solon.annotation.Configuration;
+
+/**
+ * 自动装配基于内存策略配置
+ *
+ * @author yl
+ * created on 2021/12/6
+ */
+@Configuration
+@Condition(
+ onProperty = "${"+WxCpProperties.PREFIX + ".configStorage.type:memory} = memory"
+)
+@RequiredArgsConstructor
+public class WxCpInMemoryConfigStorageConfiguration extends AbstractWxCpConfigStorageConfiguration {
+ private final WxCpProperties wxCpProperties;
+
+ @Bean
+ @Condition(onMissingBean=WxCpConfigStorage.class)
+ public WxCpConfigStorage wxCpConfigStorage() {
+ WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
+ return this.config(config, wxCpProperties);
+ }
+}
diff --git a/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInRedissonConfigStorageConfiguration.java b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInRedissonConfigStorageConfiguration.java
new file mode 100644
index 0000000000..0aef4d520a
--- /dev/null
+++ b/solon-plugins/wx-java-cp-solon-plugin/src/main/java/com/binarywang/solon/wxjava/cp/storage/WxCpInRedissonConfigStorageConfiguration.java
@@ -0,0 +1,65 @@
+package com.binarywang.solon.wxjava.cp.storage;
+
+import com.binarywang.solon.wxjava.cp.properties.WxCpProperties;
+import com.binarywang.solon.wxjava.cp.properties.WxCpRedisProperties;
+import lombok.RequiredArgsConstructor;
+import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import me.chanjar.weixin.cp.config.impl.WxCpRedissonConfigImpl;
+import org.apache.commons.lang3.StringUtils;
+import org.noear.solon.annotation.Bean;
+import org.noear.solon.annotation.Condition;
+import org.noear.solon.annotation.Configuration;
+import org.noear.solon.core.AppContext;
+import org.redisson.Redisson;
+import org.redisson.api.RedissonClient;
+import org.redisson.config.Config;
+import org.redisson.config.TransportMode;
+
+/**
+ * 自动装配基于 redisson 策略配置
+ *
+ * @author yl
+ * created on 2023/04/23
+ */
+@Configuration
+@Condition(
+ onProperty = "${"+WxCpProperties.PREFIX + ".configStorage.type} = redisson",
+ onClass = Redisson.class
+)
+@RequiredArgsConstructor
+public class WxCpInRedissonConfigStorageConfiguration extends AbstractWxCpConfigStorageConfiguration {
+ private final WxCpProperties wxCpProperties;
+ private final AppContext applicationContext;
+
+ @Bean
+ @Condition(onMissingBean=WxCpConfigStorage.class)
+ public WxCpConfigStorage wxCpConfigStorage() {
+ WxCpDefaultConfigImpl config = getConfigStorage();
+ return this.config(config, wxCpProperties);
+ }
+
+ private WxCpRedissonConfigImpl getConfigStorage() {
+ WxCpRedisProperties redisProperties = wxCpProperties.getConfigStorage().getRedis();
+ RedissonClient redissonClient;
+ if (redisProperties != null && StringUtils.isNotEmpty(redisProperties.getHost())) {
+ redissonClient = getRedissonClient();
+ } else {
+ redissonClient = applicationContext.getBean(RedissonClient.class);
+ }
+ return new WxCpRedissonConfigImpl(redissonClient, wxCpProperties.getConfigStorage().getKeyPrefix());
+ }
+
+ private RedissonClient getRedissonClient() {
+ WxCpProperties.ConfigStorage storage = wxCpProperties.getConfigStorage();
+ WxCpRedisProperties redis = storage.getRedis();
+
+ Config config = new Config();
+ config.useSingleServer()
+ .setAddress("redis://" + redis.getHost() + ":" + redis.getPort())
+ .setDatabase(redis.getDatabase())
+ .setPassword(redis.getPassword());
+ config.setTransportMode(TransportMode.NIO);
+ return Redisson.create(config);
+ }
+}
diff --git a/solon-plugins/wx-java-cp-solon-plugin/src/main/resources/META-INF/solon/wx-java-cp-solon-plugin.properties b/solon-plugins/wx-java-cp-solon-plugin/src/main/resources/META-INF/solon/wx-java-cp-solon-plugin.properties
new file mode 100644
index 0000000000..c765affecb
--- /dev/null
+++ b/solon-plugins/wx-java-cp-solon-plugin/src/main/resources/META-INF/solon/wx-java-cp-solon-plugin.properties
@@ -0,0 +1,2 @@
+solon.plugin=com.binarywang.solon.wxjava.cp.integration.WxCpPluginImpl
+solon.plugin.priority=10
diff --git a/solon-plugins/wx-java-cp-solon-plugin/src/test/java/features/test/LoadTest.java b/solon-plugins/wx-java-cp-solon-plugin/src/test/java/features/test/LoadTest.java
new file mode 100644
index 0000000000..d049f5a51a
--- /dev/null
+++ b/solon-plugins/wx-java-cp-solon-plugin/src/test/java/features/test/LoadTest.java
@@ -0,0 +1,15 @@
+package features.test;
+
+import org.junit.jupiter.api.Test;
+import org.noear.solon.test.SolonTest;
+
+/**
+ * @author noear 2024/9/4 created
+ */
+@SolonTest
+public class LoadTest {
+ @Test
+ public void load(){
+
+ }
+}
diff --git a/solon-plugins/wx-java-cp-solon-plugin/src/test/resources/app.properties b/solon-plugins/wx-java-cp-solon-plugin/src/test/resources/app.properties
new file mode 100644
index 0000000000..0c99c8b64d
--- /dev/null
+++ b/solon-plugins/wx-java-cp-solon-plugin/src/test/resources/app.properties
@@ -0,0 +1,20 @@
+# ???????(??)
+wx.cp.corp-id = @corp-id
+wx.cp.corp-secret = @corp-secret
+# ??
+wx.cp.agent-id = @agent-id
+wx.cp.token = @token
+wx.cp.aes-key = @aes-key
+wx.cp.msg-audit-priKey = @msg-audit-priKey
+wx.cp.msg-audit-lib-path = @msg-audit-lib-path
+# ConfigStorage ??????
+wx.cp.config-storage.type=memory # ????: memory(??), jedis, redisson, redistemplate
+# http ?????????
+wx.cp.config-storage.http-proxy-host=
+wx.cp.config-storage.http-proxy-port=
+wx.cp.config-storage.http-proxy-username=
+wx.cp.config-storage.http-proxy-password=
+# ??????????5 ?????? 0??? 0
+wx.cp.config-storage.max-retry-times=5
+# ????????????1000 ??????? 0??? 1000
+wx.cp.config-storage.retry-sleep-millis=1000
diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/README.md b/solon-plugins/wx-java-miniapp-multi-solon-plugin/README.md
new file mode 100644
index 0000000000..4555a4fc5e
--- /dev/null
+++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/README.md
@@ -0,0 +1,95 @@
+# wx-java-miniapp-multi-solon-plugin
+
+## 快速开始
+
+1. 引入依赖
+ ```xml
+
+ * {@link cn.binarywang.wx.miniapp.api.WxMaService#setMaxRetryTimes(int)}
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+
+ /**
+ * http 请求重试间隔
+ *
+ * {@link cn.binarywang.wx.miniapp.api.WxMaService#setRetrySleepMillis(int)}
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+ }
+
+ public enum StorageType {
+ /**
+ * 内存
+ */
+ MEMORY,
+ /**
+ * jedis
+ */
+ JEDIS,
+ /**
+ * redisson
+ */
+ REDISSON,
+ /**
+ * redisTemplate
+ */
+ REDIS_TEMPLATE
+ }
+
+ public enum HttpClientType {
+ /**
+ * HttpClient
+ */
+ HTTP_CLIENT,
+ /**
+ * OkHttp
+ */
+ OK_HTTP,
+ /**
+ * JoddHttp
+ */
+ JODD_HTTP,
+ /**
+ * HttpComponents
+ */
+ HTTP_COMPONENTS
+ }
+}
diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaMultiRedisProperties.java b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaMultiRedisProperties.java
new file mode 100644
index 0000000000..1f4c07806e
--- /dev/null
+++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaMultiRedisProperties.java
@@ -0,0 +1,56 @@
+package com.binarywang.solon.wxjava.miniapp.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author monch
+ * created on 2024/9/6
+ */
+@Data
+@NoArgsConstructor
+public class WxMaMultiRedisProperties implements Serializable {
+ private static final long serialVersionUID = -5924815351660074401L;
+
+ /**
+ * 主机地址.
+ */
+ private String host = "127.0.0.1";
+
+ /**
+ * 端口号.
+ */
+ private int port = 6379;
+
+ /**
+ * 密码.
+ */
+ private String password;
+
+ /**
+ * 超时.
+ */
+ private int timeout = 2000;
+
+ /**
+ * 数据库.
+ */
+ private int database = 0;
+
+ /**
+ * sentinel ips
+ */
+ private String sentinelIps;
+
+ /**
+ * sentinel name
+ */
+ private String sentinelName;
+
+ private Integer maxActive;
+ private Integer maxIdle;
+ private Integer maxWaitMillis;
+ private Integer minIdle;
+}
diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaSingleProperties.java b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaSingleProperties.java
new file mode 100644
index 0000000000..f61985716e
--- /dev/null
+++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/properties/WxMaSingleProperties.java
@@ -0,0 +1,40 @@
+package com.binarywang.solon.wxjava.miniapp.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author monch
+ * created on 2024/9/6
+ */
+@Data
+@NoArgsConstructor
+public class WxMaSingleProperties implements Serializable {
+ private static final long serialVersionUID = 1980986361098922525L;
+ /**
+ * 设置微信公众号的 appid.
+ */
+ private String appId;
+
+ /**
+ * 设置微信公众号的 app secret.
+ */
+ private String appSecret;
+
+ /**
+ * 设置微信公众号的 token.
+ */
+ private String token;
+
+ /**
+ * 设置微信公众号的 EncodingAESKey.
+ */
+ private String aesKey;
+
+ /**
+ * 是否使用稳定版 Access Token
+ */
+ private boolean useStableAccessToken = false;
+}
diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/service/WxMaMultiServices.java b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/service/WxMaMultiServices.java
new file mode 100644
index 0000000000..80d073cceb
--- /dev/null
+++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/service/WxMaMultiServices.java
@@ -0,0 +1,27 @@
+package com.binarywang.solon.wxjava.miniapp.service;
+
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+
+/**
+ * 微信小程序 {@link WxMaService} 所有实例存放类.
+ *
+ * @author monch
+ * created on 2024/9/6
+ */
+public interface WxMaMultiServices {
+ /**
+ * 通过租户 Id 获取 WxMaService
+ *
+ * @param tenantId 租户 Id
+ * @return WxMaService
+ */
+ WxMaService getWxMaService(String tenantId);
+
+ /**
+ * 根据租户 Id,从列表中移除一个 WxMaService 实例
+ *
+ * @param tenantId 租户 Id
+ */
+ void removeWxMaService(String tenantId);
+}
diff --git a/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/service/WxMaMultiServicesImpl.java b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/service/WxMaMultiServicesImpl.java
new file mode 100644
index 0000000000..d0ba21cdb8
--- /dev/null
+++ b/solon-plugins/wx-java-miniapp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/miniapp/service/WxMaMultiServicesImpl.java
@@ -0,0 +1,36 @@
+package com.binarywang.solon.wxjava.miniapp.service;
+
+import cn.binarywang.wx.miniapp.api.WxMaService;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 微信小程序 {@link WxMaMultiServices} 默认实现
+ *
+ * @author monch
+ * created on 2024/9/6
+ */
+public class WxMaMultiServicesImpl implements WxMaMultiServices {
+ private final Map
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+ /**
+ * http 请求最大重试次数
+ *
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+ }
+
+}
diff --git a/solon-plugins/wx-java-miniapp-solon-plugin/src/main/resources/META-INF/solon/wx-java-miniapp-solon-plugin.properties b/solon-plugins/wx-java-miniapp-solon-plugin/src/main/resources/META-INF/solon/wx-java-miniapp-solon-plugin.properties
new file mode 100644
index 0000000000..ba1049647e
--- /dev/null
+++ b/solon-plugins/wx-java-miniapp-solon-plugin/src/main/resources/META-INF/solon/wx-java-miniapp-solon-plugin.properties
@@ -0,0 +1,2 @@
+solon.plugin=com.binarywang.solon.wxjava.miniapp.integration.WxMiniappPluginImpl
+solon.plugin.priority=10
diff --git a/solon-plugins/wx-java-miniapp-solon-plugin/src/test/java/features/test/LoadTest.java b/solon-plugins/wx-java-miniapp-solon-plugin/src/test/java/features/test/LoadTest.java
new file mode 100644
index 0000000000..d049f5a51a
--- /dev/null
+++ b/solon-plugins/wx-java-miniapp-solon-plugin/src/test/java/features/test/LoadTest.java
@@ -0,0 +1,15 @@
+package features.test;
+
+import org.junit.jupiter.api.Test;
+import org.noear.solon.test.SolonTest;
+
+/**
+ * @author noear 2024/9/4 created
+ */
+@SolonTest
+public class LoadTest {
+ @Test
+ public void load(){
+
+ }
+}
diff --git a/solon-plugins/wx-java-miniapp-solon-plugin/src/test/resources/app.properties b/solon-plugins/wx-java-miniapp-solon-plugin/src/test/resources/app.properties
new file mode 100644
index 0000000000..22a9a4e627
--- /dev/null
+++ b/solon-plugins/wx-java-miniapp-solon-plugin/src/test/resources/app.properties
@@ -0,0 +1,18 @@
+# ?????(??)
+wx.miniapp.appid = appId
+wx.miniapp.secret = @secret
+wx.miniapp.token = @token
+wx.miniapp.aesKey = @aesKey
+wx.miniapp.msgDataFormat = @msgDataFormat # ?????XML??JSON.
+# ????redis(??)
+# ??: ??redis.host???????????redis??(JedisPool)
+wx.miniapp.config-storage.type = Jedis # ????: Memory(??), Jedis, RedisTemplate
+wx.miniapp.config-storage.key-prefix = wa # ??redis????: wa(??)
+wx.miniapp.config-storage.redis.host = 127.0.0.1
+wx.miniapp.config-storage.redis.port = 6379
+# http?????
+wx.miniapp.config-storage.http-client-type=HttpClient # http?????: HttpClient(??), OkHttp, JoddHttp
+wx.miniapp.config-storage.http-proxy-host=
+wx.miniapp.config-storage.http-proxy-port=
+wx.miniapp.config-storage.http-proxy-username=
+wx.miniapp.config-storage.http-proxy-password=
diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/README.md b/solon-plugins/wx-java-mp-multi-solon-plugin/README.md
new file mode 100644
index 0000000000..0d2b332d5a
--- /dev/null
+++ b/solon-plugins/wx-java-mp-multi-solon-plugin/README.md
@@ -0,0 +1,100 @@
+# wx-java-mp-multi-solon-plugin
+
+## 快速开始
+
+1. 引入依赖
+ ```xml
+
+ * {@link me.chanjar.weixin.mp.api.WxMpService#setMaxRetryTimes(int)}
+ * {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+
+ /**
+ * http 请求重试间隔
+ *
+ * {@link me.chanjar.weixin.mp.api.WxMpService#setRetrySleepMillis(int)}
+ * {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+ }
+
+ public enum StorageType {
+ /**
+ * 内存
+ */
+ MEMORY,
+ /**
+ * jedis
+ */
+ JEDIS,
+ /**
+ * redisson
+ */
+ REDISSON,
+ /**
+ * redisTemplate
+ */
+ REDIS_TEMPLATE
+ }
+
+ public enum HttpClientType {
+ /**
+ * HttpClient
+ */
+ HTTP_CLIENT,
+ /**
+ * OkHttp
+ */
+ OK_HTTP,
+ /**
+ * JoddHttp
+ */
+ JODD_HTTP,
+ /**
+ * HttpComponents
+ */
+ HTTP_COMPONENTS
+ }
+}
diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpMultiRedisProperties.java b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpMultiRedisProperties.java
new file mode 100644
index 0000000000..12646d4eaf
--- /dev/null
+++ b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpMultiRedisProperties.java
@@ -0,0 +1,56 @@
+package com.binarywang.solon.wxjava.mp_multi.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author yl
+ * created on 2024/1/23
+ */
+@Data
+@NoArgsConstructor
+public class WxMpMultiRedisProperties implements Serializable {
+ private static final long serialVersionUID = -5924815351660074401L;
+
+ /**
+ * 主机地址.
+ */
+ private String host = "127.0.0.1";
+
+ /**
+ * 端口号.
+ */
+ private int port = 6379;
+
+ /**
+ * 密码.
+ */
+ private String password;
+
+ /**
+ * 超时.
+ */
+ private int timeout = 2000;
+
+ /**
+ * 数据库.
+ */
+ private int database = 0;
+
+ /**
+ * sentinel ips
+ */
+ private String sentinelIps;
+
+ /**
+ * sentinel name
+ */
+ private String sentinelName;
+
+ private Integer maxActive;
+ private Integer maxIdle;
+ private Integer maxWaitMillis;
+ private Integer minIdle;
+}
diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpSingleProperties.java b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpSingleProperties.java
new file mode 100644
index 0000000000..22938cb67c
--- /dev/null
+++ b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/properties/WxMpSingleProperties.java
@@ -0,0 +1,40 @@
+package com.binarywang.solon.wxjava.mp_multi.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * @author yl
+ * created on 2024/1/23
+ */
+@Data
+@NoArgsConstructor
+public class WxMpSingleProperties implements Serializable {
+ private static final long serialVersionUID = 1980986361098922525L;
+ /**
+ * 设置微信公众号的 appid.
+ */
+ private String appId;
+
+ /**
+ * 设置微信公众号的 app secret.
+ */
+ private String appSecret;
+
+ /**
+ * 设置微信公众号的 token.
+ */
+ private String token;
+
+ /**
+ * 设置微信公众号的 EncodingAESKey.
+ */
+ private String aesKey;
+
+ /**
+ * 是否使用稳定版 Access Token
+ */
+ private boolean useStableAccessToken = false;
+}
diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/service/WxMpMultiServices.java b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/service/WxMpMultiServices.java
new file mode 100644
index 0000000000..a59b5962ad
--- /dev/null
+++ b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/service/WxMpMultiServices.java
@@ -0,0 +1,27 @@
+package com.binarywang.solon.wxjava.mp_multi.service;
+
+
+import me.chanjar.weixin.mp.api.WxMpService;
+
+/**
+ * 企业微信 {@link WxMpService} 所有实例存放类.
+ *
+ * @author yl
+ * created on 2024/1/23
+ */
+public interface WxMpMultiServices {
+ /**
+ * 通过租户 Id 获取 WxMpService
+ *
+ * @param tenantId 租户 Id
+ * @return WxMpService
+ */
+ WxMpService getWxMpService(String tenantId);
+
+ /**
+ * 根据租户 Id,从列表中移除一个 WxMpService 实例
+ *
+ * @param tenantId 租户 Id
+ */
+ void removeWxMpService(String tenantId);
+}
diff --git a/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/service/WxMpMultiServicesImpl.java b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/service/WxMpMultiServicesImpl.java
new file mode 100644
index 0000000000..d87cd4e8df
--- /dev/null
+++ b/solon-plugins/wx-java-mp-multi-solon-plugin/src/main/java/com/binarywang/solon/wxjava/mp_multi/service/WxMpMultiServicesImpl.java
@@ -0,0 +1,36 @@
+package com.binarywang.solon.wxjava.mp_multi.service;
+
+import me.chanjar.weixin.mp.api.WxMpService;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 企业微信 {@link WxMpMultiServices} 默认实现
+ *
+ * @author yl
+ * created on 2024/1/23
+ */
+public class WxMpMultiServicesImpl implements WxMpMultiServices {
+ private final Map
+ * {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setRetrySleepMillis(int)}
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+ /**
+ * http 请求最大重试次数
+ *
+ * {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setMaxRetryTimes(int)}
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+
+ }
+
+ public enum StorageType {
+ /**
+ * 内存.
+ */
+ memory,
+ /**
+ * jedis.
+ */
+ jedis,
+ /**
+ * redisson.
+ */
+ redisson,
+ /**
+ * redistemplate
+ */
+ redistemplate
+ }
+
+ public enum HttpClientType {
+ /**
+ * HttpClient.
+ */
+ httpclient
+ }
+}
diff --git a/solon-plugins/wx-java-open-solon-plugin/src/main/java/com/binarywang/solon/wxjava/open/properties/WxOpenRedisProperties.java b/solon-plugins/wx-java-open-solon-plugin/src/main/java/com/binarywang/solon/wxjava/open/properties/WxOpenRedisProperties.java
new file mode 100644
index 0000000000..6b7a2d8654
--- /dev/null
+++ b/solon-plugins/wx-java-open-solon-plugin/src/main/java/com/binarywang/solon/wxjava/open/properties/WxOpenRedisProperties.java
@@ -0,0 +1,45 @@
+package com.binarywang.solon.wxjava.open.properties;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Redis配置.
+ *
+ * @author someone
+ */
+@Data
+public class WxOpenRedisProperties implements Serializable {
+ private static final long serialVersionUID = -5924815351660074401L;
+
+ /**
+ * 主机地址.
+ */
+ private String host;
+
+ /**
+ * 端口号.
+ */
+ private int port = 6379;
+
+ /**
+ * 密码.
+ */
+ private String password;
+
+ /**
+ * 超时.
+ */
+ private int timeout = 2000;
+
+ /**
+ * 数据库.
+ */
+ private int database = 0;
+
+ private Integer maxActive;
+ private Integer maxIdle;
+ private Integer maxWaitMillis;
+ private Integer minIdle;
+}
diff --git a/solon-plugins/wx-java-open-solon-plugin/src/main/resources/META-INF/solon/wx-java-open-solon-plugin.properties b/solon-plugins/wx-java-open-solon-plugin/src/main/resources/META-INF/solon/wx-java-open-solon-plugin.properties
new file mode 100644
index 0000000000..289aca5eeb
--- /dev/null
+++ b/solon-plugins/wx-java-open-solon-plugin/src/main/resources/META-INF/solon/wx-java-open-solon-plugin.properties
@@ -0,0 +1,2 @@
+solon.plugin=com.binarywang.solon.wxjava.open.integration.WxOpenPluginImpl
+solon.plugin.priority=10
diff --git a/solon-plugins/wx-java-open-solon-plugin/src/test/java/features/test/LoadTest.java b/solon-plugins/wx-java-open-solon-plugin/src/test/java/features/test/LoadTest.java
new file mode 100644
index 0000000000..d049f5a51a
--- /dev/null
+++ b/solon-plugins/wx-java-open-solon-plugin/src/test/java/features/test/LoadTest.java
@@ -0,0 +1,15 @@
+package features.test;
+
+import org.junit.jupiter.api.Test;
+import org.noear.solon.test.SolonTest;
+
+/**
+ * @author noear 2024/9/4 created
+ */
+@SolonTest
+public class LoadTest {
+ @Test
+ public void load(){
+
+ }
+}
diff --git a/solon-plugins/wx-java-open-solon-plugin/src/test/resources/app.properties b/solon-plugins/wx-java-open-solon-plugin/src/test/resources/app.properties
new file mode 100644
index 0000000000..fc2e79c95b
--- /dev/null
+++ b/solon-plugins/wx-java-open-solon-plugin/src/test/resources/app.properties
@@ -0,0 +1,11 @@
+# ?????(??)
+wx.open.appId = appId
+wx.open.secret = @secret
+wx.open.token = @token
+wx.open.aesKey = @aesKey
+# ????redis(??)
+# ???????(JedisPool, RedissonClient), ????wx.open.config-storage.redis.host, ????????redis????
+wx.open.config-storage.type = redis # ????: memory(??), redis(jedis), jedis, redisson, redistemplate
+wx.open.config-storage.key-prefix = wx # ??redis????: wx(??)
+wx.open.config-storage.redis.host = 127.0.0.1
+wx.open.config-storage.redis.port = 6379
diff --git a/solon-plugins/wx-java-pay-solon-plugin/README.md b/solon-plugins/wx-java-pay-solon-plugin/README.md
new file mode 100644
index 0000000000..b0e212593b
--- /dev/null
+++ b/solon-plugins/wx-java-pay-solon-plugin/README.md
@@ -0,0 +1,43 @@
+# 使用说明
+1. 在自己的Solon项目里,引入maven依赖
+```xml
+ + * 微信支付自动配置 + * Created by BinaryWang on 2019/4/17. + *+ * + * @author Binary Wang + */ +@Configuration +@Condition( + onProperty = "${wx.pay.enabled:true} = true", + onClass=WxPayService.class +) +public class WxPayAutoConfiguration { + private WxPayProperties properties; + + public WxPayAutoConfiguration(WxPayProperties properties) { + this.properties = properties; + } + + /** + * 构造微信支付服务对象. + * + * @return 微信支付service + */ + @Bean + @Condition(onMissingBean=WxPayService.class) + public WxPayService wxPayService() { + final WxPayServiceImpl wxPayService = new WxPayServiceImpl(); + WxPayConfig payConfig = new WxPayConfig(); + payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId())); + payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId())); + payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey())); + payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId())); + payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId())); + payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); + payConfig.setUseSandboxEnv(this.properties.isUseSandboxEnv()); + payConfig.setNotifyUrl(StringUtils.trimToNull(this.properties.getNotifyUrl())); + payConfig.setRefundNotifyUrl(StringUtils.trimToNull(this.properties.getRefundNotifyUrl())); + //以下是apiv3以及支付分相关 + payConfig.setServiceId(StringUtils.trimToNull(this.properties.getServiceId())); + payConfig.setPayScoreNotifyUrl(StringUtils.trimToNull(this.properties.getPayScoreNotifyUrl())); + payConfig.setPayScorePermissionNotifyUrl(StringUtils.trimToNull(this.properties.getPayScorePermissionNotifyUrl())); + payConfig.setPrivateKeyPath(StringUtils.trimToNull(this.properties.getPrivateKeyPath())); + payConfig.setPrivateCertPath(StringUtils.trimToNull(this.properties.getPrivateCertPath())); + payConfig.setCertSerialNo(StringUtils.trimToNull(this.properties.getCertSerialNo())); + payConfig.setApiV3Key(StringUtils.trimToNull(this.properties.getApiv3Key())); + payConfig.setPublicKeyId(StringUtils.trimToNull(this.properties.getPublicKeyId())); + payConfig.setPublicKeyPath(StringUtils.trimToNull(this.properties.getPublicKeyPath())); + payConfig.setApiHostUrl(StringUtils.trimToNull(this.properties.getApiHostUrl())); + payConfig.setStrictlyNeedWechatPaySerial(this.properties.isStrictlyNeedWechatPaySerial()); + payConfig.setFullPublicKeyModel(this.properties.isFullPublicKeyModel()); + + wxPayService.setConfig(payConfig); + return wxPayService; + } + +} diff --git a/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/integration/WxPayPluginImpl.java b/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/integration/WxPayPluginImpl.java new file mode 100644 index 0000000000..e7ba275ca0 --- /dev/null +++ b/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/integration/WxPayPluginImpl.java @@ -0,0 +1,18 @@ +package com.binarywang.solon.wxjava.pay.integration; + +import com.binarywang.solon.wxjava.pay.config.WxPayAutoConfiguration; +import com.binarywang.solon.wxjava.pay.properties.WxPayProperties; +import org.noear.solon.core.AppContext; +import org.noear.solon.core.Plugin; + +/** + * @author noear 2024/9/2 created + */ +public class WxPayPluginImpl implements Plugin { + @Override + public void start(AppContext context) throws Throwable { + context.beanMake(WxPayProperties.class); + + context.beanMake(WxPayAutoConfiguration.class); + } +} diff --git a/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/properties/WxPayProperties.java b/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/properties/WxPayProperties.java new file mode 100644 index 0000000000..d394fefbd1 --- /dev/null +++ b/solon-plugins/wx-java-pay-solon-plugin/src/main/java/com/binarywang/solon/wxjava/pay/properties/WxPayProperties.java @@ -0,0 +1,126 @@ +package com.binarywang.solon.wxjava.pay.properties; + +import lombok.Data; +import org.noear.solon.annotation.Configuration; +import org.noear.solon.annotation.Inject; + +/** + *
+ * 微信支付属性配置类 + * Created by Binary Wang on 2019/4/17. + *+ * + * @author Binary Wang + */ +@Data +@Configuration +@Inject("${wx.pay}") +public class WxPayProperties { + /** + * 设置微信公众号或者小程序等的appid. + */ + private String appId; + + /** + * 微信支付商户号. + */ + private String mchId; + + /** + * 微信支付商户密钥. + */ + private String mchKey; + + /** + * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除. + */ + private String subAppId; + + /** + * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除. + */ + private String subMchId; + + /** + * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定. + */ + private String keyPath; + + /** + * 微信支付分serviceId + */ + private String serviceId; + + /** + * 证书序列号 + */ + private String certSerialNo; + + /** + * apiV3秘钥 + */ + private String apiv3Key; + + /** + * 微信支付分回调地址 + */ + private String payScoreNotifyUrl; + + /** + * apiv3 商户apiclient_key.pem + */ + private String privateKeyPath; + + /** + * apiv3 商户apiclient_cert.pem + */ + private String privateCertPath; + + /** + * 微信支付是否使用仿真测试环境. + * 默认不使用 + */ + private boolean useSandboxEnv; + + /** + * 微信支付异步回调地址,通知url必须为直接可访问的url,不能携带参数 + */ + private String notifyUrl; + + /** + * 退款结果异步回调地址,通知url必须为直接可访问的url,不能携带参数. + */ + private String refundNotifyUrl; + + /** + * 微信支付分授权回调地址 + */ + private String payScorePermissionNotifyUrl; + + /** + * 公钥ID + */ + private String publicKeyId; + + /** + * pub_key.pem证书文件的绝对路径或者以classpath:开头的类路径. + */ + private String publicKeyPath; + + /** + * 自定义API主机地址,用于替换默认的 https://api.mch.weixin.qq.com + * 例如:http://proxy.company.com:8080 + */ + private String apiHostUrl; + + /** + * 是否将全部v3接口的请求都添加Wechatpay-Serial请求头,默认不添加 + */ + private boolean strictlyNeedWechatPaySerial = false; + + /** + * 是否完全使用公钥模式(用以微信从平台证书到公钥的灰度切换),默认不使用 + */ + private boolean fullPublicKeyModel = false; + +} diff --git a/solon-plugins/wx-java-pay-solon-plugin/src/main/resources/META-INF/solon/wx-java-pay-solon-plugin.properties b/solon-plugins/wx-java-pay-solon-plugin/src/main/resources/META-INF/solon/wx-java-pay-solon-plugin.properties new file mode 100644 index 0000000000..98783176e2 --- /dev/null +++ b/solon-plugins/wx-java-pay-solon-plugin/src/main/resources/META-INF/solon/wx-java-pay-solon-plugin.properties @@ -0,0 +1,2 @@ +solon.plugin=com.binarywang.solon.wxjava.pay.integration.WxPayPluginImpl +solon.plugin.priority=10 diff --git a/solon-plugins/wx-java-pay-solon-plugin/src/test/java/features/test/LoadTest.java b/solon-plugins/wx-java-pay-solon-plugin/src/test/java/features/test/LoadTest.java new file mode 100644 index 0000000000..d049f5a51a --- /dev/null +++ b/solon-plugins/wx-java-pay-solon-plugin/src/test/java/features/test/LoadTest.java @@ -0,0 +1,15 @@ +package features.test; + +import org.junit.jupiter.api.Test; +import org.noear.solon.test.SolonTest; + +/** + * @author noear 2024/9/4 created + */ +@SolonTest +public class LoadTest { + @Test + public void load(){ + + } +} diff --git a/solon-plugins/wx-java-pay-solon-plugin/src/test/resources/app.yml b/solon-plugins/wx-java-pay-solon-plugin/src/test/resources/app.yml new file mode 100644 index 0000000000..1d6a61d7e5 --- /dev/null +++ b/solon-plugins/wx-java-pay-solon-plugin/src/test/resources/app.yml @@ -0,0 +1,6 @@ +wx: + pay: + appId: + mchId: + mchKey: + keyPath: diff --git a/solon-plugins/wx-java-qidian-solon-plugin/README.md b/solon-plugins/wx-java-qidian-solon-plugin/README.md new file mode 100644 index 0000000000..42daa3e4c8 --- /dev/null +++ b/solon-plugins/wx-java-qidian-solon-plugin/README.md @@ -0,0 +1,45 @@ +# wx-java-qidian-solon-plugin + +## 快速开始 + +1. 引入依赖 + ```xml +
{@link me.chanjar.weixin.channel.api.WxChannelService#setMaxRetryTimes(int)}
+ *{@link me.chanjar.weixin.channel.api.impl.BaseWxChannelServiceImpl#setMaxRetryTimes(int)}
+ */ + private int maxRetryTimes = 5; + + /** + * http 请求重试间隔 + * + *{@link me.chanjar.weixin.channel.api.WxChannelService#setRetrySleepMillis(int)}
+ *{@link me.chanjar.weixin.channel.api.impl.BaseWxChannelServiceImpl#setRetrySleepMillis(int)}
+ */ + private int retrySleepMillis = 1000; + } +} diff --git a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelMultiRedisProperties.java b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelMultiRedisProperties.java new file mode 100644 index 0000000000..99c426765c --- /dev/null +++ b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelMultiRedisProperties.java @@ -0,0 +1,63 @@ +package com.binarywang.spring.starter.wxjava.channel.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * Redis配置 + * + * @author Winnie + * @date 2024/9/13 + */ +@Data +@NoArgsConstructor +public class WxChannelMultiRedisProperties implements Serializable { + private static final long serialVersionUID = 9061055444734277357L; + + /** + * 主机地址. + */ + private String host = "127.0.0.1"; + + /** + * 端口号. + */ + private int port = 6379; + + /** + * 密码. + */ + private String password; + + /** + * 超时. + */ + private int timeout = 2000; + + /** + * 数据库. + */ + private int database = 0; + + /** + * 最大活动连接数 + */ + private Integer maxActive; + + /** + * 最大空闲连接数 + */ + private Integer maxIdle; + + /** + * 最小空闲连接数 + */ + private Integer minIdle; + + /** + * 最大等待时间 + */ + private Integer maxWaitMillis; +} diff --git a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelSingleProperties.java b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelSingleProperties.java new file mode 100644 index 0000000000..4b613e3bf6 --- /dev/null +++ b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/properties/WxChannelSingleProperties.java @@ -0,0 +1,55 @@ +package com.binarywang.spring.starter.wxjava.channel.properties; + +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 微信视频号相关配置属性 + * + * @author Winnie + * @date 2024/9/13 + */ +@Data +@NoArgsConstructor +public class WxChannelSingleProperties implements Serializable { + private static final long serialVersionUID = 5306630351265124825L; + + /** + * 设置微信视频号的 appid. + */ + private String appId; + + /** + * 设置微信视频号的 secret. + */ + private String secret; + + /** + * 设置微信视频号的 token. + */ + private String token; + + /** + * 设置微信视频号的 EncodingAESKey. + */ + private String aesKey; + + /** + * 是否使用稳定版 Access Token + */ + private boolean useStableAccessToken = false; + + /** + * 自定义API主机地址,用于替换默认的 https://api.weixin.qq.com + * 例如:http://proxy.company.com:8080 + */ + private String apiHostUrl; + + /** + * 自定义获取AccessToken地址,用于向自定义统一服务获取AccessToken + * 例如:http://proxy.company.com:8080/oauth/token + */ + private String accessTokenUrl; +} diff --git a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/service/WxChannelMultiServices.java b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/service/WxChannelMultiServices.java new file mode 100644 index 0000000000..acd4ebf20b --- /dev/null +++ b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/service/WxChannelMultiServices.java @@ -0,0 +1,26 @@ +package com.binarywang.spring.starter.wxjava.channel.service; + +import me.chanjar.weixin.channel.api.WxChannelService; + +/** + * 视频号 {@link WxChannelService} 所有实例存放类. + * + * @author Winnie + * @date 2024/9/13 + */ +public interface WxChannelMultiServices { + /** + * 通过租户 Id 获取 WxChannelService + * + * @param tenantId 租户 Id + * @return WxChannelService + */ + WxChannelService getWxChannelService(String tenantId); + + /** + * 根据租户 Id,从列表中移除一个 WxChannelService 实例 + * + * @param tenantId 租户 Id + */ + void removeWxChannelService(String tenantId); +} diff --git a/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/service/WxChannelMultiServicesImpl.java b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/service/WxChannelMultiServicesImpl.java new file mode 100644 index 0000000000..1673289cb5 --- /dev/null +++ b/spring-boot-starters/wx-java-channel-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/channel/service/WxChannelMultiServicesImpl.java @@ -0,0 +1,36 @@ +package com.binarywang.spring.starter.wxjava.channel.service; + +import me.chanjar.weixin.channel.api.WxChannelService; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 视频号 {@link WxChannelMultiServices} 实现 + * + * @author Winnie + * @date 2024/9/13 + */ +public class WxChannelMultiServicesImpl implements WxChannelMultiServices { + private final Map
+ * {@link me.chanjar.weixin.cp.api.WxCpService#setMaxRetryTimes(int)}
+ * {@link me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+
+ /**
+ * http 请求重试间隔
+ *
+ * {@link me.chanjar.weixin.cp.api.WxCpService#setRetrySleepMillis(int)}
+ * {@link me.chanjar.weixin.cp.api.impl.BaseWxCpServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+ }
+
+ public enum StorageType {
+ /**
+ * 内存
+ */
+ memory,
+ /**
+ * jedis
+ */
+ jedis,
+ /**
+ * redisson
+ */
+ redisson,
+ /**
+ * redistemplate
+ */
+ redistemplate
+ }
+
+ public enum HttpClientType {
+ /**
+ * HttpClient
+ */
+ HTTP_CLIENT,
+ /**
+ * OkHttp
+ */
+ OK_HTTP,
+ /**
+ * JoddHttp
+ */
+ JODD_HTTP
+ }
+}
diff --git a/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpMultiRedisProperties.java b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpMultiRedisProperties.java
new file mode 100644
index 0000000000..b94711216f
--- /dev/null
+++ b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpMultiRedisProperties.java
@@ -0,0 +1,48 @@
+package com.binarywang.spring.starter.wxjava.cp.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * Redis配置.
+ *
+ * @author yl
+ * created on 2023/10/16
+ */
+@Data
+@NoArgsConstructor
+public class WxCpTpMultiRedisProperties implements Serializable {
+ private static final long serialVersionUID = -5924815351660074401L;
+
+ /**
+ * 主机地址.
+ */
+ private String host;
+
+ /**
+ * 端口号.
+ */
+ private int port = 6379;
+
+ /**
+ * 密码.
+ */
+ private String password;
+
+ /**
+ * 超时.
+ */
+ private int timeout = 2000;
+
+ /**
+ * 数据库.
+ */
+ private int database = 0;
+
+ private Integer maxActive;
+ private Integer maxIdle;
+ private Integer maxWaitMillis;
+ private Integer minIdle;
+}
diff --git a/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpSingleProperties.java b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpSingleProperties.java
new file mode 100644
index 0000000000..02a52657db
--- /dev/null
+++ b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpSingleProperties.java
@@ -0,0 +1,43 @@
+package com.binarywang.spring.starter.wxjava.cp.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 企业微信企业相关配置属性
+ *
+ * @author yl
+ * created on 2023/10/16
+ */
+@Data
+@NoArgsConstructor
+public class WxCpTpSingleProperties implements Serializable {
+ private static final long serialVersionUID = -7502823825007859418L;
+ /**
+ * 微信企业号 corpId
+ */
+ private String corpId;
+ /**
+ * 微信企业号 服务商 providerSecret
+ */
+ private String providerSecret;
+ /**
+ * 微信企业号应用 token
+ */
+ private String token;
+
+ private String encodingAESKey;
+
+ /**
+ * 微信企业号 第三方 应用 ID
+ */
+ private String suiteId;
+ /**
+ * 微信企业号应用
+ */
+ private String suiteSecret;
+
+
+}
diff --git a/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/service/WxCpTpMultiServices.java b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/service/WxCpTpMultiServices.java
new file mode 100644
index 0000000000..c0a9faf51e
--- /dev/null
+++ b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/service/WxCpTpMultiServices.java
@@ -0,0 +1,29 @@
+package com.binarywang.spring.starter.wxjava.cp.service;
+
+
+import me.chanjar.weixin.cp.tp.service.WxCpTpService;
+
+/**
+ * 企业微信 {@link WxCpTpService} 所有实例存放类.
+ *
+ * @author yl
+ * created on 2023/10/16
+ */
+public interface WxCpTpMultiServices {
+ /**
+ * 通过租户 Id 获取 WxCpTpService
+ *
+ * @param tenantId 租户 Id
+ * @return WxCpTpService
+ */
+ WxCpTpService getWxCpTpService(String tenantId);
+
+ void addWxCpTpService(String tenantId, WxCpTpService wxCpService);
+
+ /**
+ * 根据租户 Id,从列表中移除一个 WxCpTpService 实例
+ *
+ * @param tenantId 租户 Id
+ */
+ void removeWxCpTpService(String tenantId);
+}
diff --git a/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/service/WxCpTpMultiServicesImpl.java b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/service/WxCpTpMultiServicesImpl.java
new file mode 100644
index 0000000000..84b381230c
--- /dev/null
+++ b/spring-boot-starters/wx-java-cp-tp-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/service/WxCpTpMultiServicesImpl.java
@@ -0,0 +1,44 @@
+package com.binarywang.spring.starter.wxjava.cp.service;
+
+
+import me.chanjar.weixin.cp.tp.service.WxCpTpService;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 企业微信 {@link WxCpTpMultiServices} 默认实现
+ *
+ * @author yl
+ * created on 2023/10/16
+ */
+public class WxCpTpMultiServicesImpl implements WxCpTpMultiServices {
+ private final Map
+ * {@link cn.binarywang.wx.miniapp.api.WxMaService#setMaxRetryTimes(int)}
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+
+ /**
+ * http 请求重试间隔
+ *
+ * {@link cn.binarywang.wx.miniapp.api.WxMaService#setRetrySleepMillis(int)}
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+
+ /**
+ * 多租户实现模式.
+ * + * 使用单个 WxMaService 实例管理多个租户配置,通过 switchover 切换租户。 + * 相比 {@link WxMaMultiServicesImpl},此实现共享 HTTP 客户端,节省资源。 + *
+ *+ * 注意:由于使用 ThreadLocal 切换配置,在异步或多线程场景需要特别注意线程上下文切换。 + *
+ * + * @author Binary Wang + * created on 2026/1/9 + */ +@RequiredArgsConstructor +public class WxMaMultiServicesSharedImpl implements WxMaMultiServices { + private final WxMaService sharedWxMaService; + + @Override + public WxMaService getWxMaService(String tenantId) { + if (tenantId == null) { + return null; + } + // 使用 switchover 检查配置是否存在,保持与隔离模式 API 行为一致(不存在时返回 null) + if (!sharedWxMaService.switchover(tenantId)) { + return null; + } + return sharedWxMaService; + } + + @Override + public void removeWxMaService(String tenantId) { + if (tenantId != null) { + sharedWxMaService.removeConfig(tenantId); + } + } + + /** + * 添加租户配置到共享的 WxMaService 实例 + * + * @param tenantId 租户 ID + * @param wxMaService 要添加配置的 WxMaService(仅使用其配置,不使用其实例) + */ + public void addWxMaService(String tenantId, WxMaService wxMaService) { + if (tenantId != null && wxMaService != null) { + sharedWxMaService.addConfig(tenantId, wxMaService.getWxMaConfig()); + } + } +} diff --git a/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/src/main/resources/META-INF/spring.factories b/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..bc9bec9bfb --- /dev/null +++ b/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +com.binarywang.spring.starter.wxjava.miniapp.autoconfigure.WxMaMultiAutoConfiguration diff --git a/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000000..3023f06bdd --- /dev/null +++ b/spring-boot-starters/wx-java-miniapp-multi-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1 @@ +com.binarywang.spring.starter.wxjava.miniapp.autoconfigure.WxMaMultiAutoConfiguration diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md index 82f6bdd8b1..cbf0b53925 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md @@ -10,12 +10,13 @@ ``` 2. 添加配置(application.properties) ```properties - # 公众号配置(必填) + # 小程序配置(必填) wx.miniapp.appid = appId wx.miniapp.secret = @secret wx.miniapp.token = @token wx.miniapp.aesKey = @aesKey wx.miniapp.msgDataFormat = @msgDataFormat # 消息格式,XML或者JSON. + wx.miniapp.use-stable-access-token=@useStableAccessToken # 存储配置redis(可选) # 注意: 指定redis.host值后不会使用容器注入的redis连接(JedisPool) wx.miniapp.config-storage.type = Jedis # 配置类型: Memory(默认), Jedis, RedisTemplate diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index 0d076005e3..7e9ffbe308 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -4,7 +4,7 @@+ * 使用单个 WxMpService 实例管理多个租户配置,通过 switchover 切换租户。 + * 相比 {@link WxMpMultiServicesImpl},此实现共享 HTTP 客户端,节省资源。 + *
+ *+ * 注意:由于使用 ThreadLocal 切换配置,在异步或多线程场景需要特别注意线程上下文切换。 + *
+ * + * @author Binary Wang + * created on 2026/1/9 + */ +@RequiredArgsConstructor +public class WxMpMultiServicesSharedImpl implements WxMpMultiServices { + private final WxMpService sharedWxMpService; + + @Override + public WxMpService getWxMpService(String tenantId) { + if (tenantId == null) { + return null; + } + // 使用 switchover 检查配置是否存在,保持与隔离模式 API 行为一致(不存在时返回 null) + if (!sharedWxMpService.switchover(tenantId)) { + return null; + } + return sharedWxMpService; + } + + @Override + public void removeWxMpService(String tenantId) { + if (tenantId != null) { + sharedWxMpService.removeConfigStorage(tenantId); + } + } + + /** + * 添加租户配置到共享的 WxMpService 实例 + * + * @param tenantId 租户 ID + * @param wxMpService 要添加配置的 WxMpService(仅使用其配置,不使用其实例) + */ + public void addWxMpService(String tenantId, WxMpService wxMpService) { + if (tenantId != null && wxMpService != null) { + sharedWxMpService.addConfigStorage(tenantId, wxMpService.getWxMpConfigStorage()); + } + } +} diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md b/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md index 3e14f499d9..091912cfad 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md @@ -27,7 +27,7 @@ #wx.mp.config-storage.redis.sentinel-ips=127.0.0.1:16379,127.0.0.1:26379 #wx.mp.config-storage.redis.sentinel-name=mymaster # http客户端配置 - wx.mp.config-storage.http-client-type=httpclient # http客户端类型: HttpClient(默认), OkHttp, JoddHttp + wx.mp.config-storage.http-client-type=HttpComponents # http客户端类型: HttpComponents(Apache HttpClient 5.x,推荐), HttpClient(Apache HttpClient 4.x), OkHttp, JoddHttp wx.mp.config-storage.http-proxy-host= wx.mp.config-storage.http-proxy-port= wx.mp.config-storage.http-proxy-username= diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index 6b6e625214..5d0c2d0269 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@
+ * {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setMaxRetryTimes(int)}
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setMaxRetryTimes(int)}
+ *
+ */
+ private int maxRetryTimes = 5;
+
+ /**
+ * http 请求重试间隔
+ *
+ * {@link me.chanjar.weixin.mp.api.impl.BaseWxMpServiceImpl#setRetrySleepMillis(int)}
+ * {@link cn.binarywang.wx.miniapp.api.impl.BaseWxMaServiceImpl#setRetrySleepMillis(int)}
+ *
+ */
+ private int retrySleepMillis = 1000;
+
+ /**
+ * 连接超时时间,单位毫秒
+ */
+ private int connectionTimeout = 5000;
+
+ /**
+ * 读数据超时时间,即socketTimeout,单位毫秒
+ */
+ private int soTimeout = 5000;
+
+ /**
+ * 从连接池获取链接的超时时间,单位毫秒
+ */
+ private int connectionRequestTimeout = 5000;
+ }
+
+ public enum StorageType {
+ /**
+ * 内存
+ */
+ memory,
+ /**
+ * jedis
+ */
+ jedis,
+ /**
+ * redisson
+ */
+ redisson,
+ /**
+ * redisTemplate
+ */
+ redistemplate
+ }
+
+}
diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiRedisProperties.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiRedisProperties.java
new file mode 100644
index 0000000000..ae6d5368d7
--- /dev/null
+++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenMultiRedisProperties.java
@@ -0,0 +1,57 @@
+package com.binarywang.spring.starter.wxjava.open.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 微信开放平台多账号Redis配置.
+ *
+ * @author Binary Wang
+ */
+@Data
+@NoArgsConstructor
+public class WxOpenMultiRedisProperties implements Serializable {
+ private static final long serialVersionUID = -5924815351660074401L;
+
+ /**
+ * 主机地址.
+ */
+ private String host = "127.0.0.1";
+
+ /**
+ * 端口号.
+ */
+ private int port = 6379;
+
+ /**
+ * 密码.
+ */
+ private String password;
+
+ /**
+ * 超时.
+ */
+ private int timeout = 2000;
+
+ /**
+ * 数据库.
+ */
+ private int database = 0;
+
+ /**
+ * sentinel ips
+ */
+ private String sentinelIps;
+
+ /**
+ * sentinel name
+ */
+ private String sentinelName;
+
+ private Integer maxActive;
+ private Integer maxIdle;
+ private Integer maxWaitMillis;
+ private Integer minIdle;
+}
diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenSingleProperties.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenSingleProperties.java
new file mode 100644
index 0000000000..116da323dc
--- /dev/null
+++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenSingleProperties.java
@@ -0,0 +1,49 @@
+package com.binarywang.spring.starter.wxjava.open.properties;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 微信开放平台单个应用配置.
+ *
+ * @author Binary Wang
+ */
+@Data
+@NoArgsConstructor
+public class WxOpenSingleProperties implements Serializable {
+ private static final long serialVersionUID = 1980986361098922525L;
+
+ /**
+ * 设置微信开放平台的appid.
+ */
+ private String appId;
+
+ /**
+ * 设置微信开放平台的app secret.
+ */
+ private String secret;
+
+ /**
+ * 设置微信开放平台的token.
+ */
+ private String token;
+
+ /**
+ * 设置微信开放平台的EncodingAESKey.
+ */
+ private String aesKey;
+
+ /**
+ * 自定义API主机地址,用于替换默认的 https://api.weixin.qq.com
+ * 例如:http://proxy.company.com:8080
+ */
+ private String apiHostUrl;
+
+ /**
+ * 自定义获取AccessToken地址,用于向自定义统一服务获取AccessToken
+ * 例如:http://proxy.company.com:8080/oauth/token
+ */
+ private String accessTokenUrl;
+}
diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServices.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServices.java
new file mode 100644
index 0000000000..9228071a10
--- /dev/null
+++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServices.java
@@ -0,0 +1,26 @@
+package com.binarywang.spring.starter.wxjava.open.service;
+
+
+import me.chanjar.weixin.open.api.WxOpenService;
+
+/**
+ * 微信开放平台 {@link WxOpenService} 所有实例存放类.
+ *
+ * @author binarywang
+ */
+public interface WxOpenMultiServices {
+ /**
+ * 通过租户 Id 获取 WxOpenService
+ *
+ * @param tenantId 租户 Id
+ * @return WxOpenService
+ */
+ WxOpenService getWxOpenService(String tenantId);
+
+ /**
+ * 根据租户 Id,从列表中移除一个 WxOpenService 实例
+ *
+ * @param tenantId 租户 Id
+ */
+ void removeWxOpenService(String tenantId);
+}
diff --git a/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServicesImpl.java b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServicesImpl.java
new file mode 100644
index 0000000000..76fb139e6c
--- /dev/null
+++ b/spring-boot-starters/wx-java-open-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/service/WxOpenMultiServicesImpl.java
@@ -0,0 +1,35 @@
+package com.binarywang.spring.starter.wxjava.open.service;
+
+import me.chanjar.weixin.open.api.WxOpenService;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 微信开放平台 {@link WxOpenMultiServices} 默认实现
+ *
+ * @author Binary Wang
+ */
+public class WxOpenMultiServicesImpl implements WxOpenMultiServices {
+ private final Map+ * 注意:configKey 是配置文件中定义的 key(如 wx.pay.configs.<configKey>.xxx), + * 而不是 appId。如果使用 appId 作为配置 key,则可以直接传入 appId。 + *
+ * + * @param configKey 配置标识(配置文件中 wx.pay.configs 下的 key) + * @return WxPayService + */ + WxPayService getWxPayService(String configKey); + + /** + * 根据配置标识,从列表中移除一个 WxPayService 实例. + *+ * 注意:configKey 是配置文件中定义的 key(如 wx.pay.configs.<configKey>.xxx), + * 而不是 appId。如果使用 appId 作为配置 key,则可以直接传入 appId。 + *
+ * + * @param configKey 配置标识(配置文件中 wx.pay.configs 下的 key) + */ + void removeWxPayService(String configKey); +} diff --git a/spring-boot-starters/wx-java-pay-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/service/WxPayMultiServicesImpl.java b/spring-boot-starters/wx-java-pay-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/service/WxPayMultiServicesImpl.java new file mode 100644 index 0000000000..459fe3b6c0 --- /dev/null +++ b/spring-boot-starters/wx-java-pay-multi-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/service/WxPayMultiServicesImpl.java @@ -0,0 +1,92 @@ +package com.binarywang.spring.starter.wxjava.pay.service; + +import com.binarywang.spring.starter.wxjava.pay.properties.WxPayMultiProperties; +import com.binarywang.spring.starter.wxjava.pay.properties.WxPaySingleProperties; +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 微信支付多服务管理实现类. + * + * @author Binary Wang + */ +@Slf4j +public class WxPayMultiServicesImpl implements WxPayMultiServices { + private final Map+ * 本示例展示了如何使用 wx-java-pay-multi-spring-boot-starter 来管理多个公众号的支付配置。 + *
+ * + * @author Binary Wang + */ +@Slf4j +@Service +public class WxPayMultiExample { + + @Autowired + private WxPayMultiServices wxPayMultiServices; + + /** + * 示例1:根据appId创建支付订单. + *+ * 适用场景:系统需要支持多个公众号,根据用户所在的公众号动态选择支付配置 + *
+ * + * @param appId 公众号appId + * @param openId 用户的openId + * @param totalFee 支付金额(分) + * @param body 商品描述 + * @return JSAPI支付参数 + */ + public WxPayUnifiedOrderV3Result.JsapiResult createJsapiOrder(String appId, String openId, + Integer totalFee, String body) { + try { + // 根据appId获取对应的WxPayService + WxPayService wxPayService = wxPayMultiServices.getWxPayService(appId); + + if (wxPayService == null) { + log.error("未找到appId对应的微信支付配置: {}", appId); + throw new IllegalArgumentException("未找到appId对应的微信支付配置"); + } + + // 构建支付请求 + WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request(); + request.setOutTradeNo(generateOutTradeNo()); + request.setDescription(body); + request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(totalFee)); + request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(openId)); + request.setNotifyUrl(wxPayService.getConfig().getNotifyUrl()); + + // 调用微信支付API创建订单 + WxPayUnifiedOrderV3Result.JsapiResult result = + wxPayService.createOrderV3(TradeTypeEnum.JSAPI, request); + + log.info("创建JSAPI支付订单成功,appId: {}, outTradeNo: {}", appId, request.getOutTradeNo()); + return result; + + } catch (Exception e) { + log.error("创建JSAPI支付订单失败,appId: {}", appId, e); + throw new RuntimeException("创建支付订单失败", e); + } + } + + /** + * 示例2:服务商模式 - 为不同子商户创建订单. + *+ * 适用场景:服务商为多个子商户提供支付服务 + *
+ * + * @param configKey 配置标识(在配置文件中定义) + * @param subOpenId 子商户用户的openId + * @param totalFee 支付金额(分) + * @param body 商品描述 + * @return JSAPI支付参数 + */ + public WxPayUnifiedOrderV3Result.JsapiResult createPartnerOrder(String configKey, String subOpenId, + Integer totalFee, String body) { + try { + // 根据配置标识获取WxPayService + WxPayService wxPayService = wxPayMultiServices.getWxPayService(configKey); + + if (wxPayService == null) { + log.error("未找到配置: {}", configKey); + throw new IllegalArgumentException("未找到配置"); + } + + // 获取子商户信息 + String subAppId = wxPayService.getConfig().getSubAppId(); + String subMchId = wxPayService.getConfig().getSubMchId(); + log.info("使用服务商模式,子商户appId: {}, 子商户号: {}", subAppId, subMchId); + + // 构建支付请求 + WxPayUnifiedOrderV3Request request = new WxPayUnifiedOrderV3Request(); + request.setOutTradeNo(generateOutTradeNo()); + request.setDescription(body); + request.setAmount(new WxPayUnifiedOrderV3Request.Amount().setTotal(totalFee)); + request.setPayer(new WxPayUnifiedOrderV3Request.Payer().setOpenid(subOpenId)); + request.setNotifyUrl(wxPayService.getConfig().getNotifyUrl()); + + // 调用微信支付API创建订单 + WxPayUnifiedOrderV3Result.JsapiResult result = + wxPayService.createOrderV3(TradeTypeEnum.JSAPI, request); + + log.info("创建服务商支付订单成功,配置: {}, outTradeNo: {}", configKey, request.getOutTradeNo()); + return result; + + } catch (Exception e) { + log.error("创建服务商支付订单失败,配置: {}", configKey, e); + throw new RuntimeException("创建支付订单失败", e); + } + } + + /** + * 示例3:查询订单状态. + *+ * 适用场景:查询不同公众号的订单支付状态 + *
+ * + * @param appId 公众号appId + * @param outTradeNo 商户订单号 + * @return 订单状态 + */ + public String queryOrderStatus(String appId, String outTradeNo) { + try { + WxPayService wxPayService = wxPayMultiServices.getWxPayService(appId); + + if (wxPayService == null) { + log.error("未找到appId对应的微信支付配置: {}", appId); + throw new IllegalArgumentException("未找到appId对应的微信支付配置"); + } + + // 查询订单 + WxPayOrderQueryV3Result result = wxPayService.queryOrderV3(null, outTradeNo); + String tradeState = result.getTradeState(); + + log.info("查询订单状态成功,appId: {}, outTradeNo: {}, 状态: {}", appId, outTradeNo, tradeState); + return tradeState; + + } catch (Exception e) { + log.error("查询订单状态失败,appId: {}, outTradeNo: {}", appId, outTradeNo, e); + throw new RuntimeException("查询订单失败", e); + } + } + + /** + * 示例4:申请退款. + *+ * 适用场景:为不同公众号的订单申请退款 + *
+ * + * @param appId 公众号appId + * @param outTradeNo 商户订单号 + * @param refundFee 退款金额(分) + * @param totalFee 订单总金额(分) + * @param reason 退款原因 + * @return 退款单号 + */ + public String refund(String appId, String outTradeNo, Integer refundFee, + Integer totalFee, String reason) { + try { + WxPayService wxPayService = wxPayMultiServices.getWxPayService(appId); + + if (wxPayService == null) { + log.error("未找到appId对应的微信支付配置: {}", appId); + throw new IllegalArgumentException("未找到appId对应的微信支付配置"); + } + + // 构建退款请求 + com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request request = + new com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request(); + request.setOutTradeNo(outTradeNo); + request.setOutRefundNo(generateRefundNo()); + request.setReason(reason); + request.setNotifyUrl(wxPayService.getConfig().getRefundNotifyUrl()); + + com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request.Amount amount = + new com.github.binarywang.wxpay.bean.request.WxPayRefundV3Request.Amount(); + amount.setRefund(refundFee); + amount.setTotal(totalFee); + amount.setCurrency("CNY"); + request.setAmount(amount); + + // 调用微信支付API申请退款 + WxPayRefundV3Result result = wxPayService.refundV3(request); + + log.info("申请退款成功,appId: {}, outTradeNo: {}, outRefundNo: {}", + appId, outTradeNo, request.getOutRefundNo()); + return request.getOutRefundNo(); + + } catch (Exception e) { + log.error("申请退款失败,appId: {}, outTradeNo: {}", appId, outTradeNo, e); + throw new RuntimeException("申请退款失败", e); + } + } + + /** + * 示例5:动态管理配置. + *+ * 适用场景:需要在运行时更新配置(如证书更新后需要重新加载) + *
+ * + * @param configKey 配置标识 + */ + public void reloadConfig(String configKey) { + try { + // 移除缓存的WxPayService实例 + wxPayMultiServices.removeWxPayService(configKey); + log.info("移除配置成功,下次获取时将重新创建: {}", configKey); + + // 下次调用 getWxPayService 时会重新创建实例 + WxPayService wxPayService = wxPayMultiServices.getWxPayService(configKey); + if (wxPayService != null) { + log.info("重新加载配置成功: {}", configKey); + } + + } catch (Exception e) { + log.error("重新加载配置失败: {}", configKey, e); + throw new RuntimeException("重新加载配置失败", e); + } + } + + /** + * 生成商户订单号. + * + * @return 商户订单号 + */ + private String generateOutTradeNo() { + return "ORDER_" + System.currentTimeMillis(); + } + + /** + * 生成商户退款单号. + * + * @return 商户退款单号 + */ + private String generateRefundNo() { + return "REFUND_" + System.currentTimeMillis(); + } +} diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml index 7f11e6c4c5..7bbfdbfbf1 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@
* 获取access_token,本方法线程安全.
* 且在多线程同时刷新时只刷新一次,避免超出2000次/日的调用次数上限
- *
- * 另:本service的所有方法都会在access_token过期是调用此方法
+ * 使用【稳定版接口】获取access_token时,限制【20次/日】,连续使用该模式时,请保证调用时间隔至少为30s,否则不会刷新
*
* 程序员在非必要情况下尽量不要主动调用此方法
*
@@ -132,5 +131,5 @@ public interface BaseWxChannelService extends WxService {
*
* @return . request http
*/
- RequestHttp getRequestHttp();
+ RequestHttp, ?> getRequestHttp();
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java
index ac1e61729b..85c945d428 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelAfterSaleService.java
@@ -2,8 +2,8 @@
import java.util.List;
-import me.chanjar.weixin.channel.bean.after.AfterSaleInfoResponse;
-import me.chanjar.weixin.channel.bean.after.AfterSaleListResponse;
+
+import me.chanjar.weixin.channel.bean.after.*;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
import me.chanjar.weixin.channel.bean.complaint.ComplaintOrderResponse;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -24,10 +24,22 @@ public interface WxChannelAfterSaleService {
* @return 售后单列表
*
* @throws WxErrorException 异常
+ * @deprecated 使用 {@link WxChannelAfterSaleService#listIds(AfterSaleListParam)}
*/
+ @Deprecated
AfterSaleListResponse listIds(Long beginCreateTime, Long endCreateTime, String nextKey)
throws WxErrorException;
+ /**
+ * 获取售后单列表
+ *
+ * @param param 参数
+ * @return 售后单列表
+ *
+ * @throws WxErrorException 异常
+ */
+ AfterSaleListResponse listIds(AfterSaleListParam param) throws WxErrorException;
+
/**
* 获取售后单详情
*
@@ -39,26 +51,31 @@ AfterSaleListResponse listIds(Long beginCreateTime, Long endCreateTime, String n
AfterSaleInfoResponse get(String afterSaleOrderId) throws WxErrorException;
/**
- * 同意退款
+ * 同意售后
+ * 文档地址 https://developers.weixin.qq.com/doc/channels/API/aftersale/acceptapply.html
*
* @param afterSaleOrderId 售后单号
* @param addressId 同意退货时传入地址id
+ * @param acceptType 1. 同意退货退款,并通知用户退货; 2. 确认收到货并退款给用户。 如果不填则将根据当前的售后单状态自动选择相应操作。对于仅退款的情况,由于只存在一种同意的场景,无需填写此字段。
* @return BaseResponse
*
* @throws WxErrorException 异常
*/
- WxChannelBaseResponse accept(String afterSaleOrderId, String addressId) throws WxErrorException;
+ WxChannelBaseResponse accept(String afterSaleOrderId, String addressId, Integer acceptType) throws WxErrorException;
/**
* 拒绝售后
+ * 文档地址 https://developers.weixin.qq.com/doc/channels/API/aftersale/rejectapply.html
*
* @param afterSaleOrderId 售后单号
* @param rejectReason 拒绝原因
+ * @param rejectReasonType 拒绝原因枚举值
+ * @see #getRejectReason()
* @return BaseResponse
*
* @throws WxErrorException 异常
*/
- WxChannelBaseResponse reject(String afterSaleOrderId, String rejectReason) throws WxErrorException;
+ WxChannelBaseResponse reject(String afterSaleOrderId, String rejectReason, Integer rejectReasonType) throws WxErrorException;
/**
* 上传退款凭证
@@ -108,4 +125,62 @@ WxChannelBaseResponse addComplaintEvidence(String complaintId, String content, L
* @throws WxErrorException 异常
*/
ComplaintOrderResponse getComplaint(String complaintId) throws WxErrorException;
+
+
+ /**
+ * 获取全量售后原因
+ * 文档地址:https://developers.weixin.qq.com/doc/channels/API/aftersale/getaftersalereason.html
+ *
+ * @return 售后原因
+ *
+ * @throws WxErrorException 异常
+ */
+ AfterSaleReasonResponse getAllReason() throws WxErrorException;
+
+ /**
+ * 获取拒绝售后原因
+ * 文档地址:https://developers.weixin.qq.com/doc/channels/API/aftersale/getrejectreason.html
+ *
+ * @return 拒绝售后原因
+ *
+ * @throws WxErrorException 异常
+ */
+ AfterSaleRejectReasonResponse getRejectReason() throws WxErrorException;
+
+ /**
+ * 换货发货
+ * 文档地址:https://developers.weixin.qq.com/doc/store/shop/API/channels-shop-aftersale/api_acceptexchangereship.html
+ *
+ * @param afterSaleOrderId 售后单号
+ * @param waybillId 快递单号
+ * @param deliveryId 快递公司id
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse acceptExchangeReship(String afterSaleOrderId, String waybillId, String deliveryId) throws WxErrorException;
+
+ /**
+ * 换货拒绝发货
+ * 文档地址:https://developers.weixin.qq.com/doc/store/shop/API/channels-shop-aftersale/api_rejectexchangereship.html
+ *
+ * @param afterSaleOrderId 售后单号
+ * @param rejectReason 拒绝原因具体描述 ,可使用默认描述,也可以自定义描述
+ * @param rejectReasonType 拒绝原因枚举值
+ * @param rejectCertificates 退款凭证,可使用图片上传接口获取media_id(数据类型填0)
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse rejectExchangeReship(String afterSaleOrderId, String rejectReason, Integer rejectReasonType, List rejectCertificates) throws WxErrorException;
+
+ /**
+ * 商家协商
+ * 文档地址:https://developers.weixin.qq.com/doc/store/shop/API/channels-shop-aftersale/api_merchantupdateaftersale.html
+ * @param param 参数
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse merchantUpdateAfterSale(AfterSaleMerchantUpdateParam param) throws WxErrorException;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java
index ddbc99e5d4..ad86697614 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCategoryService.java
@@ -4,17 +4,16 @@
import java.util.List;
import me.chanjar.weixin.channel.bean.audit.AuditApplyResponse;
import me.chanjar.weixin.channel.bean.audit.AuditResponse;
+import me.chanjar.weixin.channel.bean.audit.CategoryAuditInfo;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
-import me.chanjar.weixin.channel.bean.category.CategoryDetailResult;
-import me.chanjar.weixin.channel.bean.category.CategoryQualificationResponse;
-import me.chanjar.weixin.channel.bean.category.PassCategoryResponse;
-import me.chanjar.weixin.channel.bean.category.ShopCategory;
+import me.chanjar.weixin.channel.bean.category.*;
import me.chanjar.weixin.common.error.WxErrorException;
/**
* 视频号小店 商品类目相关接口
*
* @author Zeyes
+ * @see 新旧类目树差异
*/
public interface WxChannelCategoryService {
@@ -30,12 +29,27 @@ public interface WxChannelCategoryService {
/**
* 获取商品类目列表(全量) 有频率限制
*
- * @param parentId 类目父id
+ * @param fCatId 类目父id
* @return 类目列表
*
* @throws WxErrorException 异常
+ * @deprecated 接口返回更新,请使用 {@link #listAvailableCategories(String)}
*/
- List listAvailableCategory(String parentId) throws WxErrorException;
+ @Deprecated
+ List listAvailableCategory(String fCatId) throws WxErrorException;
+
+ /**
+ * 获取可用的子类目详情
+ *
+ * 1.f_cat_id 为旧类目树中的非叶子类目,仅设置 cat_list 字段。
+ * 2.f_cat_id 为新类目树中的非叶子类目,仅设置 cat_list_v2 字段。
+ * 3.f_cat_id 为0,同时设置 cat_list 和 cat_list_v2 字段
+ *
+ * @param fCatId 父类目ID,可先填0获取根部类目
+ * @return 类目列表
+ * @throws WxErrorException 异常
+ */
+ ShopCategoryResponse listAvailableCategories(String fCatId) throws WxErrorException;
/**
* 获取类目信息
@@ -58,10 +72,23 @@ public interface WxChannelCategoryService {
*
* @throws WxErrorException 异常
* @see WxChannelBasicService#uploadQualificationFile(File)
+ * @deprecated 请使用 {@link #addCategory(CategoryAuditInfo)}
*/
+ @Deprecated
AuditApplyResponse addCategory(String level1, String level2, String level3, List certificate)
throws WxErrorException;
+ /**
+ * 上传类目资质
+ *
+ * @param info 类目资质信息
+ * @return 审核id
+ *
+ * @throws WxErrorException 异常
+ * @see WxChannelBasicService#uploadQualificationFile(File)
+ */
+ AuditApplyResponse addCategory(CategoryAuditInfo info) throws WxErrorException;
+
/**
* 取消类目提审
*
@@ -90,4 +117,16 @@ AuditApplyResponse addCategory(String level1, String level2, String level3, List
* @throws WxErrorException 异常
*/
PassCategoryResponse listPassCategory() throws WxErrorException;
+
+ /**
+ * 获取店铺的类目权限列表
+ *
+ * @param isFilterStatus 是否按状态筛选
+ * @param status 类目状态(当 isFilterStatus 为 true 时有效)
+ * @return 类目权限列表
+ *
+ * @throws WxErrorException 异常
+ */
+ RelationCategoryResponse listRelationCategory(Boolean isFilterStatus, Integer status) throws WxErrorException;
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCompassFinderService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCompassFinderService.java
new file mode 100644
index 0000000000..db123f61a4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCompassFinderService.java
@@ -0,0 +1,58 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.compass.finder.OverallResponse;
+import me.chanjar.weixin.channel.bean.compass.finder.ProductDataResponse;
+import me.chanjar.weixin.channel.bean.compass.finder.ProductListResponse;
+import me.chanjar.weixin.channel.bean.compass.finder.SaleProfileDataResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号助手 罗盘达人版服务
+ *
+ * @author Winnie
+ */
+public interface WxChannelCompassFinderService {
+
+ /**
+ * 获取电商概览数据
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @return 电商概览数据
+ *
+ * @throws WxErrorException 异常
+ */
+ OverallResponse getOverall(String ds) throws WxErrorException;
+
+ /**
+ * 获取带货商品数据
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @param productId 商品id
+ * @return 带货商品数据
+ *
+ * @throws WxErrorException 异常
+ */
+ ProductDataResponse getProductData(String ds, String productId) throws WxErrorException;
+
+ /**
+ * 获取带货商品列表
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @return 带货商品列表
+ *
+ * @throws WxErrorException 异常
+ */
+ ProductListResponse getProductList(String ds) throws WxErrorException;
+
+ /**
+ * 获取带货人群数据
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @param type 用户类型,1=商品曝光用户, 2=商品点击用户, 3=购买用户, 4=首购用户, 5=复购用户, 6=直播观看用户
+ * @return 带货人群数据
+ *
+ * @throws WxErrorException 异常
+ */
+ SaleProfileDataResponse getSaleProfileData(String ds, Integer type) throws WxErrorException;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCompassShopService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCompassShopService.java
new file mode 100644
index 0000000000..aa3a85fa74
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelCompassShopService.java
@@ -0,0 +1,126 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.compass.shop.FinderAuthListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderProductListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderProductOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopLiveListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopProductDataResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopProductListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopSaleProfileDataResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号/微信小店 罗盘商家版服务
+ *
+ * @author Zeyes
+ */
+public interface WxChannelCompassShopService {
+
+ /**
+ * 获取电商概览数据
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @return 电商概览数据
+ *
+ * @throws WxErrorException 异常
+ */
+ ShopOverallResponse getShopOverall(String ds) throws WxErrorException;
+
+ /**
+ * 获取授权视频号列表
+ *
+ * @return 获取授权视频号列表
+ *
+ * @throws WxErrorException 异常
+ */
+ FinderAuthListResponse getFinderAuthorizationList() throws WxErrorException;
+
+ /**
+ * 获取带货达人列表
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @return 带货达人列表
+ *
+ * @throws WxErrorException 异常
+ */
+ FinderListResponse getFinderList(String ds) throws WxErrorException;
+
+ /**
+ * 获取带货数据概览
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @return 带货数据概览
+ *
+ * @throws WxErrorException 异常
+ */
+ FinderOverallResponse getFinderOverall(String ds) throws WxErrorException;
+
+ /**
+ * 获取带货达人商品列表
+ *
+ * @param ds 日期,格式YYYYMMDD
+ * @param finderId 视频号ID
+ * @return 带货达人商品列表
+ *
+ * @throws WxErrorException 异常
+ */
+ FinderProductListResponse getFinderProductList(String ds, String finderId) throws WxErrorException;
+
+ /**
+ * 获取带货达人详情
+ *
+ * @param ds 日期,格式YYYYMMDD
+ * @param finderId 视频号ID
+ * @return 带货达人详情
+ *
+ * @throws WxErrorException 异常
+ */
+ FinderProductOverallResponse getFinderProductOverall(String ds, String finderId) throws WxErrorException;
+
+ /**
+ * 获取店铺开播列表
+ *
+ * @param ds 日期,格式YYYYMMDD
+ * @param finderId 视频号ID
+ * @return 店铺开播列表
+ *
+ * @throws WxErrorException 异常
+ */
+ ShopLiveListResponse getShopLiveList(String ds, String finderId) throws WxErrorException;
+
+ /**
+ * 获取商品详细信息
+ *
+ * @param ds 日期,格式YYYYMMDD
+ * @param productId 商品id
+ * @return 商品详细信息
+ *
+ * @throws WxErrorException 异常
+ */
+ ShopProductDataResponse getShopProductData(String ds, String productId) throws WxErrorException;
+
+ /**
+ * 获取商品列表
+ *
+ * @param ds 日期,格式YYYYMMDD
+ * @return 商品列表
+ *
+ * @throws WxErrorException 异常
+ */
+ ShopProductListResponse getShopProductList(String ds) throws WxErrorException;
+
+ /**
+ * 获取店铺人群数据
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @param type 用户类型,1商品曝光用户 2商品点击用户 3购买用户 4首购用户 5复购用户
+ * @return 店铺人群数据
+ *
+ * @throws WxErrorException 异常
+ */
+ ShopSaleProfileDataResponse getShopSaleProfileData(String ds, Integer type) throws WxErrorException;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelLiveDashboardService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelLiveDashboardService.java
new file mode 100644
index 0000000000..be93b06a97
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelLiveDashboardService.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.live.dashboard.LiveDataResponse;
+import me.chanjar.weixin.channel.bean.live.dashboard.LiveListResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号助手 直播大屏数据服务
+ *
+ * @author Winnie
+ */
+public interface WxChannelLiveDashboardService {
+
+ /**
+ * 获取直播大屏直播列表
+ *
+ * @param ds 日期,格式 yyyyMMdd
+ * @return 播大屏直播列表
+ *
+ * @throws WxErrorException 异常
+ */
+ LiveListResponse getLiveList(Long ds) throws WxErrorException;
+
+ /**
+ * 获取直播大屏数据
+ *
+ * @param exportId 直播唯一ID
+ * @return 播大屏数据
+ *
+ * @throws WxErrorException 异常
+ */
+ LiveDataResponse getLiveData(String exportId) throws WxErrorException;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelOrderService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelOrderService.java
index 6179510e78..7be0382bac 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelOrderService.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelOrderService.java
@@ -3,14 +3,17 @@
import java.util.List;
import me.chanjar.weixin.channel.bean.base.AddressInfo;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.delivery.PackageAuditInfo;
import me.chanjar.weixin.channel.bean.delivery.DeliveryCompanyResponse;
import me.chanjar.weixin.channel.bean.delivery.DeliveryInfo;
import me.chanjar.weixin.channel.bean.order.ChangeOrderInfo;
+import me.chanjar.weixin.channel.bean.order.DecodeSensitiveInfoResponse;
import me.chanjar.weixin.channel.bean.order.DeliveryUpdateParam;
import me.chanjar.weixin.channel.bean.order.OrderInfoResponse;
import me.chanjar.weixin.channel.bean.order.OrderListParam;
import me.chanjar.weixin.channel.bean.order.OrderListResponse;
import me.chanjar.weixin.channel.bean.order.OrderSearchParam;
+import me.chanjar.weixin.channel.bean.order.VirtualTelNumberResponse;
import me.chanjar.weixin.common.error.WxErrorException;
/**
@@ -31,6 +34,17 @@ public interface WxChannelOrderService {
*/
OrderInfoResponse getOrder(String orderId) throws WxErrorException;
+ /**
+ * 获取订单详情
+ *
+ * @param orderId 订单id
+ * @param encodeSensitiveInfo 是否编码敏感信息
+ * @return 订单详情
+ *
+ * @throws WxErrorException 异常
+ */
+ OrderInfoResponse getOrder(String orderId, Boolean encodeSensitiveInfo) throws WxErrorException;
+
/**
* 获取订单列表
*
@@ -125,7 +139,7 @@ WxChannelBaseResponse updatePrice(String orderId, Integer expressFee, List deliveryList) throws WxErrorException;
+
+ /**
+ * 上传生鲜质检信息
+ *
+ * 注意事项:
+ * 1. 非生鲜质检的订单不能进行上传
+ * 2. 图片url必须用图片上传接口获取 {@link WxChannelBasicService#uploadImg(int, String)}
+ *
+ * @param orderId 订单id
+ * @param items 商品打包信息
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse uploadFreshInspect(String orderId, List items) throws WxErrorException;
+
+ /**
+ * 兑换虚拟号
+ *
+ * @param orderId 订单id
+ * @return 虚拟号信息
+ * @throws WxErrorException 异常
+ */
+ VirtualTelNumberResponse getVirtualTelNumber(String orderId) throws WxErrorException;
+
+ /**
+ * 解码订单包含的敏感数据
+ *
+ * @param orderId 订单id
+ * @return 解码结果
+ * @throws WxErrorException 异常
+ */
+ DecodeSensitiveInfoResponse decodeSensitiveInfo(String orderId) 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 b962b9ec85..7064adf70f 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
@@ -1,21 +1,29 @@
package me.chanjar.weixin.channel.api;
+import java.util.List;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
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.product.SkuStockBatchResponse;
import me.chanjar.weixin.channel.bean.product.SkuStockResponse;
+import me.chanjar.weixin.channel.bean.product.SpuFastInfo;
import me.chanjar.weixin.channel.bean.product.SpuGetResponse;
import me.chanjar.weixin.channel.bean.product.SpuInfo;
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.link.ProductH5UrlResponse;
+import me.chanjar.weixin.channel.bean.product.link.ProductQrCodeResponse;
+import me.chanjar.weixin.channel.bean.product.link.ProductTagLinkResponse;
import me.chanjar.weixin.common.error.WxErrorException;
/**
* 视频号小店 商品服务接口
*
* @author Zeyes
+ * @see 商品状态流转图
*/
public interface WxChannelProductService {
@@ -27,6 +35,28 @@ public interface WxChannelProductService {
*
* @throws WxErrorException 异常
*/
+ SpuUpdateResponse addProduct(SpuUpdateInfo info) throws WxErrorException;
+
+ /**
+ * 更新商品
+ *
+ * @param info 商品信息
+ * @return 返回商品的状态和id
+ *
+ * @throws WxErrorException 异常
+ */
+ SpuUpdateResponse updateProduct(SpuUpdateInfo info) throws WxErrorException;
+
+ /**
+ * 添加商品
+ *
+ * @param info 商品信息
+ * @return 返回商品的状态和id
+ *
+ * @throws WxErrorException 异常
+ * @deprecated 请使用 {@link #addProduct(SpuUpdateInfo)}
+ */
+ @Deprecated
SpuUpdateResponse addProduct(SpuInfo info) throws WxErrorException;
/**
@@ -36,15 +66,28 @@ public interface WxChannelProductService {
* @return 返回商品的状态和id
*
* @throws WxErrorException 异常
+ * @deprecated 请使用 {@link #updateProduct(SpuUpdateInfo)}
*/
+ @Deprecated
SpuUpdateResponse updateProduct(SpuInfo info) throws WxErrorException;
+ /**
+ * 免审更新商品
+ *
+ * @param info 商品信息
+ * @return 返回商品的状态和id
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse updateProductAuditFree(SpuFastInfo info) throws WxErrorException;
+
/**
* 更新商品库存 (仅对edit_status != 2 的商品适用,其他状态的商品无法通过该接口修改库存)
*
* @param productId 内部商品ID
* @param skuId 内部sku_id
* @param diffType 修改类型 1增加 2减少 3设置
+ * 建议使用1或2,不建议使用3,因为使用3在高并发场景可能会出现预期外表现
* @param num 增加、减少或者设置的库存值
* @return WxChannelBaseResponse
*
@@ -127,6 +170,42 @@ WxChannelBaseResponse updateStock(String productId, String skuId, Integer diffTy
*/
SkuStockResponse getSkuStock(String productId, String skuId) throws WxErrorException;
+ /**
+ * 批量获取库存信息 (单次请求不能超过50个商品ID)
+ *
+ * @param productIds 商品ID列表
+ * @return 库存信息
+ * @throws WxErrorException 异常
+ */
+ SkuStockBatchResponse getSkuStockBatch(List productIds) throws WxErrorException;
+
+ /**
+ * 获取商品H5链接
+ *
+ * @param productId 商品ID
+ * @return 商品H5链接
+ * @throws WxErrorException 异常
+ */
+ ProductH5UrlResponse getProductH5Url(String productId) throws WxErrorException;
+
+ /**
+ * 获取商品二维码
+ *
+ * @param productId 商品ID
+ * @return 商品二维码
+ * @throws WxErrorException 异常
+ */
+ ProductQrCodeResponse getProductQrCode(String productId) throws WxErrorException;
+
+ /**
+ * 获取商品口令
+ *
+ * @param productId 商品ID
+ * @return 商品口令
+ * @throws WxErrorException 异常
+ */
+ ProductTagLinkResponse getProductTagLink(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 9d10f51c06..50a029c196 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
@@ -91,6 +91,27 @@ public interface WxChannelService extends BaseWxChannelService {
*/
WxChannelFundService getFundService();
+ /**
+ * 主页管理服务
+ *
+ * @return 主页管理服务
+ */
+ WxStoreHomePageService getHomePageService();
+
+ /**
+ * 合作账号服务
+ *
+ * @return 团长合作服务
+ */
+ WxStoreCooperationService getCooperationService();
+
+ /**
+ * 视频号/微信小店 罗盘商家版服务
+ *
+ * @return 罗盘商家版服务
+ */
+ WxChannelCompassShopService getCompassShopService();
+
/**
* 优选联盟-团长合作达人管理服务
*
@@ -140,11 +161,25 @@ public interface WxChannelService extends BaseWxChannelService {
*/
WxAssistantService getAssistantService();
-
/**
* 会员功能
*
* @return 会员服务
*/
WxChannelVipService getVipService();
+
+ /**
+ * 视频号助手-罗盘达人版服务
+ *
+ * @return 罗盘达人版服务
+ */
+ WxChannelCompassFinderService getCompassFinderService();
+
+ /**
+ * 视频号助手-直播大屏数据服务
+ *
+ * @return 直播大屏数据服务
+ */
+ WxChannelLiveDashboardService getLiveDashboardService();
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelVipService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelVipService.java
index 0909844f06..4100659200 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelVipService.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxChannelVipService.java
@@ -45,11 +45,11 @@ public interface WxChannelVipService {
*
* @param needPhoneNumber the need phone number
* @param pageNum the page num
- * @param PageSize the page size
+ * @param pageSize the page size
* @return the vip list
* @throws WxErrorException the wx error exception
*/
- VipListResponse getVipList(Boolean needPhoneNumber, Integer pageNum, Integer PageSize) throws WxErrorException;
+ VipListResponse getVipList(Boolean needPhoneNumber, Integer pageNum, Integer pageSize) throws WxErrorException;
/**
* 获取用户积分
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeaguePromoterService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeaguePromoterService.java
index 8a8ffb9acf..60cf112271 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeaguePromoterService.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxLeaguePromoterService.java
@@ -15,43 +15,84 @@ public interface WxLeaguePromoterService {
/**
* 新增达人
*
- * @param finderId 视频号finder_id
+ * @param finderId 视频号finder_id,待废除
* @return 结果
+ * @deprecated 使用 {@link #addPromoterV2(String)}
*/
+ @Deprecated
WxChannelBaseResponse addPromoter(String finderId) throws WxErrorException;
/**
* 编辑达人
*
- * @param finderId 视频号finder_id
+ * @param finderId 视频号finder_id,待废除
* @param type 操作 1取消邀请 2结束合作
* @return 结果
+ * @deprecated 使用 {@link #updatePromoterV2(String, int)}
*/
+ @Deprecated
WxChannelBaseResponse updatePromoter(String finderId, int type) throws WxErrorException;
/**
* 删除达人
*
- * @param finderId 视频号finder_id
+ * @param finderId 视频号finder_id,待废除
* @return 结果
+ * @deprecated 使用 {@link #deletePromoterV2(String)}
*/
+ @Deprecated
WxChannelBaseResponse deletePromoter(String finderId) throws WxErrorException;
/**
* 获取达人详情信息
*
- * @param finderId 视频号finder_id
+ * @param finderId 视频号finder_id,待废除
* @return 结果
+ * @deprecated 使用 {@link #getPromoterInfoV2(String)}
*/
+ @Deprecated
PromoterInfoResponse getPromoterInfo(String finderId) throws WxErrorException;
- /**
- * 获取达人列表
- *
- * @param pageIndex 页面下标,下标从1开始,默认为1
- * @param pageSize 单页达人数(不超过200)
- * @param status 拉取该状态下的达人列表
- * @return 结果
- */
- PromoterListResponse listPromoter(Integer pageIndex, Integer pageSize, Integer status) throws WxErrorException;
+ /**
+ * 新增达人
+ *
+ * @param promoterId 达人带货id
+ * @return 结果
+ */
+ WxChannelBaseResponse addPromoterV2(String promoterId) throws WxErrorException;
+
+ /**
+ * 编辑达人
+ *
+ * @param promoterId 达人带货id
+ * @param type 操作 1取消邀请 2结束合作
+ * @return 结果
+ */
+ WxChannelBaseResponse updatePromoterV2(String promoterId, int type) throws WxErrorException;
+
+ /**
+ * 删除达人
+ *
+ * @param promoterId 达人带货id
+ * @return 结果
+ */
+ WxChannelBaseResponse deletePromoterV2(String promoterId) throws WxErrorException;
+
+ /**
+ * 获取达人详情信息
+ *
+ * @param promoterId 达人带货id
+ * @return 结果
+ */
+ PromoterInfoResponse getPromoterInfoV2(String promoterId) throws WxErrorException;
+
+ /**
+ * 获取达人列表
+ *
+ * @param pageIndex 页面下标,下标从1开始,默认为1
+ * @param pageSize 单页达人数(不超过200)
+ * @param status 拉取该状态下的达人列表
+ * @return 结果
+ */
+ PromoterListResponse listPromoter(Integer pageIndex, Integer pageSize, Integer status) throws WxErrorException;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxStoreCooperationService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxStoreCooperationService.java
new file mode 100644
index 0000000000..96d2ff5f8d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxStoreCooperationService.java
@@ -0,0 +1,70 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.cooperation.CooperationListResponse;
+import me.chanjar.weixin.channel.bean.cooperation.CooperationQrCodeResponse;
+import me.chanjar.weixin.channel.bean.cooperation.CooperationStatusResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 微信小店 合作账号相关接口
+ *
+ * @author Zeyes
+ * @see 合作账号状态机
+ */
+public interface WxStoreCooperationService {
+
+ /**
+ * 获取合作账号列表
+ *
+ * @param sharerType 合作账号类型 2公众号 3小程序
+ * @return 合作账号列表
+ *
+ * @throws WxErrorException 异常
+ */
+ CooperationListResponse listCooperation(Integer sharerType) throws WxErrorException;
+
+ /**
+ * 获取合作账号状态
+ *
+ * @param sharerId 合作账号id 公众号: gh_开头id 小程序: appid
+ * @param sharerType 合作账号类型 2公众号 3小程序
+ * @return 合作账号状态
+ *
+ * @throws WxErrorException 异常
+ */
+ CooperationStatusResponse getCooperationStatus(String sharerId, Integer sharerType) throws WxErrorException;
+
+ /**
+ * 生成合作账号邀请二维码
+ *
+ * @param sharerId 合作账号id 公众号: gh_开头id 小程序: appid
+ * @param sharerType 合作账号类型 2公众号 3小程序
+ * @return 二维码
+ *
+ * @throws WxErrorException 异常
+ */
+ CooperationQrCodeResponse generateQrCode(String sharerId, Integer sharerType) throws WxErrorException;
+
+ /**
+ * 取消合作账号邀请
+ *
+ * @param sharerId 合作账号id 公众号: gh_开头id 小程序: appid
+ * @param sharerType 合作账号类型 2公众号 3小程序
+ * @return WxChannelBaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse cancelInvitation(String sharerId, Integer sharerType) throws WxErrorException;
+
+ /**
+ * 解绑合作账号
+ *
+ * @param sharerId 合作账号id 公众号: gh_开头id 小程序: appid
+ * @param sharerType 合作账号类型 2公众号 3小程序
+ * @return WxChannelBaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse unbind(String sharerId, Integer sharerType) throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxStoreHomePageService.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxStoreHomePageService.java
new file mode 100644
index 0000000000..bd11e471b3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/WxStoreHomePageService.java
@@ -0,0 +1,188 @@
+package me.chanjar.weixin.channel.api;
+
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.home.background.BackgroundApplyResponse;
+import me.chanjar.weixin.channel.bean.home.background.BackgroundGetResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerApplyResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerGetResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductEditInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductListInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductListResponse;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowGetResponse;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowSetResponse;
+import me.chanjar.weixin.channel.bean.home.window.WindowProductSettingResponse;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 微信小店 主页管理相关接口
+ *
+ * @author Zeyes
+ */
+public interface WxStoreHomePageService {
+
+ /**
+ * 添加分类关联的商品
+ *
+ * @param info 商品分类以及商品id
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse addTreeProduct(TreeProductEditInfo info) throws WxErrorException;
+
+ /**
+ * 删除分类关联的商品
+ *
+ * @param info 商品分类以及商品id
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse delTreeProduct(TreeProductEditInfo info) throws WxErrorException;
+
+ /**
+ * 获取分类关联的商品ID列表
+ *
+ * @param info 分类id、分页大小、分页上下文
+ * @return 商品id、分页上下文
+ *
+ * @throws WxErrorException 异常
+ */
+ TreeProductListResponse getTreeProductList(TreeProductListInfo info) throws WxErrorException;
+
+ /**
+ * 设置展示在店铺主页的商品分类
+ *
+ * @param info 分类id
+ * @return 商品分类审核结果
+ *
+ * @throws WxErrorException 异常
+ */
+ TreeShowSetResponse setShowTree(TreeShowInfo info) throws WxErrorException;
+
+ /**
+ * 获取展示在店铺主页的商品分类
+ *
+ * @return 商品分类信息
+ *
+ * @throws WxErrorException 异常
+ */
+ TreeShowGetResponse getShowTree() throws WxErrorException;
+
+ /**
+ * 获取主页展示商品列表
+ *
+ * @param pageSize 分页大小
+ * @param nextKey 分页上下文
+ * @return WindowProductSettingResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WindowProductSettingResponse listWindowProduct(Integer pageSize, String nextKey) throws WxErrorException;
+
+ /**
+ * 删除主页展示商品
+ *
+ * @param productId 商品id
+ * @param indexNum 商品重新排序后的新序号,最大移动步长为500(即新序号与当前序号的距离小于500)
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse reorderWindowProduct(String productId, Integer indexNum) throws WxErrorException;
+
+ /**
+ * 隐藏小店主页商品
+ *
+ * @param productId 商品id
+ * @param setHide 是否隐藏。1-隐藏,0-取消隐藏
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse hideWindowProduct(String productId, Integer setHide) throws WxErrorException;
+
+ /**
+ * 置顶小店主页商品
+ *
+ * @param productId 商品id
+ * @param setTop 是否顶置。1-置顶,0-取消置顶
+ * @return BaseResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse topWindowProduct(String productId, Integer setTop) throws WxErrorException;
+
+ /**
+ * 提交背景图申请
+ *
+ * @param imgUrl 图片链接。请务必使用接口上传图片(参数resp_type=1),并将返回的img_url填入此处,不接受其他任何格式的图片url。
+ * 若url曾经做过转换(url前缀为mmecimage.cn/p/),则可以直接提交。
+ * @return 申请编号
+ *
+ * @throws WxErrorException 异常
+ * @see WxChannelBasicService#uploadImg(int, String)
+ */
+ BackgroundApplyResponse applyBackground(String imgUrl) throws WxErrorException;
+
+ /**
+ * 查询背景图
+ *
+ * @return 背景图信息
+ * @throws WxErrorException 异常
+ */
+ BackgroundGetResponse getBackground() throws WxErrorException;
+
+ /**
+ * 撤销主页背景图申请
+ *
+ * @param applyId 申请编号
+ * @return BaseResponse
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse cancelBackground(Integer applyId) throws WxErrorException;
+
+ /**
+ * 清空主页背景图并撤销流程中的申请
+ *
+ * @return BaseResponse
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse removeBackground() throws WxErrorException;
+
+ /**
+ * 提交精选展示位申请
+ *
+ * @param info 展示位信息
+ * @return 申请编号
+ * @throws WxErrorException 异常
+ */
+ BannerApplyResponse applyBanner(BannerInfo info) throws WxErrorException;
+
+ /**
+ * 查询精选展示位
+ *
+ * @return 展示位信息
+ * @throws WxErrorException 异常
+ */
+ BannerGetResponse getBanner() throws WxErrorException;
+
+ /**
+ * 撤销精选展示位申请
+ *
+ * @param applyId 申请编号
+ * @return BaseResponse
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse cancelBanner(Integer applyId) throws WxErrorException;
+
+ /**
+ * 清空精选展示位并撤销流程中的申请
+ *
+ * @return BaseResponse
+ * @throws WxErrorException 异常
+ */
+ WxChannelBaseResponse removeBanner() throws WxErrorException;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelMessageServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelMessageServiceImpl.java
index 2cc75d0de1..0aeabdd7c6 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelMessageServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/BaseWxChannelMessageServiceImpl.java
@@ -23,9 +23,14 @@
import me.chanjar.weixin.channel.bean.message.product.BrandMessage;
import me.chanjar.weixin.channel.bean.message.product.CategoryAuditMessage;
import me.chanjar.weixin.channel.bean.message.product.SpuAuditMessage;
+import me.chanjar.weixin.channel.bean.message.product.SpuStockMessage;
+import me.chanjar.weixin.channel.bean.message.sharer.SharerChangeMessage;
+import me.chanjar.weixin.channel.bean.message.store.CloseStoreMessage;
+import me.chanjar.weixin.channel.bean.message.store.NicknameUpdateMessage;
import me.chanjar.weixin.channel.bean.message.supplier.SupplierItemMessage;
import me.chanjar.weixin.channel.bean.message.vip.ExchangeInfoMessage;
import me.chanjar.weixin.channel.bean.message.vip.UserInfoMessage;
+import me.chanjar.weixin.channel.bean.message.voucher.VoucherMessage;
import me.chanjar.weixin.channel.message.WxChannelMessage;
import me.chanjar.weixin.channel.message.WxChannelMessageRouter;
import me.chanjar.weixin.channel.message.WxChannelMessageRouterRule;
@@ -61,6 +66,8 @@ protected void addDefaultRule() {
this.addRule(SpuAuditMessage.class, PRODUCT_SPU_STATUS_UPDATE, this::spuStatusUpdate);
/* 商品更新 */
this.addRule(SpuAuditMessage.class, PRODUCT_SPU_UPDATE, this::spuUpdate);
+ /* 商品库存不足 */
+ this.addRule(SpuStockMessage.class, PRODUCT_STOCK_NO_ENOUGH, this::stockNoEnough);
/* 类目审核结果 */
this.addRule(CategoryAuditMessage.class, PRODUCT_CATEGORY_AUDIT, this::categoryAudit);
/* 订单下单 */
@@ -69,6 +76,8 @@ protected void addDefaultRule() {
this.addRule(OrderCancelMessage.class, ORDER_CANCEL, this::orderCancel);
/* 订单支付成功 */
this.addRule(OrderPayMessage.class, ORDER_PAY, this::orderPay);
+ /* 订单待发货 */
+ this.addRule(OrderIdMessage.class, ORDER_WAIT_SHIPPING, this::orderWaitShipping);
/* 订单发货 */
this.addRule(OrderDeliveryMessage.class, ORDER_DELIVER, this::orderDelivery);
/* 订单确认收货 */
@@ -101,6 +110,8 @@ protected void addDefaultRule() {
this.addRule(UserCouponExpireMessage.class, USER_COUPON_UNUSE, this::userCouponUnuse);
/* 优惠券返还通知 */
this.addRule(UserCouponExpireMessage.class, USER_COUPON_USE, this::userCouponUse);
+ /* 发放团购优惠成功通知 */
+ this.addRule(VoucherMessage.class, VOUCHER_SEND_SUCC, this::voucherSendSucc);
/* 结算账户变更回调 */
this.addRule(AccountNotifyMessage.class, ACCOUNT_NOTIFY, this::accountNotify);
/* 提现回调 */
@@ -110,7 +121,6 @@ protected void addDefaultRule() {
/* 团长 */
this.addRule(SupplierItemMessage.class, SUPPLIER_ITEM_UPDATE, this::supplierItemUpdate);
-
/* 用户加入会员 */
this.addRule(UserInfoMessage.class, USER_VIP_JOIN, false, this::vipJoin);
/* 用户注销会员 */
@@ -121,6 +131,14 @@ protected void addDefaultRule() {
this.addRule(UserInfoMessage.class, USER_VIP_SCORE_UPDATE, false, this::vipScoreUpdate);
/* 用户积分兑换 */
this.addRule(ExchangeInfoMessage.class, USER_VIP_SCORE_EXCHANGE, false, this::vipScoreExchange);
+
+ /* 分享员变更 */
+ this.addRule(SharerChangeMessage.class,SHARER_CHANGE,false,this::sharerChange);
+
+ /* 小店注销 */
+ this.addRule(CloseStoreMessage.class, CLOSE_STORE, this::closeStore);
+ /* 小店修改名称 */
+ this.addRule(NicknameUpdateMessage.class, SET_SHOP_NICKNAME, this::updateNickname);
}
/**
@@ -139,6 +157,7 @@ protected void addRule(Class clazz, String event
consumer.accept(message, content, appId, context, sessionManager);
return "success";
});
+ rule.setNext(true);
this.addRule(rule);
}
@@ -176,6 +195,12 @@ public void orderPay(OrderPayMessage message, String content, String appId,
log.info("订单支付成功:{}", JsonUtils.encode(message));
}
+ @Override
+ public void orderWaitShipping(OrderIdMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("订单待发货:{}", JsonUtils.encode(message));
+ }
+
@Override
public void orderDelivery(OrderDeliveryMessage message, String content, String appId,
Map context, WxSessionManager sessionManager) {
@@ -224,6 +249,12 @@ public void spuUpdate(SpuAuditMessage message, String content, String appId,
log.info("商品更新:{}", JsonUtils.encode(message));
}
+ @Override
+ public void stockNoEnough(SpuStockMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("商品库存不足:{}", JsonUtils.encode(message));
+ }
+
@Override
public void categoryAudit(CategoryAuditMessage message, String content, String appId,
Map context, WxSessionManager sessionManager) {
@@ -302,6 +333,12 @@ public void userCouponUnuse(UserCouponExpireMessage message, String content, Str
log.info("用户优惠券取消使用:{}", JsonUtils.encode(message));
}
+ @Override
+ public void voucherSendSucc(VoucherMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("发放团购优惠成功:{}", JsonUtils.encode(message));
+ }
+
@Override
public void accountNotify(AccountNotifyMessage message, String content, String appId,
Map context, WxSessionManager sessionManager) {
@@ -333,24 +370,50 @@ public Object defaultMessageHandler(WxChannelMessage message, String content, St
return null;
}
+ @Override
+ public void sharerChange(WxChannelMessage message, String content, String appId, Map context, WxSessionManager sessionManager) {
+ log.info("分享员变更:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void vipJoin(UserInfoMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("用户加入会员:{}", JsonUtils.encode(message));
+ }
+
+ @Override
+ public void vipClose(UserInfoMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("用户注销会员:{}", JsonUtils.encode(message));
+ }
@Override
- public abstract void vipJoin(UserInfoMessage message, String content, String appId,
- Map context, WxSessionManager sessionManager);
+ public void vipGradeUpdate(UserInfoMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("用户等级信息更新:{}", JsonUtils.encode(message));
+ }
@Override
- public abstract void vipClose(UserInfoMessage message, String content, String appId,
- Map context, WxSessionManager sessionManager);
+ public void vipScoreUpdate(UserInfoMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("用户积分更新:{}", JsonUtils.encode(message));
+ }
@Override
- public abstract void vipGradeUpdate(UserInfoMessage message, String content, String appId,
- Map context, WxSessionManager sessionManager);
+ public void vipScoreExchange(ExchangeInfoMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("用户积分兑换:{}", JsonUtils.encode(message));
+ }
@Override
- public abstract void vipScoreUpdate(UserInfoMessage message, String content, String appId,
- Map context, WxSessionManager sessionManager);
+ public void closeStore(CloseStoreMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("小店注销:{}", JsonUtils.encode(message));
+ }
@Override
- public abstract void vipScoreExchange(ExchangeInfoMessage message, String content, String appId,
- Map context, WxSessionManager sessionManager);
+ public void updateNickname(NicknameUpdateMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("小店修改名称:{}", JsonUtils.encode(message));
+ }
}
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 307a9e77d1..1a608e1f6a 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
@@ -47,6 +47,9 @@ public abstract class BaseWxChannelServiceImpl implements WxChannelService
private final WxChannelCouponService couponService = new WxChannelCouponServiceImpl(this);
private final WxChannelSharerService sharerService = new WxChannelSharerServiceImpl(this);
private final WxChannelFundService fundService = new WxChannelFundServiceImpl(this);
+ private WxStoreHomePageService homePageService = null;
+ private WxStoreCooperationService cooperationService = null;
+ private WxChannelCompassShopService compassShopService = null;
private WxLeagueWindowService leagueWindowService = null;
private WxLeagueSupplierService leagueSupplierService = null;
private WxLeaguePromoterService leaguePromoterService = null;
@@ -54,14 +57,16 @@ public abstract class BaseWxChannelServiceImpl implements WxChannelService
private WxLeadComponentService leadComponentService = null;
private WxFinderLiveService finderLiveService = null;
private WxAssistantService assistantService = null;
- private WxChannelVipService vipService = new WxChannelVipServiceImpl(this);
+ private WxChannelVipService vipService = null;
+ private WxChannelCompassFinderService compassFinderService = null;
+ private WxChannelLiveDashboardService liveDashboardService = null;
protected WxChannelConfig config;
private int retrySleepMillis = 1000;
private int maxRetryTimes = 5;
@Override
- public RequestHttp getRequestHttp() {
+ public RequestHttp getRequestHttp() {
return this;
}
@@ -70,7 +75,7 @@ public boolean checkSignature(String timestamp, String nonce, String signature)
try {
return SHA1.gen(this.getConfig().getToken(), timestamp, nonce).equals(signature);
} catch (Exception e) {
- log.error("Checking signature failed, and the reason is :" + e.getMessage());
+ log.error("Checking signature failed, and the reason is :{}", e.getMessage());
return false;
}
}
@@ -95,9 +100,14 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
return this.getConfig().getAccessToken();
}
} while (!locked);
- String response = doGetAccessTokenRequest();
+ String response;
+ if (getConfig().isStableAccessToken()) {
+ response = doGetStableAccessTokenRequest(forceRefresh);
+ } else {
+ response = doGetAccessTokenRequest();
+ }
return extractAccessToken(response);
- } catch (WxErrorException | InterruptedException e) {
+ } catch (IOException | InterruptedException e) {
throw new WxRuntimeException(e);
} finally {
if (locked) {
@@ -109,10 +119,18 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
/**
* 通过网络请求获取AccessToken
*
- * @return .
- * @throws IOException .
+ * @return AccessToken
+ * @throws IOException IOException
*/
- protected abstract String doGetAccessTokenRequest() throws WxErrorException;
+ protected abstract String doGetAccessTokenRequest() throws IOException;
+
+ /**
+ * 通过网络请求获取稳定版AccessToken
+ *
+ * @return Stable AccessToken
+ * @throws IOException IOException
+ */
+ protected abstract String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException;
@Override
public String get(String url, String queryParam) throws WxErrorException {
@@ -258,9 +276,9 @@ protected T executeInternal(RequestExecutor executor, String uri, E
* @throws WxErrorException 异常
*/
protected String extractAccessToken(String resultContent) throws WxErrorException {
- log.info("resultContent: " + resultContent);
+ log.debug("access-token response: {}", resultContent);
WxChannelConfig config = this.getConfig();
- WxError error = WxError.fromJson(resultContent, WxType.MiniApp);
+ WxError error = WxError.fromJson(resultContent, WxType.Channel);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
}
@@ -350,6 +368,30 @@ public WxChannelFundService getFundService() {
return fundService;
}
+ @Override
+ public synchronized WxStoreHomePageService getHomePageService() {
+ if (homePageService == null) {
+ homePageService = new WxStoreHomePageServiceImpl(this);
+ }
+ return homePageService;
+ }
+
+ @Override
+ public synchronized WxStoreCooperationService getCooperationService() {
+ if (cooperationService == null) {
+ cooperationService = new WxStoreCooperationServiceImpl(this);
+ }
+ return cooperationService;
+ }
+
+ @Override
+ public synchronized WxChannelCompassShopService getCompassShopService() {
+ if (compassShopService == null) {
+ compassShopService = new WxChannelCompassShopServiceImpl(this);
+ }
+ return compassShopService;
+ }
+
@Override
public synchronized WxLeagueWindowService getLeagueWindowService() {
if (leagueWindowService == null) {
@@ -383,7 +425,7 @@ public synchronized WxLeagueProductService getLeagueProductService() {
}
@Override
- public WxLeadComponentService getLeadComponentService() {
+ public synchronized WxLeadComponentService getLeadComponentService() {
if (leadComponentService == null) {
leadComponentService = new WxLeadComponentServiceImpl(this);
}
@@ -391,7 +433,7 @@ public WxLeadComponentService getLeadComponentService() {
}
@Override
- public WxFinderLiveService getFinderLiveService() {
+ public synchronized WxFinderLiveService getFinderLiveService() {
if (finderLiveService == null) {
finderLiveService = new WxFinderLiveServiceImpl(this);
}
@@ -399,7 +441,7 @@ public WxFinderLiveService getFinderLiveService() {
}
@Override
- public WxAssistantService getAssistantService() {
+ public synchronized WxAssistantService getAssistantService() {
if (assistantService == null) {
assistantService = new WxAssistantServiceImpl(this) {
};
@@ -408,7 +450,27 @@ public WxAssistantService getAssistantService() {
}
@Override
- public WxChannelVipService getVipService() {
+ public synchronized WxChannelVipService getVipService() {
+ if (vipService == null) {
+ vipService = new WxChannelVipServiceImpl(this);
+ }
return vipService;
}
+
+ @Override
+ public synchronized WxChannelCompassFinderService getCompassFinderService() {
+ if (compassFinderService == null) {
+ compassFinderService = new WxChannelCompassFinderServiceImpl(this);
+ }
+ return compassFinderService;
+ }
+
+ @Override
+ public synchronized WxChannelLiveDashboardService getLiveDashboardService() {
+ if (liveDashboardService == null) {
+ liveDashboardService = new WxChannelLiveDashboardServiceImpl(this);
+ }
+ return liveDashboardService;
+ }
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxAssistantServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxAssistantServiceImpl.java
index 20572c5ef0..55be5abcca 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxAssistantServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxAssistantServiceImpl.java
@@ -28,7 +28,7 @@
public class WxAssistantServiceImpl implements WxAssistantService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
@Override
public WxChannelBaseResponse addWindowProduct(AddWindowProductRequest req) throws WxErrorException {
String resJson = shopService.post(ADD_WINDOW_PRODUCT_URL, "{}");
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAddressServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAddressServiceImpl.java
index 53b9eb4d7a..20cf128559 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAddressServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAddressServiceImpl.java
@@ -29,9 +29,9 @@
public class WxChannelAddressServiceImpl implements WxChannelAddressService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelAddressServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelAddressServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java
index c29ea49b34..92f865444b 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImpl.java
@@ -1,30 +1,19 @@
package me.chanjar.weixin.channel.api.impl;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_ACCEPT_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_GET_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_LIST_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_REJECT_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.AFTER_SALE_UPLOAD_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Complaint.ADD_COMPLAINT_MATERIAL_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Complaint.ADD_COMPLAINT_PROOF_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Complaint.GET_COMPLAINT_ORDER_URL;
-
-import java.util.List;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.channel.api.WxChannelAfterSaleService;
-import me.chanjar.weixin.channel.bean.after.AfterSaleAcceptParam;
-import me.chanjar.weixin.channel.bean.after.AfterSaleIdParam;
-import me.chanjar.weixin.channel.bean.after.AfterSaleInfoResponse;
-import me.chanjar.weixin.channel.bean.after.AfterSaleListParam;
-import me.chanjar.weixin.channel.bean.after.AfterSaleListResponse;
-import me.chanjar.weixin.channel.bean.after.AfterSaleRejectParam;
-import me.chanjar.weixin.channel.bean.after.RefundEvidenceParam;
+import me.chanjar.weixin.channel.bean.after.*;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
import me.chanjar.weixin.channel.bean.complaint.ComplaintOrderResponse;
import me.chanjar.weixin.channel.bean.complaint.ComplaintParam;
import me.chanjar.weixin.channel.util.ResponseUtils;
import me.chanjar.weixin.common.error.WxErrorException;
+import java.util.List;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.AfterSale.*;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Complaint.*;
+
/**
* 视频号小店 售后服务实现
*
@@ -33,17 +22,25 @@
@Slf4j
public class WxChannelAfterSaleServiceImpl implements WxChannelAfterSaleService {
- /** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ /**
+ * 微信商店服务
+ */
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelAfterSaleServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelAfterSaleServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
@Override
public AfterSaleListResponse listIds(Long beginCreateTime, Long endCreateTime, String nextKey)
throws WxErrorException {
- AfterSaleListParam param = new AfterSaleListParam(beginCreateTime, endCreateTime, nextKey);
+ AfterSaleListParam param = new AfterSaleListParam(beginCreateTime, endCreateTime, null, null, nextKey);
+ String resJson = shopService.post(AFTER_SALE_LIST_URL, param);
+ return ResponseUtils.decode(resJson, AfterSaleListResponse.class);
+ }
+
+ @Override
+ public AfterSaleListResponse listIds(AfterSaleListParam param) throws WxErrorException {
String resJson = shopService.post(AFTER_SALE_LIST_URL, param);
return ResponseUtils.decode(resJson, AfterSaleListResponse.class);
}
@@ -56,15 +53,15 @@ public AfterSaleInfoResponse get(String afterSaleOrderId) throws WxErrorExceptio
}
@Override
- public WxChannelBaseResponse accept(String afterSaleOrderId, String addressId) throws WxErrorException {
- AfterSaleAcceptParam param = new AfterSaleAcceptParam(afterSaleOrderId, addressId);
+ public WxChannelBaseResponse accept(String afterSaleOrderId, String addressId, Integer acceptType) throws WxErrorException {
+ AfterSaleAcceptParam param = new AfterSaleAcceptParam(afterSaleOrderId, addressId, acceptType);
String resJson = shopService.post(AFTER_SALE_ACCEPT_URL, param);
return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
}
@Override
- public WxChannelBaseResponse reject(String afterSaleOrderId, String rejectReason) throws WxErrorException {
- AfterSaleRejectParam param = new AfterSaleRejectParam(afterSaleOrderId, rejectReason);
+ public WxChannelBaseResponse reject(String afterSaleOrderId, String rejectReason, Integer rejectReasonType) throws WxErrorException {
+ AfterSaleRejectParam param = new AfterSaleRejectParam(afterSaleOrderId, rejectReason, rejectReasonType);
String resJson = shopService.post(AFTER_SALE_REJECT_URL, param);
return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
}
@@ -100,4 +97,37 @@ public ComplaintOrderResponse getComplaint(String complaintId) throws WxErrorExc
String resJson = shopService.post(GET_COMPLAINT_ORDER_URL, reqJson);
return ResponseUtils.decode(resJson, ComplaintOrderResponse.class);
}
+
+ @Override
+ public AfterSaleReasonResponse getAllReason() throws WxErrorException {
+ String resJson = shopService.post(AFTER_SALE_REASON_GET_URL, "{}");
+ return ResponseUtils.decode(resJson, AfterSaleReasonResponse.class);
+ }
+
+ @Override
+ public AfterSaleRejectReasonResponse getRejectReason() throws WxErrorException {
+ String resJson = shopService.post(AFTER_SALE_REJECT_REASON_GET_URL, "{}");
+ return ResponseUtils.decode(resJson, AfterSaleRejectReasonResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse acceptExchangeReship(String afterSaleOrderId, String waybillId, String deliveryId) throws WxErrorException {
+ AfterSaleAcceptExchangeReshipParam param = new AfterSaleAcceptExchangeReshipParam(afterSaleOrderId, waybillId, deliveryId);
+ String resJson = shopService.post(AFTER_SALE_ACCEPT_EXCHANGE_RESHIP_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse rejectExchangeReship(String afterSaleOrderId, String rejectReason, Integer rejectReasonType, List rejectCertificates) throws WxErrorException {
+ AfterSaleRejectExchangeReshipParam param = new AfterSaleRejectExchangeReshipParam(afterSaleOrderId, rejectReason, rejectReasonType, rejectCertificates);
+ String resJson = shopService.post(AFTER_SALE_REJECT_EXCHANGE_RESHIP_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse merchantUpdateAfterSale(AfterSaleMerchantUpdateParam param) throws WxErrorException {
+ String resJson = shopService.post(AFTER_SALE_MERCHANT_UPDATE_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
}
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 cac5e9e513..6eb699da23 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
@@ -31,9 +31,9 @@
public class WxChannelBasicServiceImpl implements WxChannelBasicService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelBasicServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelBasicServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
@@ -56,7 +56,7 @@ public ChannelImageInfo uploadImg(int respType, String imgUrl) throws WxErrorExc
public ChannelImageInfo uploadImg(int respType, File file, int height, int width) throws WxErrorException {
String url = IMG_UPLOAD_URL + "?upload_type=0&resp_type=" + respType + "&height=" + height + "&width=" + width;
RequestExecutor executor = ChannelFileUploadRequestExecutor.create(shopService);
- String resJson = (String) shopService.execute(executor, url, file);
+ String resJson = shopService.execute(executor, url, file);
UploadImageResponse response = ResponseUtils.decode(resJson, UploadImageResponse.class);
return response.getImgInfo();
}
@@ -64,19 +64,19 @@ public ChannelImageInfo uploadImg(int respType, File file, int height, int width
@Override
public QualificationFileResponse uploadQualificationFile(File file) throws WxErrorException {
RequestExecutor executor = ChannelFileUploadRequestExecutor.create(shopService);
- String resJson = (String) shopService.execute(executor, UPLOAD_QUALIFICATION_FILE, file);
+ String resJson = shopService.execute(executor, UPLOAD_QUALIFICATION_FILE, file);
return ResponseUtils.decode(resJson, QualificationFileResponse.class);
}
@Override
public ChannelImageResponse getImg(String mediaId) throws WxErrorException {
String appId = shopService.getConfig().getAppid();
- ChannelImageResponse rs = null;
+ ChannelImageResponse rs;
try {
String url = GET_IMG_URL + "?media_id=" + mediaId;
RequestExecutor executor = ChannelMediaDownloadRequestExecutor.create(shopService,
Files.createTempDirectory("wxjava-channel-" + appId).toFile());
- rs = (ChannelImageResponse) shopService.execute(executor, url, null);
+ rs = shopService.execute(executor, url, null);
} catch (IOException e) {
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e);
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBrandServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBrandServiceImpl.java
index 19aadcc06e..c6c476b116 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBrandServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelBrandServiceImpl.java
@@ -33,9 +33,9 @@
public class WxChannelBrandServiceImpl implements WxChannelBrandService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelBrandServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelBrandServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java
index 52fdf3cdf8..7070ab9298 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImpl.java
@@ -1,13 +1,5 @@
package me.chanjar.weixin.channel.api.impl;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.ADD_CATEGORY_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.AVAILABLE_CATEGORY_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.CANCEL_CATEGORY_AUDIT_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.GET_CATEGORY_AUDIT_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.GET_CATEGORY_DETAIL_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.LIST_ALL_CATEGORY_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.LIST_PASS_CATEGORY_URL;
-
import java.util.Collections;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@@ -17,17 +9,15 @@
import me.chanjar.weixin.channel.bean.audit.CategoryAuditInfo;
import me.chanjar.weixin.channel.bean.audit.CategoryAuditRequest;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
-import me.chanjar.weixin.channel.bean.category.CategoryDetailResult;
-import me.chanjar.weixin.channel.bean.category.CategoryQualificationResponse;
-import me.chanjar.weixin.channel.bean.category.PassCategoryResponse;
-import me.chanjar.weixin.channel.bean.category.ShopCategory;
-import me.chanjar.weixin.channel.bean.category.ShopCategoryResponse;
+import me.chanjar.weixin.channel.bean.category.*;
import me.chanjar.weixin.channel.util.JsonUtils;
import me.chanjar.weixin.channel.util.ResponseUtils;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Category.*;
+
/**
* 视频号小店 商品类目相关接口
*
@@ -37,9 +27,9 @@
public class WxChannelCategoryServiceImpl implements WxChannelCategoryService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelCategoryServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelCategoryServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
@@ -56,7 +46,7 @@ public List listAvailableCategory(String parentId) throws WxErrorE
try {
pid = Long.parseLong(parentId);
} catch (Throwable e) {
- log.error("parentId必须为数字, " + parentId, e);
+ log.error("parentId必须为数字, {}", parentId, e);
return Collections.emptyList();
}
String reqJson = "{\"f_cat_id\": " + pid + "}";
@@ -66,13 +56,21 @@ public List listAvailableCategory(String parentId) throws WxErrorE
return response.getCategories();
}
+ @Override
+ public ShopCategoryResponse listAvailableCategories(String fCatId) throws WxErrorException {
+ String reqJson = "{\"f_cat_id\": " + fCatId + "}";
+ String resJson = (String) shopService.executeWithoutLog(SimplePostRequestExecutor.create(shopService),
+ AVAILABLE_CATEGORY_URL, reqJson);
+ return ResponseUtils.decode(resJson, ShopCategoryResponse.class);
+ }
+
@Override
public CategoryDetailResult getCategoryDetail(String id) throws WxErrorException {
Long catId = null;
try {
catId = Long.parseLong(id);
} catch (Throwable e) {
- log.error("id必须为数字, " + id, e);
+ log.error("id必须为数字, {}", id, e);
return ResponseUtils.internalError(CategoryDetailResult.class);
}
String reqJson = "{\"cat_id\": " + catId + "}";
@@ -89,7 +87,11 @@ public AuditApplyResponse addCategory(String level1, String level2, String level
Long l1 = Long.parseLong(level1);
Long l2 = Long.parseLong(level2);
Long l3 = Long.parseLong(level3);
- CategoryAuditInfo categoryInfo = new CategoryAuditInfo(l1, l2, l3, certificate);
+ CategoryAuditInfo categoryInfo = new CategoryAuditInfo();
+ categoryInfo.setLevel1(l1);
+ categoryInfo.setLevel2(l2);
+ categoryInfo.setLevel3(l3);
+ categoryInfo.setCertificates(certificate);
reqJson = JsonUtils.encode(new CategoryAuditRequest(categoryInfo));
} catch (Throwable e) {
log.error("微信请求异常", e);
@@ -98,6 +100,13 @@ public AuditApplyResponse addCategory(String level1, String level2, String level
return ResponseUtils.decode(resJson, AuditApplyResponse.class);
}
+ @Override
+ public AuditApplyResponse addCategory(CategoryAuditInfo info) throws WxErrorException {
+ String reqJson = JsonUtils.encode(new CategoryAuditRequest(info));
+ String resJson = shopService.post(ADD_CATEGORY_URL, reqJson);
+ return ResponseUtils.decode(resJson, AuditApplyResponse.class);
+ }
+
@Override
public WxChannelBaseResponse cancelCategoryAudit(String auditId) throws WxErrorException {
String resJson = shopService.post(CANCEL_CATEGORY_AUDIT_URL, "{\"audit_id\": \"" + auditId + "\"}");
@@ -116,4 +125,15 @@ public PassCategoryResponse listPassCategory() throws WxErrorException {
return ResponseUtils.decode(resJson, PassCategoryResponse.class);
}
+ @Override
+ public RelationCategoryResponse listRelationCategory(Boolean isFilterStatus, Integer status) throws WxErrorException {
+ RelationCategoryRequest request = new RelationCategoryRequest(
+ isFilterStatus != null ? isFilterStatus : false,
+ status != null ? status : 0
+ );
+ String reqJson = JsonUtils.encode(request);
+ String resJson = shopService.post(LIST_RELATION_CATEGORY_URL, reqJson);
+ return ResponseUtils.decode(resJson, RelationCategoryResponse.class);
+ }
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassFinderServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassFinderServiceImpl.java
new file mode 100644
index 0000000000..c80345aef2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassFinderServiceImpl.java
@@ -0,0 +1,55 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelCompassFinderService;
+import me.chanjar.weixin.channel.bean.compass.CompassFinderBaseParam;
+import me.chanjar.weixin.channel.bean.compass.finder.*;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassFinder.*;
+
+/**
+ * 视频号助手 罗盘达人版服务实现
+ *
+ * @author Winnie
+ */
+@Slf4j
+public class WxChannelCompassFinderServiceImpl implements WxChannelCompassFinderService {
+
+ /**
+ * 微信商店服务
+ */
+ private final BaseWxChannelServiceImpl, ?> shopService;
+
+ public WxChannelCompassFinderServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {this.shopService = shopService;}
+
+ @Override
+ public OverallResponse getOverall(String ds) throws WxErrorException {
+ CompassFinderBaseParam param = new CompassFinderBaseParam(ds);
+ String resJson = shopService.post(GET_OVERALL_URL, param);
+ return ResponseUtils.decode(resJson, OverallResponse.class);
+ }
+
+ @Override
+ public ProductDataResponse getProductData(String ds, String productId) throws WxErrorException {
+ ProductDataParam param = new ProductDataParam(ds, productId);
+ String resJson = shopService.post(GET_PRODUCT_DATA_URL, param);
+ return ResponseUtils.decode(resJson, ProductDataResponse.class);
+ }
+
+ @Override
+ public ProductListResponse getProductList(String ds) throws WxErrorException {
+ CompassFinderBaseParam param = new CompassFinderBaseParam(ds);
+ String resJson = shopService.post(GET_PRODUCT_LIST_URL, param);
+ return ResponseUtils.decode(resJson, ProductListResponse.class);
+ }
+
+ @Override
+ public SaleProfileDataResponse getSaleProfileData(String ds, Integer type) throws WxErrorException {
+ SaleProfileDataParam param = new SaleProfileDataParam(ds, type);
+ String resJson = shopService.post(GET_SALE_PROFILE_DATA_URL, param);
+ return ResponseUtils.decode(resJson, SaleProfileDataResponse.class);
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassShopServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassShopServiceImpl.java
new file mode 100644
index 0000000000..3a593a691f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassShopServiceImpl.java
@@ -0,0 +1,116 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.FINDER_AUTH_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.FINDER_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.GET_FINDER_OVERALL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.GET_FINDER_PRODUCT_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.GET_FINDER_PRODUCT_OVERALL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.GET_LIVE_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.GET_SHOP_OVERALL_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.GET_SHOP_PRODUCT_DATA_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.GET_SHOP_PRODUCT_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.CompassShop.GET_SHOP_SALE_PROFILE_DATA_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelCompassShopService;
+import me.chanjar.weixin.channel.bean.compass.CompassFinderBaseParam;
+import me.chanjar.weixin.channel.bean.compass.shop.CompassFinderIdParam;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderAuthListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderProductListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderProductOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopLiveListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopProductDataParam;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopProductDataResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopProductListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopSaleProfileDataParam;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopSaleProfileDataResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 视频号/微信小店 罗盘商家版 服务实现
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxChannelCompassShopServiceImpl implements WxChannelCompassShopService {
+
+ /**
+ * 微信商店服务
+ */
+ private final BaseWxChannelServiceImpl, ?> shopService;
+
+ public WxChannelCompassShopServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {this.shopService = shopService;}
+
+ @Override
+ public ShopOverallResponse getShopOverall(String ds) throws WxErrorException {
+ CompassFinderBaseParam param = new CompassFinderBaseParam(ds);
+ String resJson = shopService.post(GET_SHOP_OVERALL_URL, param);
+ return ResponseUtils.decode(resJson, ShopOverallResponse.class);
+ }
+
+ @Override
+ public FinderAuthListResponse getFinderAuthorizationList() throws WxErrorException {
+ String resJson = shopService.post(FINDER_AUTH_LIST_URL, "{}");
+ return ResponseUtils.decode(resJson, FinderAuthListResponse.class);
+ }
+
+ @Override
+ public FinderListResponse getFinderList(String ds) throws WxErrorException {
+ CompassFinderBaseParam param = new CompassFinderBaseParam(ds);
+ String resJson = shopService.post(FINDER_LIST_URL, param);
+ return ResponseUtils.decode(resJson, FinderListResponse.class);
+ }
+
+ @Override
+ public FinderOverallResponse getFinderOverall(String ds) throws WxErrorException {
+ CompassFinderBaseParam param = new CompassFinderBaseParam(ds);
+ String resJson = shopService.post(GET_FINDER_OVERALL_URL, param);
+ return ResponseUtils.decode(resJson, FinderOverallResponse.class);
+ }
+
+ @Override
+ public FinderProductListResponse getFinderProductList(String ds, String finderId) throws WxErrorException {
+ CompassFinderIdParam param = new CompassFinderIdParam(ds, finderId);
+ String resJson = shopService.post(GET_FINDER_PRODUCT_LIST_URL, param);
+ return ResponseUtils.decode(resJson, FinderProductListResponse.class);
+ }
+
+ @Override
+ public FinderProductOverallResponse getFinderProductOverall(String ds, String finderId) throws WxErrorException {
+ CompassFinderIdParam param = new CompassFinderIdParam(ds, finderId);
+ String resJson = shopService.post(GET_FINDER_PRODUCT_OVERALL_URL, param);
+ return ResponseUtils.decode(resJson, FinderProductOverallResponse.class);
+ }
+
+ @Override
+ public ShopLiveListResponse getShopLiveList(String ds, String finderId) throws WxErrorException {
+ CompassFinderIdParam param = new CompassFinderIdParam(ds, finderId);
+ String resJson = shopService.post(GET_LIVE_LIST_URL, param);
+ return ResponseUtils.decode(resJson, ShopLiveListResponse.class);
+ }
+
+ @Override
+ public ShopProductDataResponse getShopProductData(String ds, String productId) throws WxErrorException {
+ ShopProductDataParam param = new ShopProductDataParam(ds, productId);
+ String resJson = shopService.post(GET_SHOP_PRODUCT_DATA_URL, param);
+ return ResponseUtils.decode(resJson, ShopProductDataResponse.class);
+ }
+
+ @Override
+ public ShopProductListResponse getShopProductList(String ds) throws WxErrorException {
+ CompassFinderBaseParam param = new CompassFinderBaseParam(ds);
+ String resJson = shopService.post(GET_SHOP_PRODUCT_LIST_URL, param);
+ return ResponseUtils.decode(resJson, ShopProductListResponse.class);
+ }
+
+ @Override
+ public ShopSaleProfileDataResponse getShopSaleProfileData(String ds, Integer type) throws WxErrorException {
+ ShopSaleProfileDataParam param = new ShopSaleProfileDataParam(ds, type);
+ String resJson = shopService.post(GET_SHOP_SALE_PROFILE_DATA_URL, param);
+ return ResponseUtils.decode(resJson, ShopSaleProfileDataResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCouponServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCouponServiceImpl.java
index 174626f4a9..22abf25fb0 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCouponServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelCouponServiceImpl.java
@@ -35,9 +35,9 @@
public class WxChannelCouponServiceImpl implements WxChannelCouponService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelCouponServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelCouponServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFreightTemplateServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFreightTemplateServiceImpl.java
index 8fbfbd09c3..b8f00a4f84 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFreightTemplateServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFreightTemplateServiceImpl.java
@@ -24,9 +24,9 @@
@Slf4j
public class WxChannelFreightTemplateServiceImpl implements WxChannelFreightTemplateService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelFreightTemplateServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelFreightTemplateServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFundServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFundServiceImpl.java
index 050a19f44d..7cf30905ec 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFundServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelFundServiceImpl.java
@@ -54,9 +54,9 @@ public class WxChannelFundServiceImpl implements WxChannelFundService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelFundServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelFundServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelLiveDashboardServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelLiveDashboardServiceImpl.java
new file mode 100644
index 0000000000..7eace4377b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelLiveDashboardServiceImpl.java
@@ -0,0 +1,81 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxChannelLiveDashboardService;
+import me.chanjar.weixin.channel.bean.live.dashboard.LiveDataParam;
+import me.chanjar.weixin.channel.bean.live.dashboard.LiveDataResponse;
+import me.chanjar.weixin.channel.bean.live.dashboard.LiveListParam;
+import me.chanjar.weixin.channel.bean.live.dashboard.LiveListResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.apache.commons.lang3.ObjectUtils;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.LiveDashboard.*;
+
+/**
+ * 视频号助手 直播大屏数据服务实现
+ *
+ * @author Winnie
+ */
+@Slf4j
+public class WxChannelLiveDashboardServiceImpl implements WxChannelLiveDashboardService {
+
+ /**
+ * 微信商店服务
+ */
+ private final BaseWxChannelServiceImpl, ?> shopService;
+ private final ObjectMapper objectMapper = new ObjectMapper();
+
+ public WxChannelLiveDashboardServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {this.shopService = shopService;}
+
+ @Override
+ public LiveListResponse getLiveList(Long ds) throws WxErrorException {
+ LiveListParam param = new LiveListParam(ds);
+ String resJson = shopService.post(GET_LIVE_LIST_URL, param);
+ return ResponseUtils.decode(resJson, LiveListResponse.class);
+ }
+
+ @Override
+ public LiveDataResponse getLiveData(String exportId) throws WxErrorException {
+ LiveDataParam param = new LiveDataParam(exportId);
+ String resJson = shopService.post(GET_LIVE_DATA_URL, param);
+ return this.convertLiveDataResponse(resJson);
+ }
+
+ /**
+ * 微信接口获取直播数据中存在非标准JSON,方便业务处理返回前做好解析
+ * 处理参数:
+ * live_dashboard_data,live_comparison_index,live_ec_data_summary,live_ec_conversion_metric,
+ * live_ec_profile,live_distribution_channel,single_live_ec_spu_data_page_v2
+ *
+ * @param resJson 直播数据返回JSON
+ * @return LiveDataResponse
+ *
+ * @throws WxErrorException 异常
+ */
+ private LiveDataResponse convertLiveDataResponse(String resJson) throws WxErrorException {
+ try {
+ ObjectNode rootNode = (ObjectNode) objectMapper.readTree(resJson);
+ String[] dataKeyArray = new String[] {
+ "live_dashboard_data", "live_comparison_index", "live_ec_data_summary", "live_ec_conversion_metric",
+ "live_ec_profile", "live_distribution_channel", "single_live_ec_spu_data_page_v2"
+ };
+ for(String dataKey : dataKeyArray) {
+ JsonNode jsonNode = rootNode.get(dataKey);
+ if (ObjectUtils.isNotEmpty(jsonNode)) {
+ JsonNode dataJsonNode = objectMapper.readTree(jsonNode.asText());
+ rootNode.set(dataKey, dataJsonNode);
+ }
+ }
+ String json = objectMapper.writeValueAsString(rootNode);
+ return ResponseUtils.decode(json, LiveDataResponse.class);
+ } catch (JsonProcessingException e) {
+ throw new WxErrorException(e);
+ }
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImpl.java
index 65eec5dd29..fd26268333 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImpl.java
@@ -1,8 +1,20 @@
package me.chanjar.weixin.channel.api.impl;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Delivery.DELIVERY_SEND_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Delivery.GET_DELIVERY_COMPANY_NEW_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Delivery.GET_DELIVERY_COMPANY_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.*;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.ACCEPT_ADDRESS_MODIFY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.DECODE_SENSITIVE_INFO_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.ORDER_GET_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.ORDER_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.ORDER_SEARCH_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.REJECT_ADDRESS_MODIFY_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPDATE_ADDRESS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPDATE_EXPRESS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPDATE_PRICE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPDATE_REMARK_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.UPLOAD_FRESH_INSPECT_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Order.VIRTUAL_TEL_NUMBER_URL;
import java.util.List;
import lombok.extern.slf4j.Slf4j;
@@ -12,16 +24,21 @@
import me.chanjar.weixin.channel.bean.delivery.DeliveryCompanyResponse;
import me.chanjar.weixin.channel.bean.delivery.DeliveryInfo;
import me.chanjar.weixin.channel.bean.delivery.DeliverySendParam;
+import me.chanjar.weixin.channel.bean.delivery.FreshInspectParam;
+import me.chanjar.weixin.channel.bean.delivery.PackageAuditInfo;
import me.chanjar.weixin.channel.bean.order.ChangeOrderInfo;
+import me.chanjar.weixin.channel.bean.order.DecodeSensitiveInfoResponse;
import me.chanjar.weixin.channel.bean.order.DeliveryUpdateParam;
import me.chanjar.weixin.channel.bean.order.OrderAddressParam;
import me.chanjar.weixin.channel.bean.order.OrderIdParam;
+import me.chanjar.weixin.channel.bean.order.OrderInfoParam;
import me.chanjar.weixin.channel.bean.order.OrderInfoResponse;
import me.chanjar.weixin.channel.bean.order.OrderListParam;
import me.chanjar.weixin.channel.bean.order.OrderListResponse;
import me.chanjar.weixin.channel.bean.order.OrderPriceParam;
import me.chanjar.weixin.channel.bean.order.OrderRemarkParam;
import me.chanjar.weixin.channel.bean.order.OrderSearchParam;
+import me.chanjar.weixin.channel.bean.order.VirtualTelNumberResponse;
import me.chanjar.weixin.channel.util.ResponseUtils;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -35,15 +52,22 @@
public class WxChannelOrderServiceImpl implements WxChannelOrderService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelOrderServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelOrderServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
@Override
public OrderInfoResponse getOrder(String orderId) throws WxErrorException {
- OrderIdParam param = new OrderIdParam(orderId);
+ OrderInfoParam param = new OrderInfoParam(orderId, null);
+ String resJson = shopService.post(ORDER_GET_URL, param);
+ return ResponseUtils.decode(resJson, OrderInfoResponse.class);
+ }
+
+ @Override
+ public OrderInfoResponse getOrder(String orderId, Boolean encodeSensitiveInfo) throws WxErrorException {
+ OrderInfoParam param = new OrderInfoParam(orderId, encodeSensitiveInfo);
String resJson = shopService.post(ORDER_GET_URL, param);
return ResponseUtils.decode(resJson, OrderInfoResponse.class);
}
@@ -115,6 +139,16 @@ public DeliveryCompanyResponse listDeliveryCompany() throws WxErrorException {
return ResponseUtils.decode(resJson, DeliveryCompanyResponse.class);
}
+ @Override
+ public DeliveryCompanyResponse listDeliveryCompany(Boolean ewaybillOnly) throws WxErrorException {
+ String reqJson = "{}";
+ if (ewaybillOnly != null) {
+ reqJson = "{\"ewaybill_only\":" + ewaybillOnly + "}";
+ }
+ String resJson = shopService.post(GET_DELIVERY_COMPANY_NEW_URL, reqJson);
+ return ResponseUtils.decode(resJson, DeliveryCompanyResponse.class);
+ }
+
@Override
public WxChannelBaseResponse deliveryOrder(String orderId, List deliveryList)
throws WxErrorException {
@@ -122,4 +156,26 @@ public WxChannelBaseResponse deliveryOrder(String orderId, List de
String resJson = shopService.post(DELIVERY_SEND_URL, param);
return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
}
+
+ @Override
+ public WxChannelBaseResponse uploadFreshInspect(String orderId, List items)
+ throws WxErrorException {
+ FreshInspectParam param = new FreshInspectParam(orderId, items);
+ String resJson = shopService.post(UPLOAD_FRESH_INSPECT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public VirtualTelNumberResponse getVirtualTelNumber(String orderId) throws WxErrorException {
+ String reqJson = "{\"order_id\":\"" + orderId + "\"}";
+ String resJson = shopService.post(VIRTUAL_TEL_NUMBER_URL, reqJson);
+ return ResponseUtils.decode(resJson, VirtualTelNumberResponse.class);
+ }
+
+ @Override
+ public DecodeSensitiveInfoResponse decodeSensitiveInfo(String orderId) throws WxErrorException {
+ String reqJson = "{\"order_id\":\"" + orderId + "\"}";
+ String resJson = shopService.post(DECODE_SENSITIVE_INFO_URL, reqJson);
+ return ResponseUtils.decode(resJson, DecodeSensitiveInfoResponse.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 eb168a09e3..08c9638f0c 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
@@ -6,16 +6,22 @@
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.DELETE_LIMIT_TASK_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.LIST_LIMIT_TASK_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_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;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_LISTING_URL;
import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_LIST_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_QRCODE_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Spu.SPU_TAGLINK_URL;
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 java.util.List;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.channel.api.WxChannelProductService;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
@@ -23,13 +29,20 @@
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.product.SkuStockBatchParam;
+import me.chanjar.weixin.channel.bean.product.SkuStockBatchResponse;
import me.chanjar.weixin.channel.bean.product.SkuStockParam;
import me.chanjar.weixin.channel.bean.product.SkuStockResponse;
+import me.chanjar.weixin.channel.bean.product.SpuFastInfo;
import me.chanjar.weixin.channel.bean.product.SpuGetResponse;
import me.chanjar.weixin.channel.bean.product.SpuInfo;
import me.chanjar.weixin.channel.bean.product.SpuListParam;
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.link.ProductH5UrlResponse;
+import me.chanjar.weixin.channel.bean.product.link.ProductQrCodeResponse;
+import me.chanjar.weixin.channel.bean.product.link.ProductTagLinkResponse;
import me.chanjar.weixin.channel.util.JsonUtils;
import me.chanjar.weixin.channel.util.ResponseUtils;
import me.chanjar.weixin.common.error.WxErrorException;
@@ -43,12 +56,26 @@
public class WxChannelProductServiceImpl implements WxChannelProductService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelProductServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelProductServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
+ @Override
+ public SpuUpdateResponse addProduct(SpuUpdateInfo info) throws WxErrorException {
+ String reqJson = JsonUtils.encode(info);
+ String resJson = shopService.post(SPU_ADD_URL, reqJson);
+ return ResponseUtils.decode(resJson, SpuUpdateResponse.class);
+ }
+
+ @Override
+ public SpuUpdateResponse updateProduct(SpuUpdateInfo info) throws WxErrorException {
+ String reqJson = JsonUtils.encode(info);
+ String resJson = shopService.post(SPU_UPDATE_URL, reqJson);
+ return ResponseUtils.decode(resJson, SpuUpdateResponse.class);
+ }
+
@Override
public SpuUpdateResponse addProduct(SpuInfo info) throws WxErrorException {
String reqJson = JsonUtils.encode(info);
@@ -63,6 +90,13 @@ public SpuUpdateResponse updateProduct(SpuInfo info) throws WxErrorException {
return ResponseUtils.decode(resJson, SpuUpdateResponse.class);
}
+ @Override
+ public WxChannelBaseResponse updateProductAuditFree(SpuFastInfo info) throws WxErrorException {
+ String reqJson = JsonUtils.encode(info);
+ String resJson = shopService.post(SPU_AUDIT_FREE_UPDATE_URL, reqJson);
+ return ResponseUtils.decode(resJson, SpuUpdateResponse.class);
+ }
+
@Override
public WxChannelBaseResponse updateStock(String productId, String skuId, Integer diffType, Integer num)
throws WxErrorException {
@@ -148,6 +182,35 @@ public SkuStockResponse getSkuStock(String productId, String skuId) throws WxErr
return ResponseUtils.decode(resJson, SkuStockResponse.class);
}
+ @Override
+ public SkuStockBatchResponse getSkuStockBatch(List productIds) throws WxErrorException {
+ SkuStockBatchParam param = new SkuStockBatchParam(productIds);
+ String reqJson = JsonUtils.encode(param);
+ String resJson = shopService.post(SPU_GET_STOCK_BATCH_URL, reqJson);
+ return ResponseUtils.decode(resJson, SkuStockBatchResponse.class);
+ }
+
+ @Override
+ public ProductH5UrlResponse getProductH5Url(String productId) throws WxErrorException {
+ String reqJson = "{\"product_id\":\"" + productId + "\"}";
+ String resJson = shopService.post(SPU_H5URL_URL, reqJson);
+ return ResponseUtils.decode(resJson, ProductH5UrlResponse.class);
+ }
+
+ @Override
+ public ProductQrCodeResponse getProductQrCode(String productId) throws WxErrorException {
+ String reqJson = "{\"product_id\":\"" + productId + "\"}";
+ String resJson = shopService.post(SPU_QRCODE_URL, reqJson);
+ return ResponseUtils.decode(resJson, ProductQrCodeResponse.class);
+ }
+
+ @Override
+ public ProductTagLinkResponse getProductTagLink(String productId) throws WxErrorException {
+ String reqJson = "{\"product_id\":\"" + productId + "\"}";
+ String resJson = shopService.post(SPU_TAGLINK_URL, reqJson);
+ return ResponseUtils.decode(resJson, ProductTagLinkResponse.class);
+ }
+
@Override
public LimitTaskAddResponse addLimitTask(LimitTaskParam param) throws WxErrorException {
String reqJson = JsonUtils.encode(param);
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpClientImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpClientImpl.java
index e0cb767619..6f380f80fb 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpClientImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceHttpClientImpl.java
@@ -1,30 +1,28 @@
package me.chanjar.weixin.channel.api.impl;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_ACCESS_TOKEN_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_STABLE_ACCESS_TOKEN_URL;
-
-import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
-import me.chanjar.weixin.channel.api.WxChannelVipService;
-import me.chanjar.weixin.channel.bean.token.StableToken;
+import me.chanjar.weixin.channel.bean.token.StableTokenParam;
import me.chanjar.weixin.channel.config.WxChannelConfig;
import me.chanjar.weixin.channel.util.JsonUtils;
-import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.common.util.http.HttpType;
+import me.chanjar.weixin.common.util.http.HttpClientType;
+import me.chanjar.weixin.common.util.http.apache.ApacheBasicResponseHandler;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.Consts;
import org.apache.http.HttpHost;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
+import java.io.IOException;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_ACCESS_TOKEN_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_STABLE_ACCESS_TOKEN_URL;
+
/**
* @author Zeyes
*/
@@ -33,19 +31,6 @@ public class WxChannelServiceHttpClientImpl extends BaseWxChannelServiceImpl {
+
+ private CloseableHttpClient httpClient;
+ private HttpHost httpProxy;
+
+ @Override
+ public void initHttp() {
+ WxChannelConfig config = this.getConfig();
+ HttpComponentsClientBuilder apacheHttpClientBuilder = DefaultHttpComponentsClientBuilder.get();
+
+ apacheHttpClientBuilder.httpProxyHost(config.getHttpProxyHost())
+ .httpProxyPort(config.getHttpProxyPort())
+ .httpProxyUsername(config.getHttpProxyUsername())
+ .httpProxyPassword(config.getHttpProxyPassword() == null ? null : config.getHttpProxyPassword().toCharArray());
+
+ if (config.getHttpProxyHost() != null && config.getHttpProxyPort() > 0) {
+ this.httpProxy = new HttpHost(config.getHttpProxyHost(), config.getHttpProxyPort());
+ }
+
+ this.httpClient = apacheHttpClientBuilder.build();
+ }
+
+ @Override
+ public CloseableHttpClient getRequestHttpClient() {
+ return httpClient;
+ }
+
+ @Override
+ public HttpHost getRequestHttpProxy() {
+ return httpProxy;
+ }
+
+ @Override
+ public HttpClientType getRequestType() {
+ return HttpClientType.HTTP_COMPONENTS;
+ }
+
+ @Override
+ protected String doGetAccessTokenRequest() throws IOException {
+ WxChannelConfig config = this.getConfig();
+ String url = StringUtils.isNotEmpty(config.getAccessTokenUrl()) ? config.getAccessTokenUrl() :
+ StringUtils.isNotEmpty(config.getApiHostUrl()) ?
+ GET_ACCESS_TOKEN_URL.replace("https://api.weixin.qq.com", config.getApiHostUrl()) : GET_ACCESS_TOKEN_URL;
+
+ url = String.format(url, config.getAppid(), config.getSecret());
+
+ HttpGet httpGet = new HttpGet(url);
+ if (this.getRequestHttpProxy() != null) {
+ RequestConfig requestConfig = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
+ httpGet.setConfig(requestConfig);
+ }
+ return getRequestHttpClient().execute(httpGet, BasicResponseHandler.INSTANCE);
+ }
+
+ /**
+ * 获取稳定版接口调用凭据
+ *
+ * @param forceRefresh false 为普通模式, true为强制刷新模式
+ * @return 返回json的字符串
+ * @throws IOException the io exception
+ */
+ @Override
+ protected String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException {
+ WxChannelConfig config = this.getConfig();
+ String url = GET_STABLE_ACCESS_TOKEN_URL;
+
+ HttpPost httpPost = new HttpPost(url);
+ if (this.getRequestHttpProxy() != null) {
+ RequestConfig requestConfig = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
+ httpPost.setConfig(requestConfig);
+ }
+ StableTokenParam requestParam = new StableTokenParam();
+ requestParam.setAppId(config.getAppid());
+ requestParam.setSecret(config.getSecret());
+ requestParam.setGrantType("client_credential");
+ requestParam.setForceRefresh(forceRefresh);
+ String requestJson = JsonUtils.encode(requestParam);
+ assert requestJson != null;
+
+ httpPost.setEntity(new StringEntity(requestJson, ContentType.APPLICATION_JSON));
+ return getRequestHttpClient().execute(httpPost, BasicResponseHandler.INSTANCE);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java
index 1929d9baec..ccd4eafc79 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceImpl.java
@@ -8,22 +8,19 @@
* @author Zeyes
*/
@Slf4j
-public class WxChannelServiceImpl extends WxChannelServiceHttpClientImpl {
+public class WxChannelServiceImpl extends WxChannelServiceHttpComponentsImpl {
- /**
- * 设置普通模式access_token接口参数
- */
public WxChannelServiceImpl() {
- super(false, false);
}
- /**
- * 设置获取access_token接口参数.
- *
- * @param stabled false 表示调用普通模式AccessToken接口, true调用稳定模式接口
- * @param forceRefresh stabled=true使用, true表示强制刷新模式
- */
- public WxChannelServiceImpl(Boolean stabled, Boolean forceRefresh) {
- super(stabled, forceRefresh);
- }
+// /**
+// * 设置获取access_token接口参数.
+// *
+// * @param stabled false 表示调用普通模式AccessToken接口, true调用稳定模式接口
+// * @param forceRefresh stabled=true使用, true表示强制刷新模式
+// * @deprecated 请使用 {@link BaseWxChannelServiceImpl#setConfig(WxChannelConfig) } 替代
+// */
+// @Deprecated
+// public WxChannelServiceImpl(Boolean stabled, Boolean forceRefresh) {
+// }
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceOkHttpImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceOkHttpImpl.java
index df467d6988..f7b0ccc65b 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceOkHttpImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelServiceOkHttpImpl.java
@@ -1,24 +1,26 @@
package me.chanjar.weixin.channel.api.impl;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_ACCESS_TOKEN_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_STABLE_ACCESS_TOKEN_URL;
+
+import java.io.IOException;
+import java.util.Objects;
import lombok.extern.slf4j.Slf4j;
-import me.chanjar.weixin.channel.bean.token.StableToken;
+import me.chanjar.weixin.channel.bean.token.StableTokenParam;
+import me.chanjar.weixin.channel.config.WxChannelConfig;
import me.chanjar.weixin.channel.util.JsonUtils;
-import me.chanjar.weixin.common.bean.WxAccessToken;
-import me.chanjar.weixin.common.enums.WxType;
-import me.chanjar.weixin.common.error.WxError;
-import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.common.util.http.HttpType;
+import me.chanjar.weixin.common.util.http.HttpClientType;
import me.chanjar.weixin.common.util.http.okhttp.DefaultOkHttpClientBuilder;
import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo;
-import okhttp3.*;
+import okhttp3.Authenticator;
+import okhttp3.Credentials;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+import okhttp3.Response;
+import okhttp3.Route;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.Consts;
-import org.apache.http.entity.StringEntity;
-
-import java.io.IOException;
-
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_ACCESS_TOKEN_URL;
-import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.GET_STABLE_ACCESS_TOKEN_URL;
/**
* @author : zhenyun.su
@@ -28,19 +30,8 @@
public class WxChannelServiceOkHttpImpl extends BaseWxChannelServiceImpl {
private OkHttpClient httpClient;
private OkHttpProxyInfo httpProxy;
- private Boolean stabled = false;
- private Boolean forceRefresh = false;
- protected final Object globalAccessTokenRefreshLock = new Object();
- /**
- * 设置调用接口参数.
- *
- * @param stabled false 表示调用AccessToken接口, true调用稳定版接口
- * @param forceRefresh stabled=true使用, true表示强制刷新模式
- */
- public WxChannelServiceOkHttpImpl(Boolean stabled, Boolean forceRefresh) {
- this.stabled = stabled;
- this.forceRefresh = forceRefresh;
+ public WxChannelServiceOkHttpImpl() {
}
@Override
@@ -50,11 +41,11 @@ public void initHttp() {
this.httpProxy = OkHttpProxyInfo.httpProxy(this.config.getHttpProxyHost(), this.config.getHttpProxyPort(), this.config.getHttpProxyUsername(), this.config.getHttpProxyPassword());
okhttp3.OkHttpClient.Builder clientBuilder = new okhttp3.OkHttpClient.Builder();
clientBuilder.proxy(this.getRequestHttpProxy().getProxy());
- clientBuilder.authenticator(new Authenticator() {
+ clientBuilder.proxyAuthenticator(new Authenticator() {
@Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic(WxChannelServiceOkHttpImpl.this.httpProxy.getProxyUsername(), WxChannelServiceOkHttpImpl.this.httpProxy.getProxyPassword());
- return response.request().newBuilder().header("Authorization", credential).build();
+ return response.request().newBuilder().header("Proxy-Authorization", credential).build();
}
});
this.httpClient = clientBuilder.build();
@@ -74,81 +65,45 @@ public OkHttpProxyInfo getRequestHttpProxy() {
}
@Override
- public HttpType getRequestType() {
- return HttpType.OK_HTTP;
+ public HttpClientType getRequestType() {
+ return HttpClientType.OK_HTTP;
}
@Override
- protected String doGetAccessTokenRequest() throws WxErrorException {
- if (stabled) {
- return internalGetStableAccessToken(this.forceRefresh);
- } else{
- return internalGetAccessToken(forceRefresh);
- }
- }
-
- public String internalGetStableAccessToken(boolean forceRefresh) throws WxErrorException {
- if (!this.config.isAccessTokenExpired() && !forceRefresh) {
- return this.config.getAccessToken();
- } else {
- synchronized(this.globalAccessTokenRefreshLock) {
- OkHttpClient client = this.getRequestHttpClient();
-
- String url = String.format(GET_STABLE_ACCESS_TOKEN_URL, config.getAppid(), config.getSecret());
+ protected String doGetAccessTokenRequest() throws IOException {
+ WxChannelConfig config = this.getConfig();
+ String url = StringUtils.isNotEmpty(config.getAccessTokenUrl()) ? config.getAccessTokenUrl() :
+ StringUtils.isNotEmpty(config.getApiHostUrl()) ?
+ GET_ACCESS_TOKEN_URL.replace("https://api.weixin.qq.com", config.getApiHostUrl()) : GET_ACCESS_TOKEN_URL;
- StableToken stableToken = new StableToken("client_credential", config.getAppid(),config.getSecret(), forceRefresh);
+ url = String.format(url, config.getAppid(), config.getSecret());
- RequestBody body = RequestBody.Companion.create(JsonUtils.encode(stableToken), MediaType.parse("application/json; charset=utf-8"));
-
- Request request = (new Request.Builder()).url(url).post(body).build();
- String resultContent = null;
- try {
- Response response = client.newCall(request).execute();
- resultContent = response.body().string();
- } catch (IOException var9) {
- log.error(var9.getMessage(), var9);
- }
-
- WxError error = WxError.fromJson(resultContent, WxType.CP);
- if (error.getErrorCode() != 0) {
- throw new WxErrorException(error);
- }
-
- WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
- this.config.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
- }
- return this.config.getAccessToken();
+ Request request = new Request.Builder().url(url).get().build();
+ try (Response response = getRequestHttpClient().newCall(request).execute()) {
+ return Objects.requireNonNull(response.body()).string();
}
}
- public String internalGetAccessToken(boolean forceRefresh) throws WxErrorException {
- if (!this.config.isAccessTokenExpired() && !forceRefresh) {
- return this.config.getAccessToken();
- } else {
- synchronized(this.globalAccessTokenRefreshLock) {
- OkHttpClient client = this.getRequestHttpClient();
-
- String url = String.format(GET_ACCESS_TOKEN_URL, config.getAppid(), config.getSecret());
-
- Request request = (new Request.Builder()).url(url).get().build();
-
- String resultContent = null;
- try {
- Response response = client.newCall(request).execute();
- resultContent = response.body().string();
- } catch (IOException var9) {
- log.error(var9.getMessage(), var9);
- }
-
- WxError error = WxError.fromJson(resultContent, WxType.CP);
- if (error.getErrorCode() != 0) {
- throw new WxErrorException(error);
- }
-
- WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
- this.config.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
- }
- return this.config.getAccessToken();
+ @Override
+ protected String doGetStableAccessTokenRequest(boolean forceRefresh) throws IOException {
+ WxChannelConfig config = this.getConfig();
+ String url = StringUtils.isNotEmpty(config.getAccessTokenUrl()) ?
+ config.getAccessTokenUrl() : StringUtils.isNotEmpty(config.getApiHostUrl()) ?
+ GET_STABLE_ACCESS_TOKEN_URL.replace("https://api.weixin.qq.com", config.getApiHostUrl()) :
+ GET_STABLE_ACCESS_TOKEN_URL;
+
+ StableTokenParam requestParam = new StableTokenParam();
+ requestParam.setAppId(config.getAppid());
+ requestParam.setSecret(config.getSecret());
+ requestParam.setGrantType("client_credential");
+ requestParam.setForceRefresh(forceRefresh);
+ String requestJson = JsonUtils.encode(requestParam);
+ assert requestJson != null;
+
+ RequestBody body = RequestBody.Companion.create(requestJson, MediaType.parse("application/json; charset=utf-8"));
+ Request request = new Request.Builder().url(url).post(body).build();
+ try (Response response = getRequestHttpClient().newCall(request).execute()) {
+ return Objects.requireNonNull(response.body()).string();
}
}
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelSharerServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelSharerServiceImpl.java
index 676b310288..3e27b124c7 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelSharerServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelSharerServiceImpl.java
@@ -33,9 +33,9 @@
public class WxChannelSharerServiceImpl implements WxChannelSharerService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelSharerServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelSharerServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelVipServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelVipServiceImpl.java
index 1bad47593d..4644989d60 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelVipServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelVipServiceImpl.java
@@ -18,51 +18,51 @@
@Slf4j
public class WxChannelVipServiceImpl implements WxChannelVipService {
- private BaseWxChannelServiceImpl vipHttpService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelVipServiceImpl(BaseWxChannelServiceImpl vipHttpService) {
- this.vipHttpService = vipHttpService;
+ public WxChannelVipServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
+ this.shopService = shopService;
}
@Override
public VipInfoResponse getVipInfo(String openId, Boolean needPhoneNumber) throws WxErrorException {
VipInfoParam param = new VipInfoParam(openId, needPhoneNumber);
- String respJson = vipHttpService.post(VIP_USER_INFO_URL, param);
+ String respJson = shopService.post(VIP_USER_INFO_URL, param);
return ResponseUtils.decode(respJson, VipInfoResponse.class);
}
@Override
- public VipListResponse getVipList(Boolean needPhoneNumber, Integer pageNum, Integer PageSize) throws WxErrorException {
- VipListParam param = new VipListParam(needPhoneNumber, pageNum, PageSize);
- String respJson = vipHttpService.post(VIP_USER_LIST_URL, param);
+ public VipListResponse getVipList(Boolean needPhoneNumber, Integer pageNum, Integer pageSize) throws WxErrorException {
+ VipListParam param = new VipListParam(needPhoneNumber, pageNum, pageSize);
+ String respJson = shopService.post(VIP_USER_LIST_URL, param);
return ResponseUtils.decode(respJson, VipListResponse.class);
}
@Override
public VipScoreResponse getVipScore(String openId) throws WxErrorException {
- VipParam param = new VipParam(openId);
- String respJson = vipHttpService.post(VIP_SCORE_URL, param);
+ VipOpenIdParam param = new VipOpenIdParam(openId);
+ String respJson = shopService.post(VIP_SCORE_URL, param);
return ResponseUtils.decode(respJson, VipScoreResponse.class);
}
@Override
public WxChannelBaseResponse increaseVipScore(String openId, String score, String remark, String requestId) throws WxErrorException {
VipScoreParam param = new VipScoreParam(openId, score, remark, requestId);
- String respJson = vipHttpService.post(SCORE_INCREASE_URL, param);
+ String respJson = shopService.post(SCORE_INCREASE_URL, param);
return ResponseUtils.decode(respJson, WxChannelBaseResponse.class);
}
@Override
public WxChannelBaseResponse decreaseVipScore(String openId, String score, String remark, String requestId) throws WxErrorException {
VipScoreParam param = new VipScoreParam(openId, score, remark, requestId);
- String respJson = vipHttpService.post(SCORE_DECREASE_URL, param);
+ String respJson = shopService.post(SCORE_DECREASE_URL, param);
return ResponseUtils.decode(respJson, WxChannelBaseResponse.class);
}
@Override
public WxChannelBaseResponse updateVipGrade(String openId, Integer score) throws WxErrorException {
VipGradeParam param = new VipGradeParam(openId, score);
- String respJson = vipHttpService.post(GRADE_UPDATE_URL, param);
+ String respJson = shopService.post(GRADE_UPDATE_URL, param);
return ResponseUtils.decode(respJson, WxChannelBaseResponse.class);
}
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelWarehouseServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelWarehouseServiceImpl.java
index b9609e5c6b..6805f26a4f 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelWarehouseServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxChannelWarehouseServiceImpl.java
@@ -40,9 +40,9 @@
public class WxChannelWarehouseServiceImpl implements WxChannelWarehouseService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxChannelWarehouseServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxChannelWarehouseServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxFinderLiveServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxFinderLiveServiceImpl.java
index aecd1cccac..51623609cf 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxFinderLiveServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxFinderLiveServiceImpl.java
@@ -26,7 +26,7 @@
public class WxFinderLiveServiceImpl implements WxFinderLiveService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
@Override
public FinderAttrResponse getFinderAttrByAppid() throws WxErrorException {
String resJson = shopService.post(GET_FINDER_ATTR_BY_APPID, "{}");
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeadComponentServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeadComponentServiceImpl.java
index b99cfe9f47..eb1bcee28c 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeadComponentServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeadComponentServiceImpl.java
@@ -38,7 +38,7 @@
public class WxLeadComponentServiceImpl implements WxLeadComponentService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public LeadInfoResponse getLeadsInfoByComponentId(GetLeadInfoByComponentRequest req) throws WxErrorException {
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueProductServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueProductServiceImpl.java
index 29620874e2..fc8d2fbadc 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueProductServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueProductServiceImpl.java
@@ -32,9 +32,9 @@
public class WxLeagueProductServiceImpl implements WxLeagueProductService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxLeagueProductServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxLeagueProductServiceImpl(BaseWxChannelServiceImpl, ?>shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeaguePromoterServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeaguePromoterServiceImpl.java
index a6bfddfbef..c81df29533 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeaguePromoterServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeaguePromoterServiceImpl.java
@@ -24,9 +24,9 @@
public class WxLeaguePromoterServiceImpl implements WxLeaguePromoterService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxLeaguePromoterServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxLeaguePromoterServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
@@ -58,6 +58,34 @@ public PromoterInfoResponse getPromoterInfo(String finderId) throws WxErrorExcep
return ResponseUtils.decode(resJson, PromoterInfoResponse.class);
}
+ @Override
+ public WxChannelBaseResponse addPromoterV2(String promoterId) throws WxErrorException {
+ String reqJson = "{\"promoter_id\":\"" + promoterId + "\"}";
+ String resJson = shopService.post(ADD_PROMOTER_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse updatePromoterV2(String promoterId, int type) throws WxErrorException {
+ String reqJson = "{\"promoter_id\":\"" + promoterId + "\",\"type\":" + type + "}";
+ String resJson = shopService.post(EDIT_PROMOTER_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse deletePromoterV2(String promoterId) throws WxErrorException {
+ String reqJson = "{\"promoter_id\":\"" + promoterId + "\"}";
+ String resJson = shopService.post(DELETE_PROMOTER_URL, reqJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public PromoterInfoResponse getPromoterInfoV2(String promoterId) throws WxErrorException {
+ String reqJson = "{\"promoter_id\":\"" + promoterId + "\"}";
+ String resJson = shopService.post(GET_PROMOTER_URL, reqJson);
+ return ResponseUtils.decode(resJson, PromoterInfoResponse.class);
+ }
+
@Override
public PromoterListResponse listPromoter(Integer pageIndex, Integer pageSize, Integer status)
throws WxErrorException {
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueSupplierServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueSupplierServiceImpl.java
index d69296bd0f..2b280a2f6d 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueSupplierServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueSupplierServiceImpl.java
@@ -38,9 +38,9 @@
public class WxLeagueSupplierServiceImpl implements WxLeagueSupplierService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxLeagueSupplierServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxLeagueSupplierServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueWindowServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueWindowServiceImpl.java
index a59fc6efa5..a0c21ab4ef 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueWindowServiceImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxLeagueWindowServiceImpl.java
@@ -29,9 +29,9 @@
public class WxLeagueWindowServiceImpl implements WxLeagueWindowService {
/** 微信商店服务 */
- private final BaseWxChannelServiceImpl shopService;
+ private final BaseWxChannelServiceImpl, ?> shopService;
- public WxLeagueWindowServiceImpl(BaseWxChannelServiceImpl shopService) {
+ public WxLeagueWindowServiceImpl(BaseWxChannelServiceImpl, ?> shopService) {
this.shopService = shopService;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxStoreCooperationServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxStoreCooperationServiceImpl.java
new file mode 100644
index 0000000000..56dc78e09e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxStoreCooperationServiceImpl.java
@@ -0,0 +1,68 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Cooperation.CANCEL_COOPERATION_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Cooperation.GENERATE_QRCODE_COOPERATION_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Cooperation.GET_COOPERATION_STATUS_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Cooperation.LIST_COOPERATION_URL;
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.Cooperation.UNBIND_COOPERATION_URL;
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxStoreCooperationService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.cooperation.CooperationListResponse;
+import me.chanjar.weixin.channel.bean.cooperation.CooperationQrCodeResponse;
+import me.chanjar.weixin.channel.bean.cooperation.CooperationSharerParam;
+import me.chanjar.weixin.channel.bean.cooperation.CooperationStatusResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 微信小店 合作账号相关接口
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxStoreCooperationServiceImpl implements WxStoreCooperationService {
+
+ /** 微信小店服务 */
+ private final BaseWxChannelServiceImpl, ?> storeService;
+
+ public WxStoreCooperationServiceImpl(BaseWxChannelServiceImpl, ?> storeService) {
+ this.storeService = storeService;
+ }
+
+ @Override
+ public CooperationListResponse listCooperation(Integer sharerType) throws WxErrorException {
+ String paramJson = "{\"sharer_type\":" + sharerType + "}";
+ String resJson = storeService.post(LIST_COOPERATION_URL, paramJson);
+ return ResponseUtils.decode(resJson, CooperationListResponse.class);
+ }
+
+ @Override
+ public CooperationStatusResponse getCooperationStatus(String sharerId, Integer sharerType) throws WxErrorException {
+ CooperationSharerParam param = new CooperationSharerParam(sharerId, sharerType);
+ String resJson = storeService.post(GET_COOPERATION_STATUS_URL, param);
+ return ResponseUtils.decode(resJson, CooperationStatusResponse.class);
+ }
+
+ @Override
+ public CooperationQrCodeResponse generateQrCode(String sharerId, Integer sharerType) throws WxErrorException {
+ CooperationSharerParam param = new CooperationSharerParam(sharerId, sharerType);
+ String resJson = storeService.post(GENERATE_QRCODE_COOPERATION_URL, param);
+ return ResponseUtils.decode(resJson, CooperationQrCodeResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse cancelInvitation(String sharerId, Integer sharerType) throws WxErrorException {
+ CooperationSharerParam param = new CooperationSharerParam(sharerId, sharerType);
+ String resJson = storeService.post(CANCEL_COOPERATION_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse unbind(String sharerId, Integer sharerType) throws WxErrorException {
+ CooperationSharerParam param = new CooperationSharerParam(sharerId, sharerType);
+ String resJson = storeService.post(UNBIND_COOPERATION_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxStoreHomePageServiceImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxStoreHomePageServiceImpl.java
new file mode 100644
index 0000000000..e3e9f06deb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/api/impl/WxStoreHomePageServiceImpl.java
@@ -0,0 +1,164 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import static me.chanjar.weixin.channel.constant.WxChannelApiUrlConstants.HomePage.*;
+
+
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.channel.api.WxStoreHomePageService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.home.background.BackgroundApplyResponse;
+import me.chanjar.weixin.channel.bean.home.background.BackgroundGetResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerApplyParam;
+import me.chanjar.weixin.channel.bean.home.banner.BannerApplyResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerGetResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductEditInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductEditParam;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductListInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductListParam;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductListResponse;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowGetResponse;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowParam;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowSetResponse;
+import me.chanjar.weixin.channel.bean.home.window.WindowProductIndexParam;
+import me.chanjar.weixin.channel.bean.home.window.WindowProductListParam;
+import me.chanjar.weixin.channel.bean.home.window.WindowProductSetting;
+import me.chanjar.weixin.channel.bean.home.window.WindowProductSettingResponse;
+import me.chanjar.weixin.channel.util.ResponseUtils;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+/**
+ * 微信小店 主页管理相关接口
+ *
+ * @author Zeyes
+ */
+@Slf4j
+public class WxStoreHomePageServiceImpl implements WxStoreHomePageService {
+
+ /** 微信小店服务 */
+ private final BaseWxChannelServiceImpl, ?> storeService;
+
+ public WxStoreHomePageServiceImpl(BaseWxChannelServiceImpl, ?> storeService) {
+ this.storeService = storeService;
+ }
+
+
+ @Override
+ public WxChannelBaseResponse addTreeProduct(TreeProductEditInfo info) throws WxErrorException {
+ TreeProductEditParam param = new TreeProductEditParam(info);
+ String resJson = storeService.post(ADD_TREE_PRODUCT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse delTreeProduct(TreeProductEditInfo info) throws WxErrorException {
+ TreeProductEditParam param = new TreeProductEditParam(info);
+ String resJson = storeService.post(DEL_TREE_PRODUCT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public TreeProductListResponse getTreeProductList(TreeProductListInfo info) throws WxErrorException {
+ TreeProductListParam param = new TreeProductListParam(info);
+ String resJson = storeService.post(LIST_TREE_PRODUCT_URL, param);
+ return ResponseUtils.decode(resJson, TreeProductListResponse.class);
+ }
+
+ @Override
+ public TreeShowSetResponse setShowTree(TreeShowInfo info) throws WxErrorException {
+ TreeShowParam param = new TreeShowParam(info);
+ String resJson = storeService.post(SET_SHOW_TREE_URL, param);
+ return ResponseUtils.decode(resJson, TreeShowSetResponse.class);
+ }
+
+ @Override
+ public TreeShowGetResponse getShowTree() throws WxErrorException {
+ String resJson = storeService.post(GET_SHOW_TREE_URL, "");
+ return ResponseUtils.decode(resJson, TreeShowGetResponse.class);
+ }
+
+ @Override
+ public WindowProductSettingResponse listWindowProduct(Integer pageSize, String nextKey) throws WxErrorException {
+ WindowProductListParam param = new WindowProductListParam(pageSize, nextKey);
+ String resJson = storeService.post(LIST_WINDOW_PRODUCT_URL, param);
+ return ResponseUtils.decode(resJson, WindowProductSettingResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse reorderWindowProduct(String productId, Integer indexNum) throws WxErrorException {
+ WindowProductIndexParam param = new WindowProductIndexParam(productId, indexNum);
+ String resJson = storeService.post(REORDER_WINDOW_PRODUCT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse hideWindowProduct(String productId, Integer setHide) throws WxErrorException {
+ WindowProductSetting param = new WindowProductSetting();
+ param.setProductId(productId);
+ param.setSetHide(setHide);
+ String resJson = storeService.post(HIDE_WINDOW_PRODUCT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse topWindowProduct(String productId, Integer setTop) throws WxErrorException {
+ WindowProductSetting param = new WindowProductSetting();
+ param.setProductId(productId);
+ param.setSetTop(setTop);
+ String resJson = storeService.post(TOP_WINDOW_PRODUCT_URL, param);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public BackgroundApplyResponse applyBackground(String imgUrl) throws WxErrorException {
+ String paramJson = "{\"img_url\":\"" + imgUrl + "\"}";
+ String resJson = storeService.post(APPLY_BACKGROUND_URL, paramJson);
+ return ResponseUtils.decode(resJson, BackgroundApplyResponse.class);
+ }
+
+ @Override
+ public BackgroundGetResponse getBackground() throws WxErrorException {
+ String resJson = storeService.post(GET_BACKGROUND_URL, "");
+ return ResponseUtils.decode(resJson, BackgroundGetResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse cancelBackground(Integer applyId) throws WxErrorException {
+ String paramJson = "{\"apply_id\":" + applyId + "}";
+ String resJson = storeService.post(CANCEL_BACKGROUND_URL, paramJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse removeBackground() throws WxErrorException {
+ String resJson = storeService.post(REMOVE_BACKGROUND_URL, "");
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public BannerApplyResponse applyBanner(BannerInfo info) throws WxErrorException {
+ BannerApplyParam param = new BannerApplyParam(info);
+ String resJson = storeService.post(APPLY_BANNER_URL, param);
+ return ResponseUtils.decode(resJson, BannerApplyResponse.class);
+ }
+
+ @Override
+ public BannerGetResponse getBanner() throws WxErrorException {
+ String resJson = storeService.post(GET_BANNER_URL, "");
+ return ResponseUtils.decode(resJson, BannerGetResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse cancelBanner(Integer applyId) throws WxErrorException {
+ String paramJson = "{\"apply_id\":" + applyId + "}";
+ String resJson = storeService.post(CANCEL_BANNER_URL, paramJson);
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+
+ @Override
+ public WxChannelBaseResponse removeBanner() throws WxErrorException {
+ String resJson = storeService.post(REMOVE_BANNER_URL, "");
+ return ResponseUtils.decode(resJson, WxChannelBaseResponse.class);
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptExchangeReshipParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptExchangeReshipParam.java
new file mode 100644
index 0000000000..66be1c715d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptExchangeReshipParam.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * 售后单换货发货信息
+ *
+ * @author Chu
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AfterSaleAcceptExchangeReshipParam extends AfterSaleIdParam {
+ private static final long serialVersionUID = -7946679037747710613L;
+
+ /** 快递单号*/
+ @JsonProperty("waybill_id")
+ private String waybillId;
+
+ /** 快递公司id,通过获取快递公司列表接口获得,非主流快递公司可以填OTHER*/
+ @JsonProperty("delivery_id")
+ private String deliveryId;
+
+ public AfterSaleAcceptExchangeReshipParam() {
+
+ }
+
+ public AfterSaleAcceptExchangeReshipParam(String afterSaleOrderId, String waybillId, String deliveryId) {
+ super(afterSaleOrderId);
+ this.waybillId = waybillId;
+ this.deliveryId = deliveryId;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptParam.java
index ebc63a2190..32ad9154ee 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptParam.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleAcceptParam.java
@@ -19,6 +19,10 @@ public class AfterSaleAcceptParam extends AfterSaleIdParam {
@JsonProperty("address_id")
private String addressId;
+ /** 针对退货退款同意售后的阶段: 1. 同意退货退款,并通知用户退货; 2. 确认收到货并退款给用户。 如果不填则将根据当前的售后单状态自动选择相应操作。对于仅退款的情况,由于只存在一种同意的场景,无需填写此字段。*/
+ @JsonProperty("accept_type")
+ private Integer acceptType;
+
public AfterSaleAcceptParam() {
}
@@ -26,4 +30,10 @@ public AfterSaleAcceptParam(String afterSaleOrderId, String addressId) {
super(afterSaleOrderId);
this.addressId = addressId;
}
+
+ public AfterSaleAcceptParam(String afterSaleOrderId, String addressId, Integer acceptType) {
+ super(afterSaleOrderId);
+ this.addressId = addressId;
+ this.acceptType = acceptType;
+ }
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleExchangeDeliveryInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleExchangeDeliveryInfo.java
new file mode 100644
index 0000000000..277d9d4d89
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleExchangeDeliveryInfo.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+
+/**
+ * 换货类型的发货物流信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleExchangeDeliveryInfo implements Serializable {
+
+ private static final long serialVersionUID = 3039216368034112038L;
+
+ /** 快递单号 */
+ @JsonProperty("waybill_id")
+ private String waybillId;
+
+ /** 物流公司id */
+ @JsonProperty("delivery_id")
+ private String deliveryId;
+
+ /** 物流公司名称 */
+ @JsonProperty("delivery_name")
+ private String deliveryName;
+
+ /** 地址信息 */
+ @JsonProperty("address_info")
+ private AddressInfo addressInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleExchangeProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleExchangeProductInfo.java
new file mode 100644
index 0000000000..a73d6ae310
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleExchangeProductInfo.java
@@ -0,0 +1,42 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 换货商品信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleExchangeProductInfo implements Serializable {
+
+ private static final long serialVersionUID = -1341436607011117854L;
+
+ /** 商品spuid */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 旧商品skuid */
+ @JsonProperty("old_sku_id")
+ private String oldSkuId;
+
+ /** 新商品skuid */
+ @JsonProperty("new_sku_id")
+ private String newSkuId;
+
+ /** 数量 */
+ @JsonProperty("product_cnt")
+ private String productCnt;
+
+ /** 旧商品价格 */
+ @JsonProperty("old_sku_price")
+ private Integer oldSkuPrice;
+
+ /** 新商品价格 */
+ @JsonProperty("new_sku_price")
+ private Integer newSkuPrice;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfo.java
index b0d668b30e..d465766d75 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleInfo.java
@@ -82,4 +82,20 @@ public class AfterSaleInfo implements Serializable {
/** 纠纷id,该字段可用于获取纠纷信息 */
@JsonProperty("complaint_id")
private String complaintId;
+
+ /** 仅在待商家审核退款退货申请或收货期间返回,表示操作剩余时间(秒数)*/
+ @JsonProperty("deadline")
+ private Long deadline;
+
+ /** 售后换货商品信息 */
+ @JsonProperty("exchange_product_info")
+ private AfterSaleExchangeProductInfo exchangeProductInfo;
+
+ /** 售后换货物流信息 */
+ @JsonProperty("exchange_delivery_info")
+ private AfterSaleExchangeDeliveryInfo exchangeDeliveryInfo;
+
+ /** 售后换货虚拟号码信息 */
+ @JsonProperty("virtual_tel_num_info")
+ private AfterSaleVirtualNumberInfo virtualTelNumInfo;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListParam.java
index 78cc394085..a477a2c581 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListParam.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListParam.java
@@ -28,6 +28,14 @@ public class AfterSaleListParam implements Serializable {
@JsonProperty("end_create_time")
private Long endCreateTime;
+ /** 售后单更新起始时间 */
+ @JsonProperty("begin_update_time")
+ private Long beginUpdateTime;
+
+ /** 售后单更新结束时间,end_update_time减去begin_update_time不得大于24小时 */
+ @JsonProperty("end_update_time")
+ private Long endUpdateTime;
+
/** 翻页参数,从第二页开始传,来源于上一页的返回值 */
@JsonProperty("next_key")
private String nextKey;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListResponse.java
index 3ad67cffcf..dde39238a7 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListResponse.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleListResponse.java
@@ -14,7 +14,7 @@
*/
@Data
@NoArgsConstructor
-@EqualsAndHashCode
+@EqualsAndHashCode(callSuper = true)
public class AfterSaleListResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = 5033313416948732123L;
@@ -23,6 +23,7 @@ public class AfterSaleListResponse extends WxChannelBaseResponse {
private List ids;
/** 翻页参数 */
+ @JsonProperty("next_key")
private String nextKey;
/** 是否还有数据 */
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleMerchantUpdateParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleMerchantUpdateParam.java
new file mode 100644
index 0000000000..275577e1df
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleMerchantUpdateParam.java
@@ -0,0 +1,57 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 售后单商家协商信息
+ *
+ * @author Chu
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AfterSaleMerchantUpdateParam extends AfterSaleIdParam {
+ private static final long serialVersionUID = -3672834150982780L;
+
+ /** 协商修改把售后单修改成该售后类型。1:退款;2:退货退款*/
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 金额(单位:分)*/
+ @JsonProperty("amount")
+ private Integer amount;
+
+ /** 协商描述*/
+ @JsonProperty("merchant_update_desc")
+ private String merchantUpdateDesc;
+
+ /** 协商原因*/
+ @JsonProperty("update_reason_type")
+ private Integer updateReasonType;
+
+ /** 1:已协商一致,邀请买家取消售后; 2:邀请买家核实与补充凭证; 3:修改买家售后申请*/
+ @JsonProperty("merchant_update_type")
+ private Integer merchantUpdateType;
+
+ /** 协商凭证id列表,可使用图片上传接口获取media_id(数据类型填0),当update_reason_type对应的need_image为1时必填*/
+ @JsonProperty("media_ids")
+ private List mediaIds;
+
+ public AfterSaleMerchantUpdateParam() {
+ }
+
+ public AfterSaleMerchantUpdateParam(String afterSaleOrderId, Integer type, Integer updateReasonType, Integer merchantUpdateType
+ , Integer amount, String merchantUpdateDesc, List mediaIds) {
+ super(afterSaleOrderId);
+ this.type = type;
+ this.updateReasonType = updateReasonType;
+ this.merchantUpdateType = merchantUpdateType;
+ this.amount = amount;
+ this.merchantUpdateDesc = merchantUpdateDesc;
+ this.mediaIds = mediaIds;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReason.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReason.java
new file mode 100644
index 0000000000..7c66eff18f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReason.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 全量售后原因
+ *
+ * @author lizhengwu
+ * @date 2024/7/24
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleReason implements Serializable {
+
+ private static final long serialVersionUID = -3674527884494606230L;
+
+ /**
+ * 售后原因枚举
+ */
+ @JsonProperty("reason")
+ private Integer reason;
+
+ /**
+ * 售后原因说明
+ */
+ @JsonProperty("reason_text")
+ private String reasonText;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReasonResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReasonResponse.java
new file mode 100644
index 0000000000..7372dea1f1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleReasonResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+import java.util.List;
+
+/**
+ * 售后原因
+ *
+ *
+ * @author lizhengwu
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode
+public class AfterSaleReasonResponse extends WxChannelBaseResponse {
+
+
+ private static final long serialVersionUID = -580378623915041396L;
+
+ @JsonProperty("reason_list")
+ private List reasonList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectExchangeReshipParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectExchangeReshipParam.java
new file mode 100644
index 0000000000..668ffa11e9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectExchangeReshipParam.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 售后单换货拒绝发货信息
+ *
+ * @author Chu
+ */
+@Data
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class AfterSaleRejectExchangeReshipParam extends AfterSaleIdParam {
+ private static final long serialVersionUID = -7946679037747710613L;
+
+ /** 拒绝原因具体描述 ,可使用默认描述,也可以自定义描述*/
+ @JsonProperty("reject_reason")
+ private String rejectReason;
+
+ /** 拒绝原因枚举 */
+ @JsonProperty("reject_reason_type")
+ private Integer rejectReasonType;
+
+ /** 退款凭证,可使用图片上传接口获取media_id(数据类型填0)*/
+ @JsonProperty("reject_certificates")
+ private List rejectCertificates;
+
+ public AfterSaleRejectExchangeReshipParam() {
+ }
+
+ public AfterSaleRejectExchangeReshipParam(String afterSaleOrderId, String rejectReason, Integer rejectReasonType, List rejectCertificates) {
+ super(afterSaleOrderId);
+ this.rejectReason = rejectReason;
+ this.rejectReasonType = rejectReasonType;
+ this.rejectCertificates = rejectCertificates;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectParam.java
index 080665ac00..cbde459fea 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectParam.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectParam.java
@@ -15,10 +15,18 @@
public class AfterSaleRejectParam extends AfterSaleIdParam {
private static final long serialVersionUID = -7507483859864253314L;
- /** 拒绝原因 */
+ /**
+ * 拒绝原因
+ */
@JsonProperty("reject_reason")
private String rejectReason;
+ /**
+ * 拒绝原因枚举值
+ */
+ @JsonProperty("reject_reason_type")
+ private Integer rejectReasonType;
+
public AfterSaleRejectParam() {
}
@@ -26,4 +34,10 @@ public AfterSaleRejectParam(String afterSaleOrderId, String rejectReason) {
super(afterSaleOrderId);
this.rejectReason = rejectReason;
}
+
+ public AfterSaleRejectParam(String afterSaleOrderId, String rejectReason, Integer rejectReasonType) {
+ super(afterSaleOrderId);
+ this.rejectReason = rejectReason;
+ this.rejectReasonType = rejectReasonType;
+ }
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectReason.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectReason.java
new file mode 100644
index 0000000000..7987153ec0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectReason.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 拒绝售后原因
+ *
+ * @author lizhengwu
+ * @date 2024/7/24
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleRejectReason implements Serializable {
+
+ private static final long serialVersionUID = -3672834150982780L;
+
+ /**
+ * 售后拒绝原因枚举
+ */
+ @JsonProperty("reject_reason_type")
+ private Integer rejectReasonType;
+
+ /**
+ * 售后拒绝原因说明
+ */
+ @JsonProperty("reject_reason_type_text")
+ private String rejectReasonTypeText;
+
+ /**
+ * 售后拒绝原因默认描述
+ */
+ @JsonProperty("reject_reason")
+ private String rejectReason;
+
+ /**
+ * 售后拒绝原因适用场景
+ */
+ @JsonProperty("reject_scene")
+ private Integer rejectScene;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectReasonResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectReasonResponse.java
new file mode 100644
index 0000000000..7b50691d00
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleRejectReasonResponse.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+import java.util.List;
+
+/**
+ * 售后原因
+ *
+ * @author lizhengwu
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode
+public class AfterSaleRejectReasonResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -7946679037747710613L;
+
+ /**
+ * 售后原因列表
+ */
+ @JsonProperty("reject_reason_list")
+ private List rejectReasonList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleVirtualNumberInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleVirtualNumberInfo.java
new file mode 100644
index 0000000000..4366fa5ce9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/AfterSaleVirtualNumberInfo.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.after;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 虚拟号码信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class AfterSaleVirtualNumberInfo implements Serializable {
+ private static final long serialVersionUID = -5756618937333859985L;
+
+ /** 虚拟号码 */
+ @JsonProperty("virtual_tel_number")
+ private String virtualTelNumber;
+
+ /** 虚拟号码过期时间 */
+ @JsonProperty("virtual_tel_expire_time")
+ private Long virtualTelExpireTime;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundInfo.java
index 9837b72b28..73aedf99cf 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/after/RefundInfo.java
@@ -18,4 +18,8 @@ public class RefundInfo implements Serializable {
/** 退款金额(分) */
@JsonProperty("amount")
private Integer amount;
+
+ /** 标明售后单退款直接原因, 枚举值详情请参考 {@link me.chanjar.weixin.channel.enums.RefundReason} */
+ @JsonProperty("refund_reason")
+ private Integer refundReason;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditInfo.java
index 72a84bc922..485092704d 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryAuditInfo.java
@@ -1,5 +1,6 @@
package me.chanjar.weixin.channel.bean.audit;
+import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
import java.util.List;
@@ -15,6 +16,7 @@
@Data
@NoArgsConstructor
@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
public class CategoryAuditInfo implements Serializable {
private static final long serialVersionUID = -8792967130645424788L;
@@ -31,7 +33,47 @@ public class CategoryAuditInfo implements Serializable {
@JsonProperty("level3")
private Long level3;
- /** 资质材料,图片url,图片类型,最多不超过10张 */
+ /** 新类目树类目ID */
+ @JsonProperty("cats_v2")
+ private List catsV2;
+
+ /** 资质材料,图片fileid,图片类型,最多不超过10张 */
@JsonProperty("certificate")
private List certificates;
+
+ /** 报备函,图片fileid,图片类型,最多不超过10张 */
+ @JsonProperty("baobeihan")
+ private List baobeihan;
+
+ /** 经营证明,图片fileid,图片类型,最多不超过10张 */
+ @JsonProperty("jingyingzhengming")
+ private List jingyingzhengming;
+
+ /** 带货口碑,图片fileid,图片类型,最多不超过10张 */
+ @JsonProperty("daihuokoubei")
+ private List daihuokoubei;
+
+ /** 入住资质,图片fileid,图片类型,最多不超过10张 */
+ @JsonProperty("ruzhuzhizhi")
+ private List ruzhuzhizhi;
+
+ /** 经营流水,图片fileid,图片类型,最多不超过10张 */
+ @JsonProperty("jingyingliushui")
+ private List jingyingliushui;
+
+ /** 补充材料,图片fileid,图片类型,最多不超过10张 */
+ @JsonProperty("buchongcailiao")
+ private List buchongcailiao;
+
+ /** 经营平台,仅支持taobao,jd,douyin,kuaishou,pdd,other这些取值 */
+ @JsonProperty("jingyingpingtai")
+ private String jingyingpingtai;
+
+ /** 账号名称 */
+ @JsonProperty("zhanghaomingcheng")
+ private String zhanghaomingcheng;
+
+ /** 品牌列表,获取类目信息中的attr.is_limit_brand为true时必传 */
+ @JsonProperty("brand_list")
+ private List brandList;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryBrand.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryBrand.java
new file mode 100644
index 0000000000..632096e4d2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CategoryBrand.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.audit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分类中的品牌
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CategoryBrand implements Serializable {
+ private static final long serialVersionUID = -5437441266080209907L;
+
+ /** 品牌ID,是店铺申请且已审核通过的品牌ID */
+ @JsonProperty("brand_id")
+ private String brand_id;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CatsV2.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CatsV2.java
new file mode 100644
index 0000000000..b7cc6f39bc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/audit/CatsV2.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.audit;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 新类目树类目ID
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CatsV2 implements Serializable {
+ private static final long serialVersionUID = -2484092110142035589L;
+
+ /** 新类目树类目ID */
+ @JsonProperty("cat_id")
+ private String catId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java
index 8819e94312..3188bd3820 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryDetailResult.java
@@ -22,6 +22,9 @@ public class CategoryDetailResult extends WxChannelBaseResponse {
@JsonProperty("attr")
private Attr attr;
+ @JsonProperty("product_qua_list")
+ private List productQuaList;
+
@Data
@NoArgsConstructor
@@ -74,6 +77,38 @@ public static class Attr implements Serializable {
/** 佣金信息 */
@JsonProperty("transactionfee_info")
private FeeInfo feeInfo;
+
+ /** 折扣规则 */
+ @JsonProperty("coupon_rule")
+ private CouponRule couponRule;
+
+ /** 价格下限,单位分,商品售价不可低于此价格 */
+ @JsonProperty("floor_price")
+ private Long floorPrice;
+
+ /** 收货时间选项 */
+ @JsonProperty("confirm_receipt_days")
+ private List confirmReceiptDays;
+
+ /** 是否品牌定向准入,即该类目一定要有品牌 */
+ @JsonProperty("is_limit_brand")
+ private Boolean limitBrand;
+
+ /** 商品编辑要求 */
+ @JsonProperty("product_requirement")
+ private ProductRequirement productRequirement;
+
+ /** 尺码表 */
+ @JsonProperty("size_chart")
+ private SizeChart sizeChart;
+
+ /** 放心买必须打开坏损包赔 */
+ @JsonProperty("is_confidence_require_bad_must_pay")
+ private Boolean confidenceRequireBadMustPay;
+
+ /** 资质信息 */
+ @JsonProperty("product_qua_list")
+ private List productQuaList;
}
@Data
@@ -93,11 +128,27 @@ public static class ProductAttr implements Serializable {
@JsonProperty("name")
private String name;
- /** 类目必填项类型,string为自定义,select_one为多选一 */
+ /** 属性类型,string为自定义,select_one为多选一,该参数短期保留,用于兼容。将来废弃,使用type_v2替代 */
@JsonProperty("type")
private String type;
- /** 类目必填项值 */
+ /**
+ * 属性类型v2,共7种类型
+ * string:文本
+ * select_one:单选,选项列表在value中
+ * select_many:多选,选项列表在value中
+ * integer:整数,数字必须为整数
+ * decimal4:小数(4 位精度),小数部分最多 4 位
+ * integer_unit:整数 + 单位,单位的选项列表在value中
+ * decimal4_unit:小数(4 位精度) + 单位,单位的选项列表在value中
+ */
+ @JsonProperty("type_v2")
+ private String typeV2;
+
+ /**
+ * 可选项列表,当type为:select_one/select_many时,为选项列表
+ * 当type为:integer_unit/decimal4_unit时,为单位的列表
+ */
@JsonProperty("value")
private String value;
@@ -105,7 +156,13 @@ public static class ProductAttr implements Serializable {
@JsonProperty("is_required")
private Boolean required;
+ /** 输入提示,请填写提示语 */
+ @JsonProperty("hint")
+ private String hint;
+ /** 允许添加选项,当type为select_one/select_many时,标识是否允许添加新选项(value中不存在的选项) */
+ @JsonProperty("append_allowed")
+ private Boolean appendAllowed;
}
@Data
@@ -123,8 +180,78 @@ public static class FeeInfo implements Serializable {
/** 佣金激励类型,0:无激励措施,1:新店佣金减免 */
@JsonProperty("incentive_type")
private Integer incentiveType;
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class CouponRule implements Serializable {
+
+ /** 最高的折扣比例,百分比, 0表示无限制 */
+ @JsonProperty("discount_ratio_limit")
+ private Integer supportCoupon;
+
+ /** 最高的折扣金额,单位分,0表示无限制 */
+ @JsonProperty("discount_limit")
+ private Integer couponType;
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class ProductRequirement implements Serializable {
+ /** 商品标题的编辑要求 */
+ @JsonProperty("product_title_requirement")
+ private String productTitleRequirement;
+
+ /** 商品主图的编辑要求 */
+ @JsonProperty("product_img_requirement")
+ private String productImgRequirement;
+
+ /** 商品描述的编辑要求 */
+ @JsonProperty("product_desc_requirement")
+ private String productDescRequirement;
+ }
+ @Data
+ @NoArgsConstructor
+ public static class SizeChart implements Serializable {
+
+ /** 是否支持尺码表 */
+ @JsonProperty("is_support")
+ private Boolean support;
+
+ /** 尺码配置要求列表 */
+ @JsonProperty("item_list")
+ private List itemList;
+ }
+
+ @Data
+ @NoArgsConstructor
+ public static class SizeChartItem implements Serializable {
+ /** 尺码属性名称 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 尺码属性值的单位 */
+ @JsonProperty("unit")
+ private String unit;
+
+ /** 尺码属性值的类型,1:字符型,2:整数型,3:小数型 */
+ @JsonProperty("type")
+ private String type;
+
+ /** 尺码属性值的填写格式,1:单值填写,2:区间值填写,3:支持单值或区间值 */
+ @JsonProperty("format")
+ private String format;
+
+ /** 尺码属性值的限制 */
+ @JsonProperty("limit")
+ private String limit;
+
+ /** 是否必填 */
+ @JsonProperty("is_required")
+ private Boolean required;
}
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualification.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualification.java
index f384eaae45..9cac327d6c 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualification.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualification.java
@@ -2,6 +2,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import java.io.Serializable;
+import java.util.List;
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -24,8 +25,22 @@ public class CategoryQualification implements Serializable {
@JsonProperty("qua")
private QualificationInfo info;
- /** 商品资质信息 */
+ /** 商品资质信息,将废弃,使用product_qua_list代替 */
@JsonProperty("product_qua")
+ @Deprecated
private QualificationInfo productInfo;
+ /** 品牌资质信息 */
+ @JsonProperty("brand_qua")
+ @Deprecated
+ private QualificationInfo brandQua;
+
+ /** 商品资质列表,替代product_qua */
+ @JsonProperty("product_qua_list")
+ private List productQuaList;
+
+ /** 放心买必须打开坏损包赔 */
+ @JsonProperty("is_confidence_require_bad_must_pay")
+ private Boolean confidenceRequireBadMustPay;
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualificationResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualificationResponse.java
index 984a3ad79b..cbd588ebf9 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualificationResponse.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/CategoryQualificationResponse.java
@@ -22,4 +22,7 @@ public class CategoryQualificationResponse extends WxChannelBaseResponse {
@JsonProperty("cats")
private List list;
+ @JsonProperty("cats_v2")
+ private List catsV2;
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryResponse.java
index af6f484254..6509321b88 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryResponse.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/PassCategoryResponse.java
@@ -3,6 +3,7 @@
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;
@@ -13,6 +14,7 @@
*/
@Data
@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
public class PassCategoryResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = -3674591447273025743L;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/QualificationInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/QualificationInfo.java
index 197ac46528..efb7249fe3 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/QualificationInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/QualificationInfo.java
@@ -29,4 +29,8 @@ public class QualificationInfo implements Serializable {
/** 该类目申请的时候是否一定要提交资质 */
@JsonProperty("mandatory")
private Boolean mandatory;
+
+ /** 资质名称 */
+ @JsonProperty("name")
+ private String name;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryItem.java
new file mode 100644
index 0000000000..8e0bd1b0b5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryItem.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 店铺类目权限列表项
+ *
+ * @author chucheng
+ */
+@Data
+@NoArgsConstructor
+public class RelationCategoryItem implements Serializable {
+
+ /** 类目id */
+ @JsonProperty("id")
+ private Long id;
+
+ /** 类目状态, 1生效中,2已失效 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 失效原因 */
+ @JsonProperty("uneffective_reason")
+ private String uneffectiveReason;
+
+ /** 生效时间 */
+ @JsonProperty("effective_time")
+ private Long effectiveTime;
+
+ /** 失效时间 */
+ @JsonProperty("uneffective_time")
+ private Long uneffectiveTime;
+
+ /** 类目资质id */
+ @JsonProperty("qua_id")
+ private Long quaId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryRequest.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryRequest.java
new file mode 100644
index 0000000000..c514e7d9ca
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryRequest.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.category;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 类目权限列表请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class RelationCategoryRequest implements Serializable {
+
+ private static final long serialVersionUID = -8765432109876543210L;
+
+ /** 是否按状态筛选 */
+ @JsonProperty("is_filter_status")
+ private Boolean isFilterStatus;
+
+ /** 类目状态(当 isFilterStatus 为 true 时有效) */
+ @JsonProperty("status")
+ private Integer status;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryResponse.java
new file mode 100644
index 0000000000..4bd1ea96d4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/RelationCategoryResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.category;
+
+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 chucheng
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class RelationCategoryResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -8473920857463918245L;
+
+ @JsonProperty("list")
+ private List list;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategory.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategory.java
index b36edfa9e2..5dd04582f3 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategory.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategory.java
@@ -29,4 +29,8 @@ public class ShopCategory implements Serializable {
/** 层级 */
@JsonProperty("level")
private Integer level;
+
+ /** 是否为叶子类目(品类) */
+ @JsonProperty("leaf")
+ private Boolean leaf;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategoryResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategoryResponse.java
index 2af64ad1c3..fff7362a7a 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategoryResponse.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/category/ShopCategoryResponse.java
@@ -23,5 +23,7 @@ public class ShopCategoryResponse extends WxChannelBaseResponse {
@JsonProperty("cat_list")
private List categories;
-
+ /** 类目列表 */
+ @JsonProperty("cat_list_v2")
+ private List catListV2;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/CompassFinderBaseParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/CompassFinderBaseParam.java
new file mode 100644
index 0000000000..a1d5e277cc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/CompassFinderBaseParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.compass;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 获取达人罗盘数据通用请求参数
+ *
+ * @author Winnie
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CompassFinderBaseParam implements Serializable {
+
+ private static final long serialVersionUID = - 4900361041041434435L;
+
+ /**
+ * 日期,格式 yyyyMMdd
+ */
+ @JsonProperty("ds")
+ private String ds;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/Field.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/Field.java
new file mode 100644
index 0000000000..a23cde1878
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/Field.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 维度数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class Field implements Serializable {
+
+ private static final long serialVersionUID = - 4243469984232948689L;
+
+ /**
+ * 维度类别名
+ */
+ @JsonProperty("field_name")
+ private String fieldName;
+
+ /**
+ * 维度指标数据列表
+ */
+ @JsonProperty("data_list")
+ private List dataList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/FieldData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/FieldData.java
new file mode 100644
index 0000000000..a8b82c8326
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/FieldData.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 维度指标数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class FieldData implements Serializable {
+
+ private static final long serialVersionUID = - 4022953139259283599L;
+
+ /**
+ * 维度指标名
+ */
+ @JsonProperty("dim_key")
+ private String dimKey;
+
+ /**
+ * 维度指标值
+ */
+ @JsonProperty("dim_value")
+ private String dimValue;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/Overall.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/Overall.java
new file mode 100644
index 0000000000..ab77df0f97
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/Overall.java
@@ -0,0 +1,56 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 电商概览数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class Overall implements Serializable {
+
+ private static final long serialVersionUID = 2456038666608345011L;
+
+ /**
+ * 成交金额,单位分
+ */
+ @JsonProperty("pay_gmv")
+ private String payGmv;
+
+ /**
+ * 直播成交金额,单位分
+ */
+ @JsonProperty("live_pay_gmv")
+ private String livePayGmv;
+
+ /**
+ * 短视频成交金额,单位分
+ */
+ @JsonProperty("feed_pay_gmv")
+ private String feedPayGmv;
+
+ /**
+ * 橱窗成交金额,单位分
+ */
+ @JsonProperty("window_pay_gmv")
+ private String windowPayGmv;
+
+ /**
+ * 商品分享支付金额,单位分
+ */
+ @JsonProperty("product_pay_gmv")
+ private String productPayGmv;
+
+ /**
+ * 其他渠道成交金额,单位分
+ */
+ @JsonProperty("other_pay_gmv")
+ private String otherPayGmv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/OverallResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/OverallResponse.java
new file mode 100644
index 0000000000..8331726c13
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/OverallResponse.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 获取电商概览数据响应
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OverallResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 6350218415876820956L;
+
+ /**
+ * 电商概览数据
+ */
+ @JsonProperty("data")
+ private Overall data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductCompassData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductCompassData.java
new file mode 100644
index 0000000000..d84c8d367b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductCompassData.java
@@ -0,0 +1,170 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 商品罗盘数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class ProductCompassData implements Serializable {
+
+ private static final long serialVersionUID = - 1009289493985863096L;
+
+ /**
+ * 成交金额
+ */
+ @JsonProperty("pay_gmv")
+ private String payGmv;
+
+ /**
+ * 下单金额(单位:分)
+ */
+ @JsonProperty("create_gmv")
+ private String createGmv;
+
+ /**
+ * 下单订单数
+ */
+ @JsonProperty("create_cnt")
+ private String createCnt;
+
+ /**
+ * 下单人数
+ */
+ @JsonProperty("create_uv")
+ private String createUv;
+
+ /**
+ * 下单件数
+ */
+ @JsonProperty("create_product_cnt")
+ private String createProductCnt;
+
+ /**
+ * 成交订单数
+ */
+ @JsonProperty("pay_cnt")
+ private String payCnt;
+
+ /**
+ * 成交人数
+ */
+ @JsonProperty("pay_uv")
+ private String payUv;
+
+ /**
+ * 成交件数
+ */
+ @JsonProperty("pay_product_cnt")
+ private String payProductCnt;
+
+ /**
+ * 成交金额(剔除退款)(单位:分)
+ */
+ @JsonProperty("pure_pay_gmv")
+ private String purePayGmv;
+
+ /**
+ * 成交客单价(单位:分)
+ */
+ @JsonProperty("pay_gmv_per_uv")
+ private String payGmvPerUv;
+
+ /**
+ * 实际结算金额(单位:分)
+ */
+ @JsonProperty("actual_commission")
+ private String actualCommission;
+
+ /**
+ * 预估佣金金额(单位:分)
+ */
+ @JsonProperty("predict_commission")
+ private String predictCommission;
+
+ /**
+ * 商品点击人数
+ */
+ @JsonProperty("product_click_uv")
+ private String productClickUv;
+
+ /**
+ * 商品点击次数
+ */
+ @JsonProperty("product_click_cnt")
+ private String productClickCnt;
+
+ /**
+ * 成交退款金额
+ */
+ @JsonProperty("pay_refund_gmv")
+ private String payRefundGmv;
+
+ /**
+ * 成交退款人数
+ */
+ @JsonProperty("pay_refund_uv")
+ private String payRefundUv;
+
+ /**
+ * 成交退款率
+ */
+ @JsonProperty("pay_refund_ratio")
+ private Double payRefundRatio;
+
+ /**
+ * 发货后成交退款率
+ */
+ @JsonProperty("pay_refund_after_send_ratio")
+ private Double payRefundAfterSendRatio;
+
+ /**
+ * 成交退款订单数
+ */
+ @JsonProperty("pay_refund_cnt")
+ private String payRefundCnt;
+
+ /**
+ * 成交退款件数
+ */
+ @JsonProperty("pay_refund_product_cnt")
+ private String payRefundProductCnt;
+
+ /**
+ * 发货前成交退款率
+ */
+ @JsonProperty("pay_refund_before_send_ratio")
+ private Double payRefundBeforeSendRatio;
+
+ /**
+ * 退款金额(单位:分)
+ */
+ @JsonProperty("refund_gmv")
+ private String refundGmv;
+
+ /**
+ * 退款件数
+ */
+ @JsonProperty("refund_product_cnt")
+ private String refundProductCnt;
+
+ /**
+ * 退款订单数
+ */
+ @JsonProperty("refund_cnt")
+ private String refundCnt;
+
+ /**
+ * 退款人数
+ */
+ @JsonProperty("refund_uv")
+ private String refundUv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductDataParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductDataParam.java
new file mode 100644
index 0000000000..57a26a9794
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductDataParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.compass.CompassFinderBaseParam;
+
+/**
+ * 获取带货商品数据请求参数
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ProductDataParam extends CompassFinderBaseParam {
+
+ private static final long serialVersionUID = - 5016298274452168329L;
+
+ /**
+ * 商品id
+ */
+ @JsonProperty("product_id")
+ private String productId;
+
+ public ProductDataParam(String ds, String productId) {
+ super(ds);
+ this.productId = productId;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductDataResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductDataResponse.java
new file mode 100644
index 0000000000..628e0cc221
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductDataResponse.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 获取带货商品数据响应
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ProductDataResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 7264776818163943719L;
+
+ /**
+ * 带货商品数据
+ */
+ @JsonProperty("product_info")
+ private ProductInfo productInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductInfo.java
new file mode 100644
index 0000000000..3d1071b261
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductInfo.java
@@ -0,0 +1,68 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 带货商品数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class ProductInfo implements Serializable {
+
+ private static final long serialVersionUID = - 3347940276601700091L;
+
+ /**
+ * 商品id
+ */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /**
+ * 商品头图
+ */
+ @JsonProperty("head_img_url")
+ private String headImgUrl;
+
+ /**
+ * 商品标题
+ */
+ @JsonProperty("title")
+ private String title;
+
+ /**
+ * 商品价格
+ */
+ @JsonProperty("price")
+ private String price;
+
+ /**
+ * 1级类目
+ */
+ @JsonProperty("first_category_id")
+ private String firstCategoryId;
+
+ /**
+ * 2级类目
+ */
+ @JsonProperty("second_category_id")
+ private String secondCategoryId;
+
+ /**
+ * 3级类目
+ */
+ @JsonProperty("third_category_id")
+ private String thirdCategoryId;
+
+ /**
+ * 商品罗盘数据
+ */
+ @JsonProperty("data")
+ private ProductCompassData data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductListResponse.java
new file mode 100644
index 0000000000..e327531305
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/ProductListResponse.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+import java.util.List;
+
+/**
+ * 获取带货商品列表响应
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ProductListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 7903039293558611066L;
+
+ /**
+ * 带货商品列表
+ */
+ @JsonProperty("product_list")
+ private List productList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileData.java
new file mode 100644
index 0000000000..379943903e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileData.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 带货人群数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class SaleProfileData implements Serializable {
+
+ private static final long serialVersionUID = - 5542602540358792014L;
+
+ /**
+ * 维度数据列表
+ */
+ @JsonProperty("field_list")
+ private List fieldList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileDataParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileDataParam.java
new file mode 100644
index 0000000000..abe4610785
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileDataParam.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.compass.CompassFinderBaseParam;
+
+/**
+ * 获取带货人群数据请求参数
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SaleProfileDataParam extends CompassFinderBaseParam {
+
+ private static final long serialVersionUID = 4037843292285732855L;
+
+ /**
+ * 用户类型 {@link me.chanjar.weixin.channel.enums.SaleProfileUserType}
+ */
+ @JsonProperty("type")
+ private Integer type;
+
+ public SaleProfileDataParam(String ds, Integer type) {
+ super(ds);
+ this.type = type;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileDataResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileDataResponse.java
new file mode 100644
index 0000000000..a976671ba0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/finder/SaleProfileDataResponse.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.compass.finder;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 获取带货人群数据响应
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SaleProfileDataResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = - 6409722880191468272L;
+
+ /**
+ * 带货人群数据
+ */
+ @JsonProperty("data")
+ private SaleProfileData data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/CompassFinderIdParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/CompassFinderIdParam.java
new file mode 100644
index 0000000000..9383d2de2f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/CompassFinderIdParam.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.compass.CompassFinderBaseParam;
+
+/**
+ * 带货达人 请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CompassFinderIdParam extends CompassFinderBaseParam {
+
+ private static final long serialVersionUID = 9214560943091074780L;
+
+ /** 视频号ID */
+ @JsonProperty("finder_id")
+ private String finderId;
+
+ public CompassFinderIdParam(String ds, String finderId) {
+ super(ds);
+ this.finderId = finderId;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderAuthListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderAuthListResponse.java
new file mode 100644
index 0000000000..0f0351e975
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderAuthListResponse.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class FinderAuthListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -3215073536002857589L;
+
+ /** 主营视频号id */
+ @JsonProperty("main_finder_id")
+ private String mainFinderId;
+
+ /** 授权视频号id列表 */
+ @JsonProperty("authorized_finder_id_list")
+ private List authorizedFinderIdList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderGmvData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderGmvData.java
new file mode 100644
index 0000000000..822f93c4f0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderGmvData.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 带货达人数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FinderGmvData implements Serializable {
+
+ private static final long serialVersionUID = -7463331971169286175L;
+
+ /** 成交金额,单位分 */
+ @JsonProperty("pay_gmv")
+ private String payGmv;
+
+ /** 动销商品数 */
+ @JsonProperty("pay_product_id_cnt")
+ private String payProductIdCnt;
+
+ /** 成交人数 */
+ @JsonProperty("pay_uv")
+ private String payUv;
+
+ /** 退款金额,单位分 */
+ @JsonProperty("refund_gmv")
+ private String refundGmv;
+
+ /** 成交退款金额,单位分 */
+ @JsonProperty("pay_refund_gmv")
+ private String payRefundGmv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderGmvItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderGmvItem.java
new file mode 100644
index 0000000000..a102732c8a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderGmvItem.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 带货达人列表数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FinderGmvItem implements Serializable {
+
+ private static final long serialVersionUID = -3740996985044711599L;
+
+ /** 视频号id */
+ @JsonProperty("finder_id")
+ private String finderId;
+
+ /** 视频号昵称 */
+ @JsonProperty("finder_nickname")
+ private String finderNickname;
+
+ /** 带货达人数据 */
+ @JsonProperty("data")
+ private FinderGmvData data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderListResponse.java
new file mode 100644
index 0000000000..a5a37d9a2f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderListResponse.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class FinderListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 6358992001065379269L;
+
+ /** 授权视频号id列表 */
+ @JsonProperty("finder_list")
+ private List finderList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderOverallData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderOverallData.java
new file mode 100644
index 0000000000..6303202709
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderOverallData.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 带货数据概览
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FinderOverallData implements Serializable {
+
+ private static final long serialVersionUID = -994852668593815907L;
+
+ /** 成交金额,单位分 */
+ @JsonProperty("pay_gmv")
+ private String payGmv;
+
+ /** 动销达人数 */
+ @JsonProperty("pay_sales_finder_cnt")
+ private String paySalesFinderCnt;
+
+ /** 动销商品数 */
+ @JsonProperty("pay_product_id_cnt")
+ private String payProductIdCnt;
+
+ /** 点击-成交转化率 */
+ @JsonProperty("click_to_pay_uv_ratio")
+ private Double clickToPayUvRatio;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderOverallResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderOverallResponse.java
new file mode 100644
index 0000000000..fdc83fcce8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderOverallResponse.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.compass.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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class FinderOverallResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -4935555091396799318L;
+
+ /**
+ * 电商概览数据
+ */
+ @JsonProperty("data")
+ private FinderOverallData data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductListItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductListItem.java
new file mode 100644
index 0000000000..7f6ad34445
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductListItem.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 带货达人商品列表
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FinderProductListItem implements Serializable {
+
+ private static final long serialVersionUID = 1646092488200992026L;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 商品头图 */
+ @JsonProperty("head_img_url")
+ private String headImgUrl;
+
+ /** 商品标题 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 商品价格 */
+ @JsonProperty("price")
+ private String price;
+
+ /** 商品1级类目 */
+ @JsonProperty("first_category_id")
+ private String firstCategoryId;
+
+ /** 商品2级类目 */
+ @JsonProperty("second_category_id")
+ private String secondCategoryId;
+
+ /** 商品3级类目 */
+ @JsonProperty("third_category_id")
+ private String thirdCategoryId;
+
+ /** gmv */
+ @JsonProperty("data")
+ private GmvData data;
+
+
+ @Data
+ @NoArgsConstructor
+ public static class GmvData implements Serializable {
+ private static final long serialVersionUID = 1840494188469233735L;
+
+ /** 佣金率 */
+ @JsonProperty("commission_ratio")
+ private Double commissionRatio;
+
+ /** 成交金额,单位分 */
+ @JsonProperty("pay_gmv")
+ private String payGmv;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductListResponse.java
new file mode 100644
index 0000000000..bcdb1932d4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductListResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class FinderProductListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 5883861777181983173L;
+
+ /**
+ * 带货达人商品列表
+ */
+ @JsonProperty("product_list")
+ private List productList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductOverallResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductOverallResponse.java
new file mode 100644
index 0000000000..e47223a4d8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductOverallResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.compass.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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class FinderProductOverallResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 6358992001065379269L;
+
+ /** 带货达人详情 */
+ @JsonProperty("data")
+ private FinderGmvData data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductSimpleGmvData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductSimpleGmvData.java
new file mode 100644
index 0000000000..7a635dc4b0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/FinderProductSimpleGmvData.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 带货达人商品GMV数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class FinderProductSimpleGmvData implements Serializable {
+ private static final long serialVersionUID = -3740996985044711599L;
+
+ /** 佣金率 */
+ @JsonProperty("commission_ratio")
+ private Double commissionRatio;
+
+ /** 成交金额,单位分 */
+ @JsonProperty("pay_gmv")
+ private String payGmv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopField.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopField.java
new file mode 100644
index 0000000000..4acd91ace0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopField.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 维度数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopField implements Serializable {
+
+ private static final long serialVersionUID = -8669197081350262569L;
+
+ /** 维度类别名 */
+ @JsonProperty("field_name")
+ private String fieldName;
+
+ /** 维度指标数据列表 */
+ @JsonProperty("data_list")
+ private List dataList;
+
+
+ @Data
+ @NoArgsConstructor
+ public static class FieldDetail implements Serializable {
+
+ private static final long serialVersionUID = 2900633035074950462L;
+
+ /** 维度指标名 */
+ @JsonProperty("dim_key")
+ private String dimKey;
+
+ /** 维度指标值 */
+ @JsonProperty("dim_value")
+ private String dimValue;
+
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopLiveData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopLiveData.java
new file mode 100644
index 0000000000..d6a7b99451
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopLiveData.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 店铺开播数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopLiveData implements Serializable {
+
+ /** 直播id */
+ @JsonProperty("live_id")
+ private String liveId;
+
+ /** 直播标题 */
+ @JsonProperty("live_title")
+ private String liveTitle;
+
+ /** 开播时间,unix时间戳 */
+ @JsonProperty("live_time")
+ private String liveTime;
+
+ /** 直播时长,单位秒 */
+ @JsonProperty("live_duration")
+ private String liveDuration;
+
+ /** 直播封面 */
+ @JsonProperty("live_cover_img_url")
+ private String liveCoverImgUrl;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopLiveListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopLiveListResponse.java
new file mode 100644
index 0000000000..3ec9b68772
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopLiveListResponse.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ShopLiveListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -7110751559923117330L;
+
+ /** 店铺开播列表 */
+ @JsonProperty("live_list")
+ private List liveList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopOverall.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopOverall.java
new file mode 100644
index 0000000000..bf2fc8f42f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopOverall.java
@@ -0,0 +1,42 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 电商概览数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopOverall implements Serializable {
+
+ private static final long serialVersionUID = 3304918097895132226L;
+
+ /** 成交金额,单位分 */
+ @JsonProperty("pay_gmv")
+ private String payGmv;
+
+ /** 成交人数 */
+ @JsonProperty("pay_uv")
+ private String payUv;
+
+ /** 成交退款金额,单位分 */
+ @JsonProperty("pay_refund_gmv")
+ private String payRefundGmv;
+
+ /** 成交订单数 */
+ @JsonProperty("pay_order_cnt")
+ private String payOrderCnt;
+
+ /** 直播成交金额,单位分 */
+ @JsonProperty("live_pay_gmv")
+ private String livePayGmv;
+
+ /** 短视频成交金额,单位分 */
+ @JsonProperty("feed_pay_gmv")
+ private String feedPayGmv;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopOverallResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopOverallResponse.java
new file mode 100644
index 0000000000..4b371454ca
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopOverallResponse.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.compass.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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ShopOverallResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1632800741359642057L;
+
+ /**
+ * 电商概览数据
+ */
+ @JsonProperty("data")
+ private ShopOverall data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductCompassData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductCompassData.java
new file mode 100644
index 0000000000..03253e399e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductCompassData.java
@@ -0,0 +1,143 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 店铺商品罗盘数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopProductCompassData implements Serializable {
+
+ private static final long serialVersionUID = 5387546181020447627L;
+
+ /** 成交金额 */
+ @JsonProperty("pay_gmv")
+ private String payGmv;
+
+ /**下单金额,单位分 */
+ @JsonProperty("create_gmv")
+ private String createGmv;
+
+ /** 下单订单数 */
+ @JsonProperty("create_cnt")
+ private String createCnt;
+
+ /** 下单人数 */
+ @JsonProperty("create_uv")
+ private String createUv;
+
+ /** 下单件数 */
+ @JsonProperty("create_product_cnt")
+ private String createProductCnt;
+
+ /** 成交订单数 */
+ @JsonProperty("pay_cnt")
+ private String payCnt;
+
+ /** 成交人数 */
+ @JsonProperty("pay_uv")
+ private String payUv;
+
+ /** 成交件数 */
+ @JsonProperty("pay_product_cnt")
+ private String payProductCnt;
+
+ /** 成交金额(剔除退款) */
+ @JsonProperty("pure_pay_gmv")
+ private String purePayGmv;
+
+ /** 成交客单价(剔除退款) */
+ @JsonProperty("pay_gmv_per_uv")
+ private String payGmvPerUv;
+
+ /** 实际结算金额,单位分 */
+ @JsonProperty("seller_actual_settle_amount")
+ private String sellerActualSettleAmount;
+
+ /** 实际服务费金额,单位分 */
+ @JsonProperty("platform_actual_commission")
+ private String platformActualCommission;
+
+ /** 实际达人佣金支出,单位分 */
+ @JsonProperty("finderuin_actual_commission")
+ private String finderuinActualCommission;
+
+ /** 实际团长佣金支出,单位分 */
+ @JsonProperty("captain_actual_commission")
+ private String captainActualCommission;
+
+ /** 预估结算金额,单位分 */
+ @JsonProperty("seller_predict_settle_amount")
+ private String sellerPredictSettleAmount;
+
+ /** 预估服务费金额,单位分 */
+ @JsonProperty("platform_predict_commission")
+ private String platformPredictCommission;
+
+ /** 预估达人佣金支出,单位分 */
+ @JsonProperty("finderuin_predict_commission")
+ private String finderuinPredictCommission;
+
+ /** 预估团长佣金支出,单位分 */
+ @JsonProperty("captain_predict_commission")
+ private String captainPredictCommission;
+
+ /** 商品点击人数 */
+ @JsonProperty("product_click_uv")
+ private String productClickUv;
+
+ /** 商品点击次数 */
+ @JsonProperty("product_click_cnt")
+ private String productClickCnt;
+
+ /** 成交退款金额,单位分 */
+ @JsonProperty("pay_refund_gmv")
+ private String payRefundGmv;
+
+ /** 成交退款人数,单位分 */
+ @JsonProperty("pay_refund_uv")
+ private String payRefundUv;
+
+ /** 成交退款率 */
+ @JsonProperty("pay_refund_ratio")
+ private Double payRefundRatio;
+
+ /** 发货后成交退款率 */
+ @JsonProperty("pay_refund_after_send_ratio")
+ private Double payRefundAfterSendRatio;
+
+ /** 成交退款订单数 */
+ @JsonProperty("pay_refund_cnt")
+ private String payRefundCnt;
+
+ /** 成交退款件数 */
+ @JsonProperty("pay_refund_product_cnt")
+ private String payRefundProductCnt;
+
+ /** 发货前成交退款率 */
+ @JsonProperty("pay_refund_before_send_ratio")
+ private Double payRefundBeforeSendRatio;
+
+ /** 退款金额,单位分 */
+ @JsonProperty("refund_gmv")
+ private String refundGmv;
+
+ /** 退款件数 */
+ @JsonProperty("refund_product_cnt")
+ private String refundProductCnt;
+
+ /** 退款订单数 */
+ @JsonProperty("refund_cnt")
+ private String refundCnt;
+
+ /** 退款人数 */
+ @JsonProperty("refund_uv")
+ private String refundUv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductDataParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductDataParam.java
new file mode 100644
index 0000000000..74d7306273
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductDataParam.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.compass.CompassFinderBaseParam;
+
+/**
+ * 商品数据 请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ShopProductDataParam extends CompassFinderBaseParam {
+
+ private static final long serialVersionUID = - 5016298274452168329L;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ public ShopProductDataParam(String ds, String productId) {
+ super(ds);
+ this.productId = productId;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductDataResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductDataResponse.java
new file mode 100644
index 0000000000..bd7a22d243
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductDataResponse.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.compass.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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ShopProductDataResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 6903392663954301579L;
+
+ /** 商品详细信息 */
+ @JsonProperty("product_info")
+ private ShopProductInfo productInfo;
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductInfo.java
new file mode 100644
index 0000000000..1eb55eaa75
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductInfo.java
@@ -0,0 +1,51 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 店铺带货商品数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopProductInfo implements Serializable {
+
+ private static final long serialVersionUID = 3376047696301017643L;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 商品图 */
+ @JsonProperty("head_img_url")
+ private String headImgUrl;
+
+ /** 商品标题 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 商品价格,单位分 */
+ @JsonProperty("price")
+ private String price;
+
+ /** 商品一级类目 */
+ @JsonProperty("first_category_id")
+ private String firstCategoryId;
+
+ /** 商品二级类目 */
+ @JsonProperty("second_category_id")
+ private String secondCategoryId;
+
+ /** 商品三级类目 */
+ @JsonProperty("third_category_id")
+ private String thirdCategoryId;
+
+ /** 商品罗盘数据 */
+ @JsonProperty("data")
+ private ShopProductCompassData data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductListResponse.java
new file mode 100644
index 0000000000..258b8f5845
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopProductListResponse.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ShopProductListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -6328224902770141045L;
+
+ /** 商品列表 */
+ @JsonProperty("product_list")
+ private List productList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileData.java
new file mode 100644
index 0000000000..23639c5356
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileData.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 店铺人群数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class ShopSaleProfileData implements Serializable {
+
+ private static final long serialVersionUID = -6825849811081728787L;
+
+ /** 维度数据列表 */
+ @JsonProperty("field_list")
+ private List fieldList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileDataParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileDataParam.java
new file mode 100644
index 0000000000..36cab13860
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileDataParam.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.compass.shop;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.compass.CompassFinderBaseParam;
+
+/**
+ * 获取带货人群数据请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class ShopSaleProfileDataParam extends CompassFinderBaseParam {
+
+ private static final long serialVersionUID = 240010632808576923L;
+
+ /** 用户类型 */
+ @JsonProperty("type")
+ private Integer type;
+
+ public ShopSaleProfileDataParam(String ds, Integer type) {
+ super(ds);
+ this.type = type;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileDataResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileDataResponse.java
new file mode 100644
index 0000000000..a874cd6355
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/compass/shop/ShopSaleProfileDataResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.compass.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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ShopSaleProfileDataResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 8520148855114842741L;
+
+ /** 店铺人群数据 */
+ @JsonProperty("data")
+ private ShopSaleProfileData data;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintHistory.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintHistory.java
index 4570fdc615..84a558b2b1 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintHistory.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/complaint/ComplaintHistory.java
@@ -26,7 +26,7 @@ public class ComplaintHistory implements Serializable {
/** 用户联系电话 */
@JsonProperty("phone_number")
- private Integer phoneNumber;
+ private String phoneNumber;
/** 相关文本内容 */
@JsonProperty("content")
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationData.java
new file mode 100644
index 0000000000..41020f4993
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationData.java
@@ -0,0 +1,47 @@
+package me.chanjar.weixin.channel.bean.cooperation;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合作账号信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CooperationData implements Serializable {
+
+ private static final long serialVersionUID = 3930010847236599458L;
+
+ /** 合作账号id 公众号: gh_开头id 小程序: appid */
+ @JsonProperty("sharer_id")
+ private String sharerId;
+
+ /** 邀请/合作账号状态 1已绑定 2已解绑 3邀请已拒绝 4邀请接受中 5邀请接受超时 6邀请接受失败 7邀请店铺取消 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 合作账号名称 */
+ @JsonProperty("sharer_name")
+ private String sharerName;
+
+ /** 合作账号类型 2公众号 3小程序 */
+ @JsonProperty("sharer_type")
+ private Integer sharerType;
+
+ /** 接受绑定时间戳,ms */
+ @JsonProperty("bind_time")
+ private Long bindTime;
+
+ /** 用户拒绝时间戳,ms */
+ @JsonProperty("reject_time")
+ private Long rejectTime;
+
+ /** 商家取消时间戳,ms */
+ @JsonProperty("cancel_time")
+ private Long cancelTime;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationListResponse.java
new file mode 100644
index 0000000000..1b652b64d6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationListResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.cooperation;
+
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CooperationListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 6998637882644598826L;
+
+ /** 合作账号列表 */
+ @JsonProperty("data_list")
+ private List dataList;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationQrCode.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationQrCode.java
new file mode 100644
index 0000000000..272b9802da
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationQrCode.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.cooperation;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合作账号二维码数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CooperationQrCode implements Serializable {
+
+ private static final long serialVersionUID = -7096916911986699150L;
+
+ /** base64编码后的图片数据 */
+ @JsonProperty("qrcode_base64")
+ private Integer qrCodeBase64;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationQrCodeResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationQrCodeResponse.java
new file mode 100644
index 0000000000..b18b2b1c85
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationQrCodeResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.cooperation;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 合作账号二维码响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CooperationQrCodeResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 6998637882644598826L;
+
+ /** 合作账号二维码 */
+ @JsonProperty("data")
+ private CooperationQrCode data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationSharerParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationSharerParam.java
new file mode 100644
index 0000000000..4ca9bd8344
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationSharerParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.cooperation;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合作账号参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class CooperationSharerParam implements Serializable {
+
+ private static final long serialVersionUID = 5032621997764493109L;
+
+ /** 合作账号id */
+ @JsonProperty("sharer_id")
+ private String sharerId;
+
+ /** 合作账号类型 */
+ @JsonProperty("sharer_type")
+ private Integer sharerType;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationStatus.java
new file mode 100644
index 0000000000..5267be6153
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationStatus.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.cooperation;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 合作账号状态
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class CooperationStatus implements Serializable {
+
+ private static final long serialVersionUID = -7096916911986699150L;
+
+ /** 邀请/合作账号状态 1已绑定 2已解绑 3邀请已拒绝 4邀请接受中 5邀请接受超时 6邀请接受失败 7邀请店铺取消 */
+ @JsonProperty("status")
+ private Integer status;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationStatusResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationStatusResponse.java
new file mode 100644
index 0000000000..6507340c63
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/cooperation/CooperationStatusResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.cooperation;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 合作账号状态响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class CooperationStatusResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 6998637882644598826L;
+
+ /** 合作账号状态 */
+ @JsonProperty("data")
+ private CooperationStatus data;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/FreshInspectParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/FreshInspectParam.java
new file mode 100644
index 0000000000..a6db90f2f9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/FreshInspectParam.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.delivery;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品打包信息 参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class FreshInspectParam implements Serializable {
+ private static final long serialVersionUID = -1635894867602084789L;
+
+ /** 订单ID */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /** 商品打包信息 */
+ @JsonProperty("audit_items")
+ private List auditItems;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/PackageAuditInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/PackageAuditInfo.java
new file mode 100644
index 0000000000..bbb4e6c484
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/delivery/PackageAuditInfo.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.delivery;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.enums.PackageAuditItemType;
+
+/**
+ * 商品打包信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class PackageAuditInfo implements Serializable {
+ private static final long serialVersionUID = 1118087167138310282L;
+
+ /**
+ * 审核项名称,枚举类型参考 {@link PackageAuditItemType}
+ * 使用方法:DeliveryAuditItemType.EXPRESS_PIC.getKey()
+ */
+ @JsonProperty("item_name")
+ private String itemName;
+
+ /** 图片/视频url */
+ @JsonProperty("item_value")
+ private String itemValue;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/ConditionFreeDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/ConditionFreeDetail.java
index 68cb3b146e..cd0b76990d 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/ConditionFreeDetail.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/freight/ConditionFreeDetail.java
@@ -20,11 +20,11 @@ public class ConditionFreeDetail extends AddressInfoList {
@JsonProperty("min_piece")
private Integer minPiece;
- /** 最低重量 */
+ /** 最低重量,单位千克,订单商品总质量小于一千克,算作一千克 */
@JsonProperty("min_weight")
private Double minWeight;
- /** 最低金额 */
+ /** 最低金额,单位(分) */
@JsonProperty("min_amount")
private Integer minAmount;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundApplyResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundApplyResponse.java
new file mode 100644
index 0000000000..b0d8769874
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundApplyResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.home.background;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 提交背景图申请 结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BackgroundApplyResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -5627456997199822109L;
+
+ /** 申请编号 */
+ @JsonProperty("apply_id")
+ private Integer applyId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundApplyResult.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundApplyResult.java
new file mode 100644
index 0000000000..45ca4ac1dd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundApplyResult.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.home.background;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 背景图审核信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BackgroundApplyResult implements Serializable {
+
+ private static final long serialVersionUID = 3154900058221168732L;
+
+ /** 申请编号 */
+ @JsonProperty("apply_id")
+ private Integer applyId;
+
+ /** 申请状态。1审核中 2审核驳回 */
+ @JsonProperty("state")
+ private Integer state;
+
+ /** 审核结果描述。state为审核驳回时有值。 */
+ @JsonProperty("audit_desc")
+ private String auditDesc;
+
+ /** 图片url */
+ @JsonProperty("img_url")
+ private String imgUrl;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundGetResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundGetResponse.java
new file mode 100644
index 0000000000..a0fbf33a80
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/background/BackgroundGetResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.home.background;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 背景图返回结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BackgroundGetResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -9158761351220981959L;
+
+ /** 当前生效的背景图片url */
+ @JsonProperty("img_url")
+ private String imgUrl;
+
+ /** 背景图审核信息 */
+ @JsonProperty("apply")
+ private BackgroundApplyResult apply;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyDetail.java
new file mode 100644
index 0000000000..e9e58057fd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyDetail.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位申请详情
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class BannerApplyDetail implements Serializable {
+
+ private static final long serialVersionUID = -4622897527243343862L;
+
+ /** 审核状态。 1-审核中;2-审核驳回 */
+ @JsonProperty("audit_state")
+ private Integer auditState;
+
+ /** 审核结果描述。audit_state为驳回时有值。 */
+ @JsonProperty("audit_desc")
+ private String auditDesc;
+
+ /** 精选展示位申请明细 */
+ @JsonProperty("banner")
+ private BannerItem banner;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyInfo.java
new file mode 100644
index 0000000000..651c5c76fe
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyInfo.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位申请信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class BannerApplyInfo implements Serializable {
+
+ private static final long serialVersionUID = 72190625450999960L;
+
+ /** 申请编号 */
+ @JsonProperty("apply_id")
+ private Integer applyId;
+
+ /** 申请状态 1-审核中;2-审核驳回 */
+ @JsonProperty("state")
+ private Integer state;
+
+ /** 展示位的展示样式 1-小图模式;2-大图模式 */
+ @JsonProperty("scale")
+ private Integer scale;
+
+ /** 精选展示位申请明细 */
+ @JsonProperty("banner")
+ private List banner;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyParam.java
new file mode 100644
index 0000000000..04c7abc2a7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyParam.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位申请参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class BannerApplyParam implements Serializable {
+
+ private static final long serialVersionUID = 9083668032979490150L;
+
+ /** banner */
+ @JsonProperty("banner")
+ private BannerInfo banner;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyResponse.java
new file mode 100644
index 0000000000..f83f119d13
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerApplyResponse.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 提交精选展位申请 结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BannerApplyResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -2194587734444499201L;
+
+ /** 申请编号 */
+ @JsonProperty("apply_id")
+ private Integer applyId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerGetResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerGetResponse.java
new file mode 100644
index 0000000000..1c6a920636
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerGetResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 精选展位返回结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class BannerGetResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = -1563254921362215934L;
+
+ /** 当前生效的展示位 */
+ @JsonProperty("banner")
+ private BannerInfo banner;
+
+ /** 最近一次流程中的申请。不返回已生效或已撤销的申请 */
+ @JsonProperty("apply")
+ private BannerApplyInfo apply;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerInfo.java
new file mode 100644
index 0000000000..24b501a97d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerInfo.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class BannerInfo implements Serializable {
+
+ private static final long serialVersionUID = -2003175482038217418L;
+
+ /** 展示位的展示样式 1-小图模式;2-大图模式 */
+ @JsonProperty("scale")
+ private Integer scale;
+
+ /** 精选展示位明细 */
+ @JsonProperty("banner")
+ private List banner;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItem.java
new file mode 100644
index 0000000000..9a5cad9649
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItem.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位明细
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class BannerItem implements Serializable {
+
+ private static final long serialVersionUID = 6982412458700854481L;
+
+ /** 展示位类型 1-商品 3-视频号 4-公众号 {@link me.chanjar.weixin.channel.enums.BannerType} */
+ @JsonProperty("type")
+ private Integer type;
+
+ /** 展示位信息 */
+ @JsonProperty("banner")
+ private BannerItemDetail banner;
+
+ /** 商品 */
+ @JsonProperty("product")
+ private BannerItemProduct product;
+
+ /** 视频号 */
+ @JsonProperty("finder")
+ private BannerItemFinder finder;
+
+ /** 公众号 */
+ @JsonProperty("official_account")
+ private BannerItemOfficialAccount officialAccount;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemDetail.java
new file mode 100644
index 0000000000..b5cfb4a38c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemDetail.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位明细中的明细
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class BannerItemDetail implements Serializable {
+
+ private static final long serialVersionUID = 5975434996207526173L;
+
+ /** 图片url */
+ @JsonProperty("img_url")
+ private String imgUrl;
+
+ /** 标题 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 描述 */
+ @JsonProperty("description")
+ private String description;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemFinder.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemFinder.java
new file mode 100644
index 0000000000..735a2038da
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemFinder.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位明细中的视频号数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class BannerItemFinder implements Serializable {
+
+ private static final long serialVersionUID = -7397790079913284012L;
+
+ /** 视频号ID */
+ @JsonProperty("finder_user_name")
+ private String finderUserName;
+
+ /** 视频号视频的唯一标识 */
+ @JsonProperty("feed_id")
+ private String feedId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemOfficialAccount.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemOfficialAccount.java
new file mode 100644
index 0000000000..0488829642
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemOfficialAccount.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位明细中的公众号数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class BannerItemOfficialAccount implements Serializable {
+
+ private static final long serialVersionUID = -5596947592282082891L;
+
+ /** 公众号文章url */
+ @JsonProperty("url")
+ private String url;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemProduct.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemProduct.java
new file mode 100644
index 0000000000..87a51823f0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/banner/BannerItemProduct.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.home.banner;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 精选展示位明细中的商品
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(Include.NON_NULL)
+public class BannerItemProduct implements Serializable {
+
+ private static final long serialVersionUID = 8034487065591522594L;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private Long productId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/CatTreeNode.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/CatTreeNode.java
new file mode 100644
index 0000000000..c545b8637f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/CatTreeNode.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 主页分类信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class CatTreeNode implements Serializable {
+
+ private static final long serialVersionUID = 3154219180098003510L;
+
+ /** 分类id */
+ @JsonProperty("id")
+ private Integer id;
+
+ /** 分类名字 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 是否在用户端展示该分类。1为是,0为否 */
+ @JsonProperty("is_displayed")
+ private Boolean displayed;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/LevelTreeInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/LevelTreeInfo.java
new file mode 100644
index 0000000000..104588202e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/LevelTreeInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分类信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class LevelTreeInfo implements Serializable {
+
+ /** 一级分类 */
+ @JsonProperty("level_1")
+ private List level1;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/OneLevelTreeNode.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/OneLevelTreeNode.java
new file mode 100644
index 0000000000..76499c86e7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/OneLevelTreeNode.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 一级分类
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class OneLevelTreeNode extends CatTreeNode {
+
+ /** 二级分类 */
+ @JsonProperty("level_2")
+ private List level2;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeAuditResult.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeAuditResult.java
new file mode 100644
index 0000000000..b85dda46dd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeAuditResult.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 展示在店铺主页的商品分类
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class TreeAuditResult implements Serializable {
+
+ private static final long serialVersionUID = 8142657614529852121L;
+
+ /** 版本号。设置分类树的接口会用到 */
+ @JsonProperty("version")
+ private Integer version;
+
+ /** 展示在店铺主页的商品分类 */
+ @JsonProperty("audit_results")
+ private List auditResults;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeAuditResultDetail.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeAuditResultDetail.java
new file mode 100644
index 0000000000..92df865061
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeAuditResultDetail.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分类审核结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class TreeAuditResultDetail implements Serializable {
+
+ private static final long serialVersionUID = -6085892397971684732L;
+
+ /** 该分类ID的审核结果 */
+ @JsonProperty("level_id")
+ private Integer level_id;
+
+ /** 审核结果枚举。1:不通过;2:通过 */
+ @JsonProperty("result_code")
+ private Integer result_code;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductEditInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductEditInfo.java
new file mode 100644
index 0000000000..d7dd831c3d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductEditInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 添加/删除分类关联的商品 参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TreeProductEditInfo implements Serializable {
+
+ private static final long serialVersionUID = -5596947592282082891L;
+
+ /** 一级分类id */
+ @JsonProperty("level_1_id")
+ private Integer level1Id;
+
+ /** 二级分类id */
+ @JsonProperty("level_2_id")
+ private Integer level2Id;
+
+ /** 商品id列表 */
+ @JsonProperty("product_ids")
+ private List productIds;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductEditParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductEditParam.java
new file mode 100644
index 0000000000..fb42162ca6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductEditParam.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 添加/删除分类关联的商品 参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TreeProductEditParam implements Serializable {
+
+ private static final long serialVersionUID = -4906016235749892703L;
+
+ /** 参数 */
+ @JsonProperty("req")
+ private TreeProductEditInfo req;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListInfo.java
new file mode 100644
index 0000000000..a37e784d14
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListInfo.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 查询分类关联的商品 参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TreeProductListInfo implements Serializable {
+
+ private static final long serialVersionUID = 2774682583380930076L;
+
+ /** 一级分类id */
+ @JsonProperty("level_1_id")
+ private Integer level1Id;
+
+ /** 二级分类id */
+ @JsonProperty("level_2_id")
+ private Integer level2Id;
+
+ /** 分页大小 */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 从头拉取填空。翻页拉取的话填resp返回的值 */
+ @JsonProperty("page_context")
+ private String pageContext;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListParam.java
new file mode 100644
index 0000000000..7bb6a700e2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListParam.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 查询分类关联的商品 参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TreeProductListParam implements Serializable {
+
+ private static final long serialVersionUID = -8444106841479328711L;
+
+ /** 参数 */
+ @JsonProperty("req")
+ private TreeProductListInfo req;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListResponse.java
new file mode 100644
index 0000000000..ed0081d70c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListResponse.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 资金流水响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class TreeProductListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 4566848209585635054L;
+
+ /** 结果 */
+ @JsonProperty("resp")
+ private TreeProductListResult resp;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListResult.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListResult.java
new file mode 100644
index 0000000000..6e0fdfea6c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeProductListResult.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 资金流水响应 结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class TreeProductListResult implements Serializable {
+
+ private static final long serialVersionUID = 4566848209585635054L;
+
+ /** 关联的商品ID。如果返回为空,返回翻页到底了 */
+ @JsonProperty("product_ids")
+ private List productIds;
+
+ /** 总条数 */
+ @JsonProperty("total_count")
+ private Integer totalCount;
+
+ /** 拉取下一页的话,需要把这个值填到req的page_context里面 */
+ @JsonProperty("page_context")
+ private String pageContext;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowGetResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowGetResponse.java
new file mode 100644
index 0000000000..f3784c48fb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowGetResponse.java
@@ -0,0 +1,20 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class TreeShowGetResponse extends WxChannelBaseResponse {
+
+ /** resp */
+ @JsonProperty("resp")
+ private TreeShowInfo resp;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowInfo.java
new file mode 100644
index 0000000000..09da2c5b0c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowInfo.java
@@ -0,0 +1,45 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 分类展示信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TreeShowInfo implements Serializable {
+
+ /** 分类树 */
+ @JsonProperty("tree")
+ private LevelTreeInfo tree;
+
+ /** 版本号。通过获取商品分类树或者本接口得到 */
+ @JsonProperty("version")
+ private Integer version;
+
+ /** 表示有哪一些分类ID清空关联得商品,如果不清空,那么分类ID和商品得关联关系会一直存在。如果是一级分类,就填"1"。如果是二级分类,就填"1.2"。 */
+ @JsonProperty("classification_id_deleted")
+ private List classificationIdDeleted;
+
+ // 一些自定义的方法
+
+ /**
+ * 创建Tree节点
+ *
+ * @return Tree节点
+ */
+ protected LevelTreeInfo createTree() {
+ if (tree == null) {
+ tree = new LevelTreeInfo();
+ }
+ return tree;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowParam.java
new file mode 100644
index 0000000000..7277c528f4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowParam.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 设置展示在店铺主页的商品分类 参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TreeShowParam implements Serializable {
+
+ private static final long serialVersionUID = -1577647561992899360L;
+
+ /** 分类信息 */
+ @JsonProperty("req")
+ private TreeShowInfo req;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowSetResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowSetResponse.java
new file mode 100644
index 0000000000..ad65332644
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/tree/TreeShowSetResponse.java
@@ -0,0 +1,20 @@
+package me.chanjar.weixin.channel.bean.home.tree;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class TreeShowSetResponse extends WxChannelBaseResponse {
+
+ /** resp */
+ @JsonProperty("resp")
+ private TreeAuditResult resp;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductIndexParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductIndexParam.java
new file mode 100644
index 0000000000..fcc16bd0f6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductIndexParam.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.home.window;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 主页商品排序参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WindowProductIndexParam implements Serializable {
+
+ private static final long serialVersionUID = 1370480140179330908L;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 商品重新排序后的新序号,最大移动步长为500(即新序号与当前序号的距离小于500) */
+ @JsonProperty("index_num")
+ private Integer indexNum;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductListParam.java
new file mode 100644
index 0000000000..9245df9887
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductListParam.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.home.window;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 获取主页展示商品列表 参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WindowProductListParam implements Serializable {
+
+ /** 每页数量(默认10,不超过30) */
+ @JsonProperty("page_size")
+ private Integer pageSize;
+
+ /** 由上次请求返回,记录翻页的上下文。传入时会从上次返回的结果往后翻一页,不传默认获取第一页数据。 */
+ @JsonProperty("next_key")
+ private String nextKey;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductSetting.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductSetting.java
new file mode 100644
index 0000000000..725470b912
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductSetting.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.channel.bean.home.window;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 主页商品配置 返回结果 / 设置请求参数
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class WindowProductSetting implements Serializable {
+
+ private static final long serialVersionUID = -5931781905709862287L;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ private String productId;
+
+ /** 是否隐藏,设置为隐藏的商品只在首页不可见,并不代表下架。 */
+ @JsonProperty("is_set_hide")
+ private Integer setHide;
+
+ /** 是否置顶 */
+ @JsonProperty("is_set_top")
+ private Integer setTop;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductSettingResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductSettingResponse.java
new file mode 100644
index 0000000000..495910e37d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/home/window/WindowProductSettingResponse.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.home.window;
+
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class WindowProductSettingResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 1L;
+
+ /** 商品信息 */
+ @JsonProperty("products")
+ private List products;
+
+ /** 本次翻页的上下文,用于请求下一页 */
+ @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/league/promoter/PromoterListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListResponse.java
index c193550369..f7c7298c03 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListResponse.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/promoter/PromoterListResponse.java
@@ -18,11 +18,19 @@
public class PromoterListResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = 1411870432999885996L;
- /** 达人finder_id列表 */
+ /** 达人finder_id列表,待废除后续以promoter_ids为准 */
@JsonProperty("finder_ids")
private List finderIds;
/** 达人总数 */
@JsonProperty("total_num")
private Integer totalNum;
+
+ /** 后面是否还有(true: 还有内容; false: 已结束)*/
+ @JsonProperty("continue_flag")
+ private Boolean continueFlag;
+
+ /** 达人带货id列表 */
+ @JsonProperty("promoter_ids")
+ private List promoterIds;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowListResponse.java
index 468985fe3e..d4a04af981 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowListResponse.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/league/supplier/SupplierFlowListResponse.java
@@ -9,8 +9,7 @@
/**
* 资金流水列表 响应
*
- * @author LiXiZe
- * @since 2023-04-16
+ * @author Zeyes
*/
@Data
@NoArgsConstructor
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/ConversionMetric.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/ConversionMetric.java
new file mode 100644
index 0000000000..96a708be89
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/ConversionMetric.java
@@ -0,0 +1,61 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 转化率
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class ConversionMetric implements Serializable {
+
+ private static final long serialVersionUID = - 3411290344181494863L;
+
+ /**
+ * 商品曝光-点击转化率
+ */
+ @JsonProperty("product_view_click_conversion_ratio")
+ private ItemConversionMetric productViewClickConversionRatio;
+
+ /**
+ * 气泡曝光-点击转化率
+ */
+ @JsonProperty("bubble_view_click_conversion_ratio")
+ private ItemConversionMetric bubbleViewClickConversionRatio;
+
+ /**
+ * 成交转化率
+ */
+ @JsonProperty("pay_conversion_ratio")
+ private ItemConversionMetric payConversionRatio;
+
+ /**
+ * 千次观看成交金额(单位:分)
+ */
+ @JsonProperty("k_view_pay_conversion_ratio")
+ private ItemConversionMetric kViewPayConversionRatio;
+
+ /**
+ * 更新时间
+ */
+ @JsonProperty("update_time")
+ private Long updateTime;
+
+ /**
+ * 购物袋商品点击率
+ */
+ @JsonProperty("product_list_click_conversion_ratio")
+ private ItemConversionMetric productListClickConversionRatio;
+
+ /**
+ * 挂车时间(>0 则为挂车)
+ */
+ @JsonProperty("shelftime")
+ private Long shelftime;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNode.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNode.java
new file mode 100644
index 0000000000..ab749e0f82
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNode.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 统计数值
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class DataNode implements Serializable {
+
+ private static final long serialVersionUID = 3192158546911682577L;
+
+ /**
+ * 统计数值维度指标
+ */
+ @JsonProperty("fields")
+ private Fields fields;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeList.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeList.java
new file mode 100644
index 0000000000..6469e48e6e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeList.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 分类下的数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class DataNodeList implements Serializable {
+
+ private static final long serialVersionUID = - 497502210938812386L;
+
+ /**
+ * 细分类别的名称,如 "女"、"30-39岁"、"天津市"
+ */
+ @JsonProperty("key")
+ private String key;
+
+ /**
+ * 包含具体的统计数值
+ */
+ @JsonProperty("row")
+ private DataNode row;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeSecondList.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeSecondList.java
new file mode 100644
index 0000000000..7a033378c0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeSecondList.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 用户群体下不同分类的统计数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class DataNodeSecondList implements Serializable {
+
+ private static final long serialVersionUID = 42973481125049275L;
+
+ /**
+ * 每个分类对象都有一个 key,表示分类的名称,例如 "sex_distribution"、"age_distribution" {@link me.chanjar.weixin.channel.enums.EcProfileDataNodeKey}
+ */
+ @JsonProperty("key")
+ private String key;
+
+ /**
+ * 进一步细分该分类下的数据
+ */
+ @JsonProperty("row")
+ private List row;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeThirdList.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeThirdList.java
new file mode 100644
index 0000000000..7c6424b63f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/DataNodeThirdList.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 不同用户群体的统计数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class DataNodeThirdList implements Serializable {
+
+ private static final long serialVersionUID = - 7534433586440870881L;
+
+ /**
+ * 每个对象包含一个 key,表示用户群体的名称,例如 "已成交用户"、"首次购买用户"、"复购用户"
+ */
+ @JsonProperty("key")
+ private String key;
+
+ /**
+ * 包含该用户群体下不同分类的统计数据
+ */
+ @JsonProperty("row")
+ private List row;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Dimension.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Dimension.java
new file mode 100644
index 0000000000..a07e6670b4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Dimension.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 描述时间序列的维度标签
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class Dimension implements Serializable {
+
+ private static final long serialVersionUID = - 1879006149576217182L;
+
+ /**
+ * 维度的类型 {@link me.chanjar.weixin.channel.enums.DimensionType}
+ */
+ @JsonProperty("type")
+ private Integer type;
+
+ /**
+ * 维度标签
+ */
+ @JsonProperty("ux_label")
+ private String uxLabel;
+
+ /**
+ * 维度值
+ */
+ @JsonProperty("dimension_value")
+ private Long dimensionValue;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Ended.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Ended.java
new file mode 100644
index 0000000000..361a52663b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Ended.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 关播内容力数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class Ended implements Serializable {
+
+ private static final long serialVersionUID = 576815272236922652L;
+
+ /**
+ * 曝光有效CTR(万分比)
+ */
+ @JsonProperty("recommend_effective_new_watch_2_uv_over_impression_uv")
+ private EndedIndexItem recommendEffectiveNewWatch2UvOverImpressionUv;
+
+ /**
+ * 人均看播时长
+ */
+ @JsonProperty("average_watch_seconds")
+ private EndedIndexItem averageWatchSeconds;
+
+ /**
+ * 评论率(万分比)
+ */
+ @JsonProperty("comment_uv_over_new_watch_uv")
+ private EndedIndexItem commentUvOverNewWatchUv;
+
+ /**
+ * 点赞率(万分比)
+ */
+ @JsonProperty("like_uv_over_new_watch_uv")
+ private EndedIndexItem likeUvOverNewWatchUv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/EndedIndexItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/EndedIndexItem.java
new file mode 100644
index 0000000000..0823819491
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/EndedIndexItem.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 关播内容力指标数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class EndedIndexItem implements Serializable {
+
+ private static final long serialVersionUID = 7529336638744298238L;
+
+ /**
+ * 整场直播的指标值
+ */
+ @JsonProperty("value")
+ private Long value;
+
+ /**
+ * 整场直播该指标值打败了 xx% 的主播
+ */
+ @JsonProperty("percentile")
+ private Integer percentile;
+
+ /**
+ * 该指标 7 天中位数
+ */
+ @JsonProperty("median_7_days")
+ private Long median7Days;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Fields.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Fields.java
new file mode 100644
index 0000000000..b199f255a5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Fields.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 统计数值维度指标数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class Fields implements Serializable {
+
+ private static final long serialVersionUID = 228387216076265877L;
+
+ /**
+ * 维度值
+ */
+ @JsonProperty("dim_key")
+ private String dimKey;
+
+ /**
+ * 指标值
+ */
+ @JsonProperty("dim_val")
+ private String dimVal;
+
+ /**
+ * 指标值比例
+ */
+ @JsonProperty("dim_val_ratio")
+ private String dimValRatio;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/ItemConversionMetric.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/ItemConversionMetric.java
new file mode 100644
index 0000000000..6d5142b52f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/ItemConversionMetric.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 转化率数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class ItemConversionMetric implements Serializable {
+
+ private static final long serialVersionUID = - 8317027740221390754L;
+
+ /**
+ * 指标值
+ */
+ @JsonProperty("metric_value")
+ private Double metricValue;
+
+ /**
+ * 较近7天中位数
+ */
+ @JsonProperty("median_to_recent_7_days")
+ private Double medianToRecent7Days;
+
+ /**
+ * 同行对比
+ */
+ @JsonProperty("within_industry_percentage")
+ private Double withinIndustryPercentage;
+
+ /**
+ * 环比数据
+ */
+ @JsonProperty("quarterly_growth_rate")
+ private QuarterlyGrowthRate quarterlyGrowthRate;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveComparisonIndex.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveComparisonIndex.java
new file mode 100644
index 0000000000..84bfd6c226
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveComparisonIndex.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 内容力数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveComparisonIndex implements Serializable {
+
+ private static final long serialVersionUID = 525214144965479881L;
+
+ /**
+ * 是否正在直播
+ */
+ @JsonProperty("is_living")
+ private Boolean isLiving;
+
+ /**
+ * 在播数据
+ */
+ @JsonProperty("on_air")
+ private OnAir onAir;
+
+ /**
+ * 关播数据
+ */
+ @JsonProperty("ended")
+ private Ended ended;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData.java
new file mode 100644
index 0000000000..2568593f6b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 直播大屏数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDashboardData implements Serializable {
+
+ private static final long serialVersionUID = 7917049411269553153L;
+
+ /**
+ * 直播大屏数据实体
+ */
+ @JsonProperty("live_dashboard_data")
+ private LiveDashboardData2 liveDashboardData;
+
+ /**
+ * 直播时长
+ */
+ @JsonProperty("live_duration")
+ private Long liveDuration;
+
+ /**
+ * 直播开始时间
+ */
+ @JsonProperty("start_time")
+ private Long startTime;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2.java
new file mode 100644
index 0000000000..7a66f9ed1f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 直播大屏实体
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDashboardData2 implements Serializable {
+
+ private static final long serialVersionUID = 3657714024563123097L;
+
+ /**
+ * 直播基础数据
+ */
+ @JsonProperty("summary")
+ private LiveDashboardData2Summary summary;
+
+ /**
+ * 直播流量渠道
+ */
+ @JsonProperty("source")
+ private LiveDashboardData2Source source;
+
+ /**
+ * 直播观众画像
+ */
+ @JsonProperty("portrait")
+ private LiveDashboardData2Portrait portrait;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Portrait.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Portrait.java
new file mode 100644
index 0000000000..964a6936fc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Portrait.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 直播观众画像
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDashboardData2Portrait implements Serializable {
+
+ private static final long serialVersionUID = - 5603781471063785276L;
+
+ /**
+ * 在线人数的画像
+ */
+ @JsonProperty("online_watch_uv")
+ private List onlineWatchUv;
+
+ /**
+ * 观看人数的画像
+ */
+ @JsonProperty("new_watch_uv")
+ private List newWatchUv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Source.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Source.java
new file mode 100644
index 0000000000..12c6121bc7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Source.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 直播流量渠道
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDashboardData2Source implements Serializable {
+
+ private static final long serialVersionUID = 7347276250944913612L;
+
+ /**
+ * 观看人数的渠道分布
+ */
+ @JsonProperty("new_watch_uv")
+ private List newWatchUv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Summary.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Summary.java
new file mode 100644
index 0000000000..a9c46ea6e3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDashboardData2Summary.java
@@ -0,0 +1,80 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 直播基础数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDashboardData2Summary implements Serializable {
+
+ private static final long serialVersionUID = - 9029702302333930066L;
+
+ /**
+ * 观看人数
+ */
+ @JsonProperty("new_watch_uv")
+ private Long newWatchUv;
+
+ /**
+ * 最大在线人数
+ */
+ @JsonProperty("max_online_watch_uv")
+ private Long maxOnlineWatchUv;
+
+ /**
+ * 曝光人数
+ */
+ @JsonProperty("impression_uv")
+ private Long impressionUv;
+
+ /**
+ * 平均观看时长(秒)
+ */
+ @JsonProperty("average_watch_seconds_per_audience")
+ private Long averageWatchSecondsPerAudience;
+
+ /**
+ * 新增关注人数
+ */
+ @JsonProperty("new_follow_uv")
+ private Long newFollowUv;
+
+ /**
+ * 新增粉丝团人数
+ */
+ @JsonProperty("new_fans_club_uv")
+ private Long newFansClubUv;
+
+ /**
+ * 评论人数
+ */
+ @JsonProperty("comment_uv")
+ private Long commentUv;
+
+ /**
+ * 打赏人数
+ */
+ @JsonProperty("reward_uv")
+ private Long rewardUv;
+
+ /**
+ * 分享直播间人数
+ */
+ @JsonProperty("sharing_uv")
+ private Long sharingUv;
+
+ /**
+ * 热度
+ */
+ @JsonProperty("hot_quota")
+ private Long hotQuota;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDataParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDataParam.java
new file mode 100644
index 0000000000..965ed6c8c3
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDataParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 获取直播大屏数据请求参数
+ *
+ * @author Winnie
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class LiveDataParam implements Serializable {
+
+ private static final long serialVersionUID = 6346941931704153857L;
+
+ /**
+ * 直播唯一ID
+ */
+ @JsonProperty("export_id")
+ private String exportId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDataResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDataResponse.java
new file mode 100644
index 0000000000..4a5f4673bd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDataResponse.java
@@ -0,0 +1,69 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 获取直播大屏数据响应
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class LiveDataResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = - 8416743234527598719L;
+
+ /**
+ * 追踪ID,报bug带
+ */
+ @JsonProperty("trace_id")
+ private String traceId;
+
+ /**
+ * 直播大屏基础数据
+ */
+ @JsonProperty("live_dashboard_data")
+ private LiveDashboardData liveDashboardData;
+
+ /**
+ * 内容力数据
+ */
+ @JsonProperty("live_comparison_index")
+ private LiveComparisonIndex liveComparisonIndex;
+
+ /**
+ * 电商数据概要数据
+ */
+ @JsonProperty("live_ec_data_summary")
+ private LiveEcDataSummary liveEcDataSummary;
+
+ /**
+ * 电商转化力数据
+ */
+ @JsonProperty("live_ec_conversion_metric")
+ private LiveEcConversionMetric liveEcConversionMetric;
+
+ /**
+ * 电商画像数据
+ */
+ @JsonProperty("live_ec_profile")
+ private LiveEcProfile liveEcProfile;
+
+ /**
+ * 电商渠道分布
+ */
+ @JsonProperty("live_distribution_channel")
+ private LiveDistributionChannel liveDistributionChannel;
+
+ /**
+ * 电商商品数据
+ */
+ @JsonProperty("single_live_ec_spu_data_page_v2")
+ private SingleLiveEcSpuDataPageV2 singleLiveEcSpuDataPageV2;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistChannelSourceStats.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistChannelSourceStats.java
new file mode 100644
index 0000000000..9f4d876992
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistChannelSourceStats.java
@@ -0,0 +1,81 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 流量来源渠道指标数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDistChannelSourceStats implements Serializable {
+
+ private static final long serialVersionUID = - 6802106934852140579L;
+
+ /**
+ * 渠道层级
+ */
+ @JsonProperty("level")
+ private Integer level;
+
+ /**
+ * 来源渠道ID
+ */
+ @JsonProperty("source_channel_id")
+ private Long sourceChannelId;
+
+ /**
+ * 流量来源子渠道指标数据统计值
+ */
+ @JsonProperty("sub_channel_source_stats")
+ private List subChannelSourceStats;
+
+ /**
+ * GMV总值(单位:分)
+ */
+ @JsonProperty("gmv")
+ private Long gmv;
+
+ /**
+ * UV总值
+ */
+ @JsonProperty("uv")
+ private Long uv;
+
+ /**
+ * 千次看播成交(单位: 分)(GPV)
+ */
+ @JsonProperty("gmv_per_uv")
+ private Long gmvPerUv;
+
+ /**
+ * gmv占比
+ */
+ @JsonProperty("gmv_ratio")
+ private Double gmvRatio;
+
+ /**
+ * uv占比
+ */
+ @JsonProperty("uv_ratio")
+ private Double uvRatio;
+
+ /**
+ * 渠道名称
+ */
+ @JsonProperty("source_channel_name")
+ private String sourceChannelName;
+
+ /**
+ * 当前层级pv占总pv的比例
+ */
+ @JsonProperty("pv_ratio")
+ private Double pvRatio;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionByFlowTypeStat.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionByFlowTypeStat.java
new file mode 100644
index 0000000000..7b9765f955
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionByFlowTypeStat.java
@@ -0,0 +1,81 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 流量类型、渠道层级的渠道分析统计数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDistributionByFlowTypeStat implements Serializable {
+
+ private static final long serialVersionUID = 5885014384803438677L;
+
+ /**
+ * 渠道流量类型 {@link me.chanjar.weixin.channel.enums.LiveDistributionFlowType}
+ */
+ @JsonProperty("live_dst_channel_type")
+ private Integer liveDstChannelType;
+
+ /**
+ * 一级类目渠道来源指标划分
+ */
+ @JsonProperty("channel_source_stats")
+ private List channelSourceStats;
+
+ /**
+ * 在该渠道下的统计值
+ */
+ @JsonProperty("metric_value")
+ private Long metricValue;
+
+ /**
+ * GMV总值(单位:分)
+ */
+ @JsonProperty("gmv")
+ private Long gmv;
+
+ /**
+ * UV总值
+ */
+ @JsonProperty("uv")
+ private Long uv;
+
+ /**
+ * 千次看播成交(单位: 分)(GPV)
+ */
+ @JsonProperty("gmv_per_uv")
+ private Long gmvPerUv;
+
+ /**
+ * PV总值
+ */
+ @JsonProperty("pv")
+ private Long pv;
+
+ /**
+ * 当前层级pv占总pv的比例
+ */
+ @JsonProperty("pv_ratio")
+ private Double pvRatio;
+
+ /**
+ * uv占比
+ */
+ @JsonProperty("uv_ratio")
+ private Double uvRatio;
+
+ /**
+ * 在该渠道下的统计值比率
+ */
+ @JsonProperty("metric_value_ratio")
+ private Double metricValueRatio;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionChannel.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionChannel.java
new file mode 100644
index 0000000000..24eb64d4a2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionChannel.java
@@ -0,0 +1,51 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 电商渠道分布
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDistributionChannel implements Serializable {
+
+ private static final long serialVersionUID = - 5898886208775573377L;
+
+ /**
+ * 客户数
+ */
+ @JsonProperty("audience_count")
+ private Long audienceCount;
+
+ /**
+ * 总进入直播数
+ */
+ @JsonProperty("total_joinlive_count")
+ private Long totalJoinliveCount;
+
+ /**
+ * 按场景划分的渠道分析统计值
+ */
+ @JsonProperty("live_dist_channel_source_by_scene_stats")
+ private List liveDistChannelSourceBySceneStats;
+
+ /**
+ * 按照流量类型、渠道层级划分的渠道分析统计数据
+ */
+ @JsonProperty("live_dist_channel_source_stats")
+ private List liveDistChannelSourceStats;
+
+ /**
+ * 数据版本(无实际意义)
+ */
+ @JsonProperty("data_key")
+ private List dataKey;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionSceneStat.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionSceneStat.java
new file mode 100644
index 0000000000..425d69cca0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveDistributionSceneStat.java
@@ -0,0 +1,75 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 场景的渠道分析统计值
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveDistributionSceneStat implements Serializable {
+
+ private static final long serialVersionUID = 4261140121141859416L;
+
+ /**
+ * 场景类型 {@link me.chanjar.weixin.channel.enums.LiveDistributionSceneType}
+ */
+ @JsonProperty("scene_type")
+ private Integer sceneType;
+
+ /**
+ * 该场景下的渠道分析统计值
+ */
+ @JsonProperty("dist_flow_type_stats")
+ private List distFlowTypeStats;
+
+ /**
+ * 指标值总数
+ */
+ @JsonProperty("metric_value_total")
+ private Long metricValueTotal;
+
+ /**
+ * GMV总值(单位:分)
+ */
+ @JsonProperty("gmv")
+ private Long gmv;
+
+ /**
+ * UV总值
+ */
+ @JsonProperty("uv")
+ private Long uv;
+
+ /**
+ * 千次看播成交(单位: 分)
+ */
+ @JsonProperty("gmv_per_uv")
+ private Long gmvPerUv;
+
+ /**
+ * 指标值
+ */
+ @JsonProperty("metric_value")
+ private Long metricValue;
+
+ /**
+ * 在该渠道下的统计值比率
+ */
+ @JsonProperty("metric_value_ratio")
+ private Double metricValueRatio;
+
+ /**
+ * pv
+ */
+ @JsonProperty("pv")
+ private Long pv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcConversionMetric.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcConversionMetric.java
new file mode 100644
index 0000000000..e9b92821fe
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcConversionMetric.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 电商转化力数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveEcConversionMetric implements Serializable {
+
+ private static final long serialVersionUID = - 7332281175637902883L;
+
+ /**
+ * 近10分钟转化率数据
+ */
+ @JsonProperty("recent_10_min_conversion")
+ private ConversionMetric recent10MinConversion;
+
+ /**
+ * 整场直播
+ */
+ @JsonProperty("whole_live_conversion")
+ private ConversionMetric wholeLiveConversion;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcDataSummary.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcDataSummary.java
new file mode 100644
index 0000000000..d77209da56
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcDataSummary.java
@@ -0,0 +1,212 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 电商数据概要数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveEcDataSummary implements Serializable {
+
+ private static final long serialVersionUID = - 6634047980552575196L;
+
+ /**
+ * 成交金额(单位:分)
+ */
+ @JsonProperty("total_gmv")
+ private Long totalGmv;
+
+ /**
+ * 成交次数
+ */
+ @JsonProperty("total_pay_pv")
+ private Long totalPayPv;
+
+ /**
+ * 成交人数
+ */
+ @JsonProperty("total_pay_uv")
+ private Long totalPayUv;
+
+ /**
+ * 订单创建次数
+ */
+ @JsonProperty("total_create_pv")
+ private Long totalCreatePv;
+
+ /**
+ * 订单创建人数
+ */
+ @JsonProperty("total_create_uv")
+ private Long totalCreateUv;
+
+ /**
+ * 总点击次数
+ */
+ @JsonProperty("total_clk_pv")
+ private Long totalClkPv;
+
+ /**
+ * 总点击人数
+ */
+ @JsonProperty("total_clk_uv")
+ private Long totalClkUv;
+
+ /**
+ * 总曝光次数
+ */
+ @JsonProperty("total_exp_pv")
+ private Long totalExpPv;
+
+ /**
+ * 总曝光人数
+ */
+ @JsonProperty("total_exp_uv")
+ private Long totalExpUv;
+
+ /**
+ * 在线观众数
+ */
+ @JsonProperty("online_audience_count")
+ private Long onlineAudienceCount;
+
+ /**
+ * 累计观众数
+ */
+ @JsonProperty("cumulative_audience_count")
+ private Long cumulativeAudienceCount;
+
+ /**
+ * 新增观众数
+ */
+ @JsonProperty("new_audience_count")
+ private Long newAudienceCount;
+
+ /**
+ * 剩余观众数
+ */
+ @JsonProperty("leaved_audience_count")
+ private Long leavedAudienceCount;
+
+ /**
+ * 观众平均观看秒数
+ */
+ @JsonProperty("average_watch_seconds_per_audience")
+ private Long averageWatchSecondsPerAudience;
+
+ /**
+ * 新增关注数
+ */
+ @JsonProperty("new_follow_count")
+ private Long newFollowCount;
+
+ /**
+ * 新增评论数
+ */
+ @JsonProperty("new_comment_count")
+ private Long newCommentCount;
+
+ /**
+ * 分享直播观众数
+ */
+ @JsonProperty("share_live_audience_count")
+ private Long shareLiveAudienceCount;
+
+ /**
+ * 新粉丝俱乐部数
+ */
+ @JsonProperty("new_fans_club_count")
+ private Long newFansClubCount;
+
+ /**
+ * 退费次数
+ */
+ @JsonProperty("refund_pv")
+ private Long refundPv;
+
+ /**
+ * 退费人数
+ */
+ @JsonProperty("refund_uv")
+ private Long refundUv;
+
+ /**
+ * 退费率
+ */
+ @JsonProperty("refund_rate")
+ private Double refundRate;
+
+ /**
+ * 退款金额(单位:分)
+ */
+ @JsonProperty("refund_amount")
+ private Long refundAmount;
+
+ /**
+ * 退费商品件数
+ */
+ @JsonProperty("refund_product_cnt")
+ private Long refundProductCnt;
+
+ /**
+ * 广告累计观众数
+ */
+ @JsonProperty("ads_cumulative_audience_count")
+ private Long adsCumulativeAudienceCount;
+
+ /**
+ * 广告累计观看数
+ */
+ @JsonProperty("ads_cumulative_watch_count")
+ private Long adsCumulativeWatchCount;
+
+ /**
+ * 促销累计观看数
+ */
+ @JsonProperty("promotion_cumulative_watch_count")
+ private Long promotionCumulativeWatchCount;
+
+ /**
+ * 千次看播成交总额
+ */
+ @JsonProperty("gmv_per_thousand_cumulative_watch_pv")
+ private Double gmvPerThousandCumulativeWatchPv;
+
+ /**
+ * 观众成交率
+ */
+ @JsonProperty("audience_pay_ratio")
+ private Double audiencePayRatio;
+
+ /**
+ * 点击成交率
+ */
+ @JsonProperty("clk_pay_ratio")
+ private Double clkPayRatio;
+
+ /**
+ * 新买家人数
+ */
+ @JsonProperty("new_buyer_uv")
+ private Long newBuyerUv;
+
+ /**
+ * 老买家人数
+ */
+ @JsonProperty("old_buyer_uv")
+ private Long oldBuyerUv;
+
+ /**
+ * 客户价格
+ */
+ @JsonProperty("customer_price")
+ private Long customerPrice;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcProfile.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcProfile.java
new file mode 100644
index 0000000000..76f90c9942
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveEcProfile.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 电商画像数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveEcProfile implements Serializable {
+
+ private static final long serialVersionUID = 1996741772652344438L;
+
+ /**
+ * 包含不同用户群体的统计数据
+ */
+ @JsonProperty("profiles")
+ private List profiles;
+
+ /**
+ * 总体数据统计信息
+ */
+ @JsonProperty("totals")
+ private List totals;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveItem.java
new file mode 100644
index 0000000000..acea012018
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveItem.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 直播列表数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class LiveItem implements Serializable {
+
+ private static final long serialVersionUID = 6693176992531666035L;
+
+ /**
+ * 直播唯一ID
+ */
+ @JsonProperty("export_id")
+ private String exportId;
+
+ /**
+ * 直播创建时间
+ */
+ @JsonProperty("create_time")
+ private Long createTime;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveListParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveListParam.java
new file mode 100644
index 0000000000..3072e990ef
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveListParam.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 获取直播大屏直播列表请求参数
+ *
+ * @author Winnie
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class LiveListParam implements Serializable {
+
+ private static final long serialVersionUID = - 8451283214646387030L;
+
+ /**
+ * 日期,格式 yyyyMMdd
+ */
+ @JsonProperty("ds")
+ private Long ds;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveListResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveListResponse.java
new file mode 100644
index 0000000000..f9b1981dfa
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/LiveListResponse.java
@@ -0,0 +1,41 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+import java.util.List;
+
+/**
+ * 获取直播大屏直播列表响应
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class LiveListResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = - 5062337147636715367L;
+
+ /**
+ * 追踪ID,报bug带
+ */
+ @JsonProperty("trace_id")
+ private String traceId;
+
+ /**
+ * 直播列表
+ */
+ @JsonProperty("live_items")
+ private List liveItems;
+
+ /**
+ * 是否还有更多的直播
+ */
+ @JsonProperty("has_more")
+ private Boolean hasMore;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/OnAir.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/OnAir.java
new file mode 100644
index 0000000000..29aef35236
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/OnAir.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 在播内容力数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class OnAir implements Serializable {
+
+ private static final long serialVersionUID = 6354207471314033499L;
+
+ /**
+ * 曝光有效CTR(万分比)
+ */
+ @JsonProperty("recommend_effective_new_watch_2_uv_over_impression_uv")
+ private OnAirIndexItem recommendEffectiveNewWatch2UvOverImpressionUv;
+
+ /**
+ * 人均看播时长
+ */
+ @JsonProperty("average_watch_seconds")
+ private OnAirIndexItem averageWatchSeconds;
+
+ /**
+ * 评论率(万分比)
+ */
+ @JsonProperty("comment_uv_over_new_watch_uv")
+ private OnAirIndexItem commentUvOverNewWatchUv;
+
+ /**
+ * 点赞率(万分比)
+ */
+ @JsonProperty("like_uv_over_new_watch_uv")
+ private OnAirIndexItem likeUvOverNewWatchUv;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/OnAirIndexItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/OnAirIndexItem.java
new file mode 100644
index 0000000000..ebad794338
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/OnAirIndexItem.java
@@ -0,0 +1,56 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 在播内容力指标数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class OnAirIndexItem implements Serializable {
+
+ private static final long serialVersionUID = - 2988342521964183666L;
+
+ /**
+ * 描述最近多少分钟的指标值
+ */
+ @JsonProperty("n")
+ private Integer n;
+
+ /**
+ * 最近 n 分钟该指标的值
+ */
+ @JsonProperty("last_n_mins_value")
+ private Integer lastNMinsValue;
+
+ /**
+ * 最近 2n 到 n 分钟该指标的值(用于环比)
+ */
+ @JsonProperty("last_2n_to_n_mins_value")
+ private Integer last2nToNMinsValue;
+
+ /**
+ * 最近 n 分钟该指标值打败了 xx% 的在播主播
+ */
+ @JsonProperty("last_n_mins_percentile")
+ private Integer lastNMinsPercentile;
+
+ /**
+ * 整场直播的指标值
+ */
+ @JsonProperty("value")
+ private Long value;
+
+ /**
+ * 整场直播该指标值打败了 xx% 的主播
+ */
+ @JsonProperty("percentile")
+ private Integer percentile;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Point.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Point.java
new file mode 100644
index 0000000000..7f11086442
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Point.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 数据点
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class Point implements Serializable {
+
+ private static final long serialVersionUID = 3332256418933163389L;
+
+ /**
+ * 时间戳
+ */
+ @JsonProperty("ts")
+ private Long ts;
+
+ /**
+ * 指标值
+ */
+ @JsonProperty("value")
+ private Long value;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/QuarterlyGrowthRate.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/QuarterlyGrowthRate.java
new file mode 100644
index 0000000000..0acfdd7d18
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/QuarterlyGrowthRate.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 转化率环比数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class QuarterlyGrowthRate implements Serializable {
+
+ private static final long serialVersionUID = 1683118806978367016L;
+
+ /**
+ * 环比(近10分钟转化率数据才有)
+ */
+ @JsonProperty("value")
+ private Long value;
+
+ /**
+ * 环比是否是有效值(如果是false说明分母是0)
+ */
+ @JsonProperty("is_valid")
+ private Boolean isValid;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Series.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Series.java
new file mode 100644
index 0000000000..570c1b1b0d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/Series.java
@@ -0,0 +1,51 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 维度标签的时间序列(与指标的类型无关)
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class Series implements Serializable {
+
+ private static final long serialVersionUID = 507937573085880287L;
+
+ /**
+ * 数据点
+ */
+ @JsonProperty("points")
+ private List points;
+
+ /**
+ * 描述时间序列的维度标签
+ */
+ @JsonProperty("dimensions")
+ private List dimensions;
+
+ /**
+ * 每个数据点描述的时间长度(秒)
+ */
+ @JsonProperty("step")
+ private Long step;
+
+ /**
+ * 该时间序列的起始时间戳
+ */
+ @JsonProperty("begin_ts")
+ private Long beginTs;
+
+ /**
+ * 该时间序列的结束时间戳
+ */
+ @JsonProperty("end_ts")
+ private Long endTs;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SingleLiveEcSpuDataPageV2.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SingleLiveEcSpuDataPageV2.java
new file mode 100644
index 0000000000..5cdb3a97d0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SingleLiveEcSpuDataPageV2.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 电商商品数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class SingleLiveEcSpuDataPageV2 implements Serializable {
+
+ private static final long serialVersionUID = - 761977668198342583L;
+
+ /**
+ * 商品明细数据列表
+ */
+ @JsonProperty("spu_data_list")
+ private List spuDataList;
+
+ /**
+ * spu_data_list 的总长度
+ */
+ @JsonProperty("total_cnt")
+ private Integer totalCnt;
+
+ /**
+ * 数据版本(无实际意义)
+ */
+ @JsonProperty("data_key")
+ private List dataKey;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SpuBaseData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SpuBaseData.java
new file mode 100644
index 0000000000..b86279bdab
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SpuBaseData.java
@@ -0,0 +1,68 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 商品基础数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class SpuBaseData implements Serializable {
+
+ private static final long serialVersionUID = 3170611962212344198L;
+
+ /**
+ * 店铺商品id
+ */
+ @JsonProperty("src_spu_id")
+ private String srcSpuId;
+
+ /**
+ * 店铺id
+ */
+ @JsonProperty("src")
+ private Long src;
+
+ /**
+ * 商品名称
+ */
+ @JsonProperty("spu_name")
+ private String spuName;
+
+ /**
+ * 商品id
+ */
+ @JsonProperty("spu_id")
+ private Long spuId;
+
+ /**
+ * 商品小图
+ */
+ @JsonProperty("thumb_url")
+ private String thumbUrl;
+
+ /**
+ * 商品价格
+ */
+ @JsonProperty("price")
+ private Long price;
+
+ /**
+ * 店铺名称
+ */
+ @JsonProperty("src_name")
+ private String srcName;
+
+ /**
+ * 库存
+ */
+ @JsonProperty("stock")
+ private Long stock;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SpuData.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SpuData.java
new file mode 100644
index 0000000000..41a44a926d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SpuData.java
@@ -0,0 +1,350 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 商品明细数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class SpuData implements Serializable {
+
+ private static final long serialVersionUID = 7409791549917863816L;
+
+ /**
+ * 商品基础数据
+ */
+ @JsonProperty("base_data")
+ private SpuBaseData baseData;
+
+ /**
+ * 商品曝光人数
+ */
+ @JsonProperty("exp_uv")
+ private Long expUv;
+
+ /**
+ * 商品曝光次数
+ */
+ @JsonProperty("exp_pv")
+ private Long expPv;
+
+ /**
+ * 商品粉丝曝光人数
+ */
+ @JsonProperty("fans_exp_uv")
+ private Long fansExpUv;
+
+ /**
+ * 商品粉丝曝光次数
+ */
+ @JsonProperty("fans_exp_pv")
+ private Long fansExpPv;
+
+ /**
+ * 商品非粉丝曝光人数
+ */
+ @JsonProperty("non_fans_exp_uv")
+ private Long nonFansExpUv;
+
+ /**
+ * 商品非粉丝曝光次数
+ */
+ @JsonProperty("non_fans_exp_pv")
+ private Long nonFansExpPv;
+
+ /**
+ * 商品新客户曝光人数
+ */
+ @JsonProperty("new_customer_exp_uv")
+ private Long newCustomerExpUv;
+
+ /**
+ * 商品新客户曝光次数
+ */
+ @JsonProperty("new_customer_exp_pv")
+ private Long newCustomerExpPv;
+
+ /**
+ * 商品老客户曝光人数
+ */
+ @JsonProperty("repeated_customer_exp_uv")
+ private Long repeatedCustomerExpUv;
+
+ /**
+ * 商品老客户曝光次数
+ */
+ @JsonProperty("repeated_customer_exp_pv")
+ private Long repeatedCustomerExpPv;
+
+ /**
+ * 商品点击人数
+ */
+ @JsonProperty("clk_uv")
+ private Long clkUv;
+
+ /**
+ * 商品点击次数
+ */
+ @JsonProperty("clk_pv")
+ private Long clkPv;
+
+ /**
+ * 商品新客户点击人数
+ */
+ @JsonProperty("new_customer_clk_uv")
+ private Long newCustomerClkUv;
+
+ /**
+ * 商品新客户点击次数
+ */
+ @JsonProperty("new_customer_clk_pv")
+ private Long newCustomerClkPv;
+
+ /**
+ * 商品老客户点击人数
+ */
+ @JsonProperty("repeated_customer_clk_uv")
+ private Long repeatedCustomerClkUv;
+
+ /**
+ * 商品老客户点击次数
+ */
+ @JsonProperty("repeated_customer_clk_pv")
+ private Long repeatedCustomerClkPv;
+
+ /**
+ * 商品粉丝点击人数
+ */
+ @JsonProperty("fans_clk_uv")
+ private Long fansClkUv;
+
+ /**
+ * 商品粉丝点击次数
+ */
+ @JsonProperty("fans_clk_pv")
+ private Long fansClkPv;
+
+ /**
+ * 商品非粉丝点击人数
+ */
+ @JsonProperty("non_fans_clk_uv")
+ private Long nonFansClkUv;
+
+ /**
+ * 商品非粉丝点击次数
+ */
+ @JsonProperty("non_fans_clk_pv")
+ private Long nonFansClkPv;
+
+ /**
+ * 商品分享人数
+ */
+ @JsonProperty("share_uv")
+ private Long shareUv;
+
+ /**
+ * 商品分享次数
+ */
+ @JsonProperty("share_pv")
+ private Long sharePv;
+
+ /**
+ * 商品曝光点击率
+ */
+ @JsonProperty("exp_clk_ratio")
+ private Double expClkRatio;
+
+ /**
+ * 商品点击成交率
+ */
+ @JsonProperty("clk_pay_ratio")
+ private Double clkPayRatio;
+
+ /**
+ * 商品成交金额(单位:分)
+ */
+ @JsonProperty("gmv")
+ private Long gmv;
+
+ /**
+ * 商品成交订单数
+ */
+ @JsonProperty("pay_pv")
+ private Long payPv;
+
+ /**
+ * 商品成交人数
+ */
+ @JsonProperty("pay_uv")
+ private Long payUv;
+
+ /**
+ * 商品粉丝成交订单数
+ */
+ @JsonProperty("fans_pay_pv")
+ private Long fansPayPv;
+
+ /**
+ * 商品粉丝成交人数
+ */
+ @JsonProperty("fans_pay_uv")
+ private Long fansPayUv;
+
+ /**
+ * 商品非粉丝成交订单数
+ */
+ @JsonProperty("non_fans_pay_pv")
+ private Long nonFansPayPv;
+
+ /**
+ * 商品非粉丝成交人数
+ */
+ @JsonProperty("non_fans_pay_uv")
+ private Long nonFansPayUv;
+
+ /**
+ * 商品新客户成交次数
+ */
+ @JsonProperty("new_customer_pay_pv")
+ private Long newCustomerPayPv;
+
+ /**
+ * 商品新客户成交人数
+ */
+ @JsonProperty("new_customer_pay_uv")
+ private Long newCustomerPayUv;
+
+ /**
+ * 商品老客户成交次数
+ */
+ @JsonProperty("repeated_customer_pay_pv")
+ private Long repeatedCustomerPayPv;
+
+ /**
+ * 商品老客户成交人数
+ */
+ @JsonProperty("repeated_customer_pay_uv")
+ private Long repeatedCustomerPayUv;
+
+ /**
+ * 商品退款人数
+ */
+ @JsonProperty("refund_uv")
+ private Long refundUv;
+
+ /**
+ * 商品退款订单数
+ */
+ @JsonProperty("refund_pv")
+ private Long refundPv;
+
+ /**
+ * 商品退款金额(单位:分)
+ */
+ @JsonProperty("refund_amount")
+ private Long refundAmount;
+
+ /**
+ * 商品订单创建人数
+ */
+ @JsonProperty("create_uv")
+ private Long createUv;
+
+ /**
+ * 商品订单创建次数
+ */
+ @JsonProperty("create_pv")
+ private Long createPv;
+
+ /**
+ * 商品粉丝订单创建人数
+ */
+ @JsonProperty("fans_create_uv")
+ private Long fansCreateUv;
+
+ /**
+ * 商品粉丝订单创建次数
+ */
+ @JsonProperty("fans_create_pv")
+ private Long fansCreatePv;
+
+ /**
+ * 商品非粉丝订单创建人数
+ */
+ @JsonProperty("non_fans_create_uv")
+ private Long nonFansCreateUv;
+
+ /**
+ * 商品非粉丝订单创建次数
+ */
+ @JsonProperty("non_fans_create_pv")
+ private Long nonFansCreatePv;
+
+ /**
+ * 商品新客户订单创建人数
+ */
+ @JsonProperty("new_customer_create_uv")
+ private Long newCustomerCreateUv;
+
+ /**
+ * 商品新客户订单创建次数
+ */
+ @JsonProperty("new_customer_create_pv")
+ private Long newCustomerCreatePv;
+
+ /**
+ * 商品老客户订单创建人数
+ */
+ @JsonProperty("repeated_customer_create_uv")
+ private Long repeatedCustomerCreateUv;
+
+ /**
+ * 商品老客户订单创建次数
+ */
+ @JsonProperty("repeated_customer_create_pv")
+ private Long repeatedCustomerCreatePv;
+
+ /**
+ * 商品库存
+ */
+ @JsonProperty("stock")
+ private Long stock;
+
+ /**
+ * 商品退费率
+ */
+ @JsonProperty("refund_rate")
+ private Double refundRate;
+
+ /**
+ * 商品完成订单数
+ */
+ @JsonProperty("finish_pv")
+ private Long finishPv;
+
+ /**
+ * 商品未完成订单数
+ */
+ @JsonProperty("no_finish_pv")
+ private Long noFinishPv;
+
+ /**
+ * 商品新客户转换率
+ */
+ @JsonProperty("new_customer_conversion_rate")
+ private Double newCustomerConversionRate;
+
+ /**
+ * 商品讲解数
+ */
+ @JsonProperty("explanation_count")
+ private Long explanationCount;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SubLiveDistChannelSourceStats.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SubLiveDistChannelSourceStats.java
new file mode 100644
index 0000000000..7d183b738b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/live/dashboard/SubLiveDistChannelSourceStats.java
@@ -0,0 +1,92 @@
+package me.chanjar.weixin.channel.bean.live.dashboard;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 流量来源子渠道指标数据
+ *
+ * @author Winnie
+ */
+@Data
+@NoArgsConstructor
+public class SubLiveDistChannelSourceStats implements Serializable {
+
+ private static final long serialVersionUID = - 5279814435684116105L;
+
+ /**
+ * 渠道层级
+ */
+ @JsonProperty("level")
+ private Integer level;
+
+ /**
+ * 来源渠道ID
+ */
+ @JsonProperty("source_channel_id")
+ private Long sourceChannelId;
+
+ /**
+ * 在该渠道下的统计值
+ */
+ @JsonProperty("metric_value")
+ private Long metricValue;
+
+ /**
+ * GMV总值(单位:分)
+ */
+ @JsonProperty("gmv")
+ private Long gmv;
+
+ /**
+ * UV总值
+ */
+ @JsonProperty("uv")
+ private Long uv;
+
+ /**
+ * 千次看播成交(单位: 分)
+ */
+ @JsonProperty("gmv_per_uv")
+ private Long gmvPerUv;
+
+ /**
+ * gmv占比
+ */
+ @JsonProperty("gmv_ratio")
+ private Double gmvRatio;
+
+ /**
+ * uv占比
+ */
+ @JsonProperty("uv_ratio")
+ private Double uvRatio;
+
+ /**
+ * 在该渠道下的统计值比率
+ */
+ @JsonProperty("metric_value_ratio")
+ private Double metricValueRatio;
+
+ /**
+ * 渠道名称
+ */
+ @JsonProperty("source_channel_name")
+ private String sourceChannelName;
+
+ /**
+ * pv
+ */
+ @JsonProperty("pv")
+ private Long pv;
+
+ /**
+ * 当前层级pv占总pv的比例
+ */
+ @JsonProperty("pv_ratio")
+ private Double pvRatio;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuStockMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuStockMessage.java
new file mode 100644
index 0000000000..96feac5a4a
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/product/SpuStockMessage.java
@@ -0,0 +1,88 @@
+package me.chanjar.weixin.channel.bean.message.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.Map;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * SPU库存不足消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class SpuStockMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 2250860804161527363L;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ @JacksonXmlProperty(localName = "product_id")
+ private String productId;
+
+ /** 平台商品id */
+ @JsonProperty("sku_id")
+ @JacksonXmlProperty(localName = "sku_id")
+ private String skuId;
+
+ /** 剩余库存:当前实时库存数量 */
+ @JsonProperty("remaining_stock_amount")
+ @JacksonXmlProperty(localName = "remaining_stock_amount")
+ private Long remainingStockAmount;
+
+ /** 未发放的预存code数【该字段对code_source_type=2的团购优惠生效,其他类型该字段值为0】 */
+ @JsonProperty("remaining_code_amount")
+ @JacksonXmlProperty(localName = "remaining_code_amount")
+ private Long remainingCodeAmount;
+
+ /** ChannelsEcStockNoEnough */
+ @JsonProperty("channels_ec_stock_no_enough")
+ @JacksonXmlProperty(localName = "channels_ec_stock_no_enough")
+ private void stockNoEnough(Map map) {
+ this.unpackNameFromNestedObject(map);
+ }
+
+ /**
+ * 从嵌套对象中解析字段
+ *
+ * @param map 嵌套对象
+ */
+ protected void unpackNameFromNestedObject(Map map) {
+ if (map == null) {
+ return;
+ }
+ Object obj = null;
+ obj = map.get("product_id");
+ if (obj != null) {
+ this.productId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+ obj = map.get("sku_id");
+ if (obj != null) {
+ this.skuId = (obj instanceof String ? (String) obj : String.valueOf(obj));
+ }
+
+ obj = map.get("remaining_stock_amount");
+ if (obj != null) {
+ if (obj instanceof Number) {
+ this.remainingStockAmount = ((Number) obj).longValue();
+ } else if (obj instanceof String) {
+ this.remainingStockAmount = Long.parseLong((String) obj);
+ }
+ }
+ obj = map.get("remaining_code_amount");
+ if (obj != null) {
+ if (obj instanceof Number) {
+ this.remainingCodeAmount = ((Number) obj).longValue();
+ } else if (obj instanceof String) {
+ this.remainingCodeAmount = Long.parseLong((String) obj);
+ }
+ }
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/sharer/SharerChangeMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/sharer/SharerChangeMessage.java
new file mode 100644
index 0000000000..8b2036693e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/sharer/SharerChangeMessage.java
@@ -0,0 +1,48 @@
+package me.chanjar.weixin.channel.bean.message.sharer;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 分享员变更消息
+ * https://developers.weixin.qq.com/doc/channels/API/sharer/callback/channels_ec_sharer_change.html
+ *
+ * @author sd-hxf
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class SharerChangeMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 4219477394934480421L;
+
+ /**
+ * 分享员OpenID
+ */
+ @JsonProperty("openid")
+ @JacksonXmlProperty(localName = "openid")
+ private String openid;
+
+ /**
+ * 分享员类型:0-普通分享员,1-店铺分享员
+ */
+ @JsonProperty("sharer_type")
+ @JacksonXmlProperty(localName = "sharer_type")
+ private Integer sharerType;
+
+ /**
+ * 分享员绑定状态:1-绑定,2-解绑
+ */
+ @JsonProperty("bind_status")
+ @JacksonXmlProperty(localName = "bind_status")
+ private Integer bindStatus;
+
+
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/store/CloseStoreMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/store/CloseStoreMessage.java
new file mode 100644
index 0000000000..2a43483354
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/store/CloseStoreMessage.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.channel.bean.message.store;
+
+/**
+ * @author Zeyes
+ */
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 小店注销消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class CloseStoreMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 7619787772418774020L;
+
+ /** appid */
+ @JsonProperty("appid")
+ @JacksonXmlProperty(localName = "appid")
+ private String appid;
+
+ /** Unix时间戳,即格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数 */
+ @JsonProperty("close_timestamp")
+ @JacksonXmlProperty(localName = "close_timestamp")
+ private Long closeTimestamp;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/store/NicknameUpdateMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/store/NicknameUpdateMessage.java
new file mode 100644
index 0000000000..e6665497e0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/store/NicknameUpdateMessage.java
@@ -0,0 +1,43 @@
+package me.chanjar.weixin.channel.bean.message.store;
+
+/**
+ * @author Zeyes
+ */
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 小店修改名称消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class NicknameUpdateMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 7619787772418774020L;
+
+ /** appid */
+ @JsonProperty("appid")
+ @JacksonXmlProperty(localName = "appid")
+ private String appid;
+
+ /** 小店旧昵称 */
+ @JsonProperty("old_nickname")
+ @JacksonXmlProperty(localName = "old_nickname")
+ private String oldNickname;
+
+ /** 小店新昵称 */
+ @JsonProperty("new_nickname")
+ @JacksonXmlProperty(localName = "new_nickname")
+ private String newNickname;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/voucher/VoucherInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/voucher/VoucherInfo.java
new file mode 100644
index 0000000000..1b5a926205
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/voucher/VoucherInfo.java
@@ -0,0 +1,106 @@
+package me.chanjar.weixin.channel.bean.message.voucher;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class VoucherInfo implements Serializable {
+ private static final long serialVersionUID = 6007964849358969438L;
+
+ /** 券code */
+ @JsonProperty("code")
+ @JacksonXmlProperty(localName = "code")
+ private String code;
+
+ /** 劵码类型,1商户实时code 2户预存 3平台生成 */
+ @JsonProperty("code_type")
+ @JacksonXmlProperty(localName = "code_type")
+ private Integer codeType;
+
+ /** 券状态 */
+ @JsonProperty("status")
+ @JacksonXmlProperty(localName = "status")
+ private Integer status;
+
+ /** 发放时间,时间戳 */
+ @JsonProperty("send_time")
+ @JacksonXmlProperty(localName = "send_time")
+ private Long sendTime;
+
+ /** 最近更新时间,时间戳 */
+ @JsonProperty("update_time")
+ @JacksonXmlProperty(localName = "update_time")
+ private Long updateTime;
+
+ /** 核销生效时间,时间戳 */
+ @JsonProperty("start_time")
+ @JacksonXmlProperty(localName = "start_time")
+ private Long startTime;
+
+ /** 核销结束时间,时间戳 */
+ @JsonProperty("end_time")
+ @JacksonXmlProperty(localName = "end_time")
+ private Long endTime;
+
+ /** 核销时间,时间戳。次卡时不返回此字段 */
+ @JsonProperty("consume_time")
+ @JacksonXmlProperty(localName = "consume_time")
+ private Long consumeTime;
+
+ /** 退券时间,时间戳。次卡时不返回此字段 */
+ @JsonProperty("refund_time")
+ @JacksonXmlProperty(localName = "refund_time")
+ private Long refundTime;
+
+ /** 核销门店名称 */
+ @JsonProperty("consume_store_name")
+ @JacksonXmlProperty(localName = "consume_store_name")
+ private String consumeStoreName;
+
+ /** */
+ @JsonProperty("voucher_type")
+ @JacksonXmlProperty(localName = "voucher_type")
+ private Integer voucherType;
+
+ /** 券的售卖价格(分) */
+ @JsonProperty("voucher_buy_amount")
+ @JacksonXmlProperty(localName = "voucher_buy_amount")
+ private Integer voucherBuyAmount;
+
+ /** 券市场金额(分) */
+ @JsonProperty("voucher_actual_amount")
+ @JacksonXmlProperty(localName = "voucher_actual_amount")
+ private Integer voucherActualAmount;
+
+ /** 用户手机号 */
+ @JsonProperty("telphone_no")
+ @JacksonXmlProperty(localName = "telphone_no")
+ private String telPhoneNo;
+
+ /** 商品id */
+ @JsonProperty("product_id")
+ @JacksonXmlProperty(localName = "product_id")
+ private String productId;
+
+ /** 商品下的skuId */
+ @JsonProperty("sku_id")
+ @JacksonXmlProperty(localName = "sku_id")
+ private String skuId;
+
+ /** 购买券的订单id */
+ @JsonProperty("order_id")
+ @JacksonXmlProperty(localName = "order_id")
+ private String orderId;
+
+ /** 用户在商家品牌appid下的openid */
+ @JsonProperty("openid")
+ @JacksonXmlProperty(localName = "openid")
+ private String openId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/voucher/VoucherMessage.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/voucher/VoucherMessage.java
new file mode 100644
index 0000000000..941828969d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/message/voucher/VoucherMessage.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.message.voucher;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
+import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
+import java.util.List;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.message.WxChannelMessage;
+
+/**
+ * 发放团购优惠成功消息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JacksonXmlRootElement(localName = "xml")
+public class VoucherMessage extends WxChannelMessage {
+
+ private static final long serialVersionUID = 975858675917036089L;
+
+ /** 发放团购优惠成功消息 */
+ @JsonProperty("voucher_list")
+ @JacksonXmlProperty(localName = "voucher_list")
+ private List voucherInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/ChangeSkuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/ChangeSkuInfo.java
new file mode 100644
index 0000000000..b40a497755
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/ChangeSkuInfo.java
@@ -0,0 +1,42 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 更换sku信息
+ */
+@Data
+@NoArgsConstructor
+public class ChangeSkuInfo implements Serializable {
+
+ private static final long serialVersionUID = 8783442929429377519L;
+
+ /**
+ * 发货前更换sku状态。3:等待商家处理,4:商家审核通过,5:商家拒绝,6:用户主动取消,7:超时默认拒绝
+ */
+ @JsonProperty("preshipment_change_sku_state")
+ private Integer preshipmentChangeSkuState;
+
+ /**
+ * 原sku_id
+ */
+ @JsonProperty("old_sku_id")
+ private String oldSkuId;
+
+ /**
+ * 用户申请更换的sku_id
+ */
+ @JsonProperty("new_sku_id")
+ private String newSkuId;
+
+ /**
+ * 商家处理请求的最后时间,只有当前换款请求处于"等待商家处理"才有值
+ */
+ @JsonProperty("ddl_time_stamp")
+ private Integer deadlineTimeStamp;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DecodeAddressInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DecodeAddressInfo.java
new file mode 100644
index 0000000000..3aa6622eeb
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DecodeAddressInfo.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.AddressInfo;
+
+/**
+ * 解码地址数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class DecodeAddressInfo extends AddressInfo {
+
+ /** 虚拟发货订单联系方式,在发货方式为无需快递(deliver_method=1)时返回 */
+ @JsonProperty("virtual_order_tel_number")
+ private String virtualOrderTelNumber;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DecodeSensitiveInfoResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DecodeSensitiveInfoResponse.java
new file mode 100644
index 0000000000..c0431a8fd6
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DecodeSensitiveInfoResponse.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 解码订单包含的敏感数据响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class DecodeSensitiveInfoResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 935829924760021624L;
+
+ /** 收货信息 */
+ @JsonProperty("address_info")
+ private DecodeAddressInfo addressInfo;
+
+ /** 虚拟号信息 */
+ @JsonProperty("virtual_number_info")
+ private VirtualNumberInfo virtualNumberInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DropshipInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DropshipInfo.java
new file mode 100644
index 0000000000..9c5340376d
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/DropshipInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 代发相关信息
+ */
+@Data
+@NoArgsConstructor
+public class DropshipInfo implements Serializable {
+
+ private static final long serialVersionUID = -4562618835611282016L;
+
+ /**
+ * 代发单号
+ */
+ @JsonProperty("ds_order_id")
+ private Long dsOrderId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/FreeGiftInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/FreeGiftInfo.java
new file mode 100644
index 0000000000..b2612cfccd
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/FreeGiftInfo.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 赠品信息
+ */
+@Data
+@NoArgsConstructor
+public class FreeGiftInfo implements Serializable {
+
+ private static final long serialVersionUID = 2024061212345678901L;
+
+ /**
+ * 赠品对应的主品信息
+ */
+ @JsonProperty("main_product_list")
+ private List mainProductList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/MainProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/MainProductInfo.java
new file mode 100644
index 0000000000..bb13c0b0b7
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/MainProductInfo.java
@@ -0,0 +1,42 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 赠品对应的主品信息
+ */
+@Data
+@NoArgsConstructor
+public class MainProductInfo implements Serializable {
+
+ private static final long serialVersionUID = 2024061212345678901L;
+
+ /**
+ * 赠品数量
+ */
+ @JsonProperty("gift_cnt")
+ private Integer giftCnt;
+
+ /**
+ * 活动id
+ */
+ @JsonProperty("task_id")
+ private Integer taskId;
+
+ /**
+ * 商品id
+ */
+ @JsonProperty("product_id")
+ private Integer productId;
+
+ /**
+ * 主品sku_id
+ */
+ @JsonProperty("sku_id")
+ private Integer skuId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressInfo.java
index ff3e1ba332..1af5aee49e 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAddressInfo.java
@@ -20,4 +20,22 @@ public class OrderAddressInfo extends AddressInfo {
/** 虚拟发货订单联系方式(deliver_method=1时返回) */
@JsonProperty("virtual_order_tel_number")
private String virtualOrderTelNumber;
+
+ /**
+ * 额外的联系方式信息(虚拟号码相关),具体结构请参考TelNumberExtInfo结构体
+ */
+ @JsonProperty("tel_number_ext_info")
+ private TelNumberExtInfo telNumberExtInfo;
+
+ /**
+ * 0:不使用虚拟号码,1:使用虚拟号码
+ */
+ @JsonProperty("use_tel_number")
+ private Integer useTelNumber;
+
+ /**
+ * 标识当前店铺下一个唯一的用户收货地址
+ */
+ @JsonProperty("hash_code")
+ private String hashCode;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAgentInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAgentInfo.java
new file mode 100644
index 0000000000..548e36dd49
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderAgentInfo.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 授权账号信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderAgentInfo implements Serializable {
+
+ private static final long serialVersionUID = 6396067079343033841L;
+
+ /**
+ * 授权视频号id
+ */
+ @JsonProperty("agent_finder_id")
+ private String agentFinderId;
+
+ /**
+ * 授权视频号昵称
+ */
+ @JsonProperty("agent_finder_nickname")
+ private String agentFinderNickname;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java
index 78e391e774..f3cab1f4bf 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCommissionInfo.java
@@ -42,4 +42,8 @@ public class OrderCommissionInfo implements Serializable {
/** 达人openfinderid */
@JsonProperty("openfinderid")
private String openFinderId;
+
+ /** 新带货平台 id */
+ @JsonProperty("talent_id")
+ private String talentId;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCouponInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCouponInfo.java
index a8f020c0ef..34f2d670d0 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCouponInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCouponInfo.java
@@ -18,4 +18,24 @@ public class OrderCouponInfo implements Serializable {
/** 用户优惠券id */
@JsonProperty("user_coupon_id")
private String userCouponId;
+
+ /**
+ * 优惠券类型
+ * 1 商家优惠
+ * 2 达人优惠
+ * 3 平台优惠
+ * 4 国家补贴
+ * 5 地方补贴
+ */
+ @JsonProperty("coupon_type")
+ private Integer couponType;
+
+ /** 优惠金额,单位为分,该张优惠券、抵扣该商品的金额 */
+ @JsonProperty("discounted_price")
+ private Integer discountedPrice;
+
+ /** 优惠券id */
+ @JsonProperty("coupon_id")
+ private String couponId;
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCustomInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCustomInfo.java
new file mode 100644
index 0000000000..88981c6ccc
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderCustomInfo.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品定制信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderCustomInfo implements Serializable {
+ private static final long serialVersionUID = 6681266835402157651L;
+
+ /** 定制图片,custom_type=2时返回 */
+ @JsonProperty("custom_img_url")
+ private String customImgUrl;
+
+ /** 定制文字,custom_type=1时返回 */
+ @JsonProperty("custom_word")
+ private String customWord;
+
+ /** 定制类型,枚举值请参考CustomType枚举 */
+ @JsonProperty("custom_type")
+ private Integer customType;
+
+ /** 定制预览图片,开启了定制预览时返回 */
+ @JsonProperty("custom_preview_img_url")
+ private String customPreviewImgUrl;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDeliveryInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDeliveryInfo.java
index 9f3d72feac..ebe6bb8dc2 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDeliveryInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDeliveryInfo.java
@@ -44,4 +44,16 @@ public class OrderDeliveryInfo implements Serializable {
@JsonProperty("ewaybill_order_code")
private String ewaybillOrderCode;
+ /** 订单质检类型 2生鲜类质检 1珠宝玉石类质检 0不需要;不传递本字段表示不需要 */
+ @JsonProperty("quality_inspect_type")
+ private String qualityInspectType;
+
+ /** 质检信息 */
+ @JsonProperty("quality_inspect_info")
+ private QualityInsepctInfo qualityInspectInfo;
+
+ /** 虚拟商品充值账户信息 */
+ @JsonProperty("recharge_info")
+ private RechargeInfo rechargeInfo;
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDetailInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDetailInfo.java
index 8a17140cc1..4d96023be1 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDetailInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderDetailInfo.java
@@ -56,4 +56,23 @@ public class OrderDetailInfo implements Serializable {
@JsonProperty("sku_sharer_infos")
private List skuSharerInfos;
+ /** 授权账号信息 */
+ @JsonProperty("agent_info")
+ private OrderAgentInfo agentInfo;
+
+ /** 订单来源信息 */
+ @JsonProperty("source_infos")
+ private List sourceInfos;
+
+ /** 订单退款信息 */
+ @JsonProperty("refund_info")
+ private OrderSourceInfo refundInfo;
+
+ /** 订单代写商品信息 */
+ @JsonProperty("greeting_card_info")
+ private OrderGreetingCardInfo greetingCardInfo;
+
+ /** 商品定制信息 */
+ @JsonProperty("custom_info")
+ private OrderCustomInfo customInfo;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderExtInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderExtInfo.java
index 3338d1a428..a846311c61 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderExtInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderExtInfo.java
@@ -1,10 +1,11 @@
package me.chanjar.weixin.channel.bean.order;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.io.Serializable;
import lombok.Data;
import lombok.NoArgsConstructor;
+import java.io.Serializable;
+
/**
* 订单备注信息
*
@@ -15,12 +16,39 @@
public class OrderExtInfo implements Serializable {
private static final long serialVersionUID = 4568097877621455429L;
- /** 用户备注 */
+ /**
+ * 用户备注
+ */
@JsonProperty("customer_notes")
private String customerNotes;
- /** 商家备注 */
+ /**
+ * 商家备注
+ */
@JsonProperty("merchant_notes")
private String merchantNotes;
+ /**
+ * 确认收货时间,包括用户主动确认收货和超时自动确认收货
+ */
+ @JsonProperty("confirm_receipt_time")
+ private Long confirmReceiptTime;
+
+ /**
+ * 视频号id
+ */
+ @JsonProperty("finder_id")
+ private String finderId;
+
+ /**
+ * 直播id
+ */
+ @JsonProperty("live_id")
+ private String liveId;
+
+ /**
+ * 下单场景,枚举值见 {@link me.chanjar.weixin.channel.enums.OrderScene}
+ */
+ @JsonProperty("order_scene")
+ private Integer orderScene;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderGreetingCardInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderGreetingCardInfo.java
new file mode 100644
index 0000000000..6b0c37033f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderGreetingCardInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单商品贺卡信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderGreetingCardInfo implements Serializable {
+ private static final long serialVersionUID = -6391443179945240242L;
+
+ /** 贺卡落款,用户选填 */
+ @JsonProperty("giver_name")
+ private String giverName;
+
+ /** 贺卡称谓,用户选填 */
+ @JsonProperty("receiver_name")
+ private String receiverName;
+
+ /** 贺卡内容,用户必填 */
+ @JsonProperty("greeting_message")
+ private String greetingMessage;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfo.java
index 894b36f7af..00222d8487 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfo.java
@@ -39,6 +39,26 @@ public class OrderInfo implements Serializable {
@JsonProperty("aftersale_detail")
protected AfterSaleDetail afterSaleDetail;
+ /** 是否为礼物订单 */
+ @JsonProperty("is_present")
+ private Boolean present;
+
+ /** 礼物订单ID */
+ @JsonProperty("present_order_id_str")
+ private String presentOrderId;
+
+ /** 礼物订单留言 */
+ @JsonProperty("present_note")
+ private String presentNote;
+
+ /** 礼物订单赠送者openid */
+ @JsonProperty("present_giver_openid")
+ private String presentGiverOpenid;
+
+ /** 礼物订单赠送者unionid */
+ @JsonProperty("present_giver_unionid")
+ private String presentGiverUnionid;
+
/** 创建时间 秒级时间戳 */
@JsonProperty("create_time")
protected Integer createTime;
@@ -46,5 +66,4 @@ public class OrderInfo implements Serializable {
/** 更新时间 秒级时间戳 */
@JsonProperty("update_time")
protected Integer updateTime;
-
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfoParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfoParam.java
new file mode 100644
index 0000000000..e7a8c9a2b8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderInfoParam.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 获取订单详情参数
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class OrderInfoParam implements Serializable {
+
+ private static final long serialVersionUID = 42L;
+
+ /** 订单ID */
+ @JsonProperty("order_id")
+ private String orderId;
+
+ /**
+ * 用于商家提前测试订单脱敏效果,如果传true,即对订单进行脱敏,后期会默认对所有订单脱敏
+ */
+ @JsonProperty("encode_sensitive_info")
+ private Boolean encodeSensitiveInfo;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPayInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPayInfo.java
index 6c912f7c45..7a9f367d76 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPayInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPayInfo.java
@@ -16,12 +16,8 @@ public class OrderPayInfo implements Serializable {
private static final long serialVersionUID = -5085386252699113948L;
/** 预支付id */
- @JsonProperty("prepayId")
- private String prepayId;
-
- /** 预支付时间,秒级时间戳 */
- @JsonProperty("prepay_time")
- private Long prepayTime;
+ @JsonProperty("payment_method")
+ private Integer paymentMethod;
/** 支付时间,秒级时间戳 */
@JsonProperty("pay_time")
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceInfo.java
index 64e6690a66..50eac04e50 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderPriceInfo.java
@@ -1,10 +1,11 @@
package me.chanjar.weixin.channel.bean.order;
import com.fasterxml.jackson.annotation.JsonProperty;
-import java.io.Serializable;
import lombok.Data;
import lombok.NoArgsConstructor;
+import java.io.Serializable;
+
/**
* 商店订单价格信息
*
@@ -13,54 +14,127 @@
@Data
@NoArgsConstructor
public class OrderPriceInfo implements Serializable {
-
private static final long serialVersionUID = 5216506688949493432L;
- /** 商品总价,单位为分 */
+
+ /**
+ * 商品总价,单位为分
+ */
@JsonProperty("product_price")
private Integer productPrice;
- /** 订单金额,单位为分 */
+ /**
+ * 订单金额,单位为分
+ */
@JsonProperty("order_price")
private Integer orderPrice;
- /** 运费,单位为分 */
+ /**
+ * 运费,单位为分
+ */
@JsonProperty("freight")
private Integer freight;
- /** 优惠金额,单位为分 */
+ /**
+ * 优惠金额,单位为分
+ */
@JsonProperty("discounted_price")
private Integer discountedPrice;
- /** 是否有优惠 */
+ /**
+ * 是否有优惠
+ */
@JsonProperty("is_discounted")
private Boolean isDiscounted;
- /** 订单原始价格,单位为分 */
+ /**
+ * 订单原始价格,单位为分
+ */
@JsonProperty("original_order_price")
private Integer originalOrderPrice;
- /** 商品预估价格,单位为分 */
+ /**
+ * 商品预估价格,单位为分
+ */
@JsonProperty("estimate_product_price")
private Integer estimateProductPrice;
- /** 改价后降低金额,单位为分 */
+ /**
+ * 改价后降低金额,单位为分
+ */
@JsonProperty("change_down_price")
private Integer changeDownPrice;
- /** 改价后运费,单位为分 */
+ /**
+ * 改价后运费,单位为分
+ */
@JsonProperty("change_freight")
private Integer changeFreight;
- /** 是否修改运费 */
+ /**
+ * 是否修改运费
+ */
@JsonProperty("is_change_freight")
private Boolean changeFreighted;
- /** 是否使用了会员积分抵扣 */
+ /**
+ * 是否使用了会员积分抵扣
+ */
@JsonProperty("use_deduction")
private Boolean useDeduction;
- /** 会员积分抵扣金额,单位为分 */
+ /**
+ * 会员积分抵扣金额,单位为分
+ */
@JsonProperty("deduction_price")
private Integer deductionPrice;
+ /**
+ * 商家实收金额,单位为分
+ * merchant_receieve_price=original_order_price-discounted_price-deduction_price-change_down_price
+ */
+ @JsonProperty("merchant_receieve_price")
+ private Integer merchantReceivePrice;
+
+ /**
+ * 商家优惠金额,单位为分,含义同discounted_price,必填
+ */
+ @JsonProperty("merchant_discounted_price")
+ private Integer merchantDiscountedPrice;
+
+ /**
+ * 达人优惠金额,单位为分
+ */
+ @JsonProperty("finder_discounted_price")
+ private Integer finderDiscountedPrice;
+
+ /**
+ * 订单维度会员权益优惠金额
+ */
+ @JsonProperty("vip_discounted_price")
+ private Integer vipDiscountedPrice;
+
+ /**
+ * 订单维度一起买优惠金额,单位为分
+ */
+ @JsonProperty("bulkbuy_discounted_price")
+ private Integer bulkbuyDiscountedPrice;
+
+ /**
+ * 订单维度国补优惠金额
+ */
+ @JsonProperty("national_subsidy_discounted_price")
+ private Integer nationalSubsidyDiscountedPrice;
+
+ /**
+ * 订单维度平台券优惠金额,单位为分
+ */
+ @JsonProperty("cash_coupon_discounted_price")
+ private Integer cashCouponDiscountedPrice;
+
+ /**
+ * 订单维度地方补贴优惠金额(商家出资),单位为分
+ */
+ @JsonProperty("national_subsidy_merchant_discounted_price")
+ private Integer nationalSubsidyMerchantDiscountedPrice;
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderProductInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderProductInfo.java
index acef8cc4f6..e5c37e3cba 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderProductInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderProductInfo.java
@@ -1,8 +1,10 @@
package me.chanjar.weixin.channel.bean.order;
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;
@@ -17,96 +19,238 @@
public class OrderProductInfo implements Serializable {
private static final long serialVersionUID = -2193536732955185928L;
- /** 商品spu id */
+ /**
+ * 商品spu id
+ */
@JsonProperty("product_id")
private String productId;
- /** sku_id */
+ /**
+ * sku_id
+ */
@JsonProperty("sku_id")
private String skuId;
- /** sku小图 */
+ /**
+ * sku小图
+ */
@JsonProperty("thumb_img")
private String thumbImg;
- /** sku数量 */
+ /**
+ * sku数量
+ */
@JsonProperty("sku_cnt")
private Integer skuCnt;
- /** 售卖价格(单位:分) */
+ /**
+ * 售卖价格(单位:分)
+ */
@JsonProperty("sale_price")
private Integer salePrice;
- /** 商品标题 */
+ /**
+ * 商品标题
+ */
@JsonProperty("title")
private String title;
- /** 正在售后/退款流程中的 sku 数量 */
+ /**
+ * 正在售后/退款流程中的 sku 数量
+ */
@JsonProperty("on_aftersale_sku_cnt")
private Integer onAfterSaleSkuCnt;
- /** 完成售后/退款的 sku 数量 */
+ /**
+ * 完成售后/退款的 sku 数量
+ */
@JsonProperty("finish_aftersale_sku_cnt")
private Integer finishAfterSaleSkuCnt;
- /** 商品编码 */
+ /**
+ * 商品编码
+ */
@JsonProperty("sku_code")
private String skuCode;
- /** 市场价格(单位:分) */
+ /**
+ * 市场价格(单位:分)
+ */
@JsonProperty("market_price")
private Integer marketPrice;
- /** sku属性 */
+ /**
+ * sku属性
+ */
@JsonProperty("sku_attrs")
private List skuAttrs;
- /** sku实付价格 */
+ /**
+ * sku实付价格
+ */
@JsonProperty("real_price")
private Integer realPrice;
- /** 商品外部spu id */
+ /**
+ * 商品外部spu id
+ */
@JsonProperty("out_product_id")
private String outProductId;
- /** 商品外部sku id */
+ /**
+ * 商品外部sku id
+ */
@JsonProperty("out_sku_id")
private String outSkuId;
- /** 是否有优惠金额,非必填,默认为false */
+ /**
+ * 是否有优惠金额,非必填,默认为false
+ */
@JsonProperty("is_discounted")
private Boolean isDiscounted;
- /** 优惠后 sku 价格,非必填,is_discounted为 true 时有值 */
+ /**
+ * 优惠后 sku 价格,非必填,is_discounted为 true 时有值
+ */
@JsonProperty("estimate_price")
private Integer estimatePrice;
- /** 是否修改过价格,非必填,默认为false */
+ /**
+ * 是否修改过价格,非必填,默认为false
+ */
@JsonProperty("is_change_price")
private Boolean changePriced;
- /** 改价后 sku 价格,非必填,is_change_price为 true 时有值 */
+ /**
+ * 改价后 sku 价格,非必填,is_change_price为 true 时有值
+ */
@JsonProperty("change_price")
private Integer changePrice;
- /** 区域库存id */
+ /**
+ * 区域库存id
+ */
@JsonProperty("out_warehouse_id")
private String outWarehouseId;
- /** 商品发货信息 */
+ /**
+ * 商品发货信息
+ */
@JsonProperty("sku_deliver_info")
private OrderSkuDeliverInfo skuDeliverInfo;
- /** 商品额外服务信息 */
+ /**
+ * 商品额外服务信息
+ */
@JsonProperty("extra_service")
private OrderProductExtraService extraService;
- /** 是否使用了会员积分抵扣 */
+ /**
+ * 是否使用了会员积分抵扣
+ */
@JsonProperty("use_deduction")
private Boolean useDeduction;
- /** 会员积分抵扣金额,单位为分 */
+ /**
+ * 会员积分抵扣金额,单位为分
+ */
@JsonProperty("deduction_price")
private Integer deductionPrice;
+ /**
+ * 商品优惠券信息,具体结构请参考OrderProductCouponInfo结构体,逐步替换 order.order_detail.coupon_info
+ */
+ @JsonProperty("order_product_coupon_info_list")
+ private List orderProductCouponInfoList;
+
+ /**
+ * 商品发货时效,超时此时间未发货即为发货超时
+ */
+ @JsonProperty("delivery_deadline")
+ private Long deliveryDeadline;
+
+ /**
+ * 商家优惠金额,单位为分
+ */
+ @JsonProperty("merchant_discounted_price")
+ private Integer merchantDiscountedPrice;
+
+ /**
+ * 达人优惠金额,单位为分
+ */
+ @JsonProperty("finder_discounted_price")
+ private Integer finderDiscountedPrice;
+
+ /**
+ * 是否赠品,非必填,赠品商品返回,1:是赠品
+ */
+ @JsonProperty("is_free_gift")
+ private Boolean freeGift;
+
+ /**
+ * 订单内商品维度会员权益优惠金额,单位为分
+ */
+ @JsonProperty("vip_discounted_price")
+ private Integer vipDiscountedPrice;
+
+ /**
+ * 商品常量编号,订单内商品唯一标识,下单后不会发生变化
+ */
+ @JsonProperty("product_unique_id")
+ private String productUniqueId;
+
+ /**
+ * 更换sku信息
+ */
+ @JsonProperty("change_sku_info")
+ private ChangeSkuInfo changeSkuInfo;
+
+ /**
+ * 赠品信息
+ */
+ @JsonProperty("free_gift_info")
+ private FreeGiftInfo freeGiftInfo;
+
+ /**
+ * 订单内商品维度一起买优惠金额,单位为分
+ */
+ @JsonProperty("bulkbuy_discounted_price")
+ private Integer bulkbuyDiscountedPrice;
+
+ /**
+ * 订单内商品维度国补优惠金额,单位为分
+ */
+ @JsonProperty("national_subsidy_discounted_price")
+ private Integer nationalSubsidyDiscountedPrice;
+
+ /**
+ * 代发相关信息
+ */
+ @JsonProperty("dropship_info")
+ private DropshipInfo dropshipInfo;
+
+ /**
+ * 是否闪购商品
+ */
+ @JsonProperty("is_flash_sale")
+ private Boolean flashSale;
+
+ /**
+ * 订单内商品维度地方补贴优惠金额(商家出资),单位为分
+ */
+ @JsonProperty("national_subsidy_merchant_discounted_price")
+ private Integer nationalSubsidyMerchantDiscountedPrice;
+
+ /**
+ * 订单内商品维度活动商家补贴,即参与平台补贴活动时商家通过活动报名价优惠的部分,单位为分
+ */
+ @JsonProperty("platform_activity_merchant_discounted_price")
+ private Integer platformActivityMerchantDiscountedPrice;
+
+ /**
+ * 订单内商品维度平台券优惠金额,单位为分
+ */
+ @JsonProperty("cash_coupon_discounted_price")
+ private Integer cashCouponDiscountedPrice;
+
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderRefundInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderRefundInfo.java
new file mode 100644
index 0000000000..9e3ae522f8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderRefundInfo.java
@@ -0,0 +1,21 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单退款信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderRefundInfo implements Serializable {
+ private static final long serialVersionUID = -7257910073388645919L;
+
+ /** 退还运费金额,礼物订单(is_present=true)可能存在 */
+ @JsonProperty("refund_freight")
+ private Integer refundFreight;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchCondition.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchCondition.java
index 012b0fca49..a4c8373cec 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchCondition.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchCondition.java
@@ -30,12 +30,33 @@ public class OrderSearchCondition implements Serializable {
@JsonProperty("user_name")
private String userName;
- /** 收件人电话 */
+ /**
+ * 收件人电话
+ * @deprecated 当前字段已经废弃,请勿使用,如果原本填手机后四位,可正常使用,否则接口报错
+ */
@JsonProperty("tel_number")
+ @Deprecated
private String telNumber;
+ /**
+ * 收件人电话后四位
+ */
+ @JsonProperty("tel_number_last4")
+ private String telNumberLast4;
+
/** 选填,只搜一个订单时使用 */
@JsonProperty("order_id")
private String orderId;
+ /** 商家备注 */
+ @JsonProperty("merchant_notes")
+ private String merchantNotes;
+
+ /** 买家备注 */
+ @JsonProperty("customer_notes")
+ private String customerNotes;
+
+ /** 申请修改地址审核中 */
+ @JsonProperty("address_under_review")
+ private Boolean addressUnderReview;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchParam.java
index 0a9483e0d5..2f56747d19 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchParam.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSearchParam.java
@@ -25,6 +25,6 @@ public class OrderSearchParam extends StreamPageParam {
private Integer onAfterSaleOrderExist;
/** 订单状态 {@link me.chanjar.weixin.channel.enums.WxOrderStatus} */
- @JsonProperty("on_aftersale_order_exist")
+ @JsonProperty("status")
private Integer status;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSettleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSettleInfo.java
index c264a6289a..bd31931444 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSettleInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSettleInfo.java
@@ -1,7 +1,9 @@
package me.chanjar.weixin.channel.bean.order;
import com.fasterxml.jackson.annotation.JsonProperty;
+
import java.io.Serializable;
+
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -15,12 +17,33 @@
public class OrderSettleInfo implements Serializable {
private static final long serialVersionUID = 2140632631448343656L;
- /** 预计技术服务费(单位为分) */
+ /**
+ * 预计技术服务费(单位为分)
+ */
@JsonProperty("predict_commission_fee")
private Integer predictCommissionFee;
- /** 实际技术服务费(单位为分)(未结算时本字段为空) */
+ /**
+ * 实际技术服务费(单位为分)(未结算时本字段为空)
+ */
@JsonProperty("commission_fee")
private Integer commissionFee;
+ /**
+ * 预计人气卡返佣金额,单位为分(未发起结算时本字段为空)
+ */
+ @JsonProperty("predict_wecoin_commission")
+ private Integer predictWecoinCommission;
+
+ /**
+ * 实际人气卡返佣金额,单位为分(未结算时本字段为空)
+ */
+ @JsonProperty("wecoin_commission")
+ private Integer wecoinCommission;
+
+ /**
+ * 商家结算时间
+ */
+ @JsonProperty("settle_time")
+ private Long settleTime;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSharerInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSharerInfo.java
index be66463445..7ed41d2edf 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSharerInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSharerInfo.java
@@ -1,7 +1,9 @@
package me.chanjar.weixin.channel.bean.order;
import com.fasterxml.jackson.annotation.JsonProperty;
+
import java.io.Serializable;
+
import lombok.Data;
import lombok.NoArgsConstructor;
@@ -15,19 +17,33 @@
public class OrderSharerInfo implements Serializable {
private static final long serialVersionUID = 7183259072254660971L;
- /** 分享员openid */
+ /**
+ * 分享员openid
+ */
@JsonProperty("sharer_openid")
private String sharerOpenid;
- /** 分享员unionid */
+ /**
+ * 分享员unionid
+ */
@JsonProperty("sharer_unionid")
private String sharerUnionid;
- /** 分享员类型,0:普通分享员,1:店铺分享员 */
+ /**
+ * 分享员类型,0:普通分享员,1:店铺分享员
+ */
@JsonProperty("sharer_type")
private Integer sharerType;
- /** 分享场景 {@link me.chanjar.weixin.channel.enums.ShareScene} */
+ /**
+ * 分享场景 {@link me.chanjar.weixin.channel.enums.ShareScene}
+ */
@JsonProperty("share_scene")
private Integer shareScene;
+
+ /**
+ * 分享员数据是否已经解析完成【1:解析完成 0:解析中】
+ */
+ @JsonProperty("handling_progress")
+ private Integer handlingProgress;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSourceInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSourceInfo.java
new file mode 100644
index 0000000000..8d5e5aaef0
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/OrderSourceInfo.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 订单带货来源信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class OrderSourceInfo implements Serializable {
+
+ private static final long serialVersionUID = 3131907659419977296L;
+
+ /**
+ * sku_id
+ */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /**
+ * 带货账号类型,1:视频号,2:公众号,3:小程序,4:企业微信,5:带货达人,6:服务号,1000:带货机构
+ */
+ @JsonProperty("account_type")
+ private Integer accountType;
+
+ /**
+ * 带货账号id,取决于带货账号类型(分别为视频号id、公众号appid、小程序appid、企业微信id、带货达人appid、服务号appid、带货机构id)
+ */
+ @JsonProperty("account_id")
+ private String accountId;
+
+ /**
+ * 账号关联类型,0:关联账号,1:合作账号,2:授权号,100:达人带货,101:带货机构推广
+ */
+ @JsonProperty("sale_channel")
+ private Integer saleChannel;
+
+ /**
+ * 带货账号昵称
+ */
+ @JsonProperty("account_nickname")
+ private String accountNickname;
+
+ /**
+ * 带货内容类型,1:企微成员转发
+ */
+ @JsonProperty("content_type")
+ private String contentType;
+
+ /**
+ * 带货内容id,取决于带货内容类型(企微成员user_id)
+ */
+ @JsonProperty("content_id")
+ private String contentId;
+
+ /**
+ * 自营推客推广的带货机构id
+ */
+ @JsonProperty("promoter_head_supplier_id")
+ private String promoterHeadSupplierId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/QualityInsepctInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/QualityInsepctInfo.java
new file mode 100644
index 0000000000..64c1102bb2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/QualityInsepctInfo.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 质检信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class QualityInsepctInfo implements Serializable {
+
+ private static final long serialVersionUID = 8109819414306253475L;
+
+ /** 质检状态 */
+ @JsonProperty("inspect_status")
+ private Integer inspectStatus;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/RechargeInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/RechargeInfo.java
new file mode 100644
index 0000000000..452dd0677c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/RechargeInfo.java
@@ -0,0 +1,28 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 虚拟商品充值账户信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class RechargeInfo implements Serializable {
+
+ /** 虚拟商品充值账号,当account_type=qq或phone_number或mail的时候返回 */
+ @JsonProperty("account_no")
+ private String accountNo;
+
+ /** 账号充值类型,可选项: weixin(微信号),qq(qq),phone_number(电话号码),mail(邮箱) */
+ @JsonProperty("account_type")
+ private String accountType;
+
+ /** 当account_type="weixin"的时候返回 */
+ @JsonProperty("wx_openid")
+ private String wxOpenId;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/TelNumberExtInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/TelNumberExtInfo.java
new file mode 100644
index 0000000000..1d9e8b7914
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/TelNumberExtInfo.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+
+/**
+ * 联系方式信息
+ *
+ * @author imyzt
+ */
+@Data
+public class TelNumberExtInfo {
+
+ /**
+ * 脱敏手机号
+ */
+ @JsonProperty("real_tel_number")
+ private String realTelNumber;
+
+ /**
+ * 完整的虚拟号码
+ */
+ @JsonProperty("virtual_tel_number")
+ private String virtualTelNumber;
+
+ /**
+ * 主动兑换的虚拟号码过期时间
+ */
+ @JsonProperty("virtual_tel_expire_time")
+ private Long virtualTelExpireTime;
+
+ /**
+ * 主动兑换虚拟号码次数
+ */
+ @JsonProperty("get_virtual_tel_cnt")
+ private Long getVirtualTelCnt;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/VirtualNumberInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/VirtualNumberInfo.java
new file mode 100644
index 0000000000..217908e27c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/VirtualNumberInfo.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 虚拟号信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class VirtualNumberInfo implements Serializable {
+
+ private static final long serialVersionUID = -372834823737476644L;
+
+ /** 虚拟号 */
+ @JsonProperty("virtual_number")
+ private String virtualNumber;
+
+ /** 分机号 */
+ @JsonProperty("extension")
+ private String extension;
+
+ /** 过期时间戳 */
+ @JsonProperty("expiration")
+ private Long expiration;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/VirtualTelNumberResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/VirtualTelNumberResponse.java
new file mode 100644
index 0000000000..92f09b59ab
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/order/VirtualTelNumberResponse.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.order;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 兑换虚拟号 返回结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class VirtualTelNumberResponse extends WxChannelBaseResponse {
+
+ /** 虚拟号码 */
+ @JsonProperty("virtual_tel_number")
+ private String virtualTelNumber;
+
+ /** 虚拟号码过期时间 */
+ @JsonProperty("virtual_tel_expire_time")
+ private Long virtualTelExpireTime;
+
+ /** 兑换虚拟号码次数 */
+ @JsonProperty("get_virtual_tel_cnt")
+ private Integer getVirtualTelCnt;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExtraServiceInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExtraServiceInfo.java
index aeaf1a8cd6..4e9559c565 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExtraServiceInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ExtraServiceInfo.java
@@ -20,4 +20,20 @@ public class ExtraServiceInfo implements Serializable {
*/
@JsonProperty("seven_day_return")
private Integer sevenDayReturn;
+
+ /** 先用后付,0-不支持先用后付,1-支持先用后付。若店铺已开通先用后付,支持先用后付的类目商品将在上架后自动打开先用后付。 */
+ @JsonProperty("pay_after_use")
+ private Integer payAfterUse;
+
+ /** 是否支持运费险,0-不支持运费险,1-支持运费险。需要商户开通运费险服务,且当前类目支持运费险才会生效。 */
+ @JsonProperty("freight_insurance")
+ private Integer freightInsurance;
+
+ /** 是否支持假一赔三,0-不支持假一赔三,1-支持假一赔三。 */
+ @JsonProperty("fake_one_pay_three")
+ private Integer fakeOnePayThree;
+
+ /** 是否支持坏损包退,0-不支持坏损包退,1-支持坏损包退。 */
+ @JsonProperty("damage_guarantee")
+ private Integer damageGuarantee;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductQuaInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductQuaInfo.java
new file mode 100644
index 0000000000..b411ebe80f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductQuaInfo.java
@@ -0,0 +1,29 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品资质信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ProductQuaInfo implements Serializable {
+
+ private static final long serialVersionUID = -71766140204505768L;
+
+ /** 商品资质id,对应获取类目信息中的字段product_qua_list[].qua_id */
+ @JsonProperty("qua_id")
+ private String quaId;
+
+ /** 商品资质图片列表 */
+ @JsonProperty("qua_url")
+ private List quaUrl;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductSaleLimitInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductSaleLimitInfo.java
new file mode 100644
index 0000000000..9c067cc329
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/ProductSaleLimitInfo.java
@@ -0,0 +1,30 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品销售库存限制
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ProductSaleLimitInfo implements Serializable {
+
+ /** 是否受到管控,商品存在售卖限制时,固定返回1 */
+ @JsonProperty("is_limited")
+ private Integer limited;
+
+ /** 售卖限制标题 */
+ @JsonProperty("title")
+ private String title;
+
+ /** 售卖限制描述 */
+ @JsonProperty("sub_title")
+ private String subTitle;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuFastInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuFastInfo.java
new file mode 100644
index 0000000000..b37dfe472c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuFastInfo.java
@@ -0,0 +1,60 @@
+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;
+
+/**
+ * 免审商品更新Sku数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SkuFastInfo implements Serializable {
+
+ /** sku_id */
+ @JsonProperty("sku_id")
+ private String skuId;
+
+ /** 售卖价格,以分为单位,数字类型,最大不超过10000000(1000万元) */
+ @JsonProperty("sale_price")
+ private Integer salePrice;
+
+ @JsonProperty("stock_info")
+ private StockInfo stockInfo;
+
+ /** sku发货信息 */
+ @JsonProperty("sku_deliver_info")
+ private SkuDeliverInfo skuDeliverInfo;
+
+ /** 是否要删除当前sku */
+ @JsonProperty("is_delete")
+ private Boolean delete;
+
+ /** 商品sku编码 */
+ @JsonProperty("sku_code")
+ private String skuCode;
+
+ /** 更新sku状态 0-默认值;5-上架;11-下架 */
+ @JsonProperty("status")
+ private Integer status;
+
+
+ @Data
+ @NoArgsConstructor
+ public static class StockInfo implements Serializable {
+
+ /** 修改类型。1: 增加;2:减少;3:设置 */
+ @JsonProperty("diff_type")
+ protected Integer diffType;
+
+ /** 增加、减少或者设置的库存值 */
+ @JsonProperty("num")
+ protected Integer num;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java
index 3b46708039..956b188c22 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuInfo.java
@@ -54,7 +54,11 @@ public class SkuInfo implements Serializable {
/** skuID */
@JsonProperty("sku_id")
- private Long skuId;
+ private String skuId;
+
+ /** sku条形码 */
+ @JsonProperty("bar_code")
+ private String barCode;
public SkuInfo() {
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchList.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchList.java
new file mode 100644
index 0000000000..71f995692f
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchList.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * spu库存列表
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SkuStockBatchList implements Serializable {
+ private static final long serialVersionUID = -8082428962162052815L;
+
+ /** 库存信息 */
+ @JsonProperty("spu_stock_list")
+ private List spuStockList;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchParam.java
new file mode 100644
index 0000000000..93b5cca798
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchParam.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class SkuStockBatchParam implements Serializable {
+
+ private static final long serialVersionUID = 3706326762056220559L;
+
+ /** 商品ID列表 注意这里是 productId ,序列化参数没有写错 */
+ @JsonProperty("product_id")
+ private List productIds;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchResponse.java
new file mode 100644
index 0000000000..eb188bdc79
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockBatchResponse.java
@@ -0,0 +1,24 @@
+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;
+
+/**
+ * 批量查询sku库存响应
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class SkuStockBatchResponse extends WxChannelBaseResponse {
+
+ private static final long serialVersionUID = 7745444061881828137L;
+
+ /** 库存信息 */
+ @JsonProperty("data")
+ private SkuStockBatchList data;
+ }
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockInfo.java
index a0dccb1329..a480d3249b 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockInfo.java
@@ -29,7 +29,14 @@ public class SkuStockInfo implements Serializable {
@JsonProperty("warehouse_stocks")
private List warehouseStocks;
- /** 库存总量:通用库存数量 + 限时抢购库存数量 + 区域库存总量 */
+ /**
+ * 普通查询:库存总量:通用库存数量 + 限时抢购库存数量 + 区域库存总量
+ * 批量查询:库存总量:通用库存数量 + 限时抢购库存数量 + 区域库存数量 + 达人专属计划营销库存数量
+ */
@JsonProperty("total_stock_num")
private Integer totalStockNum;
+
+ /** 达人专属计划营销库存数量 */
+ @JsonProperty("finder_stock_num")
+ private Integer finderTotalNum;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockResponse.java
index 9cbd6f18c0..683aece146 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockResponse.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SkuStockResponse.java
@@ -1,5 +1,6 @@
package me.chanjar.weixin.channel.bean.product;
+import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@@ -18,5 +19,6 @@ public class SkuStockResponse extends WxChannelBaseResponse {
private static final long serialVersionUID = -2156342792354605826L;
/** 库存信息 */
+ @JsonProperty("data")
private SkuStockInfo data;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuFastInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuFastInfo.java
new file mode 100644
index 0000000000..23b1135ba5
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuFastInfo.java
@@ -0,0 +1,52 @@
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SpuFastInfo implements Serializable {
+
+ /** 商品ID */
+ @JsonProperty("product_id")
+ protected String productId;
+
+ /** SKU列表 */
+ @JsonProperty("skus")
+ protected List skus;
+
+ /** 商品编码 */
+ @JsonProperty("spu_code")
+ protected String spuCode;
+
+ /** 限购信息 */
+ @JsonProperty("limit_info")
+ protected LimitInfo limitInfo;
+
+ /** 运费信息 */
+ @JsonProperty("express_info")
+ protected ExpressInfo expressInfo;
+
+ /** 额外服务 */
+ @JsonProperty("extra_service")
+ protected ExtraServiceInfo extraService;
+
+ /** 发货方式:0-快递发货;1-无需快递,手机号发货;3-无需快递,可选发货账号类型,默认为0,若为无需快递,则无需填写运费模版id */
+ @JsonProperty("deliver_method")
+ private Integer deliverMethod;
+
+ /** 商品待开售信息 */
+ @JsonProperty("timing_onsale_info")
+ private TimingOnSaleInfo timingOnSaleInfo;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuGetResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuGetResponse.java
index b01682802f..ff15cbf0cb 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuGetResponse.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuGetResponse.java
@@ -25,4 +25,8 @@ public class SpuGetResponse extends WxChannelBaseResponse {
/** 商品草稿数据,入参data_type==1时不返回该字段 */
@JsonProperty("edit_product")
private SpuInfo editProduct;
+
+ /** 当日售卖上限提醒,当店铺受到售卖管控时返回,没有返回本字段表示没有无额外限制 */
+ @JsonProperty("sale_limit_info")
+ private ProductSaleLimitInfo saleLimitInfo;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java
index 9db4c50f70..9b2224db94 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuInfo.java
@@ -33,10 +33,18 @@ public class SpuInfo extends SpuSimpleInfo {
@JsonProperty("head_imgs")
private List headImgs;
- /** 发货方式,若为无需快递(仅对部分类目开放),则无需填写运费模版id。0:快递发货;1:无需快递;默认0 */
+ /** 发货方式:0-快递发货;1-无需快递,手机号发货;3-无需快递,可选发货账号类型,默认为0,若为无需快递,则无需填写运费模版id */
@JsonProperty("deliver_method")
private Integer deliverMethod;
+ /**
+ * 发货账号:1-微信openid;2-QQ号;3-手机号;4-邮箱。
+ * 可多选,只有deliver_method=3时,本参数有意义。
+ * 且当发货账号为微信、QQ和邮箱时,需要更新订单接口读取详情字段,详情参考订单接口的说明
+ */
+ @JsonProperty("deliver_acct_type")
+ private List deliverAcctType;
+
/** 商品详情 */
@JsonProperty("desc_info")
private DescriptionInfo descInfo;
@@ -45,6 +53,10 @@ public class SpuInfo extends SpuSimpleInfo {
@JsonProperty("cats")
private List cats;
+ /** 新类目树,商家需要先申请可使用类目 */
+ @JsonProperty("cats_v2")
+ private List catsV2;
+
/** 商品参数 */
@JsonProperty("attrs")
private List attrs;
@@ -107,10 +119,40 @@ public class SpuInfo extends SpuSimpleInfo {
@JsonProperty("product_type")
private Integer productType;
-
/**
* 商品的售后信息
*/
@JsonProperty("after_sale_info")
private AfterSaleInfo afterSaleInfo;
+
+ /**
+ * 当商品类型位福袋抽奖商品(即product_type==2)且该抽奖商品由橱窗的自营商品导入生成时有值,
+ * 表示导入的来源商品id,其他场景下该字段无值或者值为0
+ */
+ @JsonProperty("src_product_id")
+ private String srcProductId;
+
+ /** 商品资质列表 */
+ @JsonProperty("product_qua_infos")
+ private List productQuaInfos;
+
+ /** 尺码表信息 */
+ @JsonProperty("size_chart")
+ private SpuSizeChart sizeChart;
+
+ /** 短标题 */
+ @JsonProperty("short_title")
+ private String shortTitle;
+
+ /** 销量 */
+ @JsonProperty("total_sold_num")
+ private Integer totalSoldNum;
+
+ /** 发布模式,0: 普通模式;1: 极简模式 */
+ @JsonProperty("release_mode")
+ private Integer releaseMode;
+
+ /** 商品待开售信息 */
+ @JsonProperty("timing_onsale_info")
+ private TimingOnSaleInfo timingOnSaleInfo;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSimpleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSimpleInfo.java
index b1ab3febe7..3e84bb1492 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSimpleInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSimpleInfo.java
@@ -15,7 +15,7 @@ public class SpuSimpleInfo implements Serializable {
private static final long serialVersionUID = 5583726432139404883L;
- /** 交易组件平台内部商品ID */
+ /** 商品ID */
@JsonProperty("product_id")
protected String productId;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSizeChart.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSizeChart.java
new file mode 100644
index 0000000000..4e34ccfac8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSizeChart.java
@@ -0,0 +1,27 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 尺码表信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SpuSizeChart implements Serializable {
+
+ private static final long serialVersionUID = -5019617420608575610L;
+
+ /** 是否支持尺码表 */
+ @JsonProperty("enable")
+ private Boolean enable;
+
+ /** 尺码表 */
+ @JsonProperty("specification_list")
+ private List specificationList;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSizeChartItem.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSizeChartItem.java
new file mode 100644
index 0000000000..7ea4d0a66b
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuSizeChartItem.java
@@ -0,0 +1,55 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 尺码表
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SpuSizeChartItem implements Serializable {
+
+ private static final long serialVersionUID = -3757716378584654974L;
+
+ /** 尺码属性名称 */
+ @JsonProperty("name")
+ private String name;
+
+ /** 尺码属性值的单位 */
+ @JsonProperty("unit")
+ private String unit;
+
+ /** 尺码属性值是否为区间 */
+ @JsonProperty("is_range")
+ private Boolean range;
+
+ /** 尺码值与尺码属性值的映射列表 */
+ @JsonProperty("value_list")
+ private List valueList;
+
+ @Data
+ @NoArgsConstructor
+ public static class ValueRange implements Serializable {
+ /** 尺码值 */
+ @JsonProperty("key")
+ private String key;
+
+ /** 尺码属性值;尺码属性值为非区间时返回 */
+ @JsonProperty("value")
+ private String value;
+
+ /** 尺码属性值的左边界;尺码属性值为区间时返回 */
+ @JsonProperty("left")
+ private String left;
+
+ /** 尺码属性值的右边界;尺码属性值为区间时返回 */
+ @JsonProperty("right")
+ private String right;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuStockInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuStockInfo.java
new file mode 100644
index 0000000000..4564f069b8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuStockInfo.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.io.Serializable;
+import java.util.List;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * SPU库存信息
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+public class SpuStockInfo implements Serializable {
+
+ /** 商品ID */
+ @JsonProperty("product_id")
+ protected String productId;
+
+ /** sku库存 */
+ @JsonProperty("sku_stock")
+ private List skuStock;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuUpdateInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuUpdateInfo.java
new file mode 100644
index 0000000000..f6214c5d78
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/SpuUpdateInfo.java
@@ -0,0 +1,24 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 商品更新数据
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SpuUpdateInfo extends SpuInfo {
+
+ /** 添加完成后是否立即上架。1:是;0:否;默认0 */
+ @JsonProperty("listing")
+ private Integer listing;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/TimingOnSaleInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/TimingOnSaleInfo.java
new file mode 100644
index 0000000000..29270d426c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/TimingOnSaleInfo.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.channel.bean.product;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 商品待开售信息
+ *
+ * @author chu
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class TimingOnSaleInfo implements Serializable {
+
+ /** 状态枚举 0-没有待开售;1-待开售 */
+ @JsonProperty("status")
+ private Integer status;
+
+ /** 开售时间,秒级时间戳,0为未配置时间 */
+ @JsonProperty("onsale_time")
+ private Long onSaleTime;
+
+ /** 是否隐藏价格 0-不隐藏;1-隐藏 */
+ @JsonProperty("is_hide_price")
+ private Integer isHidePrice;
+
+ /** 待开售任务ID,可用于请求立即开售 */
+ @JsonProperty("task_id")
+ private Integer taskId;
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/WarehouseStockInfo.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/WarehouseStockInfo.java
index bb239c9492..b0235534bb 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/WarehouseStockInfo.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/WarehouseStockInfo.java
@@ -6,6 +6,8 @@
import lombok.NoArgsConstructor;
/**
+ * 区域库存
+ *
* @author Zeyes
*/
@Data
@@ -21,4 +23,8 @@ public class WarehouseStockInfo implements Serializable {
/** 区域库存数量 */
@JsonProperty("num")
private Integer num;
+
+ /** 区域库存的锁定库存(已下单未支付的库存)数量 */
+ @JsonProperty("lock_stock")
+ private Integer lockStock;
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductH5UrlResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductH5UrlResponse.java
new file mode 100644
index 0000000000..0dee49f165
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductH5UrlResponse.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.product.link;
+
+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 Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ProductH5UrlResponse extends WxChannelBaseResponse {
+
+ /** 商品H5短链 */
+ @JsonProperty("product_h5url")
+ private String productH5url;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductQrCodeResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductQrCodeResponse.java
new file mode 100644
index 0000000000..a6876b78f1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductQrCodeResponse.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.product.link;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品二维码 结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ProductQrCodeResponse extends WxChannelBaseResponse {
+
+ /** 商品二维码 */
+ @JsonProperty("product_qrcode")
+ private String productQrcode;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductTagLinkResponse.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductTagLinkResponse.java
new file mode 100644
index 0000000000..59712130d8
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/product/link/ProductTagLinkResponse.java
@@ -0,0 +1,22 @@
+package me.chanjar.weixin.channel.bean.product.link;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+
+/**
+ * 商品口令 结果
+ *
+ * @author Zeyes
+ */
+@Data
+@NoArgsConstructor
+@EqualsAndHashCode(callSuper = true)
+public class ProductTagLinkResponse extends WxChannelBaseResponse {
+
+ /** 商品口令 */
+ @JsonProperty("product_taglink")
+ private String productTaglink;
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/token/StableToken.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/token/StableTokenParam.java
similarity index 93%
rename from weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/token/StableToken.java
rename to weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/token/StableTokenParam.java
index 72ce83d077..8bcacb649b 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/token/StableToken.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/token/StableTokenParam.java
@@ -17,7 +17,7 @@
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
-public class StableToken implements Serializable {
+public class StableTokenParam implements Serializable {
private static final long serialVersionUID = 6849364823232834171L;
@JsonProperty("grant_type")
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/vip/VipParam.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/vip/VipOpenIdParam.java
similarity index 90%
rename from weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/vip/VipParam.java
rename to weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/vip/VipOpenIdParam.java
index e439641ed9..8f52ded878 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/vip/VipParam.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/bean/vip/VipOpenIdParam.java
@@ -17,7 +17,7 @@
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@AllArgsConstructor
-public class VipParam implements Serializable {
+public class VipOpenIdParam implements Serializable {
private static final long serialVersionUID = -7924178026258012317L;
@JsonProperty("openid")
private String openId;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/common/ChannelWxError.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/common/ChannelWxError.java
index eb8cda4996..705eacc898 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/common/ChannelWxError.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/common/ChannelWxError.java
@@ -7,7 +7,9 @@
* 微信视频号错误码
*
* @author Zeyes
+ * @deprecated 请使用 {@link me.chanjar.weixin.common.error.WxError} 替代
*/
+@Deprecated
public class ChannelWxError extends WxError {
private static final long serialVersionUID = -2638512715814977441L;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/WxChannelConfig.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/WxChannelConfig.java
index ad24234fb0..64344dae58 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/WxChannelConfig.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/WxChannelConfig.java
@@ -19,6 +19,14 @@ public interface WxChannelConfig {
*/
String getAccessToken();
+ /**
+ * Is use stable access token api
+ *
+ * @link 获取稳定版AccessToken
+ * @return the boolean
+ */
+ boolean isStableAccessToken();
+
/**
* Gets access token lock.
*
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelDefaultConfigImpl.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelDefaultConfigImpl.java
index e32bcad83e..1c3930caf5 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelDefaultConfigImpl.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/config/impl/WxChannelDefaultConfigImpl.java
@@ -33,6 +33,8 @@ public class WxChannelDefaultConfigImpl implements WxChannelConfig {
private volatile int httpProxyPort;
private volatile String httpProxyUsername;
private volatile String httpProxyPassword;
+ /** 是否使用稳定版获取accessToken接口 */
+ private volatile boolean stableAccessToken;
private volatile int retrySleepMillis = 1000;
private volatile int maxRetryTimes = 5;
@@ -63,6 +65,15 @@ public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
+ @Override
+ public boolean isStableAccessToken() {
+ return stableAccessToken;
+ }
+
+ public void setStableAccessToken(boolean stableAccessToken) {
+ this.stableAccessToken = stableAccessToken;
+ }
+
@Override
public Lock getAccessTokenLock() {
return this.accessTokenLock;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/MessageEventConstants.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/MessageEventConstants.java
index f1e445513c..675b5d8a57 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/MessageEventConstants.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/constant/MessageEventConstants.java
@@ -16,12 +16,16 @@ public interface MessageEventConstants {
String PRODUCT_SPU_UPDATE = "product_spu_update";
/** 类目审核结果 */
String PRODUCT_CATEGORY_AUDIT = "product_category_audit";
+ /** 库存不足 */
+ String PRODUCT_STOCK_NO_ENOUGH = "channels_ec_stock_no_enough";
/** 订单下单 */
String ORDER_NEW = "channels_ec_order_new";
/** 订单取消 */
String ORDER_CANCEL = "channels_ec_order_cancel";
/** 订单支付成功 */
String ORDER_PAY = "channels_ec_order_pay";
+ /** 订单待发货 */
+ String ORDER_WAIT_SHIPPING = "channels_ec_order_wait_shipping";
/** 订单发货 */
String ORDER_DELIVER = "channels_ec_order_deliver";
/** 订单确认收货 */
@@ -55,6 +59,8 @@ public interface MessageEventConstants {
String USER_COUPON_UNUSE = "channels_ec_user_coupon_unuse";
/** 优惠券核销通知 */
String USER_COUPON_USE = "channels_ec_user_coupon_use";
+ /** 发放团购优惠成功回调 */
+ String VOUCHER_SEND_SUCC = "channels_ec_voucher_send_succ";
// 资金相关
/** 结算账户变更回调 */
String ACCOUNT_NOTIFY = "channels_ec_acct_notify";
@@ -79,4 +85,14 @@ public interface MessageEventConstants {
String USER_VIP_SCORE_UPDATE = "channels_ec_vip_score_update";
/** 用户积分兑换 */
String USER_VIP_SCORE_EXCHANGE = "channels_ec_vip_score_exchange";
+
+ // 分享员相关
+ /** 分享员变更 **/
+ String SHARER_CHANGE = "channels_ec_sharer_change";
+
+ // 店铺相关
+ /** 小店注销 */
+ String CLOSE_STORE = "channels_ec_close_store";
+ /** 小店修改 */
+ String SET_SHOP_NICKNAME = "set_shop_nickname";
}
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 4be90c370b..4859b723fb 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
@@ -53,6 +53,50 @@ public interface Category {
String CANCEL_CATEGORY_AUDIT_URL = "https://api.weixin.qq.com/channels/ec/category/audit/cancel";
/** 获取账号申请通过的类目和资质信息 */
String LIST_PASS_CATEGORY_URL = "https://api.weixin.qq.com/channels/ec/category/list/get";
+ /** 获取店铺的类目权限列表 */
+ String LIST_RELATION_CATEGORY_URL = "https://api.weixin.qq.com/shop/ec/category/get_category_relation_list";
+ }
+
+ /** 主页管理相关接口 */
+ public interface HomePage {
+
+ /** 添加分类关联的商品 */
+ String ADD_TREE_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/store/classification/tree/product/add";
+ /** 删除分类关联的商品 */
+ String DEL_TREE_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/store/classification/tree/product/del";
+ /** 获取分类关联的商品ID列表 */
+ String LIST_TREE_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/store/classification/tree/product/get";
+ /** 设置展示在店铺主页的商品分类 */
+ String SET_SHOW_TREE_URL = "https://api.weixin.qq.com/channels/ec/store/classification/tree/set";
+ /** 获取在店铺主页展示的商品分类 */
+ String GET_SHOW_TREE_URL = "https://api.weixin.qq.com/channels/ec/store/classification/tree/get";
+
+ /** 获取主页展示商品列表 */
+ String LIST_WINDOW_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/store/window/product/list/get";
+ /** 重新排序主页展示商品 */
+ String REORDER_WINDOW_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/store/window/product/reorder";
+ /** 隐藏小店主页商品 */
+ String HIDE_WINDOW_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/store/window/product/hide";
+ /** 置顶小店主页商品 */
+ String TOP_WINDOW_PRODUCT_URL = "https://api.weixin.qq.com/channels/ec/store/window/product/settop";
+
+ /** 提交主页背景图申请 */
+ String APPLY_BACKGROUND_URL = "https://api.weixin.qq.com/channels/ec/basics/homepage/background/apply/submit";
+ /** 查询主页背景图 */
+ String GET_BACKGROUND_URL = "https://api.weixin.qq.com/channels/ec/basics/homepage/background/get";
+ /** 撤销主页背景图申请 */
+ String CANCEL_BACKGROUND_URL = "https://api.weixin.qq.com/channels/ec/basics/homepage/background/apply/cancel";
+ /** 清空主页背景图并撤销流程中的申请 */
+ String REMOVE_BACKGROUND_URL = "https://api.weixin.qq.com/channels/ec/basics/homepage/background/remove";
+
+ /** 提交精选展示位申请 */
+ String APPLY_BANNER_URL = "https://api.weixin.qq.com/channels/ec/basics/homepage/banner/apply/submit";
+ /** 查询精选展示位 */
+ String GET_BANNER_URL = "https://api.weixin.qq.com/channels/ec/basics/homepage/banner/get";
+ /** 撤销精选展示位申请 */
+ String CANCEL_BANNER_URL = "https://api.weixin.qq.com/channels/ec/basics/homepage/banner/apply/cancel";
+ /** 清空精选展示位并撤销流程中的申请 */
+ String REMOVE_BANNER_URL = "https://api.weixin.qq.com/channels/ec/basics/homepage/banner/remove";
}
/** 品牌资质相关接口 */
@@ -89,14 +133,24 @@ public interface Spu {
String SPU_LIST_URL = "https://api.weixin.qq.com/channels/ec/product/list/get";
/** 更新商品 */
String SPU_UPDATE_URL = "https://api.weixin.qq.com/channels/ec/product/update";
+ /** 更新商品 */
+ String SPU_AUDIT_FREE_UPDATE_URL = "https://api.weixin.qq.com/channels/ec/product/auditfree";
/** 上架商品 */
String SPU_LISTING_URL = "https://api.weixin.qq.com/channels/ec/product/listing";
/** 下架商品 */
String SPU_DELISTING_URL = "https://api.weixin.qq.com/channels/ec/product/delisting";
/** 撤回商品审核 */
String CANCEL_AUDIT_URL = "https://api.weixin.qq.com/channels/ec/product/audit/cancel";
+ /** 获取商品H5短链 */
+ String SPU_H5URL_URL = "https://api.weixin.qq.com/channels/ec/product/h5url/get";
+ /** 获取商品二维码 */
+ String SPU_QRCODE_URL = "https://api.weixin.qq.com/channels/ec/product/qrcode/get";
+ /** 获取商品口令 */
+ String SPU_TAGLINK_URL = "https://api.weixin.qq.com/channels/ec/product/taglink/get";
/** 获取实时库存 */
String SPU_GET_STOCK_URL = "https://api.weixin.qq.com/channels/ec/product/stock/get";
+ /** 获取实时库存 */
+ String SPU_GET_STOCK_BATCH_URL = "https://api.weixin.qq.com/channels/ec/product/stock/batchget";
/** 更新商品库存 */
String SPU_UPDATE_STOCK_URL = "https://api.weixin.qq.com/channels/ec/product/stock/update";
/** 添加限时抢购任务 */
@@ -155,6 +209,12 @@ public interface Order {
String REJECT_ADDRESS_MODIFY_URL = "https://api.weixin.qq.com/channels/ec/order/addressmodify/reject";
/** 订单搜索 */
String ORDER_SEARCH_URL = "https://api.weixin.qq.com/channels/ec/order/search";
+ /** 上传生鲜质检信息 */
+ String UPLOAD_FRESH_INSPECT_URL = "https://api.weixin.qq.com/channels/ec/order/freshinspect/submit";
+ /** 兑换虚拟号 */
+ String VIRTUAL_TEL_NUMBER_URL = "https://api.weixin.qq.com/channels/ec/order/virtualtelnumber/get";
+ /** 解码订单包含的敏感数据 */
+ String DECODE_SENSITIVE_INFO_URL = "https://api.weixin.qq.com/channels/ec/order/sensitiveinfo/decode";
}
/** 售后相关接口 */
@@ -170,6 +230,16 @@ public interface AfterSale {
String AFTER_SALE_REJECT_URL = "https://api.weixin.qq.com/channels/ec/aftersale/rejectapply";
/** 上传退款凭证 */
String AFTER_SALE_UPLOAD_URL = "https://api.weixin.qq.com/channels/ec/aftersale/uploadrefundcertificate";
+ /** 获取全量售后原因*/
+ String AFTER_SALE_REASON_GET_URL = "https://api.weixin.qq.com/channels/ec/aftersale/reason/get";
+ /** 获取拒绝售后原因*/
+ String AFTER_SALE_REJECT_REASON_GET_URL = "https://api.weixin.qq.com/channels/ec/aftersale/rejectreason/get";
+ /** 换货发货*/
+ String AFTER_SALE_ACCEPT_EXCHANGE_RESHIP_URL = "https://api.weixin.qq.com/channels/ec/aftersale/acceptexchangereship";
+ /** 换货拒绝发货*/
+ String AFTER_SALE_REJECT_EXCHANGE_RESHIP_URL = "https://api.weixin.qq.com/channels/ec/aftersale/rejectexchangereship";
+ /** 商家协商*/
+ String AFTER_SALE_MERCHANT_UPDATE_URL = "https://api.weixin.qq.com/channels/ec/aftersale/merchantupdateaftersale";
}
/** 纠纷相关接口 */
@@ -185,8 +255,9 @@ public interface Complaint {
/** 物流相关接口 */
public interface Delivery {
-
/** 获取快递公司列表 */
+ String GET_DELIVERY_COMPANY_NEW_URL = "https://api.weixin.qq.com/channels/ec/order/deliverycompanylist/new/get";
+ /** 获取快递公司列表(旧) */
String GET_DELIVERY_COMPANY_URL = "https://api.weixin.qq.com/channels/ec/order/deliverycompanylist/get";
/** 订单发货 */
String DELIVERY_SEND_URL = "https://api.weixin.qq.com/channels/ec/order/delivery/send";
@@ -254,6 +325,20 @@ public interface Share {
String UNBIND_SHARER_URL = "https://api.weixin.qq.com/channels/ec/sharer/unbind";
}
+ /** 合作账号相关接口 */
+ public interface Cooperation {
+ /** 获取合作账号列表 */
+ String LIST_COOPERATION_URL = "https://api.weixin.qq.com/channels/ec/cooperation/list";
+ /** 查看合作账号邀请状态 */
+ String GET_COOPERATION_STATUS_URL = "https://api.weixin.qq.com/channels/ec/cooperation/invitation/get";
+ /** 邀请合作账号 */
+ String GENERATE_QRCODE_COOPERATION_URL = "https://api.weixin.qq.com/channels/ec/cooperation/invitation/qrcode/generate";
+ /** 取消合作账号邀请 */
+ String CANCEL_COOPERATION_URL = "https://api.weixin.qq.com/channels/ec/cooperation/invitation/cancel";
+ /** 解绑合作账号 */
+ String UNBIND_COOPERATION_URL = "https://api.weixin.qq.com/channels/ec/cooperation/unbind";
+ }
+
/** 资金相关接口 */
public interface Fund {
@@ -262,9 +347,9 @@ public interface Fund {
/** 获取结算账户 */
String GET_BANK_ACCOUNT_URL = "https://api.weixin.qq.com/channels/ec/funds/getbankacct";
/** 获取资金流水详情 */
- String GET_BALANCE_FLOW_DETAIL_URL = "https://api.weixin.qq.com/channels/ec/league/funds/getfundsflowdetail";
+ String GET_BALANCE_FLOW_DETAIL_URL = "https://api.weixin.qq.com/channels/ec/funds/getfundsflowdetail";
/** 获取资金流水列表 */
- String GET_BALANCE_FLOW_LIST_URL = "https://api.weixin.qq.com/channels/ec/league/funds/getfundsflowlist";
+ String GET_BALANCE_FLOW_LIST_URL = "https://api.weixin.qq.com/channels/ec/funds/getfundsflowlist";
/** 获取提现记录 */
String GET_WITHDRAW_DETAIL_URL = "https://api.weixin.qq.com/channels/ec/funds/getwithdrawdetail";
/** 获取提现记录列表 */
@@ -424,4 +509,71 @@ public interface Vip {
/** 更新用户等级 */
String GRADE_UPDATE_URL = "https://api.weixin.qq.com/channels/ec/vip/user/grade/update";
}
+
+ /**
+ * 直播大屏数据
+ */
+ public interface LiveDashboard {
+ /**
+ * 获取直播大屏直播列表
+ */
+ String GET_LIVE_LIST_URL = "https://api.weixin.qq.com/channels/livedashboard/getlivelist";
+
+ /**
+ * 获取直播大屏数据
+ */
+ String GET_LIVE_DATA_URL = "https://api.weixin.qq.com/channels/livedashboard/getlivedata";
+ }
+
+ /**
+ * 罗盘达人版API
+ */
+ public interface CompassFinder {
+ /**
+ * 获取电商概览数据
+ */
+ String GET_OVERALL_URL = "https://api.weixin.qq.com/channels/ec/compass/finder/overall/get";
+
+ /**
+ * 获取带货商品数据
+ */
+ String GET_PRODUCT_DATA_URL = "https://api.weixin.qq.com/channels/ec/compass/finder/product/data/get";
+
+ /**
+ * 获取带货商品列表
+ */
+ String GET_PRODUCT_LIST_URL = "https://api.weixin.qq.com/channels/ec/compass/finder/product/list/get";
+
+ /**
+ * 获取带货人群数据
+ */
+ String GET_SALE_PROFILE_DATA_URL = "https://api.weixin.qq.com/channels/ec/compass/finder/sale/profile/data/get";
+ }
+
+ /**
+ * 罗盘商家版API
+ */
+ public interface CompassShop {
+
+ /** 获取电商数据概览 */
+ String GET_SHOP_OVERALL_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/overall/get";
+ /** 获取授权视频号列表 */
+ String FINDER_AUTH_LIST_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/finder/authorization/list/get";
+ /** 获取带货达人列表 */
+ String FINDER_LIST_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/finder/list/get";
+ /** 获取带货数据概览 */
+ String GET_FINDER_OVERALL_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/finder/overall/get";
+ /** 获取带货达人商品列表 */
+ String GET_FINDER_PRODUCT_LIST_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/finder/product/list/get";
+ /** 获取带货达人商品数据 */
+ String GET_FINDER_PRODUCT_OVERALL_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/finder/product/overall/get";
+ /** 获取店铺开播列表 */
+ String GET_LIVE_LIST_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/live/list/get";
+ /** 获取商品详细信息 */
+ String GET_SHOP_PRODUCT_DATA_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/product/data/get";
+ /** 获取商品列表 */
+ String GET_SHOP_PRODUCT_LIST_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/product/list/get";
+ /** 获取店铺人群数据 */
+ String GET_SHOP_SALE_PROFILE_DATA_URL = "https://api.weixin.qq.com/channels/ec/compass/shop/sale/profile/data/get";
+ }
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleStatus.java
index 60e77d9e53..b249c96bcb 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleStatus.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/AfterSaleStatus.java
@@ -39,6 +39,10 @@ public enum AfterSaleStatus {
MERCHANT_REFUND_RETRY_FAIL("MERCHANT_REFUND_RETRY_FAIL", "商家打款失败,客服关闭售后"),
/** 售后关闭 */
MERCHANT_FAIL("MERCHANT_FAIL", "售后关闭"),
+ /** 待用户处理商家协商 */
+ USER_WAIT_CONFIRM_UPDATE("USER_WAIT_CONFIRM_UPDATE", "待用户处理商家协商"),
+ /** 待用户处理商家代发起的售后申请 */
+ USER_WAIT_HANDLE_MERCHANT_AFTER_SALE("USER_WAIT_HANDLE_MERCHANT_AFTER_SALE", "待用户处理商家代发起的售后申请"),
;
private final String key;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/BannerType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/BannerType.java
new file mode 100644
index 0000000000..7cf11eb9ce
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/BannerType.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 展示位类型
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum BannerType {
+
+ /** 1 商品 */
+ PRODUCT(1, "商品"),
+ /** 3 视频号 */
+ CHANNEL(3, "视频号"),
+ /** 4 公众号 */
+ MP(4, "公众号");
+
+ ;
+
+ private final int key;
+ private final String value;
+
+ BannerType(int key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/DimensionType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/DimensionType.java
new file mode 100644
index 0000000000..b713f518ab
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/DimensionType.java
@@ -0,0 +1,80 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号助手 直播数据维度类型
+ *
+ * @author Winnie
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum DimensionType {
+
+ /**
+ * 一级渠道
+ */
+ PRIMARY_CHANNEL(1, "一级渠道"),
+ /**
+ * 年龄段
+ */
+ AGE(2, "年龄段"),
+ /**
+ * 性别
+ */
+ SEX(3, "性别"),
+ /**
+ * 关注关系
+ */
+ FOLLOW(5, "关注关系"),
+ /**
+ * 二级渠道
+ */
+ SECONDARY_CHANNEL(7, "二级渠道"),
+ /**
+ * 策略人群
+ */
+ CATE(9, "策略人群"),
+ /**
+ * 省级行政区
+ */
+ PROVINCE(10, "省级行政区"),
+ /**
+ * 地级行政区
+ */
+ CITY(11, "地级行政区"),
+ /**
+ * 消费者商品类目偏好
+ */
+ ECOM_USER_LEVEL(12, "消费者商品类目偏好"),
+ /**
+ * 客单价区间
+ */
+ GMV_PER_CNT(13, "客单价区间"),
+// /**
+// * 关注关系
+// */
+// FOLLOW(15, "关注关系"),
+ /**
+ * 流量类型(自然流量、直播加热、广告投流)
+ */
+ FLOW(16, "流量类型(自然流量、直播加热、广告投流)"),
+
+ ;
+
+ private final Integer key;
+ private final String value;
+
+ DimensionType(Integer key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Integer getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/EcProfileDataNodeKey.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/EcProfileDataNodeKey.java
new file mode 100644
index 0000000000..2374576557
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/EcProfileDataNodeKey.java
@@ -0,0 +1,64 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号助手 用户群体数据节点键
+ *
+ * @author Winnie
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum EcProfileDataNodeKey {
+
+ /**
+ * 性别分布
+ */
+ SEX("sex_distribution", "性别分布"),
+ /**
+ * 年龄分布
+ */
+ AGE("age_distribution", "年龄分布"),
+ /**
+ * 省份分布
+ */
+ PROVINCE("province_distribution", "省份分布"),
+ /**
+ * 城市分布
+ */
+ CITY("city_distribution", "城市分布"),
+ /**
+ * 关注关系分布
+ */
+ FOLLOW("follow_distribution", "关注关系分布"),
+ /**
+ * 策略人群分布
+ */
+ CATE("cate_distribution", "策略人群分布"),
+ /**
+ * 商品类目偏好分布
+ */
+ ECOM_USER_LEVEL("ecom_user_level_distribution", "商品类目偏好分布"),
+ /**
+ * 平均客单价分布
+ */
+ GMV_PER_CNT("gmv_per_cnt_distribution", "平均客单价分布"),
+
+ ;
+
+ private final String key;
+ private final String value;
+
+ EcProfileDataNodeKey(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/FundsType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/FundsType.java
index ea3f8873ec..125e8c39c7 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/FundsType.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/FundsType.java
@@ -24,12 +24,23 @@ public enum FundsType {
/** 8 运费险分账 */
FREIGHT_SHARE(8, "运费险分账"),
/** 9 联盟平台抽佣 */
- LEAGUE_COMMISSION(9, "联盟平台抽佣"),
- /** 10 小店抽佣 */
- SHOP_COMMISSION(10, "小店抽佣"),
+ LEAGUE_PLAT_COMMISSION(9, "联盟平台抽佣"),
+ /** 10 联盟抽佣 */
+ LEAGUE_COMMISSION(10, "联盟抽佣"),
+ /** 11台抽佣 */
+ PLATFORM_COMMISSION(11, "平台抽佣"),
+ /** 12 团长抽佣 */
+ LEADER_COMMISSION(12, "团长抽佣"),
+ /** 13 返佣人气卡 */
+ POPULARITY_CARD(13, "返佣人气卡"),
+ /** 14 极速退款垫资金 */
+ FAST_REFUND(14, "极速退款垫资金"),
+ /** 15 极速退款垫资回补 */
+ FAST_REFUND_REPLENISHMENT(15, "极速退款垫资回补"),
+ /** 16 运费险 */
+ FREIGHT_INSURANCE(16, "运费险"),
/** 99 分账 */
SHARE(99, "分账"),
-
;
private final int key;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/LiveDistributionFlowType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/LiveDistributionFlowType.java
new file mode 100644
index 0000000000..b086d02c34
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/LiveDistributionFlowType.java
@@ -0,0 +1,56 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号助手 直播分布流量类型
+ *
+ * @author Winnie
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum LiveDistributionFlowType {
+
+ /**
+ * 无效值
+ */
+ INVALID(0, "无效值"),
+ /**
+ * 自然流量
+ */
+ NATURAL(1, "自然流量"),
+ /**
+ * 加热流量
+ */
+ PROMOTE(2, "加热流量"),
+ /**
+ * 广告流量
+ */
+ ADS(3, "广告流量"),
+ /**
+ * 公域流量
+ */
+ COMMON_DOMAIN(4, "公域流量"),
+ /**
+ * 私域流量
+ */
+ PRIVATE_DOMAIN(5, "私域流量"),
+
+ ;
+
+ private final Integer key;
+ private final String value;
+
+ LiveDistributionFlowType(Integer key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Integer getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/LiveDistributionSceneType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/LiveDistributionSceneType.java
new file mode 100644
index 0000000000..46a65f02b4
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/LiveDistributionSceneType.java
@@ -0,0 +1,52 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 视频号助手 直播分布场景类型
+ *
+ * @author Winnie
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum LiveDistributionSceneType {
+
+ /**
+ * 商品曝光
+ */
+ PRODUCT_IMPRESSION(6, "商品曝光"),
+ /**
+ * 直播间曝光次数
+ */
+ LIVE_ROOM_IMPRESSION_PV(7, "直播间曝光次数"),
+ /**
+ * 商品点击次数
+ */
+ PRODUCT_CLICK_PV(8, "商品点击次数"),
+ /**
+ * 创建订单数按渠道统计
+ */
+ CHANNEL_TOTAL_CREATE_PV(9, "创建订单数按渠道统计"),
+ /**
+ * 成交订单数按渠道统计
+ */
+ CHANNEL_TOTAL_PAY_PV(10, "成交订单数按渠道统计"),
+
+ ;
+
+ private final Integer key;
+ private final String value;
+
+ LiveDistributionSceneType(Integer key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Integer getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/OrderScene.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/OrderScene.java
new file mode 100644
index 0000000000..c00f6a8002
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/OrderScene.java
@@ -0,0 +1,52 @@
+package me.chanjar.weixin.channel.enums;
+
+/**
+ * 下单场景
+ *
+ * @author lizhengwu
+ * @description
+ */
+public enum OrderScene {
+ /**
+ * 其他
+ */
+ OTHER(1, "其他"),
+ /**
+ * 直播间下单
+ */
+ LIVE(2, "直播间"),
+ /**
+ * 短视频
+ */
+ VIDEO(3, "短视频"),
+ /**
+ * 商品分享
+ */
+ SHARE(4, "商品分享"),
+ /**
+ * 商品橱窗主页
+ */
+ SHOW_CASE(5, "商品橱窗主页"),
+ /**
+ * 公众号文章商品卡片
+ */
+ ARTICLE_CARD(6, "公众号文章商品卡片"),
+ ;
+
+ private final int key;
+ private final String value;
+
+ OrderScene(int key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PackageAuditItemType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PackageAuditItemType.java
new file mode 100644
index 0000000000..2929b2d381
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PackageAuditItemType.java
@@ -0,0 +1,37 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 商品打包审核项
+ *
+ * @author Zeyes
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum PackageAuditItemType {
+ /** 商品快递单图片url */
+ EXPRESS_PIC("product_express_pic_url", "商品快递单图片url"),
+ /** 商品包装箱图片url */
+ BOX_PIC("product_packaging_box_pic_url", "商品包装箱图片url"),
+ /** 商品开箱图片url */
+ UNBOXING_PIC("product_unboxing_pic_url", "商品开箱图片url"),
+ /** 商品单个细节图片url */
+ DETAIL_PIC("single_product_detail_pic_url", "商品单个细节图片url"),
+ ;
+
+ public final String key;
+ public final String value;
+
+ PackageAuditItemType(String key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PromoteType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PromoteType.java
index fa0bd60913..c1ba1a3561 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PromoteType.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/PromoteType.java
@@ -9,7 +9,14 @@
*/
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum PromoteType {
- PROMOTE_TYPE_SHOP(1, "小店内推广");
+ /** 1 小店内推广 */
+ PROMOTE_TYPE_SHOP(1, "小店内推广"),
+ /** 9 会员券 */
+ MEMBER(9, "会员券"),
+ /** 10 会员开卡礼券 */
+ MEMBER_CARD(10, "会员开卡礼券"),
+
+ ;
private final int key;
private final String val;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/RefundReason.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/RefundReason.java
new file mode 100644
index 0000000000..8a2825c28c
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/RefundReason.java
@@ -0,0 +1,51 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 售后单退款直接原因
+ *
+ * @author lizhengwu
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum RefundReason {
+ /** 1 商家通过店铺管理页或者小助手发起退款 */
+ MERCHANT_INITIATED_REFUND(1, "商家通过店铺管理页或者小助手发起退款"),
+ /** 2 退货退款场景,商家同意买家未上传物流单号情况下确认收货并退款,该场景限于订单无运费险 */
+ MERCHANT_AGREES_NO_TRACKING_REFUND(2, "退货退款场景,商家同意买家未上传物流单号情况下确认收货并退款,该场景限于订单无运费险"),
+ /** 3 商家通过后台api发起退款 */
+ MERCHANT_API_INITIATED_REFUND(3, "商家通过后台api发起退款"),
+ /** 4 未发货售后平台自动同意 */
+ PRE_SHIPMENT_AUTOMATIC_REFUND(4, "未发货售后平台自动同意"),
+ /** 5 平台介入纠纷退款 */
+ PLATFORM_INTERVENED_DISPUTE_REFUND(5, "平台介入纠纷退款"),
+ /** 6 特殊场景下平台强制退款 */
+ PLATFORM_FORCED_REFUND(6, "特殊场景下平台强制退款"),
+ /** 7 退货退款场景,买家同意没有上传物流单号情况下,商家确认收货并退款,该场景限于订单包含运费险,并无法理赔 */
+ BUYER_AGREES_NO_TRACKING_REFUND(7, "退货退款场景,买家同意没有上传物流单号情况下,商家确认收货并退款,该场景限于订单包含运费险,并无法理赔"),
+ /** 8 商家发货超时,平台退款 */
+ LATE_SHIPMENT_PLATFORM_REFUND(8, "商家发货超时,平台退款"),
+ /** 9 商家处理买家售后申请超时,平台自动同意退款 */
+ MERCHANT_OVERDUE_AUTO_REFUND(9, "商家处理买家售后申请超时,平台自动同意退款"),
+ /** 10 用户确认收货超时,平台退款 */
+ BUYER_OVERDUE_AUTO_REFUND(10, "用户确认收货超时,平台退款"),
+ /** 11 商家确认收货超时,平台退款 */
+ MERCHANT_OVERDUE_CONFIRMATION_REFUND(11, "商家确认收货超时,平台退款"),
+ ;
+
+ private final int key;
+ private final String value;
+
+ RefundReason(int key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public int getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SaleProfileUserType.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SaleProfileUserType.java
new file mode 100644
index 0000000000..4bef97641e
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SaleProfileUserType.java
@@ -0,0 +1,56 @@
+package me.chanjar.weixin.channel.enums;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 带货人群用户类型
+ *
+ * @author Winnie
+ */
+@JsonFormat(shape = JsonFormat.Shape.OBJECT)
+public enum SaleProfileUserType {
+
+ /**
+ * 商品曝光用户
+ */
+ PRODUCT_IMPRESSION_USER(1, "商品曝光用户"),
+ /**
+ * 商品点击用户
+ */
+ PRODUCT_CLICK_USER(2, "商品点击用户"),
+ /**
+ * 购买用户
+ */
+ PURCHASING_USER(3, "购买用户"),
+ /**
+ * 首购用户
+ */
+ FIRST_PURCHASE_USER(4, "首购用户"),
+ /**
+ * 复购用户
+ */
+ REPURCHASE_USER(5, "复购用户"),
+ /**
+ * 直播观看用户
+ */
+ LIVE_WATCHER_USER(6, "直播观看用户"),
+
+ ;
+
+ private final Integer key;
+ private final String value;
+
+ SaleProfileUserType(Integer key, String value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public Integer getKey() {
+ return key;
+ }
+
+ public String getValue() {
+ return value;
+ }
+
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SendTime.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SendTime.java
index 85e4d4f0d6..9b5bc6e809 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SendTime.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SendTime.java
@@ -23,7 +23,11 @@ public enum SendTime {
TWENTYFOUR_HOUR("SendTime_TWENTYFOUR_HOUR", "24小时内发货"),
/** 48小时内发货 */
FOUTYEIGHT_HOUR("SendTime_FOUTYEIGHT_HOUR", "48小时内发货"),
- /** 3天内发货 */
+ /**
+ * 3天内发货
+ * @deprecated 已不支持,微信小店发货管理规则调整
+ */
+ @Deprecated
THREE_DAY("SendTime_THREE_DAY", "3天内发货"),
// /** 5天内发货 */
// FIVE_DAY("SendTime_FIVE_DAY", "5天内发货"),
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ShareScene.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ShareScene.java
index b4428dbb24..e2fb09d132 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ShareScene.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/ShareScene.java
@@ -19,7 +19,18 @@ public enum ShareScene {
CHANNEL_HOME(4, "视频号主页"),
/** 5 商品详情页 */
PRODUCT_DETAIL(5, "商品详情页"),
-
+ /** 6 带商品的公众号文章 */
+ MP_ARTICLE(6, "带商品的公众号文章"),
+ /** 7 商品链接 */
+ PRODUCT_LINK(7, "商品链接"),
+ /** 8 商品二维码 */
+ PRODUCT_QR_CODE(8, "商品二维码"),
+ /** 9 商品口令 */
+ PRODUCT_TAG_LINK(9, "商品口令"),
+ /** 12 视频号橱窗链接 */
+ WINDOW_LINK(12, "视频号橱窗链接"),
+ /** 13 视频号橱窗二维码 */
+ WINDOW_QR_CODE(13, "视频号橱窗二维码"),
;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuEditStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuEditStatus.java
index 3d6063b8cf..71c71d5a26 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuEditStatus.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuEditStatus.java
@@ -20,7 +20,13 @@ public enum SpuEditStatus {
/** 4 审核成功 */
SUCCESS(4, "审核成功"),
/** 5 商品信息写入中 */
- WRITING(5, "商品信息写入中");
+ WRITING(5, "商品信息写入中"),
+ /** 7 商品异步提交,上传中(处于该状态的商品调用上架商品接口会返回10020067) */
+ ASYNC_WRITING(7, "商品异步提交,上传中"),
+ /** 8 商品异步提交,上传失败(请重新提交) */
+ ASYNC_FAIL(8, "商品异步提交,上传失败"),
+
+ ;
private final int status;
private final String desc;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuStatus.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuStatus.java
index a74fee6b07..8f88d5ffac 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuStatus.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/SpuStatus.java
@@ -16,10 +16,20 @@ public enum SpuStatus {
UP(5, "上架"),
/** 6 回收站 */
TRASH(6, "回收站"),
+ /** 9 彻底删除,商品无法再进行任何操作 */
+ DELETE(9, "彻底删除"),
/** 11 自主下架 */
DOWN(11, "自主下架"),
/** 13 违规下架/风控系统下架 */
- SYSTEM_DOWN(13, "违规下架");
+ SYSTEM_DOWN(13, "违规下架/风控系统下架"),
+ /** 14 保证金不足下架 */
+ DEPOSIT_INSUFFICIENT(14, "保证金不足下架"),
+ /** 15 品牌过期下架 */
+ BRAND_EXPIRED(15, "品牌过期下架"),
+ /** 20 商品被封禁 */
+ BAN(20, "商品被封禁"),
+
+;
private final int status;
private final String desc;
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxChannelErrorMsgEnum.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxChannelErrorMsgEnum.java
index 4a699c20d0..18e88c0b08 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxChannelErrorMsgEnum.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/enums/WxChannelErrorMsgEnum.java
@@ -8,7 +8,9 @@
* 微信视频号全局返回码
*
* @author Zeyes
+ * @deprecated 请使用 {@link me.chanjar.weixin.common.error.WxChannelErrorMsgEnum} 替代
*/
+@Deprecated
@Getter
public enum WxChannelErrorMsgEnum {
/**
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ApacheHttpChannelFileUploadRequestExecutor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ApacheHttpChannelFileUploadRequestExecutor.java
new file mode 100644
index 0000000000..5ccb6f5cb1
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ApacheHttpChannelFileUploadRequestExecutor.java
@@ -0,0 +1,47 @@
+package me.chanjar.weixin.channel.executor;
+
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.ResponseHandler;
+import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.mime.HttpMultipartMode;
+import org.apache.http.entity.mime.MultipartEntityBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+import java.io.File;
+import java.io.IOException;
+
+public class ApacheHttpChannelFileUploadRequestExecutor extends ChannelFileUploadRequestExecutor {
+ public ApacheHttpChannelFileUploadRequestExecutor(RequestHttp requestHttp) {
+ super(requestHttp);
+ }
+
+ @Override
+ public String execute(String uri, File file, WxType wxType) throws WxErrorException, IOException {
+ HttpPost httpPost = new HttpPost(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpPost.setConfig(config);
+ }
+ if (file != null) {
+ HttpEntity entity = MultipartEntityBuilder
+ .create()
+ .addBinaryBody("media", file)
+ .setMode(HttpMultipartMode.RFC6532)
+ .build();
+ httpPost.setEntity(entity);
+ }
+ return requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);
+ }
+
+ @Override
+ public void execute(String uri, File data, ResponseHandler handler, WxType wxType)
+ throws WxErrorException, IOException {
+ handler.handle(this.execute(uri, data, wxType));
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ApacheHttpChannelMediaDownloadRequestExecutor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ApacheHttpChannelMediaDownloadRequestExecutor.java
new file mode 100644
index 0000000000..b9b44b60e2
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ApacheHttpChannelMediaDownloadRequestExecutor.java
@@ -0,0 +1,90 @@
+package me.chanjar.weixin.channel.executor;
+
+import me.chanjar.weixin.channel.bean.image.ChannelImageResponse;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.ResponseHandler;
+import me.chanjar.weixin.common.util.http.apache.InputStreamResponseHandler;
+import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.Header;
+import org.apache.http.HttpHost;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.entity.ContentType;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ApacheHttpChannelMediaDownloadRequestExecutor extends ChannelMediaDownloadRequestExecutor {
+
+ public ApacheHttpChannelMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
+ super(requestHttp, tmpDirFile);
+ }
+
+ @Override
+ public ChannelImageResponse execute(String uri, String data, WxType wxType) throws WxErrorException, IOException {
+ if (data != null) {
+ if (uri.indexOf('?') == -1) {
+ uri += '?';
+ }
+ uri += uri.endsWith("?") ? data : '&' + data;
+ }
+
+ HttpGet httpGet = new HttpGet(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpGet.setConfig(config);
+ }
+
+ try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet);
+ InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response)) {
+ Header[] contentTypeHeader = response.getHeaders("Content-Type");
+ String contentType = null;
+ if (contentTypeHeader != null && contentTypeHeader.length > 0) {
+ contentType = contentTypeHeader[0].getValue();
+ if (contentType.startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
+ // application/json; encoding=utf-8 下载媒体文件出错
+ String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
+ return JsonUtils.decode(responseContent, ChannelImageResponse.class);
+ }
+ }
+
+ String fileName = this.getFileName(response);
+ if (StringUtils.isBlank(fileName)) {
+ fileName = String.valueOf(System.currentTimeMillis());
+ }
+
+ String baseName = FilenameUtils.getBaseName(fileName);
+ if (StringUtils.isBlank(fileName) || baseName.length() < 3) {
+ baseName = String.valueOf(System.currentTimeMillis());
+ }
+ String extension = FilenameUtils.getExtension(fileName);
+ if (StringUtils.isBlank(extension)) {
+ extension = "unknown";
+ }
+ File file = createTmpFile(inputStream, baseName, extension, tmpDirFile);
+ return new ChannelImageResponse(file, contentType);
+ }
+ }
+
+ private String getFileName(CloseableHttpResponse response) throws WxErrorException {
+ Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
+ if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
+ return createDefaultFileName();
+ }
+ return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
+ }
+
+ @Override
+ public void execute(String uri, String data, ResponseHandler handler, WxType wxType)
+ throws WxErrorException, IOException {
+ handler.handle(this.execute(uri, data, wxType));
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelFileUploadRequestExecutor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelFileUploadRequestExecutor.java
index 576f1c286a..78a6735192 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelFileUploadRequestExecutor.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelFileUploadRequestExecutor.java
@@ -1,66 +1,35 @@
package me.chanjar.weixin.channel.executor;
-
-import java.io.File;
-import java.io.IOException;
-import me.chanjar.weixin.common.enums.WxType;
-import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
-import me.chanjar.weixin.common.util.http.ResponseHandler;
-import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpHost;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.mime.HttpMultipartMode;
-import org.apache.http.entity.mime.MultipartEntityBuilder;
-import org.apache.http.impl.client.CloseableHttpClient;
+
+import java.io.File;
/**
* 视频号小店 图片上传接口 请求的参数是File, 返回的结果是String
*
* @author Zeyes
*/
-public class ChannelFileUploadRequestExecutor implements RequestExecutor {
+public abstract class ChannelFileUploadRequestExecutor implements RequestExecutor {
- protected RequestHttp requestHttp;
+ protected RequestHttp requestHttp;
- public ChannelFileUploadRequestExecutor(RequestHttp requestHttp) {
+ public ChannelFileUploadRequestExecutor(RequestHttp requestHttp) {
this.requestHttp = requestHttp;
}
- @Override
- public String execute(String uri, File file, WxType wxType) throws WxErrorException, IOException {
- HttpPost httpPost = new HttpPost(uri);
- if (requestHttp.getRequestHttpProxy() != null) {
- RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
- httpPost.setConfig(config);
- }
- if (file != null) {
- HttpEntity entity = MultipartEntityBuilder
- .create()
- .addBinaryBody("media", file)
- .setMode(HttpMultipartMode.RFC6532)
- .build();
- httpPost.setEntity(entity);
+ @SuppressWarnings("unchecked")
+ public static RequestExecutor create(RequestHttp, ?> requestHttp) {
+ switch (requestHttp.getRequestType()) {
+ case APACHE_HTTP:
+ return new ApacheHttpChannelFileUploadRequestExecutor(
+ (RequestHttp) requestHttp);
+ case HTTP_COMPONENTS:
+ return new HttpComponentsChannelFileUploadRequestExecutor(
+ (RequestHttp) requestHttp);
+ default:
+ throw new IllegalArgumentException("不支持的http执行器类型:" + requestHttp.getRequestType());
}
- try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) {
- return Utf8ResponseHandler.INSTANCE.handleResponse(response);
- } finally {
- httpPost.releaseConnection();
- }
- }
-
- @Override
- public void execute(String uri, File data, ResponseHandler handler, WxType wxType)
- throws WxErrorException, IOException {
- handler.handle(this.execute(uri, data, wxType));
- }
-
- public static RequestExecutor create(RequestHttp requestHttp) {
- return new ChannelFileUploadRequestExecutor(requestHttp);
}
}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelMediaDownloadRequestExecutor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelMediaDownloadRequestExecutor.java
index 1b81dc6d15..dd4bf0ba89 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelMediaDownloadRequestExecutor.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/ChannelMediaDownloadRequestExecutor.java
@@ -1,6 +1,9 @@
package me.chanjar.weixin.channel.executor;
-import static org.apache.commons.io.FileUtils.openOutputStream;
+import me.chanjar.weixin.channel.bean.image.ChannelImageResponse;
+import me.chanjar.weixin.common.util.http.RequestExecutor;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.IOException;
@@ -9,102 +12,38 @@
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import lombok.extern.slf4j.Slf4j;
-import me.chanjar.weixin.channel.bean.image.ChannelImageResponse;
-import me.chanjar.weixin.channel.util.JsonUtils;
-import me.chanjar.weixin.common.enums.WxType;
-import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.common.util.http.RequestExecutor;
-import me.chanjar.weixin.common.util.http.RequestHttp;
-import me.chanjar.weixin.common.util.http.ResponseHandler;
-import me.chanjar.weixin.common.util.http.apache.InputStreamResponseHandler;
-import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
-import org.apache.commons.io.FilenameUtils;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.http.Header;
-import org.apache.http.HttpHost;
-import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.entity.ContentType;
-import org.apache.http.impl.client.CloseableHttpClient;
+
+import static org.apache.commons.io.FileUtils.openOutputStream;
/**
* 下载媒体文件请求执行器
*
* @author Zeyes
*/
-@Slf4j
-public class ChannelMediaDownloadRequestExecutor implements RequestExecutor {
+public abstract class ChannelMediaDownloadRequestExecutor implements RequestExecutor {
- protected RequestHttp requestHttp;
+ protected RequestHttp requestHttp;
protected File tmpDirFile;
private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\"");
- public ChannelMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
+ public ChannelMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
this.requestHttp = requestHttp;
this.tmpDirFile = tmpDirFile;
}
- @Override
- public ChannelImageResponse execute(String uri, String data, WxType wxType) throws WxErrorException, IOException {
- if (data != null) {
- if (uri.indexOf('?') == -1) {
- uri += '?';
- }
- uri += uri.endsWith("?") ? data : '&' + data;
- }
-
- HttpGet httpGet = new HttpGet(uri);
- if (requestHttp.getRequestHttpProxy() != null) {
- RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
- httpGet.setConfig(config);
+ @SuppressWarnings("unchecked")
+ public static RequestExecutor create(RequestHttp, ?> requestHttp, File tmpDirFile) {
+ switch (requestHttp.getRequestType()) {
+ case APACHE_HTTP:
+ return new ApacheHttpChannelMediaDownloadRequestExecutor(
+ (RequestHttp) requestHttp, tmpDirFile);
+ case HTTP_COMPONENTS:
+ return new HttpComponentsChannelMediaDownloadRequestExecutor(
+ (RequestHttp) requestHttp, tmpDirFile);
+ default:
+ throw new IllegalArgumentException("不支持的http执行器类型:" + requestHttp.getRequestType());
}
-
- try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet);
- InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response)) {
- Header[] contentTypeHeader = response.getHeaders("Content-Type");
- String contentType = null;
- if (contentTypeHeader != null && contentTypeHeader.length > 0) {
- contentType = contentTypeHeader[0].getValue();
- if (contentType.startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
- // application/json; encoding=utf-8 下载媒体文件出错
- String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
- return JsonUtils.decode(responseContent, ChannelImageResponse.class);
- }
- }
-
- String fileName = this.getFileName(response);
- if (StringUtils.isBlank(fileName)) {
- fileName = String.valueOf(System.currentTimeMillis());
- }
-
- String baseName = FilenameUtils.getBaseName(fileName);
- if (StringUtils.isBlank(fileName) || baseName.length() < 3) {
- baseName = String.valueOf(System.currentTimeMillis());
- }
- String extension = FilenameUtils.getExtension(fileName);
- if (StringUtils.isBlank(extension)) {
- extension = "unknown";
- }
- File file = createTmpFile(inputStream, baseName, extension, tmpDirFile);
- ChannelImageResponse result = new ChannelImageResponse(file, contentType);
- return result;
- } finally {
- httpGet.releaseConnection();
- }
- }
-
- @Override
- public void execute(String uri, String data, ResponseHandler handler, WxType wxType)
- throws WxErrorException, IOException {
- handler.handle(this.execute(uri, data, wxType));
- }
-
- public static RequestExecutor create(RequestHttp requestHttp, File tmpDirFile) {
- return new ChannelMediaDownloadRequestExecutor(requestHttp, tmpDirFile);
}
/**
@@ -125,20 +64,12 @@ public static File createTmpFile(InputStream inputStream, String name, String ex
return resultFile;
}
- private String getFileName(CloseableHttpResponse response) throws WxErrorException {
- Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
- if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
- return createDefaultFileName();
- }
- return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
- }
-
- private String createDefaultFileName() {
+ protected String createDefaultFileName() {
return UUID.randomUUID().toString();
}
- private String extractFileNameFromContentString(String content) throws WxErrorException {
- if (content == null || content.length() == 0) {
+ protected String extractFileNameFromContentString(String content) {
+ if (content == null || content.isEmpty()) {
return createDefaultFileName();
}
Matcher m = PATTERN.matcher(content);
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/HttpComponentsChannelFileUploadRequestExecutor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/HttpComponentsChannelFileUploadRequestExecutor.java
new file mode 100644
index 0000000000..3b1e7076a9
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/HttpComponentsChannelFileUploadRequestExecutor.java
@@ -0,0 +1,47 @@
+package me.chanjar.weixin.channel.executor;
+
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.ResponseHandler;
+import me.chanjar.weixin.common.util.http.hc.Utf8ResponseHandler;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
+import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+
+import java.io.File;
+import java.io.IOException;
+
+public class HttpComponentsChannelFileUploadRequestExecutor extends ChannelFileUploadRequestExecutor {
+ public HttpComponentsChannelFileUploadRequestExecutor(RequestHttp requestHttp) {
+ super(requestHttp);
+ }
+
+ @Override
+ public String execute(String uri, File file, WxType wxType) throws WxErrorException, IOException {
+ HttpPost httpPost = new HttpPost(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpPost.setConfig(config);
+ }
+ if (file != null) {
+ HttpEntity entity = MultipartEntityBuilder
+ .create()
+ .addBinaryBody("media", file)
+ .setMode(HttpMultipartMode.EXTENDED)
+ .build();
+ httpPost.setEntity(entity);
+ }
+ return requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);
+ }
+
+ @Override
+ public void execute(String uri, File data, ResponseHandler handler, WxType wxType)
+ throws WxErrorException, IOException {
+ handler.handle(this.execute(uri, data, wxType));
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/HttpComponentsChannelMediaDownloadRequestExecutor.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/HttpComponentsChannelMediaDownloadRequestExecutor.java
new file mode 100644
index 0000000000..95a13f6c86
--- /dev/null
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/executor/HttpComponentsChannelMediaDownloadRequestExecutor.java
@@ -0,0 +1,94 @@
+package me.chanjar.weixin.channel.executor;
+
+import me.chanjar.weixin.channel.bean.image.ChannelImageResponse;
+import me.chanjar.weixin.channel.util.JsonUtils;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.ResponseHandler;
+import me.chanjar.weixin.common.util.http.hc.InputStreamResponseHandler;
+import me.chanjar.weixin.common.util.http.hc.Utf8ResponseHandler;
+import org.apache.commons.io.FilenameUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hc.client5.http.ClientProtocolException;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpException;
+import org.apache.hc.core5.http.HttpHost;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class HttpComponentsChannelMediaDownloadRequestExecutor extends ChannelMediaDownloadRequestExecutor {
+
+ public HttpComponentsChannelMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
+ super(requestHttp, tmpDirFile);
+ }
+
+ @Override
+ public ChannelImageResponse execute(String uri, String data, WxType wxType) throws WxErrorException, IOException {
+ if (data != null) {
+ if (uri.indexOf('?') == -1) {
+ uri += '?';
+ }
+ uri += uri.endsWith("?") ? data : '&' + data;
+ }
+
+ HttpGet httpGet = new HttpGet(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpGet.setConfig(config);
+ }
+
+ try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet);
+ InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response)) {
+ Header[] contentTypeHeader = response.getHeaders("Content-Type");
+ String contentType = null;
+ if (contentTypeHeader != null && contentTypeHeader.length > 0) {
+ contentType = contentTypeHeader[0].getValue();
+ if (contentType.startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
+ // application/json; encoding=utf-8 下载媒体文件出错
+ String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
+ return JsonUtils.decode(responseContent, ChannelImageResponse.class);
+ }
+ }
+
+ String fileName = this.getFileName(response);
+ if (StringUtils.isBlank(fileName)) {
+ fileName = String.valueOf(System.currentTimeMillis());
+ }
+
+ String baseName = FilenameUtils.getBaseName(fileName);
+ if (StringUtils.isBlank(fileName) || baseName.length() < 3) {
+ baseName = String.valueOf(System.currentTimeMillis());
+ }
+ String extension = FilenameUtils.getExtension(fileName);
+ if (StringUtils.isBlank(extension)) {
+ extension = "unknown";
+ }
+ File file = createTmpFile(inputStream, baseName, extension, tmpDirFile);
+ return new ChannelImageResponse(file, contentType);
+ } catch (HttpException httpException) {
+ throw new ClientProtocolException(httpException.getMessage(), httpException);
+ }
+ }
+
+ private String getFileName(CloseableHttpResponse response) throws WxErrorException {
+ Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
+ if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
+ return createDefaultFileName();
+ }
+ return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
+ }
+
+ @Override
+ public void execute(String uri, String data, ResponseHandler handler, WxType wxType)
+ throws WxErrorException, IOException {
+ handler.handle(this.execute(uri, data, wxType));
+ }
+}
diff --git a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouter.java b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouter.java
index 8ccc2c5050..3236e18303 100644
--- a/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouter.java
+++ b/weixin-java-channel/src/main/java/me/chanjar/weixin/channel/message/WxChannelMessageRouter.java
@@ -121,6 +121,7 @@ public Object route(final WxChannelMessage message, final String content, final
final Map context, final WxChannelService service, final WxSessionManager sessionManager) {
// 如果是重复消息,那么就不做处理
if (isMsgDuplicated(message)) {
+ log.info("收到重复消息,{}", content);
return null;
}
@@ -136,7 +137,7 @@ public Object route(final WxChannelMessage message, final String content, final
}
}
- if (matchRules.size() == 0) {
+ if (matchRules.isEmpty()) {
return null;
}
final List> futures = new ArrayList<>();
@@ -156,7 +157,7 @@ public Object route(final WxChannelMessage message, final String content, final
}
}
- if (futures.size() > 0) {
+ if (!futures.isEmpty()) {
this.executorService.submit(() -> {
for (Future> future : futures) {
try {
@@ -178,7 +179,7 @@ public Object route(final WxChannelMessage message, final String content, final
* @param wxMessage 消息
* @return 是否重复
*/
- private boolean isMsgDuplicated(WxChannelMessage wxMessage) {
+ protected boolean isMsgDuplicated(WxChannelMessage wxMessage) {
String messageId = this.generateMessageId(wxMessage);
return this.messageDuplicateChecker.isDuplicate(messageId);
}
@@ -188,7 +189,7 @@ private boolean isMsgDuplicated(WxChannelMessage wxMessage) {
*
* @return 消息id
*/
- private String generateMessageId(WxChannelMessage wxMessage) {
+ protected String generateMessageId(WxChannelMessage wxMessage) {
StringBuilder sb = new StringBuilder();
if (wxMessage.getMsgId() == null) {
sb.append(wxMessage.getCreateTime())
@@ -211,10 +212,10 @@ private String generateMessageId(WxChannelMessage wxMessage) {
*
* @param sessionManager session管理器
* @param message 消息
- * @param sync 是否同步 打印log用
+ * @param async 是否异步 打印log用
*/
- private void sessionEndAccess(WxSessionManager sessionManager, WxChannelMessage message, boolean sync) {
- log.debug("End session access: async={}, sessionId={}", sync, message.getFromUser());
+ private void sessionEndAccess(WxSessionManager sessionManager, WxChannelMessage message, boolean async) {
+ log.debug("End session access: async={}, sessionId={}", async, message.getFromUser());
InternalSession session = ((InternalSessionManager) sessionManager).findSession(message.getFromUser());
if (session != null) {
session.endAccess();
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImplTest.java
index 7e54a9eaae..81122f7a03 100644
--- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImplTest.java
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelAfterSaleServiceImplTest.java
@@ -12,6 +12,8 @@
import me.chanjar.weixin.channel.api.WxChannelService;
import me.chanjar.weixin.channel.bean.after.AfterSaleInfoResponse;
import me.chanjar.weixin.channel.bean.after.AfterSaleListResponse;
+import me.chanjar.weixin.channel.bean.after.AfterSaleReasonResponse;
+import me.chanjar.weixin.channel.bean.after.AfterSaleRejectReasonResponse;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
import me.chanjar.weixin.channel.bean.complaint.ComplaintOrderResponse;
import me.chanjar.weixin.channel.test.ApiTestModule;
@@ -52,8 +54,8 @@ public void testGet() throws WxErrorException {
public void testAccept() throws WxErrorException {
WxChannelAfterSaleService afterSaleService = channelService.getAfterSaleService();
String afterSaleOrderId = "";
- String addressId = "123";
- WxChannelBaseResponse response = afterSaleService.accept(afterSaleOrderId, addressId);
+ String addressId = null;
+ WxChannelBaseResponse response = afterSaleService.accept(afterSaleOrderId, addressId, 2);
assertNotNull(response);
assertTrue(response.isSuccess());
}
@@ -62,8 +64,8 @@ public void testAccept() throws WxErrorException {
public void testReject() throws WxErrorException {
WxChannelAfterSaleService afterSaleService = channelService.getAfterSaleService();
String afterSaleOrderId = "";
- String rejectReason = "123";
- WxChannelBaseResponse response = afterSaleService.reject(afterSaleOrderId, rejectReason);
+ String rejectReason = null;
+ WxChannelBaseResponse response = afterSaleService.reject(afterSaleOrderId, rejectReason,1);
assertNotNull(response);
assertTrue(response.isSuccess());
}
@@ -109,4 +111,21 @@ public void testGetComplaint() throws WxErrorException {
assertNotNull(response);
assertTrue(response.isSuccess());
}
+
+
+ @Test
+ public void testGetAllReason() throws WxErrorException {
+ WxChannelAfterSaleService afterSaleService = channelService.getAfterSaleService();
+ AfterSaleReasonResponse allReason = afterSaleService.getAllReason();
+ assertNotNull(allReason);
+ assertTrue(allReason.isSuccess());
+ }
+
+ @Test
+ public void testGetRejectReason() throws WxErrorException {
+ WxChannelAfterSaleService afterSaleService = channelService.getAfterSaleService();
+ AfterSaleRejectReasonResponse rejectReason = afterSaleService.getRejectReason();
+ assertNotNull(rejectReason);
+ assertTrue(rejectReason.isSuccess());
+ }
}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImplTest.java
index 5673d85439..120e11245a 100644
--- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImplTest.java
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelBasicServiceImplTest.java
@@ -20,6 +20,8 @@
import me.chanjar.weixin.channel.util.JsonUtils;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -29,9 +31,19 @@
@Guice(modules = ApiTestModule.class)
public class WxChannelBasicServiceImplTest {
+ private static final Logger log = LoggerFactory.getLogger(WxChannelBasicServiceImplTest.class);
+
@Inject
private WxChannelService channelService;
+ @Test
+ public void testGetAccessToken() throws WxErrorException {
+ String accessToken = channelService.getAccessToken();
+ assertNotNull(accessToken);
+ log.info("accessToken: \n{}\n\n", accessToken);
+ System.out.println(accessToken);
+ }
+
@Test
public void testGetShopInfo() throws WxErrorException {
WxChannelBasicService basicService = channelService.getBasicService();
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImplTest.java
index 9b1a62ada3..06afde2993 100644
--- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImplTest.java
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCategoryServiceImplTest.java
@@ -4,18 +4,24 @@
import static org.testng.Assert.assertTrue;
import com.google.inject.Inject;
-import java.util.ArrayList;
import java.util.List;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.channel.api.WxChannelCategoryService;
import me.chanjar.weixin.channel.api.WxChannelService;
import me.chanjar.weixin.channel.bean.audit.AuditApplyResponse;
import me.chanjar.weixin.channel.bean.audit.AuditResponse;
+import me.chanjar.weixin.channel.bean.audit.CategoryAuditInfo;
+import me.chanjar.weixin.channel.bean.audit.CategoryAuditRequest;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.category.CategoryAndQualificationList;
import me.chanjar.weixin.channel.bean.category.CategoryDetailResult;
+import me.chanjar.weixin.channel.bean.category.CategoryQualification;
import me.chanjar.weixin.channel.bean.category.CategoryQualificationResponse;
import me.chanjar.weixin.channel.bean.category.PassCategoryResponse;
import me.chanjar.weixin.channel.bean.category.ShopCategory;
+import me.chanjar.weixin.channel.bean.category.ShopCategoryResponse;
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;
@@ -24,6 +30,7 @@
/**
* @author Zeyes
*/
+@Slf4j
@Guice(modules = ApiTestModule.class)
public class WxChannelCategoryServiceImplTest {
@@ -36,21 +43,40 @@ public void testListAllCategory() throws WxErrorException {
CategoryQualificationResponse response = categoryService.listAllCategory();
assertNotNull(response);
assertTrue(response.isSuccess());
- System.out.println(response);
+ //System.out.println(response);
+ // 测试分类:7231 瑜伽服上衣
+ for (CategoryAndQualificationList cat : response.getCatsV2()) {
+ if (cat.getList() == null) {
+ continue;
+ }
+ for (CategoryQualification qua : cat.getList()) {
+ if (qua.getCategory() == null) {
+ log.error("category is null");
+ }
+ if ("7231".equals(qua.getCategory().getId())) {
+ log.info("qua: {}", JsonUtils.encode(qua));
+ }
+ }
+ }
}
@Test
- public void testListAvailableCategory() throws WxErrorException {
+ public void testListAvailableCategories() throws WxErrorException {
WxChannelCategoryService categoryService = channelService.getCategoryService();
- List shopCategories = categoryService.listAvailableCategory("0");
- assertTrue(CollectionUtils.hasElements(shopCategories));
- shopCategories.forEach(System.out::println);
+ ShopCategoryResponse response = categoryService.listAvailableCategories("0");
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ List v1 = response.getCategories();
+ List v2 = response.getCatListV2();
+ assertTrue(CollectionUtils.hasElements(v1) || CollectionUtils.hasElements(v2));
+ v1.forEach(System.out::println);
+ v2.forEach(System.out::println);
}
@Test
public void testGetCategoryDetail() throws WxErrorException {
WxChannelCategoryService categoryService = channelService.getCategoryService();
- CategoryDetailResult categoryDetail = categoryService.getCategoryDetail("1602");
+ CategoryDetailResult categoryDetail = categoryService.getCategoryDetail("7231");
assertNotNull(categoryDetail);
assertTrue(categoryDetail.isSuccess());
System.out.println(categoryDetail);
@@ -58,11 +84,47 @@ public void testGetCategoryDetail() throws WxErrorException {
@Test
public void testAddCategory() throws WxErrorException {
+// WxChannelCategoryService categoryService = channelService.getCategoryService();
+// List certificates = new ArrayList<>();
+// certificates.add(
+// "hWNith8iZSrxfN7W2tXOoWSXYWi1qADRJxwImvQl2DC6wqqJrl4g8i/UEZfd59yiiEKAnqy0WETFrOcGZFcJDfpH2ccmNZddzesR1/OpAC7bbfmEiDFBK2QL7MBjhR2m");
+// AuditApplyResponse response = categoryService.addCategory("1001", "1002", "1005", certificates);
+// assertNotNull(response);
+// assertTrue(response.isSuccess());
+// System.out.println(response);
+ String json = "{\n"
+ + " \"category_info\": {\n"
+ + " \"cats_v2\":[\n"
+ + " {\n"
+ + " \"cat_id\": 6033\n"
+ + " },\n"
+ + " {\n"
+ + " \"cat_id\": 6057\n"
+ + " },\n"
+ + " {\n"
+ + " \"cat_id\": 6091\n"
+ + " },\n"
+ + " {\n"
+ + " \"cat_id\": 6093\n"
+ + " }\n"
+ + " ],\n"
+ + " \"certificate\": [\n"
+ + " \"THE_FILE_ID_1\",\n"
+ + " \"THE_FILE_ID_2\"\n"
+ + " ],\n"
+ + " \"brand_list\" : [\n"
+ + " { \"brand_id\": 1001 },\n"
+ + " { \"brand_id\": 1002 }\n"
+ + " ]\n"
+ + " }\n"
+ + "}";
+ CategoryAuditRequest param = JsonUtils.decode(json, CategoryAuditRequest.class);
+ CategoryAuditInfo info = null;
+ if (info != null) {
+ info = param.getCategoryInfo();
+ }
WxChannelCategoryService categoryService = channelService.getCategoryService();
- List certificates = new ArrayList<>();
- certificates.add(
- "hWNith8iZSrxfN7W2tXOoWSXYWi1qADRJxwImvQl2DC6wqqJrl4g8i/UEZfd59yiiEKAnqy0WETFrOcGZFcJDfpH2ccmNZddzesR1/OpAC7bbfmEiDFBK2QL7MBjhR2m");
- AuditApplyResponse response = categoryService.addCategory("1001", "1002", "1005", certificates);
+ AuditApplyResponse response = categoryService.addCategory(info);
assertNotNull(response);
assertTrue(response.isSuccess());
System.out.println(response);
@@ -96,4 +158,14 @@ public void testListPassCategory() throws WxErrorException {
assertTrue(response.isSuccess());
System.out.println(response);
}
+
+ @Test
+ public void testListRelationCategory() throws WxErrorException {
+ WxChannelCategoryService categoryService = channelService.getCategoryService();
+ me.chanjar.weixin.channel.bean.category.RelationCategoryResponse response =
+ categoryService.listRelationCategory(true, 1);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(response);
+ }
}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassFinderServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassFinderServiceImplTest.java
new file mode 100644
index 0000000000..be178ba947
--- /dev/null
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassFinderServiceImplTest.java
@@ -0,0 +1,66 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import com.google.inject.Inject;
+import me.chanjar.weixin.channel.api.WxChannelCompassFinderService;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.bean.compass.finder.OverallResponse;
+import me.chanjar.weixin.channel.bean.compass.finder.ProductDataResponse;
+import me.chanjar.weixin.channel.bean.compass.finder.ProductListResponse;
+import me.chanjar.weixin.channel.bean.compass.finder.SaleProfileDataResponse;
+import me.chanjar.weixin.channel.enums.SaleProfileUserType;
+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 static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @author Winnie
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxChannelCompassFinderServiceImplTest {
+
+ @Inject
+ private WxChannelService channelService;
+
+ @Test
+ public void testGetOverAll() throws WxErrorException {
+ WxChannelCompassFinderService compassFinderService = channelService.getCompassFinderService();
+ String ds = "20240630";
+ OverallResponse response = compassFinderService.getOverall(ds);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetProductData() throws WxErrorException {
+ WxChannelCompassFinderService compassFinderService = channelService.getCompassFinderService();
+ String ds = "20240630";
+ String productId = "10000017457793";
+ ProductDataResponse response = compassFinderService.getProductData(ds, productId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetProductList() throws WxErrorException {
+ WxChannelCompassFinderService compassFinderService = channelService.getCompassFinderService();
+ String ds = "20240630";
+ ProductListResponse response = compassFinderService.getProductList(ds);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetSaleProfileData() throws WxErrorException {
+ WxChannelCompassFinderService compassFinderService = channelService.getCompassFinderService();
+ String ds = "20240630";
+ Integer type = SaleProfileUserType.PRODUCT_IMPRESSION_USER.getKey();
+ SaleProfileDataResponse response = compassFinderService.getSaleProfileData(ds, type);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassShopServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassShopServiceImplTest.java
new file mode 100644
index 0000000000..cae4d23067
--- /dev/null
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelCompassShopServiceImplTest.java
@@ -0,0 +1,125 @@
+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.WxChannelCompassShopService;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderAuthListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderProductListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.FinderProductOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopLiveListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopOverallResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopProductDataResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopProductListResponse;
+import me.chanjar.weixin.channel.bean.compass.shop.ShopSaleProfileDataResponse;
+import me.chanjar.weixin.channel.test.ApiTestModule;
+import me.chanjar.weixin.common.error.WxErrorException;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+/**
+ * @author Zeyes
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxChannelCompassShopServiceImplTest {
+
+ @Inject
+ private WxChannelService channelService;
+
+ @Test
+ public void testGetShopOverall() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "20240306";
+ ShopOverallResponse response = service.getShopOverall(ds);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetFinderAuthorizationList() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ FinderAuthListResponse response = service.getFinderAuthorizationList();
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetFinderList() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "20240306";
+ FinderListResponse response = service.getFinderList(ds);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetFinderOverall() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "20240306";
+ FinderOverallResponse response = service.getFinderOverall(ds);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetFinderProductList() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "";
+ String finderId = "";
+ FinderProductListResponse response = service.getFinderProductList(ds, finderId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetFinderProductOverall() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "";
+ String finderId = "";
+ FinderProductOverallResponse response = service.getFinderProductOverall(ds, finderId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetShopLiveList() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "";
+ String finderId = "";
+ ShopLiveListResponse response = service.getShopLiveList(ds, finderId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetShopProductData() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "20240306";
+ String productId = "";
+ ShopProductDataResponse response = service.getShopProductData(ds, productId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetShopProductList() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "20240306";
+ ShopProductListResponse response = service.getShopProductList(ds);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetShopSaleProfileData() throws WxErrorException {
+ WxChannelCompassShopService service = channelService.getCompassShopService();
+ String ds = "20240306";
+ ShopSaleProfileDataResponse response = service.getShopSaleProfileData(ds, 3);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelLiveDashboardServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelLiveDashboardServiceImplTest.java
new file mode 100644
index 0000000000..ec2e161da1
--- /dev/null
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelLiveDashboardServiceImplTest.java
@@ -0,0 +1,44 @@
+package me.chanjar.weixin.channel.api.impl;
+
+import com.google.inject.Inject;
+import me.chanjar.weixin.channel.api.WxChannelLiveDashboardService;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.bean.live.dashboard.LiveDataResponse;
+import me.chanjar.weixin.channel.bean.live.dashboard.LiveListResponse;
+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 static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @author Winnie
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxChannelLiveDashboardServiceImplTest {
+
+ @Inject
+ private WxChannelService channelService;
+
+ @Test
+ public void testGetLiveList() throws WxErrorException {
+ WxChannelLiveDashboardService liveDashboardService = channelService.getLiveDashboardService();
+ // yyyyMMdd
+ Long ds = 20240630L;
+ LiveListResponse response = liveDashboardService.getLiveList(ds);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetLiveData() throws WxErrorException {
+ WxChannelLiveDashboardService liveDashboardService = channelService.getLiveDashboardService();
+ String exportId = "export/UzFf*****************************************************************************************64V";
+ LiveDataResponse response = liveDashboardService.getLiveData(exportId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImplTest.java
index 2eb14b062e..2c70c7bde8 100644
--- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImplTest.java
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelOrderServiceImplTest.java
@@ -12,13 +12,17 @@
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
import me.chanjar.weixin.channel.bean.delivery.DeliveryCompanyResponse;
import me.chanjar.weixin.channel.bean.delivery.DeliveryInfo;
+import me.chanjar.weixin.channel.bean.delivery.PackageAuditInfo;
import me.chanjar.weixin.channel.bean.order.ChangeOrderInfo;
+import me.chanjar.weixin.channel.bean.order.DecodeSensitiveInfoResponse;
import me.chanjar.weixin.channel.bean.order.DeliveryUpdateParam;
import me.chanjar.weixin.channel.bean.order.OrderAddressInfo;
import me.chanjar.weixin.channel.bean.order.OrderInfoResponse;
import me.chanjar.weixin.channel.bean.order.OrderListParam;
import me.chanjar.weixin.channel.bean.order.OrderListResponse;
+import me.chanjar.weixin.channel.bean.order.OrderSearchCondition;
import me.chanjar.weixin.channel.bean.order.OrderSearchParam;
+import me.chanjar.weixin.channel.bean.order.VirtualTelNumberResponse;
import me.chanjar.weixin.channel.test.ApiTestModule;
import me.chanjar.weixin.common.error.WxErrorException;
import org.testng.annotations.Guice;
@@ -42,6 +46,16 @@ public void testGetOrder() throws WxErrorException {
assertTrue(response.isSuccess());
}
+ @Test
+ public void testGetOrder2() throws WxErrorException {
+ WxChannelOrderService orderService = channelService.getOrderService();
+ String orderId = "";
+ boolean encodeSensitiveInfo = true;
+ OrderInfoResponse response = orderService.getOrder(orderId, encodeSensitiveInfo);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
@Test
public void testGetOrders() throws WxErrorException {
WxChannelOrderService orderService = channelService.getOrderService();
@@ -55,6 +69,10 @@ public void testGetOrders() throws WxErrorException {
public void testSearchOrder() throws WxErrorException {
WxChannelOrderService orderService = channelService.getOrderService();
OrderSearchParam param = new OrderSearchParam();
+ param.setPageSize(100);
+ OrderSearchCondition searchCondition = new OrderSearchCondition();
+ searchCondition.setTitle("");
+ param.setSearchCondition(searchCondition);
OrderListResponse response = orderService.searchOrder(param);
assertNotNull(response);
assertTrue(response.isSuccess());
@@ -132,7 +150,7 @@ public void testCloseOrder() {
@Test
public void testListDeliveryCompany() throws WxErrorException {
WxChannelOrderService orderService = channelService.getOrderService();
- DeliveryCompanyResponse response = orderService.listDeliveryCompany();
+ DeliveryCompanyResponse response = orderService.listDeliveryCompany(false);
assertNotNull(response);
assertTrue(response.isSuccess());
}
@@ -148,4 +166,36 @@ public void testDeliveryOrder() throws WxErrorException {
assertNotNull(response);
assertTrue(response.isSuccess());
}
+
+ @Test
+ public void testUploadFreshInspect() throws WxErrorException {
+ WxChannelOrderService orderService = channelService.getOrderService();
+ String orderId = "123";
+ List items = new ArrayList<>();
+ items.add(new PackageAuditInfo("product_express_pic_url", "https://store.mp.video.tencent-cloud.com/x"));
+ items.add(new PackageAuditInfo("product_packaging_box_panoramic_video_url", "https://store.mp.video.tencent-cloud.com/y"));
+ items.add(new PackageAuditInfo("product_unboxing_panoramic_video_url", "https://store.mp.video.tencent-cloud.com/z"));
+ items.add(new PackageAuditInfo("single_product_detail_panoramic_video_url", "https://store.mp.video.tencent-cloud.com/a"));
+ WxChannelBaseResponse response = orderService.uploadFreshInspect(orderId, items);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetVirtualTelNumber() throws WxErrorException {
+ WxChannelOrderService orderService = channelService.getOrderService();
+ String orderId = "123";
+ VirtualTelNumberResponse response = orderService.getVirtualTelNumber(orderId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testDecodeSensitiveInfo() throws WxErrorException {
+ WxChannelOrderService orderService = channelService.getOrderService();
+ String orderId = "123";
+ DecodeSensitiveInfoResponse response = orderService.decodeSensitiveInfo(orderId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImplTest.java
index b14bc9b3fc..ed83434ee0 100644
--- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImplTest.java
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelProductServiceImplTest.java
@@ -4,17 +4,23 @@
import static org.testng.Assert.assertTrue;
import com.google.inject.Inject;
+import java.util.ArrayList;
+import java.util.List;
import me.chanjar.weixin.channel.api.WxChannelProductService;
import me.chanjar.weixin.channel.api.WxChannelService;
import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
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.product.SkuStockBatchResponse;
import me.chanjar.weixin.channel.bean.product.SkuStockResponse;
import me.chanjar.weixin.channel.bean.product.SpuGetResponse;
-import me.chanjar.weixin.channel.bean.product.SpuInfo;
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.link.ProductH5UrlResponse;
+import me.chanjar.weixin.channel.bean.product.link.ProductQrCodeResponse;
+import me.chanjar.weixin.channel.bean.product.link.ProductTagLinkResponse;
import me.chanjar.weixin.channel.test.ApiTestModule;
import me.chanjar.weixin.common.error.WxErrorException;
import org.testng.annotations.Guice;
@@ -32,7 +38,7 @@ public class WxChannelProductServiceImplTest {
@Test
public void testAddProduct() throws WxErrorException {
WxChannelProductService productService = channelService.getProductService();
- SpuInfo spuInfo = new SpuInfo();
+ SpuUpdateInfo spuInfo = new SpuUpdateInfo();
// ...
SpuUpdateResponse response = productService.addProduct(spuInfo);
assertNotNull(response);
@@ -42,7 +48,7 @@ public void testAddProduct() throws WxErrorException {
@Test
public void testUpdateProduct() throws WxErrorException {
WxChannelProductService productService = channelService.getProductService();
- SpuInfo spuInfo = new SpuInfo();
+ SpuUpdateInfo spuInfo = new SpuUpdateInfo();
// ...
SpuUpdateResponse response = productService.updateProduct(spuInfo);
assertNotNull(response);
@@ -121,13 +127,53 @@ public void testDownProduct() throws WxErrorException {
@Test
public void testGetSkuStock() throws WxErrorException {
WxChannelProductService productService = channelService.getProductService();
- String productId = "";
- String skuId = "";
+ String productId = "10000076089602";
+ String skuId = "1918289111";
SkuStockResponse response = productService.getSkuStock(productId, skuId);
assertNotNull(response);
assertTrue(response.isSuccess());
}
+ @Test
+ public void testGetSkuStockBatch() throws WxErrorException {
+ WxChannelProductService productService = channelService.getProductService();
+ List productIds = new ArrayList<>();
+ productIds.add("123");
+ SkuStockBatchResponse response = productService.getSkuStockBatch(productIds);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGetProductH5Url() throws WxErrorException {
+ WxChannelProductService productService = channelService.getProductService();
+ String productId = "";
+ ProductH5UrlResponse response = productService.getProductH5Url(productId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(response.getProductH5url());
+ }
+
+ @Test
+ public void testGetProductQrCode() throws WxErrorException {
+ WxChannelProductService productService = channelService.getProductService();
+ String productId = "";
+ ProductQrCodeResponse response = productService.getProductQrCode(productId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(response.getProductQrcode());
+ }
+
+ @Test
+ public void testGetProductTagLink() throws WxErrorException {
+ WxChannelProductService productService = channelService.getProductService();
+ String productId = "";
+ ProductTagLinkResponse response = productService.getProductTagLink(productId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(response.getProductTaglink());
+ }
+
@Test
public void testAddLimitTask() throws WxErrorException {
WxChannelProductService productService = channelService.getProductService();
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelVipServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelVipServiceImplTest.java
new file mode 100644
index 0000000000..fdcf599e90
--- /dev/null
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxChannelVipServiceImplTest.java
@@ -0,0 +1,32 @@
+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.WxChannelService;
+import me.chanjar.weixin.channel.bean.vip.VipInfoResponse;
+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 Zeyes
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxChannelVipServiceImplTest {
+ @Inject
+ private WxChannelService channelService;
+
+ @Test
+ public void getVipInfo() throws WxErrorException {
+ String openId = "";
+ Boolean needPhoneNumber = false;
+ VipInfoResponse response = channelService.getVipService().getVipInfo(openId, needPhoneNumber);
+ System.out.println(JsonUtils.encode(response));
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxStoreCooperationServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxStoreCooperationServiceImplTest.java
new file mode 100644
index 0000000000..bf70ce3c78
--- /dev/null
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxStoreCooperationServiceImplTest.java
@@ -0,0 +1,66 @@
+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.WxChannelService;
+import me.chanjar.weixin.channel.api.WxStoreCooperationService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+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 Zeyes
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxStoreCooperationServiceImplTest {
+
+ @Inject
+ private WxChannelService channelService;
+
+ @Test
+ public void testListCooperation() throws WxErrorException {
+ WxStoreCooperationService service = channelService.getCooperationService();
+ Integer sharerType = 3;
+ WxChannelBaseResponse response = service.listCooperation(sharerType);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testGetCooperationStatus() throws WxErrorException {
+ WxStoreCooperationService service = channelService.getCooperationService();
+ WxChannelBaseResponse response = service.getCooperationStatus("sph3FZbOEY64mWQ", 2);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testGenerateQrCode() throws WxErrorException {
+ WxStoreCooperationService service = channelService.getCooperationService();
+ WxChannelBaseResponse response = service.generateQrCode("sph3FZbOEY64mWQ", 2);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testCancelInvitation() throws WxErrorException {
+ WxStoreCooperationService service = channelService.getCooperationService();
+ WxChannelBaseResponse response = service.cancelInvitation("sph3FZbOEY64mWQ", 2);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+
+ @Test
+ public void testUnbind() throws WxErrorException {
+ WxStoreCooperationService service = channelService.getCooperationService();
+ WxChannelBaseResponse response = service.unbind("sph3FZbOEY64mWQ", 2);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ }
+}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxStoreHomePageServiceImplTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxStoreHomePageServiceImplTest.java
new file mode 100644
index 0000000000..0d6bb8c479
--- /dev/null
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/api/impl/WxStoreHomePageServiceImplTest.java
@@ -0,0 +1,339 @@
+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.WxStoreHomePageService;
+import me.chanjar.weixin.channel.api.WxChannelService;
+import me.chanjar.weixin.channel.bean.base.WxChannelBaseResponse;
+import me.chanjar.weixin.channel.bean.home.background.BackgroundApplyResponse;
+import me.chanjar.weixin.channel.bean.home.background.BackgroundGetResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerApplyParam;
+import me.chanjar.weixin.channel.bean.home.banner.BannerApplyResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerGetResponse;
+import me.chanjar.weixin.channel.bean.home.banner.BannerInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductEditInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductEditParam;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductListInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeProductListResponse;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowGetResponse;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowInfo;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowParam;
+import me.chanjar.weixin.channel.bean.home.tree.TreeShowSetResponse;
+import me.chanjar.weixin.channel.bean.home.window.WindowProductSettingResponse;
+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 Zeyes
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxStoreHomePageServiceImplTest {
+
+ @Inject
+ private WxChannelService channelService;
+
+ @Test
+ public void testAddTreeProduct() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ // https://developers.weixin.qq.com/doc/store/API/homepage/classification/addclassificationproduct.html
+ String json = "{\n"
+ + " \"req\": {\n"
+ + " \"level_1_id\": 10000046,\n"
+ + " \"level_2_id\": 10000048,\n"
+ + " \"product_ids\": [\n"
+ + " 10000076089602\n"
+ + " ]\n"
+ + " }\n"
+ + "}";
+ TreeProductEditParam param = JsonUtils.decode(json, TreeProductEditParam.class);
+ TreeProductEditInfo info = null;
+ if (param != null) {
+ info = param.getReq();
+ }
+ WxChannelBaseResponse response = service.addTreeProduct(info);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ assertNotNull(info);
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testDelTreeProduct() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ String json = "{\n"
+ + " \"req\": {\n"
+ + " \"level_1_id\": 1,\n"
+ + " \"level_2_id\": 0,\n"
+ + " \"product_ids\": [\n"
+ + " 123\n"
+ + " ]\n"
+ + " }\n"
+ + "}";
+ TreeProductEditParam param = JsonUtils.decode(json, TreeProductEditParam.class);
+ TreeProductEditInfo info = null;
+ if (param != null) {
+ info = param.getReq();
+ }
+ WxChannelBaseResponse response = service.delTreeProduct(info);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ assertNotNull(info);
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testGetTreeProductList() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ String pageContext = "";
+ TreeProductListInfo info = new TreeProductListInfo();
+ info.setLevel1Id(1);
+ info.setLevel2Id(2);
+ info.setPageSize(10);
+ info.setPageContext(pageContext);
+ TreeProductListResponse response = service.getTreeProductList(info);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ assertNotNull(info);
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testSetShowTree() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ // https://developers.weixin.qq.com/doc/store/API/homepage/classification/setclassificationtree.html
+ String json = "{\n"
+ + " \"req\": {\n"
+ + " \"version\": 121,\n"
+ + " \"classification_id_deleted\": [\n"
+ + " \"1.2\"\n"
+ + " ],\n"
+ + " \"tree\": {\n"
+ + " \"level_1\": [\n"
+ + " {\n"
+ + " \"id\": 4,\n"
+ + " \"name\": \"测试7\",\n"
+ + " \"level_2\": [\n"
+ + " {\n"
+ + " \"id\": 5,\n"
+ + " \"name\": \"1\",\n"
+ + " \"is_displayed\": 1\n"
+ + " }\n"
+ + " ],\n"
+ + " \"is_displayed\": 1\n"
+ + " },\n"
+ + " {\n"
+ + " \"id\": 6,\n"
+ + " \"name\": \"测试8\",\n"
+ + " \"level_2\": [\n"
+ + " {\n"
+ + " \"id\": 7,\n"
+ + " \"name\": \"1\",\n"
+ + " \"is_displayed\": 1\n"
+ + " },\n"
+ + " {\n"
+ + " \"id\": 8,\n"
+ + " \"name\": \"2\",\n"
+ + " \"is_displayed\": 1\n"
+ + " }\n"
+ + " ],\n"
+ + " \"is_displayed\": 1\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + " }\n"
+ + "}";
+ TreeShowParam param = JsonUtils.decode(json, TreeShowParam.class);
+ TreeShowInfo info = null;
+ if (param != null) {
+ info = param.getReq();
+ }
+ TreeShowSetResponse response = service.setShowTree(info);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ assertNotNull(info);
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testGetShowTree() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ TreeShowGetResponse response = service.getShowTree();
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testListWindowProduct() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ Integer pageSize = 1;
+ String nextKey = "";
+ WindowProductSettingResponse response = service.listWindowProduct(pageSize, nextKey);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testReorderWindowProduct() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ String productId = "";
+ Integer indexNum = 100;
+ WxChannelBaseResponse response = service.reorderWindowProduct(productId, indexNum);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testHideWindowProduct() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ String productId = "";
+ // 0:显示 1:隐藏
+ Integer setHide = 0;
+ WxChannelBaseResponse response = service.hideWindowProduct(productId, setHide);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testTopWindowProduct() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ String productId = "";
+ // 0:取消置顶 1:置顶
+ Integer setTop = 0;
+ WxChannelBaseResponse response = service.topWindowProduct(productId, setTop);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testApplyBackground() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ String imgUrl = "https://github.githubassets.com/images/icons/emoji/octocat.png";
+ BackgroundApplyResponse response = service.applyBackground(imgUrl);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testGetBackground() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ BackgroundGetResponse response = service.getBackground();
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testCancelBackground() throws WxErrorException {
+ Integer applyId = 1;
+ WxStoreHomePageService service = channelService.getHomePageService();
+ WxChannelBaseResponse response = service.cancelBackground(applyId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testRemoveBackground() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ WxChannelBaseResponse response = service.removeBackground();
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testApplyBanner() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ // https://developers.weixin.qq.com/doc/store/API/homepage/banner/submit_banner_apply.html
+ String json = "{\n"
+ + " \"banner\": {\n"
+ + " \"scale\": 2,\n"
+ + " \"banner\": [\n"
+ + " {\n"
+ + " \"type\": 1,\n"
+ + " \"product\": {\n"
+ + " \"product_id\": 123\n"
+ + " },\n"
+ + " \"banner\": {\n"
+ + " \"description\": \"测试商品精品展示位描述\",\n"
+ + " \"img_url\": \"https://store.mp.video.tencent-cloud.com/abc\",\n"
+ + " \"title\": \"测试商品精品展示位标题\"\n"
+ + " }\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": 3,\n"
+ + " \"finder\": {\n"
+ + " \"feed_id\": \"export/abc\",\n"
+ + " \"finder_user_name\": \"sphabc\"\n"
+ + " },\n"
+ + " \"banner\": {\n"
+ + " \"description\": \"测试视频号视频精品展示位描述\",\n"
+ + " \"img_url\": \"https://store.mp.video.tencent-cloud.com/abc\",\n"
+ + " \"title\": \"测试视频号视频精品展示位标题\"\n"
+ + " }\n"
+ + " },\n"
+ + " {\n"
+ + " \"type\": 4,\n"
+ + " \"official_account\": {\n"
+ + " \"url\": \"https://mp.weixin.qq.com/abc\"\n"
+ + " },\n"
+ + " \"banner\": {\n"
+ + " \"description\": \"测试公众号文章精品展示位描述\",\n"
+ + " \"img_url\": \"https://store.mp.video.tencent-cloud.com/abc\",\n"
+ + " \"title\": \"测试公众号文章精品展示位标题\"\n"
+ + " }\n"
+ + " }\n"
+ + " ]\n"
+ + " }\n"
+ + "}";
+ BannerApplyParam param = JsonUtils.decode(json, BannerApplyParam.class);
+ BannerInfo info = null;
+ if (param != null) {
+ info = param.getBanner();
+ }
+ BannerApplyResponse response = service.applyBanner(info);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ assertNotNull(info);
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testGetBanner() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ BannerGetResponse response = service.getBanner();
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testCancelBanner() throws WxErrorException {
+ Integer applyId = 1;
+ WxStoreHomePageService service = channelService.getHomePageService();
+ WxChannelBaseResponse response = service.cancelBanner(applyId);
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+
+ @Test
+ public void testRemoveBanner() throws WxErrorException {
+ WxStoreHomePageService service = channelService.getHomePageService();
+ WxChannelBaseResponse response = service.removeBanner();
+ assertNotNull(response);
+ assertTrue(response.isSuccess());
+ System.out.println(JsonUtils.encode(response));
+ }
+}
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterRuleTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterRuleTest.java
index d1e2f72174..bff360f7cc 100644
--- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterRuleTest.java
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterRuleTest.java
@@ -6,8 +6,7 @@
import org.testng.annotations.Test;
/**
- * @author LiXiZe
- * @since 2023-04-20
+ * @author Zeyes
*/
public class WxChannelMessageRouterRuleTest {
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterTest.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterTest.java
index 755886fa4b..9d683edce6 100644
--- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterTest.java
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/message/WxChannelMessageRouterTest.java
@@ -1,7 +1,9 @@
package me.chanjar.weixin.channel.message;
import static me.chanjar.weixin.channel.constant.MessageEventConstants.BRAND;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.CLOSE_STORE;
import static me.chanjar.weixin.channel.constant.MessageEventConstants.PRODUCT_SPU_AUDIT;
+import static me.chanjar.weixin.channel.constant.MessageEventConstants.SET_SHOP_NICKNAME;
import static org.testng.Assert.*;
import com.google.inject.Inject;
@@ -10,6 +12,8 @@
import me.chanjar.weixin.channel.api.WxChannelService;
import me.chanjar.weixin.channel.bean.message.product.BrandMessage;
import me.chanjar.weixin.channel.bean.message.product.SpuAuditMessage;
+import me.chanjar.weixin.channel.bean.message.store.CloseStoreMessage;
+import me.chanjar.weixin.channel.bean.message.store.NicknameUpdateMessage;
import me.chanjar.weixin.channel.message.rule.HandlerConsumer;
import me.chanjar.weixin.channel.test.ApiTestModule;
import me.chanjar.weixin.channel.util.JsonUtils;
@@ -18,8 +22,7 @@
import org.testng.annotations.Test;
/**
- * @author LiXiZe
- * @since 2023-04-21
+ * @author Zeyes
*/
@Slf4j
@Guice(modules = ApiTestModule.class)
@@ -56,6 +59,48 @@ public void test1() {
}
}
+ @Test
+ public void closeStore() {
+ WxChannelMessageRouter router = new WxChannelMessageRouter();
+ /* 小店注销 */
+ this.addRule(router, CloseStoreMessage.class, CLOSE_STORE, this::closeStore);
+ /* 小店修改名称 */
+ this.addRule(router, NicknameUpdateMessage.class, SET_SHOP_NICKNAME, this::updateNickname);
+ String closeStoreJson = "{\n"
+ + " \"ToUserName\": \"gh_*\",\n"
+ + " \"FromUserName\": \"OPENID\",\n"
+ + " \"CreateTime\": 1662480000,\n"
+ + " \"MsgType\": \"event\",\n"
+ + " \"Event\": \"channels_ec_close_store\",\n"
+ + " \"appid\": \"APPID\",\n"
+ + " \"close_timestamp\": \"1662480000\"\n"
+ + "}";
+ String updateNicknameJson = "{\n"
+ + " \"ToUserName\": \"gh_*\", \n"
+ + " \"FromUserName\": \"OPENID\", \n"
+ + " \"CreateTime\": 1662480000, \n"
+ + " \"MsgType\": \"event\", \n"
+ + " \"Event\": \"set_shop_nickname\", \n"
+ + " \"appid\": \"APPID\",\n"
+ + " \"old_nickname\": \"旧昵称\",\n"
+ + " \"new_nickname\": \"新昵称\"\n"
+ + "}";
+ WxChannelMessage message1 = JsonUtils.decode(closeStoreJson, WxChannelMessage.class);
+ WxChannelMessage message2 = JsonUtils.decode(updateNicknameJson, WxChannelMessage.class);
+ Object result1 = router.route(message1, closeStoreJson, "123456", channelService);
+ if (result1 != null) {
+ log.info("result1:{}", result1);
+ } else {
+ log.info("result1 return null");
+ }
+ Object result2 = router.route(message2, updateNicknameJson, "123456", channelService);
+ if (result2 != null) {
+ log.info("result2:{}", result2);
+ } else {
+ log.info("result2 return null");
+ }
+ }
+
public void brandUpdate(BrandMessage message, String content, String appId,
Map context, WxSessionManager sessionManager) {
log.info("品牌更新:{}", JsonUtils.encode(message));
@@ -67,6 +112,16 @@ public void spuAudit(SpuAuditMessage message, String content, String appId,
log.info("商品审核:{}", JsonUtils.encode(message));
}
+ public void closeStore(CloseStoreMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("小店注销:{}", JsonUtils.encode(message));
+ }
+
+ public void updateNickname(NicknameUpdateMessage message, String content, String appId,
+ Map context, WxSessionManager sessionManager) {
+ log.info("昵称更新:{}", JsonUtils.encode(message));
+ }
+
/**
* 添加一条规则进入路由器
*
diff --git a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/test/ApiTestModule.java b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/test/ApiTestModule.java
index 8eba81a07e..ddfb3a4b8a 100644
--- a/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/test/ApiTestModule.java
+++ b/weixin-java-channel/src/test/java/me/chanjar/weixin/channel/test/ApiTestModule.java
@@ -29,6 +29,7 @@ public void configure(Binder binder) {
"测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成");
}
+ // 提示xml相关依赖不存在时,引入一下就好
TestConfig config = this.fromXml(TestConfig.class, inputStream);
WxChannelService service = new WxChannelServiceImpl();
diff --git a/weixin-java-channel/src/test/resources/test-config.sample.xml b/weixin-java-channel/src/test/resources/test-config.sample.xml
index b04a50e5a7..b84d8d9109 100644
--- a/weixin-java-channel/src/test/resources/test-config.sample.xml
+++ b/weixin-java-channel/src/test/resources/test-config.sample.xml
@@ -4,6 +4,7 @@
secret
Token
EncodingAESKey
+ false
可以不填写
可以不填写
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index 9a8165f6aa..33fd85d4b3 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -6,7 +6,7 @@
com.github.binarywang
wx-java
- 4.6.1.B
+ 4.8.1.B
weixin-java-common
@@ -24,18 +24,17 @@
okhttp
provided
-
+
- org.slf4j
- slf4j-api
-
-
- com.thoughtworks.xstream
- xstream
+ org.apache.httpcomponents.client5
+ httpclient5
+
+
org.apache.httpcomponents
httpclient
+ provided
commons-logging
@@ -46,6 +45,16 @@
org.apache.httpcomponents
httpmime
+ provided
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+ com.thoughtworks.xstream
+ xstream
org.slf4j
@@ -77,6 +86,11 @@
org.projectlombok
lombok
+
+ org.mockito
+ mockito-core
+ test
+
ch.qos.logback
@@ -88,11 +102,7 @@
testng
test
-
- org.mockito
- mockito-all
- test
-
+
com.google.inject
guice
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
index 14f8424f20..d7e8936e62 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
@@ -12,7 +12,7 @@
/**
* 微信开发所使用到的常量类.
*
- * @author Daniel Qian & binarywang & Wang_Wong
+ * @author Daniel Qian, binarywang, Wang_Wong
*/
@UtilityClass
public class WxConsts {
@@ -302,6 +302,7 @@ public static class EventType {
public static final String VIEW = "VIEW";
public static final String MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH";
+ public static final String SYS_APPROVAL_CHANGE = "sys_approval_change";
/**
* 扫码推事件的事件推送
*/
@@ -431,6 +432,12 @@ public static class EventType {
*/
public static final String WEAPP_AUDIT_FAIL = "weapp_audit_fail";
+
+ /**
+ * 小程序审核事件:审核延后
+ */
+ public static final String WEAPP_AUDIT_DELAY = "weapp_audit_delay";
+
/**
* 小程序自定义交易组件支付通知
*/
@@ -454,6 +461,43 @@ public static class EventType {
* 订阅通知事件:发送订阅通知回调
*/
public static final String SUBSCRIBE_MSG_SENT_EVENT = "subscribe_msg_sent_event";
+
+ /**
+ * 名称审核事件
+ */
+ public static final String WXA_NICKNAME_AUDIT = "wxa_nickname_audit";
+ /**
+ * 小程序违规记录事件
+ */
+ public static final String WXA_ILLEGAL_RECORD = "wxa_illegal_record";
+ /**
+ * 小程序申诉记录推送
+ */
+ public static final String WXA_APPEAL_RECORD = "wxa_appeal_record";
+ /**
+ * 隐私权限审核结果推送
+ */
+ public static final String WXA_PRIVACY_APPLY = "wxa_privacy_apply";
+ /**
+ * 类目审核结果事件推送
+ */
+ public static final String WXA_CATEGORY_AUDIT = "wxa_category_audit";
+ /**
+ * 小程序微信认证支付成功事件
+ */
+ public static final String WX_VERIFY_PAY_SUCC = "wx_verify_pay_succ";
+ /**
+ * 小程序微信认证派单事件
+ */
+ public static final String WX_VERIFY_DISPATCH = "wx_verify_dispatch";
+ /**
+ * 提醒需要上传发货信息事件:曾经发过货的小程序,订单超过48小时未发货时
+ */
+ public static final String TRADE_MANAGE_REMIND_SHIPPING = "trade_manage_remind_shipping";
+ /**
+ * 订单完成发货时、订单结算时
+ */
+ public static final String TRADE_MANAGE_ORDER_SETTLEMENT = "trade_manage_order_settlement";
}
/**
@@ -587,4 +631,19 @@ public static class AppIdType {
*/
public static final String MINI_TYPE = "mini";
}
+
+ /**
+ * 新建文章类型
+ */
+ @UtilityClass
+ public static class ArticleType {
+ /**
+ * 图文消息
+ */
+ public static final String NEWS = "news";
+ /**
+ * 图片消息
+ */
+ public static final String NEWS_PIC = "newspic";
+ }
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java
index c08a49063d..b339844ad6 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/oauth2/WxOAuth2AccessToken.java
@@ -7,7 +7,10 @@
import java.io.Serializable;
/**
- * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
+ * OAuth2 AccessToken
+ *
+ * 参考:{@code https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842}
+ *
*
* @author Daniel Qian
*/
@@ -36,8 +39,10 @@ public class WxOAuth2AccessToken implements Serializable {
private Integer snapshotUser;
/**
- * https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN.
* 本接口在scope参数为snsapi_base时不再提供unionID字段。
+ *
+ * 参考:{@code https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN}
+ *
*/
@SerializedName("unionid")
private String unionId;
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadCustomizeResult.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadCustomizeResult.java
index cd700be7c1..5427d5cada 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadCustomizeResult.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadCustomizeResult.java
@@ -16,7 +16,7 @@ public class WxMinishopImageUploadCustomizeResult implements Serializable {
private WxMinishopPicFileCustomizeResult imgInfo;
public static WxMinishopImageUploadCustomizeResult fromJson(String json) {
- JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
+ JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
WxMinishopImageUploadCustomizeResult result = new WxMinishopImageUploadCustomizeResult();
result.setErrcode(jsonObject.get(WxConsts.ERR_CODE).getAsNumber().toString());
if (result.getErrcode().equals("0")) {
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadResult.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadResult.java
index 324232d0ee..9c2cbaf3ba 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadResult.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMinishopImageUploadResult.java
@@ -21,7 +21,7 @@ public class WxMinishopImageUploadResult implements Serializable {
public static WxMinishopImageUploadResult fromJson(String json) {
- JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
+ JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
WxMinishopImageUploadResult result = new WxMinishopImageUploadResult();
result.setErrcode(jsonObject.get(WxConsts.ERR_CODE).getAsNumber().toString());
if (result.getErrcode().equals("0")) {
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxChannelErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxChannelErrorMsgEnum.java
new file mode 100644
index 0000000000..3491e74dc8
--- /dev/null
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxChannelErrorMsgEnum.java
@@ -0,0 +1,172 @@
+package me.chanjar.weixin.common.error;
+
+import com.google.common.collect.Maps;
+import java.util.Map;
+
+/**
+ *
+ *
+ * 微信小店公共错误码.
+ * 参考文档:微信小店公共错误码
+ *
+ *
+ * @author Zeyes
+ */
+public enum WxChannelErrorMsgEnum {
+ /**
+ * 系统繁忙,此时请开发者稍候再试 system error
+ */
+ CODE_1(-1, "系统繁忙,此时请开发者稍候再试"),
+ /**
+ * 请求成功 ok
+ */
+ CODE_0(0, "请求成功"),
+ /**
+ * 获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真检查 AppSecret 的正确性
+ * invalid credential, access_token is invalid or not latest, could get access_token by getStableAccessToken, more details at https://mmbizurl.cn/s/JtxxFh33r
+ */
+ CODE_40001(40001, "获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真检查 AppSecret 的正确性"),
+ /**
+ * 请检查 openid 的正确性
+ * invalid openid
+ */
+ CODE_40003(40003, "请检查 openid 的正确性"),
+ /**
+ * 请检查 appid 的正确性,避免异常字符,注意大小写
+ * invalid appid
+ */
+ CODE_40013(40013, "请检查 appid 的正确性,避免异常字符,注意大小写"),
+ /**
+ * 请检查API的URL是否与文档一致
+ * invalid url
+ */
+ CODE_40066(40066, "请检查API的URL是否与文档一致"),
+ /**
+ * 缺少 access_token 参数
+ * access_token missing
+ */
+ CODE_41001(41001, "缺少 access_token 参数"),
+ /**
+ * 请检查URL参数中是否有 ?appid=
+ * appid missing
+ */
+ CODE_41002(41002, "请检查URL参数中是否有 ?appid="),
+ /**
+ * 请检查POST json中是否包含component_ appid宇段
+ * missing component_appid
+ */
+ CODE_41018(41018, "请检查POST json中是否包含component_ appid宇段"),
+ /**
+ * access_token失效,需要重新获取新的access_token
+ * access_token expired
+ */
+ CODE_42001(42001, "access_token失效,需要重新获取新的access_token"),
+ /**
+ * 请检查发起API请求的Method是否为POST
+ * require POST method
+ */
+ CODE_43002(43002, "请检查发起API请求的Method是否为POST"),
+ /**
+ * 请使用HTTPS方式清求,不要使用HTTP方式
+ * require https
+ */
+ CODE_43003(43003, "请使用HTTPS方式清求,不要使用HTTP方式"),
+ /**
+ * POST 的数据包为空
+ * empty post data
+ */
+ CODE_44002(44002, "POST 的数据包为空"),
+ /**
+ * 请对数据进行压缩
+ * content size out of limit
+ */
+ CODE_45002(45002, "请对数据进行压缩"),
+ /**
+ * 查看调用次数是否符合预期,可通过get_api_quota接口获取每天的调用quota;用完后可通过clear_quota进行清空
+ * reach max api daily quota limit
+ */
+ CODE_45009(45009, "查看调用次数是否符合预期,可通过get_api_quota接口获取每天的调用quota;用完后可通过clear_quota进行清空"),
+ /**
+ * 命中每分钟的频率限制
+ * api minute-quota reach limit must slower retry next minute
+ */
+ CODE_45011(45011, "命中每分钟的频率限制"),
+ /**
+ * 需要登录 channels.weixin.qq.com/shop 配置IP白名单
+ * access clientip is not registered, not in ip-white-list
+ */
+ CODE_45035(45035, "需要登录 channels.weixin.qq.com/shop 配置IP白名单"),
+ /**
+ * 解析 JSON/XML 内容错误
+ * data format error
+ */
+ CODE_47001(47001, "解析 JSON/XML 内容错误"),
+ /**
+ * 没有该接口权限
+ * api unauthorized
+ */
+ CODE_48001(48001, "没有该接口权限"),
+ /**
+ * 接口被禁用
+ * api forbidden for irregularities
+ */
+ CODE_48004(48004, "接口被禁用"),
+ /**
+ * 请找用户获取该api授权
+ * user unauthorized
+ */
+ CODE_50001(50001, "请找用户获取该api授权"),
+ /**
+ * 请检查封禁原因
+ * user limited
+ */
+ CODE_50002(50002, "请检查封禁原因"),
+ /**
+ * 需要登录 channels.weixin.qq.com/shop 配置IP白名单
+ * access clientip is not registered, not in ip-white-list
+ */
+ CODE_61004(61004, "需要登录 channels.weixin.qq.com/shop 配置IP白名单"),
+ /**
+ * 请检查第三方平台服务商检查已获取的授权集
+ * api is unauthorized to component
+ */
+ CODE_61007(61007, "请检查第三方平台服务商检查已获取的授权集"),
+ /**
+ * 需要登录 channels.weixin.qq.com/shop 继续完成注销
+ * 账号发起注销,进入注销公示期
+ */
+ CODE_10080000(10080000, "需要登录 channels.weixin.qq.com/shop 继续完成注销"),
+ /**
+ * 账号已注销
+ */
+ CODE_10080001(10080001, "账号已注销"),
+ /**
+ * 小店的视频号带货身份为达人号,不允许使用该功能,如需使用,请将带货身份修改为商家
+ */
+ CODE_10080002(10080002, "小店的视频号带货身份为达人号,不允许使用该功能,如需使用,请将带货身份修改为商家"),
+
+ ;
+
+ private final int code;
+ private final String msg;
+
+ WxChannelErrorMsgEnum(int code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+
+ static final Map valueMap = Maps.newHashMap();
+
+ static {
+ for (WxChannelErrorMsgEnum value : WxChannelErrorMsgEnum.values()) {
+ valueMap.put(value.code, value.msg);
+ }
+ }
+
+ /**
+ * 通过错误代码查找其中文含义.
+ */
+ public static String findMsgByCode(int code) {
+ return valueMap.getOrDefault(code, null);
+ }
+}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java
index ea1e9e7c68..356d1dbbf9 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxCpErrorMsgEnum.java
@@ -453,7 +453,7 @@ public enum WxCpErrorMsgEnum {
*/
CODE_60008(60008, "部门已存在;部门ID或者部门名称已存在"),
/**
- * 部门名称含有非法字符;不能含有 \\:?*“< >| 等字符.
+ * {@code 部门名称含有非法字符;不能含有 \\:?*"< >| 等字符.}
*/
CODE_60009(60009, "部门名称含有非法字符;不能含有 \\ :?*“< >| 等字符"),
/**
@@ -521,7 +521,7 @@ public enum WxCpErrorMsgEnum {
*/
CODE_60124(60124, "无效的父部门id;父部门不存在通讯录中"),
/**
- * 非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符.
+ * {@code 非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?"< >|等字符.}
*/
CODE_60125(60125, "非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符"),
/**
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java
index 1156636ea3..1aab7f1f20 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxError.java
@@ -12,11 +12,13 @@
/**
* 微信错误码.
+ *
* 请阅读:
* 公众平台:全局返回码说明
* 企业微信:全局错误码
+ *
*
- * @author Daniel Qian & Binary Wang
+ * @author Daniel Qian, Binary Wang
*/
@Data
@NoArgsConstructor
@@ -91,6 +93,13 @@ public static WxError fromJson(String json, WxType type) {
}
break;
}
+ case Channel: {
+ final String msg = WxChannelErrorMsgEnum.findMsgByCode(wxError.getErrorCode());
+ if (msg != null) {
+ wxError.setErrorMsg(msg);
+ }
+ break;
+ }
default:
return wxError;
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java
index 46c1d3d3d2..ffe9b5e3ea 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java
@@ -46,23 +46,23 @@ public enum WxMaErrorMsgEnum {
*/
CODE_40003(40003, "openid 不正确"),
/**
- *
* 无效媒体文件类型
- * 对应操作:uploadTempMedia
+ *
+ * 对应操作:{@code uploadTempMedia}
* 对应地址:
- * POST https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
+ * {@code POST https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE}
* 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/customer-message/uploadTempMedia.html
- *
+ *
*/
CODE_40004(40004, "无效媒体文件类型"),
/**
- *
* 无效媒体文件 ID.
- * 对应操作:getTempMedia
+ *
+ * 对应操作:{@code getTempMedia}
* 对应地址:
- * GET https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
+ * {@code GET https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID}
* 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/customer-message/getTempMedia.html
- *
+ *
*/
CODE_40007(40007, "无效媒体文件 ID"),
/**
@@ -99,29 +99,29 @@ public enum WxMaErrorMsgEnum {
*/
CODE_41028(41028, "form_id 不正确,或者过期"),
/**
- *
* code 或 template_id 不正确.
- * 对应操作:code2Session, sendUniformMessage, sendTemplateMessage
+ *
+ * 对应操作:{@code code2Session}, {@code sendUniformMessage}, {@code sendTemplateMessage}
* 对应地址:
- * GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
+ * {@code GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code}
* POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN
* POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN
* 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/code2Session.html
* https://developers.weixin.qq.com/miniprogram/dev/api/open-api/uniform-message/sendUniformMessage.html
* https://developers.weixin.qq.com/miniprogram/dev/api/open-api/template-message/sendTemplateMessage.html
- *
+ *
*/
CODE_41029(41029, "请求的参数不正确"),
/**
- *
* form_id 已被使用,或者所传page页面不存在,或者小程序没有发布
- * 对应操作:sendUniformMessage, getWXACodeUnlimit
+ *
+ * 对应操作:{@code sendUniformMessage}, {@code getWXACodeUnlimit}
* 对应地址:
* POST https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN
* POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
* 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/uniform-message/sendUniformMessage.html
- * https://developers.weixin.qq.com/miniprogram/dev/api/open-api/qr-code/getWXACodeUnlimit.html
- *
+ * https://developers.weixin.qq.com/miniprogram/dev/api/open-api/qr-code/getWXACodeUnlimit.html
+ *
*/
CODE_41030(41030, "请求的参数不正确"),
/**
@@ -138,13 +138,13 @@ public enum WxMaErrorMsgEnum {
*/
CODE_45009(45009, "调用分钟频率受限"),
/**
- *
* 频率限制,每个用户每分钟100次.
- * 对应操作:code2Session
+ *
+ * 对应操作:{@code code2Session}
* 对应地址:
- * GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
+ * {@code GET https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code}
* 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/code2Session.html
- *
+ *
*/
CODE_45011(45011, "频率限制,每个用户每分钟100次"),
/**
@@ -190,12 +190,13 @@ public enum WxMaErrorMsgEnum {
*/
CODE_45072(45072, "command字段取值不对"),
/**
- *
* 下发输入状态,需要之前30秒内跟用户有过消息交互.
- * 对应操作:customerTyping
+ *
+ * 对应操作:{@code customerTyping}
* 对应地址:
* POST https://api.weixin.qq.com/cgi-bin/message/custom/typing?access_token=ACCESS_TOKEN
* 参考文档地址: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/customer-message/customerTyping.html
+ *
*/
CODE_45080(45080, "下发输入状态,需要之前30秒内跟用户有过消息交互"),
/**
@@ -686,7 +687,7 @@ public enum WxMaErrorMsgEnum {
/**
* 89252
- * 法人&企业信息一致性校验中 front checking
+ * {@code 法人&企业信息一致性校验中 front checking}
*/
CODE_89252(89252, "法人&企业信息一致性校验中"),
@@ -711,6 +712,132 @@ public enum WxMaErrorMsgEnum {
CODE_89255(89255, "code参数无效,请检查code长度以及内容是否正确_;注意code_type的值不同需要传的code长度不一样 ;注意code_type的值不同需要传的code长度不一样"),
// CODE_504002(-504002, "云函数未找到 Function not found"),
+
+ /**
+ * 半屏小程序系统错误
+ */
+ CODE_89408(89408, "半屏小程序系统错误"),
+
+ /**
+ * 获取半屏小程序列表参数错误
+ */
+ CODE_89409(89409, "获取半屏小程序列表参数错误"),
+
+ /**
+ * 添加半屏小程序appid参数错误
+ */
+ CODE_89410(89410, "添加半屏小程序appid参数错误"),
+
+ /**
+ * 添加半屏小程序appid参数为空
+ */
+ CODE_89411(89411, "添加半屏小程序appid参数为空"),
+
+ /**
+ * 添加半屏小程序申请理由不得超过30个字
+ */
+ CODE_89412(89412, "添加半屏小程序申请理由不得超过30个字"),
+
+ /**
+ * 该小程序被申请次数已达24h限制
+ */
+ CODE_89413(89413, "该小程序被申请次数已达24h限制"),
+
+ /**
+ * 每天仅允许申请50次半屏小程序
+ */
+ CODE_89414(89414, "每天仅允许申请50次半屏小程序"),
+
+ /**
+ * 删除半屏小程序appid参数为空
+ */
+ CODE_89415(89415, "删除半屏小程序appid参数为空"),
+
+ /**
+ * 取消半屏小程序授权appid参数为空
+ */
+ CODE_89416(89416, "取消半屏小程序授权appid参数为空"),
+
+ /**
+ * 修改半屏小程序方式flag参数错误
+ */
+ CODE_89417(89417, "修改半屏小程序方式flag参数错误"),
+
+ /**
+ * 获取半屏小程序每日申请次数失败
+ */
+ CODE_89418(89418, "获取半屏小程序每日申请次数失败"),
+
+ /**
+ * 获取半屏小程序每日授权次数失败
+ */
+ CODE_89419(89419, "获取半屏小程序每日授权次数失败"),
+
+ /**
+ * 不支持添加个人主体小程序
+ */
+ CODE_89420(89420, "不支持添加个人主体小程序"),
+
+ /**
+ * 删除数据未找到
+ */
+ CODE_89421(89421, "删除数据未找到"),
+
+ /**
+ * 删除状态异常
+ */
+ CODE_89422(89422, "删除状态异常"),
+
+ /**
+ * 申请次数添加到达上限
+ */
+ CODE_89423(89423, "申请次数添加到达上限"),
+
+ /**
+ * 申请添加已超时
+ */
+ CODE_89425(89425, "申请添加已超时"),
+
+ /**
+ * 申请添加状态异常
+ */
+ CODE_89426(89426, "申请添加状态异常"),
+
+ /**
+ * 申请号和授权号相同
+ */
+ CODE_89427(89427, "申请号和授权号相同"),
+
+ /**
+ * 该小程序已申请,不允许重复添加
+ */
+ CODE_89428(89428, "该小程序已申请,不允许重复添加"),
+
+ /**
+ * 已到达同一小程序每日最多申请次数
+ */
+ CODE_89429(89429, "已到达同一小程序每日最多申请次数"),
+
+ /**
+ * 该小程序已设置自动拒绝申请
+ */
+ CODE_89430(89430, "该小程序已设置自动拒绝申请"),
+
+ /**
+ * 不支持此类型小程序
+ */
+ CODE_89431(89431, "不支持此类型小程序"),
+
+ /**
+ * 不是小程序
+ */
+ CODE_89432(89432, "不是小程序"),
+
+ /**
+ * 授权次数到达上限
+ */
+ CODE_89424(89424, "授权次数到达上限"),
+
;
private final int code;
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxOpenErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxOpenErrorMsgEnum.java
index 28fb5de8ad..ba910e988b 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxOpenErrorMsgEnum.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxOpenErrorMsgEnum.java
@@ -527,7 +527,7 @@ public enum WxOpenErrorMsgEnum {
CODE_40099(40099, "invalid code, this code has consumed."),
/**
- * invalid DateInfo, Make Sure OldDateInfoType==NewDateInfoType && NewBeginTime<=OldBeginTime && OldEndTime<= NewEndTime
+ * {@code invalid DateInfo, Make Sure OldDateInfoType==NewDateInfoType && NewBeginTime<=OldBeginTime && OldEndTime<= NewEndTime}
*/
CODE_40100(40100, "invalid DateInfo, Make Sure OldDateInfoType==NewDateInfoType && NewBeginTime<=OldBeginTime && OldEndTime<= NewEndTime"),
@@ -572,7 +572,7 @@ public enum WxOpenErrorMsgEnum {
CODE_40108(40108, "invalid client version"),
/**
- * too many code size, must <= 100
+ * {@code too many code size, must <= 100}
*/
CODE_40109(40109, "too many code size, must <= 100"),
@@ -702,7 +702,7 @@ public enum WxOpenErrorMsgEnum {
CODE_40135(40135, "invalid not supply bonus, can not change card_id which supply bonus to be not supply"),
/**
- * invalid use DepositCodeMode, make sure sku.quantity>DepositCode.quantity
+ * {@code invalid use DepositCodeMode, make sure sku.quantity>DepositCode.quantity}
*/
CODE_40136(40136, "invalid use DepositCodeMode, make sure sku.quantity>DepositCode.quantity"),
@@ -1082,7 +1082,7 @@ public enum WxOpenErrorMsgEnum {
CODE_40211(40211, "invalid scope_data"),
/**
- * paegs 当中存在不合法的query,query格式遵循URL标准,即k1=v1&k2=v2 invalid query
+ * {@code paegs 当中存在不合法的query,query格式遵循URL标准,即k1=v1&k2=v2 invalid query}
*/
CODE_40212(40212, "paegs 当中存在不合法的query,query格式遵循URL标准,即k1=v1&k2=v2"),
@@ -4242,7 +4242,7 @@ public enum WxOpenErrorMsgEnum {
CODE_71005(71005, "limit exe count"),
/**
- * limit coin count, 1 <= coin_count <= 100000
+ * {@code limit coin count, 1 <= coin_count <= 100000}
*/
CODE_71006(71006, "limit coin count, 1 <= coin_count <= 100000"),
@@ -4347,7 +4347,7 @@ public enum WxOpenErrorMsgEnum {
CODE_72018(72018, "duplicate order id, invoice had inserted to user"),
/**
- * limit msg operation card list size, must <= 5
+ * {@code limit msg operation card list size, must <= 5}
*/
CODE_72019(72019, "limit msg operation card list size, must <= 5"),
@@ -6432,7 +6432,7 @@ public enum WxOpenErrorMsgEnum {
CODE_88009(88009, "reply is not exists"),
/**
- * count range error. cout <= 0 or count > 50
+ * {@code count range error. cout <= 0 or count > 50}
*/
CODE_88010(88010, "count range error. cout <= 0 or count > 50"),
@@ -6682,7 +6682,7 @@ public enum WxOpenErrorMsgEnum {
CODE_89251(89251, "模板消息已下发,待法人人脸核身校验"),
/**
- * 法人&企业信息一致性校验中 front checking
+ * {@code 法人&企业信息一致性校验中 front checking}
*/
CODE_89253(89253, "法人&企业信息一致性校验中"),
@@ -7257,7 +7257,7 @@ public enum WxOpenErrorMsgEnum {
CODE_200021(200021, "场景描述 sceneDesc 参数错误"),
/**
- * 禁止创建/更新商品(如商品创建功能被封禁) 或 禁止编辑&更新房间
+ * {@code 禁止创建/更新商品(如商品创建功能被封禁) 或 禁止编辑&更新房间}
*/
CODE_300001(300001, "禁止创建/更新商品(如商品创建功能被封禁) 或 禁止编辑&更新房间"),
@@ -8382,7 +8382,7 @@ public enum WxOpenErrorMsgEnum {
CODE_9300003(9300003, "begin_time must less than end_time"),
/**
- * end_time - begin_time > 1year
+ * {@code end_time - begin_time > 1year}
*/
CODE_9300004(9300004, "end_time - begin_time > 1year"),
@@ -8397,7 +8397,7 @@ public enum WxOpenErrorMsgEnum {
CODE_9300006(9300006, "invalid activity status"),
/**
- * gift_num must >0 and <=15
+ * {@code gift_num must >0 and <=15}
*/
CODE_9300007(9300007, "gift_num must >0 and <=15"),
@@ -8412,7 +8412,7 @@ public enum WxOpenErrorMsgEnum {
CODE_9300009(9300009, "activity can not finish"),
/**
- * card_info_list must >= 2
+ * {@code card_info_list must >= 2}
*/
CODE_9300010(9300010, "card_info_list must >= 2"),
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutor.java
index 2c9a4d7526..a93cbe1e99 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutor.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutor.java
@@ -1,11 +1,15 @@
package me.chanjar.weixin.common.executor;
+import jodd.http.HttpConnectionProvider;
+import jodd.http.ProxyInfo;
import me.chanjar.weixin.common.bean.CommonUploadParam;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.ResponseHandler;
+import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo;
+import okhttp3.OkHttpClient;
import java.io.IOException;
@@ -34,15 +38,19 @@ public void execute(String uri, CommonUploadParam data, ResponseHandler
* @param requestHttp 请求信息
* @return 执行器
*/
- @SuppressWarnings({"rawtypes", "unchecked"})
- public static RequestExecutor create(RequestHttp requestHttp) {
+ @SuppressWarnings("unchecked")
+ public static RequestExecutor create(RequestHttp, ?> requestHttp) {
switch (requestHttp.getRequestType()) {
case APACHE_HTTP:
- return new CommonUploadRequestExecutorApacheImpl(requestHttp);
+ return new CommonUploadRequestExecutorApacheImpl(
+ (RequestHttp) requestHttp);
case JODD_HTTP:
- return new CommonUploadRequestExecutorJoddHttpImpl(requestHttp);
+ return new CommonUploadRequestExecutorJoddHttpImpl((RequestHttp) requestHttp);
case OK_HTTP:
- return new CommonUploadRequestExecutorOkHttpImpl(requestHttp);
+ return new CommonUploadRequestExecutorOkHttpImpl((RequestHttp) requestHttp);
+ case HTTP_COMPONENTS:
+ return new CommonUploadRequestExecutorHttpComponentsImpl(
+ (RequestHttp) requestHttp);
default:
throw new IllegalArgumentException("不支持的http执行器类型:" + requestHttp.getRequestType());
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutorApacheImpl.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutorApacheImpl.java
index 6a3c05dd21..7f19241cdb 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutorApacheImpl.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutorApacheImpl.java
@@ -8,10 +8,10 @@
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
+import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
@@ -28,8 +28,7 @@
* @author 广州跨界
* created on 2024/01/11
*/
-public class CommonUploadRequestExecutorApacheImpl
- extends CommonUploadRequestExecutor {
+public class CommonUploadRequestExecutorApacheImpl extends CommonUploadRequestExecutor {
public CommonUploadRequestExecutorApacheImpl(RequestHttp requestHttp) {
super(requestHttp);
@@ -52,19 +51,15 @@ public String execute(String uri, CommonUploadParam param, WxType wxType) throws
.build();
httpPost.setEntity(entity);
}
- try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) {
- String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
- if (responseContent == null || responseContent.isEmpty()) {
- throw new WxErrorException(String.format("上传失败,服务器响应空 url:%s param:%s", uri, param));
- }
- WxError error = WxError.fromJson(responseContent, wxType);
- if (error.getErrorCode() != 0) {
- throw new WxErrorException(error);
- }
- return responseContent;
- } finally {
- httpPost.releaseConnection();
+ String responseContent = requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);
+ if (StringUtils.isEmpty(responseContent)) {
+ throw new WxErrorException(String.format("上传失败,服务器响应空 url:%s param:%s", uri, param));
}
+ WxError error = WxError.fromJson(responseContent, wxType);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ return responseContent;
}
/**
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutorHttpComponentsImpl.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutorHttpComponentsImpl.java
new file mode 100644
index 0000000000..f79eaa49b8
--- /dev/null
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/executor/CommonUploadRequestExecutorHttpComponentsImpl.java
@@ -0,0 +1,75 @@
+package me.chanjar.weixin.common.executor;
+
+import lombok.Getter;
+import me.chanjar.weixin.common.bean.CommonUploadData;
+import me.chanjar.weixin.common.bean.CommonUploadParam;
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxError;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.hc.Utf8ResponseHandler;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
+import org.apache.hc.client5.http.entity.mime.InputStreamBody;
+import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Apache HttpComponents 通用文件上传器
+ */
+public class CommonUploadRequestExecutorHttpComponentsImpl extends CommonUploadRequestExecutor {
+
+ public CommonUploadRequestExecutorHttpComponentsImpl(RequestHttp requestHttp) {
+ super(requestHttp);
+ }
+
+ @Override
+ public String execute(String uri, CommonUploadParam param, WxType wxType) throws WxErrorException, IOException {
+ HttpPost httpPost = new HttpPost(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpPost.setConfig(config);
+ }
+ if (param != null) {
+ CommonUploadData data = param.getData();
+ InnerStreamBody part = new InnerStreamBody(data.getInputStream(), ContentType.DEFAULT_BINARY, data.getFileName(), data.getLength());
+ HttpEntity entity = MultipartEntityBuilder
+ .create()
+ .addPart(param.getName(), part)
+ .setMode(HttpMultipartMode.EXTENDED)
+ .build();
+ httpPost.setEntity(entity);
+ }
+ String responseContent = requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);
+ if (StringUtils.isEmpty(responseContent)) {
+ throw new WxErrorException(String.format("上传失败,服务器响应空 url:%s param:%s", uri, param));
+ }
+ WxError error = WxError.fromJson(responseContent, wxType);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ return responseContent;
+ }
+
+ /**
+ * 内部流 请求体
+ */
+ @Getter
+ public static class InnerStreamBody extends InputStreamBody {
+
+ private final long contentLength;
+
+ public InnerStreamBody(final InputStream in, final ContentType contentType, final String filename, long contentLength) {
+ super(in, contentType, filename);
+ this.contentLength = contentLength;
+ }
+ }
+}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java
index 19d4046c92..d531a2a307 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/redis/RedisTemplateWxRedisOps.java
@@ -29,7 +29,7 @@ public void setValue(String key, String value, int expire, TimeUnit timeUnit) {
@Override
public Long getExpire(String key) {
- return redisTemplate.getExpire(key);
+ return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
@Override
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernApacheHttpRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernApacheHttpRequestExecutor.java
index 22cdab3f92..03bec013dd 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernApacheHttpRequestExecutor.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernApacheHttpRequestExecutor.java
@@ -8,7 +8,6 @@
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
-import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
@@ -24,7 +23,7 @@
* created on 2019/6/27 14:06
*/
public class OcrDiscernApacheHttpRequestExecutor extends OcrDiscernRequestExecutor {
- public OcrDiscernApacheHttpRequestExecutor(RequestHttp requestHttp) {
+ public OcrDiscernApacheHttpRequestExecutor(RequestHttp requestHttp) {
super(requestHttp);
}
@@ -43,15 +42,11 @@ public String execute(String uri, File file, WxType wxType) throws WxErrorExcept
.build();
httpPost.setEntity(entity);
}
- try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) {
- String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
- WxError error = WxError.fromJson(responseContent, wxType);
- if (error.getErrorCode() != 0) {
- throw new WxErrorException(error);
- }
- return responseContent;
- } finally {
- httpPost.releaseConnection();
+ String responseContent = requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);
+ WxError error = WxError.fromJson(responseContent, wxType);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
}
+ return responseContent;
}
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernHttpComponentsRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernHttpComponentsRequestExecutor.java
new file mode 100644
index 0000000000..2d02c965a8
--- /dev/null
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernHttpComponentsRequestExecutor.java
@@ -0,0 +1,46 @@
+package me.chanjar.weixin.common.requestexecuter.ocr;
+
+import me.chanjar.weixin.common.enums.WxType;
+import me.chanjar.weixin.common.error.WxError;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.hc.Utf8ResponseHandler;
+import org.apache.hc.client5.http.classic.methods.HttpPost;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.entity.mime.HttpMultipartMode;
+import org.apache.hc.client5.http.entity.mime.MultipartEntityBuilder;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+
+import java.io.File;
+import java.io.IOException;
+
+public class OcrDiscernHttpComponentsRequestExecutor extends OcrDiscernRequestExecutor {
+ public OcrDiscernHttpComponentsRequestExecutor(RequestHttp requestHttp) {
+ super(requestHttp);
+ }
+
+ @Override
+ public String execute(String uri, File file, WxType wxType) throws WxErrorException, IOException {
+ HttpPost httpPost = new HttpPost(uri);
+ if (requestHttp.getRequestHttpProxy() != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
+ httpPost.setConfig(config);
+ }
+ if (file != null) {
+ HttpEntity entity = MultipartEntityBuilder
+ .create()
+ .addBinaryBody("file", file)
+ .setMode(HttpMultipartMode.EXTENDED)
+ .build();
+ httpPost.setEntity(entity);
+ }
+ String responseContent = requestHttp.getRequestHttpClient().execute(httpPost, Utf8ResponseHandler.INSTANCE);
+ WxError error = WxError.fromJson(responseContent, wxType);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ return responseContent;
+ }
+}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernRequestExecutor.java
index 870f77d2ed..542ab4a378 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernRequestExecutor.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/requestexecuter/ocr/OcrDiscernRequestExecutor.java
@@ -5,6 +5,8 @@
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import me.chanjar.weixin.common.util.http.ResponseHandler;
+import org.apache.http.HttpHost;
+import org.apache.http.impl.client.CloseableHttpClient;
import java.io.File;
import java.io.IOException;
@@ -18,7 +20,7 @@
public abstract class OcrDiscernRequestExecutor implements RequestExecutor {
protected RequestHttp requestHttp;
- public OcrDiscernRequestExecutor(RequestHttp requestHttp) {
+ public OcrDiscernRequestExecutor(RequestHttp requestHttp) {
this.requestHttp = requestHttp;
}
@@ -27,12 +29,17 @@ public void execute(String uri, File data, ResponseHandler handler, WxTy
handler.handle(this.execute(uri, data, wxType));
}
- public static RequestExecutor create(RequestHttp requestHttp) {
+ @SuppressWarnings("unchecked")
+ public static RequestExecutor create(RequestHttp, ?> requestHttp) {
switch (requestHttp.getRequestType()) {
case APACHE_HTTP:
- return new OcrDiscernApacheHttpRequestExecutor(requestHttp);
+ return new OcrDiscernApacheHttpRequestExecutor(
+ (RequestHttp) requestHttp);
+ case HTTP_COMPONENTS:
+ return new OcrDiscernHttpComponentsRequestExecutor(
+ (RequestHttp) requestHttp);
default:
- return null;
+ throw new IllegalArgumentException("不支持的http执行器类型:" + requestHttp.getRequestType());
}
}
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java
index 39a8a93754..d0aeef8491 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/service/WxOcrService.java
@@ -12,7 +12,9 @@
/**
* 基于小程序或 H5 的身份证、银行卡、行驶证 OCR 识别.
- * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=21516712284rHWMX
+ *
+ * 参考:{@code https://mp.weixin.qq.com/wiki?t=resource/res_main&id=21516712284rHWMX}
+ *
*
* @author Binary Wang
* created on 2019-06-22
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java
index e3d9ab8351..24ea58ef38 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/session/InternalSessionManager.java
@@ -7,13 +7,12 @@ public interface InternalSessionManager {
/**
* Return the active Session, associated with this Manager, with the
- * specified session id (if any); otherwise return null.
+ * specified session id (if any); otherwise return {@code null}.
*
* @param id The session id for the session to be returned
+ * @return the session or null
* @throws IllegalStateException if a new session cannot be
* instantiated for any reason
- * @throws java.io.IOException if an input/output error occurs while
- * processing this request
*/
InternalSession findSession(String id);
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java
index 73b6cff368..d3f8d00406 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java
@@ -2,7 +2,6 @@
import com.google.common.collect.Lists;
import me.chanjar.weixin.common.annotation.Required;
-import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java
index 983d9a668f..b8fb42e0e9 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/DataUtils.java
@@ -1,5 +1,6 @@
package me.chanjar.weixin.common.util;
+import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.StringUtils;
/**
@@ -17,7 +18,7 @@ public class DataUtils {
public static E handleDataWithSecret(E data) {
E dataForLog = data;
if(data instanceof String && StringUtils.contains((String)data, "&secret=")){
- dataForLog = (E) StringUtils.replaceAll((String)data,"&secret=\\w+&","&secret=******&");
+ dataForLog = (E) RegExUtils.replaceAll((String)data,"&secret=\\w+&","&secret=******&");
}
return dataForLog;
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/RandomUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/RandomUtils.java
index bbb11992bc..a9017c0d16 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/RandomUtils.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/RandomUtils.java
@@ -4,12 +4,24 @@ public class RandomUtils {
private static final String RANDOM_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
- private static final java.util.Random RANDOM = new java.util.Random();
+ private static volatile java.util.Random random;
+
+ private static java.util.Random getRandom() {
+ if (random == null) {
+ synchronized (RandomUtils.class) {
+ if (random == null) {
+ random = new java.util.Random();
+ }
+ }
+ }
+ return random;
+ }
public static String getRandomStr() {
StringBuilder sb = new StringBuilder();
+ java.util.Random r = getRandom();
for (int i = 0; i < 16; i++) {
- sb.append(RANDOM_STR.charAt(RANDOM.nextInt(RANDOM_STR.length())));
+ sb.append(RANDOM_STR.charAt(r.nextInt(RANDOM_STR.length())));
}
return sb.toString();
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java
index fc3579d45c..1886209f98 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/SignUtils.java
@@ -25,6 +25,7 @@ public class SignUtils {
*
* @param message 签名数据
* @param key 签名密钥
+ * @return 签名结果
*/
public static String createHmacSha256Sign(String message, String key) {
try {
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/XmlUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/XmlUtils.java
index facf564e32..67faf319f4 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/XmlUtils.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/XmlUtils.java
@@ -65,7 +65,7 @@ private static Object element2MapOrString(Element element) {
final List