diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1da6859 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +.idea +*.iml +out +gen +.gradle +build +doc +gradle +generated +metamodels diff --git a/README.md b/README.md new file mode 100644 index 0000000..542a873 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ + +##语雀项目信息 +https://www.yuque.com/koksgb/wrorgp/zooms0 + +##设计文档 +https://www.processon.com/diagrams + +##模块介绍 + +###common +项目最基础的公用组件 + +###common-app-push +app的推送组件,目前使用的是友盟的app推送支持 + +###common-cache +分布式缓存组件,基于spring boot cache 并使用了Redisson的支持 + +###common-cms +自研的后端管理自动生成组件,可通过简单的注解自动生成管理端界面 + +###common-db +数据库组件,目前支持MYSQL数据库,ORM框架采用Hibernate,使用JPA及QueryDSL来提升效率 + +###common-distributed +分布式调度组件,包括分布式锁 + +###common-mq +消息队列组件,使用Redis实现消息队列 + +###common-oss +对象存储组件,使用aliyun oss作为底层支持 + +###common-security +安全组件,使用spring security实现安全控制 + +###common-web +Web组件, 使用Spring boot 和 Spring MVC实现 + +###common-web-admin +管理后台及管理员管理组件 + +###common-web-base +Web开发的一些基础组件 \ No newline at end of file diff --git a/boot-nunu/Dockerfile b/boot-nunu/Dockerfile new file mode 100644 index 0000000..ee34226 --- /dev/null +++ b/boot-nunu/Dockerfile @@ -0,0 +1,5 @@ +FROM openjdk:8-jdk-alpine +EXPOSE 8080 +ARG JAR_FILE +COPY $JAR_FILE /home/app.jar +ENTRYPOINT ["java","-jar","/home/app.jar"] \ No newline at end of file diff --git a/boot-nunu/build.gradle b/boot-nunu/build.gradle new file mode 100644 index 0000000..0809457 --- /dev/null +++ b/boot-nunu/build.gradle @@ -0,0 +1,79 @@ +plugins { + id 'org.springframework.boot' version '2.1.7.RELEASE' + id 'io.spring.dependency-management' version '1.0.7.RELEASE' + id 'java' +} + +bootJar { + launchScript() +} + + + +configurations { + querydslapt +} + +sourceSets { + main { + java { + srcDir file("metamodels") + } + } +} + +task querymodels(type: JavaCompile, group: 'build') { + doFirst { + delete file("metamodels"); + file("metamodels").mkdirs(); + } + + classpath = configurations.compile + configurations.querydslapt + destinationDir = file("metamodels") + + source = sourceSets.main.java + options.compilerArgs = [ + "-proc:only", + "-processor", "com.querydsl.apt.jpa.JPAAnnotationProcessor", + "-s", file("metamodels") + ] +} + + +dependencies { + // spring boot 单元测试支持 + testCompile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springBootVersion + //pdf转换工具 + compile group: 'com.itextpdf', name: 'itextpdf', version: '5.5.13' + //excel生成工具 + compile group: 'org.apache.poi', name: 'poi-ooxml', version: '4.1.0' + //okhttp日志系统 + compile 'com.squareup.okhttp3:logging-interceptor:3.9.1' + compile 'com.squareup.retrofit2:converter-gson:2.0.2' + + compile project(":common-web-admin") + compile project(":common-web-app-patch") + compile project(":common-app-push") + compile project(":common-db") + compile project(":common-security") + compile project(":common-oss") + compile project(":common-cms") + compile project(":common-distributed") + compile project(":common-mq") + + querydslapt("com.querydsl:querydsl-apt:4.2.1") + + compile('com.github.binarywang:weixin-java-mp:3.6.0') + compile('com.github.binarywang:weixin-java-pay:3.6.0') + compile('com.github.binarywang:weixin-java-miniapp:3.6.0') + compile('com.tencentcloudapi:tencentcloud-sdk-java:3.0.93') + //爬虫依赖 + compile("org.jsoup:jsoup:1.11.3") + + // 支付宝支付支持 + compile group: 'com.alipay.sdk', name: 'alipay-sdk-java', version: '4.8.10.ALL' + compile 'com.aliyun:aliyun-java-sdk-core:4.1.0' + // https://mvnrepository.com/artifact/org.freemarker/freemarker + compile group: 'org.freemarker', name: 'freemarker', version: '2.3.23' + +} \ No newline at end of file diff --git a/boot-nunu/src/libs/json.jar b/boot-nunu/src/libs/json.jar new file mode 100644 index 0000000..ed0bc93 Binary files /dev/null and b/boot-nunu/src/libs/json.jar differ diff --git a/boot-nunu/src/libs/ueditor-1.1.2.jar b/boot-nunu/src/libs/ueditor-1.1.2.jar new file mode 100644 index 0000000..4819fe0 Binary files /dev/null and b/boot-nunu/src/libs/ueditor-1.1.2.jar differ diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/BootNunuApplication.java b/boot-nunu/src/main/java/com/softwarebr/nunu/BootNunuApplication.java new file mode 100644 index 0000000..220a33a --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/BootNunuApplication.java @@ -0,0 +1,53 @@ +package com.softwarebr.nunu; + +import com.google.common.collect.Lists; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.EnableAspectJAutoProxy; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.transaction.annotation.EnableTransactionManagement; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.List; + +@SpringBootApplication +@EnableSwagger2 +@EnableTransactionManagement +@ComponentScan(basePackages = {"com.brframework", "com.softwarebr.nunu"}) +@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true) +@EnableScheduling +public class BootNunuApplication { + + public static void main(String[] args) { + //处理参数 + args = handlerArgs(args); + SpringApplication.run(BootNunuApplication.class, args); + + } + + /** + * 处理参数 + * @param args + * @return + */ + private static String[] handlerArgs(String[] args){ + boolean defActive = false; + for (String arg : args) { + if(arg.startsWith("--spring.profiles.active=")){ + defActive = true; + break; + } + } + + if(!defActive){ + //默认使用dev启动 + List argList = Lists.newArrayList(args); + argList.add("--spring.profiles.active=dev"); + args = argList.toArray(new String[]{}); + } + + return args; + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/AdminSwaggerConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/AdminSwaggerConfig.java new file mode 100644 index 0000000..b347ce6 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/AdminSwaggerConfig.java @@ -0,0 +1,67 @@ +package com.softwarebr.nunu.config; + +import com.brframework.commonweb.core.SwaggerContext; +import com.google.common.collect.Lists; +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.service.Parameter; +import springfox.documentation.spring.web.plugins.Docket; + +import java.util.List; + +/** + * 管理后台Swagger配置 + * @Author xu + * @Date 2018/1/3 0003 下午 3:30 + * Swagger api生成 + */ +@Configuration +@Data +public class AdminSwaggerConfig { + + @Value("${swagger.enable}") + private boolean enable; + private String groupName = "admin"; + private String packageName = "com.softwarebr.nunu.web.admin"; + private String title = "管理后台接口文档"; + private String description = "管理后台接口文档"; + private String termsOfServiceUrl = ""; + private String version = "1.0"; + + private String contactName = "beiru"; + private String contactUrl = "https://www.software-br.com"; + private String contactEmail = ""; + + + + @Bean("adminDocket") + public Docket api() { + + List list = Lists.newArrayList(); + ParameterBuilder tokenPar = new ParameterBuilder(); + tokenPar.name("Authorization").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); + list.add(tokenPar.build()); + + return SwaggerContext.createDocket(groupName, packageName, apiInfo(), list, enable); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title(title)//大标题 + .description(description)//详细描述 + .version(version)//版本 + .termsOfServiceUrl(termsOfServiceUrl) + .contact(new Contact(contactName, contactUrl, contactEmail))//作者 + .license("The Apache License, Version 2.0") + .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") + .build(); + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/AliPayConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/AliPayConfig.java new file mode 100644 index 0000000..cd2b4c3 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/AliPayConfig.java @@ -0,0 +1,81 @@ +package com.softwarebr.nunu.config; + +import cn.hutool.core.io.FileUtil; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayClient; +import com.alipay.api.CertAlipayRequest; +import com.alipay.api.DefaultAlipayClient; +import com.softwarebr.nunu.util.UUIDGenerator; +import com.softwarebr.nunu.config.domain.ConfigService; +import com.softwarebr.nunu.domain.PayConfig; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.StringUtils; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; + +/** + * @author xu + * @date 2019/10/31 10:13 + */ +@Configuration +@Slf4j +public class AliPayConfig { + + private static final String crtPath; + static { + String path = null; + try { + path = FileUtil.file("").getCanonicalPath() + File.separator + "crt" + File.separator; + } catch (IOException e) { + } + crtPath = path; + FileUtil.del(crtPath); + FileUtil.file(crtPath).mkdir(); + } + + @Autowired + ConfigService payConfigConfigService; + + @Bean + public AlipayClient appAlipayClient() throws AlipayApiException, IOException { + PayConfig payConfig = this.payConfigConfigService.get(); + if(StringUtils.isEmpty(payConfig.getAppApAlipayPublicCertContent())){ + return null; + } + + String alipayPublicCertPath = crtPath + genFileName("crt"); + String rootCertPath = crtPath + genFileName("crt"); + String certPath = crtPath + genFileName("crt"); + + FileUtil.writeString(payConfig.getAppApAlipayPublicCertContent(), alipayPublicCertPath, Charset.forName("UTF-8")); + log.info("证书alipayPublicCertPath加载完成,加载地址:{}", alipayPublicCertPath); + FileUtil.writeString(payConfig.getAppApRootCertContent(), rootCertPath, Charset.forName("UTF-8")); + log.info("证书rootCertPath加载完成,加载地址:{}", rootCertPath); + FileUtil.writeString(payConfig.getAppApCertContent(), certPath, Charset.forName("UTF-8")); + log.info("证书certPath加载完成,加载地址:{}", certPath); + + CertAlipayRequest request = new CertAlipayRequest(); + request.setServerUrl(payConfig.getApServerUrl()); + request.setAppId(payConfig.getAppApAppId()); + request.setPrivateKey(payConfig.getAppApPrivateKey()); + request.setFormat("json"); + request.setCharset("utf-8"); + request.setSignType("RSA2"); + + request.setCertPath(certPath); + request.setAlipayPublicCertPath(alipayPublicCertPath); + request.setRootCertPath(rootCertPath); + + return new DefaultAlipayClient(request); + } + + private String genFileName(String format){ + return UUIDGenerator.generateShortUuid() + "." + format; + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/ApiSwaggerConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/ApiSwaggerConfig.java new file mode 100644 index 0000000..2c97d74 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/ApiSwaggerConfig.java @@ -0,0 +1,70 @@ +package com.softwarebr.nunu.config; + +import com.brframework.commonweb.core.SwaggerContext; +import com.google.common.collect.Lists; +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.service.Parameter; +import springfox.documentation.spring.web.plugins.Docket; + +import java.util.List; + +/** + * api前端Swagger配置 + * @Author laolian + * @Date 2019-8-28 09:44:32 + * Swagger api生成 + */ +@Configuration +@Data +public class ApiSwaggerConfig { + + @Value("${swagger.enable}") + private boolean enable; + private String groupName = "api"; + private String packageName = "com.softwarebr.nunu.web.api"; + private String title = "api接口文档"; + private String description = "api接口文档"; + private String termsOfServiceUrl = ""; + private String version = "1.0"; + + private String contactName = "beiru"; + private String contactUrl = "https://www.software-br.com"; + private String contactEmail = ""; + + + + @Bean("apiDocket") + public Docket api() { + + List list = Lists.newArrayList(); + ParameterBuilder tokenPar = new ParameterBuilder(); + tokenPar.name("Authorization").description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); + ParameterBuilder requestFlagPar = new ParameterBuilder(); + requestFlagPar.name("request-flag").description("请求标记").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); + list.add(requestFlagPar.build()); + list.add(tokenPar.build()); + + return SwaggerContext.createDocket(groupName, packageName, apiInfo(), list, enable); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title(title)//大标题 + .description(description)//详细描述 + .version(version)//版本 + .termsOfServiceUrl(termsOfServiceUrl) + .contact(new Contact(contactName, contactUrl, contactEmail))//作者 + .license("The Apache License, Version 2.0") + .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") + .build(); + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/DefaultDataSourceConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/DefaultDataSourceConfig.java new file mode 100644 index 0000000..88093eb --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/DefaultDataSourceConfig.java @@ -0,0 +1,58 @@ +package com.softwarebr.nunu.config; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; +import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; +import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; + +import javax.sql.DataSource; +import java.util.Map; + +/** + * @author xu + * @date 2019/8/20 16:50 + */ +@Configuration +@EnableJpaRepositories( + basePackages = { + "com.softwarebr.nunu.dao", + "com.brframework.commonapppush.dao", + "com.brframework.webapppatch.dao", + "com.brframework.commonwebbase.dao", + "com.brframework.commonwebadmin.dao" + } +) +public class DefaultDataSourceConfig { + + @Autowired + JpaProperties jpaProperties; + + @Autowired + HibernateProperties hibernateProperties; + + @Bean(name = "entityManagerFactory") + public LocalContainerEntityManagerFactoryBean + entityManagerFactory( + EntityManagerFactoryBuilder builder + , DataSource dataSource + ) { + Map properties = hibernateProperties + .determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); + return builder + .dataSource(dataSource) + .packages("com.softwarebr.nunu.entity", + "com.brframework.commonapppush.entity", + "com.brframework.webapppatch.entity", + "com.brframework.commonwebbase.entity", + "com.brframework.commonwebadmin.entity") + .persistenceUnit("default") + .properties(properties) + .build(); + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/MessageConverterConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/MessageConverterConfig.java new file mode 100644 index 0000000..0efa137 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/MessageConverterConfig.java @@ -0,0 +1,39 @@ +package com.softwarebr.nunu.config; + +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.alibaba.fastjson.support.config.FastJsonConfig; +import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import static com.alibaba.fastjson.serializer.SerializerFeature.DisableCircularReferenceDetect; + +/** + * @Author: ljr + * @Date: 2019/9/5 15:39 + * @Description: + */ +@Configuration +public class MessageConverterConfig { + + @Bean + public HttpMessageConverters customConverters() { + FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); + FastJsonConfig config = new FastJsonConfig(); + converter.setFastJsonConfig(config); + config.setSerializerFeatures(DisableCircularReferenceDetect, + //null的字段也会输出 + SerializerFeature.WriteMapNullValue + //字符串为null字段返回"" + //SerializerFeature.WriteNullStringAsEmpty, + //List字段如果为null,输出为[],而非null + //SerializerFeature.WriteNullListAsEmpty, + ////数值字段如果为null,输出为0,而非null + //SerializerFeature.WriteNullNumberAsZero, + ////Boolean字段如果为null,输出为false,而非null + //SerializerFeature.WriteNullBooleanAsFalse); + ); + return new HttpMessageConverters(converter); + } +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/SecurityConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/SecurityConfig.java new file mode 100644 index 0000000..e32f200 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/SecurityConfig.java @@ -0,0 +1,125 @@ +package com.softwarebr.nunu.config; + +import com.brframework.commonsecurity.SecurityFilter; +import com.brframework.commonsecurity.core.SecurityExceptionHandling; +import com.brframework.commonsecurity.core.SecurityUserDetailsService; +import lombok.Data; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +/** + * @author xu + * @date 2019/8/19 20:16 + */ +@EnableWebSecurity +@Configuration +@Data +public class SecurityConfig { + + @Autowired + SecurityUserDetailsConfig config; + + /** + * + * @param redisTemplate + * @return + */ + @Bean("adminUserDetailsService") + public SecurityUserDetailsService adminUserDetailsService(@Autowired StringRedisTemplate redisTemplate) { + return new SecurityUserDetailsService(config.getAdminIss(), config.getAdminExp(), config.getAdminSecret(), config.isAdminSingleUser(), redisTemplate); + } + + + @Configuration + @Order(1) + public static class AdminSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { + + @Autowired + @Qualifier("adminUserDetailsService") + SecurityUserDetailsService userDetailsService; + + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/admin/access/**") + .addFilterBefore(new SecurityFilter(userDetailsService), UsernamePasswordAuthenticationFilter.class) + .httpBasic().and() + // 基于token,所以不需要session + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + //使用我们自己的异常处理机制 + .exceptionHandling() + .authenticationEntryPoint(new SecurityExceptionHandling()) + .accessDeniedHandler(new SecurityExceptionHandling()).and() + .csrf().disable() //禁用csrf攻击防护,因为使用的是jwt所以不存在csrf攻击的威胁 + .logout().disable() //禁用security退出功能 + .formLogin().disable() //禁用security登录功能 + .headers().disable(); + } + } + + @Configuration + @Order(3) + public static class AnySecurityConfigurerAdapter extends WebSecurityConfigurerAdapter { + + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests().anyRequest().permitAll().and() + .httpBasic().and() + // 基于token,所以不需要session + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() + .csrf().disable() //禁用csrf攻击防护,因为使用的是jwt所以不存在csrf攻击的威胁 + .cors().disable() //禁用跨域控制 + .logout().disable() //禁用security退出功能 + .formLogin().disable() //禁用security登录功能 + .headers().disable(); + } + } + + /** + * + * @param redisTemplate + * @return + */ + @Bean("apiUserDetailsService") + public SecurityUserDetailsService apiUserDetailsService(@Autowired StringRedisTemplate redisTemplate) { + return new SecurityUserDetailsService(config.getApiIss(), config.getApiExp(), config.getApiSecret(), config.isApiSingleUser(), redisTemplate); + } + + + @Configuration + @Order(2) + public static class ApiSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { + + @Autowired + @Qualifier("apiUserDetailsService") + SecurityUserDetailsService userDetailsService; + + protected void configure(HttpSecurity http) throws Exception { + http + .antMatcher("/api/access/**").authorizeRequests() + .antMatchers("/api/access/**").hasRole("USER").and() + .addFilterBefore(new SecurityFilter(userDetailsService), UsernamePasswordAuthenticationFilter.class) + .httpBasic().and() + // 基于token,所以不需要session + .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() +// //使用我们自己的异常处理机制 + .exceptionHandling() + .authenticationEntryPoint(new SecurityExceptionHandling()) + .accessDeniedHandler(new SecurityExceptionHandling()).and() + .csrf().disable() //禁用csrf攻击防护,因为使用的是jwt所以不存在csrf攻击的威胁 + .logout().disable() //禁用security退出功能 + .formLogin().disable() //禁用security登录功能 + .headers().disable(); + } + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/SecurityUserDetailsConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/SecurityUserDetailsConfig.java new file mode 100644 index 0000000..81f7177 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/SecurityUserDetailsConfig.java @@ -0,0 +1,29 @@ +package com.softwarebr.nunu.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Data +@Component +@ConfigurationProperties(value = "security.rest") +public class SecurityUserDetailsConfig { + + /** 该JWT的签发者 */ + private String adminIss; + /** 有效期 (秒) */ + private long adminExp; + /** 签名 */ + private String adminSecret; + /** 一个签发者中一个用户只能拥有一个JWT */ + private boolean adminSingleUser; + + /** api JWT的签发者 */ + private String apiIss; + /** 有效期 (秒) */ + private long apiExp; + /** 签名 */ + private String apiSecret; + /** 一个签发者中一个用户只能拥有一个JWT */ + private boolean apiSingleUser; +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/SelectConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/SelectConfig.java new file mode 100644 index 0000000..916b160 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/SelectConfig.java @@ -0,0 +1,37 @@ +package com.softwarebr.nunu.config; + +import com.brframework.commoncms.core.cms.Select; +import com.google.common.collect.Lists; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import java.util.stream.Collectors; + + +/** + * @author xu + * @date 2019/8/30 15:35 + */ +@Component +public class SelectConfig { + + /** + * 下拉获取标签 + */ + public static final String SELECT_LABEL= "SELECT_LABEL"; + + /** + * 多选框 + * + * @return + */ + @Bean + public Select selectOptions() { + return key -> { + switch (key) { + } + return null; + }; + } +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/WxMpConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/WxMpConfig.java new file mode 100644 index 0000000..ec339a5 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/WxMpConfig.java @@ -0,0 +1,38 @@ +package com.softwarebr.nunu.config; + +import com.softwarebr.nunu.config.domain.ConfigService; +import com.softwarebr.nunu.domain.PayConfig; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; +@Component +public class WxMpConfig { + + @Autowired + ConfigService payConfigService; + + @Bean + public WxMpConfigStorage wxMpConfigStorage(){ + PayConfig payConfig = payConfigService.get(); + //设置为内存存储 + WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl(); + configStorage.setAppId(payConfig.getWxAppId()); + configStorage.setSecret(payConfig.getWxAppSecret()); + //configStorage.setToken(payConfig.getWxToken()); + //configStorage.setAesKey(payConfig.getWxAesKey()); + return configStorage; + } + + + @Bean + public WxMpService wxMpService(WxMpConfigStorage wxMpConfigStorage){ + WxMpService wxMpService = new WxMpServiceImpl(); + wxMpService.setWxMpConfigStorage(wxMpConfigStorage); + return wxMpService; + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/WxPayConfig.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/WxPayConfig.java new file mode 100644 index 0000000..a50a6df --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/WxPayConfig.java @@ -0,0 +1,52 @@ +package com.softwarebr.nunu.config; + +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import com.softwarebr.nunu.config.domain.ConfigService; +import com.softwarebr.nunu.domain.PayConfig; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.io.IOException; + +/** + * @author xu + * @date 2019/10/23 10:59 + */ +@Configuration +@Slf4j +public class WxPayConfig { + + @Autowired + ConfigService payConfigService; + + public String appWeiXinCertPath() throws IOException { + + /* String newFilePath = FileUtil.file("").getCanonicalPath() + File.separator + "crt" + File.separator + "apiclient_cert.p12"; + InputStream inputStream = WxPayConfig.class.getClassLoader().getResourceAsStream("apiclient_cert.p12"); + FileUtil.writeFromStream(inputStream, newFilePath);*/ + return null; + } + + @Bean + public com.github.binarywang.wxpay.config.WxPayConfig config() throws IOException { + PayConfig payConfig = payConfigService.get(); + com.github.binarywang.wxpay.config.WxPayConfig wxPayConfig = new com.github.binarywang.wxpay.config.WxPayConfig(); + wxPayConfig.setAppId(payConfig.getWxAppId()); + wxPayConfig.setMchId(payConfig.getWxMchId()); + wxPayConfig.setMchKey(payConfig.getWxMchKey()); + wxPayConfig.setKeyPath(appWeiXinCertPath()); + wxPayConfig.setSignType(payConfig.getWxSignType()); + wxPayConfig.setNotifyUrl(payConfig.getWxOAuthRedirectUrl()); + return wxPayConfig; + } + + @Bean + public WxPayService wxPayService(com.github.binarywang.wxpay.config.WxPayConfig payConfig) { + WxPayService wxPayService = new WxPayServiceImpl(); + wxPayService.setConfig(payConfig); + return wxPayService; + } +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/AbstractConfigService.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/AbstractConfigService.java new file mode 100644 index 0000000..d5e6efa --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/AbstractConfigService.java @@ -0,0 +1,43 @@ +package com.softwarebr.nunu.config.domain; + +import com.alibaba.fastjson.JSON; +import com.brframework.commonweb.exception.HandleException; +import com.brframework.commonwebbase.service.DictionaryService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.util.StringUtils; + +/** + * @author xu + * @date 2019/10/28 17:29 + */ +@Slf4j +public abstract class AbstractConfigService implements ConfigService { + + @Autowired + DictionaryService dictionaryService; + + public abstract String getKey(); + + public abstract Class getDomainClass(); + + @Override + public Domain get() { + String s = dictionaryService.get(getKey()); + if(StringUtils.isEmpty(s)){ + try { + return getDomainClass().newInstance(); + } catch (Throwable e) { + log.error("对象实例化错误,请查看是否有无参构造方法", e); + throw new HandleException("对象实例化错误,请查看是否有无参构造方法"); + } + } + return JSON.parseObject(s, getDomainClass()); + } + + @Override + public void set(Domain config) { + dictionaryService.set(getKey(), JSON.toJSONString(config)); + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/ConfigService.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/ConfigService.java new file mode 100644 index 0000000..bc4cfa4 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/ConfigService.java @@ -0,0 +1,13 @@ +package com.softwarebr.nunu.config.domain; + +/** + * @author xu + * @date 2019/10/28 17:27 + */ +public interface ConfigService { + + Domain get(); + + void set(Domain config); + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/impl/ConfigServiceImpl.java b/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/impl/ConfigServiceImpl.java new file mode 100644 index 0000000..cd354b9 --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/config/domain/impl/ConfigServiceImpl.java @@ -0,0 +1,57 @@ +package com.softwarebr.nunu.config.domain.impl; + +import com.softwarebr.nunu.config.domain.AbstractConfigService; +import com.softwarebr.nunu.config.domain.ConfigService; +import com.softwarebr.nunu.domain.AgreementConfig; +import com.softwarebr.nunu.domain.PayConfig; +import com.softwarebr.nunu.domain.SMSConfig; +import com.softwarebr.nunu.domain.ServiceTerms; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +; + +/** + * 配置 + * 最大化适应需求变更 + * @author xu + * @date 2019/10/28 17:49 + */ +@Configuration +public class ConfigServiceImpl { + + private AbstractConfigService createConfigService(String key, Class domainClass){ + return new AbstractConfigService(){ + @Override + public String getKey() { + return key; + } + @Override + public Class getDomainClass() { + return domainClass; + } + }; + } + + @Bean + public ConfigService smsConfig(){ + return createConfigService(SMSConfig.KEY, SMSConfig.class); + } + + @Bean + public ConfigService payConfig(){ + return createConfigService(PayConfig.KEY, PayConfig.class); + } + + + @Bean + public ConfigService serviceTerms(){ + return createConfigService(ServiceTerms.KEY, ServiceTerms.class); + } + + @Bean + public ConfigService agreement(){ + return createConfigService(AgreementConfig.KEY, AgreementConfig.class); + } + +} diff --git a/boot-nunu/src/main/java/com/softwarebr/nunu/dao/go/LabelDao.java b/boot-nunu/src/main/java/com/softwarebr/nunu/dao/go/LabelDao.java new file mode 100644 index 0000000..581197b --- /dev/null +++ b/boot-nunu/src/main/java/com/softwarebr/nunu/dao/go/LabelDao.java @@ -0,0 +1,33 @@ +package com.softwarebr.nunu.dao.go; + +import com.softwarebr.nunu.entity.go.Label; +import com.brframework.commondb.core.CommonRepository; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.List; + +/** + * @date 2020-02-19 14:03:47 + * @author lilin + */ + +@Repository +public interface LabelDao extends CommonRepository { + + /** + * 根据父级查找标签 + * @param parentId + * @param status 状态{@link Label} + * @return + */ + List