| @@ -13,8 +13,8 @@ | |||
| <artifactId>mallinkAdmin</artifactId> | |||
| <properties> | |||
| <weixin-java-mp.version>3.3.0.A</weixin-java-mp.version> | |||
| <weixin-java-open.version>3.3.0.A</weixin-java-open.version> | |||
| <weixin-java-mp.version>3.3.0</weixin-java-mp.version> | |||
| <weixin-java-open.version>3.3.0</weixin-java-open.version> | |||
| </properties> | |||
| <dependencies> | |||
| @@ -1,61 +0,0 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | |||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||
| <modelVersion>4.0.0</modelVersion> | |||
| <parent> | |||
| <artifactId>mallink</artifactId> | |||
| <groupId>com.iformall</groupId> | |||
| <version>1.0</version> | |||
| </parent> | |||
| <artifactId>mallinkWechatOpen</artifactId> | |||
| <properties> | |||
| <weixin-java-mp.version>3.3.0.A</weixin-java-mp.version> | |||
| <weixin-java-open.version>3.3.0.A</weixin-java-open.version> | |||
| </properties> | |||
| <dependencies> | |||
| <dependency> | |||
| <groupId>com.iformall</groupId> | |||
| <artifactId>mallinkService</artifactId> | |||
| <version>1.0</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>weixin-java-open</artifactId> | |||
| <version>${weixin-java-open.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.github.binarywang</groupId> | |||
| <artifactId>weixin-java-mp</artifactId> | |||
| <version>${weixin-java-mp.version}</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.google.zxing</groupId> | |||
| <artifactId>core</artifactId> | |||
| <version>3.3.3</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>com.github.axet</groupId> | |||
| <artifactId>kaptcha</artifactId> | |||
| <version>0.0.9</version> | |||
| </dependency> | |||
| </dependencies> | |||
| <build> | |||
| <plugins> | |||
| <plugin> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-maven-plugin</artifactId> | |||
| <configuration> | |||
| <executable>true</executable> | |||
| </configuration> | |||
| </plugin> | |||
| </plugins> | |||
| </build> | |||
| </project> | |||
| @@ -1,41 +0,0 @@ | |||
| package com.iformall; | |||
| import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties; | |||
| import io.swagger.models.auth.In; | |||
| import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.boot.SpringApplication; | |||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | |||
| import org.springframework.context.annotation.Bean; | |||
| import springfox.documentation.swagger2.annotations.EnableSwagger2; | |||
| import tk.mybatis.spring.annotation.MapperScan; | |||
| /** | |||
| * @author stormeye | |||
| * @date 2019-01-14 | |||
| */ | |||
| @SpringBootApplication | |||
| @MapperScan(basePackages = {"com.iformall.mapper"}) | |||
| @EnableSwagger2 | |||
| @EnableEncryptableProperties | |||
| public class WechatOpenApplication { | |||
| @Value("${fm.exception}") | |||
| private boolean fmException; | |||
| @Bean | |||
| public boolean isFmException() { | |||
| return fmException; | |||
| } | |||
| @Value("${fm.delay}") | |||
| private Integer fmDelay; | |||
| @Bean | |||
| public Integer getFmDelay() { return fmDelay; } | |||
| public static void main(String[] args) { | |||
| SpringApplication.run(WechatOpenApplication.class, args); | |||
| } | |||
| } | |||
| @@ -1,52 +0,0 @@ | |||
| package com.iformall.config; | |||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||
| import org.springframework.stereotype.Component; | |||
| /** | |||
| * @author Stormeye | |||
| */ | |||
| @Component | |||
| @ConfigurationProperties(prefix = "aws") | |||
| public class AwsProperty { | |||
| // AWS ACCESS KEY | |||
| private String access; | |||
| private String secret; | |||
| private String clientRegion; | |||
| private String bucketName; | |||
| public String getAccess() { | |||
| return access; | |||
| } | |||
| public void setAccess(String access) { | |||
| this.access = access; | |||
| } | |||
| public String getSecret() { | |||
| return secret; | |||
| } | |||
| public void setSecret(String secret) { | |||
| this.secret = secret; | |||
| } | |||
| public String getClientRegion() { | |||
| return clientRegion; | |||
| } | |||
| public void setClientRegion(String clientRegion) { | |||
| this.clientRegion = clientRegion; | |||
| } | |||
| public String getBucketName() { | |||
| return bucketName; | |||
| } | |||
| public void setBucketName(String bucketName) { | |||
| this.bucketName = bucketName; | |||
| } | |||
| } | |||
| @@ -1,32 +0,0 @@ | |||
| package com.iformall.config; | |||
| import com.google.code.kaptcha.impl.DefaultKaptcha; | |||
| import com.google.code.kaptcha.util.Config; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import java.util.Properties; | |||
| /** | |||
| * 生成验证码配置 | |||
| * | |||
| * @author stormeye.wu | |||
| * @email wugq@mippoint.com | |||
| * @date 2017-04-20 19:22 | |||
| */ | |||
| @Configuration | |||
| public class KaptchaConfig { | |||
| @Bean | |||
| public DefaultKaptcha producer() { | |||
| Properties properties = new Properties(); | |||
| properties.put("kaptcha.border", "no"); | |||
| properties.put("kaptcha.textproducer.font.color", "black"); | |||
| properties.put("kaptcha.textproducer.char.space", "5"); | |||
| Config config = new Config(properties); | |||
| DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); | |||
| defaultKaptcha.setConfig(config); | |||
| return defaultKaptcha; | |||
| } | |||
| } | |||
| @@ -1,129 +0,0 @@ | |||
| package com.iformall.config; | |||
| import com.iformall.domain.po.PushLimit; | |||
| import com.iformall.domain.po.WxCUser; | |||
| import com.iformall.domain.po.WxScoreRules; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.cache.CacheManager; | |||
| import org.springframework.cache.annotation.CachingConfigurerSupport; | |||
| import org.springframework.cache.annotation.EnableCaching; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import org.springframework.data.redis.cache.RedisCacheConfiguration; | |||
| import org.springframework.data.redis.cache.RedisCacheManager; | |||
| import org.springframework.data.redis.connection.RedisConnectionFactory; | |||
| import org.springframework.data.redis.core.RedisTemplate; | |||
| import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; | |||
| import org.springframework.data.redis.serializer.StringRedisSerializer; | |||
| import java.time.Duration; | |||
| import java.util.HashMap; | |||
| import java.util.HashSet; | |||
| import java.util.Map; | |||
| import java.util.Set; | |||
| /** | |||
| * Created by Stormeye on 2018/10/1. | |||
| */ | |||
| @Configuration | |||
| @EnableCaching | |||
| public class RedisConfig extends CachingConfigurerSupport { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| //缓存管理器 | |||
| @Bean | |||
| public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { | |||
| /* | |||
| //user信息缓存配置 | |||
| RedisCacheConfiguration userCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(10)).disableCachingNullValues().prefixKeysWith("user"); | |||
| Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>(); | |||
| redisCacheConfigurationMap.put("user", userCacheConfiguration); | |||
| //初始化一个RedisCacheWriter | |||
| RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory); | |||
| // 设置CacheManager的值序列化方式为JdkSerializationRedisSerializer,但其实RedisCacheConfiguration默认就是使用StringRedisSerializer序列化key,JdkSerializationRedisSerializer序列化value,所以以下注释代码为默认实现 | |||
| // ClassLoader loader = this.getClass().getClassLoader(); | |||
| // JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer(loader); | |||
| // RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jdkSerializer); | |||
| // RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair); | |||
| RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig(); | |||
| //设置默认超过期时间是30秒 | |||
| defaultCacheConfig.entryTtl(Duration.ofSeconds(30)); | |||
| //初始化RedisCacheManager | |||
| RedisCacheManager cacheManager = new RedisCacheManager(redisCacheWriter, defaultCacheConfig, redisCacheConfigurationMap); | |||
| return cacheManager; | |||
| */ | |||
| RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig(); // 生成一个默认配置,通过config对象即可对缓存进行自定义配置 | |||
| config = config.entryTtl(Duration.ofMinutes(1)) // 设置缓存的默认过期时间,也是使用Duration设置 | |||
| .disableCachingNullValues(); // 不缓存空值 | |||
| // 设置一个初始化的缓存空间set集合 | |||
| Set<String> cacheNames = new HashSet<>(); | |||
| cacheNames.add("my-redis-cache1"); | |||
| cacheNames.add("my-redis-cache2"); | |||
| // 对每个缓存空间应用不同的配置 | |||
| Map<String, RedisCacheConfiguration> configMap = new HashMap<>(); | |||
| configMap.put("my-redis-cache1", config); | |||
| configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(120))); | |||
| RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory) // 使用自定义的缓存配置初始化一个cacheManager | |||
| .initialCacheNames(cacheNames) // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置 | |||
| .withInitialCacheConfigurations(configMap) | |||
| .build(); | |||
| return cacheManager; | |||
| } | |||
| @Bean("pushLimitRedisTemplate") | |||
| public RedisTemplate<String, PushLimit> getPushLimitRedisTemplate(RedisConnectionFactory connectionFactory) { | |||
| RedisTemplate<String, PushLimit> template = new RedisTemplate<String, PushLimit>(); | |||
| Jackson2JsonRedisSerializer<PushLimit> j = new Jackson2JsonRedisSerializer<PushLimit>(PushLimit.class); | |||
| // value值的序列化 | |||
| template.setValueSerializer(j); | |||
| template.setHashKeySerializer(j); | |||
| // key的序列化 | |||
| template.setKeySerializer(new StringRedisSerializer()); | |||
| template.setHashKeySerializer(new StringRedisSerializer()); | |||
| template.setConnectionFactory(connectionFactory); | |||
| return template; | |||
| } | |||
| @Bean("scoreRuleRedisTemplate") | |||
| public RedisTemplate<String, WxScoreRules> getScoreRuleRedisTemplate(RedisConnectionFactory connectionFactory) { | |||
| RedisTemplate<String, WxScoreRules> template = new RedisTemplate<String, WxScoreRules>(); | |||
| Jackson2JsonRedisSerializer<WxScoreRules> j = new Jackson2JsonRedisSerializer<WxScoreRules>(WxScoreRules.class); | |||
| // value值的序列化 | |||
| template.setValueSerializer(j); | |||
| template.setHashKeySerializer(j); | |||
| // key的序列化 | |||
| template.setKeySerializer(new StringRedisSerializer()); | |||
| template.setHashKeySerializer(new StringRedisSerializer()); | |||
| template.setConnectionFactory(connectionFactory); | |||
| return template; | |||
| } | |||
| @Bean("cuserTokenRedisTemplate") | |||
| public RedisTemplate<String, WxCUser> getCUserTokenRedisTemplate(RedisConnectionFactory connectionFactory) { | |||
| RedisTemplate<String, WxCUser> template = new RedisTemplate<String, WxCUser>(); | |||
| Jackson2JsonRedisSerializer<WxCUser> j = new Jackson2JsonRedisSerializer<WxCUser>(WxCUser.class); | |||
| // value值的序列化 | |||
| template.setValueSerializer(j); | |||
| template.setHashKeySerializer(j); | |||
| // key的序列化 | |||
| template.setKeySerializer(new StringRedisSerializer()); | |||
| template.setHashKeySerializer(new StringRedisSerializer()); | |||
| template.setConnectionFactory(connectionFactory); | |||
| return template; | |||
| } | |||
| } | |||
| @@ -1,124 +0,0 @@ | |||
| package com.iformall.config; | |||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||
| import redis.clients.jedis.JedisPoolConfig; | |||
| import redis.clients.jedis.Protocol; | |||
| import javax.net.ssl.HostnameVerifier; | |||
| import javax.net.ssl.SSLParameters; | |||
| import javax.net.ssl.SSLSocketFactory; | |||
| /** | |||
| * Stormeye | |||
| */ | |||
| @ConfigurationProperties(prefix = "wechat.redis") | |||
| public class RedisProperies extends JedisPoolConfig { | |||
| private String host = Protocol.DEFAULT_HOST; | |||
| private int port = Protocol.DEFAULT_PORT; | |||
| private String password; | |||
| private int database = 1; | |||
| private int connectionTimeout = Protocol.DEFAULT_TIMEOUT; | |||
| private int soTimeout = Protocol.DEFAULT_TIMEOUT; | |||
| private String clientName; | |||
| private boolean ssl; | |||
| private SSLSocketFactory sslSocketFactory; | |||
| private SSLParameters sslParameters; | |||
| private HostnameVerifier hostnameVerifier; | |||
| public boolean isSsl() { | |||
| return ssl; | |||
| } | |||
| public void setSsl(boolean ssl) { | |||
| this.ssl = ssl; | |||
| } | |||
| public SSLSocketFactory getSslSocketFactory() { | |||
| return sslSocketFactory; | |||
| } | |||
| public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) { | |||
| this.sslSocketFactory = sslSocketFactory; | |||
| } | |||
| public SSLParameters getSslParameters() { | |||
| return sslParameters; | |||
| } | |||
| public void setSslParameters(SSLParameters sslParameters) { | |||
| this.sslParameters = sslParameters; | |||
| } | |||
| public HostnameVerifier getHostnameVerifier() { | |||
| return hostnameVerifier; | |||
| } | |||
| public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { | |||
| this.hostnameVerifier = hostnameVerifier; | |||
| } | |||
| public String getHost() { | |||
| return host; | |||
| } | |||
| public void setHost(String host) { | |||
| if (host == null || "".equals(host)) { | |||
| host = Protocol.DEFAULT_HOST; | |||
| } | |||
| this.host = host; | |||
| } | |||
| public int getPort() { | |||
| return port; | |||
| } | |||
| public void setPort(int port) { | |||
| this.port = port; | |||
| } | |||
| public String getPassword() { | |||
| return password; | |||
| } | |||
| public void setPassword(String password) { | |||
| if ("".equals(password)) { | |||
| password = null; | |||
| } | |||
| this.password = password; | |||
| } | |||
| public int getDatabase() { | |||
| return database; | |||
| } | |||
| public void setDatabase(int database) { | |||
| this.database = database; | |||
| } | |||
| public String getClientName() { | |||
| return clientName; | |||
| } | |||
| public void setClientName(String clientName) { | |||
| if ("".equals(clientName)) { | |||
| clientName = null; | |||
| } | |||
| this.clientName = clientName; | |||
| } | |||
| public int getConnectionTimeout() { | |||
| return connectionTimeout; | |||
| } | |||
| public void setConnectionTimeout(int connectionTimeout) { | |||
| this.connectionTimeout = connectionTimeout; | |||
| } | |||
| public int getSoTimeout() { | |||
| return soTimeout; | |||
| } | |||
| public void setSoTimeout(int soTimeout) { | |||
| this.soTimeout = soTimeout; | |||
| } | |||
| } | |||
| @@ -1,58 +0,0 @@ | |||
| package com.iformall.config; | |||
| import java.io.IOException; | |||
| import java.util.Optional; | |||
| import javax.servlet.Filter; | |||
| import javax.servlet.FilterChain; | |||
| import javax.servlet.FilterConfig; | |||
| import javax.servlet.ServletException; | |||
| import javax.servlet.ServletRequest; | |||
| import javax.servlet.ServletResponse; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| /** | |||
| * 前后端分离RESTful接口过滤器 | |||
| * | |||
| * @author xuguoqin | |||
| * | |||
| */ | |||
| public class RestFilter implements Filter { | |||
| @Override | |||
| public void init(FilterConfig filterConfig) throws ServletException { | |||
| } | |||
| @Override | |||
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | |||
| throws IOException, ServletException { | |||
| HttpServletRequest req = null; | |||
| if (request instanceof HttpServletRequest) { | |||
| req = (HttpServletRequest) request; | |||
| } | |||
| HttpServletResponse res = null; | |||
| if (response instanceof HttpServletResponse) { | |||
| res = (HttpServletResponse) response; | |||
| } | |||
| if (req != null && res != null) { | |||
| //设置允许传递的参数 | |||
| res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization"); | |||
| //设置允许带上cookie | |||
| res.setHeader("Access-Control-Allow-Credentials", "true"); | |||
| String origin = Optional.ofNullable(req.getHeader("Origin")).orElse(req.getHeader("Referer")); | |||
| //设置允许的请求来源 | |||
| res.setHeader("Access-Control-Allow-Origin", origin); | |||
| //设置允许的请求方法 | |||
| res.setHeader("Access-Control-Allow-Methods", "GET, POST, PATCH, PUT, DELETE, OPTIONS"); | |||
| } | |||
| chain.doFilter(request, response); | |||
| } | |||
| @Override | |||
| public void destroy() { | |||
| } | |||
| } | |||
| @@ -1,24 +0,0 @@ | |||
| package com.iformall.config; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import org.springframework.http.client.ClientHttpRequestFactory; | |||
| import org.springframework.http.client.SimpleClientHttpRequestFactory; | |||
| import org.springframework.web.client.RestTemplate; | |||
| @Configuration | |||
| public class RestTemplateConfig { | |||
| @Bean | |||
| public RestTemplate restTemplate(ClientHttpRequestFactory factory) { | |||
| return new RestTemplate(factory); | |||
| } | |||
| @Bean | |||
| public ClientHttpRequestFactory simpleClientHttpRequestFactory() { | |||
| SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); | |||
| factory.setReadTimeout(5000);//ms | |||
| factory.setConnectTimeout(10000);//ms | |||
| return factory; | |||
| } | |||
| } | |||
| @@ -1,303 +0,0 @@ | |||
| package com.iformall.config; | |||
| import com.iformall.service.MallPermissionService; | |||
| import com.iformall.shiro.MyRetryLimitCredentialsMatcher; | |||
| import com.iformall.shiro.MyShiroRealm; | |||
| import org.apache.shiro.mgt.SecurityManager; | |||
| import org.apache.shiro.spring.LifecycleBeanPostProcessor; | |||
| import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor; | |||
| import org.apache.shiro.spring.web.ShiroFilterFactoryBean; | |||
| import org.apache.shiro.web.mgt.DefaultWebSecurityManager; | |||
| import org.apache.shiro.web.servlet.SimpleCookie; | |||
| import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; | |||
| import org.crazycake.shiro.RedisCacheManager; | |||
| import org.crazycake.shiro.RedisManager; | |||
| import org.crazycake.shiro.RedisSessionDAO; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.beans.factory.annotation.Qualifier; | |||
| import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.context.annotation.Bean; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import javax.servlet.Filter; | |||
| import javax.servlet.ServletRequest; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import java.util.LinkedHashMap; | |||
| import java.util.Map; | |||
| /** | |||
| * Created by yangqj on 2017/4/23. | |||
| */ | |||
| @Configuration | |||
| public class ShiroConfig { | |||
| @Autowired(required = false) | |||
| private MallPermissionService resourcesService; | |||
| @Value("${spring.redis.host}") | |||
| private String host; | |||
| @Value("${spring.redis.port}") | |||
| private int port; | |||
| @Value("${spring.redis.timeout}") | |||
| private int timeout; | |||
| @Value("${spring.redis.expire}") | |||
| private int expire; | |||
| @Value("${spring.redis.password}") | |||
| private String password; | |||
| @Bean | |||
| public static LifecycleBeanPostProcessor getLifecycleBeanPostProcessor() { | |||
| return new LifecycleBeanPostProcessor(); | |||
| } | |||
| /** | |||
| * ShiroDialect,为了在thymeleaf里使用shiro的标签的bean | |||
| * @return | |||
| */ | |||
| // @Bean | |||
| // public ShiroDialect shiroDialect() { | |||
| // return new ShiroDialect(); | |||
| // } | |||
| /** | |||
| * ShiroFilterFactoryBean 处理拦截资源文件问题。 | |||
| * 注意:单独一个ShiroFilterFactoryBean配置是或报错的,因为在 | |||
| * 初始化ShiroFilterFactoryBean的时候需要注入:SecurityManager | |||
| * <p> | |||
| * Filter Chain定义说明 | |||
| * 1、一个URL可以配置多个Filter,使用逗号分隔 | |||
| * 2、当设置多个过滤器时,全部验证通过,才视为通过 | |||
| * 3、部分过滤器可指定参数,如perms,roles | |||
| */ | |||
| @Bean | |||
| public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) { | |||
| System.out.println("ShiroConfiguration.shirFilter()"); | |||
| ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); | |||
| // 必须设置 SecurityManager | |||
| shiroFilterFactoryBean.setSecurityManager(securityManager); | |||
| Map<String, Filter> filters = new LinkedHashMap<String, Filter>(); | |||
| filters.put("token", new ShiroLoginFilter()); | |||
| filters.put("corsFilter", new RestFilter()); | |||
| //filters.put("authc", new MyFormAuthenticationFilter()); | |||
| shiroFilterFactoryBean.setFilters(filters); | |||
| // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面 | |||
| shiroFilterFactoryBean.setLoginUrl("/#/"); | |||
| // 登录成功后要跳转的链接 | |||
| shiroFilterFactoryBean.setSuccessUrl("/usersPage"); | |||
| //未授权界面; | |||
| shiroFilterFactoryBean.setUnauthorizedUrl("/403"); | |||
| //拦截器. | |||
| Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); | |||
| //配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了 | |||
| //filterChainDefinitionMap.put("/ue/**", "anon"); | |||
| //filterChainDefinitionMap.put("/config.json", "anon"); | |||
| // 静态文件 | |||
| filterChainDefinitionMap.put("/css/**", "anon"); | |||
| filterChainDefinitionMap.put("/js/**", "anon"); | |||
| filterChainDefinitionMap.put("/img/**", "anon"); | |||
| filterChainDefinitionMap.put("/font-awesome/**", "anon"); | |||
| //<!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了; | |||
| //<!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问--> | |||
| //自定义加载权限资源关系 | |||
| // Map<String,Object> map = new HashMap<>(); | |||
| // List<SysPermission> resourcesList = resourcesService.list(map); | |||
| // for(SysPermission resources:resourcesList){ | |||
| // | |||
| // if (StringUtil.isNotEmpty(resources.getUrl())) { | |||
| // String permission = "perms[" + resources.getUrl()+ "]"; | |||
| // filterChainDefinitionMap.put(resources.getUrl(),permission); | |||
| // } | |||
| // } | |||
| // 登录 | |||
| filterChainDefinitionMap.put("/captcha.jpg", "anon"); | |||
| filterChainDefinitionMap.put("/doLogin/**", "anon"); | |||
| filterChainDefinitionMap.put("/version", "anon"); | |||
| /// swagger-ui.html | |||
| filterChainDefinitionMap.put("/swagger-ui.html", "anon"); | |||
| filterChainDefinitionMap.put("/v2/**", "anon"); | |||
| filterChainDefinitionMap.put("/swagger-resources/**", "anon"); | |||
| filterChainDefinitionMap.put("/webjars/**", "anon"); | |||
| // 第三方平台 | |||
| filterChainDefinitionMap.put("/wxOpen/**", "anon"); | |||
| // filterChainDefinitionMap.put("/role/**", "corsFilter,token"); | |||
| filterChainDefinitionMap.put("/**", "corsFilter,token,authc"); | |||
| // filterChainDefinitionMap.put("/**", "anon"); | |||
| shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); | |||
| return shiroFilterFactoryBean; | |||
| } | |||
| public static boolean isAjax(ServletRequest request) { | |||
| String header = ((HttpServletRequest) request).getHeader("X-Requested-With"); | |||
| if ("XMLHttpRequest".equalsIgnoreCase(header)) { | |||
| System.out.println("当前请求为Ajax请求"); | |||
| return Boolean.TRUE; | |||
| } | |||
| System.out.println("当前请求非Ajax请求"); | |||
| return Boolean.FALSE; | |||
| } | |||
| @Bean | |||
| public SecurityManager securityManager(@Qualifier("myRetryLimitCredentialsMatcher") MyRetryLimitCredentialsMatcher matcher) { | |||
| DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); | |||
| //设置realm. | |||
| securityManager.setRealm(myShiroRealm(matcher)); | |||
| // 自定义缓存实现 使用redis | |||
| //securityManager.setCacheManager(cacheManager()); | |||
| // 自定义session管理 使用redis | |||
| securityManager.setSessionManager(sessionManager()); | |||
| return securityManager; | |||
| } | |||
| @Bean | |||
| public MyShiroRealm myShiroRealm(MyRetryLimitCredentialsMatcher matcher) { | |||
| MyShiroRealm myShiroRealm = new MyShiroRealm(); | |||
| myShiroRealm.setCredentialsMatcher(matcher); | |||
| return myShiroRealm; | |||
| } | |||
| /** | |||
| * 密码匹配凭证管理器 凭证匹配器 | |||
| * (由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了 | |||
| * 所以我们需要修改下doGetAuthenticationInfo中的代码; | |||
| * ) | |||
| * | |||
| * @return | |||
| */ | |||
| @Bean(name = "myRetryLimitCredentialsMatcher") | |||
| public MyRetryLimitCredentialsMatcher hashedCredentialsMatcher() { | |||
| MyRetryLimitCredentialsMatcher hashedCredentialsMatcher = new MyRetryLimitCredentialsMatcher(); | |||
| hashedCredentialsMatcher.setHashAlgorithmName("md5");//散列算法:这里使用MD5算法; | |||
| hashedCredentialsMatcher.setHashIterations(2);//散列的次数,比如散列两次,相当于 md5(md5("")); | |||
| return hashedCredentialsMatcher; | |||
| } | |||
| /** | |||
| * 开启shiro aop注解支持. | |||
| * 使用代理方式;所以需要开启代码支持; | |||
| * | |||
| * @param securityManager | |||
| * @return | |||
| */ | |||
| @Bean | |||
| public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { | |||
| AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); | |||
| authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); | |||
| return authorizationAttributeSourceAdvisor; | |||
| } | |||
| /** | |||
| * 配置shiro redisManager | |||
| * 使用的是shiro-redis开源插件 | |||
| * | |||
| * @return | |||
| */ | |||
| public RedisManager redisManager() { | |||
| RedisManager redisManager = new RedisManager(); | |||
| redisManager.setHost(host); | |||
| redisManager.setPort(port); | |||
| //redisManager.setExpire(expire);// 配置缓存过期时间 | |||
| redisManager.setTimeout(timeout); | |||
| redisManager.setPassword(password); | |||
| return redisManager; | |||
| } | |||
| /** | |||
| * cacheManager 缓存 redis实现 | |||
| * 使用的是shiro-redis开源插件 | |||
| * | |||
| * @return | |||
| */ | |||
| public RedisCacheManager cacheManager() { | |||
| RedisCacheManager redisCacheManager = new RedisCacheManager(); | |||
| redisCacheManager.setRedisManager(redisManager()); | |||
| return redisCacheManager; | |||
| } | |||
| /** | |||
| * RedisSessionDAO shiro sessionDao层的实现 通过redis | |||
| * 使用的是shiro-redis开源插件 | |||
| */ | |||
| @Bean | |||
| public RedisSessionDAO redisSessionDAO() { | |||
| RedisSessionDAO redisSessionDAO = new RedisSessionDAO(); | |||
| redisSessionDAO.setRedisManager(redisManager()); | |||
| return redisSessionDAO; | |||
| } | |||
| /** | |||
| * shiro session的管理 | |||
| */ | |||
| @Bean | |||
| public DefaultWebSessionManager sessionManager() { | |||
| DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); | |||
| //设置session过期时间为1小时(单位:毫秒),默认为30分钟 | |||
| sessionManager.setGlobalSessionTimeout(60 * 60 * 1000); | |||
| sessionManager.setSessionValidationSchedulerEnabled(true); | |||
| sessionManager.setSessionIdUrlRewritingEnabled(false); | |||
| sessionManager.setSessionDAO(redisSessionDAO()); | |||
| sessionManager.setSessionIdCookie(simpleCookie()); | |||
| return sessionManager; | |||
| } | |||
| @Bean | |||
| public SimpleCookie simpleCookie() { | |||
| SimpleCookie simpleCookie = new SimpleCookie("SSID"); | |||
| simpleCookie.setDomain(""); | |||
| return simpleCookie; | |||
| } | |||
| // @Bean | |||
| // public SimpleCookie rememberMeCookie(){ | |||
| // //System.out.println("ShiroConfiguration.rememberMeCookie()"); | |||
| // //这个参数是cookie的名称,对应前端的checkbox的name = rememberMe | |||
| // SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); | |||
| // //<!-- 记住我cookie生效时间30天 ,单位秒;--> | |||
| // simpleCookie.setMaxAge(60*30); | |||
| // return simpleCookie; | |||
| // } | |||
| // @Bean | |||
| // public CookieRememberMeManager rememberMeManager(){ | |||
| // //System.out.println("ShiroConfiguration.rememberMeManager()"); | |||
| // CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); | |||
| // cookieRememberMeManager.setCookie(rememberMeCookie()); | |||
| // //rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位) | |||
| // cookieRememberMeManager.setCipherKey(Base64.decodeBytes("2AvVhdsgUs0FSA3SDFAdag==")); | |||
| // return cookieRememberMeManager; | |||
| // } | |||
| // @Bean(name = "securityManager") | |||
| // public DefaultWebSecurityManager defaultWebSecurityManager(MyShiroRealm realm){ | |||
| // DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); | |||
| // //设置realm | |||
| // securityManager.setRealm(realm); | |||
| // //用户授权/认证信息Cache, 采用EhCache缓存 | |||
| // securityManager.setCacheManager(cacheManager()); | |||
| // //注入记住我管理器 | |||
| // securityManager.setRememberMeManager(rememberMeManager()); | |||
| // return securityManager; | |||
| // } | |||
| } | |||
| @@ -1,31 +0,0 @@ | |||
| package com.iformall.config; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.iformall.common.ResultData; | |||
| import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; | |||
| import javax.servlet.ServletRequest; | |||
| import javax.servlet.ServletResponse; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| public class ShiroLoginFilter extends FormAuthenticationFilter { | |||
| @Override | |||
| protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { | |||
| response.setCharacterEncoding("UTF-8"); | |||
| response.setContentType("application/json"); | |||
| ResultData resultData = new ResultData(ResultData.UNLOGIN,"用户未登录"); | |||
| response.getWriter().write(JSON.toJSONString(resultData)); | |||
| return false; | |||
| } | |||
| /** | |||
| * 判断ajax请求 | |||
| * @param request | |||
| * @return | |||
| */ | |||
| boolean isAjax(HttpServletRequest request){ | |||
| return (request.getHeader("X-Requested-With") != null && "XMLHttpRequest".equals( request.getHeader("X-Requested-With").toString()) ) ; | |||
| } | |||
| } | |||
| @@ -1,79 +0,0 @@ | |||
| package com.iformall.config; | |||
| import com.fasterxml.jackson.annotation.JsonInclude; | |||
| import com.fasterxml.jackson.databind.DeserializationConfig; | |||
| import com.fasterxml.jackson.databind.DeserializationFeature; | |||
| import com.fasterxml.jackson.databind.ObjectMapper; | |||
| import com.fasterxml.jackson.databind.module.SimpleModule; | |||
| import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import org.springframework.http.converter.HttpMessageConverter; | |||
| import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; | |||
| import org.springframework.web.servlet.config.annotation.CorsRegistry; | |||
| import org.springframework.web.servlet.config.annotation.EnableWebMvc; | |||
| import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; | |||
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | |||
| import java.math.BigDecimal; | |||
| import java.math.BigInteger; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.List; | |||
| @Configuration | |||
| @EnableWebMvc | |||
| public class WebConfig implements WebMvcConfigurer { | |||
| @Override | |||
| public void addResourceHandlers(ResourceHandlerRegistry registry) { | |||
| registry.addResourceHandler("swagger-ui.html") | |||
| .addResourceLocations("classpath:/META-INF/resources/"); | |||
| registry.addResourceHandler("/webjars/**") | |||
| .addResourceLocations("classpath:/META-INF/resources/webjars/"); | |||
| //registry.addResourceHandler("/app/**").addResourceLocations("classpath:/app/"); | |||
| } | |||
| @Override | |||
| public void addCorsMappings(CorsRegistry registry) { | |||
| registry.addMapping("/**") | |||
| .allowedOrigins("*") | |||
| .allowCredentials(true) | |||
| .allowedMethods("GET", "POST", "DELETE", "PUT") | |||
| .maxAge(3600); | |||
| } | |||
| @Override | |||
| public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { | |||
| MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); | |||
| //ObjectMapper 是Jackson库的主要类。它提供一些功能将转换成Java对象匹配JSON结构,反之亦然 | |||
| ObjectMapper objectMapper = new ObjectMapper(); | |||
| SimpleModule simpleModule = new SimpleModule(); | |||
| //不显示为null的字段 | |||
| objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); | |||
| DeserializationConfig dc = objectMapper.getDeserializationConfig(); | |||
| // 设置反序列化日期格式、忽略不存在get、set的属性 | |||
| objectMapper.setConfig( | |||
| dc.with(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")) | |||
| .without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) | |||
| ); | |||
| //序列化将Long转String类型 | |||
| simpleModule.addSerializer(Long.class, ToStringSerializer.instance); | |||
| simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance); | |||
| SimpleModule bigIntegerModule = new SimpleModule(); | |||
| //序列化将BigInteger转String类型 | |||
| bigIntegerModule.addSerializer(BigInteger.class, ToStringSerializer.instance); | |||
| SimpleModule bigDecimalModule = new SimpleModule(); | |||
| //序列化将BigDecimal转String类型 | |||
| bigDecimalModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); | |||
| objectMapper.registerModule(simpleModule); | |||
| objectMapper.registerModule(bigDecimalModule); | |||
| objectMapper.registerModule(bigIntegerModule); | |||
| jackson2HttpMessageConverter.setObjectMapper(objectMapper); | |||
| converters.add(jackson2HttpMessageConverter); | |||
| } | |||
| } | |||
| @@ -1,69 +0,0 @@ | |||
| package com.iformall.config; | |||
| import org.apache.commons.lang3.builder.ToStringBuilder; | |||
| import org.apache.commons.lang3.builder.ToStringStyle; | |||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||
| /** | |||
| * Stormeye | |||
| */ | |||
| @ConfigurationProperties(prefix = "wechat.open") | |||
| public class WechatOpenProperties { | |||
| /** | |||
| * 设置微信三方平台的appid | |||
| */ | |||
| private String componentAppId; | |||
| /** | |||
| * 设置微信三方平台的app secret | |||
| */ | |||
| private String componentSecret; | |||
| /** | |||
| * 设置微信三方平台的token | |||
| */ | |||
| private String componentToken; | |||
| /** | |||
| * 设置微信三方平台的EncodingAESKey | |||
| */ | |||
| private String componentAesKey; | |||
| public String getComponentAppId() { | |||
| return componentAppId; | |||
| } | |||
| public void setComponentAppId(String componentAppId) { | |||
| this.componentAppId = componentAppId; | |||
| } | |||
| public String getComponentSecret() { | |||
| return componentSecret; | |||
| } | |||
| public void setComponentSecret(String componentSecret) { | |||
| this.componentSecret = componentSecret; | |||
| } | |||
| public String getComponentToken() { | |||
| return componentToken; | |||
| } | |||
| public void setComponentToken(String componentToken) { | |||
| this.componentToken = componentToken; | |||
| } | |||
| public String getComponentAesKey() { | |||
| return componentAesKey; | |||
| } | |||
| public void setComponentAesKey(String componentAesKey) { | |||
| this.componentAesKey = componentAesKey; | |||
| } | |||
| @Override | |||
| public String toString() { | |||
| return ToStringBuilder.reflectionToString(this, | |||
| ToStringStyle.MULTI_LINE_STYLE); | |||
| } | |||
| } | |||
| @@ -1,45 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.iformall.utils.IPUtil; | |||
| import org.springframework.web.bind.WebDataBinder; | |||
| import org.springframework.web.bind.annotation.InitBinder; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import org.springframework.web.context.request.RequestContextHolder; | |||
| import org.springframework.web.context.request.ServletRequestAttributes; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import java.beans.PropertyEditorSupport; | |||
| import java.text.ParseException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Date; | |||
| @RestController | |||
| public class BaseController { | |||
| @InitBinder | |||
| public void InitBinder(WebDataBinder dataBinder) { | |||
| dataBinder.registerCustomEditor(Date.class, new PropertyEditorSupport() { | |||
| public void setAsText(String value) { | |||
| try { | |||
| setValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value)); | |||
| } catch(ParseException e) { | |||
| try { | |||
| setValue(new SimpleDateFormat("yyyy-MM-dd ").parse(value)); | |||
| } catch (ParseException e1) { | |||
| setValue(null); | |||
| } | |||
| } | |||
| } | |||
| public String getAsText() { | |||
| return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format((Date) getValue()); | |||
| } | |||
| }); | |||
| } | |||
| public String getIpAddr() { | |||
| HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); | |||
| String ipaddress = IPUtil.getIpAddr(request); | |||
| return ipaddress; | |||
| } | |||
| } | |||
| @@ -1,131 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.google.code.kaptcha.Constants; | |||
| import com.google.code.kaptcha.Producer; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.service.MallUserRoleService; | |||
| import com.iformall.shiro.UserSession; | |||
| import com.iformall.utils.ShiroUtils; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import org.apache.commons.io.IOUtils; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.shiro.SecurityUtils; | |||
| import org.apache.shiro.authc.UsernamePasswordToken; | |||
| import org.apache.shiro.subject.Subject; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.beans.factory.annotation.Value; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.RequestBody; | |||
| import org.springframework.web.bind.annotation.RestController; | |||
| import javax.imageio.ImageIO; | |||
| import javax.servlet.ServletException; | |||
| import javax.servlet.ServletOutputStream; | |||
| import javax.servlet.http.Cookie; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| import java.awt.image.BufferedImage; | |||
| import java.io.IOException; | |||
| @RestController | |||
| @Api(description = "登录相关接口") | |||
| public class HomeController extends BaseController { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Value("${version}") | |||
| private String version; | |||
| @Autowired | |||
| private Producer producer; | |||
| @Autowired | |||
| private MallUserRoleService mallUserRoleService; | |||
| @GetMapping("/captcha.jpg") | |||
| public void captcha(HttpServletResponse response)throws ServletException, IOException { | |||
| logger.debug("[" + getIpAddr() + "] HomeController::captcha"); | |||
| response.setHeader("Cache-Control", "no-store, no-cache"); | |||
| response.setContentType("image/jpeg"); | |||
| //生成文字验证码 | |||
| String text = producer.createText(); | |||
| //生成图片验证码 | |||
| BufferedImage image = producer.createImage(text); | |||
| //保存到shiro session | |||
| ShiroUtils.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text); | |||
| ServletOutputStream out = response.getOutputStream(); | |||
| ImageIO.write(image, "jpg", out); | |||
| IOUtils.closeQuietly(out); | |||
| } | |||
| @ApiOperation("登录") | |||
| @PostMapping("/doLogin") | |||
| public ResultData login(@RequestBody MallUserInfo user, HttpServletResponse response) { | |||
| logger.debug("[" + getIpAddr() + "] HomeController::login"); | |||
| try { | |||
| String kaptcha = ShiroUtils.getKaptcha(Constants.KAPTCHA_SESSION_KEY); | |||
| if(!user.getCaptcha().equalsIgnoreCase(kaptcha)){ | |||
| return new ResultData(ErrorCode.KAPCHA_NOT_EQUAL); | |||
| } | |||
| } catch (MallinkException e) { | |||
| logger.error("验证码" + e.getMessage()); | |||
| return new ResultData(ErrorCode.KAPCHA_NOT_VALID.getCode(), e.getMessage()); | |||
| } | |||
| ResultData data = new ResultData(); | |||
| if (StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPassword())) { | |||
| // throw new SystemException(ErrorCode.LOGIN_USER_OR_PWD_ERROR); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| try { | |||
| Subject subject = SecurityUtils.getSubject(); | |||
| UsernamePasswordToken token = new UsernamePasswordToken(user.getUsername(), user.getPassword()); | |||
| subject.login(token); | |||
| MallUserInfo info = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); | |||
| info.setPassword("保密"); | |||
| info.setBopenId("保密"); | |||
| if(StringUtils.isNotBlank(info.getWebOpenId())) { | |||
| info.setWebOpenId("保密"); | |||
| } | |||
| String menus = mallUserRoleService.getPermissionsByUser(info); | |||
| if(menus != null) { | |||
| info.setMenus(menus); | |||
| } | |||
| Cookie unameCookie = new Cookie("uname", info.getUsername()); | |||
| unameCookie.setMaxAge(60); | |||
| response.addCookie(unameCookie); | |||
| data.data = info; | |||
| } catch (Exception e) { | |||
| return new ResultData(ErrorCode.USER_PASSWD_ERR); | |||
| } | |||
| return data; | |||
| } | |||
| @ApiOperation("登出") | |||
| @GetMapping("/logout") | |||
| public ResultData logout() { | |||
| logger.debug("[" + getIpAddr() + "] HomeController::logout"); | |||
| ResultData data = new ResultData(); | |||
| SecurityUtils.getSubject().logout(); | |||
| return data; | |||
| } | |||
| @ApiOperation("获取后端版本号") | |||
| @GetMapping("/version") | |||
| public ResultData version() { | |||
| return new ResultData(version); | |||
| } | |||
| } | |||
| @@ -1,102 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.iformall.domain.po.WxAuthorizerInfo; | |||
| import com.iformall.enums.EnumWxAuthorizationStatus; | |||
| import com.iformall.service.WxAuthorizerInfoService; | |||
| import com.iformall.service.wechat.WxOpenService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Controller; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| import java.io.IOException; | |||
| import java.util.Date; | |||
| /** | |||
| * Stormeye Wu | |||
| */ | |||
| @Controller | |||
| @RequestMapping("/wt_auth") | |||
| @Api(description = "微信第三方开放平台授权相关接口") | |||
| public class WechatAuthController { | |||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private WxOpenService openService; | |||
| @Autowired | |||
| private WxAuthorizerInfoService authorizerInfoService; | |||
| @ApiOperation(value = "获取授权跳转页", notes = "") | |||
| @GetMapping("/goto_auth_url_show") | |||
| @ResponseBody | |||
| public String gotoPreAuthUrlShow() { | |||
| return "<html>" + | |||
| "<body>" + | |||
| "<a href='/O/wt_auth/goto_auth_url'>go</a>" + | |||
| "</body>" + | |||
| "</html>"; | |||
| } | |||
| @ApiOperation(value = "授权跳转页", notes = "") | |||
| @GetMapping("/goto_auth_url") | |||
| public void gotoPreAuthUrl(HttpServletRequest request, HttpServletResponse response) { | |||
| String host = request.getHeader("host"); | |||
| String url = "https://" + host + "/O/wt_auth/jump"; | |||
| try { | |||
| url = openService.getWxOpenComponentService().getPreAuthUrl(url); | |||
| response.sendRedirect(url); | |||
| } catch (WxErrorException | IOException e) { | |||
| logger.error("gotoPreAuthUrl", e); | |||
| throw new RuntimeException(e); | |||
| } | |||
| } | |||
| @ApiOperation(value = "授权", notes = "") | |||
| @GetMapping("/jump") | |||
| @ResponseBody | |||
| public void jump(@RequestParam("auth_code") String authorizationCode) { | |||
| try { | |||
| WxOpenQueryAuthResult queryAuthResult = openService.getWxOpenComponentService().getQueryAuth(authorizationCode); | |||
| logger.info("getQueryAuth", queryAuthResult); | |||
| WxOpenAuthorizerInfoResult openAuthorizerInfoResult = openService.getWxOpenComponentService().getAuthorizerInfo( | |||
| queryAuthResult.getAuthorizationInfo().getAuthorizerAppid()); | |||
| // save auth info | |||
| authorizerInfoService.saveOrUpdate(new WxAuthorizerInfo(){ | |||
| { | |||
| setAuthorizerAppid(openAuthorizerInfoResult.getAuthorizationInfo().getAuthorizerAppid()); | |||
| setAlias(openAuthorizerInfoResult.getAuthorizerInfo().getAlias()); | |||
| setHeadImg(openAuthorizerInfoResult.getAuthorizerInfo().getHeadImg()); | |||
| setQrcodeUrl(openAuthorizerInfoResult.getAuthorizerInfo().getQrcodeUrl()); | |||
| setAuthorizationStatus(EnumWxAuthorizationStatus.AUTHORIZED.getCode()); | |||
| setAuthTime(new Date()); | |||
| } | |||
| }); | |||
| } catch (WxErrorException e) { | |||
| logger.error("gotoPreAuthUrl", e); | |||
| throw new RuntimeException(e); | |||
| } | |||
| } | |||
| @ApiOperation(value = "手机跳转链接url", notes = "") | |||
| @GetMapping("/getMobilePreAuthUrl") | |||
| @ResponseBody | |||
| public String getMobilePreAuthUrl(HttpServletRequest request, HttpServletResponse response) { | |||
| String host = request.getHeader("host"); | |||
| String url = "https://" + host + "/O/wt_auth/jump"; | |||
| try { | |||
| url = openService.getWxOpenComponentService().getMobilePreAuthUrl(url); | |||
| return url; | |||
| } catch (WxErrorException e) { | |||
| logger.error("getMobilePreAuthUrl", e); | |||
| throw new RuntimeException(e); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,415 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.google.gson.Gson; | |||
| import com.google.gson.GsonBuilder; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.enums.*; | |||
| import com.iformall.service.*; | |||
| import com.iformall.service.wechat.WxOpenService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; | |||
| import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||
| import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||
| import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenPlatformResult; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenResult; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Controller; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import java.io.ByteArrayOutputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.nio.charset.Charset; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| @Controller | |||
| @RequestMapping("/wxOpen") | |||
| @Api(description = "微信第三方开放平台回调相关接口") | |||
| public class WechatCalllbackController extends BaseController { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| @Autowired | |||
| protected WxOpenService openService; | |||
| @Autowired | |||
| private WxComponentVerifyTicketService componentVerifyTicketService; | |||
| @Autowired | |||
| private WxAuthorizerInfoService authorizerInfoService; | |||
| @Autowired | |||
| private WxWeappAuditStatusService weappAuditStatusService; | |||
| @Autowired | |||
| private WxAppinfoService appinfoService; | |||
| @Autowired | |||
| private MailService mailService; | |||
| @RequestMapping(value = "/notify", method = RequestMethod.POST) | |||
| @ApiOperation("接收ticket回调") | |||
| public Object receiveTicket(HttpServletRequest request) throws IOException { | |||
| logger.info("[" +getIpAddr() + "]接收微信回调 /wxOpen/notify"); | |||
| InputStream inStream = request.getInputStream(); | |||
| ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); | |||
| byte[] buffer = new byte[1024]; | |||
| int len = 0; | |||
| while ((len = inStream.read(buffer)) != -1) { | |||
| outSteam.write(buffer, 0, len); | |||
| } | |||
| String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8")); | |||
| logger.info(resultxml); | |||
| outSteam.close(); | |||
| inStream.close(); | |||
| String timestamp = request.getParameter("timestamp"); | |||
| String nonce = request.getParameter("nonce"); | |||
| String signature = request.getParameter("signature"); | |||
| String encType = request.getParameter("encrypt_type"); | |||
| String msgSignature= request.getParameter("msg_signature"); | |||
| /* | |||
| // 测试数据 | |||
| String timestamp = "1545708083"; | |||
| String nonce = "1052028699"; | |||
| String signature = "b5fa8296b46c726cbed35f744944f20f682776a6"; | |||
| String encType = "aes"; | |||
| String msgSignature= "54bec4c513f447cb312fd091bea48326f87aedde"; | |||
| String resultxml = "<xml>\n" + | |||
| " <AppId><![CDATA[wx897e4673286c915d]]></AppId>\n" + | |||
| " <Encrypt><![CDATA[92gl+PCgxooLh85YZ74VX8gNPV3tq2w8br4tuBl2UIc9uJuJiSNBgohFxgS7tRXSMUtr5t+75MiLKlaMKvv4FH5iF3WdYbxjF6ojnA1+MBzD7mf9fo6KkWUdDq+1V0OtrooP4s8iuAC0Lx3elCtWUZXYGnCeP5Y/2A8ZZBwpvcBz73d7n2Kv8QVvLsw2dmrej1b8KGdmRAEbm/oYoVthlAkmoTTAAx+Gj10XTMem1wp1vT/a0mGxN88oJxNZoHdFvAbmc24A7VD4i5VDOt9FqwerqlGXnBX5pBAmOx8ZUsndM8yuf3I54GE9hEPRvdWBiyLb96Lb8ZnjEBlvc9kvs7PpFOSQhkbGMNQKWGW1os8UImr7O3+IiKLuBv2G1pJBb2/kIeZn5v9NuxYLOsXQmb2XijHYMXwCNHCI3Eji22k9XDiiuK1miHlUuL8Gz8X7lN9JuVcE24jd7Ty4H0pThQ==]]></Encrypt>\n" + | |||
| "</xml>"; | |||
| */ | |||
| logger.info("\n接收微信回调:[signature=[{}], encType=[{}], msgSignature=[{}]," | |||
| + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", | |||
| signature, encType, msgSignature, timestamp, nonce, resultxml); | |||
| if (!StringUtils.equalsIgnoreCase("aes", encType) | |||
| || !openService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { | |||
| throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); | |||
| } | |||
| // aes加密的消息 | |||
| WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(resultxml, | |||
| openService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); | |||
| this.logger.info("接收微信回调,消息解密后内容为:{} ", inMessage.toString()); | |||
| if(inMessage.getInfoType().equals(EnumWxAuthorizationInfoType.COMPONENT_VERIFY_TICKET.getMessage())) { | |||
| // 保存component_verify_ticket | |||
| componentVerifyTicketService.saveOrUpdate(new WxComponentVerifyTicket(){ | |||
| { | |||
| setComponentVerifyTicket(inMessage.getComponentVerifyTicket()); | |||
| setCreateTime(new Date(Long.valueOf(inMessage.getCreateTime() * 1000))); | |||
| setComponentAppid(inMessage.getAppId()); | |||
| setDeadline(new Date(Long.valueOf(System.currentTimeMillis() + (60*60*1000)))); | |||
| } | |||
| }); | |||
| } else if (inMessage.getInfoType().equals(EnumWxAuthorizationInfoType.AUTHORIZED.getMessage()) || | |||
| inMessage.getInfoType().equals(EnumWxAuthorizationInfoType.UPDATEAUTHORIZED.getMessage()) | |||
| ) { | |||
| try { | |||
| WxOpenQueryAuthResult queryAuthResult = openService.getWxOpenComponentService().getQueryAuth(inMessage.getAuthorizationCode()); | |||
| logger.info("getQueryAuth", queryAuthResult); | |||
| WxOpenAuthorizerInfoResult openAuthorizerInfoResult = openService.getWxOpenComponentService().getAuthorizerInfo( | |||
| queryAuthResult.getAuthorizationInfo().getAuthorizerAppid()); | |||
| logger.info(openAuthorizerInfoResult.toString()); | |||
| // save auth info | |||
| authorizerInfoService.saveOrUpdate(new WxAuthorizerInfo(){ | |||
| { | |||
| setAuthorizerAppid(openAuthorizerInfoResult.getAuthorizationInfo().getAuthorizerAppid()); | |||
| setAlias(openAuthorizerInfoResult.getAuthorizerInfo().getAlias()); | |||
| setHeadImg(openAuthorizerInfoResult.getAuthorizerInfo().getHeadImg()); | |||
| setQrcodeUrl(openAuthorizerInfoResult.getAuthorizerInfo().getQrcodeUrl()); | |||
| setAuthorizationStatus(EnumWxAuthorizationStatus.AUTHORIZED.getCode()); | |||
| setAuthTime(new Date()); | |||
| } | |||
| }); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| } else if (inMessage.getInfoType().equals(EnumWxAuthorizationInfoType.UNAUTHORIZED.getMessage())) { | |||
| authorizerInfoService.saveOrUpdate(new WxAuthorizerInfo(){ | |||
| { | |||
| setAuthorizerAppid(inMessage.getAuthorizerAppid()); | |||
| setAuthorizationStatus(EnumWxAuthorizationStatus.UNAUTHORIZED.getCode()); | |||
| setAuthTime(new Date()); | |||
| } | |||
| }); | |||
| } | |||
| try { | |||
| String out = openService.getWxOpenComponentService().route(inMessage); | |||
| this.logger.info("组装回复信息:{}", out); | |||
| } catch (WxErrorException e) { | |||
| this.logger.error("notify", e); | |||
| } | |||
| return "success"; | |||
| } | |||
| @RequestMapping(value = "/{appId}/callback") | |||
| @ApiOperation("消息回调") | |||
| public Object callback(@PathVariable("appId") String appId, HttpServletRequest request) throws IOException { | |||
| logger.info("[" +getIpAddr() + "]接收微信APP回调 /{appId}/callback"); | |||
| InputStream inStream = request.getInputStream(); | |||
| ByteArrayOutputStream outSteam = new ByteArrayOutputStream(); | |||
| byte[] buffer = new byte[1024]; | |||
| int len = 0; | |||
| while ((len = inStream.read(buffer)) != -1) { | |||
| outSteam.write(buffer, 0, len); | |||
| } | |||
| String resultxml = new String(outSteam.toByteArray(), Charset.forName("UTF-8")); | |||
| logger.info(resultxml); | |||
| outSteam.close(); | |||
| inStream.close(); | |||
| String timestamp = request.getParameter("timestamp"); | |||
| String nonce = request.getParameter("nonce"); | |||
| String signature = request.getParameter("signature"); | |||
| String encType = request.getParameter("encrypt_type"); | |||
| String openid = request.getParameter("openid"); | |||
| String msgSignature= request.getParameter("msg_signature"); | |||
| logger.info("接收微信APP回调:[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}]," | |||
| + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", | |||
| appId, openid, signature, encType, msgSignature, timestamp, nonce, resultxml); | |||
| if (!StringUtils.equalsIgnoreCase("aes", encType) | |||
| || !openService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { | |||
| throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); | |||
| } | |||
| String out = ""; | |||
| // aes加密的消息 | |||
| WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(resultxml, | |||
| openService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); | |||
| logger.info("接收微信APP回调,消息解密后内容为:\n{}", inMessage.toString()); | |||
| // 全网发布测试用例 | |||
| if (StringUtils.equalsAnyIgnoreCase(appId, "wx570bc396a51b8ff8", "wxd101a85aa106f53e")) { | |||
| try { | |||
| if (StringUtils.equals(inMessage.getMsgType(), "text")) { | |||
| if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) { | |||
| out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml( | |||
| WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback") | |||
| .fromUser(inMessage.getToUser()) | |||
| .toUser(inMessage.getFromUser()) | |||
| .build(), | |||
| openService.getWxOpenConfigStorage() | |||
| ); | |||
| } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) { | |||
| String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api"; | |||
| WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build(); | |||
| openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); | |||
| } | |||
| } else if (StringUtils.equals(inMessage.getMsgType(), "event")) { | |||
| WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build(); | |||
| openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); | |||
| } | |||
| } catch (WxErrorException e) { | |||
| logger.error("callback", e); | |||
| } | |||
| } else { | |||
| /**判断消息类型,调用对应的方法*/ | |||
| switch (inMessage.getMsgType()){ | |||
| case "event": { | |||
| switch (inMessage.getEvent()) { | |||
| case "weapp_audit_success": { // 审核成功 | |||
| updateAuditStatus(appId, true, ""); | |||
| break; | |||
| } | |||
| case "weapp_audit_fail": { // 审核失败 | |||
| updateAuditStatus(appId, false, inMessage.getReason()); | |||
| break; | |||
| } | |||
| default: | |||
| break; | |||
| } | |||
| return "success"; | |||
| } | |||
| case "text": | |||
| WxMpXmlOutMessage outMessage = openService.getWxOpenMessageRouter().route(inMessage, appId); | |||
| if (outMessage != null) { | |||
| out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMessage, openService.getWxOpenConfigStorage()); | |||
| logger.info(out); | |||
| } | |||
| /* | |||
| else { | |||
| WxMpXmlOutMessage outMsg = new WxMpXmlOutTextMessage(); | |||
| outMsg.setCreateTime(System.currentTimeMillis()); | |||
| outMsg.setToUserName(inMessage.getFromUser()); | |||
| outMsg.setFromUserName(inMessage.getToUser()); | |||
| outMsg.setMsgType("text"); | |||
| ((WxMpXmlOutTextMessage) outMsg).setContent(inMessage.getContent()); | |||
| out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMsg, wxOpenService.getWxOpenConfigStorage()); | |||
| } | |||
| */ | |||
| else { | |||
| out = "success"; | |||
| } | |||
| break; | |||
| default: | |||
| return "success"; | |||
| } | |||
| } | |||
| return out; | |||
| } | |||
| private void updateAuditStatus(String appId, boolean success, String reason) { | |||
| WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId); | |||
| if(auditStatus != null) { | |||
| if(success) { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode()); | |||
| auditStatus.setAuditErrCode(""); | |||
| } else { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode()); | |||
| auditStatus.setAuditErrCode(reason); | |||
| } | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.updateStatus(auditStatus); | |||
| } | |||
| // 发邮件 | |||
| WxAppinfo appinfo = appinfoService.getByAppId(appId); | |||
| if(appinfo != null) { | |||
| SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 | |||
| StringBuilder titleSB = new StringBuilder(); | |||
| if(appinfo.getType().equals(EnumAppType.C.getCode())) { | |||
| titleSB.append("C端小程序"); | |||
| } else if(appinfo.getType().equals(EnumAppType.B.getCode())) { | |||
| titleSB.append("B端小程序"); | |||
| } else if(appinfo.getType().equals(EnumAppType.MP_S.getCode())) { | |||
| titleSB.append("公众号-服务号"); | |||
| } else if(appinfo.getType().equals(EnumAppType.MP_P.getCode())) { | |||
| titleSB.append("公众号-订阅号"); | |||
| } | |||
| titleSB.append(appinfo.getName()); | |||
| if(success) { | |||
| titleSB.append("审核通过"); | |||
| } else { | |||
| titleSB.append("审核未通过"); | |||
| } | |||
| StringBuilder sb = new StringBuilder(); | |||
| sb.append(df.format(new Date())).append("\n"); | |||
| if(success) { | |||
| sb.append("审核通过\n"); | |||
| } else { | |||
| sb.append("审核未通过\n").append("原因").append(reason); | |||
| } | |||
| String[] receivers = new String[] {"wangmei@iformall.com", "wuguoqiang@iformall.com", "huanghui@iformall.com", "sunmingming@iformall.com"}; | |||
| //发送邮件 | |||
| mailService.sendSimpleMail(receivers, titleSB.toString(), sb.toString()); | |||
| } | |||
| } | |||
| @GetMapping(value = "/createOpenPlatform") | |||
| @ApiOperation("创建微信开放平台") | |||
| public ResultData createOpenPlatform(@RequestParam(value="appId") String appId) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| try { | |||
| String responseStr = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).createOpenPlatform(appId); | |||
| logger.info(responseStr); | |||
| WxOpenPlatformResult openPlatformResult = gson.fromJson(responseStr, WxOpenPlatformResult.class); | |||
| if(openPlatformResult.isSuccess()) { | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo != null) { | |||
| authorizerInfo.setId(authorizerInfo.getId()); | |||
| authorizerInfo.setOpenAppid(openPlatformResult.getOpenAppid()); | |||
| authorizerInfoService.updateOpenAppid(authorizerInfo); | |||
| } | |||
| } | |||
| return new ResultData(responseStr); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @GetMapping(value = "/bindOpenPlatform") | |||
| @ApiOperation("绑定微信开放平台") | |||
| public ResultData bindOpenPlatform(@RequestParam(value = "appId") String appId, @RequestParam(value = "openAppId") String openAppId) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| try { | |||
| String responseStr = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).bindOpenPlatform(appId, openAppId); | |||
| logger.info(responseStr); | |||
| WxOpenResult openResult = gson.fromJson(responseStr, WxOpenResult.class); | |||
| if(openResult.isSuccess()) { | |||
| return new ResultData(); | |||
| } | |||
| return new ResultData(Result.ERROR, responseStr); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @GetMapping(value = "/unbindOpenPlatform") | |||
| @ApiOperation("解绑微信开放平台") | |||
| public ResultData unbindOpenPlatform(@RequestParam(value = "appId") String appId, @RequestParam(value = "openAppId") String openAppId) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| try { | |||
| String responseStr = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).unbindOpenPlatform(appId, openAppId); | |||
| logger.info(responseStr); | |||
| WxOpenResult openResult = gson.fromJson(responseStr, WxOpenResult.class); | |||
| if(openResult.isSuccess()) { | |||
| return new ResultData(); | |||
| } | |||
| return new ResultData(Result.ERROR, responseStr); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @GetMapping(value = "/getOpenPlatform") | |||
| @ApiOperation("获取微信开放平台appId") | |||
| public ResultData getOpenPlatform(@RequestParam(value = "appId") String appId) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| try { | |||
| String responseStr = openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getBindOpenPlatform(appId); | |||
| logger.info(responseStr); | |||
| WxOpenPlatformResult openPlatformResult = gson.fromJson(responseStr, WxOpenPlatformResult.class); | |||
| if(openPlatformResult.isSuccess()) { | |||
| return new ResultData(openPlatformResult.getOpenAppid()); | |||
| } | |||
| return new ResultData(Result.ERROR, responseStr); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @GetMapping(value = "/clearQuota") | |||
| @ApiOperation("代公众号清零quota,每个公众号每个月有10次清零机会,包括在微信公众平台上的清零以及调用API进行清零") | |||
| public ResultData clearQuota(@RequestParam(value = "appId") String appId) { | |||
| try { | |||
| openService.getWxOpenComponentService().getWxMpServiceByAppid(appId).clearQuota(appId); | |||
| return new ResultData(); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,544 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.google.gson.Gson; | |||
| import com.google.gson.GsonBuilder; | |||
| import com.google.gson.reflect.TypeToken; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.domain.vo.WxWeappCodeStatusVo; | |||
| import com.iformall.enums.*; | |||
| import com.iformall.service.*; | |||
| import com.iformall.service.wechat.WxOpenService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.open.api.WxOpenMaService; | |||
| import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitExtInfo; | |||
| import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage; | |||
| import me.chanjar.weixin.open.bean.result.*; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import javax.servlet.ServletOutputStream; | |||
| import javax.servlet.http.HttpServletRequest; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| import java.net.URLEncoder; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| /** | |||
| * Stormeye Wu | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/weappCode") | |||
| @Api(description = "微信第三方开发平台-小程序-代码管理") | |||
| public class WechatWeappCodeController { | |||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private WxOpenService openService; | |||
| @Autowired | |||
| private WxWeappCodeStatusService weappCodeStatusService; | |||
| @Autowired | |||
| private WxWeappAuditStatusService weappAuditStatusService; | |||
| @Autowired | |||
| private WxWeappReleaseStatusService weappReleaseStatusService; | |||
| @Autowired | |||
| private WxAppinfoService appinfoService; | |||
| @Autowired | |||
| private WxAuthorizerInfoService authorizerInfoService; | |||
| @Autowired | |||
| private WxWeappExtSetService weappExtSetService; | |||
| @ApiOperation(value = "为授权的小程序帐号上传小程序代码", notes = "extInfo参考https://mp.weixin.qq.com/debug/wxadoc/dev/framework/config.html") | |||
| @PostMapping("/codeCommit") | |||
| public ResultData codeCommit(Long templateId, String userVersion, String userDesc, String extInfoStr) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| WxMaOpenCommitExtInfo extInfo = gson.fromJson(extInfoStr, new TypeToken<WxMaOpenCommitExtInfo>() {}.getType()); | |||
| String appId = extInfo.getExtAppid(); | |||
| // 检查appId是否已授权 | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| WxWeappCodeStatus codeStatus = weappCodeStatusService.getByAppId(appId); | |||
| WxAppinfo appinfo = appinfoService.getByAppId(appId); | |||
| int iAppType = 0; | |||
| String appTypeStr = userVersion.substring(0, 1); | |||
| if(appTypeStr.equalsIgnoreCase("C")) | |||
| iAppType = EnumAppType.C.getCode(); | |||
| else if(appTypeStr.equalsIgnoreCase("B")) | |||
| iAppType = EnumAppType.B.getCode(); | |||
| try { | |||
| // code提交 | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| logger.info(extInfo.toString()); | |||
| WxOpenResult openRet = openMaService.codeCommit(templateId, userVersion, userDesc, extInfo); | |||
| logger.info(openRet.toString()); | |||
| boolean codeCommitStatus = false; | |||
| if (openRet.isSuccess()) { | |||
| codeCommitStatus = true; | |||
| } | |||
| if (codeStatus == null) { | |||
| codeStatus = new WxWeappCodeStatus(); | |||
| codeStatus.setAppId(appId); | |||
| if (appinfo != null) { | |||
| codeStatus.setType(appinfo.getType()); | |||
| } | |||
| codeStatus.setUserVersion(userVersion); | |||
| codeStatus.setVersionDesc(userDesc); | |||
| if(codeCommitStatus) { | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.SUCCESS.getCode()); | |||
| } else { | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.FAIL.getCode()); | |||
| codeStatus.setCodeErrCode(gson.toJson(openRet)); | |||
| } | |||
| codeStatus.setCodeTime(new Date()); | |||
| weappCodeStatusService.saveStatus(codeStatus); | |||
| } else { | |||
| codeStatus.setUserVersion(userVersion); | |||
| codeStatus.setVersionDesc(userDesc); | |||
| if(codeCommitStatus) { | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.SUCCESS.getCode()); | |||
| } else { | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.FAIL.getCode()); | |||
| codeStatus.setCodeErrCode(gson.toJson(openRet)); | |||
| } | |||
| codeStatus.setCodeTime(new Date()); | |||
| weappCodeStatusService.updateStatus(codeStatus); | |||
| } | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| if (codeStatus == null) { | |||
| codeStatus = new WxWeappCodeStatus(); | |||
| codeStatus.setAppId(appId); | |||
| if (appinfo != null) { | |||
| codeStatus.setType(appinfo.getType()); | |||
| } | |||
| codeStatus.setUserVersion(userVersion); | |||
| codeStatus.setVersionDesc(userDesc); | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.FAIL.getCode()); | |||
| codeStatus.setCodeErrCode(e.getMessage()); | |||
| codeStatus.setCodeTime(new Date()); | |||
| weappCodeStatusService.saveStatus(codeStatus); | |||
| } else { | |||
| codeStatus.setUserVersion(userVersion); | |||
| codeStatus.setVersionDesc(userDesc); | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.FAIL.getCode()); | |||
| codeStatus.setCodeErrCode(e.getMessage()); | |||
| codeStatus.setCodeTime(new Date()); | |||
| weappCodeStatusService.updateStatus(codeStatus); | |||
| } | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("获取体验小程序的体验二维码") | |||
| @GetMapping("/getQrcode") | |||
| public void getQrcode(@RequestParam(value = "appId") String appId, @RequestParam(value = "pagePath") String pagePath, | |||
| @RequestParam(value = "params", required = false) Map<String, String> params, | |||
| HttpServletResponse response, HttpServletRequest req) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| File file = openMaService.getTestQrcode(pagePath, params); | |||
| ServletOutputStream out = response.getOutputStream(); | |||
| response.reset(); | |||
| response.setContentType("image/jpeg"); | |||
| String agent = req.getHeader("user-agent"); | |||
| String filename = "QRCode.jpg"; | |||
| if (agent.contains("Firefox")) { | |||
| response.setHeader("Content-disposition", | |||
| "attachment; filename=" + new String(filename.getBytes("GB2312"),"ISO-8859-1")); | |||
| } else { | |||
| response.setHeader("Content-disposition", | |||
| "attachment; filename=" + URLEncoder.encode(filename,"UTF-8")); | |||
| } | |||
| // 循环取出流中的数据 | |||
| byte[] b = new byte[1024]; | |||
| int len; | |||
| InputStream inStream = new FileInputStream(file); | |||
| while ((len = inStream.read(b)) > 0) | |||
| response.getOutputStream().write(b, 0, len); | |||
| inStream.close(); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| } catch (IOException e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("获取授权小程序帐号已设置的类目") | |||
| @GetMapping("/getCategory") | |||
| public ResultData getCategory(String appId) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenMaCategoryListResult openRet = openMaService.getCategoryList(); | |||
| logger.info(openRet.toString()); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("获取小程序的第三方提交代码的页面配置") | |||
| @GetMapping("/getPage") | |||
| public ResultData getPage(String appId) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenMaPageListResult openRet = openMaService.getPageList(); | |||
| logger.info(openRet.toString()); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("将第三方提交的代码包提交审核") | |||
| @GetMapping("/submitAudit") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "appId", value = "appId", dataType = "String", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "version", value = "version", dataType = "String", paramType = "query")}) | |||
| public ResultData submitAudit(String appId, String version) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| WxWeappExtSet extSetQ = new WxWeappExtSet(); | |||
| extSetQ.setAppId(appId); | |||
| WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ); | |||
| if(StringUtils.isBlank(extSet.getReleaseJson())) { | |||
| logger.error("Release JSON is null"); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| WxWeappCodeStatusVo codeQ = new WxWeappCodeStatusVo(); | |||
| codeQ.setAppId(appId); | |||
| if(StringUtils.isNotBlank(version)) { | |||
| codeQ.setUserVersion(version); | |||
| } | |||
| List<WxWeappCodeStatusVo> codeStatusList = weappCodeStatusService.getList(codeQ); | |||
| if(codeStatusList.size() == 1) { | |||
| WxWeappCodeStatusVo codeStatus = codeStatusList.get(0); | |||
| WxOpenMaSubmitAuditMessage subMessage = gson.fromJson(extSet.getReleaseJson(), new TypeToken<WxOpenMaSubmitAuditMessage>() {}.getType()); | |||
| if(codeStatus != null && codeStatus.getCodeStatus().equals(EnumWeappCodeCommitStatus.SUCCESS.getCode())) { | |||
| WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId); | |||
| boolean submitStatus = false; | |||
| String codeErrCode = ""; | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenMaSubmitAuditResult openRet = openMaService.submitAudit(subMessage); | |||
| logger.info(openRet.toString()); | |||
| if(openRet.isSuccess()) { | |||
| submitStatus = true; | |||
| codeErrCode = gson.toJson(openRet); | |||
| } else { | |||
| submitStatus = false; | |||
| codeErrCode = gson.toJson(openRet); | |||
| } | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| submitStatus = false; | |||
| codeErrCode = e.getMessage(); | |||
| } | |||
| if (auditStatus == null) { | |||
| auditStatus = new WxWeappAuditStatus(); | |||
| auditStatus.setId(codeStatus.getId()); | |||
| auditStatus.setAppId(codeStatus.getAppId()); | |||
| auditStatus.setType(codeStatus.getType()); | |||
| auditStatus.setUserVersion(codeStatus.getUserVersion()); | |||
| auditStatus.setVersionDesc(codeStatus.getVersionDesc()); | |||
| if(submitStatus) { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| } else { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode()); | |||
| } | |||
| auditStatus.setAuditErrCode(codeErrCode); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.saveStatus(auditStatus); | |||
| } else { | |||
| if(!submitStatus) { | |||
| if(!auditStatus.getUserVersion().equals(codeStatus.getUserVersion()) | |||
| && auditStatus.getAuditStatus().equals(EnumWeappAuditStatus.AUDITING.getCode())) { | |||
| // 提交审核失败不替换当前审核中的数据 | |||
| return new ResultData(ErrorCode.WEAPP_HAD_AUDITING); | |||
| } | |||
| codeStatus.setCodeStatus(EnumWeappAuditStatus.FAIL.getCode()); | |||
| codeStatus.setCodeErrCode(codeErrCode); | |||
| } else { | |||
| codeStatus.setCodeStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| } | |||
| auditStatus.setUserVersion(codeStatus.getUserVersion()); | |||
| auditStatus.setVersionDesc(codeStatus.getVersionDesc()); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.updateStatus(auditStatus); | |||
| } | |||
| if(submitStatus) { | |||
| return new ResultData(codeErrCode); | |||
| } else { | |||
| return new ResultData(ErrorCode.WEAPP_AUDIT_ERR); | |||
| } | |||
| } else { | |||
| logger.error(ErrorCode.WEAPP_CODE_COMMIT_ERR.getMessage()); | |||
| return new ResultData(ErrorCode.WEAPP_CODE_COMMIT_ERR); | |||
| } | |||
| } | |||
| return new ResultData(ErrorCode.WEAPP_CODE_COMMIT_ERR); | |||
| } | |||
| @ApiOperation("查询某个指定版本的审核状态") | |||
| @PostMapping("/getAuditstatus") | |||
| public ResultData getAuditstatus(String appId, String auditidStr) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| Long auditId = Long.valueOf(auditidStr); | |||
| WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId); | |||
| if(auditStatus != null && auditStatus.getAuditid().equals(auditId)) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenMaQueryAuditResult openRet = openMaService.getAuditStatus(auditId); | |||
| logger.info(openRet.toString()); | |||
| if (openRet.isSuccess()) { | |||
| auditStatus.setAuditid(openRet.getAuditId()); | |||
| // 审核状态,其中0为审核成功,1为审核失败,2为审核中,3已撤回 | |||
| switch (openRet.getStatus().intValue()) { | |||
| case 0: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode()); | |||
| break; | |||
| case 1: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode()); | |||
| break; | |||
| case 2: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| break; | |||
| case 3: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.UNDO.getCode()); | |||
| break; | |||
| default: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| break; | |||
| } | |||
| auditStatus.setAuditErrCode(gson.toJson(openRet)); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.updateStatus(auditStatus); | |||
| } | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| return new ResultData(Result.ERROR, "auditid不对应"); | |||
| } | |||
| @ApiOperation("查询最新一次提交的审核状态") | |||
| @GetMapping("/getLatestAuditstatus") | |||
| public ResultData get_latest_auditstatus(String appId) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId); | |||
| if(auditStatus != null | |||
| && auditStatus.getAuditStatus().equals(EnumWeappAuditStatus.AUDITING.getCode())) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenMaQueryAuditResult openRet = openMaService.getLatestAuditStatus(); | |||
| logger.info(openRet.toString()); | |||
| if (openRet.isSuccess()) { | |||
| auditStatus.setAuditid(openRet.getAuditId()); | |||
| // 审核状态,其中0为审核成功,1为审核失败,2为审核中,3已撤回 | |||
| switch (openRet.getStatus().intValue()) { | |||
| case 0: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode()); | |||
| break; | |||
| case 1: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode()); | |||
| break; | |||
| case 2: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| break; | |||
| case 3: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.UNDO.getCode()); | |||
| break; | |||
| default: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| break; | |||
| } | |||
| auditStatus.setAuditErrCode(gson.toJson(openRet)); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.updateStatus(auditStatus); | |||
| } | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } else { | |||
| return new ResultData(Result.ERROR, "审核状态不是审核中"); | |||
| } | |||
| } | |||
| @ApiOperation("发布已通过审核的小程序") | |||
| @GetMapping("/releaseAudited") | |||
| public ResultData releaesAudited(String appId) { | |||
| if(StringUtils.isBlank(appId)) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| Gson gson = new GsonBuilder().create(); | |||
| WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId); | |||
| if(auditStatus.getAuditStatus().equals(EnumWeappAuditStatus.SUCCESS.getCode())) { | |||
| boolean isUpdate = false; | |||
| WxWeappReleaseStatus releaseStatus = weappReleaseStatusService.getByAppId(appId); | |||
| if(releaseStatus != null) { | |||
| // 版本已发布成功,跳过 | |||
| if(releaseStatus.getUserVersion().equals(auditStatus.getUserVersion()) | |||
| && releaseStatus.getReleaseStatus().equals(EnumWeappReleaseStatus.SUCCESS.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APP_RELEASEED); | |||
| } | |||
| releaseStatus.setUserVersion(auditStatus.getUserVersion()); | |||
| releaseStatus.setVersionDesc(auditStatus.getVersionDesc()); | |||
| isUpdate = true; | |||
| } else { | |||
| releaseStatus = new WxWeappReleaseStatus(); | |||
| releaseStatus.setAppId(auditStatus.getAppId()); | |||
| releaseStatus.setType(auditStatus.getType()); | |||
| releaseStatus.setUserVersion(auditStatus.getUserVersion()); | |||
| releaseStatus.setVersionDesc(auditStatus.getVersionDesc()); | |||
| } | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenResult openRet = openMaService.releaesAudited(); | |||
| logger.info(openRet.toString()); | |||
| if(openRet.getErrcode().equals('0')) { | |||
| releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.SUCCESS.getCode()); | |||
| } else { | |||
| releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.FAIL.getCode()); | |||
| } | |||
| releaseStatus.setReleaseErrCode(gson.toJson(openRet)); | |||
| releaseStatus.setReleaseTime(new Date()); | |||
| if(isUpdate) { | |||
| weappReleaseStatusService.updateStatus(releaseStatus); | |||
| } else { | |||
| weappReleaseStatusService.saveStatus(releaseStatus); | |||
| } | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.FAIL.getCode()); | |||
| releaseStatus.setReleaseErrCode(e.getMessage()); | |||
| releaseStatus.setReleaseTime(new Date()); | |||
| if(isUpdate) { | |||
| weappReleaseStatusService.updateStatus(releaseStatus); | |||
| } else { | |||
| weappReleaseStatusService.saveStatus(releaseStatus); | |||
| } | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } else { | |||
| return new ResultData(ErrorCode.WEAPP_NOT_AUDITED); | |||
| } | |||
| } | |||
| @ApiOperation("小程序版本回退") | |||
| @GetMapping("/revertCodeRelease") | |||
| public ResultData revertCodeRelease(String appId) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| WxWeappReleaseStatus releaseStatus = weappReleaseStatusService.getByAppId(appId); | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenResult openRet = openMaService.revertCodeReleaes(); | |||
| logger.info(openRet.toString()); | |||
| if(openRet.isSuccess()) { | |||
| if(releaseStatus != null) { | |||
| releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.BACK.getCode()); | |||
| releaseStatus.setReleaseErrCode(gson.toJson(openRet)); | |||
| releaseStatus.setReleaseTime(new Date()); | |||
| weappReleaseStatusService.updateStatus(releaseStatus); | |||
| } | |||
| return new ResultData(); | |||
| } | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("查询当前设置的最低基础库版本及各版本用户占比") | |||
| @GetMapping("/getSupportVersion") | |||
| public ResultData getSupportVersion(String appId) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| String openRet = openMaService.getSupportVersion(); | |||
| logger.info(openRet.toString()); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("设置最低基础库版本") | |||
| @GetMapping("/setSupportVersion") | |||
| public ResultData setSupportVersion(String appId, String version) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| String openRet = openMaService.setSupportVersion(version); | |||
| logger.info(openRet); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation(value = "小程序审核撤回", notes = "单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。") | |||
| @GetMapping("/undoCodeAudit") | |||
| public ResultData undoCodeAudit(String appId) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId); | |||
| if(auditStatus != null) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenResult openResult = openMaService.undoCodeAudit(); | |||
| if(openResult.isSuccess()) { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.UNDO.getCode()); | |||
| auditStatus.setAuditErrCode(gson.toJson(openResult)); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.updateStatus(auditStatus); | |||
| return new ResultData("审核撤回成功"); | |||
| } | |||
| return new ResultData(Result.ERROR, "审核撤回失败"); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| return new ResultData(Result.ERROR, "没有审核记录,不能撤回"); | |||
| } | |||
| } | |||
| @@ -1,78 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.service.wechat.WxOpenService; | |||
| import io.swagger.annotations.Api; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.util.List; | |||
| /** | |||
| * Stormeye Wu | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/weappDraftTemplate") | |||
| @Api(description = "微信第三方开发平台-小程序-代码模版库管理") | |||
| public class WechatWeappDraftTemplateController { | |||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private WxOpenService openService; | |||
| @GetMapping("/tempDraftList") | |||
| public ResultData getTempDraftList() { | |||
| try { | |||
| List<WxOpenMaCodeTemplate> list = openService.getWxOpenComponentService().getTemplateDraftList(); | |||
| return new ResultData(list); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @GetMapping("/tempList") | |||
| public ResultData getTempList() { | |||
| try { | |||
| List<WxOpenMaCodeTemplate> list = openService.getWxOpenComponentService().getTemplateList(); | |||
| return new ResultData(list); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @PostMapping("/addToTemplate") | |||
| public ResultData addToTemplate(@RequestBody WxOpenMaCodeTemplate template) { | |||
| if(template == null || template.getDraftId() == null) { | |||
| return new ResultData(Result.ERROR, "draftId is null"); | |||
| } | |||
| try { | |||
| openService.getWxOpenComponentService().addToTemplate(template.getDraftId()); | |||
| return new ResultData(); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @PostMapping("/deleteTemplate") | |||
| public ResultData deleteTemplate(@RequestBody WxOpenMaCodeTemplate template) { | |||
| if(template == null || template.getTemplateId() == null) { | |||
| return new ResultData(Result.ERROR, "templateId is null"); | |||
| } | |||
| try { | |||
| openService.getWxOpenComponentService().deleteTemplate(template.getTemplateId()); | |||
| return new ResultData(); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,135 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||
| import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult; | |||
| import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryGetResult; | |||
| import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; | |||
| import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateListResult; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxAuthorizerInfo; | |||
| import com.iformall.enums.EnumWxAuthorizationStatus; | |||
| import com.iformall.service.WxAuthorizerInfoService; | |||
| import com.iformall.service.wechat.WxOpenService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| /** | |||
| * Stormeye Wu | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/weappMsgTemplate") | |||
| @Api(description = "微信第三方开发平台-小程序-消息模板设置") | |||
| public class WechatWeappMsgTemplateController { | |||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private WxOpenService openService; | |||
| @Autowired | |||
| private WxAuthorizerInfoService authorizerInfoService; | |||
| @ApiOperation("获取小程序模板库标题列表") | |||
| @GetMapping("getTmpLibList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "appId", value = "appId", dataType = "String", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData getTmpLibList(String appId, Integer pageNum, Integer pageSize) { | |||
| try { | |||
| WxMaService maService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxMaTemplateLibraryListResult ret = maService.getTemplateService().findTemplateLibraryList(pageNum, pageSize); | |||
| return new ResultData(ret); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("获取模板库某个模板标题下关键词库") | |||
| @GetMapping("getTemplateLibraryKeywordList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "appId", value = "appId", dataType = "String", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "id", value = "页数", dataType = "String", paramType = "query", required = true)}) | |||
| public ResultData findTemplateLibraryKeywordList(String appId, String id) { | |||
| try { | |||
| WxMaService maService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxMaTemplateLibraryGetResult ret = maService.getTemplateService().findTemplateLibraryKeywordList(id); | |||
| return new ResultData(ret); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("组合模板并添加至帐号下的个人模板库") | |||
| @PostMapping("addTemplate") | |||
| public ResultData addTemplate(String appId, String id, List<Integer> keywordIdList) { | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| try { | |||
| WxMaService maService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxMaTemplateAddResult ret = maService.getTemplateService().addTemplate(id, keywordIdList); | |||
| authorizerInfo.setTemplateStatus(0); | |||
| authorizerInfo.setTemplateTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| authorizerInfoService.updateTemplate(authorizerInfo); | |||
| return new ResultData(ret); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| authorizerInfo.setTemplateStatus(1); | |||
| authorizerInfo.setTemplateTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| authorizerInfoService.updateTemplate(authorizerInfo); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("获取帐号下已存在的模板列表") | |||
| @GetMapping("getTemplateList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "appId", value = "appId", dataType = "String", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData findTemplateList(String appId, Integer pageNum, Integer pageSize) { | |||
| try { | |||
| WxMaService maService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxMaTemplateListResult ret = maService.getTemplateService().findTemplateList(pageNum, pageSize); | |||
| return new ResultData(ret); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("删除帐号下的某个模板") | |||
| @PostMapping("delTemplate") | |||
| public ResultData delTemplate(@RequestParam(value = "appId") String appId, @RequestParam(value = "templateId") String templateId) { | |||
| try { | |||
| WxMaService maService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| maService.getTemplateService().delTemplate(templateId); | |||
| return new ResultData(); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,230 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxAuthorizerInfo; | |||
| import com.iformall.enums.EnumWxAuthorizationStatus; | |||
| import com.iformall.service.WxAuthorizerInfoService; | |||
| import com.iformall.service.wechat.WxOpenService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.open.api.WxOpenMaService; | |||
| import me.chanjar.weixin.open.bean.result.*; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| /** | |||
| * Stormeye Wu | |||
| */ | |||
| @RestController | |||
| @RequestMapping("/weappSet") | |||
| @Api(description = "微信第三方开发平台-小程序设置") | |||
| public class WechatWeappSetController { | |||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private WxOpenService openService; | |||
| @Autowired | |||
| private WxAuthorizerInfoService authorizerInfoService; | |||
| @ApiOperation("获取小程序的信息") | |||
| @GetMapping("/getInfo") | |||
| public ResultData getAccountBasicInfo(String appId) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| String openRet = openMaService.getAccountBasicInfo(); | |||
| logger.info(openRet.toString()); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| return new ResultData(Result.ERROR); | |||
| } | |||
| @ApiOperation("获取小程序服务器域名") | |||
| @GetMapping("/getDomain") | |||
| public ResultData getDomain(String appId) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenResult openRet = openMaService.getDomain(); | |||
| logger.info(openRet.toString()); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation("获取小程序服务器域名") | |||
| @GetMapping("/getWebDomain") | |||
| public ResultData getWebDomain(String appId) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| String openRet = openMaService.getWebViewDomain(); | |||
| logger.info(openRet); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation(value = "设置小程序服务器域名", notes = "{\n" + | |||
| " \"action\":\"add/set/delete/get\",\n" + | |||
| " \"requestdomain\":[\"https://www.qq.com\",\"https://www.qq.com\"],\n" + | |||
| " \"wsrequestdomain\":[\"wss://www.qq.com\",\"wss://www.qq.com\"],\n" + | |||
| " \"uploaddomain\":[\"https://www.qq.com\",\"https://www.qq.com\"],\n" + | |||
| " \"downloaddomain\":[\"https://www.qq.com\",\"https://www.qq.com\"],\n" + | |||
| " }") | |||
| @PostMapping("/modifyDomain") | |||
| public ResultData modifyDomain(String appId, String action, | |||
| List<String> requestDomain, List<String> wsrequestdomain, | |||
| List<String> uploaddomain, List<String> downloaddomain) { | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenMaDomainResult openRet = openMaService.modifyDomain(action, | |||
| requestDomain, wsrequestdomain, | |||
| uploaddomain, downloaddomain); | |||
| logger.info(openRet.toString()); | |||
| if(openRet.isSuccess()) { | |||
| logger.info("设置服务器域名成功"); | |||
| authorizerInfo.setDomainStatus(0); | |||
| authorizerInfo.setDomainTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| } else { | |||
| logger.info("设置服务器域名成功"); | |||
| authorizerInfo.setDomainStatus(1); | |||
| authorizerInfo.setDomainTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| } | |||
| authorizerInfoService.updateDomainUrl(authorizerInfo); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| return new ResultData(Result.ERROR); | |||
| } | |||
| @ApiOperation(value = "设置小程序业务域名", notes = "{\n" + | |||
| " \"action\":\"add/set/delete/get\",\n" + | |||
| " \"webviewdomain\":[\"https://www.qq.com\",\"https://m.qq.com\"]\n" + | |||
| " }") | |||
| @PostMapping("/modifyWebViewDomain") | |||
| public ResultData modifyWebViewDomain(String appId, String action, | |||
| List<String> urlList) { | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| String openRet = openMaService.setWebViewDomain(action, urlList); | |||
| logger.info(openRet); | |||
| JSONObject webRetObj = JSON.parseObject(openRet); | |||
| if(webRetObj.getInteger("errcode").equals(0)) { | |||
| logger.info("设置服务器业务域名成功"); | |||
| authorizerInfo.setWebdomainStatus(0); | |||
| authorizerInfo.setWebdomainTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| } else { | |||
| logger.info("设置服务器业务域名失败"); | |||
| authorizerInfo.setWebdomainStatus(1); | |||
| authorizerInfo.setWebdomainTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| } | |||
| authorizerInfoService.updateWebDomainUrl(authorizerInfo); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| return new ResultData(Result.ERROR); | |||
| } | |||
| @ApiOperation(value = "绑定微信用户为小程序体验者", notes = "{\"appId\":\"string\", \"wechatId\":\"string\"}") | |||
| @PostMapping("/bindTester") | |||
| public ResultData bindTester(@RequestBody Map<String, String> params) { | |||
| String appId = params.get("appId"); | |||
| String wechatId = params.get("wechatId"); | |||
| if(StringUtils.isBlank(appId)) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "appId不能为空"); | |||
| } | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(StringUtils.isBlank(wechatId)) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "wechatId不能为空"); | |||
| } | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenResult openRet = openMaService.bindTester(wechatId); | |||
| logger.info(openRet.toString()); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation(value = "解除绑定小程序的体验者", notes = "") | |||
| @PostMapping("/unbindTester") | |||
| public ResultData unbindTester(@RequestBody Map<String, String> params) { | |||
| String appId = params.get("appId"); | |||
| String wechatId = params.get("wechatId"); | |||
| if(StringUtils.isBlank(appId)) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "appId不能为空"); | |||
| } | |||
| if(StringUtils.isBlank(wechatId)) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "wechatId不能为空"); | |||
| } | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenResult openRet = openMaService.unbindTester(wechatId); | |||
| logger.info(openRet.toString()); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(e.getMessage()); | |||
| } | |||
| } | |||
| @ApiOperation(value = "获取体验者列表", notes = "") | |||
| @GetMapping("/getTesterList") | |||
| public ResultData getTesterList(@RequestParam(value = "appId") String appId) { | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| WxOpenResult openRet = openMaService.getTesterList(); | |||
| logger.info(openRet.toString()); | |||
| return new ResultData(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| return new ResultData(Result.ERROR); | |||
| } | |||
| } | |||
| @@ -1,62 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxWeappBasicSet; | |||
| import com.iformall.service.WxWeappBasicSetService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Controller; | |||
| import org.springframework.web.bind.annotation.*; | |||
| /** | |||
| * Stormeye Wu | |||
| */ | |||
| @Controller | |||
| @RequestMapping("/weappBasicSet") | |||
| @Api(description = "小程序基础设置接口") | |||
| public class WxWeappBasicSetController extends BaseController { | |||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private Integer getFmDelay; | |||
| @Autowired | |||
| private WxWeappBasicSetService weappBasicSetService; | |||
| @ApiOperation("分页列表接口") | |||
| @GetMapping("list") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData list(@ModelAttribute WxWeappBasicSet weappBasicSet, Integer pageNum, Integer pageSize) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappBasicSetController::list"); | |||
| if (null == weappBasicSet) weappBasicSet = new WxWeappBasicSet(); | |||
| weappBasicSet.setDeploy(getFmDelay); | |||
| final PageInfo<WxWeappBasicSet> page = weappBasicSetService.listAsPage(weappBasicSet, pageNum, pageSize); | |||
| return new ResultData(page); | |||
| } | |||
| @PostMapping("add") | |||
| public ResultData add(WxWeappBasicSet weappBasicSet) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappBasicSetController::add"); | |||
| if (null == weappBasicSet) return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| weappBasicSetService.saveOrUpdate(weappBasicSet); | |||
| return new ResultData(); | |||
| } | |||
| @PostMapping("update") | |||
| public ResultData update(WxWeappBasicSet weappBasicSet) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappBasicSetController::update"); | |||
| if (null == weappBasicSet) return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| weappBasicSetService.saveOrUpdate(weappBasicSet); | |||
| return new ResultData(); | |||
| } | |||
| } | |||
| @@ -1,61 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.WxWeappExtSet; | |||
| import com.iformall.service.WxWeappExtSetService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Controller; | |||
| import org.springframework.web.bind.annotation.GetMapping; | |||
| import org.springframework.web.bind.annotation.ModelAttribute; | |||
| import org.springframework.web.bind.annotation.PostMapping; | |||
| import org.springframework.web.bind.annotation.RequestMapping; | |||
| /** | |||
| * Stormeye Wu | |||
| */ | |||
| @Controller | |||
| @RequestMapping("/weappExtSet") | |||
| @Api(description = "小程序扩展设置接口") | |||
| public class WxWeappExtSetController extends BaseController { | |||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private WxWeappExtSetService weappExtSetService; | |||
| @ApiOperation("分页列表接口") | |||
| @GetMapping("list") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData list(@ModelAttribute WxWeappExtSet weappExtSet, Integer pageNum, Integer pageSize) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappExtSetController::list"); | |||
| if (null == weappExtSet) weappExtSet = new WxWeappExtSet(); | |||
| final PageInfo<WxWeappExtSet> page = weappExtSetService.listAsPage(weappExtSet, pageNum, pageSize); | |||
| return new ResultData(page); | |||
| } | |||
| @PostMapping("add") | |||
| public ResultData add(WxWeappExtSet weappExtSet) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappExtSetController::add"); | |||
| if (null == weappExtSet) return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| weappExtSetService.saveOrUpdate(weappExtSet); | |||
| return new ResultData(); | |||
| } | |||
| @PostMapping("update") | |||
| public ResultData update(WxWeappExtSet weappExtSet) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappBasicSetController::update"); | |||
| if (null == weappExtSet) return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| weappExtSetService.saveOrUpdate(weappExtSet); | |||
| return new ResultData(); | |||
| } | |||
| } | |||
| @@ -1,952 +0,0 @@ | |||
| package com.iformall.controller; | |||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||
| import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateAddResult; | |||
| import com.alibaba.fastjson.JSON; | |||
| import com.alibaba.fastjson.JSONArray; | |||
| import com.alibaba.fastjson.JSONObject; | |||
| import com.github.pagehelper.PageInfo; | |||
| import com.google.gson.Gson; | |||
| import com.google.gson.GsonBuilder; | |||
| import com.google.gson.reflect.TypeToken; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.common.Result; | |||
| import com.iformall.common.ResultData; | |||
| import com.iformall.domain.po.*; | |||
| import com.iformall.domain.vo.WxWeappAuditStatusVo; | |||
| import com.iformall.domain.vo.WxWeappCodeStatusVo; | |||
| import com.iformall.domain.vo.WxWeappInfo; | |||
| import com.iformall.domain.vo.WxWeappReleaseStatusVo; | |||
| import com.iformall.enums.*; | |||
| import com.iformall.service.*; | |||
| import com.iformall.service.wechat.WxOpenService; | |||
| import io.swagger.annotations.Api; | |||
| import io.swagger.annotations.ApiImplicitParam; | |||
| import io.swagger.annotations.ApiImplicitParams; | |||
| import io.swagger.annotations.ApiOperation; | |||
| import io.swagger.models.auth.In; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.open.api.WxOpenMaService; | |||
| import me.chanjar.weixin.open.bean.ma.WxMaOpenCommitExtInfo; | |||
| import me.chanjar.weixin.open.bean.message.WxOpenMaSubmitAuditMessage; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenMaDomainResult; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenMaQueryAuditResult; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenMaSubmitAuditResult; | |||
| import me.chanjar.weixin.open.bean.result.WxOpenResult; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.stereotype.Controller; | |||
| import org.springframework.web.bind.annotation.*; | |||
| import java.util.*; | |||
| /** | |||
| * Stormeye Wu | |||
| */ | |||
| @Controller | |||
| @RequestMapping("/weapp") | |||
| @Api(description = "小程序") | |||
| public class WxWeappInfoController extends BaseController { | |||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private Integer getFmDelay; | |||
| @Autowired | |||
| private WxAuthorizerInfoService authorizerInfoService; | |||
| @Autowired | |||
| private WxWeappBasicSetService weappBasicSetService; | |||
| @Autowired | |||
| private WxWeappExtSetService weappExtSetService; | |||
| @Autowired | |||
| private WxWeappCodeStatusService weappCodeStatusService; | |||
| @Autowired | |||
| private WxWeappAuditStatusService weappAuditStatusService; | |||
| @Autowired | |||
| private WxWeappReleaseStatusService weappReleaseStatusService; | |||
| @Autowired | |||
| private WxOpenService openService; | |||
| @Autowired | |||
| private WxAppinfoService appinfoService; | |||
| @Autowired | |||
| private WxTemplateMsgService templateMsgService; | |||
| @ApiOperation(value = "小程序分页列表接口", notes = "查询支持小程序类型,名称,appid,version") | |||
| @GetMapping("list") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData list(@ModelAttribute WxWeappInfo weappInfo, Integer pageNum, Integer pageSize) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::list"); | |||
| if (null == weappInfo) { | |||
| weappInfo = new WxWeappInfo(); | |||
| } else { | |||
| if(StringUtils.isBlank(weappInfo.getName())) { | |||
| weappInfo.setName(null); | |||
| } | |||
| } | |||
| weappInfo.setSortColumns(WxWeappInfo.Field.Name_ASC,WxWeappInfo.Field.Type_ASC); | |||
| final PageInfo<WxWeappInfo> page = authorizerInfoService.listVoAsPage(weappInfo, pageNum, pageSize); | |||
| return new ResultData(page); | |||
| } | |||
| @ApiOperation("小程序列表接口") | |||
| @GetMapping("allist") | |||
| public ResultData getList(@ModelAttribute WxWeappInfo weappInfo) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::list"); | |||
| if (null == weappInfo) { | |||
| weappInfo = new WxWeappInfo(); | |||
| } else { | |||
| if(StringUtils.isBlank(weappInfo.getName())) { | |||
| weappInfo.setName(null); | |||
| } | |||
| } | |||
| weappInfo.setSortColumns(WxAuthorizerInfo.Field.CurrentVersion_DESC); | |||
| final List<WxWeappInfo> list = authorizerInfoService.getList(weappInfo); | |||
| return new ResultData(list); | |||
| } | |||
| @ApiOperation(value = "APPs基础设置(服务器域名、业务域名、基础版本、微信模板)", notes = "{\"apps\":\"appid,appid\",\"type\":\"String\"}") | |||
| @PostMapping("batchBasicSet") | |||
| public ResultData batchSet(@RequestBody Map<String, String> params) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchBasicSet"); | |||
| String appsStr = params.get("apps"); | |||
| String typeStr = params.get("type"); | |||
| if(StringUtils.isBlank(typeStr)) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "type参数不能为空"); | |||
| } | |||
| Integer type = 0; | |||
| try { | |||
| type = Integer.parseInt(typeStr); | |||
| } catch (Exception e) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); | |||
| } | |||
| // 检查基础配置参数 | |||
| WxWeappBasicSet weappBasicSetQ = new WxWeappBasicSet(); | |||
| weappBasicSetQ.setType(type); | |||
| weappBasicSetQ.setDeploy(getFmDelay); | |||
| WxWeappBasicSet weappBasicSet = weappBasicSetService.getByTypeAndDeploy(weappBasicSetQ); | |||
| if(weappBasicSet == null) { | |||
| logger.error("未找到相关的基础设置参数"); | |||
| return new ResultData(ErrorCode.WEAPP_BASIC_SET_ERR); | |||
| } | |||
| JSONObject domainObj = JSON.parseObject(weappBasicSet.getDomainUrl()); | |||
| if(domainObj == null) { | |||
| logger.error("未找到相关的基础设置参数"); | |||
| return new ResultData(ErrorCode.WEAPP_BASIC_SET_DOMAIN_ERR); | |||
| } | |||
| JSONObject templeObj = JSON.parseObject(weappBasicSet.getTemplateInfo()); | |||
| if(StringUtils.isBlank(appsStr)) { | |||
| WxWeappInfo weappInfoQ = new WxWeappInfo(); | |||
| weappInfoQ.setType(type); | |||
| List<WxWeappInfo> list = authorizerInfoService.getList(weappInfoQ); | |||
| for(WxWeappInfo info: list) { | |||
| appsStr += info.getAuthorizerAppid() + ","; | |||
| } | |||
| appsStr = appsStr.substring(0, appsStr.length() - 1); | |||
| } | |||
| // 逐一设置app配置 | |||
| String [] apps = appsStr.split(","); | |||
| for(String appId: apps) { | |||
| // 检查appId是否已授权 | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| ResultData openRet = setBasicForAppId(appId, weappBasicSet, domainObj, templeObj); | |||
| if (openRet != null) return openRet; | |||
| } | |||
| return new ResultData(); | |||
| } | |||
| private ResultData setBasicForAppId(String appId, WxWeappBasicSet weappBasicSet, JSONObject domainObj, JSONObject templeObj) { | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| // 设置基础版本 | |||
| String versionRet = openMaService.setSupportVersion(weappBasicSet.getVersion()); | |||
| logger.info(versionRet); | |||
| JSONObject verObj = JSON.parseObject(versionRet); | |||
| if(verObj.getInteger("errcode").equals(0)) { | |||
| authorizerInfo.setBaseStatus(0); | |||
| } else { | |||
| authorizerInfo.setBaseStatus(1); | |||
| } | |||
| authorizerInfo.setBaseTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| authorizerInfoService.updateBaseVersion(authorizerInfo); | |||
| // 服务器域名 | |||
| String action = "set"; | |||
| JSONObject urlObj = domainObj.getJSONObject("url"); | |||
| List<String> requestDomain = getUrlList(urlObj.getJSONArray("requestdomain")); | |||
| List<String> wsrequestDomain = getUrlList(urlObj.getJSONArray("wsrequestdomain")); | |||
| List<String> uploadDomain = getUrlList(urlObj.getJSONArray("requestdomain")); | |||
| List<String> downloadDomain = getUrlList(urlObj.getJSONArray("requestdomain")); | |||
| WxOpenMaDomainResult openRet = openMaService.modifyDomain(action, | |||
| requestDomain, wsrequestDomain, | |||
| uploadDomain, downloadDomain); | |||
| logger.info(openRet.toString()); | |||
| if(openRet.isSuccess()) { | |||
| logger.info("设置服务器域名成功"); | |||
| authorizerInfo.setDomainStatus(0); | |||
| authorizerInfo.setDomainTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| } else { | |||
| logger.info("设置服务器域名成功"); | |||
| authorizerInfo.setDomainStatus(1); | |||
| authorizerInfo.setDomainTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| } | |||
| authorizerInfoService.updateDomainUrl(authorizerInfo); | |||
| // 业务域名 | |||
| JSONObject webObj = domainObj.getJSONObject("web"); | |||
| List<String> urlList = getUrlList(webObj.getJSONArray("webviewdomain")); | |||
| String openRet1 = openMaService.setWebViewDomain(action, urlList); | |||
| logger.info(openRet1); | |||
| JSONObject webRetObj = JSON.parseObject(openRet1); | |||
| if(webRetObj.getInteger("errcode").equals(0)) { | |||
| logger.info("设置服务器业务域名成功"); | |||
| authorizerInfo.setWebdomainStatus(0); | |||
| authorizerInfo.setWebdomainTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| } else { | |||
| logger.info("设置服务器业务域名失败"); | |||
| authorizerInfo.setWebdomainStatus(1); | |||
| authorizerInfo.setWebdomainTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| } | |||
| authorizerInfoService.updateWebDomainUrl(authorizerInfo); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| // 设置微信模板 | |||
| if(weappBasicSet.getType().equals(EnumAppType.C.getCode())) { | |||
| WxAppinfo appinfo = appinfoService.getByAppId(appId); | |||
| try { | |||
| WxMaService maService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appId); | |||
| // 核销成功消息 | |||
| JSONObject verify_success = templeObj.getJSONObject("verify_success"); | |||
| JSONArray keyidlist = verify_success.getJSONArray("keyword_id_list"); | |||
| List<Integer> keyArr = getIdList(keyidlist); | |||
| WxMaTemplateAddResult ret = maService.getTemplateService().addTemplate(verify_success.getString("id"), keyArr); | |||
| logger.info(ret.toString()); | |||
| if(appinfo != null) { | |||
| // wx_template_msg | |||
| WxTemplateMsg templateMsgQ = new WxTemplateMsg(); | |||
| templateMsgQ.setTenantId(appinfo.getTenantId()); | |||
| templateMsgQ.setType(EnumTemplateType.VERIFY_SUCCESS.getCode()); | |||
| WxTemplateMsg templateMsg = templateMsgService.getByObj(templateMsgQ); | |||
| if(templateMsg != null) { | |||
| templateMsg.setTemplateId(ret.getTemplateId()); | |||
| templateMsgService.saveOrUpdate(templateMsg); | |||
| } else { | |||
| templateMsgQ.setTemplateId(ret.getTemplateId()); | |||
| templateMsgService.saveOrUpdate(templateMsgQ); | |||
| } | |||
| } | |||
| // 核销失败消息 | |||
| JSONObject verify_fail = templeObj.getJSONObject("verify_fail"); | |||
| keyidlist = verify_fail.getJSONArray("keyword_id_list"); | |||
| List<Integer> keyArr1 = getIdList(keyidlist); | |||
| ret = maService.getTemplateService().addTemplate(verify_fail.getString("id"), keyArr1); | |||
| logger.info(ret.toString()); | |||
| if(appinfo != null) { | |||
| // wx_template_msg | |||
| WxTemplateMsg templateMsgQ = new WxTemplateMsg(); | |||
| templateMsgQ.setTenantId(appinfo.getTenantId()); | |||
| templateMsgQ.setType(EnumTemplateType.VERIFY_FAIL.getCode()); | |||
| WxTemplateMsg templateMsg = templateMsgService.getByObj(templateMsgQ); | |||
| if(templateMsg != null) { | |||
| templateMsg.setTemplateId(ret.getTemplateId()); | |||
| templateMsgService.saveOrUpdate(templateMsg); | |||
| } else { | |||
| templateMsgQ.setTemplateId(ret.getTemplateId()); | |||
| templateMsgService.saveOrUpdate(templateMsgQ); | |||
| } | |||
| } | |||
| // 更新状态 | |||
| authorizerInfo.setTemplateStatus(0); | |||
| authorizerInfo.setTemplateTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| authorizerInfoService.updateTemplate(authorizerInfo); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| // 更新状态 | |||
| authorizerInfo.setTemplateStatus(1); | |||
| authorizerInfo.setTemplateTime(new Date()); | |||
| authorizerInfo.setUpdateTime(new Date()); | |||
| authorizerInfoService.updateTemplate(authorizerInfo); | |||
| return new ResultData(Result.ERROR, e.getMessage()); | |||
| } | |||
| } | |||
| // 设置成功返回null | |||
| return null; | |||
| } | |||
| private List<Integer> getIdList(JSONArray keyidlist) { | |||
| List<Integer> keyArr = new ArrayList<Integer>(); | |||
| for (int i = 0; i < keyidlist.size(); i++) { | |||
| keyArr.add(keyidlist.getIntValue(i)); | |||
| } | |||
| return keyArr; | |||
| } | |||
| private List<String> getUrlList(JSONArray urlList) { | |||
| List<String> keyArr = new ArrayList<String>(); | |||
| for (int i = 0; i < urlList.size(); i++) { | |||
| keyArr.add(urlList.getString(i)); | |||
| } | |||
| return keyArr; | |||
| } | |||
| @ApiOperation(value = "批量授权的小程序code提交", notes = "{\"apps\":\"appid,appid\",\"templateId\":\"String\",\"type\":\"String\",\"userVersion\":\"String\",\"userDesc\":\"String\"}") | |||
| @PostMapping("batchCodeCommit") | |||
| public ResultData batchCodeCommit(@RequestBody Map<String, String> params) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchExtSet"); | |||
| String appsStr = params.get("apps"); | |||
| String templateIdStr = params.get("templateId"); | |||
| String typeStr = params.get("type"); | |||
| String userVersion = params.get("userVersion"); | |||
| String userDesc = params.get("userDesc"); | |||
| Integer type = null; | |||
| Long templateId = null; | |||
| try { | |||
| templateId = Long.parseLong(templateIdStr); | |||
| } catch (Exception e) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); | |||
| } | |||
| try { | |||
| type = Integer.parseInt(typeStr); | |||
| } catch (Exception e) { | |||
| logger.error("type为null"); | |||
| } | |||
| if(StringUtils.isBlank(appsStr)) { | |||
| if(type == null) { | |||
| logger.error("type为null"); | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_ERROR); | |||
| } | |||
| WxWeappInfo authQ = new WxWeappInfo(); | |||
| authQ.setType(type); | |||
| List<WxWeappInfo> appList = authorizerInfoService.getList(authQ); | |||
| appsStr = ""; | |||
| StringBuilder sb = new StringBuilder(); | |||
| boolean bfirst = true; | |||
| for(WxWeappInfo app: appList) { | |||
| if(bfirst) { | |||
| sb.append(app.getAuthorizerAppid()); | |||
| bfirst = false; | |||
| } else { | |||
| sb.append(app.getAuthorizerAppid()).append(","); | |||
| } | |||
| } | |||
| } | |||
| String [] apps = appsStr.split(","); | |||
| // 逐一检查app的设置 | |||
| for(String appId: apps) { | |||
| WxWeappExtSet extSetQ = new WxWeappExtSet(); | |||
| extSetQ.setAppId(appId); | |||
| WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ); | |||
| if(extSet == null) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| if(StringUtils.isBlank(extSet.getExtJson())) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| if(StringUtils.isBlank(extSet.getReleaseJson())) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| } | |||
| // 逐一设置app配置 | |||
| for(String appId: apps) { | |||
| // 检查appId是否已授权 | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| codeCommit(appId, userVersion, userDesc, templateId); | |||
| } | |||
| return new ResultData(); | |||
| } | |||
| private void codeCommit(String appId, String userVersion, String userDesc, Long templateId) { | |||
| WxAppinfo appinfo = appinfoService.getByAppId(appId); | |||
| int iAppType = 0; | |||
| String appTypeStr = userVersion.substring(0, 1); | |||
| if(appTypeStr.equalsIgnoreCase("C")) | |||
| iAppType = EnumAppType.C.getCode(); | |||
| else if(appTypeStr.equalsIgnoreCase("B")) | |||
| iAppType = EnumAppType.B.getCode(); | |||
| if(!appinfo.getType().equals(iAppType)) { | |||
| // 如果版本号与小程序的类型不一致,不提交版本 | |||
| return; | |||
| } | |||
| // get ext json | |||
| WxWeappExtSet extSetQ = new WxWeappExtSet(); | |||
| extSetQ.setAppId(appId); | |||
| WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ); | |||
| WxWeappCodeStatus codeStatus = weappCodeStatusService.getByAppId(appId); | |||
| if(extSet != null) { | |||
| boolean codeCommitStatus = false; | |||
| if(codeStatus != null && codeStatus.getCodeStatus().equals(0) && codeStatus.getUserVersion().equals(userVersion)) { | |||
| codeCommitStatus = true; | |||
| } | |||
| if(!codeCommitStatus) { | |||
| codeCommitStatus = doCodeCommit(userVersion, userDesc, templateId, appinfo, extSet, codeStatus); | |||
| } | |||
| } | |||
| } | |||
| @ApiOperation(value = "小程序批量提交审核", notes = "{\"type\":\"String\",\"userVersion\":\"String\",\"apps\":\"appid,appid\"}") | |||
| @PostMapping("batchCodeAudit") | |||
| public ResultData batchCodeAudit(@RequestBody Map<String, String> params) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchExtSet"); | |||
| String appsStr = params.get("apps"); | |||
| String typeStr = params.get("type"); | |||
| String userVersion = params.get("userVersion"); | |||
| Integer type = null; | |||
| try { | |||
| type = Integer.parseInt(typeStr); | |||
| } catch (Exception e) { | |||
| logger.error("小程序类型"); | |||
| } | |||
| if(StringUtils.isBlank(appsStr)) { | |||
| if(type == null) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| WxWeappInfo authQ = new WxWeappInfo(); | |||
| authQ.setType(type); | |||
| List<WxWeappInfo> appList = authorizerInfoService.getList(authQ); | |||
| appsStr = ""; | |||
| StringBuilder sb = new StringBuilder(); | |||
| boolean bfirst = true; | |||
| for(WxWeappInfo app: appList) { | |||
| if(bfirst) { | |||
| sb.append(app.getAuthorizerAppid()); | |||
| bfirst = false; | |||
| } else { | |||
| sb.append(app.getAuthorizerAppid()).append(","); | |||
| } | |||
| } | |||
| } | |||
| String [] apps = appsStr.split(","); | |||
| // 逐一检查app的设置 | |||
| for(String appId: apps) { | |||
| WxWeappExtSet extSetQ = new WxWeappExtSet(); | |||
| extSetQ.setAppId(appId); | |||
| WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ); | |||
| if(extSet == null) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| if(StringUtils.isBlank(extSet.getExtJson())) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| if(StringUtils.isBlank(extSet.getReleaseJson())) { | |||
| return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL); | |||
| } | |||
| } | |||
| // 逐一设置app配置 | |||
| for(String appId: apps) { | |||
| // 检查appId是否已授权 | |||
| WxAuthorizerInfo authorizerInfo = authorizerInfoService.getByAppId(appId); | |||
| if(authorizerInfo == null) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| if(!authorizerInfo.getAuthorizationStatus().equals(EnumWxAuthorizationStatus.AUTHORIZED.getCode())) { | |||
| return new ResultData(ErrorCode.WEAPP_APPID_NOT_AUTH); | |||
| } | |||
| codeAudit(appId, userVersion); | |||
| } | |||
| return new ResultData(); | |||
| } | |||
| private void codeAudit(String appId, String userVersion) { | |||
| // get ext json | |||
| WxWeappExtSet extSetQ = new WxWeappExtSet(); | |||
| extSetQ.setAppId(appId); | |||
| WxWeappExtSet extSet = weappExtSetService.getByObj(extSetQ); | |||
| WxWeappCodeStatus codeStatus = weappCodeStatusService.getByAppId(appId); | |||
| if(extSet != null) { | |||
| boolean codeCommitStatus = false; | |||
| if(codeStatus != null | |||
| && codeStatus.getCodeStatus().equals(EnumWeappCodeCommitStatus.SUCCESS.getCode()) | |||
| && codeStatus.getUserVersion().equals(userVersion)) { | |||
| codeCommitStatus = true; | |||
| } | |||
| if(codeCommitStatus) { | |||
| WxWeappAuditStatus auditStatus = weappAuditStatusService.getByAppId(appId); | |||
| if(auditStatus != null && auditStatus.getAuditStatus().equals(EnumWeappAuditStatus.AUDITING.getCode())) { | |||
| logger.error("审核中不能再提交审核"); | |||
| return; | |||
| } | |||
| doCodeAudit(codeStatus, auditStatus, extSet); | |||
| } else { | |||
| logger.error("CODE提交失败"); | |||
| } | |||
| } | |||
| } | |||
| private boolean doCodeCommit(String userVersion, String userDesc, Long templateId, WxAppinfo appinfo, WxWeappExtSet extSet, WxWeappCodeStatus codeStatus) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| // code提交 | |||
| boolean codeCommitStatus = false; | |||
| String codeErrCode = ""; | |||
| try { | |||
| WxMaOpenCommitExtInfo extInfo = gson.fromJson(extSet.getExtJson(), new TypeToken<WxMaOpenCommitExtInfo>() {}.getType()); | |||
| logger.info("OLD: " + extInfo.toString()); | |||
| // 自动修改提交的版本 | |||
| if(extInfo.getExtMap().containsKey("appVersion")) { | |||
| extInfo.getExtMap().put("appVersion", userVersion); | |||
| } | |||
| logger.info("NEW: " + extInfo.toString()); | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appinfo.getAppId()); | |||
| WxOpenResult openRet = openMaService.codeCommit(templateId, userVersion, userDesc, extInfo); | |||
| logger.info(openRet.toString()); | |||
| if (openRet.isSuccess()) { | |||
| codeCommitStatus = true; | |||
| } | |||
| codeErrCode = gson.toJson(openRet); | |||
| } catch (WxErrorException e) { | |||
| codeCommitStatus = false; | |||
| codeErrCode = e.getMessage(); | |||
| logger.error(codeErrCode); | |||
| } | |||
| if (codeStatus == null) { | |||
| codeStatus = new WxWeappCodeStatus(); | |||
| codeStatus.setId(appinfo.getId()); | |||
| codeStatus.setAppId(appinfo.getAppId()); | |||
| if (appinfo != null) { | |||
| codeStatus.setType(appinfo.getType()); | |||
| } | |||
| codeStatus.setUserVersion(userVersion); | |||
| codeStatus.setVersionDesc(userDesc); | |||
| if(codeCommitStatus) { | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.SUCCESS.getCode()); | |||
| } else { | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.FAIL.getCode()); | |||
| } | |||
| codeStatus.setCodeErrCode(codeErrCode); | |||
| codeStatus.setCodeTime(new Date()); | |||
| weappCodeStatusService.saveStatus(codeStatus); | |||
| } else { | |||
| codeStatus.setUserVersion(userVersion); | |||
| codeStatus.setVersionDesc(userDesc); | |||
| if(codeCommitStatus) { | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.SUCCESS.getCode()); | |||
| } else { | |||
| codeStatus.setCodeStatus(EnumWeappCodeCommitStatus.FAIL.getCode()); | |||
| } | |||
| codeStatus.setCodeErrCode(codeErrCode); | |||
| codeStatus.setCodeTime(new Date()); | |||
| weappCodeStatusService.updateStatus(codeStatus); | |||
| } | |||
| return codeCommitStatus; | |||
| } | |||
| private void doCodeAudit(WxWeappCodeStatus codeStatus, WxWeappAuditStatus auditStatus, WxWeappExtSet extSet) { | |||
| Gson gson = new GsonBuilder().create(); | |||
| boolean submitStatus = false; | |||
| Long auditid = null; | |||
| String codeErrCode = ""; | |||
| try { | |||
| WxOpenMaSubmitAuditMessage subMessage = gson.fromJson(extSet.getReleaseJson(), new TypeToken<WxOpenMaSubmitAuditMessage>() {}.getType()); | |||
| logger.info(subMessage.toString()); | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(codeStatus.getAppId()); | |||
| WxOpenMaSubmitAuditResult openRet = openMaService.submitAudit(subMessage); | |||
| logger.info(openRet.toString()); | |||
| if(openRet.isSuccess()) { | |||
| submitStatus = true; | |||
| auditid = openRet.getAuditId(); | |||
| } else { | |||
| submitStatus = false; | |||
| } | |||
| codeErrCode = gson.toJson(openRet); | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| submitStatus = false; | |||
| codeErrCode = e.getMessage(); | |||
| } | |||
| if (auditStatus == null) { | |||
| auditStatus = new WxWeappAuditStatus(); | |||
| auditStatus.setId(codeStatus.getId()); | |||
| auditStatus.setAppId(codeStatus.getAppId()); | |||
| auditStatus.setType(codeStatus.getType()); | |||
| auditStatus.setUserVersion(codeStatus.getUserVersion()); | |||
| auditStatus.setVersionDesc(codeStatus.getVersionDesc()); | |||
| if(submitStatus) { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| auditStatus.setAuditid(auditid); | |||
| } else { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode()); | |||
| } | |||
| auditStatus.setAuditErrCode(codeErrCode); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.saveStatus(auditStatus); | |||
| } else { | |||
| if(!submitStatus) { | |||
| if(!auditStatus.getUserVersion().equals(codeStatus.getUserVersion()) | |||
| && auditStatus.getAuditStatus().equals(EnumWeappAuditStatus.AUDITING.getCode())) { | |||
| // 当前审核中的数据不能替换 | |||
| return; | |||
| } | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode()); | |||
| } else { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| auditStatus.setAuditid(auditid); | |||
| } | |||
| auditStatus.setUserVersion(codeStatus.getUserVersion()); | |||
| auditStatus.setVersionDesc(codeStatus.getVersionDesc()); | |||
| auditStatus.setAuditErrCode(codeErrCode); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.updateStatus(auditStatus); | |||
| } | |||
| } | |||
| @ApiOperation(value = "批量审核查询", notes = "{\"type\":\"string\",\"version\":\"string\"}") | |||
| @PostMapping("batchAuditQuery") | |||
| public ResultData batchAuditQuery(@RequestBody Map<String, String> params) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchAuditQuery"); | |||
| Gson gson = new GsonBuilder().create(); | |||
| String typeStr = params.get("type"); | |||
| String version = params.get("version"); | |||
| Integer type = null; | |||
| try { | |||
| type = Integer.parseInt(typeStr); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| WxWeappAuditStatusVo queryVo = new WxWeappAuditStatusVo(); | |||
| if(StringUtils.isNotBlank(typeStr)) { | |||
| queryVo.setType(type); | |||
| } | |||
| if(StringUtils.isNotBlank(version)) { | |||
| queryVo.setUserVersion(version); | |||
| } | |||
| queryVo.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| List<WxWeappAuditStatusVo> apps = weappAuditStatusService.getList(queryVo); | |||
| apps.stream().forEach( auditStatus -> { | |||
| // 审核中,可以发起审核查询 | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(auditStatus.getAppId()); | |||
| WxOpenMaQueryAuditResult openResult = openMaService.getLatestAuditStatus(); | |||
| logger.info(openResult.toString()); | |||
| if (openResult.isSuccess()) { | |||
| // 审核状态,其中0为审核成功,1为审核失败,2为审核中,3已撤回 | |||
| switch (openResult.getStatus().intValue()) { | |||
| case 0: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode()); | |||
| break; | |||
| case 1: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.FAIL.getCode()); | |||
| break; | |||
| case 2: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| break; | |||
| case 3: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.UNDO.getCode()); | |||
| break; | |||
| default: | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| break; | |||
| } | |||
| auditStatus.setAuditErrCode(gson.toJson(openResult)); | |||
| auditStatus.setAuditid(openResult.getAuditId()); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.updateStatus(auditStatus); | |||
| } | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| }); | |||
| return new ResultData(); | |||
| } | |||
| @ApiOperation(value = "批量审核撤回", notes = "{\"type\":\"string\",\"version\":\"string\"}") | |||
| @PostMapping("batchAuditCancel") | |||
| public ResultData batchAuditCancel(@RequestBody Map<String, String> params) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchAuditCancel"); | |||
| Gson gson = new GsonBuilder().create(); | |||
| String typeStr = params.get("type"); | |||
| String version = params.get("version"); | |||
| Integer type = null; | |||
| try { | |||
| type = Integer.parseInt(typeStr); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| WxWeappAuditStatusVo queryVo = new WxWeappAuditStatusVo(); | |||
| if(StringUtils.isNotBlank(typeStr)) { | |||
| queryVo.setType(type); | |||
| } | |||
| if(StringUtils.isNotBlank(version)) { | |||
| queryVo.setUserVersion(version); | |||
| } | |||
| queryVo.setAuditStatus(EnumWeappAuditStatus.AUDITING.getCode()); | |||
| List<WxWeappAuditStatusVo> apps = weappAuditStatusService.getList(queryVo); | |||
| apps.stream().forEach( auditStatus -> { | |||
| // 审核通过,已发布不可撤回 | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(auditStatus.getAppId()); | |||
| WxOpenResult openResult = openMaService.undoCodeAudit(); | |||
| logger.info(openResult.toString()); | |||
| if(openResult.isSuccess()) { | |||
| auditStatus.setAuditStatus(EnumWeappAuditStatus.UNDO.getCode()); | |||
| auditStatus.setAuditErrCode(gson.toJson(openResult)); | |||
| auditStatus.setAuditTime(new Date()); | |||
| weappAuditStatusService.updateStatus(auditStatus); | |||
| } | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| }); | |||
| return new ResultData(); | |||
| } | |||
| @ApiOperation(value = "批量发布", notes = "{\"type\":\"string\", \"version\":\"string\"}") | |||
| @PostMapping("batchRelease") | |||
| public ResultData batchRelease(@RequestBody Map<String, String> params) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::batchRelease"); | |||
| Gson gson = new GsonBuilder().create(); | |||
| String typeStr = params.get("type"); | |||
| String version = params.get("version"); | |||
| Integer type = null; | |||
| try { | |||
| type = Integer.parseInt(typeStr); | |||
| } catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| WxWeappAuditStatusVo queryVo = new WxWeappAuditStatusVo(); | |||
| if(StringUtils.isNotBlank(typeStr)) { | |||
| queryVo.setType(type); | |||
| } | |||
| if(StringUtils.isNotBlank(version)) { | |||
| queryVo.setUserVersion(version); | |||
| } | |||
| queryVo.setAuditStatus(EnumWeappAuditStatus.SUCCESS.getCode()); | |||
| List<WxWeappAuditStatusVo> apps = weappAuditStatusService.getList(queryVo); | |||
| apps.stream().forEach( auditStatus -> { | |||
| boolean isUpdate = false; | |||
| WxWeappReleaseStatus releaseStatus = weappReleaseStatusService.getByAppId(auditStatus.getAppId()); | |||
| if(releaseStatus != null) { | |||
| // 当前版本已发布成功,跳过 | |||
| if(releaseStatus.getUserVersion().equals(version) | |||
| && releaseStatus.getReleaseStatus().equals(EnumWeappReleaseStatus.SUCCESS.getCode())) { | |||
| return; | |||
| } | |||
| releaseStatus.setUserVersion(auditStatus.getUserVersion()); | |||
| releaseStatus.setVersionDesc(auditStatus.getVersionDesc()); | |||
| } else { | |||
| releaseStatus = new WxWeappReleaseStatus(); | |||
| releaseStatus.setId(auditStatus.getId()); | |||
| releaseStatus.setAppId(auditStatus.getAppId()); | |||
| releaseStatus.setType(auditStatus.getType()); | |||
| releaseStatus.setUserVersion(auditStatus.getUserVersion()); | |||
| releaseStatus.setVersionDesc(auditStatus.getVersionDesc()); | |||
| isUpdate = true; | |||
| } | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(auditStatus.getAppId()); | |||
| WxOpenResult openRet = openMaService.releaesAudited(); | |||
| logger.info(openRet.toString()); | |||
| boolean releaseSuccess = false; | |||
| if(openRet.isSuccess()) { | |||
| releaseSuccess = true; | |||
| } | |||
| if(releaseSuccess) { | |||
| releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.SUCCESS.getCode()); | |||
| } else { | |||
| releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.FAIL.getCode()); | |||
| } | |||
| releaseStatus.setReleaseErrCode(gson.toJson(openRet)); | |||
| releaseStatus.setReleaseTime(new Date()); | |||
| if(isUpdate) { | |||
| weappReleaseStatusService.updateStatus(releaseStatus); | |||
| } else { | |||
| weappReleaseStatusService.saveStatus(releaseStatus); | |||
| } | |||
| } catch (WxErrorException e) { | |||
| logger.error(e.getMessage()); | |||
| releaseStatus.setReleaseStatus(EnumWeappReleaseStatus.FAIL.getCode()); | |||
| releaseStatus.setReleaseErrCode(e.getMessage()); | |||
| releaseStatus.setReleaseTime(new Date()); | |||
| if(isUpdate) { | |||
| weappReleaseStatusService.updateStatus(releaseStatus); | |||
| } else { | |||
| weappReleaseStatusService.saveStatus(releaseStatus); | |||
| } | |||
| } | |||
| }); | |||
| return new ResultData(); | |||
| } | |||
| @ApiOperation(value = "小程序code提交状态分页列表接口", notes = "查询支持小程序类型,名称,appid,version") | |||
| @GetMapping("codeStatusList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData codeStatusList(@ModelAttribute WxWeappCodeStatusVo weappCodeStatusVo, Integer pageNum, Integer pageSize) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::codeStatusList"); | |||
| if (null == weappCodeStatusVo) { | |||
| weappCodeStatusVo = new WxWeappCodeStatusVo(); | |||
| } else { | |||
| if(StringUtils.isBlank(weappCodeStatusVo.getAppId())) { | |||
| weappCodeStatusVo.setAppId(null); | |||
| } | |||
| if(StringUtils.isBlank(weappCodeStatusVo.getName())) { | |||
| weappCodeStatusVo.setName(null); | |||
| } | |||
| } | |||
| weappCodeStatusVo.setSortColumns(WxWeappCodeStatus.Field.UserVersion_DESC); | |||
| final PageInfo<WxWeappCodeStatusVo> page = weappCodeStatusService.listAsPage(weappCodeStatusVo, pageNum, pageSize); | |||
| return new ResultData(page); | |||
| } | |||
| @ApiOperation(value = "小程序审核状态分页列表接口", notes = "查询支持小程序类型,名称,appid,version") | |||
| @GetMapping("auditStatusList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData auditStatusList(@ModelAttribute WxWeappAuditStatusVo weappAuditStatusVo, Integer pageNum, Integer pageSize) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::auditStatusList"); | |||
| if (null == weappAuditStatusVo) { | |||
| weappAuditStatusVo = new WxWeappAuditStatusVo(); | |||
| } else { | |||
| if(StringUtils.isBlank(weappAuditStatusVo.getAppId())) { | |||
| weappAuditStatusVo.setAppId(null); | |||
| } | |||
| if(StringUtils.isBlank(weappAuditStatusVo.getName())) { | |||
| weappAuditStatusVo.setName(null); | |||
| } | |||
| } | |||
| weappAuditStatusVo.setSortColumns(WxWeappAuditStatus.Field.UserVersion_DESC); | |||
| final PageInfo<WxWeappAuditStatusVo> page = weappAuditStatusService.listAsPage(weappAuditStatusVo, pageNum, pageSize); | |||
| return new ResultData(page); | |||
| } | |||
| @ApiOperation(value = "小程序发布状态分页列表接口", notes = "查询支持小程序类型,名称,appid,version") | |||
| @GetMapping("releaseStatusList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData releaseStatusList(@ModelAttribute WxWeappReleaseStatusVo weappReleaseStatusVo, Integer pageNum, Integer pageSize) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::releaseStatusList"); | |||
| if (null == weappReleaseStatusVo) { | |||
| weappReleaseStatusVo = new WxWeappReleaseStatusVo(); | |||
| } else { | |||
| if(StringUtils.isBlank(weappReleaseStatusVo.getAppId())) { | |||
| weappReleaseStatusVo.setAppId(null); | |||
| } | |||
| if(StringUtils.isBlank(weappReleaseStatusVo.getName())) { | |||
| weappReleaseStatusVo.setName(null); | |||
| } | |||
| } | |||
| weappReleaseStatusVo.setSortColumns(WxWeappReleaseStatus.Field.UserVersion_DESC); | |||
| final PageInfo<WxWeappReleaseStatusVo> page = weappReleaseStatusService.listAsPage(weappReleaseStatusVo, pageNum, pageSize); | |||
| return new ResultData(page); | |||
| } | |||
| @ApiOperation("小程序code提交版本列表") | |||
| @GetMapping("codeVersionList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "type", value = "小程序类型", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData getCodeVersionList(Integer type) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::getCodeVersionList"); | |||
| final List<Map> list = weappCodeStatusService.getVersionList(type); | |||
| return new ResultData(list); | |||
| } | |||
| @ApiOperation("小程序审核版本列表") | |||
| @GetMapping("auditVersionList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "type", value = "小程序类型", dataType = "int", paramType = "query", required = true), | |||
| @ApiImplicitParam(name = "status", value = "审核状态", dataType = "int", paramType = "query")}) | |||
| public ResultData getAuditVersionList(Integer type, Integer status) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::getAuditVersionList"); | |||
| final List<Map> list = weappAuditStatusService.getVersionList(type, status); | |||
| return new ResultData(list); | |||
| } | |||
| @ApiOperation("小程序发布版本列表") | |||
| @GetMapping("releaseVersionList") | |||
| @ApiImplicitParams({ | |||
| @ApiImplicitParam(name = "type", value = "小程序类型", dataType = "int", paramType = "query", required = true)}) | |||
| public ResultData getReleaseVersionList(Integer type) { | |||
| logger.debug("[" + getIpAddr() + "] WxWeappInfoController::getReleaseVersionList"); | |||
| final List<Map> list = weappReleaseStatusService.getVersionList(type); | |||
| return new ResultData(list); | |||
| } | |||
| /* | |||
| * 0. 回调搭建好 | |||
| * 1. wx_appinfo配置好 | |||
| * | |||
| * 10. 授权 | |||
| * 11. 设置服务器域名及业务域名 - B/C 配置表 | |||
| * C 服务器域名 c.malls.iformall.com | |||
| * 业务域名 c.malls.iformall.com,game.malls.iformall.com | |||
| * B 服务器域名 b.malls.iformall.com | |||
| * 业务域名 mobile.malls.iformall.com,admin.malls.iformall.com | |||
| * C 服务器域名 ciformall.youlane.cn | |||
| * 业务域名 ciformall.youlane.cn,game.youlane.cn | |||
| * B 服务器域名 biformall.youlane.cn | |||
| * 业务域名 mobile.youlane.cn,mall.youlane.cn | |||
| * C 服务器域名 ctest.malls.iformall.com | |||
| * 业务域名 ctest.malls.iformall.com,gametest.malls.iformall.com | |||
| * B 服务器域名 btest.malls.iformall.com | |||
| * 业务域名 mobiletest.malls.iformall.com,admintest.malls.iformall.com | |||
| * 12. 设置微信基础版本 - 配置 | |||
| * 2.0.9 | |||
| * 13. 设置微信模板 - 配置 | |||
| * 核销成功模板 AT0423 14,15,16,7,10,3,9 | |||
| * 核销失败模板 AT1824 1,3,4,5 | |||
| * 14. 草稿提交 | |||
| * 15. 模板 | |||
| * 16. 上传小程序代码 - 配置 ext.json | |||
| * 17. 体验二维码 | |||
| * 18. 提交审核 - json --- 获取审核ID | |||
| * 19. 获取审核结果 - 基于审核ID查询 -- event 回调 | |||
| * 20. 审核撤回 | |||
| * 21. 发布已通过审核的小程序 | |||
| * 22. oauth2refreshAccessToken | |||
| */ | |||
| } | |||
| @@ -1,18 +0,0 @@ | |||
| package com.iformall.schedule; | |||
| import org.springframework.context.annotation.Configuration; | |||
| import org.springframework.scheduling.annotation.EnableScheduling; | |||
| import org.springframework.scheduling.annotation.SchedulingConfigurer; | |||
| import org.springframework.scheduling.config.ScheduledTaskRegistrar; | |||
| @Configuration | |||
| @EnableScheduling | |||
| public class SchedulingConfig implements SchedulingConfigurer { | |||
| @Override | |||
| public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { | |||
| } | |||
| } | |||
| @@ -1,146 +0,0 @@ | |||
| package com.iformall.schedule; | |||
| import cn.binarywang.wx.miniapp.api.WxMaService; | |||
| import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; | |||
| import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; | |||
| import com.google.common.collect.Lists; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.domain.po.WxAppinfo; | |||
| import com.iformall.domain.po.WxPayAccount; | |||
| import com.iformall.domain.vo.WxPayOrderVo; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.mapper.WxPayAccountMapper; | |||
| import com.iformall.mapper.WxPayOrderMapper; | |||
| import com.iformall.service.WxAppinfoService; | |||
| import com.iformall.service.wechat.WxOpenService; | |||
| import com.iformall.utils.MaUtil; | |||
| import me.chanjar.weixin.common.error.WxErrorException; | |||
| import me.chanjar.weixin.open.api.WxOpenMaService; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.scheduling.annotation.Scheduled; | |||
| import org.springframework.stereotype.Component; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Date; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| @Component | |||
| public class UserUnionIdSchedule { | |||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||
| private final int TIME_OUT_VALUE = 4 * 60 * 1000; //4分钟 | |||
| @Autowired | |||
| WxPayOrderMapper payOrderMapper; | |||
| @Autowired | |||
| private WxOpenService openService; | |||
| @Autowired | |||
| private WxPayAccountMapper payAccountMapper; | |||
| @Autowired | |||
| WxAppinfoService wxAppinfoService; | |||
| @Scheduled(cron = "0 */4 * * * *?") // 每4分钟检查一次 | |||
| //@Scheduled(cron = "*/10 * * * * ?") // 测试10秒中一次 | |||
| public void payOrderGetUnionIdSchedule() { | |||
| Map dateMap = new HashMap(); | |||
| Date curDate = new Date(); | |||
| Date expireDate = new Date(curDate.getTime() - TIME_OUT_VALUE ); | |||
| // 券相关订单 | |||
| dateMap.put("startDate", expireDate); | |||
| List<WxPayOrderVo> paidList = payOrderMapper.findListOfPaidOrderByDate(dateMap); | |||
| paidList.parallelStream().forEach( payOrderVo -> { | |||
| getUnionId(payOrderVo); | |||
| //sendUniformMessage(payOrderVo); | |||
| }); | |||
| } | |||
| /** | |||
| * 根据payOrder信息获取UnionId | |||
| * @param payOrderVo | |||
| */ | |||
| public void getUnionId(WxPayOrderVo payOrderVo) { | |||
| if(StringUtils.isBlank(payOrderVo.getOpenId())) { | |||
| return; | |||
| } | |||
| try { | |||
| WxOpenMaService openMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(payOrderVo.getAppId()); | |||
| if(StringUtils.isNotBlank(payOrderVo.getTransactionId())) { | |||
| String openRet = openMaService.getApiGetPaidUnionid(payOrderVo.getOpenId(), payOrderVo.getTransactionId()); | |||
| logger.info(openRet); | |||
| } else { | |||
| WxPayAccount payAccount = payAccountMapper.selectByPrimaryKey(payOrderVo.getPayId()); | |||
| if(payAccount != null) { | |||
| String openRet = openMaService.getApiGetPaidUnionid(payOrderVo.getOpenId(), payAccount.getMchId(), payOrderVo.getPayOrderNo()); | |||
| logger.info(openRet); | |||
| } | |||
| } | |||
| }catch (Exception e) { | |||
| logger.error(e.getMessage()); | |||
| } | |||
| } | |||
| /** | |||
| * 根据payOrder发送模板消息 | |||
| * @param payOrderVo | |||
| */ | |||
| public void sendUniformMessage(WxPayOrderVo payOrderVo) { | |||
| if(StringUtils.isBlank(payOrderVo.getOpenId())) { | |||
| return; | |||
| } | |||
| SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); | |||
| /** | |||
| * 卡券核销通知 p6pwzZN9GVJq11j2zh72EEhIn5fAIa6oQBBOjqVt8-U | |||
| * {{first.DATA}} | |||
| * 卡券类型:{{keyword1.DATA}} | |||
| * 卡券号码:{{keyword2.DATA}} | |||
| * 核销时间:{{keyword3.DATA}} | |||
| * {{remark.DATA}} | |||
| * | |||
| */ | |||
| String template_id = "p6pwzZN9GVJq11j2zh72EEhIn5fAIa6oQBBOjqVt8-U"; | |||
| WxMaUniformMessage.MiniProgram miniprogram = new WxMaUniformMessage.MiniProgram(); | |||
| miniprogram.setAppid(payOrderVo.getAppId()); | |||
| miniprogram.setPagePath("pages/index/index"); | |||
| miniprogram.setUsePath(true); | |||
| WxMaUniformMessage templateMessage = WxMaUniformMessage.builder() | |||
| .isMpTemplateMsg(true) | |||
| .toUser(payOrderVo.getOpenId()) | |||
| .appid("wxed2f44705544b892") | |||
| .templateId(template_id) | |||
| .url("http://iformall.com") | |||
| .page("pages/index/index") | |||
| .formId(payOrderVo.getPrepayId()) // 微信支付的formId是prepayId | |||
| .miniProgram(miniprogram) | |||
| .data(Lists.newArrayList( | |||
| new WxMaTemplateData("first", payOrderVo.getAppId(), "#173177"), | |||
| new WxMaTemplateData("keyword1", payOrderVo.getOpenId(), "#173177"), | |||
| new WxMaTemplateData("keyword2", payOrderVo.getTransactionId(), "#173177"), | |||
| new WxMaTemplateData("keyword3", dateFormat.format(new Date()), "#173177") | |||
| )) | |||
| .emphasisKeyword("keyword1.DATA") | |||
| .build(); | |||
| WxAppinfo appInfo = wxAppinfoService.getByAppId(payOrderVo.getAppId()); | |||
| WxMaService wxMaService = MaUtil.getWeappService(appInfo); | |||
| try { | |||
| wxMaService.getMsgService().sendUniformMsg(templateMessage); | |||
| } catch (WxErrorException e) { | |||
| logger.error("支付通知测试: " + e.getMessage()); | |||
| throw new MallinkException(ErrorCode.TEMPLATE_SEND_FAILED); | |||
| } | |||
| } | |||
| } | |||
| @@ -1,223 +0,0 @@ | |||
| package com.iformall.service.wechat; | |||
| import com.iformall.mapper.WxComponentVerifyTicketMapper; | |||
| import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import redis.clients.jedis.Jedis; | |||
| import redis.clients.jedis.JedisPool; | |||
| import redis.clients.util.Pool; | |||
| public class WxOpenInRedisDBConfigStorage extends WxOpenInMemoryConfigStorage { | |||
| private final static String COMPONENT_VERIFY_TICKET_KEY = "wechat_component_verify_ticket:"; | |||
| private final static String COMPONENT_ACCESS_TOKEN_KEY = "wechat_component_access_token:"; | |||
| private final static String AUTHORIZER_REFRESH_TOKEN_KEY = "wechat_authorizer_refresh_token:"; | |||
| private final static String AUTHORIZER_ACCESS_TOKEN_KEY = "wechat_authorizer_access_token:"; | |||
| private final static String JSAPI_TICKET_KEY = "wechat_jsapi_ticket:"; | |||
| private final static String CARD_API_TICKET_KEY = "wechat_card_api_ticket:"; | |||
| protected final Pool<Jedis> jedisPool; | |||
| /** | |||
| * redis 存储的 key 的前缀,可为空 | |||
| */ | |||
| private String keyPrefix; | |||
| private String componentVerifyTicketKey; | |||
| private String componentAccessTokenKey; | |||
| private String authorizerRefreshTokenKey; | |||
| private String authorizerAccessTokenKey; | |||
| private String jsapiTicketKey; | |||
| private String cardApiTicket; | |||
| @Autowired | |||
| WxComponentVerifyTicketMapper wxComponentVerifyTicketMapper; | |||
| public WxOpenInRedisDBConfigStorage(Pool<Jedis> jedisPool) { | |||
| this.jedisPool = jedisPool; | |||
| } | |||
| public WxOpenInRedisDBConfigStorage(Pool<Jedis> jedisPool, String keyPrefix) { | |||
| this.jedisPool = jedisPool; | |||
| this.keyPrefix = keyPrefix; | |||
| } | |||
| public WxOpenInRedisDBConfigStorage(JedisPool jedisPool) { | |||
| this.jedisPool = jedisPool; | |||
| } | |||
| @Override | |||
| public void setComponentAppId(String componentAppId) { | |||
| super.setComponentAppId(componentAppId); | |||
| String prefix = StringUtils.isBlank(keyPrefix) ? "" : | |||
| (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":")); | |||
| componentVerifyTicketKey = prefix + COMPONENT_VERIFY_TICKET_KEY.concat(componentAppId); | |||
| componentAccessTokenKey = prefix + COMPONENT_ACCESS_TOKEN_KEY.concat(componentAppId); | |||
| authorizerRefreshTokenKey = prefix + AUTHORIZER_REFRESH_TOKEN_KEY.concat(componentAppId); | |||
| authorizerAccessTokenKey = prefix + AUTHORIZER_ACCESS_TOKEN_KEY.concat(componentAppId); | |||
| this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(componentAppId); | |||
| this.cardApiTicket = CARD_API_TICKET_KEY.concat(componentAppId); | |||
| } | |||
| @Override | |||
| public String getComponentVerifyTicket() { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.get(this.componentVerifyTicketKey); | |||
| } | |||
| } | |||
| @Override | |||
| public void setComponentVerifyTicket(String componentVerifyTicket) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.set(this.componentVerifyTicketKey, componentVerifyTicket); | |||
| } | |||
| // TODO update to DB | |||
| } | |||
| @Override | |||
| public String getComponentAccessToken() { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.get(this.componentAccessTokenKey); | |||
| } | |||
| } | |||
| @Override | |||
| public boolean isComponentAccessTokenExpired() { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.ttl(this.componentAccessTokenKey) < 2; | |||
| } | |||
| } | |||
| @Override | |||
| public void expireComponentAccessToken(){ | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.expire(this.componentAccessTokenKey, 0); | |||
| } | |||
| } | |||
| @Override | |||
| public void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.setex(this.componentAccessTokenKey, expiresInSeconds - 200, componentAccessToken); | |||
| } | |||
| // TODO update to DB | |||
| } | |||
| private String getKey(String prefix, String appId) { | |||
| return prefix.endsWith(":") ? prefix.concat(appId) : prefix.concat(":").concat(appId); | |||
| } | |||
| @Override | |||
| public String getAuthorizerRefreshToken(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.get(this.getKey(this.authorizerRefreshTokenKey, appId)); | |||
| } | |||
| } | |||
| @Override | |||
| public void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.set(this.getKey(this.authorizerRefreshTokenKey, appId), authorizerRefreshToken); | |||
| } | |||
| // TODO update to DB | |||
| } | |||
| @Override | |||
| public String getAuthorizerAccessToken(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.get(this.getKey(this.authorizerAccessTokenKey, appId)); | |||
| } | |||
| } | |||
| @Override | |||
| public boolean isAuthorizerAccessTokenExpired(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.ttl(this.getKey(this.authorizerAccessTokenKey, appId)) < 2; | |||
| } | |||
| } | |||
| @Override | |||
| public void expireAuthorizerAccessToken(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.expire(this.getKey(this.authorizerAccessTokenKey, appId), 0); | |||
| } | |||
| // TODO update to DB | |||
| } | |||
| @Override | |||
| public void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.setex(this.getKey(this.authorizerAccessTokenKey, appId), expiresInSeconds - 200, authorizerAccessToken); | |||
| } | |||
| // TODO update to DB | |||
| } | |||
| /* | |||
| @Override | |||
| public void changeAuthorizationStatus(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.expire(this.getKey(this.authorizerAccessTokenKey, appId), 0); | |||
| } | |||
| // TODO update to DB | |||
| } | |||
| */ | |||
| @Override | |||
| public String getJsapiTicket(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.get(this.getKey(this.jsapiTicketKey, appId)); | |||
| } | |||
| } | |||
| @Override | |||
| public boolean isJsapiTicketExpired(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.ttl(this.getKey(this.jsapiTicketKey, appId)) < 2; | |||
| } | |||
| } | |||
| @Override | |||
| public void expireJsapiTicket(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.expire(this.getKey(this.jsapiTicketKey, appId), 0); | |||
| } | |||
| } | |||
| @Override | |||
| public void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.setex(this.getKey(this.jsapiTicketKey, appId), expiresInSeconds - 200, jsapiTicket); | |||
| } | |||
| // TODO update to DB | |||
| } | |||
| @Override | |||
| public String getCardApiTicket(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.get(this.getKey(this.cardApiTicket, appId)); | |||
| } | |||
| } | |||
| @Override | |||
| public boolean isCardApiTicketExpired(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| return jedis.ttl(this.getKey(this.cardApiTicket, appId)) < 2; | |||
| } | |||
| } | |||
| @Override | |||
| public void expireCardApiTicket(String appId) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.expire(this.getKey(this.cardApiTicket, appId), 0); | |||
| } | |||
| } | |||
| @Override | |||
| public void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds) { | |||
| try (Jedis jedis = this.jedisPool.getResource()) { | |||
| jedis.setex(this.getKey(this.cardApiTicket, appId), expiresInSeconds - 200, cardApiTicket); | |||
| } | |||
| // TODO update to DB | |||
| } | |||
| } | |||
| @@ -1,64 +0,0 @@ | |||
| package com.iformall.service.wechat; | |||
| import com.iformall.config.RedisProperies; | |||
| import com.iformall.config.WechatOpenProperties; | |||
| import me.chanjar.weixin.open.api.impl.WxOpenMessageRouter; | |||
| import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||
| import org.springframework.stereotype.Service; | |||
| import redis.clients.jedis.JedisPool; | |||
| import javax.annotation.PostConstruct; | |||
| /** | |||
| * Stormeye WU | |||
| */ | |||
| @Service | |||
| @EnableConfigurationProperties({WechatOpenProperties.class, RedisProperies.class}) | |||
| public class WxOpenService extends WxOpenServiceImpl { | |||
| private Logger logger = LoggerFactory.getLogger(getClass()); | |||
| @Autowired | |||
| private WechatOpenProperties wechatProperties; | |||
| @Autowired | |||
| private RedisProperies redisProperies; | |||
| private static JedisPool pool; | |||
| private WxOpenMessageRouter wxOpenMessageRouter; | |||
| @PostConstruct | |||
| public void init() { | |||
| WxOpenInRedisDBConfigStorage configStorage = new WxOpenInRedisDBConfigStorage(getJedisPool()); | |||
| configStorage.setComponentAppId(wechatProperties.getComponentAppId()); | |||
| configStorage.setComponentAppSecret(wechatProperties.getComponentSecret()); | |||
| configStorage.setComponentToken(wechatProperties.getComponentToken()); | |||
| configStorage.setComponentAesKey(wechatProperties.getComponentAesKey()); | |||
| setWxOpenConfigStorage(configStorage); | |||
| wxOpenMessageRouter = new WxOpenMessageRouter(this); | |||
| wxOpenMessageRouter.rule().handler((wxMpXmlMessage, map, wxMpService, wxSessionManager) -> { | |||
| logger.info("\n接收到 {} 公众号请求消息,内容:{}", wxMpService.getWxMpConfigStorage().getAppId(), wxMpXmlMessage); | |||
| return null; | |||
| }).next(); | |||
| } | |||
| public WxOpenMessageRouter getWxOpenMessageRouter() { | |||
| return wxOpenMessageRouter; | |||
| } | |||
| private JedisPool getJedisPool() { | |||
| if (pool == null) { | |||
| synchronized (WxOpenService.class) { | |||
| if (pool == null) { | |||
| pool = new JedisPool(redisProperies, redisProperies.getHost(), | |||
| redisProperies.getPort(), redisProperies.getConnectionTimeout(), | |||
| redisProperies.getSoTimeout(), redisProperies.getPassword(), | |||
| redisProperies.getDatabase(), redisProperies.getClientName(), | |||
| redisProperies.isSsl(), redisProperies.getSslSocketFactory(), | |||
| redisProperies.getSslParameters(), redisProperies.getHostnameVerifier()); | |||
| } | |||
| } | |||
| } | |||
| return pool; | |||
| } | |||
| } | |||
| @@ -1,24 +0,0 @@ | |||
| package com.iformall.shiro; | |||
| import com.iformall.enums.EnumLoginType; | |||
| import org.apache.shiro.authc.AuthenticationInfo; | |||
| import org.apache.shiro.authc.AuthenticationToken; | |||
| import org.apache.shiro.authc.credential.HashedCredentialsMatcher; | |||
| import org.springframework.context.annotation.Configuration; | |||
| @Configuration | |||
| public class MyRetryLimitCredentialsMatcher extends HashedCredentialsMatcher { | |||
| @Override | |||
| public boolean doCredentialsMatch(AuthenticationToken authcToken, AuthenticationInfo info) { | |||
| if(authcToken instanceof UseriFormallToken) { | |||
| UseriFormallToken tk = (UseriFormallToken) authcToken; | |||
| if(tk.getType().equals(EnumLoginType.NOPASSWD)){ | |||
| return true; | |||
| } | |||
| boolean matches = super.doCredentialsMatch(authcToken, info); | |||
| return matches; | |||
| } | |||
| boolean matches =super.doCredentialsMatch(authcToken, info); | |||
| return matches; | |||
| } | |||
| } | |||
| @@ -1,90 +0,0 @@ | |||
| package com.iformall.shiro; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.enums.EnumMallUserStatus; | |||
| import com.iformall.service.MallPermissionService; | |||
| import com.iformall.service.MallUserInfoService; | |||
| import org.apache.shiro.SecurityUtils; | |||
| import org.apache.shiro.authc.*; | |||
| import org.apache.shiro.authz.AuthorizationInfo; | |||
| import org.apache.shiro.authz.SimpleAuthorizationInfo; | |||
| import org.apache.shiro.realm.AuthorizingRealm; | |||
| import org.apache.shiro.session.Session; | |||
| import org.apache.shiro.subject.PrincipalCollection; | |||
| import org.apache.shiro.util.ByteSource; | |||
| import javax.annotation.Resource; | |||
| /** | |||
| * Created by yangqj on 2017/4/21. | |||
| */ | |||
| public class MyShiroRealm extends AuthorizingRealm { | |||
| @Resource | |||
| private MallUserInfoService userService; | |||
| @Resource | |||
| private MallPermissionService resourcesService; | |||
| //授权 | |||
| @Override | |||
| protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) { | |||
| MallUserInfo user= (MallUserInfo) SecurityUtils.getSubject().getPrincipal();//User{id=1, username='admin', password='3ef7164d1f6167cb9f2658c07d3c2f0a', enable=1} | |||
| // Map<String,Object> map = new HashMap<String,Object>(); | |||
| // map.put("userid",user.getId()); | |||
| // List<SysPermission> resourcesList = resourcesService.list(map); | |||
| // 权限信息对象info,用来存放查出的用户的所有的角色(role)及权限(permission) | |||
| SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); | |||
| // for(SysPermission resources: resourcesList){ | |||
| // info.addStringPermission(resources.getUrl()); | |||
| // } | |||
| return info; | |||
| } | |||
| //认证 | |||
| @Override | |||
| protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { | |||
| //获取用户的输入的账号. | |||
| String username = (String)token.getPrincipal(); | |||
| MallUserInfo user = userService.getByUsername(username); | |||
| if(user == null) { | |||
| throw new UnknownAccountException("用户名不存在"); | |||
| } | |||
| // if (0==user.getEnable()) { | |||
| // throw new LockedAccountException(); // 帐号锁定 | |||
| // } | |||
| //用户被禁用 | |||
| if(user.getStatus()==null || | |||
| !EnumMallUserStatus.VALID.getCode().equals(user.getStatus())) { | |||
| throw new DisabledAccountException("用户被禁用"); | |||
| } | |||
| if(!user.getTenantId().equals("1")) { | |||
| // 只支持租户为1的用户 | |||
| throw new UnknownAccountException("用户名不支持"); | |||
| } | |||
| SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( | |||
| user, //用户 | |||
| user.getPassword(), //密码 | |||
| ByteSource.Util.bytes(username), | |||
| getName() //realm name | |||
| ); | |||
| // 当验证都通过后,把用户信息放在session里 | |||
| Session session = SecurityUtils.getSubject().getSession(); | |||
| session.setAttribute(UserSession.userInfo, user); | |||
| session.setAttribute(UserSession.userId, user.getId()); | |||
| session.setAttribute(UserSession.tenantId, user.getTenantId()); | |||
| return authenticationInfo; | |||
| } | |||
| /** | |||
| * 指定principalCollection 清除 | |||
| */ | |||
| /* public void clearCachedAuthorizationInfo(PrincipalCollection principalCollection) { | |||
| SimplePrincipalCollection principals = new SimplePrincipalCollection( | |||
| principalCollection, getName()); | |||
| super.clearCachedAuthorizationInfo(principals); | |||
| } | |||
| */ | |||
| } | |||
| @@ -1,32 +0,0 @@ | |||
| package com.iformall.shiro; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import org.apache.shiro.crypto.hash.SimpleHash; | |||
| import org.apache.shiro.util.ByteSource; | |||
| public class PasswordHelper { | |||
| //private RandomNumberGenerator randomNumberGenerator = new SecureRandomNumberGenerator(); | |||
| private String algorithmName = "md5"; | |||
| private int hashIterations = 2; | |||
| public void encryptPassword(MallUserInfo user) { | |||
| //String salt=randomNumberGenerator.nextBytes().toHex(); | |||
| String newPassword = new SimpleHash(algorithmName, user.getPassword(), ByteSource.Util.bytes(user.getUsername()), hashIterations).toHex(); | |||
| //String newPassword = new SimpleHash(algorithmName, user.getPassword()).toHex(); | |||
| user.setPassword(newPassword); | |||
| } | |||
| public static void main(String[] args) { | |||
| MallUserInfo user = new MallUserInfo(); | |||
| user.setUsername("fmadmin"); | |||
| user.setPassword("admin123"); | |||
| PasswordHelper passwordHelper = new PasswordHelper(); | |||
| passwordHelper.encryptPassword(user); | |||
| System.out.println(user); | |||
| System.out.println(user.getPassword()); | |||
| } | |||
| } | |||
| @@ -1,126 +0,0 @@ | |||
| package com.iformall.shiro; | |||
| import com.iformall.service.MallPermissionService; | |||
| import org.apache.shiro.spring.web.ShiroFilterFactoryBean; | |||
| import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager; | |||
| import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver; | |||
| import org.apache.shiro.web.servlet.AbstractShiroFilter; | |||
| import org.crazycake.shiro.RedisSessionDAO; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import java.util.LinkedHashMap; | |||
| import java.util.Map; | |||
| /** | |||
| * Created by yangqj on 2017/4/30. | |||
| */ | |||
| //@Service | |||
| public class ShiroService { | |||
| @Autowired | |||
| private ShiroFilterFactoryBean shiroFilterFactoryBean; | |||
| @Autowired | |||
| private MallPermissionService resourcesService; | |||
| @Autowired | |||
| private RedisSessionDAO redisSessionDAO; | |||
| /** | |||
| * 初始化权限 | |||
| */ | |||
| public Map<String, String> loadFilterChainDefinitions() { | |||
| // 权限控制map.从数据库获取 | |||
| Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); | |||
| filterChainDefinitionMap.put("/logout", "logout"); | |||
| filterChainDefinitionMap.put("/css/**","anon"); | |||
| filterChainDefinitionMap.put("/js/**","anon"); | |||
| filterChainDefinitionMap.put("/img/**","anon"); | |||
| filterChainDefinitionMap.put("/user/**","anon"); | |||
| filterChainDefinitionMap.put("/font-awesome/**","anon"); | |||
| // Map<String,Object> map = new HashMap<>(); | |||
| // List<SysPermission> resourcesList = resourcesService.list(map); | |||
| // for(SysPermission resources:resourcesList){ | |||
| // | |||
| // if (StringUtil.isNotEmpty(resources.getUrl())) { | |||
| // String permission = "perms[" + resources.getUrl()+ "]"; | |||
| // filterChainDefinitionMap.put(resources.getUrl(),permission); | |||
| // } | |||
| // } | |||
| filterChainDefinitionMap.put("/**", "authc"); | |||
| return filterChainDefinitionMap; | |||
| } | |||
| /** | |||
| * 重新加载权限 | |||
| */ | |||
| public void updatePermission() { | |||
| synchronized (shiroFilterFactoryBean) { | |||
| AbstractShiroFilter shiroFilter = null; | |||
| try { | |||
| shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean | |||
| .getObject(); | |||
| } catch (Exception e) { | |||
| throw new RuntimeException( | |||
| "get ShiroFilter from shiroFilterFactoryBean error!"); | |||
| } | |||
| PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter | |||
| .getFilterChainResolver(); | |||
| DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver | |||
| .getFilterChainManager(); | |||
| // 清空老的权限控制 | |||
| manager.getFilterChains().clear(); | |||
| shiroFilterFactoryBean.getFilterChainDefinitionMap().clear(); | |||
| shiroFilterFactoryBean | |||
| .setFilterChainDefinitionMap(loadFilterChainDefinitions()); | |||
| // 重新构建生成 | |||
| Map<String, String> chains = shiroFilterFactoryBean | |||
| .getFilterChainDefinitionMap(); | |||
| for (Map.Entry<String, String> entry : chains.entrySet()) { | |||
| String url = entry.getKey(); | |||
| String chainDefinition = entry.getValue().trim() | |||
| .replace(" ", ""); | |||
| manager.createChain(url, chainDefinition); | |||
| } | |||
| System.out.println("更新权限成功!!"); | |||
| } | |||
| } | |||
| /** | |||
| * 根据userId 清除当前session存在的用户的权限缓存 | |||
| * @param userIds 已经修改了权限的userId | |||
| */ | |||
| /* public void clearUserAuthByUserId(List<Integer> userIds){ | |||
| if(null == userIds || userIds.size() == 0) return ; | |||
| //获取所有session | |||
| Collection<Session> sessions = redisSessionDAO.getActiveSessions(); | |||
| //定义返回 | |||
| List<SimplePrincipalCollection> list = new ArrayList<SimplePrincipalCollection>(); | |||
| for (Session session:sessions){ | |||
| //获取session登录信息。 | |||
| Object obj = session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY); | |||
| if(null != obj && obj instanceof SimplePrincipalCollection){ | |||
| //强转 | |||
| SimplePrincipalCollection spc = (SimplePrincipalCollection)obj; | |||
| //判断用户,匹配用户ID。 | |||
| obj = spc.getPrimaryPrincipal(); | |||
| if(null != obj && obj instanceof User){ | |||
| User user = (User) obj; | |||
| System.out.println("user:"+user); | |||
| //比较用户ID,符合即加入集合 | |||
| if(null != user && userIds.contains(user.getId())){ | |||
| list.add(spc); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| RealmSecurityManager securityManager = | |||
| (RealmSecurityManager) SecurityUtils.getSecurityManager(); | |||
| MyShiroRealm realm = (MyShiroRealm)securityManager.getRealms().iterator().next(); | |||
| for (SimplePrincipalCollection simplePrincipalCollection : list) { | |||
| realm.clearCachedAuthorizationInfo(simplePrincipalCollection); | |||
| } | |||
| }*/ | |||
| } | |||
| @@ -1,11 +0,0 @@ | |||
| package com.iformall.shiro; | |||
| public class UserSession { | |||
| public static String userInfo="userSession"; | |||
| public static String userId ="userSessionId"; | |||
| public static String tenantId ="TENANT_ID"; | |||
| } | |||
| @@ -1,39 +0,0 @@ | |||
| package com.iformall.shiro; | |||
| import com.iformall.enums.EnumLoginType; | |||
| import org.apache.shiro.authc.UsernamePasswordToken; | |||
| public class UseriFormallToken extends UsernamePasswordToken { | |||
| private static final long serialVersionUID = -2564928913725078138L; | |||
| private EnumLoginType type; | |||
| public UseriFormallToken() { | |||
| super(); | |||
| } | |||
| public UseriFormallToken(String username, String password, EnumLoginType type, boolean rememberMe, String host) { | |||
| super(username, password, rememberMe, host); | |||
| this.type = type; | |||
| } | |||
| /** 免密登录 */ | |||
| public UseriFormallToken(String username) { | |||
| super(username, "", false, null); | |||
| this.type = EnumLoginType.NOPASSWD; | |||
| } | |||
| /** 账号密码登录 */ | |||
| public UseriFormallToken(String username, String pwd) { | |||
| super(username, pwd, false, null); | |||
| this.type = EnumLoginType.PASSWORD; | |||
| } | |||
| public EnumLoginType getType() { | |||
| return type; | |||
| } | |||
| public void setType(EnumLoginType type) { | |||
| this.type = type; | |||
| } | |||
| } | |||
| @@ -1,61 +0,0 @@ | |||
| package com.iformall.utils; | |||
| import com.iformall.common.ErrorCode; | |||
| import com.iformall.domain.po.MallUserInfo; | |||
| import com.iformall.exception.MallinkException; | |||
| import com.iformall.shiro.UserSession; | |||
| import org.apache.shiro.SecurityUtils; | |||
| import org.apache.shiro.session.Session; | |||
| import org.apache.shiro.subject.Subject; | |||
| /** | |||
| * Shiro工具类 | |||
| * | |||
| * @author stormeye.wu | |||
| * @email wugq@mippoint.com | |||
| * @date 2016年11月12日 上午9:49:19 | |||
| */ | |||
| public class ShiroUtils { | |||
| public static Session getSession() { | |||
| return SecurityUtils.getSubject().getSession(); | |||
| } | |||
| public static Subject getSubject() { | |||
| return SecurityUtils.getSubject(); | |||
| } | |||
| public static MallUserInfo getUserInfo() { | |||
| return (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); | |||
| } | |||
| public static Long getUserId() { | |||
| return getUserInfo().getId(); | |||
| } | |||
| public static void setSessionAttribute(Object key, Object value) { | |||
| getSession().setAttribute(key, value); | |||
| } | |||
| public static Object getSessionAttribute(Object key) { | |||
| return getSession().getAttribute(key); | |||
| } | |||
| public static boolean isLogin() { | |||
| return SecurityUtils.getSubject().getPrincipal() != null; | |||
| } | |||
| public static void logout() { | |||
| SecurityUtils.getSubject().logout(); | |||
| } | |||
| public static String getKaptcha(String key) { | |||
| Object kaptcha = getSessionAttribute(key); | |||
| if (kaptcha == null) { | |||
| throw new MallinkException(ErrorCode.KAPCHA_NOT_VALID); | |||
| } | |||
| getSession().removeAttribute(key); | |||
| return kaptcha.toString(); | |||
| } | |||
| } | |||
| @@ -1,93 +0,0 @@ | |||
| spring: | |||
| profiles: | |||
| include: rabbitMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://202.165.179.86:3306/mallinkDev?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useUnicode=true&useSSL=false | |||
| username: ENC(dZ8fmrtuBMQYaRytKQgTqg==) | |||
| password: ENC(WGu0+1DPIHrqorDhrbq1+7wr7xNG53mN) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| driver-class-name: com.mysql.cj.jdbc.Driver | |||
| filters: stat | |||
| maxActive: 20 | |||
| initialSize: 1 | |||
| maxWait: 60000 | |||
| minIdle: 1 | |||
| timeBetweenEvictionRunsMillis: 28000 | |||
| minEvictableIdleTimeMillis: 28000 | |||
| validationQuery: select 'x' | |||
| testWhileIdle: true | |||
| testOnBorrow: false | |||
| testOnReturn: false | |||
| poolPreparedStatements: true | |||
| maxOpenPreparedStatements: 20 | |||
| connectionProperties: "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=6000" | |||
| #jackson: | |||
| #date-format: yyyy-MM-dd HH:mm:ss | |||
| # REDIS | |||
| redis: | |||
| host: 202.165.179.86 | |||
| port: 6379 | |||
| password: ENC(aYJ3Wr2UWtkORRQjjrWWpz2ZeTISsHOA) | |||
| timeout: 3600 | |||
| expire: 1800 #30分钟 | |||
| database: 10 | |||
| defaultExpiration: 2592000 # 默认生命周期30天 | |||
| jedis: | |||
| pool: | |||
| max-active: 50 | |||
| max-idle: 50 | |||
| max-wait: -1 | |||
| min-idle: 10 | |||
| mail: | |||
| host: smtp.exmail.qq.com | |||
| username: ENC(R0bER9E9OB9/YQcpNXMyYDwofNVb8/pFl4nrApS8mi0=) | |||
| password: ENC(50YqJd0iK/2r2YnmEd5RKaki3ktU73UDapBJrVYfqmc=) # 授权密码 | |||
| properties: | |||
| mail: | |||
| smtp: | |||
| auth: true | |||
| starttls: | |||
| enable: true | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| bucketName: iformall-net | |||
| access: ENC(3gx5ghDFBqGrEhO3Wf8aYmXsnwHO7Cj3HNKJGOeUj0o=) | |||
| secret: ENC(HVKIJwCJKVXLlUpGlQPwNqJOlnpxn4xYuy91SH0seTSm2uAttIQHvA49fXWWax90v5wloIk0QuU=) | |||
| wechat: | |||
| open: | |||
| componentAppId: "wx897e4673286c915d" | |||
| componentSecret: "cdfdfda65c45689beb6766c4c427eed2" | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 202.165.179.86 | |||
| port: 6379 | |||
| password: ENC(aYJ3Wr2UWtkORRQjjrWWpz2ZeTISsHOA) | |||
| timeout: 3600 | |||
| expire: 1800 #30分钟 | |||
| database: 2 | |||
| defaultExpiration: 2592000 # 默认生命周期30天 | |||
| jedis: | |||
| pool: | |||
| max-active: 100 | |||
| max-idle: 500 | |||
| max-wait: -1 | |||
| min-idle: 10 | |||
| jasypt: | |||
| encryptor: | |||
| password: oRqdnDbK5pj3eMmB | |||
| fm: | |||
| exception: false | |||
| delay: 1 | |||
| logging: | |||
| level: | |||
| tk.mybatis: debug | |||
| com.iformall.mapper: debug | |||
| path: ./logs/o | |||
| @@ -1,87 +0,0 @@ | |||
| spring: | |||
| profiles: | |||
| include: rocketMQ | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://formalldb.cfqyqflkdlit.rds.cn-northwest-1.amazonaws.com.cn:3306/mallink?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false | |||
| username: ENC(NUzgQOdJnCbVLKT6BaX0aw==) | |||
| password: ENC(mvuoDRiu0jqYaKNRwwTuXZ6U7aoIaqsjdiPqTLgi/nY=) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| driver-class-name: com.mysql.cj.jdbc.Driver | |||
| filters: stat | |||
| maxActive: 20 | |||
| initialSize: 1 | |||
| maxWait: 60000 | |||
| minIdle: 1 | |||
| timeBetweenEvictionRunsMillis: 28000 | |||
| minEvictableIdleTimeMillis: 28000 | |||
| validationQuery: select 'x' | |||
| testWhileIdle: true | |||
| testOnBorrow: false | |||
| testOnReturn: false | |||
| poolPreparedStatements: true | |||
| maxOpenPreparedStatements: 20 | |||
| connectionProperties: "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=6000" | |||
| # REDIS | |||
| redis: | |||
| host: 127.0.0.1 | |||
| port: 6379 | |||
| password: ENC(8gYU47Fu93NUJPhwPCiPbAT+6VFA1YDx1egK4Z0Nl6w=) | |||
| timeout: 3600 | |||
| expire: 1800 #30分钟 | |||
| database: 1 | |||
| defaultExpiration: 2592000 # 默认生命周期30天 | |||
| jedis: | |||
| pool: | |||
| max-active: 8 | |||
| max-idle: 8 | |||
| max-wait: -1 | |||
| min-idle: 0 | |||
| mail: | |||
| host: smtp.exmail.qq.com | |||
| username: ENC(I2YKxnRVPY7J1r/bwzwHOhQCjj3nVqCWEbVTJvBq7y0=) | |||
| password: ENC(APQMO9XQRzMKd0eap+oSSOYH9MQe/r5K0YFF9A9mizU=) # 授权密码 | |||
| properties: | |||
| mail: | |||
| smtp: | |||
| auth: true | |||
| starttls: | |||
| enable: true | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| bucketName: iformall-net | |||
| access: ENC(a6SN1sZ1enNL49ypiOXkg/pPPAnZD8H4buQFTTKN08s=) | |||
| secret: ENC(5P5ff4bTMJUbXVR4ZsM03UHzOKZ4+Zg5Iutcdkyp/Quny/oXg+A4KpfwEyGarlLu3vQMJahGP5M=) | |||
| wechat: | |||
| open: | |||
| componentAppId: ENC(b3JG0MUZgQfz5Zj+DC2ZM1zDeLOiGTmmeokfe2O8kaM=) | |||
| componentSecret: ENC(QVyc4BPGdnSjXGs2ivgpDBE1v8wPWHLLRMYI7Vv8uYwC0SiZHQz0QpyyQV/b48Pb) | |||
| componentToken: ENC(rkxj0733WxFFDLgA9x01m2s5Fi2L+0PC) | |||
| componentAesKey: ENC(EIbJUBpbYOrLb4YQ/HXLQmxlxgAqIp2ZmpnGICC8pu5xiTz3Cqfkbwd2S8raCcK/IvYcX2GmedI=) | |||
| redis: | |||
| host: 127.0.0.1 | |||
| port: 6379 | |||
| password: ENC(8gYU47Fu93NUJPhwPCiPbAT+6VFA1YDx1egK4Z0Nl6w=) | |||
| timeout: 3600 | |||
| expire: 1800 #30分钟 | |||
| database: 2 | |||
| defaultExpiration: 2592000 # 默认生命周期30天 | |||
| jedis: | |||
| pool: | |||
| max-active: 100 | |||
| max-idle: 100 | |||
| max-wait: -1 | |||
| min-idle: 10 | |||
| fm: | |||
| exception: true | |||
| delay: 3 | |||
| logging: | |||
| level: | |||
| tk.mybatis: debug | |||
| com.iformall: debug | |||
| path: ./logs/o | |||
| @@ -1,85 +0,0 @@ | |||
| spring: | |||
| # JDBC | |||
| datasource: | |||
| url: jdbc:mysql://formalldb.cfqyqflkdlit.rds.cn-northwest-1.amazonaws.com.cn:3306/mallinkTest?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false | |||
| username: ENC(Uc0AjgkytxHHCwZrmDASWg==) | |||
| password: ENC(nV4Mi3bEbBx0Fj7uUyYH55eTaqsFMjKvmNzagicH4pc=) | |||
| type: com.alibaba.druid.pool.DruidDataSource | |||
| driver-class-name: com.mysql.cj.jdbc.Driver | |||
| filters: stat | |||
| maxActive: 20 | |||
| initialSize: 1 | |||
| maxWait: 60000 | |||
| minIdle: 1 | |||
| timeBetweenEvictionRunsMillis: 28000 | |||
| minEvictableIdleTimeMillis: 28000 | |||
| validationQuery: select 'x' | |||
| testWhileIdle: true | |||
| testOnBorrow: false | |||
| testOnReturn: false | |||
| poolPreparedStatements: true | |||
| maxOpenPreparedStatements: 20 | |||
| connectionProperties: "druid.stat.mergeSql=true;druid.stat.slowSqlMillis=6000" | |||
| # REDIS | |||
| redis: | |||
| host: 127.0.0.1 | |||
| port: 6379 | |||
| password: ENC(QFwqv3NshvvGhFPiP8rwhvbnxk+rFSqhJi8Pw6TogSg=) | |||
| timeout: 3600 | |||
| expire: 1800 #30分钟 | |||
| database: 1 | |||
| defaultExpiration: 2592000 # 默认生命周期30天 | |||
| jedis: | |||
| pool: | |||
| max-active: 8 | |||
| max-idle: 8 | |||
| max-wait: -1 | |||
| min-idle: 0 | |||
| mail: | |||
| host: smtp.exmail.qq.com | |||
| username: ENC(HFbRXtAFVxU36Hk0yT3reyvRuLrw3RhMlbxFj9Ev/VY=) | |||
| password: ENC(pk4+/3C5n2hMYmgi+VTqI4P1m77DllW8y4KElMXXmIo=) # 授权密码 | |||
| properties: | |||
| mail: | |||
| smtp: | |||
| auth: true | |||
| starttls: | |||
| enable: true | |||
| aws: | |||
| clientRegion: cn-northwest-1 | |||
| bucketName: iformall-net | |||
| access: ENC(NCLcmjwKpAWdn/abD17OKIY7yKepVLWzEpqRYUlURCw=) | |||
| secret: ENC(TRcZqql0Rq5PExlMeH/4WiZ/i02b8FXKmLTBChJmbluTa1uoLS9LrHyNEMrqe1DK+QgOAdvqGBo=) | |||
| wechat: | |||
| open: | |||
| componentAppId: "wx897e4673286c915d" | |||
| componentSecret: "cdfdfda65c45689beb6766c4c427eed2" | |||
| componentToken: "formall2018" | |||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||
| redis: | |||
| host: 127.0.0.1 | |||
| port: 6379 | |||
| password: ENC(QFwqv3NshvvGhFPiP8rwhvbnxk+rFSqhJi8Pw6TogSg=) | |||
| timeout: 3600 | |||
| expire: 1800 #30分钟 | |||
| database: 2 | |||
| defaultExpiration: 2592000 # 默认生命周期30天 | |||
| jedis: | |||
| pool: | |||
| max-active: 100 | |||
| max-idle: 100 | |||
| max-wait: -1 | |||
| min-idle: 10 | |||
| fm: | |||
| exception: true | |||
| delay: 2 | |||
| logging: | |||
| level: | |||
| tk.mybatis: debug | |||
| com.iformall: debug | |||
| path: ./logs/o | |||
| @@ -1,58 +0,0 @@ | |||
| server: | |||
| port: 6060 | |||
| servlet: | |||
| context-path: / | |||
| spring: | |||
| application: | |||
| name: mallink | |||
| profiles: | |||
| active: dev | |||
| jackson: | |||
| date-format: yyyy-MM-dd HH:mm:ss | |||
| time-zone: GMT+8 | |||
| default-property-inclusion: non_null | |||
| servlet: | |||
| multipart: | |||
| max-file-size: 2MB | |||
| max-request-size: 2MB | |||
| cache: | |||
| type: REDIS | |||
| cache-names: redis_cache #缓存的名字(可以不指定) | |||
| redis: | |||
| time-to-live: 60000ms #很重要,缓存的有效时间,以便缓存的过期(单位为毫秒) | |||
| # @{link} https://github.com/abel533 | |||
| #Mybatis | |||
| mybatis: | |||
| type-aliases-package: com.iformall.domain.po | |||
| mapper-locations: classpath:mapper/*Mapper.xml | |||
| configuration: | |||
| map-underscore-to-camel-case: true | |||
| cache-enabled: true | |||
| lazy-loading-enabled: true | |||
| use-generated-keys: true | |||
| default-fetch-size: 100 | |||
| default-statement-timeout: 10 | |||
| #PageHelper | |||
| pagehelper: | |||
| helperDialect: mysql | |||
| reasonable: false | |||
| supportMethodsArguments: true | |||
| params: count=countSql | |||
| offset-as-page-num: true | |||
| page-size-zero: true | |||
| row-bounds-with-count: true | |||
| mapper: | |||
| mappers: | |||
| - com.iformall.common.CommonMapper | |||
| pay: | |||
| real: true | |||
| version: @project.version@ | |||
| @@ -1,100 +0,0 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <configuration scan="true" scanPeriod="10 seconds"> | |||
| <!-- 外部指定路径 --> | |||
| <springProperty scop="context" name="logPath" source="logging.path" /> | |||
| <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | |||
| <encoder> | |||
| <Pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] --%mdc{client}%msg%n</Pattern> | |||
| </encoder> | |||
| </appender> | |||
| <appender name="TRACE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
| <file>${logPath}/trace.log</file> | |||
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
| <FileNamePattern>${logPath}/daily/trace.%d{yyyy-MM-dd}.log</FileNamePattern> | |||
| <maxHistory>180</maxHistory> <!-- 保留180天 --> | |||
| </rollingPolicy> | |||
| <layout> | |||
| <pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] [%logger:%line]--%mdc{client} %msg%n</pattern> | |||
| </layout> | |||
| </appender> | |||
| <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
| <file>${logPath}/info.log</file> | |||
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
| <FileNamePattern>${logPath}/daily/info.%d{yyyy-MM-dd}.log</FileNamePattern> | |||
| <maxHistory>180</maxHistory> <!-- 保留180天 --> | |||
| </rollingPolicy> | |||
| <layout> | |||
| <pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] [%logger:%line]--%mdc{client} %msg%n</pattern> | |||
| </layout> | |||
| <filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||
| <level>INFO</level> | |||
| <onMatch>ACCEPT</onMatch> | |||
| <onMismatch>DENY</onMismatch> | |||
| </filter> | |||
| </appender> | |||
| <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
| <file>${logPath}/debug.log</file> | |||
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
| <FileNamePattern>${logPath}/daily/debug.%d{yyyy-MM-dd}.log</FileNamePattern> | |||
| <maxHistory>180</maxHistory> <!-- 保留180天 --> | |||
| </rollingPolicy> | |||
| <layout> | |||
| <pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] [%logger:%line]--%mdc{client} %msg%n</pattern> | |||
| </layout> | |||
| <filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||
| <level>DEBUG</level> | |||
| <onMatch>ACCEPT</onMatch> | |||
| <onMismatch>DENY</onMismatch> | |||
| </filter> | |||
| </appender> | |||
| <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
| <file>${logPath}/warn.log</file> | |||
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
| <FileNamePattern>${logPath}/daily/warn.%d{yyyy-MM-dd}.log</FileNamePattern> | |||
| <maxHistory>180</maxHistory> <!-- 保留180天 --> | |||
| </rollingPolicy> | |||
| <layout> | |||
| <pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] [%logger:%line]--%mdc{client} %msg%n</pattern> | |||
| </layout> | |||
| <filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||
| <level>WARN</level> | |||
| <onMatch>ACCEPT</onMatch> | |||
| <onMismatch>DENY</onMismatch> | |||
| </filter> | |||
| </appender> | |||
| <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> | |||
| <file>${logPath}/error.log</file> | |||
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> | |||
| <FileNamePattern>${logPath}/daily/error.%d{yyyy-MM-dd}.log</FileNamePattern> | |||
| <maxHistory>180</maxHistory> <!-- 保留180天 --> | |||
| </rollingPolicy> | |||
| <layout> | |||
| <pattern>[%date{yyyy-MM-dd HH:mm:ss}] [%-5level] [%logger:%line]--%mdc{client} %msg%n</pattern> | |||
| </layout> | |||
| <filter class="ch.qos.logback.classic.filter.LevelFilter"> | |||
| <level>ERROR</level> | |||
| <onMatch>ACCEPT</onMatch> | |||
| <onMismatch>DENY</onMismatch> | |||
| </filter> | |||
| </appender> | |||
| <root level="TRACE"> | |||
| <appender-ref ref="TRACE_FILE" /> | |||
| <appender-ref ref="INFO_FILE" /> | |||
| <!-- <appender-ref ref="DEBUG_FILE" /> --> | |||
| <!-- <appender-ref ref="WARN_FILE" /> --> | |||
| <appender-ref ref="ERROR_FILE" /> | |||
| </root> | |||
| <root level="INFO"> | |||
| <appender-ref ref="STDOUT" /> | |||
| </root> | |||
| </configuration> | |||
| @@ -17,22 +17,21 @@ | |||
| <module>mallinkCApi</module> | |||
| <module>mallinkBApi</module> | |||
| <module>mallinkSchedule</module> | |||
| <module>mallinkWechatOpen</module> | |||
| <module>mallinkMQConsumer</module> | |||
| </modules> | |||
| <parent> | |||
| <groupId>org.springframework.boot</groupId> | |||
| <artifactId>spring-boot-starter-parent</artifactId> | |||
| <version>2.0.6.RELEASE</version> | |||
| <version>2.0.7.RELEASE</version> | |||
| <relativePath/> | |||
| </parent> | |||
| <properties> | |||
| <weixin-java-common.version>3.3.0.A</weixin-java-common.version> | |||
| <weixin-java-mp.version>3.3.0.A</weixin-java-mp.version> | |||
| <weixin-java-miniapp.version>3.3.0.A</weixin-java-miniapp.version> | |||
| <weixin-java-pay.version>3.3.0.A</weixin-java-pay.version> | |||
| <weixin-java-common.version>3.3.0</weixin-java-common.version> | |||
| <weixin-java-mp.version>3.3.0</weixin-java-mp.version> | |||
| <weixin-java-miniapp.version>3.3.0</weixin-java-miniapp.version> | |||
| <weixin-java-pay.version>3.3.0</weixin-java-pay.version> | |||
| <quartz.version>2.3.0</quartz.version> | |||
| </properties> | |||