@@ -6,7 +6,7 @@ | |||
<modelVersion>4.0.0</modelVersion> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>wx-java</artifactId> | |||
<version>3.5.0</version> | |||
<version>3.6.0</version> | |||
<packaging>pom</packaging> | |||
<name>WxJava - Weixin/Wechat Java SDK</name> | |||
<description>微信开发Java SDK</description> | |||
@@ -105,9 +105,7 @@ | |||
<module>weixin-java-pay</module> | |||
<module>weixin-java-miniapp</module> | |||
<module>weixin-java-open</module> | |||
<module>spring-boot-starters/wx-java-pay-spring-boot-starter</module> | |||
<module>spring-boot-starters/wx-java-mp-spring-boot-starter</module> | |||
<module>spring-boot-starters/wx-java-miniapp-spring-boot-starter</module> | |||
<module>spring-boot-starters</module> | |||
<!--module>weixin-java-osgi</module--> | |||
</modules> | |||
@@ -27,7 +27,6 @@ | |||
<property name="max" value="120"/> | |||
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/> | |||
</module> | |||
<module name="AvoidStarImport"/> | |||
<module name="OneTopLevelClass"/> | |||
<module name="NoLineWrap"/> | |||
<module name="EmptyBlock"> | |||
@@ -0,0 +1,45 @@ | |||
<?xml version="1.0"?> | |||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" | |||
xmlns="http://maven.apache.org/POM/4.0.0"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>wx-java</artifactId> | |||
<version>3.6.0</version> | |||
</parent> | |||
<packaging>pom</packaging> | |||
<artifactId>wx-java-spring-boot-starters</artifactId> | |||
<name>WxJava - Spring Boot Starters</name> | |||
<description>WxJava 各个模块的 Spring Boot Starter</description> | |||
<properties> | |||
<spring.boot.version>2.1.4.RELEASE</spring.boot.version> | |||
</properties> | |||
<modules> | |||
<module>wx-java-miniapp-spring-boot-starter</module> | |||
<module>wx-java-mp-spring-boot-starter</module> | |||
<module>wx-java-pay-spring-boot-starter</module> | |||
<module>wx-java-open-spring-boot-starter</module> | |||
</modules> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-autoconfigure</artifactId> | |||
<version>${spring.boot.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-configuration-processor</artifactId> | |||
<version>${spring.boot.version}</version> | |||
<optional>true</optional> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<scope>provided</scope> | |||
</dependency> | |||
</dependencies> | |||
</project> |
@@ -3,10 +3,9 @@ | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<parent> | |||
<artifactId>wx-java</artifactId> | |||
<artifactId>wx-java-spring-boot-starters</artifactId> | |||
<groupId>com.github.binarywang</groupId> | |||
<version>3.5.0</version> | |||
<relativePath>../../</relativePath> | |||
<version>3.6.0</version> | |||
</parent> | |||
<modelVersion>4.0.0</modelVersion> | |||
@@ -14,27 +13,7 @@ | |||
<name>WxJava - Spring Boot Starter for MiniApp</name> | |||
<description>微信小程序开发的 Spring Boot Starter</description> | |||
<properties> | |||
<spring.boot.version>2.1.4.RELEASE</spring.boot.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-autoconfigure</artifactId> | |||
<version>${spring.boot.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-configuration-processor</artifactId> | |||
<version>${spring.boot.version}</version> | |||
<optional>true</optional> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-miniapp</artifactId> | |||
@@ -2,34 +2,18 @@ | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<modelVersion>4.0.0</modelVersion> | |||
<parent> | |||
<artifactId>wx-java-spring-boot-starters</artifactId> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>wx-java</artifactId> | |||
<version>3.5.0</version> | |||
<relativePath>../../</relativePath> | |||
<version>3.6.0</version> | |||
</parent> | |||
<modelVersion>4.0.0</modelVersion> | |||
<artifactId>wx-java-mp-spring-boot-starter</artifactId> | |||
<name>WxJava - Spring Boot Starter for MP</name> | |||
<description>微信公众号开发的 Spring Boot Starter</description> | |||
<properties> | |||
<spring.boot.version>2.1.4.RELEASE</spring.boot.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-autoconfigure</artifactId> | |||
<version>${spring.boot.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-configuration-processor</artifactId> | |||
<version>${spring.boot.version}</version> | |||
<optional>true</optional> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-mp</artifactId> | |||
@@ -38,11 +22,7 @@ | |||
<dependency> | |||
<groupId>redis.clients</groupId> | |||
<artifactId>jedis</artifactId> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<scope>provided</scope> | |||
<scope>compile</scope> | |||
</dependency> | |||
</dependencies> | |||
@@ -1,13 +1,9 @@ | |||
package com.binarywang.spring.starter.wxjava.mp.config; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import me.chanjar.weixin.mp.api.WxMpService; | |||
import me.chanjar.weixin.mp.api.*; | |||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; | |||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; | |||
import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | |||
import org.springframework.context.ApplicationContext; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
@@ -18,38 +14,118 @@ import org.springframework.context.annotation.Configuration; | |||
*/ | |||
@Configuration | |||
public class WxMpServiceAutoConfiguration { | |||
@Autowired | |||
private ApplicationContext ctx; | |||
@Bean | |||
@ConditionalOnMissingBean | |||
public WxMpService wxMpService(WxMpConfigStorage configStorage) { | |||
WxMpService wxMpService = new WxMpServiceImpl(); | |||
wxMpService.setWxMpConfigStorage(configStorage); | |||
registerWxMpSubService(wxMpService); | |||
return wxMpService; | |||
} | |||
@ConditionalOnBean(WxMpService.class) | |||
public Object registerWxMpSubService(WxMpService wxMpService) { | |||
ConfigurableListableBeanFactory factory = (ConfigurableListableBeanFactory) ctx.getAutowireCapableBeanFactory(); | |||
factory.registerSingleton("wxMpKefuService", wxMpService.getKefuService()); | |||
factory.registerSingleton("wxMpMaterialService", wxMpService.getMaterialService()); | |||
factory.registerSingleton("wxMpMenuService", wxMpService.getMenuService()); | |||
factory.registerSingleton("wxMpUserService", wxMpService.getUserService()); | |||
factory.registerSingleton("wxMpUserTagService", wxMpService.getUserTagService()); | |||
factory.registerSingleton("wxMpQrcodeService", wxMpService.getQrcodeService()); | |||
factory.registerSingleton("wxMpCardService", wxMpService.getCardService()); | |||
factory.registerSingleton("wxMpDataCubeService", wxMpService.getDataCubeService()); | |||
factory.registerSingleton("wxMpUserBlacklistService", wxMpService.getBlackListService()); | |||
factory.registerSingleton("wxMpStoreService", wxMpService.getStoreService()); | |||
factory.registerSingleton("wxMpTemplateMsgService", wxMpService.getTemplateMsgService()); | |||
factory.registerSingleton("wxMpSubscribeMsgService", wxMpService.getSubscribeMsgService()); | |||
factory.registerSingleton("wxMpDeviceService", wxMpService.getDeviceService()); | |||
factory.registerSingleton("wxMpShakeService", wxMpService.getShakeService()); | |||
factory.registerSingleton("wxMpMemberCardService", wxMpService.getMemberCardService()); | |||
factory.registerSingleton("wxMpMassMessageService", wxMpService.getMassMessageService()); | |||
return Boolean.TRUE; | |||
@Bean | |||
public WxMpKefuService wxMpKefuService(WxMpService wxMpService) { | |||
return wxMpService.getKefuService(); | |||
} | |||
@Bean | |||
public WxMpMaterialService wxMpMaterialService(WxMpService wxMpService) { | |||
return wxMpService.getMaterialService(); | |||
} | |||
@Bean | |||
public WxMpMenuService wxMpMenuService(WxMpService wxMpService) { | |||
return wxMpService.getMenuService(); | |||
} | |||
@Bean | |||
public WxMpUserService wxMpUserService(WxMpService wxMpService) { | |||
return wxMpService.getUserService(); | |||
} | |||
@Bean | |||
public WxMpUserTagService wxMpUserTagService(WxMpService wxMpService) { | |||
return wxMpService.getUserTagService(); | |||
} | |||
@Bean | |||
public WxMpQrcodeService wxMpQrcodeService(WxMpService wxMpService) { | |||
return wxMpService.getQrcodeService(); | |||
} | |||
@Bean | |||
public WxMpCardService wxMpCardService(WxMpService wxMpService) { | |||
return wxMpService.getCardService(); | |||
} | |||
@Bean | |||
public WxMpDataCubeService wxMpDataCubeService(WxMpService wxMpService) { | |||
return wxMpService.getDataCubeService(); | |||
} | |||
@Bean | |||
public WxMpUserBlacklistService wxMpUserBlacklistService(WxMpService wxMpService) { | |||
return wxMpService.getBlackListService(); | |||
} | |||
@Bean | |||
public WxMpStoreService wxMpStoreService(WxMpService wxMpService) { | |||
return wxMpService.getStoreService(); | |||
} | |||
@Bean | |||
public WxMpTemplateMsgService wxMpTemplateMsgService(WxMpService wxMpService) { | |||
return wxMpService.getTemplateMsgService(); | |||
} | |||
@Bean | |||
public WxMpSubscribeMsgService wxMpSubscribeMsgService(WxMpService wxMpService) { | |||
return wxMpService.getSubscribeMsgService(); | |||
} | |||
@Bean | |||
public WxMpDeviceService wxMpDeviceService(WxMpService wxMpService) { | |||
return wxMpService.getDeviceService(); | |||
} | |||
@Bean | |||
public WxMpShakeService wxMpShakeService(WxMpService wxMpService) { | |||
return wxMpService.getShakeService(); | |||
} | |||
@Bean | |||
public WxMpMemberCardService wxMpMemberCardService(WxMpService wxMpService) { | |||
return wxMpService.getMemberCardService(); | |||
} | |||
@Bean | |||
public WxMpMassMessageService wxMpMassMessageService(WxMpService wxMpService) { | |||
return wxMpService.getMassMessageService(); | |||
} | |||
@Bean | |||
public WxMpAiOpenService wxMpAiOpenService(WxMpService wxMpService) { | |||
return wxMpService.getAiOpenService(); | |||
} | |||
@Bean | |||
public WxMpWifiService wxMpWifiService(WxMpService wxMpService) { | |||
return wxMpService.getWifiService(); | |||
} | |||
@Bean | |||
public WxMpMarketingService wxMpMarketingService(WxMpService wxMpService) { | |||
return wxMpService.getMarketingService(); | |||
} | |||
@Bean | |||
public WxMpCommentService wxMpCommentService(WxMpService wxMpService) { | |||
return wxMpService.getCommentService(); | |||
} | |||
@Bean | |||
public WxMpOcrService wxMpOcrService(WxMpService wxMpService) { | |||
return wxMpService.getOcrService(); | |||
} | |||
} |
@@ -0,0 +1,34 @@ | |||
# wx-java-open-spring-boot-starter | |||
## 快速开始 | |||
1. 引入依赖 | |||
```xml | |||
<dependency> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>wx-java-open-spring-boot-starter</artifactId> | |||
<version>${version}</version> | |||
</dependency> | |||
``` | |||
2. 添加配置(application.properties) | |||
``` | |||
# 开放平台配置(必填) | |||
wx.open.appId = @appId | |||
wx.open.secret = @secret | |||
wx.open.token = @token | |||
wx.open.aesKey = @aesKey | |||
# 存储配置redis(可选), 优先使用(wx.open.config-storage.redis)配置的redis, 支持自定注入的JedisPool | |||
wx.open.config-storage.type = redis # 可选值, memory(默认), redis | |||
wx.open.config-storage.redis.host = 127.0.0.1 | |||
wx.open.config-storage.redis.port = 6379 | |||
``` | |||
3. 支持自动注入的类型: `WxOpenService, WxOpenMessageRouter, WxOpenComponentService` | |||
4. 覆盖自动配置: 自定义注入的bean会覆盖自动注入的 | |||
- WxOpenConfigStorage | |||
- WxOpenService | |||
@@ -0,0 +1,52 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project xmlns="http://maven.apache.org/POM/4.0.0" | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<parent> | |||
<artifactId>wx-java-spring-boot-starters</artifactId> | |||
<groupId>com.github.binarywang</groupId> | |||
<version>3.6.0</version> | |||
</parent> | |||
<modelVersion>4.0.0</modelVersion> | |||
<artifactId>wx-java-open-spring-boot-starter</artifactId> | |||
<name>WxJava - Spring Boot Starter for WxOpen</name> | |||
<description>微信开放平台开发的 Spring Boot Starter</description> | |||
<dependencies> | |||
<dependency> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-open</artifactId> | |||
<version>${project.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>redis.clients</groupId> | |||
<artifactId>jedis</artifactId> | |||
<scope>compile</scope> | |||
</dependency> | |||
</dependencies> | |||
<build> | |||
<plugins> | |||
<plugin> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-maven-plugin</artifactId> | |||
<version>${spring.boot.version}</version> | |||
</plugin> | |||
<plugin> | |||
<groupId>org.apache.maven.plugins</groupId> | |||
<artifactId>maven-source-plugin</artifactId> | |||
<version>2.2.1</version> | |||
<executions> | |||
<execution> | |||
<id>attach-sources</id> | |||
<goals> | |||
<goal>jar-no-fork</goal> | |||
</goals> | |||
</execution> | |||
</executions> | |||
</plugin> | |||
</plugins> | |||
</build> | |||
</project> |
@@ -0,0 +1,17 @@ | |||
package com.binarywang.spring.starter.wxjava.open.config; | |||
import com.binarywang.spring.starter.wxjava.open.properties.WxOpenProperties; | |||
import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||
import org.springframework.context.annotation.Configuration; | |||
import org.springframework.context.annotation.Import; | |||
/** | |||
* . | |||
* | |||
* @author someone | |||
*/ | |||
@Configuration | |||
@EnableConfigurationProperties(WxOpenProperties.class) | |||
@Import({WxOpenStorageAutoConfiguration.class, WxOpenServiceAutoConfiguration.class}) | |||
public class WxOpenAutoConfiguration { | |||
} |
@@ -0,0 +1,39 @@ | |||
package com.binarywang.spring.starter.wxjava.open.config; | |||
import me.chanjar.weixin.open.api.WxOpenComponentService; | |||
import me.chanjar.weixin.open.api.WxOpenConfigStorage; | |||
import me.chanjar.weixin.open.api.WxOpenService; | |||
import me.chanjar.weixin.open.api.impl.WxOpenMessageRouter; | |||
import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl; | |||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
/** | |||
* 微信开放平台相关服务自动注册. | |||
* | |||
* @author someone | |||
*/ | |||
@Configuration | |||
public class WxOpenServiceAutoConfiguration { | |||
@Bean | |||
@ConditionalOnMissingBean | |||
public WxOpenService wxOpenService(WxOpenConfigStorage configStorage) { | |||
WxOpenService wxOpenService = new WxOpenServiceImpl(); | |||
wxOpenService.setWxOpenConfigStorage(configStorage); | |||
return wxOpenService; | |||
} | |||
@Bean | |||
public WxOpenMessageRouter wxOpenMessageRouter(WxOpenService wxOpenService) { | |||
return new WxOpenMessageRouter(wxOpenService); | |||
} | |||
@Bean | |||
public WxOpenComponentService wxOpenComponentService(WxOpenService wxOpenService) { | |||
return wxOpenService.getWxOpenComponentService(); | |||
} | |||
} |
@@ -0,0 +1,93 @@ | |||
package com.binarywang.spring.starter.wxjava.open.config; | |||
import com.binarywang.spring.starter.wxjava.open.properties.RedisProperties; | |||
import com.binarywang.spring.starter.wxjava.open.properties.WxOpenProperties; | |||
import lombok.RequiredArgsConstructor; | |||
import me.chanjar.weixin.open.api.WxOpenConfigStorage; | |||
import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; | |||
import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.springframework.beans.factory.annotation.Autowired; | |||
import org.springframework.beans.factory.annotation.Value; | |||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | |||
import org.springframework.context.annotation.Bean; | |||
import org.springframework.context.annotation.Configuration; | |||
import redis.clients.jedis.JedisPool; | |||
import redis.clients.jedis.JedisPoolConfig; | |||
/** | |||
* 微信公众号存储策略自动配置. | |||
* | |||
* @author someone | |||
*/ | |||
@Configuration | |||
@RequiredArgsConstructor | |||
public class WxOpenStorageAutoConfiguration { | |||
private final WxOpenProperties properties; | |||
@Autowired(required = false) | |||
private JedisPool jedisPool; | |||
@Value("${wx.open.config-storage.redis.host:}") | |||
private String redisHost; | |||
@Bean | |||
@ConditionalOnMissingBean(WxOpenConfigStorage.class) | |||
public WxOpenConfigStorage wxOpenConfigStorage() { | |||
WxOpenProperties.ConfigStorage storage = properties.getConfigStorage(); | |||
WxOpenProperties.StorageType type = storage.getType(); | |||
if (type == WxOpenProperties.StorageType.redis) { | |||
return getWxOpenInRedisConfigStorage(); | |||
} | |||
return getWxOpenInMemoryConfigStorage(); | |||
} | |||
private WxOpenInMemoryConfigStorage getWxOpenInMemoryConfigStorage() { | |||
WxOpenInMemoryConfigStorage config = new WxOpenInMemoryConfigStorage(); | |||
setWxOpenInfo(config); | |||
return config; | |||
} | |||
private WxOpenInRedisConfigStorage getWxOpenInRedisConfigStorage() { | |||
JedisPool poolToUse = jedisPool; | |||
if (jedisPool == null || StringUtils.isNotEmpty(redisHost)) { | |||
poolToUse = getJedisPool(); | |||
} | |||
WxOpenInRedisConfigStorage config = new WxOpenInRedisConfigStorage(poolToUse); | |||
setWxOpenInfo(config); | |||
return config; | |||
} | |||
private void setWxOpenInfo(WxOpenConfigStorage config) { | |||
config.setComponentAppId(properties.getAppId()); | |||
config.setComponentAppSecret(properties.getSecret()); | |||
config.setComponentToken(properties.getToken()); | |||
config.setComponentAesKey(properties.getAesKey()); | |||
} | |||
private JedisPool getJedisPool() { | |||
WxOpenProperties.ConfigStorage storage = properties.getConfigStorage(); | |||
RedisProperties 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); | |||
JedisPool pool = new JedisPool(config, redis.getHost(), redis.getPort(), | |||
redis.getTimeout(), redis.getPassword(), redis.getDatabase()); | |||
return pool; | |||
} | |||
} |
@@ -0,0 +1,45 @@ | |||
package com.binarywang.spring.starter.wxjava.open.properties; | |||
import lombok.Data; | |||
import java.io.Serializable; | |||
/** | |||
* Redis配置. | |||
* | |||
* @author someone | |||
*/ | |||
@Data | |||
public class RedisProperties 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; | |||
private Integer maxActive; | |||
private Integer maxIdle; | |||
private Integer maxWaitMillis; | |||
private Integer minIdle; | |||
} |
@@ -0,0 +1,68 @@ | |||
package com.binarywang.spring.starter.wxjava.open.properties; | |||
import lombok.Data; | |||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||
import java.io.Serializable; | |||
import static com.binarywang.spring.starter.wxjava.open.properties.WxOpenProperties.PREFIX; | |||
import static com.binarywang.spring.starter.wxjava.open.properties.WxOpenProperties.StorageType.memory; | |||
/** | |||
* 微信接入相关配置属性. | |||
* | |||
* @author someone | |||
*/ | |||
@Data | |||
@ConfigurationProperties(PREFIX) | |||
public class WxOpenProperties { | |||
public static final String PREFIX = "wx.open"; | |||
/** | |||
* 设置微信开放平台的appid. | |||
*/ | |||
private String appId; | |||
/** | |||
* 设置微信开放平台的app secret. | |||
*/ | |||
private String secret; | |||
/** | |||
* 设置微信开放平台的token. | |||
*/ | |||
private String token; | |||
/** | |||
* 设置微信开放平台的EncodingAESKey. | |||
*/ | |||
private String aesKey; | |||
/** | |||
* 存储策略, memory, redis. | |||
*/ | |||
private ConfigStorage configStorage = new ConfigStorage(); | |||
@Data | |||
public static class ConfigStorage implements Serializable { | |||
private static final long serialVersionUID = 4815731027000065434L; | |||
private StorageType type = memory; | |||
private RedisProperties redis = new RedisProperties(); | |||
} | |||
public enum StorageType { | |||
/** | |||
* 内存. | |||
*/ | |||
memory, | |||
/** | |||
* redis. | |||
*/ | |||
redis | |||
} | |||
} |
@@ -0,0 +1 @@ | |||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.binarywang.spring.starter.wxjava.open.config.WxOpenAutoConfiguration |
@@ -3,10 +3,9 @@ | |||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
<parent> | |||
<artifactId>wx-java</artifactId> | |||
<artifactId>wx-java-spring-boot-starters</artifactId> | |||
<groupId>com.github.binarywang</groupId> | |||
<version>3.5.0</version> | |||
<relativePath>../../</relativePath> | |||
<version>3.6.0</version> | |||
</parent> | |||
<modelVersion>4.0.0</modelVersion> | |||
@@ -14,27 +13,7 @@ | |||
<name>WxJava - Spring Boot Starter for WxPay</name> | |||
<description>微信支付开发的 Spring Boot Starter</description> | |||
<properties> | |||
<spring.boot.version>2.1.4.RELEASE</spring.boot.version> | |||
</properties> | |||
<dependencies> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-autoconfigure</artifactId> | |||
<version>${spring.boot.version}</version> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.springframework.boot</groupId> | |||
<artifactId>spring-boot-configuration-processor</artifactId> | |||
<version>${spring.boot.version}</version> | |||
<optional>true</optional> | |||
</dependency> | |||
<dependency> | |||
<groupId>org.projectlombok</groupId> | |||
<artifactId>lombok</artifactId> | |||
<scope>provided</scope> | |||
</dependency> | |||
<dependency> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>weixin-java-pay</artifactId> | |||
@@ -6,7 +6,7 @@ | |||
<parent> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>wx-java</artifactId> | |||
<version>3.5.0</version> | |||
<version>3.6.0</version> | |||
</parent> | |||
<artifactId>weixin-java-common</artifactId> | |||
@@ -10,23 +10,23 @@ package me.chanjar.weixin.common; | |||
*/ | |||
public enum WxType { | |||
/** | |||
* 企业微信 | |||
* 企业微信. | |||
*/ | |||
CP, | |||
/** | |||
* 微信公众号 | |||
* 微信公众号. | |||
*/ | |||
MP, | |||
/** | |||
* 微信小程序 | |||
* 微信小程序. | |||
*/ | |||
MiniApp, | |||
/** | |||
* 微信开放平台 | |||
* 微信开放平台. | |||
*/ | |||
Open, | |||
/** | |||
* 微信支付 | |||
* 微信支付. | |||
*/ | |||
Pay; | |||
} |
@@ -380,4 +380,19 @@ public class WxConsts { | |||
public static final String VIDEO = "video"; | |||
} | |||
/** | |||
* 网络检测入参. | |||
*/ | |||
public static class NetCheckArgs { | |||
public static final String ACTIONDNS = "dns"; | |||
public static final String ACTIONPING = "ping"; | |||
public static final String ACTIONALL = "all"; | |||
public static final String OPERATORUNICOM = "UNICOM"; | |||
public static final String OPERATORCHINANET = "CHINANET"; | |||
public static final String OPERATORCAP = "CAP"; | |||
public static final String OPERATORDEFAULT = "DEFAULT"; | |||
} | |||
} |
@@ -0,0 +1,43 @@ | |||
package me.chanjar.weixin.common.bean; | |||
import lombok.Data; | |||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||
import java.io.Serializable; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
/** | |||
* 网络检测. | |||
* @author billytomato | |||
*/ | |||
@Data | |||
public class WxNetCheckResult implements Serializable { | |||
private static final long serialVersionUID = 6918924418847404172L; | |||
private List<WxNetCheckDnsInfo> dnsInfos = new ArrayList<>(); | |||
private List<WxNetCheckPingInfo> pingInfos = new ArrayList<>(); | |||
public static WxNetCheckResult fromJson(String json) { | |||
return WxGsonBuilder.create().fromJson(json, WxNetCheckResult.class); | |||
} | |||
@Data | |||
public static class WxNetCheckDnsInfo implements Serializable{ | |||
private static final long serialVersionUID = 82631178029516008L; | |||
private String ip; | |||
private String realOperator; | |||
} | |||
@Data | |||
public static class WxNetCheckPingInfo implements Serializable{ | |||
private static final long serialVersionUID = -1871970825359178319L; | |||
private String ip; | |||
private String fromOperator; | |||
private String packageLoss; | |||
private String time; | |||
} | |||
} | |||
@@ -14,771 +14,771 @@ import lombok.Getter; | |||
@Getter | |||
public enum WxCpErrorMsgEnum { | |||
/** | |||
* 系统繁忙;服务器暂不可用,建议稍候重试。建议重试次数不超过3次。 | |||
* 系统繁忙;服务器暂不可用,建议稍候重试。建议重试次数不超过3次. | |||
*/ | |||
CODE_1(-1, "系统繁忙;服务器暂不可用,建议稍候重试。建议重试次数不超过3次。"), | |||
/** | |||
* 请求成功;接口调用成功 | |||
* 请求成功;接口调用成功. | |||
*/ | |||
CODE_0(0, "请求成功;接口调用成功"), | |||
/** | |||
* 不合法的secret参数;secret在应用详情/通讯录管理助手可查看 | |||
* 不合法的secret参数;secret在应用详情/通讯录管理助手可查看. | |||
*/ | |||
CODE_40001(40001, "不合法的secret参数;secret在应用详情/通讯录管理助手可查看"), | |||
/** | |||
* 无效的UserID | |||
* 无效的UserID. | |||
*/ | |||
CODE_40003(40003, "无效的UserID"), | |||
/** | |||
* 不合法的媒体文件类型;不满足系统文件要求。参考:上传的媒体文件限制 | |||
* 不合法的媒体文件类型;不满足系统文件要求。参考:上传的媒体文件限制. | |||
*/ | |||
CODE_40004(40004, "不合法的媒体文件类型;不满足系统文件要求。参考:上传的媒体文件限制"), | |||
/** | |||
* 不合法的type参数;合法的type取值,参考:上传临时素材 | |||
* 不合法的type参数;合法的type取值,参考:上传临时素材. | |||
*/ | |||
CODE_40005(40005, "不合法的type参数;合法的type取值,参考:上传临时素材"), | |||
/** | |||
* 不合法的文件大小;系统文件要求,参考:上传的媒体文件限制 | |||
* 不合法的文件大小;系统文件要求,参考:上传的媒体文件限制. | |||
*/ | |||
CODE_40006(40006, "不合法的文件大小;系统文件要求,参考:上传的媒体文件限制"), | |||
/** | |||
* 不合法的media_id参数 | |||
* 不合法的media_id参数. | |||
*/ | |||
CODE_40007(40007, "不合法的media_id参数"), | |||
/** | |||
* 不合法的msgtype参数;合法的msgtype取值,参考:消息类型 | |||
* 不合法的msgtype参数;合法的msgtype取值,参考:消息类型. | |||
*/ | |||
CODE_40008(40008, "不合法的msgtype参数;合法的msgtype取值,参考:消息类型"), | |||
/** | |||
* 上传图片大小不是有效值;图片大小的系统限制,参考上传的媒体文件限制 | |||
* 上传图片大小不是有效值;图片大小的系统限制,参考上传的媒体文件限制. | |||
*/ | |||
CODE_40009(40009, "上传图片大小不是有效值;图片大小的系统限制,参考上传的媒体文件限制"), | |||
/** | |||
* 上传视频大小不是有效值;视频大小的系统限制,参考上传的媒体文件限制 | |||
* 上传视频大小不是有效值;视频大小的系统限制,参考上传的媒体文件限制. | |||
*/ | |||
CODE_40011(40011, "上传视频大小不是有效值;视频大小的系统限制,参考上传的媒体文件限制"), | |||
/** | |||
* 不合法的CorpID;需确认CorpID是否填写正确,在 web管理端-设置 可查看 | |||
* 不合法的CorpID;需确认CorpID是否填写正确,在 web管理端-设置 可查看. | |||
*/ | |||
CODE_40013(40013, "不合法的CorpID;需确认CorpID是否填写正确,在 web管理端-设置 可查看"), | |||
/** | |||
* 不合法的access_token | |||
* 不合法的access_token. | |||
*/ | |||
CODE_40014(40014, "不合法的access_token"), | |||
/** | |||
* 不合法的按钮个数;菜单按钮1-3个 | |||
* 不合法的按钮个数;菜单按钮1-3个. | |||
*/ | |||
CODE_40016(40016, "不合法的按钮个数;菜单按钮1-3个"), | |||
/** | |||
* 不合法的按钮类型;支持的类型,参考:按钮类型 | |||
* 不合法的按钮类型;支持的类型,参考:按钮类型. | |||
*/ | |||
CODE_40017(40017, "不合法的按钮类型;支持的类型,参考:按钮类型"), | |||
/** | |||
* 不合法的按钮名字长度;长度应不超过16个字节 | |||
* 不合法的按钮名字长度;长度应不超过16个字节. | |||
*/ | |||
CODE_40018(40018, "不合法的按钮名字长度;长度应不超过16个字节"), | |||
/** | |||
* 不合法的按钮KEY长度;长度应不超过128字节 | |||
* 不合法的按钮KEY长度;长度应不超过128字节. | |||
*/ | |||
CODE_40019(40019, "不合法的按钮KEY长度;长度应不超过128字节"), | |||
/** | |||
* 不合法的按钮URL长度;长度应不超过1024字节 | |||
* 不合法的按钮URL长度;长度应不超过1024字节. | |||
*/ | |||
CODE_40020(40020, "不合法的按钮URL长度;长度应不超过1024字节"), | |||
/** | |||
* 不合法的子菜单级数;只能包含一级菜单和二级菜单 | |||
* 不合法的子菜单级数;只能包含一级菜单和二级菜单. | |||
*/ | |||
CODE_40022(40022, "不合法的子菜单级数;只能包含一级菜单和二级菜单"), | |||
/** | |||
* 不合法的子菜单按钮个数;子菜单按钮1-5个 | |||
* 不合法的子菜单按钮个数;子菜单按钮1-5个. | |||
*/ | |||
CODE_40023(40023, "不合法的子菜单按钮个数;子菜单按钮1-5个"), | |||
/** | |||
* 不合法的子菜单按钮类型;支持的类型,参考:按钮类型 | |||
* 不合法的子菜单按钮类型;支持的类型,参考:按钮类型. | |||
*/ | |||
CODE_40024(40024, "不合法的子菜单按钮类型;支持的类型,参考:按钮类型"), | |||
/** | |||
* 不合法的子菜单按钮名字长度;支持的类型,参考:按钮类型 | |||
* 不合法的子菜单按钮名字长度;支持的类型,参考:按钮类型. | |||
*/ | |||
CODE_40025(40025, "不合法的子菜单按钮名字长度;支持的类型,参考:按钮类型"), | |||
/** | |||
* 不合法的子菜单按钮KEY长度;长度应不超过60个字节 | |||
* 不合法的子菜单按钮KEY长度;长度应不超过60个字节. | |||
*/ | |||
CODE_40026(40026, "不合法的子菜单按钮KEY长度;长度应不超过60个字节"), | |||
/** | |||
* 不合法的子菜单按钮URL长度;长度应不超过1024字节 | |||
* 不合法的子菜单按钮URL长度;长度应不超过1024字节. | |||
*/ | |||
CODE_40027(40027, "不合法的子菜单按钮URL长度;长度应不超过1024字节"), | |||
/** | |||
* 不合法的oauth_code | |||
* 不合法的oauth_code. | |||
*/ | |||
CODE_40029(40029, "不合法的oauth_code"), | |||
/** | |||
* 不合法的UserID列表;指定的UserID列表,至少存在一个UserID不在通讯录中 | |||
* 不合法的UserID列表;指定的UserID列表,至少存在一个UserID不在通讯录中. | |||
*/ | |||
CODE_40031(40031, "不合法的UserID列表;指定的UserID列表,至少存在一个UserID不在通讯录中"), | |||
/** | |||
* 不合法的UserID列表长度 | |||
* 不合法的UserID列表长度. | |||
*/ | |||
CODE_40032(40032, "不合法的UserID列表长度"), | |||
/** | |||
* 不合法的请求字符;不能包含\\uxxxx格式的字符 | |||
* 不合法的请求字符;不能包含\\uxxxx格式的字符. | |||
*/ | |||
CODE_40033(40033, "不合法的请求字符;不能包含\\uxxxx格式的字符"), | |||
/** | |||
* 不合法的参数 | |||
* 不合法的参数. | |||
*/ | |||
CODE_40035(40035, "不合法的参数"), | |||
/** | |||
* chatid不存在;会话需要先创建后,才可修改会话详情或者发起聊天 | |||
* chatid不存在;会话需要先创建后,才可修改会话详情或者发起聊天. | |||
*/ | |||
CODE_40050(40050, "chatid不存在;会话需要先创建后,才可修改会话详情或者发起聊天"), | |||
/** | |||
* 不合法的子菜单url域名 | |||
* 不合法的子菜单url域名. | |||
*/ | |||
CODE_40054(40054, "不合法的子菜单url域名"), | |||
/** | |||
* 不合法的菜单url域名 | |||
* 不合法的菜单url域名. | |||
*/ | |||
CODE_40055(40055, "不合法的菜单url域名"), | |||
/** | |||
* 不合法的agentid | |||
* 不合法的agentid. | |||
*/ | |||
CODE_40056(40056, "不合法的agentid"), | |||
/** | |||
* 不合法的callbackurl或者callbackurl验证失败;可自助到开发调试工具重现 | |||
* 不合法的callbackurl或者callbackurl验证失败;可自助到开发调试工具重现. | |||
*/ | |||
CODE_40057(40057, "不合法的callbackurl或者callbackurl验证失败;可自助到开发调试工具重现"), | |||
/** | |||
* 不合法的参数;传递参数不符合系统要求,需要参照具体API接口说明 | |||
* 不合法的参数;传递参数不符合系统要求,需要参照具体API接口说明. | |||
*/ | |||
CODE_40058(40058, "不合法的参数;传递参数不符合系统要求,需要参照具体API接口说明"), | |||
/** | |||
* 不合法的上报地理位置标志位;开关标志位只能填 0 或者 1 | |||
* 不合法的上报地理位置标志位;开关标志位只能填 0 或者 1. | |||
*/ | |||
CODE_40059(40059, "不合法的上报地理位置标志位;开关标志位只能填 0 或者 1"), | |||
/** | |||
* 参数为空 | |||
* 参数为空. | |||
*/ | |||
CODE_40063(40063, "参数为空"), | |||
/** | |||
* 不合法的部门列表;部门列表为空,或者至少存在一个部门ID不存在于通讯录中 | |||
* 不合法的部门列表;部门列表为空,或者至少存在一个部门ID不存在于通讯录中. | |||
*/ | |||
CODE_40066(40066, "不合法的部门列表;部门列表为空,或者至少存在一个部门ID不存在于通讯录中"), | |||
/** | |||
* 不合法的标签ID;标签ID未指定,或者指定的标签ID不存在 | |||
* 不合法的标签ID;标签ID未指定,或者指定的标签ID不存在. | |||
*/ | |||
CODE_40068(40068, "不合法的标签ID;标签ID未指定,或者指定的标签ID不存在"), | |||
/** | |||
* 指定的标签范围结点全部无效 | |||
* 指定的标签范围结点全部无效. | |||
*/ | |||
CODE_40070(40070, "指定的标签范围结点全部无效"), | |||
/** | |||
* 不合法的标签名字;标签名字已经存在 | |||
* 不合法的标签名字;标签名字已经存在. | |||
*/ | |||
CODE_40071(40071, "不合法的标签名字;标签名字已经存在"), | |||
/** | |||
* 不合法的标签名字长度;不允许为空,最大长度限制为32个字(汉字或英文字母) | |||
* 不合法的标签名字长度;不允许为空,最大长度限制为32个字(汉字或英文字母). | |||
*/ | |||
CODE_40072(40072, "不合法的标签名字长度;不允许为空,最大长度限制为32个字(汉字或英文字母)"), | |||
/** | |||
* 不合法的openid;openid不存在,需确认获取来源 | |||
* 不合法的openid;openid不存在,需确认获取来源. | |||
*/ | |||
CODE_40073(40073, "不合法的openid;openid不存在,需确认获取来源"), | |||
/** | |||
* news消息不支持保密消息类型;图文消息支持保密类型需改用mpnews | |||
* news消息不支持保密消息类型;图文消息支持保密类型需改用mpnews. | |||
*/ | |||
CODE_40074(40074, "news消息不支持保密消息类型;图文消息支持保密类型需改用mpnews"), | |||
/** | |||
* 不合法的pre_auth_code参数;预授权码不存在,参考:获取预授权码 | |||
* 不合法的pre_auth_code参数;预授权码不存在,参考:获取预授权码. | |||
*/ | |||
CODE_40077(40077, "不合法的pre_auth_code参数;预授权码不存在,参考:获取预授权码"), | |||
/** | |||
* 不合法的auth_code参数;需确认获取来源,并且只能消费一次 | |||
* 不合法的auth_code参数;需确认获取来源,并且只能消费一次. | |||
*/ | |||
CODE_40078(40078, "不合法的auth_code参数;需确认获取来源,并且只能消费一次"), | |||
/** | |||
* 不合法的suite_secret;套件secret可在第三方管理端套件详情查看 | |||
* 不合法的suite_secret;套件secret可在第三方管理端套件详情查看. | |||
*/ | |||
CODE_40080(40080, "不合法的suite_secret;套件secret可在第三方管理端套件详情查看"), | |||
/** | |||
* 不合法的suite_token | |||
* 不合法的suite_token. | |||
*/ | |||
CODE_40082(40082, "不合法的suite_token"), | |||
/** | |||
* 不合法的suite_id;suite_id不存在 | |||
* 不合法的suite_id;suite_id不存在. | |||
*/ | |||
CODE_40083(40083, "不合法的suite_id;suite_id不存在"), | |||
/** | |||
* 不合法的permanent_code参数 | |||
* 不合法的permanent_code参数. | |||
*/ | |||
CODE_40084(40084, "不合法的permanent_code参数"), | |||
/** | |||
* 不合法的的suite_ticket参数;suite_ticket不存在或者已失效 | |||
* 不合法的的suite_ticket参数;suite_ticket不存在或者已失效. | |||
*/ | |||
CODE_40085(40085, "不合法的的suite_ticket参数;suite_ticket不存在或者已失效"), | |||
/** | |||
* 不合法的第三方应用appid;至少有一个不存在应用id | |||
* 不合法的第三方应用appid;至少有一个不存在应用id. | |||
*/ | |||
CODE_40086(40086, "不合法的第三方应用appid;至少有一个不存在应用id"), | |||
/** | |||
* jobid不存在;请检查 jobid 来源 | |||
* jobid不存在;请检查 jobid 来源. | |||
*/ | |||
CODE_40088(40088, "jobid不存在;请检查 jobid 来源"), | |||
/** | |||
* 批量任务的结果已清理;系统仅保存最近5次批量任务的结果。可在通讯录查看实际导入情况 | |||
* 批量任务的结果已清理;系统仅保存最近5次批量任务的结果。可在通讯录查看实际导入情况. | |||
*/ | |||
CODE_40089(40089, "批量任务的结果已清理;系统仅保存最近5次批量任务的结果。可在通讯录查看实际导入情况"), | |||
/** | |||
* secret不合法;可能用了别的企业的secret | |||
* secret不合法;可能用了别的企业的secret. | |||
*/ | |||
CODE_40091(40091, "secret不合法;可能用了别的企业的secret"), | |||
/** | |||
* 导入文件存在不合法的内容 | |||
* 导入文件存在不合法的内容. | |||
*/ | |||
CODE_40092(40092, "导入文件存在不合法的内容"), | |||
/** | |||
* 不合法的jsapi_ticket参数;ticket已失效,或者拼写错误 | |||
* 不合法的jsapi_ticket参数;ticket已失效,或者拼写错误. | |||
*/ | |||
CODE_40093(40093, "不合法的jsapi_ticket参数;ticket已失效,或者拼写错误"), | |||
/** | |||
* 不合法的URL;缺少主页URL参数,或者URL不合法(链接需要带上协议头,以 http:// 或者 https:// 开头) | |||
* 不合法的URL;缺少主页URL参数,或者URL不合法(链接需要带上协议头,以 http:// 或者 https:// 开头). | |||
*/ | |||
CODE_40094(40094, "不合法的URL;缺少主页URL参数,或者URL不合法(链接需要带上协议头,以 http:// 或者 https:// 开头)"), | |||
/** | |||
* 缺少access_token参数 | |||
* 缺少access_token参数. | |||
*/ | |||
CODE_41001(41001, "缺少access_token参数"), | |||
/** | |||
* 缺少corpid参数 | |||
* 缺少corpid参数. | |||
*/ | |||
CODE_41002(41002, "缺少corpid参数"), | |||
/** | |||
* 缺少secret参数 | |||
* 缺少secret参数. | |||
*/ | |||
CODE_41004(41004, "缺少secret参数"), | |||
/** | |||
* 缺少media_id参数;media_id为调用接口必填参数,请确认是否有传递 | |||
* 缺少media_id参数;media_id为调用接口必填参数,请确认是否有传递. | |||
*/ | |||
CODE_41006(41006, "缺少media_id参数;media_id为调用接口必填参数,请确认是否有传递"), | |||
/** | |||
* 缺少auth code参数 | |||
* 缺少auth code参数. | |||
*/ | |||
CODE_41008(41008, "缺少auth code参数"), | |||
/** | |||
* 缺少userid参数 | |||
* 缺少userid参数. | |||
*/ | |||
CODE_41009(41009, "缺少userid参数"), | |||
/** | |||
* 缺少url参数 | |||
* 缺少url参数. | |||
*/ | |||
CODE_41010(41010, "缺少url参数"), | |||
/** | |||
* 缺少agentid参数 | |||
* 缺少agentid参数. | |||
*/ | |||
CODE_41011(41011, "缺少agentid参数"), | |||
/** | |||
* 缺少 description 参数;发送文本卡片消息接口,description 是必填字段 | |||
* 缺少 description 参数;发送文本卡片消息接口,description 是必填字段. | |||
*/ | |||
CODE_41033(41033, "缺少 description 参数;发送文本卡片消息接口,description 是必填字段"), | |||
/** | |||
* 缺少title参数;发送图文消息,标题是必填参数。请确认参数是否有传递。 | |||
* 缺少title参数;发送图文消息,标题是必填参数。请确认参数是否有传递. | |||
*/ | |||
CODE_41016(41016, "缺少title参数;发送图文消息,标题是必填参数。请确认参数是否有传递。"), | |||
/** | |||
* 缺少 department 参数 | |||
* 缺少 department 参数. | |||
*/ | |||
CODE_41019(41019, "缺少 department 参数"), | |||
/** | |||
* 缺少tagid参数 | |||
* 缺少tagid参数. | |||
*/ | |||
CODE_41017(41017, "缺少tagid参数"), | |||
/** | |||
* 缺少suite_id参数 | |||
* 缺少suite_id参数. | |||
*/ | |||
CODE_41021(41021, "缺少suite_id参数"), | |||
/** | |||
* 缺少suite_access_token参数 | |||
* 缺少suite_access_token参数. | |||
*/ | |||
CODE_41022(41022, "缺少suite_access_token参数"), | |||
/** | |||
* 缺少suite_ticket参数 | |||
* 缺少suite_ticket参数. | |||
*/ | |||
CODE_41023(41023, "缺少suite_ticket参数"), | |||
/** | |||
* 缺少secret参数 | |||
* 缺少secret参数. | |||
*/ | |||
CODE_41024(41024, "缺少secret参数"), | |||
/** | |||
* 缺少permanent_code参数 | |||
* 缺少permanent_code参数. | |||
*/ | |||
CODE_41025(41025, "缺少permanent_code参数"), | |||
/** | |||
* access_token已过期;access_token有时效性,需要重新获取一次 | |||
* access_token已过期;access_token有时效性,需要重新获取一次. | |||
*/ | |||
CODE_42001(42001, "access_token已过期;access_token有时效性,需要重新获取一次"), | |||
/** | |||
* pre_auth_code已过期;pre_auth_code有时效性,需要重新获取一次 | |||
* pre_auth_code已过期;pre_auth_code有时效性,需要重新获取一次. | |||
*/ | |||
CODE_42007(42007, "pre_auth_code已过期;pre_auth_code有时效性,需要重新获取一次"), | |||
/** | |||
* suite_access_token已过期;suite_access_token有时效性,需要重新获取一次 | |||
* suite_access_token已过期;suite_access_token有时效性,需要重新获取一次. | |||
*/ | |||
CODE_42009(42009, "suite_access_token已过期;suite_access_token有时效性,需要重新获取一次"), | |||
/** | |||
* 指定的userid未绑定微信或未关注微信插件;需要成员使用微信登录企业微信或者关注微信插件才能获取openid | |||
* 指定的userid未绑定微信或未关注微信插件;需要成员使用微信登录企业微信或者关注微信插件才能获取openid. | |||
*/ | |||
CODE_43004(43004, "指定的userid未绑定微信或未关注微信插件;需要成员使用微信登录企业微信或者关注微信插件才能获取openid"), | |||
/** | |||
* 多媒体文件为空;上传格式参考:上传临时素材,确认header和body的内容正确。 | |||
* 多媒体文件为空;上传格式参考:上传临时素材,确认header和body的内容正确. | |||
*/ | |||
CODE_44001(44001, "多媒体文件为空;上传格式参考:上传临时素材,确认header和body的内容正确。"), | |||
/** | |||
* 文本消息content参数为空;发文本消息content为必填参数,且不能为空 | |||
* 文本消息content参数为空;发文本消息content为必填参数,且不能为空. | |||
*/ | |||
CODE_44004(44004, "文本消息content参数为空;发文本消息content为必填参数,且不能为空"), | |||
/** | |||
* 多媒体文件大小超过限制;图片不可超过5M;音频不可超过5M;文件不可超过20M | |||
* 多媒体文件大小超过限制;图片不可超过5M;音频不可超过5M;文件不可超过20M. | |||
*/ | |||
CODE_45001(45001, "多媒体文件大小超过限制;图片不可超过5M;音频不可超过5M;文件不可超过20M"), | |||
/** | |||
* 消息内容大小超过限制 | |||
* 消息内容大小超过限制. | |||
*/ | |||
CODE_45002(45002, "消息内容大小超过限制"), | |||
/** | |||
* 应用description参数长度不符合系统限制;设置应用若带有description参数,则长度必须为4至120个字符 | |||
* 应用description参数长度不符合系统限制;设置应用若带有description参数,则长度必须为4至120个字符. | |||
*/ | |||
CODE_45004(45004, "应用description参数长度不符合系统限制;设置应用若带有description参数,则长度必须为4至120个字符"), | |||
/** | |||
* 语音播放时间超过限制;语音播放时长不能超过60秒 | |||
* 语音播放时间超过限制;语音播放时长不能超过60秒. | |||
*/ | |||
CODE_45007(45007, "语音播放时间超过限制;语音播放时长不能超过60秒"), | |||
/** | |||
* 图文消息的文章数量不符合系统限制;图文消息的文章数量不能超过8条 | |||
* 图文消息的文章数量不符合系统限制;图文消息的文章数量不能超过8条. | |||
*/ | |||
CODE_45008(45008, "图文消息的文章数量不符合系统限制;图文消息的文章数量不能超过8条"), | |||
/** | |||
* 接口调用超过限制 | |||
* 接口调用超过限制. | |||
*/ | |||
CODE_45009(45009, "接口调用超过限制"), | |||
/** | |||
* 应用name参数长度不符合系统限制;设置应用若带有name参数,则不允许为空,且不超过32个字符 | |||
* 应用name参数长度不符合系统限制;设置应用若带有name参数,则不允许为空,且不超过32个字符. | |||
*/ | |||
CODE_45022(45022, "应用name参数长度不符合系统限制;设置应用若带有name参数,则不允许为空,且不超过32个字符"), | |||
/** | |||
* 帐号数量超过上限 | |||
* 帐号数量超过上限. | |||
*/ | |||
CODE_45024(45024, "帐号数量超过上限"), | |||
/** | |||
* 触发删除用户数的保护;限制参考:全量覆盖成员 | |||
* 触发删除用户数的保护;限制参考:全量覆盖成员. | |||
*/ | |||
CODE_45026(45026, "触发删除用户数的保护;限制参考:全量覆盖成员"), | |||
/** | |||
* 图文消息author参数长度超过限制;最长64个字节 | |||
* 图文消息author参数长度超过限制;最长64个字节. | |||
*/ | |||
CODE_45032(45032, "图文消息author参数长度超过限制;最长64个字节"), | |||
/** | |||
* 接口并发调用超过限制 | |||
* 接口并发调用超过限制. | |||
*/ | |||
CODE_45033(45033, "接口并发调用超过限制"), | |||
/** | |||
* 菜单未设置;菜单需发布后才能获取到数据 | |||
* 菜单未设置;菜单需发布后才能获取到数据. | |||
*/ | |||
CODE_46003(46003, "菜单未设置;菜单需发布后才能获取到数据"), | |||
/** | |||
* 指定的用户不存在;需要确认指定的用户存在于通讯录中 | |||
* 指定的用户不存在;需要确认指定的用户存在于通讯录中. | |||
*/ | |||
CODE_46004(46004, "指定的用户不存在;需要确认指定的用户存在于通讯录中"), | |||
/** | |||
* API接口无权限调用 | |||
* API接口无权限调用. | |||
*/ | |||
CODE_48002(48002, "API接口无权限调用"), | |||
/** | |||
* 不合法的suite_id;确认suite_access_token由指定的suite_id生成 | |||
* 不合法的suite_id;确认suite_access_token由指定的suite_id生成. | |||
*/ | |||
CODE_48003(48003, "不合法的suite_id;确认suite_access_token由指定的suite_id生成"), | |||
/** | |||
* 授权关系无效;可能是无授权或授权已被取消 | |||
* 授权关系无效;可能是无授权或授权已被取消. | |||
*/ | |||
CODE_48004(48004, "授权关系无效;可能是无授权或授权已被取消"), | |||
/** | |||
* API接口已废弃;接口已不再支持,建议改用新接口或者新方案 | |||
* API接口已废弃;接口已不再支持,建议改用新接口或者新方案. | |||
*/ | |||
CODE_48005(48005, "API接口已废弃;接口已不再支持,建议改用新接口或者新方案"), | |||
/** | |||
* redirect_url未登记可信域名 | |||
* redirect_url未登记可信域名. | |||
*/ | |||
CODE_50001(50001, "redirect_url未登记可信域名"), | |||
/** | |||
* 成员不在权限范围;请检查应用或管理组的权限范围 | |||
* 成员不在权限范围;请检查应用或管理组的权限范围. | |||
*/ | |||
CODE_50002(50002, "成员不在权限范围;请检查应用或管理组的权限范围"), | |||
/** | |||
* 应用已禁用;禁用的应用无法使用API接口。可在”管理端-企业应用”启用应用 | |||
* 应用已禁用;禁用的应用无法使用API接口。可在”管理端-企业应用”启用应用. | |||
*/ | |||
CODE_50003(50003, "应用已禁用;禁用的应用无法使用API接口。可在”管理端-企业应用”启用应用"), | |||
/** | |||
* 部门长度不符合限制;部门名称不能为空且长度不能超过32个字 | |||
* 部门长度不符合限制;部门名称不能为空且长度不能超过32个字. | |||
*/ | |||
CODE_60001(60001, "部门长度不符合限制;部门名称不能为空且长度不能超过32个字"), | |||
/** | |||
* 部门ID不存在;需要确认部门ID是否有带,并且存在通讯录中 | |||
* 部门ID不存在;需要确认部门ID是否有带,并且存在通讯录中. | |||
*/ | |||
CODE_60003(60003, "部门ID不存在;需要确认部门ID是否有带,并且存在通讯录中"), | |||
/** | |||
* 父部门不存在;需要确认父亲部门ID是否有带,并且存在通讯录中 | |||
* 父部门不存在;需要确认父亲部门ID是否有带,并且存在通讯录中. | |||
*/ | |||
CODE_60004(60004, "父部门不存在;需要确认父亲部门ID是否有带,并且存在通讯录中"), | |||
/** | |||
* 部门下存在成员;不允许删除有成员的部门 | |||
* 部门下存在成员;不允许删除有成员的部门. | |||
*/ | |||
CODE_60005(60005, "部门下存在成员;不允许删除有成员的部门"), | |||
/** | |||
* 部门下存在子部门;不允许删除有子部门的部门 | |||
* 部门下存在子部门;不允许删除有子部门的部门. | |||
*/ | |||
CODE_60006(60006, "部门下存在子部门;不允许删除有子部门的部门"), | |||
/** | |||
* 不允许删除根部门 | |||
* 不允许删除根部门. | |||
*/ | |||
CODE_60007(60007, "不允许删除根部门"), | |||
/** | |||
* 部门已存在;部门ID或者部门名称已存在 | |||
* 部门已存在;部门ID或者部门名称已存在. | |||
*/ | |||
CODE_60008(60008, "部门已存在;部门ID或者部门名称已存在"), | |||
/** | |||
* 部门名称含有非法字符;不能含有 \\:?*“< >| 等字符 | |||
* 部门名称含有非法字符;不能含有 \\:?*“< >| 等字符. | |||
*/ | |||
CODE_60009(60009, "部门名称含有非法字符;不能含有 \\ :?*“< >| 等字符"), | |||
/** | |||
* 部门存在循环关系 | |||
* 部门存在循环关系. | |||
*/ | |||
CODE_60010(60010, "部门存在循环关系"), | |||
/** | |||
* 指定的成员/部门/标签参数无权限 | |||
* 指定的成员/部门/标签参数无权限. | |||
*/ | |||
CODE_60011(60011, "指定的成员/部门/标签参数无权限"), | |||
/** | |||
* 不允许删除默认应用;默认应用的id为0 | |||
* 不允许删除默认应用;默认应用的id为0. | |||
*/ | |||
CODE_60012(60012, "不允许删除默认应用;默认应用的id为0"), | |||
/** | |||
* 访问ip不在白名单之中;请确认访问ip是否在服务商白名单IP列表 | |||
* 访问ip不在白名单之中;请确认访问ip是否在服务商白名单IP列表. | |||
*/ | |||
CODE_60020(60020, "访问ip不在白名单之中;请确认访问ip是否在服务商白名单IP列表"), | |||
/** | |||
* 不允许修改第三方应用的主页 URL;第三方应用类型,不允许通过接口修改该应用的主页 URL | |||
* 不允许修改第三方应用的主页 URL;第三方应用类型,不允许通过接口修改该应用的主页 URL. | |||
*/ | |||
CODE_60028(60028, "不允许修改第三方应用的主页 URL;第三方应用类型,不允许通过接口修改该应用的主页 URL"), | |||
/** | |||
* UserID已存在 | |||
* UserID已存在. | |||
*/ | |||
CODE_60102(60102, "UserID已存在"), | |||
/** | |||
* 手机号码不合法;长度不超过32位,字符仅支持数字,加号和减号 | |||
* 手机号码不合法;长度不超过32位,字符仅支持数字,加号和减号. | |||
*/ | |||
CODE_60103(60103, "手机号码不合法;长度不超过32位,字符仅支持数字,加号和减号"), | |||
/** | |||
* 手机号码已存在;同一个企业内,成员的手机号不能重复。建议更换手机号,或者更新已有的手机记录。 | |||
* 手机号码已存在;同一个企业内,成员的手机号不能重复。建议更换手机号,或者更新已有的手机记录. | |||
*/ | |||
CODE_60104(60104, "手机号码已存在;同一个企业内,成员的手机号不能重复。建议更换手机号,或者更新已有的手机记录。"), | |||
/** | |||
* 邮箱不合法;长度不超过64位,且为有效的email格式 | |||
* 邮箱不合法;长度不超过64位,且为有效的email格式. | |||
*/ | |||
CODE_60105(60105, "邮箱不合法;长度不超过64位,且为有效的email格式"), | |||
/** | |||
* 邮箱已存在;同一个企业内,成员的邮箱不能重复。建议更换邮箱,或者更新已有的邮箱记录。 | |||
* 邮箱已存在;同一个企业内,成员的邮箱不能重复。建议更换邮箱,或者更新已有的邮箱记录. | |||
*/ | |||
CODE_60106(60106, "邮箱已存在;同一个企业内,成员的邮箱不能重复。建议更换邮箱,或者更新已有的邮箱记录。"), | |||
/** | |||
* 微信号不合法;微信号格式由字母、数字、”-“、”_“组成,长度为 3-20 字节,首字符必须是字母或”-“或”_“ | |||
* 微信号不合法;微信号格式由字母、数字、”-“、”_“组成,长度为 3-20 字节,首字符必须是字母或”-“或”_“. | |||
*/ | |||
CODE_60107(60107, "微信号不合法;微信号格式由字母、数字、”-“、”_“组成,长度为 3-20 字节,首字符必须是字母或”-“或”_“"), | |||
/** | |||
* 用户所属部门数量超过限制;用户同时归属部门不超过20个 | |||
* 用户所属部门数量超过限制;用户同时归属部门不超过20个. | |||
*/ | |||
CODE_60110(60110, "用户所属部门数量超过限制;用户同时归属部门不超过20个"), | |||
/** | |||
* UserID不存在;UserID参数为空,或者不存在通讯录中 | |||
* UserID不存在;UserID参数为空,或者不存在通讯录中. | |||
*/ | |||
CODE_60111(60111, "UserID不存在;UserID参数为空,或者不存在通讯录中"), | |||
/** | |||
* 成员name参数不合法;不能为空,且不能超过64字符 | |||
* 成员name参数不合法;不能为空,且不能超过64字符. | |||
*/ | |||
CODE_60112(60112, "成员name参数不合法;不能为空,且不能超过64字符"), | |||
/** | |||
* 无效的部门id;部门不存在通讯录中 | |||
* 无效的部门id;部门不存在通讯录中. | |||
*/ | |||
CODE_60123(60123, "无效的部门id;部门不存在通讯录中"), | |||
/** | |||
* 无效的父部门id;父部门不存在通讯录中 | |||
* 无效的父部门id;父部门不存在通讯录中. | |||
*/ | |||
CODE_60124(60124, "无效的父部门id;父部门不存在通讯录中"), | |||
/** | |||
* 非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符 | |||
* 非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符. | |||
*/ | |||
CODE_60125(60125, "非法部门名字;不能为空,且不能超过64字节,且不能含有\\:*?”< >|等字符"), | |||
/** | |||
* 缺少department参数 | |||
* 缺少department参数. | |||
*/ | |||
CODE_60127(60127, "缺少department参数"), | |||
/** | |||
* 成员手机和邮箱都为空;成员手机和邮箱至少有个非空 | |||
* 成员手机和邮箱都为空;成员手机和邮箱至少有个非空. | |||
*/ | |||
CODE_60129(60129, "成员手机和邮箱都为空;成员手机和邮箱至少有个非空"), | |||
/** | |||
* 发票已被其他公众号锁定 | |||
* 发票已被其他公众号锁定. | |||
*/ | |||
CODE_72023(72023, "发票已被其他公众号锁定"), | |||
/** | |||
* 发票状态错误;reimburse_status状态错误,参考:更新发票状态 | |||
* 发票状态错误;reimburse_status状态错误,参考:更新发票状态. | |||
*/ | |||
CODE_72024(72024, "发票状态错误;reimburse_status状态错误,参考:更新发票状态"), | |||
/** | |||
* 存在发票不属于该用户;只能批量更新该openid的发票,参考:批量更新发票状态 | |||
* 存在发票不属于该用户;只能批量更新该openid的发票,参考:批量更新发票状态. | |||
*/ | |||
CODE_72037(72037, "存在发票不属于该用户;只能批量更新该openid的发票,参考:批量更新发票状态"), | |||
/** | |||
* 可信域名不正确,或者无ICP备案 | |||
* 可信域名不正确,或者无ICP备案. | |||
*/ | |||
CODE_80001(80001, "可信域名不正确,或者无ICP备案"), | |||
/** | |||
* 部门下的结点数超过限制(3W) | |||
* 部门下的结点数超过限制(3W). | |||
*/ | |||
CODE_81001(81001, "部门下的结点数超过限制(3W)"), | |||
/** | |||
* 部门最多15层 | |||
* 部门最多15层. | |||
*/ | |||
CODE_81002(81002, "部门最多15层"), | |||
/** | |||
* 无权限操作标签 | |||
* 无权限操作标签. | |||
*/ | |||
CODE_81011(81011, "无权限操作标签"), | |||
/** | |||
* UserID、部门ID、标签ID全部非法或无权限 | |||
* UserID、部门ID、标签ID全部非法或无权限. | |||
*/ | |||
CODE_81013(81013, "UserID、部门ID、标签ID全部非法或无权限"), | |||
/** | |||
* 标签添加成员,单次添加user或party过多 | |||
* 标签添加成员,单次添加user或party过多. | |||
*/ | |||
CODE_81014(81014, "标签添加成员,单次添加user或party过多"), | |||
/** | |||
* 指定的成员/部门/标签全部无效 | |||
* 指定的成员/部门/标签全部无效. | |||
*/ | |||
CODE_82001(82001, "指定的成员/部门/标签全部无效"), | |||
/** | |||
* 不合法的PartyID列表长度;发消息,单次不能超过100个部门 | |||
* 不合法的PartyID列表长度;发消息,单次不能超过100个部门. | |||
*/ | |||
CODE_82002(82002, "不合法的PartyID列表长度;发消息,单次不能超过100个部门"), | |||
/** | |||
* 不合法的TagID列表长度;发消息,单次不能超过100个标签 | |||
* 不合法的TagID列表长度;发消息,单次不能超过100个标签. | |||
*/ | |||
CODE_82003(82003, "不合法的TagID列表长度;发消息,单次不能超过100个标签"), | |||
/** | |||
* 成员票据过期 | |||
* 成员票据过期. | |||
*/ | |||
CODE_84014(84014, "成员票据过期"), | |||
/** | |||
* 成员票据无效;确认user_ticket参数来源是否正确。参考接口:根据code获取成员信息 | |||
* 成员票据无效;确认user_ticket参数来源是否正确。参考接口:根据code获取成员信息. | |||
*/ | |||
CODE_84015(84015, "成员票据无效;确认user_ticket参数来源是否正确。参考接口:根据code获取成员信息"), | |||
/** | |||
* 缺少templateid参数 | |||
* 缺少templateid参数. | |||
*/ | |||
CODE_84019(84019, "缺少templateid参数"), | |||
/** | |||
* templateid不存在;确认参数是否有带,并且已创建 | |||
* templateid不存在;确认参数是否有带,并且已创建. | |||
*/ | |||
CODE_84020(84020, "templateid不存在;确认参数是否有带,并且已创建"), | |||
/** | |||
* 缺少register_code参数 | |||
* 缺少register_code参数. | |||
*/ | |||
CODE_84021(84021, "缺少register_code参数"), | |||
/** | |||
* 无效的register_code参数 | |||
* 无效的register_code参数. | |||
*/ | |||
CODE_84022(84022, "无效的register_code参数"), | |||
/** | |||
* 不允许调用设置通讯录同步完成接口 | |||
* 不允许调用设置通讯录同步完成接口. | |||
*/ | |||
CODE_84023(84023, "不允许调用设置通讯录同步完成接口"), | |||
/** | |||
* 无注册信息 | |||
* 无注册信息. | |||
*/ | |||
CODE_84024(84024, "无注册信息"), | |||
/** | |||
* 不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节 | |||
* 不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节. | |||
*/ | |||
CODE_84025(84025, "不符合的state参数;必须是[a-zA-Z0-9]的参数值,长度不可超过128个字节"), | |||
/** | |||
* 包含不合法的词语 | |||
* 包含不合法的词语. | |||
*/ | |||
CODE_85002(85002, "包含不合法的词语"), | |||
/** | |||
* 每企业每个月设置的可信域名不可超过20个 | |||
* 每企业每个月设置的可信域名不可超过20个. | |||
*/ | |||
CODE_85004(85004, "每企业每个月设置的可信域名不可超过20个"), | |||
/** | |||
* 可信域名未通过所有权校验 | |||
* 可信域名未通过所有权校验. | |||
*/ | |||
CODE_85005(85005, "可信域名未通过所有权校验"), | |||
/** | |||
* 参数 chatid 不合法 | |||
* 参数 chatid 不合法. | |||
*/ | |||
CODE_86001(86001, "参数 chatid 不合法"), | |||
/** | |||
* 参数 chatid 不存在 | |||
* 参数 chatid 不存在. | |||
*/ | |||
CODE_86003(86003, "参数 chatid 不存在"), | |||
/** | |||
* 参数 群名不合法 | |||
* 参数 群名不合法. | |||
*/ | |||
CODE_86004(86004, "参数 群名不合法"), | |||
/** | |||
* 参数 群主不合法 | |||
* 参数 群主不合法. | |||
*/ | |||
CODE_86005(86005, "参数 群主不合法"), | |||
/** | |||
* 群成员数过多或过少 | |||
* 群成员数过多或过少. | |||
*/ | |||
CODE_86006(86006, "群成员数过多或过少"), | |||
/** | |||
* 不合法的群成员 | |||
* 不合法的群成员. | |||
*/ | |||
CODE_86007(86007, "不合法的群成员"), | |||
/** | |||
* 非法操作非自己创建的群 | |||
* 非法操作非自己创建的群. | |||
*/ | |||
CODE_86008(86008, "非法操作非自己创建的群"), | |||
/** | |||
* 存在非法会话成员ID | |||
* 存在非法会话成员ID. | |||
*/ | |||
CODE_86216(86216, "存在非法会话成员ID"), | |||
/** | |||
* 会话发送者不在会话成员列表中;会话的发送者,必须是会话的成员列表之一 | |||
* 会话发送者不在会话成员列表中;会话的发送者,必须是会话的成员列表之一. | |||
*/ | |||
CODE_86217(86217, "会话发送者不在会话成员列表中;会话的发送者,必须是会话的成员列表之一"), | |||
/** | |||
* 指定的会话参数不合法 | |||
* 指定的会话参数不合法. | |||
*/ | |||
CODE_86220(86220, "指定的会话参数不合法"), | |||
/** | |||
* 未认证摇一摇周边 | |||
* 未认证摇一摇周边. | |||
*/ | |||
CODE_90001(90001, "未认证摇一摇周边"), | |||
/** | |||
* 缺少摇一摇周边ticket参数 | |||
* 缺少摇一摇周边ticket参数. | |||
*/ | |||
CODE_90002(90002, "缺少摇一摇周边ticket参数"), | |||
/** | |||
* 摇一摇周边ticket参数不合法 | |||
* 摇一摇周边ticket参数不合法. | |||
*/ | |||
CODE_90003(90003, "摇一摇周边ticket参数不合法"), | |||
/** | |||
* 非法的对外属性类型 | |||
* 非法的对外属性类型. | |||
*/ | |||
CODE_90100(90100, "非法的对外属性类型"), | |||
/** | |||
* 对外属性:文本类型长度不合法;文本长度不可超过12个UTF8字符 | |||
* 对外属性:文本类型长度不合法;文本长度不可超过12个UTF8字符. | |||
*/ | |||
CODE_90101(90101, "对外属性:文本类型长度不合法;文本长度不可超过12个UTF8字符"), | |||
/** | |||
* 对外属性:网页类型标题长度不合法;标题长度不可超过12个UTF8字符 | |||
* 对外属性:网页类型标题长度不合法;标题长度不可超过12个UTF8字符. | |||
*/ | |||
CODE_90102(90102, "对外属性:网页类型标题长度不合法;标题长度不可超过12个UTF8字符"), | |||
/** | |||
* 对外属性:网页url不合法 | |||
* 对外属性:网页url不合法. | |||
*/ | |||
CODE_90103(90103, "对外属性:网页url不合法"), | |||
/** | |||
* 对外属性:小程序类型标题长度不合法;标题长度不可超过12个UTF8字符 | |||
* 对外属性:小程序类型标题长度不合法;标题长度不可超过12个UTF8字符. | |||
*/ | |||
CODE_90104(90104, "对外属性:小程序类型标题长度不合法;标题长度不可超过12个UTF8字符"), | |||
/** | |||
* 对外属性:小程序类型pagepath不合法 | |||
* 对外属性:小程序类型pagepath不合法. | |||
*/ | |||
CODE_90105(90105, "对外属性:小程序类型pagepath不合法"), | |||
/** | |||
* 对外属性:请求参数不合法 | |||
* 对外属性:请求参数不合法. | |||
*/ | |||
CODE_90106(90106, "对外属性:请求参数不合法"), | |||
/** | |||
* 获取ticket的类型无效 | |||
* 获取ticket的类型无效. | |||
*/ | |||
CODE_91040(91040, "获取ticket的类型无效"), | |||
/** | |||
* 无权限操作指定的应用 | |||
* 无权限操作指定的应用. | |||
*/ | |||
CODE_301002(301002, "无权限操作指定的应用"), | |||
/** | |||
* 不允许删除创建者;创建者不允许从通讯录中删除。如果需要删除该成员,需要先在WEB管理端转移创建者身份。 | |||
* 不允许删除创建者;创建者不允许从通讯录中删除。如果需要删除该成员,需要先在WEB管理端转移创建者身份. | |||
*/ | |||
CODE_301005(301005, "不允许删除创建者;创建者不允许从通讯录中删除。如果需要删除该成员,需要先在WEB管理端转移创建者身份。"), | |||
/** | |||
* 参数 position 不合法;长度不允许超过128个字符 | |||
* 参数 position 不合法;长度不允许超过128个字符. | |||
*/ | |||
CODE_301012(301012, "参数 position 不合法;长度不允许超过128个字符"), | |||
/** | |||
* 参数 telephone 不合法;telephone必须由1-32位的纯数字或’-‘号组成。 | |||
* 参数 telephone 不合法;telephone必须由1-32位的纯数字或’-‘号组成. | |||
*/ | |||
CODE_301013(301013, "参数 telephone 不合法;telephone必须由1-32位的纯数字或’-‘号组成。"), | |||
/** | |||
* 参数 english_name 不合法;参数如果有传递,不允许为空字符串,同时不能超过64字节,只能是由字母、数字、点(.)、减号(-)、空格或下划线(_)组成 | |||
* 参数 english_name 不合法;参数如果有传递,不允许为空字符串,同时不能超过64字节,只能是由字母、数字、点(.)、减号(-)、空格或下划线(_)组成. | |||
*/ | |||
CODE_301014(301014, "参数 english_name 不合法;参数如果有传递,不允许为空字符串,同时不能超过64字节,只能是由字母、数字、点(.)、减号(-)、空格或下划线(_)组成"), | |||
/** | |||
* 参数 mediaid 不合法;请检查 mediaid 来源,应该通过上传临时素材的图片类型获得mediaid | |||
* 参数 mediaid 不合法;请检查 mediaid 来源,应该通过上传临时素材的图片类型获得mediaid. | |||
*/ | |||
CODE_301015(301015, "参数 mediaid 不合法;请检查 mediaid 来源,应该通过上传临时素材的图片类型获得mediaid"), | |||
/** | |||
* 上传语音文件不符合系统要求;语音文件的系统限制,参考上传的媒体文件限制 | |||
* 上传语音文件不符合系统要求;语音文件的系统限制,参考上传的媒体文件限制. | |||
*/ | |||
CODE_301016(301016, "上传语音文件不符合系统要求;语音文件的系统限制,参考上传的媒体文件限制"), | |||
/** | |||
* 上传语音文件仅支持AMR格式;语音文件的系统限制,参考上传的媒体文件限制 | |||
* 上传语音文件仅支持AMR格式;语音文件的系统限制,参考上传的媒体文件限制. | |||
*/ | |||
CODE_301017(301017, "上传语音文件仅支持AMR格式;语音文件的系统限制,参考上传的媒体文件限制"), | |||
/** | |||
* 参数 userid 无效;至少有一个userid不存在于通讯录中 | |||
* 参数 userid 无效;至少有一个userid不存在于通讯录中. | |||
*/ | |||
CODE_301021(301021, "参数 userid 无效;至少有一个userid不存在于通讯录中"), | |||
/** | |||
* 获取打卡数据失败;系统失败,可重试处理 | |||
* 获取打卡数据失败;系统失败,可重试处理. | |||
*/ | |||
CODE_301022(301022, "获取打卡数据失败;系统失败,可重试处理"), | |||
/** | |||
* useridlist非法或超过限额;列表数量不能为0且不超过100 | |||
* useridlist非法或超过限额;列表数量不能为0且不超过100. | |||
*/ | |||
CODE_301023(301023, "useridlist非法或超过限额;列表数量不能为0且不超过100"), | |||
/** | |||
* 获取打卡记录时间间隔超限;保证开始时间大于0 且结束时间大于 0 且结束时间大于开始时间,且间隔少于93天 | |||
* 获取打卡记录时间间隔超限;保证开始时间大于0 且结束时间大于 0 且结束时间大于开始时间,且间隔少于93天. | |||
*/ | |||
CODE_301024(301024, "获取打卡记录时间间隔超限;保证开始时间大于0 且结束时间大于 0 且结束时间大于开始时间,且间隔少于93天"), | |||
/** | |||
* 不允许更新该用户的userid | |||
* 不允许更新该用户的userid. | |||
*/ | |||
CODE_301036(301036, "不允许更新该用户的userid"), | |||
/** | |||
* 批量导入任务的文件中userid有重复 | |||
* 批量导入任务的文件中userid有重复. | |||
*/ | |||
CODE_302003(302003, "批量导入任务的文件中userid有重复"), | |||
/** | |||
* 组织架构不合法(1不是一棵树,2 多个一样的partyid,3 partyid空,4 partyid name 空,5 同一个父节点下有两个子节点 部门名字一样 可能是以上情况,请一一排查) | |||
* 组织架构不合法(1不是一棵树,2 多个一样的partyid,3 partyid空,4 partyid name 空,5 同一个父节点下有两个子节点 部门名字一样 可能是以上情况,请一一排查). | |||
*/ | |||
CODE_302004(302004, "组织架构不合法(1不是一棵树,2 多个一样的partyid,3 partyid空,4 partyid name 空,5 同一个父节点下有两个子节点 部门名字一样 可能是以上情况,请一一排查)"), | |||
/** | |||
* 批量导入系统失败,请重新尝试导入 | |||
* 批量导入系统失败,请重新尝试导入. | |||
*/ | |||
CODE_302005(302005, "批量导入系统失败,请重新尝试导入"), | |||
/** | |||
* 批量导入任务的文件中partyid有重复 | |||
* 批量导入任务的文件中partyid有重复. | |||
*/ | |||
CODE_302006(302006, "批量导入任务的文件中partyid有重复"), | |||
/** | |||
* 批量导入任务的文件中,同一个部门下有两个子部门名字一样 | |||
* 批量导入任务的文件中,同一个部门下有两个子部门名字一样. | |||
*/ | |||
CODE_302007(302007, "批量导入任务的文件中,同一个部门下有两个子部门名字一样"), | |||
/** | |||
* CorpId参数无效;指定的CorpId不存在 | |||
* CorpId参数无效;指定的CorpId不存在. | |||
*/ | |||
CODE_2000002(2000002, "CorpId参数无效;指定的CorpId不存在"); | |||
@@ -791,7 +791,7 @@ public enum WxCpErrorMsgEnum { | |||
} | |||
/** | |||
* 通过错误代码查找其中文含义. | |||
* 通过错误代码查找其中文含义.. | |||
*/ | |||
public static String findMsgByCode(int code) { | |||
for (WxCpErrorMsgEnum value : WxCpErrorMsgEnum.values()) { | |||
@@ -1,13 +1,12 @@ | |||
package me.chanjar.weixin.common.error; | |||
import java.io.Serializable; | |||
import org.apache.commons.lang3.StringUtils; | |||
import lombok.Builder; | |||
import lombok.Data; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||
import org.apache.commons.lang3.StringUtils; | |||
import java.io.Serializable; | |||
/** | |||
* 微信错误码. | |||
@@ -46,29 +45,38 @@ public class WxError implements Serializable { | |||
public static WxError fromJson(String json, WxType type) { | |||
final WxError wxError = WxGsonBuilder.create().fromJson(json, WxError.class); | |||
if (StringUtils.isNotEmpty(wxError.getErrorMsg())) { | |||
wxError.setErrorMsgEn(wxError.getErrorMsg()); | |||
if (wxError.getErrorCode() == 0 || type == null) { | |||
return wxError; | |||
} | |||
if (type == null) { | |||
return wxError; | |||
if (StringUtils.isNotEmpty(wxError.getErrorMsg())) { | |||
wxError.setErrorMsgEn(wxError.getErrorMsg()); | |||
} | |||
if (type == WxType.MP) { | |||
final String msg = WxMpErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); | |||
if (msg != null) { | |||
wxError.setErrorMsg(msg); | |||
switch (type) { | |||
case MP: { | |||
final String msg = WxMpErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); | |||
if (msg != null) { | |||
wxError.setErrorMsg(msg); | |||
} | |||
break; | |||
} | |||
} else if (type == WxType.CP) { | |||
final String msg = WxCpErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); | |||
if (msg != null) { | |||
wxError.setErrorMsg(msg); | |||
case CP: { | |||
final String msg = WxCpErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); | |||
if (msg != null) { | |||
wxError.setErrorMsg(msg); | |||
} | |||
break; | |||
} | |||
} else if (type == WxType.MiniApp) { | |||
case MiniApp: { | |||
final String msg = WxMaErrorMsgEnum.findMsgByCode(wxError.getErrorCode()); | |||
if (msg != null) { | |||
wxError.setErrorMsg(msg); | |||
} | |||
break; | |||
} | |||
default: | |||
return wxError; | |||
} | |||
return wxError; | |||
@@ -76,10 +84,11 @@ public class WxError implements Serializable { | |||
@Override | |||
public String toString() { | |||
if (this.json != null) { | |||
return this.json; | |||
if (this.json == null) { | |||
return "错误代码:" + this.errorCode + ", 错误信息:" + this.errorMsg; | |||
} | |||
return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg; | |||
return "错误代码:" + this.errorCode + ", 错误信息:" + this.errorMsg + ",微信原始报文:" + this.json; | |||
} | |||
} |
@@ -227,7 +227,232 @@ public enum WxMaErrorMsgEnum { | |||
* https://developers.weixin.qq.com/miniprogram/dev/api/open-api/sec-check/msgSecCheck.html | |||
* </pre> | |||
*/ | |||
CODE_87014(87014, "内容含有违法违规内容"); | |||
CODE_87014(87014, "内容含有违法违规内容"), | |||
/** | |||
* 系统繁忙,此时请开发者稍候再试. | |||
*/ | |||
CODE_MINUS_1(-1, "系统繁忙,此时请开发者稍候再试"), | |||
/** | |||
* code 无效. | |||
*/ | |||
CODE_40029(40029, "code 无效"), | |||
/** | |||
* access_token 过期. | |||
*/ | |||
CODE_42001(42001, "access_token 过期"), | |||
/** | |||
* post 数据为空. | |||
*/ | |||
CODE_44002(44002, "post 数据为空"), | |||
/** | |||
* post 数据中参数缺失. | |||
*/ | |||
CODE_47001(47001, "post 数据中参数缺失"), | |||
/** | |||
* 参数 activity_id 错误. | |||
*/ | |||
CODE_47501(47501, "参数 activity_id 错误"), | |||
/** | |||
* 参数 target_state 错误. | |||
*/ | |||
CODE_47502(47502, "参数 target_state 错误"), | |||
/** | |||
* 参数 version_type 错误. | |||
*/ | |||
CODE_47503(47503, "参数 version_type 错误"), | |||
/** | |||
* activity_id 过期. | |||
*/ | |||
CODE_47504(47504, "activity_id 过期"), | |||
/** | |||
* 没有绑定开放平台帐号. | |||
*/ | |||
CODE_89002(89002, "没有绑定开放平台帐号"), | |||
/** | |||
* 订单无效. | |||
*/ | |||
CODE_89300(89300, "订单无效"), | |||
/** | |||
* 代小程序实现业务的错误码,部分和小程序业务一致 | |||
* https://developers.weixin.qq.com/doc/oplatform/Third-party_Platforms/Mini_Programs/Intro.html | |||
*/ | |||
CODE_85060(85060, "无效的taskid"), | |||
CODE_85027(85027, "身份证绑定管理员名额达到上限"), | |||
CODE_85061(85061, "手机号绑定管理员名额达到上限"), | |||
CODE_85026(85026, "微信号绑定管理员名额达到上限"), | |||
CODE_85063(85063, "身份证黑名单"), | |||
CODE_85062(85062, "手机号黑名单"), | |||
CODE_85016(85016, "域名数量超过限制"), | |||
CODE_85017(85017, "没有新增域名,请确认小程序已经添加了域名或该域名是否没有在第三方平台添加"), | |||
CODE_85018(85018, "域名没有在第三方平台设置"), | |||
CODE_89019(89019, "业务域名无更改,无需重复设置"), | |||
CODE_89020(89020, "尚未设置小程序业务域名,请先在第三方平台中设置小程序业务域名后在调用本接口"), | |||
CODE_89021(89021, "请求保存的域名不是第三方平台中已设置的小程序业务域名或子域名"), | |||
CODE_89029(89029, "业务域名数量超过限制"), | |||
CODE_89231(89231, "个人小程序不支持调用 setwebviewdomain 接口"), | |||
CODE_91001(91001, "不是公众号快速创建的小程序"), | |||
CODE_91002(91002, "小程序发布后不可改名"), | |||
CODE_91003(91003, "改名状态不合法"), | |||
CODE_91004(91004, "昵称不合法"), | |||
CODE_91005(91005, "昵称 15 天主体保护"), | |||
CODE_91006(91006, "昵称命中微信号"), | |||
CODE_91007(91007, "昵称已被占用"), | |||
CODE_91008(91008, "昵称命中 7 天侵权保护期"), | |||
CODE_91009(91009, "需要提交材料"), | |||
CODE_91010(91010, "其他错误"), | |||
CODE_91011(91011, "查不到昵称修改审核单信息"), | |||
CODE_91012(91012, "其他错误"), | |||
CODE_91013(91013, "占用名字过多"), | |||
CODE_91014(91014, "+号规则 同一类型关联名主体不一致"), | |||
CODE_91015(91015, "原始名不同类型主体不一致"), | |||
CODE_91016(91016, "名称占用者 ≥2"), | |||
CODE_91017(91017, "+号规则 不同类型关联名主体不一致"), | |||
CODE_40097(40097, "参数错误"), | |||
CODE_41006(41006, "media_id 不能为空"), | |||
CODE_46001(46001, "media_id 不存在"), | |||
CODE_40009(40009, "图片尺寸太大"), | |||
CODE_53202(53202, "本月头像修改次数已用完"), | |||
CODE_53200(53200, "本月功能介绍修改次数已用完"), | |||
CODE_53201(53201, "功能介绍内容命中黑名单关键字"), | |||
CODE_85083(85083, "搜索标记位被封禁,无法修改"), | |||
CODE_85084(85084, "非法的 status 值,只能填 0 或者 1"), | |||
CODE_85013(85013, "无效的自定义配置"), | |||
CODE_85014(85014, "无效的模版编号"), | |||
CODE_85043(85043, "模版错误"), | |||
CODE_85044(85044, "代码包超过大小限制"), | |||
CODE_85045(85045, "ext_json 有不存在的路径"), | |||
CODE_85046(85046, "tabBar 中缺少 path"), | |||
CODE_85047(85047, "pages 字段为空"), | |||
CODE_85048(85048, "ext_json 解析失败"), | |||
CODE_80082(80082, "没有权限使用该插件"), | |||
CODE_80067(80067, "找不到使用的插件"), | |||
CODE_80066(80066, "非法的插件版本"), | |||
CODE_86000(86000, "不是由第三方代小程序进行调用"), | |||
CODE_86001(86001, "不存在第三方的已经提交的代码"), | |||
CODE_85006(85006, "标签格式错误"), | |||
CODE_85007(85007, "页面路径错误"), | |||
CODE_85008(85008, "类目填写错误"), | |||
CODE_85009(85009, "已经有正在审核的版本"), | |||
CODE_85010(85010, "item_list 有项目为空"), | |||
CODE_85011(85011, "标题填写错误"), | |||
CODE_85023(85023, "审核列表填写的项目数不在 1-5 以内"), | |||
CODE_85077(85077, "小程序类目信息失效(类目中含有官方下架的类目,请重新选择类目)"), | |||
CODE_86002(86002, "小程序还未设置昵称、头像、简介。请先设置完后再重新提交"), | |||
CODE_85085(85085, "近 7 天提交审核的小程序数量过多,请耐心等待审核完毕后再次提交"), | |||
CODE_85086(85086, "提交代码审核之前需提前上传代码"), | |||
CODE_85087(85087, "小程序已使用 api navigateToMiniProgram,请声明跳转 appid 列表后再次提交"), | |||
CODE_85012(85012, "无效的审核 id"), | |||
CODE_87013(87013, "撤回次数达到上限(每天一次,每个月 10 次)"), | |||
CODE_85019(85019, "没有审核版本"), | |||
CODE_85020(85020, "审核状态未满足发布"), | |||
CODE_87011(87011, "现网已经在灰度发布,不能进行版本回退"), | |||
CODE_87012(87012, "该版本不能回退,可能的原因:1:无上一个线上版用于回退 2:此版本为已回退版本,不能回退 3:此版本为回退功能上线之前的版本,不能回退"), | |||
CODE_85079(85079, "小程序没有线上版本,不能进行灰度"), | |||
CODE_85080(85080, "小程序提交的审核未审核通过"), | |||
CODE_85081(85081, "无效的发布比例"), | |||
CODE_85082(85082, "当前的发布比例需要比之前设置的高"), | |||
CODE_85021(85021, "状态不可变"), | |||
CODE_85022(85022, "action 非法"), | |||
CODE_89401(89401, "系统不稳定,请稍后再试,如多次失败请通过社区反馈"), | |||
CODE_89402(89402, "该审核单不在待审核队列,请检查是否已提交审核或已审完"), | |||
CODE_89403(89403, "本单属于平台不支持加急种类,请等待正常审核流程"), | |||
CODE_89404(89404, "本单已加速成功,请勿重复提交"), | |||
CODE_89405(89405, "本月加急额度不足,请提升提审质量以获取更多额度"), | |||
CODE_85064(85064, "找不到模版/草稿"), | |||
CODE_85065(85065, "模版库已满"), | |||
/** | |||
* 小程序订阅消息错误码 | |||
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | |||
*/ | |||
CODE_43101(43101, "用户拒绝接受消息,如果用户之前曾经订阅过,则表示用户取消了订阅关系"), | |||
CODE_47003(47003, "模板参数不准确,可能为空或者不满足规则,errmsg会提示具体是哪个字段出错"), | |||
; | |||
private int code; | |||
private String msg; | |||
@@ -238,7 +463,6 @@ public enum WxMaErrorMsgEnum { | |||
} | |||
/** | |||
* <pre> | |||
* 通过错误代码查找其中文含义. | |||
*/ | |||
public static String findMsgByCode(int code) { | |||
@@ -14,621 +14,635 @@ import lombok.Getter; | |||
@Getter | |||
public enum WxMpErrorMsgEnum { | |||
/** | |||
* 系统繁忙,此时请开发者稍候再试 | |||
* 系统繁忙,此时请开发者稍候再试. | |||
*/ | |||
CODE_1(-1, "系统繁忙,此时请开发者稍候再试"), | |||
/** | |||
* 请求成功 | |||
* 请求成功. | |||
*/ | |||
CODE_0(0, "请求成功"), | |||
/** | |||
* 获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口 | |||
* 获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口. | |||
*/ | |||
CODE_40001(40001, "获取 access_token 时 AppSecret 错误,或者 access_token 无效。请开发者认真比对 AppSecret 的正确性,或查看是否正在为恰当的公众号调用接口"), | |||
/** | |||
* 不合法的凭证类型 | |||
* 不合法的凭证类型. | |||
*/ | |||
CODE_40002(40002, "不合法的凭证类型"), | |||
/** | |||
* 不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID | |||
* 不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID. | |||
*/ | |||
CODE_40003(40003, "不合法的 OpenID ,请开发者确认 OpenID (该用户)是否已关注公众号,或是否是其他公众号的 OpenID"), | |||
/** | |||
* 不合法的媒体文件类型 | |||
* 不合法的媒体文件类型. | |||
*/ | |||
CODE_40004(40004, "不合法的媒体文件类型"), | |||
/** | |||
* 不合法的文件类型 | |||
* 不合法的文件类型. | |||
*/ | |||
CODE_40005(40005, "不合法的文件类型"), | |||
/** | |||
* 不合法的文件大小 | |||
* 不合法的文件大小. | |||
*/ | |||
CODE_40006(40006, "不合法的文件大小"), | |||
/** | |||
* 不合法的媒体文件 id | |||
* 不合法的媒体文件 id. | |||
*/ | |||
CODE_40007(40007, "不合法的媒体文件 id"), | |||
/** | |||
* 不合法的消息类型 | |||
* 不合法的消息类型. | |||
*/ | |||
CODE_40008(40008, "不合法的消息类型"), | |||
/** | |||
* 不合法的图片文件大小 | |||
* 不合法的图片文件大小. | |||
*/ | |||
CODE_40009(40009, "不合法的图片文件大小"), | |||
/** | |||
* 不合法的语音文件大小 | |||
* 不合法的语音文件大小. | |||
*/ | |||
CODE_40010(40010, "不合法的语音文件大小"), | |||
/** | |||
* 不合法的视频文件大小 | |||
* 不合法的视频文件大小. | |||
*/ | |||
CODE_40011(40011, "不合法的视频文件大小"), | |||
/** | |||
* 不合法的缩略图文件大小 | |||
* 不合法的缩略图文件大小. | |||
*/ | |||
CODE_40012(40012, "不合法的缩略图文件大小"), | |||
/** | |||
* 不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写 | |||
* 不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写. | |||
*/ | |||
CODE_40013(40013, "不合法的 AppID ,请开发者检查 AppID 的正确性,避免异常字符,注意大小写"), | |||
/** | |||
* 不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口 | |||
* 不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口. | |||
*/ | |||
CODE_40014(40014, "不合法的 access_token ,请开发者认真比对 access_token 的有效性(如是否过期),或查看是否正在为恰当的公众号调用接口"), | |||
/** | |||
* 不合法的菜单类型 | |||
* 不合法的菜单类型. | |||
*/ | |||
CODE_40015(40015, "不合法的菜单类型"), | |||
/** | |||
* 不合法的按钮个数 | |||
* 不合法的按钮个数. | |||
*/ | |||
CODE_40016(40016, "不合法的按钮个数"), | |||
/** | |||
* 不合法的按钮个数 | |||
* 不合法的按钮个数. | |||
*/ | |||
CODE_40017(40017, "不合法的按钮个数"), | |||
/** | |||
* 不合法的按钮名字长度 | |||
* 不合法的按钮名字长度. | |||
*/ | |||
CODE_40018(40018, "不合法的按钮名字长度"), | |||
/** | |||
* 不合法的按钮 KEY 长度 | |||
* 不合法的按钮 KEY 长度. | |||
*/ | |||
CODE_40019(40019, "不合法的按钮 KEY 长度"), | |||
/** | |||
* 不合法的按钮 URL 长度 | |||
* 不合法的按钮 URL 长度. | |||
*/ | |||
CODE_40020(40020, "不合法的按钮 URL 长度"), | |||
/** | |||
* 不合法的菜单版本号 | |||
* 不合法的菜单版本号. | |||
*/ | |||
CODE_40021(40021, "不合法的菜单版本号"), | |||
/** | |||
* 不合法的子菜单级数 | |||
* 不合法的子菜单级数. | |||
*/ | |||
CODE_40022(40022, "不合法的子菜单级数"), | |||
/** | |||
* 不合法的子菜单按钮个数 | |||
* 不合法的子菜单按钮个数. | |||
*/ | |||
CODE_40023(40023, "不合法的子菜单按钮个数"), | |||
/** | |||
* 不合法的子菜单按钮类型 | |||
* 不合法的子菜单按钮类型. | |||
*/ | |||
CODE_40024(40024, "不合法的子菜单按钮类型"), | |||
/** | |||
* 不合法的子菜单按钮名字长度 | |||
* 不合法的子菜单按钮名字长度. | |||
*/ | |||
CODE_40025(40025, "不合法的子菜单按钮名字长度"), | |||
/** | |||
* 不合法的子菜单按钮 KEY 长度 | |||
* 不合法的子菜单按钮 KEY 长度. | |||
*/ | |||
CODE_40026(40026, "不合法的子菜单按钮 KEY 长度"), | |||
/** | |||
* 不合法的子菜单按钮 URL 长度 | |||
* 不合法的子菜单按钮 URL 长度. | |||
*/ | |||
CODE_40027(40027, "不合法的子菜单按钮 URL 长度"), | |||
/** | |||
* 不合法的自定义菜单使用用户 | |||
* 不合法的自定义菜单使用用户. | |||
*/ | |||
CODE_40028(40028, "不合法的自定义菜单使用用户"), | |||
/** | |||
* 不合法的 oauth_code | |||
* 不合法的 oauth_code. | |||
*/ | |||
CODE_40029(40029, "不合法的 oauth_code"), | |||
/** | |||
* 不合法的 refresh_token | |||
* 不合法的 refresh_token. | |||
*/ | |||
CODE_40030(40030, "不合法的 refresh_token"), | |||
/** | |||
* 不合法的 openid 列表 | |||
* 不合法的 openid 列表. | |||
*/ | |||
CODE_40031(40031, "不合法的 openid 列表"), | |||
/** | |||
* 不合法的 openid 列表长度 | |||
* 不合法的 openid 列表长度. | |||
*/ | |||
CODE_40032(40032, "不合法的 openid 列表长度"), | |||
/** | |||
* 不合法的请求字符,不能包含\\uxxxx 格式的字符 | |||
* 不合法的请求字符,不能包含\\uxxxx 格式的字符. | |||
*/ | |||
CODE_40033(40033, "不合法的请求字符,不能包含\\uxxxx 格式的字符"), | |||
/** | |||
* 不合法的参数 | |||
* 不合法的参数. | |||
*/ | |||
CODE_40035(40035, "不合法的参数"), | |||
/** | |||
* 不合法的请求格式 | |||
* 不合法的请求格式. | |||
*/ | |||
CODE_40038(40038, "不合法的请求格式"), | |||
/** | |||
* 不合法的 URL 长度 | |||
* 不合法的 URL 长度. | |||
*/ | |||
CODE_40039(40039, "不合法的 URL 长度"), | |||
/** | |||
* 不合法的分组 id | |||
* 不合法的分组 id. | |||
*/ | |||
CODE_40050(40050, "不合法的分组 id"), | |||
/** | |||
* 分组名字不合法 | |||
* 分组名字不合法. | |||
*/ | |||
CODE_40051(40051, "分组名字不合法"), | |||
/** | |||
* 删除单篇图文时,指定的 article_idx 不合法 | |||
* 删除单篇图文时,指定的 article_idx 不合法. | |||
*/ | |||
CODE_40060(40060, "删除单篇图文时,指定的 article_idx 不合法"), | |||
/** | |||
* 分组名字不合法 | |||
* 分组名字不合法. | |||
*/ | |||
CODE_40117(40117, "分组名字不合法"), | |||
/** | |||
* media_id 大小不合法 | |||
* media_id 大小不合法. | |||
*/ | |||
CODE_40118(40118, "media_id 大小不合法"), | |||
/** | |||
* button 类型错误 | |||
* button 类型错误. | |||
*/ | |||
CODE_40119(40119, "button 类型错误"), | |||
/** | |||
* button 类型错误 | |||
* button 类型错误. | |||
*/ | |||
CODE_40120(40120, "button 类型错误"), | |||
/** | |||
* 不合法的 media_id 类型 | |||
* 不合法的 media_id 类型. | |||
*/ | |||
CODE_40121(40121, "不合法的 media_id 类型"), | |||
/** | |||
* 微信号不合法 | |||
* 微信号不合法. | |||
*/ | |||
CODE_40132(40132, "微信号不合法"), | |||
/** | |||
* 不支持的图片格式 | |||
* 不支持的图片格式. | |||
*/ | |||
CODE_40137(40137, "不支持的图片格式"), | |||
/** | |||
* 请勿添加其他公众号的主页链接 | |||
* 请勿添加其他公众号的主页链接. | |||
*/ | |||
CODE_40155(40155, "请勿添加其他公众号的主页链接"), | |||
/** | |||
* 缺少 access_token 参数 | |||
* 缺少 access_token 参数. | |||
*/ | |||
CODE_41001(41001, "缺少 access_token 参数"), | |||
/** | |||
* 缺少 appid 参数 | |||
* 缺少 appid 参数. | |||
*/ | |||
CODE_41002(41002, "缺少 appid 参数"), | |||
/** | |||
* 缺少 refresh_token 参数 | |||
* 缺少 refresh_token 参数. | |||
*/ | |||
CODE_41003(41003, "缺少 refresh_token 参数"), | |||
/** | |||
* 缺少 secret 参数 | |||
* 缺少 secret 参数. | |||
*/ | |||
CODE_41004(41004, "缺少 secret 参数"), | |||
/** | |||
* 缺少多媒体文件数据 | |||
* 缺少多媒体文件数据. | |||
*/ | |||
CODE_41005(41005, "缺少多媒体文件数据"), | |||
/** | |||
* 缺少 media_id 参数 | |||
* 缺少 media_id 参数. | |||
*/ | |||
CODE_41006(41006, "缺少 media_id 参数"), | |||
/** | |||
* 缺少子菜单数据 | |||
* 缺少子菜单数据. | |||
*/ | |||
CODE_41007(41007, "缺少子菜单数据"), | |||
/** | |||
* 缺少 oauth code | |||
* 缺少 oauth code. | |||
*/ | |||
CODE_41008(41008, "缺少 oauth code"), | |||
/** | |||
* 缺少 openid | |||
* 缺少 openid. | |||
*/ | |||
CODE_41009(41009, "缺少 openid"), | |||
/** | |||
* access_token 超时,请检查 access_token 的有效期,请参考基础支持 - 获取 access_token 中,对 access_token 的详细机制说明 | |||
* access_token 超时,请检查 access_token 的有效期,请参考基础支持 - 获取 access_token 中,对 access_token 的详细机制说明. | |||
*/ | |||
CODE_42001(42001, "access_token 超时,请检查 access_token 的有效期,请参考基础支持 - 获取 access_token 中,对 access_token 的详细机制说明"), | |||
/** | |||
* refresh_token 超时 | |||
* refresh_token 超时. | |||
*/ | |||
CODE_42002(42002, "refresh_token 超时"), | |||
/** | |||
* oauth_code 超时 | |||
* oauth_code 超时. | |||
*/ | |||
CODE_42003(42003, "oauth_code 超时"), | |||
/** | |||
* 用户修改微信密码, accesstoken 和 refreshtoken 失效,需要重新授权 | |||
* 用户修改微信密码, accesstoken 和 refreshtoken 失效,需要重新授权. | |||
*/ | |||
CODE_42007(42007, "用户修改微信密码, accesstoken 和 refreshtoken 失效,需要重新授权"), | |||
/** | |||
* 需要 GET 请求 | |||
* 需要 GET 请求. | |||
*/ | |||
CODE_43001(43001, "需要 GET 请求"), | |||
/** | |||
* 需要 POST 请求 | |||
* 需要 POST 请求. | |||
*/ | |||
CODE_43002(43002, "需要 POST 请求"), | |||
/** | |||
* 需要 HTTPS 请求 | |||
* 需要 HTTPS 请求. | |||
*/ | |||
CODE_43003(43003, "需要 HTTPS 请求"), | |||
/** | |||
* 需要接收者关注 | |||
* 需要接收者关注. | |||
*/ | |||
CODE_43004(43004, "需要接收者关注"), | |||
/** | |||
* 需要好友关系 | |||
* 需要好友关系. | |||
*/ | |||
CODE_43005(43005, "需要好友关系"), | |||
/** | |||
* 需要将接收者从黑名单中移除 | |||
* 需要将接收者从黑名单中移除. | |||
*/ | |||
CODE_43019(43019, "需要将接收者从黑名单中移除"), | |||
/** | |||
* 多媒体文件为空 | |||
* 多媒体文件为空. | |||
*/ | |||
CODE_44001(44001, "多媒体文件为空"), | |||
/** | |||
* POST 的数据包为空 | |||
* POST 的数据包为空. | |||
*/ | |||
CODE_44002(44002, "POST 的数据包为空"), | |||
/** | |||
* 图文消息内容为空 | |||
* 图文消息内容为空. | |||
*/ | |||
CODE_44003(44003, "图文消息内容为空"), | |||
/** | |||
* 文本消息内容为空 | |||
* 文本消息内容为空. | |||
*/ | |||
CODE_44004(44004, "文本消息内容为空"), | |||
/** | |||
* 多媒体文件大小超过限制 | |||
* 多媒体文件大小超过限制. | |||
*/ | |||
CODE_45001(45001, "多媒体文件大小超过限制"), | |||
/** | |||
* 消息内容超过限制 | |||
* 消息内容超过限制. | |||
*/ | |||
CODE_45002(45002, "消息内容超过限制"), | |||
/** | |||
* 标题字段超过限制 | |||
* 标题字段超过限制. | |||
*/ | |||
CODE_45003(45003, "标题字段超过限制"), | |||
/** | |||
* 描述字段超过限制 | |||
* 描述字段超过限制. | |||
*/ | |||
CODE_45004(45004, "描述字段超过限制"), | |||
/** | |||
* 链接字段超过限制 | |||
* 链接字段超过限制. | |||
*/ | |||
CODE_45005(45005, "链接字段超过限制"), | |||
/** | |||
* 图片链接字段超过限制 | |||
* 图片链接字段超过限制. | |||
*/ | |||
CODE_45006(45006, "图片链接字段超过限制"), | |||
/** | |||
* 语音播放时间超过限制 | |||
* 语音播放时间超过限制. | |||
*/ | |||
CODE_45007(45007, "语音播放时间超过限制"), | |||
/** | |||
* 图文消息超过限制 | |||
* 图文消息超过限制. | |||
*/ | |||
CODE_45008(45008, "图文消息超过限制"), | |||
/** | |||
* 接口调用超过限制 | |||
* 接口调用超过限制. | |||
*/ | |||
CODE_45009(45009, "接口调用超过限制"), | |||
/** | |||
* 创建菜单个数超过限制 | |||
* 创建菜单个数超过限制. | |||
*/ | |||
CODE_45010(45010, "创建菜单个数超过限制"), | |||
/** | |||
* API 调用太频繁,请稍候再试 | |||
* API 调用太频繁,请稍候再试. | |||
*/ | |||
CODE_45011(45011, "API 调用太频繁,请稍候再试"), | |||
/** | |||
* 回复时间超过限制 | |||
* 回复时间超过限制. | |||
*/ | |||
CODE_45015(45015, "回复时间超过限制"), | |||
/** | |||
* 系统分组,不允许修改 | |||
* 系统分组,不允许修改. | |||
*/ | |||
CODE_45016(45016, "系统分组,不允许修改"), | |||
/** | |||
* 分组名字过长 | |||
* 分组名字过长. | |||
*/ | |||
CODE_45017(45017, "分组名字过长"), | |||
/** | |||
* 分组数量超过上限 | |||
* 分组数量超过上限. | |||
*/ | |||
CODE_45018(45018, "分组数量超过上限"), | |||
/** | |||
* 客服接口下行条数超过上限 | |||
* 客服接口下行条数超过上限. | |||
*/ | |||
CODE_45047(45047, "客服接口下行条数超过上限"), | |||
/** | |||
* 不存在媒体数据 | |||
* 非法的tag_id. | |||
*/ | |||
CODE_45159(45159, "非法的tag_id"), | |||
/** | |||
* 不存在媒体数据. | |||
*/ | |||
CODE_46001(46001, "不存在媒体数据"), | |||
/** | |||
* 不存在的菜单版本 | |||
* 不存在的菜单版本. | |||
*/ | |||
CODE_46002(46002, "不存在的菜单版本"), | |||
/** | |||
* 不存在的菜单数据 | |||
* 不存在的菜单数据. | |||
*/ | |||
CODE_46003(46003, "不存在的菜单数据"), | |||
/** | |||
* 不存在的用户 | |||
* 不存在的用户. | |||
*/ | |||
CODE_46004(46004, "不存在的用户"), | |||
/** | |||
* 解析 JSON/XML 内容错误 | |||
* 解析 JSON/XML 内容错误. | |||
*/ | |||
CODE_47001(47001, "解析 JSON/XML 内容错误"), | |||
/** | |||
* api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限 | |||
* api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限. | |||
*/ | |||
CODE_48001(48001, "api 功能未授权,请确认公众号已获得该接口,可以在公众平台官网 - 开发者中心页中查看接口权限"), | |||
/** | |||
* 粉丝拒收消息(粉丝在公众号选项中,关闭了 “ 接收消息 ” ) | |||
* 粉丝拒收消息(粉丝在公众号选项中,关闭了 “ 接收消息 ” ). | |||
*/ | |||
CODE_48002(48002, "粉丝拒收消息(粉丝在公众号选项中,关闭了 “ 接收消息 ” )"), | |||
/** | |||
* api 接口被封禁,请登录 mp.weixin.qq.com 查看详情 | |||
* api 接口被封禁,请登录 mp.weixin.qq.com 查看详情. | |||
*/ | |||
CODE_48004(48004, "api 接口被封禁,请登录 mp.weixin.qq.com 查看详情"), | |||
/** | |||
* api 禁止删除被自动回复和自定义菜单引用的素材 | |||
* api 禁止删除被自动回复和自定义菜单引用的素材. | |||
*/ | |||
CODE_48005(48005, "api 禁止删除被自动回复和自定义菜单引用的素材"), | |||
/** | |||
* api 禁止清零调用次数,因为清零次数达到上限 | |||
* api 禁止清零调用次数,因为清零次数达到上限. | |||
*/ | |||
CODE_48006(48006, "api 禁止清零调用次数,因为清零次数达到上限"), | |||
/** | |||
* 没有该类型消息的发送权限 | |||
* 没有该类型消息的发送权限. | |||
*/ | |||
CODE_48008(48008, "没有该类型消息的发送权限"), | |||
/** | |||
* 用户未授权该 api | |||
* 用户未授权该 api. | |||
*/ | |||
CODE_50001(50001, "用户未授权该 api"), | |||
/** | |||
* 用户受限,可能是违规后接口被封禁 | |||
* 用户受限,可能是违规后接口被封禁. | |||
*/ | |||
CODE_50002(50002, "用户受限,可能是违规后接口被封禁"), | |||
/** | |||
* 用户未关注公众号 | |||
* 用户未关注公众号. | |||
*/ | |||
CODE_50005(50005, "用户未关注公众号"), | |||
/** | |||
* 参数错误 (invalid parameter) | |||
* 参数错误 (invalid parameter). | |||
*/ | |||
CODE_61451(61451, "参数错误 (invalid parameter)"), | |||
/** | |||
* 无效客服账号 (invalid kf_account) | |||
* 无效客服账号 (invalid kf_account). | |||
*/ | |||
CODE_61452(61452, "无效客服账号 (invalid kf_account)"), | |||
/** | |||
* 客服帐号已存在 (kf_account exsited) | |||
* 客服帐号已存在 (kf_account exsited). | |||
*/ | |||
CODE_61453(61453, "客服帐号已存在 (kf_account exsited)"), | |||
/** | |||
* 客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )(invalid kf_acount length) | |||
* 客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )(invalid kf_acount length). | |||
*/ | |||
CODE_61454(61454, "客服帐号名长度超过限制 ( 仅允许 10 个英文字符,不包括 @ 及 @ 后的公众号的微信号 )(invalid kf_acount length)"), | |||
/** | |||
* 客服帐号名包含非法字符 ( 仅允许英文 + 数字 )(illegal character in kf_account) | |||
* 客服帐号名包含非法字符 ( 仅允许英文 + 数字 )(illegal character in kf_account). | |||
*/ | |||
CODE_61455(61455, "客服帐号名包含非法字符 ( 仅允许英文 + 数字 )(illegal character in kf_account)"), | |||
/** | |||
* 客服帐号个数超过限制 (10 个客服账号 )(kf_account count exceeded) | |||
* 客服帐号个数超过限制 (10 个客服账号 )(kf_account count exceeded). | |||
*/ | |||
CODE_61456(61456, "客服帐号个数超过限制 (10 个客服账号 )(kf_account count exceeded)"), | |||
/** | |||
* 无效头像文件类型 (invalid file type) | |||
* 无效头像文件类型 (invalid file type). | |||
*/ | |||
CODE_61457(61457, "无效头像文件类型 (invalid file type)"), | |||
/** | |||
* 系统错误 (system error) | |||
* 系统错误 (system error). | |||
*/ | |||
CODE_61450(61450, "系统错误 (system error)"), | |||
/** | |||
* 日期格式错误 | |||
* 日期格式错误. | |||
*/ | |||
CODE_61500(61500, "日期格式错误"), | |||
/** | |||
* 不存在此 menuid 对应的个性化菜单 | |||
* 不存在此 menuid 对应的个性化菜单. | |||
*/ | |||
CODE_65301(65301, "不存在此 menuid 对应的个性化菜单"), | |||
/** | |||
* 没有相应的用户 | |||
* 没有相应的用户. | |||
*/ | |||
CODE_65302(65302, "没有相应的用户"), | |||
/** | |||
* 没有默认菜单,不能创建个性化菜单 | |||
* 没有默认菜单,不能创建个性化菜单. | |||
*/ | |||
CODE_65303(65303, "没有默认菜单,不能创建个性化菜单"), | |||
/** | |||
* MatchRule 信息为空 | |||
* MatchRule 信息为空. | |||
*/ | |||
CODE_65304(65304, "MatchRule 信息为空"), | |||
/** | |||
* 个性化菜单数量受限 | |||
* 个性化菜单数量受限. | |||
*/ | |||
CODE_65305(65305, "个性化菜单数量受限"), | |||
/** | |||
* 不支持个性化菜单的帐号 | |||
* 不支持个性化菜单的帐号. | |||
*/ | |||
CODE_65306(65306, "不支持个性化菜单的帐号"), | |||
/** | |||
* 个性化菜单信息为空 | |||
* 个性化菜单信息为空. | |||
*/ | |||
CODE_65307(65307, "个性化菜单信息为空"), | |||
/** | |||
* 包含没有响应类型的 button | |||
* 包含没有响应类型的 button. | |||
*/ | |||
CODE_65308(65308, "包含没有响应类型的 button"), | |||
/** | |||
* 个性化菜单开关处于关闭状态 | |||
* 个性化菜单开关处于关闭状态. | |||
*/ | |||
CODE_65309(65309, "个性化菜单开关处于关闭状态"), | |||
/** | |||
* 填写了省份或城市信息,国家信息不能为空 | |||
* 填写了省份或城市信息,国家信息不能为空. | |||
*/ | |||
CODE_65310(65310, "填写了省份或城市信息,国家信息不能为空"), | |||
/** | |||
* 填写了城市信息,省份信息不能为空 | |||
* 填写了城市信息,省份信息不能为空. | |||
*/ | |||
CODE_65311(65311, "填写了城市信息,省份信息不能为空"), | |||
/** | |||
* 不合法的国家信息 | |||
* 不合法的国家信息. | |||
*/ | |||
CODE_65312(65312, "不合法的国家信息"), | |||
/** | |||
* 不合法的省份信息 | |||
* 不合法的省份信息. | |||
*/ | |||
CODE_65313(65313, "不合法的省份信息"), | |||
/** | |||
* 不合法的城市信息 | |||
* 不合法的城市信息. | |||
*/ | |||
CODE_65314(65314, "不合法的城市信息"), | |||
/** | |||
* 该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接) | |||
* 该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接). | |||
*/ | |||
CODE_65316(65316, "该公众号的菜单设置了过多的域名外跳(最多跳转到 3 个域名的链接)"), | |||
/** | |||
* 不合法的 URL | |||
* 不合法的 URL. | |||
*/ | |||
CODE_65317(65317, "不合法的 URL"), | |||
/** | |||
* POST 数据参数不合法 | |||
* POST 数据参数不合法. | |||
*/ | |||
CODE_9001001(9001001, "POST 数据参数不合法"), | |||
/** | |||
* 远端服务不可用 | |||
* 远端服务不可用. | |||
*/ | |||
CODE_9001002(9001002, "远端服务不可用"), | |||
/** | |||
* Ticket 不合法 | |||
* Ticket 不合法. | |||
*/ | |||
CODE_9001003(9001003, "Ticket 不合法"), | |||
/** | |||
* 获取摇周边用户信息失败 | |||
* 获取摇周边用户信息失败. | |||
*/ | |||
CODE_9001004(9001004, "获取摇周边用户信息失败"), | |||
/** | |||
* 获取商户信息失败 | |||
* 获取商户信息失败. | |||
*/ | |||
CODE_9001005(9001005, "获取商户信息失败"), | |||
/** | |||
* 获取 OpenID 失败 | |||
* 获取 OpenID 失败. | |||
*/ | |||
CODE_9001006(9001006, "获取 OpenID 失败"), | |||
/** | |||
* 上传文件缺失 | |||
* 上传文件缺失. | |||
*/ | |||
CODE_9001007(9001007, "上传文件缺失"), | |||
/** | |||
* 上传素材的文件类型不合法 | |||
* 上传素材的文件类型不合法. | |||
*/ | |||
CODE_9001008(9001008, "上传素材的文件类型不合法"), | |||
/** | |||
* 上传素材的文件尺寸不合法 | |||
* 上传素材的文件尺寸不合法. | |||
*/ | |||
CODE_9001009(9001009, "上传素材的文件尺寸不合法"), | |||
/** | |||
* 上传失败 | |||
* 上传失败. | |||
*/ | |||
CODE_9001010(9001010, "上传失败"), | |||
/** | |||
* 帐号不合法 | |||
* 帐号不合法. | |||
*/ | |||
CODE_9001020(9001020, "帐号不合法"), | |||
/** | |||
* 已有设备激活率低于 50% ,不能新增设备 | |||
* 已有设备激活率低于 50% ,不能新增设备. | |||
*/ | |||
CODE_9001021(9001021, "已有设备激活率低于 50% ,不能新增设备"), | |||
/** | |||
* 设备申请数不合法,必须为大于 0 的数字 | |||
* 设备申请数不合法,必须为大于 0 的数字. | |||
*/ | |||
CODE_9001022(9001022, "设备申请数不合法,必须为大于 0 的数字"), | |||
/** | |||
* 已存在审核中的设备 ID 申请 | |||
* 已存在审核中的设备 ID 申请. | |||
*/ | |||
CODE_9001023(9001023, "已存在审核中的设备 ID 申请"), | |||
/** | |||
* 一次查询设备 ID 数量不能超过 50 | |||
* 一次查询设备 ID 数量不能超过 50. | |||
*/ | |||
CODE_9001024(9001024, "一次查询设备 ID 数量不能超过 50"), | |||
/** | |||
* 设备 ID 不合法 | |||
* 设备 ID 不合法. | |||
*/ | |||
CODE_9001025(9001025, "设备 ID 不合法"), | |||
/** | |||
* 页面 ID 不合法 | |||
* 页面 ID 不合法. | |||
*/ | |||
CODE_9001026(9001026, "页面 ID 不合法"), | |||
/** | |||
* 页面参数不合法 | |||
* 页面参数不合法. | |||
*/ | |||
CODE_9001027(9001027, "页面参数不合法"), | |||
/** | |||
* 一次删除页面 ID 数量不能超过 10 | |||
* 一次删除页面 ID 数量不能超过 10. | |||
*/ | |||
CODE_9001028(9001028, "一次删除页面 ID 数量不能超过 10"), | |||
/** | |||
* 页面已应用在设备中,请先解除应用关系再删除 | |||
* 页面已应用在设备中,请先解除应用关系再删除. | |||
*/ | |||
CODE_9001029(9001029, "页面已应用在设备中,请先解除应用关系再删除"), | |||
/** | |||
* 一次查询页面 ID 数量不能超过 50 | |||
* 一次查询页面 ID 数量不能超过 50. | |||
*/ | |||
CODE_9001030(9001030, "一次查询页面 ID 数量不能超过 50"), | |||
/** | |||
* 时间区间不合法 | |||
* 时间区间不合法. | |||
*/ | |||
CODE_9001031(9001031, "时间区间不合法"), | |||
/** | |||
* 保存设备与页面的绑定关系参数错误 | |||
* 保存设备与页面的绑定关系参数错误. | |||
*/ | |||
CODE_9001032(9001032, "保存设备与页面的绑定关系参数错误"), | |||
/** | |||
* 门店 ID 不合法 | |||
* 门店 ID 不合法. | |||
*/ | |||
CODE_9001033(9001033, "门店 ID 不合法"), | |||
/** | |||
* 设备备注信息过长 | |||
* 设备备注信息过长. | |||
*/ | |||
CODE_9001034(9001034, "设备备注信息过长"), | |||
/** | |||
* 设备申请参数不合法 | |||
* 设备申请参数不合法. | |||
*/ | |||
CODE_9001035(9001035, "设备申请参数不合法"), | |||
/** | |||
* 查询起始值 begin 不合法 | |||
* 查询起始值 begin 不合法. | |||
*/ | |||
CODE_9001036(9001036, "查询起始值 begin 不合法"), | |||
/** | |||
* 设置的 speed 参数不在0到4的范围内 | |||
*/ | |||
CODE_45083(45083, "设置的 speed 参数不在0到4的范围内"), | |||
/** | |||
* 没有设置 speed 参数 | |||
*/ | |||
CODE_9001036(9001036, "查询起始值 begin 不合法"); | |||
CODE_45084(45084, "没有设置 speed 参数"); | |||
private int code; | |||
private String msg; | |||
@@ -639,7 +653,7 @@ public enum WxMpErrorMsgEnum { | |||
} | |||
/** | |||
* 通过错误代码查找其中文含义. | |||
* 通过错误代码查找其中文含义.. | |||
*/ | |||
public static String findMsgByCode(int code) { | |||
for (WxMpErrorMsgEnum value : WxMpErrorMsgEnum.values()) { | |||
@@ -270,10 +270,10 @@ public class WxCryptUtil { | |||
throw new RuntimeException(e); | |||
} | |||
// appid不相同的情况 | |||
if (!fromAppid.equals(this.appidOrCorpid)) { | |||
throw new RuntimeException("AppID不正确,请核实!"); | |||
} | |||
// appid不相同的情况 暂时忽略这段判断 | |||
// if (!fromAppid.equals(this.appidOrCorpid)) { | |||
// throw new RuntimeException("AppID不正确,请核实!"); | |||
// } | |||
return xmlContent; | |||
@@ -3,6 +3,7 @@ package me.chanjar.weixin.common.util.http; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheMediaDownloadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.jodd.JoddHttpMediaDownloadRequestExecutor; | |||
@@ -25,8 +26,8 @@ public abstract class BaseMediaDownloadRequestExecutor<H, P> implements RequestE | |||
} | |||
@Override | |||
public void execute(String uri, String data, ResponseHandler<File> handler) throws WxErrorException, IOException { | |||
handler.handle(this.execute(uri, data)); | |||
public void execute(String uri, String data, ResponseHandler<File> handler, WxType wxType) throws WxErrorException, IOException { | |||
handler.handle(this.execute(uri, data, wxType)); | |||
} | |||
public static RequestExecutor<File, String> create(RequestHttp requestHttp, File tmpDirFile) { | |||
@@ -3,6 +3,7 @@ package me.chanjar.weixin.common.util.http; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheMediaUploadRequestExecutor; | |||
@@ -23,8 +24,8 @@ public abstract class MediaUploadRequestExecutor<H, P> implements RequestExecuto | |||
} | |||
@Override | |||
public void execute(String uri, File data, ResponseHandler<WxMediaUploadResult> handler) throws WxErrorException, IOException { | |||
handler.handle(this.execute(uri, data)); | |||
public void execute(String uri, File data, ResponseHandler<WxMediaUploadResult> handler, WxType wxType) throws WxErrorException, IOException { | |||
handler.handle(this.execute(uri, data, wxType)); | |||
} | |||
public static RequestExecutor<WxMediaUploadResult, File> create(RequestHttp requestHttp) { | |||
@@ -1,9 +1,10 @@ | |||
package me.chanjar.weixin.common.util.http; | |||
import java.io.IOException; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import java.io.IOException; | |||
/** | |||
* http请求执行器. | |||
* | |||
@@ -16,23 +17,24 @@ public interface RequestExecutor<T, E> { | |||
/** | |||
* 执行http请求. | |||
* | |||
* @param uri uri | |||
* @param data 数据 | |||
* @param uri uri | |||
* @param data 数据 | |||
* @param wxType 微信模块类型 | |||
* @return 响应结果 | |||
* @throws WxErrorException 自定义异常 | |||
* @throws IOException io异常 | |||
*/ | |||
T execute(String uri, E data) throws WxErrorException, IOException; | |||
T execute(String uri, E data, WxType wxType) throws WxErrorException, IOException; | |||
/** | |||
* 执行http请求. | |||
* | |||
* @param uri uri | |||
* @param data 数据 | |||
* @param uri uri | |||
* @param data 数据 | |||
* @param handler http响应处理器 | |||
* @param wxType 微信模块类型 | |||
* @throws WxErrorException 自定义异常 | |||
* @throws IOException io异常 | |||
*/ | |||
void execute(String uri, E data, ResponseHandler<T> handler) throws WxErrorException, IOException; | |||
void execute(String uri, E data, ResponseHandler<T> handler, WxType wxType) throws WxErrorException, IOException; | |||
} |
@@ -2,6 +2,7 @@ package me.chanjar.weixin.common.util.http; | |||
import java.io.IOException; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientSimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimpleGetRequestExecutor; | |||
@@ -21,8 +22,8 @@ public abstract class SimpleGetRequestExecutor<H, P> implements RequestExecutor< | |||
} | |||
@Override | |||
public void execute(String uri, String data, ResponseHandler<String> handler) throws WxErrorException, IOException { | |||
handler.handle(this.execute(uri, data)); | |||
public void execute(String uri, String data, ResponseHandler<String> handler, WxType wxType) throws WxErrorException, IOException { | |||
handler.handle(this.execute(uri, data, wxType)); | |||
} | |||
public static RequestExecutor<String, String> create(RequestHttp requestHttp) { | |||
@@ -2,6 +2,7 @@ package me.chanjar.weixin.common.util.http; | |||
import java.io.IOException; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheSimplePostRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimplePostRequestExecutor; | |||
@@ -21,8 +22,9 @@ public abstract class SimplePostRequestExecutor<H, P> implements RequestExecutor | |||
} | |||
@Override | |||
public void execute(String uri, String data, ResponseHandler<String> handler) throws WxErrorException, IOException { | |||
handler.handle(this.execute(uri, data)); | |||
public void execute(String uri, String data, ResponseHandler<String> handler, WxType wxType) | |||
throws WxErrorException, IOException { | |||
handler.handle(this.execute(uri, data, wxType)); | |||
} | |||
public static RequestExecutor<String, String> create(RequestHttp requestHttp) { | |||
@@ -34,7 +36,7 @@ public abstract class SimplePostRequestExecutor<H, P> implements RequestExecutor | |||
case OK_HTTP: | |||
return new OkHttpSimplePostRequestExecutor(requestHttp); | |||
default: | |||
return null; | |||
throw new IllegalArgumentException("非法请求参数"); | |||
} | |||
} | |||
@@ -1,29 +1,31 @@ | |||
package me.chanjar.weixin.common.util.http.apache; | |||
import java.io.IOException; | |||
import me.chanjar.weixin.common.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.SimpleGetRequestExecutor; | |||
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.impl.client.CloseableHttpClient; | |||
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.SimpleGetRequestExecutor; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/4. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/4 | |||
*/ | |||
public class ApacheHttpClientSimpleGetRequestExecutor extends SimpleGetRequestExecutor<CloseableHttpClient, HttpHost> { | |||
public ApacheHttpClientSimpleGetRequestExecutor(RequestHttp requestHttp) { | |||
super(requestHttp); | |||
} | |||
@Override | |||
public String execute(String uri, String queryParam) throws WxErrorException, IOException { | |||
public String execute(String uri, String queryParam, WxType wxType) throws WxErrorException, IOException { | |||
if (queryParam != null) { | |||
if (uri.indexOf('?') == -1) { | |||
uri += '?'; | |||
@@ -38,7 +40,7 @@ public class ApacheHttpClientSimpleGetRequestExecutor extends SimpleGetRequestEx | |||
try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet)) { | |||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -1,9 +1,12 @@ | |||
package me.chanjar.weixin.common.util.http.apache; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
import org.apache.commons.io.FilenameUtils; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.apache.http.Header; | |||
@@ -14,15 +17,15 @@ import org.apache.http.client.methods.HttpGet; | |||
import org.apache.http.entity.ContentType; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
/** | |||
* Created by ecoolper on 2017/5/5. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/5 | |||
*/ | |||
public class ApacheMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<CloseableHttpClient, HttpHost> { | |||
public ApacheMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | |||
@@ -30,7 +33,7 @@ public class ApacheMediaDownloadRequestExecutor extends BaseMediaDownloadRequest | |||
} | |||
@Override | |||
public File execute(String uri, String queryParam) throws WxErrorException, IOException { | |||
public File execute(String uri, String queryParam, WxType wxType) throws WxErrorException, IOException { | |||
if (queryParam != null) { | |||
if (uri.indexOf('?') == -1) { | |||
uri += '?'; | |||
@@ -51,7 +54,7 @@ public class ApacheMediaDownloadRequestExecutor extends BaseMediaDownloadRequest | |||
if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) { | |||
// application/json; encoding=utf-8 下载媒体文件出错 | |||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||
throw new WxErrorException(WxError.fromJson(responseContent)); | |||
throw new WxErrorException(WxError.fromJson(responseContent, wxType)); | |||
} | |||
} | |||
@@ -1,7 +1,8 @@ | |||
package me.chanjar.weixin.common.util.http.apache; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
@@ -26,7 +27,7 @@ public class ApacheMediaUploadRequestExecutor extends MediaUploadRequestExecutor | |||
} | |||
@Override | |||
public WxMediaUploadResult execute(String uri, File file) throws WxErrorException, IOException { | |||
public WxMediaUploadResult 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(); | |||
@@ -42,7 +43,7 @@ public class ApacheMediaUploadRequestExecutor extends MediaUploadRequestExecutor | |||
} | |||
try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { | |||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -1,5 +1,6 @@ | |||
package me.chanjar.weixin.common.util.http.apache; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
@@ -15,16 +16,18 @@ import org.apache.http.impl.client.CloseableHttpClient; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/4. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/4 | |||
*/ | |||
public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor<CloseableHttpClient, HttpHost> { | |||
public ApacheSimplePostRequestExecutor(RequestHttp requestHttp) { | |||
super(requestHttp); | |||
} | |||
@Override | |||
public String execute(String uri, String postEntity) throws WxErrorException, IOException { | |||
public String execute(String uri, String postEntity, WxType wxType) throws WxErrorException, IOException { | |||
HttpPost httpPost = new HttpPost(uri); | |||
if (requestHttp.getRequestHttpProxy() != null) { | |||
RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); | |||
@@ -47,7 +50,7 @@ public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor<C | |||
return responseContent; | |||
} | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -1,36 +1,38 @@ | |||
package me.chanjar.weixin.common.util.http.jodd; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import org.apache.commons.io.FilenameUtils; | |||
import org.apache.commons.lang3.StringUtils; | |||
import jodd.http.HttpConnectionProvider; | |||
import jodd.http.HttpRequest; | |||
import jodd.http.HttpResponse; | |||
import jodd.http.ProxyInfo; | |||
import jodd.util.StringPool; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.HttpResponseProxy; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
import org.apache.commons.io.FilenameUtils; | |||
import org.apache.commons.lang3.StringUtils; | |||
import java.io.ByteArrayInputStream; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
/** | |||
* Created by ecoolper on 2017/5/5. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/5 | |||
*/ | |||
public class JoddHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<HttpConnectionProvider, ProxyInfo> { | |||
public JoddHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | |||
super(requestHttp, tmpDirFile); | |||
} | |||
@Override | |||
public File execute(String uri, String queryParam) throws WxErrorException, IOException { | |||
public File execute(String uri, String queryParam, WxType wxType) throws WxErrorException, IOException { | |||
if (queryParam != null) { | |||
if (uri.indexOf('?') == -1) { | |||
uri += '?'; | |||
@@ -50,7 +52,7 @@ public class JoddHttpMediaDownloadRequestExecutor extends BaseMediaDownloadReque | |||
String contentType = response.header("Content-Type"); | |||
if (contentType != null && contentType.startsWith("application/json")) { | |||
// application/json; encoding=utf-8 下载媒体文件出错 | |||
throw new WxErrorException(WxError.fromJson(response.bodyText())); | |||
throw new WxErrorException(WxError.fromJson(response.bodyText(), wxType)); | |||
} | |||
String fileName = new HttpResponseProxy(response).getFileName(); | |||
@@ -5,9 +5,9 @@ import jodd.http.HttpRequest; | |||
import jodd.http.HttpResponse; | |||
import jodd.http.ProxyInfo; | |||
import jodd.util.StringPool; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
@@ -16,7 +16,10 @@ import java.io.File; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/5. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/5 | |||
*/ | |||
public class JoddHttpMediaUploadRequestExecutor extends MediaUploadRequestExecutor<HttpConnectionProvider, ProxyInfo> { | |||
public JoddHttpMediaUploadRequestExecutor(RequestHttp requestHttp) { | |||
@@ -24,7 +27,7 @@ public class JoddHttpMediaUploadRequestExecutor extends MediaUploadRequestExecut | |||
} | |||
@Override | |||
public WxMediaUploadResult execute(String uri, File file) throws WxErrorException, IOException { | |||
public WxMediaUploadResult execute(String uri, File file, WxType wxType) throws WxErrorException, IOException { | |||
HttpRequest request = HttpRequest.post(uri); | |||
if (requestHttp.getRequestHttpProxy() != null) { | |||
requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); | |||
@@ -35,7 +38,7 @@ public class JoddHttpMediaUploadRequestExecutor extends MediaUploadRequestExecut | |||
response.charset(StringPool.UTF_8); | |||
String responseContent = response.bodyText(); | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -1,8 +1,11 @@ | |||
package me.chanjar.weixin.common.util.http.jodd; | |||
import jodd.http.*; | |||
import jodd.http.HttpConnectionProvider; | |||
import jodd.http.HttpRequest; | |||
import jodd.http.HttpResponse; | |||
import jodd.http.ProxyInfo; | |||
import jodd.util.StringPool; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
@@ -11,16 +14,18 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/4. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/4 | |||
*/ | |||
public class JoddHttpSimpleGetRequestExecutor extends SimpleGetRequestExecutor<HttpConnectionProvider, ProxyInfo> { | |||
public JoddHttpSimpleGetRequestExecutor(RequestHttp requestHttp) { | |||
super(requestHttp); | |||
} | |||
@Override | |||
public String execute(String uri, String queryParam) throws WxErrorException, IOException { | |||
public String execute(String uri, String queryParam, WxType wxType) throws WxErrorException, IOException { | |||
if (queryParam != null) { | |||
if (uri.indexOf('?') == -1) { | |||
uri += '?'; | |||
@@ -38,7 +43,7 @@ public class JoddHttpSimpleGetRequestExecutor extends SimpleGetRequestExecutor<H | |||
String responseContent = response.bodyText(); | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -5,6 +5,7 @@ import jodd.http.HttpRequest; | |||
import jodd.http.HttpResponse; | |||
import jodd.http.ProxyInfo; | |||
import jodd.util.StringPool; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
@@ -13,16 +14,18 @@ import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/4. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/4 | |||
*/ | |||
public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor<HttpConnectionProvider, ProxyInfo> { | |||
public JoddHttpSimplePostRequestExecutor(RequestHttp requestHttp) { | |||
super(requestHttp); | |||
} | |||
@Override | |||
public String execute(String uri, String postEntity) throws WxErrorException, IOException { | |||
public String execute(String uri, String postEntity, WxType wxType) throws WxErrorException, IOException { | |||
HttpConnectionProvider provider = requestHttp.getRequestHttpClient(); | |||
ProxyInfo proxyInfo = requestHttp.getRequestHttpProxy(); | |||
@@ -39,8 +42,7 @@ public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor | |||
String responseContent = response.bodyText(); | |||
if (responseContent.isEmpty()) { | |||
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容") | |||
.build()); | |||
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); | |||
} | |||
if (responseContent.startsWith("<xml>")) { | |||
@@ -48,7 +50,7 @@ public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor | |||
return responseContent; | |||
} | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -1,5 +1,7 @@ | |||
package me.chanjar.weixin.common.util.http.okhttp; | |||
import lombok.extern.slf4j.Slf4j; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||
@@ -19,18 +21,18 @@ import java.io.File; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/5. | |||
*. | |||
* @author ecoolper | |||
* @date 2017/5/5 | |||
*/ | |||
@Slf4j | |||
public class OkHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<OkHttpClient, OkHttpProxyInfo> { | |||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
public OkHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) { | |||
super(requestHttp, tmpDirFile); | |||
} | |||
@Override | |||
public File execute(String uri, String queryParam) throws WxErrorException, IOException { | |||
logger.debug("OkHttpMediaDownloadRequestExecutor is running"); | |||
public File execute(String uri, String queryParam, WxType wxType) throws WxErrorException, IOException { | |||
if (queryParam != null) { | |||
if (uri.indexOf('?') == -1) { | |||
uri += '?'; | |||
@@ -48,7 +50,7 @@ public class OkHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequest | |||
String contentType = response.header("Content-Type"); | |||
if (contentType != null && contentType.startsWith("application/json")) { | |||
// application/json; encoding=utf-8 下载媒体文件出错 | |||
throw new WxErrorException(WxError.fromJson(response.body().string())); | |||
throw new WxErrorException(WxError.fromJson(response.body().string(), wxType)); | |||
} | |||
String fileName = new HttpResponseProxy(response).getFileName(); | |||
@@ -1,32 +1,29 @@ | |||
package me.chanjar.weixin.common.util.http.okhttp; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
import okhttp3.*; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.File; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/5. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/5 | |||
*/ | |||
public class OkHttpMediaUploadRequestExecutor extends MediaUploadRequestExecutor<OkHttpClient, OkHttpProxyInfo> { | |||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
public OkHttpMediaUploadRequestExecutor(RequestHttp requestHttp) { | |||
super(requestHttp); | |||
} | |||
@Override | |||
public WxMediaUploadResult execute(String uri, File file) throws WxErrorException, IOException { | |||
logger.debug("OkHttpMediaUploadRequestExecutor is running"); | |||
//得到httpClient | |||
OkHttpClient client = requestHttp.getRequestHttpClient(); | |||
public WxMediaUploadResult execute(String uri, File file, WxType wxType) throws WxErrorException, IOException { | |||
RequestBody body = new MultipartBody.Builder() | |||
.setType(MediaType.parse("multipart/form-data")) | |||
@@ -36,9 +33,9 @@ public class OkHttpMediaUploadRequestExecutor extends MediaUploadRequestExecutor | |||
.build(); | |||
Request request = new Request.Builder().url(uri).post(body).build(); | |||
Response response = client.newCall(request).execute(); | |||
Response response = requestHttp.getRequestHttpClient().newCall(request).execute(); | |||
String responseContent = response.body().string(); | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -1,28 +1,29 @@ | |||
package me.chanjar.weixin.common.util.http.okhttp; | |||
import me.chanjar.weixin.common.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.SimpleGetRequestExecutor; | |||
import okhttp3.*; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import okhttp3.OkHttpClient; | |||
import okhttp3.Request; | |||
import okhttp3.Response; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/4. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/4 | |||
*/ | |||
public class OkHttpSimpleGetRequestExecutor extends SimpleGetRequestExecutor<OkHttpClient, OkHttpProxyInfo> { | |||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
public OkHttpSimpleGetRequestExecutor(RequestHttp requestHttp) { | |||
super(requestHttp); | |||
} | |||
@Override | |||
public String execute(String uri, String queryParam) throws WxErrorException, IOException { | |||
logger.debug("OkHttpSimpleGetRequestExecutor is running"); | |||
public String execute(String uri, String queryParam, WxType wxType) throws WxErrorException, IOException { | |||
if (queryParam != null) { | |||
if (uri.indexOf('?') == -1) { | |||
uri += '?'; | |||
@@ -35,7 +36,7 @@ public class OkHttpSimpleGetRequestExecutor extends SimpleGetRequestExecutor<OkH | |||
Request request = new Request.Builder().url(uri).build(); | |||
Response response = client.newCall(request).execute(); | |||
String responseContent = response.body().string(); | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -1,42 +1,38 @@ | |||
package me.chanjar.weixin.common.util.http.okhttp; | |||
import lombok.extern.slf4j.Slf4j; | |||
import me.chanjar.weixin.common.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.SimplePostRequestExecutor; | |||
import okhttp3.*; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.IOException; | |||
/** | |||
* Created by ecoolper on 2017/5/4. | |||
* . | |||
* | |||
* @author ecoolper | |||
* @date 2017/5/4 | |||
*/ | |||
@Slf4j | |||
public class OkHttpSimplePostRequestExecutor extends SimplePostRequestExecutor<OkHttpClient, OkHttpProxyInfo> { | |||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
public OkHttpSimplePostRequestExecutor(RequestHttp requestHttp) { | |||
super(requestHttp); | |||
} | |||
@Override | |||
public String execute(String uri, String postEntity) throws WxErrorException, IOException { | |||
logger.debug("OkHttpSimplePostRequestExecutor running"); | |||
//得到httpClient | |||
OkHttpClient client = requestHttp.getRequestHttpClient(); | |||
MediaType mediaType = MediaType.parse("text/plain; charset=utf-8"); | |||
RequestBody body = RequestBody.create(mediaType, postEntity); | |||
public String execute(String uri, String postEntity, WxType wxType) throws WxErrorException, IOException { | |||
RequestBody body = RequestBody.create(MediaType.parse("text/plain; charset=utf-8"), postEntity); | |||
Request request = new Request.Builder().url(uri).post(body).build(); | |||
Response response = client.newCall(request).execute(); | |||
Response response = requestHttp.getRequestHttpClient().newCall(request).execute(); | |||
String responseContent = response.body().string(); | |||
WxError error = WxError.fromJson(responseContent); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
} | |||
@@ -3,6 +3,7 @@ package me.chanjar.weixin.common.util.json; | |||
import com.google.gson.Gson; | |||
import com.google.gson.GsonBuilder; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.bean.WxNetCheckResult; | |||
import me.chanjar.weixin.common.bean.menu.WxMenu; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
@@ -21,6 +22,8 @@ public class WxGsonBuilder { | |||
INSTANCE.registerTypeAdapter(WxError.class, new WxErrorAdapter()); | |||
INSTANCE.registerTypeAdapter(WxMenu.class, new WxMenuGsonAdapter()); | |||
INSTANCE.registerTypeAdapter(WxMediaUploadResult.class, new WxMediaUploadResultAdapter()); | |||
INSTANCE.registerTypeAdapter(WxNetCheckResult.class, new WxNetCheckResultGsonAdapter()); | |||
} | |||
public static Gson create() { | |||
@@ -0,0 +1,51 @@ | |||
package me.chanjar.weixin.common.util.json; | |||
import com.google.gson.*; | |||
import me.chanjar.weixin.common.bean.WxNetCheckResult; | |||
import java.lang.reflect.Type; | |||
import java.util.ArrayList; | |||
import java.util.List; | |||
/** | |||
* @author billytomato | |||
*/ | |||
public class WxNetCheckResultGsonAdapter implements JsonDeserializer<WxNetCheckResult> { | |||
@Override | |||
public WxNetCheckResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { | |||
WxNetCheckResult result = new WxNetCheckResult(); | |||
JsonArray dnssJson = json.getAsJsonObject().get("dns").getAsJsonArray(); | |||
List<WxNetCheckResult.WxNetCheckDnsInfo> dnsInfoList = new ArrayList<>(); | |||
if (dnssJson != null && dnssJson.size() > 0) { | |||
for (int i = 0; i < dnssJson.size(); i++) { | |||
JsonObject buttonJson = dnssJson.get(i).getAsJsonObject(); | |||
WxNetCheckResult.WxNetCheckDnsInfo dnsInfo = new WxNetCheckResult.WxNetCheckDnsInfo(); | |||
dnsInfo.setIp(GsonHelper.getString(buttonJson, "ip")); | |||
dnsInfo.setRealOperator(GsonHelper.getString(buttonJson, "real_operator")); | |||
dnsInfoList.add(dnsInfo); | |||
} | |||
} | |||
JsonArray pingsJson = json.getAsJsonObject().get("ping").getAsJsonArray(); | |||
List<WxNetCheckResult.WxNetCheckPingInfo> pingInfoList = new ArrayList<>(); | |||
if (pingsJson != null && pingsJson.size() > 0) { | |||
for (int i = 0; i < pingsJson.size(); i++) { | |||
JsonObject pingJson = pingsJson.get(i).getAsJsonObject(); | |||
WxNetCheckResult.WxNetCheckPingInfo pingInfo = new WxNetCheckResult.WxNetCheckPingInfo(); | |||
pingInfo.setIp(GsonHelper.getString(pingJson, "ip")); | |||
pingInfo.setFromOperator(GsonHelper.getString(pingJson, "from_operator")); | |||
pingInfo.setPackageLoss(GsonHelper.getString(pingJson, "package_loss")); | |||
pingInfo.setTime(GsonHelper.getString(pingJson, "time")); | |||
pingInfoList.add(pingInfo); | |||
} | |||
} | |||
result.setDnsInfos(dnsInfoList); | |||
result.setPingInfos(pingInfoList); | |||
return result; | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
package me.chanjar.weixin.common.util.xml; | |||
import com.google.common.base.Joiner; | |||
import com.google.common.base.Splitter; | |||
import com.google.common.collect.Iterables; | |||
import com.thoughtworks.xstream.converters.basic.StringConverter; | |||
/** | |||
* Integer型数组转换器. | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
* @date 2019-08-22 | |||
*/ | |||
public class IntegerArrayConverter extends StringConverter { | |||
@Override | |||
public boolean canConvert(Class type) { | |||
return type == Integer[].class; | |||
} | |||
@Override | |||
public String toString(Object obj) { | |||
return "<![CDATA[" + Joiner.on(",").join((Integer[]) obj) + "]]>"; | |||
} | |||
@Override | |||
public Object fromString(String str) { | |||
final Iterable<String> iterable = Splitter.on(",").split(str); | |||
final String[] strings = Iterables.toArray(iterable, String.class); | |||
Integer[] result = new Integer[strings.length]; | |||
int index = 0; | |||
for (String string : strings) { | |||
result[index++] = Integer.parseInt(string); | |||
} | |||
return result; | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
package me.chanjar.weixin.common.util.xml; | |||
import com.google.common.base.Joiner; | |||
import com.google.common.base.Splitter; | |||
import com.google.common.collect.Iterables; | |||
import com.thoughtworks.xstream.converters.basic.StringConverter; | |||
/** | |||
* Long型数组转换器. | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
* @date 2019-08-22 | |||
*/ | |||
public class LongArrayConverter extends StringConverter { | |||
@Override | |||
public boolean canConvert(Class type) { | |||
return type == Long[].class; | |||
} | |||
@Override | |||
public String toString(Object obj) { | |||
return "<![CDATA[" + Joiner.on(",").join((Long[]) obj) + "]]>"; | |||
} | |||
@Override | |||
public Object fromString(String str) { | |||
final Iterable<String> iterable = Splitter.on(",").split(str); | |||
final String[] strings = Iterables.toArray(iterable, String.class); | |||
Long[] result = new Long[strings.length]; | |||
int index = 0; | |||
for (String string : strings) { | |||
result[index++] = Long.parseLong(string); | |||
} | |||
return result; | |||
} | |||
} |
@@ -2,6 +2,11 @@ package me.chanjar.weixin.common.util.xml; | |||
import com.thoughtworks.xstream.converters.basic.StringConverter; | |||
/** | |||
* CDATA 内容转换器,加上CDATA标签. | |||
* | |||
* @author Daniel Qian | |||
*/ | |||
public class XStreamCDataConverter extends StringConverter { | |||
@Override | |||
@@ -1,34 +1,34 @@ | |||
package me.chanjar.weixin.common.error; | |||
import org.testng.Assert; | |||
import me.chanjar.weixin.common.WxType; | |||
import org.testng.annotations.Test; | |||
import static org.testng.Assert.*; | |||
import static org.testng.Assert.assertEquals; | |||
import static org.testng.Assert.assertNull; | |||
@Test | |||
public class WxErrorTest { | |||
public void testFromJson() { | |||
String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; | |||
WxError wxError = WxError.fromJson(json); | |||
WxError wxError = WxError.fromJson(json, WxType.MP); | |||
assertEquals(40003, wxError.getErrorCode()); | |||
assertEquals(wxError.getErrorMsg(), "invalid openid"); | |||
assertEquals(wxError.getErrorMsgEn(), "invalid openid"); | |||
} | |||
public void testFromBadJson1() { | |||
String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; | |||
WxError wxError = WxError.fromJson(json); | |||
WxError wxError = WxError.fromJson(json, WxType.MP); | |||
assertEquals(40003, wxError.getErrorCode()); | |||
assertEquals(wxError.getErrorMsg(), "invalid openid"); | |||
assertEquals(wxError.getErrorMsgEn(), "invalid openid"); | |||
} | |||
public void testFromBadJson2() { | |||
String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; | |||
WxError wxError = WxError.fromJson(json); | |||
WxError wxError = WxError.fromJson(json, WxType.MP); | |||
assertEquals(0, wxError.getErrorCode()); | |||
assertEquals(wxError.getErrorMsg(), null); | |||
assertNull(wxError.getErrorMsg()); | |||
} | |||
@@ -7,7 +7,7 @@ | |||
<parent> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>wx-java</artifactId> | |||
<version>3.5.0</version> | |||
<version>3.6.0</version> | |||
</parent> | |||
<artifactId>weixin-java-cp</artifactId> | |||
@@ -10,10 +10,12 @@ import me.chanjar.weixin.common.util.http.RequestHttp; | |||
import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult; | |||
import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | |||
import me.chanjar.weixin.cp.bean.WxCpProviderToken; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
/** | |||
* 微信API的Service. | |||
* | |||
* @author chanjaster | |||
*/ | |||
public interface WxCpService { | |||
@@ -72,9 +74,10 @@ public interface WxCpService { | |||
/** | |||
* 获得jsapi_ticket,不强制刷新jsapi_ticket | |||
* 应用的jsapi_ticket用于计算agentConfig(参见“通过agentConfig注入应用的权限”)的签名,签名计算方法与上述介绍的config的签名算法完全相同,但需要注意以下区别: | |||
* | |||
* <p> | |||
* 签名的jsapi_ticket必须使用以下接口获取。且必须用wx.agentConfig中的agentid对应的应用secret去获取access_token。 | |||
* 签名用的noncestr和timestamp必须与wx.agentConfig中的nonceStr和timestamp相同。 | |||
* | |||
* @see #getJsapiTicket(boolean) | |||
*/ | |||
String getAgentJsapiTicket() throws WxErrorException; | |||
@@ -134,6 +137,26 @@ public interface WxCpService { | |||
*/ | |||
String[] getCallbackIp() throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 获取服务商凭证 | |||
* 文档地址:https://work.weixin.qq.com/api/doc#90001/90143/91200 | |||
* 请求方式:POST(HTTPS) | |||
* 请求地址: https://qyapi.weixin.qq.com/cgi-bin/service/get_provider_token | |||
* </pre> | |||
* | |||
* @param corpId 服务商的corpid | |||
* @param providerSecret 服务商的secret,在服务商管理后台可见 | |||
* @return { | |||
* "errcode":0 , | |||
* "errmsg":"ok" , | |||
* "provider_access_token":"enLSZ5xxxxxxJRL", | |||
* "expires_in":7200 | |||
* } | |||
* @throws WxErrorException . | |||
*/ | |||
WxCpProviderToken getProviderToken(String corpId, String providerSecret) throws WxErrorException; | |||
/** | |||
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 | |||
* | |||
@@ -206,7 +229,7 @@ public interface WxCpService { | |||
* @return WxSessionManager | |||
*/ | |||
WxSessionManager getSessionManager(); | |||
/** | |||
* <pre> | |||
* 设置WxSessionManager,只有当需要使用个性化的WxSessionManager的时候才需要调用此方法, | |||
@@ -289,7 +312,7 @@ public interface WxCpService { | |||
/** | |||
* 获取群聊服务 | |||
* | |||
* | |||
* @return 群聊服务 | |||
*/ | |||
WxCpChatService getChatService(); | |||
@@ -18,11 +18,29 @@ import java.util.List; | |||
*/ | |||
public interface WxCpTagService { | |||
/** | |||
* 创建标签. | |||
* <pre> | |||
* 请求地址:https://qyapi.weixin.qq.com/cgi-bin/tag/create?access_token=ACCESS_TOKEN | |||
* 文档地址:https://work.weixin.qq.com/api/doc#90000/90135/90210 | |||
* </pre> | |||
* | |||
* @param name 标签名称,长度限制为32个字以内(汉字或英文字母),标签名不可与其他标签重名。 | |||
* @param id 标签id,非负整型,指定此参数时新增的标签会生成对应的标签id,不指定时则以目前最大的id自增。 | |||
* @return 标签id | |||
* @throws WxErrorException . | |||
*/ | |||
String create(String name, Integer id) throws WxErrorException; | |||
/** | |||
* 创建标签. | |||
* | |||
* @param tagName 标签名 | |||
* @return 标签id | |||
* @throws WxErrorException . | |||
* @deprecated 建议使用 {@link #create(String, Integer)},其中后面的参数可以为空 | |||
*/ | |||
@Deprecated | |||
String create(String tagName) throws WxErrorException; | |||
/** | |||
@@ -30,6 +48,7 @@ public interface WxCpTagService { | |||
* | |||
* @param tagId 标签id | |||
* @param tagName 标签名 | |||
* @throws WxErrorException . | |||
*/ | |||
void update(String tagId, String tagName) throws WxErrorException; | |||
@@ -37,11 +56,15 @@ public interface WxCpTagService { | |||
* 删除标签. | |||
* | |||
* @param tagId 标签id | |||
* @throws WxErrorException . | |||
*/ | |||
void delete(String tagId) throws WxErrorException; | |||
/** | |||
* 获得标签列表. | |||
* | |||
* @return 标签列表 | |||
* @throws WxErrorException . | |||
*/ | |||
List<WxCpTag> listAll() throws WxErrorException; | |||
@@ -49,6 +72,8 @@ public interface WxCpTagService { | |||
* 获取标签成员. | |||
* | |||
* @param tagId 标签ID | |||
* @return 成员列表 | |||
* @throws WxErrorException . | |||
*/ | |||
List<WxCpUser> listUsersByTagId(String tagId) throws WxErrorException; | |||
@@ -57,6 +82,8 @@ public interface WxCpTagService { | |||
* 对应: http://qydev.weixin.qq.com/wiki/index.php?title=管理标签 中的get接口 | |||
* | |||
* @param tagId 标签id | |||
* @return . | |||
* @throws WxErrorException . | |||
*/ | |||
WxCpTagGetResult get(String tagId) throws WxErrorException; | |||
@@ -66,6 +93,8 @@ public interface WxCpTagService { | |||
* @param tagId 标签id | |||
* @param userIds 用户ID 列表 | |||
* @param partyIds 企业部门ID列表 | |||
* @return . | |||
* @throws WxErrorException . | |||
*/ | |||
WxCpTagAddOrRemoveUsersResult addUsers2Tag(String tagId, List<String> userIds, List<String> partyIds) throws WxErrorException; | |||
@@ -75,6 +104,8 @@ public interface WxCpTagService { | |||
* @param tagId 标签id | |||
* @param userIds 用户id列表 | |||
* @param partyIds 企业部门ID列表 | |||
* @return . | |||
* @throws WxErrorException . | |||
*/ | |||
WxCpTagAddOrRemoveUsersResult removeUsersFromTag(String tagId, List<String> userIds, List<String> partyIds) throws WxErrorException; | |||
@@ -15,7 +15,6 @@ import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; | |||
* @author zhenjun cai | |||
*/ | |||
public interface WxCpTpService { | |||
/** | |||
* <pre> | |||
* 验证推送过来的消息的正确性 | |||
@@ -84,15 +83,15 @@ public interface WxCpTpService { | |||
WxAccessToken getCorpToken(String authCorpid, String permanentCode) throws WxErrorException; | |||
/** | |||
* 获取企业永久授权码 | |||
* 获取企业永久授权码 . | |||
* | |||
* @param authCode | |||
* @return | |||
* @param authCode . | |||
* @return . | |||
*/ | |||
WxCpTpCorp getPermanentCode(String authCode) throws WxErrorException; | |||
/** | |||
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 | |||
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求. | |||
* | |||
* @param url 接口地址 | |||
* @param queryParam 请求参数 | |||
@@ -100,7 +99,7 @@ public interface WxCpTpService { | |||
String get(String url, String queryParam) throws WxErrorException; | |||
/** | |||
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 | |||
* 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求. | |||
* | |||
* @param url 接口地址 | |||
* @param postData 请求body字符串 | |||
@@ -124,7 +123,7 @@ public interface WxCpTpService { | |||
/** | |||
* <pre> | |||
* 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试 | |||
* 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试. | |||
* 默认:1000ms | |||
* </pre> | |||
* | |||
@@ -134,7 +133,7 @@ public interface WxCpTpService { | |||
/** | |||
* <pre> | |||
* 设置当微信系统响应系统繁忙时,最大重试次数 | |||
* 设置当微信系统响应系统繁忙时,最大重试次数. | |||
* 默认:5次 | |||
* </pre> | |||
* | |||
@@ -148,21 +147,21 @@ public interface WxCpTpService { | |||
void initHttp(); | |||
/** | |||
* 获取WxMpConfigStorage 对象 | |||
* 获取WxMpConfigStorage 对象. | |||
* | |||
* @return WxMpConfigStorage | |||
*/ | |||
WxCpTpConfigStorage getWxCpTpConfigStorage(); | |||
/** | |||
* 注入 {@link WxCpTpConfigStorage} 的实现 | |||
* 注入 {@link WxCpTpConfigStorage} 的实现. | |||
* | |||
* @param wxConfigProvider 配置对象 | |||
*/ | |||
void setWxCpTpConfigStorage(WxCpTpConfigStorage wxConfigProvider); | |||
/** | |||
* http请求对象 | |||
* http请求对象. | |||
*/ | |||
RequestHttp<?, ?> getRequestHttp(); | |||
@@ -6,6 +6,7 @@ import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import lombok.extern.slf4j.Slf4j; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
@@ -23,10 +24,8 @@ import me.chanjar.weixin.cp.api.*; | |||
import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult; | |||
import me.chanjar.weixin.cp.bean.WxCpMessage; | |||
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; | |||
import me.chanjar.weixin.cp.bean.WxCpProviderToken; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import java.io.File; | |||
import java.io.IOException; | |||
@@ -36,34 +35,36 @@ import java.util.Map; | |||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.*; | |||
/** | |||
* . | |||
* | |||
* @author chanjarster | |||
*/ | |||
@Slf4j | |||
public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestHttp<H, P> { | |||
private WxCpUserService userService = new WxCpUserServiceImpl(this); | |||
private WxCpChatService chatService = new WxCpChatServiceImpl(this); | |||
private WxCpUserService userService = new WxCpUserServiceImpl(this); | |||
private WxCpChatService chatService = new WxCpChatServiceImpl(this); | |||
private WxCpDepartmentService departmentService = new WxCpDepartmentServiceImpl(this); | |||
private WxCpMediaService mediaService = new WxCpMediaServiceImpl(this); | |||
private WxCpMenuService menuService = new WxCpMenuServiceImpl(this); | |||
private WxCpOAuth2Service oauth2Service = new WxCpOAuth2ServiceImpl(this); | |||
private WxCpTagService tagService = new WxCpTagServiceImpl(this); | |||
private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); | |||
private WxCpOaService oaService = new WxCpOaServiceImpl(this); | |||
private WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this); | |||
private WxCpMediaService mediaService = new WxCpMediaServiceImpl(this); | |||
private WxCpMenuService menuService = new WxCpMenuServiceImpl(this); | |||
private WxCpOAuth2Service oauth2Service = new WxCpOAuth2ServiceImpl(this); | |||
private WxCpTagService tagService = new WxCpTagServiceImpl(this); | |||
private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); | |||
private WxCpOaService oaService = new WxCpOaServiceImpl(this); | |||
private WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this); | |||
private WxCpExternalContactService externalContactService = new WxCpExternalContactServiceImpl(this); | |||
/** | |||
* 全局的是否正在刷新access token的锁 | |||
* 全局的是否正在刷新access token的锁. | |||
*/ | |||
protected final Object globalAccessTokenRefreshLock = new Object(); | |||
/** | |||
* 全局的是否正在刷新jsapi_ticket的锁 | |||
* 全局的是否正在刷新jsapi_ticket的锁. | |||
*/ | |||
protected final Object globalJsapiTicketRefreshLock = new Object(); | |||
/** | |||
* 全局的是否正在刷新agent的jsapi_ticket的锁 | |||
* 全局的是否正在刷新agent的jsapi_ticket的锁. | |||
*/ | |||
protected final Object globalAgentJsapiTicketRefreshLock = new Object(); | |||
@@ -72,7 +73,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH | |||
private WxSessionManager sessionManager = new StandardSessionManager(); | |||
/** | |||
* 临时文件目录 | |||
* 临时文件目录. | |||
*/ | |||
private File tmpDirFile; | |||
private int retrySleepMillis = 1000; | |||
@@ -183,8 +184,8 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH | |||
params.put("js_code", jsCode); | |||
params.put("grant_type", "authorization_code"); | |||
String result = this.get(this.configStorage.getApiUrl(JSCODE_TO_SESSION), Joiner.on("&").withKeyValueSeparator("=").join(params)); | |||
return WxCpMaJsCode2SessionResult.fromJson(result); | |||
final String url = this.configStorage.getApiUrl(JSCODE_TO_SESSION); | |||
return WxCpMaJsCode2SessionResult.fromJson(this.get(url, Joiner.on("&").withKeyValueSeparator("=").join(params))); | |||
} | |||
@Override | |||
@@ -199,6 +200,14 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH | |||
return ips; | |||
} | |||
@Override | |||
public WxCpProviderToken getProviderToken(String corpId, String providerSecret) throws WxErrorException { | |||
JsonObject jsonObject = new JsonObject(); | |||
jsonObject.addProperty("corpid", corpId); | |||
jsonObject.addProperty("provider_secret", providerSecret); | |||
return WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(GET_PROVIDER_TOKEN), jsonObject.toString())); | |||
} | |||
@Override | |||
public String get(String url, String queryParam) throws WxErrorException { | |||
return execute(SimpleGetRequestExecutor.create(this), url, queryParam); | |||
@@ -258,7 +267,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH | |||
String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken; | |||
try { | |||
T result = executor.execute(uriWithAccessToken, data); | |||
T result = executor.execute(uriWithAccessToken, data, WxType.CP); | |||
log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | |||
return result; | |||
} catch (WxErrorException e) { | |||
@@ -18,14 +18,17 @@ import me.chanjar.weixin.cp.api.WxCpTpService; | |||
import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult; | |||
import me.chanjar.weixin.cp.bean.WxCpTpCorp; | |||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
import java.io.File; | |||
import java.io.IOException; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tp.*; | |||
/** | |||
* . | |||
* | |||
* @author zhenjun cai | |||
*/ | |||
@Slf4j | |||
@@ -73,7 +76,7 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ | |||
@Override | |||
public String getSuiteTicket(boolean forceRefresh) throws WxErrorException { | |||
// suite ticket由微信服务器推送,不能强制刷新 | |||
// suite ticket由微信服务器推送,不能强制刷新 | |||
// if (forceRefresh) { | |||
// this.configStorage.expireSuiteTicket(); | |||
// } | |||
@@ -93,8 +96,8 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ | |||
params.put("js_code", jsCode); | |||
params.put("grant_type", "authorization_code"); | |||
String result = this.get(configStorage.getApiUrl(WxCpApiPathConsts.Tp.JSCODE_TO_SESSION), Joiner.on("&").withKeyValueSeparator("=").join(params)); | |||
return WxCpMaJsCode2SessionResult.fromJson(result); | |||
final String url = configStorage.getApiUrl(JSCODE_TO_SESSION); | |||
return WxCpMaJsCode2SessionResult.fromJson(this.get(url, Joiner.on("&").withKeyValueSeparator("=").join(params))); | |||
} | |||
@@ -103,20 +106,19 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ | |||
JsonObject jsonObject = new JsonObject(); | |||
jsonObject.addProperty("auth_corpid", authCorpid); | |||
jsonObject.addProperty("permanent_code", permanentCode); | |||
String result = post(configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_CORP_TOKEN), jsonObject.toString()); | |||
String result = post(configStorage.getApiUrl(GET_CORP_TOKEN), jsonObject.toString()); | |||
return WxAccessToken.fromJson(result); | |||
} | |||
@Override | |||
public WxCpTpCorp getPermanentCode(String authCode) throws WxErrorException { | |||
JsonObject jsonObject = new JsonObject(); | |||
jsonObject.addProperty("auth_code", authCode); | |||
String result = post(configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_PERMANENT_CODE), jsonObject.toString()); | |||
String result = post(configStorage.getApiUrl(GET_PERMANENT_CODE), jsonObject.toString()); | |||
jsonObject = new JsonParser().parse(result).getAsJsonObject(); | |||
WxCpTpCorp wxCpTpCorp = WxCpTpCorp.fromJson(jsonObject.get("auth_corp_info").getAsString()); | |||
WxCpTpCorp wxCpTpCorp = WxCpTpCorp.fromJson(jsonObject.get("auth_corp_info").getAsJsonObject().toString()); | |||
wxCpTpCorp.setPermanentCode(jsonObject.get("permanent_code").getAsString()); | |||
return wxCpTpCorp; | |||
} | |||
@@ -180,7 +182,7 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ | |||
String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "suite_access_token=" + suiteAccessToken; | |||
try { | |||
T result = executor.execute(uriWithAccessToken, data); | |||
T result = executor.execute(uriWithAccessToken, data, WxType.CP); | |||
log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | |||
return result; | |||
} catch (WxErrorException e) { | |||
@@ -4,6 +4,7 @@ import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.reflect.TypeToken; | |||
import lombok.RequiredArgsConstructor; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.cp.api.WxCpAgentService; | |||
@@ -36,8 +37,8 @@ public class WxCpAgentServiceImpl implements WxCpAgentService { | |||
throw new IllegalArgumentException("缺少agentid参数"); | |||
} | |||
String responseContent = this.mainService.get(String.format(this.mainService.getWxCpConfigStorage().getApiUrl(AGENT_GET), agentId), null); | |||
return WxCpAgent.fromJson(responseContent); | |||
final String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(AGENT_GET), agentId); | |||
return WxCpAgent.fromJson(this.mainService.get(url, null)); | |||
} | |||
@Override | |||
@@ -46,7 +47,7 @@ public class WxCpAgentServiceImpl implements WxCpAgentService { | |||
String responseContent = this.mainService.post(url, agentInfo.toJson()); | |||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||
if (jsonObject.get("errcode").getAsInt() != 0) { | |||
throw new WxErrorException(WxError.fromJson(responseContent)); | |||
throw new WxErrorException(WxError.fromJson(responseContent, WxType.CP)); | |||
} | |||
} | |||
@@ -56,7 +57,7 @@ public class WxCpAgentServiceImpl implements WxCpAgentService { | |||
String responseContent = this.mainService.get(url, null); | |||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||
if (jsonObject.get("errcode").getAsInt() != 0) { | |||
throw new WxErrorException(WxError.fromJson(responseContent)); | |||
throw new WxErrorException(WxError.fromJson(responseContent, WxType.CP)); | |||
} | |||
return WxCpGsonBuilder.create().fromJson(jsonObject.get("agentlist").toString(), new TypeToken<List<WxCpAgent>>() { | |||
@@ -43,13 +43,14 @@ public class WxCpChatServiceImpl implements WxCpChatService { | |||
if (StringUtils.isNotBlank(chatId)) { | |||
data.put("chatid", chatId); | |||
} | |||
String result = this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_CREATE), WxGsonBuilder.create().toJson(data)); | |||
final String url = this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_CREATE); | |||
String result = this.cpService.post(url, WxGsonBuilder.create().toJson(data)); | |||
return new JsonParser().parse(result).getAsJsonObject().get("chatid").getAsString(); | |||
} | |||
@Override | |||
public String create(String name, String owner, List<String> users, String chatId) throws WxErrorException { | |||
return chatCreate(name, owner, users, chatId); | |||
return this.chatCreate(name, owner, users, chatId); | |||
} | |||
@Override | |||
@@ -72,24 +73,27 @@ public class WxCpChatServiceImpl implements WxCpChatService { | |||
data.put("del_user_list", usersToDelete); | |||
} | |||
this.cpService.post(this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_UPDATE), WxGsonBuilder.create().toJson(data)); | |||
final String url = this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_UPDATE); | |||
this.cpService.post(url, WxGsonBuilder.create().toJson(data)); | |||
} | |||
@Override | |||
public void update(String chatId, String name, String owner, List<String> usersToAdd, List<String> usersToDelete) throws WxErrorException { | |||
public void update(String chatId, String name, String owner, List<String> usersToAdd, List<String> usersToDelete) | |||
throws WxErrorException { | |||
chatUpdate(chatId, name, owner, usersToAdd, usersToDelete); | |||
} | |||
@Override | |||
public WxCpChat chatGet(String chatId) throws WxErrorException { | |||
String result = this.cpService.get(this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_GET_CHATID + chatId), null); | |||
return WxCpGsonBuilder.create() | |||
.fromJson(JSON_PARSER.parse(result).getAsJsonObject().getAsJsonObject("chat_info").toString(), WxCpChat.class); | |||
final String url = this.cpService.getWxCpConfigStorage().getApiUrl(APPCHAT_GET_CHATID + chatId); | |||
String result = this.cpService.get(url, null); | |||
final String chatInfo = JSON_PARSER.parse(result).getAsJsonObject().getAsJsonObject("chat_info").toString(); | |||
return WxCpGsonBuilder.create().fromJson(chatInfo, WxCpChat.class); | |||
} | |||
@Override | |||
public WxCpChat get(String chatId) throws WxErrorException { | |||
return chatGet(chatId); | |||
return this.chatGet(chatId); | |||
} | |||
@Override | |||
@@ -20,22 +20,22 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic | |||
@Override | |||
public WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException { | |||
String responseContent = this.mainService.get(this.mainService.getWxCpConfigStorage().getApiUrl(GET_EXTERNAL_CONTACT + userId), null); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_EXTERNAL_CONTACT + userId); | |||
String responseContent = this.mainService.get(url, null); | |||
return WxCpUserExternalContactInfo.fromJson(responseContent); | |||
} | |||
@Override | |||
public List<String> listExternalContacts(String userId) throws WxErrorException { | |||
String responseContent = this.mainService.get(this.mainService.getWxCpConfigStorage().getApiUrl(LIST_EXTERNAL_CONTACT + userId), null); | |||
WxCpUserExternalContactList list = WxCpUserExternalContactList.fromJson(responseContent); | |||
return list.getExternalUserId(); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_EXTERNAL_CONTACT + userId); | |||
String responseContent = this.mainService.get(url, null); | |||
return WxCpUserExternalContactList.fromJson(responseContent).getExternalUserId(); | |||
} | |||
@Override | |||
public List<String> listFollowUser() throws WxErrorException { | |||
String responseContent = this.mainService.get(this.mainService.getWxCpConfigStorage().getApiUrl(GET_FOLLOW_USER_LIST), null); | |||
WxCpUserWithExternalPermission list = WxCpUserWithExternalPermission.fromJson(responseContent); | |||
return list.getFollowUser(); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_FOLLOW_USER_LIST); | |||
String responseContent = this.mainService.get(url, null); | |||
return WxCpUserWithExternalPermission.fromJson(responseContent).getFollowUser(); | |||
} | |||
} |
@@ -6,6 +6,7 @@ import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.RequestExecutor; | |||
import me.chanjar.weixin.cp.api.WxCpMediaService; | |||
import me.chanjar.weixin.cp.api.WxCpService; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
@@ -59,8 +60,8 @@ public class WxCpMediaServiceImpl implements WxCpMediaService { | |||
@Override | |||
public String uploadImg(File file) throws WxErrorException { | |||
final WxMediaUploadResult result = this.mainService | |||
.execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), this.mainService.getWxCpConfigStorage().getApiUrl(IMG_UPLOAD), file); | |||
return result.getUrl(); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(IMG_UPLOAD); | |||
return this.mainService.execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), url, file) | |||
.getUrl(); | |||
} | |||
} |
@@ -22,6 +22,8 @@ import java.util.List; | |||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; | |||
/** | |||
* . | |||
* | |||
* @author Element | |||
* @date 2019-04-06 11:20 | |||
*/ | |||
@@ -60,7 +62,8 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||
jsonObject.add("useridlist", jsonArray); | |||
String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_CHECKIN_DATA), jsonObject.toString()); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CHECKIN_DATA); | |||
String responseContent = this.mainService.post(url, jsonObject.toString()); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return WxCpGsonBuilder.create() | |||
.fromJson( | |||
@@ -89,7 +92,8 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||
jsonObject.addProperty("datetime", datetime.getTime() / 1000L); | |||
jsonObject.add("useridlist", jsonArray); | |||
String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_CHECKIN_OPTION), jsonObject.toString()); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CHECKIN_OPTION); | |||
String responseContent = this.mainService.post(url, jsonObject.toString()); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return WxCpGsonBuilder.create() | |||
@@ -109,12 +113,14 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||
jsonObject.addProperty("next_spnum", nextSpnum); | |||
} | |||
String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_DATA), jsonObject.toString()); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_DATA); | |||
String responseContent = this.mainService.post(url, jsonObject.toString()); | |||
return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalDataResult.class); | |||
} | |||
@Override | |||
public List<WxCpDialRecord> getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) throws WxErrorException { | |||
public List<WxCpDialRecord> getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) | |||
throws WxErrorException { | |||
JsonObject jsonObject = new JsonObject(); | |||
if (offset == null) { | |||
@@ -141,14 +147,13 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||
jsonObject.addProperty("end_time", endtimestamp); | |||
} | |||
String responseContent = this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(GET_DIAL_RECORD), jsonObject.toString()); | |||
final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_DIAL_RECORD); | |||
String responseContent = this.mainService.post(url, jsonObject.toString()); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return WxCpGsonBuilder.create() | |||
.fromJson( | |||
tmpJsonElement.getAsJsonObject().get("record"), | |||
new TypeToken<List<WxCpDialRecord>>() { | |||
}.getType() | |||
); | |||
return WxCpGsonBuilder.create().fromJson(tmpJsonElement.getAsJsonObject().get("record"), | |||
new TypeToken<List<WxCpDialRecord>>() { | |||
}.getType() | |||
); | |||
} | |||
} |
@@ -10,14 +10,11 @@ import me.chanjar.weixin.cp.bean.WxCpTag; | |||
import me.chanjar.weixin.cp.bean.WxCpTagAddOrRemoveUsersResult; | |||
import me.chanjar.weixin.cp.bean.WxCpTagGetResult; | |||
import me.chanjar.weixin.cp.bean.WxCpUser; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
import java.util.List; | |||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tag.*; | |||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tag.TAG_CREATE; | |||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tag.TAG_UPDATE; | |||
/** | |||
* <pre> | |||
@@ -31,12 +28,27 @@ import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tag.TAG_UPDATE; | |||
public class WxCpTagServiceImpl implements WxCpTagService { | |||
private final WxCpService mainService; | |||
@Override | |||
public String create(String name, Integer id) throws WxErrorException { | |||
JsonObject o = new JsonObject(); | |||
o.addProperty("tagname", name); | |||
if (id != null) { | |||
o.addProperty("tagid", id); | |||
} | |||
return this.create(o); | |||
} | |||
@Override | |||
public String create(String tagName) throws WxErrorException { | |||
JsonObject o = new JsonObject(); | |||
o.addProperty("tagname", tagName); | |||
return this.create(o); | |||
} | |||
private String create(JsonObject param) throws WxErrorException { | |||
String url = this.mainService.getWxCpConfigStorage().getApiUrl(TAG_CREATE); | |||
String responseContent = this.mainService.post(url, o.toString()); | |||
String responseContent = this.mainService.post(url, param.toString()); | |||
JsonElement tmpJsonElement = new JsonParser().parse(responseContent); | |||
return tmpJsonElement.getAsJsonObject().get("tagid").getAsString(); | |||
} | |||
@@ -10,7 +10,6 @@ import me.chanjar.weixin.cp.api.WxCpUserService; | |||
import me.chanjar.weixin.cp.bean.WxCpInviteResult; | |||
import me.chanjar.weixin.cp.bean.WxCpUser; | |||
import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
import java.util.List; | |||
@@ -61,7 +60,7 @@ public class WxCpUserServiceImpl implements WxCpUserService { | |||
} | |||
jsonObject.add("useridlist", jsonArray); | |||
this.mainService.post(USER_BATCH_DELETE, jsonObject.toString()); | |||
this.mainService.post(this.mainService.getWxCpConfigStorage().getApiUrl(USER_BATCH_DELETE), jsonObject.toString()); | |||
} | |||
@Override | |||
@@ -94,7 +93,8 @@ public class WxCpUserServiceImpl implements WxCpUserService { | |||
} | |||
@Override | |||
public List<WxCpUser> listSimpleByDepartment(Long departId, Boolean fetchChild, Integer status) throws WxErrorException { | |||
public List<WxCpUser> listSimpleByDepartment(Long departId, Boolean fetchChild, Integer status) | |||
throws WxErrorException { | |||
String params = ""; | |||
if (fetchChild != null) { | |||
params += "&fetch_child=" + (fetchChild ? "1" : "0"); | |||
@@ -117,7 +117,8 @@ public class WxCpUserServiceImpl implements WxCpUserService { | |||
} | |||
@Override | |||
public WxCpInviteResult invite(List<String> userIds, List<String> partyIds, List<String> tagIds) throws WxErrorException { | |||
public WxCpInviteResult invite(List<String> userIds, List<String> partyIds, List<String> tagIds) | |||
throws WxErrorException { | |||
JsonObject jsonObject = new JsonObject(); | |||
if (userIds != null) { | |||
JsonArray jsonArray = new JsonArray(); | |||
@@ -6,9 +6,9 @@ import lombok.AllArgsConstructor; | |||
import lombok.Builder; | |||
import lombok.Data; | |||
import lombok.NoArgsConstructor; | |||
import me.chanjar.weixin.cp.constant.WxCpConsts.AppChatMsgType; | |||
import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | |||
import me.chanjar.weixin.cp.bean.article.NewArticle; | |||
import me.chanjar.weixin.cp.constant.WxCpConsts.AppChatMsgType; | |||
import java.io.Serializable; | |||
import java.util.List; | |||
@@ -28,16 +28,49 @@ import java.util.List; | |||
public class WxCpAppChatMessage implements Serializable { | |||
private static final long serialVersionUID = -5469013416372240229L; | |||
/** | |||
* 消息类型 | |||
*/ | |||
private String msgType; | |||
/** | |||
* 消息内容 | |||
*/ | |||
private String content; | |||
/** | |||
* 群聊id | |||
*/ | |||
private String chatId; | |||
/** | |||
* 图片媒体文件id,可以调用上传临时素材接口获取 | |||
*/ | |||
private String mediaId; | |||
/** | |||
* 视频消息的标题,不超过128个字节,超过会自动截断 | |||
*/ | |||
private String title; | |||
/** | |||
* 视频消息的描述,不超过512个字节,超过会自动截断 | |||
*/ | |||
private String description; | |||
/** | |||
* 表示是否是保密消息 | |||
*/ | |||
private Boolean safe; | |||
/** | |||
* 点击后跳转的链接。 | |||
*/ | |||
private String url; | |||
/** | |||
* 按钮文字。 默认为“详情”, 不超过4个文字,超过自动截断。 | |||
*/ | |||
private String btnTxt; | |||
/** | |||
* 图文消息,一个图文消息支持1到8条图文 | |||
*/ | |||
private List<NewArticle> articles; | |||
/** | |||
* Mpnews图文消息,一个图文消息支持1到8条图文 | |||
*/ | |||
private List<MpnewsArticle> mpnewsArticles; | |||
/** | |||
@@ -7,10 +7,10 @@ import java.io.Serializable; | |||
import java.util.Map; | |||
/** | |||
* 企业微信 OA 审批数据. | |||
* | |||
* @author Element | |||
* @Package me.chanjar.weixin.cp.bean | |||
* @date 2019-04-06 14:36 | |||
* @Description: 企业微信 OA 审批数据 | |||
*/ | |||
@Data | |||
public class WxCpApprovalDataResult implements Serializable { | |||
@@ -27,17 +27,16 @@ public class WxCpApprovalDataResult implements Serializable { | |||
private Integer total; | |||
@SerializedName("next_spnum") | |||
private Long nextSpnum; | |||
private Long nextSpNum; | |||
private WxCpApprovalData[] data; | |||
@Data | |||
public static class WxCpApprovalData implements Serializable{ | |||
public static class WxCpApprovalData implements Serializable { | |||
private static final long serialVersionUID = -3051785319608491640L; | |||
private String spname; | |||
@SerializedName("spname") | |||
private String spName; | |||
@SerializedName("apply_name") | |||
private String applyName; | |||
@@ -64,6 +63,6 @@ public class WxCpApprovalDataResult implements Serializable { | |||
private String applyUserId; | |||
@SerializedName("comm") | |||
private Map<String,String> comm; | |||
private Map<String, String> comm; | |||
} | |||
} |
@@ -7,14 +7,13 @@ import java.io.Serializable; | |||
import java.util.List; | |||
/** | |||
* 企业微信打卡数据. | |||
* | |||
* @author Element | |||
* @Package me.chanjar.weixin.cp.bean | |||
* @date 2019-04-06 11:01 | |||
* @Description: 企业微信打卡数据 | |||
*/ | |||
@Data | |||
public class WxCpCheckinData implements Serializable { | |||
private static final long serialVersionUID = 1915820330847799605L; | |||
@SerializedName("userid") | |||
@@ -42,7 +41,7 @@ public class WxCpCheckinData implements Serializable { | |||
private String wifiName; | |||
@SerializedName("wifimac") | |||
private String wifiMAC; | |||
private String wifiMac; | |||
private String notes; | |||
@@ -7,10 +7,10 @@ import java.io.Serializable; | |||
import java.util.List; | |||
/** | |||
* 企业微信打卡规则. | |||
* | |||
* @author Element | |||
* @Package me.chanjar.weixin.cp.bean | |||
* @date 2019-04-06 13:22 | |||
* @Description: 企业微信打卡规则 | |||
*/ | |||
@Data | |||
public class WxCpCheckinOption implements Serializable { | |||
@@ -21,10 +21,8 @@ public class WxCpCheckinOption implements Serializable { | |||
private Group group; | |||
@Data | |||
public static class CheckinDate implements Serializable { | |||
private static final long serialVersionUID = -5601722383347110974L; | |||
private List<Integer> workdays; | |||
@@ -36,15 +34,14 @@ public class WxCpCheckinOption implements Serializable { | |||
private Long flexTime; | |||
@SerializedName("noneed_offwork") | |||
private Boolean noneedOffwork; | |||
private Boolean noNeedOffwork; | |||
@SerializedName("limit_aheadtime") | |||
private Long limitAheadtime; | |||
private Long limitAheadTime; | |||
} | |||
@Data | |||
public static class CheckinTime implements Serializable { | |||
private static final long serialVersionUID = -8579954143265336276L; | |||
@SerializedName("work_sec") | |||
@@ -90,16 +87,16 @@ public class WxCpCheckinOption implements Serializable { | |||
private Boolean needPhoto; | |||
@SerializedName("note_can_use_local_pic") | |||
private Boolean note_can_use_local_pic; | |||
private Boolean noteCanUseLocalPic; | |||
@SerializedName("allow_checkin_offworkday") | |||
private Boolean allow_checkin_offworkday; | |||
private Boolean allowCheckinOffWorkday; | |||
@SerializedName("allow_apply_offworkday") | |||
private Boolean allow_apply_offworkday; | |||
private Boolean allowApplyOffWorkday; | |||
@SerializedName("wifimac_infos") | |||
private List<WifiMACInfo> wifiMACInfos; | |||
private List<WifiMacInfo> wifiMacInfos; | |||
@SerializedName("loc_infos") | |||
private List<LocInfo> locInfos; | |||
@@ -107,8 +104,7 @@ public class WxCpCheckinOption implements Serializable { | |||
} | |||
@Data | |||
public static class WifiMACInfo implements Serializable{ | |||
public static class WifiMacInfo implements Serializable { | |||
private static final long serialVersionUID = -4657809185716627368L; | |||
@SerializedName("wifiname") | |||
@@ -119,8 +115,7 @@ public class WxCpCheckinOption implements Serializable { | |||
} | |||
@Data | |||
public static class LocInfo implements Serializable{ | |||
public static class LocInfo implements Serializable { | |||
private static final long serialVersionUID = -618965280668099608L; | |||
private Long lat; | |||
@@ -136,8 +131,7 @@ public class WxCpCheckinOption implements Serializable { | |||
} | |||
@Data | |||
public static class SpeDay implements Serializable{ | |||
public static class SpeDay implements Serializable { | |||
private static final long serialVersionUID = -3538818921359212748L; | |||
private Long timestamp; | |||
@@ -7,10 +7,10 @@ import java.io.Serializable; | |||
import java.util.List; | |||
/** | |||
* 公费电话拨打记录. | |||
* | |||
* @author Element | |||
* @Package me.chanjar.weixin.cp.bean | |||
* @date 2019-04-06 15:38 | |||
* @Description: 公费电话拨打记录 | |||
*/ | |||
@Data | |||
public class WxCpDialRecord implements Serializable { | |||
@@ -39,7 +39,7 @@ public class WxCpDialRecord implements Serializable { | |||
* 主叫信息 | |||
*/ | |||
@Data | |||
public static class Caller implements Serializable{ | |||
public static class Caller implements Serializable { | |||
private static final long serialVersionUID = 4792200404338145607L; | |||
@@ -53,7 +53,7 @@ public class WxCpDialRecord implements Serializable { | |||
* 被叫信息 | |||
*/ | |||
@Data | |||
public static class Callee implements Serializable{ | |||
public static class Callee implements Serializable { | |||
private static final long serialVersionUID = 2390963671336179550L; | |||
@@ -8,7 +8,6 @@ import me.chanjar.weixin.cp.bean.article.MpnewsArticle; | |||
import me.chanjar.weixin.cp.bean.article.NewArticle; | |||
import me.chanjar.weixin.cp.bean.messagebuilder.*; | |||
import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; | |||
import me.chanjar.weixin.cp.constant.WxCpConsts; | |||
import org.apache.commons.lang3.StringUtils; | |||
import java.io.Serializable; | |||
@@ -0,0 +1,30 @@ | |||
package me.chanjar.weixin.cp.bean; | |||
import com.google.gson.annotations.SerializedName; | |||
import lombok.Data; | |||
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | |||
/** | |||
* 服务商凭证. | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
* @date 2019-11-02 | |||
*/ | |||
@Data | |||
public class WxCpProviderToken { | |||
/** | |||
* 服务商的access_token,最长为512字节。 | |||
*/ | |||
@SerializedName("provider_access_token") | |||
private String providerAccessToken; | |||
/** | |||
* provider_access_token有效期(秒) | |||
*/ | |||
@SerializedName("expires_in") | |||
private Integer expiresIn; | |||
public static WxCpProviderToken fromJson(String json) { | |||
return WxCpGsonBuilder.create().fromJson(json, WxCpProviderToken.class); | |||
} | |||
} |
@@ -1,55 +1,55 @@ | |||
package me.chanjar.weixin.cp.bean; | |||
import java.io.Serializable; | |||
import java.util.Map; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import com.thoughtworks.xstream.annotations.XStreamConverter; | |||
import lombok.Data; | |||
import me.chanjar.weixin.common.util.XmlUtils; | |||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.ImageBuilder; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.NewsBuilder; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.TextBuilder; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.VideoBuilder; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.VoiceBuilder; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | |||
import me.chanjar.weixin.cp.util.xml.XStreamTransformer; | |||
/** | |||
* 回调消息包. | |||
* https://work.weixin.qq.com/api/doc#90001/90143/91116 | |||
* | |||
* @author zhenjun cai | |||
*/ | |||
@XStreamAlias("xml") | |||
@Data | |||
public class WxCpTpXmlPackage implements Serializable { | |||
private static final long serialVersionUID = 6031833682211475786L; | |||
/** | |||
* 使用dom4j解析的存放所有xml属性和值的map. | |||
*/ | |||
private Map<String, Object> allFieldsMap; | |||
@XStreamAlias("ToUserName") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
protected String toUserName; | |||
@XStreamAlias("AgentID") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
protected String agentId; | |||
@XStreamAlias("Encrypt") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
protected String msgEncrypt; | |||
public static WxCpTpXmlPackage fromXml(String xml) { | |||
//修改微信变态的消息内容格式,方便解析 | |||
//xml = xml.replace("</PicList><PicList>", ""); | |||
final WxCpTpXmlPackage xmlPackage = XStreamTransformer.fromXml(WxCpTpXmlPackage.class, xml); | |||
xmlPackage.setAllFieldsMap(XmlUtils.xml2Map(xml)); | |||
return xmlPackage; | |||
} | |||
} | |||
package me.chanjar.weixin.cp.bean; | |||
import java.io.Serializable; | |||
import java.util.Map; | |||
import com.thoughtworks.xstream.annotations.XStreamAlias; | |||
import com.thoughtworks.xstream.annotations.XStreamConverter; | |||
import lombok.Data; | |||
import me.chanjar.weixin.common.util.XmlUtils; | |||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.ImageBuilder; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.NewsBuilder; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.TextBuilder; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.VideoBuilder; | |||
import me.chanjar.weixin.cp.bean.outxmlbuilder.VoiceBuilder; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | |||
import me.chanjar.weixin.cp.util.xml.XStreamTransformer; | |||
/** | |||
* 回调消息包. | |||
* https://work.weixin.qq.com/api/doc#90001/90143/91116 | |||
* | |||
* @author zhenjun cai | |||
*/ | |||
@XStreamAlias("xml") | |||
@Data | |||
public class WxCpTpXmlPackage implements Serializable { | |||
private static final long serialVersionUID = 6031833682211475786L; | |||
/** | |||
* 使用dom4j解析的存放所有xml属性和值的map. | |||
*/ | |||
private Map<String, Object> allFieldsMap; | |||
@XStreamAlias("ToUserName") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
protected String toUserName; | |||
@XStreamAlias("AgentID") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
protected String agentId; | |||
@XStreamAlias("Encrypt") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
protected String msgEncrypt; | |||
public static WxCpTpXmlPackage fromXml(String xml) { | |||
//修改微信变态的消息内容格式,方便解析 | |||
//xml = xml.replace("</PicList><PicList>", ""); | |||
final WxCpTpXmlPackage xmlPackage = XStreamTransformer.fromXml(WxCpTpXmlPackage.class, xml); | |||
xmlPackage.setAllFieldsMap(XmlUtils.xml2Map(xml)); | |||
return xmlPackage; | |||
} | |||
} |
@@ -27,6 +27,10 @@ public class WxCpUser implements Serializable { | |||
private Gender gender; | |||
private String email; | |||
private String avatar; | |||
/** | |||
* 地址。长度最大128个字符 | |||
*/ | |||
private String address; | |||
private String avatarMediaId; | |||
private Integer status; | |||
private Integer enable; | |||
@@ -7,6 +7,8 @@ import lombok.Data; | |||
import lombok.extern.slf4j.Slf4j; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.common.util.XmlUtils; | |||
import me.chanjar.weixin.common.util.xml.IntegerArrayConverter; | |||
import me.chanjar.weixin.common.util.xml.LongArrayConverter; | |||
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; | |||
@@ -214,7 +216,7 @@ public class WxCpXmlMessage implements Serializable { | |||
* 成员部门列表,变更时推送,仅返回该应用有查看权限的部门id. | |||
*/ | |||
@XStreamAlias("Department") | |||
@XStreamConverter(value = XStreamCDataConverter.class) | |||
@XStreamConverter(value = LongArrayConverter.class) | |||
private Long[] departments; | |||
/** | |||
@@ -268,6 +270,7 @@ public class WxCpXmlMessage implements Serializable { | |||
* 表示所在部门是否为上级,0-否,1-是,顺序与Department字段的部门逐一对应. | |||
*/ | |||
@XStreamAlias("IsLeaderInDept") | |||
@XStreamConverter(value = IntegerArrayConverter.class) | |||
private Integer[] isLeaderInDept; | |||
/** | |||
@@ -17,12 +17,34 @@ import java.io.Serializable; | |||
public class MpnewsArticle implements Serializable { | |||
private static final long serialVersionUID = 6985871812170756481L; | |||
/** | |||
* 标题,不超过128个字节,超过会自动截断 | |||
*/ | |||
private String title; | |||
/** | |||
* 图文消息缩略图的media_id, 可以通过素材管理接口获得。此处thumb_media_id即上传接口返回的media_id | |||
*/ | |||
private String thumbMediaId; | |||
/** | |||
* 图文消息的作者,不超过64个字节 | |||
*/ | |||
private String author; | |||
/** | |||
* 图文消息点击“阅读原文”之后的页面链接 | |||
*/ | |||
private String contentSourceUrl; | |||
/** | |||
* 图文消息的内容,支持html标签,不超过666 K个字节 | |||
*/ | |||
private String content; | |||
/** | |||
* 图文消息的描述,不超过512个字节,超过会自动截断 | |||
*/ | |||
private String digest; | |||
/** | |||
* 可能已经废弃了,官方文档里已经看不到了 | |||
*/ | |||
@Deprecated | |||
private String showCoverPic; | |||
} |
@@ -1,12 +1,12 @@ | |||
package me.chanjar.weixin.cp.bean.article; | |||
import java.io.Serializable; | |||
import lombok.AllArgsConstructor; | |||
import lombok.Builder; | |||
import lombok.Data; | |||
import lombok.NoArgsConstructor; | |||
import java.io.Serializable; | |||
/** | |||
* <pre> | |||
* Created by BinaryWang on 2017/3/27. | |||
@@ -20,10 +20,21 @@ import lombok.NoArgsConstructor; | |||
@NoArgsConstructor | |||
public class NewArticle implements Serializable { | |||
private static final long serialVersionUID = 4087852055781140659L; | |||
/** | |||
* 标题,不超过128个字节,超过会自动截断 | |||
*/ | |||
private String title; | |||
/** | |||
* 描述,不超过512个字节,超过会自动截断 | |||
*/ | |||
private String description; | |||
/** | |||
* 点击后跳转的链接。 | |||
*/ | |||
private String url; | |||
/** | |||
* 图文消息的图片链接,支持JPG、PNG格式,较好的效果为大图1068*455,小图150*150。 | |||
*/ | |||
private String picUrl; | |||
} |
@@ -20,7 +20,8 @@ public final class WxCpApiPathConsts { | |||
public static final String BATCH_REPLACE_USER = "/cgi-bin/batch/replaceuser"; | |||
public static final String BATCH_GET_RESULT = "/cgi-bin/batch/getresult?jobid="; | |||
public static final String JSCODE_TO_SESSION = "/cgi-bin/miniprogram/jscode2session"; | |||
public static final String GET_TOKEN = "/cgi-bin/gettoken?&corpid=%s&corpsecret=%s"; | |||
public static final String GET_TOKEN = "/cgi-bin/gettoken?corpid=%s&corpsecret=%s"; | |||
public static final String GET_PROVIDER_TOKEN = "/cgi-bin/service/get_provider_token"; | |||
public static class Agent { | |||
public static final String AGENT_GET = "/cgi-bin/agent/get?agentid=%d"; | |||
@@ -1,9 +1,6 @@ | |||
package me.chanjar.weixin.cp.message; | |||
import java.util.ArrayList; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.*; | |||
import java.util.concurrent.ExecutionException; | |||
import java.util.concurrent.ExecutorService; | |||
import java.util.concurrent.Executors; | |||
@@ -18,7 +15,6 @@ import me.chanjar.weixin.common.api.WxMessageDuplicateChecker; | |||
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker; | |||
import me.chanjar.weixin.common.session.InternalSession; | |||
import me.chanjar.weixin.common.session.InternalSessionManager; | |||
import me.chanjar.weixin.common.session.StandardSessionManager; | |||
import me.chanjar.weixin.common.session.WxSessionManager; | |||
import me.chanjar.weixin.common.util.LogExceptionHandler; | |||
import me.chanjar.weixin.cp.api.WxCpService; | |||
@@ -54,9 +50,8 @@ import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; | |||
* @author Daniel Qian | |||
*/ | |||
public class WxCpMessageRouter { | |||
private static final int DEFAULT_THREAD_POOL_SIZE = 100; | |||
protected final Logger log = LoggerFactory.getLogger(WxCpMessageRouter.class); | |||
private final Logger log = LoggerFactory.getLogger(WxCpMessageRouter.class); | |||
private final List<WxCpMessageRouterRule> rules = new ArrayList<>(); | |||
private final WxCpService wxCpService; | |||
@@ -69,6 +64,9 @@ public class WxCpMessageRouter { | |||
private WxErrorExceptionHandler exceptionHandler; | |||
/** | |||
* 构造方法. | |||
*/ | |||
public WxCpMessageRouter(WxCpService wxCpService) { | |||
this.wxCpService = wxCpService; | |||
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE); | |||
@@ -82,8 +80,6 @@ public class WxCpMessageRouter { | |||
* 设置自定义的 {@link ExecutorService} | |||
* 如果不调用该方法,默认使用 Executors.newFixedThreadPool(100) | |||
* </pre> | |||
* | |||
* @param executorService | |||
*/ | |||
public void setExecutorService(ExecutorService executorService) { | |||
this.executorService = executorService; | |||
@@ -94,8 +90,6 @@ public class WxCpMessageRouter { | |||
* 设置自定义的 {@link me.chanjar.weixin.common.api.WxMessageDuplicateChecker} | |||
* 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker} | |||
* </pre> | |||
* | |||
* @param messageDuplicateChecker | |||
*/ | |||
public void setMessageDuplicateChecker(WxMessageDuplicateChecker messageDuplicateChecker) { | |||
this.messageDuplicateChecker = messageDuplicateChecker; | |||
@@ -106,8 +100,6 @@ public class WxCpMessageRouter { | |||
* 设置自定义的{@link me.chanjar.weixin.common.session.WxSessionManager} | |||
* 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.session.StandardSessionManager} | |||
* </pre> | |||
* | |||
* @param sessionManager | |||
*/ | |||
public void setSessionManager(WxSessionManager sessionManager) { | |||
this.sessionManager = sessionManager; | |||
@@ -118,8 +110,6 @@ public class WxCpMessageRouter { | |||
* 设置自定义的{@link me.chanjar.weixin.common.api.WxErrorExceptionHandler} | |||
* 如果不调用该方法,默认使用 {@link me.chanjar.weixin.common.util.LogExceptionHandler} | |||
* </pre> | |||
* | |||
* @param exceptionHandler | |||
*/ | |||
public void setExceptionHandler(WxErrorExceptionHandler exceptionHandler) { | |||
this.exceptionHandler = exceptionHandler; | |||
@@ -130,20 +120,17 @@ public class WxCpMessageRouter { | |||
} | |||
/** | |||
* 开始一个新的Route规则 | |||
* 开始一个新的Route规则. | |||
*/ | |||
public WxCpMessageRouterRule rule() { | |||
return new WxCpMessageRouterRule(this); | |||
} | |||
/** | |||
* 处理微信消息 | |||
* | |||
* @param wxMessage | |||
* @param context | |||
* 处理微信消息. | |||
*/ | |||
public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage, final Map<String, Object> context) { | |||
if (isDuplicateMessage(wxMessage)) { | |||
if (isMsgDuplicated(wxMessage)) { | |||
// 如果是重复消息,那么就不做处理 | |||
return null; | |||
} | |||
@@ -207,48 +194,46 @@ public class WxCpMessageRouter { | |||
return res; | |||
} | |||
/** | |||
* 处理微信消息. | |||
* | |||
*/ | |||
public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) { | |||
return this.route(wxMessage, new HashMap<String, Object>(2)); | |||
} | |||
protected boolean isDuplicateMessage(WxCpXmlMessage wxMessage) { | |||
String messageId; | |||
private boolean isMsgDuplicated(WxCpXmlMessage wxMessage) { | |||
StringBuilder messageId = new StringBuilder(); | |||
if (wxMessage.getMsgId() == null) { | |||
messageId = String.valueOf(wxMessage.getCreateTime()) | |||
+ "-" + StringUtils.trimToEmpty(String.valueOf(wxMessage.getAgentId())) | |||
+ "-" + wxMessage.getFromUserName() | |||
+ "-" + StringUtils.trimToEmpty(wxMessage.getEventKey()) | |||
+ "-" + StringUtils.trimToEmpty(wxMessage.getEvent()) | |||
; | |||
messageId.append(wxMessage.getCreateTime()) | |||
.append("-").append(StringUtils.trimToEmpty(String.valueOf(wxMessage.getAgentId()))) | |||
.append("-").append(wxMessage.getFromUserName()) | |||
.append("-").append(StringUtils.trimToEmpty(wxMessage.getEventKey())) | |||
.append("-").append(StringUtils.trimToEmpty(wxMessage.getEvent())); | |||
} else { | |||
messageId = new StringBuilder().append(wxMessage.getMsgId()) | |||
messageId.append(wxMessage.getMsgId()) | |||
.append("-").append(wxMessage.getCreateTime()) | |||
.append("-").append(wxMessage.getFromUserName()) | |||
.toString(); | |||
.append("-").append(wxMessage.getFromUserName()); | |||
} | |||
return this.messageDuplicateChecker.isDuplicate(messageId); | |||
if (StringUtils.isNotEmpty(wxMessage.getUserId())) { | |||
messageId.append("-").append(wxMessage.getUserId()); | |||
} | |||
if (StringUtils.isNotEmpty(wxMessage.getChangeType())) { | |||
messageId.append("-").append(wxMessage.getChangeType()); | |||
} | |||
return this.messageDuplicateChecker.isDuplicate(messageId.toString()); | |||
} | |||
/** | |||
* 对session的访问结束 | |||
* | |||
* @param wxMessage | |||
* 对session的访问结束. | |||
*/ | |||
protected void sessionEndAccess(WxCpXmlMessage wxMessage) { | |||
private void sessionEndAccess(WxCpXmlMessage wxMessage) { | |||
InternalSession session = ((InternalSessionManager) this.sessionManager).findSession(wxMessage.getFromUserName()); | |||
if (session != null) { | |||
session.endAccess(); | |||
} | |||
} | |||
} |
@@ -1,52 +1,30 @@ | |||
/** | |||
* 对公众平台发送给公众账号的消息加解密示例代码. | |||
* | |||
* @copyright Copyright (c) 1998-2014 Tencent Inc. | |||
* <p> | |||
* 针对org.apache.commons.codec.binary.Base64, | |||
* 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本) | |||
* 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi | |||
* <p> | |||
* 针对org.apache.commons.codec.binary.Base64, | |||
* 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本) | |||
* 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi | |||
*/ | |||
// ------------------------------------------------------------------------ | |||
/** | |||
* 针对org.apache.commons.codec.binary.Base64, | |||
* 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本) | |||
* 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi | |||
*/ | |||
package me.chanjar.weixin.cp.util.crypto; | |||
import org.apache.commons.codec.binary.Base64; | |||
import me.chanjar.weixin.common.util.crypto.WxCryptUtil; | |||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; | |||
public class WxCpTpCryptUtil extends WxCryptUtil { | |||
/** | |||
* 构造函数 | |||
* | |||
* @param wxCpConfigStorage | |||
*/ | |||
public WxCpTpCryptUtil(WxCpTpConfigStorage wxCpTpConfigStorage) { | |||
/* | |||
* @param token 公众平台上,开发者设置的token | |||
* @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey | |||
* @param appidOrCorpid 公众平台corpId | |||
*/ | |||
String encodingAesKey = wxCpTpConfigStorage.getAesKey(); | |||
String token = wxCpTpConfigStorage.getToken(); | |||
String corpId = wxCpTpConfigStorage.getCorpId(); | |||
this.token = token; | |||
this.appidOrCorpid = corpId; | |||
this.aesKey = Base64.decodeBase64(encodingAesKey + "="); | |||
} | |||
} | |||
package me.chanjar.weixin.cp.util.crypto; | |||
import me.chanjar.weixin.common.util.crypto.WxCryptUtil; | |||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; | |||
import org.apache.commons.codec.binary.Base64; | |||
/** | |||
* @author someone | |||
*/ | |||
public class WxCpTpCryptUtil extends WxCryptUtil { | |||
/** | |||
* 构造函数. | |||
*/ | |||
public WxCpTpCryptUtil(WxCpTpConfigStorage wxCpTpConfigStorage) { | |||
/* | |||
* @param token 公众平台上,开发者设置的token | |||
* @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey | |||
* @param appidOrCorpid 公众平台corpId | |||
*/ | |||
String encodingAesKey = wxCpTpConfigStorage.getAesKey(); | |||
String token = wxCpTpConfigStorage.getToken(); | |||
String corpId = wxCpTpConfigStorage.getCorpId(); | |||
this.token = token; | |||
this.appidOrCorpid = corpId; | |||
this.aesKey = Base64.decodeBase64(encodingAesKey + "="); | |||
} | |||
} |
@@ -66,6 +66,7 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||
user.setGender(Gender.fromCode(GsonHelper.getString(o, "gender"))); | |||
user.setEmail(GsonHelper.getString(o, "email")); | |||
user.setAvatar(GsonHelper.getString(o, "avatar")); | |||
user.setAddress(GsonHelper.getString(o, "address")); | |||
user.setAvatarMediaId(GsonHelper.getString(o, "avatar_mediaid")); | |||
user.setStatus(GsonHelper.getInteger(o, "status")); | |||
user.setEnable(GsonHelper.getInteger(o, "enable")); | |||
@@ -186,6 +187,9 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||
if (user.getAvatar() != null) { | |||
o.addProperty("avatar", user.getAvatar()); | |||
} | |||
if (user.getAddress() != null) { | |||
o.addProperty("address", user.getAddress()); | |||
} | |||
if (user.getAvatarMediaId() != null) { | |||
o.addProperty("avatar_mediaid", user.getAvatarMediaId()); | |||
} | |||
@@ -33,4 +33,9 @@ public class BaseWxCpServiceImplTest { | |||
public void testJsCode2Session() throws WxErrorException { | |||
assertThat(this.wxService.jsCode2Session("111")).isNotNull(); | |||
} | |||
@Test | |||
public void testGetProviderToken() throws WxErrorException { | |||
assertThat(this.wxService.getProviderToken("111","123")).isNotNull(); | |||
} | |||
} |
@@ -0,0 +1,172 @@ | |||
package me.chanjar.weixin.cp.api.impl; | |||
import com.google.gson.JsonObject; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.cp.api.WxCpService; | |||
import me.chanjar.weixin.cp.api.WxCpTpService; | |||
import me.chanjar.weixin.cp.bean.WxCpTpCorp; | |||
import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; | |||
import me.chanjar.weixin.cp.config.impl.WxCpTpDefaultConfigImpl; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
import org.testng.annotations.Test; | |||
import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tp.GET_PERMANENT_CODE; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.mockito.Matchers.any; | |||
import static org.mockito.Matchers.anyString; | |||
import static org.mockito.Mockito.*; | |||
import static org.testng.Assert.*; | |||
/** | |||
* 测试代码. | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
* @date 2019-08-18 | |||
*/ | |||
public class BaseWxCpTpServiceImplTest { | |||
private WxCpTpService tpService = spy(new WxCpTpServiceImpl()); | |||
@Test | |||
public void testCheckSignature() { | |||
} | |||
@Test | |||
public void testGetSuiteAccessToken() { | |||
} | |||
@Test | |||
public void testGetSuiteTicket() { | |||
} | |||
@Test | |||
public void testTestGetSuiteTicket() { | |||
} | |||
@Test | |||
public void testJsCode2Session() { | |||
} | |||
@Test | |||
public void testGetCorpToken() { | |||
} | |||
@Test | |||
public void testGetPermanentCode() throws WxErrorException { | |||
String returnJson = "{\n" + | |||
" \"errcode\":0 ,\n" + | |||
" \"errmsg\":\"ok\" ,\n" + | |||
" \"access_token\": \"xxxxxx\", \n" + | |||
" \"expires_in\": 7200, \n" + | |||
" \"permanent_code\": \"xxxx\", \n" + | |||
" \"dealer_corp_info\": \n" + | |||
" {\n" + | |||
" \"corpid\": \"xxxx\",\n" + | |||
" \"corp_name\": \"name\"\n" + | |||
" },\n" + | |||
" \"auth_corp_info\": \n" + | |||
" {\n" + | |||
" \"corpid\": \"xxxx\",\n" + | |||
" \"corp_name\": \"name\",\n" + | |||
" \"corp_type\": \"verified\",\n" + | |||
" \"corp_square_logo_url\": \"yyyyy\",\n" + | |||
" \"corp_user_max\": 50,\n" + | |||
" \"corp_agent_max\": 30,\n" + | |||
" \"corp_full_name\":\"full_name\",\n" + | |||
" \"verified_end_time\":1431775834,\n" + | |||
" \"subject_type\": 1,\n" + | |||
" \"corp_wxqrcode\": \"zzzzz\",\n" + | |||
" \"corp_scale\": \"1-50人\",\n" + | |||
" \"corp_industry\": \"IT服务\",\n" + | |||
" \"corp_sub_industry\": \"计算机软件/硬件/信息服务\",\n" + | |||
" \"location\":\"广东省广州市\"\n" + | |||
" },\n" + | |||
" \"auth_info\":\n" + | |||
" {\n" + | |||
" \"agent\" :\n" + | |||
" [\n" + | |||
" {\n" + | |||
" \"agentid\":1,\n" + | |||
" \"name\":\"NAME\",\n" + | |||
" \"round_logo_url\":\"xxxxxx\",\n" + | |||
" \"square_logo_url\":\"yyyyyy\",\n" + | |||
" \"appid\":1,\n" + | |||
" \"privilege\":\n" + | |||
" {\n" + | |||
" \"level\":1,\n" + | |||
" \"allow_party\":[1,2,3],\n" + | |||
" \"allow_user\":[\"zhansan\",\"lisi\"],\n" + | |||
" \"allow_tag\":[1,2,3],\n" + | |||
" \"extra_party\":[4,5,6],\n" + | |||
" \"extra_user\":[\"wangwu\"],\n" + | |||
" \"extra_tag\":[4,5,6]\n" + | |||
" }\n" + | |||
" },\n" + | |||
" {\n" + | |||
" \"agentid\":2,\n" + | |||
" \"name\":\"NAME2\",\n" + | |||
" \"round_logo_url\":\"xxxxxx\",\n" + | |||
" \"square_logo_url\":\"yyyyyy\",\n" + | |||
" \"appid\":5\n" + | |||
" }\n" + | |||
" ]\n" + | |||
" },\n" + | |||
" \"auth_user_info\":\n" + | |||
" {\n" + | |||
" \"userid\":\"aa\",\n" + | |||
" \"name\":\"xxx\",\n" + | |||
" \"avatar\":\"http://xxx\"\n" + | |||
" }\n" + | |||
"}\n"; | |||
final WxCpTpConfigStorage configStorage = new WxCpTpDefaultConfigImpl(); | |||
tpService.setWxCpTpConfigStorage(configStorage); | |||
JsonObject jsonObject = new JsonObject(); | |||
String authCode = ""; | |||
jsonObject.addProperty("auth_code", authCode); | |||
doReturn(returnJson).when(tpService).post(configStorage.getApiUrl(GET_PERMANENT_CODE), jsonObject.toString()); | |||
final WxCpTpCorp tpCorp = tpService.getPermanentCode(authCode); | |||
assertThat(tpCorp.getPermanentCode()).isEqualTo("xxxx"); | |||
} | |||
@Test | |||
public void testGet() { | |||
} | |||
@Test | |||
public void testPost() { | |||
} | |||
@Test | |||
public void testExecute() { | |||
} | |||
@Test | |||
public void testExecuteInternal() { | |||
} | |||
@Test | |||
public void testSetWxCpTpConfigStorage() { | |||
} | |||
@Test | |||
public void testSetRetrySleepMillis() { | |||
} | |||
@Test | |||
public void testSetMaxRetryTimes() { | |||
} | |||
@Test | |||
public void testGetTmpDirFile() { | |||
} | |||
@Test | |||
public void testSetTmpDirFile() { | |||
} | |||
@Test | |||
public void testGetRequestHttp() { | |||
} | |||
} |
@@ -6,13 +6,17 @@ import me.chanjar.weixin.cp.api.ApiTestModule; | |||
import me.chanjar.weixin.cp.api.WxCpAgentService; | |||
import me.chanjar.weixin.cp.api.WxCpService; | |||
import me.chanjar.weixin.cp.bean.WxCpAgent; | |||
import me.chanjar.weixin.cp.config.WxCpConfigStorage; | |||
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; | |||
import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||
import me.chanjar.weixin.cp.constant.WxCpConsts; | |||
import org.testng.annotations.Guice; | |||
import org.testng.annotations.Test; | |||
import java.util.List; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.core.api.Assertions.contentOf; | |||
import static org.mockito.Mockito.mock; | |||
import static org.mockito.Mockito.when; | |||
import static org.testng.Assert.assertEquals; | |||
@@ -71,7 +75,9 @@ public class WxCpAgentServiceImplTest { | |||
@Test | |||
public void testGet() throws Exception { | |||
String returnJson = "{\"errcode\": 0,\"errmsg\": \"ok\",\"agentid\": 9,\"name\": \"测试应用\",\"square_logo_url\": \"http://wx.qlogo.cn/mmhead/alksjf;lasdjf;lasjfuodiuj3rj2o34j/0\",\"description\": \"这是一个企业号应用\",\"allow_userinfos\": {\"user\": [{\"userid\": \"0009854\"}, {\"userid\": \"1723\"}, {\"userid\": \"5625\"}]},\"allow_partys\": {\"partyid\": [42762742]},\"allow_tags\": {\"tagid\": [23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7]},\"close\": 0,\"redirect_domain\": \"weixin.com.cn\",\"report_location_flag\": 0,\"isreportenter\": 0,\"home_url\": \"\"}"; | |||
when(wxService.get(String.format(wxService.getWxCpConfigStorage().getApiUrl(WxCpApiPathConsts.Agent.AGENT_GET), 9), null)).thenReturn(returnJson); | |||
final WxCpConfigStorage configStorage = new WxCpDefaultConfigImpl(); | |||
when(wxService.getWxCpConfigStorage()).thenReturn(configStorage); | |||
when(wxService.get(String.format(configStorage.getApiUrl(WxCpApiPathConsts.Agent.AGENT_GET), 9), null)).thenReturn(returnJson); | |||
when(wxService.getAgentService()).thenReturn(new WxCpAgentServiceImpl(wxService)); | |||
WxCpAgentService wxAgentService = this.wxService.getAgentService(); | |||
@@ -0,0 +1,28 @@ | |||
package me.chanjar.weixin.cp.bean; | |||
import org.testng.annotations.Test; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.testng.Assert.*; | |||
/** | |||
* . | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
* @date 2019-08-18 | |||
*/ | |||
public class WxCpTpXmlPackageTest { | |||
@Test | |||
public void testFromXml() { | |||
WxCpTpXmlPackage result = WxCpTpXmlPackage.fromXml("<xml> \n" + | |||
" <ToUserName><![CDATA[toUser]]></ToUserName>\n" + | |||
" <AgentID><![CDATA[toAgentID]]></AgentID>\n" + | |||
" <Encrypt><![CDATA[msg_encrypt]]></Encrypt>\n" + | |||
"</xml>\n"); | |||
assertThat(result).isNotNull(); | |||
assertThat(result.getToUserName()).isEqualTo("toUser"); | |||
assertThat(result.getAgentId()).isEqualTo("toAgentID"); | |||
assertThat(result.getMsgEncrypt()).isEqualTo("msg_encrypt"); | |||
} | |||
} |
@@ -2,9 +2,11 @@ package me.chanjar.weixin.cp.bean; | |||
import me.chanjar.weixin.common.api.WxConsts; | |||
import me.chanjar.weixin.cp.constant.WxCpConsts; | |||
import me.chanjar.weixin.cp.util.xml.XStreamTransformer; | |||
import org.testng.annotations.Test; | |||
import static me.chanjar.weixin.cp.constant.WxCpConsts.EventType.TASKCARD_CLICK; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.testng.Assert.assertEquals; | |||
import static org.testng.Assert.assertNotNull; | |||
@@ -222,4 +224,52 @@ public class WxCpXmlMessageTest { | |||
assertEquals(wxMessage.getUserId(), "zhangsan"); | |||
assertEquals(wxMessage.getExternalUserId(), "woAJ2GCAAAXtWyujaWJHDDGi0mACH71w"); | |||
} | |||
public void testChangeContact() { | |||
String xml = "<xml>\n" + | |||
" <ToUserName><![CDATA[toUser]]></ToUserName>\n" + | |||
" <FromUserName><![CDATA[sys]]></FromUserName> \n" + | |||
" <CreateTime>1403610513</CreateTime>\n" + | |||
" <MsgType><![CDATA[event]]></MsgType>\n" + | |||
" <Event><![CDATA[change_contact]]></Event>\n" + | |||
" <ChangeType>update_user</ChangeType>\n" + | |||
" <UserID><![CDATA[zhangsan]]></UserID>\n" + | |||
" <NewUserID><![CDATA[zhangsan001]]></NewUserID>\n" + | |||
" <Name><![CDATA[张三]]></Name>\n" + | |||
" <Department><![CDATA[1,2,3]]></Department>\n" + | |||
" <IsLeaderInDept><![CDATA[1,0,0]]></IsLeaderInDept>\n" + | |||
" <Position><![CDATA[产品经理]]></Position>\n" + | |||
" <Mobile>15913215421</Mobile>\n" + | |||
" <Gender>1</Gender>\n" + | |||
" <Email><![CDATA[zhangsan@gzdev.com]]></Email>\n" + | |||
" <Status>1</Status>\n" + | |||
" <Avatar><![CDATA[http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0]]></Avatar>\n" + | |||
" <Alias><![CDATA[zhangsan]]></Alias>\n" + | |||
" <Telephone><![CDATA[020-3456788]]></Telephone>\n" + | |||
" <Address><![CDATA[广州市]]></Address>\n" + | |||
" <ExtAttr>\n" + | |||
" <Item>\n" + | |||
" <Name><![CDATA[爱好]]></Name>\n" + | |||
" <Type>0</Type>\n" + | |||
" <Text>\n" + | |||
" <Value><![CDATA[旅游]]></Value>\n" + | |||
" </Text>\n" + | |||
" </Item>\n" + | |||
" <Item>\n" + | |||
" <Name><![CDATA[卡号]]></Name>\n" + | |||
" <Type>1</Type>\n" + | |||
" <Web>\n" + | |||
" <Title><![CDATA[企业微信]]></Title>\n" + | |||
" <Url><![CDATA[https://work.weixin.qq.com]]></Url>\n" + | |||
" </Web>\n" + | |||
" </Item>\n" + | |||
" </ExtAttr>\n" + | |||
"</xml>"; | |||
WxCpXmlMessage wxCpXmlMessage = WxCpXmlMessage.fromXml(xml); | |||
assertThat(wxCpXmlMessage).isNotNull(); | |||
assertThat(wxCpXmlMessage.getDepartments()).isNotEmpty(); | |||
System.out.println(XStreamTransformer.toXml(WxCpXmlMessage.class, wxCpXmlMessage)); | |||
} | |||
} |
@@ -1,8 +1,7 @@ | |||
package me.chanjar.weixin.cp.util.json; | |||
import org.testng.annotations.*; | |||
import me.chanjar.weixin.cp.bean.WxCpUser; | |||
import org.testng.annotations.Test; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -32,6 +31,7 @@ public class WxCpUserGsonAdapterTest { | |||
" \"isleader\": 1,\n" + | |||
" \"avatar\": \"http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3WJ6DSZUfiakYe37PKnQhBIeOQBO4czqrnZDS79FH5Wm5m4X69TBicnHFlhiafvDwklOpZeXYQQ2icg/0\",\n" + | |||
" \"telephone\": \"020-123456\",\n" + | |||
" \"address\": \"广州市海珠区新港中路\"," + | |||
" \"enable\": 1,\n" + | |||
" \"alias\": \"jackzhang\",\n" + | |||
" \"extattr\": {\n" + | |||
@@ -82,7 +82,7 @@ public class WxCpUserGsonAdapterTest { | |||
assertThat(user.getOrders()[0]).isEqualTo(1); | |||
assertThat(user.getOrders()[1]).isEqualTo(2); | |||
assertThat(user.getAddress()).isEqualTo("广州市海珠区新港中路"); | |||
assertThat(user.getExternalAttrs()).isNotEmpty(); | |||
final WxCpUser.ExternalAttribute externalAttr1 = user.getExternalAttrs().get(0); | |||
@@ -7,7 +7,7 @@ | |||
<parent> | |||
<groupId>com.github.binarywang</groupId> | |||
<artifactId>wx-java</artifactId> | |||
<version>3.5.0</version> | |||
<version>3.6.0</version> | |||
</parent> | |||
<artifactId>weixin-java-miniapp</artifactId> | |||
@@ -1,6 +1,7 @@ | |||
package cn.binarywang.wx.miniapp.api; | |||
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | |||
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; | |||
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; | |||
import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
@@ -15,6 +16,7 @@ import me.chanjar.weixin.common.error.WxErrorException; | |||
public interface WxMaMsgService { | |||
String KEFU_MESSAGE_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/custom/send"; | |||
String TEMPLATE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send"; | |||
String SUBSCRIBE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send"; | |||
String UNIFORM_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send"; | |||
/** | |||
@@ -36,6 +38,15 @@ public interface WxMaMsgService { | |||
void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | |||
* </pre> | |||
* 发送订阅消息 | |||
*/ | |||
void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 下发小程序和公众号统一的服务消息 | |||
@@ -1,5 +1,6 @@ | |||
package cn.binarywang.wx.miniapp.api; | |||
import cn.binarywang.wx.miniapp.bean.WxMaMediaAsyncCheckResult; | |||
import java.io.File; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
@@ -18,6 +19,8 @@ public interface WxMaSecCheckService { | |||
String MSG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/msg_sec_check"; | |||
String MEDIA_CHECK_ASYNC_URL = "https://api.weixin.qq.com/wxa/media_check_async"; | |||
/** | |||
* <pre> | |||
* 校验一张图片是否含有违法违规内容. | |||
@@ -39,5 +42,25 @@ public interface WxMaSecCheckService { | |||
* 详情请见: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/sec-check/msgSecCheck.html | |||
* </pre> | |||
*/ | |||
boolean checkMessage(String msgString); | |||
boolean checkMessage(String msgString) throws WxErrorException; | |||
/** | |||
* <pre> | |||
* 异步校验图片/音频是否含有违法违规内容。 | |||
* 应用场景举例: | |||
* 语音风险识别:社交类用户发表的语音内容检测; | |||
* 图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等; | |||
* 敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。 | |||
* 频率限制: | |||
* 单个 appId 调用上限为 2000 次/分钟,200,000 次/天;文件大小限制:单个文件大小不超过10M | |||
* 详情请见: | |||
* https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/sec-check/security.mediaCheckAsync.html | |||
* </pre> | |||
* @param mediaUrl 要检测的多媒体url | |||
* @param mediaType 媒体类型,{@link cn.binarywang.wx.miniapp.constant.WxMaConstants.SecCheckMediaType} | |||
* @return | |||
*/ | |||
WxMaMediaAsyncCheckResult mediaCheckAsync(String mediaUrl,int mediaType) throws WxErrorException; | |||
} |
@@ -9,20 +9,29 @@ import me.chanjar.weixin.common.error.WxErrorException; | |||
import java.util.List; | |||
public interface WxMaTemplateService { | |||
//获取小程序模板库标题列表 | |||
/** | |||
* 获取小程序模板库标题列表. | |||
*/ | |||
String TEMPLATE_LIBRARY_LIST_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/library/list"; | |||
//获取模板库某个模板标题下关键词库 | |||
/** | |||
* 获取模板库某个模板标题下关键词库. | |||
*/ | |||
String TEMPLATE_LIBRARY_KEYWORD_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/library/get"; | |||
//组合模板并添加至帐号下的个人模板库 | |||
/** | |||
* 组合模板并添加至帐号下的个人模板库. | |||
*/ | |||
String TEMPLATE_ADD_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/add"; | |||
//获取帐号下已存在的模板列表 | |||
/** | |||
* 获取帐号下已存在的模板列表. | |||
*/ | |||
String TEMPLATE_LIST_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/list"; | |||
//删除帐号下的某个模板 | |||
/** | |||
* 删除帐号下的某个模板. | |||
*/ | |||
String TEMPLATE_DEL_URL = "https://api.weixin.qq.com/cgi-bin/wxopen/template/del"; | |||
/** | |||
@@ -32,9 +41,6 @@ public interface WxMaTemplateService { | |||
* 详情请见: <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500465446_j4CgR&token=&lang=zh_CN">获取小程序模板库标题列表</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/library/list?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* @param offset | |||
* @param count | |||
* @return | |||
*/ | |||
WxMaTemplateLibraryListResult findTemplateLibraryList(int offset, int count) throws WxErrorException; | |||
@@ -45,8 +51,6 @@ public interface WxMaTemplateService { | |||
* 详情请见: <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500465446_j4CgR&token=&lang=zh_CN">获取小程序模板库标题列表</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/library/get?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* @param id | |||
* @return | |||
*/ | |||
WxMaTemplateLibraryGetResult findTemplateLibraryKeywordList(String id) throws WxErrorException; | |||
@@ -57,9 +61,6 @@ public interface WxMaTemplateService { | |||
* 详情请见: <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500465446_j4CgR&token=&lang=zh_CN">获取小程序模板库标题列表</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/add?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* @param id | |||
* @param keywordIdList | |||
* @return | |||
*/ | |||
WxMaTemplateAddResult addTemplate(String id, List<Integer> keywordIdList) throws WxErrorException; | |||
@@ -70,9 +71,6 @@ public interface WxMaTemplateService { | |||
* 详情请见: <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500465446_j4CgR&token=&lang=zh_CN">获取小程序模板库标题列表</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/list?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* @param offset | |||
* @param count | |||
* @return | |||
*/ | |||
WxMaTemplateListResult findTemplateList(int offset, int count) throws WxErrorException; | |||
@@ -83,7 +81,6 @@ public interface WxMaTemplateService { | |||
* 详情请见: <a href="https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1500465446_j4CgR&token=&lang=zh_CN">获取小程序模板库标题列表</a> | |||
* 接口url格式: https://api.weixin.qq.com/cgi-bin/wxopen/template/list?access_token=ACCESS_TOKEN | |||
* </pre> | |||
* @param templateId | |||
*/ | |||
boolean delTemplate(String templateId) throws WxErrorException; | |||
} |
@@ -12,6 +12,7 @@ import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import com.google.gson.reflect.TypeToken; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import org.apache.commons.lang3.time.DateFormatUtils; | |||
@@ -23,14 +24,11 @@ import java.util.List; | |||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||
* @since 2018-04-28 | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaAnalysisServiceImpl implements WxMaAnalysisService { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
private WxMaService wxMaService; | |||
public WxMaAnalysisServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public List<WxMaSummaryTrend> getDailySummaryTrend(Date beginDate, Date endDate) throws WxErrorException { | |||
return getAnalysisResultAsList(GET_DAILY_SUMMARY_TREND_URL, beginDate, endDate, | |||
@@ -8,6 +8,7 @@ import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import java.util.List; | |||
import lombok.AllArgsConstructor; | |||
import org.apache.commons.lang3.StringUtils; | |||
import cn.binarywang.wx.miniapp.api.WxMaCodeService; | |||
@@ -31,14 +32,11 @@ import me.chanjar.weixin.common.util.json.GsonHelper; | |||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||
* @since 2018-04-26 20:00 | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaCodeServiceImpl implements WxMaCodeService { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
private WxMaService wxMaService; | |||
public WxMaCodeServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public void commit(WxMaCodeCommitRequest commitRequest) throws WxErrorException { | |||
this.wxMaService.post(COMMIT_URL, commitRequest.toJson()); | |||
@@ -50,7 +48,7 @@ public class WxMaCodeServiceImpl implements WxMaCodeService { | |||
Path qrCodeFilePath = null; | |||
try { | |||
RequestExecutor<File, String> executor = BaseMediaDownloadRequestExecutor | |||
.create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("weixin-java-tools-ma-" + appId).toFile()); | |||
.create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxjava-ma-" + appId).toFile()); | |||
final StringBuilder url = new StringBuilder(GET_QRCODE_URL); | |||
if (StringUtils.isNotBlank(path)) { | |||
@@ -5,6 +5,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import com.google.gson.JsonElement; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.RandomUtils; | |||
@@ -19,19 +20,18 @@ import java.util.concurrent.locks.Lock; | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaJsapiServiceImpl implements WxMaJsapiService { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
private WxMaService wxMaService; | |||
public WxMaJsapiServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public String getCardApiTicket() throws WxErrorException { | |||
return getCardApiTicket(false); | |||
} | |||
@Override | |||
public String getCardApiTicket(boolean forceRefresh) throws WxErrorException { | |||
Lock lock = this.wxMaService.getWxMaConfig().getCardApiTicketLock(); | |||
try { | |||
@@ -2,8 +2,9 @@ package cn.binarywang.wx.miniapp.api.impl; | |||
import cn.binarywang.wx.miniapp.api.WxMaMediaService; | |||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.fs.FileUtils; | |||
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | |||
@@ -19,13 +20,10 @@ import java.util.UUID; | |||
/** | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaMediaServiceImpl implements WxMaMediaService { | |||
private WxMaService wxMaService; | |||
public WxMaMediaServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public WxMediaUploadResult uploadMedia(String mediaType, String fileType, InputStream inputStream) throws WxErrorException { | |||
try { | |||
@@ -3,37 +3,51 @@ package cn.binarywang.wx.miniapp.api.impl; | |||
import cn.binarywang.wx.miniapp.api.WxMaMsgService; | |||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; | |||
import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; | |||
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; | |||
import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; | |||
import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||
import com.google.gson.JsonObject; | |||
import com.google.gson.JsonParser; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
/** | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaMsgServiceImpl implements WxMaMsgService { | |||
private static final JsonParser JSON_PARSER = new JsonParser(); | |||
private WxMaService wxMaService; | |||
public WxMaMsgServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public boolean sendKefuMsg(WxMaKefuMessage message) throws WxErrorException { | |||
String responseContent = this.wxMaService.post(KEFU_MESSAGE_SEND_URL, message.toJson()); | |||
return responseContent != null; | |||
} | |||
/** | |||
* <pre> | |||
* 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能 | |||
* </pre> | |||
*/ | |||
@Override | |||
public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { | |||
String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); | |||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||
if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { | |||
throw new WxErrorException(WxError.fromJson(responseContent)); | |||
throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp)); | |||
} | |||
} | |||
@Override | |||
public void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException { | |||
String responseContent = this.wxMaService.post(SUBSCRIBE_MSG_SEND_URL, subscribeMessage.toJson()); | |||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||
if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { | |||
throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp)); | |||
} | |||
} | |||
@@ -42,7 +56,7 @@ public class WxMaMsgServiceImpl implements WxMaMsgService { | |||
String responseContent = this.wxMaService.post(UNIFORM_MSG_SEND_URL, uniformMessage.toJson()); | |||
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||
if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) { | |||
throw new WxErrorException(WxError.fromJson(responseContent)); | |||
throw new WxErrorException(WxError.fromJson(responseContent, WxType.MiniApp)); | |||
} | |||
} | |||
@@ -4,33 +4,28 @@ import cn.binarywang.wx.miniapp.api.WxMaPluginService; | |||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import cn.binarywang.wx.miniapp.bean.WxMaPluginListResult; | |||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
import com.google.common.collect.ImmutableMap; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
@AllArgsConstructor | |||
public class WxMaPluginServiceImpl implements WxMaPluginService { | |||
private WxMaService wxMaService; | |||
public WxMaPluginServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public void applyPlugin(String pluginAppId, String reason) throws WxErrorException { | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("action", "apply"); | |||
params.put("plugin_appid", pluginAppId); | |||
params.put("reason", reason); | |||
Map<String, String> params = ImmutableMap.of("action", "apply", | |||
"plugin_appid", pluginAppId, | |||
"reason", reason); | |||
this.wxMaService.post(PLUGIN_URL, WxMaGsonBuilder.create().toJson(params)); | |||
} | |||
@Override | |||
public WxMaPluginListResult getPluginList() throws WxErrorException { | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("action", "list"); | |||
Map<String, String> params = ImmutableMap.of("action", "list"); | |||
String responseContent = this.wxMaService.post(PLUGIN_URL, WxMaGsonBuilder.create().toJson(params)); | |||
return WxMaPluginListResult.fromJson(responseContent); | |||
@@ -38,19 +33,15 @@ public class WxMaPluginServiceImpl implements WxMaPluginService { | |||
@Override | |||
public void unbindPlugin(String pluginAppId) throws WxErrorException { | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("action", "unbind"); | |||
params.put("plugin_appid", pluginAppId); | |||
Map<String, String> params = ImmutableMap.of("action", "unbind", "plugin_appid", pluginAppId); | |||
this.wxMaService.post(PLUGIN_URL, WxMaGsonBuilder.create().toJson(params)); | |||
} | |||
@Override | |||
public void updatePlugin(String pluginAppId, String userVersion) throws WxErrorException { | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("action", "update"); | |||
params.put("plugin_appid", pluginAppId); | |||
params.put("user_version", userVersion); | |||
Map<String, String> params = ImmutableMap.of("action", "update", | |||
"plugin_appid", pluginAppId, | |||
"user_version", userVersion); | |||
this.wxMaService.post(PLUGIN_URL, WxMaGsonBuilder.create().toJson(params)); | |||
} | |||
@@ -1,7 +1,5 @@ | |||
package cn.binarywang.wx.miniapp.api.impl; | |||
import java.io.File; | |||
import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | |||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | |||
@@ -10,18 +8,18 @@ import cn.binarywang.wx.miniapp.bean.WxaCode; | |||
import cn.binarywang.wx.miniapp.bean.WxaCodeUnlimit; | |||
import cn.binarywang.wx.miniapp.util.QrcodeBytesRequestExecutor; | |||
import cn.binarywang.wx.miniapp.util.QrcodeRequestExecutor; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import java.io.File; | |||
/** | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaQrcodeServiceImpl implements WxMaQrcodeService { | |||
private WxMaService wxMaService; | |||
public WxMaQrcodeServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public byte[] createQrcodeBytes(String path, int width) throws WxErrorException { | |||
final QrcodeBytesRequestExecutor executor = new QrcodeBytesRequestExecutor(this.wxMaService.getRequestHttp()); | |||
@@ -6,6 +6,7 @@ import cn.binarywang.wx.miniapp.api.WxMaRunService; | |||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import cn.binarywang.wx.miniapp.bean.WxMaRunStepInfo; | |||
import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; | |||
import lombok.AllArgsConstructor; | |||
/** | |||
* <pre> | |||
@@ -15,13 +16,10 @@ import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaRunServiceImpl implements WxMaRunService { | |||
private WxMaService service; | |||
public WxMaRunServiceImpl(WxMaService service) { | |||
this.service = service; | |||
} | |||
@Override | |||
public List<WxMaRunStepInfo> getRunStepInfo(String sessionKey, String encryptedData, String ivStr) { | |||
return WxMaRunStepInfo.fromJson(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr)); | |||
@@ -1,10 +1,11 @@ | |||
package cn.binarywang.wx.miniapp.api.impl; | |||
import java.io.File; | |||
import cn.binarywang.wx.miniapp.api.WxMaSecCheckService; | |||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import cn.binarywang.wx.miniapp.bean.WxMaMediaAsyncCheckResult; | |||
import com.google.gson.JsonObject; | |||
import java.io.File; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
@@ -17,12 +18,10 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||
* | |||
* @author <a href="https://github.com/binarywang">Binary Wang</a> | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaSecCheckServiceImpl implements WxMaSecCheckService { | |||
private WxMaService service; | |||
public WxMaSecCheckServiceImpl(WxMaService service) { | |||
this.service = service; | |||
} | |||
private WxMaService service; | |||
@Override | |||
public boolean checkImage(File file) throws WxErrorException { | |||
@@ -33,16 +32,24 @@ public class WxMaSecCheckServiceImpl implements WxMaSecCheckService { | |||
} | |||
@Override | |||
public boolean checkMessage(String msgString) { | |||
public boolean checkMessage(String msgString) throws WxErrorException { | |||
JsonObject jsonObject = new JsonObject(); | |||
jsonObject.addProperty("content", msgString); | |||
try { | |||
this.service.post(MSG_SEC_CHECK_URL, jsonObject.toString()); | |||
} catch (WxErrorException e) { | |||
return false; | |||
} | |||
this.service.post(MSG_SEC_CHECK_URL, jsonObject.toString()); | |||
return true; | |||
} | |||
@Override | |||
public WxMaMediaAsyncCheckResult mediaCheckAsync(String mediaUrl, int mediaType) | |||
throws WxErrorException { | |||
JsonObject jsonObject = new JsonObject(); | |||
jsonObject.addProperty("media_url", mediaUrl); | |||
jsonObject.addProperty("media_type", mediaType); | |||
return WxMaMediaAsyncCheckResult | |||
.fromJson(this.service.post(MEDIA_CHECK_ASYNC_URL, jsonObject.toString())); | |||
} | |||
} |
@@ -119,7 +119,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||
} | |||
try (CloseableHttpResponse response = getRequestHttpClient().execute(httpGet)) { | |||
String resultContent = new BasicResponseHandler().handleResponse(response); | |||
WxError error = WxError.fromJson(resultContent); | |||
WxError error = WxError.fromJson(resultContent, WxType.MiniApp); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
@@ -251,7 +251,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||
String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + accessToken; | |||
try { | |||
T result = executor.execute(uriWithAccessToken, data); | |||
T result = executor.execute(uriWithAccessToken, data, WxType.MiniApp); | |||
log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | |||
return result; | |||
} catch (WxErrorException e) { | |||
@@ -4,6 +4,7 @@ import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import cn.binarywang.wx.miniapp.api.WxMaSettingService; | |||
import cn.binarywang.wx.miniapp.bean.WxMaDomainAction; | |||
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import java.util.HashMap; | |||
@@ -13,13 +14,10 @@ import java.util.Map; | |||
* @author <a href="https://github.com/charmingoh">Charming</a> | |||
* @since 2018-04-27 15:46 | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaSettingServiceImpl implements WxMaSettingService { | |||
private WxMaService wxMaService; | |||
public WxMaSettingServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public WxMaDomainAction modifyDomain(WxMaDomainAction domainAction) throws WxErrorException { | |||
String responseContent = this.wxMaService.post(MODIFY_DOMAIN_URL, domainAction.toJson()); | |||
@@ -4,17 +4,15 @@ import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import cn.binarywang.wx.miniapp.api.WxMaShareService; | |||
import cn.binarywang.wx.miniapp.bean.WxMaShareInfo; | |||
import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; | |||
import lombok.AllArgsConstructor; | |||
/** | |||
* @author zhfish | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaShareServiceImpl implements WxMaShareService { | |||
private WxMaService service; | |||
public WxMaShareServiceImpl(WxMaService service) { | |||
this.service = service; | |||
} | |||
@Override | |||
public WxMaShareInfo getShareInfo(String sessionKey, String encryptedData, String ivStr) { | |||
return WxMaShareInfo.fromJson(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr)); | |||
@@ -1,101 +1,58 @@ | |||
package cn.binarywang.wx.miniapp.api.impl; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||
import cn.binarywang.wx.miniapp.api.WxMaTemplateService; | |||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult; | |||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; | |||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; | |||
import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import com.google.common.collect.ImmutableMap; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||
public class WxMaTemplateServiceImpl implements WxMaTemplateService { | |||
import java.util.List; | |||
import java.util.Map; | |||
/** | |||
* @author Binary | |||
*/ | |||
@AllArgsConstructor | |||
public class WxMaTemplateServiceImpl implements WxMaTemplateService { | |||
private WxMaService wxMaService; | |||
public WxMaTemplateServiceImpl(WxMaService wxMaService) { | |||
this.wxMaService = wxMaService; | |||
} | |||
@Override | |||
public WxMaTemplateLibraryListResult findTemplateLibraryList(int offset, int count) throws WxErrorException { | |||
Map<String, Integer> params = new HashMap<>(); | |||
params.put("offset", offset); | |||
params.put("count", count); | |||
Map<String, Integer> params = ImmutableMap.of("offset", offset, "count", count); | |||
String responseText = this.wxMaService.post(TEMPLATE_LIBRARY_LIST_URL, WxGsonBuilder.create().toJson(params)); | |||
WxError wxError = WxError.fromJson(responseText); | |||
if (wxError.getErrorCode() == 0) { | |||
return WxMaTemplateLibraryListResult.fromJson(responseText); | |||
} else { | |||
throw new WxErrorException(wxError); | |||
} | |||
return WxMaTemplateLibraryListResult.fromJson(responseText); | |||
} | |||
@Override | |||
public WxMaTemplateLibraryGetResult findTemplateLibraryKeywordList(String id) throws WxErrorException { | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("id", id); | |||
String responseText = this.wxMaService.post(TEMPLATE_LIBRARY_KEYWORD_URL, WxGsonBuilder.create().toJson(params)); | |||
WxError wxError = WxError.fromJson(responseText); | |||
if (wxError.getErrorCode() == 0) { | |||
return WxMaTemplateLibraryGetResult.fromJson(responseText); | |||
} else { | |||
throw new WxErrorException(wxError); | |||
} | |||
String responseText = this.wxMaService.post(TEMPLATE_LIBRARY_KEYWORD_URL, | |||
WxGsonBuilder.create().toJson(ImmutableMap.of("id", id))); | |||
return WxMaTemplateLibraryGetResult.fromJson(responseText); | |||
} | |||
@Override | |||
public WxMaTemplateAddResult addTemplate(String id, List<Integer> keywordIdList) throws WxErrorException { | |||
Map<String, Object> params = new HashMap<>(); | |||
params.put("id", id); | |||
params.put("keyword_id_list", keywordIdList.toArray()); | |||
String responseText = this.wxMaService.post(TEMPLATE_ADD_URL, WxGsonBuilder.create().toJson(params)); | |||
WxError wxError = WxError.fromJson(responseText); | |||
if (wxError.getErrorCode() == 0) { | |||
return WxMaTemplateAddResult.fromJson(responseText); | |||
} else { | |||
throw new WxErrorException(wxError); | |||
} | |||
String responseText = this.wxMaService.post(TEMPLATE_ADD_URL, | |||
WxGsonBuilder.create().toJson(ImmutableMap.of("id", id, "keyword_id_list", keywordIdList.toArray()))); | |||
return WxMaTemplateAddResult.fromJson(responseText); | |||
} | |||
@Override | |||
public WxMaTemplateListResult findTemplateList(int offset, int count) throws WxErrorException { | |||
Map<String, Integer> params = new HashMap<>(); | |||
params.put("offset", offset); | |||
params.put("count", count); | |||
Map<String, Integer> params = ImmutableMap.of("offset", offset, "count", count); | |||
String responseText = this.wxMaService.post(TEMPLATE_LIST_URL, WxGsonBuilder.create().toJson(params)); | |||
WxError wxError = WxError.fromJson(responseText); | |||
if (wxError.getErrorCode() == 0) { | |||
return WxMaTemplateListResult.fromJson(responseText); | |||
} else { | |||
throw new WxErrorException(wxError); | |||
} | |||
return WxMaTemplateListResult.fromJson(responseText); | |||
} | |||
@Override | |||
public boolean delTemplate(String templateId) throws WxErrorException { | |||
Map<String, String> params = new HashMap<>(); | |||
params.put("template_id", templateId); | |||
String responseText = this.wxMaService.post(TEMPLATE_DEL_URL, WxGsonBuilder.create().toJson(params)); | |||
WxError wxError = WxError.fromJson(responseText); | |||
if (wxError.getErrorCode() == 0) { | |||
return true; | |||
} else { | |||
throw new WxErrorException(wxError); | |||
} | |||
Map<String, String> params = ImmutableMap.of("template_id", templateId); | |||
this.wxMaService.post(TEMPLATE_DEL_URL, WxGsonBuilder.create().toJson(params)); | |||
return true; | |||
} | |||
} |
@@ -10,7 +10,6 @@ import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; | |||
import com.google.gson.JsonArray; | |||
import com.google.gson.JsonObject; | |||
import lombok.AllArgsConstructor; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.SignUtils; | |||
import org.apache.commons.codec.digest.DigestUtils; | |||
@@ -49,11 +48,7 @@ public class WxMaUserServiceImpl implements WxMaUserService { | |||
String params = param.toString(); | |||
String signature = SignUtils.createHmacSha256Sign(params, sessionKey); | |||
String url = String.format(SET_USER_STORAGE, config.getAppid(), signature, openid, "hmac_sha256"); | |||
String result = this.service.post(url, params); | |||
WxError error = WxError.fromJson(result); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
this.service.post(url, params); | |||
} | |||
@Override | |||