提交 f9ed7097 编写于 作者: zhouweidong's avatar zhouweidong

合并分支 'dev' 到 'master'

版本合并20200721

查看合并请求 !17
# **iBiz4j Spring R7 Template ChangeLog**
## [v2020.07.21]
增强:
- 数据查询:支持上下文的in查询
- 数据查询:支持无值忽略条件
- 支持实体数据导入
修复:
- 补充mapping别名,解决实体在多服务接口中,boot启动mapping重名问题
- 修复服务接口嵌套版本检查bug
- 附加逻辑添加逻辑所有者判断
## [v2020.07.14]
- 支持nacos.eureka服务注册中心,通过配置进行切换
- 支持serviceId动态化配置
- 支持mybatis-plus动态数据源
- 支持数据审计
## [v2020.07.02]
- 支持测试行为模式
- 数据保存时增加版本检查
......
......@@ -2,20 +2,29 @@
TARGET=PSSYSAPP
</#ibiztemplate>
<#assign httpPort = "8080">
<#assign timezone = "Asia/Shanghai">
<#if sysrun?? >
<#if sysrun.getPSDevSlnMSDepApp()??>
<#if sysrun.getPSDevSlnMSDepApp().getHttpPort()??>
<#assign httpPort = sysrun.getPSDevSlnMSDepApp().getHttpPort()?c>
</#if>
<#if sysrun.getPSDevSlnMSDepApp().getUserParam("timezone","")?? && sysrun.getPSDevSlnMSDepApp().getUserParam("timezone","")!="">
<#assign timezone = sysrun.getPSDevSlnMSDepApp().getUserParam("timezone","")>
<#elseif sysrun.getPSDevSlnMSDepApp().getPSDCMSPlatform().getUserParam("timezone","")?? && sysrun.getPSDevSlnMSDepApp().getPSDCMSPlatform().getUserParam("timezone","")!="">
<#assign timezone = sysrun.getPSDevSlnMSDepApp().getPSDCMSPlatform().getUserParam("timezone","")>
</#if>
</#if>
</#if>
FROM openjdk:8-jre-alpine
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
ENV TZ=${timezone} \
SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
IBIZ_SLEEP=0 \
JAVA_OPTS=""
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
CMD echo "The application will start in ${r'${IBIZ_SLEEP}'}s..." && \
sleep ${r'${IBIZ_SLEEP}'} && \
java ${r'${JAVA_OPTS}'} -Djava.security.egd=file:/dev/./urandom -jar /${pub.getCodeName()?lower_case}-app-${app.getPKGCodeName()?lower_case}.jar
......
<#ibiztemplate>
TARGET=PSSYSAPP
</#ibiztemplate>
<#assign bDynamicDS=false>
<#list sys.getAllPSDataEntities() as entity>
<#if (entity.getStorageMode()==1 || entity.getStorageMode()==2) && entity.getDSLink()!='DEFAULT'>
<#assign bDynamicDS=true>
<#break>
</#if>
</#list>
package ${pub.getPKGCodeName()}.${app.getPKGCodeName()?lower_case};
import lombok.extern.slf4j.Slf4j;
......@@ -42,6 +49,9 @@ import java.util.List;
<#if bmogo==false>
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
</#if>
<#if bDynamicDS>
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure.class
</#if>
})
public class ${app.getPKGCodeName()}Application extends WebMvcConfigurerAdapter{
......
......@@ -109,6 +109,7 @@ public class ${app.getPKGCodeName()}SecurityConfig extends WebSecurityConfigurer
"/**/fonts/**",
"/**/js/**",
"/**/img/**",
"/**/svg/**",
"/"
).permitAll()
//放行登录请求
......
......@@ -30,7 +30,9 @@ zuul:
<#if psDataEntity.hasPSDEWF()?? && psDataEntity.hasPSDEWF()==true>
<#assign haswfentity=true>
</#if>
<#if psDataEntity.getStorageMode()==4>
<#assign sybSysServiceType=(psDataEntity.getPSSubSysServiceAPI().getServiceType())!''>
<#comment>服务类型为中台和MASA走自身处理</#comment>
<#if psDataEntity.getStorageMode()==4 && (sybSysServiceType!='MIDDLEPLATFORM' && sybSysServiceType!='MASA')>
<#comment>serviceApi模式</#comment>
<#assign serviceId=(psDataEntity.getPSSubSysServiceAPI().getServiceCodeName())!''>
<#assign serviceUrl=srfpluralize(appDataEntity.codeName?lower_case)>
......@@ -40,6 +42,7 @@ zuul:
<#assign serviceId=systemName+"-"+sysApi>
</#if>
<#if serviceId!="">
<#assign serviceId="$"+"{ibiz.ref.service."+serviceId?lower_case+":"+serviceId+"}">
${appEntity}:
path: /${serviceUrl}/**
serviceId: ${serviceId}
......@@ -49,30 +52,30 @@ zuul:
<#if haswfentity==true>
wfcore:
path: /wfcore/**
serviceId: ibzwf-api
serviceId: ${r'${ibiz.ref.service.wf:ibzwf-api}'}
stripPrefix: true
</#if>
<#if sys.getPSSystemSetting()?? && sys.getPSSystemSetting().getDataAccCtrlArch()?? && sys.getPSSystemSetting().getDataAccCtrlArch()==1>
loginv7:
path: /v7/login
serviceId: ibzuaa-api
serviceId: ${r'${ibiz.ref.service.uaa:ibzuaa-api}'}
stripPrefix: false
changepwd:
path: /v7/changepwd
serviceId: ibzuaa-api
serviceId: ${r'${ibiz.ref.service.uaa:ibzuaa-api}'}
stripPrefix: false
uaa:
path: /uaa/**
serviceId: ibzuaa-api
serviceId: ${r'${ibiz.ref.service.uaa:ibzuaa-api}'}
stripPrefix: false
config:
path: /config/**
serviceId: ibzuaa-api
serviceId: ${r'${ibiz.ref.service.uaa:ibzuaa-api}'}
stripPrefix: false
<#if sys.getCodeName()!='ibzou' && sys.getCodeName()!='ibzrt'>
oucore:
path: /ibzorganizations/**
serviceId: ibzou-api
serviceId: ${r'${ibiz.ref.service.ou:ibzou-api}'}
stripPrefix: false
</#if>
</#if>
......
......@@ -3,6 +3,6 @@ TARGET=PSSYSAPP
</#ibiztemplate>
spring:
profiles:
include: sys , ${app.getPKGCodeName()?lower_case}-prod
include: sys ,nacos, ${app.getPKGCodeName()?lower_case}-prod
application:
name: ${sys.getCodeName()?lower_case}-${app.getPKGCodeName()?lower_case}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign bDynamicDS=false>
<#list sys.getAllPSDataEntities() as entity>
<#if (entity.getStorageMode()==1 || entity.getStorageMode()==2) && entity.getDSLink()!='DEFAULT'>
<#assign bDynamicDS=true>
<#break>
</#if>
</#list>
package ${pub.getPKGCodeName()};
import lombok.extern.slf4j.Slf4j;
......@@ -14,6 +21,8 @@ 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;
@Slf4j
......@@ -34,6 +43,9 @@ import java.util.List;
<#if bmogo==false>
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
</#if>
<#if bDynamicDS>
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure.class
</#if>
})
@ComponentScan(basePackages = {"${pub.getPKGCodeName()}"}
// ,excludeFilters={
......@@ -43,6 +55,8 @@ import java.util.List;
@Import({
org.springframework.cloud.openfeign.FeignClientsConfiguration.class
})
@EnableAsync
@EnableScheduling
public class DevBootApplication extends WebMvcConfigurerAdapter{
public static void main(String[] args) {
......
......@@ -50,7 +50,8 @@ zuul:
<#comment>serviceApi模式</#comment>
<#assign serviceId=(psDataEntity.getPSSubSysServiceAPI().getServiceCodeName())!''>
<#assign serviceUrl=srfpluralize(appDataEntity.name?lower_case)>
<#if serviceId!="">
<#if serviceId!="">
<#assign serviceId="$"+"{ibiz.ref.service."+serviceId?lower_case+":"+serviceId+"}">
${appEntity}:
path: /${serviceUrl}/**
serviceId: ${serviceId}
......@@ -61,30 +62,30 @@ zuul:
<#if haswfentity==true>
wfcore:
path: /wfcore/**
serviceId: ibzwf-api
serviceId: ${r'${ibiz.ref.service.wf:ibzwf-api}'}
stripPrefix: true
</#if>
<#if sys.getPSSystemSetting()?? && sys.getPSSystemSetting().getDataAccCtrlArch()?? && sys.getPSSystemSetting().getDataAccCtrlArch()==1>
loginv7:
path: /v7/login
serviceId: ibzuaa-api
serviceId: ${r'${ibiz.ref.service.uaa:ibzuaa-api}'}
stripPrefix: false
changepwd:
path: /v7/changepwd
serviceId: ibzuaa-api
serviceId: ${r'${ibiz.ref.service.uaa:ibzuaa-api}'}
stripPrefix: false
uaa:
path: /uaa/**
serviceId: ibzuaa-api
serviceId: ${r'${ibiz.ref.service.uaa:ibzuaa-api}'}
stripPrefix: false
config:
path: /config/**
serviceId: ibzuaa-api
serviceId: ${r'${ibiz.ref.service.uaa:ibzuaa-api}'}
stripPrefix: false
<#if sys.getCodeName()!='ibzou' && sys.getCodeName()!='ibzrt'>
oucore:
path: /ibzorganizations/**
serviceId: ibzou-api
serviceId: ${r'${ibiz.ref.service.ou:ibzou-api}'}
stripPrefix: false
</#if>
</#if>
......
......@@ -19,7 +19,7 @@ TARGET=PSSYSTEM
</#if>
spring:
profiles:
include: sys , <#if refAppYaml!=''>${refAppYaml}</#if> <#if refProviderYaml!=''> ${refProviderYaml} </#if> dev
include: sys ,nacos, <#if refAppYaml!=''>${refAppYaml}</#if> <#if refProviderYaml!=''> ${refProviderYaml} </#if> dev
application:
name: ${item.getCodeName()?lower_case}
main:
......
......@@ -25,10 +25,15 @@ import org.springframework.cloud.openfeign.FeignClient;
</#if>
<#comment>contextId存在下划线时,项目运行报错,模板中转中划线处理</#comment>
<#assign contextId=item.codeName?replace("_","-")>
<#if ((item.getPSSubSysServiceAPI().getServiceCodeName())!'')!=''>
<#assign serviceId="$"+"{ibiz.ref.service."+item.getPSSubSysServiceAPI().getServiceCodeName()?lower_case+":"+item.getPSSubSysServiceAPI().getServiceCodeName()+"}">
<#else>
<#assign serviceId="$"+"{ibiz.ref.service."+item.getPSSubSysServiceAPI().codeName?lower_case+":}">
</#if>
/**
* 实体[${item.codeName}] 服务对象接口
*/
@FeignClient(value = "${(item.getPSSubSysServiceAPI().getServiceCodeName())!''}", contextId = "${contextId}", fallback = ${item.codeName}Fallback.class)
@FeignClient(value = "${serviceId}", contextId = "${contextId}", fallback = ${item.codeName}Fallback.class)
public interface ${item.codeName}FeignClient {
<#if item.getPSSubSysServiceAPIDEMethods()??>
......
......@@ -24,6 +24,7 @@ import ${pub.getPKGCodeName()}.util.enums.DEFieldDefaultValueType;
import java.io.Serializable;
import lombok.*;
import org.springframework.data.annotation.Transient;
import ${pub.getPKGCodeName()}.util.annotation.Audit;
<#comment>SQL存储-Mybatis</#comment>
<#if de.getStorageMode()==1>
......@@ -86,9 +87,37 @@ public class ${item.getCodeName()} extends EntityMP implements Serializable {
</#if>
</#if>
</#if>
<#comment>审计</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
<#assign defStdType=srfjavatype(defield.stdDataType)>
<#if defieldano?? && defieldano!='' >
<#assign defieldano = defieldano+" , ">
</#if>
<#assign defieldano = defieldano+"value = \""+jsonfield+"\"">
<#if defield.getPSCodeList?? && defield.getPSCodeList()??>
<#if ((defield.getPredefinedType())!'')!='LOGICVALID'>
<#assign defieldano=defieldano+",dict=\""+defield.getPSCodeList().codeName+"\"">
</#if>
</#if>
<#if defDataType == "DATETIME"|| defDataType == "DATE" || defDataType == "TIME" || defDataType=='PICKUPDATA'&& defStdType=='Timestamp'>
<#if defDataType == "DATETIME">
<#assign defieldano=defieldano+",fieldType=\"DATETIME\",format=\"yyyy-MM-dd HH:mm:ss\"">
<#elseif defDataType == "DATE">
<#assign defieldano=defieldano+",fieldType=\"DATE\",format=\"yyyy-MM-dd\"">
<#elseif defDataType == "TIME">
<#assign defieldano=defieldano+",fieldType=\"TIME\",format=\"HH:mm\"">
<#elseif defDataType=='PICKUPDATA'&& defStdType=='Timestamp'><#comment>外键值附加数据,数据类型为时间</#comment>
<#assign defieldano=defieldano+",fieldType=\"DATETIME\",format=\"yyyy-MM-dd HH:mm:ss\"">
</#if>
</#if>
</#if>
/**
* ${defield.getLogicName()}
*/
<#comment>审计注解</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
@Audit
</#if>
<#comment>属性默认值</#comment>
<#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true>
@DEField(${defieldano})
......@@ -337,6 +366,10 @@ public class ${item.getCodeName()} extends EntityMongo implements Serializable {
<#if defield.isKeyDEField()==true>
@Id()
</#if>
<#comment>审计注解</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
@Audit
</#if>
<#comment>属性默认值</#comment>
<#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true>
@DEField(${defieldano})
......@@ -501,6 +534,10 @@ public class ${item.getCodeName()} extends EntityClient implements Serializable
/**
* ${defield.getLogicName()}
*/
<#comment>审计注解</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
@Audit
</#if>
<#comment>属性默认值</#comment>
<#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true>
@DEField(${defieldano})
......@@ -677,6 +714,10 @@ public class ${item.getCodeName()} extends EntityBase implements Serializable {
/**
* ${defield.getLogicName()}
*/
<#comment>审计注解</#comment>
<#if defield.isEnableAudit()==true && de.getAuditMode()!=0>
@Audit
</#if>
<#comment>属性默认值</#comment>
<#if defieldano?? && defieldano!='' && defield.isPhisicalDEField()==true>
@DEField(${defieldano})
......
......@@ -21,6 +21,11 @@ import java.io.Serializable;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.alibaba.fastjson.JSONObject;
<#if item.getDSLink?? && item.getDSLink()??>
<#if item.getDSLink()!='DEFAULT'>
@com.baomidou.dynamic.datasource.annotation.DS("${item.getDSLink()?lower_case}")
</#if>
</#if>
public interface ${item.getCodeName()}Mapper extends BaseMapper<${item.getCodeName()}>{
<#if item.getAllPSDEDataSets()??>
......
<#ibiztemplate>
TARGET=PSDEDATAIMP
</#ibiztemplate>
package ${pub.getPKGCodeName()}.core.${de.getPSSystemModule().codeName?lower_case}.mapping;
import ${pub.getPKGCodeName()}.core.${de.getPSSystemModule().codeName?lower_case}.domain.${de.codeName};
import org.mapstruct.*;
import java.util.List;
@Mapper(componentModel = "spring", uses = {})
public interface ${de.codeName}${item.codeName} {
<#assign keyFieldName=srfcaseformat(de.getKeyPSDEField().getCodeName(),'l_u2lC')>
<#if item.getPSDEDataImportItems?? && item.getPSDEDataImportItems()??>
@Mappings({
@Mapping(target = "${keyFieldName}",source = "${keyFieldName}"),
<#list item.getPSDEDataImportItems() as importItem>
<#if importItem.getPSDEField()?? && importItem.getPSDEField().isKeyDEField()==false>
<#assign deFieldName = srfcaseformat(importItem.getPSDEField().getCodeName(),'l_u2lC')>
@Mapping(target = "${deFieldName}",source = "${deFieldName}"),
</#if>
</#list>
})
@BeanMapping(ignoreByDefault = true)
</#if>
${de.codeName} toDomain(${de.codeName} entity);
List<${de.codeName}> toDomain(List<${de.codeName}> entities);
}
......@@ -7,6 +7,14 @@ TARGET=PSDATAENTITY
<#if de.getPSDEFieldByPDT('ORGID',true)?? || de.getPSDEFieldByPDT('ORGSECTORID',true)?? || de.getPSDEFieldByPDT('CREATEMAN',true)?? >
<#assign hasDEPrefield=true>
</#if>
<#assign hasDEImport=false>
<#comment>实体数据导入</#comment>
<#if de.getAllPSDEDataImports?? && de.getAllPSDEDataImports()??>
<#list de.getAllPSDEDataImports() as deImport>
<#assign hasDEImport=true>
<#break>
</#list>
</#if>
<#if de.getStorageMode()==1 || de.getStorageMode()==2 ||de.getStorageMode()==4||de.getStorageMode()==0>
package ${pub.getPKGCodeName()}.core.${item.getPSSystemModule().getCodeName()?lower_case}.service;
......@@ -194,6 +202,10 @@ public interface I${item.codeName}Service{
</#if>
</#list>
</#if>
<#comment>实体数据导入</#comment>
<#if hasDEImport>
JSONObject importData(List<${de.codeName}> entities,int batchSize,boolean isIgnoreError);
</#if>
</#macro>
<#comment>输出测试行为</#comment>
......
<#ibiztemplate>
TARGET=PSDATAENTITY
</#ibiztemplate>
<#comment>判断当前实体是否包含自定义行为</#comment>
<#assign hasServiceEx=false>
<#if item.getAllPSDEActions()??>
<#list item.getAllPSDEActions() as deaction>
<#if deaction.isEnableBackend() && deaction.getActionType()=='USERCUSTOM'>
<#assign hasServiceEx=true>
<#break>
<#elseif deaction.isEnableBackend() && deaction.getTestActionMode?? && deaction.getTestActionMode()?? && (deaction.getTestActionMode() ==1 || deaction.getTestActionMode() ==3)>
<#assign hasServiceEx=true>
<#break>
</#if>
</#list>
</#if>
<#if hasServiceEx && (de.getStorageMode()==1 || de.getStorageMode()==2 ||de.getStorageMode()==4||de.getStorageMode()==0 ) >
package ${pub.getPKGCodeName()}.core.extensions.service;
/**
* 扩展目录已变更,请到[${pub.getPKGCodeName()}.core.extensions.service.xxExService]中来进行扩展
* 若您之前有在当前目录下扩展过其它的service对象,请将扩展的代码移到新的扩展类中,并注释掉老的扩展类,防止Bean重复
*/
@Deprecated
public class ${item.codeName}ServiceEx{
}
</#if>
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<changeSet author="Think (generated)" id="1566027230162-1">
<preConditions onFail="MARK_RAN" >
<not>
<tableExists tableName="IBZDATAAUDIT" />
</not>
</preConditions>
<createTable remarks="数据审计" tableName="IBZDATAAUDIT">
<column name="DATAAUDITID" remarks="数据审计标识" type="VARCHAR2(100 BYTE)">
<constraints primaryKey="true" primaryKeyName="SYS_C00115093"/>
</column>
<column name="OPPERSONID" remarks="操作人标识" type="VARCHAR2(100 BYTE)"/>
<column name="OPPERSONNAME" remarks="操作人名称" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITTYPE" remarks="审计行为类型" type="VARCHAR2(60 BYTE)"/>
<column name="OPTIME" remarks="操作时间" type="date"/>
<column name="IPADDRESS" remarks="访问地址" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITOBJECTDATA" remarks="审计对象(表数据)" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITOBJECT" remarks="审计对象(表)" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITINFO" remarks="审计明细" type="CLOB"/>
<column name="ISDATACHANGED" remarks="审计数据是否发生变化" type="INTEGER"/>
</createTable>
</changeSet>
</databaseChangeLog>
......@@ -204,8 +204,10 @@ TARGET=PSDATAENTITY
<#comment>数据查询context条件转换</#comment>
<#function contextParamConvert contextParam>
<#comment>补充上下文的IN查询(in通过$获取参数,其余为#): IN (${srfdatacontext('cityid','{"defname":"CITYID","dename":"CITY"}')}) -->IN ( ${srf.srfdatacontext.cityid} ) </#comment>
<#assign resultParam=contextParam?replace("(IN|in) \\(\\$\\{srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)}\\)","$1 (\\$\{srf.$2.$3})","r")>
<#comment>平台配置格式替换${srfdatacontext('cityid','{"defname":"CITYID","dename":"CITY"}')} --> #{srf.srfdatacontext.cityid} </#comment>
<#assign resultParam=contextParam?replace("\\$\\{srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)}","#\{srf.$1.$2}","r")>
<#assign resultParam=resultParam?replace("\\$\\{srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)}","#\{srf.$1.$2}","r")>
<#comment>用户配置格式替换${srfdatacontext('cityid')} --> #{srf.srfdatacontext.cityid} </#comment>
<#assign resultParam=resultParam?replace("\\$\\{srf(datacontext|sessioncontext|webcontext)\\('(\\w+)'\\)}","#\{srf.$1.$2}","r")>
<#comment>将上下文参数转小写 #{srf.srfdatacontext.SRFORGID} --> #{srf.srfdatacontext.srforgid}</#comment>
......@@ -213,14 +215,6 @@ TARGET=PSDATAENTITY
<#list params as param>
<#assign resultParam=resultParam?replace(param,param?lower_case,'i')>
</#list>
<#--<#assign resultParam="">-->
<#--<#assign resultParam=contextParam?replace('$\{srfdatacontext(\'','#\{srf.datacontext.')?replace("','\\{[\\S]*}'\\)}","\\}","r")><#comment>数据上下文</#comment>-->
<#--<#assign resultParam=resultParam?replace('$\{srfsessioncontext(\'','#\{srf.sessioncontext.')?replace("','\\{[\\S]*}'\\)}","\\}","r")><#comment>用户上下文</#comment>-->
<#--<#assign resultParam=resultParam?replace('$\{srfwebcontext(\'','#\{srf.webcontext.')?replace("','\\{[\\S]*}'\\)}","\\}","r")><#comment>网页请求上下文</#comment>-->
<#--<#assign params=resultParam?matches('#\\{srf.[\\S]*}')>-->
<#--<#list params as param>-->
<#--<#assign resultParam=resultParam?replace(param,param?lower_case)><#comment>将上下文参数转小写</#comment>-->
<#--</#list>-->
<#return resultParam>
</#function>
......@@ -228,8 +222,10 @@ TARGET=PSDATAENTITY
<#function checkNullContextParamConvert contextParam>
<#comment>获取数据查询中的条件,并对条件进行转义 <![CDATA[ age <='20' ]]></#comment>
<#assign resultParam=contextParam?replace("(\\s+[\\w|\\.|\\`]+\\s*?)(<>|<=|<|>=|>)(\\s*[\\w|\\'|$\{}()'\",:\\\\]+\\s+?)"," <![CDATA[ $1$2$3 ]]> ","r")>
<#comment>补充上下文的IN查询(in通过$获取参数,其余为#)</#comment>
<#assign resultParam=resultParam?replace("<#assign _value=srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)><#if _value\\?length gt 0>(.*?)\\(\\$\\{_value}\\)<#else>1=1</#if>","<choose><when test=\"srf.$1.$2 != null\"> <![CDATA[ $4 \\$\{srf.$1.$2} ]]> </when><otherwise>1=1</otherwise></choose>","r")>
<#comment>获取模型中的空值条件,在条件外层补充mybatis判断条件 <choose><when test="srf.datacontext.name != null"> <![CDATA[ t1.`NAME` <= #{srf.datacontext.name} ]]> </when><otherwise>1=1</otherwise></choose> </#comment>
<#assign resultParam=resultParam?replace("<#assign _value=srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)><#if _value\\?length gt 0>(.*?)=(.*?)<#else>1=1</#if>","<choose><when test=\"srf.$1.$2 != null\"> <![CDATA[ $4= #\{srf.$1.$2} ]]> </when><otherwise>1=1</otherwise></choose>","r")>
<#assign resultParam=resultParam?replace("<#assign _value=srf(datacontext|sessioncontext|webcontext)\\('(\\w+)','(.*?)'\\)><#if _value\\?length gt 0>(.*?)\\$\\{_value}.*?<#else>1=1</#if>","<choose><when test=\"srf.$1.$2 != null\"> <![CDATA[ $4 #\{srf.$1.$2} ]]> </when><otherwise>1=1</otherwise></choose>","r")>
<#comment>对数据查询中的其余条件的context进行解析</#comment>
<#assign resultParam=contextParamConvert(resultParam)>
<#return resultParam>
......@@ -239,7 +235,7 @@ TARGET=PSDATAENTITY
<#function checkIgnoreNullvalueCond dataQueryCode>
<#if dataQueryCode.getPSDEDataQueryCodeConds()??>
<#list dataQueryCode.getPSDEDataQueryCodeConds() as dedqfieldcond>
<#if srfjavasqlcode(dedqfieldcond.getCustomCond())?matches("(.*?)srfdatacontext(.*?)\\\\\"ignoreempty\\\\\":true(.*?)")>
<#if srfjavasqlcode(dedqfieldcond.getCustomCond())?matches("(.*?)srf(datacontext|sessioncontext|webcontext)(.*?)\\\\\"ignoreempty\\\\\":true(.*?)")>
<#return true>
</#if>
</#list>
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign bDynamicDS=false>
<#list sys.getAllPSDataEntities() as entity>
<#if (entity.getStorageMode()==1 || entity.getStorageMode()==2) && entity.getDSLink()!='DEFAULT'>
<#assign bDynamicDS=true>
<#break>
</#if>
</#list>
<?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"
......@@ -81,6 +88,9 @@ TARGET=PSSYSTEM
<!--baomidou-jobs定时服务 -->
<baomidou-jobs.version>1.0.3</baomidou-jobs.version>
<!-- eureka微服务注册中心 -->
<eureka-client.version>2.2.1.RELEASE</eureka-client.version>
<#if sys.getAllPSSystemDBConfigs()??>
<#list sys.getAllPSSystemDBConfigs() as dbConfig>
<#if dbConfig.getDBType()=='MYSQL5'>
......@@ -337,6 +347,13 @@ TARGET=PSSYSTEM
<artifactId>h2</artifactId>
</dependency>
<!-- eureka服务注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>${r'${eureka-client.version}'}</version>
</dependency>
<#if sys.getAllPSSystemDBConfigs()??>
<#list sys.getAllPSSystemDBConfigs() as dbConfig>
<#if dbConfig.getDBType()=='MYSQL5'>
......@@ -363,6 +380,14 @@ TARGET=PSSYSTEM
</#list>
</#if>
<#if bDynamicDS>
<!-- mp动态数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
</dependency>
</#if>
</dependencies>
</project>
......@@ -2,20 +2,29 @@
TARGET=PSSYSSERVICEAPI
</#ibiztemplate>
<#assign httpPort = "8081">
<#assign timezone = "Asia/Shanghai">
<#if sysrun?? >
<#if sysrun.getPSDevSlnMSDepAPI()??>
<#if sysrun.getPSDevSlnMSDepAPI().getHttpPort()??>
<#assign httpPort = sysrun.getPSDevSlnMSDepAPI().getHttpPort()?c>
<#assign httpPort = sysrun.getPSDevSlnMSDepAPI().getHttpPort()?c>
</#if>
<#if sysrun.getPSDevSlnMSDepAPI().getUserParam("timezone","")?? && sysrun.getPSDevSlnMSDepAPI().getUserParam("timezone","")!="">
<#assign timezone = sysrun.getPSDevSlnMSDepAPI().getUserParam("timezone","")>
<#elseif sysrun.getPSDevSlnMSDepAPI().getPSDCMSPlatform().getUserParam("timezone","")?? && sysrun.getPSDevSlnMSDepAPI().getPSDCMSPlatform().getUserParam("timezone","")!="">
<#assign timezone = sysrun.getPSDevSlnMSDepAPI().getPSDCMSPlatform().getUserParam("timezone","")>
</#if>
</#if>
</#if>
FROM openjdk:8-jre-alpine
ENV SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
ENV TZ=${timezone} \
SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
IBIZ_SLEEP=0 \
JAVA_OPTS=""
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
CMD echo "The application will start in ${r'${IBIZ_SLEEP}'}s..." && \
sleep ${r'${IBIZ_SLEEP}'} && \
java ${r'${JAVA_OPTS}'} -Djava.security.egd=file:/dev/./urandom -jar /${pub.getCodeName()?lower_case}-provider-${api.getCodeName()?lower_case}.jar
......
<#ibiztemplate>
TARGET=PSSYSSERVICEAPI
</#ibiztemplate>
<#assign bDynamicDS=false>
<#list sys.getAllPSDataEntities() as entity>
<#if (entity.getStorageMode()==1 || entity.getStorageMode()==2) && entity.getDSLink()!='DEFAULT'>
<#assign bDynamicDS=true>
<#break>
</#if>
</#list>
package ${pub.getPKGCodeName()}.${item.codeName?lower_case};
import lombok.extern.slf4j.Slf4j;
......@@ -16,6 +23,8 @@ 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 java.util.List;
@Slf4j
......@@ -43,11 +52,16 @@ import java.util.List;
<#if bmogo==false>
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
</#if>
<#if bDynamicDS>
com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure.class
</#if>
})
@Import({
org.springframework.cloud.openfeign.FeignClientsConfiguration.class
})
@EnableFeignClients(basePackages = {"${pub.getPKGCodeName()}" })
@EnableAsync
@EnableScheduling
public class ${sys.codeName}${item.codeName}Application extends WebMvcConfigurerAdapter{
public static void main(String[] args) {
......
......@@ -13,6 +13,9 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@ConditionalOnClass(${item.codeName}RestConfiguration.class)
......@@ -27,6 +30,18 @@ public class ${item.codeName}AutoConfiguration implements ApplicationContextAwar
this.applicationContext = applicationContext;
}
@Bean("asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(2000);
executor.setKeepAliveSeconds(600);
executor.setThreadNamePrefix("asyncExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
// @Bean
// public ServletRegistrationBean ${item.codeName?lower_case}Servlet() {
// AnnotationConfigWebApplicationContext dispatcherServletConfiguration = new AnnotationConfigWebApplicationContext();
......
......@@ -5,6 +5,8 @@ TARGET=PSDESERVICEAPI
<#if de.isSubSysDE()==false && de.getAllPSDEServiceAPIs()??>
<#assign pubPkgCodeName = pub.getPKGCodeName()>
<#assign itemSysApiCodeNameLC = item.getPSSysServiceAPI().getCodeName()?lower_case>
<#assign itemSysApiCodeName = item.getPSSysServiceAPI().getCodeName()>
<#assign mappingName=itemSysApiCodeName+item.codeName+"Mapping">
package ${pubPkgCodeName}.${itemSysApiCodeNameLC}.mapping;
import org.mapstruct.*;
......@@ -13,7 +15,7 @@ import ${pubPkgCodeName}.${itemSysApiCodeNameLC}.dto.${item.getCodeName()}DTO;
import ${pub.getPKGCodeName()}.util.domain.MappingBase;
import org.mapstruct.factory.Mappers;
@Mapper(componentModel = "spring", uses = {},
@Mapper(componentModel = "spring", uses = {},implementationName="${mappingName}",
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public interface ${item.getCodeName()}Mapping extends MappingBase<${item.codeName}DTO, ${de.codeName}> {
......
......@@ -22,6 +22,14 @@ TARGET=PSDESERVICEAPI
<#if de.getPSDEFieldByPDT('ORGID',true)?? || de.getPSDEFieldByPDT('ORGSECTORID',true)?? || de.getPSDEFieldByPDT('CREATEMAN',true)?? >
<#assign hasDEPrefield=true>
</#if>
<#assign hasDEImport=false>
<#comment>实体数据导入</#comment>
<#if de.getAllPSDEDataImports?? && de.getAllPSDEDataImports()??>
<#list de.getAllPSDEDataImports() as deImport>
<#assign hasDEImport=true>
<#break>
</#list>
</#if>
package ${pubPkgCodeName}.${itemSysApiCodeNameLC}.rest;
import java.sql.Timestamp;
......@@ -250,11 +258,11 @@ public class ${itemCodeName}Resource {
<#else>
<@SecurityAnnotation deaction/>
@ApiOperation(value = "${deaction.getLogicName()}", tags = {"${deLogicName}" }, notes = "${deaction.getLogicName()}")
@RequestMapping(method = RequestMethod.${reqMtd}, value = "${fullPath}/{${itemCodeNameLC + keyCNLC}}/${deactionCodeName?lower_case}")
@RequestMapping(method = RequestMethod.${reqMtd}, value = "${fullPath}<#if deaction.getRequestParamType() == 'NOKEY'><#else>/{${itemCodeNameLC + keyCNLC}}</#if>/${deactionCodeName?lower_case}")
<#if de.getStorageMode()==4><#else> @Transactional</#if>
public ResponseEntity<${itemCodeName}DTO> ${deactionCodeName?uncap_first}(${id_etParams}) {
public ResponseEntity<${itemCodeName}DTO> ${deactionCodeName?uncap_first}(<#if deaction.getRequestParamType() == 'NOKEY'>${id_etParams4}<#else>${id_etParams}</#if>) {
${deCodeName} domain = ${itemCodeNameLC}Mapping.toDomain(${itemCodeNameLC}dto);
domain.set${dePKCodeName}(${itemCodeNameLC + keyCNLC});
<#if deaction.getRequestParamType() == 'NOKEY'><#else>domain.set${dePKCodeName}(${itemCodeNameLC + keyCNLC});</#if>
domain = ${deCodeNameLC}Service.${srfmethodname(deactionCodeName)}(domain);
${itemCodeNameLC}dto = ${itemCodeNameLC}Mapping.toDto(domain);
return ResponseEntity.status(HttpStatus.OK).body(${itemCodeNameLC}dto);
......@@ -557,9 +565,9 @@ public class ${itemCodeName}Resource {
<#else>
<@SecurityAnnotation deaction/>
@ApiOperation(value = "${byTagParams}${deLogicName}", tags = {"${deLogicName}" }, notes = "${byTagParams}${deLogicName}")
@RequestMapping(method = RequestMethod.${reqMtd}, value = "${fullPath}/{${itemCodeNameLC + keyCNLC}}/${deactionCodeName?lower_case}")
@RequestMapping(method = RequestMethod.${reqMtd}, value = "${fullPath}<#if deaction.getRequestParamType() == 'NOKEY'><#else>/{${itemCodeNameLC + keyCNLC}}</#if>/${deactionCodeName?lower_case}")
<#if de.getStorageMode()==4><#else> @Transactional</#if>
public ResponseEntity<${itemCodeName}DTO> ${deactionCodeName?uncap_first}${byParams}(${id_etParams}) {
public ResponseEntity<${itemCodeName}DTO> ${deactionCodeName?uncap_first}${byParams}(<#if deaction.getRequestParamType() == 'NOKEY'>${id_etParams4}<#else>${id_etParams}</#if>) {
${deCodeName} domain = ${itemCodeNameLC}Mapping.toDomain(${itemCodeNameLC}dto);
${parentSetParams}
domain = ${deCodeNameLC}Service.${srfmethodname(deactionCodeName)}(domain) ;
......@@ -614,7 +622,37 @@ public class ${itemCodeName}Resource {
</#if>
</#list>
</#if>
<#-- 关系接口 end -->
<#comment>实体数据导入</#comment>
<#if hasDEImport>
<#list de.getAllPSDEDataImports() as deImport>
@Autowired
${pub.getPKGCodeName()}.core.${de.getPSSystemModule().codeName?lower_case}.mapping.${deCodeName}${deImport.codeName} ${deImport.codeName?lower_case}ImpMapping;
</#list>
@RequestMapping(method = RequestMethod.POST, value = "/${srfpluralize(itemCodeNameLC)}/import")
public ResponseEntity<JSONObject> importData(@RequestParam(value = "config") String config , @RequestBody List<${deCodeName}> dtos){
JSONObject rs=new JSONObject();
if(dtos.size()==0){
rs.put("rst", 1);
rs.put("msg", "未传入内容");
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(rs);
}
else{
<#list de.getAllPSDEDataImports() as deImport>
<#if deImport_index==0>
if(config.equals("${deImport.codeName}")){
rs=${deCodeNameLC}Service.importData(${deImport.codeName?lower_case}ImpMapping.toDomain(dtos),${deImport.getBatchSize()?c},${deImport.isIgnoreError()?c});
}
<#else>
else if(config.equals("${deImport.codeName}")){
rs=${deCodeNameLC}Service.importData(${deImport.codeName?lower_case}ImpMapping.toDomain(dtos),${deImport.getBatchSize()?c},${deImport.isIgnoreError()?c});
}
</#if>
</#list>
return ResponseEntity.status(HttpStatus.OK).body(rs);
}
}
</#if>
}
</#if>
</#if>
......@@ -784,9 +822,9 @@ public class ${itemCodeName}Resource {
<#else>
<@SecurityAnnotation deaction/>
@ApiOperation(value = "${deaction.getLogicName()}", tags = {"${deLogicName}" }, notes = "${deaction.getLogicName()}")
@RequestMapping(method = RequestMethod.${reqMtd}, value = "${fullPath}/{${itemCodeNameLC + keyCNLC}}/${deactionCodeName?lower_case}/test")
@RequestMapping(method = RequestMethod.${reqMtd}, value = "${fullPath}<#if deaction.getRequestParamType() == 'NOKEY'><#else>/{${itemCodeNameLC + keyCNLC}}</#if>/${deactionCodeName?lower_case}/test")
<#if de.getStorageMode()==4><#else> @Transactional</#if>
public ResponseEntity<Boolean> test${deactionCodeName?cap_first}(${id_etParams}) {
public ResponseEntity<Boolean> test${deactionCodeName?cap_first}(<#if deaction.getRequestParamType() == 'NOKEY'>${id_etParams4}<#else>${id_etParams}</#if>) {
${deCodeName} domain = ${itemCodeNameLC}Mapping.toDomain(${itemCodeNameLC}dto);
return ResponseEntity.status(HttpStatus.OK).body(${deCodeNameLC}Service.test${srfmethodname(deactionCodeName)?cap_first}(domain));
}
......
......@@ -3,6 +3,6 @@ TARGET=PSSYSSERVICEAPI
</#ibiztemplate>
spring:
profiles:
include: sys , ${item.codeName?lower_case}-prod
include: sys ,nacos, ${item.codeName?lower_case}-prod
application:
name: ${sys.getCodeName()?lower_case}-${item.getCodeName()?lower_case}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD})
public @interface Audit
{
}
......@@ -19,6 +19,11 @@ public @interface DEField
* @return
*/
String name() default "";
/**
* 属性名称
* @return
*/
String value() default "";
/**
* 是否为数据主键
* @return
......@@ -29,29 +34,40 @@ public @interface DEField
* @return
*/
String defaultValue() default "";
/**
* 属性类型
* @return
*/
String fieldType() default"";
/**
* 默认值类型
* @return
*/
DEFieldDefaultValueType defaultValueType() default DEFieldDefaultValueType.NONE;
/**
* 预置属性类型
* @return
*/
DEPredefinedFieldType preType() default DEPredefinedFieldType.NONE;
/**
/**
* 逻辑删除有效值
* @return
*/
String logicval() default "";
/**
* 逻辑删除无效值
* @return
*/
String logicdelval() default "";
/**
* 代码表
* @return
*/
String dict() default "";
/**
* 日期格式化
* @return
*/
String format() default "";
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.aspect;
import lombok.SneakyThrows;
import ${pub.getPKGCodeName()}.util.annotation.Audit;
import ${pub.getPKGCodeName()}.util.domain.EntityBase;
import ${pub.getPKGCodeName()}.util.helper.DEFieldCacheMap;
import ${pub.getPKGCodeName()}.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(* ${pub.getPKGCodeName()}.core.*.service.*.create(..))")
@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];
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);
return;
}
/**
* 实体数据更新切面,在成功更新数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* 使用环切【@Around】获取到更新前后的实体数据并进行差异比较,并将差异内容记入审计日志内
* @param point
*/
@Around("execution(* ${pub.getPKGCodeName()}.core.*.service.*.update(..))")
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];
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;
}
/**
* 实体数据更新切面,在成功更新数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* 使用环切【@Around】获取要删除的完整数据,并将审计属性相关信息记录到审计日志中
* @param point
* @return
* @throws Throwable
*/
@Around("execution(* ${pub.getPKGCodeName()}.core.*.service.*.remove(..))")
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
......@@ -98,9 +98,9 @@ public class DEFieldDefaultValueAspect
for(Object item:(List)obj) {
if(item instanceof EntityBase) {
if(deFields==null) {
deFields = DEFieldCacheMap.getDEFields(obj.getClass());
deFields = DEFieldCacheMap.getDEFields(item.getClass());
curUser = AuthenticationUser.getAuthenticationUser();
keyField=DEFieldCacheMap.getDEKeyField(obj.getClass());
keyField=DEFieldCacheMap.getDEKeyField(item.getClass());
if(StringUtils.isEmpty(keyField))
return true;
}
......
......@@ -50,14 +50,16 @@ public class VersionCheckAspect
@Before("execution(* ${pub.getPKGCodeName()}.*.rest.*.updateBy*(..)) && @annotation(versionCheck)")
public void BeforeUpdateBy(JoinPoint point, VersionCheck versionCheck){
Object[] args = point.getArgs();
Object id=args[1];
Object dto=args[2];
if(ObjectUtils.isEmpty(id) || ObjectUtils.isEmpty(dto))
return;
String versionField=versionCheck.versionfield();
if(StringUtils.isEmpty(versionField))
return;
versionCheck(versionCheck,point.getTarget(),dto,id);
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 ){
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache;
public class CacheConfig {
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.layering;
public class LayeringCache {
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.layering;
public class LayeringCacheManager {
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.redis;
public class CustomizedRedisCache {
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.redis;
<#--import com.alibaba.fastjson.JSON;-->
<#--import com.alibaba.fastjson.serializer.SerializerFeature;-->
<#--import org.springframework.data.redis.serializer.RedisSerializer;-->
<#--import org.springframework.data.redis.serializer.SerializationException;-->
<#--import java.nio.charset.Charset;-->
public class FastJsonRedisSerializer
{
<#--public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");-->
<#--private Class<T> clazz;-->
<#--public FastJsonRedisSerializer(Class<T> clazz) {-->
<#--super();-->
<#--this.clazz = clazz;-->
<#--}-->
<#--@Override-->
<#--public byte[] serialize(T t) throws SerializationException-->
<#--{-->
<#--if (t == null) {-->
<#--return new byte[0];-->
<#--}-->
<#--return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);-->
<#--}-->
<#--@Override-->
<#--public T deserialize(byte[] bytes) throws SerializationException-->
<#--{-->
<#--if (bytes == null || bytes.length <= 0) {-->
<#--return null;-->
<#--}-->
<#--String str = new String(bytes, DEFAULT_CHARSET);-->
<#--return (T) JSON.parseObject(str, clazz);-->
<#--}-->
}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.redis;
public class KryoRedisSerializer{
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.redis;
public class RedisConfig {
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.cache.redis;
public class StringRedisSerializer {
}
......@@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import java.util.Map;
import java.util.Set;
@FeignClient(value = "ibzou-api",fallback = IBZOUFallback.class)
@FeignClient(value = "${r'${ibiz.ref.service.ou:ibzou-api}'}",fallback = IBZOUFallback.class)
public interface IBZOUFeignClient
{
/**
......
......@@ -10,7 +10,7 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import com.alibaba.fastjson.JSONObject;
@FeignClient(value = "ibzuaa-api",fallback = IBZUAAFallback.class)
@FeignClient(value = "${r'${ibiz.ref.service.uaa:ibzuaa-api}'}",fallback = IBZUAAFallback.class)
public interface IBZUAAFeignClient
{
/**
......
......@@ -7,7 +7,7 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@FeignClient(value = "ibzwf-api",fallback = IBZWFFallback.class)
@FeignClient(value = "${r'${ibiz.ref.service.wf:ibzwf-api}'}",fallback = IBZWFFallback.class)
public interface IBZWFFeignClient
{
@RequestMapping(method = RequestMethod.GET, value = "/{system}-app-{appname}/{entity}/process-definitions/{processDefinitionKey}/usertasks/{taskDefinitionKey}/tasks")
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Objects;
/**
* 实体[DataAudit] 数据对象
*/
@TableName(value = "IBZDATAAUDIT")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class IBZDataAudit implements Serializable{
@TableId(value= "dataauditid",type=IdType.UUID)//指定主键生成策略
private String dataauditid;
private String dataauditname;
private String oppersonid;
private String oppersonname;
private String audittype;
private Timestamp optime;
private String ipaddress;
private String auditinfo;
private Object auditobjectdata;
private String auditobject;
private int isdatachanged;
}
\ No newline at end of file
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign bDynamicDS=false>
<#list sys.getAllPSDataEntities() as entity>
<#if (entity.getStorageMode()==1 || entity.getStorageMode()==2) && entity.getDSLink()!='DEFAULT'>
<#assign bDynamicDS=true>
<#break>
</#if>
</#list>
package ${pub.getPKGCodeName()}.util.domain;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
<#if bDynamicDS>
@ConfigurationProperties(prefix = "spring.datasource.dynamic.datasource.master")
<#else>
@ConfigurationProperties(prefix = "spring.datasource")
@Data
</#if>
public class LiquibaseProp{
private String url;
......
......@@ -4,6 +4,7 @@ TARGET=PSSYSTEM
package ${pub.getPKGCodeName()}.util.helper;
import ${pub.getPKGCodeName()}.util.annotation.Audit;
import ${pub.getPKGCodeName()}.util.annotation.DEField;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
......@@ -25,6 +26,8 @@ public class DEFieldCacheMap {
private static Hashtable<String, Hashtable<String,DEField>> cacheDEField = new Hashtable<>();
private static Hashtable<String, Hashtable<String,Audit>> cacheAuditField = new Hashtable<>();
private static Hashtable<String, String> cacheDEKeyField = new Hashtable<>();
private static Object objLock1=new Object();
......@@ -47,6 +50,7 @@ public class DEFieldCacheMap {
List<Field> list=new ArrayList<Field>();
Hashtable<String,String> keys=new Hashtable<String,String>();
Hashtable<String,DEField> defields=new Hashtable<>();
Hashtable<String, Audit> auditfields=new Hashtable<>();
Hashtable<String,String> dekeyfields=new Hashtable<>();
Field[] fields=clazz.getDeclaredFields();
for(Field field:fields){
......@@ -54,16 +58,21 @@ public class DEFieldCacheMap {
list.add(field);
keys.put(field.getName().toLowerCase(),field.getName());
DEField deField=field.getAnnotation(DEField.class);
Audit auditField=field.getAnnotation(Audit.class);
if(!ObjectUtils.isEmpty(deField)) {
defields.put(field.getName(),deField);
if(deField.isKeyField())
cacheDEKeyField.put(className,field.getName());
}
if(!ObjectUtils.isEmpty(auditField)) {
auditfields.put(field.getName(),auditField);
}
}
cacheMap.put(className, result);
cacheList.put(className,list);
cacheKey.put(className,keys);
cacheDEField.put(className,defields);
cacheAuditField.put(className,auditfields);
return result;
}
}
......@@ -100,6 +109,23 @@ public class DEFieldCacheMap {
}
}
/**
* 从缓存中查询审计属性集合
* @param
* @return
*/
public static <T> Hashtable<String,Audit> getAuditFields(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheAuditField.containsKey(className))
return cacheAuditField.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheAuditField.get(className);
}
}
/**
* 从缓存中查询实体对象主键
* @param
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import ${pub.getPKGCodeName()}.util.domain.IBZDataAudit;
public interface IBZDataAuditMapper extends BaseMapper<IBZDataAudit> {
}
\ No newline at end of file
......@@ -68,6 +68,10 @@ public class AuthenticationUser implements UserDetails
@JsonIgnore
private Map<String,Object> userSessionParam;//用户自定义session
private Map<String, Set<String>> orgInfo;//上下级组织信息
private String porg;
private String sorg;
private String pdept;
private String sdept;
@JsonIgnore
......@@ -136,6 +140,10 @@ public class AuthenticationUser implements UserDetails
sessionParams.put("srflocale", this.getLang());
sessionParams.put("srftimezone", "");
sessionParams.put("srfusercode", this.getUsercode());
sessionParams.put("srfporg", this.getPorg());
sessionParams.put("srfsorg", this.getSorg());
sessionParams.put("srfpdept", this.getPdept());
sessionParams.put("srfsdept", this.getSdept());
}
return this.sessionParams;
}
......@@ -146,6 +154,26 @@ public class AuthenticationUser implements UserDetails
return new HashMap<>();
}
public void setOrgInfo(Map<String, Set<String>> orgInfo) {
this.orgInfo = orgInfo;
if(!ObjectUtils.isEmpty(orgInfo) && !ObjectUtils.isEmpty(orgInfo.get("parentorg"))){
porg=(String.format("'%s'",String.join("','",orgInfo.get("parentorg"))));
this.getSessionParams().put("srfporg",porg);
}
if(!ObjectUtils.isEmpty(orgInfo) && !ObjectUtils.isEmpty(orgInfo.get("suborg")) ){
sorg=(String.format("'%s'",String.join("','",orgInfo.get("suborg"))));
this.getSessionParams().put("srfsorg",sorg);
}
if(!ObjectUtils.isEmpty(orgInfo) && !ObjectUtils.isEmpty(orgInfo.get("parentdept"))){
pdept=(String.format("'%s'",String.join("','",orgInfo.get("parentdept"))));
this.getSessionParams().put("srfpdept",pdept);
}
if(!ObjectUtils.isEmpty(orgInfo) && !ObjectUtils.isEmpty(orgInfo.get("subdept"))){
sdept=(String.format("'%s'",String.join("','",orgInfo.get("subdept"))));
this.getSessionParams().put("srfsdept",sdept);
}
}
public void setPermissionList(JSONObject permissionList) {
this.permissionList = permissionList;
if(authorities==null && permissionList !=null){
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
package ${pub.getPKGCodeName()}.util.service;
import ${pub.getPKGCodeName()}.util.annotation.Audit;
import ${pub.getPKGCodeName()}.util.domain.EntityBase;
import org.springframework.scheduling.annotation.Async;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 实体[DataAudit] 服务对象接口
*/
public interface IBZDataAuditService {
@Async("asyncExecutor")
void createAudit(HttpServletRequest request,EntityBase entity,Object idValue,Map<String, Audit> auditFields);
@Async("asyncExecutor")
void updateAudit(HttpServletRequest request, EntityBase beforeEntity, Object serviceObj, Object idValue, Map<String, Audit> auditFields);
@Async("asyncExecutor")
void removeAudit(HttpServletRequest request,EntityBase entity,Object idValue,Map<String, Audit> auditFields);
}
\ No newline at end of file
......@@ -32,6 +32,8 @@ public class FeignRequestInterceptor implements RequestInterceptor {
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
if(name.equalsIgnoreCase("transfer-encoding"))
continue;
String values = request.getHeader(name);
requestTemplate.header(name, values);
}
......
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign eurekaUrl = "http://127.0.0.1:8762/eureka/" >
<#comment>前端应用微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepApps()??>
<#list sys.getAllPSDevSlnMSDepApps() as depApp>
<#if depApp.getPSDCMSPlatform()??>
<#assign appPlatform=depApp.getPSDCMSPlatform()>
<#if appPlatform.getUserParam("eureka","http://127.0.0.1:8762/eureka/")??>
<#assign eurekaUrl = appPlatform.getUserParam("eureka","http://127.0.0.1:8762/eureka/")>
</#if>
<#break>
</#if>
</#list>
</#if>
<#comment>服务接口微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepAPIs()??>
<#list sys.getAllPSDevSlnMSDepAPIs() as depSysApi>
<#if depSysApi.getPSDCMSPlatform()?? >
<#assign sysApiPlatform=depSysApi.getPSDCMSPlatform()>
<#if sysApiPlatform.getUserParam("eureka","http://127.0.0.1:8762/eureka/")??>
<#assign eurekaUrl = sysApiPlatform.getUserParam("eureka","http://127.0.0.1:8762/eureka/")>
</#if>
<#break>
</#if>
</#list>
</#if>
#eureka配置中心
spring:
cloud:
nacos:
discovery:
enabled: false
eureka:
client:
enabled: true
serviceUrl:
defaultZone: ${eurekaUrl}
<#ibiztemplate>
TARGET=PSSYSTEM
</#ibiztemplate>
<#assign nacosUrl = "127.0.0.1:8848" >
<#comment>前端应用微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepApps()??>
<#list sys.getAllPSDevSlnMSDepApps() as depApp>
<#if depApp.getPSDCMSPlatform()??>
<#assign appPlatform=depApp.getPSDCMSPlatform()>
<#if appPlatform.getUserParam("nacos","127.0.0.1:8848")??>
<#assign nacosUrl = appPlatform.getUserParam("nacos","127.0.0.1:8848")>
</#if>
<#break>
</#if>
</#list>
</#if>
<#comment>服务接口微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepAPIs()??>
<#list sys.getAllPSDevSlnMSDepAPIs() as depSysApi>
<#if depSysApi.getPSDCMSPlatform()?? >
<#assign sysApiPlatform=depSysApi.getPSDCMSPlatform()>
<#if sysApiPlatform.getUserParam("nacos","127.0.0.1:8848")??>
<#assign nacosUrl = sysApiPlatform.getUserParam("nacos","127.0.0.1:8848")>
</#if>
<#break>
</#if>
</#list>
</#if>
#nacos配置中心
spring:
cloud:
nacos:
discovery:
server-addr: ${nacosUrl}
enabled: true
eureka:
client:
enabled: false
......@@ -2,7 +2,6 @@
TARGET=PSSYSTEM
</#ibiztemplate>
<#comment>通用配置文件</#comment>
<#assign nacosUrl = "127.0.0.1:8848" >
<#assign redisHost = "127.0.0.1" >
<#assign redisPort = "6379" >
<#assign redisDataBase = "0" >
......@@ -10,14 +9,18 @@ TARGET=PSSYSTEM
<#assign dbPassWord="root">
<#assign dbUrl="jdbc:mysql://127.0.0.1:3306/"+sys.name+"?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true">
<#assign dbDriver="com.mysql.jdbc.Driver">
<#assign bDynamicDS=false>
<#list sys.getAllPSDataEntities() as entity>
<#if (entity.getStorageMode()==1 || entity.getStorageMode()==2) && entity.getDSLink()!='DEFAULT'>
<#assign bDynamicDS=true>
<#break>
</#if>
</#list>
<#comment>前端应用微服务平台配置</#comment>
<#if sys.getAllPSDevSlnMSDepApps()??>
<#list sys.getAllPSDevSlnMSDepApps() as depApp>
<#if depApp.getPSDCMSPlatform()??>
<#assign appPlatform=depApp.getPSDCMSPlatform()>
<#if appPlatform.getUserParam("nacos","127.0.0.1:8848")??>
<#assign nacosUrl = appPlatform.getUserParam("nacos","127.0.0.1:8848")>
</#if>
<#if appPlatform.getUserParam("spring.redis.host","127.0.0.1")??>
<#assign redisHost = appPlatform.getUserParam("spring.redis.host","127.0.0.1")>
</#if>
......@@ -36,9 +39,6 @@ TARGET=PSSYSTEM
<#list sys.getAllPSDevSlnMSDepAPIs() as depSysApi>
<#if depSysApi.getPSDCMSPlatform()?? >
<#assign sysApiPlatform=depSysApi.getPSDCMSPlatform()>
<#if sysApiPlatform.getUserParam("nacos","127.0.0.1:8848")??>
<#assign nacosUrl = sysApiPlatform.getUserParam("nacos","127.0.0.1:8848")>
</#if>
<#if sysApiPlatform.getUserParam("spring.redis.host","127.0.0.1")??>
<#assign redisHost = sysApiPlatform.getUserParam("spring.redis.host","127.0.0.1")>
</#if>
......@@ -122,12 +122,8 @@ TARGET=PSSYSTEM
</#if>
</#list>
</#if>
#nacos配置中心、数据源
#缓存、数据源
spring:
cloud:
nacos:
discovery:
server-addr: ${nacosUrl}
cache:
redis:
time-to-live: 3600
......@@ -144,32 +140,11 @@ spring:
max-wait: 300ms
max-idle: 16
min-idle: 8
datasource:
username: ${dbUserName}
password: '${dbPassWord}'
url: ${dbUrl}
driver-class-name: ${dbDriver}
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
isSyncDBSchema: false
defaultSchema: ${dbUserName}
conf: classpath:liquibase/master.xml
<#if bDynamicDS>
<@dynamicDatasourceConfig/>
<#else>
<@singleDatasourceConfig/>
</#if>
#Mybatis-plus配置
mybatis-plus:
......@@ -234,3 +209,82 @@ server:
mime-types: application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
min-response-size: 10240
<#macro singleDatasourceConfig>
datasource:
username: ${dbUserName}
password: '${dbPassWord}'
url: ${dbUrl}
driver-class-name: ${dbDriver}
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
isSyncDBSchema: false
defaultSchema: ${dbUserName}
conf: classpath:liquibase/master.xml
</#macro>
<#macro dynamicDatasourceConfig>
datasource:
dynamic:
druid: #以下是全局默认值,可以全局更改
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
datasource:
master:
username: ${dbUserName}
password: '${dbPassWord}'
url: ${dbUrl}
driver-class-name: ${dbDriver}
conf: classpath:liquibase/master.xml
isSyncDBSchema: false
defaultSchema: ${dbUserName}
<#list sys.getAllPSDataEntities() as entity>
<#if (entity.getStorageMode()==1 || entity.getStorageMode()==2) && entity.getDSLink()!='DEFAULT'>
<#assign dbLink=entity.getDSLink()?lower_case>
<#if !P.exists('dynamicDatasource',dbLink)>
${dbLink}:
username: ${dbUserName}
password: '${dbPassWord}'
url: ${dbUrl}
driver-class-name: ${dbDriver}
conf: classpath:liquibase/master.xml
isSyncDBSchema: false
defaultSchema: ${dbUserName}
</#if>
</#if>
</#list>
</#macro>
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册