| @@ -6,7 +6,7 @@ | |||||
| <modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <artifactId>wx-java</artifactId> | <artifactId>wx-java</artifactId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| <packaging>pom</packaging> | <packaging>pom</packaging> | ||||
| <name>WxJava - Weixin/Wechat Java SDK</name> | <name>WxJava - Weixin/Wechat Java SDK</name> | ||||
| <description>微信开发Java SDK</description> | <description>微信开发Java SDK</description> | ||||
| @@ -99,6 +99,7 @@ | |||||
| </scm> | </scm> | ||||
| <modules> | <modules> | ||||
| <module>weixin-graal</module> | |||||
| <module>weixin-java-common</module> | <module>weixin-java-common</module> | ||||
| <module>weixin-java-cp</module> | <module>weixin-java-cp</module> | ||||
| <module>weixin-java-mp</module> | <module>weixin-java-mp</module> | ||||
| @@ -172,7 +173,7 @@ | |||||
| <dependency> | <dependency> | ||||
| <groupId>com.thoughtworks.xstream</groupId> | <groupId>com.thoughtworks.xstream</groupId> | ||||
| <artifactId>xstream</artifactId> | <artifactId>xstream</artifactId> | ||||
| <version>1.4.11</version> | |||||
| <version>1.4.11.1</version> | |||||
| </dependency> | </dependency> | ||||
| <!-- 由于guava较新的21.0版本需要jdk8,故而此处采用较低版本 --> | <!-- 由于guava较新的21.0版本需要jdk8,故而此处采用较低版本 --> | ||||
| <dependency> | <dependency> | ||||
| @@ -242,6 +243,12 @@ | |||||
| <version>2.9.0</version> | <version>2.9.0</version> | ||||
| <scope>provided</scope> | <scope>provided</scope> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>org.redisson</groupId> | |||||
| <artifactId>redisson</artifactId> | |||||
| <version>3.12.0</version> | |||||
| <scope>provided</scope> | |||||
| </dependency> | |||||
| <dependency> | <dependency> | ||||
| <groupId>org.projectlombok</groupId> | <groupId>org.projectlombok</groupId> | ||||
| <artifactId>lombok</artifactId> | <artifactId>lombok</artifactId> | ||||
| @@ -325,6 +332,14 @@ | |||||
| </plugins> | </plugins> | ||||
| </build> | </build> | ||||
| </profile> | </profile> | ||||
| <profile> | |||||
| <id>native-image</id> | |||||
| <activation> | |||||
| <activeByDefault>false</activeByDefault> | |||||
| </activation> | |||||
| </profile> | |||||
| </profiles> | </profiles> | ||||
| <build> | <build> | ||||
| @@ -6,7 +6,7 @@ | |||||
| <parent> | <parent> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <artifactId>wx-java</artifactId> | <artifactId>wx-java</artifactId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| </parent> | </parent> | ||||
| <packaging>pom</packaging> | <packaging>pom</packaging> | ||||
| <artifactId>wx-java-spring-boot-starters</artifactId> | <artifactId>wx-java-spring-boot-starters</artifactId> | ||||
| @@ -5,7 +5,7 @@ | |||||
| <parent> | <parent> | ||||
| <artifactId>wx-java-spring-boot-starters</artifactId> | <artifactId>wx-java-spring-boot-starters</artifactId> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| </parent> | </parent> | ||||
| <modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
| @@ -5,7 +5,7 @@ | |||||
| <parent> | <parent> | ||||
| <artifactId>wx-java-spring-boot-starters</artifactId> | <artifactId>wx-java-spring-boot-starters</artifactId> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| </parent> | </parent> | ||||
| <modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
| @@ -24,6 +24,11 @@ | |||||
| <artifactId>jedis</artifactId> | <artifactId>jedis</artifactId> | ||||
| <scope>compile</scope> | <scope>compile</scope> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>org.redisson</groupId> | |||||
| <artifactId>redisson</artifactId> | |||||
| <scope>compile</scope> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor; | |||||
| import me.chanjar.weixin.mp.config.WxMpConfigStorage; | import me.chanjar.weixin.mp.config.WxMpConfigStorage; | ||||
| import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; | import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; | ||||
| import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; | import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; | ||||
| import org.redisson.api.RedissonClient; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| import org.springframework.context.annotation.Bean; | import org.springframework.context.annotation.Bean; | ||||
| @@ -26,6 +27,9 @@ public class WxMpStorageAutoConfiguration { | |||||
| @Autowired(required = false) | @Autowired(required = false) | ||||
| private JedisPool jedisPool; | private JedisPool jedisPool; | ||||
| @Autowired(required = false) | |||||
| private RedissonClient redissonClient; | |||||
| @Bean | @Bean | ||||
| @ConditionalOnMissingBean(WxMpConfigStorage.class) | @ConditionalOnMissingBean(WxMpConfigStorage.class) | ||||
| public WxMpConfigStorage wxMpInMemoryConfigStorage() { | public WxMpConfigStorage wxMpInMemoryConfigStorage() { | ||||
| @@ -5,7 +5,7 @@ | |||||
| <parent> | <parent> | ||||
| <artifactId>wx-java-spring-boot-starters</artifactId> | <artifactId>wx-java-spring-boot-starters</artifactId> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| </parent> | </parent> | ||||
| <modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
| @@ -24,6 +24,11 @@ | |||||
| <artifactId>jedis</artifactId> | <artifactId>jedis</artifactId> | ||||
| <scope>compile</scope> | <scope>compile</scope> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>org.redisson</groupId> | |||||
| <artifactId>redisson</artifactId> | |||||
| <scope>compile</scope> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -6,7 +6,12 @@ import lombok.RequiredArgsConstructor; | |||||
| import me.chanjar.weixin.open.api.WxOpenConfigStorage; | import me.chanjar.weixin.open.api.WxOpenConfigStorage; | ||||
| import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; | import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; | ||||
| import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage; | import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage; | ||||
| import me.chanjar.weixin.open.api.impl.WxOpenInRedissonConfigStorage; | |||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.redisson.Redisson; | |||||
| import org.redisson.api.RedissonClient; | |||||
| import org.redisson.config.Config; | |||||
| import org.redisson.config.TransportMode; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.beans.factory.annotation.Value; | import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||||
| @@ -28,6 +33,9 @@ public class WxOpenStorageAutoConfiguration { | |||||
| @Autowired(required = false) | @Autowired(required = false) | ||||
| private JedisPool jedisPool; | private JedisPool jedisPool; | ||||
| @Autowired(required = false) | |||||
| private RedissonClient redissonClient; | |||||
| @Value("${wx.open.config-storage.redis.host:}") | @Value("${wx.open.config-storage.redis.host:}") | ||||
| private String redisHost; | private String redisHost; | ||||
| @@ -40,12 +48,20 @@ public class WxOpenStorageAutoConfiguration { | |||||
| if (type == WxOpenProperties.StorageType.redis) { | if (type == WxOpenProperties.StorageType.redis) { | ||||
| return getWxOpenInRedisConfigStorage(); | return getWxOpenInRedisConfigStorage(); | ||||
| } | } | ||||
| if (type == WxOpenProperties.StorageType.jedis) { | |||||
| return getWxOpenInRedisConfigStorage(); | |||||
| } | |||||
| if (type == WxOpenProperties.StorageType.redisson) { | |||||
| return getWxOpenInRedissonConfigStorage(); | |||||
| } | |||||
| return getWxOpenInMemoryConfigStorage(); | return getWxOpenInMemoryConfigStorage(); | ||||
| } | } | ||||
| private WxOpenInMemoryConfigStorage getWxOpenInMemoryConfigStorage() { | private WxOpenInMemoryConfigStorage getWxOpenInMemoryConfigStorage() { | ||||
| WxOpenInMemoryConfigStorage config = new WxOpenInMemoryConfigStorage(); | WxOpenInMemoryConfigStorage config = new WxOpenInMemoryConfigStorage(); | ||||
| setWxOpenInfo(config); | |||||
| config.setWxOpenInfo(properties.getAppId(), properties.getSecret(), properties.getToken(), properties.getAesKey()); | |||||
| return config; | return config; | ||||
| } | } | ||||
| @@ -54,18 +70,22 @@ public class WxOpenStorageAutoConfiguration { | |||||
| if (jedisPool == null || StringUtils.isNotEmpty(redisHost)) { | if (jedisPool == null || StringUtils.isNotEmpty(redisHost)) { | ||||
| poolToUse = getJedisPool(); | poolToUse = getJedisPool(); | ||||
| } | } | ||||
| WxOpenInRedisConfigStorage config = new WxOpenInRedisConfigStorage(poolToUse); | |||||
| setWxOpenInfo(config); | |||||
| WxOpenInRedisConfigStorage config = new WxOpenInRedisConfigStorage(poolToUse, properties.getConfigStorage().getKeyPrefix()); | |||||
| config.setWxOpenInfo(properties.getAppId(), properties.getSecret(), properties.getToken(), properties.getAesKey()); | |||||
| return 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 WxOpenInRedissonConfigStorage getWxOpenInRedissonConfigStorage() { | |||||
| RedissonClient redissonClientToUse = this.redissonClient; | |||||
| if (redissonClient == null) { | |||||
| redissonClientToUse = getRedissonClient(); | |||||
| } | |||||
| WxOpenInRedissonConfigStorage config = new WxOpenInRedissonConfigStorage(redissonClientToUse, properties.getConfigStorage().getKeyPrefix()); | |||||
| config.setWxOpenInfo(properties.getAppId(), properties.getSecret(), properties.getToken(), properties.getAesKey()); | |||||
| return config; | |||||
| } | } | ||||
| private JedisPool getJedisPool() { | private JedisPool getJedisPool() { | ||||
| WxOpenProperties.ConfigStorage storage = properties.getConfigStorage(); | WxOpenProperties.ConfigStorage storage = properties.getConfigStorage(); | ||||
| RedisProperties redis = storage.getRedis(); | RedisProperties redis = storage.getRedis(); | ||||
| @@ -90,4 +110,16 @@ public class WxOpenStorageAutoConfiguration { | |||||
| redis.getTimeout(), redis.getPassword(), redis.getDatabase()); | redis.getTimeout(), redis.getPassword(), redis.getDatabase()); | ||||
| return pool; | return pool; | ||||
| } | } | ||||
| private RedissonClient getRedissonClient() { | |||||
| WxOpenProperties.ConfigStorage storage = properties.getConfigStorage(); | |||||
| RedisProperties redis = storage.getRedis(); | |||||
| Config config = new Config(); | |||||
| config.useSingleServer() | |||||
| .setAddress("redis://" + redis.getHost() + ":" + redis.getPort()) | |||||
| .setPassword(redis.getPassword()); | |||||
| config.setTransportMode(TransportMode.NIO); | |||||
| return Redisson.create(config); | |||||
| } | |||||
| } | } | ||||
| @@ -53,6 +53,8 @@ public class WxOpenProperties { | |||||
| private RedisProperties redis = new RedisProperties(); | private RedisProperties redis = new RedisProperties(); | ||||
| private String keyPrefix; | |||||
| } | } | ||||
| public enum StorageType { | public enum StorageType { | ||||
| @@ -63,6 +65,14 @@ public class WxOpenProperties { | |||||
| /** | /** | ||||
| * redis. | * redis. | ||||
| */ | */ | ||||
| redis | |||||
| redis, | |||||
| /** | |||||
| * jedis. | |||||
| */ | |||||
| jedis, | |||||
| /** | |||||
| * redisson. | |||||
| */ | |||||
| redisson | |||||
| } | } | ||||
| } | } | ||||
| @@ -5,7 +5,7 @@ | |||||
| <parent> | <parent> | ||||
| <artifactId>wx-java-spring-boot-starters</artifactId> | <artifactId>wx-java-spring-boot-starters</artifactId> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| </parent> | </parent> | ||||
| <modelVersion>4.0.0</modelVersion> | <modelVersion>4.0.0</modelVersion> | ||||
| @@ -0,0 +1,40 @@ | |||||
| <?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.7.0</version> | |||||
| </parent> | |||||
| <artifactId>weixin-graal</artifactId> | |||||
| <name>WxJava - Graal</name> | |||||
| <description>微信开发Java内部配合graal以产生native-image配置的辅助工具, 可以通过项目的 native-image Profile 来启用: mvn -P native-image ... | |||||
| </description> | |||||
| <dependencies> | |||||
| <dependency> | |||||
| <groupId>org.projectlombok</groupId> | |||||
| <artifactId>lombok</artifactId> | |||||
| <scope>compile</scope> | |||||
| </dependency> | |||||
| </dependencies> | |||||
| <build> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>org.apache.maven.plugins</groupId> | |||||
| <artifactId>maven-compiler-plugin</artifactId> | |||||
| <version>3.5.1</version> | |||||
| <configuration> | |||||
| <proc>none</proc> | |||||
| </configuration> | |||||
| </plugin> | |||||
| </plugins> | |||||
| </build> | |||||
| </project> | |||||
| @@ -0,0 +1,167 @@ | |||||
| package cn.binarywang.wx.graal; | |||||
| import lombok.Data; | |||||
| import javax.annotation.processing.AbstractProcessor; | |||||
| import javax.annotation.processing.RoundEnvironment; | |||||
| import javax.annotation.processing.SupportedAnnotationTypes; | |||||
| import javax.annotation.processing.SupportedSourceVersion; | |||||
| import javax.lang.model.SourceVersion; | |||||
| import javax.lang.model.element.TypeElement; | |||||
| import javax.lang.model.type.DeclaredType; | |||||
| import javax.lang.model.type.TypeKind; | |||||
| import javax.lang.model.type.TypeMirror; | |||||
| import javax.lang.model.util.ElementFilter; | |||||
| import javax.tools.FileObject; | |||||
| import javax.tools.StandardLocation; | |||||
| import java.io.IOException; | |||||
| import java.io.Writer; | |||||
| import java.util.Set; | |||||
| import java.util.SortedSet; | |||||
| import java.util.TreeSet; | |||||
| // 目前仅仅处理@Data,且必须在lombok自己的processor之前执行,千万注意!!!!! | |||||
| @SupportedAnnotationTypes("lombok.Data") | |||||
| @SupportedSourceVersion(SourceVersion.RELEASE_7) | |||||
| public class GraalProcessor extends AbstractProcessor { | |||||
| private static final String REFLECTION_CONFIG_JSON = "reflection-config.json"; | |||||
| private static final String NATIVE_IMAGE_PROPERTIES = "native-image.properties"; | |||||
| private SortedSet<String> classSet = new TreeSet<>(); | |||||
| private String shortestPackageName = null; | |||||
| @Override | |||||
| public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { | |||||
| for (TypeElement annotatedClass : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Data.class))) { | |||||
| registerClass(annotatedClass.getQualifiedName().toString()); | |||||
| handleSuperClass(annotatedClass); | |||||
| } | |||||
| //只有最后一轮才可以写文件,否则文件会被重复打开,报错! | |||||
| if (!roundEnv.processingOver()) return false; | |||||
| // 如果没有文件要写,跳过 | |||||
| if (classSet.isEmpty()) return false; | |||||
| writeFiles(); | |||||
| //必须返回false,以便让lombok能继续处理。 | |||||
| return false; | |||||
| } | |||||
| /** | |||||
| * 设置当前最短的package名称 | |||||
| * | |||||
| * @param packageName 包名 | |||||
| */ | |||||
| private void setShortestPackageName(String packageName) { | |||||
| if (shortestPackageName == null) { | |||||
| shortestPackageName = packageName; | |||||
| } else if (packageName.length() < shortestPackageName.length()) { | |||||
| shortestPackageName = packageName; | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 更加完整的类名来获取package名称 | |||||
| * | |||||
| * @param fullClassName 完整的类名 | |||||
| * @return package name | |||||
| */ | |||||
| private String getPackageName(String fullClassName) { | |||||
| int last = fullClassName.lastIndexOf('.'); | |||||
| if (last == -1) return fullClassName; | |||||
| return fullClassName.substring(0, last); | |||||
| } | |||||
| /** | |||||
| * 保存文件 | |||||
| * META-INF/native-image/.../reflection-config.json | |||||
| * META-INF/native-image/.../native-image.properties | |||||
| */ | |||||
| private void writeFiles() { | |||||
| String basePackage = shortestPackageName; | |||||
| String module; | |||||
| if (basePackage.contains(".")) { | |||||
| final int i = basePackage.lastIndexOf('.'); | |||||
| module = basePackage.substring(i + 1); | |||||
| basePackage = basePackage.substring(0, i); | |||||
| } else { | |||||
| module = basePackage; | |||||
| } | |||||
| String path = "META-INF/native-image/" + basePackage + "/" + module + "/"; | |||||
| String reflectFile = path + REFLECTION_CONFIG_JSON; | |||||
| String propsFile = path + NATIVE_IMAGE_PROPERTIES; | |||||
| try { | |||||
| FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", propsFile); | |||||
| Writer writer = fileObject.openWriter(); | |||||
| writer.append("Args = -H:ReflectionConfigurationResources=${.}/" + REFLECTION_CONFIG_JSON); | |||||
| writer.close(); | |||||
| } catch (IOException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| try { | |||||
| FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", reflectFile); | |||||
| Writer writer = fileObject.openWriter(); | |||||
| writer.write("[\n"); | |||||
| boolean first = true; | |||||
| for (String name : classSet) { | |||||
| if (first) { | |||||
| first = false; | |||||
| } else { | |||||
| writer.write(","); | |||||
| } | |||||
| writer.write(assetGraalJsonElement(name)); | |||||
| writer.append('\n'); | |||||
| } | |||||
| writer.write("]"); | |||||
| writer.close(); | |||||
| } catch (IOException e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| } | |||||
| private String assetGraalJsonElement(String className) { | |||||
| return "{\n" + | |||||
| " \"name\" : \"" + className + "\",\n" + | |||||
| " \"allDeclaredFields\":true,\n" + | |||||
| " \"allDeclaredMethods\":true,\n" + | |||||
| " \"allDeclaredConstructors\":true,\n" + | |||||
| " \"allPublicMethods\" : true\n" + | |||||
| "}"; | |||||
| } | |||||
| /** | |||||
| * 登记一个class | |||||
| * | |||||
| * @param className 完整的类名 | |||||
| */ | |||||
| private void registerClass(String className) { | |||||
| classSet.add(className); | |||||
| setShortestPackageName(getPackageName(className)); | |||||
| } | |||||
| /** | |||||
| * 获取一个类型的所有的父类,并登记 | |||||
| * | |||||
| * @param typeElement 类型元素 | |||||
| */ | |||||
| private void handleSuperClass(TypeElement typeElement) { | |||||
| TypeMirror superclass = typeElement.getSuperclass(); | |||||
| if (superclass.getKind() == TypeKind.DECLARED) { | |||||
| TypeElement s = (TypeElement) ((DeclaredType) superclass).asElement(); | |||||
| String sName = s.toString(); | |||||
| // ignore java.**/javax.** | |||||
| if (sName.startsWith("java.") || sName.startsWith("javax.")) return; | |||||
| registerClass(sName); | |||||
| handleSuperClass(s); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1 @@ | |||||
| cn.binarywang.wx.graal.GraalProcessor | |||||
| @@ -1,12 +1,12 @@ | |||||
| <?xml version="1.0"?> | <?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"> | |||||
| <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> | <modelVersion>4.0.0</modelVersion> | ||||
| <parent> | <parent> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <artifactId>wx-java</artifactId> | <artifactId>wx-java</artifactId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| </parent> | </parent> | ||||
| <artifactId>weixin-java-common</artifactId> | <artifactId>weixin-java-common</artifactId> | ||||
| @@ -134,4 +134,36 @@ | |||||
| </plugins> | </plugins> | ||||
| </build> | </build> | ||||
| <profiles> | |||||
| <profile> | |||||
| <id>native-image</id> | |||||
| <activation> | |||||
| <activeByDefault>false</activeByDefault> | |||||
| </activation> | |||||
| <build> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>org.apache.maven.plugins</groupId> | |||||
| <artifactId>maven-compiler-plugin</artifactId> | |||||
| <version>3.5.1</version> | |||||
| <configuration> | |||||
| <annotationProcessors> | |||||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||||
| </annotationProcessors> | |||||
| <annotationProcessorPaths> | |||||
| <path> | |||||
| <groupId>com.github.binarywang</groupId> | |||||
| <artifactId>weixin-graal</artifactId> | |||||
| <version>${project.version}</version> | |||||
| </path> | |||||
| </annotationProcessorPaths> | |||||
| </configuration> | |||||
| </plugin> | |||||
| </plugins> | |||||
| </build> | |||||
| </profile> | |||||
| </profiles> | |||||
| </project> | </project> | ||||
| @@ -452,6 +452,19 @@ public enum WxMaErrorMsgEnum { | |||||
| CODE_43101(43101, "用户拒绝接受消息,如果用户之前曾经订阅过,则表示用户取消了订阅关系"), | CODE_43101(43101, "用户拒绝接受消息,如果用户之前曾经订阅过,则表示用户取消了订阅关系"), | ||||
| CODE_47003(47003, "模板参数不准确,可能为空或者不满足规则,errmsg会提示具体是哪个字段出错"), | CODE_47003(47003, "模板参数不准确,可能为空或者不满足规则,errmsg会提示具体是哪个字段出错"), | ||||
| /** | |||||
| * 小程序绑定体验者 | |||||
| */ | |||||
| CODE_85001(85001, "微信号不存在或微信号设置为不可搜索"), | |||||
| CODE_85002(85002, "小程序绑定的体验者数量达到上限"), | |||||
| CODE_85003(85003, "微信号绑定的小程序体验者达到上限"), | |||||
| CODE_85004(85004, "微信号已经绑定"), | |||||
| // CODE_504002(-504002, "云函数未找到 Function not found"), | |||||
| ; | ; | ||||
| private int code; | private int code; | ||||
| @@ -1,15 +1,14 @@ | |||||
| package me.chanjar.weixin.common.util.http; | package me.chanjar.weixin.common.util.http; | ||||
| import java.io.IOException; | |||||
| import me.chanjar.weixin.common.WxType; | import me.chanjar.weixin.common.WxType; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheSimplePostRequestExecutor; | import me.chanjar.weixin.common.util.http.apache.ApacheSimplePostRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimplePostRequestExecutor; | import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimplePostRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.okhttp.OkHttpSimplePostRequestExecutor; | import me.chanjar.weixin.common.util.http.okhttp.OkHttpSimplePostRequestExecutor; | ||||
| import java.io.IOException; | |||||
| /** | /** | ||||
| * 用装饰模式实现 | |||||
| * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | ||||
| * | * | ||||
| * @author Daniel Qian | * @author Daniel Qian | ||||
| @@ -36,6 +36,7 @@ public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor<C | |||||
| if (postEntity != null) { | if (postEntity != null) { | ||||
| StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); | StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); | ||||
| entity.setContentType("application/json; charset=utf-8"); | |||||
| httpPost.setEntity(entity); | httpPost.setEntity(entity); | ||||
| } | } | ||||
| @@ -25,7 +25,7 @@ public class Utf8ResponseHandler implements ResponseHandler<String> { | |||||
| final HttpEntity entity = response.getEntity(); | final HttpEntity entity = response.getEntity(); | ||||
| if (statusLine.getStatusCode() >= 300) { | if (statusLine.getStatusCode() >= 300) { | ||||
| EntityUtils.consume(entity); | EntityUtils.consume(entity); | ||||
| throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); | |||||
| throw new HttpResponseException(statusLine.getStatusCode(), statusLine.toString()); | |||||
| } | } | ||||
| return entity == null ? null : EntityUtils.toString(entity, Consts.UTF_8); | return entity == null ? null : EntityUtils.toString(entity, Consts.UTF_8); | ||||
| } | } | ||||
| @@ -7,7 +7,7 @@ | |||||
| <parent> | <parent> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <artifactId>wx-java</artifactId> | <artifactId>wx-java</artifactId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| </parent> | </parent> | ||||
| <artifactId>weixin-java-cp</artifactId> | <artifactId>weixin-java-cp</artifactId> | ||||
| @@ -95,4 +95,36 @@ | |||||
| </plugins> | </plugins> | ||||
| </build> | </build> | ||||
| <profiles> | |||||
| <profile> | |||||
| <id>native-image</id> | |||||
| <activation> | |||||
| <activeByDefault>false</activeByDefault> | |||||
| </activation> | |||||
| <build> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>org.apache.maven.plugins</groupId> | |||||
| <artifactId>maven-compiler-plugin</artifactId> | |||||
| <version>3.5.1</version> | |||||
| <configuration> | |||||
| <annotationProcessors> | |||||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||||
| </annotationProcessors> | |||||
| <annotationProcessorPaths> | |||||
| <path> | |||||
| <groupId>com.github.binarywang</groupId> | |||||
| <artifactId>weixin-graal</artifactId> | |||||
| <version>${project.version}</version> | |||||
| </path> | |||||
| </annotationProcessorPaths> | |||||
| </configuration> | |||||
| </plugin> | |||||
| </plugins> | |||||
| </build> | |||||
| </profile> | |||||
| </profiles> | |||||
| </project> | </project> | ||||
| @@ -24,25 +24,54 @@ public interface WxCpExternalContactService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param userId 外部联系人的userid | * @param userId 外部联系人的userid | ||||
| * @return . | |||||
| * @deprecated 建议使用 {@link #getContactDetail(String)} | |||||
| */ | */ | ||||
| @Deprecated | |||||
| WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException; | WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException; | ||||
| /** | /** | ||||
| * 获取外部联系人列表. | |||||
| * 获取客户详情. | |||||
| * <pre> | * <pre> | ||||
| * 企业可通过此接口获取指定成员添加的客户列表。 | |||||
| * 客户是指配置了客户联系功能的成员所添加的外部联系人。 | |||||
| * 没有配置客户联系功能的成员,所添加的外部联系人将不会作为客户返回。 | |||||
| * | |||||
| * 企业可通过此接口,根据外部联系人的userid(如何获取?),拉取客户详情。 | |||||
| * | |||||
| * 请求方式:GET(HTTPS) | |||||
| * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=ACCESS_TOKEN&external_userid=EXTERNAL_USERID | |||||
| * | |||||
| * 权限说明: | |||||
| * | |||||
| * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?); | |||||
| * 第三方/自建应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。 | |||||
| * </pre> | |||||
| * | |||||
| * @param userId 外部联系人的userid,注意不是企业成员的帐号 | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCpUserExternalContactInfo getContactDetail(String userId) throws WxErrorException; | |||||
| /** | |||||
| * 获取客户列表. | |||||
| * <pre> | |||||
| * 企业可通过此接口获取指定成员添加的客户列表。客户是指配置了客户联系功能的成员所添加的外部联系人。没有配置客户联系功能的成员,所添加的外部联系人将不会作为客户返回。 | |||||
| * | |||||
| * 请求方式:GET(HTTPS) | |||||
| * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list?access_token=ACCESS_TOKEN&userid=USERID | |||||
| * | |||||
| * 权限说明: | |||||
| * | |||||
| * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?); | |||||
| * 第三方应用需拥有“企业客户”权限。 | * 第三方应用需拥有“企业客户”权限。 | ||||
| * 第三方应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。 | |||||
| * 第三方/自建应用只能获取到可见范围内的配置了客户联系功能的成员。 | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @param userId 外部联系人的userid | |||||
| * @param userId 企业成员的userid | |||||
| * @return List of External wx id | * @return List of External wx id | ||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| List<String> listExternalContacts(String userId) throws WxErrorException; | List<String> listExternalContacts(String userId) throws WxErrorException; | ||||
| /** | /** | ||||
| * 企业和第三方服务商可通过此接口获取配置了客户联系功能的成员(Customer Contact)列表。 | * 企业和第三方服务商可通过此接口获取配置了客户联系功能的成员(Customer Contact)列表。 | ||||
| * <pre> | * <pre> | ||||
| @@ -52,6 +81,7 @@ public interface WxCpExternalContactService { | |||||
| * </pre> | * </pre> | ||||
| * | * | ||||
| * @return List of CpUser id | * @return List of CpUser id | ||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| List<String> listFollowUser() throws WxErrorException; | List<String> listFollowUser() throws WxErrorException; | ||||
| @@ -1,10 +1,8 @@ | |||||
| package me.chanjar.weixin.cp.api; | package me.chanjar.weixin.cp.api; | ||||
| import lombok.NonNull; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.bean.WxCpApprovalDataResult; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinData; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinOption; | |||||
| import me.chanjar.weixin.cp.bean.WxCpDialRecord; | |||||
| import me.chanjar.weixin.cp.bean.oa.*; | |||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.List; | import java.util.List; | ||||
| @@ -30,7 +28,8 @@ public interface WxCpOaService { | |||||
| * @return 打卡数据列表 | * @return 打卡数据列表 | ||||
| * @throws WxErrorException 异常 | * @throws WxErrorException 异常 | ||||
| */ | */ | ||||
| List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, List<String> userIdList) throws WxErrorException; | |||||
| List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, | |||||
| List<String> userIdList) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -41,13 +40,63 @@ public interface WxCpOaService { | |||||
| * @param datetime 需要获取规则的当天日期 | * @param datetime 需要获取规则的当天日期 | ||||
| * @param userIdList 需要获取打卡规则的用户列表 | * @param userIdList 需要获取打卡规则的用户列表 | ||||
| * @return 打卡规则列表 | * @return 打卡规则列表 | ||||
| * @throws WxErrorException 异常 | |||||
| * @throws WxErrorException | |||||
| */ | */ | ||||
| List<WxCpCheckinOption> getCheckinOption(Date datetime, List<String> userIdList) throws WxErrorException; | List<WxCpCheckinOption> getCheckinOption(Date datetime, List<String> userIdList) throws WxErrorException; | ||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 获取审批数据 | |||||
| * | |||||
| * 批量获取审批单号 | |||||
| * | |||||
| * 审批应用及有权限的自建应用,可通过Secret调用本接口,以获取企业一段时间内企业微信“审批应用”单据的审批编号,支持按模板类型、申请人、部门、申请单审批状态等条件筛选。 | |||||
| * 自建应用调用此接口,需在“管理后台-应用管理-审批-API-审批数据权限”中,授权应用允许提交审批单据。 | |||||
| * | |||||
| * 一次拉取调用最多拉取100个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。 | |||||
| * | |||||
| * API doc : https://work.weixin.qq.com/api/doc/90000/90135/91816 | |||||
| * </pre> | |||||
| * | |||||
| * @param startTime 开始时间 | |||||
| * @param endTime 结束时间 | |||||
| * @param cursor 分页查询游标,默认为0,后续使用返回的next_cursor进行分页拉取 | |||||
| * @param size 一次请求拉取审批单数量,默认值为100,上限值为100 | |||||
| * @param filters 筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件,nullable | |||||
| * @return WxCpApprovalInfo | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime, Integer cursor, Integer size, | |||||
| List<WxCpApprovalInfoQueryFilter> filters) throws WxErrorException; | |||||
| /** | |||||
| * short method | |||||
| * | |||||
| * @param startTime 开始时间 | |||||
| * @param endTime 结束时间 | |||||
| * @return WxCpApprovalInfo | |||||
| * @throws WxErrorException | |||||
| * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalInfo | |||||
| */ | |||||
| WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取审批申请详情 | |||||
| * | |||||
| * 企业可通过审批应用或自建应用Secret调用本接口,根据审批单号查询企业微信“审批应用”的审批申请详情。 | |||||
| * | |||||
| * API Doc : https://work.weixin.qq.com/api/doc/90000/90135/91983 | |||||
| * </pre> | |||||
| * | |||||
| * @param spNo 审批单编号。 | |||||
| * @return WxCpApprovaldetail | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| WxCpApprovalDetailResult getApprovalDetail(@NonNull String spNo) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取审批数据 (已过期, 请使用"批量获取审批单号" && "获取审批申请详情") | |||||
| * 通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。 | * 通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。 | ||||
| * API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530 | * API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530 | ||||
| * </pre> | * </pre> | ||||
| @@ -55,10 +104,32 @@ public interface WxCpOaService { | |||||
| * @param startTime 获取审批记录的开始时间 | * @param startTime 获取审批记录的开始时间 | ||||
| * @param endTime 获取审批记录的结束时间 | * @param endTime 获取审批记录的结束时间 | ||||
| * @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取 | * @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取 | ||||
| * @throws WxErrorException 异常 | |||||
| * @throws WxErrorException | |||||
| * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalInfo | |||||
| * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalDetail | |||||
| */ | */ | ||||
| @Deprecated | |||||
| WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException; | WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException; | ||||
| List<WxCpDialRecord> getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) throws WxErrorException; | |||||
| /** | |||||
| * 获取公费电话拨打记录 | |||||
| * | |||||
| * @param startTime 查询的起始时间戳 | |||||
| * @param endTime 查询的结束时间戳 | |||||
| * @param offset 分页查询的偏移量 | |||||
| * @param limit 分页查询的每页大小,默认为100条,如该参数大于100则按100处理 | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| List<WxCpDialRecord> getDialRecord(Date startTime, Date endTime, Integer offset, | |||||
| Integer limit) throws WxErrorException; | |||||
| /** | |||||
| * 获取审批模板详情 | |||||
| * @param templateId 模板ID | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| */ | |||||
| WxCpTemplateResult getTemplateDetail(@NonNull String templateId)throws WxErrorException; | |||||
| } | } | ||||
| @@ -205,7 +205,7 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH | |||||
| JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
| jsonObject.addProperty("corpid", corpId); | jsonObject.addProperty("corpid", corpId); | ||||
| jsonObject.addProperty("provider_secret", providerSecret); | jsonObject.addProperty("provider_secret", providerSecret); | ||||
| return WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(GET_PROVIDER_TOKEN), jsonObject.toString())); | |||||
| return WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(Tp.GET_PROVIDER_TOKEN), jsonObject.toString())); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -281,7 +281,9 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH | |||||
| if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { | ||||
| // 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | // 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token | ||||
| this.configStorage.expireAccessToken(); | this.configStorage.expireAccessToken(); | ||||
| return execute(executor, uri, data); | |||||
| if (this.getWxCpConfigStorage().autoRefreshToken()) { | |||||
| return this.execute(executor, uri, data); | |||||
| } | |||||
| } | } | ||||
| if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
| @@ -194,7 +194,9 @@ public abstract class BaseWxCpTpServiceImpl<H, P> implements WxCpTpService, Requ | |||||
| if (error.getErrorCode() == 42009) { | if (error.getErrorCode() == 42009) { | ||||
| // 强制设置wxCpTpConfigStorage它的suite access token过期了,这样在下一次请求里就会刷新suite access token | // 强制设置wxCpTpConfigStorage它的suite access token过期了,这样在下一次请求里就会刷新suite access token | ||||
| this.configStorage.expireSuiteAccessToken(); | this.configStorage.expireSuiteAccessToken(); | ||||
| return execute(executor, uri, data); | |||||
| if (this.getWxCpTpConfigStorage().autoRefreshToken()) { | |||||
| return this.execute(executor, uri, data); | |||||
| } | |||||
| } | } | ||||
| if (error.getErrorCode() != 0) { | if (error.getErrorCode() != 0) { | ||||
| @@ -25,6 +25,13 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic | |||||
| return WxCpUserExternalContactInfo.fromJson(responseContent); | return WxCpUserExternalContactInfo.fromJson(responseContent); | ||||
| } | } | ||||
| @Override | |||||
| public WxCpUserExternalContactInfo getContactDetail(String userId) throws WxErrorException { | |||||
| final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CONTACT_DETAIL + userId); | |||||
| String responseContent = this.mainService.get(url, null); | |||||
| return WxCpUserExternalContactInfo.fromJson(responseContent); | |||||
| } | |||||
| @Override | @Override | ||||
| public List<String> listExternalContacts(String userId) throws WxErrorException { | public List<String> listExternalContacts(String userId) throws WxErrorException { | ||||
| final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_EXTERNAL_CONTACT + userId); | final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_EXTERNAL_CONTACT + userId); | ||||
| @@ -5,15 +5,12 @@ import com.google.gson.JsonElement; | |||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
| import com.google.gson.reflect.TypeToken; | import com.google.gson.reflect.TypeToken; | ||||
| import lombok.NonNull; | |||||
| import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.api.WxCpOaService; | import me.chanjar.weixin.cp.api.WxCpOaService; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpApprovalDataResult; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinData; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinOption; | |||||
| import me.chanjar.weixin.cp.bean.WxCpDialRecord; | |||||
| import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; | |||||
| import me.chanjar.weixin.cp.bean.oa.*; | |||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| @@ -22,7 +19,7 @@ import java.util.List; | |||||
| import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; | import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; | ||||
| /** | /** | ||||
| * . | |||||
| * 企业微信 OA 接口实现 | |||||
| * | * | ||||
| * @author Element | * @author Element | ||||
| * @date 2019-04-06 11:20 | * @date 2019-04-06 11:20 | ||||
| @@ -31,6 +28,9 @@ import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; | |||||
| public class WxCpOaServiceImpl implements WxCpOaService { | public class WxCpOaServiceImpl implements WxCpOaService { | ||||
| private final WxCpService mainService; | private final WxCpService mainService; | ||||
| private static final int MONTH_SECONDS = 30 * 24 * 60 * 60; | |||||
| private static final int USER_IDS_LIMIT = 100; | |||||
| @Override | @Override | ||||
| public List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, | public List<WxCpCheckinData> getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, | ||||
| List<String> userIdList) throws WxErrorException { | List<String> userIdList) throws WxErrorException { | ||||
| @@ -38,14 +38,14 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| throw new RuntimeException("starttime and endtime can't be null"); | throw new RuntimeException("starttime and endtime can't be null"); | ||||
| } | } | ||||
| if (userIdList == null || userIdList.size() > 100) { | |||||
| throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取"); | |||||
| if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) { | |||||
| throw new RuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取"); | |||||
| } | } | ||||
| long endtimestamp = endTime.getTime() / 1000L; | long endtimestamp = endTime.getTime() / 1000L; | ||||
| long starttimestamp = startTime.getTime() / 1000L; | long starttimestamp = startTime.getTime() / 1000L; | ||||
| if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) { | |||||
| if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= MONTH_SECONDS) { | |||||
| throw new RuntimeException("获取记录时间跨度不超过一个月"); | throw new RuntimeException("获取记录时间跨度不超过一个月"); | ||||
| } | } | ||||
| @@ -79,8 +79,8 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| throw new RuntimeException("datetime can't be null"); | throw new RuntimeException("datetime can't be null"); | ||||
| } | } | ||||
| if (userIdList == null || userIdList.size() > 100) { | |||||
| throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取"); | |||||
| if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) { | |||||
| throw new RuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取"); | |||||
| } | } | ||||
| JsonArray jsonArray = new JsonArray(); | JsonArray jsonArray = new JsonArray(); | ||||
| @@ -104,6 +104,59 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| ); | ); | ||||
| } | } | ||||
| @Override | |||||
| public WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime, | |||||
| Integer cursor, Integer size, List<WxCpApprovalInfoQueryFilter> filters) throws WxErrorException { | |||||
| if (cursor == null) { | |||||
| cursor = 0; | |||||
| } | |||||
| if (size == null) { | |||||
| size = 100; | |||||
| } | |||||
| if (size < 0 || size > 100) { | |||||
| throw new IllegalArgumentException("size参数错误,请使用[1-100]填充,默认100"); | |||||
| } | |||||
| JsonObject jsonObject = new JsonObject(); | |||||
| jsonObject.addProperty("starttime", startTime.getTime() / 1000L); | |||||
| jsonObject.addProperty("endtime", endTime.getTime() / 1000L); | |||||
| jsonObject.addProperty("size", size); | |||||
| jsonObject.addProperty("cursor", cursor); | |||||
| if (filters != null && !filters.isEmpty()) { | |||||
| JsonArray filterJsonArray = new JsonArray(); | |||||
| for (WxCpApprovalInfoQueryFilter filter : filters) { | |||||
| filterJsonArray.add(new JsonParser().parse(filter.toJson())); | |||||
| } | |||||
| jsonObject.add("filters", filterJsonArray); | |||||
| } | |||||
| final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_INFO); | |||||
| String responseContent = this.mainService.post(url, jsonObject.toString()); | |||||
| return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalInfo.class); | |||||
| } | |||||
| @Override | |||||
| public WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime) throws WxErrorException { | |||||
| return this.getApprovalInfo(startTime, endTime, null, null, null); | |||||
| } | |||||
| @Override | |||||
| public WxCpApprovalDetailResult getApprovalDetail(@NonNull String spNo) throws WxErrorException { | |||||
| JsonObject jsonObject = new JsonObject(); | |||||
| jsonObject.addProperty("sp_no", spNo); | |||||
| final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_DETAIL); | |||||
| String responseContent = this.mainService.post(url, jsonObject.toString()); | |||||
| return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalDetailResult.class); | |||||
| } | |||||
| @Override | @Override | ||||
| public WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException { | public WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException { | ||||
| JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
| @@ -139,7 +192,7 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| long endtimestamp = endTime.getTime() / 1000L; | long endtimestamp = endTime.getTime() / 1000L; | ||||
| long starttimestamp = startTime.getTime() / 1000L; | long starttimestamp = startTime.getTime() / 1000L; | ||||
| if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) { | |||||
| if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= MONTH_SECONDS) { | |||||
| throw new RuntimeException("受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询"); | throw new RuntimeException("受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询"); | ||||
| } | } | ||||
| @@ -156,4 +209,13 @@ public class WxCpOaServiceImpl implements WxCpOaService { | |||||
| }.getType() | }.getType() | ||||
| ); | ); | ||||
| } | } | ||||
| @Override | |||||
| public WxCpTemplateResult getTemplateDetail(@NonNull String templateId) throws WxErrorException { | |||||
| JsonObject jsonObject = new JsonObject(); | |||||
| jsonObject.addProperty("template_id",templateId); | |||||
| final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_TEMPLATE_DETAIL); | |||||
| String responseContent = this.mainService.post(url, jsonObject.toString()); | |||||
| return WxCpGsonBuilder.create().fromJson(responseContent,WxCpTemplateResult.class); | |||||
| } | |||||
| } | } | ||||
| @@ -1,15 +1,15 @@ | |||||
| package me.chanjar.weixin.cp.bean; | package me.chanjar.weixin.cp.bean; | ||||
| import java.io.Serializable; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
| import lombok.Builder; | import lombok.Builder; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | import lombok.NoArgsConstructor; | ||||
| import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; | ||||
| import java.io.Serializable; | |||||
| import java.util.ArrayList; | |||||
| import java.util.List; | |||||
| /** | /** | ||||
| * 微信用户信息. | * 微信用户信息. | ||||
| * | * | ||||
| @@ -27,6 +27,8 @@ public class WxCpUser implements Serializable { | |||||
| private Gender gender; | private Gender gender; | ||||
| private String email; | private String email; | ||||
| private String avatar; | private String avatar; | ||||
| private String thumbAvatar; | |||||
| /** | /** | ||||
| * 地址。长度最大128个字符 | * 地址。长度最大128个字符 | ||||
| */ | */ | ||||
| @@ -34,6 +36,10 @@ public class WxCpUser implements Serializable { | |||||
| private String avatarMediaId; | private String avatarMediaId; | ||||
| private Integer status; | private Integer status; | ||||
| private Integer enable; | private Integer enable; | ||||
| /** | |||||
| * 别名;第三方仅通讯录应用可获取 | |||||
| */ | |||||
| private String alias; | |||||
| private Integer isLeader; | private Integer isLeader; | ||||
| /** | /** | ||||
| * is_leader_in_dept. | * is_leader_in_dept. | ||||
| @@ -0,0 +1,21 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.cp.bean.oa.applydata.Content; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批申请数据 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalApplyData implements Serializable { | |||||
| private static final long serialVersionUID = 4061352949894274704L; | |||||
| private List<Content> contents; | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 申请人信息 | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalApplyer extends WxCpOperator implements Serializable { | |||||
| private static final long serialVersionUID = -8974662568286821271L; | |||||
| /** | |||||
| * 申请人所在部门id | |||||
| */ | |||||
| @SerializedName("partyid") | |||||
| private String partyId; | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批申请备注信息 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalComment implements Serializable { | |||||
| private static final long serialVersionUID = -5430367411926856292L; | |||||
| /** | |||||
| * 备注人信息 | |||||
| */ | |||||
| private WxCpOperator commentUserInfo; | |||||
| /** | |||||
| * 备注提交时间戳,Unix时间戳 | |||||
| */ | |||||
| @SerializedName("commenttime") | |||||
| private Long commentTime; | |||||
| /** | |||||
| * 备注id | |||||
| */ | |||||
| @SerializedName("commentid") | |||||
| private String commentId; | |||||
| /** | |||||
| * 备注文本内容 | |||||
| */ | |||||
| @SerializedName("commentcontent") | |||||
| private String commentContent; | |||||
| /** | |||||
| * 备注附件id,可能有多个 | |||||
| */ | |||||
| @SerializedName("media_id") | |||||
| private List<String> mediaIds; | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| @@ -12,6 +12,7 @@ import java.util.Map; | |||||
| * @author Element | * @author Element | ||||
| * @date 2019-04-06 14:36 | * @date 2019-04-06 14:36 | ||||
| */ | */ | ||||
| @Deprecated | |||||
| @Data | @Data | ||||
| public class WxCpApprovalDataResult implements Serializable { | public class WxCpApprovalDataResult implements Serializable { | ||||
| private static final long serialVersionUID = -1046940445840716590L; | private static final long serialVersionUID = -1046940445840716590L; | ||||
| @@ -0,0 +1,78 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批申请详情 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalDetail implements Serializable { | |||||
| private static final long serialVersionUID = 1353393306564207170L; | |||||
| /** | |||||
| * 审批编号 | |||||
| */ | |||||
| @SerializedName("sp_no") | |||||
| private String spNo; | |||||
| /** | |||||
| * 审批申请类型名称(审批模板名称) | |||||
| */ | |||||
| @SerializedName("sp_name") | |||||
| private String spName; | |||||
| /** | |||||
| * 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付 | |||||
| */ | |||||
| @SerializedName("sp_status") | |||||
| private WxCpSpStatus spStatus; | |||||
| /** | |||||
| * 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。 | |||||
| */ | |||||
| @SerializedName("template_id") | |||||
| private String templateId; | |||||
| /** | |||||
| * 审批申请提交时间,Unix时间戳 | |||||
| */ | |||||
| @SerializedName("apply_time") | |||||
| private Long applyTime; | |||||
| /** | |||||
| * 申请人信息 | |||||
| */ | |||||
| private WxCpApprovalApplyer applyer; | |||||
| /** | |||||
| * 审批流程信息,可能有多个审批节点 | |||||
| */ | |||||
| @SerializedName("sp_record") | |||||
| private WxCpApprovalRecord spRecord; | |||||
| /** | |||||
| * 抄送信息,可能有多个抄送节点 | |||||
| */ | |||||
| @SerializedName("notifyer") | |||||
| private WxCpOperator notifyer; | |||||
| /** | |||||
| * 审批申请数据 | |||||
| */ | |||||
| @SerializedName("apply_data") | |||||
| private WxCpApprovalApplyData applyData; | |||||
| /** | |||||
| * 审批申请备注信息,可能有多个备注节点 | |||||
| */ | |||||
| @SerializedName("comments") | |||||
| private List<WxCpApprovalComment> comments; | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 审批申请详情响应结果 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalDetailResult implements Serializable { | |||||
| private static final long serialVersionUID = 3909779949756252918L; | |||||
| @SerializedName("errcode") | |||||
| private Integer errCode; | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| @SerializedName("info") | |||||
| private WxCpApprovalDetail info; | |||||
| } | |||||
| @@ -0,0 +1,29 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| /** | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalInfo implements Serializable { | |||||
| private static final long serialVersionUID = 7387181805254287167L; | |||||
| @SerializedName("errcode") | |||||
| private Integer errCode; | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| @SerializedName("sp_no_list") | |||||
| private List<String> spNoList; | |||||
| @SerializedName("next_cursor") | |||||
| private Integer nextCursor; | |||||
| } | |||||
| @@ -0,0 +1,61 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * <pre> | |||||
| * 批量获取审批单号的筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件 | |||||
| * 注意: | |||||
| * 仅“部门”支持同时配置多个筛选条件。 | |||||
| * 不同类型的筛选条件之间为“与”的关系,同类型筛选条件之间为“或”的关系 | |||||
| * </pre> | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalInfoQueryFilter implements Serializable { | |||||
| private static final long serialVersionUID = 3318064927980231802L; | |||||
| private WxCpApprovalInfoQueryFilter.KEY key; | |||||
| private Object value; | |||||
| public String toJson() { | |||||
| return WxGsonBuilder.create().toJson(this); | |||||
| } | |||||
| public static enum KEY { | |||||
| /** | |||||
| * template_id - 模板类型/模板id; | |||||
| */ | |||||
| @SerializedName("template_id") | |||||
| TEMPLATE_ID("template_id"), | |||||
| /** | |||||
| * creator - 申请人; | |||||
| */ | |||||
| @SerializedName("creator") | |||||
| CREATOR("creator"), | |||||
| /** | |||||
| * department - 审批单提单者所在部门; | |||||
| */ | |||||
| @SerializedName("department") | |||||
| DEPARTMENT("department"), | |||||
| /** | |||||
| * sp_status - 审批状态。 | |||||
| */ | |||||
| @SerializedName("sp_status") | |||||
| SP_STATUS("sp_status"); | |||||
| private String value; | |||||
| private KEY(String value) { | |||||
| this.value = value; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批流程信息 | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalRecord implements Serializable { | |||||
| private static final long serialVersionUID = -327230786004105887L; | |||||
| @SerializedName("sp_status") | |||||
| private WxCpRecordSpStatus status; | |||||
| @SerializedName("approverattr") | |||||
| private WxCpApproverAttr approverAttr; | |||||
| private List<WxCpApprovalRecordDetail> details; | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 审批节点详情 | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpApprovalRecordDetail implements Serializable { | |||||
| private static final long serialVersionUID = -9142079764088495301L; | |||||
| /** | |||||
| * 分支审批人 | |||||
| */ | |||||
| @SerializedName("approver") | |||||
| private WxCpOperator approver; | |||||
| /** | |||||
| * 审批意见 | |||||
| */ | |||||
| @SerializedName("speech") | |||||
| private String speech; | |||||
| /** | |||||
| * 分支审批人审批状态 | |||||
| */ | |||||
| @SerializedName("sp_status") | |||||
| private WxCpRecordSpStatus spStatus; | |||||
| /** | |||||
| * 节点分支审批人审批操作时间戳,0表示未操作 | |||||
| */ | |||||
| @SerializedName("sptime") | |||||
| private Long spTime; | |||||
| /** | |||||
| * 节点分支审批人审批意见附件 | |||||
| */ | |||||
| @SerializedName("media_id") | |||||
| private List<String> mediaIds; | |||||
| } | |||||
| @@ -0,0 +1,28 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * 审批方式 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| public enum WxCpApproverAttr { | |||||
| /** | |||||
| * 或签 | |||||
| */ | |||||
| @SerializedName("1") | |||||
| ONE_SIGN(1), | |||||
| /** | |||||
| * 会签 | |||||
| */ | |||||
| @SerializedName("2") | |||||
| ALL_SIGN(2); | |||||
| private Integer attr; | |||||
| private WxCpApproverAttr(Integer attr) { | |||||
| this.attr = attr; | |||||
| } | |||||
| } | |||||
| @@ -1,4 +1,4 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| @@ -47,4 +47,8 @@ public class WxCpCheckinData implements Serializable { | |||||
| @SerializedName("mediaids") | @SerializedName("mediaids") | ||||
| private List<String> mediaIds; | private List<String> mediaIds; | ||||
| private Integer lat; | |||||
| private Integer lng; | |||||
| } | } | ||||
| @@ -1,4 +1,4 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| @@ -1,4 +1,4 @@ | |||||
| package me.chanjar.weixin.cp.bean; | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| @@ -0,0 +1,24 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 企业微信操作人 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class WxCpOperator implements Serializable { | |||||
| private static final long serialVersionUID = 5797144853574346736L; | |||||
| /** | |||||
| * 企业微信userid | |||||
| */ | |||||
| @SerializedName("userid") | |||||
| private String userId; | |||||
| } | |||||
| @@ -0,0 +1,41 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * 审批记录(节点)分支审批状态 | |||||
| * | |||||
| * 1-审批中;2-已同意;3-已驳回;4-已转审 | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| public enum WxCpRecordSpStatus { | |||||
| /** | |||||
| * 审批中 | |||||
| */ | |||||
| @SerializedName("1") | |||||
| AUDITING(1), | |||||
| /** | |||||
| * 已同意 | |||||
| */ | |||||
| @SerializedName("2") | |||||
| PASSED(2), | |||||
| /** | |||||
| * 已驳回 | |||||
| */ | |||||
| @SerializedName("3") | |||||
| REJECTED(3), | |||||
| /** | |||||
| * 已转审 | |||||
| */ | |||||
| @SerializedName("4") | |||||
| TURNED(4); | |||||
| private Integer status; | |||||
| private WxCpRecordSpStatus(Integer status) { | |||||
| this.status = status; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,54 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| /** | |||||
| * 审批单状态 | |||||
| * (1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付) | |||||
| * | |||||
| * @author element | |||||
| */ | |||||
| public enum WxCpSpStatus { | |||||
| /** | |||||
| * 审批中 | |||||
| */ | |||||
| @SerializedName("1") | |||||
| AUDITING(1), | |||||
| /** | |||||
| * 已通过 | |||||
| */ | |||||
| @SerializedName("2") | |||||
| PASSED(2), | |||||
| /** | |||||
| * 已驳回 | |||||
| */ | |||||
| @SerializedName("3") | |||||
| REJECTED(3), | |||||
| /** | |||||
| * 已撤销 | |||||
| */ | |||||
| @SerializedName("4") | |||||
| UNDONE(4), | |||||
| /** | |||||
| * 通过后撤销 | |||||
| */ | |||||
| @SerializedName("6") | |||||
| PASS_UNDONE(6), | |||||
| /** | |||||
| * 已删除 | |||||
| */ | |||||
| @SerializedName("7") | |||||
| DELETED(7), | |||||
| /** | |||||
| * 已支付 | |||||
| */ | |||||
| @SerializedName("10") | |||||
| ALREADY_PAY(10); | |||||
| private Integer status; | |||||
| private WxCpSpStatus(Integer status) { | |||||
| this.status = status; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,35 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa; | |||||
| import com.google.gson.JsonObject; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateContent; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateControls; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateTitle; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * 审批模板详情 | |||||
| * | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class WxCpTemplateResult implements Serializable { | |||||
| private static final long serialVersionUID = 6690547131189343887L; | |||||
| @SerializedName("errcode") | |||||
| private Integer errCode; | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| @SerializedName("template_names") | |||||
| private List<TemplateTitle> templateNames; | |||||
| @SerializedName("template_content") | |||||
| private TemplateContent templateContent; | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.applydata; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class Content implements Serializable { | |||||
| private static final long serialVersionUID = 8456821731930526935L; | |||||
| private String control; | |||||
| private String id; | |||||
| @SerializedName("title") | |||||
| private List<ContentTitle> titles; | |||||
| private ContentValue value; | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.applydata; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class ContentTitle implements Serializable { | |||||
| private static final long serialVersionUID = -4501999157383517007L; | |||||
| private String text; | |||||
| private String lang; | |||||
| } | |||||
| @@ -0,0 +1,103 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.applydata; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author element | |||||
| */ | |||||
| @Data | |||||
| public class ContentValue implements Serializable { | |||||
| private static final long serialVersionUID = -5607678965965065261L; | |||||
| private String text; | |||||
| @SerializedName("new_number") | |||||
| private Integer newNumber; | |||||
| @SerializedName("new_money") | |||||
| private Integer newMoney; | |||||
| private ContentValue.Date date; | |||||
| private ContentValue.Selector selector; | |||||
| private List<ContentValue.Member> members; | |||||
| private List<ContentValue.Department> departments; | |||||
| private List<ContentValue.File> files; | |||||
| private List<ContentValue.Child> children; | |||||
| @Data | |||||
| public static class Date implements Serializable { | |||||
| private static final long serialVersionUID = -6181554080062231138L; | |||||
| private String type; | |||||
| @SerializedName("s_timestamp") | |||||
| private Long timestamp; | |||||
| } | |||||
| @Data | |||||
| public static class Selector implements Serializable { | |||||
| private static final long serialVersionUID = 7305458759126951773L; | |||||
| private String type; | |||||
| private List<Option> options; | |||||
| @Data | |||||
| public static class Option implements Serializable { | |||||
| private static final long serialVersionUID = -3471071106328280252L; | |||||
| private String key; | |||||
| @SerializedName("value") | |||||
| private List<ContentTitle> values; | |||||
| } | |||||
| } | |||||
| @Data | |||||
| public static class Member implements Serializable { | |||||
| private static final long serialVersionUID = 1316551341955496067L; | |||||
| @SerializedName("userid") | |||||
| private String userId; | |||||
| private String name; | |||||
| } | |||||
| @Data | |||||
| public static class Department implements Serializable { | |||||
| private static final long serialVersionUID = -2513762192924826234L; | |||||
| @SerializedName("openapi_id") | |||||
| private String openApiId; | |||||
| private String name; | |||||
| } | |||||
| @Data | |||||
| public static class File implements Serializable { | |||||
| private static final long serialVersionUID = 3890971381800855142L; | |||||
| @SerializedName("file_id") | |||||
| private String fileId; | |||||
| } | |||||
| @Data | |||||
| public static class Child implements Serializable { | |||||
| private static final long serialVersionUID = -3500102073821161558L; | |||||
| private List<Content> list; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,37 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.control.*; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。 | |||||
| * 目前有配置信息的控件类型有: | |||||
| * Date-日期/日期+时间; | |||||
| * Selector-单选/多选; | |||||
| * Contact-成员/部门; | |||||
| * Table-明细; | |||||
| * Attendance-假勤组件(请假、外出、出差、加班) | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateConfig implements Serializable { | |||||
| private static final long serialVersionUID = 6993937809371277669L; | |||||
| private TemplateDate date; | |||||
| private TemplateSelector selector; | |||||
| private TemplateContact contact; | |||||
| private TemplateTable table; | |||||
| private TemplateAttendance attendance; | |||||
| @SerializedName("vacation_list") | |||||
| private TemplateVacation vacationList; | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateContent implements Serializable { | |||||
| private static final long serialVersionUID = -5640250983775840865L; | |||||
| private List<TemplateControls> controls; | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * @author Administrator | |||||
| */ | |||||
| @Data | |||||
| public class TemplateControls implements Serializable { | |||||
| private static final long serialVersionUID = -7496794407355510374L; | |||||
| private TemplateProperty property; | |||||
| private TemplateConfig config; | |||||
| } | |||||
| @@ -0,0 +1,19 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateDateRange implements Serializable { | |||||
| private static final long serialVersionUID = -9209035461466543180L; | |||||
| /** | |||||
| * 时间刻度:hour-精确到分钟, halfday—上午/下午 | |||||
| */ | |||||
| private String type; | |||||
| } | |||||
| @@ -0,0 +1,16 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author gyv123@163.com | |||||
| */ | |||||
| public class TemplateOptions implements Serializable { | |||||
| private static final long serialVersionUID = -7883792668568772078L; | |||||
| private String key; | |||||
| private List<TemplateTitle> value; | |||||
| } | |||||
| @@ -0,0 +1,41 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata; | |||||
| import com.google.gson.JsonObject; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import me.chanjar.weixin.cp.bean.oa.WxCpTemplateResult; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.control.TemplateContact; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| public class TemplateProperty implements Serializable { | |||||
| private static final long serialVersionUID = -3429251158540167453L; | |||||
| private String control; | |||||
| private String id; | |||||
| private List<TemplateTitle> title; | |||||
| /** | |||||
| * 控件说明,向申请者展示的控件填写说明,若配置了多语言则会包含中英文的控件说明,默认为zh_CN中文 | |||||
| */ | |||||
| private List<TemplateTitle> placeholder; | |||||
| /** | |||||
| * 是否必填:1-必填;0-非必填 | |||||
| */ | |||||
| private Integer require; | |||||
| /** | |||||
| * 是否参与打印:1-不参与打印;0-参与打印 | |||||
| */ | |||||
| @SerializedName("un_print") | |||||
| private Integer unPrint; | |||||
| private TemplateConfig config; | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateTitle implements Serializable { | |||||
| private static final long serialVersionUID = -3229779834737051398L; | |||||
| private String text; | |||||
| private String lang; | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateVacationItem implements Serializable { | |||||
| private static final long serialVersionUID = 4510594801023791319L; | |||||
| private Integer id; | |||||
| private TemplateTitle name; | |||||
| } | |||||
| @@ -0,0 +1,25 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata.control; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateDateRange; | |||||
| import java.io.Serializable; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateAttendance implements Serializable { | |||||
| private static final long serialVersionUID = 5800412600894589065L; | |||||
| @SerializedName("date_range") | |||||
| private TemplateDateRange dateRange; | |||||
| /** | |||||
| * 假勤控件类型:1-请假,3-出差,4-外出,5-加班 | |||||
| */ | |||||
| private Integer type; | |||||
| } | |||||
| @@ -0,0 +1,22 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata.control; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateContact implements Serializable { | |||||
| private static final long serialVersionUID = -7840088884653172851L; | |||||
| /** | |||||
| * 选择方式:single-单选;multi-多选 | |||||
| */ | |||||
| private String type; | |||||
| /** | |||||
| * 选择对象:user-成员;department-部门 | |||||
| */ | |||||
| private String mode; | |||||
| } | |||||
| @@ -0,0 +1,18 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata.control; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * @author Administrator | |||||
| */ | |||||
| @Data | |||||
| public class TemplateDate implements Serializable { | |||||
| private static final long serialVersionUID = 1300634733160349684L; | |||||
| /** | |||||
| * day-日期;hour-日期+时间 | |||||
| */ | |||||
| private String type; | |||||
| } | |||||
| @@ -0,0 +1,20 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata.control; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateOptions; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author | |||||
| */ | |||||
| public class TemplateSelector implements Serializable { | |||||
| private static final long serialVersionUID = 4995408101489736881L; | |||||
| /** | |||||
| * single-单选;multi-多选 | |||||
| */ | |||||
| private String type; | |||||
| private List<TemplateOptions> options; | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata.control; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateControls; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateTable implements Serializable { | |||||
| private static final long serialVersionUID = -8181588935694605858L; | |||||
| private List<TemplateControls> children; | |||||
| private String[] statField; | |||||
| } | |||||
| @@ -0,0 +1,17 @@ | |||||
| package me.chanjar.weixin.cp.bean.oa.templatedata.control; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateVacationItem; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author gyv12345@163.com | |||||
| */ | |||||
| @Data | |||||
| public class TemplateVacation implements Serializable { | |||||
| private List<TemplateVacationItem> item; | |||||
| } | |||||
| @@ -97,4 +97,10 @@ public interface WxCpConfigStorage { | |||||
| * @return ApacheHttpClientBuilder | * @return ApacheHttpClientBuilder | ||||
| */ | */ | ||||
| ApacheHttpClientBuilder getApacheHttpClientBuilder(); | ApacheHttpClientBuilder getApacheHttpClientBuilder(); | ||||
| /** | |||||
| * 是否自动刷新token | |||||
| * @return . | |||||
| */ | |||||
| boolean autoRefreshToken(); | |||||
| } | } | ||||
| @@ -83,4 +83,10 @@ public interface WxCpTpConfigStorage { | |||||
| * @return ApacheHttpClientBuilder | * @return ApacheHttpClientBuilder | ||||
| */ | */ | ||||
| ApacheHttpClientBuilder getApacheHttpClientBuilder(); | ApacheHttpClientBuilder getApacheHttpClientBuilder(); | ||||
| /** | |||||
| * 是否自动刷新token | |||||
| * @return . | |||||
| */ | |||||
| boolean autoRefreshToken(); | |||||
| } | } | ||||
| @@ -262,6 +262,11 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable { | |||||
| return this.apacheHttpClientBuilder; | return this.apacheHttpClientBuilder; | ||||
| } | } | ||||
| @Override | |||||
| public boolean autoRefreshToken() { | |||||
| return true; | |||||
| } | |||||
| public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | ||||
| this.apacheHttpClientBuilder = apacheHttpClientBuilder; | this.apacheHttpClientBuilder = apacheHttpClientBuilder; | ||||
| } | } | ||||
| @@ -320,6 +320,11 @@ public class WxCpRedisConfigImpl implements WxCpConfigStorage { | |||||
| return this.apacheHttpClientBuilder; | return this.apacheHttpClientBuilder; | ||||
| } | } | ||||
| @Override | |||||
| public boolean autoRefreshToken() { | |||||
| return true; | |||||
| } | |||||
| public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | ||||
| this.apacheHttpClientBuilder = apacheHttpClientBuilder; | this.apacheHttpClientBuilder = apacheHttpClientBuilder; | ||||
| } | } | ||||
| @@ -242,6 +242,11 @@ public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializabl | |||||
| return this.apacheHttpClientBuilder; | return this.apacheHttpClientBuilder; | ||||
| } | } | ||||
| @Override | |||||
| public boolean autoRefreshToken() { | |||||
| return true; | |||||
| } | |||||
| public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { | ||||
| this.apacheHttpClientBuilder = apacheHttpClientBuilder; | this.apacheHttpClientBuilder = apacheHttpClientBuilder; | ||||
| } | } | ||||
| @@ -21,7 +21,6 @@ public final class WxCpApiPathConsts { | |||||
| public static final String BATCH_GET_RESULT = "/cgi-bin/batch/getresult?jobid="; | 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 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 class Agent { | ||||
| public static final String AGENT_GET = "/cgi-bin/agent/get?agentid=%d"; | public static final String AGENT_GET = "/cgi-bin/agent/get?agentid=%d"; | ||||
| @@ -65,8 +64,13 @@ public final class WxCpApiPathConsts { | |||||
| public static class Oa { | public static class Oa { | ||||
| public static final String GET_CHECKIN_DATA = "/cgi-bin/checkin/getcheckindata"; | public static final String GET_CHECKIN_DATA = "/cgi-bin/checkin/getcheckindata"; | ||||
| public static final String GET_CHECKIN_OPTION = "/cgi-bin/checkin/getcheckinoption"; | public static final String GET_CHECKIN_OPTION = "/cgi-bin/checkin/getcheckinoption"; | ||||
| public static final String GET_APPROVAL_DATA = "/cgi-bin/corp/getapprovaldata"; | |||||
| public static final String GET_APPROVAL_INFO = "/cgi-bin/oa/getapprovalinfo"; | |||||
| public static final String GET_APPROVAL_DETAIL = "/cgi-bin/oa/getapprovaldetail"; | |||||
| public static final String GET_DIAL_RECORD = "/cgi-bin/dial/get_dial_record"; | public static final String GET_DIAL_RECORD = "/cgi-bin/dial/get_dial_record"; | ||||
| @Deprecated | |||||
| public static final String GET_APPROVAL_DATA = "/cgi-bin/corp/getapprovaldata"; | |||||
| public static final String GET_TEMPLATE_DETAIL = "/cgi-bin/oa/gettemplatedetail"; | |||||
| public static final String APPLY_EVENT="/cgi-bin/oa/applyevent"; | |||||
| } | } | ||||
| public static class Tag { | public static class Tag { | ||||
| @@ -88,6 +92,7 @@ public final class WxCpApiPathConsts { | |||||
| public static final String GET_CORP_TOKEN = "/cgi-bin/service/get_corp_token"; | public static final String GET_CORP_TOKEN = "/cgi-bin/service/get_corp_token"; | ||||
| public static final String GET_PERMANENT_CODE = "/cgi-bin/service/get_permanent_code"; | public static final String GET_PERMANENT_CODE = "/cgi-bin/service/get_permanent_code"; | ||||
| public static final String GET_SUITE_TOKEN = "/cgi-bin/service/get_suite_token"; | public static final String GET_SUITE_TOKEN = "/cgi-bin/service/get_suite_token"; | ||||
| public static final String GET_PROVIDER_TOKEN = "/cgi-bin/service/get_provider_token"; | |||||
| } | } | ||||
| public static class User { | public static class User { | ||||
| @@ -107,8 +112,11 @@ public final class WxCpApiPathConsts { | |||||
| } | } | ||||
| public static class ExternalContact { | public static class ExternalContact { | ||||
| @Deprecated | |||||
| public static final String GET_EXTERNAL_CONTACT = "/cgi-bin/crm/get_external_contact?external_userid="; | public static final String GET_EXTERNAL_CONTACT = "/cgi-bin/crm/get_external_contact?external_userid="; | ||||
| public static final String LIST_EXTERNAL_CONTACT = "/cgi-bin/externalcontact/list?userid="; | |||||
| public static final String GET_FOLLOW_USER_LIST = "/cgi-bin/externalcontact/get_follow_user_list"; | public static final String GET_FOLLOW_USER_LIST = "/cgi-bin/externalcontact/get_follow_user_list"; | ||||
| public static final String GET_CONTACT_DETAIL = "/cgi-bin/externalcontact/get?external_userid="; | |||||
| public static final String LIST_EXTERNAL_CONTACT = "/cgi-bin/externalcontact/list?userid="; | |||||
| } | } | ||||
| } | } | ||||
| @@ -94,6 +94,11 @@ public class WxCpConsts { | |||||
| */ | */ | ||||
| public static final String CHANGE_EXTERNAL_CONTACT = "change_external_contact"; | public static final String CHANGE_EXTERNAL_CONTACT = "change_external_contact"; | ||||
| /** | |||||
| * 企业微信审批事件推送 | |||||
| */ | |||||
| public static final String OPEN_APPROVAL_CHANGE = "open_approval_change"; | |||||
| } | } | ||||
| @@ -109,6 +114,15 @@ public class WxCpConsts { | |||||
| * 删除外部联系人 | * 删除外部联系人 | ||||
| */ | */ | ||||
| public static final String DEL_EXTERNAL_CONTACT = "del_external_contact"; | public static final String DEL_EXTERNAL_CONTACT = "del_external_contact"; | ||||
| /** | |||||
| * 外部联系人免验证添加成员事件 | |||||
| */ | |||||
| public static final String ADD_HALF_EXTERNAL_CONTACT = "add_half_external_contact"; | |||||
| /** | |||||
| * 删除跟进成员事件 | |||||
| */ | |||||
| public static final String DEL_FOLLOW_USER = "del_follow_user"; | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -66,10 +66,12 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||||
| user.setGender(Gender.fromCode(GsonHelper.getString(o, "gender"))); | user.setGender(Gender.fromCode(GsonHelper.getString(o, "gender"))); | ||||
| user.setEmail(GsonHelper.getString(o, "email")); | user.setEmail(GsonHelper.getString(o, "email")); | ||||
| user.setAvatar(GsonHelper.getString(o, "avatar")); | user.setAvatar(GsonHelper.getString(o, "avatar")); | ||||
| user.setThumbAvatar(GsonHelper.getString(o, "thumb_avatar")); | |||||
| user.setAddress(GsonHelper.getString(o, "address")); | user.setAddress(GsonHelper.getString(o, "address")); | ||||
| user.setAvatarMediaId(GsonHelper.getString(o, "avatar_mediaid")); | user.setAvatarMediaId(GsonHelper.getString(o, "avatar_mediaid")); | ||||
| user.setStatus(GsonHelper.getInteger(o, "status")); | user.setStatus(GsonHelper.getInteger(o, "status")); | ||||
| user.setEnable(GsonHelper.getInteger(o, "enable")); | user.setEnable(GsonHelper.getInteger(o, "enable")); | ||||
| user.setAlias(GsonHelper.getString(o, "alias")); | |||||
| user.setIsLeader(GsonHelper.getInteger(o, "isleader")); | user.setIsLeader(GsonHelper.getInteger(o, "isleader")); | ||||
| user.setIsLeaderInDept(GsonHelper.getIntArray(o, "is_leader_in_dept")); | user.setIsLeaderInDept(GsonHelper.getIntArray(o, "is_leader_in_dept")); | ||||
| user.setHideMobile(GsonHelper.getInteger(o, "hide_mobile")); | user.setHideMobile(GsonHelper.getInteger(o, "hide_mobile")); | ||||
| @@ -187,6 +189,9 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||||
| if (user.getAvatar() != null) { | if (user.getAvatar() != null) { | ||||
| o.addProperty("avatar", user.getAvatar()); | o.addProperty("avatar", user.getAvatar()); | ||||
| } | } | ||||
| if (user.getThumbAvatar() != null) { | |||||
| o.addProperty("thumb_avatar", user.getThumbAvatar()); | |||||
| } | |||||
| if (user.getAddress() != null) { | if (user.getAddress() != null) { | ||||
| o.addProperty("address", user.getAddress()); | o.addProperty("address", user.getAddress()); | ||||
| } | } | ||||
| @@ -199,6 +204,9 @@ public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSeri | |||||
| if (user.getEnable() != null) { | if (user.getEnable() != null) { | ||||
| o.addProperty("enable", user.getEnable()); | o.addProperty("enable", user.getEnable()); | ||||
| } | } | ||||
| if (user.getAlias() != null) { | |||||
| o.addProperty("alias", user.getAlias()); | |||||
| } | |||||
| if (user.getIsLeader() != null) { | if (user.getIsLeader() != null) { | ||||
| o.addProperty("isleader", user.getIsLeader()); | o.addProperty("isleader", user.getIsLeader()); | ||||
| } | } | ||||
| @@ -42,4 +42,13 @@ public class WxCpExternalContactServiceImplTest { | |||||
| System.out.println(ret); | System.out.println(ret); | ||||
| assertNotNull(ret); | assertNotNull(ret); | ||||
| } | } | ||||
| @Test | |||||
| public void testGetContactDetail() throws WxErrorException { | |||||
| String externalUserId = this.configStorage.getExternalUserId(); | |||||
| WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getContactDetail(externalUserId); | |||||
| System.out.println(result); | |||||
| assertNotNull(result); | |||||
| } | |||||
| } | } | ||||
| @@ -1,33 +1,37 @@ | |||||
| package me.chanjar.weixin.cp.api.impl; | package me.chanjar.weixin.cp.api.impl; | ||||
| import com.google.common.collect.Lists; | |||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.cp.api.ApiTestModule; | import me.chanjar.weixin.cp.api.ApiTestModule; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinData; | |||||
| import me.chanjar.weixin.cp.bean.WxCpCheckinOption; | |||||
| import me.chanjar.weixin.cp.bean.oa.*; | |||||
| import org.apache.commons.lang3.time.DateFormatUtils; | import org.apache.commons.lang3.time.DateFormatUtils; | ||||
| import org.testng.annotations.Guice; | import org.testng.annotations.Guice; | ||||
| import org.testng.annotations.Test; | import org.testng.annotations.Test; | ||||
| import org.testng.collections.Lists; | |||||
| import java.text.ParseException; | import java.text.ParseException; | ||||
| import java.util.ArrayList; | |||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.List; | import java.util.List; | ||||
| import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||
| /** | /** | ||||
| * 企业微信 OA数据接口 测试用例 | |||||
| * | |||||
| * @author Element | * @author Element | ||||
| * @date 2019-04-20 13:46 | |||||
| */ | */ | ||||
| @Guice(modules = ApiTestModule.class) | @Guice(modules = ApiTestModule.class) | ||||
| public class WxCpOaServiceImplTest { | public class WxCpOaServiceImplTest { | ||||
| @Inject | @Inject | ||||
| protected WxCpService wxService; | protected WxCpService wxService; | ||||
| @Inject | |||||
| protected Gson gson; | |||||
| @Test | @Test | ||||
| public void testGetCheckinData() throws ParseException, WxErrorException { | public void testGetCheckinData() throws ParseException, WxErrorException { | ||||
| Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-04-11"); | Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-04-11"); | ||||
| @@ -37,13 +41,52 @@ public class WxCpOaServiceImplTest { | |||||
| .getCheckinData(1, startTime, endTime, Lists.newArrayList("binary")); | .getCheckinData(1, startTime, endTime, Lists.newArrayList("binary")); | ||||
| assertThat(results).isNotNull(); | assertThat(results).isNotNull(); | ||||
| System.out.println("results "); | |||||
| System.out.println(gson.toJson(results)); | |||||
| } | } | ||||
| @Test | @Test | ||||
| public void testGetCheckinOption() throws WxErrorException { | public void testGetCheckinOption() throws WxErrorException { | ||||
| Date now = new Date(); | Date now = new Date(); | ||||
| List<WxCpCheckinOption> results = wxService.getOAService() | |||||
| .getCheckinOption(now, Lists.newArrayList("binary")); | |||||
| List<WxCpCheckinOption> results = wxService.getOAService().getCheckinOption(now, Lists.newArrayList("binary")); | |||||
| assertThat(results).isNotNull(); | assertThat(results).isNotNull(); | ||||
| System.out.println("results "); | |||||
| System.out.println(gson.toJson(results)); | |||||
| } | } | ||||
| @Test | |||||
| public void testGetApprovalInfo() throws WxErrorException, ParseException { | |||||
| Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-12-01"); | |||||
| Date endTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-12-31"); | |||||
| WxCpApprovalInfo result = wxService.getOAService().getApprovalInfo(startTime, endTime); | |||||
| assertThat(result).isNotNull(); | |||||
| System.out.println("result "); | |||||
| System.out.println(gson.toJson(result)); | |||||
| } | |||||
| @Test | |||||
| public void testGetApprovalDetail() throws WxErrorException { | |||||
| String spNo = "201912020001"; | |||||
| WxCpApprovalDetailResult result = wxService.getOAService().getApprovalDetail(spNo); | |||||
| assertThat(result).isNotNull(); | |||||
| System.out.println("result "); | |||||
| System.out.println(gson.toJson(result)); | |||||
| } | |||||
| @Test | |||||
| public void testGetTemplateDetail() throws WxErrorException{ | |||||
| String templateId="3TkZjxugodbqpEMk9j7X6h6zKqYkc7MxQrrFmT7H"; | |||||
| WxCpTemplateResult result=wxService.getOAService().getTemplateDetail(templateId); | |||||
| assertThat(result).isNotNull(); | |||||
| System.out.println("result "); | |||||
| System.out.println(gson.toJson(result)); | |||||
| } | |||||
| } | } | ||||
| @@ -83,6 +83,7 @@ public class WxCpUserGsonAdapterTest { | |||||
| assertThat(user.getOrders()[1]).isEqualTo(2); | assertThat(user.getOrders()[1]).isEqualTo(2); | ||||
| assertThat(user.getAddress()).isEqualTo("广州市海珠区新港中路"); | assertThat(user.getAddress()).isEqualTo("广州市海珠区新港中路"); | ||||
| assertThat(user.getAlias()).isEqualTo("jackzhang"); | |||||
| assertThat(user.getExternalAttrs()).isNotEmpty(); | assertThat(user.getExternalAttrs()).isNotEmpty(); | ||||
| final WxCpUser.ExternalAttribute externalAttr1 = user.getExternalAttrs().get(0); | final WxCpUser.ExternalAttribute externalAttr1 = user.getExternalAttrs().get(0); | ||||
| @@ -102,6 +103,7 @@ public class WxCpUserGsonAdapterTest { | |||||
| assertThat(externalAttr3.getAppid()).isEqualTo("wx8bd80126147df384"); | assertThat(externalAttr3.getAppid()).isEqualTo("wx8bd80126147df384"); | ||||
| assertThat(externalAttr3.getPagePath()).isEqualTo("/index"); | assertThat(externalAttr3.getPagePath()).isEqualTo("/index"); | ||||
| assertThat(externalAttr3.getTitle()).isEqualTo("my miniprogram"); | assertThat(externalAttr3.getTitle()).isEqualTo("my miniprogram"); | ||||
| } | } | ||||
| @Test | @Test | ||||
| @@ -7,7 +7,7 @@ | |||||
| <parent> | <parent> | ||||
| <groupId>com.github.binarywang</groupId> | <groupId>com.github.binarywang</groupId> | ||||
| <artifactId>wx-java</artifactId> | <artifactId>wx-java</artifactId> | ||||
| <version>3.6.0</version> | |||||
| <version>3.7.0</version> | |||||
| </parent> | </parent> | ||||
| <artifactId>weixin-java-miniapp</artifactId> | <artifactId>weixin-java-miniapp</artifactId> | ||||
| @@ -80,12 +80,12 @@ | |||||
| <groupId>org.projectlombok</groupId> | <groupId>org.projectlombok</groupId> | ||||
| <artifactId>lombok</artifactId> | <artifactId>lombok</artifactId> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>com.github.jedis-lock</groupId> | |||||
| <artifactId>jedis-lock</artifactId> | |||||
| <version>1.0.0</version> | |||||
| <optional>true</optional> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.github.jedis-lock</groupId> | |||||
| <artifactId>jedis-lock</artifactId> | |||||
| <version>1.0.0</version> | |||||
| <optional>true</optional> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -102,4 +102,35 @@ | |||||
| </plugins> | </plugins> | ||||
| </build> | </build> | ||||
| <profiles> | |||||
| <profile> | |||||
| <id>native-image</id> | |||||
| <activation> | |||||
| <activeByDefault>false</activeByDefault> | |||||
| </activation> | |||||
| <build> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>org.apache.maven.plugins</groupId> | |||||
| <artifactId>maven-compiler-plugin</artifactId> | |||||
| <version>3.5.1</version> | |||||
| <configuration> | |||||
| <annotationProcessors> | |||||
| cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor | |||||
| </annotationProcessors> | |||||
| <annotationProcessorPaths> | |||||
| <path> | |||||
| <groupId>com.github.binarywang</groupId> | |||||
| <artifactId>weixin-graal</artifactId> | |||||
| <version>${project.version}</version> | |||||
| </path> | |||||
| </annotationProcessorPaths> | |||||
| </configuration> | |||||
| </plugin> | |||||
| </plugins> | |||||
| </build> | |||||
| </profile> | |||||
| </profiles> | |||||
| </project> | </project> | ||||
| @@ -0,0 +1,317 @@ | |||||
| package cn.binarywang.wx.miniapp.api; | |||||
| import cn.binarywang.wx.miniapp.bean.cloud.*; | |||||
| import com.google.gson.JsonArray; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 云开发相关接口. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-22 | |||||
| */ | |||||
| public interface WxMaCloudService { | |||||
| String INVOKE_CLOUD_FUNCTION_URL = "https://api.weixin.qq.com/tcb/invokecloudfunction?env=%s&name=%s"; | |||||
| String DATABASE_COLLECTION_GET_URL = "https://api.weixin.qq.com/tcb/databasecollectionget"; | |||||
| String DATABASE_COLLECTION_DELETE_URL = "https://api.weixin.qq.com/tcb/databasecollectiondelete"; | |||||
| String DATABASE_COLLECTION_ADD_URL = "https://api.weixin.qq.com/tcb/databasecollectionadd"; | |||||
| String GET_QCLOUD_TOKEN_URL = "https://api.weixin.qq.com/tcb/getqcloudtoken"; | |||||
| String BATCH_DELETE_FILE_URL = "https://api.weixin.qq.com/tcb/batchdeletefile"; | |||||
| String UPLOAD_FILE_URL = "https://api.weixin.qq.com/tcb/uploadfile"; | |||||
| String DATABASE_MIGRATE_QUERY_INFO_URL = "https://api.weixin.qq.com/tcb/databasemigratequeryinfo"; | |||||
| String DATABASE_MIGRATE_EXPORT_URL = "https://api.weixin.qq.com/tcb/databasemigrateexport"; | |||||
| String DATABASE_MIGRATE_IMPORT_URL = "https://api.weixin.qq.com/tcb/databasemigrateimport"; | |||||
| String UPDATE_INDEX_URL = "https://api.weixin.qq.com/tcb/updateindex"; | |||||
| String DATABASE_COUNT_URL = "https://api.weixin.qq.com/tcb/databasecount"; | |||||
| String DATABASE_AGGREGATE_URL = "https://api.weixin.qq.com/tcb/databaseaggregate"; | |||||
| String DATABASE_QUERY_URL = "https://api.weixin.qq.com/tcb/databasequery"; | |||||
| String DATABASE_UPDATE_URL = "https://api.weixin.qq.com/tcb/databaseupdate"; | |||||
| String DATABASE_DELETE_URL = "https://api.weixin.qq.com/tcb/databasedelete"; | |||||
| String DATABASE_ADD_URL = "https://api.weixin.qq.com/tcb/databaseadd"; | |||||
| /** | |||||
| * <pre> | |||||
| * 触发云函数。注意:HTTP API 途径触发云函数不包含用户信息。 | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/functions/invokeCloudFunction.html | |||||
| * | |||||
| * 请求地址 | |||||
| * POST https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=ACCESS_TOKEN&env=ENV&name=FUNCTION_NAME | |||||
| * | |||||
| * </pre> | |||||
| * | |||||
| * @param env string 是 云开发环境ID | |||||
| * @param name string 是 云函数名称 | |||||
| * @param body string 是 云函数的传入参数,具体结构由开发者定义。 | |||||
| * @return resp_data string 云函数返回的buffer | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| String invokeCloudFunction(String env, String name, String body) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 数据库插入记录 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseAdd.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databaseadd?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param query 数据库操作语句 | |||||
| * @return 插入成功的数据集合主键_id | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| JsonArray databaseAdd(String env, String query) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 数据库删除记录 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseDelete.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasedelete?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param query 数据库操作语句 | |||||
| * @return 删除记录数量 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| int databaseDelete(String env, String query) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 数据库更新记录 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseUpdate.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databaseupdate?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param query 数据库操作语句 | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCloudDatabaseUpdateResult databaseUpdate(String env, String query) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 数据库查询记录 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseQuery.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasequery?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param query 数据库操作语句 | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCloudDatabaseQueryResult databaseQuery(String env, String query) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 数据库聚合记录 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseAggregate.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databaseaggregate?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param query 数据库操作语句 | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| JsonArray databaseAggregate(String env, String query) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 统计集合记录数或统计查询语句对应的结果记录数 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCount.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasecount?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param query 数据库操作语句 | |||||
| * @return 记录数量 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| Long databaseCount(String env, String query) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 变更数据库索引 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/updateIndex.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/updateindex?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param collectionName 集合名称 | |||||
| * @param createIndexes 新增索引对象 | |||||
| * @param dropIndexNames 要删除的索引的名字 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| void updateIndex(String env, String collectionName, List<WxCloudDatabaseCreateIndexRequest> createIndexes, | |||||
| List<String> dropIndexNames) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 数据库导入 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateImport.html | |||||
| * 请求地址: POST https://api.weixin.qq.com/tcb/databasemigrateimport?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param collectionName 导入collection名 | |||||
| * @param filePath 导入文件路径(导入文件需先上传到同环境的存储中,可使用开发者工具或 HTTP API的上传文件 API上传) | |||||
| * @param fileType 导入文件类型, 1 JSON, 2 CSV | |||||
| * @param stopOnError 是否在遇到错误时停止导入 | |||||
| * @param conflictMode 冲突处理模式 : 1 INSERT , 2 UPSERT | |||||
| * @return jobId | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| Long databaseMigrateImport(String env, String collectionName, String filePath, int fileType, boolean stopOnError, | |||||
| int conflictMode) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 数据库导出 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateExport.html | |||||
| * 请求地址: POST https://api.weixin.qq.com/tcb/databasemigrateexport?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param filePath 导出文件路径(文件会导出到同环境的云存储中,可使用获取下载链接 API 获取下载链接) | |||||
| * @param fileType 导出文件类型, 1 JSON, 2 CSV | |||||
| * @param query 导出条件 | |||||
| * @return jobId | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| Long databaseMigrateExport(String env, String filePath, int fileType, String query) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 数据库迁移状态查询 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateQueryInfo.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasemigratequeryinfo?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param jobId 迁移任务ID | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCloudCloudDatabaseMigrateQueryInfoResult databaseMigrateQueryInfo(String env, Long jobId) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取文件上传链接 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/uploadFile.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/uploadfile?access_token=ACCESS_TOKEN | |||||
| * | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param path 上传路径 | |||||
| * @return 上传结果 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCloudUploadFileResult uploadFile(String env, String path) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取文件下载链接 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/batchDownloadFile.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/batchdownloadfile?access_token=ACCESS_TOKEN | |||||
| * | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param fileIds 文件ID列表 | |||||
| * @param maxAges 下载链接有效期列表,对应文件id列表 | |||||
| * @return 下载链接信息 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCloudBatchDownloadFileResult batchDownloadFile(String env, String[] fileIds, long[] maxAges) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 删除文件 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/batchDeleteFile.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/batchdeletefile?access_token=ACCESS_TOKEN | |||||
| * | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param fileIds 文件ID列表 | |||||
| * @return 下载链接信息 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCloudBatchDeleteFileResult batchDeleteFile(String env, String[] fileIds) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取腾讯云API调用凭证 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/utils/getQcloudToken.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/getqcloudtoken?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param lifeSpan 有效期(单位为秒,最大7200) | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCloudGetQcloudTokenResult getQcloudToken(long lifeSpan) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 新增集合 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionAdd.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionadd?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param collectionName 集合名称 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| void databaseCollectionAdd(String env, String collectionName) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 删除集合 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionDelete.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionadd?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param collectionName 集合名称 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| void databaseCollectionDelete(String env, String collectionName) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取特定云环境下集合信息 | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionGet.html | |||||
| * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionget?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param env 云环境ID | |||||
| * @param limit 获取数量限制,默认值:10 | |||||
| * @param offset 偏移量,默认值:0 | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxCloudDatabaseCollectionGetResult databaseCollectionGet(String env, Long limit, Long offset) throws WxErrorException; | |||||
| } | |||||
| @@ -0,0 +1,203 @@ | |||||
| package cn.binarywang.wx.miniapp.api; | |||||
| import cn.binarywang.wx.miniapp.bean.express.WxMaExpressAccount; | |||||
| import cn.binarywang.wx.miniapp.bean.express.WxMaExpressDelivery; | |||||
| import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPath; | |||||
| import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPrinter; | |||||
| import cn.binarywang.wx.miniapp.bean.express.request.*; | |||||
| import cn.binarywang.wx.miniapp.bean.express.result.WxMaExpressOrderInfoResult; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 小程序物流助手 | |||||
| * @author <a href="https://github.com/mr-xiaoyu">xiaoyu</a> | |||||
| * @since 2019-11-26 | |||||
| */ | |||||
| public interface WxMaExpressService { | |||||
| /** | |||||
| * 获取支持的快递公司列表 | |||||
| */ | |||||
| String ALL_DELIVERY_URL = "https://api.weixin.qq.com/cgi-bin/express/business/delivery/getall"; | |||||
| /** | |||||
| * 获取所有绑定的物流账号 | |||||
| */ | |||||
| String ALL_ACCOUNT_URL = "https://api.weixin.qq.com/cgi-bin/express/business/account/getall"; | |||||
| /** | |||||
| * 绑定、解绑物流账号 | |||||
| */ | |||||
| String BIND_ACCOUNT_URL = "https://api.weixin.qq.com/cgi-bin/express/business/account/bind"; | |||||
| /** | |||||
| * 获取电子面单余额 | |||||
| */ | |||||
| String GET_QUOTA_URL = "https://api.weixin.qq.com/cgi-bin/express/business/quota/get"; | |||||
| /** | |||||
| * 配置面单打印员 | |||||
| */ | |||||
| String UPDATE_PRINTER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/printer/update"; | |||||
| /** | |||||
| * 获取打印员 | |||||
| */ | |||||
| String GET_PRINTER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/printer/getall"; | |||||
| /** | |||||
| * 生成运单 | |||||
| */ | |||||
| String ADD_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/add"; | |||||
| /** | |||||
| * 批量获取运单数据 | |||||
| */ | |||||
| String BATCH_GET_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/batchget"; | |||||
| /** | |||||
| * 取消运单 | |||||
| */ | |||||
| String CANCEL_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/cancel"; | |||||
| /** | |||||
| * 获取运单数据 | |||||
| */ | |||||
| String GET_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/get"; | |||||
| /** | |||||
| * 查询运单轨迹 | |||||
| */ | |||||
| String GET_PATH_URL = "https://api.weixin.qq.com/cgi-bin/express/business/path/get"; | |||||
| /** | |||||
| * 模拟快递公司更新订单状态 | |||||
| */ | |||||
| String TEST_UPDATE_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/test_update_order"; | |||||
| /** | |||||
| * 获取支持的快递公司列表 | |||||
| * @return 快递公司列表 | |||||
| * @throws WxErrorException 获取失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.getAllDelivery.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| List<WxMaExpressDelivery> getAllDelivery() throws WxErrorException; | |||||
| /** | |||||
| * 获取所有绑定的物流账号 | |||||
| * @return 物流账号list | |||||
| * @throws WxErrorException 获取失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.getAllAccount.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| List<WxMaExpressAccount> getAllAccount() throws WxErrorException; | |||||
| /** | |||||
| * 绑定、解绑物流账号 | |||||
| * @param wxMaExpressBindAccountRequest 物流账号对象 | |||||
| * @throws WxErrorException 请求失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.bindAccount.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| void bindAccount(WxMaExpressBindAccountRequest wxMaExpressBindAccountRequest) throws WxErrorException; | |||||
| /** | |||||
| * 获取电子面单余额。仅在使用加盟类快递公司时,才可以调用。 | |||||
| * @param wxMaExpressBindAccountRequest 物流账号对象 | |||||
| * @return 电子面单余额 | |||||
| * @throws WxErrorException 获取失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.getQuota.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| Integer getQuota(WxMaExpressBindAccountRequest wxMaExpressBindAccountRequest) throws WxErrorException; | |||||
| /** | |||||
| * 配置面单打印员,可以设置多个,若需要使用微信打单 PC 软件,才需要调用。 | |||||
| * @param wxMaExpressPrinterUpdateRequest 面单打印员对象 | |||||
| * @throws WxErrorException 请求失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.updatePrinter.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| void updatePrinter(WxMaExpressPrinterUpdateRequest wxMaExpressPrinterUpdateRequest) throws WxErrorException; | |||||
| /** | |||||
| * 获取打印员。若需要使用微信打单 PC 软件,才需要调用 | |||||
| * @return 打印员 | |||||
| * @throws WxErrorException 获取失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.getPrinter.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| WxMaExpressPrinter getPrinter() throws WxErrorException; | |||||
| /** | |||||
| * 生成运单 | |||||
| * @param wxMaExpressAddOrderRequest 生成运单请求对象 | |||||
| * @return 生成运单结果 | |||||
| * @throws WxErrorException 请求失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.addOrder.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| WxMaExpressOrderInfoResult addOrder(WxMaExpressAddOrderRequest wxMaExpressAddOrderRequest) throws WxErrorException; | |||||
| /** | |||||
| * 批量获取运单数据 | |||||
| * @param requests 获取运单请求对象集合,最多不能超过1000个 | |||||
| * @return 运单信息集合 | |||||
| * @throws WxErrorException 获取失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.batchGetOrder.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| List<WxMaExpressOrderInfoResult> batchGetOrder(List<WxMaExpressGetOrderRequest> requests) throws WxErrorException; | |||||
| /** | |||||
| * 取消运单 | |||||
| * @param wxMaExpressGetOrderRequest 运单信息请求对象 | |||||
| * @throws WxErrorException 取消失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.cancelOrder.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| void cancelOrder(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException; | |||||
| /** | |||||
| * 获取运单数据 | |||||
| * @param wxMaExpressGetOrderRequest 运单信息请求对象 | |||||
| * @return 运单信息 | |||||
| * @throws WxErrorException 获取失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.getOrder.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| WxMaExpressOrderInfoResult getOrder(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException; | |||||
| /** | |||||
| * 查询运单轨迹 | |||||
| * @param wxMaExpressGetOrderRequest 运单信息请求对象 | |||||
| * @return 运单轨迹对象 | |||||
| * @throws WxErrorException 查询失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.getPath.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| WxMaExpressPath getPath(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException; | |||||
| /** | |||||
| * 模拟快递公司更新订单状态, 该接口只能用户测试 | |||||
| * @param wxMaExpressTestUpdateOrderRequest 模拟快递公司更新订单状态请求对象 | |||||
| * @throws WxErrorException 模拟更新订单状态失败时返回 | |||||
| * <pre> | |||||
| * <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/express/by-business/logistics.testUpdateOrder.html">查看文档</a> | |||||
| * </pre> | |||||
| */ | |||||
| void testUpdateOrder(WxMaExpressTestUpdateOrderRequest wxMaExpressTestUpdateOrderRequest) throws WxErrorException; | |||||
| } | |||||
| @@ -1,9 +1,7 @@ | |||||
| package cn.binarywang.wx.miniapp.api; | 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 cn.binarywang.wx.miniapp.bean.*; | |||||
| import com.google.gson.JsonObject; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||
| /** | /** | ||||
| @@ -18,6 +16,8 @@ public interface WxMaMsgService { | |||||
| String TEMPLATE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/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 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"; | String UNIFORM_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send"; | ||||
| String ACTIVITY_ID_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create"; | |||||
| String UPDATABLE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send"; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -25,6 +25,10 @@ public interface WxMaMsgService { | |||||
| * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/customerServiceMessage.send.html">发送客服消息</a> | * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/customerServiceMessage.send.html">发送客服消息</a> | ||||
| * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN | * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN | ||||
| * </pre> | * </pre> | ||||
| * | |||||
| * @param message 客服消息 | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| boolean sendKefuMsg(WxMaKefuMessage message) throws WxErrorException; | boolean sendKefuMsg(WxMaKefuMessage message) throws WxErrorException; | ||||
| @@ -33,26 +37,63 @@ public interface WxMaMsgService { | |||||
| * 发送模板消息 | * 发送模板消息 | ||||
| * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/templateMessage.send.html">发送模板消息</a> | * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/templateMessage.send.html">发送模板消息</a> | ||||
| * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN | * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN | ||||
| * 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能 | |||||
| * </pre> | * </pre> | ||||
| * | |||||
| * @param templateMessage 模版消息 | |||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| @Deprecated | |||||
| void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException; | void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException; | ||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 发送订阅消息 | |||||
| * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | ||||
| * </pre> | * </pre> | ||||
| * 发送订阅消息 | |||||
| * | |||||
| * @param subscribeMessage 订阅消息 | |||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException; | void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException; | ||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 下发小程序和公众号统一的服务消息 | * 下发小程序和公众号统一的服务消息 | ||||
| * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api/open-api/uniform-message/sendUniformMessage.html">下发小程序和公众号统一的服务消息</a> | * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api/open-api/uniform-message/sendUniformMessage.html">下发小程序和公众号统一的服务消息</a> | ||||
| * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN | * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN | ||||
| * </pre> | * </pre> | ||||
| * | |||||
| * @param uniformMessage 消息 | |||||
| * @throws WxErrorException . | |||||
| */ | */ | ||||
| void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorException; | void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorException; | ||||
| /** | |||||
| * <pre> | |||||
| * 创建被分享动态消息的 activity_id. | |||||
| * 动态消息: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share/updatable-message.html | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/updatable-message/updatableMessage.createActivityId.html | |||||
| * 接口地址:GET https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| JsonObject createUpdatableMessageActivityId() throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 修改被分享的动态消息. | |||||
| * 动态消息: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share/updatable-message.html | |||||
| * | |||||
| * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/updatable-message/updatableMessage.setUpdatableMsg.html | |||||
| * 接口地址:POST https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param msg 动态消息 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| void setUpdatableMsg(WxMaUpdatableMsg msg) throws WxErrorException; | |||||
| } | } | ||||
| @@ -32,6 +32,14 @@ public interface WxMaSecCheckService { | |||||
| */ | */ | ||||
| boolean checkImage(File file) throws WxErrorException; | boolean checkImage(File file) throws WxErrorException; | ||||
| /** | |||||
| * 校验一张图片是否含有违法违规内容 | |||||
| * @param fileUrl 文件网络地址 | |||||
| * @return 是否违规 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| boolean checkImage(String fileUrl) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * 检查一段文本是否含有违法违规内容。 | * 检查一段文本是否含有违法违规内容。 | ||||
| @@ -86,6 +86,11 @@ public interface WxMaService { | |||||
| */ | */ | ||||
| String post(String url, String postData) throws WxErrorException; | String post(String url, String postData) throws WxErrorException; | ||||
| /** | |||||
| * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求. | |||||
| */ | |||||
| String post(String url, Object obj) throws WxErrorException; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| * Service没有实现某个API的时候,可以用这个, | * Service没有实现某个API的时候,可以用这个, | ||||
| @@ -158,6 +163,13 @@ public interface WxMaService { | |||||
| */ | */ | ||||
| WxMaTemplateService getTemplateService(); | WxMaTemplateService getTemplateService(); | ||||
| /** | |||||
| * 返回订阅消息配置相关接口方法的实现类对象, 以方便调用其各个接口. | |||||
| * | |||||
| * @return WxMaSubscribeService | |||||
| */ | |||||
| WxMaSubscribeService getSubscribeService(); | |||||
| /** | /** | ||||
| * 数据分析相关查询服务. | * 数据分析相关查询服务. | ||||
| * | * | ||||
| @@ -224,5 +236,15 @@ public interface WxMaService { | |||||
| */ | */ | ||||
| RequestHttp getRequestHttp(); | RequestHttp getRequestHttp(); | ||||
| /** | |||||
| * 获取物流助手接口服务对象 | |||||
| * | |||||
| * @return | |||||
| */ | |||||
| WxMaExpressService getExpressService(); | |||||
| /** | |||||
| * 获取云开发接口服务对象 | |||||
| */ | |||||
| WxMaCloudService getCloudService(); | |||||
| } | } | ||||
| @@ -0,0 +1,153 @@ | |||||
| package cn.binarywang.wx.miniapp.api; | |||||
| import cn.binarywang.wx.miniapp.bean.template.WxMaPubTemplateTitleListResult; | |||||
| import lombok.Data; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 订阅消息类 | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2019-12-15 | |||||
| */ | |||||
| public interface WxMaSubscribeService { | |||||
| /** | |||||
| * 获取模板标题下的关键词列表. | |||||
| */ | |||||
| String GET_PUB_TEMPLATE_TITLE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles"; | |||||
| /** | |||||
| * 获取模板标题下的关键词列表. | |||||
| */ | |||||
| String GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords"; | |||||
| /** | |||||
| * 组合模板并添加至帐号下的个人模板库. | |||||
| */ | |||||
| String TEMPLATE_ADD_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate"; | |||||
| /** | |||||
| * 获取当前帐号下的个人模板列表. | |||||
| */ | |||||
| String TEMPLATE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate"; | |||||
| /** | |||||
| * 删除帐号下的某个模板. | |||||
| */ | |||||
| String TEMPLATE_DEL_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate"; | |||||
| /** | |||||
| * 获取小程序账号的类目 | |||||
| */ | |||||
| String GET_CATEGORY_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory"; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取帐号所属类目下的公共模板标题 | |||||
| * | |||||
| * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getPubTemplateTitleList.html">获取帐号所属类目下的公共模板标题</a> | |||||
| * 接口url格式: https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param ids 类目 id,多个用逗号隔开 | |||||
| * @param limit 用于分页,表示拉取 limit 条记录。最大为 30。 | |||||
| * @param start 用于分页,表示从 start 开始。从 0 开始计数。 | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| WxMaPubTemplateTitleListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取模板库某个模板标题下关键词库 | |||||
| * | |||||
| * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getPubTemplateKeyWordsById.html">获取模板标题下的关键词列表</a> | |||||
| * 接口url格式: GET https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param id 模板标题 id,可通过接口获取 | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| List<PubTemplateKeyword> getPubTemplateKeyWordsById(String id) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 组合模板并添加至帐号下的个人模板库 | |||||
| * | |||||
| * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.addTemplate.html">获取小程序模板库标题列表</a> | |||||
| * 接口url格式: POST https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param id 模板标题 id,可通过接口获取,也可登录小程序后台查看获取 | |||||
| * @param keywordIdList 模板关键词列表 | |||||
| * @param sceneDesc 服务场景描述,15个字以内 | |||||
| * @return 添加至帐号下的模板id,发送小程序订阅消息时所需 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| String addTemplate(String id, List<Integer> keywordIdList, String sceneDesc) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取当前帐号下的个人模板列表 | |||||
| * | |||||
| * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getTemplateList.html">获取当前帐号下的个人模板列表</a> | |||||
| * 接口url格式: GET https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| List<TemplateInfo> getTemplateList() throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 删除帐号下的某个模板 | |||||
| * | |||||
| * 详情请见: <a href="https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.deleteTemplate.html">删除帐号下的个人模板</a> | |||||
| * 接口url格式: POST https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @param templateId 要删除的模板id | |||||
| * @return 删除是否成功 | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| boolean delTemplate(String templateId) throws WxErrorException; | |||||
| /** | |||||
| * <pre> | |||||
| * 获取小程序账号的类目 | |||||
| * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getCategory.html | |||||
| * GET https://api.weixin.qq.com/wxaapi/newtmpl/getcategory?access_token=ACCESS_TOKEN | |||||
| * </pre> | |||||
| * | |||||
| * @return . | |||||
| * @throws WxErrorException . | |||||
| */ | |||||
| List<CategoryData> getCategory() throws WxErrorException; | |||||
| @Data | |||||
| class CategoryData { | |||||
| int id; | |||||
| String name; | |||||
| } | |||||
| @Data | |||||
| class TemplateInfo { | |||||
| private String priTmplId; | |||||
| private String title; | |||||
| private String content; | |||||
| private String example; | |||||
| private int type; | |||||
| } | |||||
| @Data | |||||
| class PubTemplateKeyword { | |||||
| private int kid; | |||||
| private String name; | |||||
| private String example; | |||||
| private String rule; | |||||
| } | |||||
| } | |||||
| @@ -8,6 +8,10 @@ import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import java.util.List; | import java.util.List; | ||||
| /** | |||||
| * @author IOMan(lewis.lynn1006@gmail.com) | |||||
| */ | |||||
| @Deprecated | |||||
| public interface WxMaTemplateService { | public interface WxMaTemplateService { | ||||
| /** | /** | ||||
| * 获取小程序模板库标题列表. | * 获取小程序模板库标题列表. | ||||
| @@ -0,0 +1,178 @@ | |||||
| package cn.binarywang.wx.miniapp.api.impl; | |||||
| import cn.binarywang.wx.miniapp.api.WxMaCloudService; | |||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
| import cn.binarywang.wx.miniapp.bean.cloud.*; | |||||
| import com.google.common.collect.ImmutableMap; | |||||
| import com.google.common.collect.Lists; | |||||
| import com.google.gson.JsonArray; | |||||
| import com.google.gson.JsonObject; | |||||
| import com.google.gson.JsonParser; | |||||
| import lombok.RequiredArgsConstructor; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
| import java.io.Serializable; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * 云开发相关接口实现类. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-22 | |||||
| */ | |||||
| @Slf4j | |||||
| @RequiredArgsConstructor | |||||
| public class WxMaCloudServiceImpl implements WxMaCloudService { | |||||
| private static final JsonParser JSON_PARSER = new JsonParser(); | |||||
| private final WxMaService wxMaService; | |||||
| @Override | |||||
| public String invokeCloudFunction(String env, String name, String body) throws WxErrorException { | |||||
| final String response = this.wxMaService.post(String.format(INVOKE_CLOUD_FUNCTION_URL, env, name), body); | |||||
| return JSON_PARSER.parse(response).getAsJsonObject().get("resp_data").getAsString(); | |||||
| } | |||||
| @Override | |||||
| public JsonArray databaseAdd(String env, String query) throws WxErrorException { | |||||
| String response = this.wxMaService.post(DATABASE_ADD_URL, ImmutableMap.of("env", env, "query", query)); | |||||
| return JSON_PARSER.parse(response).getAsJsonObject().get("id_list").getAsJsonArray(); | |||||
| } | |||||
| @Override | |||||
| public int databaseDelete(String env, String query) throws WxErrorException { | |||||
| String response = this.wxMaService.post(DATABASE_DELETE_URL, ImmutableMap.of("env", env, "query", query)); | |||||
| return JSON_PARSER.parse(response).getAsJsonObject().get("deleted").getAsInt(); | |||||
| } | |||||
| @Override | |||||
| public WxCloudDatabaseUpdateResult databaseUpdate(String env, String query) throws WxErrorException { | |||||
| String response = this.wxMaService.post(DATABASE_UPDATE_URL, ImmutableMap.of("env", env, "query", query)); | |||||
| return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseUpdateResult.class); | |||||
| } | |||||
| @Override | |||||
| public WxCloudDatabaseQueryResult databaseQuery(String env, String query) throws WxErrorException { | |||||
| String response = this.wxMaService.post(DATABASE_QUERY_URL, ImmutableMap.of("env", env, "query", query)); | |||||
| return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseQueryResult.class); | |||||
| } | |||||
| @Override | |||||
| public JsonArray databaseAggregate(String env, String query) throws WxErrorException { | |||||
| String response = this.wxMaService.post(DATABASE_AGGREGATE_URL, ImmutableMap.of("env", env, "query", query)); | |||||
| return JSON_PARSER.parse(response).getAsJsonObject().get("data").getAsJsonArray(); | |||||
| } | |||||
| @Override | |||||
| public Long databaseCount(String env, String query) throws WxErrorException { | |||||
| String response = this.wxMaService.post(DATABASE_COUNT_URL, ImmutableMap.of("env", env, "query", query)); | |||||
| return JSON_PARSER.parse(response).getAsJsonObject().get("count").getAsLong(); | |||||
| } | |||||
| @Override | |||||
| public void updateIndex(String env, String collectionName, List<WxCloudDatabaseCreateIndexRequest> createIndexes, | |||||
| List<String> dropIndexNames) throws WxErrorException { | |||||
| List<Map<String, String>> dropIndexes = Lists.newArrayList(); | |||||
| if (dropIndexNames != null) { | |||||
| for (String index : dropIndexNames) { | |||||
| dropIndexes.add(ImmutableMap.of("name", index)); | |||||
| } | |||||
| } | |||||
| this.wxMaService.post(UPDATE_INDEX_URL, ImmutableMap.of("env", env, | |||||
| "collection_name", collectionName, "create_indexes", createIndexes, "drop_indexes", dropIndexes)); | |||||
| } | |||||
| @Override | |||||
| public Long databaseMigrateImport(String env, String collectionName, String filePath, int fileType, | |||||
| boolean stopOnError, int conflictMode) throws WxErrorException { | |||||
| JsonObject params = new JsonObject(); | |||||
| params.addProperty("env", env); | |||||
| params.addProperty("collection_name", collectionName); | |||||
| params.addProperty("file_path", filePath); | |||||
| params.addProperty("file_type", fileType); | |||||
| params.addProperty("stop_on_error", stopOnError); | |||||
| params.addProperty("conflict_mode", conflictMode); | |||||
| String response = this.wxMaService.post(DATABASE_MIGRATE_IMPORT_URL, params.toString()); | |||||
| return JSON_PARSER.parse(response).getAsJsonObject().get("job_id").getAsLong(); | |||||
| } | |||||
| @Override | |||||
| public Long databaseMigrateExport(String env, String filePath, int fileType, String query) throws WxErrorException { | |||||
| JsonObject params = new JsonObject(); | |||||
| params.addProperty("env", env); | |||||
| params.addProperty("file_path", filePath); | |||||
| params.addProperty("file_type", fileType); | |||||
| params.addProperty("query", query); | |||||
| String response = this.wxMaService.post(DATABASE_MIGRATE_EXPORT_URL, params.toString()); | |||||
| return JSON_PARSER.parse(response).getAsJsonObject().get("job_id").getAsLong(); | |||||
| } | |||||
| @Override | |||||
| public WxCloudCloudDatabaseMigrateQueryInfoResult databaseMigrateQueryInfo(String env, Long jobId) throws WxErrorException { | |||||
| String response = this.wxMaService.post(DATABASE_MIGRATE_QUERY_INFO_URL, ImmutableMap.of("env", env, "job_id", jobId)); | |||||
| return WxGsonBuilder.create().fromJson(response, WxCloudCloudDatabaseMigrateQueryInfoResult.class); | |||||
| } | |||||
| @Override | |||||
| public WxCloudUploadFileResult uploadFile(String env, String path) throws WxErrorException { | |||||
| String response = this.wxMaService.post(UPLOAD_FILE_URL, ImmutableMap.of("env", env, "path", path)); | |||||
| return WxGsonBuilder.create().fromJson(response, WxCloudUploadFileResult.class); | |||||
| } | |||||
| @Override | |||||
| public WxCloudBatchDownloadFileResult batchDownloadFile(String env, String[] fileIds, long[] maxAges) throws WxErrorException { | |||||
| List<Map<String, Serializable>> fileList = Lists.newArrayList(); | |||||
| int i = 0; | |||||
| for (String fileId : fileIds) { | |||||
| fileList.add(ImmutableMap.of("fileid", fileId, "max_age", (Serializable) maxAges[i++])); | |||||
| } | |||||
| String response = this.wxMaService.post(GET_QCLOUD_TOKEN_URL, ImmutableMap.of("env", env, "file_list", fileList)); | |||||
| return WxGsonBuilder.create().fromJson(response, WxCloudBatchDownloadFileResult.class); | |||||
| } | |||||
| @Override | |||||
| public WxCloudBatchDeleteFileResult batchDeleteFile(String env, String[] fileIds) throws WxErrorException { | |||||
| String response = this.wxMaService.post(BATCH_DELETE_FILE_URL, ImmutableMap.of("env", env, "fileid_list", fileIds)); | |||||
| return WxGsonBuilder.create().fromJson(response, WxCloudBatchDeleteFileResult.class); | |||||
| } | |||||
| @Override | |||||
| public WxCloudGetQcloudTokenResult getQcloudToken(long lifeSpan) throws WxErrorException { | |||||
| String response = this.wxMaService.post(GET_QCLOUD_TOKEN_URL, ImmutableMap.of("lifespan", lifeSpan)); | |||||
| return WxGsonBuilder.create().fromJson(response, WxCloudGetQcloudTokenResult.class); | |||||
| } | |||||
| @Override | |||||
| public void databaseCollectionAdd(String env, String collectionName) throws WxErrorException { | |||||
| this.wxMaService.post(DATABASE_COLLECTION_ADD_URL, ImmutableMap.of("env", env, "collection_name", collectionName)); | |||||
| } | |||||
| @Override | |||||
| public void databaseCollectionDelete(String env, String collectionName) throws WxErrorException { | |||||
| this.wxMaService.post(DATABASE_COLLECTION_DELETE_URL, ImmutableMap.of("env", env, "collection_name", collectionName)); | |||||
| } | |||||
| @Override | |||||
| public WxCloudDatabaseCollectionGetResult databaseCollectionGet(String env, Long limit, Long offset) throws WxErrorException { | |||||
| Map<String, Object> params = new HashMap<>(2); | |||||
| params.put("env", env); | |||||
| if (limit != null) { | |||||
| params.put("limit", limit); | |||||
| } | |||||
| if (offset != null) { | |||||
| params.put("offset", offset); | |||||
| } | |||||
| String response = this.wxMaService.post(DATABASE_COLLECTION_GET_URL, params); | |||||
| return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseCollectionGetResult.class); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,98 @@ | |||||
| package cn.binarywang.wx.miniapp.api.impl; | |||||
| import cn.binarywang.wx.miniapp.api.WxMaExpressService; | |||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
| import cn.binarywang.wx.miniapp.bean.express.WxMaExpressAccount; | |||||
| import cn.binarywang.wx.miniapp.bean.express.WxMaExpressDelivery; | |||||
| import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPath; | |||||
| import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPrinter; | |||||
| import cn.binarywang.wx.miniapp.bean.express.request.*; | |||||
| import cn.binarywang.wx.miniapp.bean.express.result.WxMaExpressOrderInfoResult; | |||||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||||
| import lombok.AllArgsConstructor; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import java.util.HashMap; | |||||
| import java.util.List; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * @author <a href="https://github.com/mr-xiaoyu">xiaoyu</a> | |||||
| * @since 2019-11-26 | |||||
| */ | |||||
| @AllArgsConstructor | |||||
| public class WxMaExpressServiceImpl implements WxMaExpressService { | |||||
| private WxMaService wxMaService; | |||||
| @Override | |||||
| public List<WxMaExpressDelivery> getAllDelivery() throws WxErrorException { | |||||
| String responseContent = this.wxMaService.get(ALL_DELIVERY_URL, null); | |||||
| return WxMaExpressDelivery.fromJson(responseContent); | |||||
| } | |||||
| @Override | |||||
| public List<WxMaExpressAccount> getAllAccount() throws WxErrorException { | |||||
| String responseContent = this.wxMaService.get(ALL_ACCOUNT_URL, null); | |||||
| return WxMaExpressAccount.fromJsonList(responseContent); | |||||
| } | |||||
| @Override | |||||
| public void bindAccount(WxMaExpressBindAccountRequest wxMaExpressBindAccountRequest) throws WxErrorException { | |||||
| this.wxMaService.post(BIND_ACCOUNT_URL,wxMaExpressBindAccountRequest.toJson()); | |||||
| } | |||||
| @Override | |||||
| public Integer getQuota(WxMaExpressBindAccountRequest wxMaExpressBindAccountRequest) throws WxErrorException { | |||||
| String responseContent = this.wxMaService.post(GET_QUOTA_URL,wxMaExpressBindAccountRequest.toJson()); | |||||
| WxMaExpressAccount account = WxMaExpressAccount.fromJson(responseContent); | |||||
| return account.getQuotaNum(); | |||||
| } | |||||
| @Override | |||||
| public void updatePrinter(WxMaExpressPrinterUpdateRequest wxMaExpressPrinterUpdateRequest) throws WxErrorException { | |||||
| this.wxMaService.post(UPDATE_PRINTER_URL,wxMaExpressPrinterUpdateRequest.toJson()); | |||||
| } | |||||
| @Override | |||||
| public WxMaExpressPrinter getPrinter() throws WxErrorException { | |||||
| String responseContent = this.wxMaService.get(GET_PRINTER_URL, null); | |||||
| return WxMaExpressPrinter.fromJson(responseContent); | |||||
| } | |||||
| @Override | |||||
| public WxMaExpressOrderInfoResult addOrder(WxMaExpressAddOrderRequest wxMaExpressAddOrderRequest) throws WxErrorException { | |||||
| String responseContent = this.wxMaService.post(ADD_ORDER_URL,wxMaExpressAddOrderRequest.toJson()); | |||||
| return WxMaExpressOrderInfoResult.fromJson(responseContent); | |||||
| } | |||||
| @Override | |||||
| public List<WxMaExpressOrderInfoResult> batchGetOrder(List<WxMaExpressGetOrderRequest> requests) throws WxErrorException { | |||||
| Map<String, Object> param = new HashMap<>(1); | |||||
| param.put("order_list", requests); | |||||
| String responseContent = this.wxMaService.post(BATCH_GET_ORDER_URL, WxMaGsonBuilder.create().toJson(param)); | |||||
| return WxMaExpressOrderInfoResult.toList(responseContent); | |||||
| } | |||||
| @Override | |||||
| public void cancelOrder(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException { | |||||
| this.wxMaService.post(CANCEL_ORDER_URL,wxMaExpressGetOrderRequest.toJson()); | |||||
| } | |||||
| @Override | |||||
| public WxMaExpressOrderInfoResult getOrder(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException { | |||||
| String responseContent = this.wxMaService.post(GET_ORDER_URL,wxMaExpressGetOrderRequest.toJson()); | |||||
| return WxMaExpressOrderInfoResult.fromJson(responseContent); | |||||
| } | |||||
| @Override | |||||
| public WxMaExpressPath getPath(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException { | |||||
| String responseContent = this.wxMaService.post(GET_PATH_URL,wxMaExpressGetOrderRequest.toJson()); | |||||
| return WxMaExpressPath.fromJson(responseContent); | |||||
| } | |||||
| @Override | |||||
| public void testUpdateOrder(WxMaExpressTestUpdateOrderRequest wxMaExpressTestUpdateOrderRequest) throws WxErrorException { | |||||
| this.wxMaService.post(TEST_UPDATE_ORDER_URL,wxMaExpressTestUpdateOrderRequest.toJson()); | |||||
| } | |||||
| } | |||||
| @@ -51,7 +51,7 @@ public class WxMaJsapiServiceImpl implements WxMaJsapiService { | |||||
| } finally { | } finally { | ||||
| lock.unlock(); | lock.unlock(); | ||||
| } | } | ||||
| return this.wxMaService.getWxMaConfig().getJsapiTicket(); | |||||
| return this.wxMaService.getWxMaConfig().getCardApiTicket(); | |||||
| } | } | ||||
| @Override | @Override | ||||
| @@ -2,11 +2,9 @@ package cn.binarywang.wx.miniapp.api.impl; | |||||
| import cn.binarywang.wx.miniapp.api.WxMaMsgService; | import cn.binarywang.wx.miniapp.api.WxMaMsgService; | ||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | 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.bean.*; | |||||
| import cn.binarywang.wx.miniapp.constant.WxMaConstants; | import cn.binarywang.wx.miniapp.constant.WxMaConstants; | ||||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
| import com.google.gson.JsonParser; | import com.google.gson.JsonParser; | ||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
| @@ -28,11 +26,6 @@ public class WxMaMsgServiceImpl implements WxMaMsgService { | |||||
| return responseContent != null; | return responseContent != null; | ||||
| } | } | ||||
| /** | |||||
| * <pre> | |||||
| * 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能 | |||||
| * </pre> | |||||
| */ | |||||
| @Override | @Override | ||||
| public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { | public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { | ||||
| String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); | String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); | ||||
| @@ -60,4 +53,15 @@ public class WxMaMsgServiceImpl implements WxMaMsgService { | |||||
| } | } | ||||
| } | } | ||||
| @Override | |||||
| public JsonObject createUpdatableMessageActivityId() throws WxErrorException { | |||||
| final String responseContent = this.wxMaService.get(ACTIVITY_ID_CREATE_URL, null); | |||||
| return JSON_PARSER.parse(responseContent).getAsJsonObject(); | |||||
| } | |||||
| @Override | |||||
| public void setUpdatableMsg(WxMaUpdatableMsg msg) throws WxErrorException { | |||||
| this.wxMaService.post(UPDATABLE_MSG_SEND_URL, WxMaGsonBuilder.create().toJson(msg)); | |||||
| } | |||||
| } | } | ||||
| @@ -4,11 +4,16 @@ import cn.binarywang.wx.miniapp.api.WxMaSecCheckService; | |||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||
| import cn.binarywang.wx.miniapp.bean.WxMaMediaAsyncCheckResult; | import cn.binarywang.wx.miniapp.bean.WxMaMediaAsyncCheckResult; | ||||
| import com.google.gson.JsonObject; | import com.google.gson.JsonObject; | ||||
| import java.io.File; | |||||
| import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | 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.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
| import org.apache.commons.io.FileUtils; | |||||
| import java.io.File; | |||||
| import java.io.IOException; | |||||
| import java.net.URL; | |||||
| /** | /** | ||||
| * <pre> | * <pre> | ||||
| @@ -20,17 +25,28 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | |||||
| */ | */ | ||||
| @AllArgsConstructor | @AllArgsConstructor | ||||
| public class WxMaSecCheckServiceImpl implements WxMaSecCheckService { | public class WxMaSecCheckServiceImpl implements WxMaSecCheckService { | ||||
| private WxMaService service; | private WxMaService service; | ||||
| @Override | @Override | ||||
| public boolean checkImage(File file) throws WxErrorException { | public boolean checkImage(File file) throws WxErrorException { | ||||
| //这里只是借用MediaUploadRequestExecutor,并不使用其返回值WxMediaUploadResult | |||||
| WxMediaUploadResult result = this.service.execute(MediaUploadRequestExecutor | WxMediaUploadResult result = this.service.execute(MediaUploadRequestExecutor | ||||
| .create(this.service.getRequestHttp()), IMG_SEC_CHECK_URL, file); | .create(this.service.getRequestHttp()), IMG_SEC_CHECK_URL, file); | ||||
| return result != null; | return result != null; | ||||
| } | } | ||||
| @Override | |||||
| public boolean checkImage(String fileUrl) throws WxErrorException { | |||||
| File file = new File(FileUtils.getTempDirectory(), System.currentTimeMillis() + ".tmp"); | |||||
| try { | |||||
| URL url = new URL(fileUrl); | |||||
| FileUtils.copyURLToFile(url, file); | |||||
| } catch (IOException e) { | |||||
| throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件地址读取异常").build(), e); | |||||
| } | |||||
| return this.checkImage(file); | |||||
| } | |||||
| @Override | @Override | ||||
| public boolean checkMessage(String msgString) throws WxErrorException { | public boolean checkMessage(String msgString) throws WxErrorException { | ||||
| JsonObject jsonObject = new JsonObject(); | JsonObject jsonObject = new JsonObject(); | ||||
| @@ -16,6 +16,7 @@ import me.chanjar.weixin.common.util.crypto.SHA1; | |||||
| import me.chanjar.weixin.common.util.http.*; | import me.chanjar.weixin.common.util.http.*; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; | ||||
| import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; | ||||
| import me.chanjar.weixin.common.util.json.WxGsonBuilder; | |||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.http.HttpHost; | import org.apache.http.HttpHost; | ||||
| import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
| @@ -54,6 +55,9 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
| private WxMaRunService runService = new WxMaRunServiceImpl(this); | private WxMaRunService runService = new WxMaRunServiceImpl(this); | ||||
| private WxMaSecCheckService secCheckService = new WxMaSecCheckServiceImpl(this); | private WxMaSecCheckService secCheckService = new WxMaSecCheckServiceImpl(this); | ||||
| private WxMaPluginService pluginService = new WxMaPluginServiceImpl(this); | private WxMaPluginService pluginService = new WxMaPluginServiceImpl(this); | ||||
| private WxMaExpressService expressService = new WxMaExpressServiceImpl(this); | |||||
| private WxMaSubscribeService subscribeService = new WxMaSubscribeServiceImpl(this); | |||||
| private WxMaCloudService cloudService = new WxMaCloudServiceImpl(this); | |||||
| private int retrySleepMillis = 1000; | private int retrySleepMillis = 1000; | ||||
| private int maxRetryTimes = 5; | private int maxRetryTimes = 5; | ||||
| @@ -204,6 +208,11 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
| return execute(SimplePostRequestExecutor.create(this), url, postData); | return execute(SimplePostRequestExecutor.create(this), url, postData); | ||||
| } | } | ||||
| @Override | |||||
| public String post(String url, Object obj) throws WxErrorException { | |||||
| return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj)); | |||||
| } | |||||
| /** | /** | ||||
| * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 | ||||
| */ | */ | ||||
| @@ -326,6 +335,11 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
| return this.templateService; | return this.templateService; | ||||
| } | } | ||||
| @Override | |||||
| public WxMaSubscribeService getSubscribeService() { | |||||
| return this.subscribeService; | |||||
| } | |||||
| @Override | @Override | ||||
| public WxMaAnalysisService getAnalysisService() { | public WxMaAnalysisService getAnalysisService() { | ||||
| return this.analysisService; | return this.analysisService; | ||||
| @@ -365,4 +379,14 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||
| public WxMaPluginService getPluginService() { | public WxMaPluginService getPluginService() { | ||||
| return this.pluginService; | return this.pluginService; | ||||
| } | } | ||||
| @Override | |||||
| public WxMaExpressService getExpressService() { | |||||
| return this.expressService; | |||||
| } | |||||
| @Override | |||||
| public WxMaCloudService getCloudService() { | |||||
| return this.cloudService; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,73 @@ | |||||
| package cn.binarywang.wx.miniapp.api.impl; | |||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
| import cn.binarywang.wx.miniapp.api.WxMaSubscribeService; | |||||
| import cn.binarywang.wx.miniapp.bean.template.WxMaPubTemplateTitleListResult; | |||||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | |||||
| import com.google.common.base.Joiner; | |||||
| import com.google.common.collect.ImmutableMap; | |||||
| 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.StringUtils; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2019-12-15 | |||||
| */ | |||||
| @AllArgsConstructor | |||||
| public class WxMaSubscribeServiceImpl implements WxMaSubscribeService { | |||||
| private WxMaService wxMaService; | |||||
| @Override | |||||
| public WxMaPubTemplateTitleListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException { | |||||
| ImmutableMap<String, ? extends Serializable> params = ImmutableMap.of("ids", StringUtils.join(ids, ","), | |||||
| "start", start, "limit", limit); | |||||
| String responseText = this.wxMaService.get(GET_PUB_TEMPLATE_TITLE_LIST_URL, | |||||
| Joiner.on("&").withKeyValueSeparator("=").join(params)); | |||||
| return WxMaPubTemplateTitleListResult.fromJson(responseText); | |||||
| } | |||||
| @Override | |||||
| public List<PubTemplateKeyword> getPubTemplateKeyWordsById(String id) throws WxErrorException { | |||||
| String responseText = this.wxMaService.get(GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL, | |||||
| Joiner.on("&").withKeyValueSeparator("=").join(ImmutableMap.of("tid", id))); | |||||
| return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() | |||||
| .getAsJsonArray("data"), new TypeToken<List<PubTemplateKeyword>>() { | |||||
| }.getType()); | |||||
| } | |||||
| @Override | |||||
| public String addTemplate(String id, List<Integer> keywordIdList, String sceneDesc) throws WxErrorException { | |||||
| String responseText = this.wxMaService.post(TEMPLATE_ADD_URL, ImmutableMap.of("tid", id, | |||||
| "kidList", keywordIdList.toArray(), | |||||
| "sceneDesc", sceneDesc)); | |||||
| return new JsonParser().parse(responseText).getAsJsonObject().get("priTmplId").getAsString(); | |||||
| } | |||||
| @Override | |||||
| public List<TemplateInfo> getTemplateList() throws WxErrorException { | |||||
| String responseText = this.wxMaService.get(TEMPLATE_LIST_URL, null); | |||||
| return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() | |||||
| .getAsJsonArray("data"), new TypeToken<List<TemplateInfo>>() { | |||||
| }.getType()); | |||||
| } | |||||
| @Override | |||||
| public boolean delTemplate(String templateId) throws WxErrorException { | |||||
| this.wxMaService.post(TEMPLATE_DEL_URL, ImmutableMap.of("priTmplId", templateId)); | |||||
| return true; | |||||
| } | |||||
| @Override | |||||
| public List<CategoryData> getCategory() throws WxErrorException { | |||||
| String responseText = this.wxMaService.get(GET_CATEGORY_URL, null); | |||||
| return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() | |||||
| .getAsJsonArray("data"), new TypeToken<List<CategoryData>>() { | |||||
| }.getType()); | |||||
| } | |||||
| } | |||||
| @@ -2,10 +2,15 @@ package cn.binarywang.wx.miniapp.bean; | |||||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
| import com.google.gson.annotations.SerializedName; | import com.google.gson.annotations.SerializedName; | ||||
| import lombok.Data; | |||||
| import java.io.Serializable; | import java.io.Serializable; | ||||
| /** | |||||
| * @author borisbao | |||||
| */ | |||||
| @Data | |||||
| public class WxMaMediaAsyncCheckResult implements Serializable { | public class WxMaMediaAsyncCheckResult implements Serializable { | ||||
| private static final long serialVersionUID = 3928132365399916183L; | private static final long serialVersionUID = 3928132365399916183L; | ||||
| /** | /** | ||||
| @@ -1,12 +1,5 @@ | |||||
| package cn.binarywang.wx.miniapp.bean; | package cn.binarywang.wx.miniapp.bean; | ||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.Serializable; | |||||
| import java.nio.charset.StandardCharsets; | |||||
| import org.apache.commons.io.IOUtils; | |||||
| import cn.binarywang.wx.miniapp.config.WxMaConfig; | import cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||
| import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; | import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils; | ||||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
| @@ -16,6 +9,12 @@ import com.thoughtworks.xstream.annotations.XStreamAlias; | |||||
| import com.thoughtworks.xstream.annotations.XStreamConverter; | import com.thoughtworks.xstream.annotations.XStreamConverter; | ||||
| import lombok.Data; | import lombok.Data; | ||||
| import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; | ||||
| import org.apache.commons.io.IOUtils; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.io.Serializable; | |||||
| import java.nio.charset.StandardCharsets; | |||||
| /** | /** | ||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||
| @@ -108,6 +107,34 @@ public class WxMaMessage implements Serializable { | |||||
| @XStreamConverter(value = XStreamCDataConverter.class) | @XStreamConverter(value = XStreamCDataConverter.class) | ||||
| private String sessionFrom; | private String sessionFrom; | ||||
| /** | |||||
| * 以下是异步校验图片/音频是否含有违法违规内容的异步检测结果推送报文中的参数 | |||||
| */ | |||||
| @SerializedName("isrisky") | |||||
| @XStreamAlias("isrisky") | |||||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||||
| private String isRisky; | |||||
| @SerializedName("extra_info_json") | |||||
| @XStreamAlias("extra_info_json") | |||||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||||
| private String extraInfoJson; | |||||
| @SerializedName("appid") | |||||
| @XStreamAlias("appid") | |||||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||||
| private String appid; | |||||
| @SerializedName("trace_id") | |||||
| @XStreamAlias("trace_id") | |||||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||||
| private String traceId; | |||||
| @SerializedName("status_code") | |||||
| @XStreamAlias("status_code") | |||||
| @XStreamConverter(value = XStreamCDataConverter.class) | |||||
| private String statusCode; | |||||
| public static WxMaMessage fromXml(String xml) { | public static WxMaMessage fromXml(String xml) { | ||||
| return XStreamTransformer.fromXml(WxMaMessage.class, xml); | return XStreamTransformer.fromXml(WxMaMessage.class, xml); | ||||
| } | } | ||||
| @@ -1,30 +0,0 @@ | |||||
| package cn.binarywang.wx.miniapp.bean; | |||||
| import lombok.Data; | |||||
| import lombok.NoArgsConstructor; | |||||
| /** | |||||
| * <pre> | |||||
| * 参考文档 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | |||||
| * </pre> | |||||
| */ | |||||
| @Data | |||||
| @NoArgsConstructor | |||||
| public class WxMaSubscribeData { | |||||
| private String name; | |||||
| private String value; | |||||
| private String color; | |||||
| public WxMaSubscribeData(String name, String value) { | |||||
| this.name = name; | |||||
| this.value = value; | |||||
| } | |||||
| public WxMaSubscribeData(String name, String value, String color) { | |||||
| this.name = name; | |||||
| this.value = value; | |||||
| this.color = color; | |||||
| } | |||||
| } | |||||
| @@ -1,5 +1,6 @@ | |||||
| package cn.binarywang.wx.miniapp.bean; | package cn.binarywang.wx.miniapp.bean; | ||||
| import cn.binarywang.wx.miniapp.constant.WxMaConstants; | |||||
| import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; | ||||
| import lombok.*; | import lombok.*; | ||||
| @@ -10,6 +11,8 @@ import java.util.List; | |||||
| /** | /** | ||||
| * 订阅消息. | * 订阅消息. | ||||
| * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html | ||||
| * | |||||
| * @author S | |||||
| */ | */ | ||||
| @Getter | @Getter | ||||
| @Setter | @Setter | ||||
| @@ -17,7 +20,6 @@ import java.util.List; | |||||
| @AllArgsConstructor | @AllArgsConstructor | ||||
| @Builder | @Builder | ||||
| public class WxMaSubscribeMessage implements Serializable { | public class WxMaSubscribeMessage implements Serializable { | ||||
| private static final long serialVersionUID = 6846729898251286686L; | private static final long serialVersionUID = 6846729898251286686L; | ||||
| /** | /** | ||||
| @@ -58,13 +60,23 @@ public class WxMaSubscribeMessage implements Serializable { | |||||
| * 描述: 模板内容,不填则下发空模板 | * 描述: 模板内容,不填则下发空模板 | ||||
| * </pre> | * </pre> | ||||
| */ | */ | ||||
| private List<WxMaSubscribeData> data; | |||||
| private List<Data> data; | |||||
| /** | |||||
| * 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 | |||||
| */ | |||||
| private String miniprogramState = WxMaConstants.MiniprogramState.FORMAL; | |||||
| /** | |||||
| * 进入小程序查看的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN | |||||
| */ | |||||
| private String lang = WxMaConstants.MiniprogramLang.ZH_CN; | |||||
| public WxMaSubscribeMessage addData(WxMaSubscribeData datum) { | |||||
| public WxMaSubscribeMessage addData(Data datum) { | |||||
| if (this.data == null) { | if (this.data == null) { | ||||
| this.data = new ArrayList<>(); | this.data = new ArrayList<>(); | ||||
| } | } | ||||
| this.data.add(datum); | this.data.add(datum); | ||||
| return this; | return this; | ||||
| @@ -74,4 +86,14 @@ public class WxMaSubscribeMessage implements Serializable { | |||||
| return WxMaGsonBuilder.create().toJson(this); | return WxMaGsonBuilder.create().toJson(this); | ||||
| } | } | ||||
| @lombok.Data | |||||
| @NoArgsConstructor | |||||
| @AllArgsConstructor | |||||
| public static class Data implements Serializable { | |||||
| private static final long serialVersionUID = 1L; | |||||
| private String name; | |||||
| private String value; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,76 @@ | |||||
| package cn.binarywang.wx.miniapp.bean; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import lombok.experimental.Accessors; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 动态消息. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-02-17 | |||||
| */ | |||||
| @Data | |||||
| @Accessors(chain = true) | |||||
| public class WxMaUpdatableMsg implements Serializable { | |||||
| private static final long serialVersionUID = 6231957192034798165L; | |||||
| /** | |||||
| * 动态消息的 ID,通过 updatableMessage.createActivityId 接口获取 | |||||
| */ | |||||
| @SerializedName("activity_id") | |||||
| private String activityId; | |||||
| /** | |||||
| * 动态消息修改后的状态 | |||||
| * 0 未开始 | |||||
| * 1 已开始 | |||||
| */ | |||||
| @SerializedName("target_state") | |||||
| private Integer targetState; | |||||
| /** | |||||
| * 动态消息对应的模板信息 | |||||
| */ | |||||
| @SerializedName("template_info") | |||||
| private TemplateInfo templateInfo; | |||||
| @Data | |||||
| @Accessors(chain = true) | |||||
| public static class TemplateInfo implements Serializable { | |||||
| private static final long serialVersionUID = -9218473401759062841L; | |||||
| /** | |||||
| * 模板中需要修改的参数 | |||||
| */ | |||||
| @SerializedName("parameter_list") | |||||
| private List<Parameter> parameterList; | |||||
| } | |||||
| @Data | |||||
| @Accessors(chain = true) | |||||
| public static class Parameter implements Serializable { | |||||
| private static final long serialVersionUID = 7444716050341038046L; | |||||
| /** | |||||
| * 要修改的参数名 | |||||
| * <pre> | |||||
| * 合法值: | |||||
| * member_count target_state = 0 时必填,文字内容模板中 member_count 的值 | |||||
| * room_limit target_state = 0 时必填,文字内容模板中 room_limit 的值 | |||||
| * path target_state = 1 时必填,点击「进入」启动小程序时使用的路径。对于小游戏,没有页面的概念,可以用于传递查询字符串(query),如 "?foo=bar" | |||||
| * version_type target_state = 1 时必填,点击「进入」启动小程序时使用的版本。 | |||||
| * 有效参数值为:develop(开发版),trial(体验版),release(正式版) | |||||
| * </pre> | |||||
| */ | |||||
| private String name; | |||||
| /** | |||||
| * 修改后的参数值 | |||||
| */ | |||||
| private String value; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,44 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 文件删除结果. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-27 | |||||
| */ | |||||
| @Data | |||||
| public class WxCloudBatchDeleteFileResult implements Serializable { | |||||
| private static final long serialVersionUID = -1133274298839868115L; | |||||
| @SerializedName("delete_list") | |||||
| private List<FileDownloadInfo> fileList; | |||||
| @Data | |||||
| public static class FileDownloadInfo implements Serializable { | |||||
| private static final long serialVersionUID = 5812969045277862211L; | |||||
| /** | |||||
| * fileid string 文件ID | |||||
| */ | |||||
| @SerializedName("fileid") | |||||
| private String fileId; | |||||
| /** | |||||
| * status number 状态码 | |||||
| */ | |||||
| @SerializedName("status") | |||||
| private Integer status; | |||||
| /** | |||||
| * errmsg string 该文件错误信息 | |||||
| */ | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,50 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 获取文件下载链接结果. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-27 | |||||
| */ | |||||
| @Data | |||||
| public class WxCloudBatchDownloadFileResult implements Serializable { | |||||
| private static final long serialVersionUID = 646423661372964402L; | |||||
| @SerializedName("file_list") | |||||
| private List<FileDownloadInfo> fileList; | |||||
| @Data | |||||
| public static class FileDownloadInfo implements Serializable { | |||||
| private static final long serialVersionUID = 5812969045277862211L; | |||||
| /** | |||||
| * fileid string 文件ID | |||||
| */ | |||||
| @SerializedName("fileid") | |||||
| private String fileId; | |||||
| /** | |||||
| * download_url string 下载链接 | |||||
| */ | |||||
| @SerializedName("download_url") | |||||
| private String downloadUrl; | |||||
| /** | |||||
| * status number 状态码 | |||||
| */ | |||||
| @SerializedName("status") | |||||
| private Integer status; | |||||
| /** | |||||
| * errmsg string 该文件错误信息 | |||||
| */ | |||||
| @SerializedName("errmsg") | |||||
| private String errMsg; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,47 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 云开发数据库迁移状态查询结果. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-26 | |||||
| */ | |||||
| @Data | |||||
| public class WxCloudCloudDatabaseMigrateQueryInfoResult implements Serializable { | |||||
| private static final long serialVersionUID = 2014197503355968243L; | |||||
| /** | |||||
| * status string 导出状态 | |||||
| */ | |||||
| private String status; | |||||
| /** | |||||
| * record_success number 导出成功记录数 | |||||
| */ | |||||
| @SerializedName("record_success") | |||||
| private Integer recordSuccess; | |||||
| /** | |||||
| * record_fail number 导出失败记录数 | |||||
| */ | |||||
| @SerializedName("record_fail") | |||||
| private Integer recordFail; | |||||
| /** | |||||
| * err_msg string 导出错误信息 | |||||
| */ | |||||
| @SerializedName("err_msg") | |||||
| private String errMsg; | |||||
| /** | |||||
| * file_url string 导出文件下载地址 | |||||
| */ | |||||
| @SerializedName("file_url") | |||||
| private String fileUrl; | |||||
| } | |||||
| @@ -0,0 +1,86 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 云开发获取集合接口的结果. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-28 | |||||
| */ | |||||
| @Data | |||||
| public class WxCloudDatabaseCollectionGetResult implements Serializable { | |||||
| private static final long serialVersionUID = 3702855196387039823L; | |||||
| /** | |||||
| * 分页信息 | |||||
| */ | |||||
| private WxCloudDatabaseQueryResult.Pager pager; | |||||
| /** | |||||
| * 查询结果 | |||||
| */ | |||||
| private CollectionInfo[] collections; | |||||
| @Data | |||||
| public static class CollectionInfo implements Serializable { | |||||
| private static final long serialVersionUID = -3280126948752330438L; | |||||
| /** | |||||
| * name string 集合名 | |||||
| */ | |||||
| @SerializedName("name") | |||||
| private String name; | |||||
| /** | |||||
| * count number 表中文档数量 | |||||
| */ | |||||
| @SerializedName("count") | |||||
| private Long count; | |||||
| /** | |||||
| * size number 表的大小(即表中文档总大小),单位:字节 | |||||
| */ | |||||
| @SerializedName("size") | |||||
| private Long size; | |||||
| /** | |||||
| * index_count number 索引数量 | |||||
| */ | |||||
| @SerializedName("index_count") | |||||
| private Long indexCount; | |||||
| /** | |||||
| * index_size number 索引占用大小,单位:字节 | |||||
| */ | |||||
| @SerializedName("index_size") | |||||
| private Long indexSize; | |||||
| } | |||||
| @Data | |||||
| public static class Pager implements Serializable { | |||||
| private static final long serialVersionUID = 5045727687673687839L; | |||||
| /** | |||||
| * Offset number 偏移 | |||||
| */ | |||||
| @SerializedName("Offset") | |||||
| private Long offset; | |||||
| /** | |||||
| * Limit number 单次查询限制 | |||||
| */ | |||||
| @SerializedName("Limit") | |||||
| private Long limit; | |||||
| /** | |||||
| * Total number 符合查询条件的记录总数 | |||||
| */ | |||||
| @SerializedName("Total") | |||||
| private Long total; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,59 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import lombok.Builder; | |||||
| import lombok.Data; | |||||
| import lombok.experimental.Accessors; | |||||
| import java.io.Serializable; | |||||
| import java.util.List; | |||||
| /** | |||||
| * 云开发新增索引的请求对象. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-26 | |||||
| */ | |||||
| @Accessors(chain = true) | |||||
| @Data | |||||
| public class WxCloudDatabaseCreateIndexRequest implements Serializable { | |||||
| private static final long serialVersionUID = -8308393731157121109L; | |||||
| /** | |||||
| * name string 是 索引名 | |||||
| */ | |||||
| private String name; | |||||
| /** | |||||
| * unique boolean 是 是否唯一 | |||||
| */ | |||||
| private boolean unique; | |||||
| /** | |||||
| * keys Array.<Object> 是 索引字段 | |||||
| */ | |||||
| private List<IndexKey> keys; | |||||
| @Data | |||||
| @Accessors(chain = true) | |||||
| public static class IndexKey implements Serializable { | |||||
| private static final long serialVersionUID = -252641130547960325L; | |||||
| /** | |||||
| * name string 是 字段名 | |||||
| */ | |||||
| private String name; | |||||
| /** | |||||
| * direction string 是 字段排序 | |||||
| * <pre> | |||||
| * direction 的合法值 | |||||
| * 值 说明 | |||||
| * "1" 升序 | |||||
| * "-1" 降序 | |||||
| * "2dsphere" 地理位置 | |||||
| * | |||||
| * </pre> | |||||
| */ | |||||
| private String direction; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,51 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 云开发数据库查询记录接口请求结果. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-26 | |||||
| */ | |||||
| @Data | |||||
| public class WxCloudDatabaseQueryResult implements Serializable { | |||||
| private static final long serialVersionUID = 8291820029137872536L; | |||||
| /** | |||||
| * 分页信息 | |||||
| */ | |||||
| private Pager pager; | |||||
| /** | |||||
| * 查询结果 | |||||
| */ | |||||
| private String[] data; | |||||
| @Data | |||||
| public static class Pager implements Serializable{ | |||||
| private static final long serialVersionUID = 8556239063823985674L; | |||||
| /** | |||||
| * Offset number 偏移 | |||||
| */ | |||||
| @SerializedName("Offset") | |||||
| private Long offset; | |||||
| /** | |||||
| * Limit number 单次查询限制 | |||||
| */ | |||||
| @SerializedName("Limit") | |||||
| private Long limit; | |||||
| /** | |||||
| * Total number 符合查询条件的记录总数 | |||||
| */ | |||||
| @SerializedName("Total") | |||||
| private Long total; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,32 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 云开发数据库更新记录接口请求结果. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-26 | |||||
| */ | |||||
| @Data | |||||
| public class WxCloudDatabaseUpdateResult implements Serializable { | |||||
| private static final long serialVersionUID = -3905429931117999004L; | |||||
| /** | |||||
| * matched number 更新条件匹配到的结果数 | |||||
| */ | |||||
| private Long matched; | |||||
| /** | |||||
| * modified number 修改的记录数,注意:使用set操作新插入的数据不计入修改数目 | |||||
| */ | |||||
| private Long modified; | |||||
| /** | |||||
| * id string 新插入记录的id,注意:只有使用set操作新插入数据时这个字段会有值 | |||||
| */ | |||||
| private String id; | |||||
| } | |||||
| @@ -0,0 +1,41 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 获取腾讯云API调用凭证结果. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-27 | |||||
| */ | |||||
| @Data | |||||
| public class WxCloudGetQcloudTokenResult implements Serializable { | |||||
| private static final long serialVersionUID = -1505786395531138286L; | |||||
| /** | |||||
| * secretid | |||||
| */ | |||||
| @SerializedName("secretid") | |||||
| private String secretId; | |||||
| /** | |||||
| * secretkey | |||||
| */ | |||||
| @SerializedName("secretkey") | |||||
| private String secretKey; | |||||
| /** | |||||
| * token | |||||
| */ | |||||
| @SerializedName("token") | |||||
| private String token; | |||||
| /** | |||||
| * 过期时间戳 | |||||
| */ | |||||
| @SerializedName("expired_time") | |||||
| private Long expiredTime; | |||||
| } | |||||
| @@ -0,0 +1,47 @@ | |||||
| package cn.binarywang.wx.miniapp.bean.cloud; | |||||
| import com.google.gson.annotations.SerializedName; | |||||
| import lombok.Data; | |||||
| import java.io.Serializable; | |||||
| /** | |||||
| * 云开发文件上传接口响应结果. | |||||
| * | |||||
| * @author <a href="https://github.com/binarywang">Binary Wang</a> | |||||
| * @date 2020-01-27 | |||||
| */ | |||||
| @Data | |||||
| public class WxCloudUploadFileResult implements Serializable { | |||||
| private static final long serialVersionUID = 787346474470048318L; | |||||
| /** | |||||
| * 上传url | |||||
| */ | |||||
| @SerializedName("url") | |||||
| private String url; | |||||
| /** | |||||
| * token | |||||
| */ | |||||
| @SerializedName("token") | |||||
| private String token; | |||||
| /** | |||||
| * authorization | |||||
| */ | |||||
| @SerializedName("authorization") | |||||
| private String authorization; | |||||
| /** | |||||
| * 文件ID | |||||
| */ | |||||
| @SerializedName("file_id") | |||||
| private String fileId; | |||||
| /** | |||||
| * cos文件ID | |||||
| */ | |||||
| @SerializedName("cos_file_id") | |||||
| private String cosFileId; | |||||
| } | |||||