diff --git a/pear-entrance/pom.xml b/pear-entrance/pom.xml index 53e06c6e7fff863adc5ef9982b916144ecdf77ef..54e55cc225d1fdf4d80689049baeca28b5255c6d 100644 --- a/pear-entrance/pom.xml +++ b/pear-entrance/pom.xml @@ -46,6 +46,11 @@ pear-schedule 0.0.1-SNAPSHOT + + com.pearadmin + pear-generator + 0.0.1-SNAPSHOT + org.springframework.boot spring-boot-starter-thymeleaf diff --git a/pear-entrance/src/main/resources/application-druid.yml b/pear-entrance/src/main/resources/application-druid.yml index 6feca8954dc1481b05b1135bc0e598f6157fbc9a..c64edc65acafa40271acffa7a6e5fa3d1f3214c2 100644 --- a/pear-entrance/src/main/resources/application-druid.yml +++ b/pear-entrance/src/main/resources/application-druid.yml @@ -7,9 +7,9 @@ spring: username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/pear-admin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true + url: jdbc:mysql://114.55.218.200:3307/pear-admin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true slave: username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost:3306/pear-admin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true \ No newline at end of file + url: jdbc:mysql://114.55.218.200:3307/pear-admin?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true \ No newline at end of file diff --git a/pear-modules/pear-generator/pom.xml b/pear-modules/pear-generator/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..876cf2e75db1a47fb91edbf9698480c8ca400aba --- /dev/null +++ b/pear-modules/pear-generator/pom.xml @@ -0,0 +1,101 @@ + + + 4.0.0 + + com.pearadmin + pear-modules + 0.0.1-SNAPSHOT + + com.pearadmin + pear-generator + 0.0.1-SNAPSHOT + pear-generator + Demo project for Spring Boot + + + 1.8 + + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 1.1.1 + + + com.github.pagehelper + pagehelper-spring-boot-starter + 1.2.10 + + + com.pearadmin + pear-system + 0.0.1-SNAPSHOT + + + + commons-io + commons-io + 2.5 + + + commons-configuration + commons-configuration + 1.10 + + + velocity + org.apache.velocity + 1.7 + + + org.apache.velocity + velocity-tools + 2.0 + + + dom4j + dom4j + + + oro + oro + + + sslext + sslext + + + struts-core + org.apache.struts + + + struts-taglib + org.apache.struts + + + struts-tiles + org.apache.struts + + + commons-validator + commons-validator + + + commons-beanutils + commons-beanutils + + + commons-chain + commons-chain + + + commons-collections + commons-collections + + + + + + diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/controller/SysGeneratorController.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/controller/SysGeneratorController.java new file mode 100644 index 0000000000000000000000000000000000000000..f787eb8862ccb53615e5fbfd69e3b543c916cfb7 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/controller/SysGeneratorController.java @@ -0,0 +1,71 @@ +package com.pearadmin.generator.controller; + +import com.pearadmin.generator.service.SysGeneratorService; +import com.pearadmin.generator.utils.PageUtils; +import com.pearadmin.generator.utils.Query; +import com.pearadmin.generator.utils.R; +import com.pearadmin.generator.utils.XssHttpServletRequestWrapper; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +/** + * 代码生成器 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年12月19日 下午9:12:58 + */ +@Controller +@RequestMapping("sys/generator") +public class SysGeneratorController { + @Autowired + private SysGeneratorService sysGeneratorService; + + /** + * 列表 + */ + @ResponseBody + @RequestMapping("/list") + public R list(@RequestParam Map params){ + //查询列表数据 + Query query = new Query(params); + List> list = sysGeneratorService.queryList(query); + int total = sysGeneratorService.queryTotal(query); + + PageUtils pageUtil = new PageUtils(list, total, query.getLimit(), query.getPage()); + + return R.ok().put("page", pageUtil); + } + + /** + * 生成代码 + */ + @RequestMapping("/code") + public void code(HttpServletRequest request, HttpServletResponse response) throws IOException{ + //获取表名,不进行xss过滤 + HttpServletRequest orgRequest = XssHttpServletRequestWrapper.getOrgRequest(request); + String tables = orgRequest.getParameter("tables"); + + String[] tableNames; + tableNames = tables.split(","); + + byte[] data = sysGeneratorService.generatorCode(tableNames); + + response.reset(); + response.setHeader("Content-Disposition", "attachment; filename=\"yuanjilu.zip\""); + response.addHeader("Content-Length", "" + data.length); + response.setContentType("application/octet-stream; charset=UTF-8"); + + IOUtils.write(data, response.getOutputStream()); + } +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/dao/SysGeneratorDao.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/dao/SysGeneratorDao.java new file mode 100644 index 0000000000000000000000000000000000000000..5fe59b92c16989f0a81ffaa80845bae800e23169 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/dao/SysGeneratorDao.java @@ -0,0 +1,33 @@ +package com.pearadmin.generator.dao; + +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; +import java.util.Map; + +/** + * 代码生成器 + * + * @author chenshun + * @email sunlightcs@gmail.com + * @date 2016年12月19日 下午3:32:04 + */ +@Mapper +public interface SysGeneratorDao { + + List> queryMySQLList(Map map); + + int queryMySQLTotal(Map map); + + Map queryMySQLTable(String tableName); + + List> queryMySQLColumns(String tableName); + + List> queryOracleList(Map map); + + int queryOracleTotal(Map map); + + Map queryOracleTable(String tableName); + + List> queryOracleColumns(String tableName); +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/dao/SysGeneratorDao.xml b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/dao/SysGeneratorDao.xml new file mode 100644 index 0000000000000000000000000000000000000000..5099baff3810a00eb7e8d5e936f849f3bf5bf71b --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/dao/SysGeneratorDao.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/entity/ColumnEntity.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/entity/ColumnEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..31abb634f0d0c30acf32a00dffda8d86e8d1a302 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/entity/ColumnEntity.java @@ -0,0 +1,69 @@ +package com.pearadmin.generator.entity; + +/** + * 列的属性 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年12月20日 上午12:01:45 + */ +public class ColumnEntity { + //列名 + private String columnName; + //列名类型 + private String dataType; + //列名备注 + private String comments; + + //属性名称(第一个字母大写),如:user_name => UserName + private String attrName; + //属性名称(第一个字母小写),如:user_name => userName + private String attrname; + //属性类型 + private String attrType; + //auto_increment + private String extra; + + public String getColumnName() { + return columnName; + } + public void setColumnName(String columnName) { + this.columnName = columnName; + } + public String getDataType() { + return dataType; + } + public void setDataType(String dataType) { + this.dataType = dataType; + } + public String getComments() { + return comments; + } + public void setComments(String comments) { + this.comments = comments; + } + public String getAttrname() { + return attrname; + } + public void setAttrname(String attrname) { + this.attrname = attrname; + } + public String getAttrName() { + return attrName; + } + public void setAttrName(String attrName) { + this.attrName = attrName; + } + public String getAttrType() { + return attrType; + } + public void setAttrType(String attrType) { + this.attrType = attrType; + } + public String getExtra() { + return extra; + } + public void setExtra(String extra) { + this.extra = extra; + } +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/entity/TableEntity.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/entity/TableEntity.java new file mode 100644 index 0000000000000000000000000000000000000000..56202c13cb1208c95466fc7f8a46e3ac61b331bf --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/entity/TableEntity.java @@ -0,0 +1,63 @@ +package com.pearadmin.generator.entity; + +import java.util.List; + +/** + * 表数据 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年12月20日 上午12:02:55 + */ +public class TableEntity { + //表的名称 + private String tableName; + //表的备注 + private String comments; + //表的主键 + private ColumnEntity pk; + //表的列名(不包含主键) + private List columns; + + //类名(第一个字母大写),如:sys_user => SysUser + private String className; + //类名(第一个字母小写),如:sys_user => sysUser + private String classname; + + public String getTableName() { + return tableName; + } + public void setTableName(String tableName) { + this.tableName = tableName; + } + public String getComments() { + return comments; + } + public void setComments(String comments) { + this.comments = comments; + } + public ColumnEntity getPk() { + return pk; + } + public void setPk(ColumnEntity pk) { + this.pk = pk; + } + public List getColumns() { + return columns; + } + public void setColumns(List columns) { + this.columns = columns; + } + public String getClassName() { + return className; + } + public void setClassName(String className) { + this.className = className; + } + public String getClassname() { + return classname; + } + public void setClassname(String classname) { + this.classname = classname; + } +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/service/SysGeneratorService.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/service/SysGeneratorService.java new file mode 100644 index 0000000000000000000000000000000000000000..6b5ee4dbefe0db53d1e7ea3974093194dcc46a6d --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/service/SysGeneratorService.java @@ -0,0 +1,27 @@ +package com.pearadmin.generator.service; + +import java.util.List; +import java.util.Map; + +/** + * 代码生成器 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年12月19日 下午3:33:38 + */ +public interface SysGeneratorService { + + List> queryList(Map map); + + int queryTotal(Map map); + + Map queryTable(String tableName); + + List> queryColumns(String tableName); + + /** + * 生成代码 + */ + byte[] generatorCode(String[] tableNames); +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/service/impl/SysGeneratorServiceImpl.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/service/impl/SysGeneratorServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..aaff1f20a14d25c81f008199a6086ae007bdb4e4 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/service/impl/SysGeneratorServiceImpl.java @@ -0,0 +1,92 @@ +package com.pearadmin.generator.service.impl; + +import com.pearadmin.generator.dao.SysGeneratorDao; +import com.pearadmin.generator.service.SysGeneratorService; +import com.pearadmin.generator.utils.GenUtils; +import com.pearadmin.generator.utils.initContants; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.io.ByteArrayOutputStream; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipOutputStream; + +@Service("sysGeneratorService") +public class SysGeneratorServiceImpl implements SysGeneratorService { + @Autowired + private SysGeneratorDao sysGeneratorDao; + + @Override + public List> queryList(Map map) { + + switch (initContants.databaseType) { + case ORACLE: + return sysGeneratorDao.queryOracleList(map); + case MYSQL: + return sysGeneratorDao.queryMySQLList(map); + default: + break; + } + return sysGeneratorDao.queryMySQLList(map); + } + + @Override + public int queryTotal(Map map) { + + switch (initContants.databaseType) { + case ORACLE: + return sysGeneratorDao.queryOracleTotal(map); + case MYSQL: + return sysGeneratorDao.queryMySQLTotal(map); + default: + break; + } + return sysGeneratorDao.queryMySQLTotal(map); + } + + @Override + public Map queryTable(String tableName) { + switch (initContants.databaseType) { + case ORACLE: + return sysGeneratorDao.queryOracleTable(tableName); + case MYSQL: + return sysGeneratorDao.queryMySQLTable(tableName); + default: + break; + } + return sysGeneratorDao.queryMySQLTable(tableName); + } + + @Override + public List> queryColumns(String tableName) { + switch (initContants.databaseType) { + case ORACLE: + return sysGeneratorDao.queryOracleColumns(tableName); + case MYSQL: + return sysGeneratorDao.queryMySQLColumns(tableName); + default: + break; + } + return sysGeneratorDao.queryMySQLColumns(tableName); + } + + @Override + public byte[] generatorCode(String[] tableNames) { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + ZipOutputStream zip = new ZipOutputStream(outputStream); + + for(String tableName : tableNames){ + //查询表信息 + Map table = queryTable(tableName); + //查询列信息 + List> columns = queryColumns(tableName); + //生成代码 + GenUtils.generatorCode(table, columns, zip); + } + IOUtils.closeQuietly(zip); + return outputStream.toByteArray(); + } + +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/DateGenUtils.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/DateGenUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..381882a79703220eb81a665fbb623557d412c39f --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/DateGenUtils.java @@ -0,0 +1,268 @@ +package com.pearadmin.generator.utils; + +import org.apache.commons.lang3.time.DateFormatUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Timestamp; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 日期处理 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年12月21日 下午12:53:33 + */ +public class DateGenUtils extends org.apache.commons.lang3.time.DateUtils{ + private static Logger logger = LoggerFactory.getLogger(DateGenUtils.class); + /** 时间格式(yyyy-MM-dd) */ + public final static String DATE_PATTERN = "yyyy-MM-dd"; + /** 时间格式(yyyyMMdd) */ + public final static String DATE_PATTERN_NO_ = "yyyyMMdd"; + /** 时间格式(yyyy-MM-dd HH:mm:ss) */ + public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + private static String[] parsePatterns = { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", + "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" }; + + public static String format(Date date) { + return format(date, DATE_PATTERN); + } + + public static String format(Date date, String pattern) { + if(date != null){ + SimpleDateFormat df = new SimpleDateFormat(pattern); + return df.format(date); + } + return null; + } + + /** + + * 得到当前日期字符串 格式(yyyy-MM-dd) + + */ + public static String getDate() { + return getDate("yyyy-MM-dd"); + } + + /** + + * 得到当前日期字符串 格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E" + + */ + public static String getDate(String pattern) { + return DateFormatUtils.format(new Date(), pattern); + } + + /** + + * 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:"yyyy-MM-dd" "HH:mm:ss" "E" + + */ + public static String formatDate(Date date, Object... pattern) { + String formatDate = null; + if (pattern != null && pattern.length > 0) { + formatDate = DateFormatUtils.format(date, pattern[0].toString()); + } else { + formatDate = DateFormatUtils.format(date, "yyyy-MM-dd"); + } + return formatDate; + } + + /** + + * 得到日期时间字符串,转换格式(yyyy-MM-dd HH:mm:ss) + + */ + public static String formatDateTime(Date date) { + return formatDate(date, "yyyy-MM-dd HH:mm:ss"); + } + + /** + + * 得到当前时间字符串 格式(HH:mm:ss) + + */ + public static String getTime() { + return formatDate(new Date(), "HH:mm:ss"); + } + + /** + + * 得到当前日期和时间字符串 格式(yyyy-MM-dd HH:mm:ss) + + */ + public static String getDateTime() { + return formatDate(new Date(), "yyyy-MM-dd HH:mm:ss"); + } + + /** + + * 得到当前年份字符串 格式(yyyy) + + */ + public static String getYear() { + return formatDate(new Date(), "yyyy"); + } + + /** + + * 得到当前月份字符串 格式(MM) + + */ + public static String getMonth() { + return formatDate(new Date(), "MM"); + } + + /** + + * 得到当天字符串 格式(dd) + + */ + public static String getDay() { + return formatDate(new Date(), "dd"); + } + + /** + + * 得到当前星期字符串 格式(E)星期几 + + */ + public static String getWeek() { + return formatDate(new Date(), "E"); + } + + /** + + * 日期型字符串转化为日期 格式 + + * { "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", + + * "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" } + + */ + public static Date parseDate(Object str) { + if (str == null){ + return null; + } + try { + return parseDate(str.toString(), parsePatterns); + } catch (ParseException e) { + logger.error("日期格式解析异常", e); + return null; + } + } + + /** + + * 获取过去的天数 + + * @param date + + * @return + + */ + public static long pastDays(Date date) { + long t = new Date().getTime()-date.getTime(); + return t/(24*60*60*1000); + } + + + public static Date getDateStart(Date date) { + if(date==null) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try { + date= sdf.parse(formatDate(date, "yyyy-MM-dd")+" 00:00:00"); + } catch (ParseException e) { + logger.error("日期格式解析异常", e); + } + return date; + } + + public static Date getDateEnd(Date date) { + if(date==null) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try { + date= sdf.parse(formatDate(date, "yyyy-MM-dd") +" 23:59:59"); + } catch (ParseException e) { + logger.error("日期格式解析异常", e); + } + return date; + } + + /** + + * 判断字符串是否是日期 + + * @param timeString + + * @return + + */ + public static boolean isDate(String timeString){ + SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd"); + format.setLenient(false); + try{ + format.parse(timeString); + }catch(Exception e){ + return false; + } + return true; + } + + /** + + * 格式化时间 + + * @param timestamp + + * @return + + */ + public static String dateFormat(Date timestamp){ + SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return format.format(timestamp); + } + + /** + + * 获取系统时间Timestamp + + * @return + + */ + public static Timestamp getSysTimestamp(){ + return new Timestamp(System.currentTimeMillis()); + } + + /** + + * 获取系统时间Date + + * @return + + */ + public static Date getSysDate(){ + return new Date(); + } + + /** + + * 生成时间随机数 + + * @return + + */ + public static String getDateRandom(){ + String s=new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()); + return s; + } +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/GenUtils.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/GenUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..9db1efe5d8f4f5dca196120c073ca8f81c17aeb1 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/GenUtils.java @@ -0,0 +1,226 @@ +package com.pearadmin.generator.utils; + +import com.pearadmin.generator.entity.ColumnEntity; +import com.pearadmin.generator.entity.TableEntity; +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.WordUtils; +import org.apache.velocity.Template; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.Velocity; + + +import java.io.File; +import java.io.IOException; +import java.io.StringWriter; +import java.util.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * 代码生成器 工具类 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年12月19日 下午11:40:24 + */ +public class GenUtils { + + public static List getTemplates(){ + List templates = new ArrayList(); + templates.add("template/Entity.java.vm"); + templates.add("template/Dao.java.vm"); + templates.add("template/Dao.xml.vm"); + templates.add("template/Service.java.vm"); + templates.add("template/ServiceImpl.java.vm"); + templates.add("template/Controller.java.vm"); + templates.add("template/Api.java.vm"); + templates.add("template/list.html.vm"); + templates.add("template/list.js.vm"); + templates.add("template/menu.sql.vm"); + return templates; + } + + /** + * 生成代码 + */ + public static void generatorCode(Map table, + List> columns, ZipOutputStream zip){ + //配置信息 + Configuration config = getConfig(); + + //表信息 + TableEntity tableEntity = new TableEntity(); + tableEntity.setTableName(table.get("tableName")); + tableEntity.setComments(table.get("tableComment")); + //表名转换成Java类名 + String className = tableToJava(tableEntity.getTableName(), config.getString("tablePrefix")); + tableEntity.setClassName(className); + tableEntity.setClassname(StringUtils.uncapitalize(className)); + + //列信息 + List columsList = new ArrayList<>(); + for(Map column : columns){ + ColumnEntity columnEntity = new ColumnEntity(); + + //跳过version字段的生成 + if("version".equalsIgnoreCase(column.get("columnName"))){ + continue; + } + + columnEntity.setColumnName(column.get("columnName")); + columnEntity.setDataType(column.get("dataType").toLowerCase()); + columnEntity.setComments(column.get("columnComment")); + columnEntity.setExtra(column.get("extra")); + + //列名转换成Java属性名 + String attrName = columnToJava(columnEntity.getColumnName()); + columnEntity.setAttrName(attrName); + columnEntity.setAttrname(StringUtils.uncapitalize(attrName)); + + //列的数据类型,转换成Java类型 + String attrType = config.getString(columnEntity.getDataType(), "unknowType"); + columnEntity.setAttrType(attrType); + + //是否主键 + if("PRI".equalsIgnoreCase(column.get("columnKey")) && tableEntity.getPk() == null){ + tableEntity.setPk(columnEntity); + } + + columsList.add(columnEntity); + } + tableEntity.setColumns(columsList); + + //没主键,则第一个字段为主键 + if(tableEntity.getPk() == null){ + tableEntity.setPk(tableEntity.getColumns().get(0)); + } + + //设置velocity资源加载器 + Properties prop = new Properties(); + prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); + Velocity.init(prop); + + //封装模板数据 + Map map = new HashMap<>(); + map.put("tableName", tableEntity.getTableName()); + map.put("comments", tableEntity.getComments()); + map.put("pk", tableEntity.getPk()); + map.put("className", tableEntity.getClassName()); + map.put("classname", tableEntity.getClassname()); + map.put("pathName", tableEntity.getClassname().toLowerCase()); + map.put("modername", config.getString("modelname").toLowerCase()); + map.put("columns", tableEntity.getColumns()); + map.put("package", config.getString("package")); + map.put("author", config.getString("author")); + map.put("email", config.getString("email")); + map.put("datetime", DateGenUtils.format(new Date(), DateGenUtils.DATE_TIME_PATTERN)); + VelocityContext context = new VelocityContext(map); + + //获取模板列表 + List templates = getTemplates(); + for(String template : templates){ + //渲染模板 + StringWriter sw = new StringWriter(); + Template tpl = Velocity.getTemplate(template, "UTF-8"); + tpl.merge(context, sw); + + try { + //添加到zip + zip.putNextEntry(new ZipEntry(getFileName(template, tableEntity.getClassName(), config.getString("package")))); + IOUtils.write(sw.toString(), zip, "UTF-8"); + IOUtils.closeQuietly(sw); + zip.closeEntry(); + } catch (IOException e) { + throw new RRException("渲染模板失败,表名:" + tableEntity.getTableName(), e); + } + } + } + + + /** + * 列名转换成Java属性名 + */ + public static String columnToJava(String columnName) { + return WordUtils.capitalizeFully(columnName, new char[]{'_'}).replace("_", ""); + } + + /** + * 表名转换成Java类名 + */ + public static String tableToJava(String tableName, String tablePrefix) { + if(StringUtils.isNotBlank(tablePrefix)){ + tableName = tableName.replace(tablePrefix, ""); + } + return columnToJava(tableName); + } + + /** + * 获取配置信息 + */ + public static Configuration getConfig(){ + try { + return new PropertiesConfiguration("generator.properties"); + } catch (ConfigurationException e) { + throw new RRException("获取配置文件失败,", e); + } + } + + /** + * 获取文件名 + */ + public static String getFileName(String template, String className, String packageName){ + //配置信息 + Configuration config = getConfig(); + String packagePath = "main" + File.separator + "java" + File.separator; + if(StringUtils.isNotBlank(packageName)){ + packagePath += packageName.replace(".", File.separator) + File.separator; + } + + if(template.contains("Entity.java.vm")){ + return packagePath + "entity" + File.separator + className + "Entity.java"; + } + + if(template.contains("Dao.java.vm")){ + return packagePath + "dao" + File.separator + className + "Dao.java"; + } + + if(template.contains("Dao.xml.vm")){ + return packagePath + "dao" + File.separator + className + "Dao.xml"; + } + + if(template.contains("Service.java.vm")){ + return packagePath + "service" + File.separator + className + "Service.java"; + } + + if(template.contains("ServiceImpl.java.vm")){ + return packagePath + "service" + File.separator + "impl" + File.separator + className + "ServiceImpl.java"; + } + + if(template.contains("Controller.java.vm")){ + return packagePath + "controller" + File.separator + className + "Controller.java"; + } + + if(template.contains("Api.java.vm")){ + return packagePath + "api" + File.separator +"Api"+ className + "Controller.java"; + } + + if(template.contains("list.html.vm")){ + return "main" + File.separator + "webapp" + File.separator + "WEB-INF" + File.separator + "page" + + File.separator + config.getString("modelname").toLowerCase() + File.separator + className.toLowerCase() + ".html"; + } + + if(template.contains("list.js.vm")){ + return "main" + File.separator + "webapp" + File.separator + "js" + File.separator + config.getString("modelname").toLowerCase() + File.separator + className.toLowerCase() + ".js"; + } + + if(template.contains("menu.sql.vm")){ + return className.toLowerCase() + "_menu.sql"; + } + + return null; + } +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/HTMLFilter.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/HTMLFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..06e636e3badcac612891b361e5558e91478d73d5 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/HTMLFilter.java @@ -0,0 +1,530 @@ +package com.pearadmin.generator.utils; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * HTML filtering utility for protecting against XSS (Cross Site Scripting). + * + * This code is licensed LGPLv3 + * + * This code is a Java port of the original work in PHP by Cal Hendersen. + * http://code.iamcal.com/php/lib_filter/ + * + * The trickiest part of the translation was handling the differences in regex handling + * between PHP and Java. These resources were helpful in the process: + * + * http://java.sun.com/j2se/1.4.2/docs/api/java/util/regex/Pattern.html + * http://us2.php.net/manual/en/reference.pcre.pattern.modifiers.php + * http://www.regular-expressions.info/modifiers.html + * + * A note on naming conventions: instance variables are prefixed with a "v"; global + * constants are in all caps. + * + * Sample use: + * String input = ... + * String clean = new HTMLFilter().filter( input ); + * + * The class is not thread safe. Create a new instance if in doubt. + * + * If you find bugs or have suggestions on improvement (especially regarding + * performance), please contact us. The latest version of this + * source, and our contact details, can be found at http://xss-html-filter.sf.net + * + * @author Joseph O'Connell + * @author Cal Hendersen + * @author Michael Semb Wever + */ +public final class HTMLFilter { + + /** regex flag union representing /si modifiers in php **/ + private static final int REGEX_FLAGS_SI = Pattern.CASE_INSENSITIVE | Pattern.DOTALL; + private static final Pattern P_COMMENTS = Pattern.compile("", Pattern.DOTALL); + private static final Pattern P_COMMENT = Pattern.compile("^!--(.*)--$", REGEX_FLAGS_SI); + private static final Pattern P_TAGS = Pattern.compile("<(.*?)>", Pattern.DOTALL); + private static final Pattern P_END_TAG = Pattern.compile("^/([a-z0-9]+)", REGEX_FLAGS_SI); + private static final Pattern P_START_TAG = Pattern.compile("^([a-z0-9]+)(.*?)(/?)$", REGEX_FLAGS_SI); + private static final Pattern P_QUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)=([\"'])(.*?)\\2", REGEX_FLAGS_SI); + private static final Pattern P_UNQUOTED_ATTRIBUTES = Pattern.compile("([a-z0-9]+)(=)([^\"\\s']+)", REGEX_FLAGS_SI); + private static final Pattern P_PROTOCOL = Pattern.compile("^([^:]+):", REGEX_FLAGS_SI); + private static final Pattern P_ENTITY = Pattern.compile("&#(\\d+);?"); + private static final Pattern P_ENTITY_UNICODE = Pattern.compile("&#x([0-9a-f]+);?"); + private static final Pattern P_ENCODE = Pattern.compile("%([0-9a-f]{2});?"); + private static final Pattern P_VALID_ENTITIES = Pattern.compile("&([^&;]*)(?=(;|&|$))"); + private static final Pattern P_VALID_QUOTES = Pattern.compile("(>|^)([^<]+?)(<|$)", Pattern.DOTALL); + private static final Pattern P_END_ARROW = Pattern.compile("^>"); + private static final Pattern P_BODY_TO_END = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_XML_CONTENT = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_STRAY_LEFT_ARROW = Pattern.compile("<([^>]*?)(?=<|$)"); + private static final Pattern P_STRAY_RIGHT_ARROW = Pattern.compile("(^|>)([^<]*?)(?=>)"); + private static final Pattern P_AMP = Pattern.compile("&"); + private static final Pattern P_QUOTE = Pattern.compile("<"); + private static final Pattern P_LEFT_ARROW = Pattern.compile("<"); + private static final Pattern P_RIGHT_ARROW = Pattern.compile(">"); + private static final Pattern P_BOTH_ARROWS = Pattern.compile("<>"); + + // @xxx could grow large... maybe use sesat's ReferenceMap + private static final ConcurrentMap P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap(); + private static final ConcurrentMap P_REMOVE_SELF_BLANKS = new ConcurrentHashMap(); + + /** set of allowed html elements, along with allowed attributes for each element **/ + private final Map> vAllowed; + /** counts of open tags for each (allowable) html element **/ + private final Map vTagCounts = new HashMap(); + + /** html elements which must always be self-closing (e.g. "") **/ + private final String[] vSelfClosingTags; + /** html elements which must always have separate opening and closing tags (e.g. "") **/ + private final String[] vNeedClosingTags; + /** set of disallowed html elements **/ + private final String[] vDisallowed; + /** attributes which should be checked for valid protocols **/ + private final String[] vProtocolAtts; + /** allowed protocols **/ + private final String[] vAllowedProtocols; + /** tags which should be removed if they contain no content (e.g. "" or "") **/ + private final String[] vRemoveBlanks; + /** entities allowed within html markup **/ + private final String[] vAllowedEntities; + /** flag determining whether comments are allowed in input String. */ + private final boolean stripComment; + private final boolean encodeQuotes; + private boolean vDebug = false; + /** + * flag determining whether to try to make tags when presented with "unbalanced" + * angle brackets (e.g. "" becomes " text "). If set to false, + * unbalanced angle brackets will be html escaped. + */ + private final boolean alwaysMakeTags; + + /** Default constructor. + * + */ + public HTMLFilter() { + vAllowed = new HashMap<>(); + + final ArrayList a_atts = new ArrayList(); + a_atts.add("href"); + a_atts.add("target"); + vAllowed.put("a", a_atts); + + final ArrayList img_atts = new ArrayList(); + img_atts.add("src"); + img_atts.add("width"); + img_atts.add("height"); + img_atts.add("alt"); + vAllowed.put("img", img_atts); + + final ArrayList no_atts = new ArrayList(); + vAllowed.put("b", no_atts); + vAllowed.put("strong", no_atts); + vAllowed.put("i", no_atts); + vAllowed.put("em", no_atts); + + vSelfClosingTags = new String[]{"img"}; + vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"}; + vDisallowed = new String[]{}; + vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp. + vProtocolAtts = new String[]{"src", "href"}; + vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"}; + vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"}; + stripComment = true; + encodeQuotes = true; + alwaysMakeTags = true; + } + + /** Set debug flag to true. Otherwise use default settings. See the default constructor. + * + * @param debug turn debug on with a true argument + */ + public HTMLFilter(final boolean debug) { + this(); + vDebug = debug; + + } + + /** Map-parameter configurable constructor. + * + * @param conf map containing configuration. keys match field names. + */ + public HTMLFilter(final Map conf) { + + assert conf.containsKey("vAllowed") : "configuration requires vAllowed"; + assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags"; + assert conf.containsKey("vNeedClosingTags") : "configuration requires vNeedClosingTags"; + assert conf.containsKey("vDisallowed") : "configuration requires vDisallowed"; + assert conf.containsKey("vAllowedProtocols") : "configuration requires vAllowedProtocols"; + assert conf.containsKey("vProtocolAtts") : "configuration requires vProtocolAtts"; + assert conf.containsKey("vRemoveBlanks") : "configuration requires vRemoveBlanks"; + assert conf.containsKey("vAllowedEntities") : "configuration requires vAllowedEntities"; + + vAllowed = Collections.unmodifiableMap((HashMap>) conf.get("vAllowed")); + vSelfClosingTags = (String[]) conf.get("vSelfClosingTags"); + vNeedClosingTags = (String[]) conf.get("vNeedClosingTags"); + vDisallowed = (String[]) conf.get("vDisallowed"); + vAllowedProtocols = (String[]) conf.get("vAllowedProtocols"); + vProtocolAtts = (String[]) conf.get("vProtocolAtts"); + vRemoveBlanks = (String[]) conf.get("vRemoveBlanks"); + vAllowedEntities = (String[]) conf.get("vAllowedEntities"); + stripComment = conf.containsKey("stripComment") ? (Boolean) conf.get("stripComment") : true; + encodeQuotes = conf.containsKey("encodeQuotes") ? (Boolean) conf.get("encodeQuotes") : true; + alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true; + } + + private void reset() { + vTagCounts.clear(); + } + + private void debug(final String msg) { + if (vDebug) { + Logger.getAnonymousLogger().info(msg); + } + } + + //--------------------------------------------------------------- + // my versions of some PHP library functions + public static String chr(final int decimal) { + return String.valueOf((char) decimal); + } + + public static String htmlSpecialChars(final String s) { + String result = s; + result = regexReplace(P_AMP, "&", result); + result = regexReplace(P_QUOTE, """, result); + result = regexReplace(P_LEFT_ARROW, "<", result); + result = regexReplace(P_RIGHT_ARROW, ">", result); + return result; + } + + //--------------------------------------------------------------- + /** + * given a user submitted input String, filter out any invalid or restricted + * html. + * + * @param input text (i.e. submitted by a user) than may contain html + * @return "clean" version of input, with only valid, whitelisted html elements allowed + */ + public String filter(final String input) { + reset(); + String s = input; + + debug("************************************************"); + debug(" INPUT: " + input); + + s = escapeComments(s); + debug(" escapeComments: " + s); + + s = balanceHTML(s); + debug(" balanceHTML: " + s); + + s = checkTags(s); + debug(" checkTags: " + s); + + s = processRemoveBlanks(s); + debug("processRemoveBlanks: " + s); + + s = validateEntities(s); + debug(" validateEntites: " + s); + + debug("************************************************\n\n"); + return s; + } + + public boolean isAlwaysMakeTags(){ + return alwaysMakeTags; + } + + public boolean isStripComments(){ + return stripComment; + } + + private String escapeComments(final String s) { + final Matcher m = P_COMMENTS.matcher(s); + final StringBuffer buf = new StringBuffer(); + if (m.find()) { + final String match = m.group(1); //(.*?) + m.appendReplacement(buf, Matcher.quoteReplacement("")); + } + m.appendTail(buf); + + return buf.toString(); + } + + private String balanceHTML(String s) { + if (alwaysMakeTags) { + // + // try and form html + // + s = regexReplace(P_END_ARROW, "", s); + s = regexReplace(P_BODY_TO_END, "<$1>", s); + s = regexReplace(P_XML_CONTENT, "$1<$2", s); + + } else { + // + // escape stray brackets + // + s = regexReplace(P_STRAY_LEFT_ARROW, "<$1", s); + s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2><", s); + + // + // the last regexp causes '<>' entities to appear + // (we need to do a lookahead assertion so that the last bracket can + // be used in the next pass of the regexp) + // + s = regexReplace(P_BOTH_ARROWS, "", s); + } + + return s; + } + + private String checkTags(String s) { + Matcher m = P_TAGS.matcher(s); + + final StringBuffer buf = new StringBuffer(); + while (m.find()) { + String replaceStr = m.group(1); + replaceStr = processTag(replaceStr); + m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr)); + } + m.appendTail(buf); + + s = buf.toString(); + + // these get tallied in processTag + // (remember to reset before subsequent calls to filter method) + for (String key : vTagCounts.keySet()) { + for (int ii = 0; ii < vTagCounts.get(key); ii++) { + s += ""; + } + } + + return s; + } + + private String processRemoveBlanks(final String s) { + String result = s; + for (String tag : vRemoveBlanks) { + if(!P_REMOVE_PAIR_BLANKS.containsKey(tag)){ + P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?>")); + } + result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result); + if(!P_REMOVE_SELF_BLANKS.containsKey(tag)){ + P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>")); + } + result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result); + } + + return result; + } + + private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) { + Matcher m = regex_pattern.matcher(s); + return m.replaceAll(replacement); + } + + private String processTag(final String s) { + // ending tags + Matcher m = P_END_TAG.matcher(s); + if (m.find()) { + final String name = m.group(1).toLowerCase(); + if (allowed(name)) { + if (!inArray(name, vSelfClosingTags)) { + if (vTagCounts.containsKey(name)) { + vTagCounts.put(name, vTagCounts.get(name) - 1); + return ""; + } + } + } + } + + // starting tags + m = P_START_TAG.matcher(s); + if (m.find()) { + final String name = m.group(1).toLowerCase(); + final String body = m.group(2); + String ending = m.group(3); + + //debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" ); + if (allowed(name)) { + String params = ""; + + final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body); + final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body); + final List paramNames = new ArrayList(); + final List paramValues = new ArrayList(); + while (m2.find()) { + paramNames.add(m2.group(1)); //([a-z0-9]+) + paramValues.add(m2.group(3)); //(.*?) + } + while (m3.find()) { + paramNames.add(m3.group(1)); //([a-z0-9]+) + paramValues.add(m3.group(3)); //([^\"\\s']+) + } + + String paramName, paramValue; + for (int ii = 0; ii < paramNames.size(); ii++) { + paramName = paramNames.get(ii).toLowerCase(); + paramValue = paramValues.get(ii); + +// debug( "paramName='" + paramName + "'" ); +// debug( "paramValue='" + paramValue + "'" ); +// debug( "allowed? " + vAllowed.get( name ).contains( paramName ) ); + + if (allowedAttribute(name, paramName)) { + if (inArray(paramName, vProtocolAtts)) { + paramValue = processParamProtocol(paramValue); + } + params += " " + paramName + "=\"" + paramValue + "\""; + } + } + + if (inArray(name, vSelfClosingTags)) { + ending = " /"; + } + + if (inArray(name, vNeedClosingTags)) { + ending = ""; + } + + if (ending == null || ending.length() < 1) { + if (vTagCounts.containsKey(name)) { + vTagCounts.put(name, vTagCounts.get(name) + 1); + } else { + vTagCounts.put(name, 1); + } + } else { + ending = " /"; + } + return "<" + name + params + ending + ">"; + } else { + return ""; + } + } + + // comments + m = P_COMMENT.matcher(s); + if (!stripComment && m.find()) { + return "<" + m.group() + ">"; + } + + return ""; + } + + private String processParamProtocol(String s) { + s = decodeEntities(s); + final Matcher m = P_PROTOCOL.matcher(s); + if (m.find()) { + final String protocol = m.group(1); + if (!inArray(protocol, vAllowedProtocols)) { + // bad protocol, turn into local anchor link instead + s = "#" + s.substring(protocol.length() + 1, s.length()); + if (s.startsWith("#//")) { + s = "#" + s.substring(3, s.length()); + } + } + } + + return s; + } + + private String decodeEntities(String s) { + StringBuffer buf = new StringBuffer(); + + Matcher m = P_ENTITY.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.decode(match).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENTITY_UNICODE.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + buf = new StringBuffer(); + m = P_ENCODE.matcher(s); + while (m.find()) { + final String match = m.group(1); + final int decimal = Integer.valueOf(match, 16).intValue(); + m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal))); + } + m.appendTail(buf); + s = buf.toString(); + + s = validateEntities(s); + return s; + } + + private String validateEntities(final String s) { + StringBuffer buf = new StringBuffer(); + + // validate entities throughout the string + Matcher m = P_VALID_ENTITIES.matcher(s); + while (m.find()) { + final String one = m.group(1); //([^&;]*) + final String two = m.group(2); //(?=(;|&|$)) + m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two))); + } + m.appendTail(buf); + + return encodeQuotes(buf.toString()); + } + + private String encodeQuotes(final String s){ + if(encodeQuotes){ + StringBuffer buf = new StringBuffer(); + Matcher m = P_VALID_QUOTES.matcher(s); + while (m.find()) { + final String one = m.group(1); //(>|^) + final String two = m.group(2); //([^<]+?) + final String three = m.group(3); //(<|$) + m.appendReplacement(buf, Matcher.quoteReplacement(one + regexReplace(P_QUOTE, """, two) + three)); + } + m.appendTail(buf); + return buf.toString(); + }else{ + return s; + } + } + + private String checkEntity(final String preamble, final String term) { + + return ";".equals(term) && isValidEntity(preamble) + ? '&' + preamble + : "&" + preamble; + } + + private boolean isValidEntity(final String entity) { + return inArray(entity, vAllowedEntities); + } + + private static boolean inArray(final String s, final String[] array) { + for (String item : array) { + if (item != null && item.equals(s)) { + return true; + } + } + return false; + } + + private boolean allowed(final String name) { + return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed); + } + + private boolean allowedAttribute(final String name, final String paramName) { + return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName)); + } +} \ No newline at end of file diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/PageUtils.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/PageUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..540cdca14f6a933c298c1d84ae9c48dfb2e53694 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/PageUtils.java @@ -0,0 +1,81 @@ +package com.pearadmin.generator.utils; + +import java.io.Serializable; +import java.util.List; + +/** + * 分页工具类 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年11月4日 下午12:59:00 + */ +public class PageUtils implements Serializable { + private static final long serialVersionUID = 1L; + //总记录数 + private int totalCount; + //每页记录数 + private int pageSize; + //总页数 + private int totalPage; + //当前页数 + private int currPage; + //列表数据 + private List list; + + /** + * 分页 + * @param list 列表数据 + * @param totalCount 总记录数 + * @param pageSize 每页记录数 + * @param currPage 当前页数 + */ + public PageUtils(List list, int totalCount, int pageSize, int currPage) { + this.list = list; + this.totalCount = totalCount; + this.pageSize = pageSize; + this.currPage = currPage; + this.totalPage = (int)Math.ceil((double)totalCount/pageSize); + } + + public int getTotalCount() { + return totalCount; + } + + public void setTotalCount(int totalCount) { + this.totalCount = totalCount; + } + + public int getPageSize() { + return pageSize; + } + + public void setPageSize(int pageSize) { + this.pageSize = pageSize; + } + + public int getTotalPage() { + return totalPage; + } + + public void setTotalPage(int totalPage) { + this.totalPage = totalPage; + } + + public int getCurrPage() { + return currPage; + } + + public void setCurrPage(int currPage) { + this.currPage = currPage; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/Query.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/Query.java new file mode 100644 index 0000000000000000000000000000000000000000..8a96f68e9c25d854255e266b3820c7354f8a27c7 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/Query.java @@ -0,0 +1,54 @@ +package com.pearadmin.generator.utils; + + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 查询参数 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2017-08-14 23:15 + */ +public class Query extends LinkedHashMap { + private static final long serialVersionUID = 1L; + //当前页码 + private int page; + //每页条数 + private int limit; + + public Query(Map params){ + this.putAll(params); + + //分页参数 + this.page = Integer.parseInt(params.get("page")+""); + this.limit = Integer.parseInt(params.get("limit")+""); + //this.put("offset", (page - 1) * limit);//框架升级,不使用mysql直接分页,使用com.github.pagehelper.PageInterceptor进行统一分页,兼容oracle + this.put("page", page); + this.put("limit", limit); + + //防止SQL注入(因为sidx、order是通过拼接SQL实现排序的,会有SQL注入风险) + String sidx = params.get("sidx")+""; + String order = params.get("order")+""; + this.put("sidx", SQLFilter.sqlInject(sidx)); + this.put("order", SQLFilter.sqlInject(order)); + } + + + public int getPage() { + return page; + } + + public void setPage(int page) { + this.page = page; + } + + public int getLimit() { + return limit; + } + + public void setLimit(int limit) { + this.limit = limit; + } +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/R.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/R.java new file mode 100644 index 0000000000000000000000000000000000000000..07505d34e2a532b0298291d526427a7e146f41bc --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/R.java @@ -0,0 +1,67 @@ +package com.pearadmin.generator.utils; + +import java.util.HashMap; +import java.util.Map; + +/** + * 返回数据 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年10月27日 下午9:59:27 + */ +public class R extends HashMap { + private static final long serialVersionUID = 1L; + + public final static String CODE = "code"; + public final static String MSG = "msg"; + + public R() { + put(CODE, 0); + } + + /* + * 在错误的情况下,不允许直接返回未知异常,要定义错误代码和消息 + */ + @Deprecated + public static R error() { + return error(RRException.CODE_TYPE_OTHER, "未知异常,请联系管理员"); + } + + /* + * 在错误的情况下,不允许直接返回未知异常,要定义错误代码和消息 + */ + @Deprecated + public static R error(String msg) { + return error(RRException.CODE_TYPE_OTHER, msg); + } + + public static R error(int code, String msg) { + R r = new R(); + r.put(CODE, code); + r.put(MSG, msg); + return r; + } + + public static R ok(String msg) { + R r = new R(); + r.put(MSG, msg); + return r; + } + + public static R ok(Map map) { + R r = new R(); + r.putAll(map); + return r; + } + + public static R ok() { + return new R(); + } + @Override + public R put(String key, Object value) { + super.put(key, value); + return this; + } + +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/RRException.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/RRException.java new file mode 100644 index 0000000000000000000000000000000000000000..ba226a41ece02f6d380f39a4ce628b22d607815b --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/RRException.java @@ -0,0 +1,106 @@ +package com.pearadmin.generator.utils; + +/** + * 自定义异常 + * + * @author chenjunfei + * @email kkomge@qq.com + * @date 2016年10月27日 下午10:11:27 + */ +public class RRException extends RuntimeException { + private static final long serialVersionUID = 1L; + /** + * 框架错误 + */ + public static final int CODE_TYPE_FRAMEWORK=10; + /** + * 数据库错误 + */ + public static final int CODE_TYPE_DATABASE=100; + /** + * 权限错误 + */ + public static final int CODE_TYPE_AUTHORIZATION=200; + /** + * 工具错误 + */ + public static final int CODE_TYPE_UTILS=300; + /** + * 其他内部错误 + */ + public static final int CODE_TYPE_OTHER=400; + /** + * api授权错误 + */ + public static final int CODE_TYPE_API_TOKEN=500; + /** + * 业务错误 + */ + public static final int CODE_TYPE_BUSINESS=600; + + private String msg; + private int code = CODE_TYPE_OTHER; + + /** + * 在错误的情况下,不允许直接返回未知异常,要定义错误代码和消息 + */ + @Deprecated + public RRException(String msg) { + super(msg); + this.msg = msg; + } + /** + * 在错误的情况下,不允许直接返回未知异常,要定义错误代码和消息 + */ + @Deprecated + public RRException(Throwable e) { + super(e); + } + /** + * 在错误的情况下,不允许直接返回未知异常,要定义错误代码和消息 + */ + @Deprecated + public RRException(String msg, Throwable e) { + super(msg, e); + this.msg = msg; + } + + public RRException(String msg, int code) { + super(msg); + this.msg = msg; + this.code = code; + } + + public RRException(String msg, int code, Throwable e) { + super(msg, e); + this.msg = msg; + this.code = code; + } + + public RRException(R r) { + if(null == r.get(R.MSG) || null == r.get(R.CODE)) { + throw new NullPointerException("无效的构造参数"); + } + + this.msg = r.get(R.MSG) + ""; + this.code = Integer.parseInt(r.get(R.CODE) + ""); + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + +} \ No newline at end of file diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/SQLFilter.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/SQLFilter.java new file mode 100644 index 0000000000000000000000000000000000000000..fcc9aef53a5dd1956f7b4aed78cb71b02419fdb0 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/SQLFilter.java @@ -0,0 +1,43 @@ +package com.pearadmin.generator.utils; + + +import org.apache.commons.lang3.StringUtils; + +/** + * SQL过滤 + * @author chenjunfei + * @email kkomge@qq.com + * @date 2017-04-01 16:16 + */ +public class SQLFilter { + + /** + * SQL注入过滤 + * @param str 待验证的字符串 + */ + public static String sqlInject(String str){ + if(StringUtils.isBlank(str)){ + return null; + } + //去掉'|"|;|\字符 + str = StringUtils.replace(str, "'", ""); + str = StringUtils.replace(str, "\"", ""); + str = StringUtils.replace(str, ";", ""); + str = StringUtils.replace(str, "\\", ""); + + //转换成小写 + str = str.toLowerCase(); + + //非法字符 + String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alert", "drop"}; + + //判断是否包含非法字符 + for(String keyword : keywords){ + if(str.contains(keyword)){ + throw new RRException("包含非法字符"); + } + } + + return str; + } +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/XssHttpServletRequestWrapper.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/XssHttpServletRequestWrapper.java new file mode 100644 index 0000000000000000000000000000000000000000..0522e8159a92eec9ef4078445282b33a95a9ada8 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/XssHttpServletRequestWrapper.java @@ -0,0 +1,146 @@ +package com.pearadmin.generator.utils; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * XSS过滤处理 + * @author chenjunfei + * @email kkomge@qq.com + * @date 2017-04-01 11:29 + */ +public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper { + //没被包装过的HttpServletRequest(特殊场景,需要自己过滤) + HttpServletRequest orgRequest; + //对body也进行guolv + private String body; + //html过滤 + private final static HTMLFilter HTML_FILTER = new HTMLFilter(); + + public XssHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + orgRequest = request; + } + + @Override + public ServletInputStream getInputStream() throws IOException { + //非json类型,直接返回 + String header = super.getHeader(HttpHeaders.CONTENT_TYPE); + if(header!=null&&!header.equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)){ + return super.getInputStream(); + } + + //为空,直接返回 + String json = IOUtils.toString(super.getInputStream(), "utf-8"); + if (StringUtils.isBlank(json)) { + return super.getInputStream(); + } + + //xss过滤 + json = xssEncode(json); + final ByteArrayInputStream bis = new ByteArrayInputStream(json.getBytes("utf-8")); + return new ServletInputStream() { + @Override + public boolean isFinished() { + return true; + } + + @Override + public boolean isReady() { + return true; + } + + @Override + public void setReadListener(ReadListener readListener) { + } + + @Override + public int read() throws IOException { + return bis.read(); + } + }; + } + + @Override + public String getParameter(String name) { + String value = super.getParameter(xssEncode(name)); + if (StringUtils.isNotBlank(value)) { + value = xssEncode(value); + } + return value; + } + + @Override + public String[] getParameterValues(String name) { + String[] parameters = super.getParameterValues(name); + if (parameters == null || parameters.length == 0) { + return null; + } + + for (int i = 0; i < parameters.length; i++) { + parameters[i] = xssEncode(parameters[i]); + } + return parameters; + } + + @Override + public Map getParameterMap() { + Map map = new LinkedHashMap<>(); + Map parameters = super.getParameterMap(); + for (String key : parameters.keySet()) { + String[] values = parameters.get(key); + for (int i = 0; i < values.length; i++) { + values[i] = xssEncode(values[i]); + } + map.put(key, values); + } + return map; + } + + /** + * 覆盖getHeader方法,将参数名和参数值都做xss过滤. + * 如果需要获得原始的值,则通过super.getHeaders(name)来获取 + * getHeaderNames 也可能需要覆盖 + */ + @Override + public String getHeader(String name) { + String value = super.getHeader(xssEncode(name)); + if (StringUtils.isNotBlank(value)) { + value = xssEncode(value); + } + return value; + } + + private String xssEncode(String input) { + return HTML_FILTER.filter(input); + } + + /** + * 获取最原始的request + */ + public HttpServletRequest getOrgRequest() { + return orgRequest; + } + + /** + * 获取最原始的request + */ + public static HttpServletRequest getOrgRequest(HttpServletRequest request) { + if (request instanceof XssHttpServletRequestWrapper) { + return ((XssHttpServletRequestWrapper) request).getOrgRequest(); + } + return request; + } + +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/init.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/init.java new file mode 100644 index 0000000000000000000000000000000000000000..0d1a11f5c2b153b0f25fe30d93daac26fc4eb776 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/init.java @@ -0,0 +1,36 @@ +package com.pearadmin.generator.utils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.ApplicationArguments; +import org.springframework.boot.ApplicationRunner; +import org.springframework.stereotype.Component; + +import javax.sql.DataSource; + +/** + * springBoot启动成功后执行的事件 + */ +@Component +public class init implements ApplicationRunner { + + Logger logger= LoggerFactory.getLogger(getClass()); + + @Autowired + private DataSource dataSource; + + @Override + public void run(ApplicationArguments args) throws Exception { + //设置数据库的类型 + String url = dataSource.getConnection().getMetaData().getURL(); + if (url.contains("jdbc:oracle")) { + initContants.databaseType = initContants.DatabaseType.ORACLE; + logger.info("----------------系统使用oracle数据库----------------"); + }else { + logger.info("----------------系统使用mysql数据库----------------"); + initContants.databaseType = initContants.DatabaseType.MYSQL; + } + } + +} diff --git a/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/initContants.java b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/initContants.java new file mode 100644 index 0000000000000000000000000000000000000000..a78b3e6508d7bcf1a386076413e887a6ac8c47b4 --- /dev/null +++ b/pear-modules/pear-generator/src/main/java/com/pearadmin/generator/utils/initContants.java @@ -0,0 +1,20 @@ +package com.pearadmin.generator.utils; + + + +public class initContants { + + public static initContants.DatabaseType databaseType = null; + + + public enum DatabaseType { + /** + * mysql数据库 + */ + MYSQL, + /** + * oracle + */ + ORACLE + } +} diff --git a/pear-modules/pear-generator/src/main/resources/generator.properties b/pear-modules/pear-generator/src/main/resources/generator.properties new file mode 100644 index 0000000000000000000000000000000000000000..4df6883e5d16489a5cdea46c12c55da226b21c1d --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/generator.properties @@ -0,0 +1,38 @@ +#\u4EE3\u7801\u751F\u6210\u5668\uFF0C\u914D\u7F6E\u4FE1\u606F + +#\u5305\u540D +package=com.pearadmin +#\u4F5C\u8005 +author=fenghua +#Email +email=1548695346@QQ.COM +#\u8868\u524D\u7F00(\u7C7B\u540D\u4E0D\u4F1A\u5305\u542B\u8868\u524D\u7F00) +tablePrefix=tb_ +modelname=bpm +#\u7C7B\u578B\u8F6C\u6362\uFF0C\u914D\u7F6E\u4FE1\u606F +tinyint=Integer +smallint=Integer +mediumint=Integer +int=Integer +integer=Integer +number=Integer +bigint=Long +float=Float +double=Double +decimal=BigDecimal + + +char=String +varchar=String +varchar2=String +nvarchar2=String +tinytext=String +text=String +mediumtext=String +longtext=String +blob=String +clob=String + +date=Date +datetime=Date +timestamp=Date \ No newline at end of file diff --git a/pear-modules/pear-generator/src/main/resources/template/Api.java.vm b/pear-modules/pear-generator/src/main/resources/template/Api.java.vm new file mode 100644 index 0000000000000000000000000000000000000000..8d81cad9d64a36c2f618ca00533a60d46415f372 --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/Api.java.vm @@ -0,0 +1,93 @@ +package ${package}.api; + +import java.util.List; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; + +import ${package}.entity.${className}Entity; +import ${package}.service.${className}Service; +import ${package}.utils.PageUtils; +import ${package}.utils.Query; +import ${package}.utils.R; + + +/** + * ${comments}对外接口 + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +@Api(tags = "${comments}对外接口") +@RestController +@RequestMapping("api/${pathName}") +public class Api${className}Controller { + @Autowired + private ${className}Service ${classname}Service; + + /** + * 列表 + */ + @RequestMapping("/list") + public R list(@RequestParam Map params){ + //查询列表数据 + Query query = new Query(params); + + List<${className}Entity> ${classname}List = ${classname}Service.queryList(query); + int total = ${classname}Service.queryTotal(query); + + PageUtils pageUtil = new PageUtils(${classname}List, total, query.getLimit(), query.getPage()); + + return R.ok().put("page", pageUtil); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{${pk.attrname}}") + public R info(@PathVariable("${pk.attrname}") ${pk.attrType} ${pk.attrname}){ + ${className}Entity ${classname} = ${classname}Service.queryObject(${pk.attrname}); + + return R.ok().put("${classname}", ${classname}); + } + + /** + * 保存 + */ + @RequestMapping("/save") + public R save(@RequestBody ${className}Entity ${classname}){ + ${classname}Service.save(${classname}); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + public R update(@RequestBody ${className}Entity ${classname}){ + ${classname}Service.update(${classname}); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + public R delete(@RequestBody ${pk.attrType}[] ${pk.attrname}s){ + ${classname}Service.deleteBatch(${pk.attrname}s); + + return R.ok(); + } + +} diff --git a/pear-modules/pear-generator/src/main/resources/template/Controller.java.vm b/pear-modules/pear-generator/src/main/resources/template/Controller.java.vm new file mode 100644 index 0000000000000000000000000000000000000000..acb9f4d27cb8c7c9bf83a87cd3b5a6a8aa3cb29c --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/Controller.java.vm @@ -0,0 +1,98 @@ +package ${package}.controller; + +import java.util.List; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; +import io.swagger.annotations.Api; + +import ${package}.entity.${className}Entity; +import ${package}.service.${className}Service; +import ${package}.utils.PageUtils; +import ${package}.utils.Query; +import ${package}.utils.R; + + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +@Api(tags = "${comments}") +@RestController +@RequestMapping("${pathName}") +public class ${className}Controller { + @Autowired + private ${className}Service ${classname}Service; + + /** + * 列表 + */ + @RequestMapping("/list") + @RequiresPermissions("${modername}:${pathName}:list") + public R list(@RequestParam Map params){ + //查询列表数据 + Query query = new Query(params); + + List<${className}Entity> ${classname}List = ${classname}Service.queryList(query); + int total = ${classname}Service.queryTotal(query); + + PageUtils pageUtil = new PageUtils(${classname}List, total, query.getLimit(), query.getPage()); + + return R.ok().put("page", pageUtil); + } + + + /** + * 信息 + */ + @RequestMapping("/info/{${pk.attrname}}") + @RequiresPermissions("${modername}:${pathName}:info") + public R info(@PathVariable("${pk.attrname}") ${pk.attrType} ${pk.attrname}){ + ${className}Entity ${classname} = ${classname}Service.queryObject(${pk.attrname}); + + return R.ok().put("${classname}", ${classname}); + } + + /** + * 保存 + */ + @RequestMapping("/save") + @RequiresPermissions("${modername}:${pathName}:save") + public R save(@RequestBody ${className}Entity ${classname}){ + ${classname}Service.save(${classname}); + + return R.ok(); + } + + /** + * 修改 + */ + @RequestMapping("/update") + @RequiresPermissions("${modername}:${pathName}:update") + public R update(@RequestBody ${className}Entity ${classname}){ + ${classname}Service.update(${classname}); + + return R.ok(); + } + + /** + * 删除 + */ + @RequestMapping("/delete") + @RequiresPermissions("${modername}:${pathName}:delete") + public R delete(@RequestBody ${pk.attrType}[] ${pk.attrname}s){ + ${classname}Service.deleteBatch(${pk.attrname}s); + + return R.ok(); + } + +} diff --git a/pear-modules/pear-generator/src/main/resources/template/Dao.java.vm b/pear-modules/pear-generator/src/main/resources/template/Dao.java.vm new file mode 100644 index 0000000000000000000000000000000000000000..d25f828fccb5d633537a23792239106839b804cc --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/Dao.java.vm @@ -0,0 +1,15 @@ +package ${package}.dao; + +import ${package}.entity.${className}Entity; + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +@Repository +public interface ${className}Dao extends BaseDao<${className}Entity> { + +} diff --git a/pear-modules/pear-generator/src/main/resources/template/Dao.xml.vm b/pear-modules/pear-generator/src/main/resources/template/Dao.xml.vm new file mode 100644 index 0000000000000000000000000000000000000000..d7897d4fa92cff2a9a1161e737acdf9ba539a58b --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/Dao.xml.vm @@ -0,0 +1,77 @@ + + + + + + + +#foreach($column in $columns) + +#end + + + + + + + + + + insert into ${tableName} + ( +#foreach($column in $columns) +#if($column.columnName != $pk.columnName || $pk.extra != 'auto_increment') + $column.columnName#if($velocityCount != $columns.size()), #end + +#end +#end + ) + values + ( +#foreach($column in $columns) +#if($column.columnName != $pk.columnName || $pk.extra != 'auto_increment') + #{$column.attrname}#if($velocityCount != $columns.size()), #end + +#end +#end + ) + + + + update ${tableName} + +#foreach($column in $columns) +#if($column.columnName != $pk.columnName) + $column.columnName = #{$column.attrname}#if($velocityCount != $columns.size()), #end +#end +#end + + where ${pk.columnName} = #{${pk.attrname}} + + + + delete from ${tableName} where ${pk.columnName} = #{value} + + + + delete from ${tableName} where ${pk.columnName} in + + #{${pk.attrname}} + + + + \ No newline at end of file diff --git a/pear-modules/pear-generator/src/main/resources/template/Entity.java.vm b/pear-modules/pear-generator/src/main/resources/template/Entity.java.vm new file mode 100644 index 0000000000000000000000000000000000000000..25b2ca190b3f0f1b8b0957c03cafcf38955e8af4 --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/Entity.java.vm @@ -0,0 +1,41 @@ +package ${package}.entity; + +import java.io.Serializable; +import java.util.Date; +import xyz.yuanjilu.common.base.BaseEntity; + +#if(${hasBigDecimal}) +import java.math.BigDecimal; +#end + + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +public class ${className}Entity extends BaseEntity implements Serializable{ + private static final long serialVersionUID = 1L; + +#foreach ($column in $columns) + //$column.comments + private $column.attrType $column.attrname; +#end + +#foreach ($column in $columns) + /** + * 设置:${column.comments} + */ + public void set${column.attrName}($column.attrType $column.attrname) { + this.$column.attrname = $column.attrname; + } + /** + * 获取:${column.comments} + */ + public $column.attrType get${column.attrName}() { + return $column.attrname; + } +#end +} diff --git a/pear-modules/pear-generator/src/main/resources/template/Service.java.vm b/pear-modules/pear-generator/src/main/resources/template/Service.java.vm new file mode 100644 index 0000000000000000000000000000000000000000..24fa0cc74ad8d12614d62d9d9f1a48c7b1346b79 --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/Service.java.vm @@ -0,0 +1,30 @@ +package ${package}.service; + +import ${package}.entity.${className}Entity; + +import java.util.List; +import java.util.Map; + +/** + * ${comments} + * + * @author ${author} + * @email ${email} + * @date ${datetime} + */ +public interface ${className}Service { + + ${className}Entity queryObject(${pk.attrType} ${pk.attrname}); + + List<${className}Entity> queryList(Map map); + + int queryTotal(Map map); + + void save(${className}Entity ${classname}); + + void update(${className}Entity ${classname}); + + void delete(${pk.attrType} ${pk.attrname}); + + void deleteBatch(${pk.attrType}[] ${pk.attrname}s); +} diff --git a/pear-modules/pear-generator/src/main/resources/template/ServiceImpl.java.vm b/pear-modules/pear-generator/src/main/resources/template/ServiceImpl.java.vm new file mode 100644 index 0000000000000000000000000000000000000000..160d588012e29280e22a5104b9b0e939e2d22291 --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/ServiceImpl.java.vm @@ -0,0 +1,61 @@ +package ${package}.service.impl; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.Map; + +import ${package}.dao.${className}Dao; +import ${package}.entity.${className}Entity; +import ${package}.service.${className}Service; +import xyz.yuanjilu.common.utils.RRException; + + +@Service("${classname}Service") +public class ${className}ServiceImpl implements ${className}Service { + @Autowired + private ${className}Dao ${classname}Dao; + + @Override + public ${className}Entity queryObject(${pk.attrType} ${pk.attrname}){ + return ${classname}Dao.queryObject(${pk.attrname}); + } + + @Override + public List<${className}Entity> queryList(Map map){ + return ${classname}Dao.queryList(map); + } + + @Override + public int queryTotal(Map map){ + return ${classname}Dao.queryTotal(map); + } + + @Override + @Transactional(propagation=Propagation.REQUIRED,rollbackFor={RRException.class}) + public void save(${className}Entity ${classname}){ + ${classname}Dao.save(${classname}); + } + + @Override + @Transactional(propagation=Propagation.REQUIRED,rollbackFor={RRException.class}) + public void update(${className}Entity ${classname}){ + ${classname}Dao.update(${classname}); + } + + @Override + @Transactional(propagation=Propagation.REQUIRED,rollbackFor={RRException.class}) + public void delete(${pk.attrType} ${pk.attrname}){ + ${classname}Dao.delete(${pk.attrname}); + } + + @Override + @Transactional(propagation=Propagation.REQUIRED,rollbackFor={RRException.class}) + public void deleteBatch(${pk.attrType}[] ${pk.attrname}s){ + ${classname}Dao.deleteBatch(${pk.attrname}s); + } + +} diff --git a/pear-modules/pear-generator/src/main/resources/template/list.html.vm b/pear-modules/pear-generator/src/main/resources/template/list.html.vm new file mode 100644 index 0000000000000000000000000000000000000000..dcf83cb9ff0477076891223e80457be5da131142 --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/list.html.vm @@ -0,0 +1,54 @@ + + + +${comments} +#set($header='#parse("sys/header.html")') +#set($save='#if($shiro.hasPermission("'+${modername}+':'+${pathName}+':save"))') +#set($update='#if($shiro.hasPermission("'+${modername}+':'+${pathName}+':update"))') +#set($delete='#if($shiro.hasPermission("'+${modername}+':'+${pathName}+':delete"))') +#set($end='#end') +$header + + +
+
+
+ $save +  新增 + $end + $update +  修改 + $end + $delete +  删除 + $end +
+
+
+
+ +
+
{{title}}
+
+ #foreach($column in $columns) + #if($column.columnName != $pk.columnName) +
+
${column.comments}
+
+ +
+
+ #end + #end +
+
+ +    +
+
+
+
+ + + + \ No newline at end of file diff --git a/pear-modules/pear-generator/src/main/resources/template/list.js.vm b/pear-modules/pear-generator/src/main/resources/template/list.js.vm new file mode 100644 index 0000000000000000000000000000000000000000..b1b70dea0af530276fca416de8b6da606ea57780 --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/list.js.vm @@ -0,0 +1,103 @@ +$(function () { + $("#jqGrid").createGrid({ + url: baseURL+'/${pathName}/list', + datatype: "json", + colModel: [ +#foreach($column in $columns) +#if($column.columnName == $pk.columnName) + { label: '${column.attrname}', name: '${column.attrname}', index: '${column.columnName}', width: 50, key: true }, +#else + { label: '${column.comments}', name: '${column.attrname}', index: '${column.columnName}', width: 80 }#if($velocityCount != $columns.size()), #end + +#end +#end + ], + viewrecords: true, + height: 385, + }); +}); + +var vueappSetting={ + el:'#rrapp', + data:{ + showList: true, + title: null, + ${classname}: {} + }, + methods: { + query: function () { + vm.reload(); + }, + add: function(){ + vm.showList = false; + vm.title = "新增"; + vm.${classname} = {}; + }, + update: function (event) { + var $pk.attrname = getSelectedRow(); + if($pk.attrname == null){ + return ; + } + vm.showList = false; + vm.title = "修改"; + + vm.getInfo(${pk.attrname}) + }, + saveOrUpdate: function (event) { + var url = vm.${classname}.${pk.attrname} == null ? baseURL+"/${pathName}/save" : baseURL+"/${pathName}/update"; + $.ajax({ + type: "POST", + url: url, + contentType: "application/json", + data: JSON.stringify(vm.${classname}), + success: function(r){ + if(r.code === 0){ + alert('操作成功', function(index){ + vm.reload(); + }); + }else{ + alert(r.msg); + } + } + }); + }, + del: function (event) { + var ${pk.attrname}s = getSelectedRows(); + if(${pk.attrname}s == null){ + return ; + } + + confirm('确定要删除选中的记录?', function(){ + $.ajax({ + type: "POST", + url: baseURL+"/${pathName}/delete", + contentType: "application/json", + data: JSON.stringify(${pk.attrname}s), + success: function(r){ + if(r.code == 0){ + alert('操作成功', function(index){ + $("#jqGrid").trigger("reloadGrid"); + }); + }else{ + alert(r.msg); + } + } + }); + }); + }, + getInfo: function(${pk.attrname}){ + $.get(baseURL+"/${pathName}/info/"+${pk.attrname}, function(r){ + vm.${classname} = r.${classname}; + }); + }, + reload: function (event) { + vm.showList = true; + var page = $("#jqGrid").jqGrid('getGridParam','page'); + $("#jqGrid").jqGrid('setGridParam',{ + page:page + }).trigger("reloadGrid"); + } + } +}; +vueappSetting =$.extend(true,vueappPageConfig,vueappSetting); +var vm = new Vue(vueappSetting); \ No newline at end of file diff --git a/pear-modules/pear-generator/src/main/resources/template/menu.sql.vm b/pear-modules/pear-generator/src/main/resources/template/menu.sql.vm new file mode 100644 index 0000000000000000000000000000000000000000..e3c1421032e7ab5df4a0ab1bbcf4d74a6f0244d4 --- /dev/null +++ b/pear-modules/pear-generator/src/main/resources/template/menu.sql.vm @@ -0,0 +1,21 @@ +-- 菜单SQL + +-- 按钮父菜单ID +set @parentId = REPLACE(UUID(),"-",""); + +INSERT INTO `sys_menu` (`menu_id`,`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + VALUES ( @parentId,'1', '${comments}', '${modername}/${pathName}.html', NULL, '1', 'fa fa-file-code-o', '6'); + +-- 菜单对应按钮SQL +INSERT INTO `sys_menu` (`menu_id`,`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + VALUES ( + REPLACE(UUID(),"-",""), @parentId, '查看', null, '${modername}:${pathName}:list,${modername}:${pathName}:info', '2', null, '6'); +INSERT INTO `sys_menu` (`menu_id`,`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + VALUES ( + REPLACE(UUID(),"-",""), @parentId, '新增', null, '${modername}:${pathName}:save', '2', null, '6'); +INSERT INTO `sys_menu` (`menu_id`,`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + VALUES ( + REPLACE(UUID(),"-",""), @parentId, '修改', null, '${modername}:${pathName}:update', '2', null, '6'); +INSERT INTO `sys_menu` (`menu_id`,`parent_id`, `name`, `url`, `perms`, `type`, `icon`, `order_num`) + VALUES ( + REPLACE(UUID(),"-",""), @parentId, '删除', null, '${modername}:${pathName}:delete', '2', null, '6'); diff --git a/pear-modules/pom.xml b/pear-modules/pom.xml index 7877289945a46313c3232eb2a44b615de038c678..1ed6077064f34a637d1b2c8c0d7f34d56e171b06 100644 --- a/pear-modules/pom.xml +++ b/pear-modules/pom.xml @@ -39,6 +39,7 @@ pear-system pear-security pear-schedule + pear-generator