提交 9744b5dd 编写于 作者: sq3536's avatar sq3536

update

上级 9e083037
package cn.ibizlab.codegen.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.model.dataentity.action.IPSDEAction;
import net.ibizsys.model.dataentity.action.IPSDELogicAction;
import net.ibizsys.model.dataentity.action.IPSDEScriptAction;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.util.HashSet;
import java.util.Set;
@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class ActionModel extends BaseModel{
public ActionModel(EntityModel entityModel, IPSDEAction action)
{
this.opt=action;
this.entity=entityModel;
this.setCodeName(action.getCodeName());
this.setName(action.getName());
this.setId(String.format("%1$s-%2$s",entity.getCodeName(),action.getCodeName()));
}
public IPSDEAction getDEAction()
{
return (IPSDEAction)opt;
}
private EntityModel entity;
public Set<String> getLogics()
{
Set<String> validLogic=new HashSet<>();
if(!ObjectUtils.isEmpty(getDEAction().getBeforePSDEActionLogics()))
{
getDEAction().getBeforePSDEActionLogics().forEach(logic->{
if ((logic.isValid() && logic.isInternalLogic() && logic.getPSDELogic().isEnableBackend()) ||
(logic.getDstPSDE()!=null && logic.getDstPSDEAction()!=null && (!(logic.getDstPSDEAction() instanceof IPSDEScriptAction))))
validLogic.add((entity.codeName+this.codeName).toLowerCase()+"before.bpmn");
});
}
if(!ObjectUtils.isEmpty(getDEAction().getAfterPSDEActionLogics()))
{
getDEAction().getAfterPSDEActionLogics().forEach(logic->{
if ((logic.isValid() && logic.isInternalLogic() && logic.getPSDELogic().isEnableBackend()) ||
(logic.getDstPSDE()!=null && logic.getDstPSDEAction()!=null && (!(logic.getDstPSDEAction() instanceof IPSDEScriptAction))))
validLogic.add((entity.codeName+this.codeName).toLowerCase()+"after.bpmn");
});
}
if("DELOGIC".equalsIgnoreCase(getDEAction().getActionType())&&getDEAction() instanceof IPSDELogicAction)
{
validLogic.add((entity.codeName+this.codeName).toLowerCase()+"exec.bpmn");
}
return validLogic;
}
}
package cn.ibizlab.codegen.model;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.model.dataentity.action.IPSDEAction;
@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class DEActionModel extends BaseModel{
public DEActionModel(EntityModel entityModel, IPSDEAction action)
{
this.opt=action;
this.entity=entityModel;
this.setCodeName(action.getCodeName());
this.setName(action.getName());
this.setId(String.format("%1$s-%2$s",entity.getCodeName(),action.getCodeName()));
}
private EntityModel entity;
}
package cn.ibizlab.codegen.model; package cn.ibizlab.codegen.model;
import cn.ibizlab.codegen.utils.DataObject; import cn.ibizlab.codegen.utils.DataObject;
import cn.ibizlab.codegen.utils.Inflector;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
...@@ -297,9 +294,12 @@ public class EntityModel extends BaseModel { ...@@ -297,9 +294,12 @@ public class EntityModel extends BaseModel {
public List<FieldModel> getUnionKeyFields() { public List<FieldModel> getUnionKeyFields() {
if(fields!=null&&unionKeyFields==null) { if(fields!=null&&unionKeyFields==null) {
unionKeyFields = new ArrayList<>(); unionKeyFields = new ArrayList<>();
for (FieldModel fieldModel : fields) if(getDataEntity().getUnionKeyValuePSDEFields()!=null)
if (fieldModel.isUnionKeyField()) {
unionKeyFields.add(fieldModel); getDataEntity().getUnionKeyValuePSDEFields().forEach(def->{
unionKeyFields.add(getFieldMap().get(def.getCodeName()));
});
}
} }
return unionKeyFields; return unionKeyFields;
} }
...@@ -319,9 +319,9 @@ public class EntityModel extends BaseModel { ...@@ -319,9 +319,9 @@ public class EntityModel extends BaseModel {
} }
private Map<String,DEActionModel> actions; private Map<String, ActionModel> actions;
public EntityModel addAction(DEActionModel action) public EntityModel addAction(ActionModel action)
{ {
if(actions==null) if(actions==null)
actions=new LinkedHashMap<>(); actions=new LinkedHashMap<>();
...@@ -334,7 +334,7 @@ public class EntityModel extends BaseModel { ...@@ -334,7 +334,7 @@ public class EntityModel extends BaseModel {
add("createbatch");add("savebatch");add("updatebatch");add("removebatch"); add("createbatch");add("savebatch");add("updatebatch");add("removebatch");
}}; }};
public List<DEActionModel> getExtActions() public List<ActionModel> getExtActions()
{ {
return actions.values().stream().filter(s->!ignoActions.contains(s.getCodeName().toLowerCase())).collect(Collectors.toList()); return actions.values().stream().filter(s->!ignoActions.contains(s.getCodeName().toLowerCase())).collect(Collectors.toList());
} }
...@@ -421,6 +421,63 @@ public class EntityModel extends BaseModel { ...@@ -421,6 +421,63 @@ public class EntityModel extends BaseModel {
return false; return false;
} }
public boolean isHasDupCheck()
{
if(this.getDefaultDataQuery()==null)
return false;
if(getDataEntity().getStorageMode()!=1&&getDataEntity().getStorageMode()!=2)
return false;
for(IPSDEField field:getDataEntity().getAllPSDEFields())
{
if("ALL".equalsIgnoreCase(field.getDupCheckMode()))
return true;
}
return false;
}
public boolean isNeedTypeHandler()
{
if(!"NONE".equalsIgnoreCase(getStorage()))
return false;
if(isHasReferences())
{
for(RelationshipModel ref:getReferences())
{
if(ref.getDer() instanceof IPSDER1N && ref.getRelEntity().getStorage().equalsIgnoreCase("SQL"))
{
IPSDEField def=((IPSDER1N) ref.getDer()).getPSOne2ManyDataDEField();
if(def!=null&&def.isPhisicalDEField())
return true;
}
}
}
return false;
}
public List getMqPublishers()
{
List publishers=new ArrayList();
if(getDataEntity().getAllPSDEDataSyncs()!=null)
{
getDataEntity().getAllPSDEDataSyncs().forEach(dataSync->{
if(dataSync.getOutPSSysDataSyncAgent()!=null&&dataSync.getEventType()!=0)
{
Map map=new HashMap();
map.put("dataSync",dataSync);
Set<String> monitors=new LinkedHashSet<>();
map.put("monitors",monitors);
if((dataSync.getEventType()&1)>0)
monitors.add("create");
if((dataSync.getEventType()&2)>0)
monitors.add("update");
if((dataSync.getEventType()&4)>0)
monitors.add("remove");
publishers.add(map);
}
});
}
return publishers;
}
private Map<String, POSchema> poSchemas; private Map<String, POSchema> poSchemas;
...@@ -851,7 +908,7 @@ public class EntityModel extends BaseModel { ...@@ -851,7 +908,7 @@ public class EntityModel extends BaseModel {
{ {
this.getDataEntity().getAllPSDEActions().forEach(item->{ this.getDataEntity().getAllPSDEActions().forEach(item->{
String tag=item.getCodeName().toLowerCase(); String tag=item.getCodeName().toLowerCase();
addAction(new DEActionModel(this,item)); addAction(new ActionModel(this,item));
}); });
} }
......
...@@ -6,6 +6,7 @@ import lombok.NoArgsConstructor; ...@@ -6,6 +6,7 @@ import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import net.ibizsys.model.IPSSystem; import net.ibizsys.model.IPSSystem;
import net.ibizsys.model.codelist.IPSCodeList;
import net.ibizsys.model.database.IPSDEFDTColumn; import net.ibizsys.model.database.IPSDEFDTColumn;
import net.ibizsys.model.dataentity.IPSDataEntity; import net.ibizsys.model.dataentity.IPSDataEntity;
import net.ibizsys.model.dataentity.defield.IPSDEField; import net.ibizsys.model.dataentity.defield.IPSDEField;
...@@ -94,6 +95,7 @@ public class SystemModel extends BaseModel { ...@@ -94,6 +95,7 @@ public class SystemModel extends BaseModel {
private Set<String> mqSubscribes; private Set<String> mqSubscribes;
private Map<String,EntityModel> entitiesMap; private Map<String,EntityModel> entitiesMap;
public synchronized Map<String, EntityModel> getEntitiesMap() { public synchronized Map<String, EntityModel> getEntitiesMap() {
if(entitiesMap==null) { if(entitiesMap==null) {
...@@ -112,8 +114,11 @@ public class SystemModel extends BaseModel { ...@@ -112,8 +114,11 @@ public class SystemModel extends BaseModel {
if(entity.getAllPSDEDataSyncs()!=null) if(entity.getAllPSDEDataSyncs()!=null)
{ {
entity.getAllPSDEDataSyncs().forEach(sync->{ entity.getAllPSDEDataSyncs().forEach(sync->{
if(mqSubscribes==null) mqSubscribes=new LinkedHashSet<>(); if(sync.getInPSSysDataSyncAgent()!=null)
mqSubscribes.add(sync.getCodeName()); {
if(mqSubscribes==null) mqSubscribes=new LinkedHashSet<>();
mqSubscribes.add(sync.getCodeName());
}
}); });
} }
entitiesMap.put(entity.getCodeName(),new EntityModel(this,entity)); entitiesMap.put(entity.getCodeName(),new EntityModel(this,entity));
...@@ -122,6 +127,24 @@ public class SystemModel extends BaseModel { ...@@ -122,6 +127,24 @@ public class SystemModel extends BaseModel {
return entitiesMap; return entitiesMap;
} }
public boolean isHasMsgTemplate()
{
return !ObjectUtils.isEmpty(getSystem().getAllPSSysMsgTempls());
}
public boolean isHasRuntimeDict()
{
if(getSystem().getAllPSCodeLists()!=null)
{
for(IPSCodeList dict:getSystem().getAllPSCodeLists())
{
if("RUNTIME".equalsIgnoreCase(dict.getPredefinedType()))
return true;
}
}
return false;
}
public Collection<EntityModel> getEntities(){ public Collection<EntityModel> getEntities(){
return getEntitiesMap().values(); return getEntitiesMap().values();
} }
......
...@@ -19,8 +19,6 @@ ...@@ -19,8 +19,6 @@
<modules> <modules>
<!-- dependencies --> <!-- dependencies -->
<module>{{projectName}}-dependencies</module> <module>{{projectName}}-dependencies</module>
<!-- utils -->
<module>{{projectName}}-util</module>
<!-- cores --> <!-- cores -->
<module>{{projectName}}-core</module> <module>{{projectName}}-core</module>
<!-- services --> <!-- services -->
...@@ -46,6 +44,19 @@ ...@@ -46,6 +44,19 @@
<updatePolicy>always</updatePolicy> <updatePolicy>always</updatePolicy>
</snapshots> </snapshots>
</repository> </repository>
<repository>
<id>ibizmvnrepository</id>
<name>ibizmvnrepository</name>
<url>http://172.16.240.220:8081/nexus/content/groups/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories> </repositories>
</project> </project>
...@@ -15,11 +15,6 @@ ...@@ -15,11 +15,6 @@
<packaging>${project.packaging}</packaging> <packaging>${project.packaging}</packaging>
<dependencies> <dependencies>
<dependency>
<groupId>{{packageName}}</groupId>
<artifactId>{{projectName}}-util</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>
<properties> <properties>
......
...@@ -10,7 +10,7 @@ import org.springframework.boot.ApplicationRunner; ...@@ -10,7 +10,7 @@ import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import javax.management.MBeanServer; import javax.management.MBeanServer;
import javax.management.ObjectName; import javax.management.ObjectName;
import javax.management.Query; import javax.management.Query;
...@@ -72,5 +72,4 @@ public class NacosRegisterConfig implements ApplicationRunner { ...@@ -72,5 +72,4 @@ public class NacosRegisterConfig implements ApplicationRunner {
} }
return port; return port;
} }
} }
</#if> \ No newline at end of file
\ No newline at end of file
package {{packageName}}.${app.getPKGCodeName()?lower_case}; package {{packageName}}.{{apps}};
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
......
...@@ -14,13 +14,6 @@ ...@@ -14,13 +14,6 @@
<description>{{projectDesc}} Core</description> <description>{{projectDesc}} Core</description>
<dependencies> <dependencies>
<dependency>
<groupId>{{packageName}}</groupId>
<artifactId>{{projectName}}-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId> <artifactId>spring-data-commons</artifactId>
...@@ -122,7 +115,6 @@ ...@@ -122,7 +115,6 @@
</exclusions> </exclusions>
</dependency> </dependency>
{{/system.enableGlobalTransaction}} {{/system.enableGlobalTransaction}}
</dependencies> </dependencies>
<properties> <properties>
......
package {{packageName}}.core.util.aspect;
import lombok.SneakyThrows;
import {{packageName}}.util.annotation.Audit;
import {{packageName}}.util.domain.EntityBase;
import {{packageName}}.util.helper.DEFieldCacheMap;
import {{packageName}}.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}}.core.util.aspect;
import {{packageName}}.util.annotation.DEField;
import {{packageName}}.util.domain.EntityBase;
import {{packageName}}.util.enums.DEFieldDefaultValueType;
import {{packageName}}.util.enums.DEPredefinedFieldType;
import {{packageName}}.util.helper.DEFieldCacheMap;
import {{packageName}}.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}}.core.util.aspect;
import lombok.extern.slf4j.Slf4j;
import {{packageName}}.util.domain.DELogic;
import {{packageName}}.util.domain.EntityBase;
import {{packageName}}.util.errors.BadRequestAlertException;
import {{packageName}}.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)) {
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}}.core.util.aspect;
import lombok.extern.slf4j.Slf4j;
import {{packageName}}.util.annotation.DEField;
import {{packageName}}.util.enums.DupCheck;
import {{packageName}}.util.errors.BadRequestAlertException;
import {{packageName}}.util.filter.QueryFilter;
import {{packageName}}.util.filter.SearchContextBase;
import {{packageName}}.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}}");
}
{{/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}}.core.util.aspect;
import lombok.extern.slf4j.Slf4j;
import {{packageName}}.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
package {{packageName}}.core.util.aspect;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import {{packageName}}.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.I{{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);
}
}
}
\ No newline at end of file
package {{packageName}}.core.util.aspect;
import lombok.SneakyThrows;
import {{packageName}}.util.annotation.VersionCheck;
import {{packageName}}.util.domain.EntityBase;
import {{packageName}}.util.errors.BadRequestAlertException;
import {{packageName}}.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;
}
}
...@@ -10,7 +10,7 @@ import org.springframework.boot.ApplicationRunner; ...@@ -10,7 +10,7 @@ import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import javax.management.MBeanServer; import javax.management.MBeanServer;
import javax.management.ObjectName; import javax.management.ObjectName;
import javax.management.Query; import javax.management.Query;
...@@ -72,5 +72,4 @@ public class NacosRegisterConfig implements ApplicationRunner { ...@@ -72,5 +72,4 @@ public class NacosRegisterConfig implements ApplicationRunner {
} }
return port; return port;
} }
} }
</#if> \ No newline at end of file
\ No newline at end of file
package {{packageName}}.core.util.job;
import {{packageName}}.util.client.IBZUAAFeignClient;
import {{packageName}}.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.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:{{system.getCodeName}} }")
private String systemId;
@Value("${ ibiz.systemname:{{system.getName}} }")
private String systemName;
@Autowired
@Lazy
private IBZUAAFeignClient uaaClient;
@Autowired
@Lazy
IBZLiteFeignClient liteClient;
{{#if system.enableWorkflow}}
@Autowired
@Lazy
private {{packageName}}.util.client.IBZWFFeignClient wfClient;
{{/if}}
{{#if system.hasMsgTemplate}}
@Autowired
@Lazy
private {{packageName}}.util.client.IBZNotifyFeignClient notifyClient;
{{/if}}
{{#if system.hasRuntimeDict}}
@Autowired
@Lazy
{{packageName}}.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", systemId);
system.put("pssystemname", 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/${sys.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
{{#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.{{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 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.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;
@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
@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}}
*/
{{#enableAudit}}
@Audit
{{/enableAudit}}
@DEField({{annotation}})
@JsonProperty("{{jsonName}}")
{{#timeType}}
@JsonFormat(pattern = "{{format}}", locale = "zh", timezone = "GMT+8")
{{/timeType}}
@JSONField(name = "{{jsonName}}"{{#timeType}} , format = "{{format}}"{{/timeType}})
@ApiModelProperty("{{logicName}}")
private {{type.java}} {{camelCase codeName}};
{{/unless}}
{{/each}}
{{#each entity.references}}
/**
* {{entityLogicName}}
*/
@JSONField(name = "{{lowerCase codeName}}")
@JsonProperty("{{lowerCase codeName}}")
private {{packageName}}.core.{{module}}.domain.{{entityCodeName}} {{camelCase codeName}};
{{/each}}
{{#each entity.nesteds}}
/**
* {{entityLogicName}}
*/
{{#if listCode}}
@JSONField(name = "{{listCode}}")
@JsonProperty("{{listCode}}")
{{else}}
@JsonIgnore
@JSONField(serialize = false)
{{/if}}
private List<{{packageName}}.core.{{module}}.domain.{{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
...@@ -14,6 +14,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; ...@@ -14,6 +14,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.DigestUtils; import org.springframework.util.DigestUtils;
import org.springframework.util.Assert;
import cn.ibizlab.util.domain.EntityBase; import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.annotation.DEField; import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.enums.DEPredefinedFieldType; import cn.ibizlab.util.enums.DEPredefinedFieldType;
...@@ -24,6 +25,7 @@ import cn.ibizlab.util.enums.DupCheck; ...@@ -24,6 +25,7 @@ import cn.ibizlab.util.enums.DupCheck;
import cn.ibizlab.util.domain.EntityMP; import cn.ibizlab.util.domain.EntityMP;
import java.io.Serializable; import java.io.Serializable;
import lombok.*; import lombok.*;
import lombok.experimental.Accessors;
import org.springframework.data.annotation.Transient; import org.springframework.data.annotation.Transient;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
...@@ -47,9 +49,11 @@ public class {{entity.codeName}} extends EntityMP implements Serializable ...@@ -47,9 +49,11 @@ public class {{entity.codeName}} extends EntityMP implements Serializable
* {{logicName}} * {{logicName}}
*/ */
{{#if keyDEField}} {{#if keyDEField}}
{{#phisicalDEField}} {{#if phisicalDEField}}
@TableId(value = "{{columnName}}"{{#type.number}} , type = IdType.ASSIGN_ID{{/type.number}}{{#type.string}} , type = IdType.ASSIGN_UUID{{/type.string}}) @TableId(value = "{{columnName}}"{{#type.number}} , type = IdType.ASSIGN_ID{{/type.number}}{{#type.string}} , type = IdType.ASSIGN_UUID{{/type.string}})
{{/phisicalDEField}} {{else}}
@TableField(exist = false)
{{/if}}
{{else}} {{else}}
@TableField(value = "{{columnName}}"{{#insertOnly}} , fill = FieldFill.INSERT{{/insertOnly}}{{^phisicalDEField}} , exist = false{{/phisicalDEField}}) @TableField(value = "{{columnName}}"{{#insertOnly}} , fill = FieldFill.INSERT{{/insertOnly}}{{^phisicalDEField}} , exist = false{{/phisicalDEField}})
{{#logicValidField}} {{#logicValidField}}
...@@ -144,7 +148,68 @@ public class {{entity.codeName}} extends EntityMP implements Serializable ...@@ -144,7 +148,68 @@ public class {{entity.codeName}} extends EntityMP implements Serializable
{{/entity.nesteds}} {{/entity.nesteds}}
{{#unionKeyMode}} {{#entity.unionKeyMode}}
{{/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 entity.keyField.type.number}}
@Override
public Serializable getDefaultKey(boolean gen) {
return IdWorker.getId();
}
{{/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
...@@ -15,7 +15,7 @@ import org.springframework.cache.annotation.CacheEvict; ...@@ -15,7 +15,7 @@ import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
import java.io.Serializable; import java.io.Serializable;
import com.baomidou.mybatisplus.core.toolkit.Constants; import com.baomidou.mybatisplus.core.toolkit.Constants;
import om.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.annotation.DS;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
{{#dsName}} {{#dsName}}
......
...@@ -16,8 +16,8 @@ import com.alibaba.fastjson.JSONObject; ...@@ -16,8 +16,8 @@ import com.alibaba.fastjson.JSONObject;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import om.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.annotation.DS;
import cn.ibizlab.util.helper.CachedBeanCopier;
import {{packageName}}.core.{{module}}.domain.{{entity.codeName}}; import {{packageName}}.core.{{module}}.domain.{{entity.codeName}};
import {{packageName}}.core.{{module}}.filter.{{entity.codeName}}SearchContext; import {{packageName}}.core.{{module}}.filter.{{entity.codeName}}SearchContext;
......
...@@ -437,7 +437,11 @@ ...@@ -437,7 +437,11 @@
</dependency> </dependency>
{{/system.enableMysql}} {{/system.enableMysql}}
<dependency>
<groupId>cn.ibizlab</groupId>
<artifactId>ibizlab-util</artifactId>
<version>0.0.2</version>
</dependency>
</dependencies> </dependencies>
</project> </project>
...@@ -5,7 +5,7 @@ import lombok.Data; ...@@ -5,7 +5,7 @@ import lombok.Data;
@ConfigurationProperties(prefix = "service.{{apis}}") @ConfigurationProperties(prefix = "service.{{apis}}")
@Data @Data
public class {{apis.codeName}}ServiceProperties { public class {{api.codeName}}ServiceProperties {
private boolean enabled; private boolean enabled;
......
{{#unless apiEntity.subSysDE}} {{#unless apiEntity.subSysDE}}
<#assign pubPkgCodeName = pub.getPKGCodeName()>
<#assign itemSysApiCodeNameLC = item.getPSSysServiceAPI().getCodeName()?lower_case>
<#assign itemSysApiCodeName = item.getPSSysServiceAPI().getCodeName()>
<#assign mappingName=itemSysApiCodeName+item.codeName+"Mapping">
package {{packageName}}.{{apis}}.mapping; package {{packageName}}.{{apis}}.mapping;
{{#with api.entity as | entity | }} {{#with apiEntity.entity as | entity | }}
import org.mapstruct.*; import org.mapstruct.*;
import {{packageName}}.core.{{entity.model}}.domain.{{entity.codeName}}; import {{packageName}}.core.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.{{apis}}.dto.{{apiEntity.codeName}}DTO; import {{packageName}}.{{apis}}.dto.{{apiEntity.codeName}}DTO;
import cn.ibizlab.util.domain.MappingBase; import cn.ibizlab.util.domain.MappingBase;
......
<?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}}-util</artifactId>
<name>{{projectDesc}} Util</name>
<description>{{projectDesc}} Util</description>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<dependency>
<groupId>org.zalando</groupId>
<artifactId>problem-spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo-shaded</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
<!-- drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-json-converter</artifactId>
</dependency>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-ui-modeler-conf</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册