Easycode模板,逆向工程,单表增删改查,从前端到后端不需要任何一点代码
目录结构
模板亮点
1、接口类默认继承实体类
实体类不做任何修改保证类与表统一
2、实体类涵盖多种注解
日期格式编码、Long类型转String、字段自动填充、validate校验
3、自带insertOrUpdateBatch方法
4、自动生成前端的增删改查页面
字符限制
5、牛逼的导入导出解决方案
支持导出模板、导出数据
支持导入校验,字符长度校验,日期类型校验,布尔类型校验,小数精度校验
上传文件,如果异常会返回批改后的文件(红色字体批注)
容错导入,正常数据会自动导入,异常数据会批改后返回
直接导入(如果有错,会批改导入文件,并下载出来)
允许容错
正确的数据会导入成功并删除,错误的数据会留下并下载出来
使用方式
部分代码需要下载资源,自己改造也可以
{
"author" : "Wsong",
"version" : "1.2.8",
"userSecure" : "",
"currTypeMapperGroupName" : "Default",
"currTemplateGroupName" : "ShuRong",
"currColumnConfigGroupName" : "Default",
"currGlobalConfigGroupName" : "Default",
"typeMapper" : {
"Default" : {
"name" : "Default",
"elementList" : [ {
"matchType" : "REGEX",
"columnType" : "varchar(\\(\\d+\\))?",
"javaType" : "java.lang.String"
}, {
"matchType" : "REGEX",
"columnType" : "char(\\(\\d+\\))?",
"javaType" : "java.lang.String"
}, {
"matchType" : "REGEX",
"columnType" : "(tiny|medium|long)*text",
"javaType" : "java.lang.String"
}, {
"matchType" : "REGEX",
"columnType" : "decimal(\\(\\d+,\\d+\\))?",
"javaType" : "java.lang.Double"
}, {
"matchType" : "ORDINARY",
"columnType" : "integer",
"javaType" : "java.lang.Integer"
}, {
"matchType" : "REGEX",
"columnType" : "(tiny|small|medium)*int(\\(\\d+\\))?",
"javaType" : "java.lang.Integer"
}, {
"matchType" : "ORDINARY",
"columnType" : "int4",
"javaType" : "java.lang.Integer"
}, {
"matchType" : "ORDINARY",
"columnType" : "int8",
"javaType" : "java.lang.Long"
}, {
"matchType" : "REGEX",
"columnType" : "bigint(\\(\\d+\\))?",
"javaType" : "java.lang.Long"
}, {
"matchType" : "ORDINARY",
"columnType" : "date",
"javaType" : "java.time.LocalDate"
}, {
"matchType" : "ORDINARY",
"columnType" : "datetime",
"javaType" : "java.time.LocalDateTime"
}, {
"matchType" : "ORDINARY",
"columnType" : "timestamp",
"javaType" : "java.time.LocalDateTime"
}, {
"matchType" : "ORDINARY",
"columnType" : "time",
"javaType" : "java.time.LocalTime"
}, {
"matchType" : "ORDINARY",
"columnType" : "boolean",
"javaType" : "java.lang.Boolean"
} ]
}
},
"template" : {
"ShuRong" : {
"name" : "ShuRong",
"elementList" : [ {
"name" : "controller.java.vm",
"code" : "##导入宏定义\n$!{define.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"Controller\")\n\n##保存文件(宏定义)\n#save(\"/controller\", \"Controller.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"controller\")\n\n##定义服务名\n#set($serviceName = $!tool.append($!tool.firstLowerCase($!tableInfo.name), \"Service\"))\n\n##定义实体对象名\n#set($entityName = $!tool.firstLowerCase($!tableInfo.name))\n\n#set($tree = $tool.toJson($tableInfo.fullColumn).contains('\"name\":\"pid\"')&&$tool.toJson($tableInfo.fullColumn).contains('\"name\":\"id\"'))\n\nimport cn.dmp.common.easycode.EasyValidateGroup;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.baomidou.mybatisplus.extension.api.ApiController;\nimport com.baomidou.mybatisplus.extension.api.R;\nimport $!{tableInfo.savePackageName}.entity.$!tableInfo.name;\nimport $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;\nimport org.springframework.web.bind.annotation.*;\nimport org.springframework.web.multipart.MultipartFile;\nimport org.springframework.validation.annotation.Validated;\n\nimport javax.servlet.http.HttpServletResponse;\nimport javax.annotation.Resource;\nimport java.io.Serializable;\nimport java.util.List;\n\n##表注释(宏定义)\n#tableComment(\"表控制层\")\n@RestController\n@RequestMapping(\"$!tool.firstLowerCase($!tableInfo.name)\")\npublic class $!{tableName} extends ApiController {\n /**\n * 服务对象\n */\n @Resource\n private $!{tableInfo.name}Service $!{serviceName};\n\n \n #if($tree)\n \n /**\n * 树\n * @param $!entityName 查询实体\n * @return 所有数据\n */\n @GetMapping(\"tree\")\n public R<List<$!tableInfo.name>> tree($!tableInfo.name $!entityName) {\n\n return success(this.$!{serviceName}.tree($!entityName));\n }\n /**\n * 懒加载树\n * @param $!entityName 查询实体\n * @return 所有数据\n */\n @GetMapping(\"treeLazy\")\n public R<List<$!tableInfo.name>> treeLazy($!tableInfo.name $!entityName) {\n\n return success(this.$!{serviceName}.treeLazy($!entityName));\n }\n #end\n\n /**\n * 分页查询所有数据\n *\n * @param page 分页对象\n * @param $!entityName 查询实体\n * @return 所有数据\n */\n @GetMapping(\"page\")\n public R<Page<$!tableInfo.name>> selectAll(Page<$!tableInfo.name> page, $!tableInfo.name $!entityName) {\n return success(this.$!{serviceName}.pagem(page, $!entityName));\n }\n /**\n * 查询所有数据\n *\n * @param $!entityName 查询实体\n * @return 所有数据\n */\n @GetMapping(\"list\")\n public R<List<$!tableInfo.name>> list($!tableInfo.name $!entityName) {\n return success(this.$!{serviceName}.listm($!entityName));\n }\n /**\n * 通过主键查询单条数据\n *\n * @param id 主键\n * @return 单条数据\n */\n @GetMapping(\"get/{id}\")\n public R<$!tableInfo.name> selectOne(@PathVariable Long id) {\n return success(this.$!{serviceName}.getById(id));\n }\n\n /**\n * 新增数据\n *\n * @param $!entityName 实体对象\n * @return 新增结果\n */\n @PostMapping\n public R<Boolean> insert(@RequestBody @Validated(EasyValidateGroup.AddGroup.class) $!tableInfo.name $!entityName) {\n return success(this.$!{serviceName}.savem($!entityName));\n }\n\n /**\n * 修改数据\n *\n * @param $!entityName 实体对象\n * @return 修改结果\n */\n @PutMapping\n public R<Boolean> update(@RequestBody @Validated(EasyValidateGroup.UpdGroup.class) $!tableInfo.name $!entityName) {\n return success(this.$!{serviceName}.updatem($!entityName));\n }\n\n /**\n * 删除数据\n *\n * @param idList 主键结合\n * @return 删除结果\n */\n @DeleteMapping\n public R<Boolean> delete(@RequestParam(\"idList\") List<Long> idList) {\n return success(this.$!{serviceName}.removem(idList));\n }\n \n /**\n * 模板导出\n *\n * @param response excel文件\n * @return\n * @throws Exception\n */\n @GetMapping(\"export/template\")\n public void exportTemplate(HttpServletResponse response) throws Exception {\n this.$!{serviceName}.exportTemplate(response);\n }\n\n\n /**\n * 数据导出\n *\n * @param response excel文件\n * @return\n * @throws Exception\n */\n @GetMapping(\"export/data\")\n public void exportData(HttpServletResponse response,Page<$!tableInfo.name> page, $!tableInfo.name $!entityName) throws Exception {\n this.$!{serviceName}.exportData(page,$!entityName,response);\n }\n \n \n /**\n * 指标类型导入\n *\n * @param file 文件\n */\n @PostMapping(\"import/data/{allError}\")\n public void importData(HttpServletResponse response,@RequestParam(\"file\") MultipartFile file,@PathVariable String allError) {\n this.$!{serviceName}.importData(response,file,allError);\n }\n}\n"
}, {
"name" : "service.java.vm",
"code" : "##导入宏定义\n$!{define.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"Service\")\n\n##保存文件(宏定义)\n#save(\"/service\", \"Service.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"service\")\n\n#set($tree = $tool.toJson($tableInfo.fullColumn).contains('\"name\":\"pid\"')&&$tool.toJson($tableInfo.fullColumn).contains('\"name\":\"id\"'))\n\n##定义实体对象名\n#set($entityName = $!tool.firstLowerCase($!tableInfo.name))\n\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.baomidou.mybatisplus.extension.service.IService;\nimport $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\nimport org.springframework.web.multipart.MultipartFile;\n\nimport javax.servlet.http.HttpServletResponse;\nimport java.util.List;\n\n##表注释(宏定义)\n#tableComment(\"表服务接口\")\npublic interface $!{tableName} extends IService<$!{tableInfo.name}> {\n #if($tree)\n List<$!{tableInfo.name}> tree($!{tableInfo.name} $!tool.firstLowerCase($!tableInfo.name));\n\n List<$!{tableInfo.name}> treeLazy($!{tableInfo.name} $!tool.firstLowerCase($!tableInfo.name));\n #end\n \n Page<$!tableInfo.name> pagem(Page<$!tableInfo.name> page, $!tableInfo.name $!entityName);\n \n List<$!tableInfo.name> listm($!tableInfo.name $!entityName);\n \n Boolean savem($!tableInfo.name $!entityName);\n \n Boolean updatem($!tableInfo.name $!entityName);\n \n Boolean removem(List<Long> idList);\n \n void exportTemplate(HttpServletResponse response);\n\n void exportData(Page<$!tableInfo.name> page, $!tableInfo.name $!entityName, HttpServletResponse response);\n \n void importData(HttpServletResponse response, MultipartFile file,String allError);\n}\n"
}, {
"name" : "serviceImpl.java.vm",
"code" : "##导入宏定义\n$!{define.vm}\n##引入mybatis支持\n$!{mybatisSupport.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"ServiceImpl\")\n\n##保存文件(宏定义)\n#save(\"/service/impl\", \"ServiceImpl.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"service.impl\")\n##定义实体对象名\n#set($entityName = $!tool.firstLowerCase($!tableInfo.name))\n\n#set($tree = $tool.toJson($tableInfo.fullColumn).contains('\"name\":\"pid\"')&&$tool.toJson($tableInfo.fullColumn).contains('\"name\":\"id\"'))\n\nimport cn.hutool.core.bean.BeanUtil;\nimport cn.hutool.core.util.ObjectUtil;\nimport cn.hutool.poi.excel.ExcelReader;\nimport cn.hutool.poi.excel.ExcelUtil;\nimport cn.hutool.poi.excel.ExcelWriter;\nimport com.baomidou.mybatisplus.extension.plugins.pagination.Page;\nimport com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\nimport $!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper;\nimport $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\nimport $!{tableInfo.savePackageName}.excel.$!{tableInfo.name}Excel;\nimport $!{tableInfo.savePackageName}.service.$!{tableInfo.name}Service;\nimport org.apache.commons.lang3.StringUtils;\nimport org.apache.poi.ss.usermodel.*;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\nimport lombok.extern.slf4j.Slf4j;\n\nimport java.io.IOException;\nimport java.util.*;\nimport java.util.stream.Collectors;\n\nimport com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;\nimport org.springframework.transaction.annotation.Transactional;\nimport org.springframework.web.multipart.MultipartFile;\n\nimport javax.servlet.http.HttpServletResponse;\n\nimport cn.dmp.common.easycode.EasyCodeResult;\nimport static cn.dmp.common.easycode.EasyCodeUtils.*;\n\n#if($tree)\nimport java.util.stream.Collectors;\nimport java.util.Optional;\n#end\n\n##表注释(宏定义)\n#tableComment(\"表服务实现类\")\n@Slf4j\n@Service(\"$!{entityName}Service\")\npublic class $!{tableName} extends ServiceImpl<$!{tableInfo.name}Mapper, $!{tableInfo.name}> implements $!{tableInfo.name}Service {\n \n#if($tree)\n @Override\n public List<$!{tableInfo.name}> tree($!{tableInfo.name} $!{entityName}) {\n QueryWrapper<$!{tableInfo.name}> wrapper = new QueryWrapper<>($!{entityName});\n List<$!{tableInfo.name}> list = this.list(wrapper);\n List<Long> ids = list.stream().map($!{tableInfo.name}::getId).collect(Collectors.toList());\n for ($!{tableInfo.name} di : list) {\n List<$!{tableInfo.name}> child = list.stream().filter(a -> Objects.equals(a.getPid(), di.getId())).collect(Collectors.toList());\n di.setChildren(Optional.of(child).orElse(new ArrayList<>()));\n }\n return list.stream().filter(a -> !ids.contains(a.getPid())).collect(Collectors.toList());\n }\n\n @Override\n public List<$!{tableInfo.name}> treeLazy($!{tableInfo.name} $!{entityName}) {\n QueryWrapper<$!{tableInfo.name}> wrapper = new QueryWrapper<>($!{entityName});\n if( $!{entityName}.getId()!=null&& $!{entityName}.getId()!=0){\n wrapper.notInSql(\"pid\",\"select id from $!{tableInfo.obj.name}\");\n }else{\n wrapper.eq(\"pid\", $!{entityName}.getId());\n }\n return this.list(wrapper);\n }\n#end\n\n @Override\n public Page<$!tableInfo.name> pagem(Page<$!tableInfo.name> page, $!tableInfo.name $!entityName){\n \n QueryWrapper<$!tableInfo.name> wrapper = new QueryWrapper<>();\n #foreach($column in $tableInfo.fullColumn)\n #if($column.type == \"java.lang.String\" && \"create_user\" != $!column.obj.name && \"update_user\" != $!column.obj.name)\n if(StringUtils.isNotBlank($!{entityName}.get$tool.firstUpperCase($!{column.name})())){\n wrapper.like(\"$column.obj.name\",$!{entityName}.get$tool.firstUpperCase($!{column.name})());\n }\n #end\n #end\n return this.page(page, wrapper);\n }\n \n @Override\n public List<$!tableInfo.name> listm($!tableInfo.name $!entityName){\n return this.list(new QueryWrapper<>($!entityName));\n }\n \n @Override\n public Boolean savem($!tableInfo.name $!entityName){\n return this.save($!entityName);\n }\n \n @Override\n public Boolean updatem($!tableInfo.name $!entityName){\n return this.updateById($!entityName);\n }\n \n @Override\n public Boolean removem(List<Long> idList){\n return this.removeByIds(idList);\n }\n \n @Override\n public void exportTemplate(HttpServletResponse response) {\n try {\n easyTemplateExport(response, ${tableInfo.name}Excel.class);\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }\n\n\n @Override\n public void exportData(Page<$!tableInfo.name> page, $!tableInfo.name $!entityName, HttpServletResponse response) {\n \n try {\n Page<$!tableInfo.name> pg = this.pagem(page,$!entityName);\n List<$!tableInfo.name> records = pg.getRecords();\n // 修改collect数据,控制导出的内容\n List<Map<String, Object>> collect = records.stream().map(BeanUtil::beanToMap).collect(Collectors.toList());\n List<${tableInfo.name}Excel> list = easyMap2Bean(collect, ${tableInfo.name}Excel.#[[class]]#);\n easyDataExport(list,response, ${tableInfo.name}Excel.#[[class]]#);\n } catch (IOException e) {\n throw new RuntimeException(e);\n }\n }\n \n \n @Override\n @Transactional\n public void importData(HttpServletResponse response, MultipartFile file,String allError) {\n if (file == null) {\n throw new RuntimeException(\"导入文件为空!\");\n }\n try {\n ExcelReader reader = ExcelUtil.getReader(file.getInputStream());\n Workbook workbook = reader.getWorkbook();\n Sheet sheet = workbook.getSheetAt(0);\n EasyCodeResult result = easyDataHandel(sheet, ${tableInfo.name}Excel.#[[class]]#);\n dataCheck(result);\n List<Map<String,Object>> data = result.getData();\n Map<String, String> errMaps = result.getErrMaps();\n result.setSuccessCount(data.size());\n if (StringUtils.equalsIgnoreCase(allError, ALLOW_ERR) || errMaps.isEmpty()) {\n // 如果允许容错才写部分的错误数据\n List<${tableInfo.name}> dataBeans = easyMap2Bean(data, ${tableInfo.name}.#[[class]]#);\n this.saveBatch(dataBeans);\n }\n\n if (!errMaps.isEmpty()) {\n ExcelWriter errs = easyWriteError(sheet, allError, errMaps);\n errs.flush(response.getOutputStream());\n errs.close();\n }\n\n } catch (Exception e) {\n throw new RuntimeException(e);\n }\n }\n /**\n * 修改data数据,控制写入内容\n * 修改errMaps数据,控制批改数据,errMaps的key为excel的xy坐标,value为写出的批改数据\n * 已知错误数据如何获取错误数据的坐标?\n * x坐标从result.getHeaderIndex中通过字段名获取\n * y坐标从result.getData.get(i).get(\"excelIndex\")获取\n * errMaps.put(\"1,1\",\"张三\"),导出的excel中第二行第二列(2,B),会红色字体显示张三\n * 见下方实例代码\n */\n private static void dataCheck(EasyCodeResult result) {\n // List<Map<String, Object>> data = result.getData();\n // List<Map<String, Object>> newData = new ArrayList<>();\n // Map<String, String> errMaps = result.getErrMaps();\n // Map<String, Integer> headers = result.getHeaderIndex();\n // List<String> itemName = new ArrayList<>();\n // for (Map<String, Object> row : data) {\n // Object className = row.get(\"className\");\n // // 通过类名称获取id\n // row.put(\"classId\", className);\n // // 去重\n // Object title = row.get(\"itemName\");\n // if (itemName.contains((String) title)) {\n // errMaps.put(row.get(\"excelIndex\") + \",\" + headers.get(\"itemName\"), title + \"【指标名称已存在】\");\n // } else {\n // itemName.add((String) title);\n // newData.add(row);\n // }\n // }\n // result.setData(newData);\n }\n}\n"
}, {
"name" : "mapper.xml.vm",
"code" : "##引入mybatis支持\n$!{mybatisSupport.vm}\n\n\n##设置保存名称与保存位置\n$!callback.setFileName($tool.append($!{tableInfo.name}, \"Mapper.xml\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/mapper/\"))\n\n\n##拿到主键\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n<mapper namespace=\"$!{tableInfo.savePackageName}.mapper.$!{tableInfo.name}Mapper\">\n\n <resultMap id=\"BaseResultMap\" type=\"$!{tableInfo.savePackageName}.entity.$!{tableInfo.name}\">\n <!--@Table $!{tableInfo.obj.name}-->\n#foreach($column in $tableInfo.fullColumn)\n <result property=\"$!column.name\" column=\"$!column.obj.name\" jdbcType=\"$!column.ext.jdbcType\"/>\n#end\n </resultMap>\n<!-- 批量插入 -->\n <insert id=\"insertBatch\" keyProperty=\"$!pk.name\" useGeneratedKeys=\"true\">\n insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.fullColumn)$!column.obj.name#if( $foreach.hasNext ),#end#end)\n values\n <foreach collection=\"entities\" item=\"entity\" separator=\",\">\n (#foreach($column in $tableInfo.fullColumn)#{entity.$!{column.name}}#if( $foreach.hasNext ),#end#end)\n </foreach>\n </insert>\n <!-- 批量插入或按主键更新 -->\n <insert id=\"insertOrUpdateBatch\" keyProperty=\"$!pk.name\" useGeneratedKeys=\"true\">\n \n insert into $!{tableInfo.obj.name}(#foreach($column in $tableInfo.fullColumn)$!column.obj.name#if( $foreach.hasNext ),#end#end)\n values\n <foreach collection=\"entities\" item=\"entity\" separator=\",\">\n (#foreach($column in $tableInfo.fullColumn)#{entity.$!{column.name}}#if( $foreach.hasNext ),#end#end)\n </foreach>\n on duplicate key update\n #foreach($column in $tableInfo.fullColumn)$!column.obj.name = values($!column.name)#if( $foreach.hasNext ),#end#end\n </insert>\n\n</mapper>\n"
}, {
"name" : "mapper.java.vm",
"code" : "##导入宏定义\n$!{define.vm}\n\n##设置表后缀(宏定义)\n#setTableSuffix(\"Mapper\")\n\n##保存文件(宏定义)\n#save(\"/mapper\", \"Mapper.java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"mapper\")\n\nimport org.apache.ibatis.annotations.Mapper;\nimport com.baomidou.mybatisplus.core.mapper.BaseMapper;\nimport $!{tableInfo.savePackageName}.entity.$!{tableInfo.name};\nimport org.apache.ibatis.annotations.Param;\n\nimport java.util.List;\n##表注释(宏定义)\n#tableComment(\"表数据库访问层\")\n@Mapper\npublic interface $!{tableName} extends BaseMapper<$!{tableInfo.name}> {\n/**\n* 批量新增数据(MyBatis原生foreach方法)\n*\n* @param entities List<$!{tableInfo.name}> 实例对象列表\n* @return 影响行数\n*/\nint insertBatch(@Param(\"entities\") List<$!{tableInfo.name}> entities);\n\n/**\n* 批量新增或按主键更新数据(MyBatis原生foreach方法)\n*\n* @param entities List<$!{tableInfo.name}> 实例对象列表\n* @return 影响行数\n* @throws org.springframework.jdbc.BadSqlGrammarException 入参是空List的时候会抛SQL语句错误的异常,请自行校验入参\n*/\nint insertOrUpdateBatch(@Param(\"entities\") List<$!{tableInfo.name}> entities);\n\n}\n"
}, {
"name" : "entity.java.vm",
"code" : "##导入宏定义\n$!{define.vm}\n\n##保存文件(宏定义)\n#save(\"/entity\", \".java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"entity\")\n\n$!callback.setFileName($tool.append($!{tableInfo.name}, \"Entity.java\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/entity/\"))\n\n##自动导入包(全局变量)\n$!{autoImport.vm}\nimport com.baomidou.mybatisplus.annotation.FieldFill;\nimport com.baomidou.mybatisplus.annotation.IdType;\nimport com.baomidou.mybatisplus.annotation.TableField;\nimport com.baomidou.mybatisplus.annotation.TableId;\nimport com.baomidou.mybatisplus.extension.activerecord.Model;\nimport com.fasterxml.jackson.annotation.JsonFormat;\nimport org.springframework.format.annotation.DateTimeFormat;\nimport com.fasterxml.jackson.databind.annotation.JsonSerialize;\nimport com.fasterxml.jackson.databind.ser.std.ToStringSerializer;\nimport java.io.Serializable;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport cn.dmp.common.easycode.EasyValidateGroup;\nimport org.springframework.validation.annotation.Validated;\nimport javax.validation.constraints.NotNull;\nimport javax.validation.constraints.Size;\n\n##表注释(宏定义)\n#tableComment(\"表实体类\")\n@EqualsAndHashCode(callSuper = true)\n@Data\npublic class $!{tableInfo.name}Entity extends Model<$!{tableInfo.name}Entity> {\n#foreach($column in $tableInfo.fullColumn)\n \n #if(${column.comment}) // ${column.comment}#end\n \n #if($column.type == \"java.time.LocalDateTime\") @DateTimeFormat(pattern = \"yyyy-MM-dd HH:mm:ss\")\n @JsonFormat(pattern = \"yyyy-MM-dd HH:mm:ss\")#end\n #if($column.type == \"java.time.LocalDate\") @DateTimeFormat(pattern = \"yyyy-MM-dd\")\n @JsonFormat(pattern = \"yyyy-MM-dd\")#end\n #if($column.type == \"java.time.LocalTime\") @DateTimeFormat(pattern = \"HH:mm:ss\")\n @JsonFormat(pattern = \"HH:mm:ss\")#end\n #if($column.type == \"java.lang.Long\") @JsonSerialize(using= ToStringSerializer.class)#end\n #if($column.name == \"createUser\") @TableField(fill = FieldFill.INSERT)#end\n #if($column.name == \"createTime\") @TableField(fill = FieldFill.INSERT)#end\n #if($column.name == \"updateUser\") @TableField(fill = FieldFill.INSERT_UPDATE)#end\n #if($column.name == \"updateTime\") @TableField(fill = FieldFill.INSERT_UPDATE)#end\n #if($column.name == \"id\") @TableId(type = IdType.ASSIGN_ID)#end\n #if($!column.name!=\"id\"&&$!column.name!=\"createTime\"&&$!column.name!=\"createUser\"&&$!column.name!=\"updateTime\"&&$!column.name!=\"updateUser\"&&$!column.name!=\"isDeleted\")\n #if(${column.obj.notNull})\n @NotNull(message = \"${column.comment}不能为空\",groups = {EasyValidateGroup.AddGroup.class,EasyValidateGroup.UpdGroup.class})\n #end\n #if($column.obj.dataType.length > 0 && $column.ext.sqlType=='varchar')\n @Size( max = $column.obj.dataType.length, message = \"${column.comment}必须小于${column.obj.dataType.length}字符\", groups = {EasyValidateGroup.AddGroup.class,EasyValidateGroup.UpdGroup.class})\n #end\n #end\n private $!{tool.getClsNameByFullName($column.type)} $!{column.name};\n \n#end\n\n\n#foreach($column in $tableInfo.pkColumn)\n /**\n * 获取主键值\n *\n * @return 主键值\n */\n @Override\n protected Serializable pkVal() {\n return this.$!column.name;\n }\n #break\n#end\n}\n"
}, {
"name" : "dto.java.vm",
"code" : "##导入宏定义\n$!{define.vm}\n##引入mybatis支持\n$!{mybatisSupport.vm}\n\n##保存文件(宏定义)\n#save(\"/entity\", \".java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"entity\")\n\n##自动导入包(全局变量)\nimport com.alibaba.fastjson.annotation.JSONField;\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\n#set($tree = $tool.toJson($tableInfo.fullColumn).contains('\"name\":\"pid\"')&&$tool.toJson($tableInfo.fullColumn).contains('\"name\":\"id\"'))\n#if($tree)\n\nimport com.baomidou.mybatisplus.annotation.TableField;\nimport java.util.List;\n#end\nimport java.util.LinkedHashMap;\nimport java.util.Map;\n\n/**\n * $!{tableInfo.comment}($!{tableInfo.name})交互类\n * 字段需要添加 @TableField(exist = false)\n * @author $!author\n * @since $!time.currTime()\n */\n@EqualsAndHashCode(callSuper = true)\n@Data\npublic class $!{tableInfo.name} extends $!{tableInfo.name}Entity {\n\n // 如何控制,不反给前端某些字段 @JSONField(serialize = false)\n\n // 如何控制,不被数据库表识别 @TableField(exist = false)\n\n\n #if($tree)\n // 因为检测到pid,因此创建树结构的children字段\n @TableField(exist = false)\n private List<$!{tableInfo.name}> children;\n #end\n}\n"
}, {
"name" : "addorupdate.vue.vm",
"code" : "##引入mybatis支持\n$!{mybatisSupport.vm}\n\n\n##设置保存名称与保存位置\n$!callback.setFileName($tool.append('add-or-update', \".vue\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/vue/\",$tableInfo.name))\n\n##拿到主键\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n#set($size = $tableInfo.fullColumn.size())\n#set($inputs = $tool.newArrayList())\n#set($areas = $tool.newArrayList())\n#foreach($column in $tableInfo.fullColumn) \n\n\n#if ($column.ext.sqlType == \"text\"||($column.obj.dataType.length>1000&&$column.ext.sqlType == \"varchar\"))\n#set($xx = $areas.add($column))\n#elseif($column.name != \"projectCode\" && $column.name != \"id\" && $column.name != \"updateUser\" && $column.name != \"updateTime\" && $column.name != \"createTime\" && $column.name != \"createUser\" && $column.name != \"isDeleted\" && $column.name != \"orderId\" )\n#set($xx = $inputs.add($column))\n#end\n#end\n\n#set($cols = ($inputs.size()+$areas.size())/7+1)\n#if($cols>3)\n#set($cols = 3)\n#end\n\n#set($span = 24/$cols)\n\n#if($cols==3)\n#set($width = 75)\n#elseif($cols==2)\n#set($width = 50)\n#elseif($cols==1)\n#set($width = 30)\n#end\n\n<template>\n <div>\n <el-dialog :title=\"title\" width=\"$width%\" :visible.sync=\"visible\" :close-on-click-modal=\"false\" @close=\"close\">\n <el-form :model=\"dataForm\" :rules=\"dataRule\" @keyup.enter.native=\"dataFormSubmitHandle()\" @submit.native.prevent label-width=\"120px\" size=\"small\" ref=\"dataForm\">\n \n #foreach($column in $inputs)\n #if(($foreach.index % (24/$span)) == 0)\n <el-row>\n #end\n <el-col :span=\"$span\">\n #if($column.ext.sqlType== \"int\"||$column.ext.sqlType== \"bigint\")\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <el-input-number :controls=\"false\" v-model=\"dataForm.${column.name}\" style=\"width: 100%\"/>\n </el-form-item>\n #elseif($column.ext.sqlType== \"date\")\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <el-date-picker style=\"width: 100%\" placeholder=\"${column.comment}\" v-model=\"dataForm.${column.name}\" value-format=\"yyyy-MM-dd\" format=\"yyyy-MM-dd\"></el-date-picker>\n </el-form-item>\n #elseif($column.ext.sqlType== \"datetime\"||$column.ext.sqlType== \"timestamp\")\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <el-date-picker style=\"width: 100%\" placeholder=\"${column.comment}\" v-model=\"dataForm.${column.name}\" value-format=\"yyyy-MM-dd HH:mm:ss\" format=\"yyyy-MM-dd HH:mm:ss\"></el-date-picker>\n </el-form-item>\n #elseif($column.ext.sqlType== \"tinyint\")\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <el-select style=\"width: 100%\" placeholder=\"${column.comment}\" v-model=\"dataForm.${column.name}\">\n <el-option label=\"是\" :value=\"1\"></el-option>\n <el-option label=\"否\" :value=\"0\"></el-option>\n </el-select>\n </el-form-item>\n #elseif($column.ext.sqlType== \"decimal\")\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <el-input-number style=\"width: 100%\" placeholder=\"${column.comment}\" v-model=\"dataForm.${column.name}\" :controls=\"false\" precision=\"$column.obj.dataType.scale\" />\n </el-form-item>\n #else\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <el-input placeholder=\"${column.comment}\" v-model=\"dataForm.${column.name}\" clearable show-word-limit maxlength=\"$column.obj.dataType.length\"></el-input> \n </el-form-item>\n #end\n </el-col>\n #if((($foreach.index+1) % (24/$span)) == 0)\n </el-row>\n #end\n #end\n \n #foreach($column in $areas)\n <el-row>\n <el-col :span=\"24\">\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <el-input type=\"textarea\" placeholder=\"${column.comment}\" v-model=\"dataForm.${column.name}\" clearable show-word-limit maxlength=\"#if($column.obj.dataType.length<0)65535#else$column.obj.dataType.length#end\"></el-input> \n </el-form-item>\n </el-col>\n </el-row>\n #end\n </el-form>\n <template slot=\"footer\">\n <el-button @click=\"handleClose\" size=\"mini\">关闭</el-button>\n <el-button :disabled=\"!visible||loading\" @click=\"dataFormSubmitHandle()\" size=\"mini\" type=\"primary\">确认</el-button>\n </template>\n </el-dialog>\n </div>\n</template>\n\n<script>\n import * as api from './api'\n\n export default {\n data() {\n return {\n visible: false,\n dataForm: {\n#foreach($column in $tableInfo.fullColumn)\n #if ($column.name != \"id\" && $column.name != \"updateUser\" && $column.name != \"updateTime\" && $column.name != \"createTime\" && $column.name != \"createUser\" && $column.name != \"isDeleted\" && $column.name != \"orderId\" )\n ${column.name}: null #if( $foreach.hasNext ),#end\n #end \n#end\n },\n title: '',\n loading: false\n }\n },\n computed: {\n dataRule() {\n return {\n#foreach($column in $tableInfo.fullColumn)\n##使用的代码id\n#set($require=false)\n#if ($column.ext.require && $column.name != \"id\" && $column.name != \"updateUser\" && $column.name != \"updateTime\" && $column.name != \"createTime\" && $column.name != \"createUser\" && $column.name != \"isDeleted\" && $column.name != \"orderId\" )\n#set($require=$column.ext.require)\n#end\n##主键输入\n#set($pkinput=false)\n#if ($column.ext.pkinput)\n#set($pkinput=true)\n#end\n#if((${column.obj.isNotNull()} || $require) && ($column.name != $pkColumn.name || $pkinput) && $column.name != \"createUser\" && $column.name != \"createTime\" && $column.name != \"updateUser\" && $column.name != \"updateTime\"&& $column.name != \"id\" ) \n ${column.name}: [{ required: true, message: \"$column.comment是必填项!\" , trigger: 'blur' }],\n#end \n#end \n }\n }\n },\n methods: {\n init() {\n this.title = !this.dataForm.$!{pk.name} ? '新增' : '修改'\n this.visible = true\n this.#[[$]]#nextTick(() => {\n if (this.dataForm.id) this.getInfo()\n })\n },\n handleClose() {\n let field = Object.keys(this.dataForm).filter(s => this.dataForm[s] || this.dataForm[s] === 0);\n if (field.length === 0) {\n this.visible = false\n return;\n }\n this.$confirm(`确认关闭?`, '提示', {\n confirmButtonText: '确认',\n cancelButtonText: '取消',\n type: 'warning'\n }).then(() => {\n this.close()\n }).catch((err) => {\n })\n },\n // 获取信息\n getInfo() {\n api.info(this.dataForm.id).then(data => {\n this.dataForm = data.data\n })\n },\n // 表单提交\n async dataFormSubmitHandle() {\n let valid = await this.#[[$]]#refs.dataForm.validate().catch(() => {\n this.#[[$]]#message.error('校验错误')\n })\n if (!valid) return\n this.loading = true\n if (this.dataForm.id) {\n await api.update(this.dataForm).then(res=>{\n this.$message.success('保存成功')\n }).catch((err) => {\n this.loading = false\n throw err\n })\n } else {\n await api.save(this.dataForm).then(res=>{\n this.$message.success('保存成功')\n }).catch((err) => {\n this.loading = false\n throw err\n })\n }\n\n this.visible = false\n this.#[[$]]#emit('refreshDataList', this.dataForm)\n this.close()\n },\n close() {\n Object.keys(this.dataForm).forEach(k => this.dataForm[k] = null)\n this.visible = false\n }\n },\n watch: {\n }\n }\n</script>\n<style scoped>\n::v-deep .el-row {\n padding-top:25px;\n}\n::v-deep .el-input-number.is-without-controls .el-input__inner{\n text-align: left;\n}\n::v-deep .el-input-number.is-without-controls .el-input__inner{\n text-align: left;\n}\n::v-deep .el-dialog {\n position: relative;\n display: flex;\n flex-direction: column;\n left: 50%;\n top: 40%;\n transform: translate(-50%, -40%);\n margin: 0px !important;\n max-height:calc(100% - 30px);\n}\n::v-deep .el-dialog .el-dialog__body{\n padding-right: 40px;\n flex:1;\n overflow-y: auto;\n padding-bottom: 20px;\n}\n</style>\n"
}, {
"name" : "api.js.vm",
"code" : "##引入mybatis支持\n$!{mybatisSupport.vm}\n\n\n##设置保存名称与保存位置\n$!callback.setFileName($tool.append('api', \".js\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/vue/\",$tableInfo.name))\n\n#set($tree = $tool.toJson($tableInfo.fullColumn).contains('\"name\":\"pid\"')&&$tool.toJson($tableInfo.fullColumn).contains('\"name\":\"id\"'))\n\n##拿到主键\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\nimport io from '@/module/io'\n\n/** 树查询 */\nexport function tree(payload) {\n return io.get(`$!tool.firstLowerCase($!tableInfo.name)/tree`, payload, () => {}, () => {}, { emulateJSON: false, contentType: 'application/json'})\n}\n\n/** 树懒加载树查询 */\nexport function treeLazy(payload) {\n return io.get(`$!tool.firstLowerCase($!tableInfo.name)/treeLazy`, payload, () => {}, () => {}, { emulateJSON: false, contentType: 'application/json'})\n}\n\n/** 分页查询 */\nexport function page(payload) {\n return io.get(`$!tool.firstLowerCase($!tableInfo.name)/page`, payload, () => {}, () => {}, { emulateJSON: false, contentType: 'application/json'})\n}\n\n/** 列表查询 */\nexport function list() {\n return io.get(`$!tool.firstLowerCase($!tableInfo.name)/list`)\n}\n\n/** 单条查询 */\nexport function info(id) {\n return io.get(`$!tool.firstLowerCase($!tableInfo.name)/get/#[[$]]#{id}`)\n}\n\n/** 新增 */\nexport function save(payload) {\n return io.post(`$!tool.firstLowerCase($!tableInfo.name)`, payload, () => {}, () => {}, { emulateJSON: false, contentType: 'application/json'})\n}\n\n/** 更新 */\nexport function update(payload) {\n return io.put(`$!tool.firstLowerCase($!tableInfo.name)`, payload, () => {}, () => {}, { emulateJSON: false, contentType: 'application/json'})\n}\n\n/** 删除 */\nexport function remove(payload) {\n return io.delete(`$!tool.firstLowerCase($!tableInfo.name)?idList=#[[$]]#{payload}`)\n}\n\n/** 导出表模板 */\nexport function exportTemplate(){\n return new Promise((resolve, reject) => {\n io.get(`$!tool.firstLowerCase($!tableInfo.name)/export/template`,{},res => {\n resolve(res)\n }, e => {\n reject(e)\n }, \n { emulateJSON: false, contentType: \"application/json\",responseType:'blob' }\n )\n })\n}\n\n/** 导出表数据 */\nexport function exportData(params){\n return new Promise((resolve, reject) => {\n io.get(`$!tool.firstLowerCase($!tableInfo.name)/export/data`,params,res => {\n resolve(res)\n }, e => {\n reject(e)\n }, \n { emulateJSON: false, contentType: \"application/json\",responseType:'blob' }\n )\n })\n}\n\nexport function importData (params,allowError){\n return new Promise((resolve, reject) => {\n io.post(`$!tool.firstLowerCase($!tableInfo.name)/import/data/#[[$]]#{allowError}`, res => {\n resolve(res)\n }, e => {\n reject(e)\n }, {\n data: params,\n responseType:'blob',\n emulateJSON: false,\n onUploadProgress(e){}\n })\n })\n}\n"
}, {
"name" : "tree.vue.vm",
"code" : "##引入mybatis支持\n$!{mybatisSupport.vm}\n\n\n##设置保存名称与保存位置\n$!callback.setFileName($tool.append('tree', \".vue\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/vue/\",$tableInfo.name))\n\n\n#set($tree = $tool.toJson($tableInfo.fullColumn).contains('\"name\":\"pid\"')&&$tool.toJson($tableInfo.fullColumn).contains('\"name\":\"id\"'))\n\n\n#foreach($item in $tableInfo.fullColumn)\n#if($item.name.contains(\"Name\")||$item.name.contains(\"Title\")||$item.name.contains(\"Label\"))\n#set($label = $item.name)\n#break\n#end\n#end\n\n#if($tree)\n<template>\n\n\n <div style=\"height: 100%\">\n <div style=\"min-height:45px\">\n <el-input v-model=\"filterText\" style=\"width: 160px;margin-bottom: 15px;\" size=\"mini\"\n placeholder=\"输入关键字过滤\" prefix-icon=\"el-icon-search\" clearable></el-input>\n <span class=\"tree-button\">\n <el-button @click=\"addHandle()\" size=\"mini\">新增</el-button>\n </span>\n </div>\n\n <el-tree v-loading=\"treeLoading\" node-key=\"id\" class=\"filter-tree\" :data=\"dictTree\"\n :default-expanded-keys=\"defaultExpandIds\"\n :props=\"defaultProps\"\n :style=\"{'height':heightY-topY + 10 +'px'}\"\n @node-click=\"handleNodeClick\"\n @node-contextmenu=\"rightClickOption\"\n :filter-node-method=\"filterNode\"\n @node-expand=\"handleNodeExpand\"\n @node-collapse=\"handleNodeCollapse\"\n ref=\"classTree\">\n\n </el-tree>\n\n <div v-show=\"optionCardShow\" id=\"option-button-group\"\n :style=\"`left:#[[$]]#{optionCardX}px;top:#[[$]]#{optionCardY}px;`\">\n <el-button @click=\"addHandle(node)\" class=\"option-card-button\">新增\n </el-button>\n <el-button @click=\"updateHandle(node)\" class=\"option-card-button\">编辑\n </el-button>\n <el-button @click=\"getTreeData()\" class=\"option-card-button\">刷新\n </el-button>\n <el-button @click=\"deleteHandle([node.id])\" class=\"option-card-button\">删除\n </el-button>\n </div>\n\n <add-or-update @refreshDataList=\"getTreeData\" ref=\"addOrUpdate\" v-show=\"addOrUpdateVisible\"></add-or-update>\n\n </div>\n</template>\n<script>\nimport * as api from './api'\nimport AddOrUpdate from './add-or-update'\n\nexport default {\n name: 'vue_dmpt_indi_class',\n components: {\n AddOrUpdate\n },\n data() {\n return {\n topY: 285,\n heightY: document.documentElement.clientHeight,\n treeLoading: false,\n addOrUpdateVisible: false,\n dictTree: [],\n defaultProps: {\n children: 'children',\n label: '${label}'\n },\n filterText: '',\n defaultExpandIds: [],\n optionCardX: \"\", // 让右键菜单出现在鼠标右键的位置\n optionCardY: \"\",\n node: {}, // 将当前节点保存\n optionCardShow: false, // 控制右键菜单的显示与隐藏\n treeLevel: null, // 记录当前树层级\n parentId: null, // 记录当前树层级\n }\n },\n mounted() {\n window.addEventListener(\"click\", this.handleClickDoc);\n window.onresize = () => {\n return (() => {\n if (typeof (this.onResize) === 'function') {\n this.onResize({\n w: document.body.clientWidth,\n h: document.body.clientHeight\n })\n }\n })()\n }\n this.getTreeData()\n },\n methods: {\n onResize(e) {\n if (e.h >= 400) {\n this.heightY = e.h\n }\n },\n init() {\n\n },\n getTreeData(id) {\n this.treeLoading = true\n api.tree({})\n .then(res => {\n this.dictTree = res.data\n if (id) {\n this.#[[$]]#nextTick(() => {\n this.#[[$]]#refs.classTree.store.nodesMap[id].expanded = true;\n this.defaultExpandIds.push(id)\n })\n }\n }).catch(err => {\n err.msg ? this.#[[$]]#message.error(err.msg) : \"\";\n }).finally(() => {\n this.treeLoading = false\n })\n },\n\n // 树节点展开\n handleNodeExpand(data) {\n // 保存当前展开的节点\n let flag = false\n this.defaultExpandIds.some(item => {\n if (item === data.id) { // 判断当前节点是否存在, 存在不做处理\n flag = true\n return true\n }\n })\n if (!flag) { // 不存在则存到数组里\n this.defaultExpandIds.push(data.id)\n }\n },\n // 树节点关闭\n handleNodeCollapse(data) {\n // 删除当前关闭的节点\n this.defaultExpandIds.some((item, i) => {\n if (item === data.id) {\n this.defaultExpandIds.splice(i, 1)\n }\n })\n this.removeChildrenIds(data) // 这里主要针对多级树状结构,当关闭父节点时,递归删除父节点下的所有子节点\n },\n // 删除树子节点\n removeChildrenIds(data) {\n const ts = this\n if (data.children) {\n data.children.forEach(function (item) {\n const index = ts.defaultExpandIds.indexOf(item.id)\n if (index > 0) {\n ts.defaultExpandIds.splice(index, 1)\n }\n ts.removeChildrenIds(item)\n })\n }\n },\n //过滤树节点\n filterNode(value, data) {\n if (!value) return true;\n return data.className.toLowerCase().indexOf(value.toLowerCase()) !== -1;\n },\n //点击树节点触发事件\n handleNodeClick(data) {\n this.parentId = data.id\n this.optionCardShow = false\n this.#[[$]]#emit(\"node-click\", data)\n },\n // 点击鼠标右键触发事件\n rightClickOption(e, data, n, t) {\n this.treeLevel = n.level;\n this.optionCardShow = false;\n this.optionCardX = e.x; // 让菜单出现在鼠标右键的位置\n if (n.data.id == 1) {\n this.optionCardY = e.y;\n } else {\n this.optionCardY = e.y - 100;\n }\n //cloneObj(n.data)\n this.node = JSON.parse(JSON.stringify(n.data)); // 将当前节点保存\n this.optionCardShow = true; // 展示右键菜单\n },\n // 点击到树节点以外的区域,隐藏右键菜单\n handleClickDoc() {\n this.optionCardShow = false;\n },\n addHandle(node) {\n this.optionCardShow = false\n this.addOrUpdateVisible = true\n this.#[[$]]#nextTick(() => {\n if(!node){\n node = {}\n node.id = -1\n node[this.defaultProps.label]= '根节点'\n }\n this.#[[$]]#refs.addOrUpdate.dataForm.pid = node.id\n this.#[[$]]#refs.addOrUpdate.dataForm.pidName = node[this.defaultProps.label]\n this.#[[$]]#refs.addOrUpdate.init()\n })\n },\n updateHandle(node) {\n this.optionCardShow = false\n this.addOrUpdateVisible = true\n this.#[[$]]#nextTick(() => {\n this.#[[$]]#refs.addOrUpdate.dataForm.id = node.id\n this.#[[$]]#refs.addOrUpdate.init()\n })\n },\n async deleteHandle() {\n this.optionCardShow = false\n if(this.node.children.length>0){\n this.#[[$]]#message.warning('请先删除下级节点!')\n return\n }\n this.#[[$]]#confirm(`是否确定删除选择的项目?`, '提示', {\n confirmButtonText: '确定',\n cancelButtonText: '取消',\n type: 'warning'\n }).then(() => {\n let data = [this.node.id]\n api.remove(data).then(res=>{\n this.getTreeData()\n }).catch((err)=>{\n err.msg ? this.#[[$]]#message.error(err.msg) : '';\n })\n }).catch((err) => {\n this.dataListLoading = false\n err.msg ? this.#[[$]]#message.error(err.msg) : '';\n })\n }\n },\n watch: {\n filterText(val) {//监听树组件搜索关键字变化\n this.#[[$]]#refs.classTree.filter(val);\n if (val == '') {\n this.defaultExpandIds.splice(0, this.defaultExpandIds.length, []);\n this.getTreeData();\n }\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.dep-card {\n height: 99%;\n}\n\n.openclassifyManage {\n margin: 10px 0;\n}\n\n.tree-button {\n .el-button {\n margin-bottom: 15px;\n }\n}\n\n.filter-tree {\n overflow: hidden;\n height: 90%;\n overflow-y: auto;\n flex: 1;\n\n .comp-tr-node {\n display: inline-block;\n width: 210px;\n\n span {\n width: 100%;\n display: inline-block;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n height: 30px;\n line-height: 30px;\n }\n }\n}\n#option-button-group {\n z-index: 9999;\n position: fixed;\n width: 100px;\n background: white;\n box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04);\n\n .option-card-button {\n width: 100%;\n margin-left: 0;\n font-size: 10.5px;\n border-radius: 0;\n border: 0;\n background-color: #f5f5f5\n }\n}\n\n.option-card-button:hover {\n background-color: #006f4f44\n}\n\n//tree滚动条\n.el-tree:hover::-webkit-scrollbar-thumb {\n background: #2A455B;\n min-width: 200px;\n}\n\n.el-tree::-webkit-scrollbar {\n width: 5px;\n height: 10px;\n}\n\n.el-tree::-webkit-scrollbar-track {\n background: transparent;\n border-radius: 5px;\n margin: 4px 0;\n}\n\n.el-tree::-webkit-scrollbar-thumb {\n background: #2A455B;\n border-radius: 5px;\n}\n.el-tree.scrollbar-show::-webkit-scrollbar-thumb {\n background: #2A455B;\n}\n\n</style>\n#end"
}, {
"name" : "index.vue.vm",
"code" : "##引入mybatis支持\n$!{mybatisSupport.vm}\n\n\n##设置保存名称与保存位置\n$!callback.setFileName($tool.append('index', \".vue\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/vue/\",$tableInfo.name))\n\n##拿到主键\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n#set($tree = $tool.toJson($tableInfo.fullColumn).contains('\"name\":\"pid\"')&&$tool.toJson($tableInfo.fullColumn).contains('\"name\":\"id\"'))\n\n#set($search = $tool.newArrayList())\n\n#foreach($column in $tableInfo.fullColumn) \n#if($column.name.contains(\"name\")||$column.name.contains(\"Name\")||$column.name.contains(\"title\")||$column.name.contains(\"Title\"))\n#set($xx = $search.add($column))\n#end\n#if($search.index>=4)\n#break\n#end\n#end\n\n#if($search.size()==0)\n#foreach($column in $tableInfo.fullColumn) \n#set($xx = $search.add($column))\n#if($search.index>=2)\n#break\n#end\n#end\n#end\n\n\n<template>\n <m-list-construction :hasRouteTitle=\"false\" :customTitle=\"pageTitle\" :isFill=\"true\"\n v-loading=\"dataListLoading\" >\n <template slot=\"content\">\n#if($tree)\n <div class=\"openclassifyManage\" style=\"height:100%\">\n <split-pane :min-percent=\"10\" :max-percent=\"30\" :default-percent=\"16.85\" split=\"vertical\">\n <template slot=\"paneL\">\n <el-card class=\"dep-card\" style=\"margin-right:10px;\" shadow=\"never\">\n <mtree @node-click=\"nodeClickHandel\"></mtree>\n </el-card>\n </template>\n <template slot=\"paneR\">\n <el-card class=\"dep-card\" style=\"margin-left:10px;\" shadow=\"never\">\n#end \n <div class=\"button-box\">\n <div class=\"nav-button-box\">\n <el-button @click=\"addOrUpdateHandle()\" size=\"mini\">新增\n </el-button>\n <el-button @click=\"importHandle()\" size=\"mini\">导入\n </el-button>\n <el-button @click=\"exportHandle()\" size=\"mini\">导出\n </el-button>\n <el-button @click=\"deleteHandle()\" size=\"mini\">批量删除\n </el-button>\n </div>\n \n <el-form ref=\"searchForm\" :inline=\"true\" @keyup.enter.native=\"searchHandel()\" @submit.native.prevent size=\"mini\">\n #foreach($column in $search)\n <el-form-item>\n <el-input clearable placeholder=\"$!column.comment\" v-model=\"dataForm.$!column.name\"></el-input>\n </el-form-item>\n #end\n <el-form-item>\n <el-button icon=\"el-icon-search\" @click=\"searchHandel()\" size=\"mini\"></el-button>\n <el-button @click=\"resetSearch\" icon=\"el-icon-refresh-right\" size=\"mini\"></el-button>\n </el-form-item>\n </el-form>\n </div>\n \n <template v-if=\"dataList.length === 0\">\n <m-no-data></m-no-data>\n </template>\n <template v-else>\n \n <el-table\n ref=\"listTable\"\n :data=\"dataList\"\n @selection-change=\"dataListSelectionChangeHandle\"\n @sort-change=\"dataListSortChangeHandle\"\n highlight-current-row\n :height=\"heightY-topY+'px'\"\n style=\"width: 100%;\"\n size=\"mini\"\n v-loading=\"dataListLoading\">\n <el-table-column align=\"center\" header-align=\"center\" type=\"index\" width=\"50\"></el-table-column>\n <el-table-column align=\"center\" header-align=\"center\" type=\"selection\" width=\"50\" ></el-table-column>\n #foreach($column in $tableInfo.fullColumn)\n #if ($column.name == \"projectCode\" ||$column.name == \"id\" || $column.name == \"updateUser\" || $column.name == \"updateTime\" || $column.name == \"createUser\" ||$column.name == \"isDeleted\" || $column.name == \"orderId\" )\n #elseif($column.ext.sqlType== \"int\"||$column.ext.sqlType== \"bigint\"||$column.ext.sqlType== \"date\"||$column.ext.sqlType== \"datetime\"||$column.ext.sqlType== \"timestamp\"||$column.ext.sqlType== \"decimal\")\n <el-table-column prop=\"$!{column.name}\" :sortable=\"true\" label=\"$!{column.comment}\" min-width=\"150\" show-overflow-tooltip align=\"center\"></el-table-column>\n #elseif($column.ext.sqlType== \"tinyint\")\n <el-table-column prop=\"$!{column.name}\" :sortable=\"true\" label=\"$!{column.comment}\" min-width=\"150\" show-overflow-tooltip align=\"center\">\n <template slot-scope=\"scope\">\n {{scope.row.${column.name}===1?'是':'否'}}\n </template>\n </el-table-column>\n #elseif($column.ext.sqlType== \"text\")\n <el-table-column prop=\"$!{column.name}\" label=\"$!{column.comment}\" min-width=\"250\" show-overflow-tooltip align=\"left\"></el-table-column>\n #else\n <el-table-column prop=\"$!{column.name}\" label=\"$!{column.comment}\" min-width=\"150\" show-overflow-tooltip align=\"center\"></el-table-column>\n #end\n #end\n <el-table-column align=\"center\" fixed=\"right\" header-align=\"center\" label=\"操作\" width=\"150\">\n <template slot-scope=\"scope\">\n <el-button @click=\"detailHandle(scope.row.$!pk.name)\" size=\"mini\" type=\"text\">查看\n </el-button>\n <el-button @click=\"addOrUpdateHandle(scope.row.$!pk.name)\" size=\"mini\" type=\"text\">修改\n </el-button>\n <el-button @click=\"deleteHandle(scope.row.$!pk.name)\" size=\"mini\" type=\"text\">删除\n </el-button>\n </template>\n </el-table-column>\n </el-table>\n <div class=\"pagination-box\">\n <el-pagination :current-page=\"current\"\n :page-size=\"size\"\n :page-sizes=\"[10, 20, 50, 100]\"\n :total=\"total\"\n @current-change=\"pageCurrentChangeHandle\"\n @size-change=\"pageSizeChangeHandle\"\n layout=\"->,total, sizes, prev, pager, next, jumper\">\n </el-pagination>\n </div>\n \n </template>\n \n #if($tree)\n </el-card>\n </template>\n </split-pane>\n </div>\n #end\n \n <!-- 弹窗, 新增 / 修改 -->\n <add-or-update @refreshDataList=\"getDataList\" ref=\"addOrUpdate\" v-show=\"addOrUpdateVisible\"></add-or-update>\n <!-- 弹窗, 详情 -->\n <detail-dialog ref=\"detail\" v-show=\"detailVisible\"></detail-dialog>\n <!-- 弹窗, 上传 -->\n <import-dialog @close=\"getDataList\" ref=\"import\" v-show=\"importVisible\"></import-dialog>\n </template>\n </m-list-construction>\n</template>\n\n<script>\n import mNoData from \"@/module/components/noData/noData\";\n import mListConstruction from \"@/module/components/listConstruction/listConstruction\";\n import { fileDownloadEasycode } from '@/module/util'\n import * as api from './api'\n \n import AddOrUpdate from './add-or-update'\n import detailDialog from './detail'\n import importDialog from './import'\n import mtree from './tree.vue'\n \n export default {\n name: 'vue_$tableInfo.obj.name',\n components: {\n detailDialog,\n importDialog,\n mtree,\n mNoData,\n mListConstruction,\n AddOrUpdate\n },\n data() {\n return {\n topY: #if($tree)270#else 240 #end,\n heightY: document.documentElement.clientHeight,\n pageTitle: '$tableInfo.comment',\n dataForm: {\n #foreach($column in $tableInfo.fullColumn)\n #if($column.type == \"java.lang.String\" && \"create_user\" != $!column.obj.name && \"update_user\" != $!column.obj.name)\n $!column.name: null,\n #end\n #end\n },\n dataList: [],// 数据\n orders: [\n // isEnable设置为true,前端控制数据排序\n {column: 'createTime', column_table: 'create_time', asc: false, isEnable: true},\n#foreach($column in $tableInfo.fullColumn)\n#if (($column.shortType ==\"Integer\"||$column.shortType ==\"Long\"||$column.ext.sqlType.contains(\"date\"))&&\n !($column.name == \"id\" || $column.name == \"updateUser\" || $column.name == \"updateTime\" || $column.name == \"createTime\" || $column.name == \"createUser\" ||$column.name == \"isDeleted\" || $column.name == \"orderId\"))\n {column: '$column.name', column_table: '$column.obj.name', asc: false, isEnable: false},\n#end\n#end\n ],\n current: 1, // 当前页码\n size: 10, // 每页数 size 不会与字段重复\n total: 0, // 总条数\n dataListLoading: false,\n searchShow: false,\n dataListSelections: [], // 数据列表,多选项\n addOrUpdateVisible: false,// 新增/更新,弹窗visible状态\n detailVisible: false,// 详情,弹窗visible状态\n importVisible: false// 上传,弹窗visible状态\n }\n },\n mounted() {\n window.onresize = () => {\n return (() => {\n if (typeof (this.onResize) === 'function') {\n this.onResize({\n w: document.body.clientWidth,\n h: document.body.clientHeight\n })\n }\n })()\n }\n this.getDataList()\n },\n methods: {\n onResize (e) {\n if (e.h >= 400) {\n this.heightY = e.h\n }\n },\n init() {\n\n },\n searchHandel() {\n this.current = 1\n this.getDataList()\n },\n resetSearch() {\n this.$refs['searchForm'].resetFields()\n this.searchHandel()\n },\n getDataList() {\n let params = {\n current: this.current,\n size: this.size,\n ...this.orders,\n ...this.dataForm\n }\n this.dataSortParam(params)\n this.dataListLoading = true\n api.page(params).then((data) => {\n this.dataList = data.data.records\n this.total = data.data.total * 1\n }).catch((err) => {\n this.dataListLoading = false\n err.msg ? this.#[[$]]#message.error(err.msg) : '';\n })\n this.dataListLoading = false\n },\n dataListSelectionChangeHandle(val) {\n this.dataListSelections = val\n },\n // 排序参数设置\n dataSortParam(params) {\n let ors = this.orders.filter(s => s.isEnable);\n for (let i = 0; i < ors.length; i++) {\n params[\"orders[\" + i + \"].column\"] = ors[i].column_table\n params[\"orders[\" + i + \"].asc\"] = ors[i].asc\n }\n },\n // 排序\n dataListSortChangeHandle(data) {\n this.orders.forEach(s => {\n if (s.column === data.prop) {\n s.isEnable = (data.order != null)\n s.asc = data.order === \"ascending\"\n }\n })\n this.getDataList()\n },\n addOrUpdateHandle(id) {\n this.addOrUpdateVisible = true\n this.#[[$]]#nextTick(() => {\n this.#[[$]]#refs.addOrUpdate.dataForm.id = id\n this.#[[$]]#refs.addOrUpdate.init()\n })\n },\n detailHandle(id) {\n this.detailVisible = true\n this.#[[$]]#nextTick(() => {\n this.#[[$]]#refs.detail.dataForm.id = id\n this.#[[$]]#refs.detail.init()\n })\n },\n async exportHandle() {\n if (this.dataList.length > 0) {\n let params = {\n current: this.current,\n size: this.size,\n ...this.dataForm\n }\n this.$message.success('已收到下载请求,正在组装数据,请稍等!')\n const res = await api.exportData(params);\n fileDownloadEasycode(res, '下载文件').then(res => {\n if(res.code === 1){\n this.#[[$]]#message.error(`暂无数据!`)\n }\n }).catch(res => {\n this.#[[$]]#message.error(res.msg)\n })\n \n }\n },\n importHandle() {\n this.importVisible = true\n this.#[[$]]#nextTick(() => {\n this.#[[$]]#refs.import.init()\n })\n },\n deleteHandle (id) { \n this.$confirm(`是否确定删除选择的项目?`, '提示', {\n confirmButtonText: '确定',\n cancelButtonText: '取消',\n type: 'warning'\n }).then(() => {\n let data = id ? [id] : this.dataListSelections.map(item => item.$!pk.name )\n this.$message.success('删除成功')\n api.remove(data).then(res=>{\n this.getDataList()\n })\n }).catch((err) => {\n this.dataListLoading = false\n err.msg ? this.#[[$]]#message.error(err.msg) : '';\n }) \n },\n // 分页, 每页条数\n pageSizeChangeHandle(val) {\n this.current = 1\n this.size = val\n this.getDataList()\n },\n // 分页, 当前页\n pageCurrentChangeHandle(val) {\n this.current = val\n this.getDataList()\n },\n #if($tree)\n nodeClickHandel(data){\n this.#[[$]]#message.warning('//TODO vue_$tableInfo.obj.name点击事件,待处理')\n }\n #end\n }\n }\n</script>\n\n\n<style lang=\"scss\" scoped>\n #if($tree)\n ::v-deep .splitter-pane-resizer {\n background: #888;\n width: 2px !important;\n margin: 0;\n margin-left: 0 !important;\n border: none !important;\n height: 15px !important;\n top: calc((100% - 20px) / 2);\n}\n\n::v-deep .splitter-pane-resizer:before {\n content: \"\";\n display: block;\n width: 2px;\n height: 8px;\n border-radius: 10px;\n line-height: 100%;\n top: calc((100% - 8px) / 2);\n position: absolute;\n left: -4px;\n background: #888;\n}\n\n::v-deep .splitter-pane-resizer:after {\n content: \"\";\n display: block;\n width: 2px;\n height: 8px;\n border-radius: 10px;\n line-height: 100%;\n top: calc((100% - 8px) / 2);\n position: absolute;\n right: -4px;\n background: #888;\n}\n \n.dep-card {\n height: 99%;\n}\n\n.openclassifyManage {\n margin: 10px 0;\n}\n\n.tree-button {\n .el-button {\n margin-bottom: 15px;\n }\n}\n\n.filter-tree {\n overflow: hidden;\n height: 90%;\n overflow-y: auto;\n flex: 1;\n\n .comp-tr-node {\n display: inline-block;\n width: 210px;\n\n span {\n width: 100%;\n display: inline-block;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n height: 30px;\n line-height: 30px;\n }\n }\n}\n\n::v-deep .splitter-pane-resizer {\n background: #888;\n width: 2px !important;\n margin: 0;\n margin-left: 0 !important;\n border: none !important;\n height: 15px !important;\n top: calc((100% - 20px) / 2);\n}\n\n::v-deep .splitter-pane-resizer:before {\n content: \"\";\n display: block;\n width: 2px;\n height: 8px;\n border-radius: 10px;\n line-height: 100%;\n top: calc((100% - 8px) / 2);\n position: absolute;\n left: -4px;\n background: #888;\n}\n\n::v-deep .splitter-pane-resizer:after {\n content: \"\";\n display: block;\n width: 2px;\n height: 8px;\n border-radius: 10px;\n line-height: 100%;\n top: calc((100% - 8px) / 2);\n position: absolute;\n right: -4px;\n background: #888;\n}\n\n#end\n.button-box{\n position: relative;\n width: 100%;\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n #if(!$tree)margin-top: 15px;#end\n}\n.pagination-box{\n position: relative;\n height: 50px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n}\n::v-deep .el-form-item{\n margin-bottom: 15px;\n}\n</style>"
}, {
"name" : "import.vue.vm",
"code" : "##导入宏定义\n$!{define.vm}\n##引入mybatis支持\n$!{mybatisSupport.vm}\n##设置保存名称与保存位置\n$!callback.setFileName($tool.append('import', \".vue\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/vue/\",$tableInfo.name))\n\n\n<template>\n <div>\n <el-dialog title=\"导入\" :visible.sync=\"visible\"\n width=\"450px\" :close-on-click-modal=\"false\" @close=\"close\">\n <template>\n <div class=\"import_file_box\">\n <el-upload style=\"width: 100%\" drag ref=\"upload\" :multiple=\"false\"\n :http-request=\"()=>{}\" :before-upload=\"beforeFileUpload\" :on-remove=\"handleRemove\"\n :file-list=\"fileList\" :limit=\"1\" :on-exceed=\"handleExceed\" accept=\".xlsx,.xls\">\n <em class=\"el-icon-upload\"></em>\n <div class=\"el-upload__text\">将文件拖到此处,或<em>点击上传</em></div>\n </el-upload>\n\n <div class=\"import_file_text\">* 仅允许导入xls、xIsx格式文件。<span @click=\"downloadTemplate\"\n class=\"download_block\">下载模板</span>\n </div>\n <div class=\"import_file_text\">* 数据量与错误数据量,会影响导入效率。\n </div>\n </div>\n </template>\n <template slot=\"footer\" class=\"dialog-footer\">\n <div class=\"switch-box\">\n <el-switch v-model=\"allowError\" size=\"mini\" active-text=\"允许容错\" active-value=\"1\"\n inactive-value=\"2\">\n </el-switch>\n <el-tooltip effect=\"dark\" placement=\"top\">\n <div slot=\"content\">\n 允许容错:忽略异常数据,其他正常数据可导入;\n <br/>\n 不允许容错:不忽略异常数据,数据中任一条异常都会导致所有数据无法导入。\n </div>\n <i class=\"el-icon-warning-outline\"></i>\n </el-tooltip>\n </div>\n <el-button @click=\"close\">取 消</el-button>\n <el-button type=\"primary\" :loading=\"loading\" @click=\"submitImport\">确 定</el-button>\n </template>\n </el-dialog>\n </div>\n</template>\n\n<script>\nimport * as api from './api'\nimport { Message } from 'element-ui';\nimport { fileDownloadEasycode } from '@/module/util'\n\nexport default {\n data() {\n return {\n loading: false,\n allowError: '2',\n formData: {},\n //导入新增\n fileList: [],\n form: {\n fileName: \"\",\n upFile: \"\",\n suffix: \"\",\n fileSize: \"\",\n },\n visible:false\n }\n },\n props: {\n },\n components: {\n },\n\n methods: {\n init() {\n this.title = '导入'\n this.visible = true\n },\n handleExceed() {\n if (this.form.upFile !== null) {\n this.#[[$]]#message.warning('请先删除已上传文件')\n return\n }\n },\n beforeFileUpload(file) {//文件校验\n if (file) {\n let acceptList = [\"xlsx\", \"xls\"]\n // 根据文件名获取文件的后缀名\n let fileType = file.name.split('.').pop().toLowerCase()\n // 判断文件格式是否符合要求\n if (acceptList.indexOf(fileType) === -1) {\n this.#[[$]]#message.error('只能上传 xlsx/xls 格式的文件 !');\n return false\n }\n this.form.fileName = file.name\n this.form.upFile = file\n this.form.suffix = file.name.split('.')[1]\n this.form.fileSize = file.size\n } else {\n return\n }\n },\n handleRemove() {\n this.form = this.$options.data().form\n },\n async downloadTemplate() {//下载模板文件\n let url = ''\n const res = await api.exportTemplate();\n fileDownloadEasycode(res, '模板文件').then(res => {\n if (res.code === 2) {\n this.#[[$]]#message.success(`下载成功文件!`)\n }else if(res.code === 1){\n this.#[[$]]#message.error(`暂无数据!`)\n }\n this.loading = false\n }).catch(res => {\n this.#[[$]]#message.error(res.msg)\n this.loading = false\n })\n },\n async submitImport() {//点击确认上传\n const {upFile} = this.form;\n if (upFile) {\n this.loading = true\n const formData = new FormData();\n formData.append('file', upFile);\n let res = await api.importData(formData, this.allowError);\n fileDownloadEasycode(res, '错误信息').then(res => {\n if (res.code === 2) {\n this.#[[$]]#message.success(`错误数据详情,请关注下载文件!`)\n } else if (res.code === 1) {\n this.#[[$]]#message.success(`导入成功`)\n this.close()\n }\n this.loading = false\n }).catch(res => {\n this.#[[$]]#message.error(res.msg)\n this.loading = false\n })\n } else {\n this.#[[$]]#message.warning('请选择导入文件!')\n }\n },\n close() {\n this.visible = false\n this.fileList = this.$options.data().fileList\n this.form = this.$options.data().form\n this.#[[$]]#emit('close')\n }\n },\n\n}\n</script>\n\n<style lang=\"scss\" scoped>\n::v-deep .el-upload__input {\n display: none !important;\n}\n\n::v-deep .el-upload {\n width: 100%\n}\n\n::v-deep .el-upload-dragger {\n width: 100%;\n}\n\n.import_file_text {\n text-align: left;\n font-size: 13px;\n color: gray;\n margin-top: 10px;\n .download_block {\n color: #1890ff;\n cursor: pointer;\n }\n}\n\n.el-icon-upload {\n color: #c4e0ff;\n}\n\n.switch-box {\n position: absolute;\n left: 15px;\n margin-top: 10px;\n}\n\n.el-dialog__footer {\n padding: 10px 20px 20px;\n text-align: right;\n box-sizing: border-box;\n align-items: center;\n display: flex;\n justify-content: flex-end;\n}\n::v-deep .el-message__content{\n line-height: 18px;\n}\n//容错报错弹窗\n.content-error-box{\n padding: 10px;\n}\n.error-arr-box{\n position: relative;\n width: 100%;\n max-height: 200px;\n overflow-y: auto;\n border-radius: 8px;\n background-color: #fafafa;\n padding: 10px;\n font-size: 12px;\n font-weight: normal;\n line-height: 20px;\n color: #666;\n margin-top: 8px;\n\n}\n.error-arr-box:hover::-webkit-scrollbar-thumb {\n background: #2A455B;\n min-width: 200px;\n}\n\n.error-arr-box::-webkit-scrollbar {\n width: 5px;\n height: 10px;\n}\n\n.error-arr-box::-webkit-scrollbar-track {\n background: transparent;\n border-radius: 5px;\n margin: 4px 0;\n}\n\n.error-arr-box::-webkit-scrollbar-thumb {\n background: #2A455B;\n border-radius: 5px;\n}\n.error-arr-box.scrollbar-show::-webkit-scrollbar-thumb {\n background: #2A455B;\n}\n.error-arr-title{\n position: relative;\n font-weight: 400;\n margin-top: 16px;\n}\n.error-arr-title-icon{\n width: 10px;\n height: 10px;\n background: #006f4f;\n border-radius: 50%;\n position: relative;\n display: inline-block;\n margin-right: 3px;\n}\n</style>\n"
}, {
"name" : "detail.vue.vm",
"code" : "##引入mybatis支持\n$!{mybatisSupport.vm}\n\n##设置保存名称与保存位置\n$!callback.setFileName($tool.append('detail', \".vue\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/vue/\",$tableInfo.name))\n\n##拿到主键\n#if(!$tableInfo.pkColumn.isEmpty())\n #set($pk = $tableInfo.pkColumn.get(0))\n#end\n\n#set($size = $tableInfo.fullColumn.size())\n#set($inputs = $tool.newArrayList())\n#set($areas = $tool.newArrayList())\n#foreach($column in $tableInfo.fullColumn) \n\n\n#if ($column.ext.sqlType == \"text\"||($column.obj.dataType.length>1000&&$column.ext.sqlType == \"varchar\"))\n#set($xx = $areas.add($column))\n#elseif($column.name != \"projectCode\" && $column.name != \"id\" && $column.name != \"updateUser\" && $column.name != \"updateTime\" && $column.name != \"createTime\" && $column.name != \"createUser\" && $column.name != \"isDeleted\" && $column.name != \"orderId\" )\n#set($xx = $inputs.add($column))\n#end\n#end\n\n#set($cols = ($inputs.size()+$areas.size())/7+1)\n#if($cols>3)\n#set($cols = 3)\n#end\n\n#set($span = 24/$cols)\n\n#if($cols==3)\n#set($width = 75)\n#elseif($cols==2)\n#set($width = 50)\n#elseif($cols==1)\n#set($width = 30)\n#end\n\n\n\n<template>\n <div>\n <el-dialog title=\"查看\" width=\"$width%\" :visible.sync=\"visible\" :close-on-click-modal=\"false\">\n <template>\n <div class=\"create-menu-model\">\n <el-form :model=\"dataForm\" label-width=\"120px\" size=\"small\" ref=\"dataForm\">\n #foreach($column in $inputs)\n #if(($foreach.index % (24/$span)) == 0)\n <el-row>\n #end\n <el-col :span=\"$span\">\n #if($column.ext.sqlType== \"tinyint\")\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <div>\n {{dataForm.${column.name}===1?'是':'否'}}\n </div>\n </el-form-item>\n #else\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <div>\n {{dataForm.${column.name}}}\n </div>\n </el-form-item>\n #end\n </el-col>\n #if((($foreach.index+1) % (24/$span)) == 0)\n </el-row>\n #end\n #end\n \n #foreach($column in $areas)\n <el-row>\n <el-col :span=\"24\">\n <el-form-item label=\"${column.comment}\" label-width=\"120px\" prop=\"${column.name}\">\n <div>\n {{dataForm.${column.name}}}\n </div>\n </el-form-item>\n </el-col>\n </el-row>\n #end\n \n </el-form>\n </div>\n </template>\n <template slot=\"footer\">\n <el-button @click=\"handleClose\" size=\"mini\">关闭</el-button>\n </template>\n </el-dialog>\n </div>\n</template>\n\n<script>\n import * as api from './api'\n\n export default {\n data() {\n return {\n nowCol: $!cols,\n visible: false,\n dataForm: {\n#foreach($column in $tableInfo.fullColumn)\n #if ($column.name != \"id\" && $column.name != \"updateUser\" && $column.name != \"updateTime\" && $column.name != \"createTime\" && $column.name != \"createUser\" && $column.name != \"isDeleted\" && $column.name != \"orderId\" )\n ${column.name}: null #if( $foreach.hasNext ),#end\n #end \n#end\n }\n }\n },\n computed: {\n \n },\n methods: {\n init() {\n this.visible = true\n this.#[[$]]#nextTick(() => {\n if (this.dataForm.id) this.getInfo()\n })\n },\n handleClose() {\n this.visible = false\n },\n // 获取信息\n getInfo() {\n api.info(this.dataForm.id).then(data => {\n this.dataForm = data.data\n })\n }\n },\n watch: {\n \n }\n }\n</script>\n<style lang=\"scss\" scoped>\n::v-deep .el-form-item {\n margin-bottom: 5px;\n}\n\n::v-deep label {\n font-weight: 400;\n}\n\n::v-deep .el-dialog .el-dialog__body {\n padding: 10px 23px;\n /* padding-right: 40px; */\n}\n\n::v-deep .el-dialog {\n position: relative;\n display: flex;\n flex-direction: column;\n left: 50%;\n top: 40%;\n transform: translate(-50%, -40%);\n margin: 0px !important;\n max-height:calc(100% - 30px);\n}\n::v-deep .el-dialog .el-dialog__body{\n padding-right: 40px;\n flex:1;\n overflow-y: auto;\n padding-bottom: 20px;\n}\n\n.el-dialog .el-form .el-form-item {\n margin-bottom: 20px\n}\n\n::v-deep .el-select {\n position: relative;\n width: 100%;\n}\n</style>\n"
}, {
"name" : "excel.java.vm",
"code" : "##导入宏定义\n$!{define.vm}\n##引入mybatis支持\n$!{mybatisSupport.vm}\n\n##保存文件(宏定义)\n#save(\"/excel\", \".java\")\n\n##包路径(宏定义)\n#setPackageSuffix(\"excel\")\n\n$!callback.setFileName($tool.append($!{tableInfo.name}, \"Excel.java\"))\n$!callback.setSavePath($tool.append($tableInfo.savePath, \"/excel/\"))\n\n##自动导入包(全局变量)\nimport lombok.Data;\nimport lombok.EqualsAndHashCode;\nimport cn.dmp.common.easycode.EasyCodeConfig;\nimport java.util.LinkedHashMap;\nimport java.util.Map;\nimport java.time.LocalDate;\nimport java.time.LocalDateTime;\n\n/**\n * $!{tableInfo.comment}($!{tableInfo.name})Excel 模板\n * @author $!author\n * @since $!time.currTime()\n */\n@Data\npublic class $!{tableInfo.name}Excel {\n // 导出字段配置,字段名、字段配置 请注意修改表字段后 需要同步这里!!\n\n#foreach($column in $tableInfo.fullColumn)\n#if($!column.name!=\"id\"&&$!column.name!=\"createTime\"&&$!column.name!=\"createUser\"&&$!column.name!=\"updateTime\"&&$!column.name!=\"updateUser\"&&$!column.name!=\"isDeleted\")\n #if($column.ext.sqlType=='date')\n @EasyCodeConfig(title = \"${column.comment}\",propName = \"${column.name}\" ,length= $column.obj.dataType.length ,tip = \"日期类型,格式:1999-12-01\", type = \"date\" ,noNull = ${column.obj.notNull},comment = \"${column.comment}\")\n #elseif($column.ext.sqlType=='datetime'||$column.ext.sqlType=='timestampe')\n @EasyCodeConfig(title = \"${column.comment}\",propName = \"${column.name}\" ,length= $column.obj.dataType.length ,tip = \"时间类型,格式:1999-12-01 23:01:04\", type = \"datetime\" ,noNull = ${column.obj.notNull},comment = \"${column.comment}\")\n #elseif($column.ext.sqlType=='int')\n @EasyCodeConfig(title = \"${column.comment}\",propName = \"${column.name}\" ,length= $column.obj.dataType.length ,tip = \"整数类型,范围:-2,147,483,648 到 2,147,483,64\", type = \"$column.ext.sqlType\" ,noNull = ${column.obj.notNull},comment = \"${column.comment}\")\n #elseif($column.ext.sqlType=='bigint')\n @EasyCodeConfig(title = \"${column.comment}\",propName = \"${column.name}\" ,length= $column.obj.dataType.length ,tip = \"长整数类型,范围:-2^63 到 2^63-1\", type = \"$column.ext.sqlType\" ,noNull = ${column.obj.notNull},comment = \"${column.comment}\")\n #elseif($column.ext.sqlType=='tinyint')\n @EasyCodeConfig(title = \"${column.comment}\",propName = \"${column.name}\" ,length= $column.obj.dataType.length ,tip = \"布尔类型,只允许是/否\", type = \"$column.ext.sqlType\" ,noNull = ${column.obj.notNull},comment = \"${column.comment}\")\n #elseif($column.ext.sqlType == 'decimal')\n @EasyCodeConfig(title = \"${column.comment}\",propName = \"${column.name}\" ,length= $column.obj.dataType.length , scale = $column.obj.dataType.scale ,tip = \"小数类型,限制${column.obj.dataType.scale}小数位\", type = \"$column.ext.sqlType\" ,noNull = ${column.obj.notNull},comment = \"${column.comment}\")\n #elseif( $column.ext.sqlType=='text')\n @EasyCodeConfig(title = \"${column.comment}\",propName = \"${column.name}\" ,length= 65535 ,tip = \"字符类型,限制${column.obj.dataType.length}个字符\", type = \"$column.ext.sqlType\" ,noNull = ${column.obj.notNull},comment = \"${column.comment}\")\n #else\n @EasyCodeConfig(title = \"${column.comment}\",propName = \"${column.name}\" ,length= $column.obj.dataType.length ,tip = \"字符类型,限制${column.obj.dataType.length}个字符\", type = \"varchar\" ,noNull = ${column.obj.notNull},comment = \"${column.comment}\")\n #end\n private $!{tool.getClsNameByFullName($column.type)} $!{column.name};\n#end\n#end\n}\n"
} ]
}
},
"columnConfig" : {
"Default" : {
"name" : "Default",
"elementList" : [ {
"title" : "disable",
"type" : "BOOLEAN",
"selectValue" : ""
}, {
"title" : "support",
"type" : "SELECT",
"selectValue" : "add,edit,query,del,ui"
} ]
}
},
"globalConfig" : {
"Default" : {
"name" : "Default",
"elementList" : [ {
"name" : "autoImport.vm",
"value" : "##自动导入包(仅导入实体属性需要的包,通常用于实体类)\n#foreach($import in $importList)\nimport $!import;\n#end"
}, {
"name" : "define.vm",
"value" : "##(Velocity宏定义)\n\n##定义设置表名后缀的宏定义,调用方式:#setTableSuffix(\"Test\")\n#macro(setTableSuffix $suffix)\n #set($tableName = $!tool.append($tableInfo.name, $suffix))\n#end\n\n##定义设置包名后缀的宏定义,调用方式:#setPackageSuffix(\"Test\")\n#macro(setPackageSuffix $suffix)\n#if($suffix!=\"\")package #end#if($tableInfo.savePackageName!=\"\")$!{tableInfo.savePackageName}.#{end}$!suffix;\n#end\n\n##定义直接保存路径与文件名简化的宏定义,调用方式:#save(\"/entity\", \".java\")\n#macro(save $path $fileName)\n $!callback.setSavePath($tool.append($tableInfo.savePath, $path))\n $!callback.setFileName($tool.append($tableInfo.name, $fileName))\n#end\n\n##定义表注释的宏定义,调用方式:#tableComment(\"注释信息\")\n#macro(tableComment $desc)\n/**\n * $!{tableInfo.comment}($!{tableInfo.name})$desc\n *\n * @author $!author\n * @since $!time.currTime()\n */\n#end\n\n##定义GET,SET方法的宏定义,调用方式:#getSetMethod($column)\n#macro(getSetMethod $column)\n\n public $!{tool.getClsNameByFullName($column.type)} get$!{tool.firstUpperCase($column.name)}() {\n return $!{column.name};\n }\n\n public void set$!{tool.firstUpperCase($column.name)}($!{tool.getClsNameByFullName($column.type)} $!{column.name}) {\n this.$!{column.name} = $!{column.name};\n }\n#end"
}, {
"name" : "init.vm",
"value" : "##初始化区域\n\n##去掉表的t_前缀\n$!tableInfo.setName($tool.getClassName($tableInfo.obj.name.replaceFirst(\"book_\",\"\")))\n\n##参考阿里巴巴开发手册,POJO 类中布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误\n#foreach($column in $tableInfo.fullColumn)\n#if($column.name.startsWith(\"is\") && $column.type.equals(\"java.lang.Boolean\"))\n $!column.setName($tool.firstLowerCase($column.name.substring(2)))\n#end\n#end\n\n##实现动态排除列\n#set($temp = $tool.newHashSet(\"testCreateTime\", \"otherColumn\"))\n#foreach($item in $temp)\n #set($newList = $tool.newArrayList())\n #foreach($column in $tableInfo.fullColumn)\n #if($column.name!=$item)\n ##带有反回值的方法调用时使用$tool.call来消除返回值\n $tool.call($newList.add($column))\n #end\n #end\n ##重新保存\n $tableInfo.setFullColumn($newList)\n#end\n\n##对importList进行篡改\n#set($temp = $tool.newHashSet())\n#foreach($column in $tableInfo.fullColumn)\n #if(!$column.type.startsWith(\"java.lang.\"))\n ##带有反回值的方法调用时使用$tool.call来消除返回值\n $tool.call($temp.add($column.type))\n #end\n#end\n##覆盖\n#set($importList = $temp)"
}, {
"name" : "mybatisSupport.vm",
"value" : "##针对Mybatis 进行支持,主要用于生成xml文件\n#foreach($column in $tableInfo.fullColumn)\n ##储存列类型\n $tool.call($column.ext.put(\"sqlType\", $tool.getField($column.obj.dataType, \"typeName\")))\n #if($tool.newHashSet(\"java.lang.String\").contains($column.type))\n #set($jdbcType=\"VARCHAR\")\n #elseif($tool.newHashSet(\"java.lang.Boolean\", \"boolean\").contains($column.type))\n #set($jdbcType=\"BOOLEAN\")\n #elseif($tool.newHashSet(\"java.lang.Byte\", \"byte\").contains($column.type))\n #set($jdbcType=\"BYTE\")\n #elseif($tool.newHashSet(\"java.lang.Integer\", \"int\", \"java.lang.Short\", \"short\").contains($column.type))\n #set($jdbcType=\"INTEGER\")\n #elseif($tool.newHashSet(\"java.lang.Long\", \"long\").contains($column.type))\n #set($jdbcType=\"INTEGER\")\n #elseif($tool.newHashSet(\"java.lang.Float\", \"float\", \"java.lang.Double\", \"double\").contains($column.type))\n #set($jdbcType=\"NUMERIC\")\n #elseif($tool.newHashSet(\"java.util.Date\", \"java.sql.Timestamp\", \"java.time.Instant\", \"java.time.LocalDateTime\", \"java.time.OffsetDateTime\", \"\tjava.time.ZonedDateTime\").contains($column.type))\n #set($jdbcType=\"TIMESTAMP\")\n #elseif($tool.newHashSet(\"java.sql.Date\", \"java.time.LocalDate\").contains($column.type))\n #set($jdbcType=\"TIMESTAMP\")\n #else\n ##其他类型\n #set($jdbcType=\"VARCHAR\")\n #end\n $tool.call($column.ext.put(\"jdbcType\", $jdbcType))\n#end\n\n##定义宏,查询所有列\n#macro(allSqlColumn)#foreach($column in $tableInfo.fullColumn)$column.obj.name#if($velocityHasNext), #end#end#end\n"
} ]
}
}
}
前端效果展示
tree 结构
支持左右拖拽