package com.vci.web.service.impl; import com.alibaba.fastjson.JSONObject; import com.vci.bo.OsCodeGenAttributeBO; import com.vci.bo.OsCodeGenButtonBO; import com.vci.corba.common.PLException; import com.vci.dto.OsCodeGenSchemaDTO; import com.vci.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.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.BeanUtilForVCI; 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.web.dao.OsCodeGenSchemaDaoI; import com.vci.web.service.OsCodeGenSchemaServiceI; import com.vci.web.service.WebBtmServiceI; 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; /** * 业务类型相关的操作 */ @Resource private WebBtmServiceI btmService; /** * 代码生成的文件夹 */ private static final String CODE_FOLDER = "codes"; /** * 对象操作工具类 */ @Autowired private RevisionModelUtil revisionModelUtil; /** * 代码生成方案列表 * * @param conditionMap 查询条件 * @param pageHelper 分页对象 * @return 方案的显示对象 * @throws VciBaseException 执行出错可能会抛出异常 */ @Override public DataGrid gridSchema(Map conditionMap, PageHelper pageHelper) throws VciBaseException { if(pageHelper == null){ pageHelper = new PageHelper(-1); } //默认使用ID属性排序 pageHelper.addSort("createTime",pageHelper.desc); List schemaDOList = codeGenSchemaDOMapper.selectByWrapper(conditionMap,pageHelper); DataGrid dataGrid = new DataGrid(); List 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 codeGenSchemaDO2VOs(List schemaDOList) { List schemaVOList = new ArrayList(); 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){ BeanUtilForVCI.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(); BeanUtilForVCI.convert(codeGenSchemaDTO,codeGenSchemaDO); checkJsonFormate(codeGenSchemaDO); //实现类是前端直接填写 codeGenSchemaDOMapper.insert(codeGenSchemaDO); return codeGenSchemaDO2VO(codeGenSchemaDO); } /** * 校验特殊属性是否为json格式 * @param codeGenSchemaDO 数据对象 */ private void checkJsonFormate(OsCodeGenSchemaDO codeGenSchemaDO){ Map checkAttrsMap = new HashMap(); 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 mainDataMap = new HashMap(); //使用方案里的名称 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 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 attributes = new ArrayList(); List uiAttributes = new ArrayList(); List referAttributes = new ArrayList(); String booleanClass = Boolean.class.getSimpleName(); String stringClass = String.class.getSimpleName(); List attributeVOS = btmService.listAttributeByBtmId(btmId); if(CollectionUtils.isEmpty(attributeVOS)){ attributeVOS = new ArrayList<>(); } //处理id,name和description的内容 Map 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")){ BeanUtilForVCI.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")){ BeanUtilForVCI.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")){ BeanUtilForVCI.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 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(); BeanUtilForVCI.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 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 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 switchButtons(String buttonsJson, String errorMsg) throws VciBaseException{ List buttonBOS = new ArrayList(); 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 BUTTON_ICONCLS_MAP = new HashMap(){{ 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 TEMPLATE_NAME_LIST = new ArrayList(){{ 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 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 fileContentMap = new HashMap(); //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)); } }