提交 06232cf0 编写于 作者: sq3536's avatar sq3536

update

上级 c8e48f99
......@@ -360,31 +360,31 @@ public class EntityModel extends BaseModel {
private String storageMode="SQL";
private String storage="SQL";
public void setStorageMode(Integer type)
public void setStorage(Integer type)
{
switch(type){
case 0:
this.storageMode="NONE";
this.storage="NONE";
break;
case 1:
this.storageMode="SQL";
this.storage="SQL";
break;
case 2:
this.storageMode="NoSQL";
this.storage="NoSQL";
break;
case 4:
this.storageMode="ServiceAPI";
this.storage="ServiceAPI";
break;
default:
this.storageMode="SQL";
this.storage="SQL";
break;
}
}
public void setStorageMode(String type)
public void setStorage(String type)
{
this.storageMode=type;
this.storage=type;
}
......@@ -480,7 +480,7 @@ public class EntityModel extends BaseModel {
this.system=systemModel;
this.setCodeName(dataEntity.getCodeName());
this.setName(dataEntity.getName());
this.setStorageMode(dataEntity.getStorageMode());
this.setStorage(dataEntity.getStorageMode());
List<String> dsTypes=new ArrayList<>();
if(dataEntity.getAllPSDEDBConfigs()!=null)
......
......@@ -45,7 +45,7 @@ public class LabelExt implements java.io.Serializable, Comparable<String>, CharS
}
public String toPluralize() {
return Inflector.getInstance().pluralize(toCamelCase());
return Inflector.getInstance().pluralize(toCamelCase().toLowerCase());
}
public String getLowerCase()
......
......@@ -138,7 +138,7 @@ public class ModelStorage {
else if(type.equals(TemplateFileType.entity))
{
getSystemModel().getEntities().forEach(item->{
CliOption opt=newCliOption(TemplateFileType.entity).setCliSubType(item.getStorageMode()).setModule(item.getModule())
CliOption opt=newCliOption(TemplateFileType.entity).setCliSubType(item.getStorage()).setModule(item.getModule())
.baseData(item,item.getCodeName().toString());
rt.addOption(opt);
});
......
package cn.ibizlab.codegen.model;
import cn.ibizlab.codegen.utils.StringAdvUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
......@@ -292,7 +293,7 @@ public class PojoSchema {
if(!referenceMap.containsKey(prop.getOptions().getCodeName().toLowerCase()))
referenceMap.put(prop.getOptions().getCodeName().toLowerCase(), prop);
}
String pluralize= Inflector.getInstance().pluralize(StringUtils.isEmpty(prop.getOptions().getCodeName())?prop.getOptions().getEntityName():prop.getOptions().getCodeName()).toLowerCase();
String pluralize= Inflector.getInstance().pluralize(StringAdvUtils.camelcase(StringUtils.isEmpty(prop.getOptions().getCodeName())?prop.getOptions().getEntityName():prop.getOptions().getCodeName()).toLowerCase());
if(!referenceMap.containsKey(pluralize))
referenceMap.put(pluralize, prop);
}
......
......@@ -92,6 +92,8 @@ public class SystemModel extends BaseModel {
private IPSSysSFPub pub;
private Set<String> mqSubscribes;
private Map<String,EntityModel> entitiesMap;
public synchronized Map<String, EntityModel> getEntitiesMap() {
if(entitiesMap==null) {
......@@ -107,6 +109,13 @@ public class SystemModel extends BaseModel {
enableES=true;
if(!ObjectUtils.isEmpty(entity.getAllPSDEDataSyncs()))
enableMQ=true;
if(entity.getAllPSDEDataSyncs()!=null)
{
entity.getAllPSDEDataSyncs().forEach(sync->{
if(mqSubscribes==null) mqSubscribes=new LinkedHashSet<>();
mqSubscribes.add(sync.getCodeName());
});
}
entitiesMap.put(entity.getCodeName(),new EntityModel(this,entity));
});
}
......
package cn.ibizlab.codegen.model;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.model.service.IPSSysServiceAPI;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class test {
private String type;
@JsonIgnore
@JSONField(serialize = false)
private Map<String,Object> extensionparams=new HashMap<String,Object>();
@JsonAnyGetter
@JSONField(name = "_any", unwrapped = true, serialize = true, deserialize = false)
public Map<String , Object> getExtensionparams() {
return extensionparams;
}
@JsonAnySetter
@JSONField(name = "_any", unwrapped = true, serialize = false, deserialize = true)
public test set(String field, Object value) {
extensionparams.put(field,value);
return this;
}
public static void main(String[] args) {
String str="{'a':'b','c':'d','type':'12'}";
test t= JSON.parseObject(str,test.class);
System.out.print(JSON.toJSONString(t));
}
}
......@@ -115,7 +115,7 @@ public enum StringHelpers implements Helper<Object> {
pluralize {
@Override
protected CharSequence safeApply(final Object value, final Options options) {
return Inflector.getInstance().pluralize(StringAdvUtils.camelcase(value.toString()));
return Inflector.getInstance().pluralize(StringAdvUtils.camelcase(value.toString()).toLowerCase());
}
};
......
......@@ -36,7 +36,7 @@ public class PluralizeLambda implements Mustache.Lambda {
@Override
public void execute(Template.Fragment fragment, Writer writer) throws IOException {
String text = Inflector.getInstance().pluralize(StringAdvUtils.camelcase(fragment.execute()));
String text = Inflector.getInstance().pluralize(StringAdvUtils.camelcase(fragment.execute()).toLowerCase());
writer.write(text);
......
FROM image.ibizlab.cn/library/openjdk:8-jre-alpine
ENV TZ="Asia/Shanghai" \
SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
IBIZ_SLEEP=0 \
JAVA_OPTS=""
CMD echo "The application will start in ${IBIZ_SLEEP}s..." && \
sleep ${IBIZ_SLEEP} && \
java ${JAVA_OPTS} -Duser.timezone=$TZ -Djava.security.egd=file:/dev/./urandom -jar /{{projectName}}-app-{{apps}}.jar
EXPOSE {{#if app.httpPort}}{{app.httpPort}}{{else}}8080{{/if}}
ADD {{projectName}}-app-{{apps}}.jar /{{projectName}}-app-{{apps}}.jar
package {{packageName}}.{{apps}}.config;
import com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration;
import cn.ibizlab.util.errors.BadRequestAlertException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.Query;
import java.lang.management.ManagementFactory;
import java.util.Set;
/**
* 外部容器启动服务时,自动注册服务到nacos
*/
@Component
@Slf4j
@ConditionalOnExpression("'${ibiz.deploy.packagetype:jar}'.equals('war')")
public class NacosRegisterConfig implements ApplicationRunner {
@Autowired(required = false)
private NacosAutoServiceRegistration registration;
@Value("${server.port:8080}")
Integer port;
@Override
public void run(ApplicationArguments args) {
log.info("正在尝试将应用程序注册到nacos");
if (registration != null && port != null) {
try {
String containerPort = getContainerPort();
if(!StringUtils.isEmpty(containerPort)){
registration.setPort(new Integer(containerPort));
}
else{
registration.setPort(port);
log.info("无法获取外部容器端口,将使用程序默认端口{}",port);
}
registration.start();
} catch (Exception e) {
throw new BadRequestAlertException("应用程序注册到nacos失败,"+e,"","");
}
log.info("已将应用程序成功注册到nacos");
}
else{
log.info("无法获取应用程序端口,将应用程序注册到nacos请求被忽略。");
}
}
/**
* 获取外部容器端口
*/
public String getContainerPort(){
String port = null;
try {
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"), Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
if(!ObjectUtils.isEmpty(objectNames)){
port = objectNames.iterator().next().getKeyProperty("port");
}
}
catch (Exception e) {
log.error("获取外部容器端口失败!"+e);
}
return port;
}
}
</#if>
\ No newline at end of file
package {{packageName}}.{{apps}}.config;
import {{packageName}}.util.security.AuthenticationEntryPoint;
import {{packageName}}.util.security.AuthorizationTokenFilter;
import {{packageName}}.util.service.AuthenticationUserService;
import cn.ibizlab.util.security.AuthenticationEntryPoint;
import cn.ibizlab.util.security.AuthorizationTokenFilter;
import cn.ibizlab.util.service.AuthenticationUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
......@@ -39,22 +39,22 @@ public class {{app.codeName}}SecurityConfig extends WebSecurityConfigurerAdapter
@Autowired
AuthorizationTokenFilter authenticationTokenFilter;
@Value("${ibiz.auth.path:v7/login}"})
@Value("${ibiz.auth.path:v7/login}")
private String loginPath;
@Value("${ibiz.auth.logoutpath:v7/logout}"})
@Value("${ibiz.auth.logoutpath:v7/logout}")
private String logoutPath;
@Value("${ibiz.file.uploadpath:ibizutil/upload}"})
@Value("${ibiz.file.uploadpath:ibizutil/upload}")
private String uploadpath;
@Value("${ibiz.file.downloadpath:ibizutil/download}"})
@Value("${ibiz.file.downloadpath:ibizutil/download}")
private String downloadpath;
@Value("${ibiz.file.previewpath:ibizutil/preview}"})
@Value("${ibiz.file.previewpath:ibizutil/preview}")
private String previewpath;
@Value("${ibiz.auth.excludesPattern:}"})
@Value("${ibiz.auth.excludesPattern:}")
private String[] excludesPattern;
@Autowired
......
......@@ -13,7 +13,7 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import {{packageName}}.util.web.SearchContextHandlerMethodArgumentResolver;
import cn.ibizlab.util.web.SearchContextHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
......
package {{packageName}}.${app.getPKGCodeName()?lower_case};
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* 提供外部容器启动服务能力
*/
@Slf4j
public class {{app.codeName}}Initializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
log.info("--正在使用外部容器启动服务--");
return builder.sources({{app.codeName}}Application.class);
}
}
\ No newline at end of file
......@@ -7,12 +7,12 @@ logging:
#zuul网关路由设置
zuul:
routes:
{{#enableWorkflow}}
{{#if system.enableWorkflow}}
wfcore:
path: /wfcore/**
serviceId: ${ibiz.ref.service.wf:ibzwf-api}}
stripPrefix: true
{{/enableWorkflow}}
{{/if}}
loginv7:
path: /v7/login
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}}
......@@ -71,9 +71,9 @@ zuul:
stripPrefix: false
{{#each app.appEntities}}
{{#serviceId}}
{{lowerCase codeName}}:
{{apps}}-{{lowerCase codeName}}:
path: /{{pluralize codeName}}/**
serviceId: ${ibiz.ref.service.{{serviceId}}:{{serviceId}}\}
serviceId: ${ ibiz.ref.service.{{serviceId}}:{{serviceId}} }
stripPrefix: false
{{/serviceId}}
{{/each}}
......
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<property name="LOG_PATH" value="logs" />
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %-40.40logger{39} : %msg%n" />
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="LOG_PATTERN2" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr([${LOG_LEVEL_PATTERN:-%5p}]) %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}}" />
<!-- 控制台输出 -->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}}</pattern>
</encoder>
</appender>
<!--<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">-->
<!-- <destination>127.0.0.1:9601</destination>-->
<!-- <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">-->
<!-- <customFields>{"appname":"{{projectName}}-{{apps}}"}</customFields>-->
<!-- </encoder>-->
<!--</appender>-->
<!-- 按照每天生成日志文件 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_PATH}}/{{projectName}}-{{apps}}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}}</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="Console" />
<appender-ref ref="file" />
<!--<appender-ref ref="LOGSTASH" />-->
</root>
</configuration>
package {{packageName}};
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.List;
import cn.ibizlab.util.web.SearchContextHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
@Slf4j
@EnableDiscoveryClient
@Configuration
@EnableTransactionManagement
@EnableFeignClients(basePackages = {"{{packageName}}" })
@SpringBootApplication(exclude = {
{{#unless system.enableMongo}}
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
{{/unless}}
{{#if system.enableDS}}
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure.class
{{/if}}
})
@ComponentScan(basePackages = {"{{packageName}}"}
// ,excludeFilters = {
// @ComponentScan.Filter(type= org.springframework.context.annotation.FilterType.REGEX, pattern="{{packageName}}.xxx.rest.xxx"),
// }
)
@Import({
org.springframework.cloud.openfeign.FeignClientsConfiguration.class
})
@EnableAsync
@EnableScheduling
public class DevBootApplication extends WebMvcConfigurerAdapter {
@Autowired
SearchContextHandlerMethodArgumentResolver resolver;
public static void main(String[] args) {
SpringApplication.run(DevBootApplication.class, args);
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(resolver);
}
}
package {{packageName}}.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
{{#if system.enableGlobalTransaction}}
@Import({com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration.class})
{{/if}}
public class DevBootAutoConfiguration {
}
{{#eq system.saaSMode 4}}
package {{packageName}}.config;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class DevBootHeaderFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.addZuulRequestHeader("srfsystem", "{{system.codeName}}");
return null;
}
}
{{/eq}}
\ No newline at end of file
package {{packageName}}.config;
import cn.ibizlab.util.security.AuthenticationEntryPoint;
import cn.ibizlab.util.security.AuthorizationTokenFilter;
import cn.ibizlab.util.service.AuthenticationUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.core.GrantedAuthorityDefaults;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.beans.factory.annotation.Qualifier;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class DevBootSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationEntryPoint unauthorizedHandler;
@Autowired
private AuthenticationUserService userDetailsService;
/**
* 自定义基于JWT的安全过滤器
*/
@Autowired
AuthorizationTokenFilter authenticationTokenFilter;
@Value("${ibiz.auth.path:v7/login}")
private String loginPath;
@Value("${ibiz.auth.logoutpath:v7/logout}")
private String logoutPath;
@Value("${ibiz.file.uploadpath:ibizutil/upload}")
private String uploadpath;
@Value("${ibiz.file.downloadpath:ibizutil/download}")
private String downloadpath;
@Value("${ibiz.file.previewpath:ibizutil/preview}")
private String previewpath;
@Value("${ibiz.auth.excludesPattern:}")
private String[] excludesPattern;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoderBean());
}
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
// Remove the ROLE_ prefix
return new GrantedAuthorityDefaults("");
}
@Bean
public PasswordEncoder passwordEncoderBean() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// 禁用 CSRF
.csrf().disable()
// 授权异常
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 不创建会话
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求
.authorizeRequests()
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**/*.ico",
"/**/assets/**",
"/**/css/**",
"/**/fonts/**",
"/**/js/**",
"/**/img/**",
"/",
"webjars/**",
"/swagger-resources/**",
"/v2/**"
).permitAll()
//放行登录请求
.antMatchers( HttpMethod.POST, "/"+loginPath).permitAll()
//放行注销请求
.antMatchers( HttpMethod.GET, "/"+logoutPath).permitAll()
// 文件操作
.antMatchers("/"+downloadpath+"/**").permitAll()
.antMatchers("/"+uploadpath).permitAll()
.antMatchers("/"+previewpath+"/**").permitAll();
for (String excludePattern : excludesPattern) {
authenticationTokenFilter.addExcludePattern(excludePattern);
httpSecurity.authorizeRequests().antMatchers(excludePattern).permitAll();
}
httpSecurity.authorizeRequests().anyRequest().authenticated()
// 防止iframe 造成跨域
.and().headers().frameOptions().disable();
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
server:
port: 8080
#zuul网关路由设置
zuul:
routes:
{{#if system.enableWorkflow}}
wfcore:
path: /wfcore/**
serviceId: ${ibiz.ref.service.wf:ibzwf-api}}
stripPrefix: true
{{/if}}
loginv7:
path: /v7/login
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}}
stripPrefix: false
changepwd:
path: /v7/changepwd
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}}
stripPrefix: false
uaa:
path: /uaa/**
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}}
stripPrefix: false
config:
path: /configs/**
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}}
stripPrefix: false
oucore:
path: /ibzorganizations/**
serviceId: ${ibiz.ref.service.ou:ibzou-api}}
stripPrefix: false
oudict:
path: /dictionarys/**/Ibzou**
serviceId: ${ibiz.ref.service.ou:ibzou-api}}
stripPrefix: false
ou:
path: /ibzdepartments/**
serviceId: ${ibiz.ref.service.ou:ibzou-api}}
stripPrefix: false
uaadict:
path: /dictionarys/**/SysOperator
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}}
stripPrefix: false
dict:
path: /dictionarys/**
serviceId: ${ibiz.ref.service.dict:ibzdict-api}}
stripPrefix: false
disk:
path: /net-disk/**
serviceId: ${ibiz.ref.service.disk:ibzdisk-api}}
stripPrefix: false
ou_sys_org:
path: /sysorganizations/**
serviceId: ${ibiz.ref.service.ou:ibzou-api}}
stripPrefix: false
ou_sys_dept:
path: /sysdepartments/**
serviceId: ${ibiz.ref.service.ou:ibzou-api}}
stripPrefix: false
lite-core:
path: /lite/**
serviceId: ${ibiz.ref.service.lite:ibzlite-api}}
stripPrefix: false
sysauthlog:
path: /sysauthlogs
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}}
stripPrefix: false
{{#each system.apps as | app |}}
{{#each app.appEntities}}
{{#eq entity.storage "ServiceAPI"}}
{{#serviceId}}
{{apps}}-{{lowerCase codeName}}:
path: /{{pluralize codeName}}/**
serviceId: ${ ibiz.ref.service.{{serviceId}}:{{serviceId}} }
stripPrefix: false
{{/serviceId}}
{{/eq}}
{{/each}}
{{/each}}
sensitive-headers:
- Cookie,Set-Cookie,Authorization
\ No newline at end of file
spring:
profiles:
include: sys , nacos ,{{#each apps}} {{apps}}-dev ,{{/each}}{{#each apis}} {{apis}}-dev ,{{/each}} dev
application:
name: {{projectName}}
main:
allow-bean-definition-overriding: true
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<property name="LOG_PATH" value="logs" />
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %-40.40logger{39} : %msg%n" />
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="LOG_PATTERN2" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr([${LOG_LEVEL_PATTERN:-%5p}]) %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}}" />
<!-- 控制台输出 -->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}}</pattern>
</encoder>
</appender>
<!--<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">-->
<!-- <destination>127.0.0.1:9601</destination>-->
<!-- <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">-->
<!-- <customFields>{"appname":"{{projectName}}"}</customFields>-->
<!-- </encoder>-->
<!--</appender>-->
<!-- 按照每天生成日志文件 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_PATH}}/{{projectName}}.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}}</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="Console" />
<appender-ref ref="file" />
<!--<appender-ref ref="LOGSTASH" />-->
</root>
</configuration>
package {{packageName}}.core.util.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* 通用配置类
*/
@Configuration
public class CommonAutoConfig {
@Value("${jbpm.enable.multi.con:true}")
private String flag;
/**
* 处理逻辑节点支持多来源配置
*/
@Component
public class InstallSystemParamsCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... var1){
System.setProperty("jbpm.enable.multi.con", flag);
}
}
}
package {{packageName}}.core.util.config;
import org.kie.api.KieServices;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.runtime.KieContainer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DroolsAutoConfiguration {
@Bean
@ConditionalOnMissingBean(KieContainer.class)
public KieContainer kieContainer() {
KieServices kieServices = KieServices.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieServices.newKieBuilder(kieFileSystem).buildAll();
return kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
}
}
\ No newline at end of file
package {{packageName}}.core.util.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import java.util.Properties;
import org.springframework.context.annotation.Primary;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.jdbc.DataSourceBuilder;
import cn.ibizlab.util.domain.LiquibaseProp;
import org.springframework.beans.factory.annotation.Autowired;
import liquibase.integration.spring.SpringLiquibase;
import org.springframework.util.StringUtils;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
@Configuration
public class LiquibaseConfiguration {
/**
* 主数据源版本管理
* @param
* @return
*/
@Bean
public SpringLiquibase masterliquibase(LiquibaseProp masterProperties) {
return LiquibaseInit(masterProperties);
}
/**
* liquibase初始化数据库
* @param properties
* @return
*/
private SpringLiquibase LiquibaseInit(LiquibaseProp properties){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUsername(properties.getUsername());
druidDataSource.setPassword(properties.getPassword());
druidDataSource.setUrl(properties.getUrl());
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(druidDataSource);
liquibase.setChangeLog(getChangelog(properties.getIsSyncDBSchema(),properties.getConf()));
liquibase.setContexts("development,test,production");
liquibase.setShouldRun(true);
liquibase.setDefaultSchema(properties.getDefaultSchema());
return liquibase;
}
/**
* 获取数据库差异文件
* @param isSyncDBSchema 是否同步表结构
* @param conf //liquibase配置文件
* @return
*/
private String getChangelog(String isSyncDBSchema,String conf){
String defaultChangelog="classpath:liquibase/empty.xml";
if((!StringUtils.isEmpty(isSyncDBSchema))&&(!StringUtils.isEmpty(conf))){
if(isSyncDBSchema.toLowerCase().equals("true"))
defaultChangelog=conf;
}
return defaultChangelog;
}
}
\ No newline at end of file
package {{packageName}}.core.util.config;
import cn.ibizlab.util.helper.JSR310DateConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.core.convert.*;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class MongoDBConfig {
@Bean
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converterList = new ArrayList<>();
converterList.add(JSR310DateConverters.DateToZonedDateTimeConverter.INSTANCE);
converterList.add(JSR310DateConverters.ZonedDateTimeToDateConverter.INSTANCE);
converterList.add(JSR310DateConverters.DurationToLongConverter.INSTANCE);
converterList.add(JSR310DateConverters.TimestampToDateConverter.INSTANCE);
converterList.add(JSR310DateConverters.DateToTimestampConverter.INSTANCE);
return new MongoCustomConversions(converterList);
}
}
\ No newline at end of file
package {{packageName}}.core.util.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
/**
* mybatis自动配置
*/
@Configuration
@ConditionalOnClass(MybatisConfiguration.class)
@ConditionalOnWebApplication
public class MybatisAutoConfiguration {
}
package {{packageName}}.core.util.config;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import cn.ibizlab.util.helper.UniqueNameGenerator;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Properties;
{{#eq system.saaSMode 4}}
import com.baomidou.mybatisplus.core.parser.ISqlParserFilter;
import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import com.baomidou.mybatisplus.core.parser.ISqlParser;
import org.apache.ibatis.mapping.MappedStatement;
import java.util.ArrayList;
import java.util.List;
{{/eq}}
/**
* mybatis全局配置类
*/
@Configuration
@MapperScan(value="{{packageName}}.core.*.mapper",nameGenerator = UniqueNameGenerator.class)
public class MybatisConfiguration {
{{#eq system.saaSMode 4}}
@Autowired
private {{packageName}}.core.util.config.SaaSTenantProperties saaSTenantProperties;
{{/eq}}
/**
* mybatis适配多数据库
* @return
*/
@Bean
public DatabaseIdProvider getDatabaseIdProvider() {
DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
Properties p = new Properties();
p.setProperty("Oracle", "oracle");
p.setProperty("MySQL", "mysql");
p.setProperty("PostgreSQL", "postgresql");
p.setProperty("DM", "oracle");//达梦数据库使用oracle模式
p.setProperty("H2", "mysql");//根据当前运行的数据库设置h2对应的databaseid
databaseIdProvider.setProperties(p);
return databaseIdProvider;
}
/**
* mybatis-plus分页
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor({{#eq system.saaSMode 4}}SaaSTenantHandler saaSTenantHandler{{/eq}}) {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInterceptor.setLimit(-1);
{{#eq system.saaSMode 4}}
// 创建SQL解析器集合
List<ISqlParser> sqlParserList = new ArrayList<>();
// 创建租户SQL解析器
SaaSTenantSqlParser tenantSqlParser = new SaaSTenantSqlParser();
// 设置租户处理器
tenantSqlParser.setTenantHandler(saaSTenantHandler);
sqlParserList.add(tenantSqlParser);
paginationInterceptor.setSqlParserList(sqlParserList);
// 设置租户忽略
paginationInterceptor.setSqlParserFilter(ignoreParserFilter());
{{/eq}}
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
{{#eq system.saaSMode 4}}
@Bean
public ISqlParserFilter ignoreParserFilter() {
return metaObject -> {
// 此处就过滤
MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
if (saaSTenantProperties.getIgnoreMappers().contains(ms.getId())) {
return true;
}
return false;
};
}
{{/eq}}
}
\ No newline at end of file
package {{packageName}}.core.util.config;
import com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration;
import cn.ibizlab.util.errors.BadRequestAlertException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.management.Query;
import java.lang.management.ManagementFactory;
import java.util.Set;
/**
* 外部容器启动服务时,自动注册服务到nacos
*/
@Component
@Slf4j
@ConditionalOnExpression("'${ibiz.deploy.packagetype:jar}'.equals('war')")
public class NacosRegisterConfig implements ApplicationRunner {
@Autowired(required = false)
private NacosAutoServiceRegistration registration;
@Value("${server.port:8080}")
Integer port;
@Override
public void run(ApplicationArguments args) {
log.info("正在尝试将应用程序注册到nacos");
if (registration != null && port != null) {
try {
String containerPort = getContainerPort();
if(!StringUtils.isEmpty(containerPort)){
registration.setPort(new Integer(containerPort));
}
else{
registration.setPort(port);
log.info("无法获取外部容器端口,将使用程序默认端口{}",port);
}
registration.start();
} catch (Exception e) {
throw new BadRequestAlertException("应用程序注册到nacos失败,"+e,"","");
}
log.info("已将应用程序成功注册到nacos");
}
else{
log.info("无法获取应用程序端口,将应用程序注册到nacos请求被忽略。");
}
}
/**
* 获取外部容器端口
*/
public String getContainerPort(){
String port = null;
try {
MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
Set<ObjectName> objectNames = beanServer.queryNames(new ObjectName("*:type=Connector,*"), Query.match(Query.attr("protocol"), Query.value("HTTP/1.1")));
if(!ObjectUtils.isEmpty(objectNames)){
port = objectNames.iterator().next().getKeyProperty("port");
}
}
catch (Exception e) {
log.error("获取外部容器端口失败!"+e);
}
return port;
}
}
</#if>
\ No newline at end of file
package {{packageName}}.core.util.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@Slf4j
@Configuration
@ConditionalOnExpression("'${rocketmq.consumer.isOnOff:off}'.equals('on')")
public class RocketMQConsumer {
@Value("${rocketmq.consumer.groupName:default}")
private String groupName;
@Value("${rocketmq.consumer.topic:default}")
private String topic;
@Value("${rocketmq.consumer.namesrvAddr:127.0.0.1:9876}")
private String namesrvAddr;
@Value("${rocketmq.consumer.consumeThreadMin:1}")
private Integer consumeThreadMin;
@Value("${rocketmq.consumer.consumeThreadMax:1}")
private Integer consumeThreadMax;
@Value("${rocketmq.consumer.consumeMessageBatchMaxSize:1}")
private Integer consumeMessageBatchMaxSize;
@Autowired
@Lazy
private RocketMQListenerProcessor listenerProcessor;
/**
* mq 消费者配置
*
* @return
* @throws MQClientException
*/
@Bean
public DefaultMQPushConsumer defaultConsumer() {
log.info("defaultConsumer 正在创建---------------------------------------");
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(groupName);
consumer.setNamesrvAddr(namesrvAddr);
consumer.setConsumeThreadMin(consumeThreadMin);
consumer.setConsumeThreadMax(consumeThreadMax);
consumer.setConsumeMessageBatchMaxSize(consumeMessageBatchMaxSize);
// 设置监听
consumer.registerMessageListener(listenerProcessor);
/**
* 设置consumer第一次启动是从队列头部开始还是队列尾部开始
* 如果不是第一次启动,那么按照上次消费的位置继续消费
*/
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
/**
* 设置消费模型,集群还是广播,默认为集群
*/
//consumer.setMessageModel(MessageModel.CLUSTERING);
try {
consumer.subscribe(topic, "{{#each system.mqSubscribes}}{{#unless @first}} || {{/unless}}{{lowerCase this}}{{/each}}");
consumer.start();
log.info("rocketmq consumer 创建成功 groupName={}, topics={}, namesrvAddr={}", groupName, topic, namesrvAddr);
} catch (MQClientException e) {
log.error("rocketmq consumer 创建失败!" + e);
}
return consumer;
}
}
\ No newline at end of file
package {{packageName}}.core.util.config;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import cn.ibizlab.util.domain.EntityBase;
import java.util.List;
import java.util.Map;
/**
* MQ订阅消息处理
*/
@Slf4j
@Component
@ConditionalOnExpression("'${rocketmq.consumer.isOnOff:off}'.equals('on')")
public class RocketMQListenerProcessor implements MessageListenerOrderly {
{{#each system.entities as | entity |}}
{{#if entity.allPSDEDataSyncs}}
@Autowired
@Lazy
{{packageName}}.core.{{entity.module}}.service.I{{entity.codeName}}Service {{camelCase entity.codeName}}Service;
{{/if}}
{{/each}}
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> list, ConsumeOrderlyContext consumeOrderlyContext) {
if (CollectionUtils.isEmpty(list)) {
log.info("MQ接收消息为空,直接返回成功");
return ConsumeOrderlyStatus.SUCCESS;
}
for (MessageExt messageExt : list) {
log.info("MQ接收到的消息为:" + messageExt.toString());
try {
String topic = messageExt.getTopic();
String tags = messageExt.getTags();
String body = new String(messageExt.getBody(),"utf-8");
log.info("MQ消息topic={}, tags={}, 消息内容={}", topic, tags, body);
{{#each system.entities as | entity |}}
{{#each entity.allPSDEDataSyncs as | dataSync |}}
{{#if dataSync.inPSSysDataSyncAgent}}
{{#if dataSync.inTestPSDEAction}}
{{#unless @first}}else {{/unless}}if ("{{lowerCase dataSync.codeName}}".equalsIgnoreCase(tags)) {
{{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}} domain = EntityBase.fromJSONString(body,{{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}}.class);
{{camelCase entity.codeName}}Service.{{camelCase dataSync.inTestPSDEAction.codeName}}(domain);
}
{{else}}
log.info("接收到[{"+tags+"}]消息,但未配置实体输入过滤行为,消息将被忽略。"+body);
{{/if}}
{{/if}}
{{/each}}
{{/each}}
} catch (Exception e) {
log.error("获取MQ消息内容异常{}", e);
}
}
return ConsumeOrderlyStatus.SUCCESS;
}
}
\ No newline at end of file
package {{packageName}}.core.util.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@Slf4j
@Configuration
@ConditionalOnExpression("'${rocketmq.producer.isOnOff:off}'.equals('on')")
public class RocketMQProducer {
@Value("${rocketmq.producer.groupName:default}")
private String groupName;
@Value("${rocketmq.producer.namesrvAddr:127.0.0.1:9876}")
private String namesrvAddr;
// 消息最大值
@Value("${rocketmq.producer.maxMessageSize:409600}")
private Integer maxMessageSize;
// 消息发送超时时间
@Value("${rocketmq.producer.sendMsgTimeOut:3000}")
private Integer sendMsgTimeOut;
// 失败重试次数
@Value("${rocketmq.producer.retryTimesWhenSendFailed:2}")
private Integer retryTimesWhenSendFailed;
/**
* mq 生成者配置
*
* @return
* @throws MQClientException
*/
@Bean
public DefaultMQProducer defaultProducer() throws MQClientException {
log.info("rocketmq defaultProducer 正在创建---------------------------------------");
DefaultMQProducer producer = new DefaultMQProducer(groupName);
producer.setNamesrvAddr(namesrvAddr);
producer.setVipChannelEnabled(false);
producer.setMaxMessageSize(maxMessageSize);
producer.setSendMsgTimeout(sendMsgTimeOut);
producer.setRetryTimesWhenSendAsyncFailed(retryTimesWhenSendFailed);
producer.start();
log.info("rocketmq producer server 开启成功----------------------------------");
return producer;
}
}
{{#eq system.saaSMode 4}}
package {{packageName}}.core.util.config;
import cn.ibizlab.util.security.AuthenticationUser;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@EnableConfigurationProperties(SaaSTenantProperties.class)
public class SaaSTenantHandler implements TenantHandler {
@Autowired
private SaaSTenantProperties saaSTenantProperties;
@Override
public Expression getTenantId(boolean where) {
AuthenticationUser user = AuthenticationUser.getAuthenticationUser();
return new StringValue(user.getSrfdcid());
}
@Override
public String getTenantIdColumn() {
return saaSTenantProperties.getColumn();
}
@Override
public boolean doTableFilter(String tableName) {
String strTableName = tableName.replace("`","") ;
if (saaSTenantProperties.getSysTables().stream().anyMatch(table -> table.equalsIgnoreCase(strTableName)))
return true;
return false;
}
}
{{/eq}}
\ No newline at end of file
{{#eq system.saaSMode 4}}
package {{packageName}}.core.util.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.List;
@Getter
@Setter
@ConfigurationProperties(prefix = "ibiz.saas")
public class SaaSTenantProperties {
/**
* 多租户字段名称
*/
private String column = "SRFDCID";
/**
* 多租户系统数据表
*/
private List<String> sysTables = new ArrayList<>();
/**
* 多租户忽略租户查询
*/
private List<String> ignoreMappers = new ArrayList<>();
}
{{/eq}}
\ No newline at end of file
{{#eq system.saaSMode 4}}
package {{packageName}}.core.util.config;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import net.sf.jsqlparser.expression.*;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.Division;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.expression.operators.arithmetic.Subtraction;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.*;
import java.util.List;
public class SaaSTenantSqlParser extends TenantSqlParser {
/**
* 处理 PlainSelect
*
* @param plainSelect ignore
* @param addColumn 是否添加租户列,insert into select语句中需要
*/
@Override
protected void processPlainSelect(PlainSelect plainSelect, boolean addColumn) {
//处理selectItem表达式
processSelectItem(plainSelect);
FromItem fromItem = plainSelect.getFromItem();
if (fromItem instanceof Table) {
Table fromTable = (Table) fromItem;
if (!this.getTenantHandler().doTableFilter(fromTable.getName())) {
plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable));
if (addColumn) {
if (fromItem.getAlias() != null) {
plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(fromItem.getAlias().getName() + StringPool.DOT + this.getTenantHandler().getTenantIdColumn())));
}else {
plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(this.getTenantHandler().getTenantIdColumn())));
}
}
}
} else {
processFromItem(fromItem);
}
List<Join> joins = plainSelect.getJoins();
if (joins != null && joins.size() > 0) {
joins.forEach(j -> {
processJoin(j);
processFromItem(j.getRightItem());
});
}
//处理where表达式
processExcepression(plainSelect.getWhere());
}
/**
* exception 表达式处理
*/
protected void processExcepression(Expression exception) {
if (exception == null) {
return;
}else if (exception instanceof AndExpression) {
processExcepression(((AndExpression) exception).getLeftExpression());
processExcepression(((AndExpression) exception).getRightExpression());
} else if (exception instanceof OrExpression) {
processExcepression(((OrExpression) exception).getLeftExpression());
processExcepression(((OrExpression) exception).getRightExpression());
} else if (exception instanceof Parenthesis) {
processExcepression(((Parenthesis) exception).getExpression());
} else if (exception instanceof NotExpression) {
processExcepression(((NotExpression) exception).getExpression());
} else if (exception instanceof InExpression) {
processExcepression(((InExpression) exception).getLeftExpression());
if(((InExpression) exception).getRightItemsList() instanceof SubSelect) {
this.processSelectBody(((SubSelect) ((InExpression) exception).getRightItemsList()).getSelectBody());
}
} else if (exception instanceof EqualsTo) {
processExcepression(((EqualsTo) exception).getLeftExpression());
processExcepression(((EqualsTo) exception).getRightExpression());
} else if (exception instanceof ExistsExpression) {
processExcepression(((ExistsExpression) exception).getRightExpression());
} else if (exception instanceof GreaterThan) {
processExcepression(((GreaterThan) exception).getLeftExpression());
processExcepression(((GreaterThan) exception).getRightExpression());
} else if (exception instanceof GreaterThanEquals) {
processExcepression(((GreaterThanEquals) exception).getLeftExpression());
processExcepression(((GreaterThanEquals) exception).getRightExpression());
} else if (exception instanceof MinorThan) {
processExcepression(((MinorThan) exception).getLeftExpression());
processExcepression(((MinorThan) exception).getRightExpression());
} else if (exception instanceof MinorThanEquals) {
processExcepression(((MinorThanEquals) exception).getLeftExpression());
processExcepression(((MinorThanEquals) exception).getRightExpression());
} else if (exception instanceof NotEqualsTo) {
processExcepression(((NotEqualsTo) exception).getLeftExpression());
processExcepression(((NotEqualsTo) exception).getRightExpression());
} else if (exception instanceof IsBooleanExpression) {
processExcepression(((IsBooleanExpression) exception).getLeftExpression());
} else if (exception instanceof IsNullExpression) {
processExcepression(((IsNullExpression) exception).getLeftExpression());
} else if (exception instanceof LikeExpression) {
processExcepression(((LikeExpression) exception).getLeftExpression());
processExcepression(((LikeExpression) exception).getRightExpression());
} else if (exception instanceof Between) {
processExcepression(((Between) exception).getLeftExpression());
processExcepression(((Between) exception).getBetweenExpressionStart());
processExcepression(((Between) exception).getBetweenExpressionEnd());
} else if (exception instanceof Function) {
if(null != ((Function) exception).getParameters()) {
for (Expression e : ((Function) exception).getParameters().getExpressions()) {
processExcepression(e);
}
}
} else if (exception instanceof CaseExpression) {
CaseExpression caseExpression = (CaseExpression) exception;
processExcepression(caseExpression.getElseExpression());
processExcepression(caseExpression.getSwitchExpression());
for (WhenClause whenClause : caseExpression.getWhenClauses()) {
processExcepression(whenClause.getWhenExpression());
processExcepression(whenClause.getThenExpression());
}
}else if(exception instanceof Subtraction){
processExcepression(((Subtraction) exception).getLeftExpression());
processExcepression(((Subtraction) exception).getRightExpression());
}else if(exception instanceof Multiplication){
processExcepression(((Multiplication) exception).getLeftExpression());
processExcepression(((Multiplication) exception).getRightExpression());
}else if(exception instanceof Addition){
processExcepression(((Addition) exception).getLeftExpression());
processExcepression(((Addition) exception).getRightExpression());
}else if(exception instanceof Division){
processExcepression(((Division) exception).getLeftExpression());
processExcepression(((Division) exception).getRightExpression());
} else if (exception instanceof SubSelect) {
this.processSelectBody(((SubSelect) exception).getSelectBody());
}
}
/**
* select 中包含 select、function 添加租户id
*/
protected void processSelectItem(PlainSelect plainSelect) {
List<SelectItem> selectItems = plainSelect.getSelectItems();
for (SelectItem selectItem : selectItems) {
if (selectItem instanceof SelectExpressionItem) {
Expression selectExcepression = ((SelectExpressionItem) selectItem).getExpression();
processExcepression(selectExcepression);
}
}
}
}
{{/eq}}
\ No newline at end of file
......@@ -14,14 +14,14 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.util.ObjectUtils;
import org.springframework.util.DigestUtils;
import {{packageName}}.util.domain.EntityBase;
import {{packageName}}.util.annotation.DEField;
import {{packageName}}.util.enums.DEPredefinedFieldType;
import {{packageName}}.util.enums.DEFieldDefaultValueType;
import {{packageName}}.util.helper.DataObject;
import {{packageName}}.util.annotation.Audit;
import {{packageName}}.util.enums.DupCheck;
import {{packageName}}.util.domain.EntityMP;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.enums.DEPredefinedFieldType;
import cn.ibizlab.util.enums.DEFieldDefaultValueType;
import cn.ibizlab.util.helper.DataObject;
import cn.ibizlab.util.annotation.Audit;
import cn.ibizlab.util.enums.DupCheck;
import cn.ibizlab.util.domain.EntityMP;
import java.io.Serializable;
import lombok.*;
import org.springframework.data.annotation.Transient;
......
......@@ -18,7 +18,7 @@ import org.springframework.util.StringUtils;
{{#entity.enableES}}
import org.elasticsearch.index.query.QueryBuilders;
{{/entity.enableES}}
import {{packageName}}.util.filter.QueryWrapperContext;
import cn.ibizlab.util.filter.QueryWrapperContext;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import {{packageName}}.core.{{module}}.filte.{{entity.codeName}};
/**
......
......@@ -27,6 +27,10 @@ import {{packageName}}.core.{{module}}.filter.{{entity.codeName}}SearchContext;
public interface I{{entity.codeName}}Service extends IService<{{entity.codeName}}> {
{{entity.codeName}} get({{entity.keyField.type.java}} key);
default {{entity.codeName}} get({{entity.codeName}} et) {
CachedBeanCopier.copy(get(et.get{{pascalCase entity.keyField.codeName}}()), et);
return et;
}
List<{{entity.codeName}}> getByIds(Collection<{{entity.keyField.type.java}}> idList);
List<{{entity.codeName}}> getByEntities(Collection<{{entity.codeName}}> entities);
......@@ -53,6 +57,9 @@ public interface I{{entity.codeName}}Service extends IService<{{entity.codeName}
boolean saveBatch(List<{{entity.codeName}}> list);
boolean remove({{entity.keyField.type.java}} key);
default boolean remove({{entity.codeName}} et) {
return remove(et.get{{pascalCase entity.keyField.codeName}}());
}
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
......
......@@ -21,7 +21,7 @@ import org.springframework.data.domain.Pageable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import {{packageName}}.util.errors.BadRequestAlertException;
import cn.ibizlab.util.errors.BadRequestAlertException;
<#system.enableGlobalTransaction>
import io.seata.spring.annotation.GlobalTransactional;
</system.enableGlobalTransaction>
......@@ -31,8 +31,8 @@ import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
import {{packageName}}.core.{{entity.module}}.service.I{{entity.codeName}}Service;
import {{packageName}}.core.{{entity.module}}.mapper.${item.getCodeName()}Mapper;
import {{packageName}}.util.helper.CachedBeanCopier;
import {{packageName}}.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.helper.CachedBeanCopier;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign eurekaUrl = "http://127.0.0.1:8762/eureka/" >
<#comment>前端应用微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepApps()??>
<#list sys.getAllPSDevSlnMSDepApps() as depApp>
<#if depApp.getPSDCMSPlatform()??>
<#assign appPlatform=depApp.getPSDCMSPlatform()>
<#if appPlatform.getUserParam("eureka","http://127.0.0.1:8762/eureka/")??>
<#assign eurekaUrl = appPlatform.getUserParam("eureka","http://127.0.0.1:8762/eureka/")>
</#if>
<#break>
</#if>
</#list>
</#if>
<#comment>服务接口微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepAPIs()??>
<#list sys.getAllPSDevSlnMSDepAPIs() as depSysApi>
<#if depSysApi.getPSDCMSPlatform()?? >
<#assign sysApiPlatform=depSysApi.getPSDCMSPlatform()>
<#if sysApiPlatform.getUserParam("eureka","http://127.0.0.1:8762/eureka/")??>
<#assign eurekaUrl = sysApiPlatform.getUserParam("eureka","http://127.0.0.1:8762/eureka/")>
</#if>
<#break>
</#if>
</#list>
</#if>
#eureka配置中心
spring:
cloud:
nacos:
discovery:
enabled: false
eureka:
client:
enabled: true
serviceUrl:
defaultZone: ${eurekaUrl}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign nacosUrl = "127.0.0.1:8848" >
<#comment>前端应用微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepApps()??>
<#list sys.getAllPSDevSlnMSDepApps() as depApp>
<#if depApp.getPSDCMSPlatform()??>
<#assign appPlatform=depApp.getPSDCMSPlatform()>
<#if appPlatform.getUserParam("nacos","127.0.0.1:8848")??>
<#assign nacosUrl = appPlatform.getUserParam("nacos","127.0.0.1:8848")>
</#if>
<#break>
</#if>
</#list>
</#if>
<#comment>服务接口微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepAPIs()??>
<#list sys.getAllPSDevSlnMSDepAPIs() as depSysApi>
<#if depSysApi.getPSDCMSPlatform()?? >
<#assign sysApiPlatform=depSysApi.getPSDCMSPlatform()>
<#if sysApiPlatform.getUserParam("nacos","127.0.0.1:8848")??>
<#assign nacosUrl = sysApiPlatform.getUserParam("nacos","127.0.0.1:8848")>
</#if>
<#break>
</#if>
</#list>
</#if>
#nacos配置中心
spring:
cloud:
nacos:
discovery:
server-addr: ${nacosUrl}
enabled: true
eureka:
client:
enabled: false
......@@ -83,6 +83,8 @@
<!-- 阿里seata分布式事务 -->
<alibaba-seata.version>1.3.0</alibaba-seata.version>
<log4j2.version>2.16.0</log4j2.version>
{{#system.enableOracle}}
<oracle.version>19.8.0.0</oracle.version>
{{/system.enableOracle}}
......
FROM image.ibizlab.cn/library/openjdk:8-jre-alpine
ENV TZ="Asia/Shanghai" \
SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
IBIZ_SLEEP=0 \
JAVA_OPTS=""
CMD echo "The application will start in ${IBIZ_SLEEP}s..." && \
sleep ${IBIZ_SLEEP} && \
java ${JAVA_OPTS} -Duser.timezone=$TZ -Djava.security.egd=file:/dev/./urandom -jar /{{projectName}}-provider-{{apis}}.jar
EXPOSE {{#if app.httpPort}}{{app.httpPort}}{{else}}8080{{/if}}
ADD {{projectName}}-provider-{{apis}}.jar /{{projectName}}-provider-{{apis}}.jar
package {{packageName}}.swagger;
import cn.ibizlab.util.security.SpringContextHolder;
import cn.ibizlab.util.web.IBZOperationParameterReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.plugin.core.PluginRegistry;
import org.springframework.plugin.core.PluginRegistrySupport;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.EnumTypeDeterminer;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.spring.web.readers.operation.OperationParameterReader;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
@Configuration
@EnableSwagger2
@ConditionalOnExpression("${swagger.enable:false}")
public class SwaggerConfiguration {
@Bean
public Docket docket() {
Docket docket = new Docket(DocumentationType.SWAGGER_2)
.groupName("DEFAULT")
.pathMapping("/")
.apiInfo(
new ApiInfoBuilder()
.title("DEFAULT")
.build()
)
.select()
.apis(RequestHandlerSelectors.basePackage("{{packageName}}"))
//.paths(or(regex("/rest/.*")))
.paths(PathSelectors.any())
.build();
removeDefaultPlugin();
return docket ;
}
@Bean
public Docket {{apis}}Docket() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("{{api.name}}")
.pathMapping("/")
.apiInfo(
new ApiInfoBuilder()
.title("{{api.name}}")
.version("{{api.aPIVersion}}")
.build()
)
.select()
.apis(RequestHandlerSelectors.basePackage("{{packageName}}.{{api.codeName}}"))
.paths(PathSelectors.any())
.build();
}
private void removeDefaultPlugin() {
// 从spring容器中获取swagger插件注册表
PluginRegistry<OperationBuilderPlugin, DocumentationType> pluginRegistry = SpringContextHolder.getBean("operationBuilderPluginRegistry");
// 插件集合
List<OperationBuilderPlugin> plugins = pluginRegistry.getPlugins();
// 从spring容器中获取需要删除的插件
OperationParameterReader operationParameterReader = SpringContextHolder.getBean(OperationParameterReader.class);
if(operationParameterReader==null)
return ;
// 原plugins集合不能修改,创建新集合,通过反射替换
if (pluginRegistry.contains(operationParameterReader)) {
List<OperationBuilderPlugin> plugins_new = new ArrayList<OperationBuilderPlugin>(plugins);
plugins_new.remove(operationParameterReader);
try {
Field field = PluginRegistrySupport.class.getDeclaredField("plugins");
field.setAccessible(true);
field.set(pluginRegistry, plugins_new);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Bean
public IBZOperationParameterReader iBZOperationParameterReader(ModelAttributeParameterExpander expander,EnumTypeDeterminer enumTypeDeterminer){
IBZOperationParameterReader iBZOperationParameterReader = new IBZOperationParameterReader(expander, enumTypeDeterminer) ;
return iBZOperationParameterReader ;
}
}
package {{packageName}}.{{apis}}.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Import;
{{#if system.enableGlobalTransaction}}
@Import({com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration.class})
{{/if}}
@Configuration
@ConditionalOnClass({{api.codeName}}RestConfiguration.class)
@ConditionalOnWebApplication
@EnableConfigurationProperties({{api.codeName}}ServiceProperties.class)
public class {{api.codeName}}AutoConfiguration implements ApplicationContextAware {
protected ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Bean("asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(2000);
executor.setKeepAliveSeconds(600);
executor.setThreadNamePrefix("asyncExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
// @Bean
// public ServletRegistrationBean {{api.codeName}}Servlet() {
// AnnotationConfigWebApplicationContext dispatcherServletConfiguration = new AnnotationConfigWebApplicationContext();
// dispatcherServletConfiguration.setParent(applicationContext);
// dispatcherServletConfiguration.register({{api.codeName}}RestConfiguration.class);
// DispatcherServlet servlet = new DispatcherServlet(dispatcherServletConfiguration);
// String path = "/{{lowerCase api.codeName}}";
// String urlMapping = (path.endsWith("/") ? path + "*" : path + "/*");
// ServletRegistrationBean registrationBean = new ServletRegistrationBean(servlet, urlMapping);
// registrationBean.setName("{{api.codeName}}");
// return registrationBean;
// }
}
package {{packageName}}.{{apis}}.config;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("{{packageName}}.{{apis}}")
public class {{api.codeName}}RestConfiguration {
}
package {{packageName}}.{{apis}}.config;
import cn.ibizlab.util.security.AuthenticationEntryPoint;
import cn.ibizlab.util.security.AuthorizationTokenFilter;
import cn.ibizlab.util.service.AuthenticationUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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.core.GrantedAuthorityDefaults;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.context.annotation.Profile;
import org.springframework.beans.factory.annotation.Qualifier;
@Profile("{{apis}}-prod")
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class {{api.codeName}}SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationEntryPoint unauthorizedHandler;
@Autowired
private AuthenticationUserService userDetailsService;
/**
* 自定义基于JWT的安全过滤器
*/
@Autowired
AuthorizationTokenFilter authenticationTokenFilter;
@Value("${ibiz.auth.path:v7/login}")
private String loginPath;
@Value("${ibiz.auth.logoutpath:v7/logout}")
private String logoutPath;
@Value("${ibiz.file.uploadpath:ibizutil/upload}")
private String uploadpath;
@Value("${ibiz.file.downloadpath:ibizutil/download}")
private String downloadpath;
@Value("${ibiz.file.previewpath:ibizutil/preview}")
private String previewpath;
@Value("${ibiz.auth.excludesPattern:}")
private String[] excludesPattern;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoderBean());
}
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
// Remove the ROLE_ prefix
return new GrantedAuthorityDefaults("");
}
@Bean
public PasswordEncoder passwordEncoderBean() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// 禁用 CSRF
.csrf().disable()
// 授权异常
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 不创建会话
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求
.authorizeRequests()
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**/*.ico",
"/**/assets/**",
"/**/css/**",
"/**/fonts/**",
"/**/js/**",
"/**/img/**",
"/",
"webjars/**",
"/swagger-resources/**",
"/v2/**"
).permitAll()
//放行登录请求
.antMatchers( HttpMethod.POST, "/"+loginPath).permitAll()
//放行注销请求
.antMatchers( HttpMethod.GET, "/"+logoutPath).permitAll()
// 文件操作
.antMatchers("/"+downloadpath+"/**").permitAll()
.antMatchers("/"+uploadpath).permitAll()
.antMatchers("/"+previewpath+"/**").permitAll();
for (String excludePattern : excludesPattern) {
authenticationTokenFilter.addExcludePattern(excludePattern);
httpSecurity.authorizeRequests().antMatchers(excludePattern).permitAll();
}
// 所有请求都需要认证
httpSecurity.authorizeRequests().anyRequest().authenticated()
// 防止iframe 造成跨域
.and().headers().frameOptions().disable();
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
package {{packageName}}.{{apis}}.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Data;
@ConfigurationProperties(prefix = "service.{{apis}}")
@Data
public class {{apis.codeName}}ServiceProperties {
private boolean enabled;
private boolean auth;
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSDESERVICEAPI
</#ibiztemplate>
<#comment>引入驼峰配置</#comment>
<#ibizinclude>/SLN/globalfunc.cfg</#ibizinclude>
<#comment>不发布子系统实体</#comment>
<#if de.isSubSysDE()==false>
<#assign pubPkgCodeName = pub.getPKGCodeName()>
<#assign itemSysApiCodeNameLC = item.getPSSysServiceAPI().getCodeName()?lower_case>
<#assign dtoBase="DTOBase">
<#comment>中台模式通过DTOClient设置dirtyflag</#comment>
<#if ((de.getPSSubSysServiceAPI().getServiceType())!'')=='MIDDLEPLATFORM'>
<#assign dtoBase="DTOClient">
</#if>
<#assign hasValueRuleGroup=false>
<#if sys.codeName == 'Sample'>
<#if de.getAllPSDEFValueRules()??>
<#list de.getAllPSDEFValueRules() as deRule>
<#if deRule.codeName!='Default'>
<#if deRule.getPSDEFVRGroupCondition()??>
<#assign hasValueRuleGroup=true>
<#break>
</#if>
</#if>
</#list>
</#if>
</#if>
package {{packageName}}.{{apis}}.dto;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.math.BigInteger;
import java.util.Map;
import java.util.HashMap;
import java.io.Serializable;
import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.alibaba.fastjson.annotation.JSONField;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import cn.ibizlab.util.domain.DTOBase;
import cn.ibizlab.util.domain.DTOClient;
import lombok.Data;
<#if hasValueRuleGroup>
import cn.ibizlab.util.annotation.ValueRuleCheck;
</#if>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 服务DTO对象[${item.getCodeName()}DTO]
*/
@Data
<@valueRuleGroup/>
@ApiModel("${item.getLogicName()}")
public class ${item.getCodeName()}DTO extends ${dtoBase} implements Serializable {
private static final long serialVersionUID = 1L;
<#if item.getPSDEServiceAPIFields()??>
<#comment>接口属性集合</#comment>
<#list item.getPSDEServiceAPIFields() as apifield>
<#assign defDataType = (apifield.getPSDEField().getDataType())!"">
<#assign columnname = apifield.getName()?lower_case>
<#assign prvateCodeName = srfr7templcaseformat(apifield.getCodeName()) >
<#assign publicCodeName = prvateCodeName?cap_first >
<#assign jsonfield = apifield.getCodeName()?lower_case >
<#assign defield=(apifield.getPSDEField())!"">
<#if defDataType!='ONE2MANYDATA'>
/**
* 属性 [${apifield.getName()}]
*
*/
<#if defDataType == "DATETIME" || ((defDataType=='PICKUPDATA'||defDataType=='INHERIT') && srfdatatype(apifield.getStdDataType())== "DATETIME" && apifield.getPSDEField().getValueFormat()=="%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS")>
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", locale = "zh" , timezone="GMT+8")
@JSONField(name = "${jsonfield}" , format="yyyy-MM-dd HH:mm:ss")
<#elseif defDataType == "DATE" || ((defDataType=='PICKUPDATA'||defDataType=='INHERIT') && srfdatatype(apifield.getStdDataType())== "DATETIME" && apifield.getPSDEField().getValueFormat()=="%1$tY-%1$tm-%1$td")>
@JsonFormat(pattern="yyyy-MM-dd", locale = "zh" , timezone="GMT+8")
@JSONField(name = "${jsonfield}" , format="yyyy-MM-dd")
<#elseif defDataType == "TIME" || ((defDataType=='PICKUPDATA'||defDataType=='INHERIT') && srfdatatype(apifield.getStdDataType())== "DATETIME" && apifield.getPSDEField().getValueFormat()=="%1$tH:%1$tM:%1$tS")>
@JsonFormat(pattern="HH:mm:ss", locale = "zh" , timezone="GMT+8")
@JSONField(name = "${jsonfield}" , format="HH:mm:ss")
<#else>
@JSONField(name = "${jsonfield}")
</#if>
@JsonProperty("${jsonfield}")
<#comment>Long型数据转String,解决前端精度丢失问题</#comment>
<#if srfr7javatype(apifield.getStdDataType())=='Long'>
@JsonSerialize(using = ToStringSerializer.class)
</#if>
<@valueRule defield />
@ApiModelProperty("${apifield.getLogicName()}")
private ${srfr7javatype(apifield.getStdDataType())} ${prvateCodeName};
</#if>
</#list>
</#if>
<#comment>输出set方法用于设置null值</#comment>
<#list item.getPSDEServiceAPIFields() as apifield>
<#assign defield = apifield.getPSDEField() >
<#assign defDataType = (defield.getDataType())!"">
<#assign columnname = apifield.getName()?lower_case>
<#assign prvateCodeName = srfr7templcaseformat(apifield.getCodeName()) >
<#assign publicCodeName = prvateCodeName?cap_first >
<#if defield.isPhisicalDEField()==true && defield.isKeyDEField()==false && defDataType!='ONE2MANYDATA'>
<#if defield.getPredefinedType()?? && defield.getPredefinedType()!=''>
<#else >
/**
* 设置 [${apifield.getName()}]
*/
public void set${publicCodeName}(${srfr7javatype(apifield.getStdDataType())} ${prvateCodeName}){
this.${prvateCodeName} = ${prvateCodeName} ;
this.modify("${columnname}",${prvateCodeName});
}
</#if>
</#if>
</#list>
<#comment>输出关系数据(子实体)</#comment>
<#if item.getPSDEServiceAPIRSs()?? >
<#list item.getPSDEServiceAPIRSs() as apider>
<#if apider.getPSDER1N()??>
<#assign der = apider.getPSDER1N() >
<#if apider.getMinorPSDEServiceAPI().isNested()>
<#assign subDTOs = srfpluralize(apider.getMinorPSDEServiceAPI().getCodeName())?lower_case >
<#assign subcode = srfr7templcaseformat((der.getMinorCodeName()!der.getMinorPSDataEntity().getCodeName())) >
<#if subcode?? && subcode==''><#assign subcode=srfr7templcaseformat(der.getMinorPSDataEntity().getCodeName())></#if>
/**
* [${apider.getMinorPSDEServiceAPI().getName()}]
*/
@JsonProperty("${subDTOs}")
@JSONField(name = "${subDTOs}")
private List<${apider.getMinorPSDEServiceAPI().getCodeName()}DTO> ${subcode} ;
</#if>
</#if>
</#list>
</#if>
}
</#if>
<#comment>属性值规则</#comment>
<#macro valueRule defield>
<#if defield !=''>
<#if defield.isKeyDEField()==true || defield.getPredefinedType()?? && defield.getPredefinedType()!=''>
<#else>
<#if defield.isAllowEmpty()==false>
<#assign notNullMsg="["+defield.getLogicName()+"]不允许为空!">
<#if srfr7javatype(defield.stdDataType)=='String'>
@NotBlank(message = "${notNullMsg}")
<#else>
@NotNull(message = "${notNullMsg}")
</#if>
</#if>
</#if>
<#if defield.getAllPSDEFValueRules()??>
<#list defield.getAllPSDEFValueRules() as defieldVR>
<#if defieldVR.getPSDEFVRGroupCondition?? && defieldVR.getPSDEFVRGroupCondition()?? && defieldVR.getCodeName()=='Default'>
<#assign vrCond=defieldVR.getPSDEFVRGroupCondition()>
<#assign vrCondType=vrCond.getCondType()>
<#assign vrCondOp=vrCond.getCondOp()>
<#if vrCond.getPSDEFVRConditions?? && vrCond.getPSDEFVRConditions()??>
<#list vrCond.getPSDEFVRConditions() as subVRCond>
<#if subVRCond.getCondType()=='STRINGLENGTH'>
<#if subVRCond.getMaxValue()?c!='-1'>
@Size(min = 0, max = ${subVRCond.getMaxValue()?c}, message = "${subVRCond.getRuleInfo()}")
</#if>
</#if>
</#list>
</#if>
</#if>
</#list>
</#if>
</#if>
</#macro>
<#comment>属性值规则(规则组)</#comment>
<#macro valueRuleGroup>
<#if hasValueRuleGroup>
<#assign ruleMsg="">
@ValueRuleCheck.List({
<#list de.getAllPSDEFValueRules() as deRule>
<#if deRule.codeName!='Default'>
<#if deRule.getPSDEFVRGroupCondition()??>
<#assign ruleName=(de.codeName+"_"+deRule.getPSDEField().codeName+"_"+deRule.codeName)?lower_case>
<#assign ruleField=(deRule.getPSDEField().codeName)?lower_case>
<#assign group=deRule.getPSDEFVRGroupCondition()>
@ValueRuleCheck(field = "${ruleField}", rule = "${ruleName}"),
</#if>
</#if>
</#list>
})
</#if>
</#macro>
\ No newline at end of file
{{#unless apiEntity.subSysDE}}
<#assign pubPkgCodeName = pub.getPKGCodeName()>
<#assign itemSysApiCodeNameLC = item.getPSSysServiceAPI().getCodeName()?lower_case>
<#assign itemSysApiCodeName = item.getPSSysServiceAPI().getCodeName()>
<#assign mappingName=itemSysApiCodeName+item.codeName+"Mapping">
package {{packageName}}.{{apis}}.mapping;
{{#with api.entity as | entity | }}
import org.mapstruct.*;
import {{packageName}}.core.{{entity.model}}.domain.{{entity.codeName}};
import {{packageName}}.{{apis}}.dto.{{apiEntity.codeName}}DTO;
import cn.ibizlab.util.domain.MappingBase;
@Mapper(componentModel = "spring", uses = {}, implementationName = "{{api.codeName}}{{apiEntity.codeName}}Mapping",
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public interface {{apiEntity.codeName}}Mapping extends MappingBase<{{apiEntity.codeName}}DTO, {{entity.codeName}}> {
}
{{/with}}
{{/unless}}
\ No newline at end of file
package {{packageName}}.{{apis}};
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import cn.ibizlab.util.web.SearchContextHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@Slf4j
@EnableDiscoveryClient
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"{{packageName}}"}
// ,excludeFilters={
// @ComponentScan.Filter(type= org.springframework.context.annotation.FilterType.REGEX,pattern="{{packageName}}.${item.codeName?lower_case}.rest.xxx"),
// }
)
@EnableMongoRepositories(basePackages = {"{{packageName}}"})
@MapperScan("{{packageName}}.*.mapper")
@SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
{{#unless system.enableMongo}}
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
{{/unless}}
{{#if system.enableDS}}
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure.class
{{/if}}
})
@Import({
org.springframework.cloud.openfeign.FeignClientsConfiguration.class
})
@EnableFeignClients(basePackages = {"{{packageName}}" })
@EnableAsync
@EnableScheduling
public class {{system.codeName}}{{api.codeName}}Application extends WebMvcConfigurerAdapter{
@Autowired
SearchContextHandlerMethodArgumentResolver resolver;
public static void main(String[] args) {
SpringApplication.run({{system.codeName}}{{api.codeName}}Application.class, args);
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(resolver);
}
}
package {{packageName}}.{{apis}};
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
* 提供外部容器启动服务能力
*/
@Slf4j
public class {{system.codeName}}{{api.codeName}}Initializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
log.info("--正在使用外部容器启动服务--");
return builder.sources({{system.codeName}}{{api.codeName}}Application.class);
}
}
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册