提交 9b80a1ca 编写于 作者: sq3536's avatar sq3536

ibizlab模板

上级 030c3bf4
......@@ -49,6 +49,8 @@ public class ActionModel extends BaseModel{
param=this.getEntity().getKeyField().getType().java;
else if("KEYFIELDS".equalsIgnoreCase(getDEAction().getPSDEActionInput().getType()))
param="List<"+this.getEntity().getKeyField().getType().java+">";
else if("DTOS".equalsIgnoreCase(getDEAction().getPSDEActionInput().getType()))
param="List<"+param+">";
return param;
}
......
......@@ -9,6 +9,7 @@ import net.ibizsys.model.dataentity.service.IPSDEServiceAPI;
import net.ibizsys.model.dataentity.service.IPSDEServiceAPIMethod;
import net.ibizsys.model.dataentity.service.IPSDEServiceAPIRS;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.util.*;
......@@ -20,6 +21,15 @@ public class ApiEntityModel extends BaseModel {
private List<ApiDtoModel> dtos = new ArrayList<>();
private String apiName;
public String getApiName()
{
if(apiName==null)
this.apiName= ObjectUtils.isEmpty(getApiDataEntity().getLogicName())?getEntity().getLogicName():getApiDataEntity().getLogicName();
return apiName;
}
public ApiEntityModel(ApiModel apiModel, IPSDEServiceAPI apiDataEntity) {
this.opt = apiDataEntity;
this.api = apiModel;
......@@ -32,6 +42,7 @@ public class ApiEntityModel extends BaseModel {
}
}
}
public IPSDEServiceAPI getApiDataEntity() {
......@@ -40,8 +51,11 @@ public class ApiEntityModel extends BaseModel {
private ApiModel api;
private EntityModel entity;
public EntityModel getEntity() {
return api.getSystem().getEntity(getApiDataEntity().getPSDataEntity().getCodeName());
if(entity==null)
entity = api.getSystem().getEntity(getApiDataEntity().getPSDataEntity().getCodeName());
return entity;
}
private List<FieldModel> properties;
......
......@@ -11,10 +11,9 @@ import net.ibizsys.model.dataentity.IPSDataEntity;
import net.ibizsys.model.dataentity.service.*;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;
@Getter
@Setter
......@@ -22,7 +21,18 @@ import java.util.List;
@Accessors(chain = true)
public class ApiMethodModel extends BaseModel {
private String[] ignoreMethodNames = new String[]{"GET", "CREATE", "UPDATE", "REMOVE"};
private static String[] ignoreMethodNames = new String[]{"GET", "CREATE", "UPDATE", "REMOVE"};
private static String[] booleanMethodNames = new String[]{"CREATE", "UPDATE", "REMOVE", "SAVE", "CREATEBATCH", "UPDATEBATCH", "REMOVEBATCH", "SAVEBATCH"};
private static Map<String,String> lang=new HashMap<String,String>(){{
put("GET","获取");
put("CREATE","创建");
put("UPDATE","更新");
put("SAVE","保存");
put("REMOVE","删除");
put("GETDRAFT","草稿");
put("CHECKKEY","校验");
}};
private ApiModel api;
......@@ -30,6 +40,22 @@ public class ApiMethodModel extends BaseModel {
private List<ApiEntityRSModel> parentApiEntities;
public String getTags() {
return apiEntity.getApiName();
}
private String notes;
private String apiName;
public String getApiName()
{
if(lang.containsKey(apiName.toUpperCase()))
return lang.get(apiName.toUpperCase())+apiName;
else if(apiName.toUpperCase().startsWith("FETCH"))
return "查询"+apiName;
return apiName;
}
public ApiMethodModel(ApiEntityModel apiEntityModel, List<ApiEntityRSModel> parentApiEntities, IPSDEServiceAPIMethod iPSDEServiceAPIMethod) {
this.opt = iPSDEServiceAPIMethod;
this.apiEntity = apiEntityModel;
......@@ -37,6 +63,8 @@ public class ApiMethodModel extends BaseModel {
this.parentApiEntities = parentApiEntities;
this.setCodeName(iPSDEServiceAPIMethod.getCodeName());
this.setName(iPSDEServiceAPIMethod.getName());
this.apiName=ObjectUtils.isEmpty(iPSDEServiceAPIMethod.getLogicName())?iPSDEServiceAPIMethod.getName():iPSDEServiceAPIMethod.getLogicName();
this.notes=apiEntityModel.getCodeName()+"-"+name;
}
public IPSDEServiceAPIMethod getPSDEServiceAPIMethod() {
......@@ -65,7 +93,7 @@ public class ApiMethodModel extends BaseModel {
//主键
String strPlurlize = Inflector.getInstance().pluralize(StringAdvUtils.camelcase(apiEntity.getCodeName()).toLowerCase());
if (getPSDEServiceAPIMethod().isNeedResourceKey()) {
if (getPSDEServiceAPIMethod().isNeedResourceKey()&&(!"save".equalsIgnoreCase(name))) {
path = path + String.format("/%s/{%s}", strPlurlize, StringAdvUtils.camelcase(apiEntity.getEntity().getKeyField().getCodeName()));
} else {
path = path + String.format("/%s", strPlurlize);
......@@ -90,7 +118,7 @@ public class ApiMethodModel extends BaseModel {
pathVariables.add(0, pathVariable);
}
}
if (getPSDEServiceAPIMethod().isNeedResourceKey()) {
if (getPSDEServiceAPIMethod().isNeedResourceKey()&&(!"save".equalsIgnoreCase(name))) {
JSONObject pathVariable = new JSONObject();
pathVariable.put("name", apiEntity.getEntity().getKeyField().getCodeName());
pathVariable.put("type", apiEntity.getEntity().getKeyField().getType());
......@@ -100,31 +128,154 @@ public class ApiMethodModel extends BaseModel {
}
public String getBody() {
IPSDEServiceAPIMethodInput iPSDEServiceAPIMethodInput = getPSDEServiceAPIMethod().getPSDEServiceAPIMethodInput();
if (iPSDEServiceAPIMethodInput != null) {
if ("DTO".equals(iPSDEServiceAPIMethodInput.getType())) {
if ("DEFAULT".equals(iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getType()))
return iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getName();
else if ("DEFILTER".equals(iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getType()))
return iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getName().replace("FilterDTO", "SearchContext");
} else if ("DTOS".equals(iPSDEServiceAPIMethodInput.getType())) {
return iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getName();
} else if ("KEYFIELD".equals(iPSDEServiceAPIMethodInput.getType())
&& getPSDEServiceAPIMethod().getPSDEAction()!=null
&& getPSDEServiceAPIMethod().getPSDEAction().getActionType().equals("USERCUSTOM")) {
return apiEntity.getCodeName() + "DTO";
}
if(!ObjectUtils.isEmpty(getInParam()))
{
return getInParam()+" "+getInParamName();
}
return null;
}
public IPSDEServiceAPIMethodInput getInput() {
return getPSDEServiceAPIMethod().getPSDEServiceAPIMethodInput();
public IPSDEMethodDTO getInputDTO() {
return getPSDEServiceAPIMethod().getPSDEServiceAPIMethodInput().getPSDEMethodDTO();
}
public IPSDEMethodDTO getReturnDTO() {
if(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn()==null||getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getPSDEMethodDTO()==null)
return getInputDTO();
return getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getPSDEMethodDTO();
}
private String inParam;
private String inParam2;
public String getInParam()
{
if(inParam==null) {
String param=this.getApiEntity().getCodeName()+"DTO";
IPSDEServiceAPIMethodInput iPSDEServiceAPIMethodInput = getPSDEServiceAPIMethod().getPSDEServiceAPIMethodInput();
if(iPSDEServiceAPIMethodInput!=null&&iPSDEServiceAPIMethodInput.getPSDEMethodDTO()!=null)
param=iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getName().replace("FilterDTO", "SearchContext");
if("KEYFIELD".equalsIgnoreCase(iPSDEServiceAPIMethodInput.getType())){
param = "";
inParam2=getApiEntity().getEntity().getKeyField().getType().java;
inParamName = StringAdvUtils.camelcase(apiEntity.getEntity().getKeyField().getCodeName());
inParamName2=StringAdvUtils.camelcase(apiEntity.getEntity().getKeyField().getCodeName());
}
else if("KEYFIELDS".equalsIgnoreCase(iPSDEServiceAPIMethodInput.getType())) {
param = "List<" + getApiEntity().getEntity().getKeyField().getType().java + ">";
inParam2 = param;
inParamName = "list";
inParamName2="list";
}
else if("DTO".equalsIgnoreCase(iPSDEServiceAPIMethodInput.getType())) {
inParam2 = apiEntity.getEntity().getCodeName();
inParamName = "dto";
inParamName2="domain";
}
else if("DTOS".equalsIgnoreCase(iPSDEServiceAPIMethodInput.getType())) {
param = "List<" + param + ">";
inParam2 = "List<" + apiEntity.getEntity().getCodeName() + ">";
inParamName = "dtos";
inParamName2="domains";
}
inParam=param;
}
return inParam;
}
public boolean isNeedDto2Domain()
{
if("FETCH".equalsIgnoreCase(getPSDEServiceAPIMethod().getMethodType()))
return false;
IPSDEServiceAPIMethodInput iPSDEServiceAPIMethodInput = getPSDEServiceAPIMethod().getPSDEServiceAPIMethodInput();
if(iPSDEServiceAPIMethodInput==null)
return false;
return "DTOS".equalsIgnoreCase(iPSDEServiceAPIMethodInput.getType())||"DTO".equalsIgnoreCase(iPSDEServiceAPIMethodInput.getType());
}
public boolean isListIn()
{
IPSDEServiceAPIMethodInput iPSDEServiceAPIMethodInput = getPSDEServiceAPIMethod().getPSDEServiceAPIMethodInput();
if(iPSDEServiceAPIMethodInput==null)
return false;
return "KEYFIELDS".equalsIgnoreCase(iPSDEServiceAPIMethodInput.getType())||"DTOS".equalsIgnoreCase(iPSDEServiceAPIMethodInput.getType());
}
private String inParamName;
private String inParamName2;
public boolean isListReturn()
{
if(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn()==null)
return false;
if ("DTOS".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType())
||"OBJECTS".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType())
||"SIMPLES".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType()))
return true;
return false;
}
public String typeReturn()
{
if(isListReturn()) {
if ("SIMPLES".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType()))
return PropType.findType(this.getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getStdDataType()).java;
else if ("DTOS".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType())
||"OBJECTS".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType()))
return this.getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getName();
}
return "";
}
public IPSDEServiceAPIMethodReturn getReturn() {
return getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn();
public boolean isBooleanReturn() {
return ArrayUtils.contains(booleanMethodNames,this.getName().toUpperCase());
}
private boolean needDomain2Dto=true;
private String outParam;
private String outParam2;
public String getOutParam()
{
if(outParam==null)
{
String param=this.getApiEntity().getCodeName()+"DTO";
if(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn()!=null&&getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getPSDEMethodDTO()!=null)
param=getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getPSDEMethodDTO().getName();
if ("VOID".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType())) {
needDomain2Dto=isNeedDto2Domain();
param = getInParam();
outParam2 = getInParam2();
}
else if ("SIMPLE".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType())) {
needDomain2Dto=false;
param = PropType.findType(this.getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getStdDataType()).java;
outParam2=param;
}
else if ("SIMPLES".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType())) {
needDomain2Dto=false;
param = "List<" + PropType.findType(this.getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getStdDataType()).java + ">";
outParam2=param;
}
else if ("DTO".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType()))
{
outParam2=apiEntity.getEntity().getCodeName();
}
else if ("DTOS".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType())
||"OBJECTS".equalsIgnoreCase(getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn().getType())) {
param = "List<" + param + ">";
outParam2="List<" + apiEntity.getEntity().getCodeName()+">";
}
if("FETCH".equalsIgnoreCase(getPSDEServiceAPIMethod().getMethodType()))
outParam="List<" + param + ">";
else
outParam=param;
}
return outParam;
}
}
......@@ -142,6 +142,8 @@ public class AppEntityModel extends BaseModel{
public EntityModel getEntity()
{
if(getAppDataEntity().getPSDataEntity()==null)
return null;
return app.getSystem().getEntity(getAppDataEntity().getPSDataEntity().getCodeName());
}
......
*volumes
*target
.settings
*node_modules
*bin
*.project
*.classpath
*.factorypath
.history
.vscode
.idea
**.iml
*.jar
*.log
.DS_Store
**.ibizlab-generator-ignore
**.DS_Store
**@macro/**
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>{{projectName}}</artifactId>
<groupId>{{packageName}}</groupId>
<version>1.0.0.0</version>
<name>{{projectDesc}}</name>
<description></description>
<packaging>pom</packaging>
<parent>
<groupId>cn.ibizlab</groupId>
<artifactId>ibizlab-boot-starter-parent</artifactId>
<version>2.4.0-SNAPSHOT</version>
</parent>
<modules>
<!-- cores -->
<module>{{projectName}}-core</module>
<!-- boot -->
<module>{{projectName}}-boot</module>
</modules>
<dependencies>
{{#eq system.pub.contentType "CODE"}}
{{#each system.pub.psSysSFPubPkgs as |package|}}
{{#if package.pkgParam}}
{{package.pkgParam}}
{{/if}}
{{/each}}
{{/eq}}
</dependencies>
<repositories>
<repository>
<id>ibizmvnrepository</id>
<name>ibizmvnrepository</name>
<url>http://172.16.240.220:8081/repository/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
<repository>
<id>aliyunmaven</id>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>ibizmvnrepository-plugin</id>
<url>http://172.16.240.220:8081/repository/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>aliyun-plugin</id>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<configuration>
<generateBackupPoms>false</generateBackupPoms>
</configuration>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>{{projectName}}</artifactId>
<groupId>{{packageName}}</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>{{projectName}}-boot</artifactId>
<name>{{projectDesc}} Dev Monolithic Boot</name>
<description>{{projectDesc}} Boot</description>
<dependencies>
<dependency>
<groupId>{{packageName}}</groupId>
<artifactId>{{projectName}}-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<!--由于boot是通过dependency来关联所有子项目,页面和配置等信息都存在与子项目中,
所以您在对boot进行打包前,需要先将子项目install到maven仓库,以确保boot可以正常引用所有完整的子项目-->
<profiles>
<profile>
<id>boot</id>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>{{projectName}}</finalName>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
<mainClass>{{packageName}}.DevBootApplication</mainClass>
<outputDirectory>../</outputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
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}}","cn.ibizlab.util"})
@SpringBootApplication(exclude = {
{{#unless system.enableMongo}}
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
{{/unless}}
{{#unless system.enableDS}}
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure.class
{{/unless}}
})
@ComponentScan(basePackages = {"{{packageName}}","cn.ibizlab.util"}
// ,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.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
{{#if system.enableGlobalTransaction}}
@Import({com.alibaba.cloud.seata.feign.SeataFeignClientAutoConfiguration.class})
{{/if}}
public class DevBootAutoConfiguration {
@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;
}
}
\ No newline at end of file
{{#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 | webapp |}}
{{#each webapp.appEntities as |appEntity|}}
{{#if appEntity.entity}}
{{#eq appEntity.entity.storage "ServiceAPI"}}
{{#appEntity.serviceId}}
{{lowerCase webapp.codeName}}-{{lowerCase appEntity.codeName}}:
path: /{{pluralize appEntity.codeName}}/**
serviceId: {{refServiceId}}
stripPrefix: false
{{/appEntity.serviceId}}
{{/eq}}
{{/if}}
{{/each}}
{{/each}}
sensitive-headers:
- Cookie,Set-Cookie,Authorization
\ No newline at end of file
spring:
profiles:
include: sys , nacos ,{{#each system.apps}} {{lowerCase codeName}}-dev ,{{/each}}{{#each system.apis}} {{lowerCase codeName}}-dev ,{{/each}} dev
application:
name: {{lowerCase system.codeName}}
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}.%i.log</FileNamePattern>
<!--日志文件最大的大小-->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="Console" />
<appender-ref ref="file" />
<!--<appender-ref ref="LOGSTASH" />-->
</root>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>{{projectName}}</artifactId>
<groupId>{{packageName}}</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>{{projectName}}-core</artifactId>
<name>{{projectDesc}} Core</name>
<description>{{projectDesc}} Core</description>
<dependencies>
<dependency>
<groupId>cn.ibizlab</groupId>
<artifactId>ibizlab-boot-starter-data</artifactId>
<version>2.4.0-SNAPSHOT</version>
</dependency>
{{#system.enableES}}
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
{{/system.enableES}}
{{#system.enableMQ}}
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>${rocketmq.version}</version>
</dependency>
{{/system.enableMQ}}
{{#system.enableOAuth2}}
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
<version>2.3.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
<version>1.0.10.RELEASE</version>
</dependency>
{{/system.enableOAuth2}}
{{#system.enableOracle}}
<!-- Oracle驱动包 -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
</dependency>
<dependency>
<groupId>com.oracle.database.nls</groupId>
<artifactId>orai18n</artifactId>
</dependency>
{{/system.enableOracle}}
{{#system.enablePostgreSQL}}
<!-- PostgreSQL驱动包 -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
{{/system.enablePostgreSQL}}
{{#system.enableMysql}}
<!-- MySQL驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
{{/system.enableMysql}}
{{#system.enableGlobalTransaction}}
<!-- 阿里seata分布式事务 -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
<exclusions>
<exclusion>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
</exclusion>
</exclusions>
</dependency>
{{/system.enableGlobalTransaction}}
</dependencies>
<properties>
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
</properties>
<profiles>
<profile>
<id>diff</id>
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>${liquibase.version}</version>
<executions>
<execution>
<id>prepare-newdb</id>
<configuration>
<changeLogFile>${project.basedir}/src/main/resources/liquibase/h2_table.xml</changeLogFile>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:file:${project.build.directory}/db/new;MODE=mysql</url>
<username>root</username>
<dropFirst>true</dropFirst>
</configuration>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
<execution>
<id>prepare-olddb</id>
<configuration>
<changeLogFile>${project.basedir}/src/main/resources/liquibase/master_table.xml</changeLogFile>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:file:${project.build.directory}/db/last;MODE=mysql</url>
<username>root</username>
<dropFirst>true</dropFirst>
</configuration>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
<execution>
<id>make-diff</id>
<configuration>
<changeLogFile>${project.basedir}/src/main/resources/liquibase/empty.xml</changeLogFile>
<diffChangeLogFile>${project.basedir}/src/main/resources/liquibase/changelog/${maven.build.timestamp}_changelog.xml</diffChangeLogFile>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:file:${project.build.directory}/db/last;MODE=mysql</url>
<username>root</username>
<password></password>
<referenceUrl>jdbc:h2:file:${project.build.directory}/db/new;MODE=mysql</referenceUrl>
<referenceDriver>org.h2.Driver</referenceDriver>
<referenceUsername>root</referenceUsername>
<verbose>true</verbose>
<logging>debug</logging>
<contexts>!test</contexts>
<diffExcludeObjects>Index:.*,table:ibzfile,ibzuser,ibzdataaudit,ibzcfg,IBZFILE,IBZUSER,IBZDATAAUDIT,IBZCFG</diffExcludeObjects>
</configuration>
<phase>process-resources</phase>
<goals>
<goal>diff</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
{{#if entity.needTypeHandler}}
package {{packageName}}.core.{{entity.module}}.domain.handlers;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@MappedTypes({List.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class {{entity.codeName}}TypeHandler extends AbstractJsonTypeHandler<List>
{
private static ObjectMapper objectMapper = new ObjectMapper();
private JavaType type;
public {{entity.codeName}}TypeHandler(Class<List> type) {
this.type = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, {{entity.codeName}}.class);
}
@Override
protected List parse(String json) {
try {
return objectMapper.readValue(json, type);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
protected String toJson(List obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static void setObjectMapper(ObjectMapper objectMapper) {
{{entity.codeName}}TypeHandler.objectMapper = objectMapper;
}
}
{{/if}}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.domain;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.math.BigInteger;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.annotation.JSONField;
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 org.springframework.util.ObjectUtils;
import org.springframework.util.DigestUtils;
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.EntityBase;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Transient;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
{{#entity.relEntities}}
import {{packageName}}.core.{{module}}.domain.{{codeName}};
{{/entity.relEntities}}
@Getter
@Setter
@NoArgsConstructor
@JsonIgnoreProperties(value = "handler")
@ApiModel("{{entity.logicName}}")
public class {{entity.codeName}} extends EntityBase implements Serializable
{
{{#each entity.fields}}
{{#unless deepStructure}}
/**
* {{logicName}}
*/
{{#enableAudit}}
@Audit
{{/enableAudit}}
@DEField({{annotation}})
@JsonProperty("{{jsonName}}")
{{#timeType}}
@JsonFormat(pattern = "{{format}}", locale = "zh", timezone = "GMT+8")
{{/timeType}}
@JSONField(name = "{{jsonName}}"{{#timeType}} , format = "{{format}}"{{/timeType}})
{{#eq type.java "Long"}}
@JsonSerialize(using = ToStringSerializer.class)
{{/eq}}
@ApiModelProperty("{{logicName}}")
private {{type.java}} {{camelCase codeName}};
{{/unless}}
{{/each}}
{{#each entity.references}}
/**
* {{entityLogicName}}
*/
@JSONField(name = "{{lowerCase codeName}}")
@JsonProperty("{{lowerCase codeName}}")
private {{entityCodeName}} {{camelCase codeName}};
{{/each}}
{{#each entity.nesteds}}
/**
* {{entityLogicName}}
*/
{{#if listCode}}
@JSONField(name = "{{listCode}}")
@JsonProperty("{{listCode}}")
{{else}}
@JsonIgnore
@JSONField(serialize = false)
{{/if}}
private List<{{entityCodeName}}> {{camelCase codeName}};
{{/each}}
{{#each entity.fields}}
{{#unless deepStructure}}
{{#timeType}}
/**
* 格式化日期 [{{logicName}}]
*/
public String format{{pascalCase codeName}}() {
if (this.{{camelCase codeName}} == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat("{{format}}");
return sdf.format({{camelCase codeName}});
}
{{/timeType}}
{{/unless}}
{{/each}}
}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.domain;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.math.BigInteger;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.annotation.JSONField;
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 org.springframework.util.ObjectUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.Assert;
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 lombok.experimental.Accessors;
import org.springframework.data.annotation.Transient;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
{{#entity.relEntities}}
import {{packageName}}.core.{{module}}.domain.{{codeName}};
{{/entity.relEntities}}
@Getter
@Setter
@NoArgsConstructor
@JsonIgnoreProperties(value = "handler")
@TableName(value = "{{entity.tableName}}", resultMap = "{{entity.codeName}}ResultMap")
@ApiModel("{{entity.logicName}}")
public class {{entity.codeName}} extends EntityMP implements Serializable
{
{{#each entity.fields}}
{{#unless deepStructure}}
/**
* {{logicName}}
*/
{{#if keyDEField}}
{{#if phisicalDEField}}
@TableId(value = "{{columnName}}"{{#type.number}} , type = IdType.ASSIGN_ID{{/type.number}}{{#type.string}} , type = IdType.ASSIGN_UUID{{/type.string}})
{{else}}
@TableField(exist = false)
{{/if}}
{{else}}
@TableField(value = "{{columnName}}"{{#insertOnly}} , fill = FieldFill.INSERT{{/insertOnly}}{{^phisicalDEField}} , exist = false{{/phisicalDEField}})
{{#logicValidField}}
@TableLogic{{#validLogicValue}}(value = "{{validLogicValue}}"{{#invalidLogicValue}} , delval = "{{invalidLogicValue}}"{{/invalidLogicValue}}){{/validLogicValue}}
{{/logicValidField}}
{{/if}}
{{#enableAudit}}
@Audit
{{/enableAudit}}
@DEField({{annotation}})
@JsonProperty("{{jsonName}}")
{{#timeType}}
@JsonFormat(pattern = "{{format}}", locale = "zh", timezone = "GMT+8")
{{/timeType}}
@JSONField(name = "{{jsonName}}"{{#timeType}} , format = "{{format}}"{{/timeType}})
{{#eq type.java "Long"}}
@JsonSerialize(using = ToStringSerializer.class)
{{/eq}}
@ApiModelProperty("{{logicName}}")
private {{type.java}} {{camelCase codeName}};
{{/unless}}
{{/each}}
{{#each entity.references}}
/**
* {{entityLogicName}}
*/
@JsonIgnore
@JSONField(serialize = false)
@TableField(exist = false)
private {{entityCodeName}} {{camelCase codeName}};
{{/each}}
{{#each entity.nesteds}}
/**
* {{entityLogicName}}
*/
{{#if listCode}}
@JSONField(name = "{{listCode}}")
@JsonProperty("{{listCode}}")
{{else}}
@JsonIgnore
@JSONField(serialize = false)
{{/if}}
{{#if columnName}}
@TableField(value = "{{columnName}}" , typeHandler = {{packageName}}.core.{{module}}.domain.handlers.{{entityCodeName}}TypeHandler.class)
{{else}}
@TableField(exist = false)
{{/if}}
protected List<{{entityCodeName}}> {{camelCase codeName}};
{{/each}}
{{#each entity.fields}}
{{#unless deepStructure}}
{{#unless keyDEField}}
{{#unless predefinedType}}
/**
* 设置 [{{logicName}}]
*/
public {{entity.codeName}} set{{pascalCase codeName}}({{type.java}} {{camelCase codeName}}) {
this.{{camelCase codeName}} = {{camelCase codeName}};
this.modify("{{lowerCase name}}", {{camelCase codeName}});
return this;
}
{{/unless}}
{{/unless}}
{{/unless}}
{{/each}}
{{#entity.nesteds}}
{{#columnName}}
/**
* 设置 [{{entityLogicName}}]
*/
public {{entity.codeName}} set{{pascalCase codeName}}(List<{{entityCodeName}}> {{camelCase codeName}}) {
this.{{camelCase codeName}} = {{camelCase codeName}};
this.modify("{{columnName}}", ({{camelCase codeName}}!=null)?{{camelCase codeName}}:(new ArrayList()));
return this;
}
{{/columnName}}
{{/entity.nesteds}}
{{#if entity.keyField.type.number}}
@Override
public Serializable getDefaultKey(boolean gen) {
return IdWorker.getId();
}
{{else}}
{{#entity.unionKeyMode}}
{{#unless entity.keyField.phisicalDEField}}
/**
* 设置 [{{logicName}}]
*/
public {{entity.codeName}} set{{pascalCase entity.keyField.codeName}}({{entity.keyField.type.java}} {{camelCase entity.keyField.codeName}}) {
this.{{camelCase entity.keyField.codeName}} = {{camelCase entity.keyField.codeName}};
if(!ObjectUtils.isEmpty({{camelCase entity.keyField.codeName}})) {
String [] args={{camelCase entity.keyField.codeName}}.split("\\|\\|");
{{#each entity.unionKeyFields}}
this.set("{{camelCase codeName}}", args[{{@index}}]);
{{/each}}
}
return this;
}
public {{entity.keyField.type.java}} get{{pascalCase entity.keyField.codeName}}() {
if(ObjectUtils.isEmpty(this.{{camelCase entity.keyField.codeName}}))
this.{{camelCase entity.keyField.codeName}} = ({{entity.keyField.type.java}})getDefaultKey(true);
return this.{{camelCase entity.keyField.codeName}};
}
{{/unless}}
@Override
public Serializable getDefaultKey(boolean gen) {
{{#each entity.unionKeyFields}}
Assert.notNull(get{{pascalCase codeName}}(),"未设置{{logicName}}");
{{/each}}
String key = String.format("{{#each entity.unionKeyFields}}{{#unless @first}}||{{/unless}}%s{{/each}}"
{{#each entity.unionKeyFields}},{{#if timeType}}DataObject.datetimeFormat.format(get{{pascalCase codeName}}()){{else}}get{{pascalCase codeName}}(){{/if}}{{/each}});
{{#if entity.keyField.phisicalDEField}}
key = DigestUtils.md5DigestAsHex(key.getBytes());
{{/if}}
return key;
}
{{/entity.unionKeyMode}}
{{/if}}
{{#if entity.hasResetField}}
/**
* 复制当前对象数据到目标对象(粘贴重置)
* @param targetEntity 目标数据对象
* @param bIncEmpty 是否包括空值
* @param <T>
* @return
*/
@Override
public <T> T copyTo(T targetEntity, boolean bIncEmpty) {
{{#each entity.fields}}
{{#if pasteReset}}
this.reset("{{lowerCase name}}");
{{/if}}
{{/each}}
return super.copyTo(targetEntity, bIncEmpty);
}
{{/if}}
}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.domain;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.math.BigInteger;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.annotation.JSONField;
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 org.springframework.util.ObjectUtils;
import org.springframework.util.DigestUtils;
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.EntityClient;
import java.io.Serializable;
import lombok.*;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Transient;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
{{#entity.relEntities}}
import {{packageName}}.core.{{module}}.domain.{{codeName}};
{{/entity.relEntities}}
@Getter
@Setter
@NoArgsConstructor
@JsonIgnoreProperties(value = "handler")
@ApiModel("{{entity.logicName}}")
public class {{entity.codeName}} extends EntityClient implements Serializable
{
{{#each entity.fields}}
{{#unless deepStructure}}
/**
* {{logicName}}
*/
{{#enableAudit}}
@Audit
{{/enableAudit}}
@DEField({{annotation}})
@JsonProperty("{{jsonName}}")
{{#timeType}}
@JsonFormat(pattern = "{{format}}", locale = "zh", timezone = "GMT+8")
{{/timeType}}
@JSONField(name = "{{jsonName}}"{{#timeType}} , format = "{{format}}"{{/timeType}})
{{#eq type.java "Long"}}
@JsonSerialize(using = ToStringSerializer.class)
{{/eq}}
@ApiModelProperty("{{logicName}}")
private {{type.java}} {{camelCase codeName}};
{{/unless}}
{{/each}}
{{#each entity.references}}
/**
* {{entityLogicName}}
*/
@JSONField(name = "{{lowerCase codeName}}")
@JsonProperty("{{lowerCase codeName}}")
private {{entityCodeName}} {{camelCase codeName}};
{{/each}}
{{#each entity.nesteds}}
/**
* {{entityLogicName}}
*/
{{#if listCode}}
@JSONField(name = "{{listCode}}")
@JsonProperty("{{listCode}}")
{{else}}
@JsonIgnore
@JSONField(serialize = false)
{{/if}}
private List<{{entityCodeName}}> {{camelCase codeName}};
{{/each}}
{{#each entity.fields}}
{{#unless deepStructure}}
{{#unless keyDEField}}
{{#unless predefinedType}}
/**
* 设置 [{{logicName}}]
*/
public {{entity.codeName}} set{{pascalCase codeName}}({{type.java}} {{camelCase codeName}}) {
this.{{camelCase codeName}} = {{camelCase codeName}};
this.modify("{{lowerCase codeName}}", {{camelCase codeName}});
return this;
}
{{/unless}}
{{/unless}}
{{/unless}}
{{/each}}
{{#entity.nesteds}}
{{#if listCode}}
/**
* 设置 [{{entityLogicName}}]
*/
public {{entity.codeName}} set{{pascalCase codeName}}(List<{{entityCodeName}}> {{camelCase codeName}}) {
this.{{camelCase codeName}} = {{camelCase codeName}};
this.modify("{{listCode}}", ({{camelCase codeName}}!=null)?{{camelCase codeName}}:(new ArrayList()));
return this;
}
{{/if}}
{{/entity.nesteds}}
}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.filter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.fastjson.annotation.JSONField;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
{{#entity.enableES}}
import org.elasticsearch.index.query.QueryBuilders;
{{/entity.enableES}}
import cn.ibizlab.util.filter.QueryWrapperContext;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
/**
* 关系型数据实体[{{entity.codeName}}] 查询条件对象
*/
@Slf4j
@Getter
@Setter
@NoArgsConstructor
@ApiModel("{{entity.logicName}}")
public class {{entity.codeName}}SearchContext extends QueryWrapperContext<{{entity.codeName}}> {
{{#each entity.fields as |field|}}
{{#each field.allPSDEFSearchModes as |formitem|}}
{{#unless formitem.valueFunc}}
{{#if (or (eq formitem.valueOP "IN") (eq formitem.valueOP "ISNULL") (eq formitem.valueOP "ISNOTNULL"))}}
@JsonProperty("{{lowerCase formitem.name}}")
@JSONField(name = "{{lowerCase formitem.name}}")
{{else}}
@JsonProperty("{{lowerCase formitem.name}}")
{{#timeType}}
@JsonFormat(pattern = "{{format}}", locale = "zh", timezone = "GMT+8")
{{/timeType}}
@JSONField(name = "{{lowerCase formitem.name}}"{{#timeType}} , format = "{{format}}"{{/timeType}})
{{#eq type.java "Long"}}
@JsonSerialize(using = ToStringSerializer.class)
{{/eq}}
{{/if}}
@ApiModelProperty("{{field.logicName}}{{formitem.valueOP}}")
private {{#if (or (eq formitem.valueOP "IN") (eq formitem.valueOP "ISNULL") (eq formitem.valueOP "ISNOTNULL"))}}String{{else}}{{field.type.java}}{{/if}} {{camelCase field.codeName}}{{formitem.valueOP}};
public {{entity.codeName}}SearchContext set{{pascalCase field.codeName}}{{formitem.valueOP}}({{#if (or (eq formitem.valueOP "IN") (eq formitem.valueOP "ISNULL") (eq formitem.valueOP "ISNOTNULL"))}}String{{else}}{{field.type.java}}{{/if}} {{camelCase field.codeName}}{{formitem.valueOP}}) {
this.{{camelCase field.codeName}}{{formitem.valueOP}} = {{camelCase field.codeName}}{{formitem.valueOP}};
if(!ObjectUtils.isEmpty(this.{{camelCase field.codeName}}{{formitem.valueOP}})){
{{#eq formitem.valueOP "LIKE"}}
this.getSearchCond().like("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "LEFTLIKE"}}
this.getSearchCond().likeRight("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "RIGHTLIKE"}}
this.getSearchCond().likeLeft("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "EQ"}}
this.getSearchCond().eq("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "NOTEQ"}}
this.getSearchCond().ne("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "GT"}}
this.getSearchCond().gt("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "GTANDEQ"}}
this.getSearchCond().ge("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "LT"}}
this.getSearchCond().lt("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "LTANDEQ"}}
this.getSearchCond().le("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "ISNOTNULL"}}
if(this.{{camelCase field.codeName}}{{formitem.valueOP}}.equals("1")){
this.getSearchCond().isNotNull("{{lowerCase field.name}}");
}
{{/eq}}
{{#eq formitem.valueOP "ISNULL"}}
if(this.{{camelCase field.codeName}}{{formitem.valueOP}}.equals("1")){
this.getSearchCond().isNull("{{lowerCase field.name}}");
}
{{/eq}}
{{#eq formitem.valueOP "IN"}}
this.getSearchCond().in("{{lowerCase field.name}}",this.{{camelCase field.codeName}}{{formitem.valueOP}}.split(";|,|;|,"));
{{/eq}}
{{#eq formitem.valueOP "NOTIN"}}
this.getSearchCond().notIn("{{lowerCase field.name}}",this.{{camelCase field.codeName}}{{formitem.valueOP}}.split(";|,|;|,"));
{{/eq}}
{{#if entity.enableES}}
{{#eq formitem.valueOP "LIKE"}}
this.getEsCond().must(QueryBuilders.wildcardQuery("{{lowerCase field.name}}", String.format("*%s*",{{camelCase field.codeName}}{{formitem.valueOP}})));
{{/eq}}
{{#eq formitem.valueOP "LEFTLIKE"}}
this.getEsCond().must(QueryBuilders.wildcardQuery("{{lowerCase field.name}}", String.format("%s*",{{camelCase field.codeName}}{{formitem.valueOP}})));
{{/eq}}
{{#eq formitem.valueOP "RIGHTLIKE"}}
this.getEsCond().must(QueryBuilders.wildcardQuery("{{lowerCase field.name}}", String.format("*%s",{{camelCase field.codeName}}{{formitem.valueOP}})));
{{/eq}}
{{#eq formitem.valueOP "EQ"}}
this.getEsCond().must(QueryBuilders.termQuery("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "NOTEQ"}}
this.getEsCond().mustNot(QueryBuilders.termQuery("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "GT"}}
this.getEsCond().must(QueryBuilders.rangeQuery("{{lowerCase field.name}}").gt({{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "GTANDEQ"}}
this.getEsCond().must(QueryBuilders.rangeQuery("{{lowerCase field.name}}").gte({{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "LT"}}
this.getEsCond().must(QueryBuilders.rangeQuery("{{lowerCase field.name}}").lt({{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "LTANDEQ"}}
this.getEsCond().must(QueryBuilders.rangeQuery("{{lowerCase field.name}}").lte({{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "ISNOTNULL"}}
if(this.{{camelCase field.codeName}}{{formitem.valueOP}}.equals("1")){
this.getEsCond().mustNot(QueryBuilders.existsQuery("{{lowerCase field.name}}"));
}
{{/eq}}
{{#eq formitem.valueOP "ISNULL"}}
if(this.{{camelCase field.codeName}}{{formitem.valueOP}}.equals("1")){
this.getEsCond().must(QueryBuilders.existsQuery("{{lowerCase field.name}}"));
}
{{/eq}}
{{/if}}
}
return this;
}
{{/unless}}
{{/each}}
{{/each}}
/**
* 启用快速搜索
*/
public void setQuery(String query)
{
this.query=query;
if(!StringUtils.isEmpty(query)){
{{#each entity.quickSearchFields as |field|}}
{{#if @first}}
this.getSearchCond().and( wrapper ->
wrapper.like("{{lowerCase field.name}}", query)
{{else}}
.or().like("{{lowerCase field.name}}", query)
{{/if}}
{{#if @last}}
);
{{/if}}
{{/each}}
}
}
}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.filter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.fastjson.annotation.JSONField;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
{{#entity.enableES}}
import org.elasticsearch.index.query.QueryBuilders;
{{/entity.enableES}}
import cn.ibizlab.util.filter.QueryWrapperContext;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
/**
* 关系型数据实体[{{entity.codeName}}] 查询条件对象
*/
@Slf4j
@Getter
@Setter
@NoArgsConstructor
@ApiModel("{{entity.logicName}}")
public class {{entity.codeName}}SearchContext extends QueryWrapperContext<{{entity.codeName}}> {
{{#each entity.fields as |field|}}
{{#each field.allPSDEFSearchModes as |formitem|}}
{{#if (or (eq formitem.valueOP "IN") (eq formitem.valueOP "ISNULL") (eq formitem.valueOP "ISNOTNULL"))}}
@JsonProperty("{{lowerCase formitem.name}}")
@JSONField(name = "{{lowerCase formitem.name}}")
{{else}}
@JsonProperty("{{lowerCase formitem.name}}")
{{#timeType}}
@JsonFormat(pattern = "{{format}}", locale = "zh", timezone = "GMT+8")
{{/timeType}}
@JSONField(name = "{{lowerCase formitem.name}}"{{#timeType}} , format = "{{format}}"{{/timeType}})
{{#eq type.java "Long"}}
@JsonSerialize(using = ToStringSerializer.class)
{{/eq}}
{{/if}}
@ApiModelProperty("{{field.logicName}}{{formitem.valueOP}}")
private {{#if (or (eq formitem.valueOP "IN") (eq formitem.valueOP "ISNULL") (eq formitem.valueOP "ISNOTNULL"))}}String{{else}}{{field.type.java}}{{/if}} {{camelCase field.codeName}}{{formitem.valueOP}};
public {{entity.codeName}}SearchContext set{{pascalCase field.codeName}}{{formitem.valueOP}}({{#if (or (eq formitem.valueOP "IN") (eq formitem.valueOP "ISNULL") (eq formitem.valueOP "ISNOTNULL"))}}String{{else}}{{field.type.java}}{{/if}} {{camelCase field.codeName}}{{formitem.valueOP}}) {
this.{{camelCase field.codeName}}{{formitem.valueOP}} = {{camelCase field.codeName}}{{formitem.valueOP}};
if(!ObjectUtils.isEmpty(this.{{camelCase field.codeName}}{{formitem.valueOP}})){
{{#eq formitem.valueOP "LIKE"}}
this.getSearchCond().like("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "LEFTLIKE"}}
this.getSearchCond().likeRight("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "RIGHTLIKE"}}
this.getSearchCond().likeLeft("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "EQ"}}
this.getSearchCond().eq("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "NOTEQ"}}
this.getSearchCond().ne("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "GT"}}
this.getSearchCond().gt("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "GTANDEQ"}}
this.getSearchCond().ge("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "LT"}}
this.getSearchCond().lt("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "LTANDEQ"}}
this.getSearchCond().le("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}});
{{/eq}}
{{#eq formitem.valueOP "ISNOTNULL"}}
if(this.{{camelCase field.codeName}}{{formitem.valueOP}}.equals("1")){
this.getSearchCond().isNotNull("{{lowerCase field.name}}");
}
{{/eq}}
{{#eq formitem.valueOP "ISNULL"}}
if(this.{{camelCase field.codeName}}{{formitem.valueOP}}.equals("1")){
this.getSearchCond().isNull("{{lowerCase field.name}}");
}
{{/eq}}
{{#eq formitem.valueOP "IN"}}
this.getSearchCond().in("{{lowerCase field.name}}",this.{{camelCase field.codeName}}{{formitem.valueOP}}.split(";|,|;|,"));
{{/eq}}
{{#eq formitem.valueOP "NOTIN"}}
this.getSearchCond().notIn("{{lowerCase field.name}}",this.{{camelCase field.codeName}}{{formitem.valueOP}}.split(";|,|;|,"));
{{/eq}}
{{#if entity.enableES}}
{{#eq formitem.valueOP "LIKE"}}
this.getEsCond().must(QueryBuilders.wildcardQuery("{{lowerCase field.name}}", String.format("*%s*",{{camelCase field.codeName}}{{formitem.valueOP}})));
{{/eq}}
{{#eq formitem.valueOP "LEFTLIKE"}}
this.getEsCond().must(QueryBuilders.wildcardQuery("{{lowerCase field.name}}", String.format("%s*",{{camelCase field.codeName}}{{formitem.valueOP}})));
{{/eq}}
{{#eq formitem.valueOP "RIGHTLIKE"}}
this.getEsCond().must(QueryBuilders.wildcardQuery("{{lowerCase field.name}}", String.format("*%s",{{camelCase field.codeName}}{{formitem.valueOP}})));
{{/eq}}
{{#eq formitem.valueOP "EQ"}}
this.getEsCond().must(QueryBuilders.termQuery("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "NOTEQ"}}
this.getEsCond().mustNot(QueryBuilders.termQuery("{{lowerCase field.name}}", {{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "GT"}}
this.getEsCond().must(QueryBuilders.rangeQuery("{{lowerCase field.name}}").gt({{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "GTANDEQ"}}
this.getEsCond().must(QueryBuilders.rangeQuery("{{lowerCase field.name}}").gte({{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "LT"}}
this.getEsCond().must(QueryBuilders.rangeQuery("{{lowerCase field.name}}").lt({{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "LTANDEQ"}}
this.getEsCond().must(QueryBuilders.rangeQuery("{{lowerCase field.name}}").lte({{camelCase field.codeName}}{{formitem.valueOP}}));
{{/eq}}
{{#eq formitem.valueOP "ISNOTNULL"}}
if(this.{{camelCase field.codeName}}{{formitem.valueOP}}.equals("1")){
this.getEsCond().mustNot(QueryBuilders.existsQuery("{{lowerCase field.name}}"));
}
{{/eq}}
{{#eq formitem.valueOP "ISNULL"}}
if(this.{{camelCase field.codeName}}{{formitem.valueOP}}.equals("1")){
this.getEsCond().must(QueryBuilders.existsQuery("{{lowerCase field.name}}"));
}
{{/eq}}
{{/if}}
}
return this;
}
{{/each}}
{{/each}}
/**
* 启用快速搜索
*/
public void setQuery(String query)
{
this.query=query;
if(!StringUtils.isEmpty(query)){
{{#each entity.quickSearchFields as |field|}}
{{#if @first}}
this.getSearchCond().and( wrapper ->
wrapper.like("{{lowerCase field.name}}", query)
{{else}}
.or().like("{{lowerCase field.name}}", query)
{{/if}}
{{#if @last}}
);
{{/if}}
{{/each}}
}
}
}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.mapper;
import java.util.List;
import org.apache.ibatis.annotations.*;
import java.util.Map;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import java.util.Map;
import org.apache.ibatis.annotations.Select;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import java.io.Serializable;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.alibaba.fastjson.JSONObject;
{{#dsName}}
@DS("{{entity.dataSource}}")
{{/dsName}}
public interface {{entity.codeName}}Mapper extends BaseMapper<{{entity.codeName}}> {
{{#entity.dataSets}}
Page<{{#if enableGroup}}Map{{else}}{{entity.codeName}}{{/if}}> search{{pascalCase codeName}}(IPage page, @Param("ctx") {{entity.codeName}}SearchContext context, @Param("ew") Wrapper<{{entity.codeName}}> wrapper);
List<{{#if enableGroup}}Map{{else}}{{entity.codeName}}{{/if}}> list{{pascalCase codeName}}(@Param("ctx") {{entity.codeName}}SearchContext context, @Param("ew") Wrapper<{{entity.codeName}}> wrapper);
{{/entity.dataSets}}
@Override
{{#enableEntityCache}}
@Cacheable(value = "{{lowerCase entity.codeName}}", key = "'row:'+#p0")
{{/enableEntityCache}}
{{entity.codeName}} selectById(Serializable id);
{{#enableEntityCache}}
@Cacheable(value = "{{lowerCase entity.codeName}}", key = "'row:'+#p0.{{camelCase entity.keyField.codeName}}")
{{/enableEntityCache}}
{{entity.codeName}} selectEntity({{entity.codeName}} entity);
List<{{entity.codeName}}> selectEntities(@Param("list") List<{{entity.codeName}}> list);
@Override
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", key = "'row:'+#p0.{{camelCase entity.keyField.codeName}}")
{{/enableEntityCache}}
int insert({{entity.codeName}} entity);
@Override
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", key = "'row:'+#p0.{{camelCase entity.keyField.codeName}}")
{{/enableEntityCache}}
int updateById(@Param(Constants.ENTITY) {{entity.codeName}} entity);
@Override
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", key = "'row:'+#p0.{{camelCase entity.keyField.codeName}}", condition ="#p0 != null")
{{/enableEntityCache}}
int update(@Param(Constants.ENTITY) {{entity.codeName}} entity, @Param("ew") Wrapper<{{entity.codeName}}> updateWrapper);
@Override
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", key = "'row:'+#p0")
{{/enableEntityCache}}
int deleteById(Serializable id);
/**
* 自定义查询SQL
* @param sql
* @return
*/
@Select("${sql}")
List<JSONObject> selectBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义更新SQL
* @param sql
* @return
*/
@Update("${sql}")
boolean updateBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义插入SQL
* @param sql
* @return
*/
@Insert("${sql}")
boolean insertBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义删除SQL
* @param sql
* @return
*/
@Delete("${sql}")
boolean deleteBySQL(@Param("sql") String sql, @Param("et")Map param);
{{#entity.references}}
List<{{entity.codeName}}> selectBy{{pascalCase fkField.codeName}}(@Param("{{camelCase fkField.codeName}}") Serializable {{camelCase fkField.codeName}});
{{/entity.references}}
}
\ No newline at end of file
{{#if entity.indexSubDE}}
package {{packageName}}.core.{{entity.module}}.mapping;
import org.mapstruct.*;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.indexRelation.module}}.domain.{{entity.indexRelation.relEntity.codeName}};
import java.util.List;
@Mapper(componentModel = "spring", uses = {})
public interface {{entity.codeName}}InheritMapping {
@Mappings({
@Mapping(target ="focusNull",ignore = true),
{{#each entity.indexRelation.lookup as |lookup|}}
@Mapping(source ="{{camelCase lookup.codeName}}",target = "{{camelCase lookup.refCodeName}}"),
{{/each}}
})
{{entity.indexRelation.relEntity.codeName}} to{{pascalCase entity.indexRelation.relEntity.codeName}}({{entity.codeName}} {{camelCase entity.codeName}});
@Mappings({
@Mapping(target ="focusNull",ignore = true),
{{#each entity.indexRelation.lookup as |lookup|}}
@Mapping(source ="{{camelCase lookup.refCodeName}}",target = "{{camelCase lookup.codeName}}"),
{{/each}}
})
{{entity.codeName}} to{{pascalCase entity.codeName}}({{entity.indexRelation.relEntity.codeName}} {{camelCase entity.indexRelation.relEntity.codeName}});
List<{{entity.indexRelation.relEntity.codeName}}> to{{pascalCase entity.indexRelation.relEntity.codeName}}(List<{{entity.codeName}}> list);
List<{{entity.codeName}}> to{{pascalCase entity.codeName}}(List<{{entity.indexRelation.relEntity.codeName}}> list);
}
{{/if}}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.service.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.math.BigInteger;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.security.SpringContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.Assert;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import cn.ibizlab.util.errors.BadRequestAlertException;
{{#system.enableGlobalTransaction}}
import io.seata.spring.annotation.GlobalTransactional;
{{/system.enableGlobalTransaction}}
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Lazy;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
import {{packageName}}.core.{{entity.module}}.service.{{entity.codeName}}Service;
import {{packageName}}.core.{{entity.module}}.mapper.{{entity.codeName}}Mapper;
import cn.ibizlab.util.helper.CachedBeanCopier;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.security.AuthenticationUser;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
{{#entity.relEntities}}
import {{packageName}}.core.{{module}}.domain.{{codeName}};
{{#neq storage "NONE"}}
import {{packageName}}.core.{{module}}.service.{{codeName}}Service;
{{/neq}}
{{/entity.relEntities}}
/**
* 实体[{{entity.logicName}}] 服务对象接口实现
*/
@Slf4j
@Service("{{entity.codeName}}Service")
public class {{entity.codeName}}ServiceBase extends ServiceImpl<{{entity.codeName}}Mapper,{{entity.codeName}}> implements {{entity.codeName}}Service {
protected {{entity.codeName}}Service getProxyService() {
return SpringContextHolder.getBean(this.getClass());
}
{{#entity.relEntities}}
{{#neq storage "NONE"}}
@Autowired
@Lazy
protected {{codeName}}Service {{camelCase codeName}}Service;
{{/neq}}
{{/entity.relEntities}}
{{#if entity.indexSubDE}}
@Autowired
@Lazy
protected {{packageName}}.core.{{entity.module}}.mapping.{{entity.codeName}}InheritMapping {{camelCase entity.codeName}}InheritMapping;
{{/if}}
protected int batchSize = 500;
public {{entity.codeName}} get({{entity.codeName}} et) {
{{entity.codeName}} rt = this.baseMapper.selectEntity(et);
Assert.notNull(rt,"数据不存在,{{entity.logicName}}:"+et.get{{pascalCase entity.keyField.codeName}}());
BeanUtils.copyProperties(rt, et);
{{#entity.nesteds}}
{{#unless listCode}}
{{#unless columnName}}
//设置 [{{entityLogicName}}]
et.set{{pascalCase codeName}}({{camelCase entityCodeName}}Service.selectBy{{pascalCase fkField.codeName}}(et.get{{pascalCase entity.keyField.codeName}}()));
{{/unless}}
{{/unless}}
{{/entity.nesteds}}
return et;
}
public List<{{entity.codeName}}> getByEntities(List<{{entity.codeName}}> entities) {
return this.baseMapper.selectEntities(entities);
}
{{#entity.hasReferences}}
public void fillParentData({{entity.codeName}} et) {
{{#each entity.references as |reference|}}
{{#gt reference.relFieldCount 1}}
if(!ObjectUtils.isEmpty(et.get{{pascalCase reference.fkField.codeName}}())) {
{{reference.entityCodeName}} {{camelCase reference.entityCodeName}} = et.get{{pascalCase reference.codeName}}();
if(!ObjectUtils.isEmpty({{camelCase reference.entityCodeName}})) {
{{#each reference.fields as |field|}}
{{#neq field.dataType 'PICKUP'}}
et.set{{pascalCase field.codeName}}({{camelCase reference.entityCodeName}}.get{{pascalCase field.refFieldCodeName}}());
{{/neq}}
{{/each}}
}
}
{{/gt}}
{{/each}}
}
{{/entity.hasReferences}}
public {{entity.codeName}} getDraft({{entity.codeName}} et) {
{{#entity.hasReferences}}
fillParentData(et);
{{/entity.hasReferences}}
return et;
}
public Integer checkKey({{entity.codeName}} et) {
return this.count(Wrappers.lambdaQuery(et))>0?1:0;
}
@Override
{{#eq entity.actions.create.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.create.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean create({{entity.codeName}} et) {
{{#entity.hasReferences}}
fillParentData(et);
{{/entity.hasReferences}}
{{#entity.isIndexSubDE}}
if(ObjectUtils.isEmpty(et.get{{pascalCase entity.keyField.codeName}}()))
et.set{{pascalCase entity.keyField.codeName}}(({{entity.keyField.type.java}})et.getDefaultKey(true));
{{entity.indexRelation.entityCodeName}} {{camelCase entity.indexRelation.entityCodeName}} = {{camelCase entity.codeName}}InheritMapping.to{{pascalCase entity.indexRelation.entityCodeName}}(et);
{{#if entity.indexRelation.indexTypePSDEField}}
{{camelCase entity.indexRelation.entityCodeName}}.set("{{lowerCase entity.indexRelation.indexTypePSDEField.codeName}}","{{entity.indexRelation.typeValue}}");
{{/if}}
{{camelCase entity.indexRelation.entityCodeName}}Service.create({{camelCase entity.indexRelation.entityCodeName}});
{{/entity.isIndexSubDE}}
{{#if entity.isLogicInheritDE}}
if(!update(et, (Wrapper) et.getUpdateWrapper(true).eq("{{lowerCase entity.keyField.name}}", et.get{{pascalCase keyField.codeName}}())))
return false;
{{else}}
if(!this.retBool(this.baseMapper.insert(et)))
return false;
{{/if}}
{{#each entity.nesteds}}
{{#unless listCode}}
{{#unless columnName}}
{{camelCase entityCodeName}}Service.saveBy{{pascalCase fkField.codeName}}(et,et.get{{pascalCase codeName}}());
{{/unless}}
{{/unless}}
{{/each}}
get(et);
{{#if entity.hasPSDERsMapping}}
updateParentData(et);
{{/if}}
return true;
}
{{#eq entity.actions.create.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.create.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean createBatch(List<{{entity.codeName}}> list) {
{{#if (or entity.actions.create.psDEActionLogics entity.isIndexSubDE)}}
for ({{entity.codeName}} et : list) {
{{#if entity.unionKeyMode}}
getProxyService().save(et);
{{else}}
getProxyService().create(et);
{{/if}}
}
{{else}}
{{#entity.hasReferences}}
list.forEach(et->fillParentData(et));
{{/entity.hasReferences}}
{{#if entity.unionKeyMode}}
this.saveOrUpdateBatch(list,batchSize);
{{else}}
this.saveBatch(list, batchSize);
{{/if}}
{{#if entity.hasPSDERsMapping}}
updateParentDataBatch(list);
{{/if}}
{{/if}}
return true;
}
{{#eq entity.actions.update.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.update.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean update({{entity.codeName}} et) {
{{#entity.hasReferences}}
fillParentData(et);
{{/entity.hasReferences}}
{{#entity.isIndexSubDE}}
{{entity.indexRelation.entityCodeName}} {{camelCase entity.indexRelation.entityCodeName}} = {{camelCase entity.codeName}}InheritMapping.to{{pascalCase entity.indexRelation.entityCodeName}}(et);
{{#if entity.indexRelation.indexTypePSDEField}}
{{camelCase entity.indexRelation.entityCodeName}}.set("{{lowerCase entity.indexRelation.indexTypePSDEField.codeName}}","{{entity.indexRelation.typeValue}}");
{{/if}}
{{camelCase entity.indexRelation.entityCodeName}}Service.save({{camelCase entity.indexRelation.entityCodeName}});
{{/entity.isIndexSubDE}}
UpdateWrapper qw=et.getUpdateWrapper(true);
{{#each entity.keyFields as |field|}}
qw.eq("{{lowerCase field.name}}", et.get{{pascalCase field.codeName}}());
{{/each}}
if(!update(et, qw)) {
return false;
}
{{#each entity.nesteds}}
{{#unless listCode}}
{{#unless columnName}}
{{camelCase entityCodeName}}Service.saveBy{{pascalCase fkField.codeName}}(et,et.get{{pascalCase codeName}}());
{{/unless}}
{{/unless}}
{{/each}}
get(et);
{{#if entity.hasPSDERsMapping}}
updateParentData(et);
{{/if}}
return true;
}
{{#eq entity.actions.update.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.update.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean updateBatch(List<{{entity.codeName}}> list) {
{{#if (or entity.actions.update.psDEActionLogics entity.isIndexSubDE (not entity.keyField.phisicalDEField))}}
for ({{entity.codeName}} et : list) {
getProxyService().update(et);
}
{{else}}
{{#entity.hasReferences}}
list.forEach(et->fillParentData(et));
{{/entity.hasReferences}}
updateBatchById(list, batchSize);
{{#if entity.hasPSDERsMapping}}
updateParentDataBatch(list);
{{/if}}
{{/if}}
return true;
}
{{#eq entity.actions.save.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.save.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean save({{entity.codeName}} et) {
if(checkKey(et)==0)
return getProxyService().update(et);
else
return getProxyService().create(et);
}
{{#eq entity.actions.save.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.save.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean saveBatch(List<{{entity.codeName}}> list) {
List<{{entity.codeName}}> rt=this.getByEntities(list);
Set<Serializable> keys=new HashSet<>();
rt.forEach(et->{
Serializable key = et.get{{pascalCase entity.keyField.codeName}}();
if(!ObjectUtils.isEmpty(key))
keys.add(key);
});
List<{{entity.codeName}}> _create=new ArrayList<>();
List<{{entity.codeName}}> _update=new ArrayList<>();
list.forEach(et-> {
Serializable key = et.get{{pascalCase entity.keyField.codeName}}();
if(keys.contains(key))
_update.add(et);
else
_create.add(et);
});
List rtList=new ArrayList<>();
if(_update.size()>0 && (!getProxyService().updateBatch(_update)))
return false;
if(_create.size()>0 && (!getProxyService().createBatch(_create)))
return false;
return true;
}
{{#eq entity.actions.remove.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.remove.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean remove({{entity.codeName}} et) {
{{entity.keyField.type.java}} key = et.get{{pascalCase entity.keyField.codeName}}();
{{#if entity.hasPSDERsMapping}}
get(et);
{{/if}}
{{#entity.nesteds}}
{{#unless listCode}}
{{#unless columnName}}
{{#eq removeActionType 1}}
{{camelCase entityCodeName}}Service.removeBy{{pascalCase fkField.codeName}}(key);
{{/eq}}
{{#eq removeActionType 2}}
{{camelCase entityCodeName}}Service.resetBy{{pascalCase fkField.codeName}}(key);
{{/eq}}
{{#eq removeActionType 3}}
if(!ObjectUtils.isEmpty({{camelCase entityCodeName}}Service.removeBy{{pascalCase fkField.codeName}}(key)))
throw new BadRequestAlertException("删除数据失败,当前数据存在关系实体[{{camelCase entityCodeName}}]数据,无法删除!","","");
{{/eq}}
{{/unless}}
{{/unless}}
{{/entity.nesteds}}
{{#entity.isIndexSubDE}}
{{camelCase entity.indexRelation.entityCodeName}}Service.remove({{camelCase entity.codeName}}InheritMapping.to{{pascalCase entity.indexRelation.entityCodeName}}(et));
{{/entity.isIndexSubDE}}
if(!remove(new QueryWrapper<{{entity.codeName}}>()
{{#each entity.keyFields as |field|}}
.eq("{{lowerCase field.name}}", et.get{{pascalCase field.codeName}}())
{{/each}}
)) {
return false;
}
{{#if entity.hasPSDERsMapping}}
updateParentData(et);
{{/if}}
return true ;
}
{{#eq entity.actions.remove.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.remove.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean removeBatch(Collection<{{entity.keyField.type.java}}> ids) {
{{#if (or entity.actions.update.psDEActionLogics entity.isIndexSubDE (not entity.keyField.phisicalDEField) entity.hasPSDERsMapping)}}
for ({{entity.keyField.type.java}} et : ids)
getProxyService().remove(et);
{{else}}
if(!removeByIds(ids))
return false;
{{/if}}
return true;
}
{{#entity.extActions}}
{{#eq transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq transactionMode "DEFAULT"}}@Transactional{{/eq}}
public {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}}) {
{{#if voidReturn}}
return {{inParamName}};
{{else}}
return null;
{{/if}}
}
{{/entity.extActions}}
{{#entity.dataSets}}
public Page<{{entity.codeName}}> search{{pascalCase codeName}}({{entity.codeName}}SearchContext context) {
{{#if entity.hasPSDEWF}}
Map<String,Map<String,Object>> businesskeys = fillWFTaskContext(context);
{{/if}}
com.baomidou.mybatisplus.extension.plugins.pagination.Page<{{#if enableGroup}}Map{{else}}{{entity.codeName}}{{/if}}> pages=baseMapper.search{{pascalCase codeName}}(context.getPages(),context,context.getSelectCond());
{{#if entity.hasPSDEWF}}
if(!StringUtils.isEmpty(context.getSrfWF()))
fillWFParam(pages,businesskeys);
{{/if}}
return new PageImpl<{{entity.codeName}}>(com.alibaba.fastjson.JSON.parseArray(com.alibaba.fastjson.JSON.toJSONString(pages.getRecords()),{{entity.codeName}}.class), context.getPageable(), pages.getTotal());
}
public List<{{entity.codeName}}> list{{pascalCase codeName}}({{entity.codeName}}SearchContext context) {
return com.alibaba.fastjson.JSON.parseArray(com.alibaba.fastjson.JSON.toJSONString(baseMapper.list{{pascalCase codeName}}(context,context.getSelectCond())),{{entity.codeName}}.class);
}
{{/entity.dataSets}}
{{#entity.references}}
public List<{{entity.codeName}}> selectBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
return baseMapper.selectBy{{pascalCase fkField.codeName}}({{camelCase fkField.codeName}});
}
public boolean removeBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
return this.remove(new QueryWrapper<{{entity.codeName}}>().eq("{{lowerCase fkField.name}}",{{camelCase fkField.codeName}}));
}
public boolean resetBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
return this.update(new UpdateWrapper<{{entity.codeName}}>().set("{{lowerCase fkField.name}}",null).eq("{{lowerCase fkField.name}}",{{camelCase fkField.codeName}}));
}
public boolean saveBy{{pascalCase fkField.codeName}}({{entityCodeName}} {{camelCase entityCodeName}},List<{{entity.codeName}}> list) {
if(list==null)
return true;
Set<{{entity.keyField.type.java}}> delIds=new HashSet<{{entity.keyField.type.java}}>();
List<{{entity.codeName}}> _update=new ArrayList<{{entity.codeName}}>();
List<{{entity.codeName}}> _create=new ArrayList<{{entity.codeName}}>();
for({{entity.codeName}} before:selectBy{{pascalCase fkField.codeName}}({{camelCase entityCodeName}}.get{{pascalCase relEntity.keyField.codeName}}())){
delIds.add(before.get{{pascalCase entity.keyField.codeName}}());
}
for({{entity.codeName}} sub:list) {
sub.set{{pascalCase fkField.codeName}}({{camelCase entityCodeName}}.get{{pascalCase relEntity.keyField.codeName}}());
sub.set{{pascalCase codeName}}({{camelCase entityCodeName}});
if(ObjectUtils.isEmpty(sub.get{{pascalCase entity.keyField.codeName}}()))
sub.set{{pascalCase entity.keyField.codeName}}(({{entity.keyField.type.java}})sub.getDefaultKey(true));
if(delIds.contains(sub.get{{pascalCase entity.keyField.codeName}}())) {
delIds.remove(sub.get{{pascalCase entity.keyField.codeName}}());
_update.add(sub);
}
else
_create.add(sub);
}
if(_update.size()>0 && (!getProxyService().updateBatch(_update)))
return false;
if(_create.size()>0 && (!getProxyService().createBatch(_create)))
return false;
if(delIds.size()>0 && (!getProxyService().removeBatch(delIds)))
return false;
return true;
}
{{/entity.references}}
{{#if entity.hasPSDEWF}}
@Autowired
private cn.ibizlab.util.client.IBZWFFeignClient ibzwfFeignClient;
/**
* 查询统一工作流待办
* @param context
*/
private Map<String,Map<String,Object>> fillWFTaskContext({{entity.codeName}}SearchContext context){
Map<String, Map<String, Object>> keys = null;
Collection<String> businessKeys = null;
if(!StringUtils.isEmpty(context.getSrfWF())){
keys= ibzwfFeignClient.getMyTask("{{lowerCase system.codeName}}", "", "{{pluralize entity.codeName}}");
if(!ObjectUtils.isEmpty(keys))
businessKeys = keys.keySet();
}
else if(!StringUtils.isEmpty(context.getUserTaskId()) && !StringUtils.isEmpty(context.getProcessDefinitionKey()))
businessKeys= ibzwfFeignClient.getbusinesskeysByUserId("{{lowerCase system.codeName}}", AuthenticationUser.getAuthenticationUser().getUserid(),"{{pluralize entity.codeName}}",context.getProcessDefinitionKey(),context.getUserTaskId());
if(!ObjectUtils.isEmpty(businessKeys))
context.getSelectCond().in("{{entity.keyField.columnName}}",businessKeys);
else
context.getSelectCond().apply("1<>1");
return keys;
}
/**
* 填充工作流参数
* @param pages
* @param businesskeys
*/
private void fillWFParam(com.baomidou.mybatisplus.extension.plugins.pagination.Page<{{entity.codeName}}> pages, Map<String, Map<String, Object>> businesskeys) {
if (!ObjectUtils.isEmpty(businesskeys)) {
for ({{entity.codeName}} entity : pages.getRecords()) {
Object id = entity.get{{pascalCase entity.keyField.codeName}}();
if (!ObjectUtils.isEmpty(id) && businesskeys.containsKey(id)) {
Map<String, Object> params = businesskeys.get(id);
for (Map.Entry<String, Object> entry : params.entrySet()) {
entity.set(entry.getKey(), entry.getValue());
}
}
}
}
}
{{/if}}
}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.service.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.math.BigInteger;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.security.SpringContextHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.Assert;
import org.springframework.beans.factory.annotation.Value;
import cn.ibizlab.util.errors.BadRequestAlertException;
{{#system.enableGlobalTransaction}}
import io.seata.spring.annotation.GlobalTransactional;
{{/system.enableGlobalTransaction}}
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Lazy;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
import {{packageName}}.core.{{entity.module}}.service.{{entity.codeName}}Service;
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;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
/**
* 实体[{{entity.logicName}}] 服务对象接口实现
*/
@Slf4j
@Service("{{entity.codeName}}Service")
public class {{entity.codeName}}ServiceBase implements {{entity.codeName}}Service {
protected {{entity.codeName}}Service {{camelCase entity.codeName}}Service = SpringContextHolder.getBean(this.getClass());
{{#entity.relEntities}}
{{#neq storage "NONE"}}
@Autowired
@Lazy
protected {{packageName}}.core.{{module}}.service.{{codeName}}Service {{camelCase codeName}}Service;
{{/neq}}
{{/entity.relEntities}}
{{#if entity.indexSubDE}}
@Autowired
@Lazy
protected {{packageName}}.core.{{entity.module}}.mapping.{{entity.codeName}}InheritMapping {{camelCase entity.codeName}}InheritMapping;
{{/if}}
protected int batchSize = 500;
public {{entity.codeName}} get({{entity.codeName}} et) {
return et;
}
public List<{{entity.codeName}}> getByEntities(List<{{entity.codeName}}> entities) {
return null;
}
{{#entity.hasReferences}}
public void fillParentData({{entity.codeName}} et) {
}
{{/entity.hasReferences}}
public {{entity.codeName}} getDraft({{entity.codeName}} et) {
{{#entity.hasReferences}}
fillParentData(et);
{{/entity.hasReferences}}
return et;
}
public Integer checkKey({{entity.codeName}} et) {
return null;
}
@Override
{{#eq entity.actions.create.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.create.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean create({{entity.codeName}} et) {
return true;
}
{{#eq entity.actions.create.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.create.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean createBatch(List<{{entity.codeName}}> list) {
return true;
}
{{#eq entity.actions.update.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.update.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean update({{entity.codeName}} et) {
{{#entity.hasReferences}}
fillParentData(et);
{{/entity.hasReferences}}
return true;
}
{{#eq entity.actions.update.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.update.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean updateBatch(List<{{entity.codeName}}> list) {
return true;
}
{{#eq entity.actions.save.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.save.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean save({{entity.codeName}} et) {
if(checkKey(et)==0)
return {{camelCase entity.codeName}}Service.update(et);
else
return {{camelCase entity.codeName}}Service.create(et);
}
{{#eq entity.actions.save.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.save.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean saveBatch(List<{{entity.codeName}}> list) {
List<{{entity.codeName}}> rt=this.getByEntities(list);
Set<Serializable> keys=new HashSet<>();
rt.forEach(et->{
Serializable key = et.get{{pascalCase entity.keyField.codeName}}();
if(!ObjectUtils.isEmpty(key))
keys.add(key);
});
List<{{entity.codeName}}> _create=new ArrayList<>();
List<{{entity.codeName}}> _update=new ArrayList<>();
list.forEach(et-> {
Serializable key = et.get{{pascalCase entity.keyField.codeName}}();
if(keys.contains(key))
_update.add(et);
else
_create.add(et);
});
List rtList=new ArrayList<>();
if(_update.size()>0 && (!{{camelCase entity.codeName}}Service.updateBatch(_update)))
return false;
if(_create.size()>0 && (!{{camelCase entity.codeName}}Service.createBatch(_create)))
return false;
return true;
}
{{#eq entity.actions.remove.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.remove.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean remove({{entity.codeName}} et) {
return false ;
}
{{#eq entity.actions.remove.transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq entity.actions.remove.transactionMode "DEFAULT"}}@Transactional{{/eq}}
public boolean removeBatch(Collection<{{entity.keyField.type.java}}> ids) {
return false;
}
{{#entity.extActions}}
{{#eq transactionMode "GLOBAL"}}@GlobalTransactional{{/eq}}{{#eq transactionMode "DEFAULT"}}@Transactional{{/eq}}
public {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}}) {
{{#if voidReturn}}
return {{inParamName}};
{{else}}
return null;
{{/if}}
}
{{/entity.extActions}}
{{#entity.dataSets}}
public Page<{{entity.codeName}}> search{{pascalCase codeName}}({{entity.codeName}}SearchContext context) {
return null;
}
public List<{{entity.codeName}}> list{{pascalCase codeName}}({{entity.codeName}}SearchContext context) {
return null;
}
{{/entity.dataSets}}
{{#entity.references}}
public List<{{entity.codeName}}> selectBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
return null;
}
public boolean removeBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
return false;
}
public boolean resetBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}}) {
return false;
}
public boolean saveBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}},List<{{entity.codeName}}> list) {
return false;
}
{{/entity.references}}
}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.service;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;
import java.math.BigInteger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cache.annotation.CacheEvict;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.dynamic.datasource.annotation.DS;
import cn.ibizlab.util.helper.CachedBeanCopier;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
{{#dsName}}
@DS("{{entity.dataSource}}")
{{/dsName}}
public interface {{entity.codeName}}Service extends IService<{{entity.codeName}}> {
{{entity.codeName}} get({{entity.codeName}} et);
default {{entity.codeName}} get({{entity.keyField.type.java}} key) {
{{entity.codeName}} et = new {{entity.codeName}}();
et.set{{pascalCase entity.keyField.codeName}}(key);
return get(et);
}
default List<{{entity.codeName}}> getByIds(Collection<{{entity.keyField.type.java}}> ids) {
List<{{entity.codeName}}> entities =new ArrayList();
ids.forEach(key -> {
{{entity.codeName}} et = new {{entity.codeName}}();
et.set{{pascalCase entity.keyField.codeName}}(key);
entities.add(et);
});
return getByEntities(entities);
}
List<{{entity.codeName}}> getByEntities(List<{{entity.codeName}}> entities);
{{entity.codeName}} getDraft({{entity.codeName}} et);
Integer checkKey({{entity.codeName}} et);
boolean create({{entity.codeName}} et);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean createBatch(List<{{entity.codeName}}> list);
boolean update({{entity.codeName}} et);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean updateBatch(List<{{entity.codeName}}> list);
boolean save({{entity.codeName}} et);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean saveBatch(List<{{entity.codeName}}> list);
default boolean remove({{entity.keyField.type.java}} key) {
{{entity.codeName}} et = new {{entity.codeName}}();
et.set{{pascalCase entity.keyField.codeName}}(key);
return remove(et);
}
default boolean remove(List<{{entity.keyField.type.java}}> key) {
return removeBatch(key);
}
boolean remove({{entity.codeName}} et);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean removeBatch(Collection<{{entity.keyField.type.java}}> ids);
{{#each entity.extActions}}
default {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}}) {
{{#if voidReturn}}
return {{inParamName}};
{{else}}
return null;
{{/if}}
}
{{/each}}
{{#entity.dataSets}}
Page<{{entity.codeName}}> search{{pascalCase codeName}}({{entity.codeName}}SearchContext context);
List<{{entity.codeName}}> list{{pascalCase codeName}}({{entity.codeName}}SearchContext context);
{{/entity.dataSets}}
{{#entity.references}}
List<{{entity.codeName}}> selectBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean removeBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean resetBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean saveBy{{pascalCase fkField.codeName}}({{packageName}}.core.{{module}}.domain.{{entityCodeName}} {{camelCase entityCodeName}},List<{{entity.codeName}}> list);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
default boolean saveBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}},List<{{entity.codeName}}> list) {
{{packageName}}.core.{{module}}.domain.{{entityCodeName}} et = new {{packageName}}.core.{{module}}.domain.{{entityCodeName}}();
et.set{{pascalCase relEntity.keyField.codeName}}({{camelCase fkField.codeName}});
return saveBy{{pascalCase fkField.codeName}}(et,list);
}
{{/entity.references}}
}
\ No newline at end of file
package {{packageName}}.core.{{entity.module}}.service;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;
import java.math.BigInteger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cache.annotation.CacheEvict;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.dynamic.datasource.annotation.DS;
import cn.ibizlab.util.helper.CachedBeanCopier;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
{{#dsName}}
@DS("{{entity.dataSource}}")
{{/dsName}}
public interface {{entity.codeName}}Service {
{{entity.codeName}} get({{entity.codeName}} et);
default {{entity.codeName}} get({{entity.keyField.type.java}} key) {
{{entity.codeName}} et = new {{entity.codeName}}();
et.set{{pascalCase entity.keyField.codeName}}(key);
return get(et);
}
default List<{{entity.codeName}}> getByIds(Collection<{{entity.keyField.type.java}}> ids) {
List<{{entity.codeName}}> entities =new ArrayList();
ids.forEach(key -> {
{{entity.codeName}} et = new {{entity.codeName}}();
et.set{{pascalCase entity.keyField.codeName}}(key);
entities.add(et);
});
return getByEntities(entities);
}
List<{{entity.codeName}}> getByEntities(List<{{entity.codeName}}> entities);
{{entity.codeName}} getDraft({{entity.codeName}} et);
Integer checkKey({{entity.codeName}} et);
boolean create({{entity.codeName}} et);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean createBatch(List<{{entity.codeName}}> list);
boolean update({{entity.codeName}} et);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean updateBatch(List<{{entity.codeName}}> list);
boolean save({{entity.codeName}} et);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean saveBatch(List<{{entity.codeName}}> list);
default boolean remove({{entity.keyField.type.java}} key) {
{{entity.codeName}} et = new {{entity.codeName}}();
et.set{{pascalCase entity.keyField.codeName}}(key);
return remove(et);
}
default boolean remove(List<{{entity.keyField.type.java}}> key) {
return removeBatch(key);
}
boolean remove({{entity.codeName}} et);
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean removeBatch(Collection<{{entity.keyField.type.java}}> ids);
{{#each entity.extActions}}
default {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}}) {
{{#if voidReturn}}
return {{inParamName}};
{{else}}
return null;
{{/if}}
}
{{/each}}
{{#entity.dataSets}}
Page<{{entity.codeName}}> search{{pascalCase codeName}}({{entity.codeName}}SearchContext context);
List<{{entity.codeName}}> list{{pascalCase codeName}}({{entity.codeName}}SearchContext context);
{{/entity.dataSets}}
{{#entity.references}}
List<{{entity.codeName}}> selectBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean removeBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean resetBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}});
{{#enableEntityCache}}
@CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
{{/enableEntityCache}}
boolean saveBy{{pascalCase fkField.codeName}}({{fkField.type.java}} {{camelCase fkField.codeName}},List<{{entity.codeName}}> list);
{{/entity.references}}
}
\ No newline at end of file
package {{packageName}}.util.aspect;
import lombok.SneakyThrows;
import cn.ibizlab.util.annotation.Audit;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.service.IBZDataAuditService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 实体数据审计切面类
*/
@Aspect
@Component
public class AuditAspect
{
private final ExpressionParser parser = new SpelExpressionParser();
@Autowired
IBZDataAuditService dataAuditService;
/**
* 实体数据建立切面,在成功创建数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* @param point
*/
@AfterReturning(value = "execution(* {{packageName}}.core.*.service.*.create(..)){{#system.enableES}}&& !execution(* {{packageName}}.core.es.service.*.create*(..)){{/system.enableES}}")
@SneakyThrows
public void create(JoinPoint point) {
HttpServletRequest request = null;
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null) {
request = ((ServletRequestAttributes)requestAttributes).getRequest();
}
Object [] args = point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0) {
return;
}
Object serviceParam = args[0];
if(serviceParam instanceof EntityBase) {
EntityBase entity = (EntityBase)serviceParam;
Map<String, Audit> auditFields = DEFieldCacheMap.getAuditFields(entity.getClass());
//是否有审计属性
if(auditFields.size()==0) {
return;
}
String idField = DEFieldCacheMap.getDEKeyField(entity.getClass());
Object idValue = "";
if(!StringUtils.isEmpty(idField)) {
idValue=entity.get(idField);
}
//记录审计日志
dataAuditService.createAudit(request, entity, idValue, auditFields);
}
}
/**
* 实体数据更新切面,在成功更新数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* 使用环切【@Around】获取到更新前后的实体数据并进行差异比较,并将差异内容记入审计日志内
* @param point
*/
@Around("execution(* {{packageName}}.core.*.service.*.update(..)){{#system.enableES}}&& !execution(* {{packageName}}.core.es.service.*.update*(..)){{/system.enableES}}")
public Object update(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = null;
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null) {
request=((ServletRequestAttributes)requestAttributes).getRequest();
}
Object serviceObj = point.getTarget();
Object args[] = point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0) {
return point.proceed();
}
Object arg = args[0];
if(arg instanceof EntityBase) {
EntityBase entity = (EntityBase) arg;
Map<String, Audit> auditFields = DEFieldCacheMap.getAuditFields(entity.getClass());
//是否有审计属性
if(auditFields.size()==0) {
return point.proceed();
}
String idField = DEFieldCacheMap.getDEKeyField(entity.getClass());
Object idValue = "";
if(!StringUtils.isEmpty(idField)){
idValue = entity.get(idField);
}
if(ObjectUtils.isEmpty(idValue)) {
return point.proceed();
}
//获取更新前实体
EntityBase beforeEntity = getEntity(serviceObj, idValue);
//执行更新操作
point.proceed();
//记录审计日志
dataAuditService.updateAudit(request, beforeEntity, serviceObj, idValue, auditFields);
return true;
}
return point.proceed();
}
/**
* 实体数据更新切面,在成功更新数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* 使用环切【@Around】获取要删除的完整数据,并将审计属性相关信息记录到审计日志中
* @param point
* @return
* @throws Throwable
*/
@Around("execution(* {{packageName}}.core.*.service.*.remove(..)){{#system.enableES}}&& !execution(* {{packageName}}.core.es.service.*.remove*(..)){{/system.enableES}}")
public Object remove(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request = null;
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if(requestAttributes!= null) {
request = ((ServletRequestAttributes)requestAttributes).getRequest();
}
Object serviceObj = point.getTarget();
Object args[] = point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0) {
return point.proceed();
}
Object idValue = args[0];
EntityBase entity = getEntity(serviceObj, idValue);
Map<String, Audit> auditFields = DEFieldCacheMap.getAuditFields(entity.getClass());
if(auditFields.size()==0) {
return point.proceed();
}
else{
//执行删除操作
point.proceed();
//记录审计日志
dataAuditService.removeAudit(request, entity, idValue, auditFields);
return true;
}
}
/**
* 获取实体
* @param service
* @param id
* @return
*/
@SneakyThrows
private EntityBase getEntity(Object service, Object id) {
EntityBase entity = null;
if(!ObjectUtils.isEmpty(service)) {
EvaluationContext oldContext = new StandardEvaluationContext();
oldContext.setVariable("service", service);
oldContext.setVariable("id", id);
Expression oldExp = parser.parseExpression("#service.get(#id)");
return oldExp.getValue(oldContext, EntityBase.class);
}
return entity;
}
}
\ No newline at end of file
package {{packageName}}.util.aspect;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.enums.DEFieldDefaultValueType;
import cn.ibizlab.util.enums.DEPredefinedFieldType;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.security.AuthenticationUser;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.AlternativeJdkIdGenerator;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 实体属性默认值切面,只有新建(Create)时才会填充默认值
*/
@Aspect
@Order(50)
@Component
public class DEFieldDefaultValueAspect
{
/**
* 操作用户标识
*/
final static String TAG_PERSONID = "SRF_PERSONID";
/**
* 操作用户名称
*/
final static String TAG_PERSONNAME = "SRF_PERSONNAME";
/**
* 新建数据切入点
* @param point
* @throws Exception
*/
@Before(value = "execution(* {{packageName}}.core.*.service.*.create(..))")
public void BeforeCreate(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
@Before(value = "execution(* {{packageName}}.core.*.service.*.createBatch(..))")
public void BeforeCreateBatch(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
/**
* 更新数据切入点
* @param point
* @throws Exception
*/
@Before(value = "execution(* {{packageName}}.core.*.service.*.update(..))")
public void BeforeUpdate(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
@Before(value = "execution(* {{packageName}}.core.*.service.*.updateBatch(..))")
public void BeforeUpdateBatch(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
/**
* 保存数据切入点
* @param point
* @throws Exception
*/
@Before(value = "execution(* {{packageName}}.core.*.service.*.save(..))")
public void BeforeSave(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
@Before(value = "execution(* {{packageName}}.core.*.service.*.saveBatch(..))")
public void BeforeSaveBatch(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
/**
* 填充属性默认值
* @param joinPoint
* @return
* @throws Exception
*/
public Object fillDEFieldDefaultValue(JoinPoint joinPoint) throws Exception {
Object[] args = joinPoint.getArgs();
if (args.length > 0) {
Object obj = args[0];
String actionName = joinPoint.getSignature().getName();
if(obj instanceof EntityBase) {
Map<String, DEField> deFields = DEFieldCacheMap.getDEFields(obj.getClass());
AuthenticationUser curUser = AuthenticationUser.getAuthenticationUser();
String keyField = DEFieldCacheMap.getDEKeyField(obj.getClass());
if(StringUtils.isEmpty(keyField)) {
return true;
}
fillDEField((EntityBase)obj, deFields, actionName, curUser, keyField);
}
else if (obj instanceof List) {
Map<String, DEField> deFields = null;
AuthenticationUser curUser = null;
String keyField = "";
for(Object item : (List)obj) {
if(item instanceof EntityBase) {
if(deFields == null) {
deFields = DEFieldCacheMap.getDEFields(item.getClass());
curUser = AuthenticationUser.getAuthenticationUser();
keyField = DEFieldCacheMap.getDEKeyField(item.getClass());
if(StringUtils.isEmpty(keyField)) {
return true;
}
}
fillDEField((EntityBase)item, deFields, actionName, curUser, keyField);
}
}
}
}
return true;
}
/**
* 填充系统预置属性
* @param et 当前实体对象
*/
private void fillDEField(EntityBase et, Map<String, DEField> deFields, String actionName, AuthenticationUser curUser, String keyField) throws Exception {
if(deFields.size()==0) {
return;
}
if(actionName.toLowerCase().startsWith("save")) {
if(ObjectUtils.isEmpty(et.get(keyField))) {
actionName="create";
}
}
for (Map.Entry<String, DEField> entry : deFields.entrySet()) {
String fieldname=entry.getKey();
//获取注解
DEField fieldAnnotation=entry.getValue();
//获取默认值类型
DEFieldDefaultValueType deFieldType=fieldAnnotation.defaultValueType();
//获取属性默认值
String deFieldDefaultValue = fieldAnnotation.defaultValue();
//获取预置属性类型
DEPredefinedFieldType predefinedFieldType = fieldAnnotation.preType();
//填充系统默认值
if(actionName.toLowerCase().startsWith("create") && (deFieldType!= DEFieldDefaultValueType.NONE || (!StringUtils.isEmpty(deFieldDefaultValue)))) {
fillFieldDefaultValue(fieldname, deFieldType, deFieldDefaultValue, et , curUser) ;
}
//填充系统预置属性
if(predefinedFieldType != DEPredefinedFieldType.NONE) {
fillPreFieldValue(fieldname, predefinedFieldType , et ,actionName ,fieldAnnotation.logicval(),curUser);
}
}
}
/**
* 填充属性默认值
* @param fieldname 实体属性名
* @param deFieldType 默认值类型
* @param deFieldDefaultValue 默认值
* @param et 当前实体对象
* @throws Exception
*/
private void fillFieldDefaultValue(String fieldname, DEFieldDefaultValueType deFieldType, String deFieldDefaultValue, EntityBase et , AuthenticationUser curUser) throws Exception {
Object fieldValue = et.get(fieldname);
if(org.springframework.util.ObjectUtils.isEmpty(fieldValue)) {
//填充直接值及其余默认值类型
if( (deFieldType== DEFieldDefaultValueType.NONE && !StringUtils.isEmpty(deFieldDefaultValue)) || (deFieldType != DEFieldDefaultValueType.NONE)) {
switch(deFieldType) {
case SESSION:
if(!StringUtils.isEmpty(deFieldDefaultValue)) {
Object sessionFieldValue = curUser.getSessionParams().get(deFieldDefaultValue.toLowerCase());
if(!ObjectUtils.isEmpty(sessionFieldValue)) {
et.set(fieldname, sessionFieldValue);
}
}
break;
case APPLICATION:
//暂未实现
break;
case UNIQUEID:
et.set(fieldname, (new AlternativeJdkIdGenerator()).generateId().toString().replace("-", ""));
break;
case CONTEXT:
if(!StringUtils.isEmpty(deFieldDefaultValue)) {
Object paramFieldValue=et.get(deFieldDefaultValue);
if(!ObjectUtils.isEmpty(paramFieldValue)) {
et.set(fieldname, paramFieldValue);
}
}
break;
case PARAM:
if(!StringUtils.isEmpty(deFieldDefaultValue)) {
Object paramFieldValue=et.get(deFieldDefaultValue);
if(!ObjectUtils.isEmpty(paramFieldValue)) {
et.set(fieldname, paramFieldValue);
}
}
break;
case OPERATOR:
et.set(fieldname, curUser.getUserid());
break;
case OPERATORNAME:
et.set(fieldname, curUser.getPersonname());
break;
case CURTIME:
et.set(fieldname, new Timestamp(new Date().getTime()));
break;
case APPDATA:
//暂未实现
break;
case NONE:
et.set(fieldname, deFieldDefaultValue);
break;
}
}
}
}
private void fillPreFieldValue(String fieldname, DEPredefinedFieldType preFieldType, EntityBase et, String actionName, String logicValue, AuthenticationUser curUser) throws Exception {
Object fieldValue = et.get(fieldname);
//为预置属性进行赋值
if(actionName.toLowerCase().startsWith("create") ||
preFieldType== DEPredefinedFieldType.UPDATEDATE|| preFieldType== DEPredefinedFieldType.UPDATEMAN||
preFieldType== DEPredefinedFieldType.UPDATEMANNAME) {
switch(preFieldType) {
case CREATEMAN:
et.set(fieldname, StringUtils.isEmpty(curUser.getUserid()) ? et.get(TAG_PERSONID) : curUser.getUserid());
break;
case CREATEMANNAME:
et.set(fieldname, StringUtils.isEmpty(curUser.getPersonname()) ? et.get(TAG_PERSONNAME) : curUser.getPersonname());
break;
case UPDATEMAN:
et.set(fieldname, StringUtils.isEmpty(curUser.getUserid()) ? et.get(TAG_PERSONID) : curUser.getUserid());
break;
case UPDATEMANNAME:
et.set(fieldname, StringUtils.isEmpty(curUser.getPersonname()) ? et.get(TAG_PERSONNAME) : curUser.getPersonname());
break;
case CREATEDATE:
et.set(fieldname, new Timestamp(new Date().getTime()));
break;
case UPDATEDATE:
et.set(fieldname, new Timestamp(new Date().getTime()));
break;
case ORGID:
if(org.springframework.util.StringUtils.isEmpty(fieldValue)) {
et.set(fieldname, curUser.getOrgid());
}
break;
case ORGNAME:
if(org.springframework.util.StringUtils.isEmpty(fieldValue)) {
et.set(fieldname, curUser.getOrgname());
}
break;
case ORGSECTORID:
if(org.springframework.util.StringUtils.isEmpty(fieldValue)) {
et.set(fieldname, curUser.getMdeptid());
}
break;
case ORGSECTORNAME:
if(org.springframework.util.StringUtils.isEmpty(fieldValue)) {
et.set(fieldname, curUser.getMdeptname());
}
break;
case LOGICVALID:
if(StringUtils.isEmpty(logicValue)) {
logicValue="1";
}
et.set(fieldname, logicValue);
break;
}
}
}
}
package {{packageName}}.util.aspect;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.domain.DELogic;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import org.apache.commons.io.IOUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.*;
import org.flowable.bpmn.model.Process;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.Message;
import org.kie.api.builder.Results;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.core.annotation.Order;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* 实体处理逻辑切面(前后附加逻辑、实体行为调用处理逻辑)
*/
@Aspect
@Component
@Slf4j
@Order(100)
public class DELogicAspect {
private static BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();
private final ExpressionParser parser = new SpelExpressionParser();
private ConcurrentMap<String, DELogic> deLogicMap = new ConcurrentHashMap<>();
private static Set<String> validLogic = new HashSet<>();
/**
* 执行实体行为附加逻辑、实体行为调用处理逻辑
*
* @param point
* @return
* @throws Throwable
*/
@Around("execution(* {{packageName}}.core.*.service.*.*(..)) && !execution(* {{packageName}}.core.es.service.*.*(..))")
public Object executeLogic(ProceedingJoinPoint point) throws Throwable {
Object args[] = point.getArgs();
if (ObjectUtils.isEmpty(args) || args.length == 0) {
return point.proceed();
}
Object service = point.getTarget();
Object arg = args[0];
String action = point.getSignature().getName();
EntityBase entity = null;
if (("remove".equalsIgnoreCase(action) || "get".equalsIgnoreCase(action)) && (!(arg instanceof EntityBase))) {
entity = getEntity(service.getClass());
if(!ObjectUtils.isEmpty(entity)) {
String id = DEFieldCacheMap.getDEKeyField(entity.getClass());
if(StringUtils.isEmpty(id)) {
log.debug("无法获取实体主键属性[{}]",getEntityName(entity));
return point.proceed();
}
entity.set(id, arg);
}
} else if (arg instanceof EntityBase) {
entity = (EntityBase) arg;
}
if (entity != null) {
executeBeforeLogic(entity, action);
Object result = point.proceed();
if("get".equalsIgnoreCase(action) && result instanceof EntityBase){
entity = (EntityBase) result;
}
executeLogic(entity, action);
executeAfterLogic(entity, action);
return result;
}
return point.proceed();
}
/**
* 判断类是否被代理类代理
*/
private String getEntityName(Object entity){
String entityName = entity.getClass().getSimpleName();
if(entityName.contains("$$")){
entityName = ClassUtils.getUserClass(entity.getClass()).getSimpleName();
}
return entityName;
}
/**
* 前附加逻辑
*
* @param entity
* @param action
*/
private void executeBeforeLogic(EntityBase entity, String action) {
Resource bpmnFile = getLocalModel(getEntityName(entity), action, LogicExecMode.BEFORE);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action);
}
}
/**
* 后附加逻辑
*
* @param entity
* @param action
*/
private void executeAfterLogic(EntityBase entity, String action) {
Resource bpmnFile = getLocalModel(getEntityName(entity), action, LogicExecMode.AFTER);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action);
}
}
/**
* 实体行为调用处理逻辑
*
* @param entity
* @param action
*/
private void executeLogic(EntityBase entity, String action) {
Resource bpmnFile = getLocalModel(getEntityName(entity), action, LogicExecMode.EXEC);
if (bpmnFile != null && bpmnFile.exists() && isValid(bpmnFile, entity, action)) {
executeLogic(bpmnFile, entity, action);
}
}
/**
* 编译并执行规则(bpmn、drl)
*
* @param bpmnFile
* @param entity
*/
private void executeLogic(Resource bpmnFile, Object entity, String action) {
try {
log.debug("开始执行实体处理逻辑[{}:{}:{}:本地模式]", getEntityName(entity), action, bpmnFile.getFilename());
String bpmnId = DigestUtils.md5DigestAsHex(bpmnFile.getURL().getPath().getBytes());
DELogic logic = getDELogic(bpmnFile);
if (logic == null) {
return;
}
if (deLogicMap.containsKey(bpmnId) && logic.getMd5().equals(deLogicMap.get(bpmnId).getMd5())) {
logic = deLogicMap.get(bpmnId);
} else {
reloadLogic(logic);
deLogicMap.put(bpmnId, logic);
}
KieContainer container = logic.getContainer();
KieSession kieSession = container.getKieBase().newKieSession();
Process mainProcess = logic.getProcess();
//主流程参数
fillGlobalParam(kieSession, mainProcess, entity);
//子流程参数
if (!ObjectUtils.isEmpty(logic.getRefLogic())) {
for (DELogic subLogic : logic.getRefLogic()) {
fillGlobalParam(kieSession, subLogic.getProcess(), entity);
}
}
kieSession.startProcess(mainProcess.getId());
log.debug("实体处理逻辑[{}:{}:{}:本地模式]执行结束", getEntityName(entity), action, bpmnFile.getFilename());
} catch (Exception e) {
log.error("实体处理逻辑[{}:{}:{}:本地模式]发生异常", getEntityName(entity), action, bpmnFile.getFilename());
throw new BadRequestAlertException("执行实体处理逻辑发生异常" + e.getMessage(), "DELogicAspect", "executeLogic");
}
}
/**
* 编译规则
*
* @param logic
*/
private void reloadLogic(DELogic logic) throws IOException {
KieServices kieServices = KieServices.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
for (Resource bpmn : logic.getRefRuleFiles()) {
kieFileSystem.write(ResourceFactory.newUrlResource(bpmn.getURL()));
}
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();
Results results = kieBuilder.getResults();
if (results.hasMessages(Message.Level.ERROR)) {
throw new BadRequestAlertException(String.format("编译实体处理逻辑 [%s] 发生异常, %s", logic.getName(), results.getMessages()), "DELogicAspect", "reloadLogic");
}
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
logic.setContainer(kieContainer);
}
/**
* 填充逻辑参数
*
* @param kieSession
* @param process
* @param entity
*/
private void fillGlobalParam(KieSession kieSession, Process process, Object entity) {
Map<String, List<ExtensionElement>> params = process.getExtensionElements();
for (Map.Entry<String, List<ExtensionElement>> param : params.entrySet()) {
if ("metaData".equalsIgnoreCase(param.getKey())) {
List<ExtensionElement> globalParams = param.getValue();
for (ExtensionElement globalParam : globalParams) {
Object value = null;
Map<String, List<ExtensionAttribute>> globalParamAttr = globalParam.getAttributes();
if (globalParamAttr.containsKey("name") && globalParamAttr.containsKey("type") && globalParamAttr.containsKey("express")) {
ExtensionAttribute name = globalParamAttr.get("name").get(0);
ExtensionAttribute type = globalParamAttr.get("type").get(0);
ExtensionAttribute express = globalParamAttr.get("express").get(0);
String express_value = express.getValue();
EvaluationContext oldContext = new StandardEvaluationContext();
if ("entity".equalsIgnoreCase(type.getValue())) {
value = entity;
}
if (!ObjectUtils.isEmpty(type.getValue()) && ObjectUtils.isEmpty(value)) {
Expression oldExp = parser.parseExpression(express_value);
value = oldExp.getValue(oldContext);
}
if ("entity".equalsIgnoreCase(type.getValue()) || "refentity".equalsIgnoreCase(type.getValue())) {
kieSession.insert(value);
}
kieSession.setGlobal(name.getValue(), value);
}
}
}
}
}
/**
* 获取逻辑配置
*
* @param bpmnFile
* @return
*/
private DELogic getDELogic(Resource bpmnFile) {
DELogic logic = null;
XMLStreamReader reader = null;
InputStream bpmn = null;
try {
if (bpmnFile.exists()) {
XMLInputFactory factory = XMLInputFactory.newInstance();
bpmn = bpmnFile.getInputStream();
reader = factory.createXMLStreamReader(bpmn);
BpmnModel model = bpmnXMLConverter.convertToBpmnModel(reader);
Process mainProcess = model.getMainProcess();
if (mainProcess == null) {
return null;
}
log.debug("正在加载 BPMN:{}", bpmnFile.getURL().getPath());
List<DELogic> refLogics = new ArrayList<>();
List<Resource> refFiles = new ArrayList<>();
//自己 bpmn 及 drl
refFiles.add(bpmnFile);
Resource drlFile = getDrl(bpmnFile);
if (drlFile != null && drlFile.exists()) {
refFiles.add(drlFile);
log.debug("正在加载 DRL:{}", drlFile.getURL().getPath());
}
//子 bpmn 及 drl
if (!ObjectUtils.isEmpty(model.getMainProcess()) && !ObjectUtils.isEmpty(model.getMainProcess().getFlowElementMap())) {
model.getMainProcess().getFlowElementMap().values().forEach(item -> {
if (item instanceof CallActivity) {
CallActivity subBpmn = (CallActivity) item;
String bpmnFileName = subBpmn.getName();
Resource subBpmnFile = getSubBpmn(bpmnFileName);
DELogic refLogic = getDELogic(subBpmnFile);
if (refLogic != null) {
refLogics.add(refLogic);
if (!ObjectUtils.isEmpty(refLogic.getRefRuleFiles())) {
refFiles.addAll(refLogic.getRefRuleFiles());
}
}
}
});
}
logic = new DELogic();
logic.setId(mainProcess.getId());
logic.setName(mainProcess.getName());
logic.setProcess(mainProcess);
logic.setRefLogic(refLogics);
logic.setRefRuleFiles(refFiles);
logic.setMd5(getMd5(refFiles));
}
} catch (Exception e) {
log.error("执行处理逻辑失败" + e);
} finally {
try {
if (reader != null) {
reader.close();
}
if (bpmn != null) {
bpmn.close();
}
} catch (Exception e) {
log.error("执行处理逻辑失败" + e);
}
}
return logic;
}
/**
* 获取实体
*
* @param service
* @return
*/
private EntityBase getEntity(Class service) {
Method[] methods = service.getDeclaredMethods();
for (Method method : methods) {
for (Class cls : method.getParameterTypes()) {
try {
Object arg = cls.newInstance();
if (arg instanceof EntityBase) {
return (EntityBase) arg;
}
} catch (Exception e) {
}
}
}
if (!ObjectUtils.isEmpty(service.getSuperclass()) && !service.getSuperclass().getName().equals(Object.class.getName())) {
return getEntity(service.getSuperclass());
}
log.error("获取实体信息失败,未能在[{}]中找到参数为实体类对象的行为,如create.update等", service.getSimpleName());
return null;
}
/**
* 获取bpmn md5
*
* @param subFiles
* @return
*/
private String getMd5(List<Resource> subFiles) {
try {
StringBuffer buffer = new StringBuffer();
for (Resource file : subFiles) {
InputStream bpmnFile = null;
try {
bpmnFile = file.getInputStream();
if (!ObjectUtils.isEmpty(bpmnFile)) {
String strBpmn = IOUtils.toString(bpmnFile, "UTF-8");
buffer.append(strBpmn);
}
} catch (Exception e) {
log.error("处理逻辑版本检查失败" + e);
} finally {
if (bpmnFile != null) {
bpmnFile.close();
}
}
}
if (!StringUtils.isEmpty(buffer.toString())) {
return DigestUtils.md5DigestAsHex(buffer.toString().getBytes());
} else {
return null;
}
} catch (Exception e) {
log.error("处理逻辑版本检查失败" + e);
return null;
}
}
/**
* 本地逻辑
*
* @param entity
* @param action
* @param logicExecMode
* @return
*/
private Resource getLocalModel(String entity, String action, LogicExecMode logicExecMode) {
return new ClassPathResource("rules" + File.separator + entity + File.separator + action.toLowerCase() + File.separator + logicExecMode.text + ".bpmn");
}
/**
* 处理逻辑 bpmn
*
* @param logicName
* @return
*/
private Resource getSubBpmn(String logicName) {
return new ClassPathResource(String.format("rules/%s", logicName));
}
/**
* 处理逻辑 drl
*
* @param bpmn
* @return
*/
private Resource getDrl(Resource bpmn) {
String filePath = ((ClassPathResource) bpmn).getPath();
filePath = filePath.endsWith("RuleFlow.bpmn") ? filePath.replace("RuleFlow.bpmn", "Rule.drl") : filePath.replace(".bpmn", ".drl");
return new ClassPathResource(filePath);
}
/**
* 逻辑是否有效
*
* @param bpmn
* @param entity
* @param action
* @return
*/
private boolean isValid(Resource bpmn, Object entity, Object action) {
String logicId = String.format("%s%s%s", getEntityName(entity), action, bpmn.getFilename()).toLowerCase();
if (validLogic.contains(logicId)) {
return true;
} else {
return false;
}
}
static {
{{#each system.entities as | entity | }}
{{#each entity.actions as | action |}}
{{#each action.logics as | logic |}}
validLogic.add("{{logic}}");
{{/each}}
{{/each}}
{{/each}}
}
public enum LogicExecMode {
/**
* 前附加逻辑
*/
BEFORE("0", "before"),
/**
* 后附加逻辑
*/
AFTER("1", "after"),
/**
*
*/
EXEC("2", "exec");
LogicExecMode(String value, String text) {
this.value = value;
this.text = text;
}
private String value;
private String text;
}
}
\ No newline at end of file
package {{packageName}}.util.aspect;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.enums.DupCheck;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.filter.QueryFilter;
import cn.ibizlab.util.filter.SearchContextBase;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.data.domain.Page;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.Map;
/**
* 属性重复值检查切面
*/
@Aspect
@Component
@Slf4j
public class DupCheckAspect {
private final ExpressionParser parser = new SpelExpressionParser();
{{#each system.entities as |entity|}}
{{#if entity.hasDupCheck}}
/**
* 实体[{{entity.codeName}}]
*
* @param point
*/
@AfterReturning(value = "(execution(* {{packageName}}.core.*.service.*{{entity.codeName}}*.create*(..))||execution(* {{packageName}}.core.*.service.*{{entity.codeName}}*.update*(..))||execution(* {{packageName}}.core.*.service.*{{entity.codeName}}*.save*(..)) ) && !execution(* {{packageName}}.core.es.service.*.create*(..)) && !execution(* {{packageName}}.core.es.service.*.update*(..)) && !execution(* {{packageName}}.core.es.service.*.save*(..)) ")
public void check{{pascalCase entity.codeName}}(JoinPoint point) {
check(point, "search{{pascalCase entity.defaultDataQuery.codeName}}");
}
{{/if}}
{{/each}}
/**
* 实体属性重复值检查
* @param point 切点
* @param defaultDS 实体默认数据集名称
*/
private void check(JoinPoint point, String defaultDS) {
Object[] args = point.getArgs();
if (args.length > 0) {
Object entity = args[0];
Object service = point.getTarget();
Map<String, DEField> deFields = DEFieldCacheMap.getDEFields(entity.getClass());
for (Map.Entry<String, DEField> deField : deFields.entrySet()) {
String fieldName = deField.getKey();
DEField fieldAnnotation = deField.getValue();
DupCheck dupCheck = fieldAnnotation.dupCheck();
String dupCheckField=fieldAnnotation.dupCheckField();
if (dupCheck == DupCheck.ALL) {
Object newValue =getDEFieldValue(entity,fieldName);
//获取searchContext
EvaluationContext searchContextCtx = new StandardEvaluationContext();
searchContextCtx.setVariable("service", service);
Expression searchContextExp = parser.parseExpression("#service.getSearchContext()");
SearchContextBase searchContext = searchContextExp.getValue(searchContextCtx, SearchContextBase.class);
//设置检查属性值
QueryFilter filter = new QueryFilter();
setValue(entity, filter, fieldName, newValue);
//设定重复值检查范围
if(!StringUtils.isEmpty(dupCheckField)) {
Object dupFieldValue=getDEFieldValue(entity,dupCheckField);
setValue(entity, filter, dupCheckField, dupFieldValue);
}
searchContext.setFilter(filter);
//使用当前值到数据库中进行查询,判断是否重复
EvaluationContext oldValueMappingCtx = new StandardEvaluationContext();
oldValueMappingCtx.setVariable("service", service);
oldValueMappingCtx.setVariable("searchContext", searchContext);
Expression oldValueMappingExp = parser.parseExpression(String.format("#service.%s(#searchContext)", defaultDS));
Page oldData = oldValueMappingExp.getValue(oldValueMappingCtx, Page.class);
if (!ObjectUtils.isEmpty(oldData) && !ObjectUtils.isEmpty(oldData.getContent()) && oldData.getContent().size() > 1) {
throw new BadRequestAlertException(String.format("数据保存失败,属性[%s]:值[%s]已存在!", fieldName, newValue), "DupCheckAspect", "DupCheck");
}
}
}
}
}
/**
* 获取实体属性值
* @param entity
* @param fieldName
* @return
*/
private Object getDEFieldValue(Object entity, String fieldName) {
EvaluationContext exMappingCtx = new StandardEvaluationContext();
exMappingCtx.setVariable("entity", entity);
Expression esMappingExp = parser.parseExpression(String.format("#entity.get(\"%s\")", fieldName));
return esMappingExp.getValue(exMappingCtx);
}
/**
* 设置filter
* @param entity
* @param filter
* @param value
*/
private void setValue(Object entity , QueryFilter filter, String fieldName, Object value){
if(ObjectUtils.isEmpty(value)) {
filter.isnull(DEFieldCacheMap.getFieldColumnName(entity.getClass(), fieldName));
}
else {
filter.eq(DEFieldCacheMap.getFieldColumnName(entity.getClass(), fieldName), value);
}
}
}
\ No newline at end of file
{{#if system.enableES}}
package {{packageName}}.util.aspect;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.domain.EntityBase;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* es同步数据切面
*/
@Aspect
@Component
@Slf4j
public class ESAspect
{
private final ExpressionParser parser = new SpelExpressionParser();
{{#each system.entities as | entity |}}
{{#if entity.enableES}}
/**
* 实体[{{entity.codeName}}]es切面
* @param point
*/
@AfterReturning(value = "(execution(* {{packageName}}.core.*.service.*{{entity.codeName}}*.create*(..))||execution(* {{packageName}}.core.*.service.*{{entity.codeName}}*.update*(..))||execution(* {{packageName}}.core.*.service.*{{entity.codeName}}*.save*(..)) ||execution(* {{packageName}}.core.*.service.*{{entity.codeName}}*.remove*(..))) && !execution(* {{packageName}}.core.es.service.*.create*(..)) && !execution(* {{packageName}}.core.es.service.*.update*(..)) && !execution(* {{packageName}}.core.es.service.*.save*(..)) && !execution(* {{packageName}}.core.es.service.*.remove*(..))")
@Async
public void Sync{{entity.codeName}}(JoinPoint point) {
syncSaveESData(point,"{{entity.codeName}}");
}
{{/if}}
{{/each}}
/**
* 异步往es中保存数据
* @param point
*/
public void syncSaveESData(JoinPoint point, String deName) {
try {
Object service=point.getTarget();
String action=point.getSignature().getName();
Object [] args = point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0 || StringUtils.isEmpty(action)) {
return;
}
EvaluationContext exServiceCtx = new StandardEvaluationContext();
exServiceCtx.setVariable("service", service);
Expression esServiceExp = parser.parseExpression("#service.getESService()");
Object exService=esServiceExp.getValue(exServiceCtx);
if(ObjectUtils.isEmpty(exService)) {
log.error("获取[{}]实体全文检索服务对象失败",deName);
return;
}
Object arg=args[0];
if ("remove".equals(action) || "removeBatch".equals(action)) {
executeESMethod(exService, action, arg);
}
else if(arg instanceof EntityBase || arg instanceof List) {
EvaluationContext exMappingCtx = new StandardEvaluationContext();
exMappingCtx.setVariable("service", service);
Expression esMappingExp = parser.parseExpression("#service.getESMapping()");
Object exMapping=esMappingExp.getValue(exMappingCtx);
if(ObjectUtils.isEmpty(exMapping)) {
log.error("获取[{}]实体全文检索映射对象失败", deName);
return;
}
EvaluationContext exDomainCtx = new StandardEvaluationContext();
exDomainCtx.setVariable("mapping", exMapping);
exDomainCtx.setVariable("arg", arg);
Expression esDomainExp = parser.parseExpression("#mapping.toESDomain(#arg)");
arg=esDomainExp.getValue(exDomainCtx);
executeESMethod(exService, action, arg);
}
} catch (Exception e) {
log.error("同步[{}]实体全文检索数据失败,{}", deName, e);
}
}
/**
* 执行es方法
* @param exService
* @param action
* @param arg
*/
private void executeESMethod(Object exService, Object action, Object arg) {
EvaluationContext esContext = new StandardEvaluationContext();
esContext.setVariable("exService", exService);
esContext.setVariable("arg", arg);
Expression exExp = parser.parseExpression(String.format("#exService.%s(#arg)", action));
exExp.getValue(esContext);
}
}
{{/if}}
\ No newline at end of file
{{#system.enableMQ}}
package {{packageName}}.util.aspect;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.domain.EntityBase;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Lazy;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* rocketMQ消息切面
*/
@Slf4j
@Aspect
@Component
@ConditionalOnExpression("'${rocketmq.producer.isOnOff:off}'.equals('on')")
public class RocketMQAspect
{
private final ExpressionParser parser = new SpelExpressionParser();
@Autowired
@Lazy
DefaultMQProducer defaultMQProducer;
@Value("${rocketmq.producer.topic:default}")
private String topic;
{{#each system.entities as | entity | }}
{{#each entity.mqPublishers}}
@Around(value = "{{#each monitors as | monitor |}}{{#unless @first}} || {{/unless}}execution(* {{packageName}}.core.{{entity.module}}.service.{{entity.codeName}}Service.{{monitor}}*(..)){{/each}}")
public Object {{camelCase entity.codeName}}{{pascalCase dataSync.codeName}}(ProceedingJoinPoint point) throws Throwable{
Object entity = getEntity(point);
Object result = point.proceed();
{{#if dataSync.outTestPSDEAction}}
outputAction(point, "{{camelCase dataSync.outTestPSDEAction.codeName}}", entity);
{{/if}}
sendMsg(topic, "{{lowerCase dataSync.codeName}}", entity);
return result;
}
{{/each}}
{{/each}}
/**
* 输出过滤行为
* @param point
* @param actionName
* @param entity
*/
private void outputAction(JoinPoint point, String actionName, Object entity) {
Object[] args = point.getArgs();
if (ObjectUtils.isEmpty(args) || args.length == 0 || ObjectUtils.isEmpty(entity)) {
return;
}
Object service = point.getTarget();
EvaluationContext serviceCtx = new StandardEvaluationContext();
serviceCtx.setVariable("service", service);
serviceCtx.setVariable("arg", entity);
Expression serviceExp = parser.parseExpression(String.format("#service.%s(#arg)", actionName));
serviceExp.getValue(serviceCtx);
}
/**
* 获取实体对象
*
* @param point
* @return
*/
private Object getEntity(ProceedingJoinPoint point) {
Object entity = null;
try {
String action = point.getSignature().getName();
Object[] args = point.getArgs();
Object serviceObj = point.getTarget();
if (ObjectUtils.isEmpty(args) || args.length == 0 || StringUtils.isEmpty(action)) {
return entity;
}
if ("remove".equalsIgnoreCase(action)) {
Object idValue = args[0];
if (!ObjectUtils.isEmpty(serviceObj)) {
EvaluationContext oldContext = new StandardEvaluationContext();
oldContext.setVariable("service", serviceObj);
oldContext.setVariable("id", idValue);
Expression oldExp = parser.parseExpression("#service.get(#id)");
entity = oldExp.getValue(oldContext, EntityBase.class);
}
} else {
entity = args[0];
}
} catch (Exception e) {
log.error("发送消息失败,无法获取实体对象" + e);
}
return entity;
}
/**
* 发送消息
*
* @param topic
* @param tag
* @param body
*/
private void sendMsg(String topic, String tag, Object body) {
if (ObjectUtils.isEmpty(body)) {
log.error("消息内容为空,[{}]消息将被忽略!", tag);
return;
}
try {
Message message = new Message(topic, tag, JSON.toJSONString(body).getBytes());
SendResult sendResult = defaultMQProducer.send(message);
log.info("消息发送响应:" + sendResult.toString());
} catch (Exception e) {
log.error("消息发送异常," + e);
}
}
}
{{/system.enableMQ}}
\ No newline at end of file
package {{packageName}}.util.aspect;
import lombok.SneakyThrows;
import cn.ibizlab.util.annotation.VersionCheck;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.RuleUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
/**
* 数据库版本检查
*/
@Aspect
@Order(50)
@Component
public class VersionCheckAspect
{
private final ExpressionParser parser = new SpelExpressionParser();
private final String IgnoreField = "ignoreversioncheck";
@SneakyThrows
@Before("execution(* {{packageName}}.*.rest.*.update(..)) && @annotation(versionCheck)")
public void BeforeUpdate(JoinPoint point, VersionCheck versionCheck) {
Object[] args = point.getArgs();
Object id = args[0];
Object dto = args[1];
if(ObjectUtils.isEmpty(id) || ObjectUtils.isEmpty(dto)) {
return;
}
String versionField = versionCheck.versionfield();
if(StringUtils.isEmpty(versionField)) {
return;
}
versionCheck(versionCheck,point.getTarget(), dto, id);
}
@SneakyThrows
@Before("execution(* {{packageName}}.*.rest.*.updateBy*(..)) && @annotation(versionCheck)")
public void BeforeUpdateBy(JoinPoint point, VersionCheck versionCheck) {
Object[] args = point.getArgs();
if(args.length>=2) {
Object id = args[args.length-2];
Object dto = args[args.length-1];
if(ObjectUtils.isEmpty(id) || ObjectUtils.isEmpty(dto)) {
return;
}
String versionField = versionCheck.versionfield();
if(StringUtils.isEmpty(versionField)) {
return;
}
versionCheck(versionCheck, point.getTarget(), dto, id);
}
}
private void versionCheck(VersionCheck versionCheck, Object resource, Object dto, Object id) {
EvaluationContext context = new StandardEvaluationContext();
context.setVariable("dto", dto);
//忽略版本检查
Expression dtoParamsExp = parser.parseExpression("#dto.extensionparams");
Map dtoParam = dtoParamsExp.getValue(context, Map.class);
if(!ObjectUtils.isEmpty(dtoParam) && !ObjectUtils.isEmpty(dtoParam.get(IgnoreField)) && dtoParam.get(IgnoreField).equals(1)) {
return;
}
Expression newExp = parser.parseExpression(String.format("#dto.%s", versionCheck.versionfield()));
Object newVersion = newExp.getValue(context);
if(ObjectUtils.isEmpty(newVersion)) {
return;
}
//进行版本检查
Object oldVersion = getDBVersion(versionCheck,getService(resource, versionCheck.entity()), id);
if(!ObjectUtils.isEmpty(oldVersion)) {
if(RuleUtils.gt(newVersion, oldVersion)) {
throw new BadRequestAlertException("数据已变更,可能后台数据已被修改,请重新加载数据", "VersionCheckAspect", "versionCheck");
}
}
}
/**
* 获取实体服务对象
* @param resource
* @param entity
* @return
*/
@SneakyThrows
private Object getService(Object resource, String entity) {
Object service = null;
Field[] fields = resource.getClass().getDeclaredFields();
for(Field field : fields) {
if(field.getModifiers()==1 && field.getName().equalsIgnoreCase(String.format("%sService",entity))) {
service = field.get(resource);
break;
}
}
return service;
}
/**
* 获取数据库版本
* @param versionCheck
* @param service
* @param id
* @return
*/
@SneakyThrows
private Object getDBVersion(VersionCheck versionCheck, Object service, Object id) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Timestamp dbVersion = null;
String versionField = versionCheck.versionfield();
if(!ObjectUtils.isEmpty(service)) {
EvaluationContext oldContext = new StandardEvaluationContext();
oldContext.setVariable("service", service);
oldContext.setVariable("id", id);
Expression oldExp = parser.parseExpression("#service.get(#id)");
EntityBase oldEntity = oldExp.getValue(oldContext, EntityBase.class);
Object oldDate = oldEntity.get(versionField);
if(oldDate!=null && oldDate instanceof Timestamp) {
Timestamp db_time = (Timestamp) oldDate;
Date db_date = sdf.parse(sdf.format(db_time));
dbVersion = new Timestamp(db_date.getTime());
}
}
return dbVersion;
}
}
package {{packageName}}.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}}.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}}.util.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Configuration;
import com.baomidou.jobs.starter.EnableJobs;
@EnableJobs
@Configuration
@ConditionalOnExpression("!'${jobs.admin-address:NA}'.equals('NA')")
public class JobConfig {
}
package {{packageName}}.util.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
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
@ConditionalOnProperty( name = "spring.datasource.isSyncDBSchema", havingValue = "true")
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}}.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}}.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}}.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}}.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}}.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 org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
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;
}
}
\ No newline at end of file
{{#system.enableMQ}}
package {{packageName}}.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;
}
}
{{/system.enableMQ}}
\ No newline at end of file
{{#system.enableMQ}}
package {{packageName}}.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.{{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 = JSON.parseObject(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;
}
}
{{/system.enableMQ}}
\ No newline at end of file
{{#system.enableMQ}}
package {{packageName}}.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;
}
}
{{/system.enableMQ}}
\ No newline at end of file
{{#eq system.saaSMode 4}}
package {{packageName}}.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}}.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}}.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
package {{packageName}}.util.job;
import cn.ibizlab.util.client.IBZUAAFeignClient;
import cn.ibizlab.util.client.IBZLiteFeignClient;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONArray;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
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.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.DigestUtils;
import java.io.InputStream;
import java.util.*;
/**
* 权限:向uaa同步当前系统菜单、权限资源任务类
*/
@Slf4j
@Component
@ConditionalOnProperty( name = "ibiz.enablePermissionValid", havingValue = "true")
public class PermissionSyncJob implements ApplicationRunner {
@Value("${ibiz.systemid}")
private String systemId;
@Value("${ibiz.systemname}")
private String systemName;
@Autowired
@Lazy
private IBZUAAFeignClient uaaClient;
@Autowired
@Lazy
IBZLiteFeignClient liteClient;
{{#if system.enableWorkflow}}
@Autowired
@Lazy
private cn.ibizlab.util.client.IBZWFFeignClient wfClient;
{{/if}}
{{#if system.hasMsgTemplate}}
@Autowired
@Lazy
private cn.ibizlab.util.client.IBZNotifyFeignClient notifyClient;
{{/if}}
{{#if system.hasRuntimeDict}}
@Autowired
@Lazy
cn.ibizlab.util.client.IBZDictFeignClient dictClient;
{{/if}}
@Override
public void run(ApplicationArguments args) {
try {
Thread.sleep(10000);
InputStream permission = this.getClass().getResourceAsStream("/permission/systemResource.json"); //权限资源
if (!ObjectUtils.isEmpty(permission)) {
String strPermission = IOUtils.toString(permission, "UTF-8");
JSONObject system = new JSONObject();
system.put("pssystemid", StringUtils.isEmpty(systemId)?"{{system.codeName}}":systemId);
system.put("pssystemname", StringUtils.isEmpty(systemName)?"{{system.logicName}}":systemName);
system.put("sysstructure", JSONObject.parseObject(strPermission));
system.put("md5check", DigestUtils.md5DigestAsHex(strPermission.getBytes()));
if (uaaClient.syncSysAuthority(system)) {
log.info("向[uaa]同步系统资源成功");
} else {
log.error("向[uaa]同步系统资源失败");
}
}
} catch (Exception ex) {
log.error("向[uaa]同步系统资源失败,请检查[uaa]服务是否正常运行! {}", ex.getMessage());
}
try {
InputStream model = this.getClass().getResourceAsStream("/sysmodel/{{system.codeName}}.json"); //系统模型
if (!ObjectUtils.isEmpty(model)) {
String strModel = IOUtils.toString(model, "UTF-8");
if (liteClient.syncSysModel(JSONObject.parseObject(strModel))) {
log.info("向[lite]同步模型成功");
} else {
log.error("向[lite]同步模型失败");
}
}
} catch (Exception ex) {
log.error("向[lite]同步系统模型失败,请检查[lite]服务是否正常运行! {}", ex.getMessage());
}
{{#if system.enableWorkflow}}
try {
List<Map<String, Object>> workflows = new ArrayList(); //工作流
{{#each system.allPSWorkflows as |wf|}}
{{#each wf.psWFVersions as |wfvs|}}
if (!ObjectUtils.isEmpty(this.getClass().getResourceAsStream("/workflow/{{wfvs.codeName}}.bpmn"))) {
Map<String, Object> map=new HashMap<String, Object>();
map.put("{{wfvs.codeName}}.bpmn", IOUtils.toString(this.getClass().getResourceAsStream("/workflow/{{wfvs.codeName}}.bpmn"), "UTF-8"));
workflows.add(map);
}
{{/each}}
{{/each}}
if (workflows.size() > 0) {
if (wfClient.deployBpmnFile(workflows)) {
log.info("向[wf]部署流程成功");
} else {
log.error("向[wf]部署流程失败");
}
}
} catch (Exception ex) {
log.error("向[wf]部署流程失败,请检查[wf]服务是否正常运行! {}", ex.getMessage());
}
{{/if}}
{{#if system.hasMsgTemplate}}
try {
InputStream template = this.getClass().getResourceAsStream("/msgtempl/systemMsgTempl.json"); //消息模板
if (!ObjectUtils.isEmpty(template)) {
String strTemplate = IOUtils.toString(template, "UTF-8");
JSONObject arg=new JSONObject();
arg.put("template", JSONArray.parseArray(strTemplate));
if (notifyClient.createMsgTemplate(arg)) {
log.info("向[notify]同步消息模板成功");
} else {
log.error("向[notify]同步消息模板失败");
}
}
} catch (Exception ex) {
log.error("向[notify]同步消息模板失败,请检查[notify]服务是否正常运行! {}", ex.getMessage());
}
{{/if}}
{{#if system.hasRuntimeDict}}
try {
InputStream dict = this.getClass().getResourceAsStream("/sysmodel/RuntimeDict.json"); //代码表
if (!ObjectUtils.isEmpty(dict)) {
String strDict = IOUtils.toString(dict, "UTF-8");
if (dictClient.syncRuntimeDict(JSONArray.parseArray(strDict))) {
log.info("向[dict]同步代码表成功");
} else {
log.error("向[dict]同步代码表失败");
}
}
} catch (Exception ex) {
log.error("向[dict]同步代码表失败,请检查[dict]服务是否正常运行! {}", ex.getMessage());
}
{{/if}}
}
}
\ No newline at end of file
package {{packageName}}.util.security;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.SneakyThrows;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.enums.DEPredefinedFieldType;
import cn.ibizlab.util.filter.QueryWrapperContext;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.security.AuthenticationUser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.Consumer;
/**
* spring security 权限管理类
* 重写权限控制方法
*/
@Component
public class AuthPermissionEvaluator implements PermissionEvaluator {
@Value("${ibiz.enablePermissionValid:false}")
boolean enablePermissionValid; //是否开启权限校验
/**
* 服务接口鉴权
* @param authentication 用户
* @param entity 实体
* @param action 操作
* @return
*/
@Override
@SneakyThrows
public boolean hasPermission(Authentication authentication, Object entity, Object action) {
if(!enablePermissionValid){
return true;
}
Object principal = authentication.getPrincipal();
if(ObjectUtils.isEmpty(principal)){
return false;
}
AuthenticationUser authenticationUser= (AuthenticationUser) authentication.getPrincipal();
if(authenticationUser.getSuperuser()==1){
return true;
}
String strAction=String.valueOf(action);
Set<String> userAuthorities = getAuthorities(authentication,strAction);
if(userAuthorities.size()==0){
return false;
}
if(isAllData(strAction,userAuthorities)){
return true;
}
if(entity instanceof ArrayList){
List<EntityBase> entities= (List<EntityBase>) entity;
for(EntityBase entityBase: entities){
boolean result=actionValid(entityBase, strAction ,userAuthorities,authenticationUser);
if(!result){
return false;
}
}
}
else if (entity instanceof QueryWrapperContext){
QueryWrapperContext queryWrapperContext= (QueryWrapperContext) entity;
setPermissionCondToSearchContext(getEntity(queryWrapperContext),queryWrapperContext,userAuthorities,authenticationUser);
}
else{
EntityBase entityBase= (EntityBase) entity;
return actionValid(entityBase , strAction ,userAuthorities,authenticationUser);
}
return true;
}
/**
* 获取实体信息
* @param qc
* @return
*/
@SneakyThrows
private EntityBase getEntity(QueryWrapperContext qc){
EntityBase entity=null;
Type type =qc.getClass().getGenericSuperclass();
if(type instanceof ParameterizedType){
ParameterizedType parameterizedType= (ParameterizedType) qc.getClass().getGenericSuperclass();
Type [] typeArr= parameterizedType.getActualTypeArguments();
if(typeArr.length>0){
Class<EntityBase> entityClass = (Class) typeArr[0];
return entityClass.newInstance();
}
}
return entity;
}
/**
* 在searchContext中拼接权限条件
* @param entity 实体
* @param qc 查询上下文
* @param userAuthorities 用户权限
* @param authenticationUser 当前用户
*/
@SneakyThrows
private void setPermissionCondToSearchContext(EntityBase entity, QueryWrapperContext qc , Set<String> userAuthorities ,AuthenticationUser authenticationUser){
if(entity==null){
return ;
}
Map<String,String> permissionField=getPermissionField(entity);//获取组织、部门预置属性
String orgField=permissionField.get("orgfield");
String orgDeptField=permissionField.get("orgsecfield");
String createManField=permissionField.get("createmanfield");
Map<String, Set<String>> userInfo = authenticationUser.getOrgInfo();
Set<String> orgParent = userInfo.get("parentorg");
Set<String> orgChild = userInfo.get("suborg");
Set<String> orgDeptParent = userInfo.get("parentdept");
Set<String> orgDeptChild = userInfo.get("subdept");
Set<String> userOrg = new HashSet<>();
Set<String> userOrgDept = new HashSet<>();
Set<String> userCreateMan = new HashSet<>();
for(String authority:userAuthorities){
if(authority.endsWith("curorg")){ //本单位
userOrg.add(authenticationUser.getOrgid());
}
else if(authority.endsWith("porg")){//上级单位
userOrg.addAll(orgParent);
}
else if(authority.endsWith("sorg")){//下级单位
userOrg.addAll(orgChild);
}
else if(authority.endsWith("curorgdept")){//本部门
userOrgDept.add(authenticationUser.getMdeptid());
}
else if(authority.endsWith("porgdept")){//上级部门
userOrgDept.addAll(orgDeptParent);
}
else if(authority.endsWith("sorgdept")){//下级部门
userOrgDept.addAll(orgDeptChild);
}
else if (authority.endsWith("createman")){
userCreateMan.add(authority);
}
}
if(userOrg.size()==0 && userOrgDept.size()==0 && userCreateMan.size()==0){
qc.getSelectCond().apply("1<>1");
}
else{
Consumer<QueryWrapper> consumer = qw -> {
if(userOrg.size()>0){
Consumer<QueryWrapper> org = orgQw -> {
orgQw.in(orgField,userOrg);
};
qw.or(org);
}
if(userOrgDept.size()>0){
Consumer<QueryWrapper> dept = deptQw -> {
deptQw.in(orgDeptField,userOrgDept);
};
qw.or(dept);
}
if(userCreateMan.size()>0){
Consumer<QueryWrapper> createMan = createManQw -> {
createManQw.eq(createManField,authenticationUser.getUserid());
};
qw.or(createMan);
}
};
qc.getSelectCond().and(consumer);
}
}
@Override
public boolean hasPermission(Authentication authentication, Serializable id, String action, Object params) {
return true;
}
/**
* 获取用户权限资源
* @param authentication
* @param action
* @return
*/
private Set<String> getAuthorities(Authentication authentication , String action){
Collection authorities=authentication.getAuthorities();
Set<String> userAuthorities = new HashSet();
Iterator it = authorities.iterator();
while(it.hasNext()) {
GrantedAuthority authority = (GrantedAuthority)it.next();
if(authority.getAuthority().contains(action)){
userAuthorities.add(authority.getAuthority());
}
}
return userAuthorities;
}
/**
* 是否为全部数据
* @param action
* @param entityDataRange
* @return
*/
private boolean isAllData(String action , Set<String> entityDataRange) {
for(String dataRange : entityDataRange ){
if(dataRange.endsWith(String.format("%s-all",action))){
return true;
}
}
return false;
}
/**
* 实体行为权限校验
* @param entity
* @param userAuthorities
* @return
*/
private boolean actionValid(EntityBase entity, String action , Set<String> userAuthorities ,AuthenticationUser authenticationUser){
Map<String,String> permissionField=getPermissionField(entity);//获取组织、部门预置属性
String orgField=permissionField.get("orgfield");
String orgDeptField=permissionField.get("orgsecfield");
String createManField=permissionField.get("createmanfield");
Map<String, Set<String>> userInfo = authenticationUser.getOrgInfo();
Set<String> orgParent = userInfo.get("parentorg");
Set<String> orgChild = userInfo.get("suborg");
Set<String> orgDeptParent = userInfo.get("parentdept");
Set<String> orgDeptChild = userInfo.get("subdept");
Object orgFieldValue=entity.get(orgField);
Object orgDeptFieldValue=entity.get(orgDeptField);
Object crateManFieldValue=entity.get(createManField);
Set<String> userOrg = new HashSet<>();
Set<String> userOrgDept = new HashSet<>();
for(String authority:userAuthorities){
if(authority.endsWith("curorg")){ //本单位
userOrg.add(authenticationUser.getOrgid());
}
else if(authority.endsWith("porg")){//上级单位
userOrg.addAll(orgParent);
}
else if(authority.endsWith("sorg")){//下级单位
userOrg.addAll(orgChild);
}
else if(authority.endsWith("curorgdept")){//本部门
userOrgDept.add(authenticationUser.getMdeptid());
}
else if(authority.endsWith("porgdept")){//上级部门
userOrgDept.addAll(orgDeptParent);
}
else if(authority.endsWith("sorgdept")){//下级部门
userOrgDept.addAll(orgDeptChild);
}
}
if(action.endsWith("Create") || action.endsWith("Save")){
if(!ObjectUtils.isEmpty(orgFieldValue) && !userOrg.contains(orgFieldValue)){
return false;
}
if(!ObjectUtils.isEmpty(orgDeptFieldValue) && !userOrgDept.contains(orgDeptFieldValue)){
return false;
}
if(!ObjectUtils.isEmpty(crateManFieldValue) && !authenticationUser.getUserid().equals(crateManFieldValue)){
return false;
}
return true;
}
else{
if(!ObjectUtils.isEmpty(orgFieldValue) && userOrg.contains(orgFieldValue)){
return true;
}
if(!ObjectUtils.isEmpty(orgDeptFieldValue) && userOrgDept.contains(orgDeptFieldValue)){
return true;
}
if(!ObjectUtils.isEmpty(crateManFieldValue) && authenticationUser.getUserid().equals(crateManFieldValue)){
return true;
}
return false;
}
}
/**
* 获取实体权限字段 orgid/orgsecid
* @param entityBase
* @return
*/
private Map<String,String> getPermissionField(EntityBase entityBase){
Map<String,String> permissionFiled=new HashMap<>();
String orgField="orgid"; //组织属性
String orgDeptField="orgsectorid"; //部门属性
String createManField="createman"; //创建人属性
DEFieldCacheMap.getFieldMap(entityBase.getClass().getName());
Map <String, DEField> preFields= DEFieldCacheMap.getDEFields(entityBase.getClass()); //从缓存中获取当前类预置属性
for (Map.Entry<String,DEField> entry : preFields.entrySet()){
DEField fieldAnnotation=entry.getValue();//获取注解值
String fieldName=fieldAnnotation.name();//获取注解字段
DEPredefinedFieldType prefieldType=fieldAnnotation.preType();
if(!StringUtils.isEmpty(fieldName)){
//用户配置系统预置属性-组织机构标识
if(prefieldType==prefieldType.ORGID){
orgField=fieldName;
}
//用户配置系统预置属性-部门标识
if(prefieldType==prefieldType.ORGSECTORID){
orgDeptField=fieldName;
}
//用户配置系统预置属性-部门标识
if(prefieldType==prefieldType.CREATEMAN){
createManField=fieldName;
}
}
}
permissionFiled.put("orgfield",orgField);
permissionFiled.put("orgsecfield",orgDeptField);
permissionFiled.put("createmanfield",createManField);
return permissionFiled;
}
}
\ No newline at end of file
{{#unless apiDto.apiEntity.subSysDE}}
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.*;
import lombok.experimental.Accessors;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 服务DTO对象[{{apiDto.codeName}}]
*/
@Getter
@Setter
@NoArgsConstructor
@ApiModel("{{apiDto.logicName}}")
public class {{apiDto.codeName}} extends {{#eq apiDto.apiEntity.entity.psSubSysServiceAPI.serviceType "MIDDLEPLATFORM"}}DTOClient{{else}}DTOBase{{/eq}} implements Serializable {
private static final long serialVersionUID = 1L;
{{#each apiDto.apiDtoFields}}
/**
* {{logicName}}
*/
@JsonProperty("{{jsonName}}")
{{#timeType}}
@JsonFormat(pattern = "{{format}}", locale = "zh", timezone = "GMT+8")
{{/timeType}}
@JSONField(name = "{{jsonName}}"{{#timeType}} , format = "{{format}}"{{/timeType}})
{{#eq javaType "Long"}}
@JsonSerialize(using = ToStringSerializer.class)
{{/eq}}
@ApiModelProperty("{{logicName}}")
private {{javaType}} {{camelCase codeName}};
{{/each}}
{{#each apiDto.apiDtoFields}}
{{#unless keyDEField}}
{{#unless predefinedType}}
/**
* 设置 [{{logicName}}]
*/
public {{apiDto.codeName}} set{{pascalCase codeName}}({{javaType}} {{camelCase codeName}}) {
this.{{camelCase codeName}} = {{camelCase codeName}};
this.modify("{{lowerCase name}}", {{camelCase codeName}});
return this;
}
{{/unless}}
{{/unless}}
{{/each}}
}
{{/unless}}
\ No newline at end of file
{{#eq apiEntity.codeName ""}}
{{#unless apiEntity.subSysDE}}
package {{packageName}}.{{lowerCase apiEntity.api.codeName}}.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.*;
import lombok.experimental.Accessors;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
* 服务DTO对象[{{apiEntity.codeName}}DTO]
*/
@Getter
@Setter
@NoArgsConstructor
@ApiModel("{{apiEntity.logicName}}")
public class {{apiEntity.codeName}}DTO extends {{#eq apiEntity.entity.psSubSysServiceAPI.serviceType "MIDDLEPLATFORM"}}DTOClient{{else}}DTOBase{{/eq}} implements Serializable {
private static final long serialVersionUID = 1L;
{{#each apiEntity.properties}}
{{#unless deepStructure}}
/**
* {{logicName}}
*/
@JsonProperty("{{jsonName}}")
{{#timeType}}
@JsonFormat(pattern = "{{format}}", locale = "zh", timezone = "GMT+8")
{{/timeType}}
@JSONField(name = "{{jsonName}}"{{#timeType}} , format = "{{format}}"{{/timeType}})
{{#eq type.java "Long"}}
@JsonSerialize(using = ToStringSerializer.class)
{{/eq}}
@ApiModelProperty("{{logicName}}")
private {{type.java}} {{camelCase codeName}};
{{/unless}}
{{/each}}
{{#each apiEntity.entity.nesteds}}
/**
* {{entityLogicName}}
*/
@JSONField(name = "{{pluralize codeName}}")
@JsonProperty("{{pluralize codeName}}")
private List<{{packageName}}.core.{{module}}.domain.{{entityCodeName}}> {{camelCase codeName}};
{{/each}}
{{#each apiEntity.properties}}
{{#unless deepStructure}}
{{#unless keyDEField}}
{{#unless predefinedType}}
/**
* 设置 [{{logicName}}]
*/
public {{apiEntity.codeName}}DTO set{{pascalCase codeName}}({{type.java}} {{camelCase codeName}}) {
this.{{camelCase codeName}} = {{camelCase codeName}};
this.modify("{{lowerCase name}}", {{camelCase codeName}});
return this;
}
{{/unless}}
{{/unless}}
{{/unless}}
{{/each}}
{{#apiEntity.entity.nesteds}}
{{#columnName}}
/**
* 设置 [{{entityLogicName}}]
*/
public {{apiEntity.codeName}}DTO set{{pascalCase codeName}}(List<{{packageName}}.core.{{module}}.domain.{{entityCodeName}}> {{camelCase codeName}}) {
this.{{camelCase codeName}} = {{camelCase codeName}};
this.modify("{{columnName}}", ({{camelCase codeName}}!=null)?{{camelCase codeName}}:(new ArrayList()));
return this;
}
{{/columnName}}
{{/apiEntity.entity.nesteds}}
}
{{/unless}}
{{/eq}}
\ No newline at end of file
{{#unless apiDto.apiEntity.subSysDE}}
package {{packageName}}.{{apis}}.mapping;
{{#with apiDto.apiEntity.entity as | entity | }}
import org.mapstruct.*;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.{{apis}}.dto.{{apiDto.codeName}};
import cn.ibizlab.util.domain.MappingBase;
@Mapper(componentModel = "spring", uses = {}, implementationName = "{{apiDto.apiEntity.api.codeName}}{{apiDto.codeName}}Mapping",
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public interface {{apiDto.codeName}}Mapping extends MappingBase<{{apiDto.codeName}}, {{entity.codeName}}> {
}
{{/with}}
{{/unless}}
\ No newline at end of file
{{#eq apiEntity.codeName ""}}
{{#unless apiEntity.subSysDE}}
package {{packageName}}.{{lowerCase apiEntity.api.codeName}}.mapping;
{{#with apiEntity.entity as | entity | }}
import org.mapstruct.*;
import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.{{lowerCase apiEntity.api.codeName}}.dto.{{apiEntity.codeName}}DTO;
import cn.ibizlab.util.domain.MappingBase;
@Mapper(componentModel = "spring", uses = {}, implementationName = "{{apiEntity.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}}
{{/eq}}
\ No newline at end of file
{{#neq apiEntity.entity.storage "NONE"}}
package {{packageName}}.{{lowerCase apiEntity.api.codeName}}.rest;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.math.BigInteger;
import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.ServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.validation.annotation.Validated;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import {{packageName}}.{{lowerCase apiEntity.api.codeName}}.dto.*;
import {{packageName}}.{{lowerCase apiEntity.api.codeName}}.mapping.*;
import {{packageName}}.core.{{apiEntity.entity.module}}.domain.{{apiEntity.entity.codeName}};
import {{packageName}}.core.{{apiEntity.entity.module}}.service.{{apiEntity.entity.codeName}}Service;
import {{packageName}}.core.{{apiEntity.entity.module}}.filter.{{apiEntity.entity.codeName}}SearchContext;
import cn.ibizlab.util.annotation.VersionCheck;
@Slf4j
@Api(tags = {"{{apiEntity.apiName}}" })
@RestController("{{lowerCase apiEntity.api.codeName}}-{{lowerCase apiEntity.codeName}}")
@RequestMapping("/{{lowerCase apiEntity.api.codeName}}")
public class {{apiEntity.codeName}}Resource {
@Autowired
public {{apiEntity.entity.codeName}}Service {{camelCase apiEntity.entity.codeName}}Service;
{{#each apiEntity.dtos}}
{{#eq type "DEFAULT"}}
@Autowired
@Lazy
public {{codeName}}Mapping {{camelCase codeName}}Mapping;
{{/eq}}
{{/each}}
{{#each apiEntity.methods}}
{{#neq name "Select"}}
@ApiOperation(value = "{{apiName}}", tags = {"{{tags}}" }, notes = "{{notes}}")
@RequestMapping(method = RequestMethod.{{requestMethod}}, value = "{{requestPath}}")
public ResponseEntity<{{outParam}}> {{camelCase name}}{{#each pathVariables}}{{#if @first}}By{{else}}And{{/if}}{{pascalCase name}}{{/each}}
({{#each pathVariables}}{{#unless @first}}, {{/unless}}@PathVariable("{{camelCase name}}") {{type.java}} {{camelCase name}}{{/each}}{{#if body}}{{#if pathVariables}}, {{/if}}{{#neq requestMethod 'GET'}}@Validated @RequestBody {{/neq}}{{body}}{{/if}}) {
{{!行为}}
{{#eq methodType "DEACTION"}}
{{#if needDto2Domain}}
{{inParam2}} {{inParamName2}} = {{camelCase inputDTO.name}}Mapping.toDomain({{inParamName}});
{{#if listIn}}
{{#if pathVariables}}
{{inParamName2}}.forEach(item -> {
{{#each pathVariables}}{{#if @last}}
item.set{{pascalCase name}}({{camelCase name}});
{{/if}}{{/each}}
});
{{/if}}
{{else}}
{{#each pathVariables}}{{#if @last}}
{{inParamName2}}.set{{pascalCase name}}({{camelCase name}});
{{/if}}{{/each}}
{{/if}}
{{/if}}
{{#if booleanReturn}}
{{camelCase apiEntity.entity.codeName}}Service.{{camelCase name}}({{inParamName2}});
{{outParam2}} rt = {{inParamName2}};
{{else}}
{{outParam2}} rt = {{camelCase apiEntity.entity.codeName}}Service.{{camelCase name}}({{inParamName2}});
{{/if}}
{{#if needDomain2Dto}}
return ResponseEntity.status(HttpStatus.OK).body({{camelCase returnDTO.name}}Mapping.toDto(rt));
{{else}}
return ResponseEntity.status(HttpStatus.OK).body(rt);
{{/if}}
{{/eq}}
{{!数据集}}
{{#eq methodType "FETCH"}}
{{#each pathVariables}}
{{#if @last}}
{{inParamName}}.set{{pascalCase name}}EQ({{camelCase name}});
{{/if}}
{{/each}}
Page<{{apiEntity.entity.codeName}}> domains = {{camelCase apiEntity.entity.codeName}}Service.search{{pascalCase pSDEDataSet.codeName}}({{inParamName}}) ;
{{outParam}} list = {{camelCase returnDTO.name}}Mapping.toDto(domains.getContent());
return ResponseEntity.status(HttpStatus.OK)
.header("x-page", String.valueOf({{inParamName}}.getPageable().getPageNumber()))
.header("x-per-page", String.valueOf({{inParamName}}.getPageable().getPageSize()))
.header("x-total", String.valueOf(domains.getTotalElements()))
.body(list);
{{/eq}}
}
{{/neq}}
{{/each}}
}
{{/neq}}
\ No newline at end of file
{{#eq apiEntity.code ""}}
{{#if apiEntity.major}}
{{#neq apiEntity.entity.storage "NONE"}}
package {{packageName}}.{{lowerCase apiEntity.api.codeName}}.rest;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.math.BigInteger;
import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
import com.alibaba.fastjson.JSONObject;
import javax.servlet.ServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.HttpStatus;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.validation.annotation.Validated;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import {{packageName}}.{{lowerCase apiEntity.api.codeName}}.dto.*;
import {{packageName}}.{{lowerCase apiEntity.api.codeName}}.mapping.*;
import {{packageName}}.core.{{apiEntity.entity.module}}.domain.{{apiEntity.entity.codeName}};
import {{packageName}}.core.{{apiEntity.entity.module}}.service.{{apiEntity.entity.codeName}}Service;
import {{packageName}}.core.{{apiEntity.entity.module}}.filter.{{apiEntity.entity.codeName}}SearchContext;
import cn.ibizlab.util.annotation.VersionCheck;
@Slf4j
@Api(tags = {"{{apiEntity.entity.logicName}}" })
@RestController("{{lowerCase apiEntity.api.codeName}}-{{lowerCase apiEntity.codeName}}")
@RequestMapping("")
public class {{apiEntity.codeName}}Resource {
@Autowired
public {{apiEntity.entity.codeName}}Service service;
@Autowired
@Lazy
public {{apiEntity.codeName}}Mapping mapping;
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Create-all')")
@ApiOperation(value = "新建{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "新建{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.POST, value = "/{{pluralize apiEntity.codeName}}")
public ResponseEntity<{{apiEntity.codeName}}DTO> create(@Validated @RequestBody {{apiEntity.codeName}}DTO dto) {
{{apiEntity.entity.codeName}} domain = mapping.toDomain(dto);
service.create(domain);
return ResponseEntity.status(HttpStatus.OK).body(mapping.toDto(domain));
}
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Create-all')")
@ApiOperation(value = "批量新建{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "批量新建{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.POST, value = "/{{pluralize apiEntity.codeName}}/batch")
public ResponseEntity<Boolean> createBatch(@RequestBody List<{{apiEntity.codeName}}DTO> dtos) {
service.createBatch(mapping.toDomain(dtos));
return ResponseEntity.status(HttpStatus.OK).body(true);
}
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Get-all')")
@ApiOperation(value = "获取{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "获取{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.GET, value = "/{{pluralize apiEntity.codeName}}/{id}")
public ResponseEntity<{{apiEntity.codeName}}DTO> get(@PathVariable("id") {{apiEntity.entity.keyField.type.java}} id) {
{{apiEntity.entity.codeName}} domain = service.get(id);
{{apiEntity.codeName}}DTO dto = mapping.toDto(domain);
return ResponseEntity.status(HttpStatus.OK).body(dto);
}
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Remove-all')")
@ApiOperation(value = "删除{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "删除{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.DELETE, value = "/{{pluralize apiEntity.codeName}}/{id}")
public ResponseEntity<Boolean> remove(@PathVariable("id") {{apiEntity.entity.keyField.type.java}} id) {
return ResponseEntity.status(HttpStatus.OK).body(service.remove(id));
}
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Remove-all')")
@ApiOperation(value = "批量删除{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "批量删除{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.DELETE, value = "/{{pluralize apiEntity.codeName}}/batch")
public ResponseEntity<Boolean> removeBatch(@RequestBody List<{{apiEntity.entity.keyField.type.java}}> ids) {
service.removeBatch(ids);
return ResponseEntity.status(HttpStatus.OK).body(true);
}
{{#if apiEntity.entity.lastModifyField}}
@VersionCheck(entity = "{{lowerCase apiEntity.entity.codeName}}" , versionfield = "{{camelCase apiEntity.entity.lastModifyField.codeName}}")
{{/if}}
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Update-all')")
@ApiOperation(value = "更新{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "更新{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.PUT, value = "/{{pluralize apiEntity.codeName}}/{id}")
public ResponseEntity<{{apiEntity.codeName}}DTO> update(@PathVariable("id") {{apiEntity.entity.keyField.type.java}} id, @RequestBody {{apiEntity.codeName}}DTO dto) {
{{apiEntity.entity.codeName}} domain = mapping.toDomain(dto);
domain.set{{pascalCase apiEntity.entity.keyField.codeName}}(id);
service.update(domain);
return ResponseEntity.status(HttpStatus.OK).body(mapping.toDto(domain));
}
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Update-all')")
@ApiOperation(value = "批量更新{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "批量更新{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.PUT, value = "/{{pluralize apiEntity.codeName}}/batch")
public ResponseEntity<Boolean> updateBatch(@RequestBody List<{{apiEntity.codeName}}DTO> dtos) {
service.updateBatch(mapping.toDomain(dtos));
return ResponseEntity.status(HttpStatus.OK).body(true);
}
@ApiOperation(value = "检查{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "检查{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.POST, value = "/{{pluralize apiEntity.codeName}}/checkkey")
public ResponseEntity<Boolean> checkKey(@RequestBody {{apiEntity.codeName}}DTO dto) {
return ResponseEntity.status(HttpStatus.OK).body(service.checkKey(mapping.toDomain(dto)));
}
@ApiOperation(value = "获取{{apiEntity.entity.logicName}}草稿", tags = {"{{apiEntity.entity.logicName}}" }, notes = "获取{{apiEntity.entity.logicName}}草稿")
@RequestMapping(method = RequestMethod.GET, value = "/{{pluralize apiEntity.codeName}}/getdraft")
public ResponseEntity<{{apiEntity.codeName}}DTO> getDraft({{apiEntity.codeName}}DTO dto) {
{{apiEntity.entity.codeName}} domain = mapping.toDomain(dto);
return ResponseEntity.status(HttpStatus.OK).body(mapping.toDto(service.getDraft(domain)));
}
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Save-all')")
@ApiOperation(value = "保存{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "保存{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.POST, value = "/{{pluralize apiEntity.codeName}}/save")
public ResponseEntity<{{apiEntity.codeName}}DTO> save(@RequestBody {{apiEntity.codeName}}DTO dto) {
{{apiEntity.entity.codeName}} domain = mapping.toDomain(dto);
service.save(domain);
return ResponseEntity.status(HttpStatus.OK).body(mapping.toDto(domain));
}
@PreAuthorize("hasAnyAuthority('ROLE_SUPERADMIN','{{projectName}}-{{apiEntity.entity.codeName}}-Save-all')")
@ApiOperation(value = "批量保存{{apiEntity.entity.logicName}}", tags = {"{{apiEntity.entity.logicName}}" }, notes = "批量保存{{apiEntity.entity.logicName}}")
@RequestMapping(method = RequestMethod.POST, value = "/{{pluralize apiEntity.codeName}}/savebatch")
public ResponseEntity<Boolean> saveBatch(@RequestBody List<{{apiEntity.codeName}}DTO> dtos) {
service.saveBatch(mapping.toDomain(dtos));
return ResponseEntity.status(HttpStatus.OK).body(true);
}
{{#each apiEntity.entity.dataSets as |dataSet|}}
@ApiOperation(value = "获取{{dataSet.name}}", tags = {"{{apiEntity.entity.logicName}}" } ,notes = "获取{{dataSet.name}}")
@RequestMapping(method= RequestMethod.GET , value="/{{pluralize apiEntity.codeName}}/fetch{{lowerCase dataSet.codeName}}")
{{#if dataSet.enableGroup}}
public ResponseEntity<List<Map>> fetch{{dataSet.codeName}}({{apiEntity.entity.codeName}}SearchContext context) {
Page<Map> page = service.search{{dataSet.codeName}}(context) ;
return ResponseEntity.status(HttpStatus.OK)
.header("x-page", String.valueOf(context.getPageable().getPageNumber()))
.header("x-per-page", String.valueOf(context.getPageable().getPageSize()))
.header("x-total", String.valueOf(page.getTotalElements()))
.body(page.getContent());
}
{{else}}
public ResponseEntity<List<{{apiEntity.codeName}}DTO>> fetch{{dataSet.codeName}}({{apiEntity.entity.codeName}}SearchContext context) {
Page<{{apiEntity.entity.codeName}}> domains = service.search{{dataSet.codeName}}(context) ;
List<{{apiEntity.codeName}}DTO> list = mapping.toDto(domains.getContent());
return ResponseEntity.status(HttpStatus.OK)
.header("x-page", String.valueOf(context.getPageable().getPageNumber()))
.header("x-per-page", String.valueOf(context.getPageable().getPageSize()))
.header("x-total", String.valueOf(domains.getTotalElements()))
.body(list);
}
{{/if}}
@ApiOperation(value = "查询{{dataSet.name}}", tags = {"{{apiEntity.entity.logicName}}" } ,notes = "查询{{dataSet.name}}")
@RequestMapping(method= RequestMethod.POST , value="/{{pluralize apiEntity.codeName}}/search{{lowerCase dataSet.codeName}}")
{{#if dataSet.enableGroup}}
public ResponseEntity<Page<Map>> search{{dataSet.codeName}}(@RequestBody {{apiEntity.entity.codeName}}SearchContext context) {
Page<Map> page = service.search{{dataSet.codeName}}(context) ;
return ResponseEntity.status(HttpStatus.OK)
.body(new PageImpl(page.getContent(), context.getPageable(), page.getTotalElements()));
}
{{else}}
public ResponseEntity<Page<{{apiEntity.codeName}}DTO>> search{{dataSet.codeName}}(@RequestBody {{apiEntity.entity.codeName}}SearchContext context) {
Page<{{apiEntity.entity.codeName}}> domains = service.search{{dataSet.codeName}}(context) ;
return ResponseEntity.status(HttpStatus.OK)
.body(new PageImpl(mapping.toDto(domains.getContent()), context.getPageable(), domains.getTotalElements()));
}
{{/if}}
{{/each}}
}
{{/neq}}
{{/if}}
{{/eq}}
\ No newline at end of file
package {{packageName}}.{{lowerCase api.codeName}};
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}}","cn.ibizlab.util"}
// ,excludeFilters={
// @ComponentScan.Filter(type= org.springframework.context.annotation.FilterType.REGEX,pattern="{{packageName}}.{{lowerCase api.codeName}}.rest.xxx"),
// }
)
@EnableMongoRepositories(basePackages = {"{{packageName}}"})
@MapperScan({"{{packageName}}.*.mapper","cn.ibizlab.util.mapper" })
@SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
{{#unless system.enableMongo}}
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
{{/unless}}
{{#unless system.enableDS}}
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure.class
{{/unless}}
})
@Import({
org.springframework.cloud.openfeign.FeignClientsConfiguration.class
})
@EnableFeignClients(basePackages = {"{{packageName}}","cn.ibizlab.util" })
@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}}.{{lowerCase api.codeName}};
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
#eureka配置中心
spring:
cloud:
nacos:
discovery:
enabled: false
eureka:
client:
enabled: true
serviceUrl:
defaultZone: http://127.0.0.1:8762/eureka/
\ No newline at end of file
#nacos配置中心
spring:
cloud:
nacos:
discovery:
server-addr: 172.16.100.77:8848
enabled: true
eureka:
client:
enabled: false
\ No newline at end of file
#缓存、数据源
spring:
cache:
redis:
time-to-live: 3600
caffeine:
spec: initialCapacity=5,maximumSize=500,expireAfterWrite=3600s
redis:
host: 127.0.0.1
port: 6379
password:
database: 0
lettuce:
pool:
max-active: 32
max-wait: 300ms
max-idle: 16
min-idle: 8
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
{{#if (or system.enableMongo system.enableES)}}
data:
{{/if}}
{{#if system.enableMongo}}
mongodb:
uri: mongodb://admin:admin@127.0.0.1:27017/{{projectName}}
{{/if}}
{{#if system.enableES}}
elasticsearch:
cluster-name: es-cluster
cluster-nodes: 127.0.0.1:9300
repositories:
enabled: true
{{/if}}
datasource:
username: a_LAB01_da1af574b
password: 'D33f8870'
url: jdbc:mysql://172.16.186.185:3306/a_LAB01_da1af574b?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
driver-class-name: com.mysql.jdbc.Driver
isSyncDBSchema: false
defaultSchema: a_LAB01_da1af574b
{{#if system.enableDS}}
dynamic:
druid: #以下是全局默认值,可以全局更改
filters: stat,log4j2
#配置初始化大小/最小/最大
initial-size: 1
min-idle: 1
max-active: 20
#获取连接等待超时时间
max-wait: 60000
#间隔多久进行一次检测,检测需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
#一个连接在池中最小生存的时间
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
#打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false
pool-prepared-statements: false
max-pool-prepared-statement-per-connection-size: 20
datasource:
master:
username: ${spring.datasource.username}
password: ${spring.datasource.password}
url: ${spring.datasource.url}
driver-class-name: ${spring.datasource.driver-class-name}
conf: classpath:liquibase/master.xml
isSyncDBSchema: ${spring.datasource.isSyncDBSchema}
defaultSchema: ${spring.datasource.defaultSchema}
db2:
username: ${spring.datasource.username}
password: ${spring.datasource.password}
url: ${spring.datasource.url}
driver-class-name: ${spring.datasource.driver-class-name}
conf: classpath:liquibase/master.xml
isSyncDBSchema: ${spring.datasource.isSyncDBSchema}
defaultSchema: ${spring.datasource.defaultSchema}
{{else}}
conf: classpath:liquibase/master.xml
filters: stat,wall,log4j2
#配置初始化大小/最小/最大
initial-size: 1
min-idle: 1
max-active: 20
#获取连接等待超时时间
max-wait: 60000
#间隔多久进行一次检测,检测需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
#一个连接在池中最小生存的时间
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
#打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false
pool-prepared-statements: false
max-pool-prepared-statement-per-connection-size: 20
{{/if}}
#Mybatis-plus配置
mybatis-plus:
global-config:
refresh-mapper: true
db-config:
# 全局逻辑已删除默认值
logic-delete-value: 0
# 全局逻辑未删除默认值
logic-not-delete-value: 1
mapper-locations: classpath*:/mapper/*/*/*.xml
configuration:
jdbc-type-for-null: 'null'
map-underscore-to-camel-case: false
#阿里sentinel熔断器
feign:
httpclient:
enabled: true
sentinel:
enabled: true
compression:
request:
enabled: true
mime-types: application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
min-response-size: 10240
response:
enabled: true
{{#if system.enableES}}
management:
health:
elasticsearch:
enabled: false
{{/if}}
{{#if system.enableGlobalTransaction}}
seata:
enabled: true #是否开启全局事务
application-id: {{projectName}} #服务标识
tx-service-group: {{projectName}}group #事务组
service:
vgroup-mapping:
{{projectName}}group: default #指定事务组对应的Tc Server集群
registry:
type: nacos #注册中心
nacos:
application: seata-server #Tc Server服务标识
server-addr: 127.0.0.1:8848 #注册中心地址
group: DEFAULT_GROUP #服务组
namespace: #服务命名空间
userName: #用户名
password: #密码
{{/if}}
{{#if system.enableMQ}}
rocketmq:
producer:
namesrvAddr: 127.0.0.1:9876
isOnOff: 'off'
groupName: default
topic: default
consumer:
namesrvAddr: 127.0.0.1:9876
isOnOff: 'off'
groupName: default
topic: default
{{/if}}
#Log配置
logging:
level:
cn.ibizlab: debug
{{packageName}}: debug
org.springframework.boot.autoconfigure: ERROR
#zuul网关超时设置
ribbon:
ReadTimeout: 60000
ConnectTimeout: 60000
#系统是否开启权限验证、是否开启缓存
#缓存级别:无缓存(无配置项)、一级缓存(L1)、二级缓存(L2)
ibiz:
systemid: {{system.codeName}}
systemname: {{system.logicName}}
enablePermissionValid: true
cacheLevel: L1 #(L1)一级本地caffeine缓存;(L2)caffeine缓存+Redis缓存
{{#eq system.saaSMode 4}}
saas:
column: SRFDCID
sys-tables: ACT_RU_TASK,act_re_procdef,databasechangelog,databasechangeloglock{{#each system.entities as |entity|}}{{#if (and (eq entity.storage "SQL") (entity.saaSMode 0))}},{{entity.tableName}}{{/if}}{{/each}}
{{/eq}}
### jobs
jobs:
#admin-address: http://127.0.0.1:40005
app-name: ibznotify
app-port: 9999
#app-ip: 127.0.0.1
### 启用Gzip压缩
server:
compression:
enabled: true
mime-types: application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
min-response-size: 10240
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="{{packageName}}.core.{{entity.module}}.mapper.{{entity.codeName}}Mapper">
<!--通过mybatis将查询结果注入到entity中,通过配置autoMapping="true"由mybatis自动处理映射关系 -->
<resultMap id="{{entity.codeName}}ResultMap" type="{{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}}" autoMapping="true">
{{#entity.keyField.phisicalDEField}}
<id property="{{camelCase entity.keyField.codeName}}" column="{{entity.keyField.columnName}}" /><!--主键字段映射-->
{{/entity.keyField.phisicalDEField}}
{{#each entity.fields}}
{{#alias}}
{{#unless deepStructure}}
{{#unless keyDEField}}
<result property="{{alias}}" column="{{columnName}}" />
{{/unless}}
{{/unless}}
{{/alias}}
{{/each}}
{{#each entity.nesteds}}
{{#columnName}}
<result property="{{camelCase codeName}}" column="{{columnName}}" typeHandler="{{packageName}}.core.{{module}}.domain.handlers.{{entityCodeName}}TypeHandler" />
{{/columnName}}
{{/each}}
{{#each entity.references}}
<association property="{{camelCase codeName}}" javaType="{{packageName}}.core.{{module}}.domain.{{entityCodeName}}" column="{{fkField.columnName}}" select="{{packageName}}.core.{{module}}.mapper.{{entityCodeName}}Mapper.selectById" fetchType="lazy"></association>
{{/each}}
</resultMap>
<select id="selectById" resultMap="{{entity.codeName}}ResultMap">
{{#if entity.viewDataQuery}}
{{#if entity.keyField.phisicalDEField}}
<include refid="view" />
{{#if entity.viewDataQuery.where}}
and
{{else}}
where
{{/if}}
{{else}}
select t1.* from ( <include refid="view" /> ) t1
where
{{/if}}
{{else}}
select t1.* from {{entity.viewName}} t1
where
{{#if entity.logicValid}}
{{#if entity.logicValidField.type.number}}
{{entity.logicValidField.columnName}} = {{entity.validLogicValue}}
{{else}}
{{entity.logicValidField.columnName}} = '{{entity.validLogicValue}}'
{{/if}}
and
{{/if}}
{{/if}}
t1.{{entity.keyField.columnName}}=#{id}
</select>
<select id="selectEntity" parameterType="{{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}}" resultMap="{{entity.codeName}}ResultMap">
{{#if entity.viewDataQuery}}
<include refid="view" />
{{#if entity.viewDataQuery.where}}
and
{{else}}
where
{{/if}}
{{else}}
select t1.* from {{entity.viewName}} t1
where
{{#if entity.logicValid}}
{{#if entity.logicValidField.type.number}}
{{entity.logicValidField.columnName}} = {{entity.validLogicValue}}
{{else}}
{{entity.logicValidField.columnName}} = '{{entity.validLogicValue}}'
{{/if}}
and
{{/if}}
{{/if}}
({{#each entity.keyFields as |field|}}{{#unless @first}} and {{/unless}}{{field.columnName}} = #{ {{camelCase field.codeName}} }{{/each}})
</select>
<select id="selectEntities" parameterType="java.util.List" resultMap="{{entity.codeName}}ResultMap">
{{#if entity.viewDataQuery}}
<include refid="view" />
{{#if entity.viewDataQuery.where}}
and
{{else}}
where
{{/if}}
{{else}}
select t1.* from {{entity.viewName}} t1
where
{{#if entity.logicValid}}
{{#if entity.logicValidField.type.number}}
{{entity.logicValidField.columnName}} = {{entity.validLogicValue}}
{{else}}
{{entity.logicValidField.columnName}} = '{{entity.validLogicValue}}'
{{/if}}
and
{{/if}}
{{/if}}
({{#each entity.keyFields as |field|}}{{#unless @first}},{{/unless}}{{field.columnName}}{{/each}})
in (<foreach collection="list" item="item" index="index" separator=","> ({{#each entity.keyFields as |field|}}{{#unless @first}},{{/unless}}#{ item.{{camelCase field.codeName}} }{{/each}}) </foreach>)
</select>
{{#each entity.dataQueries}}
<sql id="{{camelCase codeName}}" databaseId="{{dsType}}">
<![CDATA[
{{dsCode}}
]]>
</sql>
{{/each}}
{{#each entity.dataSets}}
<select id="search{{pascalCase codeName}}" parameterType="{{packageName}}.core.{{entity.module}}.filter.{{entity.codeName}}SearchContext" {{#if enableGroup}}resultType="java.util.HashMap"{{else}}resultMap="{{entity.codeName}}ResultMap"{{/if}}>
{{select}}
from (
{{#each queries}}
<include refid="{{camelCase this}}"/>
{{#unless @last}}
union all
{{/unless}}
{{/each}}
) t1
<where><if test="ew!=null and ew.sqlSegment!=null and !ew.emptyOfWhere">${ew.sqlSegment}</if></where>
<if test="ew!=null and ew.sqlSegment!=null and ew.emptyOfWhere">${ew.sqlSegment}</if>
{{groupBy}}
{{orderBy}}
</select>
{{/each}}
{{#each entity.references as | reference |}}
<select id="selectBy{{pascalCase reference.fkField.codeName}}" resultMap="{{entity.codeName}}ResultMap">
{{#if entity.defaultDataQuery}}
<include refid="{{camelCase entity.defaultDataQuery.codeName}}" />
{{#if entity.defaultDataQuery.where}}
and
{{else}}
where
{{/if}}
{{else}}
select t1.* from {{#if entity.viewName}}{{entity.viewName}}{{else}}{{entity.tableName}}{{/if}} t1 where
{{/if}}
{{reference.fkField.columnName}} = #{ {{camelCase reference.fkField.codeName}} }
</select>
{{/each}}
</mapper>
\ No newline at end of file
{{#if system.allPSSysMsgTempls}}
[
{{#each system.allPSSysMsgTempls as |msgTempl|}}
{
"tid":"{{lowerCase msgTempl.codeName}}",
"template_name":"{{msgTempl.getName}}",
"content":"{{msgTempl.content}}"
}{{#unless @last}},{{/unless}}
{{/each}}
]
{{/if}}
\ No newline at end of file
{{#*inline "getAppMenuItems"}}[
{{#each menuGroup.psAppMenuItems as |appMenuItem|}}
{
"id": "{{appMenuItem.name}}",
"name": "{{appMenuItem.caption}}"{{#if appMenuItem.psAppMenuItems}},
"item": {{>getAppMenuItems menuGroup=appMenuItem}}
{{/if}}
}{{#unless @last}},{{/unless}}
{{/each}}
]
{{/inline}}
{
"systemid": "{{system.codeName}}",
"systemname": "{{system.logicName}}",
"unires": [
{{#each system.allPSSysUniReses as |unires|}}
{
"unirescode": "{{unires.resCode}}",
"uniresname": "{{unires.name}}"
}{{#unless @last}},{{/unless}}
{{/each}}
],
"appmenus": [
{{#each system.apps as |app|}}
{
"appid": "{{app.codeName}}",
"appname": "{{app.name}}",
"appmenu": [
{{#each app.allPSAppMenuModels as |appMenu|}}
{
"menuid": "{{appMenu.codeName}}",
"menuname": "{{appMenu.name}}",
"menuitem": {{>getAppMenuItems menuGroup=appMenu}}
}{{#unless @last}},{{/unless}}
{{/each}}
]
}{{#unless @last}},{{/unless}}
{{/each}}
],
"entities": [
{{#each system.entities as |de|}}
{
"dename":"{{de.codeName}}",
"delogicname": "{{de.logicName}}",
"sysmodule": {
"id": "{{upperCase de.psSystemModule.codeName}}",
"name": "{{de.psSystemModule.name}}"
},
"dedataset": [
{{#each de.dataSets as |dataSet|}}
{
"id": "{{dataSet.codeName}}",
"name": "{{#if dataSet.logicName}}{{dataSet.logicName}}{{else}}{{dataSet.codeName}}{{/if}}"
}{{#unless @last}},{{/unless}}
{{/each}}
],
"deaction": [
{{#each de.actions as |action|}}
{
"id": "{{action.codeName}}",
"name": "{{#if action.logicName}}{{action.logicName}}{{else}}{{action.codeName}}{{/if}}",
"type": "{{action.actionType}}"
}{{#unless @last}},{{/unless}}
{{/each}}
],
"datascope": [
{{#each de.dataScopes as |dataScope|}}
{
"id": "{{dataScope.id}}",
"name": "{{dataScope.name}}"
}{{#unless @last}},{{/unless}}
{{/each}}
]
}{{#unless @last}},{{/unless}}
{{/each}}
]
}
{{#eq system.codeName "1"}}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
{
"systemid":"${sys.codeName}",
"systemname":"${sys.getLogicName()}",
"entities":[
<#if sys.getAllPSDataEntities()??>
<#list sys.getAllPSDataEntities() as de>
{
"entity_name":"${de.name}",
"logic_name":"${de.logicName}",
"code_name":"${de.codeName}",
"table_name":"${de.getTableName()}",
"system_id":"${sys.codeName}",
"system_name":"${sys.logicName}",
"module_id":"${de.getPSSystemModule().codeName}",
"module_name":"${de.getPSSystemModule().name}",
<#--"ds_id":null,-->
<#--"ds_name":"",-->
"fields":[
<#if de.getPSDEFields()??>
<#list de.getPSDEFields() as defield>
{
"fieldname":"${defield.name}" ,
"codename":"${defield.codeName}",
"field_logic_name":"${defield.logicName}",
"entity_name":"${de.name}",
<#if defield.getRelatedPSDEField?? && defield.getRelatedPSDEField()??>
"ref_de":"${defield.getRelatedPSDEField().getPSDataEntity().name}",
"ref_field_name":"${defield.getRelatedPSDEField().name}",
</#if>
<#if (((defield.dataType())!'')=='PICKUP' || ((defield.dataType())!'')=='PICKUPDATA' || ((defield.dataType())!'')=='PICKUPTEXT' ) && defield.getPSDER1N()?? >
"relation_name":"${defield.getPSDER1N().getName()}",
"relation_codename":"${defield.getPSDER1N().getCodeName()}",
</#if>
"field_type":"${defield.getDataType()}",
<#if defield.getPSCodeList()??>
"dict":"${defield.getPSCodeList().codeName}",
</#if>
"nullable":<#if defield.isAllowEmpty()>1<#else>0</#if>,
"physical_field":<#if defield.isPhisicalDEField()>1<#else>0</#if>,
"data_type":"${srfdatatype(defield.getStdDataType())}",
<#if defield.getLength()?c!='-1'>
"data_length":${defield.getLength()?c},
</#if>
<#if defield.getPrecision()?c!='0'>
"data_preci":${defield.getPrecision()?c},
</#if>
<#if defield.getDefaultPSDEFDTColumn?? && defield.getDefaultPSDEFDTColumn()?? && defield.getDefaultPSDEFDTColumn().isFormula()==true>
"expression":"${defield.getDefaultPSDEFDTColumn().getFormulaFormat()}",
</#if>
<#if defield.getPredefinedType()?? && defield.getPredefinedType()!=''>
"predefined":"${defield.getPredefinedType()}",
</#if>
"key_field":<#if defield.isKeyDEField()==true>1<#else>0</#if>,
<#if defield.getUnionKeyValue()?? && defield.getUnionKeyValue()!=''>
"union_key":"${defield.getUnionKeyValue()}",
</#if>
<#if defield.getOrderValue?? && defield.getOrderValue()??>
"show_order":${defield.getOrderValue()?c},
</#if>
"major_field":<#if defield.isMajorDEField()==true>1<#else>0</#if>
}<#if defield_has_next>,</#if>
</#list>
</#if>
],
"subEntitys":[
<#if de.getMinorPSDERs()??>
<#list de.getMajorPSDERs() as majorPSDER>
{"name":"${majorPSDER.name}",
"relation_type":"${majorPSDER.getDERType()}",
"code_name":"${majorPSDER.getCodeName()}",
"entity_name":"${majorPSDER.getMinorPSDataEntity().name}",
"ref_entity_name":"${majorPSDER.getMajorPSDataEntity().name}"
<#--"nested_name":"",-->
<#--"lookup":""-->
}<#if majorPSDER_has_next>,</#if>
</#list>
</#if>
],
"parentEntitys":[
<#if de.getMinorPSDERs()??>
<#list de.getMinorPSDERs() as minorPSDER>
{"name":"${minorPSDER.name}",
"relation_type":"${minorPSDER.getDERType()}",
"code_name":"${minorPSDER.getCodeName()}",
"entity_name":"${minorPSDER.getMinorPSDataEntity().name}",
"ref_entity_name":"${minorPSDER.getMajorPSDataEntity().name}"
<#--"nested_name":"",-->
<#--"lookup":""-->
}<#if minorPSDER_has_next>,</#if>
</#list>
</#if>
]
}
<#if de_has_next>,</#if>
</#list>
</#if>
]
}
{{/eq}}
\ No newline at end of file
[
{{#each system.allPSCodeLists as |codelist|}}
{{#eq codelist.predefinedType 'RUNTIME'}}
{
"name": "{{codelist.name}}",
"code": "{{codelist.codeName}}",
"group": "",
"memo": "",
{{#if codelist.allPSCodeItems}}
"items": [
{{#each codelist.allPSCodeItems as |codeItem|}}
{
"catalog_id": "{{codelist.codeName}}",
"catalog_name": "{{codelist.name}}",
"value_key": "{{codelist.codeName}}-{{codeItem.codeName}}",
"value": "{{codeItem.value}}",
"label":"{{codeItem.text}}",
"disabled": "0",
{{#if codeItem.parentCodeItem}}
"parent": "{{codeItem.parentCodeItem.value}}",
{{/if}}
"showorder": {{@index}}
}{{#unless @last}},{{/unless}}
{{/each}}
]
{{/if}}
}
{{/eq}}
{{/each}}
]
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
<process id="{{workflow.id}}" isClosed="false" isExecutable="true" name="{{workflow.name}}" processType="None">
<extensionElements>
<flowable:eventListener delegateExpression="${processInstanceListener}" />
{{#if workflow.refGroups}}
<flowable:field name="refgroups">
<flowable:string>{{#each workflow.refGroups as |refGroup|}}{{@key}}{{#unless @last}},{{/unless}}{{/each}}</flowable:string>
</flowable:field>
{{/if}}
{{#if workflow.bookings}}
<flowable:field name="bookings">
<flowable:string>{{#each workflow.bookings as |booking|}}{{pluralize booking.codeName}}{{#unless @last}},{{/unless}}{{/each}}</flowable:string>
</flowable:field>
{{/if}}
{{#if workflow.mobApps}}
{{#each workflow.mobApps as |mobApp|}}
<flowable:field name="bookingmobs_{{pluralize @key}}">
<flowable:string>{{#each this as |app|}}{{app.codeName}}{{#unless @last}},{{/unless}}{{/each}}</flowable:string>
</flowable:field>
{{/each}}
{{/if}}
{{#if workflow.webApps}}
{{#each workflow.webApps as |webApp|}}
<flowable:field name="bookingapps_{{pluralize @key}}">
<flowable:string>{{#each this as |app|}}{{app.codeName}}{{#unless @last}},{{/unless}}{{/each}}</flowable:string>
</flowable:field>
{{/each}}
{{/if}}
{{#each workflow.psWorkflow.psWFDEs as |wfde|}}
{{#if wfde.wFStepPSDEField}}
<flowable:field name="wfstepfield_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{lowerCase wfde.wFStepPSDEField.codeName}}</flowable:string>
</flowable:field>
{{/if}}
{{#if wfde.wFInstPSDEField}}
<flowable:field name="wfinstfield_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{lowerCase wfde.wFInstPSDEField.codeName}}</flowable:string>
</flowable:field>
{{/if}}
{{#if wfde.uDStatePSDEField}}
<flowable:field name="udstatefield_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{lowerCase wfde.uDStatePSDEField.codeName}}</flowable:string>
</flowable:field>
{{/if}}
{{#if workflow.psWorkflow.entityWFState}}
<flowable:field name="udstateingval_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{workflow.psWorkflow.entityWFState}}</flowable:string>
</flowable:field>
{{/if}}
{{#if workflow.psWorkflow.entityWFFinishState}}
{{#neq workflow.psWorkflow.entityWFFinishState ""}}
<flowable:field name="wffinishval_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{workflow.psWorkflow.entityWFFinishState}}</flowable:string>
</flowable:field>
{{/neq}}
{{/if}}
{{#if workflow.psWorkflow.entityWFErrorState}}
{{#neq workflow.psWorkflow.entityWFErrorState ""}}
<flowable:field name="wferrorval_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{workflow.psWorkflow.entityWFErrorState}}</flowable:string>
</flowable:field>
{{/neq}}
{{/if}}
{{#if wfde.wFStatePSDEField}}
<flowable:field name="wfstatefield_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{lowerCase wfde.wFStatePSDEField.codeName}}</flowable:string>
</flowable:field>
{{/if}}
{{#if wfde.wFVerPSDEField}}
<flowable:field name="wfverfield_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{lowerCase wfde.wFVerPSDEField.codeName}}</flowable:string>
</flowable:field>
{{/if}}
{{#if wfde.psDataEntity.majorPSDEField}}
<flowable:field name="majortext_{{pluralize wfde.psDataEntity.codeName}}">
<flowable:string>{{lowerCase wfde.psDataEntity.majorPSDEField.codeName}}</flowable:string>
</flowable:field>
{{/if}}
{{/each}}
{{#each workflow.bookings as |booking|}}
{{#if booking.orgField}}
<flowable:field name="orgfield_{{pluralize booking.codeName}}">
<flowable:string>{{lowerCase booking.orgField.codeName}}</flowable:string>
</flowable:field>
{{/if}}
{{/each}}
<flowable:field name="isvalid"><flowable:string>{{#if workflow.valid}}1{{else}}0{{/if}}</flowable:string></flowable:field>
</extensionElements>
{{#if workflow.psWFProcesses}}
{{#each workflow.psWFProcesses as |WFProcess|}}
{{#eq WFProcess.wFProcessType 'START'}}
<startEvent id="sid-{{WFProcess.codeName}}" name="{{WFProcess.name}}">
{{#if (or WFProcess.formCodeName WFProcess.mobFormCodeName)}}
<extensionElements>
<flowable:form {{#if WFProcess.formCodeName}}process-form="{{WFProcess.formCodeName}}"{{/if}} {{#if WFProcess.mobFormCodeName}}process-mobform="{{WFProcess.mobFormCodeName}}"{{/if}} {{#if WFProcess.wFVersion}}wfversion="{{WFProcess.wFVersion}}"{{/if}}/>
</extensionElements>
{{/if}}
</startEvent>
{{/eq}}
{{#eq WFProcess.wFProcessType 'END'}}
<endEvent id="sid-{{WFProcess.codeName}}" name="{{WFProcess.name}}">
{{#if (or (and WFProcess.userData (neq WFProcess.userData "")) (and WFProcess.userData2 (neq WFProcess.userData2 "")))}}
<extensionElements>
<flowable:form {{#if (and WFProcess.userData (neq WFProcess.userData ""))}}userdata="{{WFProcess.userData}}"{{/if}} {{#if (and WFProcess.userData2 (neq WFProcess.userData2 ""))}}userdata2="{{WFProcess.userData2}}"{{/if}} />
</extensionElements>
{{/if}}
</endEvent>
{{/eq}}
{{#eq WFProcess.wFProcessType 'PARALLELGATEWAY'}}
<parallelGateway id="sid-{{WFProcess.codeName}}"/>
{{/eq}}
{{#eq WFProcess.wFProcessType 'INCLUSIVEGATEWAY'}}
<inclusiveGateway id="sid-{{WFProcess.codeName}}"/>
{{/eq}}
{{#eq WFProcess.wFProcessType 'EXCLUSIVEGATEWAY'}}
<exclusiveGateway id="sid-{{WFProcess.codeName}}"/>
{{/eq}}
{{#eq WFProcess.wFProcessType 'PROCESS'}}
<serviceTask id="sid-{{WFProcess.codeName}}" name="{{WFProcess.name}}" flowable:expression="${wfCoreService.execute(execution, activedata)}" >
<extensionElements>
<flowable:field name="service-entity"><flowable:string>{{pluralize WFProcess.psDataEntity.codeName}}</flowable:string></flowable:field>
<flowable:field name="service-deaction"><flowable:string>{{lowerCase WFProcess.psDEAction.codeName}}</flowable:string></flowable:field>
{{#if WFProcess.psWFProcessParams}}
{{#each WFProcess.psWFProcessParams as |processparams|}}
{{#if processparams.dstField (neq processparams.dstField "")}}
{{#if (and processparams.srcValueType (neq processparams.srcValueType ""))}}
{{#eq processparams.srcValue "CURTIME"}}
<flowable:field name="params-{{lowerCase processparams.dstField}}"><flowable:expression><![CDATA[${wfCoreService.getnow()}]]></flowable:expression></flowable:field>
{{/eq}}
{{#eq processparams.srcValue "OPERATOR"}}
<flowable:field name="params-{{lowerCase processparams.dstField}}"><flowable:expression><![CDATA[${curuser.userid}]]></flowable:expression></flowable:field>
{{/eq}}
{{#eq processparams.srcValue "OPERATORNAME"}}
<flowable:field name="params-{{lowerCase processparams.dstField}}"><flowable:expression><![CDATA[${curuser.personname}]]></flowable:expression></flowable:field>
{{/eq}}
{{#eq processparams.srcValue "CONTEXT"}}
<flowable:field name="params-{{lowerCase processparams.dstField}}"><flowable:expression><![CDATA[${activedata.{{lowerCase processparams.srcValue}} }]]></flowable:expression></flowable:field>
{{/eq}}
{{#eq processparams.srcValue "SESSION"}}
<flowable:field name="params-{{lowerCase processparams.dstField}}"><flowable:expression><![CDATA[${curuser.sessionParams.{{lowerCase processparams.srcValue}} }]]></flowable:expression></flowable:field>
{{/eq}}
{{else}}
{{#if (and processparams.srcValue (neq processparams.srcValue ""))}}
<flowable:field name="params-{{lowerCase processparams.dstField}}"><flowable:string>{{processparams.srcValue}}</flowable:string></flowable:field>
{{/if}}
{{/if}}
{{/if}}
{{/each}}
{{/if}}
</extensionElements>
</serviceTask>
{{/eq}}
{{/each}}
{{#each workflow.userTasks as |userTask|}}
<userTask flowable:category="${businessKey}" {{#if userTask.timeOut}}flowable:dueDate="{{userTask.timeoutStrategy}}" {{/if}}flowable:candidateUsers="{{#if userTask.multiInstanceLoopCharacteristics}}${candidateUsers}{{else}}{{userTask.assignCond}}{{/if}}" flowable:exclusive="true"
id="tid-{{userTask.process.wFStepValue}}-{{userTask.process.codeName}}"
name="{{userTask.process.name}}" {{#if (or (eq userTask.process.wFProcessType "CALLORGACTIVITY") (eq userTask.process.wFProcessType "EMBED"))}}flowable:formKey="{{userTask.process.wFProcessType}}"{{/if}}>
<documentation>${majortext}</documentation>
{{#if userTask.formParam}}
<extensionElements>
<flowable:form {{#each userTask.formParam as |itemParam|}}{{itemParam}} {{/each}}/>
</extensionElements>
{{/if}}
{{#if userTask.multiInstanceLoopCharacteristics}}
<multiInstanceLoopCharacteristics flowable:collection="candidateUsersList" flowable:elementVariable="candidateUsers" isSequential="{{userTask.sequential}}">
<completionCondition><![CDATA[${nrOfCompletedInstances/nrOfInstances == 1}]]></completionCondition>
</multiInstanceLoopCharacteristics>
{{/if}}
</userTask>
{{#if userTask.timeOut}}
<boundaryEvent id="bid-{{userTask.process.wFStepValue}}-{{userTask.process.codeName}}" name="timeout-{{userTask.process.name}}" attachedToRef="tid-{{userTask.process.wFStepValue}}-{{userTask.process.codeName}}" cancelActivity="true">
<timerEventDefinition>
<timeDate>{{userTask.timeoutStrategy}}</timeDate>
</timerEventDefinition>
</boundaryEvent>
{{/if}}
{{/each}}
{{/if}}
{{#each workflow.sequenceFlows as |sequenceFlow|}}
<sequenceFlow id="{{sequenceFlow.flowId}}" sourceRef="{{sequenceFlow.sourceProcessId}}" targetRef="{{sequenceFlow.targetProcessId}}" name="{{sequenceFlow.link.logicName}}">
{{#if sequenceFlow.linkCond}}
<conditionExpression xsi:type="tFormalExpression" >{{sequenceFlow.linkCond}}</conditionExpression>
{{/if}}
{{#if sequenceFlow.linkParam}}
<extensionElements>
<flowable:form {{#each sequenceFlow.linkParam as |itemParam|}}{{itemParam}} {{/each}}/>
</extensionElements>
{{/if}}
</sequenceFlow>
{{/each}}
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_{{workflow.id}}">
<bpmndi:BPMNPlane id="BPMNPlane_{{workflow.id}}" bpmnElement="{{workflow.id}}">
{{#each workflow.processes as |task|}}
<bpmndi:BPMNShape id="BPMNShape-{{task.processId}}" bpmnElement="{{task.processId}}">
<omgdi:Bounds x="{{task.process.leftPos}}" y="{{task.process.topPos}}" width="{{task.process.width}}" height="{{task.process.height}}" />
</bpmndi:BPMNShape>
{{/each}}
{{#each workflow.sequenceFlows as |sequenceFlow|}}
<bpmndi:BPMNEdge id="BPMNEdge-{{sequenceFlow.flowId}}" bpmnElement="{{sequenceFlow.flowId}}">
<omgdi:waypoint x="0" y="0" />
<omgdi:waypoint x="0" y="0" />
</bpmndi:BPMNEdge>
{{/each}}
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
\ No newline at end of file
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册