package com.vci.web.service.impl;
|
|
import com.alibaba.fastjson.JSONObject;
|
import com.vci.corba.common.PLException;
|
import com.vci.starter.revision.service.RevisionModelUtil;
|
import com.vci.starter.web.annotation.Column;
|
import com.vci.starter.web.constant.FrameWorkLcStatusConstant;
|
import com.vci.starter.web.enumpck.BooleanEnum;
|
import com.vci.starter.web.enumpck.VciFieldTypeEnum;
|
import com.vci.starter.web.exception.VciBaseException;
|
import com.vci.starter.web.pagemodel.DataGrid;
|
import com.vci.starter.web.pagemodel.PageHelper;
|
import com.vci.starter.web.util.BeanUtil;
|
import com.vci.starter.web.util.LocalFileUtil;
|
import com.vci.starter.web.util.VciBaseUtil;
|
import com.vci.starter.web.util.VciDateUtil;
|
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
|
import com.vci.bo.OsCodeGenAttributeBO;
|
import com.vci.bo.OsCodeGenButtonBO;
|
import com.vci.web.dao.OsCodeGenSchemaDaoI;
|
import com.vci.dto.OsCodeGenSchemaDTO;
|
import com.vci.web.enumpck.OsCodeGenJsPanelTypeEnum;
|
import com.vci.model.OsCodeGenSchemaDO;
|
import com.vci.pagemodel.OsBtmTypeAttributeVO;
|
import com.vci.pagemodel.OsBtmTypeVO;
|
import com.vci.pagemodel.OsCodeGenSchemaVO;
|
import com.vci.web.service.OsAttributeServiceI;
|
import com.vci.web.service.OsBtmServiceI;
|
import com.vci.web.service.OsCodeGenSchemaServiceI;
|
import com.vci.web.service.WebBtmIOServiceI;
|
import com.vci.web.util.WebUtil;
|
import com.vci.web.util.file.VciZipUtil;
|
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.lang3.StringUtils;
|
import org.apache.velocity.Template;
|
import org.apache.velocity.VelocityContext;
|
import org.apache.velocity.app.Velocity;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.CollectionUtils;
|
import org.springframework.web.util.HtmlUtils;
|
|
import javax.annotation.Resource;
|
import java.io.*;
|
import java.lang.reflect.Field;
|
import java.util.*;
|
import java.util.stream.Collectors;
|
|
/**
|
* 生成方案服务
|
* @author weidy
|
* @date 2020/7/30
|
*/
|
@Service
|
public class OsCodeGenSchemaServiceImpl implements OsCodeGenSchemaServiceI {
|
|
/**
|
* zip操作类
|
*/
|
@Autowired
|
private VciZipUtil zipUtil;
|
|
/**
|
* 日志
|
*/
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
|
/**
|
* 生成方案数据库操作类
|
*/
|
@Resource
|
private OsCodeGenSchemaDaoI codeGenSchemaDOMapper;
|
|
/**
|
* 业务类型
|
*/
|
@Autowired
|
private WebBtmIOServiceI btmIOService;
|
|
/**
|
* 业务类型相关的操作
|
*/
|
@Autowired
|
private OsBtmServiceI btmService;
|
|
/**
|
* 属性的服务
|
*/
|
@Autowired
|
private OsAttributeServiceI attrServiceI;
|
|
/**
|
* 代码生成的文件夹
|
*/
|
private static final String CODE_FOLDER = "codes";
|
|
/**
|
* 对象操作工具类
|
*/
|
@Autowired
|
private RevisionModelUtil revisionModelUtil;
|
|
/**
|
* 代码生成方案列表
|
*
|
* @param conditionMap 查询条件
|
* @param pageHelper 分页对象
|
* @return 方案的显示对象
|
* @throws VciBaseException 执行出错可能会抛出异常
|
*/
|
@Override
|
public DataGrid<OsCodeGenSchemaVO> gridSchema(Map<String, String> conditionMap, PageHelper pageHelper) throws VciBaseException {
|
if(pageHelper == null){
|
pageHelper = new PageHelper(-1);
|
}
|
//默认使用ID属性排序
|
pageHelper.addSort("createTime",pageHelper.desc);
|
List<OsCodeGenSchemaDO> schemaDOList = codeGenSchemaDOMapper.selectByWrapper(conditionMap,pageHelper);
|
DataGrid<OsCodeGenSchemaVO> dataGrid = new DataGrid<OsCodeGenSchemaVO>();
|
List<OsCodeGenSchemaVO> schemaVOList = codeGenSchemaDO2VOs(schemaDOList);
|
dataGrid.setData(schemaVOList);
|
if(!CollectionUtils.isEmpty(schemaVOList) && schemaVOList.size()>0){
|
Integer total = codeGenSchemaDOMapper.countByWrapper(conditionMap);
|
dataGrid.setTotal(total);
|
}else{
|
dataGrid.setTotal(0);
|
}
|
return dataGrid;
|
}
|
|
/**
|
* 数据对象列表转为显示对象列表
|
* @param schemaDOList 数据对象列表
|
* @return 显示对象列表
|
*/
|
@Override
|
public List<OsCodeGenSchemaVO> codeGenSchemaDO2VOs(List<OsCodeGenSchemaDO> schemaDOList) {
|
List<OsCodeGenSchemaVO> schemaVOList = new ArrayList<OsCodeGenSchemaVO>();
|
if(!CollectionUtils.isEmpty(schemaDOList)){
|
for(OsCodeGenSchemaDO schemaDO :schemaDOList){
|
OsCodeGenSchemaVO schemaVO = codeGenSchemaDO2VO(schemaDO);
|
if(schemaVO != null){
|
schemaVOList.add(schemaVO);
|
}
|
}
|
}
|
return schemaVOList;
|
}
|
|
/**
|
* 数据对象转换为显示对象
|
* @param schemaDO 数据对象
|
* @return 显示对象
|
*/
|
@Override
|
public OsCodeGenSchemaVO codeGenSchemaDO2VO(OsCodeGenSchemaDO schemaDO) {
|
OsCodeGenSchemaVO schemaVO = new OsCodeGenSchemaVO();
|
if(schemaDO!=null){
|
BeanUtil.convert(schemaDO,schemaVO);
|
schemaVO.setWestLayoutPanelTypeText(OsCodeGenJsPanelTypeEnum.getTextByValue(schemaVO.getWestLayoutPanelType()));
|
schemaVO.setCenterLayoutPanelTypeText(OsCodeGenJsPanelTypeEnum.getTextByValue(schemaVO.getCenterLayoutPanelType()));
|
schemaVO.setSouthLayoutPanelTypeText(OsCodeGenJsPanelTypeEnum.getTextByValue(schemaVO.getSouthLayoutPanelType()));
|
}
|
return schemaVO;
|
}
|
|
/**
|
* 添加代码生成方案
|
*
|
* @param codeGenSchemaDTO 方案数据传输对象
|
* @return 方案显示对象
|
* @throws VciBaseException 参数为空或者执行出错的时候会抛出异常
|
*/
|
@Override
|
public OsCodeGenSchemaVO addSchema(OsCodeGenSchemaDTO codeGenSchemaDTO) throws VciBaseException {
|
VciBaseUtil.alertNotNull(codeGenSchemaDTO,"要添加的方案");
|
OsCodeGenSchemaDO codeGenSchemaDO = new OsCodeGenSchemaDO();
|
BeanUtil.convert(codeGenSchemaDTO,codeGenSchemaDO);
|
checkJsonFormate(codeGenSchemaDO);
|
//实现类是前端直接填写
|
codeGenSchemaDOMapper.insert(codeGenSchemaDO);
|
return codeGenSchemaDO2VO(codeGenSchemaDO);
|
}
|
|
/**
|
* 校验特殊属性是否为json格式
|
* @param codeGenSchemaDO 数据对象
|
*/
|
private void checkJsonFormate(OsCodeGenSchemaDO codeGenSchemaDO){
|
Map<String,String> checkAttrsMap = new HashMap<String,String>();
|
|
codeGenSchemaDO.setCenterQueryConfig(StringUtils.isBlank(codeGenSchemaDO.getCenterQueryConfig())?"":HtmlUtils.htmlUnescape(codeGenSchemaDO.getCenterQueryConfig()));
|
codeGenSchemaDO.setCenterButtons(StringUtils.isBlank(codeGenSchemaDO.getCenterButtons())?"":HtmlUtils.htmlUnescape(codeGenSchemaDO.getCenterButtons()));
|
codeGenSchemaDO.setWestQueryConfig(StringUtils.isBlank(codeGenSchemaDO.getWestQueryConfig())?"":HtmlUtils.htmlUnescape(codeGenSchemaDO.getWestQueryConfig()));
|
codeGenSchemaDO.setWestButtons(StringUtils.isBlank(codeGenSchemaDO.getWestButtons())?"":HtmlUtils.htmlUnescape(codeGenSchemaDO.getWestButtons()));
|
codeGenSchemaDO.setSouthButtons(StringUtils.isBlank(codeGenSchemaDO.getSouthButtons())?"":HtmlUtils.htmlUnescape(codeGenSchemaDO.getSouthButtons()));
|
codeGenSchemaDO.setSouthQueryConfig(StringUtils.isBlank(codeGenSchemaDO.getSouthQueryConfig())?"":HtmlUtils.htmlUnescape(codeGenSchemaDO.getSouthQueryConfig()));
|
checkAttrsMap.put(codeGenSchemaDO.getWestQueryConfig(),"西区查询条件");
|
checkAttrsMap.put(codeGenSchemaDO.getCenterQueryConfig(),"中心区查询条件");
|
checkAttrsMap.put(codeGenSchemaDO.getSouthQueryConfig(),"南区查询条件");
|
checkAttrsMap.put(codeGenSchemaDO.getWestButtons(),"西区按钮");
|
checkAttrsMap.put(codeGenSchemaDO.getCenterButtons(),"中心区按钮");
|
checkAttrsMap.put(codeGenSchemaDO.getSouthButtons(),"南区按钮");
|
for(String attr:checkAttrsMap.keySet()){
|
String msg = checkAttrsMap.get(attr);
|
checkStringIsJson(attr,msg);
|
}
|
}
|
|
/**
|
* 检验字符串是不是为json格式
|
* @param s 字符串
|
* @param msg 不是json时的提示信息
|
*/
|
private void checkStringIsJson(String s, String msg){
|
if(StringUtils.isNotBlank(s)) {
|
try {
|
JSONObject.parseObject(s);
|
} catch (Throwable e) {
|
throw new VciBaseException(msg + "不是有效的json格式");
|
}
|
}
|
}
|
|
/**
|
* 修改代码生成方案
|
*
|
* @param codeGenSchemaDTO 方案数据传输对象
|
* @return 方案显示对象
|
* @throws VciBaseException 参数为空或者执行出错的时候会抛出异常
|
*/
|
@Override
|
public OsCodeGenSchemaVO editSchema(OsCodeGenSchemaDTO codeGenSchemaDTO) throws VciBaseException {
|
VciBaseUtil.alertNotNull(codeGenSchemaDTO,"要修改的方案",codeGenSchemaDTO.getOid(),"方案的主键");
|
OsCodeGenSchemaDO codeGenSchemaDO = selectByOid(codeGenSchemaDTO.getOid());
|
revisionModelUtil.copyFromDTO(codeGenSchemaDTO,codeGenSchemaDO);
|
checkJsonFormate(codeGenSchemaDO);
|
|
codeGenSchemaDOMapper.updateByPrimaryKey(codeGenSchemaDO);
|
return codeGenSchemaDO2VO(codeGenSchemaDO);
|
}
|
|
/**
|
* 选择主键
|
* @param oid 主键
|
* @return 方案的数据对象
|
* @throws VciBaseException 参数为空或者数据不存在会抛出异常
|
*/
|
private OsCodeGenSchemaDO selectByOid(String oid) throws VciBaseException{
|
VciBaseUtil.alertNotNull(oid,"方案的主键");
|
OsCodeGenSchemaDO codeGenSchemaDO = codeGenSchemaDOMapper.selectByPrimaryKey(oid);
|
if(codeGenSchemaDO == null || StringUtils.isBlank(codeGenSchemaDO.getOid())){
|
throw new VciBaseException("代码生成方案不存在");
|
}
|
return codeGenSchemaDO;
|
}
|
|
/**
|
* 代码模板路径
|
*/
|
private static final String CODE_TEMPLATE_FOLDER = "/codeTemplate";
|
|
/**
|
* 生成代码文件
|
*
|
* @param oid 方案的主键
|
* @throws VciBaseException 参数为空,方案不存在会抛出异常
|
*/
|
@Override
|
public void productCodeFile(String oid) throws VciBaseException, PLException {
|
OsCodeGenSchemaDO codeGenSchemaDO = selectByOid(oid);
|
//处理临时文件夹,在临时文件夹中添加codes/{业务类型的英文名称}
|
String tempFolder =LocalFileUtil.getProjectFolder();
|
tempFolder = tempFolder + File.separator + CODE_FOLDER + File.separator+ codeGenSchemaDO.getId();
|
File folder = new File(tempFolder);
|
if(!folder.exists()){
|
folder.mkdirs();
|
}
|
if(logger.isDebugEnabled()){
|
logger.debug("生成代码,临时文件夹{}",tempFolder);
|
}
|
//查询业务类型的所有的属性.getBtmTypeByOid里就包含属性和属性用的枚举映射的值
|
|
String classFullName = codeGenSchemaDO.getClassName();
|
VciBaseUtil.alertNotNull(classFullName,"业务类型的实体类的名称");
|
String className = classFullName;
|
String packageName = "";
|
if(className.indexOf(".")>-1){
|
packageName = classFullName.substring(0,classFullName.lastIndexOf("."));
|
if(packageName.indexOf(".")>-1){
|
packageName = packageName.substring(0,packageName.lastIndexOf("."));
|
}
|
className = className.substring(className.lastIndexOf(".")+1 );
|
|
}
|
|
|
//封装所有需要的属性
|
//1.先封装所有的公共的属性
|
Map<String,Object> mainDataMap = new HashMap<String,Object>();
|
//使用方案里的名称
|
mainDataMap.put("comments",codeGenSchemaDO.getName());
|
String doClassName = className;
|
mainDataMap.put("doClassName",doClassName);
|
if(className.endsWith("DO")){
|
className = className.substring(0,className.length()-2);
|
}
|
//类的名称
|
mainDataMap.put("className",className);
|
//类名称的首字母小写
|
mainDataMap.put("classNameFristLowwer",VciBaseUtil.toLowForFirst(className));
|
//作者
|
String author = codeGenSchemaDO.getAuthor();
|
if(StringUtils.isBlank(author)){
|
author = WebUtil.getCurrentUserId();
|
}
|
mainDataMap.put("author",author);
|
mainDataMap.put("datetime", VciDateUtil.getNowString(VciDateUtil.DateFormat));
|
ObjectStreamClass os = ObjectStreamClass.lookup(OsCodeGenSchemaDO.class);
|
long serialVersionUID = os.getSerialVersionUID();
|
//do不生成,do是所有的源头
|
String doPackage = (StringUtils.isBlank(codeGenSchemaDO.getDoPackage())?(packageName + ".model"):codeGenSchemaDO.getDoPackage());
|
mainDataMap.put("doPackage",doPackage);
|
mainDataMap.put("doSerialVersionUID",String.valueOf((serialVersionUID + (doPackage + "." + className + "DO").hashCode())) + "L");
|
//vo的包名
|
String voPackage = (StringUtils.isBlank(codeGenSchemaDO.getVoPackage())?(packageName + ".pageModel"):codeGenSchemaDO.getVoPackage());
|
mainDataMap.put("voPackage",voPackage);
|
mainDataMap.put("voSerialVersionUID", String.valueOf((serialVersionUID + (voPackage + "." + className + "VO").hashCode())) + "L");
|
//dto的包名
|
String dtoPackage = (StringUtils.isBlank(codeGenSchemaDO.getDtoPackage())?(packageName + ".dto"):codeGenSchemaDO.getDtoPackage());
|
mainDataMap.put("dtoPackage",dtoPackage);
|
mainDataMap.put("dtoSerialVersionUID", String.valueOf((serialVersionUID + (dtoPackage + "." + className + "DTO").hashCode())) + "L");
|
|
//po的包名
|
String poPackage = packageName + ".po";
|
mainDataMap.put("poPackage",poPackage);
|
|
//暂时不开放权限
|
mainDataMap.put("hasPermisssion",false);
|
//看看是否有生命周期
|
String lcStatusClassName = "";
|
String lcStatusFullClassName = "";
|
Map<String, OsBtmTypeVO> allBtmMap = btmService.selectAllBtmMap();
|
String btmId = codeGenSchemaDO.getId();
|
if(!allBtmMap.containsKey(btmId)){
|
throw new VciBaseException("业务类型{0}在系统里不存在",new String[]{btmId});
|
}
|
mainDataMap.put("lcStatusClassName",lcStatusClassName);
|
mainDataMap.put("lcStatusFullClassName",lcStatusFullClassName);
|
|
//看看是否有启用和停用
|
boolean hasEnable = false;
|
boolean hasExcel = false;
|
mainDataMap.put("hasEnable",hasEnable);
|
mainDataMap.put("hasExcel",hasExcel);
|
|
OsBtmTypeVO btmItem = allBtmMap.get(btmId);
|
if(StringUtils.isNotBlank(btmItem.getLifeCycleId()) && !FrameWorkLcStatusConstant.EMTYPE_LIFE_CYCLE.equalsIgnoreCase(btmItem.getLifeCycleId())){
|
mainDataMap.put("hasStatus",true);
|
}else{
|
mainDataMap.put("hasStatus",false);
|
}
|
//看有没有上级属性
|
boolean hasParentField = false;
|
String parentFieldName = "";
|
if(BooleanEnum.TRUE.getValue().equalsIgnoreCase(codeGenSchemaDO.getUseLayoutRegion())){
|
parentFieldName = codeGenSchemaDO.getWestNextRegionParam();
|
if(StringUtils.isNotBlank(parentFieldName)){
|
hasParentField = true;
|
}
|
}
|
|
mainDataMap.put("hasParentField",hasParentField);
|
mainDataMap.put("parentFieldName",parentFieldName);
|
mainDataMap.put("parentFieldNameLow",parentFieldName.toLowerCase(Locale.ROOT));
|
//转换所有的属性
|
List<OsCodeGenAttributeBO> attributes = new ArrayList<OsCodeGenAttributeBO>();
|
List<OsCodeGenAttributeBO> uiAttributes = new ArrayList<OsCodeGenAttributeBO>();
|
List<OsCodeGenAttributeBO> referAttributes = new ArrayList<OsCodeGenAttributeBO>();
|
String booleanClass = Boolean.class.getSimpleName();
|
String stringClass = String.class.getSimpleName();
|
List<OsBtmTypeAttributeVO> attributeVOS = btmService.listAttributeByBtmId(btmId);
|
if(CollectionUtils.isEmpty(attributeVOS)){
|
attributeVOS = new ArrayList<>();
|
}
|
//处理id,name和description的内容
|
Map<String,OsBtmTypeAttributeVO> defaultAttrMap = new HashMap<>();
|
if(StringUtils.isNotBlank(classFullName)){
|
try {
|
Class<?> aClass = Class.forName(classFullName);
|
OsBtmTypeAttributeVO idAttr = fieldToAttrVO(aClass, "id");
|
if(idAttr!=null){
|
defaultAttrMap.put("id",idAttr);
|
}
|
OsBtmTypeAttributeVO nameAttr = fieldToAttrVO(aClass, "name");
|
if(nameAttr!=null){
|
defaultAttrMap.put("name",idAttr);
|
}
|
OsBtmTypeAttributeVO descAttr = fieldToAttrVO(aClass, "description");
|
if(descAttr!=null){
|
defaultAttrMap.put("desc",descAttr);
|
}
|
} catch (Throwable e) {
|
e.printStackTrace();
|
}
|
}
|
OsBtmTypeAttributeVO idAttr = new OsBtmTypeAttributeVO();
|
if(defaultAttrMap.containsKey("id")){
|
BeanUtil.convert(defaultAttrMap.get("id"),idAttr);
|
idAttr.setId("id");
|
if(StringUtils.isBlank(idAttr.getName())){
|
idAttr.setName("编号");
|
}
|
idAttr.setAttributeDataType(VciFieldTypeEnum.VTString.name());
|
if(idAttr.getAttributeLength() == null || idAttr.getAttributeLength() <= 0){
|
idAttr.setAttributeLength(50);
|
}
|
attributeVOS.add(idAttr);
|
}
|
|
OsBtmTypeAttributeVO nameAttr = new OsBtmTypeAttributeVO();
|
if(defaultAttrMap.containsKey("name")){
|
BeanUtil.convert(defaultAttrMap.get("name"),nameAttr);
|
nameAttr.setId("name");
|
if(StringUtils.isBlank(nameAttr.getName())){
|
nameAttr.setName("名称");
|
}
|
nameAttr.setAttributeDataType(VciFieldTypeEnum.VTString.name());
|
if(nameAttr.getAttributeLength() == null || nameAttr.getAttributeLength() <= 0){
|
nameAttr.setAttributeLength(150);
|
}
|
attributeVOS.add(nameAttr);
|
}
|
|
OsBtmTypeAttributeVO descAttr = new OsBtmTypeAttributeVO();
|
if(defaultAttrMap.containsKey("desc")){
|
BeanUtil.convert(defaultAttrMap.get("desc"),descAttr);
|
descAttr.setId("description");
|
if(StringUtils.isBlank(descAttr.getName())){
|
descAttr.setName("描述");
|
}
|
descAttr.setAttributeDataType(VciFieldTypeEnum.VTString.name());
|
if(descAttr.getAttributeLength() == null || descAttr.getAttributeLength() <= 0){
|
descAttr.setAttributeLength(250);
|
}
|
attributeVOS.add(descAttr);
|
}
|
Set<String> attrIdSet = attributeVOS.stream().map(s->s.getId().toLowerCase(Locale.ROOT)).collect(Collectors.toSet());
|
if(!CollectionUtils.isEmpty(attributeVOS)){
|
attributeVOS.stream().forEach(attr->{
|
OsCodeGenAttributeBO attributeBO = new OsCodeGenAttributeBO();
|
BeanUtil.convert(attr, attributeBO);
|
attributeBO.setIdUpper(attr.getId().toUpperCase());
|
if(VciQueryWrapperForDO.LC_STATUS_FIELD.equalsIgnoreCase(attributeBO.getId())){
|
attributeBO.setName("状态");
|
}
|
attributeBO.setVciAttrDataType(attr.getAttributeDataType());
|
attributeBO.setNullable(String.valueOf(attr.isNullableFlag()));
|
attributeBO.setAttrDataType(getAttrDateTypeFromVci(attributeBO.getVciAttrDataType()));
|
attributeBO.setJdbcType(getJdbcTypeFromVci(attributeBO.getVciAttrDataType()));
|
attributeBO.setSetter(getSetter(attributeBO.getId(), attributeBO.getAttrDataType()));
|
attributeBO.setGetter(getGetter(attributeBO.getId(), attributeBO.getAttrDataType()));
|
//VTBoolean,在vo和dto里要使用boolean类型
|
if (VciFieldTypeEnum.VTBoolean.name().equalsIgnoreCase(attributeBO.getAttrDataType())) {
|
attributeBO.setVoJavaDataType(booleanClass);
|
attributeBO.setVoGetter(getGetter(attributeBO.getId(), attributeBO.getVoJavaDataType()));
|
attributeBO.setVoSetter(getSetter(attributeBO.getId(), attributeBO.getVoJavaDataType()));
|
} else {
|
attributeBO.setVoJavaDataType(attributeBO.getAttrDataType());
|
attributeBO.setVoGetter(attributeBO.getGetter());
|
attributeBO.setVoSetter(attributeBO.getSetter());
|
}
|
if (StringUtils.isNotBlank(attr.getReferBtmTypeId())) {
|
//是参照的
|
attributeBO.setReferFlag(true);
|
attributeBO.setReferDBField(attributeBO.getId() + ".name");
|
attributeBO.setReferBtmTypeId(attributeBO.getReferBtmTypeId());
|
attributeBO.setReferBtmTypeShowField(attr.getId() + "Name");
|
attributeBO.setReferBtmTypeShowFieldGetter(getGetter(attributeBO.getReferBtmTypeShowField(), stringClass));
|
attributeBO.setReferBtmTypeShowFieldSetter(getSetter(attributeBO.getReferBtmTypeShowField(), stringClass));
|
//处理参照的字段
|
OsCodeGenAttributeBO referAttrBO = new OsCodeGenAttributeBO();
|
referAttrBO.setId(attributeBO.getReferBtmTypeShowField());
|
referAttrBO.setIdUpper(referAttrBO.getId().toUpperCase());
|
referAttrBO.setJdbcType("VARCHAR");
|
if("grid".equalsIgnoreCase(attributeBO.getReferType())){
|
attributeBO.setReferControlUrl("uiDataController/defaultReferDataGrid");
|
}else{
|
attributeBO.setReferControlUrl("uiDataController/defaultReferTree");
|
}
|
if(!attrIdSet.contains(referAttrBO.getId().toLowerCase(Locale.ROOT))) {
|
attributeBO.setReferNameExist(false);
|
referAttributes.add(referAttrBO);
|
}
|
}
|
if (StringUtils.isNotBlank(attr.getEnumId())) {
|
attributeBO.setEnumFlag(true);
|
attributeBO.setEnumId(attributeBO.getEnumId().trim());
|
attributeBO.setEnumShowField(attr.getId() + "Text");
|
attributeBO.setEnumDBField(attributeBO.getEnumId().trim() + "_" + attributeBO.getId().toLowerCase());
|
attributeBO.setEnumShowFieldGetter(getGetter(attributeBO.getEnumShowField(), stringClass));
|
attributeBO.setEnumShowFieldSetter(getSetter(attributeBO.getEnumShowField(), stringClass));
|
}
|
attributes.add(attributeBO);
|
uiAttributes.add(attributeBO);
|
});
|
}
|
mainDataMap.put("attributes",attributes);
|
mainDataMap.put("uiAttributes",uiAttributes);
|
mainDataMap.put("referAttributes",referAttributes);
|
|
//controller相关的
|
String requestMap = codeGenSchemaDO.getControllerRequestMap();
|
String controllerUrl = requestMap;
|
if(!requestMap.startsWith("/")){
|
requestMap = "/" + requestMap;
|
}
|
if(requestMap.endsWith("/")){
|
requestMap = requestMap.substring(0,requestMap.length()-1);
|
}
|
if(controllerUrl.startsWith("/")){
|
controllerUrl = controllerUrl.substring(1);
|
}
|
if(!controllerUrl.endsWith("/")){
|
controllerUrl = controllerUrl + "/";
|
}
|
//controller里面要使用/开头,在Ui里开头不能有/,因为backPath里已经包含了
|
mainDataMap.put("controllerRequestMap",requestMap);
|
mainDataMap.put("controllerUrl",controllerUrl);
|
mainDataMap.put("controllerPackage",codeGenSchemaDO.getControllerPackage());
|
mainDataMap.put("backPath",codeGenSchemaDO.getBackPath());
|
|
boolean useWest = BooleanEnum.TRUE.getValue().equalsIgnoreCase(codeGenSchemaDO.getUseLayoutRegion());
|
mainDataMap.put("useWest",useWest);
|
if(useWest ){
|
//处理按钮
|
List<OsCodeGenButtonBO> buttonBOS = switchButtons(codeGenSchemaDO.getWestButtons(),"西区按钮不是有效的json对象,{0}");
|
mainDataMap.put("westButtons",buttonBOS);
|
//处理查询条件
|
checkQueryIsJson(codeGenSchemaDO.getWestQueryConfig(),"西区的查询条件不是有效的json对象,{0}");
|
mainDataMap.put("westQuerys", StringUtils.isBlank(codeGenSchemaDO.getWestQueryConfig())?"":codeGenSchemaDO.getWestQueryConfig());
|
mainDataMap.put("westLayoutPanelType",codeGenSchemaDO.getWestLayoutPanelType());
|
mainDataMap.put("westNextRegionParam",codeGenSchemaDO.getWestNextRegionParam());
|
}
|
|
//处理中心区
|
//处理按钮
|
List<OsCodeGenButtonBO> buttonBOS = switchButtons(codeGenSchemaDO.getCenterButtons(),"中心区按钮不是有效的json对象,{0}");
|
mainDataMap.put("centerButtons",buttonBOS);
|
//处理查询条件
|
checkQueryIsJson(codeGenSchemaDO.getCenterQueryConfig(),"中心区的查询条件不是有效的json对象,{0}");
|
mainDataMap.put("centerQuerys", StringUtils.isBlank(codeGenSchemaDO.getCenterQueryConfig())?"":codeGenSchemaDO.getCenterQueryConfig());
|
mainDataMap.put("centerLayoutPanelType",codeGenSchemaDO.getCenterLayoutPanelType());
|
|
//处理service相关的
|
String servicePackage = (StringUtils.isBlank(codeGenSchemaDO.getServicePackage())?(packageName + ".service"):codeGenSchemaDO.getServicePackage());
|
mainDataMap.put("servicePackage",servicePackage);
|
mainDataMap.put("btmTypeId",btmId);
|
mainDataMap.put("btmTypeIdLow",btmId.toLowerCase());
|
|
//处理mapper和xml的
|
String mapperPackage = (StringUtils.isBlank(codeGenSchemaDO.getMapperPackage())?(packageName + ".dao"):codeGenSchemaDO.getMapperPackage());
|
mainDataMap.put("mapperPackage",mapperPackage);
|
mainDataMap.put("mapperImplPackage",mapperPackage + ".impl");
|
mainDataMap.put("tableName", VciBaseUtil.getTableName(btmId));
|
|
//设置velocity资源加载器
|
Properties prop = new Properties();
|
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
|
Velocity.init(prop);
|
VelocityContext context = new VelocityContext(mainDataMap);
|
String finalTempFolder = tempFolder;
|
|
String finalClassName = className;
|
String xmlPackage = (StringUtils.isBlank(codeGenSchemaDO.getMapperXmlPackage())?(mapperPackage + ".impl"):codeGenSchemaDO.getMapperXmlPackage());
|
String jsPackage = codeGenSchemaDO.getJsPackage();
|
mainDataMap.put("jsPackage",jsPackage);
|
for(String template : TEMPLATE_NAME_LIST){
|
//先拷贝文件
|
String templateFile = finalTempFolder + File.separator;
|
if(!CollectionUtils.isEmpty(defaultAttrMap) && template.startsWith("DO.")){
|
//说明有DO的对象,那么这个就不生成
|
continue;
|
}
|
if(template.startsWith("Controller.")){
|
templateFile += codeGenSchemaDO.getControllerPackage().replace(".", File.separator) + File.separator + finalClassName + "Controller.java";
|
}else if(template.startsWith("DO.")){
|
templateFile += doPackage.replace(".", File.separator) + File.separator + finalClassName + "DO.java";
|
}else if(template.startsWith("VO.")){
|
templateFile += voPackage.replace(".", File.separator) + File.separator + finalClassName + "VO.java";
|
}else if(template.startsWith("DTO.")){
|
templateFile += dtoPackage.replace(".", File.separator) + File.separator + finalClassName + "DTO.java";
|
}else if(template.startsWith("PO.")){
|
templateFile += poPackage.replace(".", File.separator) + File.separator + finalClassName + "PO.java";
|
}else if(template.startsWith("DO.")){
|
templateFile += doPackage.replace(".", File.separator) + File.separator + doClassName + ".java";
|
}else if(template.startsWith("Mapper.java")){
|
templateFile += mapperPackage.replace(".", File.separator) + File.separator + finalClassName + "DaoI.java";
|
}else if(template.startsWith("Mapper.impl")){
|
templateFile += xmlPackage.replace(".",File.separator) + File.separator + finalClassName + "DaoImpl.java";
|
}else if(template.startsWith("Service.java")){
|
templateFile += servicePackage.replace(".", File.separator) + File.separator + finalClassName + "ServiceI.java";
|
}else if(template.startsWith("Service.impl")){
|
templateFile += servicePackage.replace(".", File.separator) + File.separator + "impl" + File.separator + finalClassName + "ServiceImpl.java";
|
}else if(template.startsWith("ui.js")){
|
templateFile += jsPackage.replace(".", File.separator) + ".js";
|
}
|
File tempFile = new File(templateFile);
|
if(tempFile.exists()){
|
tempFile.delete();
|
}
|
LocalFileUtil.copyFileInJar(CODE_TEMPLATE_FOLDER + "/" + template,templateFile);
|
StringWriter sw = new StringWriter();
|
Template tpl = Velocity.getTemplate(CODE_TEMPLATE_FOLDER + "/" + template, "UTF-8");
|
tpl.merge(context, sw);
|
OutputStream outs ;
|
try{
|
outs = new FileOutputStream(templateFile);
|
}catch (FileNotFoundException e){
|
throw new VciBaseException("从模板中拷贝文件没有成功",new String[]{},e);
|
}catch (Throwable e){
|
throw new VciBaseException("从模板中拷贝文件没有成功",new String[]{},e);
|
}
|
try {
|
IOUtils.write(sw.toString(), outs, "UTF-8" );
|
} catch (IOException e) {
|
throw new VciBaseException("写入数据到模板没有成功",new String[]{},e);
|
}finally {
|
IOUtils.closeQuietly(sw);
|
IOUtils.closeQuietly(outs);
|
}
|
}
|
codeGenSchemaDO.setLastProductDate(new Date());
|
codeGenSchemaDOMapper.updateByPrimaryKey(codeGenSchemaDO);
|
}
|
|
|
/**
|
* 校验查询配置是否有效的json格式
|
* @param queryJson 查询条件的json字符串
|
* @param errorMsg 错误信息
|
* @throws VciBaseException 不是有效的json字符串的时候,会抛出异常
|
*/
|
private void checkQueryIsJson(String queryJson, String errorMsg) throws VciBaseException{
|
if(StringUtils.isNotBlank(queryJson)){
|
try {
|
JSONObject queryJsonObj = JSONObject.parseObject(queryJson);
|
}catch (Throwable e){
|
throw new VciBaseException(errorMsg,new String[]{queryJson});
|
}
|
}
|
}
|
|
/**
|
* 字段转换为属性显示对象
|
* @param aClass 对象类
|
* @param fieldName 字段名称
|
* @return 属性的信息,没有字段描述的时候会返回null
|
*/
|
private OsBtmTypeAttributeVO fieldToAttrVO(Class<?> aClass,String fieldName){
|
//我们去获取它的属性
|
Field idField = VciBaseUtil.getFieldForObject(fieldName, aClass);
|
if(idField!=null){
|
idField.setAccessible(true);
|
if(idField.isAnnotationPresent(Column.class)){
|
Column column = idField.getAnnotation(Column.class);
|
if(StringUtils.isNotBlank(column.columnDefinition())){
|
OsBtmTypeAttributeVO idAttr = new OsBtmTypeAttributeVO();
|
idAttr.setName(column.columnDefinition());
|
idAttr.setNullableFlag(column.nullable());
|
if(column.length()>0) {
|
idAttr.setAttributeLength(column.length());
|
}
|
idAttr.setDefaultValue(column.defaultValue());
|
return idAttr;
|
}
|
}
|
}
|
return null;
|
}
|
|
/**
|
* 获取按钮的对象
|
* @param buttonsJson 按钮的json字符串
|
* @param errorMsg 错误的信息
|
* @return 按钮对象
|
* @throws VciBaseException json格式出错的时候会抛出异常
|
*/
|
private List<OsCodeGenButtonBO> switchButtons(String buttonsJson, String errorMsg) throws VciBaseException{
|
List<OsCodeGenButtonBO> buttonBOS = new ArrayList<OsCodeGenButtonBO>();
|
if(StringUtils.isNotBlank(buttonsJson)){
|
try {
|
JSONObject buttons = JSONObject.parseObject(buttonsJson);
|
buttons.keySet().stream().sorted(((o1, o2) -> o1.compareTo(o2))).forEach(id->{
|
String text = (String)buttons.get(id);
|
String iconCls = BUTTON_ICONCLS_MAP.getOrDefault(id,"layui-icon-app");
|
OsCodeGenButtonBO buttonBO = new OsCodeGenButtonBO();
|
buttonBO.setId(id);
|
buttonBO.setText(text);
|
buttonBO.setIconCls(iconCls);
|
buttonBOS.add(buttonBO);
|
});
|
}catch (Throwable e){
|
throw new VciBaseException(errorMsg,new String[]{buttonsJson});
|
}
|
}
|
return buttonBOS;
|
}
|
|
/**
|
* 按钮的图标
|
*/
|
private static final Map<String,String> BUTTON_ICONCLS_MAP = new HashMap<String,String>(){{
|
put("ADD","layui-icon-add-1");
|
put("EDIT","layui-icon-edit");
|
put("DEL","layui-icon-delete");
|
put("DEL","layui-icon-delete");
|
put("ENABLE","layui-icon-ok-circle");
|
put("DISABLE","layui-icon-404");
|
put("refresh","layui-icon-refresh");
|
put("ADVQUERY","layui-icon-search");
|
put("EXPORT","layui-icon-export");
|
put("IMPORT","layui-icon-upload-drag");
|
put("RELEASE","layui-icon-release");
|
}};
|
|
/**
|
* 模板的名称
|
*/
|
public static final List<String> TEMPLATE_NAME_LIST = new ArrayList<String>(){{
|
add("Controller.java.vm");
|
add("DTO.java.vm");
|
add("VO.java.vm");
|
add("PO.java.vm");
|
add("Service.java.vm");
|
add("Service.impl.java.vm");
|
add("ui.js.vm");
|
|
add("Mapper.java.vm");
|
add("Mapper.impl.java.vm");
|
}};
|
|
/**
|
* 获取set方法
|
* @param id 属性的名称
|
* @param attrDataType 属性的java类型
|
* @return set方法
|
*/
|
private String getSetter(String id, String attrDataType) {
|
return "set" + VciBaseUtil.toUpForFirst(id);
|
}
|
|
/**
|
* 获取get方法
|
* @param id 属性的名称
|
* @param attrDataType 属性的java类型
|
* @return get方法
|
*/
|
private String getGetter(String id, String attrDataType){
|
if(Boolean.class.getSimpleName().equalsIgnoreCase(attrDataType)){
|
return "is" + VciBaseUtil.toUpForFirst(id);
|
}
|
return "get" + VciBaseUtil.toUpForFirst(id);
|
}
|
|
/**
|
* 把平台的属性类型转换为jdbc的类型
|
* @param vciAttrDataType 平台的属性类型
|
* @return jdbc的类型
|
*/
|
private String getJdbcTypeFromVci(String vciAttrDataType) {
|
VciFieldTypeEnum typeEnum = VciFieldTypeEnum.valueOf(vciAttrDataType);
|
if(typeEnum == null){
|
typeEnum = VciFieldTypeEnum.VTString;
|
}
|
switch (typeEnum){
|
case VTDate:
|
case VTDateTime:
|
case VTTime:
|
return "TIMESTAMP";
|
case VTInteger:
|
case VTLong:
|
case VTDouble:
|
return "DECIMAL";
|
default:
|
return "VARCHAR";
|
}
|
}
|
|
/**
|
* 把平台的属性类型转换为java的类型
|
* @param vciAttrDataType 平台的属性类型
|
* @return java的类型,注意vo和dto需要单独处理
|
*/
|
private String getAttrDateTypeFromVci(String vciAttrDataType) {
|
VciFieldTypeEnum typeEnum = VciFieldTypeEnum.valueOf(vciAttrDataType);
|
if(typeEnum == null){
|
typeEnum = VciFieldTypeEnum.VTString;
|
}
|
switch (typeEnum){
|
case VTDate:
|
case VTDateTime:
|
case VTTime:
|
return Date.class.getSimpleName();
|
case VTInteger:
|
return Integer.class.getSimpleName();
|
case VTLong:
|
return Long.class.getSimpleName();
|
case VTDouble:
|
return Double.class.getSimpleName();
|
default:
|
return String.class.getSimpleName();
|
}
|
}
|
|
/**
|
* 预览代码文件
|
*
|
* @param oid 方案的主键
|
* @return key是文件类别,value是文件的内容
|
* @throws VciBaseException 参数为空,方案不存在会抛出异常
|
*/
|
@Override
|
public Map<String, String> previewCodeFile(String oid) throws VciBaseException {
|
OsCodeGenSchemaDO codeGenSchemaDO = selectByOid(oid);
|
String tempFolder = LocalFileUtil.getProjectFolder();
|
tempFolder = tempFolder + File.separator + CODE_FOLDER + File.separator+ codeGenSchemaDO.getId() + File.separator ;
|
String classFullName = codeGenSchemaDO.getClassName();
|
String className = classFullName;
|
String packageName = "";
|
if(className.indexOf(".")>-1){
|
packageName = classFullName.substring(0,classFullName.lastIndexOf("."));
|
if(packageName.indexOf(".")>-1){
|
packageName = packageName.substring(0,packageName.lastIndexOf("."));
|
}
|
className = className.substring(className.lastIndexOf(".")+1 );
|
|
}
|
if(className.endsWith("DO")){
|
className = className.substring(0,className.length()-2);
|
}
|
Map<String,String> fileContentMap = new HashMap<String,String>();
|
|
//VO
|
String voFileName = tempFolder + codeGenSchemaDO.getVoPackage().replace(".", File.separator) + File.separator + className + "VO.java";
|
fileContentMap.put("VO",LocalFileUtil.readContentForFile(voFileName));
|
//dto
|
String dtoFileName = tempFolder + codeGenSchemaDO.getDtoPackage().replace(".", File.separator) + File.separator + className + "DTO.java";
|
fileContentMap.put("DTO",LocalFileUtil.readContentForFile(dtoFileName));
|
|
//mapper
|
String mapperFileName = tempFolder + codeGenSchemaDO.getMapperPackage().replace(".", File.separator) + File.separator + className + "Mapper.java";
|
fileContentMap.put("Mapper",LocalFileUtil.readContentForFile(mapperFileName));
|
|
//mapper.xml
|
String mapperXmlFileName = tempFolder + codeGenSchemaDO.getMapperXmlPackage() + File.separator + className + "Mapper.xml";
|
fileContentMap.put("Mapperxml",LocalFileUtil.readContentForFile(mapperXmlFileName));
|
|
//controller
|
String controllerFileName = tempFolder + codeGenSchemaDO.getControllerPackage().replace(".", File.separator) + File.separator + className + "Controller.java";
|
fileContentMap.put("Controller",LocalFileUtil.readContentForFile(controllerFileName));
|
|
//Service
|
String serviceFileName = tempFolder + codeGenSchemaDO.getServicePackage().replace(".", File.separator) + File.separator + className + "ServiceI.java";
|
fileContentMap.put("Service",LocalFileUtil.readContentForFile(serviceFileName));
|
|
//Service.impl
|
String serviceImplFileName = tempFolder + codeGenSchemaDO.getServicePackage().replace(".", File.separator) + File.separator + "impl" + File.separator + className + "ServiceImpl.java";
|
fileContentMap.put("ServiceImpl",LocalFileUtil.readContentForFile(serviceImplFileName));
|
|
//js
|
String jsFileName = tempFolder + codeGenSchemaDO.getJsPackage() + ".js";
|
fileContentMap.put("UI",LocalFileUtil.readContentForFile(jsFileName));
|
|
//Service
|
String poFileName = tempFolder + packageName.replace(".", File.separator) + File.separator + "po" + File.separator + className + "PO.java";
|
File poFile = new File(poFileName);
|
if(poFile.exists()) {
|
fileContentMap.put("PO", LocalFileUtil.readContentForFile(serviceFileName));
|
}
|
return fileContentMap;
|
}
|
|
/**
|
* 下载代码文件
|
*
|
* @param oid 方案的主键
|
* @return zip文件的路径
|
* @throws VciBaseException 参数为空,方案不存在会抛出异常
|
*/
|
@Override
|
public String downloadCodeFile(String oid) throws VciBaseException {
|
OsCodeGenSchemaDO codeGenSchemaDO = selectByOid(oid);
|
String codeFolder = LocalFileUtil.getProjectFolder();
|
codeFolder = codeFolder + File.separator + CODE_FOLDER + File.separator+ codeGenSchemaDO.getId() ;
|
String tempZipFileName = LocalFileUtil.getDefaultTempFolder() + File.separator + codeGenSchemaDO.getId() + ".zip";
|
File folder = new File(codeFolder);
|
if(!folder.exists()){
|
throw new VciBaseException("代码可能没有生成,没有在{0}找到代码文件",new String[]{codeFolder});
|
}
|
zipUtil.folderToZipFile(codeFolder,tempZipFileName);
|
return tempZipFileName;
|
}
|
|
/**
|
* 根据主键获取显示对象
|
*
|
* @param oid 主键
|
* @return 方案的显示对象
|
* @throws VciBaseException 参数为空,方案不存在会抛出异常
|
*/
|
@Override
|
public OsCodeGenSchemaVO getObjectByOid(String oid) throws VciBaseException {
|
return codeGenSchemaDO2VO(selectByOid(oid));
|
}
|
}
|